diff options
Diffstat (limited to 'tags/1.1.0')
-rw-r--r-- | tags/1.1.0/COPYING | 202 | ||||
-rw-r--r-- | tags/1.1.0/MANIFEST.in | 2 | ||||
-rw-r--r-- | tags/1.1.0/OWNERS | 4 | ||||
-rw-r--r-- | tags/1.1.0/README | 8 | ||||
-rw-r--r-- | tags/1.1.0/ipaddr.py | 1386 | ||||
-rwxr-xr-x | tags/1.1.0/ipaddr_test.py | 612 | ||||
-rwxr-xr-x | tags/1.1.0/setup.py | 35 | ||||
-rwxr-xr-x | tags/1.1.0/test-2to3.sh | 15 |
8 files changed, 0 insertions, 2264 deletions
diff --git a/tags/1.1.0/COPYING b/tags/1.1.0/COPYING deleted file mode 100644 index d645695..0000000 --- a/tags/1.1.0/COPYING +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/tags/1.1.0/MANIFEST.in b/tags/1.1.0/MANIFEST.in deleted file mode 100644 index 4c16e20..0000000 --- a/tags/1.1.0/MANIFEST.in +++ /dev/null @@ -1,2 +0,0 @@ -include COPYING -include ipaddr_test.py diff --git a/tags/1.1.0/OWNERS b/tags/1.1.0/OWNERS deleted file mode 100644 index 501673e..0000000 --- a/tags/1.1.0/OWNERS +++ /dev/null @@ -1,4 +0,0 @@ -pmoody -harro -mshields -smart diff --git a/tags/1.1.0/README b/tags/1.1.0/README deleted file mode 100644 index 1b54294..0000000 --- a/tags/1.1.0/README +++ /dev/null @@ -1,8 +0,0 @@ -ipaddr.py is a library for working with IP addresses, both IPv4 and IPv6. -It was developed by Google for internal use, and is now open source. - -Project home page: http://code.google.com/p/ipaddr-py/ - -Please send contributions to ipaddr-py-dev@googlegroups.com. Code should -include unit tests and follow the Google Python style guide: -http://code.google.com/p/soc/wiki/PythonStyleGuide diff --git a/tags/1.1.0/ipaddr.py b/tags/1.1.0/ipaddr.py deleted file mode 100644 index 4248ea4..0000000 --- a/tags/1.1.0/ipaddr.py +++ /dev/null @@ -1,1386 +0,0 @@ -#!/usr/bin/python -# -# Copyright 2007 Google Inc. -# Licensed to PSF under a Contributor Agreement. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. See the License for the specific language governing -# permissions and limitations under the License. - -"""An IPv4/IPv6 manipulation library in Python. - -This library is used to create/poke/manipulate IPv4 and IPv6 addresses -and prefixes. - -""" - -__version__ = '1.1.0' - -import struct - -class Error(Exception): - - """Base class for exceptions.""" - - -class IPTypeError(Error): - - """Tried to perform a v4 action on v6 object or vice versa.""" - - -class IPAddressExclusionError(Error): - - """An Error we should never see occurred in address exclusion.""" - - -class IPv4IpValidationError(Error): - - """Raised when an IPv4 address is invalid.""" - - def __init__(self, ip): - Error.__init__(self) - self.ip = ip - - def __str__(self): - return repr(self.ip) + ' is not a valid IPv4 address' - - -class IPv4NetmaskValidationError(Error): - - """Raised when a netmask is invalid.""" - - def __init__(self, netmask): - Error.__init__(self) - self.netmask = netmask - - def __str__(self): - return repr(self.netmask) + ' is not a valid IPv4 netmask' - - -class IPv6IpValidationError(Error): - - """Raised when an IPv6 address is invalid.""" - - def __init__(self, ip): - Error.__init__(self) - self.ip = ip - - def __str__(self): - return repr(self.ip) + ' is not a valid IPv6 address' - - -class IPv6NetmaskValidationError(Error): - - """Raised when an IPv6 netmask is invalid.""" - - def __init__(self, netmask): - Error.__init__(self) - self.netmask = netmask - - def __str__(self): - return repr(self.netmask) + ' is not a valid IPv6 netmask' - - -class PrefixlenDiffInvalidError(Error): - - """Raised when Sub/Supernets is called with a bad prefixlen_diff.""" - - def __init__(self, error_str): - Error.__init__(self) - self.error_str = error_str - - -def IP(ipaddr): - """Take an IP string/int and return an object of the correct type. - - Args: - ipaddr: A string or integer, the IP address. Either IPv4 or - IPv6 addresses may be supplied; integers less than 2**32 will - be considered to be IPv4. - - Returns: - An IPv4 or IPv6 object. - - Raises: - ValueError: if the string passed isn't either a v4 or a v6 - address. - - """ - - try: - return IPv4(ipaddr) - except (IPv4IpValidationError, IPv4NetmaskValidationError): - pass - - try: - return IPv6(ipaddr) - except (IPv6IpValidationError, IPv6NetmaskValidationError): - pass - - raise ValueError('%r does not appear to be an IPv4 or IPv6 address' % - ipaddr) - - -def _collapse_address_list_recursive(addresses): - """Loops through the addresses, collapsing concurrent netblocks. - - Example: - - ip1 = IPv4('1.1.0.0/24') - ip2 = IPv4('1.1.1.0/24') - ip3 = IPv4('1.1.2.0/24') - ip4 = IPv4('1.1.3.0/24') - ip5 = IPv4('1.1.4.0/24') - ip6 = IPv4('1.1.0.1/22') - - _collapse_address_list_recursive([ip1, ip2, ip3, ip4, ip5, ip6]) -> - [IPv4('1.1.0.0/22'), IPv4('1.1.4.0/24')] - - This shouldn't be called directly; it is called via - collapse_address_list([]). - - Args: - addresses: A list of IPv4 or IPv6 objects. - - Returns: - A list of IPv4 or IPv6 objects depending on what we were passed. - - """ - ret_array = [] - optimized = False - - for cur_addr in addresses: - if not ret_array: - ret_array.append(cur_addr) - continue - if cur_addr in ret_array[-1]: - optimized = True - elif cur_addr == ret_array[-1].supernet().subnet()[1]: - ret_array.append(ret_array.pop().supernet()) - optimized = True - else: - ret_array.append(cur_addr) - - if optimized: - return _collapse_address_list_recursive(ret_array) - - return ret_array - - -def collapse_address_list(addresses): - """Collapse a list of IP objects. - - Example: - collapse_address_list([IPv4('1.1.0.0/24'), IPv4('1.1.1.0/24')]) -> - [IPv4('1.1.0.0/23')] - - Args: - addresses: A list of IPv4 or IPv6 objects. - - Returns: - A list of IPv4 or IPv6 objects depending on what we were passed. - - """ - return _collapse_address_list_recursive( - sorted(addresses, key=BaseIP._get_networks_key)) - -# backwards compatibility -CollapseAddrList = collapse_address_list - -# Test whether this Python implementation supports byte objects that -# are not identical to str ones. -# We need to exclude platforms where bytes == str so that we can -# distinguish between packed representations and strings, for example -# b'12::' (the IPv4 address 49.50.58.58) and '12::' (an IPv6 address). -try: - _compat_has_real_bytes = bytes != str -except NameError: # <Python2.6 - _compat_has_real_bytes = False - -class BaseIP(object): - - """A generic IP object. - - This IP class contains most of the methods which are used by - the IPv4 and IPv6 classes. - - """ - - def __getitem__(self, n): - if n >= 0: - if self.network + n > self.broadcast: - raise IndexError - return self._string_from_ip_int(self.network + n) - else: - n += 1 - if self.broadcast + n < self.network: - raise IndexError - return self._string_from_ip_int(self.broadcast + n) - - def __lt__(self, other): - try: - return (self.version < other.version - or self.ip < other.ip - or self.netmask < other.netmask) - except AttributeError: - return NotImplemented - - def __gt__(self, other): - try: - return (self.version > other.version - or self.ip > other.ip - or self.netmask > other.netmask) - except AttributeError: - return NotImplemented - - def __eq__(self, other): - try: - return (self.version == other.version - and self.ip == other.ip - and self.netmask == other.netmask) - except AttributeError: - return NotImplemented - - def __ne__(self, other): - eq = self.__eq__(other) - if eq is NotImplemented: - return NotImplemented - return not eq - - def __le__(self, other): - gt = self.__gt__(other) - if gt is NotImplemented: - return NotImplemented - return not gt - - def __ge__(self, other): - lt = self.__lt__(other) - if lt is NotImplemented: - return NotImplemented - return not lt - - def __repr__(self): - return '%s(%r)' % (self.__class__.__name__, str(self)) - - def __index__(self): - return self.ip - - def __int__(self): - return self.ip - - def __hex__(self): - return hex(int(self)) - - def address_exclude(self, other): - """Remove an address from a larger block. - - For example: - - addr1 = IP('10.1.1.0/24') - addr2 = IP('10.1.1.0/26') - addr1.address_exclude(addr2) = - [IP('10.1.1.64/26'), IP('10.1.1.128/25')] - - or IPv6: - - addr1 = IP('::1/32') - addr2 = IP('::1/128') - addr1.address_exclude(addr2) = [IP('::0/128'), - IP('::2/127'), - IP('::4/126'), - IP('::8/125'), - ... - IP('0:0:8000::/33')] - - Args: - other: An IP object of the same type. - - Returns: - A sorted list of IP objects addresses which is self minus - other. - - Raises: - IPTypeError: If self and other are of difffering address - versions. - IPAddressExclusionError: There was some unknown error in the - address exclusion process. This likely points to a bug - elsewhere in this code. - ValueError: If other is not completely contained by self. - - """ - if not self.version == other.version: - raise IPTypeError("%s and %s aren't of the same version" % ( - str(self), str(other))) - - if other not in self: - raise ValueError('%s not contained in %s' % (str(other), - str(self))) - - ret_addrs = [] - - # Make sure we're comparing the network of other. - other = IP(other.network_ext + '/' + str(other.prefixlen)) - - s1, s2 = self.subnet() - while s1 != other and s2 != other: - if other in s1: - ret_addrs.append(s2) - s1, s2 = s1.subnet() - elif other in s2: - ret_addrs.append(s1) - s1, s2 = s2.subnet() - else: - # If we got here, there's a bug somewhere. - raise IPAddressExclusionError('Error performing exclusion: ' - 's1: %s s2: %s other: %s' % - (str(s1), str(s2), str(other))) - if s1 == other: - ret_addrs.append(s2) - elif s2 == other: - ret_addrs.append(s1) - else: - # If we got here, there's a bug somewhere. - raise IPAddressExclusionError('Error performing exclusion: ' - 's1: %s s2: %s other: %s' % - (str(s1), str(s2), str(other))) - - return sorted(ret_addrs, key=BaseIP._get_networks_key) - - def compare_networks(self, other): - """Compare two IP objects. - - This is only concerned about the comparison of the integer - representation of the network addresses. This means that the - host bits aren't considered at all in this method. If you want - to compare host bits, you can easily enough do a - 'HostA.ip < HostB.ip' - - Args: - other: An IP object. - - Returns: - If the IP versions of self and other are the same, returns: - - -1 if self < other: - eg: IPv4('1.1.1.0/24') < IPv4('1.1.2.0/24') - IPv6('1080::200C:417A') < IPv6('1080::200B:417B') - 0 if self == other - eg: IPv4('1.1.1.1/24') == IPv4('1.1.1.2/24') - IPv6('1080::200C:417A/96') == IPv6('1080::200C:417B/96') - 1 if self > other - eg: IPv4('1.1.1.0/24') > IPv4('1.1.0.0/24') - IPv6('1080::1:200C:417A/112') > - IPv6('1080::0:200C:417A/112') - - If the IP versions of self and other are different, returns: - - -1 if self.version < other.version - eg: IPv4('10.0.0.1/24') < IPv6('::1/128') - 1 if self.version > other.version - eg: IPv6('::1/128') > IPv4('255.255.255.0/24') - - """ - if self.version < other.version: - return -1 - if self.version > other.version: - return 1 - # self.version == other.version below here: - if self.network < other.network: - return -1 - if self.network > other.network: - return 1 - # self.network == other.network below here: - if self.netmask < other.netmask: - return -1 - if self.netmask > other.netmask: - return 1 - # self.network == other.network and self.netmask == other.netmask - return 0 - - def _get_networks_key(self): - """Network-only key function. - - Returns an object that identifies this address' network and - netmask. This function is a suitable "key" argument for sorted() - and list.sort(). - - """ - return (self.version, self.network, self.netmask) - - prefixlen = property( - fget=lambda self: self._prefixlen, - fset=lambda self, prefixlen: self._set_prefix(prefixlen)) - - def __str__(self): - return '%s/%s' % (self._string_from_ip_int(self.ip), - str(self.prefixlen)) - - def __hash__(self): - return hash(self.ip ^ self.netmask) - - def __contains__(self, other): - return self.network <= other.ip and self.broadcast >= other.broadcast - - @property - def ip_ext(self): - """Dotted decimal or colon string version of the IP address.""" - return self._string_from_ip_int(self.ip) - - @property - def ip_ext_full(self): - """Canonical string version of the IP address.""" - return self.ip_ext - - @property - def broadcast(self): - """Integer representation of the broadcast address.""" - return self.ip | self.hostmask - - @property - def broadcast_ext(self): - """Dotted decimal or colon string version of the broadcast.""" - return self._string_from_ip_int(self.broadcast) - - @property - def hostmask(self): - """Integer representation of the hostmask.""" - return self.netmask ^ self._ALL_ONES - - @property - def hostmask_ext(self): - """Dotted decimal or colon string version of the hostmask.""" - return self._string_from_ip_int(self.hostmask) - - @property - def network(self): - """Integer representation of the network.""" - return self.ip & self.netmask - - @property - def network_ext(self): - """Dotted decimal or colon string version of the network.""" - return self._string_from_ip_int(self.network) - - @property - def netmask_ext(self): - """Dotted decimal or colon string version of the netmask.""" - return self._string_from_ip_int(self.netmask) - - @property - def numhosts(self): - """Number of hosts in the current subnet.""" - return self.broadcast - self.network + 1 - - @property - def version(self): - raise NotImplementedError('BaseIP has no version') - - def _ip_int_from_prefix(self, prefixlen=None): - """Turn the prefix length netmask into a int for comparison. - - Args: - prefixlen: An integer, the prefix length. - - Returns: - An integer. - - """ - if not prefixlen and prefixlen != 0: - prefixlen = self.prefixlen - return self._ALL_ONES ^ (self._ALL_ONES >> prefixlen) - - def _prefix_from_ip_int(self, ip_int, mask=32): - """Return prefix length from the decimal netmask. - - Args: - ip_int: An integer, the IP address. - mask: The netmask. Defaults to 32. - - Returns: - An integer, the prefix length. - - """ - while mask: - if ip_int & 1 == 1: - break - ip_int >>= 1 - mask -= 1 - - return mask - - def _ip_string_from_prefix(self, prefixlen=None): - """Turn a prefix length into a dotted decimal string. - - Args: - prefixlen: An integer, the netmask prefix length. - - Returns: - A string, the dotted decimal netmask string. - - """ - if not prefixlen: - prefixlen = self.prefixlen - return self._string_from_ip_int(self._ip_int_from_prefix(prefixlen)) - - # backwards compatibility - AddressExclude = address_exclude - CompareNetworks = compare_networks - Contains = __contains__ - def set_prefix(self, prefixlen): self.prefixlen = prefixlen - SetPrefix = set_prefix - def get_prefix(self): return self.prefixlen - - -class IPv4(BaseIP): - - """This class represents and manipulates 32-bit IPv4 addresses. - - Attributes: [examples for IPv4('1.2.3.4/27')] - .ip: 16909060 - .ip_ext: '1.2.3.4' - .ip_ext_full: '1.2.3.4' - .network: 16909056L - .network_ext: '1.2.3.0' - .hostmask: 31L (0x1F) - .hostmask_ext: '0.0.0.31' - .broadcast: 16909087L (0x102031F) - .broadcast_ext: '1.2.3.31' - .netmask: 4294967040L (0xFFFFFFE0) - .netmask_ext: '255.255.255.224' - .prefixlen: 27 - - """ - - # Equivalent to 255.255.255.255 or 32 bits of 1's. - _ALL_ONES = (2**32) - 1 - - def __init__(self, ipaddr): - """Instantiate a new IPv4 object. - - Args: - ipaddr: A string or integer representing the IP [& network]. - '192.168.1.1/32' - '192.168.1.1/255.255.255.255' - '192.168.1.1/0.0.0.255' - '192.168.1.1' - are all functionally the same in IPv4. That is to say, - failing to provide a subnetmask will create an object with - a mask of /32. A netmask of '255.255.255.255' is assumed - to be /32 and '0.0.0.0' is assumed to be /0, even though - other netmasks can be expressed both as host- and - net-masks. (255.0.0.0 == 0.255.255.255) - - Additionally, an integer can be passed, so - IPv4('192.168.1.1') == IPv4(3232235777). - or, more generally - IPv4(IPv4('192.168.1.1').ip) == IPv4('192.168.1.1') - - Raises: - IPv4IpValidationError: If ipaddr isn't a valid IPv4 address. - IPv4NetmaskValidationError: If the netmask isn't valid for - an IPv4 address. - - """ - BaseIP.__init__(self) - self._version = 4 - - # Efficient constructor from integer. - if isinstance(ipaddr, int) or isinstance(ipaddr, long): - self.ip = ipaddr - self._prefixlen = 32 - self.netmask = self._ALL_ONES - if ipaddr < 0 or ipaddr > self._ALL_ONES: - raise IPv4IpValidationError(ipaddr) - return - - # Constructing from a packed address - if _compat_has_real_bytes: - if isinstance(ipaddr, bytes) and len(ipaddr) == 4: - self.ip = struct.unpack('!I', ipaddr)[0] - self._prefixlen = 32 - self.netmask = self._ALL_ONES - return - - # Assume input argument to be string or any object representation - # which converts into a formatted IP prefix string. - addr = str(ipaddr).split('/') - - if len(addr) > 2: - raise IPv4IpValidationError(ipaddr) - - if not self._is_valid_ip(addr[0]): - raise IPv4IpValidationError(addr[0]) - - self.ip = self._ip_int_from_string(addr[0]) - - if len(addr) == 2: - mask = addr[1].split('.') - if len(mask) == 4: - # We have dotted decimal netmask. - if not self._is_valid_netmask(addr[1]): - raise IPv4NetmaskValidationError(addr[1]) - if self._is_hostmask(addr[1]): - self.netmask = ( - self._ip_int_from_string(addr[1]) ^ self._ALL_ONES) - else: - self.netmask = self._ip_int_from_string(addr[1]) - self._prefixlen = self._prefix_from_ip_int(self.netmask) - else: - # We have a netmask in prefix length form. - if not self._is_valid_netmask(addr[1]): - raise IPv4NetmaskValidationError(addr[1]) - self._prefixlen = int(addr[1]) - self.netmask = self._ip_int_from_prefix(self._prefixlen) - else: - self._prefixlen = 32 - self.netmask = self._ip_int_from_prefix(self._prefixlen) - - def _set_prefix(self, prefixlen): - """Change the prefix length. - - Args: - prefixlen: An integer, the new prefix length. - - Raises: - IPv4NetmaskValidationError: If prefixlen is out of bounds. - - """ - if not 0 <= prefixlen <= 32: - raise IPv4NetmaskValidationError(prefixlen) - self._prefixlen = prefixlen - self.netmask = self._ip_int_from_prefix(self._prefixlen) - - def subnet(self, prefixlen_diff=1): - """The subnets which join to make the current subnet. - - In the case that self contains only one IP - (self._prefixlen == 32), return a list with just ourself. - - Args: - prefixlen_diff: An integer, the amount the prefix length - should be increased by. Given a /24 network and a - prefixlen_diff of 3, for example, 8 subnets of size /27 - will be returned. The default value of 1 splits the - current network into two halves. - - Returns: - A list of IPv4 objects. - - Raises: - PrefixlenDiffInvalidError: The prefixlen_diff is too small - or too large. - - """ - if self._prefixlen == 32: - return [self] - - if prefixlen_diff < 0: - raise PrefixlenDiffInvalidError('prefix length diff must be > 0') - new_prefixlen = self.prefixlen + prefixlen_diff - - if not self._is_valid_netmask(str(new_prefixlen)): - raise PrefixlenDiffInvalidError( - 'prefix length diff %d is invalid for netblock %s' % ( - new_prefixlen, str(self))) - - first = IPv4( - self._string_from_ip_int(self.network) + '/' + - str(self._prefixlen + prefixlen_diff)) - subnets = [first] - current = first - while True: - broadcast = current.broadcast - if broadcast == self.broadcast: - break - current = IPv4(self._string_from_ip_int(broadcast + 1) + '/' + - str(new_prefixlen)) - subnets.append(current) - - return subnets - - def supernet(self, prefixlen_diff=1): - """The supernet containing the current network. - - Args: - prefixlen_diff: An integer, the amount the prefix length of - the network should be decreased by. For example, given a - /24 network and a prefixlen_diff of 3, a supernet with a - /21 netmask is returned. - - Returns: - An IPv4 object. - - Raises: - PrefixlenDiffInvalidError: If - self.prefixlen - prefixlen_diff < 0. I.e., you have a - negative prefix length. - - """ - if self.prefixlen == 0: - return self - if self.prefixlen - prefixlen_diff < 0: - raise PrefixlenDiffInvalidError( - 'current prefixlen is %d, cannot have a prefixlen_diff of %d' % - (self.prefixlen, prefixlen_diff)) - return IPv4(self.ip_ext + '/' + str(self.prefixlen - prefixlen_diff)) - - @property - def is_private(self): - """Test if this address is allocated for private networks. - - Returns: - A boolean, True if the address is reserved per RFC 1918. - - """ - return (self in IPv4('10.0.0.0/8') or - self in IPv4('172.16.0.0/12') or - self in IPv4('192.168.0.0/16')) - - @property - def is_multicast(self): - """Test if the address is reserved for multicast use. - - Returns: - A boolean, True if the address is multicast. - See RFC 3171 for details. - - """ - return self in IPv4('224.0.0.0/4') - - @property - def is_loopback(self): - """Test if the address is a loopback adddress. - - Returns: - A boolean, True if the address is a loopback per RFC 3330. - - """ - return self in IPv4('127.0.0.0/8') - - @property - def is_link_local(self): - """Test if the address is reserved for link-local. - - Returns: - A boolean, True if the address is link-local per RFC 3927. - - """ - return self in IPv4('169.254.0.0/16') - - @property - def version(self): - return self._version - - @property - def packed(self): - """The binary representation of this address.""" - return struct.pack('!I', self.ip) - - def _is_hostmask(self, ip_str): - """Test if the IP string is a hostmask (rather than a netmask). - - Args: - ip_str: A string, the potential hostmask. - - Returns: - A boolean, True if the IP string is a hostmask. - - """ - parts = [int(x) for x in ip_str.split('.')] - if parts[0] < parts[-1]: - return True - return False - - def _ip_int_from_string(self, ip_str): - """Turn the given IP string into an integer for comparison. - - Args: - ip_str: A string, the IP address. - - Returns: - The IP address as an integer. - - """ - packed_ip = 0 - for oc in ip_str.split('.'): - packed_ip = (packed_ip << 8) | int(oc) - return packed_ip - - def _string_from_ip_int(self, ip_int): - """Turns a 32-bit integer into dotted decimal notation. - - Args: - ip_int: An integer, the IP address. - - Returns: - The IP address as a string in dotted decimal notation. - - """ - octets = [] - for _ in xrange(4): - octets.insert(0, str(ip_int & 0xFF)) - ip_int >>= 8 - return '.'.join(octets) - - def _is_valid_ip(self, ip_str): - """Validate the dotted decimal notation IP/netmask string. - - Args: - ip_str: A string, the IP address. - - Returns: - A boolean, True if the string is a valid dotted decimal IP - string. - - """ - octets = ip_str.split('.') - if len(octets) == 1: - # We have an integer rather than a dotted decimal IP. - try: - return int(ip_str) >= 0 and int(ip_str) <= self._ALL_ONES - except ValueError: - return False - - if len(octets) != 4: - return False - - for octet in octets: - try: - if not 0 <= int(octet) <= 255: - return False - except ValueError: - return False - return True - - def _is_valid_netmask(self, netmask): - """Verify that the netmask is valid. - - Args: - netmask: A string, either a prefix or dotted decimal - netmask. - - Returns: - A boolean, True if the prefix represents a valid IPv4 - netmask. - - """ - if len(netmask.split('.')) == 4: - return self._is_valid_ip(netmask) - try: - netmask = int(netmask) - except ValueError: - return False - return 0 <= netmask <= 32 - - # backwards compatibility - Subnet = subnet - Supernet = supernet - IsRFC1918 = lambda self: self.is_private - IsMulticast = lambda self: self.is_multicast - IsLoopback = lambda self: self.is_loopback - IsLinkLocal = lambda self: self.is_link_local - -class IPv6(BaseIP): - - """This class respresents and manipulates 128-bit IPv6 addresses. - - Attributes: [examples for IPv6('2001:658:22A:CAFE:200::1/64')] - .ip: 42540616829182469433547762482097946625L - .ip_ext: '2001:658:22a:cafe:200::1' - .ip_ext_full: '2001:0658:022a:cafe:0200:0000:0000:0001' - .network: 42540616829182469433403647294022090752L - .network_ext: '2001:658:22a:cafe::' - .hostmask: 18446744073709551615L - .hostmask_ext: '::ffff:ffff:ffff:ffff' - .broadcast: 42540616829182469451850391367731642367L - .broadcast_ext: '2001:658:22a:cafe:ffff:ffff:ffff:ffff' - .netmask: 340282366920938463444927863358058659840L - .netmask_ext: 64 - .prefixlen: 64 - - """ - - _ALL_ONES = (2**128) - 1 - - def __init__(self, ipaddr): - """Instantiate a new IPv6 object. - - Args: - ipaddr: A string or integer representing the IP or the IP - and prefix/netmask. - '2001:4860::/128' - '2001:4860:0000:0000:0000:0000:0000:0000/128' - '2001:4860::' - are all functionally the same in IPv6. That is to say, - failing to provide a subnetmask will create an object with - a mask of /128. - - Additionally, an integer can be passed, so - IPv6('2001:4860::') == - IPv6(42541956101370907050197289607612071936L). - or, more generally - IPv6(IPv6('2001:4860::').ip) == IPv6('2001:4860::') - - Raises: - IPv6IpValidationError: If ipaddr isn't a valid IPv6 address. - IPv6NetmaskValidationError: If the netmask isn't valid for - an IPv6 address. - - """ - BaseIP.__init__(self) - self._version = 6 - - # Efficient constructor from integer. - if isinstance(ipaddr, long) or isinstance(ipaddr, int): - self.ip = ipaddr - self._prefixlen = 128 - self.netmask = self._ALL_ONES - if ipaddr < 0 or ipaddr > self._ALL_ONES: - raise IPv6IpValidationError(ipaddr) - return - - # Constructing from a packed address - if _compat_has_real_bytes: - if isinstance(ipaddr, bytes) and len(ipaddr) == 16: - tmp = struct.unpack('!QQ', ipaddr) - self.ip = (tmp[0] << 64) | tmp[1] - self._prefixlen = 128 - self.netmask = self._ALL_ONES - return - - # Assume input argument to be string or any object representation - # which converts into a formatted IP prefix string. - addr_str = str(ipaddr) - if not addr_str: - raise IPv6IpValidationError('') - addr = addr_str.split('/') - if len(addr) > 1: - if self._is_valid_netmask(addr[1]): - self._prefixlen = int(addr[1]) - else: - raise IPv6NetmaskValidationError(addr[1]) - else: - self._prefixlen = 128 - - self.netmask = self._ip_int_from_prefix(self._prefixlen) - - if not self._is_valid_ip(addr[0]): - raise IPv6IpValidationError(addr[0]) - - self.ip = self._ip_int_from_string(addr[0]) - - @property - def ip_ext_full(self): - """Returns the expanded version of the IPv6 string.""" - return self._explode_shorthand_ip_string(self.ip_ext) - - def _set_prefix(self, prefixlen): - """Change the prefix length. - - Args: - prefixlen: An integer, the new prefix length. - - Raises: - IPv6NetmaskValidationError: If prefixlen is out of bounds. - - """ - if not 0 <= prefixlen <= 128: - raise IPv6NetmaskValidationError(prefixlen) - self._prefixlen = prefixlen - self.netmask = self._ip_int_from_prefix(self.prefixlen) - - def subnet(self, prefixlen_diff=1): - """The subnets which join to make the current subnet. - - In the case that self contains only one IP - (self._prefixlen == 128), return a list with just ourself. - - Args: - prefixlen_diff: An integer, the amount the prefix length - should be increased by. - - Returns: - A list of IPv6 objects. - - Raises: - PrefixlenDiffInvalidError: The prefixlen_diff is too small - or too large. - - """ - # Preserve original functionality (return [self] if - # self.prefixlen == 128). - if self.prefixlen == 128: - return [self] - - if prefixlen_diff < 0: - raise PrefixlenDiffInvalidError('Prefix length diff must be > 0') - new_prefixlen = self.prefixlen + prefixlen_diff - if not self._is_valid_netmask(str(new_prefixlen)): - raise PrefixlenDiffInvalidError( - 'Prefix length diff %d is invalid for netblock %s' % ( - new_prefixlen, str(self))) - first = IPv6( - self._string_from_ip_int(self.network) + '/' + - str(self._prefixlen + prefixlen_diff)) - subnets = [first] - current = first - while True: - broadcast = current.broadcast - if current.broadcast == self.broadcast: - break - current = IPv6(self._string_from_ip_int(broadcast + 1) + '/' + - str(new_prefixlen)) - subnets.append(current) - - return subnets - - def supernet(self, prefixlen_diff=1): - """The supernet containing the current network. - - Args: - prefixlen_diff: An integer, the amount the prefix length of the - network should be decreased by. For example, given a /96 - network and a prefixlen_diff of 3, a supernet with a /93 - netmask is returned. - - Returns: - An IPv6 object. - - Raises: - PrefixlenDiffInvalidError: If - self._prefixlen - prefixlen_diff < 0. I.e., you have a - negative prefix length. - - """ - if self.prefixlen == 0: - return self - if self.prefixlen - prefixlen_diff < 0: - raise PrefixlenDiffInvalidError( - 'current prefixlen is %d, cannot have a prefixlen_diff of %d' % - (self.prefixlen, prefixlen_diff)) - return IPv6(self.ip_ext + '/' + str(self.prefixlen - prefixlen_diff)) - - @property - def is_multicast(self): - """Test if the address is reserved for multicast use. - - Returns: - A boolean, True if the address is a multicast address. - See RFC 2373 2.7 for details. - - """ - return self in IPv6('ff00::/8') - - @property - def is_unspecified(self): - """Test if the address is unspecified. - - Returns: - A boolean, True if this is the unspecified address as defined in - RFC 2373 2.5.2. - - """ - return self == IPv6('::') - - @property - def is_loopback(self): - """Test if the address is a loopback adddress. - - Returns: - A boolean, True if the address is a loopback address as defined in - RFC 2373 2.5.3. - - """ - return self == IPv6('::1') - - @property - def is_link_local(self): - """Test if the address is reserved for link-local. - - Returns: - A boolean, True if the address is reserved per RFC 4291. - - """ - return self in IPv6('fe80::/10') - - @property - def is_site_local(self): - """Test if the address is reserved for site-local. - - Note that the site-local address space has been deprecated by RFC 3879. - Use is_private to test if this address is in the space of unique local - addresses as defined by RFC 4193. - - Returns: - A boolean, True if the address is reserved per RFC 3513 2.5.6. - - """ - return self in IPv6('fec0::/10') - - @property - def is_private(self): - """Test if this address is allocated for private networks. - - Returns: - A boolean, True if the address is reserved per RFC 4193. - - """ - return self in IPv6('fc00::/7') - - @property - def version(self): - return self._version - - @property - def packed(self): - """The binary representation of this address.""" - return struct.pack('!QQ', self.ip >> 64, self.ip & (2**64 - 1)) - - def _is_shorthand_ip(self, ip_str=None): - """Determine if the address is shortened. - - Args: - ip_str: A string, the IPv6 address. - - Returns: - A boolean, True if the address is shortened. - - """ - if ip_str.count('::') == 1: - return True - return False - - def _explode_shorthand_ip_string(self, ip_str): - """Expand a shortened IPv6 address. - - Args: - ip_str: A string, the IPv6 address. - - Returns: - A string, the expanded IPv6 address. - - """ - if self._is_shorthand_ip(ip_str): - new_ip = [] - hextet = ip_str.split('::') - sep = len(hextet[0].split(':')) + len(hextet[1].split(':')) - new_ip = hextet[0].split(':') - - for _ in xrange(8 - sep): - new_ip.append('0000') - new_ip += hextet[1].split(':') - - # Now need to make sure every hextet is 4 lower case characters. - # If a hextet is < 4 characters, we've got missing leading 0's. - ret_ip = [] - for hextet in new_ip: - ret_ip.append(('0' * (4 - len(hextet)) + hextet).lower()) - return ':'.join(ret_ip) - # We've already got a longhand ip_str. - return ip_str - - def _is_valid_ip(self, ip_str=None): - """Ensure we have a valid IPv6 address. - - Probably not as exhaustive as it should be. - - Args: - ip_str: A string, the IPv6 address. - - Returns: - A boolean, True if this is a valid IPv6 address. - - """ - if not ip_str: - ip_str = self.ip_ext - - # We need to have at least one ':'. - if ':' not in ip_str: - return False - - # We can only have one '::' shortener. - if ip_str.count('::') > 1: - return False - - # '::' should be encompassed by start, digits or end. - if ':::' in ip_str: - return False - - # A single colon can neither start nor end an address. - if ((ip_str.startswith(':') and not ip_str.startswith('::')) or - (ip_str.endswith(':') and not ip_str.endswith('::'))): - return False - - # If we have no concatenation, we need to have 8 fields with 7 ':'. - if '::' not in ip_str and ip_str.count(':') != 7: - # We might have an IPv4 mapped address. - if ip_str.count('.') != 3: - return False - - ip_str = self._explode_shorthand_ip_string(ip_str) - - # Now that we have that all squared away, let's check that each of the - # hextets are between 0x0 and 0xFFFF. - for hextet in ip_str.split(':'): - if hextet.count('.') == 3: - # If we have an IPv4 mapped address, the IPv4 portion has to be - # at the end of the IPv6 portion. - if not ip_str.split(':')[-1] == hextet: - return False - try: - IPv4(hextet) - except IPv4IpValidationError: - return False - elif int(hextet, 16) < 0x0 or int(hextet, 16) > 0xFFFF: - return False - return True - - def _is_valid_netmask(self, prefixlen): - """Verify that the netmask/prefixlen is valid. - - Args: - prefixlen: A string, the netmask in prefix length format. - - Returns: - A boolean, True if the prefix represents a valid IPv6 - netmask. - - """ - try: - prefixlen = int(prefixlen) - except ValueError: - return False - return 0 <= prefixlen <= 128 - - def _ip_int_from_string(self, ip_str=None): - """Turn an IPv6 address into an integer. - - Args: - ip_str: A string, the IPv6 address. - - Returns: - A long, the IPv6 address. - - """ - if not ip_str: - ip_str = self.ip_ext - - ip_int = 0 - - fields = self._explode_shorthand_ip_string(ip_str).split(':') - - # Do we have an IPv4 mapped (::ffff:a.b.c.d) or compact (::a.b.c.d) - # address? - if fields[-1].count('.') == 3: - ipv4_string = fields.pop() - ipv4_int = IPv4(ipv4_string).ip - octets = [] - for _ in xrange(2): - octets.append(hex(ipv4_int & 0xFFFF).lstrip('0x').rstrip('L')) - ipv4_int >>= 16 - fields.extend(reversed(octets)) - - for field in fields: - ip_int = (ip_int << 16) + int(field, 16) - - return ip_int - - def _compress_hextets(self, hextets): - """Compresses a list of hextets. - - Compresses a list of strings, replacing the longest continuous - sequence of "0" in the list with "" and adding empty strings at - the beginning or at the end of the string such that subsequently - calling ":".join(hextets) will produce the compressed version of - the IPv6 address. - - Args: - hextets: A list of strings, the hextets to compress. - - Returns: - A list of strings. - - """ - best_doublecolon_start = -1 - best_doublecolon_len = 0 - doublecolon_start = -1 - doublecolon_len = 0 - for index in range(len(hextets)): - if hextets[index] == '0': - doublecolon_len += 1 - if doublecolon_start == -1: - # Start of a sequence of zeros. - doublecolon_start = index - if doublecolon_len > best_doublecolon_len: - # This is the longest sequence of zeros so far. - best_doublecolon_len = doublecolon_len - best_doublecolon_start = doublecolon_start - else: - doublecolon_len = 0 - doublecolon_start = -1 - - if best_doublecolon_len > 1: - best_doublecolon_end = (best_doublecolon_start + - best_doublecolon_len) - # For zeros at the end of the address. - if best_doublecolon_end == len(hextets): - hextets += [''] - hextets[best_doublecolon_start:best_doublecolon_end] = [''] - # For zeros at the beginning of the address. - if best_doublecolon_start == 0: - hextets = [''] + hextets - - return hextets - - def _string_from_ip_int(self, ip_int=None): - """Turns a 128-bit integer into hexadecimal notation. - - Args: - ip_int: An integer, the IP address. - - Returns: - A string, the hexadecimal representation of the address. - - Raises: - ValueError: The address is bigger than 128 bits of all ones. - - """ - if not ip_int and ip_int != 0: - ip_int = self.ip - - if ip_int > self._ALL_ONES: - raise ValueError('IPv6 address is too large') - - hex_str = '%032x' % ip_int - hextets = [] - for x in range(0, 32, 4): - hextets.append('%x' % int(hex_str[x:x+4], 16)) - - hextets = self._compress_hextets(hextets) - return ':'.join(hextets) - - @property - def netmask_ext(self): - """IPv6 extended netmask. - - We don't deal with netmasks in IPv6 like we do in IPv4. This is - here strictly for IPv4 compatibility. We simply return the - prefix length. - - Returns: - An integer. - - """ - return self.prefixlen - - # backwards compatibility - Subnet = subnet - Supernet = supernet diff --git a/tags/1.1.0/ipaddr_test.py b/tags/1.1.0/ipaddr_test.py deleted file mode 100755 index b80dc3f..0000000 --- a/tags/1.1.0/ipaddr_test.py +++ /dev/null @@ -1,612 +0,0 @@ -#!/usr/bin/python -# -# Copyright 2007 Google Inc. -# Licensed to PSF under a Contributor Agreement. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Unittest for ipaddr module.""" - - -import unittest - -import ipaddr - -# Compatibility function to cast str to bytes objects -if ipaddr._compat_has_real_bytes: - _cb = lambda bytestr: bytes(bytestr, 'charmap') -else: - _cb = str - -class IpaddrUnitTest(unittest.TestCase): - - def setUp(self): - self.ipv4 = ipaddr.IPv4('1.2.3.4/24') - self.ipv4_hostmask = ipaddr.IPv4('10.0.0.1/0.255.255.255') - self.ipv6 = ipaddr.IPv6('2001:658:22a:cafe:200:0:0:1/64') - - def testRepr(self): - self.assertEqual("IPv4('1.2.3.4/32')", repr(ipaddr.IPv4('1.2.3.4'))) - self.assertEqual("IPv6('::1/128')", repr(ipaddr.IPv6('::1'))) - - def testInvalidStrings(self): - self.assertRaises(ValueError, ipaddr.IP, '') - self.assertRaises(ValueError, ipaddr.IP, 'www.google.com') - self.assertRaises(ValueError, ipaddr.IP, '1.2.3') - self.assertRaises(ValueError, ipaddr.IP, '1.2.3.4.5') - self.assertRaises(ValueError, ipaddr.IP, '301.2.2.2') - self.assertRaises(ValueError, ipaddr.IP, '1:2:3:4:5:6:7') - self.assertRaises(ValueError, ipaddr.IP, '1:2:3:4:5:6:7:') - self.assertRaises(ValueError, ipaddr.IP, ':2:3:4:5:6:7:8') - self.assertRaises(ValueError, ipaddr.IP, '1:2:3:4:5:6:7:8:9') - self.assertRaises(ValueError, ipaddr.IP, '1:2:3:4:5:6:7:8:') - self.assertRaises(ValueError, ipaddr.IP, '1::3:4:5:6::8') - self.assertRaises(ValueError, ipaddr.IP, 'a:') - self.assertRaises(ValueError, ipaddr.IP, ':') - self.assertRaises(ValueError, ipaddr.IP, ':::') - self.assertRaises(ValueError, ipaddr.IP, '::a:') - self.assertRaises(ValueError, ipaddr.IP, '1ffff::') - self.assertRaises(ValueError, ipaddr.IP, '0xa::') - self.assertRaises(ValueError, ipaddr.IP, '1:2:3:4:5:6:1a.2.3.4') - self.assertRaises(ValueError, ipaddr.IP, '1:2:3:4:5:1.2.3.4:8') - self.assertRaises(ipaddr.IPv4IpValidationError, ipaddr.IPv4, '') - self.assertRaises(ipaddr.IPv4IpValidationError, ipaddr.IPv4, - 'google.com') - self.assertRaises(ipaddr.IPv4IpValidationError, ipaddr.IPv4, - '::1.2.3.4') - self.assertRaises(ipaddr.IPv6IpValidationError, ipaddr.IPv6, '') - self.assertRaises(ipaddr.IPv6IpValidationError, ipaddr.IPv6, - 'google.com') - self.assertRaises(ipaddr.IPv6IpValidationError, ipaddr.IPv6, - '1.2.3.4') - - def testGetNetwork(self): - self.assertEqual(self.ipv4.network, 16909056) - self.assertEqual(self.ipv4.network_ext, '1.2.3.0') - self.assertEqual(self.ipv4_hostmask.network_ext, '10.0.0.0') - - self.assertEqual(self.ipv6.network, - 42540616829182469433403647294022090752) - self.assertEqual(self.ipv6.network_ext, - '2001:658:22a:cafe::') - self.assertEqual(self.ipv6.hostmask_ext, - '::ffff:ffff:ffff:ffff') - - def testIpFromInt(self): - self.assertEqual(self.ipv4.ip, ipaddr.IPv4(16909060).ip) - self.assertRaises(ipaddr.IPv4IpValidationError, - ipaddr.IPv4, 2**32) - self.assertRaises(ipaddr.IPv4IpValidationError, - ipaddr.IPv4, -1) - - self.assertEqual(self.ipv6.ip, - ipaddr.IPv6(42540616829182469433547762482097946625).ip) - self.assertRaises(ipaddr.IPv6IpValidationError, - ipaddr.IPv6, 2**128) - self.assertRaises(ipaddr.IPv6IpValidationError, - ipaddr.IPv6, -1) - - self.assertEqual(ipaddr.IP(self.ipv4.ip).version, 4) - self.assertEqual(ipaddr.IP(self.ipv6.ip).version, 6) - - if ipaddr._compat_has_real_bytes: # on python3+ - def testIpFromPacked(self): - ip = ipaddr.IP - - self.assertEqual(self.ipv4.ip, - ip(_cb('\x01\x02\x03\x04')).ip) - self.assertEqual(ip('255.254.253.252'), - ip(_cb('\xff\xfe\xfd\xfc'))) - self.assertRaises(ValueError, ipaddr.IP, _cb('\x00' * 3)) - self.assertRaises(ValueError, ipaddr.IP, _cb('\x00' * 5)) - self.assertEqual(self.ipv6.ip, - ip(_cb('\x20\x01\x06\x58\x02\x2a\xca\xfe' - '\x02\x00\x00\x00\x00\x00\x00\x01')).ip) - self.assertEqual(ip('ffff:2:3:4:ffff::'), - ip(_cb('\xff\xff\x00\x02\x00\x03\x00\x04' + - '\xff\xff' + '\x00' * 6))) - self.assertEqual(ip('::'), - ip(_cb('\x00' * 16))) - self.assertRaises(ValueError, ip, _cb('\x00' * 15)) - self.assertRaises(ValueError, ip, _cb('\x00' * 17)) - - def testGetIp(self): - self.assertEqual(self.ipv4.ip, 16909060) - self.assertEqual(self.ipv4.ip_ext, '1.2.3.4') - self.assertEqual(self.ipv4.ip_ext_full, '1.2.3.4') - self.assertEqual(self.ipv4_hostmask.ip_ext, '10.0.0.1') - - self.assertEqual(self.ipv6.ip, 42540616829182469433547762482097946625) - self.assertEqual(self.ipv6.ip_ext, - '2001:658:22a:cafe:200::1') - self.assertEqual(self.ipv6.ip_ext_full, - '2001:0658:022a:cafe:0200:0000:0000:0001') - - def testGetNetmask(self): - self.assertEqual(self.ipv4.netmask, 4294967040L) - self.assertEqual(self.ipv4.netmask_ext, '255.255.255.0') - self.assertEqual(self.ipv4_hostmask.netmask_ext, '255.0.0.0') - self.assertEqual(self.ipv6.netmask, - 340282366920938463444927863358058659840) - self.assertEqual(self.ipv6.netmask_ext, 64) - - def testZeroNetmask(self): - ipv4_zero_netmask = ipaddr.IPv4('1.2.3.4/0') - self.assertEqual(ipv4_zero_netmask.netmask, 0) - self.assert_(ipv4_zero_netmask._is_valid_netmask(str(0))) - - ipv6_zero_netmask = ipaddr.IPv6('::1/0') - self.assertEqual(ipv6_zero_netmask.netmask, 0) - self.assert_(ipv6_zero_netmask._is_valid_netmask(str(0))) - - def testGetBroadcast(self): - self.assertEqual(self.ipv4.broadcast, 16909311L) - self.assertEqual(self.ipv4.broadcast_ext, '1.2.3.255') - - self.assertEqual(self.ipv6.broadcast, - 42540616829182469451850391367731642367) - self.assertEqual(self.ipv6.broadcast_ext, - '2001:658:22a:cafe:ffff:ffff:ffff:ffff') - - def testGetPrefixlen(self): - self.assertEqual(self.ipv4.prefixlen, 24) - - self.assertEqual(self.ipv6.prefixlen, 64) - - def testGetSupernet(self): - self.assertEqual(self.ipv4.supernet().prefixlen, 23) - self.assertEqual(self.ipv4.supernet().network_ext, '1.2.2.0') - self.assertEqual(ipaddr.IPv4('0.0.0.0/0').supernet(), - ipaddr.IPv4('0.0.0.0/0')) - - self.assertEqual(self.ipv6.supernet().prefixlen, 63) - self.assertEqual(self.ipv6.supernet().network_ext, - '2001:658:22a:cafe::') - self.assertEqual(ipaddr.IPv6('::0/0').supernet(), ipaddr.IPv6('::0/0')) - - def testGetSupernet3(self): - self.assertEqual(self.ipv4.supernet(3).prefixlen, 21) - self.assertEqual(self.ipv4.supernet(3).network_ext, '1.2.0.0') - - self.assertEqual(self.ipv6.supernet(3).prefixlen, 61) - self.assertEqual(self.ipv6.supernet(3).network_ext, - '2001:658:22a:caf8::') - - def testGetSubnet(self): - self.assertEqual(self.ipv4.subnet()[0].prefixlen, 25) - self.assertEqual(self.ipv4.subnet()[0].network_ext, '1.2.3.0') - self.assertEqual(self.ipv4.subnet()[1].network_ext, '1.2.3.128') - - self.assertEqual(self.ipv6.subnet()[0].prefixlen, 65) - - def testGetSubnetForSingle32(self): - ip = ipaddr.IPv4('1.2.3.4/32') - subnets1 = [str(x) for x in ip.subnet()] - subnets2 = [str(x) for x in ip.subnet(2)] - self.assertEqual(subnets1, ['1.2.3.4/32']) - self.assertEqual(subnets1, subnets2) - - def testGetSubnetForSingle128(self): - ip = ipaddr.IPv6('::1/128') - subnets1 = [str(x) for x in ip.subnet()] - subnets2 = [str(x) for x in ip.subnet(2)] - self.assertEqual(subnets1, ['::1/128']) - self.assertEqual(subnets1, subnets2) - - def testSubnet2(self): - ips = [str(x) for x in self.ipv4.subnet(2)] - self.assertEqual( - ips, - ['1.2.3.0/26', '1.2.3.64/26', '1.2.3.128/26', '1.2.3.192/26']) - - ipsv6 = [str(x) for x in self.ipv6.subnet(2)] - self.assertEqual( - ipsv6, - ['2001:658:22a:cafe::/66', - '2001:658:22a:cafe:4000::/66', - '2001:658:22a:cafe:8000::/66', - '2001:658:22a:cafe:c000::/66']) - - def testSubnetFailsForLargeCidrDiff(self): - self.assertRaises(ipaddr.PrefixlenDiffInvalidError, self.ipv4.subnet, 9) - self.assertRaises(ipaddr.PrefixlenDiffInvalidError, self.ipv6.subnet, - 65) - - def testSupernetFailsForLargeCidrDiff(self): - self.assertRaises(ipaddr.PrefixlenDiffInvalidError, self.ipv4.supernet, - 25) - self.assertRaises(ipaddr.PrefixlenDiffInvalidError, self.ipv6.supernet, - 65) - - def testSubnetFailsForNegativeCidrDiff(self): - self.assertRaises(ipaddr.PrefixlenDiffInvalidError, self.ipv4.subnet, - -1) - self.assertRaises(ipaddr.PrefixlenDiffInvalidError, self.ipv6.subnet, - -1) - - def testGetNumHosts(self): - self.assertEqual(self.ipv4.numhosts, 256) - self.assertEqual(self.ipv4.subnet()[0].numhosts, 128) - self.assertEqual(self.ipv4.supernet().numhosts, 512) - - self.assertEqual(self.ipv6.numhosts, 18446744073709551616) - self.assertEqual(self.ipv6.subnet()[0].numhosts, 9223372036854775808) - self.assertEqual(self.ipv6.supernet().numhosts, 36893488147419103232) - - def testContains(self): - self.assertTrue(ipaddr.IPv4('1.2.3.128/25') in self.ipv4) - self.assertFalse(ipaddr.IPv4('1.2.4.1/24') in self.ipv4) - self.assertFalse(self.ipv4 in self.ipv6) - self.assertFalse(self.ipv6 in self.ipv4) - self.assertTrue(self.ipv4 in self.ipv4) - self.assertTrue(self.ipv6 in self.ipv6) - - def testBadAddress(self): - self.assertRaises(ipaddr.IPv4IpValidationError, ipaddr.IPv4, 'poop') - self.assertRaises(ipaddr.IPv4IpValidationError, - ipaddr.IPv4, '1.2.3.256') - - self.assertRaises(ipaddr.IPv6IpValidationError, ipaddr.IPv6, 'poopv6') - self.assertRaises(ipaddr.IPv4IpValidationError, - ipaddr.IPv4, '1.2.3.4/32/24') - - def testBadNetMask(self): - self.assertRaises(ipaddr.IPv4NetmaskValidationError, - ipaddr.IPv4, '1.2.3.4/') - self.assertRaises(ipaddr.IPv4NetmaskValidationError, - ipaddr.IPv4, '1.2.3.4/33') - self.assertRaises(ipaddr.IPv4NetmaskValidationError, - ipaddr.IPv4, '1.2.3.4/254.254.255.256') - - self.assertRaises(ipaddr.IPv6NetmaskValidationError, - ipaddr.IPv6, '::1/') - self.assertRaises(ipaddr.IPv6NetmaskValidationError, - ipaddr.IPv6, '::1/129') - - def testNth(self): - self.assertEqual(self.ipv4[5], '1.2.3.5') - self.assertRaises(IndexError, self.ipv4.__getitem__, 256) - - self.assertEqual(self.ipv6[5], - '2001:658:22a:cafe::5') - - def testGetitem(self): - # http://code.google.com/p/ipaddr-py/issues/detail?id=15 - addr = ipaddr.IPv4('172.31.255.128/255.255.255.240') - self.assertEqual(28, addr.prefixlen) - addr_list = list(addr) - self.assertEqual('172.31.255.128', addr_list[0]) - self.assertEqual('172.31.255.128', addr[0]) - self.assertEqual('172.31.255.143', addr_list[-1]) - self.assertEqual('172.31.255.143', addr[-1]) - self.assertEqual(addr_list[-1], addr[-1]) - - def testEquals(self): - self.assertTrue(self.ipv4 == ipaddr.IPv4('1.2.3.4/24')) - self.assertFalse(self.ipv4 == ipaddr.IPv4('1.2.3.4/23')) - self.assertFalse(self.ipv4 == ipaddr.IPv4('1.2.3.5/24')) - self.assertFalse(self.ipv4 == ipaddr.IPv6('::1.2.3.4/24')) - self.assertFalse(self.ipv4 == '') - self.assertFalse(self.ipv4 == []) - self.assertFalse(self.ipv4 == 2) - - self.assertTrue(self.ipv6 == - ipaddr.IPv6('2001:658:22a:cafe:200::1/64')) - self.assertFalse(self.ipv6 == - ipaddr.IPv6('2001:658:22a:cafe:200::1/63')) - self.assertFalse(self.ipv6 == - ipaddr.IPv6('2001:658:22a:cafe:200::2/64')) - self.assertFalse(self.ipv6 == ipaddr.IPv4('1.2.3.4/23')) - self.assertFalse(self.ipv6 == '') - self.assertFalse(self.ipv6 == []) - self.assertFalse(self.ipv6 == 2) - - def testNotEquals(self): - self.assertFalse(self.ipv4 != ipaddr.IPv4('1.2.3.4/24')) - self.assertTrue(self.ipv4 != ipaddr.IPv4('1.2.3.4/23')) - self.assertTrue(self.ipv4 != ipaddr.IPv4('1.2.3.5/24')) - self.assertTrue(self.ipv4 != ipaddr.IPv6('::1.2.3.4/24')) - self.assertTrue(self.ipv4 != '') - self.assertTrue(self.ipv4 != []) - self.assertTrue(self.ipv4 != 2) - - self.assertFalse(self.ipv6 != - ipaddr.IPv6('2001:658:22a:cafe:200::1/64')) - self.assertTrue(self.ipv6 != - ipaddr.IPv6('2001:658:22a:cafe:200::1/63')) - self.assertTrue(self.ipv6 != - ipaddr.IPv6('2001:658:22a:cafe:200::2/64')) - self.assertTrue(self.ipv6 != ipaddr.IPv4('1.2.3.4/23')) - self.assertTrue(self.ipv6 != '') - self.assertTrue(self.ipv6 != []) - self.assertTrue(self.ipv6 != 2) - - def testSlash32Constructor(self): - self.assertEquals(str(ipaddr.IPv4('1.2.3.4/255.255.255.255')), - '1.2.3.4/32') - - def testSlash128Constructor(self): - self.assertEquals(str(ipaddr.IPv6('::1/128')), - '::1/128') - - def testSlash0Constructor(self): - self.assertEquals(str(ipaddr.IPv4('1.2.3.4/0.0.0.0')), '1.2.3.4/0') - - def testCollapsing(self): - ip1 = ipaddr.IPv4('1.1.0.0/24') - ip2 = ipaddr.IPv4('1.1.1.0/24') - ip3 = ipaddr.IPv4('1.1.2.0/24') - ip4 = ipaddr.IPv4('1.1.3.0/24') - ip5 = ipaddr.IPv4('1.1.4.0/24') - # stored in no particular order b/c we want CollapseAddr to call [].sort - ip6 = ipaddr.IPv4('1.1.0.0/22') - # check that addreses are subsumed properlly. - collapsed = ipaddr.collapse_address_list([ip1, ip2, ip3, ip4, ip5, ip6]) - self.assertEqual(collapsed, [ipaddr.IPv4('1.1.0.0/22'), - ipaddr.IPv4('1.1.4.0/24')]) - # test that two addresses are supernet'ed properlly - collapsed = ipaddr.collapse_address_list([ip1, ip2]) - self.assertEqual(collapsed, [ipaddr.IPv4('1.1.0.0/23')]) - - ip_same1 = ip_same2 = ipaddr.IPv4('1.1.1.1/32') - self.assertEqual(ipaddr.collapse_address_list([ip_same1, ip_same2]), - [ip_same1]) - ip1 = ipaddr.IPv6('::2001:1/100') - ip2 = ipaddr.IPv6('::2002:1/120') - ip3 = ipaddr.IPv6('::2001:1/96') - # test that ipv6 addresses are subsumed properly. - collapsed = ipaddr.collapse_address_list([ip1, ip2, ip3]) - self.assertEqual(collapsed, [ip3]) - - def testNetworkComparison(self): - # ip1 and ip2 have the same network address - ip1 = ipaddr.IPv4('1.1.1.0/24') - ip2 = ipaddr.IPv4('1.1.1.1/24') - ip3 = ipaddr.IPv4('1.1.2.0/24') - - self.assertTrue(ip1 < ip3) - self.assertTrue(ip3 > ip2) - - self.assertEquals(ip1.compare_networks(ip2), 0) - self.assertTrue(ip1._get_networks_key() == ip2._get_networks_key()) - self.assertEquals(ip1.compare_networks(ip3), -1) - self.assertTrue(ip1._get_networks_key() < ip3._get_networks_key()) - - ip1 = ipaddr.IPv6('2001::2000/96') - ip2 = ipaddr.IPv6('2001::2001/96') - ip3 = ipaddr.IPv6('2001:ffff::2000/96') - - self.assertTrue(ip1 < ip3) - self.assertTrue(ip3 > ip2) - self.assertEquals(ip1.compare_networks(ip2), 0) - self.assertTrue(ip1._get_networks_key() == ip2._get_networks_key()) - self.assertEquals(ip1.compare_networks(ip3), -1) - self.assertTrue(ip1._get_networks_key() < ip3._get_networks_key()) - - # Test comparing different protocols - ipv6 = ipaddr.IPv6('::/0') - ipv4 = ipaddr.IPv4('0.0.0.0/0') - self.assertTrue(ipv6 > ipv4) - self.assertTrue(ipv4 < ipv6) - - def testEmbeddedIpv4(self): - ipv4_string = '192.168.0.1' - ipv4 = ipaddr.IPv4(ipv4_string) - v4compat_ipv6 = ipaddr.IPv6('::%s' % ipv4_string) - self.assertEquals(v4compat_ipv6.ip, ipv4.ip) - v4mapped_ipv6 = ipaddr.IPv6('::ffff:%s' % ipv4_string) - self.assertNotEquals(v4mapped_ipv6.ip, ipv4.ip) - self.assertRaises(ipaddr.IPv6IpValidationError, ipaddr.IPv6, - '2001:1.1.1.1:1.1.1.1') - - def testIPVersion(self): - self.assertEqual(self.ipv4.version, 4) - self.assertEqual(self.ipv6.version, 6) - - def testPacked(self): - self.assertEqual(self.ipv4.packed, - _cb('\x01\x02\x03\x04')) - self.assertEqual(ipaddr.IPv4('255.254.253.252').packed, - _cb('\xff\xfe\xfd\xfc')) - self.assertEqual(self.ipv6.packed, - _cb('\x20\x01\x06\x58\x02\x2a\xca\xfe' - '\x02\x00\x00\x00\x00\x00\x00\x01')) - self.assertEqual(ipaddr.IPv6('ffff:2:3:4:ffff::').packed, - _cb('\xff\xff\x00\x02\x00\x03\x00\x04\xff\xff' - + '\x00' * 6)) - self.assertEqual(ipaddr.IPv6('::1:0:0:0:0').packed, - _cb('\x00' * 6 + '\x00\x01' + '\x00' * 8)) - - def testIpStrFromPrefixlen(self): - ipv4 = ipaddr.IPv4('1.2.3.4/24') - self.assertEquals(ipv4._ip_string_from_prefix(), '255.255.255.0') - self.assertEquals(ipv4._ip_string_from_prefix(28), '255.255.255.240') - - def testIpType(self): - ipv4 = ipaddr.IP('1.2.3.4') - ipv6 = ipaddr.IP('::1.2.3.4') - self.assertEquals(ipaddr.IPv4, type(ipv4)) - self.assertEquals(ipaddr.IPv6, type(ipv6)) - - def testReservedIpv4(self): - self.assertEquals(True, ipaddr.IP('224.1.1.1/31').is_multicast) - self.assertEquals(False, ipaddr.IP('240.0.0.0').is_multicast) - - self.assertEquals(True, ipaddr.IP('192.168.1.1/17').is_private) - self.assertEquals(False, ipaddr.IP('192.169.0.0').is_private) - self.assertEquals(True, ipaddr.IP('10.255.255.255').is_private) - self.assertEquals(False, ipaddr.IP('11.0.0.0').is_private) - self.assertEquals(True, ipaddr.IP('172.31.255.255').is_private) - self.assertEquals(False, ipaddr.IP('172.32.0.0').is_private) - - self.assertEquals(True, ipaddr.IP('169.254.100.200/24').is_link_local) - self.assertEquals(False, ipaddr.IP('169.255.100.200/24').is_link_local) - - self.assertEquals(True, ipaddr.IP('127.100.200.254/32').is_loopback) - self.assertEquals(True, ipaddr.IP('127.42.0.0/16').is_loopback) - self.assertEquals(False, ipaddr.IP('128.0.0.0').is_loopback) - - def testReservedIpv6(self): - ip = ipaddr.IP - - self.assertEquals(True, ip('ffff::').is_multicast) - self.assertEquals(True, ip(2**128-1).is_multicast) - self.assertEquals(True, ip('ff00::').is_multicast) - self.assertEquals(False, ip('fdff::').is_multicast) - - self.assertEquals(True, ip('fecf::').is_site_local) - self.assertEquals(True, ip('feff:ffff:ffff:ffff::').is_site_local) - self.assertEquals(False, ip('fbf:ffff::').is_site_local) - self.assertEquals(False, ip('ff00::').is_site_local) - - self.assertEquals(True, ip('fc00::').is_private) - self.assertEquals(True, ip('fc00:ffff:ffff:ffff::').is_private) - self.assertEquals(False, ip('fbff:ffff::').is_private) - self.assertEquals(False, ip('fe00::').is_private) - - self.assertEquals(True, ip('fea0::').is_link_local) - self.assertEquals(True, ip('febf:ffff::').is_link_local) - self.assertEquals(False, ip('fe7f:ffff::').is_link_local) - self.assertEquals(False, ip('fec0::').is_link_local) - - self.assertEquals(True, ip('0:0::0:01').is_loopback) - self.assertEquals(False, ip('::1/127').is_loopback) - self.assertEquals(False, ip('::').is_loopback) - self.assertEquals(False, ip('::2').is_loopback) - - self.assertEquals(True, ip('0::0').is_unspecified) - self.assertEquals(False, ip('::1').is_unspecified) - self.assertEquals(False, ip('::/127').is_unspecified) - - def testAddrExclude(self): - addr1 = ipaddr.IP('10.1.1.0/24') - addr2 = ipaddr.IP('10.1.1.0/26') - addr3 = ipaddr.IP('10.2.1.0/24') - self.assertEqual(addr1.address_exclude(addr2), - [ipaddr.IP('10.1.1.64/26'), - ipaddr.IP('10.1.1.128/25')]) - self.assertRaises(ValueError, addr1.address_exclude, addr3) - - def testHash(self): - self.assertEquals(hash(ipaddr.IP('10.1.1.0/24')), - hash(ipaddr.IP('10.1.1.0/24'))) - dummy = {} - dummy[self.ipv4] = None - dummy[self.ipv6] = None - self.assertTrue(self.ipv4 in dummy) - - def testIPv4PrefixFromInt(self): - addr1 = ipaddr.IP('10.1.1.0/24') - addr2 = ipaddr.IPv4(addr1.ip) # clone prefix - addr2.set_prefix(addr1.prefixlen) - addr3 = ipaddr.IP(123456) - - self.assertEqual(123456, addr3.ip) - self.assertRaises(ipaddr.IPv4NetmaskValidationError, - addr2.set_prefix, -1L) - self.assertEqual(addr1, addr2) - self.assertEqual(str(addr1), str(addr2)) - - def testIPv6PrefixFromInt(self): - addr1 = ipaddr.IP('2001:0658:022a:cafe:0200::1/64') - addr2 = ipaddr.IPv6(addr1.ip) # clone prefix - addr2.set_prefix(addr1.prefixlen) - addr3 = ipaddr.IP(123456) - - self.assertEqual(123456, addr3.ip) - self.assertRaises(ipaddr.IPv6NetmaskValidationError, - addr2.set_prefix, -1L) - self.assertEqual(addr1, addr2) - self.assertEqual(str(addr1), str(addr2)) - - def testCopyConstructor(self): - addr1 = ipaddr.IP('10.1.1.0/24') - addr2 = ipaddr.IP(addr1) - addr3 = ipaddr.IP('2001:658:22a:cafe:200::1/64') - addr4 = ipaddr.IP(addr3) - - self.assertEqual(addr1, addr2) - self.assertEqual(addr3, addr4) - - def testCompressIPv6Address(self): - test_addresses = { - '1:2:3:4:5:6:7:8': '1:2:3:4:5:6:7:8/128', - '2001:0:0:4:0:0:0:8': '2001:0:0:4::8/128', - '2001:0:0:4:5:6:7:8': '2001::4:5:6:7:8/128', - '2001:0:3:4:5:6:7:8': '2001:0:3:4:5:6:7:8/128', - '2001:0::3:4:5:6:7:8': '2001:0:3:4:5:6:7:8/128', - '0:0:3:0:0:0:0:ffff': '0:0:3::ffff/128', - '0:0:0:4:0:0:0:ffff': '::4:0:0:0:ffff/128', - '0:0:0:0:5:0:0:ffff': '::5:0:0:ffff/128', - '1:0:0:4:0:0:7:8': '1::4:0:0:7:8/128', - '0:0:0:0:0:0:0:0': '::/128', - '0:0:0:0:0:0:0:0/0': '::/0', - '0:0:0:0:0:0:0:1': '::1/128', - '2001:0658:022a:cafe:0000:0000:0000:0000/66': - '2001:658:22a:cafe::/66', - } - for uncompressed, compressed in test_addresses.items(): - self.assertEquals(compressed, str(ipaddr.IPv6(uncompressed))) - - def testExplodeShortHandIpStr(self): - addr1 = ipaddr.IPv6('2001::1') - self.assertEqual('2001:0000:0000:0000:0000:0000:0000:0001', - addr1._explode_shorthand_ip_string(addr1.ip_ext)) - - def testIntRepresentation(self): - self.assertEqual(16909060, int(self.ipv4)) - self.assertEqual(42540616829182469433547762482097946625, int(self.ipv6)) - - def testHexRepresentation(self): - self.assertEqual(hex(0x1020304), hex(self.ipv4)) - - self.assertEqual(hex(0x20010658022ACAFE0200000000000001), - hex(self.ipv6)) - - # backwards compatibility - def testBackwardsCompability(self): - ip = ipaddr.IP - - self.assertEqual(ipaddr.CollapseAddrList( - [ip('1.1.0.0/24'), ip('1.1.1.0/24')]), - [ip('1.1.0.0/23')]) - - self.assertEqual(ip('::42:0/112').AddressExclude(ip('::42:8000/113')), - [ip('::42:0/113')]) - - self.assertTrue(ip('1::/8').CompareNetworks(ip('2::/9')) < 0) - - self.assertEqual(ip('1::/16').Contains(ip('2::/16')), False) - - i4 = ip('1.2.3.1/12') - i4.set_prefix(0) - self.assertEqual(i4.get_prefix(), 0) - - i6 = ip('::1/2') - i6.set_prefix(0) - self.assertEqual(i6.get_prefix(), 0) - - self.assertEqual(ip('0.0.0.0/0').Subnet(), - [ip('0.0.0.0/1'), ip('128.0.0.0/1')]) - self.assertEqual(ip('::/127').Subnet(), [ip('::/128'), ip('::1/128')]) - - self.assertEqual(ip('1.0.0.0/32').Supernet(), ip('1.0.0.0/31')) - self.assertEqual(ip('::/121').Supernet(), ip('::/120')) - - self.assertEqual(ip('10.0.0.02').IsRFC1918(), True) - self.assertEqual(ip('10.0.0.0').IsMulticast(), False) - self.assertEqual(ip('127.255.255.255').IsLoopback(), True) - self.assertEqual(ip('169.255.255.255').IsLinkLocal(), False) - -if __name__ == '__main__': - unittest.main() diff --git a/tags/1.1.0/setup.py b/tags/1.1.0/setup.py deleted file mode 100755 index 6088ced..0000000 --- a/tags/1.1.0/setup.py +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/python -# -# Copyright 2008 Google Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from distutils.core import setup - -import ipaddr - - -setup(name='ipaddr', - maintainer='Google', - maintainer_email='ipaddr-py-dev@googlegroups.com', - version=ipaddr.__version__, - url='http://code.google.com/p/ipaddr-py/', - classifiers=[ - 'Development Status :: 5 - Production/Stable', - 'Intended Audience :: Developers', - 'License :: OSI Approved :: Apache Software License', - 'Operating System :: OS Independent', - 'Topic :: Internet', - 'Topic :: Software Development :: Libraries', - 'Topic :: System :: Networking'], - py_modules=['ipaddr']) diff --git a/tags/1.1.0/test-2to3.sh b/tags/1.1.0/test-2to3.sh deleted file mode 100755 index 408d665..0000000 --- a/tags/1.1.0/test-2to3.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -# Converts the python2 ipaddr files to python3 and runs the unit tests -# with both python versions. - -mkdir -p 2to3output && \ -cp -f *.py 2to3output && \ -( cd 2to3output && 2to3 . | patch -p0 ) && \ -py3version=$(python3 --version 2>&1) && \ -echo -e "\nTesting with ${py3version}" && \ -python3 2to3output/ipaddr_test.py && \ -rm -r 2to3output && \ -pyversion=$(python --version 2>&1) && \ -echo -e "\nTesting with ${pyversion}" && \ -./ipaddr_test.py |