blob: 1d72bbc91c612c103d8dfb6fb7e5af9c9ed5c1bf [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
713 def network(self):
Nick Coghlan51c30672012-05-27 00:25:58 +1000714 # XXX (ncoghlan): This is redundant now and will likely be removed
715 return self.__class__('%s/%d' % (str(self.network_address),
716 self.prefixlen))
Nick Coghlandc9b2552012-05-20 21:01:57 +1000717
718 @property
719 def with_prefixlen(self):
720 return '%s/%d' % (str(self.ip), self._prefixlen)
721
722 @property
723 def with_netmask(self):
724 return '%s/%s' % (str(self.ip), str(self.netmask))
725
726 @property
727 def with_hostmask(self):
728 return '%s/%s' % (str(self.ip), str(self.hostmask))
729
730 @property
731 def num_addresses(self):
732 """Number of hosts in the current subnet."""
733 return int(self.broadcast_address) - int(self.network_address) + 1
734
735 @property
736 def version(self):
737 raise NotImplementedError('BaseNet has no version')
738
739 @property
Nick Coghlan51c30672012-05-27 00:25:58 +1000740 def _address_class(self):
741 raise NotImplementedError('BaseNet has no associated address class')
742
743 @property
Nick Coghlandc9b2552012-05-20 21:01:57 +1000744 def prefixlen(self):
745 return self._prefixlen
746
747 def address_exclude(self, other):
748 """Remove an address from a larger block.
749
750 For example:
751
752 addr1 = ip_network('192.0.2.0/28')
753 addr2 = ip_network('192.0.2.1/32')
754 addr1.address_exclude(addr2) =
755 [IPv4Network('192.0.2.0/32'), IPv4Network('192.0.2.2/31'),
756 IPv4Network('192.0.2.4/30'), IPv4Network('192.0.2.8/29')]
757
758 or IPv6:
759
760 addr1 = ip_network('2001:db8::1/32')
761 addr2 = ip_network('2001:db8::1/128')
762 addr1.address_exclude(addr2) =
763 [ip_network('2001:db8::1/128'),
764 ip_network('2001:db8::2/127'),
765 ip_network('2001:db8::4/126'),
766 ip_network('2001:db8::8/125'),
767 ...
768 ip_network('2001:db8:8000::/33')]
769
770 Args:
771 other: An IPv4Network or IPv6Network object of the same type.
772
773 Returns:
774 An iterator of the the IPv(4|6)Network objects which is self
775 minus other.
776
777 Raises:
778 TypeError: If self and other are of difffering address
779 versions, or if other is not a network object.
780 ValueError: If other is not completely contained by self.
781
782 """
783 if not self._version == other._version:
784 raise TypeError("%s and %s are not of the same version" % (
785 str(self), str(other)))
786
787 if not isinstance(other, _BaseNetwork):
788 raise TypeError("%s is not a network object" % str(other))
789
790 if not (other.network_address >= self.network_address and
791 other.broadcast_address <= self.broadcast_address):
Hynek Schlawack072b1e12012-05-26 12:04:56 +0200792 raise ValueError('%s not contained in %s' % (other, self))
Nick Coghlandc9b2552012-05-20 21:01:57 +1000793 if other == self:
794 raise StopIteration
795
Nick Coghlandc9b2552012-05-20 21:01:57 +1000796 # Make sure we're comparing the network of other.
Nick Coghlan51c30672012-05-27 00:25:58 +1000797 other = other.__class__('%s/%s' % (str(other.network_address),
798 str(other.prefixlen)))
Nick Coghlandc9b2552012-05-20 21:01:57 +1000799
800 s1, s2 = self.subnets()
801 while s1 != other and s2 != other:
802 if (other.network_address >= s1.network_address and
803 other.broadcast_address <= s1.broadcast_address):
804 yield s2
805 s1, s2 = s1.subnets()
806 elif (other.network_address >= s2.network_address and
807 other.broadcast_address <= s2.broadcast_address):
808 yield s1
809 s1, s2 = s2.subnets()
810 else:
811 # If we got here, there's a bug somewhere.
812 raise AssertionError('Error performing exclusion: '
813 's1: %s s2: %s other: %s' %
814 (str(s1), str(s2), str(other)))
815 if s1 == other:
816 yield s2
817 elif s2 == other:
818 yield s1
819 else:
820 # If we got here, there's a bug somewhere.
821 raise AssertionError('Error performing exclusion: '
822 's1: %s s2: %s other: %s' %
823 (str(s1), str(s2), str(other)))
824
825 def compare_networks(self, other):
826 """Compare two IP objects.
827
828 This is only concerned about the comparison of the integer
829 representation of the network addresses. This means that the
830 host bits aren't considered at all in this method. If you want
831 to compare host bits, you can easily enough do a
832 'HostA._ip < HostB._ip'
833
834 Args:
835 other: An IP object.
836
837 Returns:
838 If the IP versions of self and other are the same, returns:
839
840 -1 if self < other:
841 eg: IPv4Network('192.0.2.0/25') < IPv4Network('192.0.2.128/25')
842 IPv6Network('2001:db8::1000/124') <
843 IPv6Network('2001:db8::2000/124')
844 0 if self == other
845 eg: IPv4Network('192.0.2.0/24') == IPv4Network('192.0.2.0/24')
846 IPv6Network('2001:db8::1000/124') ==
847 IPv6Network('2001:db8::1000/124')
848 1 if self > other
849 eg: IPv4Network('192.0.2.128/25') > IPv4Network('192.0.2.0/25')
850 IPv6Network('2001:db8::2000/124') >
851 IPv6Network('2001:db8::1000/124')
852
853 Raises:
854 TypeError if the IP versions are different.
855
856 """
857 # does this need to raise a ValueError?
858 if self._version != other._version:
859 raise TypeError('%s and %s are not of the same type' % (
860 str(self), str(other)))
861 # self._version == other._version below here:
862 if self.network_address < other.network_address:
863 return -1
864 if self.network_address > other.network_address:
865 return 1
866 # self.network_address == other.network_address below here:
867 if self.netmask < other.netmask:
868 return -1
869 if self.netmask > other.netmask:
870 return 1
871 return 0
872
873 def _get_networks_key(self):
874 """Network-only key function.
875
876 Returns an object that identifies this address' network and
877 netmask. This function is a suitable "key" argument for sorted()
878 and list.sort().
879
880 """
881 return (self._version, self.network_address, self.netmask)
882
883 def subnets(self, prefixlen_diff=1, new_prefix=None):
884 """The subnets which join to make the current subnet.
885
886 In the case that self contains only one IP
887 (self._prefixlen == 32 for IPv4 or self._prefixlen == 128
888 for IPv6), yield an iterator with just ourself.
889
890 Args:
891 prefixlen_diff: An integer, the amount the prefix length
892 should be increased by. This should not be set if
893 new_prefix is also set.
894 new_prefix: The desired new prefix length. This must be a
895 larger number (smaller prefix) than the existing prefix.
896 This should not be set if prefixlen_diff is also set.
897
898 Returns:
899 An iterator of IPv(4|6) objects.
900
901 Raises:
902 ValueError: The prefixlen_diff is too small or too large.
903 OR
904 prefixlen_diff and new_prefix are both set or new_prefix
905 is a smaller number than the current prefix (smaller
906 number means a larger network)
907
908 """
909 if self._prefixlen == self._max_prefixlen:
910 yield self
911 return
912
913 if new_prefix is not None:
914 if new_prefix < self._prefixlen:
915 raise ValueError('new prefix must be longer')
916 if prefixlen_diff != 1:
917 raise ValueError('cannot set prefixlen_diff and new_prefix')
918 prefixlen_diff = new_prefix - self._prefixlen
919
920 if prefixlen_diff < 0:
921 raise ValueError('prefix length diff must be > 0')
922 new_prefixlen = self._prefixlen + prefixlen_diff
923
924 if not self._is_valid_netmask(str(new_prefixlen)):
925 raise ValueError(
926 'prefix length diff %d is invalid for netblock %s' % (
927 new_prefixlen, str(self)))
928
Nick Coghlan51c30672012-05-27 00:25:58 +1000929 first = self.__class__('%s/%s' %
930 (str(self.network_address),
931 str(self._prefixlen + prefixlen_diff)))
Nick Coghlandc9b2552012-05-20 21:01:57 +1000932
933 yield first
934 current = first
935 while True:
936 broadcast = current.broadcast_address
937 if broadcast == self.broadcast_address:
938 return
Nick Coghlan51c30672012-05-27 00:25:58 +1000939 new_addr = self._address_class(int(broadcast) + 1)
940 current = self.__class__('%s/%s' % (str(new_addr),
941 str(new_prefixlen)))
Nick Coghlandc9b2552012-05-20 21:01:57 +1000942
943 yield current
944
945 def masked(self):
946 """Return the network object with the host bits masked out."""
Nick Coghlan51c30672012-05-27 00:25:58 +1000947 # XXX (ncoghlan): This is redundant now and will likely be removed
948 return self.__class__('%s/%d' % (self.network_address,
949 self._prefixlen))
Nick Coghlandc9b2552012-05-20 21:01:57 +1000950
951 def supernet(self, prefixlen_diff=1, new_prefix=None):
952 """The supernet containing the current network.
953
954 Args:
955 prefixlen_diff: An integer, the amount the prefix length of
956 the network should be decreased by. For example, given a
957 /24 network and a prefixlen_diff of 3, a supernet with a
958 /21 netmask is returned.
959
960 Returns:
961 An IPv4 network object.
962
963 Raises:
Hynek Schlawack072b1e12012-05-26 12:04:56 +0200964 ValueError: If self.prefixlen - prefixlen_diff < 0. I.e., you have
965 a negative prefix length.
Nick Coghlandc9b2552012-05-20 21:01:57 +1000966 OR
967 If prefixlen_diff and new_prefix are both set or new_prefix is a
968 larger number than the current prefix (larger number means a
969 smaller network)
970
971 """
972 if self._prefixlen == 0:
973 return self
974
975 if new_prefix is not None:
976 if new_prefix > self._prefixlen:
977 raise ValueError('new prefix must be shorter')
978 if prefixlen_diff != 1:
979 raise ValueError('cannot set prefixlen_diff and new_prefix')
980 prefixlen_diff = self._prefixlen - new_prefix
981
Nick Coghlandc9b2552012-05-20 21:01:57 +1000982 if self.prefixlen - prefixlen_diff < 0:
983 raise ValueError(
984 'current prefixlen is %d, cannot have a prefixlen_diff of %d' %
985 (self.prefixlen, prefixlen_diff))
986 # TODO (pmoody): optimize this.
Nick Coghlan51c30672012-05-27 00:25:58 +1000987 t = self.__class__('%s/%d' % (str(self.network_address),
988 self.prefixlen - prefixlen_diff),
989 strict=False)
990 return t.__class__('%s/%d' % (str(t.network_address), t.prefixlen))
Nick Coghlandc9b2552012-05-20 21:01:57 +1000991
992
993class _BaseV4(object):
994
995 """Base IPv4 object.
996
997 The following methods are used by IPv4 objects in both single IP
998 addresses and networks.
999
1000 """
1001
1002 # Equivalent to 255.255.255.255 or 32 bits of 1's.
1003 _ALL_ONES = (2**IPV4LENGTH) - 1
1004 _DECIMAL_DIGITS = frozenset('0123456789')
1005
1006 def __init__(self, address):
1007 self._version = 4
1008 self._max_prefixlen = IPV4LENGTH
1009
1010 def _explode_shorthand_ip_string(self):
1011 return str(self)
1012
1013 def _ip_int_from_string(self, ip_str):
1014 """Turn the given IP string into an integer for comparison.
1015
1016 Args:
1017 ip_str: A string, the IP ip_str.
1018
1019 Returns:
1020 The IP ip_str as an integer.
1021
1022 Raises:
1023 AddressValueError: if ip_str isn't a valid IPv4 Address.
1024
1025 """
1026 octets = ip_str.split('.')
1027 if len(octets) != 4:
1028 raise AddressValueError(ip_str)
1029
1030 packed_ip = 0
1031 for oc in octets:
1032 try:
1033 packed_ip = (packed_ip << 8) | self._parse_octet(oc)
1034 except ValueError:
1035 raise AddressValueError(ip_str)
1036 return packed_ip
1037
1038 def _parse_octet(self, octet_str):
1039 """Convert a decimal octet into an integer.
1040
1041 Args:
1042 octet_str: A string, the number to parse.
1043
1044 Returns:
1045 The octet as an integer.
1046
1047 Raises:
1048 ValueError: if the octet isn't strictly a decimal from [0..255].
1049
1050 """
1051 # Whitelist the characters, since int() allows a lot of bizarre stuff.
1052 if not self._DECIMAL_DIGITS.issuperset(octet_str):
1053 raise ValueError
1054 octet_int = int(octet_str, 10)
1055 # Disallow leading zeroes, because no clear standard exists on
1056 # whether these should be interpreted as decimal or octal.
1057 if octet_int > 255 or (octet_str[0] == '0' and len(octet_str) > 1):
1058 raise ValueError
1059 return octet_int
1060
1061 def _string_from_ip_int(self, ip_int):
1062 """Turns a 32-bit integer into dotted decimal notation.
1063
1064 Args:
1065 ip_int: An integer, the IP address.
1066
1067 Returns:
1068 The IP address as a string in dotted decimal notation.
1069
1070 """
1071 octets = []
1072 for _ in range(4):
1073 octets.insert(0, str(ip_int & 0xFF))
1074 ip_int >>= 8
1075 return '.'.join(octets)
1076
1077 @property
1078 def max_prefixlen(self):
1079 return self._max_prefixlen
1080
1081 @property
1082 def version(self):
1083 return self._version
1084
1085 @property
1086 def is_reserved(self):
1087 """Test if the address is otherwise IETF reserved.
1088
1089 Returns:
1090 A boolean, True if the address is within the
1091 reserved IPv4 Network range.
1092
1093 """
1094 reserved_network = IPv4Network('240.0.0.0/4')
1095 if isinstance(self, _BaseAddress):
1096 return self in reserved_network
1097 return (self.network_address in reserved_network and
1098 self.broadcast_address in reserved_network)
1099
1100 @property
1101 def is_private(self):
1102 """Test if this address is allocated for private networks.
1103
1104 Returns:
1105 A boolean, True if the address is reserved per RFC 1918.
1106
1107 """
1108 private_10 = IPv4Network('10.0.0.0/8')
1109 private_172 = IPv4Network('172.16.0.0/12')
1110 private_192 = IPv4Network('192.168.0.0/16')
1111 if isinstance(self, _BaseAddress):
1112 return (self in private_10 or self in private_172 or
1113 self in private_192)
1114 else:
1115 return ((self.network_address in private_10 and
1116 self.broadcast_address in private_10) or
1117 (self.network_address in private_172 and
1118 self.broadcast_address in private_172) or
1119 (self.network_address in private_192 and
1120 self.broadcast_address in private_192))
1121
1122 @property
1123 def is_multicast(self):
1124 """Test if the address is reserved for multicast use.
1125
1126 Returns:
1127 A boolean, True if the address is multicast.
1128 See RFC 3171 for details.
1129
1130 """
1131 multicast_network = IPv4Network('224.0.0.0/4')
1132 if isinstance(self, _BaseAddress):
1133 return self in IPv4Network('224.0.0.0/4')
1134 return (self.network_address in multicast_network and
1135 self.broadcast_address in multicast_network)
1136
1137 @property
1138 def is_unspecified(self):
1139 """Test if the address is unspecified.
1140
1141 Returns:
1142 A boolean, True if this is the unspecified address as defined in
1143 RFC 5735 3.
1144
1145 """
1146 unspecified_address = IPv4Address('0.0.0.0')
1147 if isinstance(self, _BaseAddress):
1148 return self in unspecified_address
1149 return (self.network_address == self.broadcast_address ==
1150 unspecified_address)
1151
1152 @property
1153 def is_loopback(self):
1154 """Test if the address is a loopback address.
1155
1156 Returns:
1157 A boolean, True if the address is a loopback per RFC 3330.
1158
1159 """
1160 loopback_address = IPv4Network('127.0.0.0/8')
1161 if isinstance(self, _BaseAddress):
1162 return self in loopback_address
1163
1164 return (self.network_address in loopback_address and
1165 self.broadcast_address in loopback_address)
1166
1167 @property
1168 def is_link_local(self):
1169 """Test if the address is reserved for link-local.
1170
1171 Returns:
1172 A boolean, True if the address is link-local per RFC 3927.
1173
1174 """
1175 linklocal_network = IPv4Network('169.254.0.0/16')
1176 if isinstance(self, _BaseAddress):
1177 return self in linklocal_network
1178 return (self.network_address in linklocal_network and
1179 self.broadcast_address in linklocal_network)
1180
1181
1182class IPv4Address(_BaseV4, _BaseAddress):
1183
1184 """Represent and manipulate single IPv4 Addresses."""
1185
1186 def __init__(self, address):
1187
1188 """
1189 Args:
1190 address: A string or integer representing the IP
1191
1192 Additionally, an integer can be passed, so
1193 IPv4Address('192.0.2.1') == IPv4Address(3221225985).
1194 or, more generally
1195 IPv4Address(int(IPv4Address('192.0.2.1'))) ==
1196 IPv4Address('192.0.2.1')
1197
1198 Raises:
1199 AddressValueError: If ipaddressisn't a valid IPv4 address.
1200
1201 """
1202 _BaseAddress.__init__(self, address)
1203 _BaseV4.__init__(self, address)
1204
1205 # Efficient constructor from integer.
1206 if isinstance(address, int):
1207 self._ip = address
1208 if address < 0 or address > self._ALL_ONES:
1209 raise AddressValueError(address)
1210 return
1211
1212 # Constructing from a packed address
1213 if isinstance(address, bytes) and len(address) == 4:
1214 self._ip = struct.unpack('!I', address)[0]
1215 return
1216
1217 # Assume input argument to be string or any object representation
1218 # which converts into a formatted IP string.
1219 addr_str = str(address)
1220 self._ip = self._ip_int_from_string(addr_str)
1221
1222 @property
1223 def packed(self):
1224 """The binary representation of this address."""
1225 return v4_int_to_packed(self._ip)
1226
1227
1228class IPv4Interface(IPv4Address):
1229
1230 # the valid octets for host and netmasks. only useful for IPv4.
1231 _valid_mask_octets = set((255, 254, 252, 248, 240, 224, 192, 128, 0))
1232
1233 def __init__(self, address):
1234 if isinstance(address, (bytes, int)):
1235 IPv4Address.__init__(self, address)
1236 self.network = IPv4Network(self._ip)
1237 self._prefixlen = self._max_prefixlen
1238 return
1239
1240 addr = str(address).split('/')
1241 if len(addr) > 2:
1242 raise AddressValueError(address)
1243 IPv4Address.__init__(self, addr[0])
1244
1245 self.network = IPv4Network(address, strict=False)
1246 self._prefixlen = self.network._prefixlen
1247
1248 self.netmask = self.network.netmask
1249 self.hostmask = self.network.hostmask
1250
Nick Coghlandc9b2552012-05-20 21:01:57 +10001251 def __str__(self):
1252 return '%s/%d' % (self._string_from_ip_int(self._ip),
1253 self.network.prefixlen)
1254
1255 def __eq__(self, other):
1256 try:
1257 return (IPv4Address.__eq__(self, other) and
1258 self.network == other.network)
1259 except AttributeError:
1260 return NotImplemented
1261
1262 def __hash__(self):
1263 return self._ip ^ self._prefixlen ^ int(self.network.network_address)
1264
1265 def _is_valid_netmask(self, netmask):
1266 """Verify that the netmask is valid.
1267
1268 Args:
1269 netmask: A string, either a prefix or dotted decimal
1270 netmask.
1271
1272 Returns:
1273 A boolean, True if the prefix represents a valid IPv4
1274 netmask.
1275
1276 """
1277 mask = netmask.split('.')
1278 if len(mask) == 4:
1279 if [x for x in mask if int(x) not in self._valid_mask_octets]:
1280 return False
1281 if [y for idx, y in enumerate(mask) if idx > 0 and
1282 y > mask[idx - 1]]:
1283 return False
1284 return True
1285 try:
1286 netmask = int(netmask)
1287 except ValueError:
1288 return False
1289 return 0 <= netmask <= self._max_prefixlen
1290
1291 def _is_hostmask(self, ip_str):
1292 """Test if the IP string is a hostmask (rather than a netmask).
1293
1294 Args:
1295 ip_str: A string, the potential hostmask.
1296
1297 Returns:
1298 A boolean, True if the IP string is a hostmask.
1299
1300 """
1301 bits = ip_str.split('.')
1302 try:
1303 parts = [int(x) for x in bits if int(x) in self._valid_mask_octets]
1304 except ValueError:
1305 return False
1306 if len(parts) != len(bits):
1307 return False
1308 if parts[0] < parts[-1]:
1309 return True
1310 return False
1311
Nick Coghlandc9b2552012-05-20 21:01:57 +10001312 @property
1313 def prefixlen(self):
1314 return self._prefixlen
1315
1316 @property
1317 def ip(self):
1318 return IPv4Address(self._ip)
1319
1320 @property
1321 def with_prefixlen(self):
1322 return self
1323
1324 @property
1325 def with_netmask(self):
1326 return '%s/%s' % (self._string_from_ip_int(self._ip),
1327 self.netmask)
Hynek Schlawack072b1e12012-05-26 12:04:56 +02001328
Nick Coghlandc9b2552012-05-20 21:01:57 +10001329 @property
1330 def with_hostmask(self):
1331 return '%s/%s' % (self._string_from_ip_int(self._ip),
1332 self.hostmask)
1333
1334
1335class IPv4Network(_BaseV4, _BaseNetwork):
1336
1337 """This class represents and manipulates 32-bit IPv4 network + addresses..
1338
1339 Attributes: [examples for IPv4Network('192.0.2.0/27')]
1340 .network_address: IPv4Address('192.0.2.0')
1341 .hostmask: IPv4Address('0.0.0.31')
1342 .broadcast_address: IPv4Address('192.0.2.32')
1343 .netmask: IPv4Address('255.255.255.224')
1344 .prefixlen: 27
1345
1346 """
Nick Coghlan51c30672012-05-27 00:25:58 +10001347 # Class to use when creating address objects
1348 # TODO (ncoghlan): Investigate using IPv4Interface instead
1349 _address_class = IPv4Address
Nick Coghlandc9b2552012-05-20 21:01:57 +10001350
1351 # the valid octets for host and netmasks. only useful for IPv4.
1352 _valid_mask_octets = set((255, 254, 252, 248, 240, 224, 192, 128, 0))
1353
1354 def __init__(self, address, strict=True):
1355
1356 """Instantiate a new IPv4 network object.
1357
1358 Args:
1359 address: A string or integer representing the IP [& network].
1360 '192.0.2.0/24'
1361 '192.0.2.0/255.255.255.0'
1362 '192.0.0.2/0.0.0.255'
1363 are all functionally the same in IPv4. Similarly,
1364 '192.0.2.1'
1365 '192.0.2.1/255.255.255.255'
1366 '192.0.2.1/32'
1367 are also functionaly equivalent. That is to say, failing to
1368 provide a subnetmask will create an object with a mask of /32.
1369
1370 If the mask (portion after the / in the argument) is given in
1371 dotted quad form, it is treated as a netmask if it starts with a
1372 non-zero field (e.g. /255.0.0.0 == /8) and as a hostmask if it
1373 starts with a zero field (e.g. 0.255.255.255 == /8), with the
1374 single exception of an all-zero mask which is treated as a
1375 netmask == /0. If no mask is given, a default of /32 is used.
1376
1377 Additionally, an integer can be passed, so
1378 IPv4Network('192.0.2.1') == IPv4Network(3221225985)
1379 or, more generally
1380 IPv4Interface(int(IPv4Interface('192.0.2.1'))) ==
1381 IPv4Interface('192.0.2.1')
1382
1383 Raises:
1384 AddressValueError: If ipaddressisn't a valid IPv4 address.
1385 NetmaskValueError: If the netmask isn't valid for
1386 an IPv4 address.
1387 ValueError: If strict was True and a network address was not
1388 supplied.
1389
1390 """
1391
1392 _BaseV4.__init__(self, address)
1393 _BaseNetwork.__init__(self, address)
1394
1395 # Constructing from a packed address
1396 if isinstance(address, bytes) and len(address) == 4:
1397 self.network_address = IPv4Address(
1398 struct.unpack('!I', address)[0])
1399 self._prefixlen = self._max_prefixlen
1400 self.netmask = IPv4Address(self._ALL_ONES)
1401 #fixme: address/network test here
1402 return
1403
1404 # Efficient constructor from integer.
1405 if isinstance(address, int):
1406 self._prefixlen = self._max_prefixlen
1407 self.netmask = IPv4Address(self._ALL_ONES)
1408 if address < 0 or address > self._ALL_ONES:
1409 raise AddressValueError(address)
1410 self.network_address = IPv4Address(address)
1411 #fixme: address/network test here.
1412 return
1413
1414 # Assume input argument to be string or any object representation
1415 # which converts into a formatted IP prefix string.
1416 addr = str(address).split('/')
1417 self.network_address = IPv4Address(self._ip_int_from_string(addr[0]))
1418
1419 if len(addr) > 2:
1420 raise AddressValueError(address)
1421
1422 if len(addr) == 2:
1423 mask = addr[1].split('.')
1424
1425 if len(mask) == 4:
1426 # We have dotted decimal netmask.
1427 if self._is_valid_netmask(addr[1]):
1428 self.netmask = IPv4Address(self._ip_int_from_string(
1429 addr[1]))
1430 elif self._is_hostmask(addr[1]):
1431 self.netmask = IPv4Address(
1432 self._ip_int_from_string(addr[1]) ^ self._ALL_ONES)
1433 else:
1434 raise NetmaskValueError('%s is not a valid netmask'
1435 % addr[1])
1436
1437 self._prefixlen = self._prefix_from_ip_int(int(self.netmask))
1438 else:
1439 # We have a netmask in prefix length form.
1440 if not self._is_valid_netmask(addr[1]):
1441 raise NetmaskValueError(addr[1])
1442 self._prefixlen = int(addr[1])
1443 self.netmask = IPv4Address(self._ip_int_from_prefix(
1444 self._prefixlen))
1445 else:
1446 self._prefixlen = self._max_prefixlen
1447 self.netmask = IPv4Address(self._ip_int_from_prefix(
1448 self._prefixlen))
1449
1450 if strict:
1451 if (IPv4Address(int(self.network_address) & int(self.netmask)) !=
1452 self.network_address):
1453 raise ValueError('%s has host bits set' % self)
1454 self.network_address = IPv4Address(int(self.network_address) &
1455 int(self.netmask))
1456
1457 if self._prefixlen == (self._max_prefixlen - 1):
1458 self.hosts = self.__iter__
1459
1460 @property
1461 def packed(self):
1462 """The binary representation of this address."""
1463 return v4_int_to_packed(self.network_address)
1464
1465 def __str__(self):
1466 return '%s/%d' % (str(self.network_address),
1467 self.prefixlen)
1468
1469 def _is_valid_netmask(self, netmask):
1470 """Verify that the netmask is valid.
1471
1472 Args:
1473 netmask: A string, either a prefix or dotted decimal
1474 netmask.
1475
1476 Returns:
1477 A boolean, True if the prefix represents a valid IPv4
1478 netmask.
1479
1480 """
1481 mask = netmask.split('.')
1482 if len(mask) == 4:
1483 if [x for x in mask if int(x) not in self._valid_mask_octets]:
1484 return False
1485 if [y for idx, y in enumerate(mask) if idx > 0 and
1486 y > mask[idx - 1]]:
1487 return False
1488 return True
1489 try:
1490 netmask = int(netmask)
1491 except ValueError:
1492 return False
1493 return 0 <= netmask <= self._max_prefixlen
1494
1495 def _is_hostmask(self, ip_str):
1496 """Test if the IP string is a hostmask (rather than a netmask).
1497
1498 Args:
1499 ip_str: A string, the potential hostmask.
1500
1501 Returns:
1502 A boolean, True if the IP string is a hostmask.
1503
1504 """
1505 bits = ip_str.split('.')
1506 try:
1507 parts = [int(x) for x in bits if int(x) in self._valid_mask_octets]
1508 except ValueError:
1509 return False
1510 if len(parts) != len(bits):
1511 return False
1512 if parts[0] < parts[-1]:
1513 return True
1514 return False
1515
1516 @property
1517 def with_prefixlen(self):
1518 return '%s/%d' % (str(self.network_address), self._prefixlen)
1519
1520 @property
1521 def with_netmask(self):
1522 return '%s/%s' % (str(self.network_address), str(self.netmask))
1523
1524 @property
1525 def with_hostmask(self):
1526 return '%s/%s' % (str(self.network_address), str(self.hostmask))
1527
1528
1529class _BaseV6(object):
1530
1531 """Base IPv6 object.
1532
1533 The following methods are used by IPv6 objects in both single IP
1534 addresses and networks.
1535
1536 """
1537
1538 _ALL_ONES = (2**IPV6LENGTH) - 1
1539 _HEXTET_COUNT = 8
1540 _HEX_DIGITS = frozenset('0123456789ABCDEFabcdef')
1541
1542 def __init__(self, address):
1543 self._version = 6
1544 self._max_prefixlen = IPV6LENGTH
1545
1546 def _ip_int_from_string(self, ip_str):
1547 """Turn an IPv6 ip_str into an integer.
1548
1549 Args:
1550 ip_str: A string, the IPv6 ip_str.
1551
1552 Returns:
1553 An int, the IPv6 address
1554
1555 Raises:
1556 AddressValueError: if ip_str isn't a valid IPv6 Address.
1557
1558 """
1559 parts = ip_str.split(':')
1560
1561 # An IPv6 address needs at least 2 colons (3 parts).
1562 if len(parts) < 3:
1563 raise AddressValueError(ip_str)
1564
1565 # If the address has an IPv4-style suffix, convert it to hexadecimal.
1566 if '.' in parts[-1]:
1567 ipv4_int = IPv4Address(parts.pop())._ip
1568 parts.append('%x' % ((ipv4_int >> 16) & 0xFFFF))
1569 parts.append('%x' % (ipv4_int & 0xFFFF))
1570
1571 # An IPv6 address can't have more than 8 colons (9 parts).
1572 if len(parts) > self._HEXTET_COUNT + 1:
1573 raise AddressValueError(ip_str)
1574
1575 # Disregarding the endpoints, find '::' with nothing in between.
1576 # This indicates that a run of zeroes has been skipped.
1577 try:
1578 skip_index, = (
1579 [i for i in range(1, len(parts) - 1) if not parts[i]] or
1580 [None])
1581 except ValueError:
1582 # Can't have more than one '::'
1583 raise AddressValueError(ip_str)
1584
1585 # parts_hi is the number of parts to copy from above/before the '::'
1586 # parts_lo is the number of parts to copy from below/after the '::'
1587 if skip_index is not None:
1588 # If we found a '::', then check if it also covers the endpoints.
1589 parts_hi = skip_index
1590 parts_lo = len(parts) - skip_index - 1
1591 if not parts[0]:
1592 parts_hi -= 1
1593 if parts_hi:
1594 raise AddressValueError(ip_str) # ^: requires ^::
1595 if not parts[-1]:
1596 parts_lo -= 1
1597 if parts_lo:
1598 raise AddressValueError(ip_str) # :$ requires ::$
1599 parts_skipped = self._HEXTET_COUNT - (parts_hi + parts_lo)
1600 if parts_skipped < 1:
1601 raise AddressValueError(ip_str)
1602 else:
Hynek Schlawack072b1e12012-05-26 12:04:56 +02001603 # Otherwise, allocate the entire address to parts_hi. The
1604 # endpoints could still be empty, but _parse_hextet() will check
1605 # for that.
Nick Coghlandc9b2552012-05-20 21:01:57 +10001606 if len(parts) != self._HEXTET_COUNT:
1607 raise AddressValueError(ip_str)
1608 parts_hi = len(parts)
1609 parts_lo = 0
1610 parts_skipped = 0
1611
1612 try:
1613 # Now, parse the hextets into a 128-bit integer.
1614 ip_int = 0
1615 for i in range(parts_hi):
1616 ip_int <<= 16
1617 ip_int |= self._parse_hextet(parts[i])
1618 ip_int <<= 16 * parts_skipped
1619 for i in range(-parts_lo, 0):
1620 ip_int <<= 16
1621 ip_int |= self._parse_hextet(parts[i])
1622 return ip_int
1623 except ValueError:
1624 raise AddressValueError(ip_str)
1625
1626 def _parse_hextet(self, hextet_str):
1627 """Convert an IPv6 hextet string into an integer.
1628
1629 Args:
1630 hextet_str: A string, the number to parse.
1631
1632 Returns:
1633 The hextet as an integer.
1634
1635 Raises:
Hynek Schlawack072b1e12012-05-26 12:04:56 +02001636 ValueError: if the input isn't strictly a hex number from
1637 [0..FFFF].
Nick Coghlandc9b2552012-05-20 21:01:57 +10001638
1639 """
1640 # Whitelist the characters, since int() allows a lot of bizarre stuff.
1641 if not self._HEX_DIGITS.issuperset(hextet_str):
1642 raise ValueError
1643 hextet_int = int(hextet_str, 16)
1644 if hextet_int > 0xFFFF:
1645 raise ValueError
1646 return hextet_int
1647
1648 def _compress_hextets(self, hextets):
1649 """Compresses a list of hextets.
1650
1651 Compresses a list of strings, replacing the longest continuous
1652 sequence of "0" in the list with "" and adding empty strings at
1653 the beginning or at the end of the string such that subsequently
1654 calling ":".join(hextets) will produce the compressed version of
1655 the IPv6 address.
1656
1657 Args:
1658 hextets: A list of strings, the hextets to compress.
1659
1660 Returns:
1661 A list of strings.
1662
1663 """
1664 best_doublecolon_start = -1
1665 best_doublecolon_len = 0
1666 doublecolon_start = -1
1667 doublecolon_len = 0
1668 for index in range(len(hextets)):
1669 if hextets[index] == '0':
1670 doublecolon_len += 1
1671 if doublecolon_start == -1:
1672 # Start of a sequence of zeros.
1673 doublecolon_start = index
1674 if doublecolon_len > best_doublecolon_len:
1675 # This is the longest sequence of zeros so far.
1676 best_doublecolon_len = doublecolon_len
1677 best_doublecolon_start = doublecolon_start
1678 else:
1679 doublecolon_len = 0
1680 doublecolon_start = -1
1681
1682 if best_doublecolon_len > 1:
1683 best_doublecolon_end = (best_doublecolon_start +
1684 best_doublecolon_len)
1685 # For zeros at the end of the address.
1686 if best_doublecolon_end == len(hextets):
1687 hextets += ['']
1688 hextets[best_doublecolon_start:best_doublecolon_end] = ['']
1689 # For zeros at the beginning of the address.
1690 if best_doublecolon_start == 0:
1691 hextets = [''] + hextets
1692
1693 return hextets
1694
1695 def _string_from_ip_int(self, ip_int=None):
1696 """Turns a 128-bit integer into hexadecimal notation.
1697
1698 Args:
1699 ip_int: An integer, the IP address.
1700
1701 Returns:
1702 A string, the hexadecimal representation of the address.
1703
1704 Raises:
1705 ValueError: The address is bigger than 128 bits of all ones.
1706
1707 """
1708 if not ip_int and ip_int != 0:
1709 ip_int = int(self._ip)
1710
1711 if ip_int > self._ALL_ONES:
1712 raise ValueError('IPv6 address is too large')
1713
1714 hex_str = '%032x' % ip_int
1715 hextets = []
1716 for x in range(0, 32, 4):
1717 hextets.append('%x' % int(hex_str[x:x+4], 16))
1718
1719 hextets = self._compress_hextets(hextets)
1720 return ':'.join(hextets)
1721
1722 def _explode_shorthand_ip_string(self):
1723 """Expand a shortened IPv6 address.
1724
1725 Args:
1726 ip_str: A string, the IPv6 address.
1727
1728 Returns:
1729 A string, the expanded IPv6 address.
1730
1731 """
1732 if isinstance(self, IPv6Network):
1733 ip_str = str(self.network_address)
1734 elif isinstance(self, IPv6Interface):
1735 ip_str = str(self.ip)
1736 else:
1737 ip_str = str(self)
1738
1739 ip_int = self._ip_int_from_string(ip_str)
1740 parts = []
1741 for i in range(self._HEXTET_COUNT):
1742 parts.append('%04x' % (ip_int & 0xFFFF))
1743 ip_int >>= 16
1744 parts.reverse()
1745 if isinstance(self, (_BaseNetwork, IPv6Interface)):
1746 return '%s/%d' % (':'.join(parts), self.prefixlen)
1747 return ':'.join(parts)
1748
1749 @property
1750 def max_prefixlen(self):
1751 return self._max_prefixlen
1752
1753 @property
1754 def packed(self):
1755 """The binary representation of this address."""
1756 return v6_int_to_packed(self._ip)
1757
1758 @property
1759 def version(self):
1760 return self._version
1761
1762 @property
1763 def is_multicast(self):
1764 """Test if the address is reserved for multicast use.
1765
1766 Returns:
1767 A boolean, True if the address is a multicast address.
1768 See RFC 2373 2.7 for details.
1769
1770 """
1771 multicast_network = IPv6Network('ff00::/8')
1772 if isinstance(self, _BaseAddress):
1773 return self in multicast_network
1774 return (self.network_address in multicast_network and
1775 self.broadcast_address in multicast_network)
1776
1777 @property
1778 def is_reserved(self):
1779 """Test if the address is otherwise IETF reserved.
1780
1781 Returns:
1782 A boolean, True if the address is within one of the
1783 reserved IPv6 Network ranges.
1784
1785 """
1786 reserved_networks = [IPv6Network('::/8'), IPv6Network('100::/8'),
1787 IPv6Network('200::/7'), IPv6Network('400::/6'),
1788 IPv6Network('800::/5'), IPv6Network('1000::/4'),
1789 IPv6Network('4000::/3'), IPv6Network('6000::/3'),
1790 IPv6Network('8000::/3'), IPv6Network('A000::/3'),
1791 IPv6Network('C000::/3'), IPv6Network('E000::/4'),
1792 IPv6Network('F000::/5'), IPv6Network('F800::/6'),
1793 IPv6Network('FE00::/9')]
1794
1795 if isinstance(self, _BaseAddress):
1796 return len([x for x in reserved_networks if self in x]) > 0
1797 return len([x for x in reserved_networks if self.network_address in x
1798 and self.broadcast_address in x]) > 0
1799
1800 @property
1801 def is_link_local(self):
1802 """Test if the address is reserved for link-local.
1803
1804 Returns:
1805 A boolean, True if the address is reserved per RFC 4291.
1806
1807 """
1808 linklocal_network = IPv6Network('fe80::/10')
1809 if isinstance(self, _BaseAddress):
1810 return self in linklocal_network
1811 return (self.network_address in linklocal_network and
1812 self.broadcast_address in linklocal_network)
1813
1814 @property
1815 def is_site_local(self):
1816 """Test if the address is reserved for site-local.
1817
1818 Note that the site-local address space has been deprecated by RFC 3879.
1819 Use is_private to test if this address is in the space of unique local
1820 addresses as defined by RFC 4193.
1821
1822 Returns:
1823 A boolean, True if the address is reserved per RFC 3513 2.5.6.
1824
1825 """
1826 sitelocal_network = IPv6Network('fec0::/10')
1827 if isinstance(self, _BaseAddress):
1828 return self in sitelocal_network
1829 return (self.network_address in sitelocal_network and
1830 self.broadcast_address in sitelocal_network)
1831
1832 @property
1833 def is_private(self):
1834 """Test if this address is allocated for private networks.
1835
1836 Returns:
1837 A boolean, True if the address is reserved per RFC 4193.
1838
1839 """
1840 private_network = IPv6Network('fc00::/7')
1841 if isinstance(self, _BaseAddress):
1842 return self in private_network
1843 return (self.network_address in private_network and
1844 self.broadcast_address in private_network)
1845
Nick Coghlandc9b2552012-05-20 21:01:57 +10001846 @property
1847 def ipv4_mapped(self):
1848 """Return the IPv4 mapped address.
1849
1850 Returns:
1851 If the IPv6 address is a v4 mapped address, return the
1852 IPv4 mapped address. Return None otherwise.
1853
1854 """
1855 if (self._ip >> 32) != 0xFFFF:
1856 return None
1857 return IPv4Address(self._ip & 0xFFFFFFFF)
1858
1859 @property
1860 def teredo(self):
1861 """Tuple of embedded teredo IPs.
1862
1863 Returns:
1864 Tuple of the (server, client) IPs or None if the address
1865 doesn't appear to be a teredo address (doesn't start with
1866 2001::/32)
1867
1868 """
1869 if (self._ip >> 96) != 0x20010000:
1870 return None
1871 return (IPv4Address((self._ip >> 64) & 0xFFFFFFFF),
1872 IPv4Address(~self._ip & 0xFFFFFFFF))
1873
1874 @property
1875 def sixtofour(self):
1876 """Return the IPv4 6to4 embedded address.
1877
1878 Returns:
1879 The IPv4 6to4-embedded address if present or None if the
1880 address doesn't appear to contain a 6to4 embedded address.
1881
1882 """
1883 if (self._ip >> 112) != 0x2002:
1884 return None
1885 return IPv4Address((self._ip >> 80) & 0xFFFFFFFF)
1886
1887 @property
1888 def is_unspecified(self):
1889 """Test if the address is unspecified.
1890
1891 Returns:
1892 A boolean, True if this is the unspecified address as defined in
1893 RFC 2373 2.5.2.
1894
1895 """
1896 if isinstance(self, (IPv6Network, IPv6Interface)):
1897 return int(self.network_address) == 0 and getattr(
1898 self, '_prefixlen', 128) == 128
1899 return self._ip == 0
1900
1901 @property
1902 def is_loopback(self):
1903 """Test if the address is a loopback address.
1904
1905 Returns:
1906 A boolean, True if the address is a loopback address as defined in
1907 RFC 2373 2.5.3.
1908
1909 """
1910 if isinstance(self, IPv6Network):
1911 return int(self.network) == 1 and getattr(
1912 self, '_prefixlen', 128) == 128
1913 elif isinstance(self, IPv6Interface):
1914 return int(self.network.network_address) == 1 and getattr(
1915 self, '_prefixlen', 128) == 128
1916 return self._ip == 1
1917
1918
1919class IPv6Address(_BaseV6, _BaseAddress):
1920
Sandro Tosib95c6342012-05-23 23:17:22 +02001921 """Represent and manipulate single IPv6 Addresses."""
Nick Coghlandc9b2552012-05-20 21:01:57 +10001922
1923 def __init__(self, address):
1924 """Instantiate a new IPv6 address object.
1925
1926 Args:
1927 address: A string or integer representing the IP
1928
1929 Additionally, an integer can be passed, so
1930 IPv6Address('2001:db8::') ==
1931 IPv6Address(42540766411282592856903984951653826560)
1932 or, more generally
1933 IPv6Address(int(IPv6Address('2001:db8::'))) ==
1934 IPv6Address('2001:db8::')
1935
1936 Raises:
1937 AddressValueError: If address isn't a valid IPv6 address.
1938
1939 """
1940 _BaseAddress.__init__(self, address)
1941 _BaseV6.__init__(self, address)
1942
1943 # Efficient constructor from integer.
1944 if isinstance(address, int):
1945 self._ip = address
1946 if address < 0 or address > self._ALL_ONES:
1947 raise AddressValueError(address)
1948 return
1949
1950 # Constructing from a packed address
1951 if isinstance(address, bytes) and len(address) == 16:
1952 tmp = struct.unpack('!QQ', address)
1953 self._ip = (tmp[0] << 64) | tmp[1]
1954 return
1955
1956 # Assume input argument to be string or any object representation
1957 # which converts into a formatted IP string.
1958 addr_str = str(address)
1959 if not addr_str:
1960 raise AddressValueError('')
1961
1962 self._ip = self._ip_int_from_string(addr_str)
1963
1964
1965class IPv6Interface(IPv6Address):
1966
1967 def __init__(self, address):
1968 if isinstance(address, (bytes, int)):
1969 IPv6Address.__init__(self, address)
1970 self.network = IPv6Network(self._ip)
1971 self._prefixlen = self._max_prefixlen
1972 return
1973
1974 addr = str(address).split('/')
1975 IPv6Address.__init__(self, addr[0])
1976 self.network = IPv6Network(address, strict=False)
1977 self.netmask = self.network.netmask
1978 self._prefixlen = self.network._prefixlen
1979 self.hostmask = self.network.hostmask
1980
Nick Coghlandc9b2552012-05-20 21:01:57 +10001981 def __str__(self):
1982 return '%s/%d' % (self._string_from_ip_int(self._ip),
1983 self.network.prefixlen)
1984
1985 def __eq__(self, other):
1986 try:
1987 return (IPv6Address.__eq__(self, other) and
1988 self.network == other.network)
1989 except AttributeError:
1990 return NotImplemented
1991
1992 def __hash__(self):
1993 return self._ip ^ self._prefixlen ^ int(self.network.network_address)
1994
1995 @property
1996 def prefixlen(self):
1997 return self._prefixlen
Hynek Schlawack072b1e12012-05-26 12:04:56 +02001998
Nick Coghlandc9b2552012-05-20 21:01:57 +10001999 @property
2000 def ip(self):
2001 return IPv6Address(self._ip)
2002
2003 @property
2004 def with_prefixlen(self):
2005 return self
2006
2007 @property
2008 def with_netmask(self):
2009 return self.with_prefixlen
Hynek Schlawack072b1e12012-05-26 12:04:56 +02002010
Nick Coghlandc9b2552012-05-20 21:01:57 +10002011 @property
2012 def with_hostmask(self):
2013 return '%s/%s' % (self._string_from_ip_int(self._ip),
2014 self.hostmask)
2015
2016
2017class IPv6Network(_BaseV6, _BaseNetwork):
2018
2019 """This class represents and manipulates 128-bit IPv6 networks.
2020
2021 Attributes: [examples for IPv6('2001:db8::1000/124')]
2022 .network_address: IPv6Address('2001:db8::1000')
2023 .hostmask: IPv6Address('::f')
2024 .broadcast_address: IPv6Address('2001:db8::100f')
2025 .netmask: IPv6Address('ffff:ffff:ffff:ffff:ffff:ffff:ffff:fff0')
2026 .prefixlen: 124
2027
2028 """
2029
Nick Coghlan51c30672012-05-27 00:25:58 +10002030 # Class to use when creating address objects
2031 # TODO (ncoghlan): Investigate using IPv6Interface instead
2032 _address_class = IPv6Address
2033
Nick Coghlandc9b2552012-05-20 21:01:57 +10002034 def __init__(self, address, strict=True):
2035 """Instantiate a new IPv6 Network object.
2036
2037 Args:
Hynek Schlawack072b1e12012-05-26 12:04:56 +02002038 address: A string or integer representing the IPv6 network or the
2039 IP and prefix/netmask.
Nick Coghlandc9b2552012-05-20 21:01:57 +10002040 '2001:db8::/128'
2041 '2001:db8:0000:0000:0000:0000:0000:0000/128'
2042 '2001:db8::'
2043 are all functionally the same in IPv6. That is to say,
2044 failing to provide a subnetmask will create an object with
2045 a mask of /128.
2046
2047 Additionally, an integer can be passed, so
2048 IPv6Network('2001:db8::') ==
2049 IPv6Network(42540766411282592856903984951653826560)
2050 or, more generally
2051 IPv6Network(int(IPv6Network('2001:db8::'))) ==
2052 IPv6Network('2001:db8::')
2053
2054 strict: A boolean. If true, ensure that we have been passed
2055 A true network address, eg, 2001:db8::1000/124 and not an
2056 IP address on a network, eg, 2001:db8::1/124.
2057
2058 Raises:
2059 AddressValueError: If address isn't a valid IPv6 address.
2060 NetmaskValueError: If the netmask isn't valid for
2061 an IPv6 address.
2062 ValueError: If strict was True and a network address was not
2063 supplied.
2064
2065 """
2066 _BaseV6.__init__(self, address)
2067 _BaseNetwork.__init__(self, address)
2068
2069 # Efficient constructor from integer.
2070 if isinstance(address, int):
2071 if address < 0 or address > self._ALL_ONES:
2072 raise AddressValueError(address)
2073 self.network_address = IPv6Address(address)
2074 self._prefixlen = self._max_prefixlen
2075 self.netmask = IPv6Address(self._ALL_ONES)
2076 if strict:
2077 if (IPv6Address(int(self.network_address) &
2078 int(self.netmask)) != self.network_address):
2079 raise ValueError('%s has host bits set' % str(self))
2080 self.network_address = IPv6Address(int(self.network_address) &
2081 int(self.netmask))
2082 return
2083
2084 # Constructing from a packed address
2085 if isinstance(address, bytes) and len(address) == 16:
2086 tmp = struct.unpack('!QQ', address)
2087 self.network_address = IPv6Address((tmp[0] << 64) | tmp[1])
2088 self._prefixlen = self._max_prefixlen
2089 self.netmask = IPv6Address(self._ALL_ONES)
2090 if strict:
2091 if (IPv6Address(int(self.network_address) &
2092 int(self.netmask)) != self.network_address):
2093 raise ValueError('%s has host bits set' % str(self))
2094 self.network_address = IPv6Address(int(self.network_address) &
2095 int(self.netmask))
2096 return
2097
2098 # Assume input argument to be string or any object representation
2099 # which converts into a formatted IP prefix string.
2100 addr = str(address).split('/')
2101
2102 if len(addr) > 2:
2103 raise AddressValueError(address)
2104
2105 self.network_address = IPv6Address(self._ip_int_from_string(addr[0]))
2106
2107 if len(addr) == 2:
2108 if self._is_valid_netmask(addr[1]):
2109 self._prefixlen = int(addr[1])
2110 else:
2111 raise NetmaskValueError(addr[1])
2112 else:
2113 self._prefixlen = self._max_prefixlen
2114
2115 self.netmask = IPv6Address(self._ip_int_from_prefix(self._prefixlen))
2116 if strict:
2117 if (IPv6Address(int(self.network_address) & int(self.netmask)) !=
2118 self.network_address):
2119 raise ValueError('%s has host bits set' % str(self))
2120 self.network_address = IPv6Address(int(self.network_address) &
2121 int(self.netmask))
2122
2123 if self._prefixlen == (self._max_prefixlen - 1):
2124 self.hosts = self.__iter__
2125
2126 def __str__(self):
2127 return '%s/%d' % (str(self.network_address),
2128 self.prefixlen)
2129
2130 def _is_valid_netmask(self, prefixlen):
2131 """Verify that the netmask/prefixlen is valid.
2132
2133 Args:
2134 prefixlen: A string, the netmask in prefix length format.
2135
2136 Returns:
2137 A boolean, True if the prefix represents a valid IPv6
2138 netmask.
2139
2140 """
2141 try:
2142 prefixlen = int(prefixlen)
2143 except ValueError:
2144 return False
2145 return 0 <= prefixlen <= self._max_prefixlen
2146
2147 @property
Nick Coghlandc9b2552012-05-20 21:01:57 +10002148 def with_prefixlen(self):
2149 return '%s/%d' % (str(self.network_address), self._prefixlen)
2150
2151 @property
2152 def with_netmask(self):
2153 return '%s/%s' % (str(self.network_address), str(self.netmask))
2154
2155 @property
2156 def with_hostmask(self):
2157 return '%s/%s' % (str(self.network_address), str(self.hostmask))