Index: /trunk/exodus/models.py
===================================================================
--- /trunk/exodus/models.py	(revision 6456)
+++ /trunk/exodus/models.py	(revision 6457)
@@ -132,5 +132,5 @@
         if not self.link:
             self.link = self
-            super(Interface, self).save(force_insert, force_update)
+            super(Interface, self).save(False, True)
         
 
Index: /trunk/exodus/tests.py
===================================================================
--- /trunk/exodus/tests.py	(revision 6456)
+++ /trunk/exodus/tests.py	(revision 6457)
@@ -22,4 +22,73 @@
         from django.db import connection
         connection.creation.destroy_test_db(self.olddbname, 0)
+
+
+class IPCalcTest(unittest.TestCase):
+    def setUp(self):
+        #Set up the client
+        from django.test.client import Client
+        self.client = Client()
+        
+        #Set up a inmemory database
+        from exodus import settings
+        self.olddbname = settings.DATABASE_NAME
+        from django.db import connection
+        self.dbname = connection.creation.create_test_db(0)
+    
+        from exodus.models import Node  
+        self.node = Node.objects.get(pk=1)
+        
+        from exodus.wlipcalc import IPCalc
+        self.ipcalc = lambda a: IPCalc(self.node, a)
+        self.IPCalc = IPCalc
+
+    def test_ipcalc_ip_size(self):
+        netmask = 25
+        ip_size = self.ipcalc(netmask)._ip_size(25)
+        self.failUnless(ip_size, 128) 
+
+    def test_ipcalc_out_of_bounds(self):
+        self.failUnlessRaises(ValueError, self.ipcalc, 33)
+        self.failUnlessRaises(ValueError, self.ipcalc, 24)
+    
+    def test_ipcalc_raise_exception(self):
+        from exodus.models import Interface
+        iface = Interface.objects.create(
+            node = self.node, type = 'eth', iface ='eth3',
+            ip = '172.16.0.130', netmask = 25)
+        
+        self.failUnlessRaises(Exception, self.ipcalc, 25)
+    
+    def test_ipcalc_32(self):
+        ip = '172.16.0.3'
+        netmask = 32
+        ipcalc = self.ipcalc(netmask)
+        
+        self.failUnlessEqual(ipcalc.network, ip) 
+        self.failUnlessEqual(ipcalc.ips, ip) 
+        self.failUnlessEqual(ipcalc.broadcast, ip) 
+        self.failUnlessEqual(ipcalc.netmask, netmask)
+
+    def test_ipcalc(self):
+        from exodus import wllogic as wl
+        netmask = 28
+        network = '172.16.0.16'
+        ipcalc = self.ipcalc(netmask)
+        self.failUnlessEqual(ipcalc.network, network )
+        self.failUnlessEqual(ipcalc.broadcast, '172.16.0.31')
+       
+        length = len(ipcalc.ips)
+        self.failUnlessEqual(length, 14)
+        parse = wl.parse_addr(network)
+        ip_list = []
+        for i in range(1, length + 1):
+            ip_list.append(wl.show_addr(parse + i))
+
+        self.failUnlessEqual(ipcalc.ips, ip_list)
+
+    def tearDown(self):
+        from django.db import connection
+        connection.creation.destroy_test_db(self.olddbname, 0)
+    
 
 
@@ -215,4 +284,5 @@
     s.addTest(unittest.makeSuite(AddTest))
     s.addTest(unittest.makeSuite(wllogic))
+    s.addTest(unittest.makeSuite(IPCalcTest))
     s.addTest(unittest.makeSuite(Link))
 
Index: /trunk/exodus/wlipcalc.py
===================================================================
--- /trunk/exodus/wlipcalc.py	(revision 6456)
+++ /trunk/exodus/wlipcalc.py	(revision 6457)
@@ -9,28 +9,21 @@
     """
 
-    #XXX: don't allow for /31
-    #XXX: we compensate for network and broadcast, but this shouln't be
-    #XXX: a /25 doesn't work 
-    #XXX: something goes wrong with a /28 with the broadcast addr
-    #       when using a /32
     def __init__(self, node, free_netmask):
-        if free_netmask < MASTERIP_NETMASK or free_netmask > 32:
+        if free_netmask <= MASTERIP_NETMASK or free_netmask > 32:
             raise ValueError, 'Netmask out of bounds.'
 
-        self.node = node
-        self.free_netmask = free_netmask
-
-        self.master_ip = node.masterip
-        self.master_netmask = MASTERIP_NETMASK
+        master_ip = node.masterip
+        master_netmask = MASTERIP_NETMASK
+        master_network = wl.get_network(master_ip, master_netmask)
 
         # calculate the number of ipaddresses in the subnetmask
-        self.master_ip_size = self._ip_size(self.master_netmask)
-        self.new_ip_size = self._ip_size(self.free_netmask)
+        master_ip_size = self._ip_size(master_netmask)
+        new_ip_size = self._ip_size(free_netmask)
         
         # generate a list of all used_ipaddresses
         # we take only the ip addresses of the interfaces that are
         # linked to itself, because they are 'master' and the slaves
-        # fall in their subnet. 
-        used_list = [self.master_ip] 
+        # on other nodes fall in their subnet. 
+        used_list = [master_ip] 
         for i in node.interface_set.all():
             #XXX: rewrite to if i.ip in masterip??
@@ -41,30 +34,31 @@
                     used_list.append(wl.show_addr(network_addr + j))
 
-        import pdb; pdb.set_trace() ; 
-
-        network_addr = wl.network(self.master_ip, self.master_netmask)
-        for i in range(self.master_ip_size/self.new_ip_size):
-            network_addr += i 
+        for i in range(master_ip_size/new_ip_size):
+            network_addr = wl.parse_addr(master_network) + (new_ip_size * i)
             k = 0
-            for j in range(self.new_ip_size):
+            for j in range(new_ip_size):
                 new_ip = wl.show_addr(network_addr + j) 
                 if new_ip not in used_list:
                     k += 1 
-            if k == self.new_ip_size:
-                self.network = wl.get_network(wl.show_addr( 
-                        network_addr),self.free_netmask)
+            if k == new_ip_size and \
+                    wl.show_addr(network_addr) != master_network:
+                self.network = wl.show_addr(network_addr)
                 break 
-   
-        # define usefull variables 
-        self.netmask = self.free_netmask
-        self.broadcast = wl.get_broadcast(self.network, self.netmask)
-        # get all ips in network, but make compensate for first and last
-        first_ip = wl.parse_addr(self.network) + 1
-        self.ips = []
-        for i in range(self.new_ip_size-1):
-            self.ips.append(wl.show_addr(network_addr + i))                    
 
-
-        #self.ip = network_ip
+        if not self.network:
+            raise Exception, "Not enough space for a /%d subnet" % \
+                (free_netmask)
+  
+        # variables for extenal calling
+        self.netmask = free_netmask
+        if free_netmask == 32:
+            self.broadcast = self.ips = self.network 
+        else: 
+            self.broadcast = wl.get_broadcast(self.network, self.netmask)
+            # get all ips in network, but make compensate for network and 
+            # broadcast addresses.
+            self.ips = []
+            for i in range(1, new_ip_size-1):
+                self.ips.append(wl.show_addr(network_addr + i))                    
     def _ip_size(self, netmask):
         return int(pow(2,32 - netmask))
