+ """A class representing a generic CIDRized network value."""
+
+ def __str__(self):
+ return self.addr + "/" + str(self.netlen)
+
+ def __repr__(self):
+ return "<" + str(self) + ">"
+
+ def __cmp__(self, other):
+ """One CIDR network block is less than another if the start
+ address is numerically less or if the block is larger. That
+ is, supernets will sort before subnets. This ordering allows
+ for an efficient search for subnets of a given network."""
+
+ res = self._base_mask(self.numaddr) - self._base_mask(other.numaddr)
+ if res == 0: res = self.netlen - other.netlen
+ if res < 0: return -1
+ if res > 0: return 1
+ return 0
+
+ def calc(self):
+ """This method should be called after any change to the main
+ internal state: netlen or numaddr."""
+
+ # make sure the network length is valid
+ if not self._is_valid_netlen(netlen):
+ raise TypeError, "network length must be between 0 and %d" % (_max_netlen())
+
+ # convert the string ipv4 address to a 32bit number
+ self.numaddr = self._convert_ipstr(self.addr)
+ # calculate our netmask
+ self.mask = self._mask(self.netlen)
+ # force the cidr address into correct masked notation
+ self.numaddr &= self.mask
+
+ # convert the number back to a string to normalize the string
+ self.addr = self._convert_ipaddr(self.numaddr)
+
+ def is_supernet(self, other):
+ """returns True if the other Cidr object is a supernet (an
+ enclosing network block) of this one. A Cidr object is a
+ supernet of itself."""
+ return other.numaddr & self.mask == self.numaddr
+
+ def is_subnet(self, other):
+ """returns True if the other Cidr object is a subnet (an
+ enclosednetwork block) of this one. A Cidr object is a
+ subnet of itself."""
+ return self.numaddr & other.mask == other.numaddr
+
+ def netmask(self):
+ """return the netmask of this Cidr network"""
+ return self._convert_ipaddr(self.mask)
+
+ def length(self):
+ """return the length (in number of addresses) of this network block"""
+ return netlen_to_length(self.netlen)
+
+ def end(self):
+ """return the last IP address in this network block"""
+ return self._convert_ipaddr(self.numaddr + self.length() - 1)
+
+ def to_netblock(self):
+ return (self.addr, self.end())
+
+ def clone(self):
+ # we can get away with a shallow copy (so far)
+ return copy.copy(self)
+
+class CidrV4(Cidr):