blob: cb35685925c2cff075a1110b727078e74c4eeea3 [file] [log] [blame]
Nick Coghlandc9b2552012-05-20 21:01:57 +10001# Copyright 2007 Google Inc.
2# Licensed to PSF under a Contributor Agreement.
Nick Coghlandc9b2552012-05-20 21:01:57 +10003
4"""A fast, lightweight IPv4/IPv6 manipulation library in Python.
5
6This library is used to create/poke/manipulate IPv4 and IPv6 addresses
7and networks.
8
9"""
10
11__version__ = '1.0'
12
13import struct
14
15IPV4LENGTH = 32
16IPV6LENGTH = 128
17
18
19class AddressValueError(ValueError):
20 """A Value Error related to the address."""
21
22
23class NetmaskValueError(ValueError):
24 """A Value Error related to the netmask."""
25
26
Nick Coghlan51c30672012-05-27 00:25:58 +100027def ip_address(address):
Nick Coghlandc9b2552012-05-20 21:01:57 +100028 """Take an IP string/int and return an object of the correct type.
29
30 Args:
31 address: A string or integer, the IP address. Either IPv4 or
32 IPv6 addresses may be supplied; integers less than 2**32 will
33 be considered to be IPv4 by default.
Nick Coghlandc9b2552012-05-20 21:01:57 +100034
35 Returns:
36 An IPv4Address or IPv6Address object.
37
38 Raises:
Sandro Tosi876ecad2012-05-23 22:26:55 +020039 ValueError: if the *address* passed isn't either a v4 or a v6
Nick Coghlan51c30672012-05-27 00:25:58 +100040 address
Nick Coghlandc9b2552012-05-20 21:01:57 +100041
42 """
Nick Coghlandc9b2552012-05-20 21:01:57 +100043 try:
44 return IPv4Address(address)
45 except (AddressValueError, NetmaskValueError):
46 pass
47
48 try:
49 return IPv6Address(address)
50 except (AddressValueError, NetmaskValueError):
51 pass
52
53 raise ValueError('%r does not appear to be an IPv4 or IPv6 address' %
54 address)
55
56
Nick Coghlan51c30672012-05-27 00:25:58 +100057def ip_network(address, strict=True):
Nick Coghlandc9b2552012-05-20 21:01:57 +100058 """Take an IP string/int and return an object of the correct type.
59
60 Args:
61 address: A string or integer, the IP network. Either IPv4 or
62 IPv6 networks may be supplied; integers less than 2**32 will
63 be considered to be IPv4 by default.
Nick Coghlandc9b2552012-05-20 21:01:57 +100064
65 Returns:
66 An IPv4Network or IPv6Network object.
67
68 Raises:
69 ValueError: if the string passed isn't either a v4 or a v6
Nick Coghlan51c30672012-05-27 00:25:58 +100070 address. Or if the network has host bits set.
Nick Coghlandc9b2552012-05-20 21:01:57 +100071
72 """
Nick Coghlandc9b2552012-05-20 21:01:57 +100073 try:
74 return IPv4Network(address, strict)
75 except (AddressValueError, NetmaskValueError):
76 pass
77
78 try:
79 return IPv6Network(address, strict)
80 except (AddressValueError, NetmaskValueError):
81 pass
82
83 raise ValueError('%r does not appear to be an IPv4 or IPv6 network' %
84 address)
85
86
Nick Coghlan51c30672012-05-27 00:25:58 +100087def ip_interface(address):
Nick Coghlandc9b2552012-05-20 21:01:57 +100088 """Take an IP string/int and return an object of the correct type.
89
90 Args:
91 address: A string or integer, the IP address. Either IPv4 or
92 IPv6 addresses may be supplied; integers less than 2**32 will
93 be considered to be IPv4 by default.
Nick Coghlandc9b2552012-05-20 21:01:57 +100094
95 Returns:
Sandro Tosi876ecad2012-05-23 22:26:55 +020096 An IPv4Interface or IPv6Interface object.
Nick Coghlandc9b2552012-05-20 21:01:57 +100097
98 Raises:
99 ValueError: if the string passed isn't either a v4 or a v6
Nick Coghlan51c30672012-05-27 00:25:58 +1000100 address.
Nick Coghlandc9b2552012-05-20 21:01:57 +1000101
102 Notes:
103 The IPv?Interface classes describe an Address on a particular
104 Network, so they're basically a combination of both the Address
105 and Network classes.
Sandro Tosib95c6342012-05-23 23:17:22 +0200106
Nick Coghlandc9b2552012-05-20 21:01:57 +1000107 """
Nick Coghlandc9b2552012-05-20 21:01:57 +1000108 try:
109 return IPv4Interface(address)
110 except (AddressValueError, NetmaskValueError):
111 pass
112
113 try:
114 return IPv6Interface(address)
115 except (AddressValueError, NetmaskValueError):
116 pass
117
118 raise ValueError('%r does not appear to be an IPv4 or IPv6 network' %
119 address)
120
121
122def v4_int_to_packed(address):
Sandro Tosi876ecad2012-05-23 22:26:55 +0200123 """Represent an address as 4 packed bytes in network (big-endian) order.
Nick Coghlandc9b2552012-05-20 21:01:57 +1000124
125 Args:
126 address: An integer representation of an IPv4 IP address.
127
128 Returns:
Sandro Tosi876ecad2012-05-23 22:26:55 +0200129 The integer address packed as 4 bytes in network (big-endian) order.
Nick Coghlandc9b2552012-05-20 21:01:57 +1000130
131 Raises:
Sandro Tosi876ecad2012-05-23 22:26:55 +0200132 ValueError: If the integer is negative or too large to be an
133 IPv4 IP address.
Sandro Tosib95c6342012-05-23 23:17:22 +0200134
Nick Coghlandc9b2552012-05-20 21:01:57 +1000135 """
Sandro Tosi876ecad2012-05-23 22:26:55 +0200136 try:
137 return struct.pack('!I', address)
138 except:
139 raise ValueError("Address negative or too large for IPv4")
Nick Coghlandc9b2552012-05-20 21:01:57 +1000140
141
142def v6_int_to_packed(address):
Sandro Tosi876ecad2012-05-23 22:26:55 +0200143 """Represent an address as 16 packed bytes in network (big-endian) order.
Nick Coghlandc9b2552012-05-20 21:01:57 +1000144
145 Args:
146 address: An integer representation of an IPv4 IP address.
147
148 Returns:
Sandro Tosi876ecad2012-05-23 22:26:55 +0200149 The integer address packed as 16 bytes in network (big-endian) order.
Sandro Tosib95c6342012-05-23 23:17:22 +0200150
Nick Coghlandc9b2552012-05-20 21:01:57 +1000151 """
Sandro Tosi876ecad2012-05-23 22:26:55 +0200152 try:
153 return struct.pack('!QQ', address >> 64, address & (2**64 - 1))
154 except:
155 raise ValueError("Address negative or too large for IPv6")
Nick Coghlandc9b2552012-05-20 21:01:57 +1000156
157
158def _find_address_range(addresses):
Sandro Tosi876ecad2012-05-23 22:26:55 +0200159 """Find a sequence of IPv#Address.
Nick Coghlandc9b2552012-05-20 21:01:57 +1000160
161 Args:
Sandro Tosi876ecad2012-05-23 22:26:55 +0200162 addresses: a list of IPv#Address objects.
Nick Coghlandc9b2552012-05-20 21:01:57 +1000163
164 Returns:
165 A tuple containing the first and last IP addresses in the sequence.
166
167 """
168 first = last = addresses[0]
169 for ip in addresses[1:]:
170 if ip._ip == last._ip + 1:
171 last = ip
172 else:
173 break
174 return (first, last)
175
Sandro Tosib95c6342012-05-23 23:17:22 +0200176
Nick Coghlandc9b2552012-05-20 21:01:57 +1000177def _get_prefix_length(number1, number2, bits):
178 """Get the number of leading bits that are same for two numbers.
179
180 Args:
181 number1: an integer.
182 number2: another integer.
183 bits: the maximum number of bits to compare.
184
185 Returns:
186 The number of leading bits that are the same for two numbers.
187
188 """
189 for i in range(bits):
190 if number1 >> i == number2 >> i:
191 return bits - i
192 return 0
193
Sandro Tosib95c6342012-05-23 23:17:22 +0200194
Nick Coghlandc9b2552012-05-20 21:01:57 +1000195def _count_righthand_zero_bits(number, bits):
196 """Count the number of zero bits on the right hand side.
197
198 Args:
199 number: an integer.
200 bits: maximum number of bits to count.
201
202 Returns:
203 The number of zero bits on the right hand side of the number.
204
205 """
206 if number == 0:
207 return bits
208 for i in range(bits):
209 if (number >> i) % 2:
210 return i
211
212
213def summarize_address_range(first, last):
214 """Summarize a network range given the first and last IP addresses.
215
216 Example:
217 >>> summarize_address_range(IPv4Address('192.0.2.0'),
218 IPv4Address('192.0.2.130'))
219 [IPv4Network('192.0.2.0/25'), IPv4Network('192.0.2.128/31'),
220 IPv4Network('192.0.2.130/32')]
221
222 Args:
223 first: the first IPv4Address or IPv6Address in the range.
224 last: the last IPv4Address or IPv6Address in the range.
225
226 Returns:
227 An iterator of the summarized IPv(4|6) network objects.
228
229 Raise:
230 TypeError:
231 If the first and last objects are not IP addresses.
232 If the first and last objects are not the same version.
233 ValueError:
234 If the last object is not greater than the first.
Nick Coghlan51c30672012-05-27 00:25:58 +1000235 If the version of the first address is not 4 or 6.
Nick Coghlandc9b2552012-05-20 21:01:57 +1000236
237 """
Hynek Schlawack072b1e12012-05-26 12:04:56 +0200238 if (not (isinstance(first, _BaseAddress) and
239 isinstance(last, _BaseAddress))):
Nick Coghlandc9b2552012-05-20 21:01:57 +1000240 raise TypeError('first and last must be IP addresses, not networks')
241 if first.version != last.version:
242 raise TypeError("%s and %s are not of the same version" % (
243 str(first), str(last)))
244 if first > last:
245 raise ValueError('last IP address must be greater than first')
246
Nick Coghlandc9b2552012-05-20 21:01:57 +1000247 if first.version == 4:
248 ip = IPv4Network
249 elif first.version == 6:
250 ip = IPv6Network
251 else:
252 raise ValueError('unknown IP version')
253
254 ip_bits = first._max_prefixlen
255 first_int = first._ip
256 last_int = last._ip
257 while first_int <= last_int:
258 nbits = _count_righthand_zero_bits(first_int, ip_bits)
259 current = None
260 while nbits >= 0:
261 addend = 2**nbits - 1
262 current = first_int + addend
263 nbits -= 1
264 if current <= last_int:
265 break
266 prefix = _get_prefix_length(first_int, current, ip_bits)
267 net = ip('%s/%d' % (str(first), prefix))
268 yield net
Nick Coghlandc9b2552012-05-20 21:01:57 +1000269 if current == ip._ALL_ONES:
270 break
271 first_int = current + 1
Nick Coghlan51c30672012-05-27 00:25:58 +1000272 first = first.__class__(first_int)
Nick Coghlandc9b2552012-05-20 21:01:57 +1000273
Sandro Tosib95c6342012-05-23 23:17:22 +0200274
Nick Coghlandc9b2552012-05-20 21:01:57 +1000275def _collapse_addresses_recursive(addresses):
276 """Loops through the addresses, collapsing concurrent netblocks.
277
278 Example:
279
280 ip1 = IPv4Network('192.0.2.0/26')
281 ip2 = IPv4Network('192.0.2.64/26')
282 ip3 = IPv4Network('192.0.2.128/26')
283 ip4 = IPv4Network('192.0.2.192/26')
284
285 _collapse_addresses_recursive([ip1, ip2, ip3, ip4]) ->
286 [IPv4Network('192.0.2.0/24')]
287
288 This shouldn't be called directly; it is called via
289 collapse_addresses([]).
290
291 Args:
292 addresses: A list of IPv4Network's or IPv6Network's
293
294 Returns:
295 A list of IPv4Network's or IPv6Network's depending on what we were
296 passed.
297
298 """
299 ret_array = []
300 optimized = False
301
302 for cur_addr in addresses:
303 if not ret_array:
304 ret_array.append(cur_addr)
305 continue
306 if (cur_addr.network_address >= ret_array[-1].network_address and
307 cur_addr.broadcast_address <= ret_array[-1].broadcast_address):
308 optimized = True
309 elif cur_addr == list(ret_array[-1].supernet().subnets())[1]:
310 ret_array.append(ret_array.pop().supernet())
311 optimized = True
312 else:
313 ret_array.append(cur_addr)
314
315 if optimized:
316 return _collapse_addresses_recursive(ret_array)
317
318 return ret_array
319
320
321def collapse_addresses(addresses):
322 """Collapse a list of IP objects.
323
324 Example:
325 collapse_addresses([IPv4Network('192.0.2.0/25'),
326 IPv4Network('192.0.2.128/25')]) ->
327 [IPv4Network('192.0.2.0/24')]
328
329 Args:
330 addresses: An iterator of IPv4Network or IPv6Network objects.
331
332 Returns:
333 An iterator of the collapsed IPv(4|6)Network objects.
334
335 Raises:
336 TypeError: If passed a list of mixed version objects.
337
338 """
339 i = 0
340 addrs = []
341 ips = []
342 nets = []
343
344 # split IP addresses and networks
345 for ip in addresses:
346 if isinstance(ip, _BaseAddress):
347 if ips and ips[-1]._version != ip._version:
348 raise TypeError("%s and %s are not of the same version" % (
349 str(ip), str(ips[-1])))
350 ips.append(ip)
351 elif ip._prefixlen == ip._max_prefixlen:
352 if ips and ips[-1]._version != ip._version:
353 raise TypeError("%s and %s are not of the same version" % (
354 str(ip), str(ips[-1])))
355 try:
356 ips.append(ip.ip)
357 except AttributeError:
358 ips.append(ip.network_address)
359 else:
360 if nets and nets[-1]._version != ip._version:
361 raise TypeError("%s and %s are not of the same version" % (
362 str(ip), str(ips[-1])))
363 nets.append(ip)
364
365 # sort and dedup
366 ips = sorted(set(ips))
367 nets = sorted(set(nets))
368
369 while i < len(ips):
370 (first, last) = _find_address_range(ips[i:])
371 i = ips.index(last) + 1
372 addrs.extend(summarize_address_range(first, last))
373
374 return iter(_collapse_addresses_recursive(sorted(
375 addrs + nets, key=_BaseNetwork._get_networks_key)))
376
377
378def get_mixed_type_key(obj):
379 """Return a key suitable for sorting between networks and addresses.
380
381 Address and Network objects are not sortable by default; they're
382 fundamentally different so the expression
383
384 IPv4Address('192.0.2.0') <= IPv4Network('192.0.2.0/24')
385
386 doesn't make any sense. There are some times however, where you may wish
387 to have ipaddress sort these for you anyway. If you need to do this, you
388 can use this function as the key= argument to sorted().
389
390 Args:
391 obj: either a Network or Address object.
392 Returns:
393 appropriate key.
394
395 """
396 if isinstance(obj, _BaseNetwork):
397 return obj._get_networks_key()
398 elif isinstance(obj, _BaseAddress):
399 return obj._get_address_key()
400 return NotImplemented
401
402
403class _IPAddressBase(object):
404
405 """The mother class."""
406
407 @property
408 def exploded(self):
409 """Return the longhand version of the IP address as a string."""
410 return self._explode_shorthand_ip_string()
411
412 @property
413 def compressed(self):
414 """Return the shorthand version of the IP address as a string."""
415 return str(self)
416
417 def _ip_int_from_prefix(self, prefixlen=None):
418 """Turn the prefix length netmask into a int for comparison.
419
420 Args:
421 prefixlen: An integer, the prefix length.
422
423 Returns:
424 An integer.
425
426 """
427 if not prefixlen and prefixlen != 0:
428 prefixlen = self._prefixlen
429 return self._ALL_ONES ^ (self._ALL_ONES >> prefixlen)
430
431 def _prefix_from_ip_int(self, ip_int, mask=32):
432 """Return prefix length from the decimal netmask.
433
434 Args:
435 ip_int: An integer, the IP address.
436 mask: The netmask. Defaults to 32.
437
438 Returns:
439 An integer, the prefix length.
440
441 """
442 while mask:
443 if ip_int & 1 == 1:
444 break
445 ip_int >>= 1
446 mask -= 1
447
448 return mask
449
450 def _ip_string_from_prefix(self, prefixlen=None):
451 """Turn a prefix length into a dotted decimal string.
452
453 Args:
454 prefixlen: An integer, the netmask prefix length.
455
456 Returns:
457 A string, the dotted decimal netmask string.
458
459 """
460 if not prefixlen:
461 prefixlen = self._prefixlen
462 return self._string_from_ip_int(self._ip_int_from_prefix(prefixlen))
463
464
465class _BaseAddress(_IPAddressBase):
466
467 """A generic IP object.
468
469 This IP class contains the version independent methods which are
470 used by single IP addresses.
471
472 """
473
474 def __init__(self, address):
475 if (not isinstance(address, bytes)
476 and '/' in str(address)):
477 raise AddressValueError(address)
478
479 def __index__(self):
480 return self._ip
481
482 def __int__(self):
483 return self._ip
484
485 def __hex__(self):
486 return hex(self._ip)
487
488 def __eq__(self, other):
489 try:
490 return (self._ip == other._ip
491 and self._version == other._version)
492 except AttributeError:
493 return NotImplemented
494
495 def __ne__(self, other):
496 eq = self.__eq__(other)
497 if eq is NotImplemented:
498 return NotImplemented
499 return not eq
500
501 def __le__(self, other):
502 gt = self.__gt__(other)
503 if gt is NotImplemented:
504 return NotImplemented
505 return not gt
506
507 def __ge__(self, other):
508 lt = self.__lt__(other)
509 if lt is NotImplemented:
510 return NotImplemented
511 return not lt
512
513 def __lt__(self, other):
514 if self._version != other._version:
515 raise TypeError('%s and %s are not of the same version' % (
516 str(self), str(other)))
517 if not isinstance(other, _BaseAddress):
518 raise TypeError('%s and %s are not of the same type' % (
519 str(self), str(other)))
520 if self._ip != other._ip:
521 return self._ip < other._ip
522 return False
523
524 def __gt__(self, other):
525 if self._version != other._version:
526 raise TypeError('%s and %s are not of the same version' % (
527 str(self), str(other)))
528 if not isinstance(other, _BaseAddress):
529 raise TypeError('%s and %s are not of the same type' % (
530 str(self), str(other)))
531 if self._ip != other._ip:
532 return self._ip > other._ip
533 return False
534
535 # Shorthand for Integer addition and subtraction. This is not
536 # meant to ever support addition/subtraction of addresses.
537 def __add__(self, other):
538 if not isinstance(other, int):
539 return NotImplemented
Nick Coghlan51c30672012-05-27 00:25:58 +1000540 return self.__class__(int(self) + other)
Nick Coghlandc9b2552012-05-20 21:01:57 +1000541
542 def __sub__(self, other):
543 if not isinstance(other, int):
544 return NotImplemented
Nick Coghlan51c30672012-05-27 00:25:58 +1000545 return self.__class__(int(self) - other)
Nick Coghlandc9b2552012-05-20 21:01:57 +1000546
547 def __repr__(self):
548 return '%s(%r)' % (self.__class__.__name__, str(self))
549
550 def __str__(self):
Hynek Schlawack072b1e12012-05-26 12:04:56 +0200551 return str(self._string_from_ip_int(self._ip))
Nick Coghlandc9b2552012-05-20 21:01:57 +1000552
553 def __hash__(self):
554 return hash(hex(int(self._ip)))
555
556 def _get_address_key(self):
557 return (self._version, self)
558
559 @property
560 def version(self):
561 raise NotImplementedError('BaseIP has no version')
562
563
564class _BaseNetwork(_IPAddressBase):
565
Nick Coghlan51c30672012-05-27 00:25:58 +1000566 """A generic IP network object.
Nick Coghlandc9b2552012-05-20 21:01:57 +1000567
568 This IP class contains the version independent methods which are
569 used by networks.
570
571 """
Nick Coghlandc9b2552012-05-20 21:01:57 +1000572 def __init__(self, address):
573 self._cache = {}
574
575 def __index__(self):
576 return int(self.network_address) ^ self.prefixlen
577
578 def __int__(self):
579 return int(self.network_address)
580
581 def __repr__(self):
582 return '%s(%r)' % (self.__class__.__name__, str(self))
583
584 def hosts(self):
585 """Generate Iterator over usable hosts in a network.
586
Sandro Tosib95c6342012-05-23 23:17:22 +0200587 This is like __iter__ except it doesn't return the network
588 or broadcast addresses.
Nick Coghlandc9b2552012-05-20 21:01:57 +1000589
590 """
591 cur = int(self.network_address) + 1
592 bcast = int(self.broadcast_address) - 1
593 while cur <= bcast:
594 cur += 1
Nick Coghlan51c30672012-05-27 00:25:58 +1000595 yield self._address_class(cur - 1)
Nick Coghlandc9b2552012-05-20 21:01:57 +1000596
597 def __iter__(self):
598 cur = int(self.network_address)
599 bcast = int(self.broadcast_address)
600 while cur <= bcast:
601 cur += 1
Nick Coghlan51c30672012-05-27 00:25:58 +1000602 yield self._address_class(cur - 1)
Nick Coghlandc9b2552012-05-20 21:01:57 +1000603
604 def __getitem__(self, n):
605 network = int(self.network_address)
606 broadcast = int(self.broadcast_address)
607 if n >= 0:
608 if network + n > broadcast:
609 raise IndexError
Nick Coghlan51c30672012-05-27 00:25:58 +1000610 return self._address_class(network + n)
Nick Coghlandc9b2552012-05-20 21:01:57 +1000611 else:
612 n += 1
613 if broadcast + n < network:
614 raise IndexError
Nick Coghlan51c30672012-05-27 00:25:58 +1000615 return self._address_class(broadcast + n)
Nick Coghlandc9b2552012-05-20 21:01:57 +1000616
617 def __lt__(self, other):
618 if self._version != other._version:
619 raise TypeError('%s and %s are not of the same version' % (
620 str(self), str(other)))
621 if not isinstance(other, _BaseNetwork):
622 raise TypeError('%s and %s are not of the same type' % (
623 str(self), str(other)))
624 if self.network_address != other.network_address:
625 return self.network_address < other.network_address
626 if self.netmask != other.netmask:
627 return self.netmask < other.netmask
628 return False
629
630 def __gt__(self, other):
631 if self._version != other._version:
632 raise TypeError('%s and %s are not of the same version' % (
633 str(self), str(other)))
634 if not isinstance(other, _BaseNetwork):
635 raise TypeError('%s and %s are not of the same type' % (
636 str(self), str(other)))
637 if self.network_address != other.network_address:
638 return self.network_address > other.network_address
639 if self.netmask != other.netmask:
640 return self.netmask > other.netmask
641 return False
642
643 def __le__(self, other):
644 gt = self.__gt__(other)
645 if gt is NotImplemented:
646 return NotImplemented
647 return not gt
648
649 def __ge__(self, other):
650 lt = self.__lt__(other)
651 if lt is NotImplemented:
652 return NotImplemented
653 return not lt
654
655 def __eq__(self, other):
656 if not isinstance(other, _BaseNetwork):
657 raise TypeError('%s and %s are not of the same type' % (
658 str(self), str(other)))
659 return (self._version == other._version and
660 self.network_address == other.network_address and
661 int(self.netmask) == int(other.netmask))
662
663 def __ne__(self, other):
664 eq = self.__eq__(other)
665 if eq is NotImplemented:
666 return NotImplemented
667 return not eq
668
669 def __str__(self):
Hynek Schlawack072b1e12012-05-26 12:04:56 +0200670 return '%s/%s' % (self.ip, self._prefixlen)
Nick Coghlandc9b2552012-05-20 21:01:57 +1000671
672 def __hash__(self):
673 return hash(int(self.network_address) ^ int(self.netmask))
674
675 def __contains__(self, other):
676 # always false if one is v4 and the other is v6.
677 if self._version != other._version:
678 return False
679 # dealing with another network.
680 if isinstance(other, _BaseNetwork):
681 return False
682 # dealing with another address
683 else:
684 # address
685 return (int(self.network_address) <= int(other._ip) <=
686 int(self.broadcast_address))
687
688 def overlaps(self, other):
689 """Tell if self is partly contained in other."""
690 return self.network_address in other or (
691 self.broadcast_address in other or (
692 other.network_address in self or (
693 other.broadcast_address in self)))
694
695 @property
696 def broadcast_address(self):
697 x = self._cache.get('broadcast_address')
698 if x is None:
Nick Coghlan51c30672012-05-27 00:25:58 +1000699 x = self._address_class(int(self.network_address) |
700 int(self.hostmask))
Nick Coghlandc9b2552012-05-20 21:01:57 +1000701 self._cache['broadcast_address'] = x
702 return x
703
704 @property
705 def hostmask(self):
706 x = self._cache.get('hostmask')
707 if x is None:
Nick Coghlan51c30672012-05-27 00:25:58 +1000708 x = self._address_class(int(self.netmask) ^ self._ALL_ONES)
Nick Coghlandc9b2552012-05-20 21:01:57 +1000709 self._cache['hostmask'] = x
710 return x
711
712 @property
Nick Coghlandc9b2552012-05-20 21:01:57 +1000713 def with_prefixlen(self):
714 return '%s/%d' % (str(self.ip), self._prefixlen)
715
716 @property
717 def with_netmask(self):
718 return '%s/%s' % (str(self.ip), str(self.netmask))
719
720 @property
721 def with_hostmask(self):
722 return '%s/%s' % (str(self.ip), str(self.hostmask))
723
724 @property
725 def num_addresses(self):
726 """Number of hosts in the current subnet."""
727 return int(self.broadcast_address) - int(self.network_address) + 1
728
729 @property
730 def version(self):
731 raise NotImplementedError('BaseNet has no version')
732
733 @property
Nick Coghlan51c30672012-05-27 00:25:58 +1000734 def _address_class(self):
735 raise NotImplementedError('BaseNet has no associated address class')
736
737 @property
Nick Coghlandc9b2552012-05-20 21:01:57 +1000738 def prefixlen(self):
739 return self._prefixlen
740
741 def address_exclude(self, other):
742 """Remove an address from a larger block.
743
744 For example:
745
746 addr1 = ip_network('192.0.2.0/28')
747 addr2 = ip_network('192.0.2.1/32')
748 addr1.address_exclude(addr2) =
749 [IPv4Network('192.0.2.0/32'), IPv4Network('192.0.2.2/31'),
750 IPv4Network('192.0.2.4/30'), IPv4Network('192.0.2.8/29')]
751
752 or IPv6:
753
754 addr1 = ip_network('2001:db8::1/32')
755 addr2 = ip_network('2001:db8::1/128')
756 addr1.address_exclude(addr2) =
757 [ip_network('2001:db8::1/128'),
758 ip_network('2001:db8::2/127'),
759 ip_network('2001:db8::4/126'),
760 ip_network('2001:db8::8/125'),
761 ...
762 ip_network('2001:db8:8000::/33')]
763
764 Args:
765 other: An IPv4Network or IPv6Network object of the same type.
766
767 Returns:
768 An iterator of the the IPv(4|6)Network objects which is self
769 minus other.
770
771 Raises:
772 TypeError: If self and other are of difffering address
773 versions, or if other is not a network object.
774 ValueError: If other is not completely contained by self.
775
776 """
777 if not self._version == other._version:
778 raise TypeError("%s and %s are not of the same version" % (
779 str(self), str(other)))
780
781 if not isinstance(other, _BaseNetwork):
782 raise TypeError("%s is not a network object" % str(other))
783
784 if not (other.network_address >= self.network_address and
785 other.broadcast_address <= self.broadcast_address):
Hynek Schlawack072b1e12012-05-26 12:04:56 +0200786 raise ValueError('%s not contained in %s' % (other, self))
Nick Coghlandc9b2552012-05-20 21:01:57 +1000787 if other == self:
788 raise StopIteration
789
Nick Coghlandc9b2552012-05-20 21:01:57 +1000790 # Make sure we're comparing the network of other.
Nick Coghlan51c30672012-05-27 00:25:58 +1000791 other = other.__class__('%s/%s' % (str(other.network_address),
792 str(other.prefixlen)))
Nick Coghlandc9b2552012-05-20 21:01:57 +1000793
794 s1, s2 = self.subnets()
795 while s1 != other and s2 != other:
796 if (other.network_address >= s1.network_address and
797 other.broadcast_address <= s1.broadcast_address):
798 yield s2
799 s1, s2 = s1.subnets()
800 elif (other.network_address >= s2.network_address and
801 other.broadcast_address <= s2.broadcast_address):
802 yield s1
803 s1, s2 = s2.subnets()
804 else:
805 # If we got here, there's a bug somewhere.
806 raise AssertionError('Error performing exclusion: '
807 's1: %s s2: %s other: %s' %
808 (str(s1), str(s2), str(other)))
809 if s1 == other:
810 yield s2
811 elif s2 == other:
812 yield s1
813 else:
814 # If we got here, there's a bug somewhere.
815 raise AssertionError('Error performing exclusion: '
816 's1: %s s2: %s other: %s' %
817 (str(s1), str(s2), str(other)))
818
819 def compare_networks(self, other):
820 """Compare two IP objects.
821
822 This is only concerned about the comparison of the integer
823 representation of the network addresses. This means that the
824 host bits aren't considered at all in this method. If you want
825 to compare host bits, you can easily enough do a
826 'HostA._ip < HostB._ip'
827
828 Args:
829 other: An IP object.
830
831 Returns:
832 If the IP versions of self and other are the same, returns:
833
834 -1 if self < other:
835 eg: IPv4Network('192.0.2.0/25') < IPv4Network('192.0.2.128/25')
836 IPv6Network('2001:db8::1000/124') <
837 IPv6Network('2001:db8::2000/124')
838 0 if self == other
839 eg: IPv4Network('192.0.2.0/24') == IPv4Network('192.0.2.0/24')
840 IPv6Network('2001:db8::1000/124') ==
841 IPv6Network('2001:db8::1000/124')
842 1 if self > other
843 eg: IPv4Network('192.0.2.128/25') > IPv4Network('192.0.2.0/25')
844 IPv6Network('2001:db8::2000/124') >
845 IPv6Network('2001:db8::1000/124')
846
847 Raises:
848 TypeError if the IP versions are different.
849
850 """
851 # does this need to raise a ValueError?
852 if self._version != other._version:
853 raise TypeError('%s and %s are not of the same type' % (
854 str(self), str(other)))
855 # self._version == other._version below here:
856 if self.network_address < other.network_address:
857 return -1
858 if self.network_address > other.network_address:
859 return 1
860 # self.network_address == other.network_address below here:
861 if self.netmask < other.netmask:
862 return -1
863 if self.netmask > other.netmask:
864 return 1
865 return 0
866
867 def _get_networks_key(self):
868 """Network-only key function.
869
870 Returns an object that identifies this address' network and
871 netmask. This function is a suitable "key" argument for sorted()
872 and list.sort().
873
874 """
875 return (self._version, self.network_address, self.netmask)
876
877 def subnets(self, prefixlen_diff=1, new_prefix=None):
878 """The subnets which join to make the current subnet.
879
880 In the case that self contains only one IP
881 (self._prefixlen == 32 for IPv4 or self._prefixlen == 128
882 for IPv6), yield an iterator with just ourself.
883
884 Args:
885 prefixlen_diff: An integer, the amount the prefix length
886 should be increased by. This should not be set if
887 new_prefix is also set.
888 new_prefix: The desired new prefix length. This must be a
889 larger number (smaller prefix) than the existing prefix.
890 This should not be set if prefixlen_diff is also set.
891
892 Returns:
893 An iterator of IPv(4|6) objects.
894
895 Raises:
896 ValueError: The prefixlen_diff is too small or too large.
897 OR
898 prefixlen_diff and new_prefix are both set or new_prefix
899 is a smaller number than the current prefix (smaller
900 number means a larger network)
901
902 """
903 if self._prefixlen == self._max_prefixlen:
904 yield self
905 return
906
907 if new_prefix is not None:
908 if new_prefix < self._prefixlen:
909 raise ValueError('new prefix must be longer')
910 if prefixlen_diff != 1:
911 raise ValueError('cannot set prefixlen_diff and new_prefix')
912 prefixlen_diff = new_prefix - self._prefixlen
913
914 if prefixlen_diff < 0:
915 raise ValueError('prefix length diff must be > 0')
916 new_prefixlen = self._prefixlen + prefixlen_diff
917
918 if not self._is_valid_netmask(str(new_prefixlen)):
919 raise ValueError(
920 'prefix length diff %d is invalid for netblock %s' % (
921 new_prefixlen, str(self)))
922
Nick Coghlan51c30672012-05-27 00:25:58 +1000923 first = self.__class__('%s/%s' %
924 (str(self.network_address),
925 str(self._prefixlen + prefixlen_diff)))
Nick Coghlandc9b2552012-05-20 21:01:57 +1000926
927 yield first
928 current = first
929 while True:
930 broadcast = current.broadcast_address
931 if broadcast == self.broadcast_address:
932 return
Nick Coghlan51c30672012-05-27 00:25:58 +1000933 new_addr = self._address_class(int(broadcast) + 1)
934 current = self.__class__('%s/%s' % (str(new_addr),
935 str(new_prefixlen)))
Nick Coghlandc9b2552012-05-20 21:01:57 +1000936
937 yield current
938
Nick Coghlandc9b2552012-05-20 21:01:57 +1000939 def supernet(self, prefixlen_diff=1, new_prefix=None):
940 """The supernet containing the current network.
941
942 Args:
943 prefixlen_diff: An integer, the amount the prefix length of
944 the network should be decreased by. For example, given a
945 /24 network and a prefixlen_diff of 3, a supernet with a
946 /21 netmask is returned.
947
948 Returns:
949 An IPv4 network object.
950
951 Raises:
Hynek Schlawack072b1e12012-05-26 12:04:56 +0200952 ValueError: If self.prefixlen - prefixlen_diff < 0. I.e., you have
953 a negative prefix length.
Nick Coghlandc9b2552012-05-20 21:01:57 +1000954 OR
955 If prefixlen_diff and new_prefix are both set or new_prefix is a
956 larger number than the current prefix (larger number means a
957 smaller network)
958
959 """
960 if self._prefixlen == 0:
961 return self
962
963 if new_prefix is not None:
964 if new_prefix > self._prefixlen:
965 raise ValueError('new prefix must be shorter')
966 if prefixlen_diff != 1:
967 raise ValueError('cannot set prefixlen_diff and new_prefix')
968 prefixlen_diff = self._prefixlen - new_prefix
969
Nick Coghlandc9b2552012-05-20 21:01:57 +1000970 if self.prefixlen - prefixlen_diff < 0:
971 raise ValueError(
972 'current prefixlen is %d, cannot have a prefixlen_diff of %d' %
973 (self.prefixlen, prefixlen_diff))
974 # TODO (pmoody): optimize this.
Nick Coghlan51c30672012-05-27 00:25:58 +1000975 t = self.__class__('%s/%d' % (str(self.network_address),
976 self.prefixlen - prefixlen_diff),
977 strict=False)
978 return t.__class__('%s/%d' % (str(t.network_address), t.prefixlen))
Nick Coghlandc9b2552012-05-20 21:01:57 +1000979
980
981class _BaseV4(object):
982
983 """Base IPv4 object.
984
985 The following methods are used by IPv4 objects in both single IP
986 addresses and networks.
987
988 """
989
990 # Equivalent to 255.255.255.255 or 32 bits of 1's.
991 _ALL_ONES = (2**IPV4LENGTH) - 1
992 _DECIMAL_DIGITS = frozenset('0123456789')
993
994 def __init__(self, address):
995 self._version = 4
996 self._max_prefixlen = IPV4LENGTH
997
998 def _explode_shorthand_ip_string(self):
999 return str(self)
1000
1001 def _ip_int_from_string(self, ip_str):
1002 """Turn the given IP string into an integer for comparison.
1003
1004 Args:
1005 ip_str: A string, the IP ip_str.
1006
1007 Returns:
1008 The IP ip_str as an integer.
1009
1010 Raises:
1011 AddressValueError: if ip_str isn't a valid IPv4 Address.
1012
1013 """
1014 octets = ip_str.split('.')
1015 if len(octets) != 4:
1016 raise AddressValueError(ip_str)
1017
1018 packed_ip = 0
1019 for oc in octets:
1020 try:
1021 packed_ip = (packed_ip << 8) | self._parse_octet(oc)
1022 except ValueError:
1023 raise AddressValueError(ip_str)
1024 return packed_ip
1025
1026 def _parse_octet(self, octet_str):
1027 """Convert a decimal octet into an integer.
1028
1029 Args:
1030 octet_str: A string, the number to parse.
1031
1032 Returns:
1033 The octet as an integer.
1034
1035 Raises:
1036 ValueError: if the octet isn't strictly a decimal from [0..255].
1037
1038 """
1039 # Whitelist the characters, since int() allows a lot of bizarre stuff.
1040 if not self._DECIMAL_DIGITS.issuperset(octet_str):
1041 raise ValueError
1042 octet_int = int(octet_str, 10)
1043 # Disallow leading zeroes, because no clear standard exists on
1044 # whether these should be interpreted as decimal or octal.
1045 if octet_int > 255 or (octet_str[0] == '0' and len(octet_str) > 1):
1046 raise ValueError
1047 return octet_int
1048
1049 def _string_from_ip_int(self, ip_int):
1050 """Turns a 32-bit integer into dotted decimal notation.
1051
1052 Args:
1053 ip_int: An integer, the IP address.
1054
1055 Returns:
1056 The IP address as a string in dotted decimal notation.
1057
1058 """
1059 octets = []
1060 for _ in range(4):
1061 octets.insert(0, str(ip_int & 0xFF))
1062 ip_int >>= 8
1063 return '.'.join(octets)
1064
1065 @property
1066 def max_prefixlen(self):
1067 return self._max_prefixlen
1068
1069 @property
1070 def version(self):
1071 return self._version
1072
1073 @property
1074 def is_reserved(self):
1075 """Test if the address is otherwise IETF reserved.
1076
1077 Returns:
1078 A boolean, True if the address is within the
1079 reserved IPv4 Network range.
1080
1081 """
1082 reserved_network = IPv4Network('240.0.0.0/4')
1083 if isinstance(self, _BaseAddress):
1084 return self in reserved_network
1085 return (self.network_address in reserved_network and
1086 self.broadcast_address in reserved_network)
1087
1088 @property
1089 def is_private(self):
1090 """Test if this address is allocated for private networks.
1091
1092 Returns:
1093 A boolean, True if the address is reserved per RFC 1918.
1094
1095 """
1096 private_10 = IPv4Network('10.0.0.0/8')
1097 private_172 = IPv4Network('172.16.0.0/12')
1098 private_192 = IPv4Network('192.168.0.0/16')
1099 if isinstance(self, _BaseAddress):
1100 return (self in private_10 or self in private_172 or
1101 self in private_192)
1102 else:
1103 return ((self.network_address in private_10 and
1104 self.broadcast_address in private_10) or
1105 (self.network_address in private_172 and
1106 self.broadcast_address in private_172) or
1107 (self.network_address in private_192 and
1108 self.broadcast_address in private_192))
1109
1110 @property
1111 def is_multicast(self):
1112 """Test if the address is reserved for multicast use.
1113
1114 Returns:
1115 A boolean, True if the address is multicast.
1116 See RFC 3171 for details.
1117
1118 """
1119 multicast_network = IPv4Network('224.0.0.0/4')
1120 if isinstance(self, _BaseAddress):
1121 return self in IPv4Network('224.0.0.0/4')
1122 return (self.network_address in multicast_network and
1123 self.broadcast_address in multicast_network)
1124
1125 @property
1126 def is_unspecified(self):
1127 """Test if the address is unspecified.
1128
1129 Returns:
1130 A boolean, True if this is the unspecified address as defined in
1131 RFC 5735 3.
1132
1133 """
1134 unspecified_address = IPv4Address('0.0.0.0')
1135 if isinstance(self, _BaseAddress):
1136 return self in unspecified_address
1137 return (self.network_address == self.broadcast_address ==
1138 unspecified_address)
1139
1140 @property
1141 def is_loopback(self):
1142 """Test if the address is a loopback address.
1143
1144 Returns:
1145 A boolean, True if the address is a loopback per RFC 3330.
1146
1147 """
1148 loopback_address = IPv4Network('127.0.0.0/8')
1149 if isinstance(self, _BaseAddress):
1150 return self in loopback_address
1151
1152 return (self.network_address in loopback_address and
1153 self.broadcast_address in loopback_address)
1154
1155 @property
1156 def is_link_local(self):
1157 """Test if the address is reserved for link-local.
1158
1159 Returns:
1160 A boolean, True if the address is link-local per RFC 3927.
1161
1162 """
1163 linklocal_network = IPv4Network('169.254.0.0/16')
1164 if isinstance(self, _BaseAddress):
1165 return self in linklocal_network
1166 return (self.network_address in linklocal_network and
1167 self.broadcast_address in linklocal_network)
1168
1169
1170class IPv4Address(_BaseV4, _BaseAddress):
1171
1172 """Represent and manipulate single IPv4 Addresses."""
1173
1174 def __init__(self, address):
1175
1176 """
1177 Args:
1178 address: A string or integer representing the IP
1179
1180 Additionally, an integer can be passed, so
1181 IPv4Address('192.0.2.1') == IPv4Address(3221225985).
1182 or, more generally
1183 IPv4Address(int(IPv4Address('192.0.2.1'))) ==
1184 IPv4Address('192.0.2.1')
1185
1186 Raises:
1187 AddressValueError: If ipaddressisn't a valid IPv4 address.
1188
1189 """
1190 _BaseAddress.__init__(self, address)
1191 _BaseV4.__init__(self, address)
1192
1193 # Efficient constructor from integer.
1194 if isinstance(address, int):
1195 self._ip = address
1196 if address < 0 or address > self._ALL_ONES:
1197 raise AddressValueError(address)
1198 return
1199
1200 # Constructing from a packed address
1201 if isinstance(address, bytes) and len(address) == 4:
1202 self._ip = struct.unpack('!I', address)[0]
1203 return
1204
1205 # Assume input argument to be string or any object representation
1206 # which converts into a formatted IP string.
1207 addr_str = str(address)
1208 self._ip = self._ip_int_from_string(addr_str)
1209
1210 @property
1211 def packed(self):
1212 """The binary representation of this address."""
1213 return v4_int_to_packed(self._ip)
1214
1215
1216class IPv4Interface(IPv4Address):
1217
1218 # the valid octets for host and netmasks. only useful for IPv4.
1219 _valid_mask_octets = set((255, 254, 252, 248, 240, 224, 192, 128, 0))
1220
1221 def __init__(self, address):
1222 if isinstance(address, (bytes, int)):
1223 IPv4Address.__init__(self, address)
1224 self.network = IPv4Network(self._ip)
1225 self._prefixlen = self._max_prefixlen
1226 return
1227
1228 addr = str(address).split('/')
1229 if len(addr) > 2:
1230 raise AddressValueError(address)
1231 IPv4Address.__init__(self, addr[0])
1232
1233 self.network = IPv4Network(address, strict=False)
1234 self._prefixlen = self.network._prefixlen
1235
1236 self.netmask = self.network.netmask
1237 self.hostmask = self.network.hostmask
1238
Nick Coghlandc9b2552012-05-20 21:01:57 +10001239 def __str__(self):
1240 return '%s/%d' % (self._string_from_ip_int(self._ip),
1241 self.network.prefixlen)
1242
1243 def __eq__(self, other):
1244 try:
1245 return (IPv4Address.__eq__(self, other) and
1246 self.network == other.network)
1247 except AttributeError:
1248 return NotImplemented
1249
1250 def __hash__(self):
1251 return self._ip ^ self._prefixlen ^ int(self.network.network_address)
1252
1253 def _is_valid_netmask(self, netmask):
1254 """Verify that the netmask is valid.
1255
1256 Args:
1257 netmask: A string, either a prefix or dotted decimal
1258 netmask.
1259
1260 Returns:
1261 A boolean, True if the prefix represents a valid IPv4
1262 netmask.
1263
1264 """
1265 mask = netmask.split('.')
1266 if len(mask) == 4:
1267 if [x for x in mask if int(x) not in self._valid_mask_octets]:
1268 return False
1269 if [y for idx, y in enumerate(mask) if idx > 0 and
1270 y > mask[idx - 1]]:
1271 return False
1272 return True
1273 try:
1274 netmask = int(netmask)
1275 except ValueError:
1276 return False
1277 return 0 <= netmask <= self._max_prefixlen
1278
1279 def _is_hostmask(self, ip_str):
1280 """Test if the IP string is a hostmask (rather than a netmask).
1281
1282 Args:
1283 ip_str: A string, the potential hostmask.
1284
1285 Returns:
1286 A boolean, True if the IP string is a hostmask.
1287
1288 """
1289 bits = ip_str.split('.')
1290 try:
1291 parts = [int(x) for x in bits if int(x) in self._valid_mask_octets]
1292 except ValueError:
1293 return False
1294 if len(parts) != len(bits):
1295 return False
1296 if parts[0] < parts[-1]:
1297 return True
1298 return False
1299
Nick Coghlandc9b2552012-05-20 21:01:57 +10001300 @property
1301 def prefixlen(self):
1302 return self._prefixlen
1303
1304 @property
1305 def ip(self):
1306 return IPv4Address(self._ip)
1307
1308 @property
1309 def with_prefixlen(self):
1310 return self
1311
1312 @property
1313 def with_netmask(self):
1314 return '%s/%s' % (self._string_from_ip_int(self._ip),
1315 self.netmask)
Hynek Schlawack072b1e12012-05-26 12:04:56 +02001316
Nick Coghlandc9b2552012-05-20 21:01:57 +10001317 @property
1318 def with_hostmask(self):
1319 return '%s/%s' % (self._string_from_ip_int(self._ip),
1320 self.hostmask)
1321
1322
1323class IPv4Network(_BaseV4, _BaseNetwork):
1324
1325 """This class represents and manipulates 32-bit IPv4 network + addresses..
1326
1327 Attributes: [examples for IPv4Network('192.0.2.0/27')]
1328 .network_address: IPv4Address('192.0.2.0')
1329 .hostmask: IPv4Address('0.0.0.31')
1330 .broadcast_address: IPv4Address('192.0.2.32')
1331 .netmask: IPv4Address('255.255.255.224')
1332 .prefixlen: 27
1333
1334 """
Nick Coghlan51c30672012-05-27 00:25:58 +10001335 # Class to use when creating address objects
1336 # TODO (ncoghlan): Investigate using IPv4Interface instead
1337 _address_class = IPv4Address
Nick Coghlandc9b2552012-05-20 21:01:57 +10001338
1339 # the valid octets for host and netmasks. only useful for IPv4.
1340 _valid_mask_octets = set((255, 254, 252, 248, 240, 224, 192, 128, 0))
1341
1342 def __init__(self, address, strict=True):
1343
1344 """Instantiate a new IPv4 network object.
1345
1346 Args:
1347 address: A string or integer representing the IP [& network].
1348 '192.0.2.0/24'
1349 '192.0.2.0/255.255.255.0'
1350 '192.0.0.2/0.0.0.255'
1351 are all functionally the same in IPv4. Similarly,
1352 '192.0.2.1'
1353 '192.0.2.1/255.255.255.255'
1354 '192.0.2.1/32'
1355 are also functionaly equivalent. That is to say, failing to
1356 provide a subnetmask will create an object with a mask of /32.
1357
1358 If the mask (portion after the / in the argument) is given in
1359 dotted quad form, it is treated as a netmask if it starts with a
1360 non-zero field (e.g. /255.0.0.0 == /8) and as a hostmask if it
1361 starts with a zero field (e.g. 0.255.255.255 == /8), with the
1362 single exception of an all-zero mask which is treated as a
1363 netmask == /0. If no mask is given, a default of /32 is used.
1364
1365 Additionally, an integer can be passed, so
1366 IPv4Network('192.0.2.1') == IPv4Network(3221225985)
1367 or, more generally
1368 IPv4Interface(int(IPv4Interface('192.0.2.1'))) ==
1369 IPv4Interface('192.0.2.1')
1370
1371 Raises:
1372 AddressValueError: If ipaddressisn't a valid IPv4 address.
1373 NetmaskValueError: If the netmask isn't valid for
1374 an IPv4 address.
1375 ValueError: If strict was True and a network address was not
1376 supplied.
1377
1378 """
1379
1380 _BaseV4.__init__(self, address)
1381 _BaseNetwork.__init__(self, address)
1382
1383 # Constructing from a packed address
1384 if isinstance(address, bytes) and len(address) == 4:
1385 self.network_address = IPv4Address(
1386 struct.unpack('!I', address)[0])
1387 self._prefixlen = self._max_prefixlen
1388 self.netmask = IPv4Address(self._ALL_ONES)
1389 #fixme: address/network test here
1390 return
1391
1392 # Efficient constructor from integer.
1393 if isinstance(address, int):
1394 self._prefixlen = self._max_prefixlen
1395 self.netmask = IPv4Address(self._ALL_ONES)
1396 if address < 0 or address > self._ALL_ONES:
1397 raise AddressValueError(address)
1398 self.network_address = IPv4Address(address)
1399 #fixme: address/network test here.
1400 return
1401
1402 # Assume input argument to be string or any object representation
1403 # which converts into a formatted IP prefix string.
1404 addr = str(address).split('/')
1405 self.network_address = IPv4Address(self._ip_int_from_string(addr[0]))
1406
1407 if len(addr) > 2:
1408 raise AddressValueError(address)
1409
1410 if len(addr) == 2:
1411 mask = addr[1].split('.')
1412
1413 if len(mask) == 4:
1414 # We have dotted decimal netmask.
1415 if self._is_valid_netmask(addr[1]):
1416 self.netmask = IPv4Address(self._ip_int_from_string(
1417 addr[1]))
1418 elif self._is_hostmask(addr[1]):
1419 self.netmask = IPv4Address(
1420 self._ip_int_from_string(addr[1]) ^ self._ALL_ONES)
1421 else:
1422 raise NetmaskValueError('%s is not a valid netmask'
1423 % addr[1])
1424
1425 self._prefixlen = self._prefix_from_ip_int(int(self.netmask))
1426 else:
1427 # We have a netmask in prefix length form.
1428 if not self._is_valid_netmask(addr[1]):
1429 raise NetmaskValueError(addr[1])
1430 self._prefixlen = int(addr[1])
1431 self.netmask = IPv4Address(self._ip_int_from_prefix(
1432 self._prefixlen))
1433 else:
1434 self._prefixlen = self._max_prefixlen
1435 self.netmask = IPv4Address(self._ip_int_from_prefix(
1436 self._prefixlen))
1437
1438 if strict:
1439 if (IPv4Address(int(self.network_address) & int(self.netmask)) !=
1440 self.network_address):
1441 raise ValueError('%s has host bits set' % self)
1442 self.network_address = IPv4Address(int(self.network_address) &
1443 int(self.netmask))
1444
1445 if self._prefixlen == (self._max_prefixlen - 1):
1446 self.hosts = self.__iter__
1447
1448 @property
1449 def packed(self):
1450 """The binary representation of this address."""
1451 return v4_int_to_packed(self.network_address)
1452
1453 def __str__(self):
1454 return '%s/%d' % (str(self.network_address),
1455 self.prefixlen)
1456
1457 def _is_valid_netmask(self, netmask):
1458 """Verify that the netmask is valid.
1459
1460 Args:
1461 netmask: A string, either a prefix or dotted decimal
1462 netmask.
1463
1464 Returns:
1465 A boolean, True if the prefix represents a valid IPv4
1466 netmask.
1467
1468 """
1469 mask = netmask.split('.')
1470 if len(mask) == 4:
1471 if [x for x in mask if int(x) not in self._valid_mask_octets]:
1472 return False
1473 if [y for idx, y in enumerate(mask) if idx > 0 and
1474 y > mask[idx - 1]]:
1475 return False
1476 return True
1477 try:
1478 netmask = int(netmask)
1479 except ValueError:
1480 return False
1481 return 0 <= netmask <= self._max_prefixlen
1482
1483 def _is_hostmask(self, ip_str):
1484 """Test if the IP string is a hostmask (rather than a netmask).
1485
1486 Args:
1487 ip_str: A string, the potential hostmask.
1488
1489 Returns:
1490 A boolean, True if the IP string is a hostmask.
1491
1492 """
1493 bits = ip_str.split('.')
1494 try:
1495 parts = [int(x) for x in bits if int(x) in self._valid_mask_octets]
1496 except ValueError:
1497 return False
1498 if len(parts) != len(bits):
1499 return False
1500 if parts[0] < parts[-1]:
1501 return True
1502 return False
1503
1504 @property
1505 def with_prefixlen(self):
1506 return '%s/%d' % (str(self.network_address), self._prefixlen)
1507
1508 @property
1509 def with_netmask(self):
1510 return '%s/%s' % (str(self.network_address), str(self.netmask))
1511
1512 @property
1513 def with_hostmask(self):
1514 return '%s/%s' % (str(self.network_address), str(self.hostmask))
1515
1516
1517class _BaseV6(object):
1518
1519 """Base IPv6 object.
1520
1521 The following methods are used by IPv6 objects in both single IP
1522 addresses and networks.
1523
1524 """
1525
1526 _ALL_ONES = (2**IPV6LENGTH) - 1
1527 _HEXTET_COUNT = 8
1528 _HEX_DIGITS = frozenset('0123456789ABCDEFabcdef')
1529
1530 def __init__(self, address):
1531 self._version = 6
1532 self._max_prefixlen = IPV6LENGTH
1533
1534 def _ip_int_from_string(self, ip_str):
1535 """Turn an IPv6 ip_str into an integer.
1536
1537 Args:
1538 ip_str: A string, the IPv6 ip_str.
1539
1540 Returns:
1541 An int, the IPv6 address
1542
1543 Raises:
1544 AddressValueError: if ip_str isn't a valid IPv6 Address.
1545
1546 """
1547 parts = ip_str.split(':')
1548
1549 # An IPv6 address needs at least 2 colons (3 parts).
1550 if len(parts) < 3:
1551 raise AddressValueError(ip_str)
1552
1553 # If the address has an IPv4-style suffix, convert it to hexadecimal.
1554 if '.' in parts[-1]:
1555 ipv4_int = IPv4Address(parts.pop())._ip
1556 parts.append('%x' % ((ipv4_int >> 16) & 0xFFFF))
1557 parts.append('%x' % (ipv4_int & 0xFFFF))
1558
1559 # An IPv6 address can't have more than 8 colons (9 parts).
1560 if len(parts) > self._HEXTET_COUNT + 1:
1561 raise AddressValueError(ip_str)
1562
1563 # Disregarding the endpoints, find '::' with nothing in between.
1564 # This indicates that a run of zeroes has been skipped.
1565 try:
1566 skip_index, = (
1567 [i for i in range(1, len(parts) - 1) if not parts[i]] or
1568 [None])
1569 except ValueError:
1570 # Can't have more than one '::'
1571 raise AddressValueError(ip_str)
1572
1573 # parts_hi is the number of parts to copy from above/before the '::'
1574 # parts_lo is the number of parts to copy from below/after the '::'
1575 if skip_index is not None:
1576 # If we found a '::', then check if it also covers the endpoints.
1577 parts_hi = skip_index
1578 parts_lo = len(parts) - skip_index - 1
1579 if not parts[0]:
1580 parts_hi -= 1
1581 if parts_hi:
1582 raise AddressValueError(ip_str) # ^: requires ^::
1583 if not parts[-1]:
1584 parts_lo -= 1
1585 if parts_lo:
1586 raise AddressValueError(ip_str) # :$ requires ::$
1587 parts_skipped = self._HEXTET_COUNT - (parts_hi + parts_lo)
1588 if parts_skipped < 1:
1589 raise AddressValueError(ip_str)
1590 else:
Hynek Schlawack072b1e12012-05-26 12:04:56 +02001591 # Otherwise, allocate the entire address to parts_hi. The
1592 # endpoints could still be empty, but _parse_hextet() will check
1593 # for that.
Nick Coghlandc9b2552012-05-20 21:01:57 +10001594 if len(parts) != self._HEXTET_COUNT:
1595 raise AddressValueError(ip_str)
1596 parts_hi = len(parts)
1597 parts_lo = 0
1598 parts_skipped = 0
1599
1600 try:
1601 # Now, parse the hextets into a 128-bit integer.
1602 ip_int = 0
1603 for i in range(parts_hi):
1604 ip_int <<= 16
1605 ip_int |= self._parse_hextet(parts[i])
1606 ip_int <<= 16 * parts_skipped
1607 for i in range(-parts_lo, 0):
1608 ip_int <<= 16
1609 ip_int |= self._parse_hextet(parts[i])
1610 return ip_int
1611 except ValueError:
1612 raise AddressValueError(ip_str)
1613
1614 def _parse_hextet(self, hextet_str):
1615 """Convert an IPv6 hextet string into an integer.
1616
1617 Args:
1618 hextet_str: A string, the number to parse.
1619
1620 Returns:
1621 The hextet as an integer.
1622
1623 Raises:
Hynek Schlawack072b1e12012-05-26 12:04:56 +02001624 ValueError: if the input isn't strictly a hex number from
1625 [0..FFFF].
Nick Coghlandc9b2552012-05-20 21:01:57 +10001626
1627 """
1628 # Whitelist the characters, since int() allows a lot of bizarre stuff.
1629 if not self._HEX_DIGITS.issuperset(hextet_str):
1630 raise ValueError
1631 hextet_int = int(hextet_str, 16)
1632 if hextet_int > 0xFFFF:
1633 raise ValueError
1634 return hextet_int
1635
1636 def _compress_hextets(self, hextets):
1637 """Compresses a list of hextets.
1638
1639 Compresses a list of strings, replacing the longest continuous
1640 sequence of "0" in the list with "" and adding empty strings at
1641 the beginning or at the end of the string such that subsequently
1642 calling ":".join(hextets) will produce the compressed version of
1643 the IPv6 address.
1644
1645 Args:
1646 hextets: A list of strings, the hextets to compress.
1647
1648 Returns:
1649 A list of strings.
1650
1651 """
1652 best_doublecolon_start = -1
1653 best_doublecolon_len = 0
1654 doublecolon_start = -1
1655 doublecolon_len = 0
1656 for index in range(len(hextets)):
1657 if hextets[index] == '0':
1658 doublecolon_len += 1
1659 if doublecolon_start == -1:
1660 # Start of a sequence of zeros.
1661 doublecolon_start = index
1662 if doublecolon_len > best_doublecolon_len:
1663 # This is the longest sequence of zeros so far.
1664 best_doublecolon_len = doublecolon_len
1665 best_doublecolon_start = doublecolon_start
1666 else:
1667 doublecolon_len = 0
1668 doublecolon_start = -1
1669
1670 if best_doublecolon_len > 1:
1671 best_doublecolon_end = (best_doublecolon_start +
1672 best_doublecolon_len)
1673 # For zeros at the end of the address.
1674 if best_doublecolon_end == len(hextets):
1675 hextets += ['']
1676 hextets[best_doublecolon_start:best_doublecolon_end] = ['']
1677 # For zeros at the beginning of the address.
1678 if best_doublecolon_start == 0:
1679 hextets = [''] + hextets
1680
1681 return hextets
1682
1683 def _string_from_ip_int(self, ip_int=None):
1684 """Turns a 128-bit integer into hexadecimal notation.
1685
1686 Args:
1687 ip_int: An integer, the IP address.
1688
1689 Returns:
1690 A string, the hexadecimal representation of the address.
1691
1692 Raises:
1693 ValueError: The address is bigger than 128 bits of all ones.
1694
1695 """
1696 if not ip_int and ip_int != 0:
1697 ip_int = int(self._ip)
1698
1699 if ip_int > self._ALL_ONES:
1700 raise ValueError('IPv6 address is too large')
1701
1702 hex_str = '%032x' % ip_int
1703 hextets = []
1704 for x in range(0, 32, 4):
1705 hextets.append('%x' % int(hex_str[x:x+4], 16))
1706
1707 hextets = self._compress_hextets(hextets)
1708 return ':'.join(hextets)
1709
1710 def _explode_shorthand_ip_string(self):
1711 """Expand a shortened IPv6 address.
1712
1713 Args:
1714 ip_str: A string, the IPv6 address.
1715
1716 Returns:
1717 A string, the expanded IPv6 address.
1718
1719 """
1720 if isinstance(self, IPv6Network):
1721 ip_str = str(self.network_address)
1722 elif isinstance(self, IPv6Interface):
1723 ip_str = str(self.ip)
1724 else:
1725 ip_str = str(self)
1726
1727 ip_int = self._ip_int_from_string(ip_str)
1728 parts = []
1729 for i in range(self._HEXTET_COUNT):
1730 parts.append('%04x' % (ip_int & 0xFFFF))
1731 ip_int >>= 16
1732 parts.reverse()
1733 if isinstance(self, (_BaseNetwork, IPv6Interface)):
1734 return '%s/%d' % (':'.join(parts), self.prefixlen)
1735 return ':'.join(parts)
1736
1737 @property
1738 def max_prefixlen(self):
1739 return self._max_prefixlen
1740
1741 @property
1742 def packed(self):
1743 """The binary representation of this address."""
1744 return v6_int_to_packed(self._ip)
1745
1746 @property
1747 def version(self):
1748 return self._version
1749
1750 @property
1751 def is_multicast(self):
1752 """Test if the address is reserved for multicast use.
1753
1754 Returns:
1755 A boolean, True if the address is a multicast address.
1756 See RFC 2373 2.7 for details.
1757
1758 """
1759 multicast_network = IPv6Network('ff00::/8')
1760 if isinstance(self, _BaseAddress):
1761 return self in multicast_network
1762 return (self.network_address in multicast_network and
1763 self.broadcast_address in multicast_network)
1764
1765 @property
1766 def is_reserved(self):
1767 """Test if the address is otherwise IETF reserved.
1768
1769 Returns:
1770 A boolean, True if the address is within one of the
1771 reserved IPv6 Network ranges.
1772
1773 """
1774 reserved_networks = [IPv6Network('::/8'), IPv6Network('100::/8'),
1775 IPv6Network('200::/7'), IPv6Network('400::/6'),
1776 IPv6Network('800::/5'), IPv6Network('1000::/4'),
1777 IPv6Network('4000::/3'), IPv6Network('6000::/3'),
1778 IPv6Network('8000::/3'), IPv6Network('A000::/3'),
1779 IPv6Network('C000::/3'), IPv6Network('E000::/4'),
1780 IPv6Network('F000::/5'), IPv6Network('F800::/6'),
1781 IPv6Network('FE00::/9')]
1782
1783 if isinstance(self, _BaseAddress):
1784 return len([x for x in reserved_networks if self in x]) > 0
1785 return len([x for x in reserved_networks if self.network_address in x
1786 and self.broadcast_address in x]) > 0
1787
1788 @property
1789 def is_link_local(self):
1790 """Test if the address is reserved for link-local.
1791
1792 Returns:
1793 A boolean, True if the address is reserved per RFC 4291.
1794
1795 """
1796 linklocal_network = IPv6Network('fe80::/10')
1797 if isinstance(self, _BaseAddress):
1798 return self in linklocal_network
1799 return (self.network_address in linklocal_network and
1800 self.broadcast_address in linklocal_network)
1801
1802 @property
1803 def is_site_local(self):
1804 """Test if the address is reserved for site-local.
1805
1806 Note that the site-local address space has been deprecated by RFC 3879.
1807 Use is_private to test if this address is in the space of unique local
1808 addresses as defined by RFC 4193.
1809
1810 Returns:
1811 A boolean, True if the address is reserved per RFC 3513 2.5.6.
1812
1813 """
1814 sitelocal_network = IPv6Network('fec0::/10')
1815 if isinstance(self, _BaseAddress):
1816 return self in sitelocal_network
1817 return (self.network_address in sitelocal_network and
1818 self.broadcast_address in sitelocal_network)
1819
1820 @property
1821 def is_private(self):
1822 """Test if this address is allocated for private networks.
1823
1824 Returns:
1825 A boolean, True if the address is reserved per RFC 4193.
1826
1827 """
1828 private_network = IPv6Network('fc00::/7')
1829 if isinstance(self, _BaseAddress):
1830 return self in private_network
1831 return (self.network_address in private_network and
1832 self.broadcast_address in private_network)
1833
Nick Coghlandc9b2552012-05-20 21:01:57 +10001834 @property
1835 def ipv4_mapped(self):
1836 """Return the IPv4 mapped address.
1837
1838 Returns:
1839 If the IPv6 address is a v4 mapped address, return the
1840 IPv4 mapped address. Return None otherwise.
1841
1842 """
1843 if (self._ip >> 32) != 0xFFFF:
1844 return None
1845 return IPv4Address(self._ip & 0xFFFFFFFF)
1846
1847 @property
1848 def teredo(self):
1849 """Tuple of embedded teredo IPs.
1850
1851 Returns:
1852 Tuple of the (server, client) IPs or None if the address
1853 doesn't appear to be a teredo address (doesn't start with
1854 2001::/32)
1855
1856 """
1857 if (self._ip >> 96) != 0x20010000:
1858 return None
1859 return (IPv4Address((self._ip >> 64) & 0xFFFFFFFF),
1860 IPv4Address(~self._ip & 0xFFFFFFFF))
1861
1862 @property
1863 def sixtofour(self):
1864 """Return the IPv4 6to4 embedded address.
1865
1866 Returns:
1867 The IPv4 6to4-embedded address if present or None if the
1868 address doesn't appear to contain a 6to4 embedded address.
1869
1870 """
1871 if (self._ip >> 112) != 0x2002:
1872 return None
1873 return IPv4Address((self._ip >> 80) & 0xFFFFFFFF)
1874
1875 @property
1876 def is_unspecified(self):
1877 """Test if the address is unspecified.
1878
1879 Returns:
1880 A boolean, True if this is the unspecified address as defined in
1881 RFC 2373 2.5.2.
1882
1883 """
1884 if isinstance(self, (IPv6Network, IPv6Interface)):
1885 return int(self.network_address) == 0 and getattr(
1886 self, '_prefixlen', 128) == 128
1887 return self._ip == 0
1888
1889 @property
1890 def is_loopback(self):
1891 """Test if the address is a loopback address.
1892
1893 Returns:
1894 A boolean, True if the address is a loopback address as defined in
1895 RFC 2373 2.5.3.
1896
1897 """
1898 if isinstance(self, IPv6Network):
Nick Coghlan2c589102012-05-27 01:03:25 +10001899 return int(self) == 1 and getattr(
Nick Coghlandc9b2552012-05-20 21:01:57 +10001900 self, '_prefixlen', 128) == 128
1901 elif isinstance(self, IPv6Interface):
1902 return int(self.network.network_address) == 1 and getattr(
1903 self, '_prefixlen', 128) == 128
1904 return self._ip == 1
1905
1906
1907class IPv6Address(_BaseV6, _BaseAddress):
1908
Sandro Tosib95c6342012-05-23 23:17:22 +02001909 """Represent and manipulate single IPv6 Addresses."""
Nick Coghlandc9b2552012-05-20 21:01:57 +10001910
1911 def __init__(self, address):
1912 """Instantiate a new IPv6 address object.
1913
1914 Args:
1915 address: A string or integer representing the IP
1916
1917 Additionally, an integer can be passed, so
1918 IPv6Address('2001:db8::') ==
1919 IPv6Address(42540766411282592856903984951653826560)
1920 or, more generally
1921 IPv6Address(int(IPv6Address('2001:db8::'))) ==
1922 IPv6Address('2001:db8::')
1923
1924 Raises:
1925 AddressValueError: If address isn't a valid IPv6 address.
1926
1927 """
1928 _BaseAddress.__init__(self, address)
1929 _BaseV6.__init__(self, address)
1930
1931 # Efficient constructor from integer.
1932 if isinstance(address, int):
1933 self._ip = address
1934 if address < 0 or address > self._ALL_ONES:
1935 raise AddressValueError(address)
1936 return
1937
1938 # Constructing from a packed address
1939 if isinstance(address, bytes) and len(address) == 16:
1940 tmp = struct.unpack('!QQ', address)
1941 self._ip = (tmp[0] << 64) | tmp[1]
1942 return
1943
1944 # Assume input argument to be string or any object representation
1945 # which converts into a formatted IP string.
1946 addr_str = str(address)
1947 if not addr_str:
1948 raise AddressValueError('')
1949
1950 self._ip = self._ip_int_from_string(addr_str)
1951
1952
1953class IPv6Interface(IPv6Address):
1954
1955 def __init__(self, address):
1956 if isinstance(address, (bytes, int)):
1957 IPv6Address.__init__(self, address)
1958 self.network = IPv6Network(self._ip)
1959 self._prefixlen = self._max_prefixlen
1960 return
1961
1962 addr = str(address).split('/')
1963 IPv6Address.__init__(self, addr[0])
1964 self.network = IPv6Network(address, strict=False)
1965 self.netmask = self.network.netmask
1966 self._prefixlen = self.network._prefixlen
1967 self.hostmask = self.network.hostmask
1968
Nick Coghlandc9b2552012-05-20 21:01:57 +10001969 def __str__(self):
1970 return '%s/%d' % (self._string_from_ip_int(self._ip),
1971 self.network.prefixlen)
1972
1973 def __eq__(self, other):
1974 try:
1975 return (IPv6Address.__eq__(self, other) and
1976 self.network == other.network)
1977 except AttributeError:
1978 return NotImplemented
1979
1980 def __hash__(self):
1981 return self._ip ^ self._prefixlen ^ int(self.network.network_address)
1982
1983 @property
1984 def prefixlen(self):
1985 return self._prefixlen
Hynek Schlawack072b1e12012-05-26 12:04:56 +02001986
Nick Coghlandc9b2552012-05-20 21:01:57 +10001987 @property
1988 def ip(self):
1989 return IPv6Address(self._ip)
1990
1991 @property
1992 def with_prefixlen(self):
1993 return self
1994
1995 @property
1996 def with_netmask(self):
1997 return self.with_prefixlen
Hynek Schlawack072b1e12012-05-26 12:04:56 +02001998
Nick Coghlandc9b2552012-05-20 21:01:57 +10001999 @property
2000 def with_hostmask(self):
2001 return '%s/%s' % (self._string_from_ip_int(self._ip),
2002 self.hostmask)
2003
2004
2005class IPv6Network(_BaseV6, _BaseNetwork):
2006
2007 """This class represents and manipulates 128-bit IPv6 networks.
2008
2009 Attributes: [examples for IPv6('2001:db8::1000/124')]
2010 .network_address: IPv6Address('2001:db8::1000')
2011 .hostmask: IPv6Address('::f')
2012 .broadcast_address: IPv6Address('2001:db8::100f')
2013 .netmask: IPv6Address('ffff:ffff:ffff:ffff:ffff:ffff:ffff:fff0')
2014 .prefixlen: 124
2015
2016 """
2017
Nick Coghlan51c30672012-05-27 00:25:58 +10002018 # Class to use when creating address objects
2019 # TODO (ncoghlan): Investigate using IPv6Interface instead
2020 _address_class = IPv6Address
2021
Nick Coghlandc9b2552012-05-20 21:01:57 +10002022 def __init__(self, address, strict=True):
2023 """Instantiate a new IPv6 Network object.
2024
2025 Args:
Hynek Schlawack072b1e12012-05-26 12:04:56 +02002026 address: A string or integer representing the IPv6 network or the
2027 IP and prefix/netmask.
Nick Coghlandc9b2552012-05-20 21:01:57 +10002028 '2001:db8::/128'
2029 '2001:db8:0000:0000:0000:0000:0000:0000/128'
2030 '2001:db8::'
2031 are all functionally the same in IPv6. That is to say,
2032 failing to provide a subnetmask will create an object with
2033 a mask of /128.
2034
2035 Additionally, an integer can be passed, so
2036 IPv6Network('2001:db8::') ==
2037 IPv6Network(42540766411282592856903984951653826560)
2038 or, more generally
2039 IPv6Network(int(IPv6Network('2001:db8::'))) ==
2040 IPv6Network('2001:db8::')
2041
2042 strict: A boolean. If true, ensure that we have been passed
2043 A true network address, eg, 2001:db8::1000/124 and not an
2044 IP address on a network, eg, 2001:db8::1/124.
2045
2046 Raises:
2047 AddressValueError: If address isn't a valid IPv6 address.
2048 NetmaskValueError: If the netmask isn't valid for
2049 an IPv6 address.
2050 ValueError: If strict was True and a network address was not
2051 supplied.
2052
2053 """
2054 _BaseV6.__init__(self, address)
2055 _BaseNetwork.__init__(self, address)
2056
2057 # Efficient constructor from integer.
2058 if isinstance(address, int):
2059 if address < 0 or address > self._ALL_ONES:
2060 raise AddressValueError(address)
2061 self.network_address = IPv6Address(address)
2062 self._prefixlen = self._max_prefixlen
2063 self.netmask = IPv6Address(self._ALL_ONES)
2064 if strict:
2065 if (IPv6Address(int(self.network_address) &
2066 int(self.netmask)) != self.network_address):
2067 raise ValueError('%s has host bits set' % str(self))
2068 self.network_address = IPv6Address(int(self.network_address) &
2069 int(self.netmask))
2070 return
2071
2072 # Constructing from a packed address
2073 if isinstance(address, bytes) and len(address) == 16:
2074 tmp = struct.unpack('!QQ', address)
2075 self.network_address = IPv6Address((tmp[0] << 64) | tmp[1])
2076 self._prefixlen = self._max_prefixlen
2077 self.netmask = IPv6Address(self._ALL_ONES)
2078 if strict:
2079 if (IPv6Address(int(self.network_address) &
2080 int(self.netmask)) != self.network_address):
2081 raise ValueError('%s has host bits set' % str(self))
2082 self.network_address = IPv6Address(int(self.network_address) &
2083 int(self.netmask))
2084 return
2085
2086 # Assume input argument to be string or any object representation
2087 # which converts into a formatted IP prefix string.
2088 addr = str(address).split('/')
2089
2090 if len(addr) > 2:
2091 raise AddressValueError(address)
2092
2093 self.network_address = IPv6Address(self._ip_int_from_string(addr[0]))
2094
2095 if len(addr) == 2:
2096 if self._is_valid_netmask(addr[1]):
2097 self._prefixlen = int(addr[1])
2098 else:
2099 raise NetmaskValueError(addr[1])
2100 else:
2101 self._prefixlen = self._max_prefixlen
2102
2103 self.netmask = IPv6Address(self._ip_int_from_prefix(self._prefixlen))
2104 if strict:
2105 if (IPv6Address(int(self.network_address) & int(self.netmask)) !=
2106 self.network_address):
2107 raise ValueError('%s has host bits set' % str(self))
2108 self.network_address = IPv6Address(int(self.network_address) &
2109 int(self.netmask))
2110
2111 if self._prefixlen == (self._max_prefixlen - 1):
2112 self.hosts = self.__iter__
2113
2114 def __str__(self):
2115 return '%s/%d' % (str(self.network_address),
2116 self.prefixlen)
2117
2118 def _is_valid_netmask(self, prefixlen):
2119 """Verify that the netmask/prefixlen is valid.
2120
2121 Args:
2122 prefixlen: A string, the netmask in prefix length format.
2123
2124 Returns:
2125 A boolean, True if the prefix represents a valid IPv6
2126 netmask.
2127
2128 """
2129 try:
2130 prefixlen = int(prefixlen)
2131 except ValueError:
2132 return False
2133 return 0 <= prefixlen <= self._max_prefixlen
2134
2135 @property
Nick Coghlandc9b2552012-05-20 21:01:57 +10002136 def with_prefixlen(self):
2137 return '%s/%d' % (str(self.network_address), self._prefixlen)
2138
2139 @property
2140 def with_netmask(self):
2141 return '%s/%s' % (str(self.network_address), str(self.netmask))
2142
2143 @property
2144 def with_hostmask(self):
2145 return '%s/%s' % (str(self.network_address), str(self.hostmask))