| OLD | NEW |
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 # | 2 # |
| 3 # Copyright 2007 Google Inc. | 3 # Copyright 2007 Google Inc. |
| 4 # Licensed to PSF under a Contributor Agreement. | 4 # Licensed to PSF under a Contributor Agreement. |
| 5 # | 5 # |
| 6 # Licensed under the Apache License, Version 2.0 (the "License"); | 6 # Licensed under the Apache License, Version 2.0 (the "License"); |
| 7 # you may not use this file except in compliance with the License. | 7 # you may not use this file except in compliance with the License. |
| 8 # You may obtain a copy of the License at | 8 # You may obtain a copy of the License at |
| 9 # | 9 # |
| 10 # http://www.apache.org/licenses/LICENSE-2.0 | 10 # http://www.apache.org/licenses/LICENSE-2.0 |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 162 | 162 |
| 163 def IPv6(address, host=False): | 163 def IPv6(address, host=False): |
| 164 """Generic IPv6 Factory function.. | 164 """Generic IPv6 Factory function.. |
| 165 | 165 |
| 166 Return an IPv6 address or network. | 166 Return an IPv6 address or network. |
| 167 """ | 167 """ |
| 168 if host: | 168 if host: |
| 169 return IPv6Address(address) | 169 return IPv6Address(address) |
| 170 return IPv6Network(address) | 170 return IPv6Network(address) |
| 171 | 171 |
| 172 |
| 173 def _find_address_range(addresses): |
| 174 """Find a sequence of addresses. |
| 175 |
| 176 Args: |
| 177 addresses: a list of IPv4 or IPv6 addresses. |
| 178 |
| 179 Returns: |
| 180 A tuple containing the first and last IP addresses in the sequence. |
| 181 |
| 182 """ |
| 183 first = last = addresses[0] |
| 184 for ip in addresses[1:]: |
| 185 if ip._ip == last._ip + 1: |
| 186 last = ip |
| 187 else: |
| 188 break |
| 189 return (first, last) |
| 190 |
| 191 def _get_prefix_length(number1, number2, bits): |
| 192 """Get the number of leading bits that are same for two numbers. |
| 193 |
| 194 Args: |
| 195 number1: an integer. |
| 196 number2: another integer. |
| 197 bits: the maximum number of bits to compare. |
| 198 |
| 199 Returns: |
| 200 The number of leading bits that are the same for two numbers. |
| 201 |
| 202 """ |
| 203 for i in range(bits): |
| 204 if number1 >> i == number2 >> i: |
| 205 return bits - i |
| 206 return 0 |
| 207 |
| 208 def _count_righthand_zero_bits(number, bits): |
| 209 """Count the number of zero bits on the right hand side. |
| 210 |
| 211 Args: |
| 212 number: an integer. |
| 213 bits: maximum number of bits to count. |
| 214 |
| 215 Returns: |
| 216 The number of zero bits on the right hand side of the number. |
| 217 |
| 218 """ |
| 219 if number == 0: |
| 220 return bits |
| 221 for i in range(bits): |
| 222 if (number >> i) % 2: |
| 223 return i |
| 224 |
| 225 def summarize_address_range(first, last): |
| 226 """Summarize a network range given the first and last IP addresses. |
| 227 |
| 228 Example: |
| 229 >>> summarize_address_range(IPv4Address('1.1.1.0'), |
| 230 IPv4Address('1.1.1.130')) |
| 231 [IPv4Network('1.1.1.0/25'), IPv4Network('1.1.1.128/31'), |
| 232 IPv4Network('1.1.1.130/32')] |
| 233 |
| 234 Args: |
| 235 first: the first IPv4 or IPv6 address in the range. |
| 236 last: the last IPv4 or IPv6 address in the range. |
| 237 |
| 238 Returns: |
| 239 The address range collapsed to a list of IPv4 or IPv6 networks. |
| 240 |
| 241 Raise: |
| 242 IPTypeError: |
| 243 If the first and last objects are not IP addresses. |
| 244 If the first and last objects are not the same version. |
| 245 ValueError: |
| 246 If the last object is not greater than the first. |
| 247 If the version is not 4 or 6. |
| 248 |
| 249 """ |
| 250 |
| 251 if not (isinstance(first, BaseIP) and isinstance(last, BaseIP)): |
| 252 raise IPTypeError("first and last must be IP addresses, not networks") |
| 253 if first.version != last.version: |
| 254 raise IPTypeError("IP addresses must be same version") |
| 255 if first > last: |
| 256 raise ValueError("last IP address must be greater than first") |
| 257 |
| 258 networks = [] |
| 259 |
| 260 if first.version == 4: |
| 261 ip = IPv4Network |
| 262 elif first.version == 6: |
| 263 ip = IPv6Network |
| 264 else: |
| 265 raise ValueError("unknown IP version") |
| 266 |
| 267 ip_bits = first._max_prefixlen |
| 268 first = first._ip |
| 269 last = last._ip |
| 270 while first <= last: |
| 271 nbits = _count_righthand_zero_bits(first, ip_bits) |
| 272 current = None |
| 273 while nbits >= 0: |
| 274 addend = 2**nbits - 1 |
| 275 current = first + addend |
| 276 nbits -= 1 |
| 277 if current <= last: |
| 278 break |
| 279 prefix = _get_prefix_length(first, current, ip_bits) |
| 280 net = ip(first) |
| 281 net.prefixlen = prefix |
| 282 networks.append(net) |
| 283 if current == ip._ALL_ONES: |
| 284 break |
| 285 first = current + 1 |
| 286 return networks |
| 172 | 287 |
| 173 def _collapse_address_list_recursive(addresses): | 288 def _collapse_address_list_recursive(addresses): |
| 174 """Loops through the addresses, collapsing concurrent netblocks. | 289 """Loops through the addresses, collapsing concurrent netblocks. |
| 175 | 290 |
| 176 Example: | 291 Example: |
| 177 | 292 |
| 178 ip1 = IPv4('1.1.0.0/24') | 293 ip1 = IPv4('1.1.0.0/24') |
| 179 ip2 = IPv4('1.1.1.0/24') | 294 ip2 = IPv4('1.1.1.0/24') |
| 180 ip3 = IPv4('1.1.2.0/24') | 295 ip3 = IPv4('1.1.2.0/24') |
| 181 ip4 = IPv4('1.1.3.0/24') | 296 ip4 = IPv4('1.1.3.0/24') |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 223 collapse_address_list([IPv4('1.1.0.0/24'), IPv4('1.1.1.0/24')]) -> | 338 collapse_address_list([IPv4('1.1.0.0/24'), IPv4('1.1.1.0/24')]) -> |
| 224 [IPv4('1.1.0.0/23')] | 339 [IPv4('1.1.0.0/23')] |
| 225 | 340 |
| 226 Args: | 341 Args: |
| 227 addresses: A list of IPv4 or IPv6 objects. | 342 addresses: A list of IPv4 or IPv6 objects. |
| 228 | 343 |
| 229 Returns: | 344 Returns: |
| 230 A list of IPv4 or IPv6 objects depending on what we were passed. | 345 A list of IPv4 or IPv6 objects depending on what we were passed. |
| 231 | 346 |
| 232 """ | 347 """ |
| 348 i = 0 |
| 349 addrs = [] |
| 350 ips = [] |
| 351 nets = [] |
| 352 # split IP addresses and networks |
| 353 for ip in addresses: |
| 354 if isinstance(ip, BaseIP): |
| 355 ips.append(ip) |
| 356 elif ip._prefixlen == ip._max_prefixlen: |
| 357 ips.append(ip.ip) |
| 358 else: |
| 359 nets.append(ip) |
| 360 # sort and dedup |
| 361 ips = sorted(set(ips)) |
| 362 nets = sorted(set(nets)) |
| 363 |
| 364 while i < len(ips): |
| 365 (first, last) = _find_address_range(ips[i:]) |
| 366 i = ips.index(last) + 1 |
| 367 addrs.extend(summarize_address_range(first, last)) |
| 368 |
| 233 return _collapse_address_list_recursive( | 369 return _collapse_address_list_recursive( |
| 234 sorted(addresses, key=BaseNet._get_networks_key)) | 370 sorted(addrs + nets, key=BaseNet._get_networks_key)) |
| 235 | 371 |
| 236 # backwards compatibility | 372 # backwards compatibility |
| 237 CollapseAddrList = collapse_address_list | 373 CollapseAddrList = collapse_address_list |
| 238 | 374 |
| 239 # Test whether this Python implementation supports byte objects that | 375 # Test whether this Python implementation supports byte objects that |
| 240 # are not identical to str ones. | 376 # are not identical to str ones. |
| 241 # We need to exclude platforms where bytes == str so that we can | 377 # We need to exclude platforms where bytes == str so that we can |
| 242 # distinguish between packed representations and strings, for example | 378 # distinguish between packed representations and strings, for example |
| 243 # b'12::' (the IPv4 address 49.50.58.58) and '12::' (an IPv6 address). | 379 # b'12::' (the IPv4 address 49.50.58.58) and '12::' (an IPv6 address). |
| 244 try: | 380 try: |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 319 return self._version > other._version | 455 return self._version > other._version |
| 320 if self._ip != other._ip: | 456 if self._ip != other._ip: |
| 321 return self._ip > other._ip | 457 return self._ip > other._ip |
| 322 return False | 458 return False |
| 323 | 459 |
| 324 def __repr__(self): | 460 def __repr__(self): |
| 325 return '%s(%r)' % (self.__class__.__name__, str(self)) | 461 return '%s(%r)' % (self.__class__.__name__, str(self)) |
| 326 | 462 |
| 327 def __str__(self): | 463 def __str__(self): |
| 328 return '%s' % self._string_from_ip_int(self._ip) | 464 return '%s' % self._string_from_ip_int(self._ip) |
| 465 |
| 466 def __hash__(self): |
| 467 return hash(self._ip) |
| 329 | 468 |
| 330 @property | 469 @property |
| 331 def version(self): | 470 def version(self): |
| 332 raise NotImplementedError('BaseIP has no version') | 471 raise NotImplementedError('BaseIP has no version') |
| 333 | 472 |
| 334 | 473 |
| 335 class BaseNet(IPAddrBase): | 474 class BaseNet(IPAddrBase): |
| 336 | 475 |
| 337 """A generic IP object. | 476 """A generic IP object. |
| 338 | 477 |
| (...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 687 The following methods are used by IPv4 objects in both single IP | 826 The following methods are used by IPv4 objects in both single IP |
| 688 addresses and networks. | 827 addresses and networks. |
| 689 | 828 |
| 690 """ | 829 """ |
| 691 | 830 |
| 692 # Equivalent to 255.255.255.255 or 32 bits of 1's. | 831 # Equivalent to 255.255.255.255 or 32 bits of 1's. |
| 693 _ALL_ONES = (2**32) - 1 | 832 _ALL_ONES = (2**32) - 1 |
| 694 | 833 |
| 695 def __init__(self, address): | 834 def __init__(self, address): |
| 696 self._version = 4 | 835 self._version = 4 |
| 836 self._max_prefixlen = 32 |
| 697 | 837 |
| 698 def _explode_shorthand_ip_string(self, ip_str=None): | 838 def _explode_shorthand_ip_string(self, ip_str=None): |
| 699 if not ip_str: | 839 if not ip_str: |
| 700 ip_str = str(self) | 840 ip_str = str(self) |
| 701 return ip_str | 841 return ip_str |
| 702 | 842 |
| 703 def _ip_int_from_string(self, ip_str): | 843 def _ip_int_from_string(self, ip_str): |
| 704 """Turn the given IP string into an integer for comparison. | 844 """Turn the given IP string into an integer for comparison. |
| 705 | 845 |
| 706 Args: | 846 Args: |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 753 if len(octets) != 4: | 893 if len(octets) != 4: |
| 754 return False | 894 return False |
| 755 | 895 |
| 756 for octet in octets: | 896 for octet in octets: |
| 757 try: | 897 try: |
| 758 if not 0 <= int(octet) <= 255: | 898 if not 0 <= int(octet) <= 255: |
| 759 return False | 899 return False |
| 760 except ValueError: | 900 except ValueError: |
| 761 return False | 901 return False |
| 762 return True | 902 return True |
| 903 |
| 904 @property |
| 905 def max_prefixlen(self): |
| 906 return self._max_prefixlen |
| 763 | 907 |
| 764 @property | 908 @property |
| 765 def packed(self): | 909 def packed(self): |
| 766 """The binary representation of this address.""" | 910 """The binary representation of this address.""" |
| 767 return struct.pack('!I', self._ip) | 911 return struct.pack('!I', self._ip) |
| 768 | 912 |
| 769 @property | 913 @property |
| 770 def version(self): | 914 def version(self): |
| 771 return self._version | 915 return self._version |
| 772 | 916 |
| (...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1107 | 1251 |
| 1108 The following methods are used by IPv6 objects in both single IP | 1252 The following methods are used by IPv6 objects in both single IP |
| 1109 addresses and networks. | 1253 addresses and networks. |
| 1110 | 1254 |
| 1111 """ | 1255 """ |
| 1112 | 1256 |
| 1113 _ALL_ONES = (2**128) - 1 | 1257 _ALL_ONES = (2**128) - 1 |
| 1114 | 1258 |
| 1115 def __init__(self, address): | 1259 def __init__(self, address): |
| 1116 self._version = 6 | 1260 self._version = 6 |
| 1261 self._max_prefixlen = 128 |
| 1117 | 1262 |
| 1118 def _ip_int_from_string(self, ip_str=None): | 1263 def _ip_int_from_string(self, ip_str=None): |
| 1119 """Turn an IPv6 ip_str into an integer. | 1264 """Turn an IPv6 ip_str into an integer. |
| 1120 | 1265 |
| 1121 Args: | 1266 Args: |
| 1122 ip_str: A string, the IPv6 ip_str. | 1267 ip_str: A string, the IPv6 ip_str. |
| 1123 | 1268 |
| 1124 Returns: | 1269 Returns: |
| 1125 A long, the IPv6 ip_str. | 1270 A long, the IPv6 ip_str. |
| 1126 | 1271 |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1313 Args: | 1458 Args: |
| 1314 ip_str: A string, the IPv6 address. | 1459 ip_str: A string, the IPv6 address. |
| 1315 | 1460 |
| 1316 Returns: | 1461 Returns: |
| 1317 A boolean, True if the address is shortened. | 1462 A boolean, True if the address is shortened. |
| 1318 | 1463 |
| 1319 """ | 1464 """ |
| 1320 if ip_str.count('::') == 1: | 1465 if ip_str.count('::') == 1: |
| 1321 return True | 1466 return True |
| 1322 return False | 1467 return False |
| 1468 |
| 1469 @property |
| 1470 def max_prefixlen(self): |
| 1471 return self._max_prefixlen |
| 1323 | 1472 |
| 1324 @property | 1473 @property |
| 1325 def packed(self): | 1474 def packed(self): |
| 1326 """The binary representation of this address.""" | 1475 """The binary representation of this address.""" |
| 1327 return struct.pack('!QQ', self._ip >> 64, self._ip & (2**64 - 1)) | 1476 return struct.pack('!QQ', self._ip >> 64, self._ip & (2**64 - 1)) |
| 1328 | 1477 |
| 1329 @property | 1478 @property |
| 1330 def version(self): | 1479 def version(self): |
| 1331 return self._version | 1480 return self._version |
| 1332 | 1481 |
| (...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1643 """ | 1792 """ |
| 1644 try: | 1793 try: |
| 1645 prefixlen = int(prefixlen) | 1794 prefixlen = int(prefixlen) |
| 1646 except ValueError: | 1795 except ValueError: |
| 1647 return False | 1796 return False |
| 1648 return 0 <= prefixlen <= 128 | 1797 return 0 <= prefixlen <= 128 |
| 1649 | 1798 |
| 1650 # backwards compatibility | 1799 # backwards compatibility |
| 1651 Subnet = subnet | 1800 Subnet = subnet |
| 1652 Supernet = supernet | 1801 Supernet = supernet |
| OLD | NEW |