diff --git a/src/network.py b/src/network.py index b4c279a..2d5f15f 100755 --- a/src/network.py +++ b/src/network.py @@ -108,10 +108,38 @@ class IntervalPool(object): #self.pool[str(i)].sort(key=ip_to_int) # cidr between thiscidr and upcidr are null, no need to sort return [True, upinterval] + # check whether the addr/cidr overlaps the self.pool + # for example, addr/cidr=172.16.0.48/29 overlaps self.pool['24']=[172.16.0.0] + def overlap(self, addr, cidr): + cidr=int(cidr) + start_cidr=int(self.info.split('/')[1]) + # test self.pool[cidr] from first cidr pool to last cidr pool + for cur_cidr in range(start_cidr, 33): + if not self.pool[str(cur_cidr)]: + continue + # for every cur_cidr, test every possible element covered by pool[cur_cidr] in range of addr/cidr + cur_addr=fix_ip(addr, min(cidr, cur_cidr)) + last_addr=next_interval(addr, cidr) + while(ip_to_int(cur_addr)=int(pool_cidr) and fix_ip(addr,pool_cidr)==pool_addr: + return True + else: + return False + # deallocate an interval with IP/CIDR - # ToDo : when free IP/CIDR, we donot check whether IP/CIDR is in pool - # maybe we check this later def free(self, addr, cidr): + if not self.inrange(addr, cidr): + return [False, '%s/%s not in range of %s' % (addr, str(cidr), self.info)] + if self.overlap(addr, cidr): + return [False, '%s/%s overlaps the center pool:%s' % (addr, str(cidr), self.__str__())] cidr = int(cidr) # cidr not in pool means CIDR out of pool range if str(cidr) not in self.pool: @@ -185,14 +213,24 @@ class EnumPool(object): return [status, result] return [True, list(map(lambda x:x+"/"+self.info.split('/')[1], result))] - # ToDo : when release : - # not check whether IP is in the range of pool - # not check whether IP is already in the pool + def inrange(self, ip): + addr = self.info.split('/')[0] + addrint = ip_to_int(addr) + cidr = int(self.info.split('/')[1]) + if addrint+1 <= ip_to_int(ip) <= addrint+pow(2, 32-cidr)-2: + return True + return False + def release(self, ip_or_ips): if type(ip_or_ips) == str: ips = [ ip_or_ips ] else: ips = ip_or_ips + # check whether all IPs are not in the pool but in the range of pool + for ip in ips: + ip = ip.split('/')[0] + if (ip in self.pool) or (not self.inrange(ip)): + return [False, 'release IPs failed for ip already existing or ip exceeding the network pool, ips to be released: %s, ip pool is: %s and content is : %s' % (ips, self.info, self.pool)] for ip in ips: # maybe ip is in format IP/CIDR ip = ip.split('/')[0] @@ -221,6 +259,14 @@ class UserPool(EnumPool): def get_gateway_cidr(self): return self.gateway+"/"+self.info.split('/')[1] + def inrange(self, ip): + addr = self.info.split('/')[0] + addrint = ip_to_int(addr) + cidr = int(self.info.split('/')[1]) + if addrint+2 <= ip_to_int(ip) <= addrint+pow(2, 32-cidr)-2: + return True + return False + def printpool(self): print("users ID:"+str(self.vlanid)+", net info:"+self.info+", gateway:"+self.gateway) print (str(self.pool))