| 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 |
| 268 first = first._ip |
| 269 last = last._ip |
| 270 while first <= last: | 270 while first <= last: |
| 271 nbits = _count_righthand_zero_bits(first._ip, ip_bits) | 271 nbits = _count_righthand_zero_bits(first, ip_bits) |
| 272 current = None | 272 current = None |
| 273 while nbits >= 0: | 273 while nbits >= 0: |
| 274 addend = 2**nbits - 1 | 274 addend = 2**nbits - 1 |
| 275 current = first._ip + addend | 275 current = first + addend |
| 276 nbits -= 1 | 276 nbits -= 1 |
| 277 if ip(current) <= last: | 277 if current <= last: |
| 278 break | 278 break |
| 279 prefix = _get_prefix_length(first._ip, current, ip_bits) | 279 prefix = _get_prefix_length(first, current, ip_bits) |
| 280 networks.append(ipnet('%s/%s' % (first, prefix))) | 280 net = ip(first) |
| 281 if current == first._ALL_ONES: | 281 net.prefixlen = prefix |
| 282 networks.append(net) |
| 283 if current == ip._ALL_ONES: |
| 282 break | 284 break |
| 283 first = ip(current + 1) | 285 first = current + 1 |
| 284 return networks | 286 return networks |
| 285 | 287 |
| 286 def _collapse_address_list_recursive(addresses): | 288 def _collapse_address_list_recursive(addresses): |
| 287 """Loops through the addresses, collapsing concurrent netblocks. | 289 """Loops through the addresses, collapsing concurrent netblocks. |
| 288 | 290 |
| 289 Example: | 291 Example: |
| 290 | 292 |
| 291 ip1 = IPv4('1.1.0.0/24') | 293 ip1 = IPv4('1.1.0.0/24') |
| 292 ip2 = IPv4('1.1.1.0/24') | 294 ip2 = IPv4('1.1.1.0/24') |
| 293 ip3 = IPv4('1.1.2.0/24') | 295 ip3 = IPv4('1.1.2.0/24') |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 336 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')]) -> |
| 337 [IPv4('1.1.0.0/23')] | 339 [IPv4('1.1.0.0/23')] |
| 338 | 340 |
| 339 Args: | 341 Args: |
| 340 addresses: A list of IPv4 or IPv6 objects. | 342 addresses: A list of IPv4 or IPv6 objects. |
| 341 | 343 |
| 342 Returns: | 344 Returns: |
| 343 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. |
| 344 | 346 |
| 345 """ | 347 """ |
| 346 _addresses = [] | |
| 347 i = 0 | 348 i = 0 |
| 348 ip_bits = addresses[0]._max_prefixlen | 349 addrs = [] |
| 349 # filter out IP addresses, dedup, and sort | 350 ips = [] |
| 350 addrs = sorted(set([ip for ip in addresses if isinstance(ip, BaseIP)])) | 351 nets = [] |
| 351 nets = sorted(set([ip for ip in addresses if isinstance(ip, BaseNet)])) | 352 # split IP addresses and networks |
| 352 | 353 for ip in addresses: |
| 353 while i < len(addrs): | 354 if isinstance(ip, BaseIP): |
| 354 (first, last) = _find_address_range(addrs[i:]) | 355 ips.append(ip) |
| 355 i = addrs.index(last) + 1 | 356 elif ip._prefixlen == ip._max_prefixlen: |
| 356 _addresses.extend( | 357 ips.append(ip.ip) |
| 357 [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)) |
| 358 | 368 |
| 359 return _collapse_address_list_recursive( | 369 return _collapse_address_list_recursive( |
| 360 sorted(_addresses + nets, key=BaseNet._get_networks_key)) | 370 sorted(addrs + nets, key=BaseNet._get_networks_key)) |
| 361 | 371 |
| 362 # backwards compatibility | 372 # backwards compatibility |
| 363 CollapseAddrList = collapse_address_list | 373 CollapseAddrList = collapse_address_list |
| 364 | 374 |
| 365 # Test whether this Python implementation supports byte objects that | 375 # Test whether this Python implementation supports byte objects that |
| 366 # are not identical to str ones. | 376 # are not identical to str ones. |
| 367 # 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 |
| 368 # distinguish between packed representations and strings, for example | 378 # distinguish between packed representations and strings, for example |
| 369 # 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). |
| 370 try: | 380 try: |
| (...skipping 1411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1782 """ | 1792 """ |
| 1783 try: | 1793 try: |
| 1784 prefixlen = int(prefixlen) | 1794 prefixlen = int(prefixlen) |
| 1785 except ValueError: | 1795 except ValueError: |
| 1786 return False | 1796 return False |
| 1787 return 0 <= prefixlen <= 128 | 1797 return 0 <= prefixlen <= 128 |
| 1788 | 1798 |
| 1789 # backwards compatibility | 1799 # backwards compatibility |
| 1790 Subnet = subnet | 1800 Subnet = subnet |
| 1791 Supernet = supernet | 1801 Supernet = supernet |
| LEFT | RIGHT |