Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(225)

Delta Between Two Patch Sets: Lib/ipaddress.py

Issue 14814: Implement PEP 3144 (the ipaddress module)
Left Patch Set: Created 1 year ago
Right Patch Set: Created 11 months, 3 weeks ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « no previous file | Lib/test/test_ipaddress.py » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 #!/usr/bin/python3
2 #
3 # Copyright 2007 Google Inc. 1 # Copyright 2007 Google Inc.
4 # Licensed to PSF under a Contributor Agreement. 2 # Licensed to PSF under a Contributor Agreement.
5 #
6 # Licensed under the Apache License, Version 2.0 (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
9 #
10 # http://www.apache.org/licenses/LICENSE-2.0
11 #
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS,
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
15 # implied. See the License for the specific language governing
16 # permissions and limitations under the License.
17 3
18 """A fast, lightweight IPv4/IPv6 manipulation library in Python. 4 """A fast, lightweight IPv4/IPv6 manipulation library in Python.
19 5
20 This library is used to create/poke/manipulate IPv4 and IPv6 addresses 6 This library is used to create/poke/manipulate IPv4 and IPv6 addresses
21 and networks. 7 and networks.
22 8
23 """ 9 """
24 10
25 __version__ = '1.0' 11 __version__ = '1.0'
26 12
13
27 import struct 14 import struct
15
28 16
29 IPV4LENGTH = 32 17 IPV4LENGTH = 32
30 IPV6LENGTH = 128 18 IPV6LENGTH = 128
31 19
32 20
33 class AddressValueError(ValueError): 21 class AddressValueError(ValueError):
34 """A Value Error related to the address.""" 22 """A Value Error related to the address."""
35 23
36 24
37 class NetmaskValueError(ValueError): 25 class NetmaskValueError(ValueError):
38 """A Value Error related to the netmask.""" 26 """A Value Error related to the netmask."""
39 27
40 28
41 def ip_address(address, version=None): 29 def ip_address(address):
42 """Take an IP string/int and return an object of the correct type. 30 """Take an IP string/int and return an object of the correct type.
43 31
44 Args: 32 Args:
45 address: A string or integer, the IP address. Either IPv4 or 33 address: A string or integer, the IP address. Either IPv4 or
46 IPv6 addresses may be supplied; integers less than 2**32 will 34 IPv6 addresses may be supplied; integers less than 2**32 will
47 be considered to be IPv4 by default. 35 be considered to be IPv4 by default.
48 version: An integer, 4 or 6. If set, don't try to automatically
49 determine what the IP address type is. Important for things
50 like ip_address(1), which could be IPv4, '192.0.2.1', or IPv6,
51 '2001:db8::1'.
52 36
53 Returns: 37 Returns:
54 An IPv4Address or IPv6Address object. 38 An IPv4Address or IPv6Address object.
55 39
56 Raises: 40 Raises:
57 ValueError: if the *address* passed isn't either a v4 or a v6 41 ValueError: if the *address* passed isn't either a v4 or a v6
58 address, or if the version is not None, 4, or 6. 42 address
59 43
60 """ 44 """
61 if version is not None:
62 if version == 4:
63 return IPv4Address(address)
64 elif version == 6:
65 return IPv6Address(address)
66 else:
67 raise ValueError()
ezio.melotti 2012/05/23 01:37:15 Shouldn't this have a message?
68
69 try: 45 try:
70 return IPv4Address(address) 46 return IPv4Address(address)
71 except (AddressValueError, NetmaskValueError): 47 except (AddressValueError, NetmaskValueError):
72 pass 48 pass
73 49
74 try: 50 try:
75 return IPv6Address(address) 51 return IPv6Address(address)
76 except (AddressValueError, NetmaskValueError): 52 except (AddressValueError, NetmaskValueError):
77 pass 53 pass
78 54
79 raise ValueError('%r does not appear to be an IPv4 or IPv6 address' % 55 raise ValueError('%r does not appear to be an IPv4 or IPv6 address' %
80 address) 56 address)
81 57
82 58
83 def ip_network(address, version=None, strict=True): 59 def ip_network(address, strict=True):
84 """Take an IP string/int and return an object of the correct type. 60 """Take an IP string/int and return an object of the correct type.
85 61
86 Args: 62 Args:
87 address: A string or integer, the IP network. Either IPv4 or 63 address: A string or integer, the IP network. Either IPv4 or
88 IPv6 networks may be supplied; integers less than 2**32 will 64 IPv6 networks may be supplied; integers less than 2**32 will
89 be considered to be IPv4 by default. 65 be considered to be IPv4 by default.
90 version: An integer, 4 or 6. If set, don't try to automatically
ezio.melotti 2012/05/23 01:37:15 Ditto for the comma.
91 determine what the IP address type is. Important for things
92 like ip_network(1), which could be IPv4, '192.0.2.1/32', or IPv6,
93 '2001:db8::1/128'.
ezio.melotti 2012/05/23 01:37:15 The strict arg is not documented.
94 66
95 Returns: 67 Returns:
96 An IPv4Network or IPv6Network object. 68 An IPv4Network or IPv6Network object.
97 69
98 Raises: 70 Raises:
99 ValueError: if the string passed isn't either a v4 or a v6 71 ValueError: if the string passed isn't either a v4 or a v6
100 address. Or if the network has host bits set. Or if the version 72 address. Or if the network has host bits set.
101 is not None, 4, or 6.
102 73
103 """ 74 """
104 if version is not None:
105 if version == 4:
106 return IPv4Network(address, strict)
107 elif version == 6:
108 return IPv6Network(address, strict)
109 else:
110 raise ValueError()
111
112 try: 75 try:
113 return IPv4Network(address, strict) 76 return IPv4Network(address, strict)
114 except (AddressValueError, NetmaskValueError): 77 except (AddressValueError, NetmaskValueError):
115 pass 78 pass
116 79
117 try: 80 try:
118 return IPv6Network(address, strict) 81 return IPv6Network(address, strict)
119 except (AddressValueError, NetmaskValueError): 82 except (AddressValueError, NetmaskValueError):
120 pass 83 pass
121 84
122 raise ValueError('%r does not appear to be an IPv4 or IPv6 network' % 85 raise ValueError('%r does not appear to be an IPv4 or IPv6 network' %
123 address) 86 address)
124 87
125 88
126 def ip_interface(address, version=None): 89 def ip_interface(address):
127 """Take an IP string/int and return an object of the correct type. 90 """Take an IP string/int and return an object of the correct type.
128 91
129 Args: 92 Args:
130 address: A string or integer, the IP address. Either IPv4 or 93 address: A string or integer, the IP address. Either IPv4 or
131 IPv6 addresses may be supplied; integers less than 2**32 will 94 IPv6 addresses may be supplied; integers less than 2**32 will
132 be considered to be IPv4 by default. 95 be considered to be IPv4 by default.
133 version: An integer, 4 or 6. If set, don't try to automatically
134 determine what the IP address type is. Important for things
135 like ip_interface(1), which could be IPv4, '192.0.2.1/32', or IPv6,
136 '2001:db8::1/128'.
137 96
138 Returns: 97 Returns:
139 An IPv4Interface or IPv6Interface object. 98 An IPv4Interface or IPv6Interface object.
140 99
141 Raises: 100 Raises:
142 ValueError: if the string passed isn't either a v4 or a v6 101 ValueError: if the string passed isn't either a v4 or a v6
143 address. Or if the version is not None, 4, or 6. 102 address.
144 103
145 Notes: 104 Notes:
146 The IPv?Interface classes describe an Address on a particular 105 The IPv?Interface classes describe an Address on a particular
147 Network, so they're basically a combination of both the Address 106 Network, so they're basically a combination of both the Address
148 and Network classes. 107 and Network classes.
108
149 """ 109 """
150 if version is not None:
151 if version == 4:
152 return IPv4Interface(address)
153 elif version == 6:
154 return IPv6Interface(address)
155 else:
156 raise ValueError()
157
158 try: 110 try:
159 return IPv4Interface(address) 111 return IPv4Interface(address)
160 except (AddressValueError, NetmaskValueError): 112 except (AddressValueError, NetmaskValueError):
161 pass 113 pass
162 114
163 try: 115 try:
164 return IPv6Interface(address) 116 return IPv6Interface(address)
165 except (AddressValueError, NetmaskValueError): 117 except (AddressValueError, NetmaskValueError):
166 pass 118 pass
167 119
168 raise ValueError('%r does not appear to be an IPv4 or IPv6 network' % 120 raise ValueError('%r does not appear to be an IPv4 or IPv6 network' %
169 address) 121 address)
170 122
171 123
172 def v4_int_to_packed(address): 124 def v4_int_to_packed(address):
173 """Represent an address as 4 packed bytes in network (big-endian) order. 125 """Represent an address as 4 packed bytes in network (big-endian) order.
174 126
175 Args: 127 Args:
176 address: An integer representation of an IPv4 IP address. 128 address: An integer representation of an IPv4 IP address.
177 129
178 Returns: 130 Returns:
179 The integer address packed as 4 bytes in network (big-endian) order. 131 The integer address packed as 4 bytes in network (big-endian) order.
180 132
181 Raises: 133 Raises:
182 ValueError: If the integer is is negative or too large to be an 134 ValueError: If the integer is negative or too large to be an
183 IPv4 IP address. 135 IPv4 IP address.
136
184 """ 137 """
185 try: 138 try:
186 return struct.pack('!I', address) 139 return struct.pack('!I', address)
187 except: 140 except:
188 raise ValueError("Address negative or too large for IPv4") 141 raise ValueError("Address negative or too large for IPv4")
ezio.melotti 2012/05/23 01:37:15 I don't like the bare except too much. Isn't the
189 142
190 143
191 def v6_int_to_packed(address): 144 def v6_int_to_packed(address):
192 """Represent an address as 16 packed bytes in network (big-endian) order. 145 """Represent an address as 16 packed bytes in network (big-endian) order.
193 146
194 Args: 147 Args:
195 address: An integer representation of an IPv4 IP address. 148 address: An integer representation of an IPv6 IP address.
196 149
197 Returns: 150 Returns:
198 The integer address packed as 16 bytes in network (big-endian) order. 151 The integer address packed as 16 bytes in network (big-endian) order.
152
199 """ 153 """
200 try: 154 try:
201 return struct.pack('!QQ', address >> 64, address & (2**64 - 1)) 155 return struct.pack('!QQ', address >> 64, address & (2**64 - 1))
202 except: 156 except:
203 raise ValueError("Address negative or too large for IPv6") 157 raise ValueError("Address negative or too large for IPv6")
204 158
205 159
206 def _find_address_range(addresses): 160 def _find_address_range(addresses):
207 """Find a sequence of IPv#Address. 161 """Find a sequence of IPv#Address.
208 162
209 Args: 163 Args:
210 addresses: a list of IPv#Address objects. 164 addresses: a list of IPv#Address objects.
ezio.melotti 2012/05/23 01:37:15 I prefer "IPv4Address or IPv6Address"
211 165
212 Returns: 166 Returns:
213 A tuple containing the first and last IP addresses in the sequence. 167 A tuple containing the first and last IP addresses in the sequence.
214 168
215 """ 169 """
216 first = last = addresses[0] 170 first = last = addresses[0]
217 for ip in addresses[1:]: 171 for ip in addresses[1:]:
218 if ip._ip == last._ip + 1: 172 if ip._ip == last._ip + 1:
219 last = ip 173 last = ip
220 else: 174 else:
221 break 175 break
222 return (first, last) 176 return (first, last)
223 177
178
224 def _get_prefix_length(number1, number2, bits): 179 def _get_prefix_length(number1, number2, bits):
225 """Get the number of leading bits that are same for two numbers. 180 """Get the number of leading bits that are same for two numbers.
226 181
227 Args: 182 Args:
228 number1: an integer. 183 number1: an integer.
229 number2: another integer. 184 number2: another integer.
230 bits: the maximum number of bits to compare. 185 bits: the maximum number of bits to compare.
231 186
232 Returns: 187 Returns:
233 The number of leading bits that are the same for two numbers. 188 The number of leading bits that are the same for two numbers.
234 189
235 """ 190 """
236 for i in range(bits): 191 for i in range(bits):
237 if number1 >> i == number2 >> i: 192 if number1 >> i == number2 >> i:
238 return bits - i 193 return bits - i
239 return 0 194 return 0
195
240 196
241 def _count_righthand_zero_bits(number, bits): 197 def _count_righthand_zero_bits(number, bits):
242 """Count the number of zero bits on the right hand side. 198 """Count the number of zero bits on the right hand side.
243 199
244 Args: 200 Args:
245 number: an integer. 201 number: an integer.
246 bits: maximum number of bits to count. 202 bits: maximum number of bits to count.
247 203
248 Returns: 204 Returns:
249 The number of zero bits on the right hand side of the number. 205 The number of zero bits on the right hand side of the number.
(...skipping 21 matching lines...) Expand all
271 227
272 Returns: 228 Returns:
273 An iterator of the summarized IPv(4|6) network objects. 229 An iterator of the summarized IPv(4|6) network objects.
274 230
275 Raise: 231 Raise:
276 TypeError: 232 TypeError:
277 If the first and last objects are not IP addresses. 233 If the first and last objects are not IP addresses.
278 If the first and last objects are not the same version. 234 If the first and last objects are not the same version.
279 ValueError: 235 ValueError:
280 If the last object is not greater than the first. 236 If the last object is not greater than the first.
281 If the version is not 4 or 6. 237 If the version of the first address is not 4 or 6.
282 238
283 """ 239 """
284 if not (isinstance(first, _BaseAddress) and isinstance(last, _BaseAddress)): 240 if (not (isinstance(first, _BaseAddress) and
241 isinstance(last, _BaseAddress))):
285 raise TypeError('first and last must be IP addresses, not networks') 242 raise TypeError('first and last must be IP addresses, not networks')
286 if first.version != last.version: 243 if first.version != last.version:
287 raise TypeError("%s and %s are not of the same version" % ( 244 raise TypeError("%s and %s are not of the same version" % (
288 str(first), str(last))) 245 str(first), str(last)))
289 if first > last: 246 if first > last:
290 raise ValueError('last IP address must be greater than first') 247 raise ValueError('last IP address must be greater than first')
291
292 networks = []
293 248
294 if first.version == 4: 249 if first.version == 4:
295 ip = IPv4Network 250 ip = IPv4Network
296 elif first.version == 6: 251 elif first.version == 6:
297 ip = IPv6Network 252 ip = IPv6Network
298 else: 253 else:
299 raise ValueError('unknown IP version') 254 raise ValueError('unknown IP version')
300 255
301 ip_bits = first._max_prefixlen 256 ip_bits = first._max_prefixlen
302 first_int = first._ip 257 first_int = first._ip
303 last_int = last._ip 258 last_int = last._ip
304 while first_int <= last_int: 259 while first_int <= last_int:
305 nbits = _count_righthand_zero_bits(first_int, ip_bits) 260 nbits = _count_righthand_zero_bits(first_int, ip_bits)
306 current = None 261 current = None
307 while nbits >= 0: 262 while nbits >= 0:
308 addend = 2**nbits - 1 263 addend = 2**nbits - 1
309 current = first_int + addend 264 current = first_int + addend
310 nbits -= 1 265 nbits -= 1
311 if current <= last_int: 266 if current <= last_int:
312 break 267 break
313 prefix = _get_prefix_length(first_int, current, ip_bits) 268 prefix = _get_prefix_length(first_int, current, ip_bits)
314 net = ip('%s/%d' % (str(first), prefix)) 269 net = ip('%s/%d' % (str(first), prefix))
315 yield net 270 yield net
316 #networks.append(net)
317 if current == ip._ALL_ONES: 271 if current == ip._ALL_ONES:
318 break 272 break
319 first_int = current + 1 273 first_int = current + 1
320 first = ip_address(first_int, version=first._version) 274 first = first.__class__(first_int)
275
321 276
322 def _collapse_addresses_recursive(addresses): 277 def _collapse_addresses_recursive(addresses):
323 """Loops through the addresses, collapsing concurrent netblocks. 278 """Loops through the addresses, collapsing concurrent netblocks.
324 279
325 Example: 280 Example:
326 281
327 ip1 = IPv4Network('192.0.2.0/26') 282 ip1 = IPv4Network('192.0.2.0/26')
328 ip2 = IPv4Network('192.0.2.64/26') 283 ip2 = IPv4Network('192.0.2.64/26')
329 ip3 = IPv4Network('192.0.2.128/26') 284 ip3 = IPv4Network('192.0.2.128/26')
330 ip4 = IPv4Network('192.0.2.192/26') 285 ip4 = IPv4Network('192.0.2.192/26')
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
399 if ips and ips[-1]._version != ip._version: 354 if ips and ips[-1]._version != ip._version:
400 raise TypeError("%s and %s are not of the same version" % ( 355 raise TypeError("%s and %s are not of the same version" % (
401 str(ip), str(ips[-1]))) 356 str(ip), str(ips[-1])))
402 try: 357 try:
403 ips.append(ip.ip) 358 ips.append(ip.ip)
404 except AttributeError: 359 except AttributeError:
405 ips.append(ip.network_address) 360 ips.append(ip.network_address)
406 else: 361 else:
407 if nets and nets[-1]._version != ip._version: 362 if nets and nets[-1]._version != ip._version:
408 raise TypeError("%s and %s are not of the same version" % ( 363 raise TypeError("%s and %s are not of the same version" % (
409 str(ip), str(ips[-1]))) 364 str(ip), str(nets[-1])))
410 nets.append(ip) 365 nets.append(ip)
411 366
412 # sort and dedup 367 # sort and dedup
413 ips = sorted(set(ips)) 368 ips = sorted(set(ips))
414 nets = sorted(set(nets)) 369 nets = sorted(set(nets))
415 370
416 while i < len(ips): 371 while i < len(ips):
417 (first, last) = _find_address_range(ips[i:]) 372 (first, last) = _find_address_range(ips[i:])
418 i = ips.index(last) + 1 373 i = ips.index(last) + 1
419 addrs.extend(summarize_address_range(first, last)) 374 addrs.extend(summarize_address_range(first, last))
(...skipping 20 matching lines...) Expand all
440 appropriate key. 395 appropriate key.
441 396
442 """ 397 """
443 if isinstance(obj, _BaseNetwork): 398 if isinstance(obj, _BaseNetwork):
444 return obj._get_networks_key() 399 return obj._get_networks_key()
445 elif isinstance(obj, _BaseAddress): 400 elif isinstance(obj, _BaseAddress):
446 return obj._get_address_key() 401 return obj._get_address_key()
447 return NotImplemented 402 return NotImplemented
448 403
449 404
450 class _IPAddressBase(object): 405 class _IPAddressBase:
451 406
452 """The mother class.""" 407 """The mother class."""
453 408
454 @property 409 @property
455 def exploded(self): 410 def exploded(self):
456 """Return the longhand version of the IP address as a string.""" 411 """Return the longhand version of the IP address as a string."""
457 return self._explode_shorthand_ip_string() 412 return self._explode_shorthand_ip_string()
458 413
459 @property 414 @property
460 def compressed(self): 415 def compressed(self):
461 """Return the shorthand version of the IP address as a string.""" 416 """Return the shorthand version of the IP address as a string."""
462 return str(self) 417 return str(self)
463 418
419 @property
420 def version(self):
421 msg = '%200s has no version specified' % (type(self),)
422 raise NotImplementedError(msg)
423
464 def _ip_int_from_prefix(self, prefixlen=None): 424 def _ip_int_from_prefix(self, prefixlen=None):
465 """Turn the prefix length netmask into a int for comparison. 425 """Turn the prefix length netmask into a int for comparison.
466 426
467 Args: 427 Args:
468 prefixlen: An integer, the prefix length. 428 prefixlen: An integer, the prefix length.
469 429
470 Returns: 430 Returns:
471 An integer. 431 An integer.
472 432
473 """ 433 """
474 if not prefixlen and prefixlen != 0: 434 if prefixlen is None:
475 prefixlen = self._prefixlen 435 prefixlen = self._prefixlen
476 return self._ALL_ONES ^ (self._ALL_ONES >> prefixlen) 436 return self._ALL_ONES ^ (self._ALL_ONES >> prefixlen)
477 437
478 def _prefix_from_ip_int(self, ip_int, mask=32): 438 def _prefix_from_ip_int(self, ip_int, mask=32):
479 """Return prefix length from the decimal netmask. 439 """Return prefix length from the decimal netmask.
480 440
481 Args: 441 Args:
482 ip_int: An integer, the IP address. 442 ip_int: An integer, the IP address.
483 mask: The netmask. Defaults to 32. 443 mask: The netmask. Defaults to 32.
484 444
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
521 def __init__(self, address): 481 def __init__(self, address):
522 if (not isinstance(address, bytes) 482 if (not isinstance(address, bytes)
523 and '/' in str(address)): 483 and '/' in str(address)):
524 raise AddressValueError(address) 484 raise AddressValueError(address)
525 485
526 def __index__(self): 486 def __index__(self):
527 return self._ip 487 return self._ip
528 488
529 def __int__(self): 489 def __int__(self):
530 return self._ip 490 return self._ip
531
532 def __hex__(self):
533 return hex(self._ip)
534 491
535 def __eq__(self, other): 492 def __eq__(self, other):
536 try: 493 try:
537 return (self._ip == other._ip 494 return (self._ip == other._ip
538 and self._version == other._version) 495 and self._version == other._version)
539 except AttributeError: 496 except AttributeError:
540 return NotImplemented 497 return NotImplemented
541 498
542 def __ne__(self, other): 499 def __ne__(self, other):
543 eq = self.__eq__(other) 500 eq = self.__eq__(other)
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
577 str(self), str(other))) 534 str(self), str(other)))
578 if self._ip != other._ip: 535 if self._ip != other._ip:
579 return self._ip > other._ip 536 return self._ip > other._ip
580 return False 537 return False
581 538
582 # Shorthand for Integer addition and subtraction. This is not 539 # Shorthand for Integer addition and subtraction. This is not
583 # meant to ever support addition/subtraction of addresses. 540 # meant to ever support addition/subtraction of addresses.
584 def __add__(self, other): 541 def __add__(self, other):
585 if not isinstance(other, int): 542 if not isinstance(other, int):
586 return NotImplemented 543 return NotImplemented
587 return ip_address(int(self) + other, version=self._version) 544 return self.__class__(int(self) + other)
588 545
589 def __sub__(self, other): 546 def __sub__(self, other):
590 if not isinstance(other, int): 547 if not isinstance(other, int):
591 return NotImplemented 548 return NotImplemented
592 return ip_address(int(self) - other, version=self._version) 549 return self.__class__(int(self) - other)
593 550
594 def __repr__(self): 551 def __repr__(self):
595 return '%s(%r)' % (self.__class__.__name__, str(self)) 552 return '%s(%r)' % (self.__class__.__name__, str(self))
596 553
597 def __str__(self): 554 def __str__(self):
598 return '%s' % self._string_from_ip_int(self._ip) 555 return str(self._string_from_ip_int(self._ip))
599 556
600 def __hash__(self): 557 def __hash__(self):
601 return hash(hex(int(self._ip))) 558 return hash(hex(int(self._ip)))
602 559
603 def _get_address_key(self): 560 def _get_address_key(self):
604 return (self._version, self) 561 return (self._version, self)
605 562
606 @property
607 def version(self):
608 raise NotImplementedError('BaseIP has no version')
609
610 563
611 class _BaseNetwork(_IPAddressBase): 564 class _BaseNetwork(_IPAddressBase):
612 565
613 """A generic IP object. 566 """A generic IP network object.
614 567
615 This IP class contains the version independent methods which are 568 This IP class contains the version independent methods which are
616 used by networks. 569 used by networks.
617 570
618 """ 571 """
619
620 def __init__(self, address): 572 def __init__(self, address):
621 self._cache = {} 573 self._cache = {}
622 574
623 def __index__(self): 575 def __index__(self):
624 return int(self.network_address) ^ self.prefixlen 576 return int(self.network_address) ^ self.prefixlen
625 577
626 def __int__(self): 578 def __int__(self):
627 return int(self.network_address) 579 return int(self.network_address)
628 580
629 def __repr__(self): 581 def __repr__(self):
630 return '%s(%r)' % (self.__class__.__name__, str(self)) 582 return '%s(%r)' % (self.__class__.__name__, str(self))
631 583
584 def __str__(self):
585 return '%s/%d' % (str(self.network_address),
586 self.prefixlen)
587
632 def hosts(self): 588 def hosts(self):
633 """Generate Iterator over usable hosts in a network. 589 """Generate Iterator over usable hosts in a network.
634 590
635 This is like __iter__ except it doesn't return the network 591 This is like __iter__ except it doesn't return the network
636 or broadcast addresses. 592 or broadcast addresses.
637 593
638 """ 594 """
639 cur = int(self.network_address) + 1 595 cur = int(self.network_address) + 1
640 bcast = int(self.broadcast_address) - 1 596 bcast = int(self.broadcast_address) - 1
641 while cur <= bcast: 597 while cur <= bcast:
642 cur += 1 598 cur += 1
643 yield ip_address(cur - 1, version=self._version) 599 yield self._address_class(cur - 1)
644 600
645 def __iter__(self): 601 def __iter__(self):
646 cur = int(self.network_address) 602 cur = int(self.network_address)
647 bcast = int(self.broadcast_address) 603 bcast = int(self.broadcast_address)
648 while cur <= bcast: 604 while cur <= bcast:
649 cur += 1 605 cur += 1
650 yield ip_address(cur - 1, version=self._version) 606 yield self._address_class(cur - 1)
651 607
652 def __getitem__(self, n): 608 def __getitem__(self, n):
653 network = int(self.network_address) 609 network = int(self.network_address)
654 broadcast = int(self.broadcast_address) 610 broadcast = int(self.broadcast_address)
655 if n >= 0: 611 if n >= 0:
656 if network + n > broadcast: 612 if network + n > broadcast:
657 raise IndexError 613 raise IndexError
658 return ip_address(network + n, version=self._version) 614 return self._address_class(network + n)
659 else: 615 else:
660 n += 1 616 n += 1
661 if broadcast + n < network: 617 if broadcast + n < network:
662 raise IndexError 618 raise IndexError
663 return ip_address(broadcast + n, version=self._version) 619 return self._address_class(broadcast + n)
664 620
665 def __lt__(self, other): 621 def __lt__(self, other):
666 if self._version != other._version: 622 if self._version != other._version:
667 raise TypeError('%s and %s are not of the same version' % ( 623 raise TypeError('%s and %s are not of the same version' % (
668 str(self), str(other))) 624 str(self), str(other)))
669 if not isinstance(other, _BaseNetwork): 625 if not isinstance(other, _BaseNetwork):
670 raise TypeError('%s and %s are not of the same type' % ( 626 raise TypeError('%s and %s are not of the same type' % (
671 str(self), str(other))) 627 str(self), str(other)))
672 if self.network_address != other.network_address: 628 if self.network_address != other.network_address:
673 return self.network_address < other.network_address 629 return self.network_address < other.network_address
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
707 return (self._version == other._version and 663 return (self._version == other._version and
708 self.network_address == other.network_address and 664 self.network_address == other.network_address and
709 int(self.netmask) == int(other.netmask)) 665 int(self.netmask) == int(other.netmask))
710 666
711 def __ne__(self, other): 667 def __ne__(self, other):
712 eq = self.__eq__(other) 668 eq = self.__eq__(other)
713 if eq is NotImplemented: 669 if eq is NotImplemented:
714 return NotImplemented 670 return NotImplemented
715 return not eq 671 return not eq
716 672
717 def __str__(self):
718 return '%s/%s' % (str(self.ip),
719 str(self._prefixlen))
720
721 def __hash__(self): 673 def __hash__(self):
722 return hash(int(self.network_address) ^ int(self.netmask)) 674 return hash(int(self.network_address) ^ int(self.netmask))
723 675
724 def __contains__(self, other): 676 def __contains__(self, other):
725 # always false if one is v4 and the other is v6. 677 # always false if one is v4 and the other is v6.
726 if self._version != other._version: 678 if self._version != other._version:
727 return False 679 return False
728 # dealing with another network. 680 # dealing with another network.
729 if isinstance(other, _BaseNetwork): 681 if isinstance(other, _BaseNetwork):
730 return False 682 return False
731 # dealing with another address 683 # dealing with another address
732 else: 684 else:
733 # address 685 # address
734 return (int(self.network_address) <= int(other._ip) <= 686 return (int(self.network_address) <= int(other._ip) <=
735 int(self.broadcast_address)) 687 int(self.broadcast_address))
736 688
737 def overlaps(self, other): 689 def overlaps(self, other):
738 """Tell if self is partly contained in other.""" 690 """Tell if self is partly contained in other."""
739 return self.network_address in other or ( 691 return self.network_address in other or (
740 self.broadcast_address in other or ( 692 self.broadcast_address in other or (
741 other.network_address in self or ( 693 other.network_address in self or (
742 other.broadcast_address in self))) 694 other.broadcast_address in self)))
743 695
744 @property 696 @property
745 def broadcast_address(self): 697 def broadcast_address(self):
746 x = self._cache.get('broadcast_address') 698 x = self._cache.get('broadcast_address')
747 if x is None: 699 if x is None:
748 x = ip_address(int(self.network_address) | int(self.hostmask), 700 x = self._address_class(int(self.network_address) |
749 version=self._version) 701 int(self.hostmask))
750 self._cache['broadcast_address'] = x 702 self._cache['broadcast_address'] = x
751 return x 703 return x
752 704
753 @property 705 @property
754 def hostmask(self): 706 def hostmask(self):
755 x = self._cache.get('hostmask') 707 x = self._cache.get('hostmask')
756 if x is None: 708 if x is None:
757 x = ip_address(int(self.netmask) ^ self._ALL_ONES, 709 x = self._address_class(int(self.netmask) ^ self._ALL_ONES)
758 version=self._version)
759 self._cache['hostmask'] = x 710 self._cache['hostmask'] = x
760 return x 711 return x
761 712
762 @property 713 @property
763 def network(self):
764 return ip_network('%s/%d' % (str(self.network_address),
765 self.prefixlen))
766
767 @property
768 def with_prefixlen(self): 714 def with_prefixlen(self):
769 return '%s/%d' % (str(self.ip), self._prefixlen) 715 return '%s/%d' % (str(self.network_address), self._prefixlen)
770 716
771 @property 717 @property
772 def with_netmask(self): 718 def with_netmask(self):
773 return '%s/%s' % (str(self.ip), str(self.netmask)) 719 return '%s/%s' % (str(self.network_address), str(self.netmask))
774 720
775 @property 721 @property
776 def with_hostmask(self): 722 def with_hostmask(self):
777 return '%s/%s' % (str(self.ip), str(self.hostmask)) 723 return '%s/%s' % (str(self.network_address), str(self.hostmask))
778 724
779 @property 725 @property
780 def num_addresses(self): 726 def num_addresses(self):
781 """Number of hosts in the current subnet.""" 727 """Number of hosts in the current subnet."""
782 return int(self.broadcast_address) - int(self.network_address) + 1 728 return int(self.broadcast_address) - int(self.network_address) + 1
783 729
784 @property 730 @property
785 def version(self): 731 def _address_class(self):
786 raise NotImplementedError('BaseNet has no version') 732 # Returning bare address objects (rather than interfaces) allows for
733 # more consistent behaviour across the network address, broadcast
734 # address and individual host addresses.
735 msg = '%200s has no associated address class' % (type(self),)
736 raise NotImplementedError(msg)
787 737
788 @property 738 @property
789 def prefixlen(self): 739 def prefixlen(self):
790 return self._prefixlen 740 return self._prefixlen
791 741
792 def address_exclude(self, other): 742 def address_exclude(self, other):
793 """Remove an address from a larger block. 743 """Remove an address from a larger block.
794 744
795 For example: 745 For example:
796 746
(...skipping 30 matching lines...) Expand all
827 """ 777 """
828 if not self._version == other._version: 778 if not self._version == other._version:
829 raise TypeError("%s and %s are not of the same version" % ( 779 raise TypeError("%s and %s are not of the same version" % (
830 str(self), str(other))) 780 str(self), str(other)))
831 781
832 if not isinstance(other, _BaseNetwork): 782 if not isinstance(other, _BaseNetwork):
833 raise TypeError("%s is not a network object" % str(other)) 783 raise TypeError("%s is not a network object" % str(other))
834 784
835 if not (other.network_address >= self.network_address and 785 if not (other.network_address >= self.network_address and
836 other.broadcast_address <= self.broadcast_address): 786 other.broadcast_address <= self.broadcast_address):
837 raise ValueError('%s not contained in %s' % (str(other), str(self))) 787 raise ValueError('%s not contained in %s' % (other, self))
838
839 if other == self: 788 if other == self:
840 raise StopIteration 789 raise StopIteration
841 790
842 ret_addrs = []
843
844 # Make sure we're comparing the network of other. 791 # Make sure we're comparing the network of other.
845 other = ip_network('%s/%s' % (str(other.network_address), 792 other = other.__class__('%s/%s' % (str(other.network_address),
846 str(other.prefixlen)), 793 str(other.prefixlen)))
847 version=other._version)
848 794
849 s1, s2 = self.subnets() 795 s1, s2 = self.subnets()
850 while s1 != other and s2 != other: 796 while s1 != other and s2 != other:
851 if (other.network_address >= s1.network_address and 797 if (other.network_address >= s1.network_address and
852 other.broadcast_address <= s1.broadcast_address): 798 other.broadcast_address <= s1.broadcast_address):
853 yield s2 799 yield s2
854 s1, s2 = s1.subnets() 800 s1, s2 = s1.subnets()
855 elif (other.network_address >= s2.network_address and 801 elif (other.network_address >= s2.network_address and
856 other.broadcast_address <= s2.broadcast_address): 802 other.broadcast_address <= s2.broadcast_address):
857 yield s1 803 yield s1
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
968 914
969 if prefixlen_diff < 0: 915 if prefixlen_diff < 0:
970 raise ValueError('prefix length diff must be > 0') 916 raise ValueError('prefix length diff must be > 0')
971 new_prefixlen = self._prefixlen + prefixlen_diff 917 new_prefixlen = self._prefixlen + prefixlen_diff
972 918
973 if not self._is_valid_netmask(str(new_prefixlen)): 919 if not self._is_valid_netmask(str(new_prefixlen)):
974 raise ValueError( 920 raise ValueError(
975 'prefix length diff %d is invalid for netblock %s' % ( 921 'prefix length diff %d is invalid for netblock %s' % (
976 new_prefixlen, str(self))) 922 new_prefixlen, str(self)))
977 923
978 first = ip_network('%s/%s' % (str(self.network_address), 924 first = self.__class__('%s/%s' %
979 str(self._prefixlen + prefixlen_diff)), 925 (str(self.network_address),
980 version=self._version) 926 str(self._prefixlen + prefixlen_diff)))
981 927
982 yield first 928 yield first
983 current = first 929 current = first
984 while True: 930 while True:
985 broadcast = current.broadcast_address 931 broadcast = current.broadcast_address
986 if broadcast == self.broadcast_address: 932 if broadcast == self.broadcast_address:
987 return 933 return
988 new_addr = ip_address(int(broadcast) + 1, version=self._version) 934 new_addr = self._address_class(int(broadcast) + 1)
989 current = ip_network('%s/%s' % (str(new_addr), str(new_prefixlen)), 935 current = self.__class__('%s/%s' % (str(new_addr),
990 version=self._version) 936 str(new_prefixlen)))
991 937
992 yield current 938 yield current
993
994 def masked(self):
995 """Return the network object with the host bits masked out."""
996 return ip_network('%s/%d' % (self.network_address, self._prefixlen),
997 version=self._version)
998 939
999 def supernet(self, prefixlen_diff=1, new_prefix=None): 940 def supernet(self, prefixlen_diff=1, new_prefix=None):
1000 """The supernet containing the current network. 941 """The supernet containing the current network.
1001 942
1002 Args: 943 Args:
1003 prefixlen_diff: An integer, the amount the prefix length of 944 prefixlen_diff: An integer, the amount the prefix length of
1004 the network should be decreased by. For example, given a 945 the network should be decreased by. For example, given a
1005 /24 network and a prefixlen_diff of 3, a supernet with a 946 /24 network and a prefixlen_diff of 3, a supernet with a
1006 /21 netmask is returned. 947 /21 netmask is returned.
1007 948
1008 Returns: 949 Returns:
1009 An IPv4 network object. 950 An IPv4 network object.
1010 951
1011 Raises: 952 Raises:
1012 ValueError: If self.prefixlen - prefixlen_diff < 0. I.e., you have a 953 ValueError: If self.prefixlen - prefixlen_diff < 0. I.e., you have
1013 negative prefix length. 954 a negative prefix length.
1014 OR 955 OR
1015 If prefixlen_diff and new_prefix are both set or new_prefix is a 956 If prefixlen_diff and new_prefix are both set or new_prefix is a
1016 larger number than the current prefix (larger number means a 957 larger number than the current prefix (larger number means a
1017 smaller network) 958 smaller network)
1018 959
1019 """ 960 """
1020 if self._prefixlen == 0: 961 if self._prefixlen == 0:
1021 return self 962 return self
1022 963
1023 if new_prefix is not None: 964 if new_prefix is not None:
1024 if new_prefix > self._prefixlen: 965 if new_prefix > self._prefixlen:
1025 raise ValueError('new prefix must be shorter') 966 raise ValueError('new prefix must be shorter')
1026 if prefixlen_diff != 1: 967 if prefixlen_diff != 1:
1027 raise ValueError('cannot set prefixlen_diff and new_prefix') 968 raise ValueError('cannot set prefixlen_diff and new_prefix')
1028 prefixlen_diff = self._prefixlen - new_prefix 969 prefixlen_diff = self._prefixlen - new_prefix
1029 970
1030
1031 if self.prefixlen - prefixlen_diff < 0: 971 if self.prefixlen - prefixlen_diff < 0:
1032 raise ValueError( 972 raise ValueError(
1033 'current prefixlen is %d, cannot have a prefixlen_diff of %d' % 973 'current prefixlen is %d, cannot have a prefixlen_diff of %d' %
1034 (self.prefixlen, prefixlen_diff)) 974 (self.prefixlen, prefixlen_diff))
1035 # TODO (pmoody): optimize this. 975 # TODO (pmoody): optimize this.
1036 t = ip_network('%s/%d' % (str(self.network_address), 976 t = self.__class__('%s/%d' % (str(self.network_address),
1037 self.prefixlen - prefixlen_diff), 977 self.prefixlen - prefixlen_diff),
1038 version=self._version, strict=False) 978 strict=False)
1039 return ip_network('%s/%d' % (str(t.network_address), t.prefixlen), 979 return t.__class__('%s/%d' % (str(t.network_address), t.prefixlen))
1040 version=t._version) 980
1041 981
1042 982 class _BaseV4:
1043 class _BaseV4(object):
1044 983
1045 """Base IPv4 object. 984 """Base IPv4 object.
1046 985
1047 The following methods are used by IPv4 objects in both single IP 986 The following methods are used by IPv4 objects in both single IP
1048 addresses and networks. 987 addresses and networks.
1049 988
1050 """ 989 """
1051 990
1052 # Equivalent to 255.255.255.255 or 32 bits of 1's. 991 # Equivalent to 255.255.255.255 or 32 bits of 1's.
1053 _ALL_ONES = (2**IPV4LENGTH) - 1 992 _ALL_ONES = (2**IPV4LENGTH) - 1
1054 _DECIMAL_DIGITS = frozenset('0123456789') 993 _DECIMAL_DIGITS = frozenset('0123456789')
994
995 # the valid octets for host and netmasks. only useful for IPv4.
996 _valid_mask_octets = set((255, 254, 252, 248, 240, 224, 192, 128, 0))
1055 997
1056 def __init__(self, address): 998 def __init__(self, address):
1057 self._version = 4 999 self._version = 4
1058 self._max_prefixlen = IPV4LENGTH 1000 self._max_prefixlen = IPV4LENGTH
1059 1001
1060 def _explode_shorthand_ip_string(self): 1002 def _explode_shorthand_ip_string(self):
1061 return str(self) 1003 return str(self)
1062 1004
1063 def _ip_int_from_string(self, ip_str): 1005 def _ip_int_from_string(self, ip_str):
1064 """Turn the given IP string into an integer for comparison. 1006 """Turn the given IP string into an integer for comparison.
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1116 1058
1117 Returns: 1059 Returns:
1118 The IP address as a string in dotted decimal notation. 1060 The IP address as a string in dotted decimal notation.
1119 1061
1120 """ 1062 """
1121 octets = [] 1063 octets = []
1122 for _ in range(4): 1064 for _ in range(4):
1123 octets.insert(0, str(ip_int & 0xFF)) 1065 octets.insert(0, str(ip_int & 0xFF))
1124 ip_int >>= 8 1066 ip_int >>= 8
1125 return '.'.join(octets) 1067 return '.'.join(octets)
1068
1069 def _is_valid_netmask(self, netmask):
1070 """Verify that the netmask is valid.
1071
1072 Args:
1073 netmask: A string, either a prefix or dotted decimal
1074 netmask.
1075
1076 Returns:
1077 A boolean, True if the prefix represents a valid IPv4
1078 netmask.
1079
1080 """
1081 mask = netmask.split('.')
1082 if len(mask) == 4:
1083 if [x for x in mask if int(x) not in self._valid_mask_octets]:
1084 return False
1085 if [y for idx, y in enumerate(mask) if idx > 0 and
1086 y > mask[idx - 1]]:
1087 return False
1088 return True
1089 try:
1090 netmask = int(netmask)
1091 except ValueError:
1092 return False
1093 return 0 <= netmask <= self._max_prefixlen
1094
1095 def _is_hostmask(self, ip_str):
1096 """Test if the IP string is a hostmask (rather than a netmask).
1097
1098 Args:
1099 ip_str: A string, the potential hostmask.
1100
1101 Returns:
1102 A boolean, True if the IP string is a hostmask.
1103
1104 """
1105 bits = ip_str.split('.')
1106 try:
1107 parts = [int(x) for x in bits if int(x) in self._valid_mask_octets]
1108 except ValueError:
1109 return False
1110 if len(parts) != len(bits):
1111 return False
1112 if parts[0] < parts[-1]:
1113 return True
1114 return False
1126 1115
1127 @property 1116 @property
1128 def max_prefixlen(self): 1117 def max_prefixlen(self):
1129 return self._max_prefixlen 1118 return self._max_prefixlen
1130 1119
1131 @property 1120 @property
1132 def version(self): 1121 def version(self):
1133 return self._version 1122 return self._version
1134 1123
1135 @property 1124 @property
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1188 def is_unspecified(self): 1177 def is_unspecified(self):
1189 """Test if the address is unspecified. 1178 """Test if the address is unspecified.
1190 1179
1191 Returns: 1180 Returns:
1192 A boolean, True if this is the unspecified address as defined in 1181 A boolean, True if this is the unspecified address as defined in
1193 RFC 5735 3. 1182 RFC 5735 3.
1194 1183
1195 """ 1184 """
1196 unspecified_address = IPv4Address('0.0.0.0') 1185 unspecified_address = IPv4Address('0.0.0.0')
1197 if isinstance(self, _BaseAddress): 1186 if isinstance(self, _BaseAddress):
1198 return self in unspecified_address 1187 return self == unspecified_address
1199 return (self.network_address == self.broadcast_address == 1188 return (self.network_address == self.broadcast_address ==
1200 unspecified_address) 1189 unspecified_address)
1201 1190
1202 @property 1191 @property
1203 def is_loopback(self): 1192 def is_loopback(self):
1204 """Test if the address is a loopback address. 1193 """Test if the address is a loopback address.
1205 1194
1206 Returns: 1195 Returns:
1207 A boolean, True if the address is a loopback per RFC 3330. 1196 A boolean, True if the address is a loopback per RFC 3330.
1208 1197
(...skipping 30 matching lines...) Expand all
1239 Args: 1228 Args:
1240 address: A string or integer representing the IP 1229 address: A string or integer representing the IP
1241 1230
1242 Additionally, an integer can be passed, so 1231 Additionally, an integer can be passed, so
1243 IPv4Address('192.0.2.1') == IPv4Address(3221225985). 1232 IPv4Address('192.0.2.1') == IPv4Address(3221225985).
1244 or, more generally 1233 or, more generally
1245 IPv4Address(int(IPv4Address('192.0.2.1'))) == 1234 IPv4Address(int(IPv4Address('192.0.2.1'))) ==
1246 IPv4Address('192.0.2.1') 1235 IPv4Address('192.0.2.1')
1247 1236
1248 Raises: 1237 Raises:
1249 AddressValueError: If ipaddressisn't a valid IPv4 address. 1238 AddressValueError: If ipaddress isn't a valid IPv4 address.
1250 1239
1251 """ 1240 """
1252 _BaseAddress.__init__(self, address) 1241 _BaseAddress.__init__(self, address)
1253 _BaseV4.__init__(self, address) 1242 _BaseV4.__init__(self, address)
1254 1243
1255 # Efficient constructor from integer. 1244 # Efficient constructor from integer.
1256 if isinstance(address, int): 1245 if isinstance(address, int):
1257 self._ip = address 1246 self._ip = address
1258 if address < 0 or address > self._ALL_ONES: 1247 if address < 0 or address > self._ALL_ONES:
1259 raise AddressValueError(address) 1248 raise AddressValueError(address)
1260 return 1249 return
1261 1250
1262 # Constructing from a packed address 1251 # Constructing from a packed address
1263 if isinstance(address, bytes) and len(address) == 4: 1252 if (not isinstance(address, str) and
1253 isinstance(address, bytes) and len(address) == 4):
1264 self._ip = struct.unpack('!I', address)[0] 1254 self._ip = struct.unpack('!I', address)[0]
1265 return 1255 return
1266 1256
1267 # Assume input argument to be string or any object representation 1257 # Assume input argument to be string or any object representation
1268 # which converts into a formatted IP string. 1258 # which converts into a formatted IP string.
1269 addr_str = str(address) 1259 addr_str = str(address)
1270 self._ip = self._ip_int_from_string(addr_str) 1260 self._ip = self._ip_int_from_string(addr_str)
1271 1261
1272 @property 1262 @property
1273 def packed(self): 1263 def packed(self):
1274 """The binary representation of this address.""" 1264 """The binary representation of this address."""
1275 return v4_int_to_packed(self._ip) 1265 return v4_int_to_packed(self._ip)
1276 1266
1277 1267
1278 class IPv4Interface(IPv4Address): 1268 class IPv4Interface(IPv4Address):
1279
1280 # the valid octets for host and netmasks. only useful for IPv4.
1281 _valid_mask_octets = set((255, 254, 252, 248, 240, 224, 192, 128, 0))
1282 1269
1283 def __init__(self, address): 1270 def __init__(self, address):
1284 if isinstance(address, (bytes, int)): 1271 if isinstance(address, (bytes, int)):
1285 IPv4Address.__init__(self, address) 1272 IPv4Address.__init__(self, address)
1286 self.network = IPv4Network(self._ip) 1273 self.network = IPv4Network(self._ip)
1287 self._prefixlen = self._max_prefixlen 1274 self._prefixlen = self._max_prefixlen
1288 return 1275 return
1289 1276
1290 addr = str(address).split('/') 1277 addr = str(address).split('/')
1291 if len(addr) > 2: 1278 if len(addr) > 2:
1292 raise AddressValueError(address) 1279 raise AddressValueError(address)
1293 IPv4Address.__init__(self, addr[0]) 1280 IPv4Address.__init__(self, addr[0])
1294 1281
1295 self.network = IPv4Network(address, strict=False) 1282 self.network = IPv4Network(address, strict=False)
1296 self._prefixlen = self.network._prefixlen 1283 self._prefixlen = self.network._prefixlen
1297 1284
1298 self.netmask = self.network.netmask 1285 self.netmask = self.network.netmask
1299 self.hostmask = self.network.hostmask 1286 self.hostmask = self.network.hostmask
1300 1287
1301
1302 def __str__(self): 1288 def __str__(self):
1303 return '%s/%d' % (self._string_from_ip_int(self._ip), 1289 return '%s/%d' % (self._string_from_ip_int(self._ip),
1304 self.network.prefixlen) 1290 self.network.prefixlen)
1305 1291
1306 def __eq__(self, other): 1292 def __eq__(self, other):
1307 try: 1293 try:
1308 return (IPv4Address.__eq__(self, other) and 1294 return (IPv4Address.__eq__(self, other) and
1309 self.network == other.network) 1295 self.network == other.network)
1310 except AttributeError: 1296 except AttributeError:
1311 return NotImplemented 1297 return NotImplemented
1312 1298
1313 def __hash__(self): 1299 def __hash__(self):
1314 return self._ip ^ self._prefixlen ^ int(self.network.network_address) 1300 return self._ip ^ self._prefixlen ^ int(self.network.network_address)
1315 1301
1316 def _is_valid_netmask(self, netmask):
1317 """Verify that the netmask is valid.
1318
1319 Args:
1320 netmask: A string, either a prefix or dotted decimal
1321 netmask.
1322
1323 Returns:
1324 A boolean, True if the prefix represents a valid IPv4
1325 netmask.
1326
1327 """
1328 mask = netmask.split('.')
1329 if len(mask) == 4:
1330 if [x for x in mask if int(x) not in self._valid_mask_octets]:
1331 return False
1332 if [y for idx, y in enumerate(mask) if idx > 0 and
1333 y > mask[idx - 1]]:
1334 return False
1335 return True
1336 try:
1337 netmask = int(netmask)
1338 except ValueError:
1339 return False
1340 return 0 <= netmask <= self._max_prefixlen
1341
1342 def _is_hostmask(self, ip_str):
1343 """Test if the IP string is a hostmask (rather than a netmask).
1344
1345 Args:
1346 ip_str: A string, the potential hostmask.
1347
1348 Returns:
1349 A boolean, True if the IP string is a hostmask.
1350
1351 """
1352 bits = ip_str.split('.')
1353 try:
1354 parts = [int(x) for x in bits if int(x) in self._valid_mask_octets]
1355 except ValueError:
1356 return False
1357 if len(parts) != len(bits):
1358 return False
1359 if parts[0] < parts[-1]:
1360 return True
1361 return False
1362
1363
1364 @property 1302 @property
1365 def prefixlen(self): 1303 def prefixlen(self):
1366 return self._prefixlen 1304 return self._prefixlen
1367 1305
1368 @property 1306 @property
1369 def ip(self): 1307 def ip(self):
1370 return IPv4Address(self._ip) 1308 return IPv4Address(self._ip)
1371 1309
1372 @property 1310 @property
1373 def with_prefixlen(self): 1311 def with_prefixlen(self):
1374 return self 1312 return self
1375 1313
1376 @property 1314 @property
1377 def with_netmask(self): 1315 def with_netmask(self):
1378 return '%s/%s' % (self._string_from_ip_int(self._ip), 1316 return '%s/%s' % (self._string_from_ip_int(self._ip),
1379 self.netmask) 1317 self.netmask)
1318
1380 @property 1319 @property
1381 def with_hostmask(self): 1320 def with_hostmask(self):
1382 return '%s/%s' % (self._string_from_ip_int(self._ip), 1321 return '%s/%s' % (self._string_from_ip_int(self._ip),
1383 self.hostmask) 1322 self.hostmask)
1384 1323
1385 1324
1386 class IPv4Network(_BaseV4, _BaseNetwork): 1325 class IPv4Network(_BaseV4, _BaseNetwork):
1387 1326
1388 """This class represents and manipulates 32-bit IPv4 network + addresses.. 1327 """This class represents and manipulates 32-bit IPv4 network + addresses..
1389 1328
1390 Attributes: [examples for IPv4Network('192.0.2.0/27')] 1329 Attributes: [examples for IPv4Network('192.0.2.0/27')]
1391 .network_address: IPv4Address('192.0.2.0') 1330 .network_address: IPv4Address('192.0.2.0')
1392 .hostmask: IPv4Address('0.0.0.31') 1331 .hostmask: IPv4Address('0.0.0.31')
1393 .broadcast_address: IPv4Address('192.0.2.32') 1332 .broadcast_address: IPv4Address('192.0.2.32')
1394 .netmask: IPv4Address('255.255.255.224') 1333 .netmask: IPv4Address('255.255.255.224')
1395 .prefixlen: 27 1334 .prefixlen: 27
1396 1335
1397 """ 1336 """
1398 1337 # Class to use when creating address objects
1399 # the valid octets for host and netmasks. only useful for IPv4. 1338 _address_class = IPv4Address
1400 _valid_mask_octets = set((255, 254, 252, 248, 240, 224, 192, 128, 0))
1401 1339
1402 def __init__(self, address, strict=True): 1340 def __init__(self, address, strict=True):
1403 1341
1404 """Instantiate a new IPv4 network object. 1342 """Instantiate a new IPv4 network object.
1405 1343
1406 Args: 1344 Args:
1407 address: A string or integer representing the IP [& network]. 1345 address: A string or integer representing the IP [& network].
1408 '192.0.2.0/24' 1346 '192.0.2.0/24'
1409 '192.0.2.0/255.255.255.0' 1347 '192.0.2.0/255.255.255.0'
1410 '192.0.0.2/0.0.0.255' 1348 '192.0.0.2/0.0.0.255'
(...skipping 11 matching lines...) Expand all
1422 single exception of an all-zero mask which is treated as a 1360 single exception of an all-zero mask which is treated as a
1423 netmask == /0. If no mask is given, a default of /32 is used. 1361 netmask == /0. If no mask is given, a default of /32 is used.
1424 1362
1425 Additionally, an integer can be passed, so 1363 Additionally, an integer can be passed, so
1426 IPv4Network('192.0.2.1') == IPv4Network(3221225985) 1364 IPv4Network('192.0.2.1') == IPv4Network(3221225985)
1427 or, more generally 1365 or, more generally
1428 IPv4Interface(int(IPv4Interface('192.0.2.1'))) == 1366 IPv4Interface(int(IPv4Interface('192.0.2.1'))) ==
1429 IPv4Interface('192.0.2.1') 1367 IPv4Interface('192.0.2.1')
1430 1368
1431 Raises: 1369 Raises:
1432 AddressValueError: If ipaddressisn't a valid IPv4 address. 1370 AddressValueError: If ipaddress isn't a valid IPv4 address.
1433 NetmaskValueError: If the netmask isn't valid for 1371 NetmaskValueError: If the netmask isn't valid for
1434 an IPv4 address. 1372 an IPv4 address.
1435 ValueError: If strict was True and a network address was not 1373 ValueError: If strict is True and a network address is not
1436 supplied. 1374 supplied.
1437 1375
1438 """ 1376 """
1439 1377
1440 _BaseV4.__init__(self, address) 1378 _BaseV4.__init__(self, address)
1441 _BaseNetwork.__init__(self, address) 1379 _BaseNetwork.__init__(self, address)
1442 1380
1443 # Constructing from a packed address 1381 # Constructing from a packed address
1444 if isinstance(address, bytes) and len(address) == 4: 1382 if isinstance(address, bytes) and len(address) == 4:
1445 self.network_address = IPv4Address( 1383 self.network_address = IPv4Address(
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1498 if strict: 1436 if strict:
1499 if (IPv4Address(int(self.network_address) & int(self.netmask)) != 1437 if (IPv4Address(int(self.network_address) & int(self.netmask)) !=
1500 self.network_address): 1438 self.network_address):
1501 raise ValueError('%s has host bits set' % self) 1439 raise ValueError('%s has host bits set' % self)
1502 self.network_address = IPv4Address(int(self.network_address) & 1440 self.network_address = IPv4Address(int(self.network_address) &
1503 int(self.netmask)) 1441 int(self.netmask))
1504 1442
1505 if self._prefixlen == (self._max_prefixlen - 1): 1443 if self._prefixlen == (self._max_prefixlen - 1):
1506 self.hosts = self.__iter__ 1444 self.hosts = self.__iter__
1507 1445
1508 @property 1446
1509 def packed(self): 1447 class _BaseV6:
1510 """The binary representation of this address."""
1511 return v4_int_to_packed(self.network_address)
1512
1513 def __str__(self):
1514 return '%s/%d' % (str(self.network_address),
1515 self.prefixlen)
1516
1517 def _is_valid_netmask(self, netmask):
1518 """Verify that the netmask is valid.
1519
1520 Args:
1521 netmask: A string, either a prefix or dotted decimal
1522 netmask.
1523
1524 Returns:
1525 A boolean, True if the prefix represents a valid IPv4
1526 netmask.
1527
1528 """
1529 mask = netmask.split('.')
1530 if len(mask) == 4:
1531 if [x for x in mask if int(x) not in self._valid_mask_octets]:
1532 return False
1533 if [y for idx, y in enumerate(mask) if idx > 0 and
1534 y > mask[idx - 1]]:
1535 return False
1536 return True
1537 try:
1538 netmask = int(netmask)
1539 except ValueError:
1540 return False
1541 return 0 <= netmask <= self._max_prefixlen
1542
1543 def _is_hostmask(self, ip_str):
1544 """Test if the IP string is a hostmask (rather than a netmask).
1545
1546 Args:
1547 ip_str: A string, the potential hostmask.
1548
1549 Returns:
1550 A boolean, True if the IP string is a hostmask.
1551
1552 """
1553 bits = ip_str.split('.')
1554 try:
1555 parts = [int(x) for x in bits if int(x) in self._valid_mask_octets]
1556 except ValueError:
1557 return False
1558 if len(parts) != len(bits):
1559 return False
1560 if parts[0] < parts[-1]:
1561 return True
1562 return False
1563
1564 @property
1565 def with_prefixlen(self):
1566 return '%s/%d' % (str(self.network_address), self._prefixlen)
1567
1568 @property
1569 def with_netmask(self):
1570 return '%s/%s' % (str(self.network_address), str(self.netmask))
1571
1572 @property
1573 def with_hostmask(self):
1574 return '%s/%s' % (str(self.network_address), str(self.hostmask))
1575
1576
1577 class _BaseV6(object):
1578 1448
1579 """Base IPv6 object. 1449 """Base IPv6 object.
1580 1450
1581 The following methods are used by IPv6 objects in both single IP 1451 The following methods are used by IPv6 objects in both single IP
1582 addresses and networks. 1452 addresses and networks.
1583 1453
1584 """ 1454 """
1585 1455
1586 _ALL_ONES = (2**IPV6LENGTH) - 1 1456 _ALL_ONES = (2**IPV6LENGTH) - 1
1587 _HEXTET_COUNT = 8 1457 _HEXTET_COUNT = 8
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1641 if parts_hi: 1511 if parts_hi:
1642 raise AddressValueError(ip_str) # ^: requires ^:: 1512 raise AddressValueError(ip_str) # ^: requires ^::
1643 if not parts[-1]: 1513 if not parts[-1]:
1644 parts_lo -= 1 1514 parts_lo -= 1
1645 if parts_lo: 1515 if parts_lo:
1646 raise AddressValueError(ip_str) # :$ requires ::$ 1516 raise AddressValueError(ip_str) # :$ requires ::$
1647 parts_skipped = self._HEXTET_COUNT - (parts_hi + parts_lo) 1517 parts_skipped = self._HEXTET_COUNT - (parts_hi + parts_lo)
1648 if parts_skipped < 1: 1518 if parts_skipped < 1:
1649 raise AddressValueError(ip_str) 1519 raise AddressValueError(ip_str)
1650 else: 1520 else:
1651 # Otherwise, allocate the entire address to parts_hi. The endpoints 1521 # Otherwise, allocate the entire address to parts_hi. The
1652 # could still be empty, but _parse_hextet() will check for that. 1522 # endpoints could still be empty, but _parse_hextet() will check
1523 # for that.
1653 if len(parts) != self._HEXTET_COUNT: 1524 if len(parts) != self._HEXTET_COUNT:
1654 raise AddressValueError(ip_str) 1525 raise AddressValueError(ip_str)
1655 parts_hi = len(parts) 1526 parts_hi = len(parts)
1656 parts_lo = 0 1527 parts_lo = 0
1657 parts_skipped = 0 1528 parts_skipped = 0
1658 1529
1659 try: 1530 try:
1660 # Now, parse the hextets into a 128-bit integer. 1531 # Now, parse the hextets into a 128-bit integer.
1661 ip_int = 0 1532 ip_int = 0
1662 for i in range(parts_hi): 1533 for i in range(parts_hi):
(...skipping 10 matching lines...) Expand all
1673 def _parse_hextet(self, hextet_str): 1544 def _parse_hextet(self, hextet_str):
1674 """Convert an IPv6 hextet string into an integer. 1545 """Convert an IPv6 hextet string into an integer.
1675 1546
1676 Args: 1547 Args:
1677 hextet_str: A string, the number to parse. 1548 hextet_str: A string, the number to parse.
1678 1549
1679 Returns: 1550 Returns:
1680 The hextet as an integer. 1551 The hextet as an integer.
1681 1552
1682 Raises: 1553 Raises:
1683 ValueError: if the input isn't strictly a hex number from [0..FFFF]. 1554 ValueError: if the input isn't strictly a hex number from
1555 [0..FFFF].
1684 1556
1685 """ 1557 """
1686 # Whitelist the characters, since int() allows a lot of bizarre stuff. 1558 # Whitelist the characters, since int() allows a lot of bizarre stuff.
1687 if not self._HEX_DIGITS.issuperset(hextet_str): 1559 if not self._HEX_DIGITS.issuperset(hextet_str):
1560 raise ValueError
1561 if len(hextet_str) > 4:
1688 raise ValueError 1562 raise ValueError
1689 hextet_int = int(hextet_str, 16) 1563 hextet_int = int(hextet_str, 16)
1690 if hextet_int > 0xFFFF: 1564 if hextet_int > 0xFFFF:
1691 raise ValueError 1565 raise ValueError
1692 return hextet_int 1566 return hextet_int
1693 1567
1694 def _compress_hextets(self, hextets): 1568 def _compress_hextets(self, hextets):
1695 """Compresses a list of hextets. 1569 """Compresses a list of hextets.
1696 1570
1697 Compresses a list of strings, replacing the longest continuous 1571 Compresses a list of strings, replacing the longest continuous
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1744 Args: 1618 Args:
1745 ip_int: An integer, the IP address. 1619 ip_int: An integer, the IP address.
1746 1620
1747 Returns: 1621 Returns:
1748 A string, the hexadecimal representation of the address. 1622 A string, the hexadecimal representation of the address.
1749 1623
1750 Raises: 1624 Raises:
1751 ValueError: The address is bigger than 128 bits of all ones. 1625 ValueError: The address is bigger than 128 bits of all ones.
1752 1626
1753 """ 1627 """
1754 if not ip_int and ip_int != 0: 1628 if ip_int is None:
1755 ip_int = int(self._ip) 1629 ip_int = int(self._ip)
1756 1630
1757 if ip_int > self._ALL_ONES: 1631 if ip_int > self._ALL_ONES:
1758 raise ValueError('IPv6 address is too large') 1632 raise ValueError('IPv6 address is too large')
1759 1633
1760 hex_str = '%032x' % ip_int 1634 hex_str = '%032x' % ip_int
1761 hextets = [] 1635 hextets = []
1762 for x in range(0, 32, 4): 1636 for x in range(0, 32, 4):
1763 hextets.append('%x' % int(hex_str[x:x+4], 16)) 1637 hextets.append('%x' % int(hex_str[x:x+4], 16))
1764 1638
(...skipping 25 matching lines...) Expand all
1790 parts.reverse() 1664 parts.reverse()
1791 if isinstance(self, (_BaseNetwork, IPv6Interface)): 1665 if isinstance(self, (_BaseNetwork, IPv6Interface)):
1792 return '%s/%d' % (':'.join(parts), self.prefixlen) 1666 return '%s/%d' % (':'.join(parts), self.prefixlen)
1793 return ':'.join(parts) 1667 return ':'.join(parts)
1794 1668
1795 @property 1669 @property
1796 def max_prefixlen(self): 1670 def max_prefixlen(self):
1797 return self._max_prefixlen 1671 return self._max_prefixlen
1798 1672
1799 @property 1673 @property
1800 def packed(self):
1801 """The binary representation of this address."""
1802 return v6_int_to_packed(self._ip)
1803
1804 @property
1805 def version(self): 1674 def version(self):
1806 return self._version 1675 return self._version
1807 1676
1808 @property 1677 @property
1809 def is_multicast(self): 1678 def is_multicast(self):
1810 """Test if the address is reserved for multicast use. 1679 """Test if the address is reserved for multicast use.
1811 1680
1812 Returns: 1681 Returns:
1813 A boolean, True if the address is a multicast address. 1682 A boolean, True if the address is a multicast address.
1814 See RFC 2373 2.7 for details. 1683 See RFC 2373 2.7 for details.
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1882 Returns: 1751 Returns:
1883 A boolean, True if the address is reserved per RFC 4193. 1752 A boolean, True if the address is reserved per RFC 4193.
1884 1753
1885 """ 1754 """
1886 private_network = IPv6Network('fc00::/7') 1755 private_network = IPv6Network('fc00::/7')
1887 if isinstance(self, _BaseAddress): 1756 if isinstance(self, _BaseAddress):
1888 return self in private_network 1757 return self in private_network
1889 return (self.network_address in private_network and 1758 return (self.network_address in private_network and
1890 self.broadcast_address in private_network) 1759 self.broadcast_address in private_network)
1891 1760
1892
1893 @property 1761 @property
1894 def ipv4_mapped(self): 1762 def ipv4_mapped(self):
1895 """Return the IPv4 mapped address. 1763 """Return the IPv4 mapped address.
1896 1764
1897 Returns: 1765 Returns:
1898 If the IPv6 address is a v4 mapped address, return the 1766 If the IPv6 address is a v4 mapped address, return the
1899 IPv4 mapped address. Return None otherwise. 1767 IPv4 mapped address. Return None otherwise.
1900 1768
1901 """ 1769 """
1902 if (self._ip >> 32) != 0xFFFF: 1770 if (self._ip >> 32) != 0xFFFF:
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1948 @property 1816 @property
1949 def is_loopback(self): 1817 def is_loopback(self):
1950 """Test if the address is a loopback address. 1818 """Test if the address is a loopback address.
1951 1819
1952 Returns: 1820 Returns:
1953 A boolean, True if the address is a loopback address as defined in 1821 A boolean, True if the address is a loopback address as defined in
1954 RFC 2373 2.5.3. 1822 RFC 2373 2.5.3.
1955 1823
1956 """ 1824 """
1957 if isinstance(self, IPv6Network): 1825 if isinstance(self, IPv6Network):
1958 return int(self.network) == 1 and getattr( 1826 return int(self) == 1 and getattr(
1959 self, '_prefixlen', 128) == 128 1827 self, '_prefixlen', 128) == 128
1960 elif isinstance(self, IPv6Interface): 1828 elif isinstance(self, IPv6Interface):
1961 return int(self.network.network_address) == 1 and getattr( 1829 return int(self.network.network_address) == 1 and getattr(
1962 self, '_prefixlen', 128) == 128 1830 self, '_prefixlen', 128) == 128
1963 return self._ip == 1 1831 return self._ip == 1
1964 1832
1965 1833
1966 class IPv6Address(_BaseV6, _BaseAddress): 1834 class IPv6Address(_BaseV6, _BaseAddress):
1967 1835
1968 """Represent and manipulate single IPv6 Addresses. 1836 """Represent and manipulate single IPv6 Addresses."""
1969 """
1970 1837
1971 def __init__(self, address): 1838 def __init__(self, address):
1972 """Instantiate a new IPv6 address object. 1839 """Instantiate a new IPv6 address object.
1973 1840
1974 Args: 1841 Args:
1975 address: A string or integer representing the IP 1842 address: A string or integer representing the IP
1976 1843
1977 Additionally, an integer can be passed, so 1844 Additionally, an integer can be passed, so
1978 IPv6Address('2001:db8::') == 1845 IPv6Address('2001:db8::') ==
1979 IPv6Address(42540766411282592856903984951653826560) 1846 IPv6Address(42540766411282592856903984951653826560)
1980 or, more generally 1847 or, more generally
1981 IPv6Address(int(IPv6Address('2001:db8::'))) == 1848 IPv6Address(int(IPv6Address('2001:db8::'))) ==
1982 IPv6Address('2001:db8::') 1849 IPv6Address('2001:db8::')
1983 1850
1984 Raises: 1851 Raises:
1985 AddressValueError: If address isn't a valid IPv6 address. 1852 AddressValueError: If address isn't a valid IPv6 address.
1986 1853
1987 """ 1854 """
1988 _BaseAddress.__init__(self, address) 1855 _BaseAddress.__init__(self, address)
1989 _BaseV6.__init__(self, address) 1856 _BaseV6.__init__(self, address)
1990 1857
1991 # Efficient constructor from integer. 1858 # Efficient constructor from integer.
1992 if isinstance(address, int): 1859 if isinstance(address, int):
1993 self._ip = address 1860 self._ip = address
1994 if address < 0 or address > self._ALL_ONES: 1861 if address < 0 or address > self._ALL_ONES:
1995 raise AddressValueError(address) 1862 raise AddressValueError(address)
1996 return 1863 return
1997 1864
1998 # Constructing from a packed address 1865 # Constructing from a packed address
1999 if isinstance(address, bytes) and len(address) == 16: 1866 if (not isinstance(address, str) and
1867 isinstance(address, bytes) and len(address) == 16):
2000 tmp = struct.unpack('!QQ', address) 1868 tmp = struct.unpack('!QQ', address)
2001 self._ip = (tmp[0] << 64) | tmp[1] 1869 self._ip = (tmp[0] << 64) | tmp[1]
2002 return 1870 return
2003 1871
2004 # Assume input argument to be string or any object representation 1872 # Assume input argument to be string or any object representation
2005 # which converts into a formatted IP string. 1873 # which converts into a formatted IP string.
2006 addr_str = str(address) 1874 addr_str = str(address)
2007 if not addr_str: 1875 if not addr_str:
2008 raise AddressValueError('') 1876 raise AddressValueError('')
2009 1877
2010 self._ip = self._ip_int_from_string(addr_str) 1878 self._ip = self._ip_int_from_string(addr_str)
1879
1880 @property
1881 def packed(self):
1882 """The binary representation of this address."""
1883 return v6_int_to_packed(self._ip)
2011 1884
2012 1885
2013 class IPv6Interface(IPv6Address): 1886 class IPv6Interface(IPv6Address):
2014 1887
2015 def __init__(self, address): 1888 def __init__(self, address):
2016 if isinstance(address, (bytes, int)): 1889 if isinstance(address, (bytes, int)):
2017 IPv6Address.__init__(self, address) 1890 IPv6Address.__init__(self, address)
2018 self.network = IPv6Network(self._ip) 1891 self.network = IPv6Network(self._ip)
2019 self._prefixlen = self._max_prefixlen 1892 self._prefixlen = self._max_prefixlen
2020 return 1893 return
2021 1894
2022 addr = str(address).split('/') 1895 addr = str(address).split('/')
2023 IPv6Address.__init__(self, addr[0]) 1896 IPv6Address.__init__(self, addr[0])
2024 self.network = IPv6Network(address, strict=False) 1897 self.network = IPv6Network(address, strict=False)
2025 self.netmask = self.network.netmask 1898 self.netmask = self.network.netmask
2026 self._prefixlen = self.network._prefixlen 1899 self._prefixlen = self.network._prefixlen
2027 self.hostmask = self.network.hostmask 1900 self.hostmask = self.network.hostmask
2028 1901
2029
2030 def __str__(self): 1902 def __str__(self):
2031 return '%s/%d' % (self._string_from_ip_int(self._ip), 1903 return '%s/%d' % (self._string_from_ip_int(self._ip),
2032 self.network.prefixlen) 1904 self.network.prefixlen)
2033 1905
2034 def __eq__(self, other): 1906 def __eq__(self, other):
2035 try: 1907 try:
2036 return (IPv6Address.__eq__(self, other) and 1908 return (IPv6Address.__eq__(self, other) and
2037 self.network == other.network) 1909 self.network == other.network)
2038 except AttributeError: 1910 except AttributeError:
2039 return NotImplemented 1911 return NotImplemented
2040 1912
2041 def __hash__(self): 1913 def __hash__(self):
2042 return self._ip ^ self._prefixlen ^ int(self.network.network_address) 1914 return self._ip ^ self._prefixlen ^ int(self.network.network_address)
2043 1915
2044 @property 1916 @property
2045 def prefixlen(self): 1917 def prefixlen(self):
2046 return self._prefixlen 1918 return self._prefixlen
1919
2047 @property 1920 @property
2048 def ip(self): 1921 def ip(self):
2049 return IPv6Address(self._ip) 1922 return IPv6Address(self._ip)
2050 1923
2051 @property 1924 @property
2052 def with_prefixlen(self): 1925 def with_prefixlen(self):
2053 return self 1926 return self
2054 1927
2055 @property 1928 @property
2056 def with_netmask(self): 1929 def with_netmask(self):
2057 return self.with_prefixlen 1930 return self.with_prefixlen
1931
2058 @property 1932 @property
2059 def with_hostmask(self): 1933 def with_hostmask(self):
2060 return '%s/%s' % (self._string_from_ip_int(self._ip), 1934 return '%s/%s' % (self._string_from_ip_int(self._ip),
2061 self.hostmask) 1935 self.hostmask)
2062 1936
2063 1937
2064 class IPv6Network(_BaseV6, _BaseNetwork): 1938 class IPv6Network(_BaseV6, _BaseNetwork):
2065 1939
2066 """This class represents and manipulates 128-bit IPv6 networks. 1940 """This class represents and manipulates 128-bit IPv6 networks.
2067 1941
2068 Attributes: [examples for IPv6('2001:db8::1000/124')] 1942 Attributes: [examples for IPv6('2001:db8::1000/124')]
2069 .network_address: IPv6Address('2001:db8::1000') 1943 .network_address: IPv6Address('2001:db8::1000')
2070 .hostmask: IPv6Address('::f') 1944 .hostmask: IPv6Address('::f')
2071 .broadcast_address: IPv6Address('2001:db8::100f') 1945 .broadcast_address: IPv6Address('2001:db8::100f')
2072 .netmask: IPv6Address('ffff:ffff:ffff:ffff:ffff:ffff:ffff:fff0') 1946 .netmask: IPv6Address('ffff:ffff:ffff:ffff:ffff:ffff:ffff:fff0')
2073 .prefixlen: 124 1947 .prefixlen: 124
2074 1948
2075 """ 1949 """
2076 1950
1951 # Class to use when creating address objects
1952 _address_class = IPv6Address
1953
2077 def __init__(self, address, strict=True): 1954 def __init__(self, address, strict=True):
2078 """Instantiate a new IPv6 Network object. 1955 """Instantiate a new IPv6 Network object.
2079 1956
2080 Args: 1957 Args:
2081 address: A string or integer representing the IPv6 network or the IP 1958 address: A string or integer representing the IPv6 network or the
2082 and prefix/netmask. 1959 IP and prefix/netmask.
2083 '2001:db8::/128' 1960 '2001:db8::/128'
2084 '2001:db8:0000:0000:0000:0000:0000:0000/128' 1961 '2001:db8:0000:0000:0000:0000:0000:0000/128'
2085 '2001:db8::' 1962 '2001:db8::'
2086 are all functionally the same in IPv6. That is to say, 1963 are all functionally the same in IPv6. That is to say,
2087 failing to provide a subnetmask will create an object with 1964 failing to provide a subnetmask will create an object with
2088 a mask of /128. 1965 a mask of /128.
2089 1966
2090 Additionally, an integer can be passed, so 1967 Additionally, an integer can be passed, so
2091 IPv6Network('2001:db8::') == 1968 IPv6Network('2001:db8::') ==
2092 IPv6Network(42540766411282592856903984951653826560) 1969 IPv6Network(42540766411282592856903984951653826560)
(...skipping 16 matching lines...) Expand all
2109 _BaseV6.__init__(self, address) 1986 _BaseV6.__init__(self, address)
2110 _BaseNetwork.__init__(self, address) 1987 _BaseNetwork.__init__(self, address)
2111 1988
2112 # Efficient constructor from integer. 1989 # Efficient constructor from integer.
2113 if isinstance(address, int): 1990 if isinstance(address, int):
2114 if address < 0 or address > self._ALL_ONES: 1991 if address < 0 or address > self._ALL_ONES:
2115 raise AddressValueError(address) 1992 raise AddressValueError(address)
2116 self.network_address = IPv6Address(address) 1993 self.network_address = IPv6Address(address)
2117 self._prefixlen = self._max_prefixlen 1994 self._prefixlen = self._max_prefixlen
2118 self.netmask = IPv6Address(self._ALL_ONES) 1995 self.netmask = IPv6Address(self._ALL_ONES)
2119 if strict:
2120 if (IPv6Address(int(self.network_address) &
2121 int(self.netmask)) != self.network_address):
2122 raise ValueError('%s has host bits set' % str(self))
2123 self.network_address = IPv6Address(int(self.network_address) &
2124 int(self.netmask))
2125 return 1996 return
2126 1997
2127 # Constructing from a packed address 1998 # Constructing from a packed address
2128 if isinstance(address, bytes) and len(address) == 16: 1999 if isinstance(address, bytes) and len(address) == 16:
2129 tmp = struct.unpack('!QQ', address) 2000 tmp = struct.unpack('!QQ', address)
2130 self.network_address = IPv6Address((tmp[0] << 64) | tmp[1]) 2001 self.network_address = IPv6Address((tmp[0] << 64) | tmp[1])
2131 self._prefixlen = self._max_prefixlen 2002 self._prefixlen = self._max_prefixlen
2132 self.netmask = IPv6Address(self._ALL_ONES) 2003 self.netmask = IPv6Address(self._ALL_ONES)
2133 if strict: 2004 return
2134 if (IPv6Address(int(self.network_address) &
2135 int(self.netmask)) != self.network_address):
2136 raise ValueError('%s has host bits set' % str(self))
2137 self.network_address = IPv6Address(int(self.network_address) &
2138 int(self.netmask))
2139 return
2140 2005
2141 # Assume input argument to be string or any object representation 2006 # Assume input argument to be string or any object representation
2142 # which converts into a formatted IP prefix string. 2007 # which converts into a formatted IP prefix string.
2143 addr = str(address).split('/') 2008 addr = str(address).split('/')
2144 2009
2145 if len(addr) > 2: 2010 if len(addr) > 2:
2146 raise AddressValueError(address) 2011 raise AddressValueError(address)
2147 2012
2148 self.network_address = IPv6Address(self._ip_int_from_string(addr[0])) 2013 self.network_address = IPv6Address(self._ip_int_from_string(addr[0]))
2149 2014
2150 if len(addr) == 2: 2015 if len(addr) == 2:
2151 if self._is_valid_netmask(addr[1]): 2016 if self._is_valid_netmask(addr[1]):
2152 self._prefixlen = int(addr[1]) 2017 self._prefixlen = int(addr[1])
2153 else: 2018 else:
2154 raise NetmaskValueError(addr[1]) 2019 raise NetmaskValueError(addr[1])
2155 else: 2020 else:
2156 self._prefixlen = self._max_prefixlen 2021 self._prefixlen = self._max_prefixlen
2157 2022
2158 self.netmask = IPv6Address(self._ip_int_from_prefix(self._prefixlen)) 2023 self.netmask = IPv6Address(self._ip_int_from_prefix(self._prefixlen))
2159 if strict: 2024 if strict:
2160 if (IPv6Address(int(self.network_address) & int(self.netmask)) != 2025 if (IPv6Address(int(self.network_address) & int(self.netmask)) !=
2161 self.network_address): 2026 self.network_address):
2162 raise ValueError('%s has host bits set' % str(self)) 2027 raise ValueError('%s has host bits set' % str(self))
2163 self.network_address = IPv6Address(int(self.network_address) & 2028 self.network_address = IPv6Address(int(self.network_address) &
2164 int(self.netmask)) 2029 int(self.netmask))
2165 2030
2166 if self._prefixlen == (self._max_prefixlen - 1): 2031 if self._prefixlen == (self._max_prefixlen - 1):
2167 self.hosts = self.__iter__ 2032 self.hosts = self.__iter__
2168 2033
2169 def __str__(self):
2170 return '%s/%d' % (str(self.network_address),
2171 self.prefixlen)
2172
2173 def _is_valid_netmask(self, prefixlen): 2034 def _is_valid_netmask(self, prefixlen):
2174 """Verify that the netmask/prefixlen is valid. 2035 """Verify that the netmask/prefixlen is valid.
2175 2036
2176 Args: 2037 Args:
2177 prefixlen: A string, the netmask in prefix length format. 2038 prefixlen: A string, the netmask in prefix length format.
2178 2039
2179 Returns: 2040 Returns:
2180 A boolean, True if the prefix represents a valid IPv6 2041 A boolean, True if the prefix represents a valid IPv6
2181 netmask. 2042 netmask.
2182 2043
2183 """ 2044 """
2184 try: 2045 try:
2185 prefixlen = int(prefixlen) 2046 prefixlen = int(prefixlen)
2186 except ValueError: 2047 except ValueError:
2187 return False 2048 return False
2188 return 0 <= prefixlen <= self._max_prefixlen 2049 return 0 <= prefixlen <= self._max_prefixlen
2189
2190 @property
2191 def with_netmask(self):
2192 return self.with_prefixlen
2193
2194 @property
2195 def with_prefixlen(self):
2196 return '%s/%d' % (str(self.network_address), self._prefixlen)
2197
2198 @property
2199 def with_netmask(self):
2200 return '%s/%s' % (str(self.network_address), str(self.netmask))
2201
2202 @property
2203 def with_hostmask(self):
2204 return '%s/%s' % (str(self.network_address), str(self.hostmask))
LEFTRIGHT

RSS Feeds Recent Issues | This issue
This is Rietveld cbc36f91f3f7