| LEFT | RIGHT |
| 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 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 242 IPTypeError: | 242 IPTypeError: |
| 243 If the first and last objects are not IP addresses. | 243 If the first and last objects are not IP addresses. |
| 244 If the first and last objects are not the same version. | 244 If the first and last objects are not the same version. |
| 245 ValueError: | 245 ValueError: |
| 246 If the last object is not greater than the first. | 246 If the last object is not greater than the first. |
| 247 If the version is not 4 or 6. | 247 If the version is not 4 or 6. |
| 248 | 248 |
| 249 """ | 249 """ |
| 250 | 250 |
| 251 if not (isinstance(first, BaseIP) and isinstance(last, BaseIP)): | 251 if not (isinstance(first, BaseIP) and isinstance(last, BaseIP)): |
| 252 raise IPTypeError("first and last must be IP addresses not networks.") | 252 raise IPTypeError("first and last must be IP addresses, not networks") |
| 253 if first.version != last.version: | 253 if first.version != last.version: |
| 254 raise IPTypeError("IP addresses must be same version") | 254 raise IPTypeError("IP addresses must be same version") |
| 255 if first > last: | 255 if first > last: |
| 256 raise ValueError("last IP address must be greater than first") | 256 raise ValueError("last IP address must be greater than first") |
| 257 | 257 |
| 258 networks = [] | 258 networks = [] |
| 259 | 259 |
| 260 if first.version == 4: | 260 if first.version == 4: |
| 261 ipnet = IPv4Network | 261 ip = IPv4Network |
| 262 ip = IPv4Address | |
| 263 elif first.version == 6: | 262 elif first.version == 6: |
| 264 ipnet = IPv6Network | 263 ip = IPv6Network |
| 265 ip = IPv6Address | |
| 266 else: | 264 else: |
| 267 raise ValueError("unknown IP version") | 265 raise ValueError("unknown IP version") |
| 268 | 266 |
| 269 ip_bits = first._max_prefixlen | 267 ip_bits = first._max_prefixlen |
| 270 first = first._ip | 268 first = first._ip |
| 271 last = last._ip | 269 last = last._ip |
| 272 while first <= last: | 270 while first <= last: |
| 273 nbits = _count_righthand_zero_bits(first, ip_bits) | 271 nbits = _count_righthand_zero_bits(first, ip_bits) |
| 274 current = None | 272 current = None |
| 275 while nbits >= 0: | 273 while nbits >= 0: |
| 276 addend = 2**nbits - 1 | 274 addend = 2**nbits - 1 |
| 277 current = first + addend | 275 current = first + addend |
| 278 nbits -= 1 | 276 nbits -= 1 |
| 279 if current <= last: | 277 if current <= last: |
| 280 break | 278 break |
| 281 prefix = _get_prefix_length(first, current, ip_bits) | 279 prefix = _get_prefix_length(first, current, ip_bits) |
| 282 net = ipnet(first) | 280 net = ip(first) |
| 283 net.prefixlen = prefix | 281 net.prefixlen = prefix |
| 284 networks.append(net) | 282 networks.append(net) |
| 285 if current == ip._ALL_ONES: | 283 if current == ip._ALL_ONES: |
| 286 break | 284 break |
| 287 first = current + 1 | 285 first = current + 1 |
| 288 return networks | 286 return networks |
| 289 | 287 |
| 290 def _collapse_address_list_recursive(addresses): | 288 def _collapse_address_list_recursive(addresses): |
| 291 """Loops through the addresses, collapsing concurrent netblocks. | 289 """Loops through the addresses, collapsing concurrent netblocks. |
| 292 | 290 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 340 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')]) -> |
| 341 [IPv4('1.1.0.0/23')] | 339 [IPv4('1.1.0.0/23')] |
| 342 | 340 |
| 343 Args: | 341 Args: |
| 344 addresses: A list of IPv4 or IPv6 objects. | 342 addresses: A list of IPv4 or IPv6 objects. |
| 345 | 343 |
| 346 Returns: | 344 Returns: |
| 347 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. |
| 348 | 346 |
| 349 """ | 347 """ |
| 350 _addresses = [] | |
| 351 i = 0 | 348 i = 0 |
| 352 ip_bits = addresses[0]._max_prefixlen | 349 addrs = [] |
| 353 # filter out IP addresses, dedup, and sort | 350 ips = [] |
| 354 addrs = sorted(set([ip for ip in addresses if isinstance(ip, BaseIP)])) | 351 nets = [] |
| 355 nets = sorted(set([ip for ip in addresses if isinstance(ip, BaseNet)])) | 352 # split IP addresses and networks |
| 356 | 353 for ip in addresses: |
| 357 while i < len(addrs): | 354 if isinstance(ip, BaseIP): |
| 358 (first, last) = _find_address_range(addrs[i:]) | 355 ips.append(ip) |
| 359 i = addrs.index(last) + 1 | 356 elif ip._prefixlen == ip._max_prefixlen: |
| 360 _addresses.extend( | 357 ips.append(ip.ip) |
| 361 [IP(ip) for ip in summarize_address_range(first, last)]) | 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)) |
| 362 | 368 |
| 363 return _collapse_address_list_recursive( | 369 return _collapse_address_list_recursive( |
| 364 sorted(_addresses + nets, key=BaseNet._get_networks_key)) | 370 sorted(addrs + nets, key=BaseNet._get_networks_key)) |
| 365 | 371 |
| 366 # backwards compatibility | 372 # backwards compatibility |
| 367 CollapseAddrList = collapse_address_list | 373 CollapseAddrList = collapse_address_list |
| 368 | 374 |
| 369 # Test whether this Python implementation supports byte objects that | 375 # Test whether this Python implementation supports byte objects that |
| 370 # are not identical to str ones. | 376 # are not identical to str ones. |
| 371 # 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 |
| 372 # distinguish between packed representations and strings, for example | 378 # distinguish between packed representations and strings, for example |
| 373 # 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). |
| 374 try: | 380 try: |
| (...skipping 1411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1786 """ | 1792 """ |
| 1787 try: | 1793 try: |
| 1788 prefixlen = int(prefixlen) | 1794 prefixlen = int(prefixlen) |
| 1789 except ValueError: | 1795 except ValueError: |
| 1790 return False | 1796 return False |
| 1791 return 0 <= prefixlen <= 128 | 1797 return 0 <= prefixlen <= 128 |
| 1792 | 1798 |
| 1793 # backwards compatibility | 1799 # backwards compatibility |
| 1794 Subnet = subnet | 1800 Subnet = subnet |
| 1795 Supernet = supernet | 1801 Supernet = supernet |
| LEFT | RIGHT |