ipaddr.py
Go to the documentation of this file.
00001 #!/usr/bin/python
00002 #
00003 # Copyright 2007 Google Inc.
00004 #  Licensed to PSF under a Contributor Agreement.
00005 #
00006 # Licensed under the Apache License, Version 2.0 (the "License");
00007 # you may not use this file except in compliance with the License.
00008 # You may obtain a copy of the License at
00009 #
00010 #      http://www.apache.org/licenses/LICENSE-2.0
00011 #
00012 # Unless required by applicable law or agreed to in writing, software
00013 # distributed under the License is distributed on an "AS IS" BASIS,
00014 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
00015 # implied. See the License for the specific language governing
00016 # permissions and limitations under the License.
00017 
00018 """A fast, lightweight IPv4/IPv6 manipulation library in Python.
00019 
00020 This library is used to create/poke/manipulate IPv4 and IPv6 addresses
00021 and networks.
00022 
00023 """
00024 
00025 __version__ = '2.1.1'
00026 
00027 import struct
00028 
00029 
00030 class AddressValueError(ValueError):
00031     """A Value Error related to the address."""
00032 
00033 
00034 class NetmaskValueError(ValueError):
00035     """A Value Error related to the netmask."""
00036 
00037 
00038 def IPAddress(address, version=None):
00039     """Take an IP string/int and return an object of the correct type.
00040 
00041     Args:
00042         address: A string or integer, the IP address.  Either IPv4 or
00043           IPv6 addresses may be supplied; integers less than 2**32 will
00044           be considered to be IPv4 by default.
00045         version: An Integer, 4 or 6. If set, don't try to automatically
00046           determine what the IP address type is. important for things
00047           like IPAddress(1), which could be IPv4, '0.0.0.0.1',  or IPv6,
00048           '::1'.
00049 
00050     Returns:
00051         An IPv4Address or IPv6Address object.
00052 
00053     Raises:
00054         ValueError: if the string passed isn't either a v4 or a v6
00055           address.
00056 
00057     """
00058     if version:
00059         if version == 4:
00060             return IPv4Address(address)
00061         elif version == 6:
00062             return IPv6Address(address)
00063 
00064     try:
00065         return IPv4Address(address)
00066     except (AddressValueError, NetmaskValueError):
00067         pass
00068 
00069     try:
00070         return IPv6Address(address)
00071     except (AddressValueError, NetmaskValueError):
00072         pass
00073 
00074     raise ValueError('%r does not appear to be an IPv4 or IPv6 address' %
00075                      address)
00076 
00077 
00078 def IPNetwork(address, version=None, strict=False):
00079     """Take an IP string/int and return an object of the correct type.
00080 
00081     Args:
00082         address: A string or integer, the IP address.  Either IPv4 or
00083           IPv6 addresses may be supplied; integers less than 2**32 will
00084           be considered to be IPv4 by default.
00085         version: An Integer, if set, don't try to automatically
00086           determine what the IP address type is. important for things
00087           like IPNetwork(1), which could be IPv4, '0.0.0.1/32', or IPv6,
00088           '::1/128'.
00089 
00090     Returns:
00091         An IPv4Network or IPv6Network object.
00092 
00093     Raises:
00094         ValueError: if the string passed isn't either a v4 or a v6
00095           address. Or if a strict network was requested and a strict
00096           network wasn't given.
00097 
00098     """
00099     if version:
00100         if version == 4:
00101             return IPv4Network(address, strict)
00102         elif version == 6:
00103             return IPv6Network(address, strict)
00104 
00105     try:
00106         return IPv4Network(address, strict)
00107     except (AddressValueError, NetmaskValueError):
00108         pass
00109 
00110     try:
00111         return IPv6Network(address, strict)
00112     except (AddressValueError, NetmaskValueError):
00113         pass
00114 
00115     raise ValueError('%r does not appear to be an IPv4 or IPv6 network' %
00116                      address)
00117 
00118 
00119 def _find_address_range(addresses):
00120     """Find a sequence of addresses.
00121 
00122     Args:
00123         addresses: a list of IPv4 or IPv6 addresses.
00124 
00125     Returns:
00126         A tuple containing the first and last IP addresses in the sequence.
00127 
00128     """
00129     first = last = addresses[0]
00130     for ip in addresses[1:]:
00131         if ip._ip == last._ip + 1:
00132             last = ip
00133         else:
00134             break
00135     return (first, last)
00136 
00137 def _get_prefix_length(number1, number2, bits):
00138     """Get the number of leading bits that are same for two numbers.
00139 
00140     Args:
00141         number1: an integer.
00142         number2: another integer.
00143         bits: the maximum number of bits to compare.
00144 
00145     Returns:
00146         The number of leading bits that are the same for two numbers.
00147 
00148     """
00149     for i in range(bits):
00150         if number1 >> i == number2 >> i:
00151             return bits - i
00152     return 0
00153 
00154 def _count_righthand_zero_bits(number, bits):
00155     """Count the number of zero bits on the right hand side.
00156 
00157     Args:
00158         number: an integer.
00159         bits: maximum number of bits to count.
00160 
00161     Returns:
00162         The number of zero bits on the right hand side of the number.
00163 
00164     """
00165     if number == 0:
00166         return bits
00167     for i in range(bits):
00168         if (number >> i) % 2:
00169             return i
00170 
00171 def summarize_address_range(first, last):
00172     """Summarize a network range given the first and last IP addresses.
00173 
00174     Example:
00175         >>> summarize_address_range(IPv4Address('1.1.1.0'),
00176             IPv4Address('1.1.1.130'))
00177         [IPv4Network('1.1.1.0/25'), IPv4Network('1.1.1.128/31'),
00178         IPv4Network('1.1.1.130/32')]
00179 
00180     Args:
00181         first: the first IPv4Address or IPv6Address in the range.
00182         last: the last IPv4Address or IPv6Address in the range.
00183 
00184     Returns:
00185         The address range collapsed to a list of IPv4Network's or
00186         IPv6Network's.
00187 
00188     Raise:
00189         TypeError:
00190             If the first and last objects are not IP addresses.
00191             If the first and last objects are not the same version.
00192         ValueError:
00193             If the last object is not greater than the first.
00194             If the version is not 4 or 6.
00195 
00196     """
00197     if not (isinstance(first, _BaseIP) and isinstance(last, _BaseIP)):
00198         raise TypeError('first and last must be IP addresses, not networks')
00199     if first.version != last.version:
00200         raise TypeError("%s and %s are not of the same version" % (
00201                 str(self), str(other)))        
00202     if first > last:
00203         raise ValueError('last IP address must be greater than first')
00204 
00205     networks = []
00206 
00207     if first.version == 4:
00208         ip = IPv4Network
00209     elif first.version == 6:
00210         ip = IPv6Network
00211     else:
00212         raise ValueError('unknown IP version')
00213 
00214     ip_bits = first._max_prefixlen
00215     first_int = first._ip
00216     last_int = last._ip
00217     while first_int <= last_int:
00218         nbits = _count_righthand_zero_bits(first_int, ip_bits)
00219         current = None
00220         while nbits >= 0:
00221             addend = 2**nbits - 1
00222             current = first_int + addend
00223             nbits -= 1
00224             if current <= last_int:
00225                 break
00226         prefix = _get_prefix_length(first_int, current, ip_bits)
00227         net = ip('%s/%d' % (str(first), prefix))
00228         networks.append(net)
00229         if current == ip._ALL_ONES:
00230             break
00231         first_int = current + 1
00232         first = IPAddress(first_int, version=first._version)
00233     return networks
00234 
00235 def _collapse_address_list_recursive(addresses):
00236     """Loops through the addresses, collapsing concurrent netblocks.
00237 
00238     Example:
00239 
00240         ip1 = IPv4Network'1.1.0.0/24')
00241         ip2 = IPv4Network'1.1.1.0/24')
00242         ip3 = IPv4Network'1.1.2.0/24')
00243         ip4 = IPv4Network'1.1.3.0/24')
00244         ip5 = IPv4Network'1.1.4.0/24')
00245         ip6 = IPv4Network'1.1.0.1/22')
00246 
00247         _collapse_address_list_recursive([ip1, ip2, ip3, ip4, ip5, ip6]) ->
00248           [IPv4Network('1.1.0.0/22'), IPv4Network('1.1.4.0/24')]
00249 
00250         This shouldn't be called directly; it is called via
00251           collapse_address_list([]).
00252 
00253     Args:
00254         addresses: A list of IPv4Network's or IPv6Network's
00255 
00256     Returns:
00257         A list of IPv4Network's or IPv6Network's depending on what we were
00258         passed.
00259 
00260     """
00261     ret_array = []
00262     optimized = False
00263 
00264     for cur_addr in addresses:
00265         if not ret_array:
00266             ret_array.append(cur_addr)
00267             continue
00268         if cur_addr in ret_array[-1]:
00269             optimized = True
00270         elif cur_addr == ret_array[-1].supernet().subnet()[1]:
00271             ret_array.append(ret_array.pop().supernet())
00272             optimized = True
00273         else:
00274             ret_array.append(cur_addr)
00275 
00276     if optimized:
00277         return _collapse_address_list_recursive(ret_array)
00278 
00279     return ret_array
00280 
00281 
00282 def collapse_address_list(addresses):
00283     """Collapse a list of IP objects.
00284 
00285     Example:
00286         collapse_address_list([IPv4('1.1.0.0/24'), IPv4('1.1.1.0/24')]) ->
00287           [IPv4('1.1.0.0/23')]
00288 
00289     Args:
00290         addresses: A list of IPv4Network or IPv6Network objects.
00291 
00292     Returns:
00293         A list of IPv4Network or IPv6Network objects depending on what we
00294         were passed.
00295 
00296     Raises:
00297         TypeError: If passed a list of mixed version objects.
00298 
00299     """
00300     i = 0
00301     addrs = []
00302     ips = []
00303     nets = []
00304 
00305     # split IP addresses and networks
00306     for ip in addresses:
00307         if isinstance(ip, _BaseIP):
00308             if ips and ips[-1]._version != ip._version:
00309                 raise TypeError("%s and %s are not of the same version" % (
00310                         str(ip), str(ips[-1])))
00311             ips.append(ip)
00312         elif ip._prefixlen == ip._max_prefixlen:
00313             if ips and ips[-1]._version != ip._version:
00314                 raise TypeError("%s and %s are not of the same version" % (
00315                         str(ip), str(ips[-1])))
00316             ips.append(ip.ip)
00317         else:
00318             if nets and nets[-1]._version != ip._version:
00319                 raise TypeError("%s and %s are not of the same version" % (
00320                         str(ip), str(ips[-1])))
00321             nets.append(ip)
00322 
00323     # sort and dedup
00324     ips = sorted(set(ips))
00325     nets = sorted(set(nets))
00326 
00327     while i < len(ips):
00328         (first, last) = _find_address_range(ips[i:])
00329         i = ips.index(last) + 1
00330         addrs.extend(summarize_address_range(first, last))
00331 
00332     return _collapse_address_list_recursive(sorted(
00333         addrs + nets, key=_BaseNet._get_networks_key))
00334 
00335 # backwards compatibility
00336 CollapseAddrList = collapse_address_list
00337 
00338 # Test whether this Python implementation supports byte objects that
00339 # are not identical to str ones.
00340 # We need to exclude platforms where bytes == str so that we can
00341 # distinguish between packed representations and strings, for example
00342 # b'12::' (the IPv4 address 49.50.58.58) and '12::' (an IPv6 address).
00343 try:
00344     _compat_has_real_bytes = bytes is not str
00345 except NameError: # <Python2.6
00346     _compat_has_real_bytes = False
00347 
00348 def get_mixed_type_key(obj):
00349     """Return a key suitable for sorting between networks and addresses.
00350 
00351     Address and Network objects are not sortable by default; they're
00352     fundamentally different so the expression
00353 
00354         IPv4Address('1.1.1.1') <= IPv4Network('1.1.1.1/24')
00355 
00356     doesn't make any sense.  There are some times however, where you may wish
00357     to have ipaddr sort these for you anyway. If you need to do this, you
00358     can use this function as the key= argument to sorted().
00359     
00360     Args:
00361       obj: either a Network or Address object.
00362     Returns:
00363       appropriate key.
00364 
00365     """
00366     if isinstance(obj, _BaseNet):
00367         return obj._get_networks_key()
00368     elif isinstance(obj, _BaseIP):
00369         return obj._get_address_key()
00370     return NotImplemented
00371 
00372 class _IPAddrBase(object):
00373 
00374     """The mother class."""
00375 
00376     def __index__(self):
00377         return self._ip
00378 
00379     def __int__(self):
00380         return self._ip
00381 
00382     def __hex__(self):
00383         return hex(self._ip)
00384 
00385     @property
00386     def exploded(self):
00387         """Return the longhand version of the IP address as a string."""
00388         return self._explode_shorthand_ip_string()
00389 
00390     @property
00391     def compressed(self):
00392         """Return the shorthand version of the IP address as a string."""
00393         return str(self)
00394 
00395 
00396 class _BaseIP(_IPAddrBase):
00397 
00398     """A generic IP object.
00399 
00400     This IP class contains the version independent methods which are
00401     used by single IP addresses.
00402 
00403     """
00404 
00405     def __init__(self, address):
00406         if '/' in str(address):
00407             raise AddressValueError(address)
00408 
00409     def __eq__(self, other):
00410         try:
00411             return (self._ip == other._ip
00412                     and self._version == other._version)
00413         except AttributeError:
00414             return NotImplemented
00415 
00416     def __ne__(self, other):
00417         eq = self.__eq__(other)
00418         if eq is NotImplemented:
00419             return NotImplemented
00420         return not eq
00421 
00422     def __le__(self, other):
00423         gt = self.__gt__(other)
00424         if gt is NotImplemented:
00425             return NotImplemented
00426         return not gt
00427 
00428     def __ge__(self, other):
00429         lt = self.__lt__(other)
00430         if lt is NotImplemented:
00431             return NotImplemented
00432         return not lt
00433 
00434     def __lt__(self, other):
00435         if self._version != other._version:
00436             raise TypeError('%s and %s are not of the same version' % (
00437                     str(self), str(other)))
00438         if not isinstance(other, _BaseIP):
00439             raise TypeError('%s and %s are not of the same type' % (
00440                     str(self), str(other)))
00441         if self._ip != other._ip:
00442             return self._ip < other._ip
00443         return False
00444 
00445     def __gt__(self, other):
00446         if self._version != other._version:
00447             raise TypeError('%s and %s are not of the same version' % (
00448                     str(self), str(other)))
00449         if not isinstance(other, _BaseIP):
00450             raise TypeError('%s and %s are not of the same type' % (
00451                     str(self), str(other)))
00452         if self._ip != other._ip:
00453             return self._ip > other._ip
00454         return False
00455 
00456     def __repr__(self):
00457         return '%s(%r)' % (self.__class__.__name__, str(self))
00458 
00459     def __str__(self):
00460         return  '%s' % self._string_from_ip_int(self._ip)
00461 
00462     def __hash__(self):
00463         return hash(hex(self._ip))
00464 
00465     def _get_address_key(self):
00466         return (self._version, self)
00467 
00468     @property
00469     def version(self):
00470         raise NotImplementedError('BaseIP has no version')
00471 
00472 
00473 class _BaseNet(_IPAddrBase):
00474 
00475     """A generic IP object.
00476 
00477     This IP class contains the version independent methods which are
00478     used by networks.
00479 
00480     """
00481 
00482     def __init__(self, address):
00483         self._cache = {}
00484 
00485     def __repr__(self):
00486         return '%s(%r)' % (self.__class__.__name__, str(self))
00487 
00488     def iterhosts(self):
00489         """Generate Iterator over usable hosts in a network.
00490 
00491            This is like __iter__ except it doesn't return the network
00492            or broadcast addresses.
00493 
00494         """
00495         cur = int(self.network) + 1
00496         bcast = int(self.broadcast) - 1
00497         while cur <= bcast:
00498             cur += 1
00499             yield IPAddress(cur - 1, version=self._version)
00500 
00501     def __iter__(self):
00502         cur = int(self.network)
00503         bcast = int(self.broadcast)
00504         while cur <= bcast:
00505             cur += 1
00506             yield IPAddress(cur - 1, version=self._version)
00507 
00508     def __getitem__(self, n):
00509         network = int(self.network)
00510         broadcast = int(self.broadcast)
00511         if n >= 0:
00512             if network + n > broadcast:
00513                 raise IndexError
00514             return IPAddress(network + n, version=self._version)
00515         else:
00516             n += 1
00517             if broadcast + n < network:
00518                 raise IndexError
00519             return IPAddress(broadcast + n, version=self._version)
00520 
00521     def __lt__(self, other):
00522         if self._version != other._version:
00523             raise TypeError('%s and %s are not of the same version' % (
00524                     str(self), str(other)))
00525         if not isinstance(other, _BaseNet):
00526             raise TypeError('%s and %s are not of the same type' % (
00527                     str(self), str(other)))
00528         if self.network != other.network:
00529             return self.network < other.network
00530         if self.netmask != other.netmask:
00531             return self.netmask < other.netmask
00532         return False
00533 
00534     def __gt__(self, other):
00535         if self._version != other._version:
00536             raise TypeError('%s and %s are not of the same version' % (
00537                     str(self), str(other)))
00538         if not isinstance(other, _BaseNet):
00539             raise TypeError('%s and %s are not of the same type' % (
00540                     str(self), str(other)))
00541         if self.network != other.network:
00542             return self.network > other.network
00543         if self.netmask != other.netmask:
00544             return self.netmask > other.netmask
00545         return False
00546 
00547     def __le__(self, other):
00548         gt = self.__gt__(other)
00549         if gt is NotImplemented:
00550             return NotImplemented
00551         return not gt
00552 
00553     def __ge__(self, other):
00554         lt = self.__lt__(other)
00555         if lt is NotImplemented:
00556             return NotImplemented
00557         return not lt
00558 
00559     def __eq__(self, other):
00560         try:
00561             return (self._version == other._version
00562                     and self.network == other.network
00563                     and int(self.netmask) == int(other.netmask))
00564         except AttributeError:
00565             return NotImplemented
00566 
00567     def __ne__(self, other):
00568         eq = self.__eq__(other)
00569         if eq is NotImplemented:
00570             return NotImplemented
00571         return not eq
00572 
00573     def __str__(self):
00574         return  '%s/%s' % (str(self.ip),
00575                            str(self._prefixlen))
00576 
00577     def __hash__(self):
00578         return hash(int(self.network) ^ int(self.netmask))
00579 
00580     def __contains__(self, other):
00581         # dealing with another network.
00582         if isinstance(other, _BaseNet):
00583             return (int(self.network) <= int(other._ip) and
00584                     int(self.broadcast) >= int(other.broadcast))
00585         # dealing with another address
00586         else:
00587             return (int(self.network) <= int(other._ip) <=
00588                     int(self.broadcast))
00589 
00590     def overlaps(self, other):
00591         """Tell if self is partly contained in other."""
00592         return self.network in other or self.broadcast in other or (
00593             other.network in self or other.broadcast in self)
00594 
00595     @property
00596     def network(self):
00597         x = self._cache.get('network')
00598         if x is None:
00599             x = IPAddress(self._ip & int(self.netmask), version=self._version)
00600             self._cache['network'] = x
00601         return x
00602 
00603     @property
00604     def broadcast(self):
00605         x = self._cache.get('broadcast')
00606         if x is None:
00607             x = IPAddress(self._ip | int(self.hostmask), version=self._version)
00608             self._cache['broadcast'] = x
00609         return x
00610 
00611     @property
00612     def hostmask(self):
00613         x = self._cache.get('hostmask')
00614         if x is None:
00615             x = IPAddress(int(self.netmask) ^ self._ALL_ONES,
00616                           version=self._version)
00617             self._cache['hostmask'] = x
00618         return x
00619 
00620     @property
00621     def with_prefixlen(self):
00622         return '%s/%d' % (str(self.ip), self._prefixlen)
00623 
00624     @property
00625     def with_netmask(self):
00626         return '%s/%s' % (str(self.ip), str(self.netmask))
00627 
00628     @property
00629     def with_hostmask(self):
00630         return '%s/%s' % (str(self.ip), str(self.hostmask))
00631 
00632     @property
00633     def numhosts(self):
00634         """Number of hosts in the current subnet."""
00635         return int(self.broadcast) - int(self.network) + 1
00636 
00637     @property
00638     def version(self):
00639         raise NotImplementedError('BaseNet has no version')
00640 
00641     @property
00642     def prefixlen(self):
00643         return self._prefixlen
00644 
00645     def address_exclude(self, other):
00646         """Remove an address from a larger block.
00647 
00648         For example:
00649 
00650             addr1 = IP('10.1.1.0/24')
00651             addr2 = IP('10.1.1.0/26')
00652             addr1.address_exclude(addr2) =
00653                 [IP('10.1.1.64/26'), IP('10.1.1.128/25')]
00654 
00655         or IPv6:
00656 
00657             addr1 = IP('::1/32')
00658             addr2 = IP('::1/128')
00659             addr1.address_exclude(addr2) = [IP('::0/128'),
00660                 IP('::2/127'),
00661                 IP('::4/126'),
00662                 IP('::8/125'),
00663                 ...
00664                 IP('0:0:8000::/33')]
00665 
00666         Args:
00667             other: An IP object of the same type.
00668 
00669         Returns:
00670             A sorted list of IP objects addresses which is self minus
00671             other.
00672 
00673         Raises:
00674             TypeError: If self and other are of difffering address
00675               versions.
00676             ValueError: If other is not completely contained by self.
00677 
00678         """
00679         if not self._version == other._version:
00680             raise TypeError("%s and %s are not of the same version" % (
00681                 str(self), str(other)))
00682 
00683         if other not in self:
00684             raise ValueError('%s not contained in %s' % (str(other),
00685                                                          str(self)))
00686         ret_addrs = []
00687 
00688         # Make sure we're comparing the network of other.
00689         other = IPNetwork('%s/%s' % (str(other.network), str(other.prefixlen)),
00690                    version=other._version)
00691 
00692         s1, s2 = self.subnet()
00693         while s1 != other and s2 != other:
00694             if other in s1:
00695                 ret_addrs.append(s2)
00696                 s1, s2 = s1.subnet()
00697             elif other in s2:
00698                 ret_addrs.append(s1)
00699                 s1, s2 = s2.subnet()
00700             else:
00701                 # If we got here, there's a bug somewhere.
00702                 assert True == False, ('Error performing exclusion: '
00703                                        's1: %s s2: %s other: %s' %
00704                                        (str(s1), str(s2), str(other)))
00705         if s1 == other:
00706             ret_addrs.append(s2)
00707         elif s2 == other:
00708             ret_addrs.append(s1)
00709         else:
00710             # If we got here, there's a bug somewhere.
00711             assert True == False, ('Error performing exclusion: '
00712                                    's1: %s s2: %s other: %s' %
00713                                    (str(s1), str(s2), str(other)))
00714 
00715         return sorted(ret_addrs, key=_BaseNet._get_networks_key)
00716 
00717     def compare_networks(self, other):
00718         """Compare two IP objects.
00719 
00720         This is only concerned about the comparison of the integer
00721         representation of the network addresses.  This means that the
00722         host bits aren't considered at all in this method.  If you want
00723         to compare host bits, you can easily enough do a
00724         'HostA._ip < HostB._ip'
00725 
00726         Args:
00727             other: An IP object.
00728 
00729         Returns:
00730             If the IP versions of self and other are the same, returns:
00731 
00732             -1 if self < other:
00733               eg: IPv4('1.1.1.0/24') < IPv4('1.1.2.0/24')
00734               IPv6('1080::200C:417A') < IPv6('1080::200B:417B')
00735             0 if self == other
00736               eg: IPv4('1.1.1.1/24') == IPv4('1.1.1.2/24')
00737               IPv6('1080::200C:417A/96') == IPv6('1080::200C:417B/96')
00738             1 if self > other
00739               eg: IPv4('1.1.1.0/24') > IPv4('1.1.0.0/24')
00740               IPv6('1080::1:200C:417A/112') >
00741               IPv6('1080::0:200C:417A/112')
00742 
00743             If the IP versions of self and other are different, returns:
00744 
00745             -1 if self._version < other._version
00746               eg: IPv4('10.0.0.1/24') < IPv6('::1/128')
00747             1 if self._version > other._version
00748               eg: IPv6('::1/128') > IPv4('255.255.255.0/24')
00749 
00750         """
00751         if self._version < other._version:
00752             return -1
00753         if self._version > other._version:
00754             return 1
00755         # self._version == other._version below here:
00756         if self.network < other.network:
00757             return -1
00758         if self.network > other.network:
00759             return 1
00760         # self.network == other.network below here:
00761         if self.netmask < other.netmask:
00762             return -1
00763         if self.netmask > other.netmask:
00764             return 1
00765         # self.network == other.network and self.netmask == other.netmask
00766         return 0
00767 
00768     def _get_networks_key(self):
00769         """Network-only key function.
00770 
00771         Returns an object that identifies this address' network and
00772         netmask. This function is a suitable "key" argument for sorted()
00773         and list.sort().
00774 
00775         """
00776         return (self._version, self.network, self.netmask)
00777 
00778     def _ip_int_from_prefix(self, prefixlen=None):
00779         """Turn the prefix length netmask into a int for comparison.
00780 
00781         Args:
00782             prefixlen: An integer, the prefix length.
00783 
00784         Returns:
00785             An integer.
00786 
00787         """
00788         if not prefixlen and prefixlen != 0:
00789             prefixlen = self._prefixlen
00790         return self._ALL_ONES ^ (self._ALL_ONES >> prefixlen)
00791 
00792     def _prefix_from_ip_int(self, ip_int, mask=32):
00793         """Return prefix length from the decimal netmask.
00794 
00795         Args:
00796             ip_int: An integer, the IP address.
00797             mask: The netmask.  Defaults to 32.
00798 
00799         Returns:
00800             An integer, the prefix length.
00801 
00802         """
00803         while mask:
00804             if ip_int & 1 == 1:
00805                 break
00806             ip_int >>= 1
00807             mask -= 1
00808 
00809         return mask
00810 
00811     def _ip_string_from_prefix(self, prefixlen=None):
00812         """Turn a prefix length into a dotted decimal string.
00813 
00814         Args:
00815             prefixlen: An integer, the netmask prefix length.
00816 
00817         Returns:
00818             A string, the dotted decimal netmask string.
00819 
00820         """
00821         if not prefixlen:
00822             prefixlen = self._prefixlen
00823         return self._string_from_ip_int(self._ip_int_from_prefix(prefixlen))
00824 
00825     def iter_subnets(self, prefixlen_diff=1, new_prefix=None):
00826         """The subnets which join to make the current subnet.
00827 
00828         In the case that self contains only one IP
00829         (self._prefixlen == 32 for IPv4 or self._prefixlen == 128
00830         for IPv6), return a list with just ourself.
00831 
00832         Args:
00833             prefixlen_diff: An integer, the amount the prefix length
00834               should be increased by. This should not be set if
00835               new_prefix is also set.
00836             new_prefix: The desired new prefix length. This must be a
00837               larger number (smaller prefix) than the existing prefix.
00838               This should not be set if prefixlen_diff is also set.
00839 
00840         Returns:
00841             An iterator of IPv(4|6) objects.
00842 
00843         Raises:
00844             ValueError: The prefixlen_diff is too small or too large.
00845                 OR
00846             prefixlen_diff and new_prefix are both set or new_prefix
00847               is a smaller number than the current prefix (smaller
00848               number means a larger network)
00849 
00850         """
00851         if self._prefixlen == self._max_prefixlen:
00852             yield self
00853             return
00854 
00855         if new_prefix is not None:
00856             if new_prefix < self._prefixlen:
00857                 raise ValueError('new prefix must be longer')
00858             if prefixlen_diff != 1:
00859                 raise ValueError('cannot set prefixlen_diff and new_prefix')
00860             prefixlen_diff = new_prefix - self._prefixlen
00861 
00862         if prefixlen_diff < 0:
00863             raise ValueError('prefix length diff must be > 0')
00864         new_prefixlen = self._prefixlen + prefixlen_diff
00865 
00866         if not self._is_valid_netmask(str(new_prefixlen)):
00867             raise ValueError(
00868                 'prefix length diff %d is invalid for netblock %s' % (
00869                     new_prefixlen, str(self)))
00870 
00871         first = IPNetwork('%s/%s' % (str(self.network),
00872                                      str(self._prefixlen + prefixlen_diff)),
00873                          version=self._version)
00874 
00875         yield first
00876         current = first
00877         while True:
00878             broadcast = current.broadcast
00879             if broadcast == self.broadcast:
00880                 return
00881             new_addr = IPAddress(int(broadcast) + 1, version=self._version)
00882             current = IPNetwork('%s/%s' % (str(new_addr), str(new_prefixlen)),
00883                                 version=self._version)
00884 
00885             yield current
00886 
00887     def subnet(self, prefixlen_diff=1, new_prefix=None):
00888         """Return a list of subnets, rather than an interator."""
00889         return list(self.iter_subnets(prefixlen_diff, new_prefix))
00890 
00891     def supernet(self, prefixlen_diff=1, new_prefix=None):
00892         """The supernet containing the current network.
00893 
00894         Args:
00895             prefixlen_diff: An integer, the amount the prefix length of
00896               the network should be decreased by.  For example, given a
00897               /24 network and a prefixlen_diff of 3, a supernet with a
00898               /21 netmask is returned.
00899 
00900         Returns:
00901             An IPv4 network object.
00902 
00903         Raises:
00904             ValueError: If self.prefixlen - prefixlen_diff < 0. I.e., you have a
00905               negative prefix length.
00906                 OR
00907             If prefixlen_diff and new_prefix are both set or new_prefix is a
00908               larger number than the current prefix (larger number means a
00909               smaller network)
00910 
00911         """
00912         if self._prefixlen == 0:
00913             return self
00914 
00915         if new_prefix is not None:
00916             if new_prefix > self._prefixlen:
00917                 raise ValueError('new prefix must be shorter')
00918             if prefixlen_diff != 1:
00919                 raise ValueError('cannot set prefixlen_diff and new_prefix')
00920             prefixlen_diff = self._prefixlen - new_prefix
00921 
00922 
00923         if self.prefixlen - prefixlen_diff < 0:
00924             raise ValueError(
00925                 'current prefixlen is %d, cannot have a prefixlen_diff of %d' %
00926                 (self.prefixlen, prefixlen_diff))
00927         return IPNetwork('%s/%s' % (str(self.network),
00928                                     str(self.prefixlen - prefixlen_diff)),
00929                          version=self._version)
00930 
00931     # backwards compatibility
00932     Subnet = subnet
00933     Supernet = supernet
00934     AddressExclude = address_exclude
00935     CompareNetworks = compare_networks
00936     Contains = __contains__
00937 
00938 
00939 class _BaseV4(object):
00940 
00941     """Base IPv4 object.
00942 
00943     The following methods are used by IPv4 objects in both single IP
00944     addresses and networks.
00945 
00946     """
00947 
00948     # Equivalent to 255.255.255.255 or 32 bits of 1's.
00949     _ALL_ONES = (2**32) - 1
00950 
00951     def __init__(self, address):
00952         self._version = 4
00953         self._max_prefixlen = 32
00954 
00955     def _explode_shorthand_ip_string(self, ip_str=None):
00956         if not ip_str:
00957             ip_str = str(self)
00958         return ip_str
00959 
00960     def _ip_int_from_string(self, ip_str):
00961         """Turn the given IP string into an integer for comparison.
00962 
00963         Args:
00964             ip_str: A string, the IP ip_str.
00965 
00966         Returns:
00967             The IP ip_str as an integer.
00968 
00969         Raises:
00970             AddressValueError: if the string isn't a valid IP string.
00971 
00972         """
00973         packed_ip = 0
00974         octets = ip_str.split('.')
00975         if len(octets) != 4:
00976             raise AddressValueError(ip_str)
00977         for oc in octets:
00978             try:
00979                 packed_ip = (packed_ip << 8) | int(oc)
00980             except ValueError:
00981                 raise AddressValueError(ip_str)
00982         return packed_ip
00983 
00984     def _string_from_ip_int(self, ip_int):
00985         """Turns a 32-bit integer into dotted decimal notation.
00986 
00987         Args:
00988             ip_int: An integer, the IP address.
00989 
00990         Returns:
00991             The IP address as a string in dotted decimal notation.
00992 
00993         """
00994         octets = []
00995         for _ in xrange(4):
00996             octets.insert(0, str(ip_int & 0xFF))
00997             ip_int >>= 8
00998         return '.'.join(octets)
00999 
01000     def _is_valid_ip(self, address):
01001         """Validate the dotted decimal notation IP/netmask string.
01002 
01003         Args:
01004             address: A string, either representing a quad-dotted ip
01005                 or an integer which is a valid IPv4 IP address.
01006 
01007         Returns:
01008             A boolean, True if the string is a valid dotted decimal IP
01009             string.
01010 
01011         """
01012         octets = address.split('.')
01013         if len(octets) == 1:
01014             # We have an integer rather than a dotted decimal IP.
01015             try:
01016                 return int(address) >= 0 and int(address) <= self._ALL_ONES
01017             except ValueError:
01018                 return False
01019 
01020         if len(octets) != 4:
01021             return False
01022 
01023         for octet in octets:
01024             try:
01025                 if not 0 <= int(octet) <= 255:
01026                     return False
01027             except ValueError:
01028                 return False
01029         return True
01030 
01031     @property
01032     def max_prefixlen(self):
01033         return self._max_prefixlen
01034 
01035     @property
01036     def packed(self):
01037         """The binary representation of this address."""
01038         return struct.pack('!I', self._ip)
01039 
01040     @property
01041     def version(self):
01042         return self._version
01043 
01044     @property
01045     def is_reserved(self):
01046        """Test if the address is otherwise IETF reserved.
01047 
01048         Returns:
01049             A boolean, True if the address is within the
01050             reserved IPv4 Network range.
01051 
01052        """
01053        return self in IPv4Network('240.0.0.0/4')
01054 
01055     @property
01056     def is_private(self):
01057         """Test if this address is allocated for private networks.
01058 
01059         Returns:
01060             A boolean, True if the address is reserved per RFC 1918.
01061 
01062         """
01063         return (self in IPv4Network('10.0.0.0/8') or
01064                 self in IPv4Network('172.16.0.0/12') or
01065                 self in IPv4Network('192.168.0.0/16'))
01066 
01067     @property
01068     def is_multicast(self):
01069         """Test if the address is reserved for multicast use.
01070 
01071         Returns:
01072             A boolean, True if the address is multicast.
01073             See RFC 3171 for details.
01074 
01075         """
01076         return self in IPv4Network('224.0.0.0/4')
01077 
01078     @property
01079     def is_unspecified(self):
01080         """Test if the address is unspecified.
01081 
01082         Returns:
01083             A boolean, True if this is the unspecified address as defined in
01084             RFC 5735 3.
01085 
01086         """
01087         return self in IPv4Network('0.0.0.0')
01088 
01089     @property
01090     def is_loopback(self):
01091         """Test if the address is a loopback address.
01092 
01093         Returns:
01094             A boolean, True if the address is a loopback per RFC 3330.
01095 
01096         """
01097         return self in IPv4Network('127.0.0.0/8')
01098 
01099     @property
01100     def is_link_local(self):
01101         """Test if the address is reserved for link-local.
01102 
01103         Returns:
01104             A boolean, True if the address is link-local per RFC 3927.
01105 
01106         """
01107         return self in IPv4Network('169.254.0.0/16')
01108 
01109 
01110 class IPv4Address(_BaseV4, _BaseIP):
01111 
01112     """Represent and manipulate single IPv4 Addresses."""
01113 
01114     def __init__(self, address):
01115 
01116         """
01117         Args:
01118             address: A string or integer representing the IP
01119               '192.168.1.1'
01120 
01121               Additionally, an integer can be passed, so
01122               IPv4Address('192.168.1.1') == IPv4Address(3232235777).
01123               or, more generally
01124               IPv4Address(int(IPv4Address('192.168.1.1'))) ==
01125                 IPv4Address('192.168.1.1')
01126 
01127         Raises:
01128             AddressValueError: If ipaddr isn't a valid IPv4 address.
01129 
01130         """
01131         _BaseIP.__init__(self, address)
01132         _BaseV4.__init__(self, address)
01133 
01134         # Efficient constructor from integer.
01135         if isinstance(address, (int, long)):
01136             self._ip = address
01137             if address < 0 or address > self._ALL_ONES:
01138                 raise AddressValueError(address)
01139             return
01140 
01141         # Constructing from a packed address
01142         if _compat_has_real_bytes:
01143             if isinstance(address, bytes) and len(address) == 4:
01144                 self._ip = struct.unpack('!I', address)[0]
01145                 return
01146 
01147         # Assume input argument to be string or any object representation
01148         # which converts into a formatted IP string.
01149         addr_str = str(address)
01150         if not self._is_valid_ip(addr_str):
01151             raise AddressValueError(addr_str)
01152 
01153         self._ip = self._ip_int_from_string(addr_str)
01154 
01155 
01156 class IPv4Network(_BaseV4, _BaseNet):
01157 
01158     """This class represents and manipulates 32-bit IPv4 networks.
01159 
01160     Attributes: [examples for IPv4Network('1.2.3.4/27')]
01161         ._ip: 16909060
01162         .ip: IPv4Address('1.2.3.4')
01163         .network: IPv4Address('1.2.3.0')
01164         .hostmask: IPv4Address('0.0.0.31')
01165         .broadcast: IPv4Address('1.2.3.31')
01166         .netmask: IPv4Address('255.255.255.224')
01167         .prefixlen: 27
01168 
01169     """
01170 
01171     # the valid octets for host and netmasks. only useful for IPv4.
01172     _valid_mask_octets = set((255, 254, 252, 248, 240, 224, 192, 128, 0))
01173 
01174     def __init__(self, address, strict=False):
01175         """Instantiate a new IPv4 network object.
01176 
01177         Args:
01178             address: A string or integer representing the IP [& network].
01179               '192.168.1.1/24'
01180               '192.168.1.1/255.255.255.0'
01181               '192.168.1.1/0.0.0.255'
01182               are all functionally the same in IPv4. Similarly,
01183               '192.168.1.1'
01184               '192.168.1.1/255.255.255.255'
01185               '192.168.1.1/32'
01186               are also functionaly equivalent. That is to say, failing to
01187               provide a subnetmask will create an object with a mask of /32.
01188 
01189               If the mask (portion after the / in the argument) is given in
01190               dotted quad form, it is treated as a netmask if it starts with a
01191               non-zero field (e.g. /255.0.0.0 == /8) and as a hostmask if it
01192               starts with a zero field (e.g. 0.255.255.255 == /8), with the
01193               single exception of an all-zero mask which is treated as a
01194               netmask == /0. If no mask is given, a default of /32 is used.
01195 
01196               Additionally, an integer can be passed, so
01197               IPv4Network('192.168.1.1') == IPv4Network(3232235777).
01198               or, more generally
01199               IPv4Network(int(IPv4Network('192.168.1.1'))) ==
01200                 IPv4Network('192.168.1.1')
01201 
01202             strict: A boolean. If true, ensure that we have been passed
01203               A true network address, eg, 192.168.1.0/24 and not an
01204               IP address on a network, eg, 192.168.1.1/24.
01205 
01206         Raises:
01207             AddressValueError: If ipaddr isn't a valid IPv4 address.
01208             NetmaskValueError: If the netmask isn't valid for
01209               an IPv4 address.
01210             ValueError: If strict was True and a network address was not
01211               supplied.
01212 
01213         """
01214         _BaseNet.__init__(self, address)
01215         _BaseV4.__init__(self, address)
01216 
01217         # Efficient constructor from integer.
01218         if isinstance(address, (int, long)):
01219             self._ip = address
01220             self.ip = IPv4Address(self._ip)
01221             self._prefixlen = 32
01222             self.netmask = IPv4Address(self._ALL_ONES)
01223             if address < 0 or address > self._ALL_ONES:
01224                 raise AddressValueError(address)
01225             return
01226 
01227         # Constructing from a packed address
01228         if _compat_has_real_bytes:
01229             if isinstance(address, bytes) and len(address) == 4:
01230                 self._ip = struct.unpack('!I', address)[0]
01231                 self.ip = IPv4Address(self._ip)
01232                 self._prefixlen = 32
01233                 self.netmask = IPv4Address(self._ALL_ONES)
01234                 return
01235 
01236         # Assume input argument to be string or any object representation
01237         # which converts into a formatted IP prefix string.
01238         addr = str(address).split('/')
01239 
01240         if len(addr) > 2:
01241             raise AddressValueError(address)
01242 
01243         if not self._is_valid_ip(addr[0]):
01244             raise AddressValueError(addr[0])
01245 
01246         self._ip = self._ip_int_from_string(addr[0])
01247         self.ip = IPv4Address(self._ip)
01248 
01249         if len(addr) == 2:
01250             mask = addr[1].split('.')
01251             if len(mask) == 4:
01252                 # We have dotted decimal netmask.
01253                 if self._is_valid_netmask(addr[1]):
01254                     self.netmask = IPv4Address(self._ip_int_from_string(
01255                             addr[1]))
01256                 elif self._is_hostmask(addr[1]):
01257                     self.netmask = IPv4Address(
01258                         self._ip_int_from_string(addr[1]) ^ self._ALL_ONES)
01259                 else:
01260                     raise NetmaskValueError('%s is not a valid netmask'
01261                                                      % addr[1])
01262 
01263                 self._prefixlen = self._prefix_from_ip_int(int(self.netmask))
01264             else:
01265                 # We have a netmask in prefix length form.
01266                 if not self._is_valid_netmask(addr[1]):
01267                     raise NetmaskValueError(addr[1])
01268                 self._prefixlen = int(addr[1])
01269                 self.netmask = IPv4Address(self._ip_int_from_prefix(
01270                     self._prefixlen))
01271         else:
01272             self._prefixlen = 32
01273             self.netmask = IPv4Address(self._ip_int_from_prefix(
01274                 self._prefixlen))
01275         if strict:
01276             if self.ip != self.network:
01277                 raise ValueError('%s has host bits set' %
01278                                  self.ip)
01279 
01280     def _is_hostmask(self, ip_str):
01281         """Test if the IP string is a hostmask (rather than a netmask).
01282 
01283         Args:
01284             ip_str: A string, the potential hostmask.
01285 
01286         Returns:
01287             A boolean, True if the IP string is a hostmask.
01288 
01289         """
01290         bits = ip_str.split('.')
01291         try:
01292             parts = [int(x) for x in bits if int(x) in self._valid_mask_octets]
01293         except ValueError:
01294             return False
01295         if len(parts) != len(bits):
01296             return False
01297         if parts[0] < parts[-1]:
01298             return True
01299         return False
01300     
01301     def _is_valid_netmask(self, netmask):
01302         """Verify that the netmask is valid.
01303 
01304         Args:
01305             netmask: A string, either a prefix or dotted decimal
01306               netmask.
01307 
01308         Returns:
01309             A boolean, True if the prefix represents a valid IPv4
01310             netmask.
01311 
01312         """
01313         mask = netmask.split('.')
01314         if len(mask) == 4:
01315             if [x for x in mask if int(x) not in self._valid_mask_octets]:
01316                 return False
01317             if [y for idx, y in enumerate(mask) if idx > 0 and
01318                 y > mask[idx - 1]]:
01319                 return False
01320             return True
01321         try:
01322             netmask = int(netmask)
01323         except ValueError:
01324             return False
01325         return 0 <= netmask <= 32
01326 
01327     # backwards compatibility
01328     IsRFC1918 = lambda self: self.is_private
01329     IsMulticast = lambda self: self.is_multicast
01330     IsLoopback = lambda self: self.is_loopback
01331     IsLinkLocal = lambda self: self.is_link_local
01332 
01333 
01334 class _BaseV6(object):
01335 
01336     """Base IPv6 object.
01337 
01338     The following methods are used by IPv6 objects in both single IP
01339     addresses and networks.
01340 
01341     """
01342 
01343     _ALL_ONES = (2**128) - 1
01344 
01345     def __init__(self, address):
01346         self._version = 6
01347         self._max_prefixlen = 128
01348 
01349     def _ip_int_from_string(self, ip_str=None):
01350         """Turn an IPv6 ip_str into an integer.
01351 
01352         Args:
01353             ip_str: A string, the IPv6 ip_str.
01354 
01355         Returns:
01356             A long, the IPv6 ip_str.
01357 
01358         Raises:
01359            AddressValueError: if ip_str isn't a valid IP Address.
01360 
01361         """
01362         if not ip_str:
01363             ip_str = str(self.ip)
01364 
01365         ip_int = 0
01366 
01367         fields = self._explode_shorthand_ip_string(ip_str).split(':')
01368 
01369         # Do we have an IPv4 mapped (::ffff:a.b.c.d) or compact (::a.b.c.d)
01370         # ip_str?
01371         if fields[-1].count('.') == 3:
01372             ipv4_string = fields.pop()
01373             ipv4_int = IPv4Network(ipv4_string)._ip
01374             octets = []
01375             for _ in xrange(2):
01376                 octets.append(hex(ipv4_int & 0xFFFF).lstrip('0x').rstrip('L'))
01377                 ipv4_int >>= 16
01378             fields.extend(reversed(octets))
01379 
01380         for field in fields:
01381             try:
01382                 ip_int = (ip_int << 16) + int(field or '0', 16)
01383             except ValueError:
01384                 raise AddressValueError(ip_str)
01385 
01386         return ip_int
01387 
01388     def _compress_hextets(self, hextets):
01389         """Compresses a list of hextets.
01390 
01391         Compresses a list of strings, replacing the longest continuous
01392         sequence of "0" in the list with "" and adding empty strings at
01393         the beginning or at the end of the string such that subsequently
01394         calling ":".join(hextets) will produce the compressed version of
01395         the IPv6 address.
01396 
01397         Args:
01398             hextets: A list of strings, the hextets to compress.
01399 
01400         Returns:
01401             A list of strings.
01402 
01403         """
01404         best_doublecolon_start = -1
01405         best_doublecolon_len = 0
01406         doublecolon_start = -1
01407         doublecolon_len = 0
01408         for index in range(len(hextets)):
01409             if hextets[index] == '0':
01410                 doublecolon_len += 1
01411                 if doublecolon_start == -1:
01412                     # Start of a sequence of zeros.
01413                     doublecolon_start = index
01414                 if doublecolon_len > best_doublecolon_len:
01415                     # This is the longest sequence of zeros so far.
01416                     best_doublecolon_len = doublecolon_len
01417                     best_doublecolon_start = doublecolon_start
01418             else:
01419                 doublecolon_len = 0
01420                 doublecolon_start = -1
01421 
01422         if best_doublecolon_len > 1:
01423             best_doublecolon_end = (best_doublecolon_start +
01424                                     best_doublecolon_len)
01425             # For zeros at the end of the address.
01426             if best_doublecolon_end == len(hextets):
01427                 hextets += ['']
01428             hextets[best_doublecolon_start:best_doublecolon_end] = ['']
01429             # For zeros at the beginning of the address.
01430             if best_doublecolon_start == 0:
01431                 hextets = [''] + hextets
01432 
01433         return hextets
01434 
01435     def _string_from_ip_int(self, ip_int=None):
01436         """Turns a 128-bit integer into hexadecimal notation.
01437 
01438         Args:
01439             ip_int: An integer, the IP address.
01440 
01441         Returns:
01442             A string, the hexadecimal representation of the address.
01443 
01444         Raises:
01445             ValueError: The address is bigger than 128 bits of all ones.
01446 
01447         """
01448         if not ip_int and ip_int != 0:
01449             ip_int = int(self._ip)
01450 
01451         if ip_int > self._ALL_ONES:
01452             raise ValueError('IPv6 address is too large')
01453 
01454         hex_str = '%032x' % ip_int
01455         hextets = []
01456         for x in range(0, 32, 4):
01457             hextets.append('%x' % int(hex_str[x:x+4], 16))
01458 
01459         hextets = self._compress_hextets(hextets)
01460         return ':'.join(hextets)
01461 
01462     def _explode_shorthand_ip_string(self, ip_str=None):
01463         """Expand a shortened IPv6 address.
01464 
01465         Args:
01466             ip_str: A string, the IPv6 address.
01467 
01468         Returns:
01469             A string, the expanded IPv6 address.
01470 
01471         """
01472         if not ip_str:
01473             ip_str = str(self)
01474             if isinstance(self, _BaseNet):
01475                 ip_str = str(self.ip)
01476 
01477         if self._is_shorthand_ip(ip_str):
01478             new_ip = []
01479             hextet = ip_str.split('::')
01480             sep = len(hextet[0].split(':')) + len(hextet[1].split(':'))
01481             new_ip = hextet[0].split(':')
01482 
01483             for _ in xrange(8 - sep):
01484                 new_ip.append('0000')
01485             new_ip += hextet[1].split(':')
01486 
01487             # Now need to make sure every hextet is 4 lower case characters.
01488             # If a hextet is < 4 characters, we've got missing leading 0's.
01489             ret_ip = []
01490             for hextet in new_ip:
01491                 ret_ip.append(('0' * (4 - len(hextet)) + hextet).lower())
01492             return ':'.join(ret_ip)
01493         # We've already got a longhand ip_str.
01494         return ip_str
01495 
01496     def _is_valid_ip(self, ip_str):
01497         """Ensure we have a valid IPv6 address.
01498 
01499         Probably not as exhaustive as it should be.
01500 
01501         Args:
01502             ip_str: A string, the IPv6 address.
01503 
01504         Returns:
01505             A boolean, True if this is a valid IPv6 address.
01506 
01507         """
01508         # We need to have at least one ':'.
01509         if ':' not in ip_str:
01510             return False
01511 
01512         # We can only have one '::' shortener.
01513         if ip_str.count('::') > 1:
01514             return False
01515 
01516         # '::' should be encompassed by start, digits or end.
01517         if ':::' in ip_str:
01518             return False
01519 
01520         # A single colon can neither start nor end an address.
01521         if ((ip_str.startswith(':') and not ip_str.startswith('::')) or
01522                 (ip_str.endswith(':') and not ip_str.endswith('::'))):
01523             return False
01524 
01525         # If we have no concatenation, we need to have 8 fields with 7 ':'.
01526         if '::' not in ip_str and ip_str.count(':') != 7:
01527             # We might have an IPv4 mapped address.
01528             if ip_str.count('.') != 3:
01529                 return False
01530 
01531         ip_str = self._explode_shorthand_ip_string(ip_str)
01532 
01533         # Now that we have that all squared away, let's check that each of the
01534         # hextets are between 0x0 and 0xFFFF.
01535         for hextet in ip_str.split(':'):
01536             if hextet.count('.') == 3:
01537                 # If we have an IPv4 mapped address, the IPv4 portion has to
01538                 # be at the end of the IPv6 portion.
01539                 if not ip_str.split(':')[-1] == hextet:
01540                     return False
01541                 try:
01542                     IPv4Network(hextet)
01543                 except AddressValueError:
01544                     return False
01545             else:
01546                 try:
01547                     # a value error here means that we got a bad hextet,
01548                     # something like 0xzzzz
01549                     if int(hextet, 16) < 0x0 or int(hextet, 16) > 0xFFFF:
01550                         return False
01551                 except ValueError:
01552                     return False
01553         return True
01554 
01555     def _is_shorthand_ip(self, ip_str=None):
01556         """Determine if the address is shortened.
01557 
01558         Args:
01559             ip_str: A string, the IPv6 address.
01560 
01561         Returns:
01562             A boolean, True if the address is shortened.
01563 
01564         """
01565         if ip_str.count('::') == 1:
01566             return True
01567         return False
01568 
01569     @property
01570     def max_prefixlen(self):
01571         return self._max_prefixlen
01572 
01573     @property
01574     def packed(self):
01575         """The binary representation of this address."""
01576         return struct.pack('!QQ', self._ip >> 64, self._ip & (2**64 - 1))
01577 
01578     @property
01579     def version(self):
01580         return self._version
01581 
01582     @property
01583     def is_multicast(self):
01584         """Test if the address is reserved for multicast use.
01585 
01586         Returns:
01587             A boolean, True if the address is a multicast address.
01588             See RFC 2373 2.7 for details.
01589 
01590         """
01591         return self in IPv6Network('ff00::/8')
01592 
01593     @property
01594     def is_reserved(self):
01595         """Test if the address is otherwise IETF reserved.
01596 
01597         Returns:
01598             A boolean, True if the address is within one of the
01599             reserved IPv6 Network ranges.
01600 
01601         """
01602         return (self in IPv6Network('::/8') or
01603                 self in IPv6Network('100::/8') or
01604                 self in IPv6Network('200::/7') or
01605                 self in IPv6Network('400::/6') or
01606                 self in IPv6Network('800::/5') or
01607                 self in IPv6Network('1000::/4') or
01608                 self in IPv6Network('4000::/3') or
01609                 self in IPv6Network('6000::/3') or
01610                 self in IPv6Network('8000::/3') or
01611                 self in IPv6Network('A000::/3') or
01612                 self in IPv6Network('C000::/3') or
01613                 self in IPv6Network('E000::/4') or
01614                 self in IPv6Network('F000::/5') or
01615                 self in IPv6Network('F800::/6') or
01616                 self in IPv6Network('FE00::/9'))
01617 
01618     @property
01619     def is_unspecified(self):
01620         """Test if the address is unspecified.
01621 
01622         Returns:
01623             A boolean, True if this is the unspecified address as defined in
01624             RFC 2373 2.5.2.
01625 
01626         """
01627         return self == IPv6Network('::')
01628 
01629     @property
01630     def is_loopback(self):
01631         """Test if the address is a loopback address.
01632 
01633         Returns:
01634             A boolean, True if the address is a loopback address as defined in
01635             RFC 2373 2.5.3.
01636 
01637         """
01638         return self == IPv6Network('::1')
01639 
01640     @property
01641     def is_link_local(self):
01642         """Test if the address is reserved for link-local.
01643 
01644         Returns:
01645             A boolean, True if the address is reserved per RFC 4291.
01646 
01647         """
01648         return self in IPv6Network('fe80::/10')
01649 
01650     @property
01651     def is_site_local(self):
01652         """Test if the address is reserved for site-local.
01653 
01654         Note that the site-local address space has been deprecated by RFC 3879.
01655         Use is_private to test if this address is in the space of unique local
01656         addresses as defined by RFC 4193.
01657 
01658         Returns:
01659             A boolean, True if the address is reserved per RFC 3513 2.5.6.
01660 
01661         """
01662         return self in IPv6Network('fec0::/10')
01663 
01664     @property
01665     def is_private(self):
01666         """Test if this address is allocated for private networks.
01667 
01668         Returns:
01669             A boolean, True if the address is reserved per RFC 4193.
01670 
01671         """
01672         return self in IPv6Network('fc00::/7')
01673 
01674     @property
01675     def ipv4_mapped(self):
01676         """Return the IPv4 mapped address.
01677 
01678         Returns:
01679             If the IPv6 address is a v4 mapped address, return the
01680             IPv4 mapped address. Return None otherwise.
01681 
01682         """
01683         hextets = self._explode_shorthand_ip_string().split(':')
01684         if hextets[-3] != 'ffff':
01685             return None
01686         try:
01687             return IPv4Address(int('%s%s' % (hextets[-2], hextets[-1]), 16))
01688         except AddressValueError:
01689             return None
01690 
01691 
01692 class IPv6Address(_BaseV6, _BaseIP):
01693 
01694     """Represent and manipulate single IPv6 Addresses.
01695     """
01696 
01697     def __init__(self, address):
01698         """Instantiate a new IPv6 address object.
01699 
01700         Args:
01701             address: A string or integer representing the IP
01702 
01703               Additionally, an integer can be passed, so
01704               IPv6Address('2001:4860::') ==
01705                 IPv6Address(42541956101370907050197289607612071936L).
01706               or, more generally
01707               IPv6Address(IPv6Address('2001:4860::')._ip) ==
01708                 IPv6Address('2001:4860::')
01709 
01710         Raises:
01711             AddressValueError: If address isn't a valid IPv6 address.
01712 
01713         """
01714         _BaseIP.__init__(self, address)
01715         _BaseV6.__init__(self, address)
01716 
01717         # Efficient constructor from integer.
01718         if isinstance(address, (int, long)):
01719             self._ip = address
01720             if address < 0 or address > self._ALL_ONES:
01721                 raise AddressValueError(address)
01722             return
01723 
01724         # Constructing from a packed address
01725         if _compat_has_real_bytes:
01726             if isinstance(address, bytes) and len(address) == 16:
01727                 tmp = struct.unpack('!QQ', address)
01728                 self._ip = (tmp[0] << 64) | tmp[1]
01729                 return
01730 
01731         # Assume input argument to be string or any object representation
01732         # which converts into a formatted IP string.
01733         addr_str = str(address)
01734         if not addr_str:
01735             raise AddressValueError('')
01736 
01737         self._ip = self._ip_int_from_string(addr_str)
01738 
01739 
01740 class IPv6Network(_BaseV6, _BaseNet):
01741 
01742     """This class represents and manipulates 128-bit IPv6 networks.
01743 
01744     Attributes: [examples for IPv6('2001:658:22A:CAFE:200::1/64')]
01745         .ip: IPv6Address('2001:658:22a:cafe:200::1')
01746         .network: IPv6Address('2001:658:22a:cafe::')
01747         .hostmask: IPv6Address('::ffff:ffff:ffff:ffff')
01748         .broadcast: IPv6Address('2001:658:22a:cafe:ffff:ffff:ffff:ffff')
01749         .netmask: IPv6Address('ffff:ffff:ffff:ffff::')
01750         .prefixlen: 64
01751 
01752     """
01753 
01754 
01755     def __init__(self, address, strict=False):
01756         """Instantiate a new IPv6 Network object.
01757 
01758         Args:
01759             address: A string or integer representing the IPv6 network or the IP
01760               and prefix/netmask.
01761               '2001:4860::/128'
01762               '2001:4860:0000:0000:0000:0000:0000:0000/128'
01763               '2001:4860::'
01764               are all functionally the same in IPv6.  That is to say,
01765               failing to provide a subnetmask will create an object with
01766               a mask of /128.
01767 
01768               Additionally, an integer can be passed, so
01769               IPv6Network('2001:4860::') ==
01770                 IPv6Network(42541956101370907050197289607612071936L).
01771               or, more generally
01772               IPv6Network(IPv6Network('2001:4860::')._ip) ==
01773                 IPv6Network('2001:4860::')
01774 
01775             strict: A boolean. If true, ensure that we have been passed
01776               A true network address, eg, 192.168.1.0/24 and not an
01777               IP address on a network, eg, 192.168.1.1/24.
01778 
01779         Raises:
01780             AddressValueError: If address isn't a valid IPv6 address.
01781             NetmaskValueError: If the netmask isn't valid for
01782               an IPv6 address.
01783             ValueError: If strict was True and a network address was not
01784               supplied.
01785 
01786         """
01787         _BaseNet.__init__(self, address)
01788         _BaseV6.__init__(self, address)
01789 
01790         # Efficient constructor from integer.
01791         if isinstance(address, (int, long)):
01792             self._ip = address
01793             self.ip = IPv6Address(self._ip)
01794             self._prefixlen = 128
01795             self.netmask = IPv6Address(self._ALL_ONES)
01796             if address < 0 or address > self._ALL_ONES:
01797                 raise AddressValueError(address)
01798             return
01799 
01800         # Constructing from a packed address
01801         if _compat_has_real_bytes:
01802             if isinstance(address, bytes) and len(address) == 16:
01803                 tmp = struct.unpack('!QQ', address)
01804                 self._ip = (tmp[0] << 64) | tmp[1]
01805                 self.ip = IPv6Address(self._ip)
01806                 self._prefixlen = 128
01807                 self.netmask = IPv6Address(self._ALL_ONES)
01808                 return
01809 
01810         # Assume input argument to be string or any object representation
01811         # which converts into a formatted IP prefix string.
01812         addr = str(address).split('/')
01813 
01814         if len(addr) > 2:
01815             raise AddressValueError(address)
01816 
01817         if not self._is_valid_ip(addr[0]):
01818             raise AddressValueError(addr[0])
01819 
01820         if len(addr) == 2:
01821             if self._is_valid_netmask(addr[1]):
01822                 self._prefixlen = int(addr[1])
01823             else:
01824                 raise NetmaskValueError(addr[1])
01825         else:
01826             self._prefixlen = 128
01827 
01828         self.netmask = IPv6Address(self._ip_int_from_prefix(self._prefixlen))
01829 
01830         self._ip = self._ip_int_from_string(addr[0])
01831         self.ip = IPv6Address(self._ip)
01832 
01833         if strict:
01834             if self.ip != self.network:
01835                 raise ValueError('%s has host bits set' %
01836                                  self.ip)
01837 
01838 
01839     def _is_valid_netmask(self, prefixlen):
01840         """Verify that the netmask/prefixlen is valid.
01841 
01842         Args:
01843             prefixlen: A string, the netmask in prefix length format.
01844 
01845         Returns:
01846             A boolean, True if the prefix represents a valid IPv6
01847             netmask.
01848 
01849         """
01850         try:
01851             prefixlen = int(prefixlen)
01852         except ValueError:
01853             return False
01854         return 0 <= prefixlen <= 128


multi_interface_roam
Author(s): Blaise Gassend
autogenerated on Thu Jan 2 2014 11:26:15