125a126 > import copy 131,135c132,136 < '0' : 'PUBLIC', # fall back < '00000000' : 'PRIVATE', # 0/8 < '00001010' : 'PRIVATE', # 10/8 < '01111111' : 'PRIVATE', # 127.0/8 < '1' : 'PUBLIC', # fall back --- > '0' : 'PUBLIC', # fall back > '00000000' : 'PRIVATE', # 0/8 > '00001010' : 'PRIVATE', # 10/8 > '01111111' : 'PRIVATE', # 127.0/8 > '1' : 'PUBLIC', # fall back 137,139c138,140 < '1100000010101000' : 'PRIVATE', # 192.168/16 < '11011111' : 'RESERVED', # 223/8 < '111' : 'RESERVED' # 224/3 --- > '1100000010101000' : 'PRIVATE', # 192.168/16 > '11011111' : 'RESERVED', # 223/8 > '111' : 'RESERVED' # 224/3 932c933 < raise ValueError, "Only networks with teh same IP version can be added." --- > raise ValueError, "Only networks with the same IP version can be added." 934c935 < other.__add__(self) --- > return other.__add__(self) 935a937,943 > # XXX This is Poopie: Need to be more straigh forward > mask = other._prefixlen > a = IP(other.int()) > a._prefixlen = mask - 1 > a = IP(a.netmask().int() & a.int()) > a._prefixlen = mask - 1 > mask = self._prefixlen 937,938c945,951 < ret._prefixlen = self.prefixlen() - 1 < return ret --- > ret._prefixlen = mask - 1 > ret = IP(ret.netmask().int() & ret.int()) > ret._prefixlen = mask - 1 > if a.net() == ret.net(): > return ret > else: > raise ValueError, "Only can add with the same network" 939a953,1153 > def __div__(self, other): > """Divide a this network into two or more subnets""" > if not self.version() == 4: > raise ValueError, "This only works with Version IPv4 Currently" > else: > maxpower = 32 - self._prefixlen > allowed = [] > for i in range(1,maxpower+1): > allowed.append(2 ** i) > if other not in allowed: > raise ValueError, "This can only be divided by powers of 2 and/or cannot be divided into move networks then hosts" > list = [self] > for i in allowed: > if i > other: > break > list2 = [] > for i in list: > holder = subnet(i) > list2.append(holder[0]) > list2.append(holder[1]) > list = list2[:] > return list > > def subnetto(self,opt): > """Subnets self to what ever CIDR notation requested > > This will return a list of the current network subnetted to the first argment. Will > raise TypeError. > > Examples: > >>> IP("192.168.1.0/24").subnetto(26) > [IP('192.168.1.0/26'), IP('192.168.1.64/26'), IP('192.168.1.128/26'), IP('192.168.1.192/26')] > > """ > if type(opt) == types.IntType: > return self._subnet_by_int(opt) > elif type(opt) == types.StringType: > if 0 < len(opt) < 4: > self._subnet_by_int(int(opt)) > elif len(opt) > 1: > # TODO This is not evan close > pass > elif isinstance(opt, IP) or isinstance(opt, IPint): > self._subnet_by_IP(opt) > > > def _matchinghash(self): > holder = self._parentsubnet().subnetto(self._prefixlen) > if holder[0] == self: > return hash(holder[1]) > else: > return hash(holder[0]) > > > def _parentsubnet(self): > acopy = copy.deepcopy(self) > holder = acopy._prefixlen - 1 > acopy._prefixlen = acopy._prefixlen - 1 > acopy = IP(acopy.netmask().int() & acopy.int()) > acopy._prefixlen = holder > return acopy > > > def _subnet_by_IP(self, opt): > if opt not in self: > raise ValueError, "You can only subnet to a smaller subnet, that is contained with in" > else: > pass > > > def _subnet_by_int(self, int): > if self.version() == 4 and (self._prefixlen > int < 33): > raise ValueError, "Must be a smaller subnet, and a Max of /32" > elif self.version() == 6 and (self._prefixlen > int < 123): > raise ValueError, "Must be a smaller subnet, and a Max of /128" > else: > holder = [self] > while 1: > if holder[0]._prefixlen == int: > break > list = [] > for i in holder: > a,b = subnet(i) > list.append(a) > list.append(b) > holder = list[:] > return holder > > > class Pool: > """Storage Object for IP address's > > This Object will store IP address and allow you add more in and it > will handle subnetting them to the highest network when it can. > > """ > def __init__(self,level=0): > self._pool = {} > self.errorlevel = level > def add(self, address): > if not isinstance(address, IP) and not isinstance(address, IPint): > raise TypeError, "This must be IP class object" > elif self._pool.has_key(str(hash(address))) and self.errorlevel: > raise ValueError, "This IP address already in pool" > elif self._pool.has_key(str(hash(address))): > return > elif self._pool.has_key(str(address._matchinghash())): > del self._pool[str(address._matchinghash())] > self.add(address._parentsubnet()) > else: > for i in self._pool.keys(): > if address in self._pool[i]: > if self.errorlevel: > raise ValueError, "This IP address/es already in pool" > else: > return > self._pool[str(hash(address))] = address > def __add__(self,other): > """Adding of IP obj, strings, list, trubles, Pool obj to current Pool > > XXX Should I be overloading the + for this type of object hummmm??? > > >>> x = Pool() > >>> x.add(IP("192.168.1.128/25")) > >>> x.printall() > 192.168.1.128/25 > >>> x += IP("192.168.1.0/25") > >>> x.printall() > 192.168.1.0/24 > >>> y = Pool() > >>> y += IP("10.0.0.0/8") > >>> z = x + y > >>> z.printall() > 10.0.0.0/8 > 192.168.1.0/24 > > """ > acopy = copy.deepcopy(self) > if type(other) == types.ListType or type(other) == types.TupleType: > for i in other: > acopy.__add__(i) > > elif (type(other) == types.StringType or \ > type(other) == types.IntType or type(other) == types.LongType): > acopy.add(IP(other)) > elif isinstance(other, Pool): > for i in other._pool.keys(): > acopy.add(copy.deepcopy(other._pool[i])) > elif isinstance(other, IP) or isinstance(other, IPint): > acopy.add(other) > else: > raise TypeError, "Object Type is unknown and could not be added." > return acopy > > def __contains__(self, other): > for i in self._pool.keys(): > if other in self._pool[i]: > return 1 > return 0 > > def numberofips(self): > """Returns the total number of IP addresses in the pool > > >>> x = Pool() > >>> x.add(IP("192.168.128.0/23")) > >>> x.add(IP("10.1.1.1")) > >>> x.numberofips() > 513 > """ > number = 0 > for i in self._pool.keys(): > number += len(self._pool[i]) > return number > > def __len__(self): > return len(self._pool) > def __str__(self): > return str(self._pool) > def printall(self): > for i in self._pool.keys(): > print self._pool[i] > > > > > > def subnet(ip): > """Return the next two subnets of a network""" > if (ip._prefixlen >= 32 and ip.version() == 4) or \ > (ip._prefixlen >= 128 and ip.version() == 6): > # XXX TypeError Or ValueError ? > raise TypeError, "Cannot subnet this IP address" > holder = ip._prefixlen > a = IP(ip.int()) > b = IP(ip.int()) > b._prefixlen = holder + 1 > a = IP((a.int() ^ (a.netmask().int() ^ b.netmask().int())) + 1) > a._prefixlen = holder + 1 > return (b,a) > >