Try to restore the old test_file and test_univnewlines as new, different files
[python.git] / Lib / ipaddr.py
bloba2d9e93ce095c4f55fafd56932f684b34b1c9846
1 # Copyright 2007 Google Inc.
2 # Licensed to PSF under a Contributor Agreement.
4 # See also: http://code.google.com/p/ipaddr-py/
6 """An IPv4/IPv6 manipulation library in Python.
8 This library is used to create/poke/manipulate IPv4 and IPv6 addresses
9 and prefixes.
11 """
13 __version__ = '1.1.1'
15 import struct
18 class Error(Exception):
20 """Base class for exceptions."""
23 class IPTypeError(Error):
25 """Tried to perform a v4 action on v6 object or vice versa."""
28 class IPAddressExclusionError(Error):
30 """An Error we should never see occurred in address exclusion."""
33 class IPv4IpValidationError(Error):
35 """Raised when an IPv4 address is invalid."""
37 def __init__(self, ip):
38 Error.__init__(self)
39 self.ip = ip
41 def __str__(self):
42 return repr(self.ip) + ' is not a valid IPv4 address'
45 class IPv4NetmaskValidationError(Error):
47 """Raised when a netmask is invalid."""
49 def __init__(self, netmask):
50 Error.__init__(self)
51 self.netmask = netmask
53 def __str__(self):
54 return repr(self.netmask) + ' is not a valid IPv4 netmask'
57 class IPv6IpValidationError(Error):
59 """Raised when an IPv6 address is invalid."""
61 def __init__(self, ip):
62 Error.__init__(self)
63 self.ip = ip
65 def __str__(self):
66 return repr(self.ip) + ' is not a valid IPv6 address'
69 class IPv6NetmaskValidationError(Error):
71 """Raised when an IPv6 netmask is invalid."""
73 def __init__(self, netmask):
74 Error.__init__(self)
75 self.netmask = netmask
77 def __str__(self):
78 return repr(self.netmask) + ' is not a valid IPv6 netmask'
81 class PrefixlenDiffInvalidError(Error):
83 """Raised when Sub/Supernets is called with a bad prefixlen_diff."""
85 def __init__(self, error_str):
86 Error.__init__(self)
87 self.error_str = error_str
90 def IP(ipaddr):
91 """Take an IP string/int and return an object of the correct type.
93 Args:
94 ipaddr: A string or integer, the IP address. Either IPv4 or
95 IPv6 addresses may be supplied; integers less than 2**32 will
96 be considered to be IPv4.
98 Returns:
99 An IPv4 or IPv6 object.
101 Raises:
102 ValueError: if the string passed isn't either a v4 or a v6
103 address.
107 try:
108 return IPv4(ipaddr)
109 except (IPv4IpValidationError, IPv4NetmaskValidationError):
110 pass
112 try:
113 return IPv6(ipaddr)
114 except (IPv6IpValidationError, IPv6NetmaskValidationError):
115 pass
117 raise ValueError('%r does not appear to be an IPv4 or IPv6 address' %
118 ipaddr)
121 def _collapse_address_list_recursive(addresses):
122 """Loops through the addresses, collapsing concurrent netblocks.
124 Example:
126 ip1 = IPv4('1.1.0.0/24')
127 ip2 = IPv4('1.1.1.0/24')
128 ip3 = IPv4('1.1.2.0/24')
129 ip4 = IPv4('1.1.3.0/24')
130 ip5 = IPv4('1.1.4.0/24')
131 ip6 = IPv4('1.1.0.1/22')
133 _collapse_address_list_recursive([ip1, ip2, ip3, ip4, ip5, ip6]) ->
134 [IPv4('1.1.0.0/22'), IPv4('1.1.4.0/24')]
136 This shouldn't be called directly; it is called via
137 collapse_address_list([]).
139 Args:
140 addresses: A list of IPv4 or IPv6 objects.
142 Returns:
143 A list of IPv4 or IPv6 objects depending on what we were passed.
146 ret_array = []
147 optimized = False
149 for cur_addr in addresses:
150 if not ret_array:
151 ret_array.append(cur_addr)
152 continue
153 if cur_addr in ret_array[-1]:
154 optimized = True
155 elif cur_addr == ret_array[-1].supernet().subnet()[1]:
156 ret_array.append(ret_array.pop().supernet())
157 optimized = True
158 else:
159 ret_array.append(cur_addr)
161 if optimized:
162 return _collapse_address_list_recursive(ret_array)
164 return ret_array
167 def collapse_address_list(addresses):
168 """Collapse a list of IP objects.
170 Example:
171 collapse_address_list([IPv4('1.1.0.0/24'), IPv4('1.1.1.0/24')]) ->
172 [IPv4('1.1.0.0/23')]
174 Args:
175 addresses: A list of IPv4 or IPv6 objects.
177 Returns:
178 A list of IPv4 or IPv6 objects depending on what we were passed.
181 return _collapse_address_list_recursive(
182 sorted(addresses, key=BaseIP._get_networks_key))
185 class BaseIP(object):
187 """A generic IP object.
189 This IP class contains most of the methods which are used by
190 the IPv4 and IPv6 classes.
194 def __getitem__(self, n):
195 if n >= 0:
196 if self.network + n > self.broadcast:
197 raise IndexError
198 return self._string_from_ip_int(self.network + n)
199 else:
200 n += 1
201 if self.broadcast + n < self.network:
202 raise IndexError
203 return self._string_from_ip_int(self.broadcast + n)
205 def __lt__(self, other):
206 try:
207 if self.version != other.version:
208 return self.version < other.version
209 if self.ip != other.ip:
210 return self.ip < other.ip
211 if self.netmask != other.netmask:
212 return self.netmask < other.netmask
213 return False
214 except AttributeError:
215 return NotImplemented
217 def __gt__(self, other):
218 try:
219 if self.version != other.version:
220 return self.version > other.version
221 if self.ip != other.ip:
222 return self.ip > other.ip
223 if self.netmask != other.netmask:
224 return self.netmask > other.netmask
225 return False
226 except AttributeError:
227 return NotImplemented
229 def __eq__(self, other):
230 try:
231 return (self.version == other.version
232 and self.ip == other.ip
233 and self.netmask == other.netmask)
234 except AttributeError:
235 return NotImplemented
237 def __ne__(self, other):
238 eq = self.__eq__(other)
239 if eq is NotImplemented:
240 return NotImplemented
241 return not eq
243 def __le__(self, other):
244 gt = self.__gt__(other)
245 if gt is NotImplemented:
246 return NotImplemented
247 return not gt
249 def __ge__(self, other):
250 lt = self.__lt__(other)
251 if lt is NotImplemented:
252 return NotImplemented
253 return not lt
255 def __repr__(self):
256 return '%s(%r)' % (self.__class__.__name__, str(self))
258 def __index__(self):
259 return self.ip
261 def __int__(self):
262 return self.ip
264 def __hex__(self):
265 return hex(int(self))
267 def address_exclude(self, other):
268 """Remove an address from a larger block.
270 For example:
272 addr1 = IP('10.1.1.0/24')
273 addr2 = IP('10.1.1.0/26')
274 addr1.address_exclude(addr2) =
275 [IP('10.1.1.64/26'), IP('10.1.1.128/25')]
277 or IPv6:
279 addr1 = IP('::1/32')
280 addr2 = IP('::1/128')
281 addr1.address_exclude(addr2) = [IP('::0/128'),
282 IP('::2/127'),
283 IP('::4/126'),
284 IP('::8/125'),
286 IP('0:0:8000::/33')]
288 Args:
289 other: An IP object of the same type.
291 Returns:
292 A sorted list of IP objects addresses which is self minus
293 other.
295 Raises:
296 IPTypeError: If self and other are of difffering address
297 versions.
298 IPAddressExclusionError: There was some unknown error in the
299 address exclusion process. This likely points to a bug
300 elsewhere in this code.
301 ValueError: If other is not completely contained by self.
304 if not self.version == other.version:
305 raise IPTypeError("%s and %s aren't of the same version" % (
306 str(self), str(other)))
308 if other not in self:
309 raise ValueError('%s not contained in %s' % (str(other),
310 str(self)))
312 ret_addrs = []
314 # Make sure we're comparing the network of other.
315 other = IP(other.network_ext + '/' + str(other.prefixlen))
317 s1, s2 = self.subnet()
318 while s1 != other and s2 != other:
319 if other in s1:
320 ret_addrs.append(s2)
321 s1, s2 = s1.subnet()
322 elif other in s2:
323 ret_addrs.append(s1)
324 s1, s2 = s2.subnet()
325 else:
326 # If we got here, there's a bug somewhere.
327 raise IPAddressExclusionError('Error performing exclusion: '
328 's1: %s s2: %s other: %s' %
329 (str(s1), str(s2), str(other)))
330 if s1 == other:
331 ret_addrs.append(s2)
332 elif s2 == other:
333 ret_addrs.append(s1)
334 else:
335 # If we got here, there's a bug somewhere.
336 raise IPAddressExclusionError('Error performing exclusion: '
337 's1: %s s2: %s other: %s' %
338 (str(s1), str(s2), str(other)))
340 return sorted(ret_addrs, key=BaseIP._get_networks_key)
342 def compare_networks(self, other):
343 """Compare two IP objects.
345 This is only concerned about the comparison of the integer
346 representation of the network addresses. This means that the
347 host bits aren't considered at all in this method. If you want
348 to compare host bits, you can easily enough do a
349 'HostA.ip < HostB.ip'
351 Args:
352 other: An IP object.
354 Returns:
355 If the IP versions of self and other are the same, returns:
357 -1 if self < other:
358 eg: IPv4('1.1.1.0/24') < IPv4('1.1.2.0/24')
359 IPv6('1080::200C:417A') < IPv6('1080::200B:417B')
360 0 if self == other
361 eg: IPv4('1.1.1.1/24') == IPv4('1.1.1.2/24')
362 IPv6('1080::200C:417A/96') == IPv6('1080::200C:417B/96')
363 1 if self > other
364 eg: IPv4('1.1.1.0/24') > IPv4('1.1.0.0/24')
365 IPv6('1080::1:200C:417A/112') >
366 IPv6('1080::0:200C:417A/112')
368 If the IP versions of self and other are different, returns:
370 -1 if self.version < other.version
371 eg: IPv4('10.0.0.1/24') < IPv6('::1/128')
372 1 if self.version > other.version
373 eg: IPv6('::1/128') > IPv4('255.255.255.0/24')
376 if self.version < other.version:
377 return -1
378 if self.version > other.version:
379 return 1
380 # self.version == other.version below here:
381 if self.network < other.network:
382 return -1
383 if self.network > other.network:
384 return 1
385 # self.network == other.network below here:
386 if self.netmask < other.netmask:
387 return -1
388 if self.netmask > other.netmask:
389 return 1
390 # self.network == other.network and self.netmask == other.netmask
391 return 0
393 def _get_networks_key(self):
394 """Network-only key function.
396 Returns an object that identifies this address' network and
397 netmask. This function is a suitable "key" argument for sorted()
398 and list.sort().
401 return (self.version, self.network, self.netmask)
403 prefixlen = property(
404 fget=lambda self: self._prefixlen,
405 fset=lambda self, prefixlen: self._set_prefix(prefixlen))
407 def __str__(self):
408 return '%s/%s' % (self._string_from_ip_int(self.ip),
409 str(self.prefixlen))
411 def __hash__(self):
412 return hash(self.ip ^ self.netmask)
414 def __contains__(self, other):
415 return self.network <= other.ip and self.broadcast >= other.broadcast
417 @property
418 def ip_ext(self):
419 """Dotted decimal or colon string version of the IP address."""
420 return self._string_from_ip_int(self.ip)
422 @property
423 def ip_ext_full(self):
424 """Canonical string version of the IP address."""
425 return self.ip_ext
427 @property
428 def broadcast(self):
429 """Integer representation of the broadcast address."""
430 return self.ip | self.hostmask
432 @property
433 def broadcast_ext(self):
434 """Dotted decimal or colon string version of the broadcast."""
435 return self._string_from_ip_int(self.broadcast)
437 @property
438 def hostmask(self):
439 """Integer representation of the hostmask."""
440 return self.netmask ^ self._ALL_ONES
442 @property
443 def hostmask_ext(self):
444 """Dotted decimal or colon string version of the hostmask."""
445 return self._string_from_ip_int(self.hostmask)
447 @property
448 def network(self):
449 """Integer representation of the network."""
450 return self.ip & self.netmask
452 @property
453 def network_ext(self):
454 """Dotted decimal or colon string version of the network."""
455 return self._string_from_ip_int(self.network)
457 @property
458 def netmask_ext(self):
459 """Dotted decimal or colon string version of the netmask."""
460 return self._string_from_ip_int(self.netmask)
462 @property
463 def numhosts(self):
464 """Number of hosts in the current subnet."""
465 return self.broadcast - self.network + 1
467 @property
468 def version(self):
469 raise NotImplementedError('BaseIP has no version')
471 def _ip_int_from_prefix(self, prefixlen=None):
472 """Turn the prefix length netmask into a int for comparison.
474 Args:
475 prefixlen: An integer, the prefix length.
477 Returns:
478 An integer.
481 if not prefixlen and prefixlen != 0:
482 prefixlen = self.prefixlen
483 return self._ALL_ONES ^ (self._ALL_ONES >> prefixlen)
485 def _prefix_from_ip_int(self, ip_int, mask=32):
486 """Return prefix length from the decimal netmask.
488 Args:
489 ip_int: An integer, the IP address.
490 mask: The netmask. Defaults to 32.
492 Returns:
493 An integer, the prefix length.
496 while mask:
497 if ip_int & 1 == 1:
498 break
499 ip_int >>= 1
500 mask -= 1
502 return mask
504 def _ip_string_from_prefix(self, prefixlen=None):
505 """Turn a prefix length into a dotted decimal string.
507 Args:
508 prefixlen: An integer, the netmask prefix length.
510 Returns:
511 A string, the dotted decimal netmask string.
514 if not prefixlen:
515 prefixlen = self.prefixlen
516 return self._string_from_ip_int(self._ip_int_from_prefix(prefixlen))
519 class IPv4(BaseIP):
521 """This class represents and manipulates 32-bit IPv4 addresses.
523 Attributes: [examples for IPv4('1.2.3.4/27')]
524 .ip: 16909060
525 .ip_ext: '1.2.3.4'
526 .ip_ext_full: '1.2.3.4'
527 .network: 16909056L
528 .network_ext: '1.2.3.0'
529 .hostmask: 31L (0x1F)
530 .hostmask_ext: '0.0.0.31'
531 .broadcast: 16909087L (0x102031F)
532 .broadcast_ext: '1.2.3.31'
533 .netmask: 4294967040L (0xFFFFFFE0)
534 .netmask_ext: '255.255.255.224'
535 .prefixlen: 27
539 # Equivalent to 255.255.255.255 or 32 bits of 1's.
540 _ALL_ONES = 0xffffffff
541 _version = 4
543 def __init__(self, ipaddr):
544 """Instantiate a new IPv4 object.
546 Args:
547 ipaddr: A string or integer representing the IP [& network].
548 '192.168.1.1/32'
549 '192.168.1.1/255.255.255.255'
550 '192.168.1.1/0.0.0.255'
551 '192.168.1.1'
552 are all functionally the same in IPv4. That is to say,
553 failing to provide a subnetmask will create an object with
554 a mask of /32. A netmask of '255.255.255.255' is assumed
555 to be /32 and '0.0.0.0' is assumed to be /0, even though
556 other netmasks can be expressed both as host- and
557 net-masks. (255.0.0.0 == 0.255.255.255)
559 Additionally, an integer can be passed, so
560 IPv4('192.168.1.1') == IPv4(3232235777).
561 or, more generally
562 IPv4(IPv4('192.168.1.1').ip) == IPv4('192.168.1.1')
564 Raises:
565 IPv4IpValidationError: If ipaddr isn't a valid IPv4 address.
566 IPv4NetmaskValidationError: If the netmask isn't valid for
567 an IPv4 address.
570 BaseIP.__init__(self)
572 # Efficient constructor from integer.
573 if isinstance(ipaddr, int) or isinstance(ipaddr, long):
574 self.ip = ipaddr
575 self._prefixlen = 32
576 self.netmask = self._ALL_ONES
577 if ipaddr < 0 or ipaddr > self._ALL_ONES:
578 raise IPv4IpValidationError(ipaddr)
579 return
581 # Assume input argument to be string or any object representation
582 # which converts into a formatted IP prefix string.
583 addr = str(ipaddr).split('/')
585 if len(addr) > 2:
586 raise IPv4IpValidationError(ipaddr)
588 if not self._is_valid_ip(addr[0]):
589 raise IPv4IpValidationError(addr[0])
591 self.ip = self._ip_int_from_string(addr[0])
593 if len(addr) == 2:
594 mask = addr[1].split('.')
595 if len(mask) == 4:
596 # We have dotted decimal netmask.
597 if not self._is_valid_netmask(addr[1]):
598 raise IPv4NetmaskValidationError(addr[1])
599 if self._is_hostmask(addr[1]):
600 self.netmask = (
601 self._ip_int_from_string(addr[1]) ^ self._ALL_ONES)
602 else:
603 self.netmask = self._ip_int_from_string(addr[1])
604 self._prefixlen = self._prefix_from_ip_int(self.netmask)
605 else:
606 # We have a netmask in prefix length form.
607 if not self._is_valid_netmask(addr[1]):
608 raise IPv4NetmaskValidationError(addr[1])
609 self._prefixlen = int(addr[1])
610 self.netmask = self._ip_int_from_prefix(self._prefixlen)
611 else:
612 self._prefixlen = 32
613 self.netmask = self._ip_int_from_prefix(self._prefixlen)
615 def _set_prefix(self, prefixlen):
616 """Change the prefix length.
618 Args:
619 prefixlen: An integer, the new prefix length.
621 Raises:
622 IPv4NetmaskValidationError: If prefixlen is out of bounds.
625 if not 0 <= prefixlen <= 32:
626 raise IPv4NetmaskValidationError(prefixlen)
627 self._prefixlen = prefixlen
628 self.netmask = self._ip_int_from_prefix(self._prefixlen)
630 def subnet(self, prefixlen_diff=1):
631 """The subnets which join to make the current subnet.
633 In the case that self contains only one IP
634 (self._prefixlen == 32), return a list with just ourself.
636 Args:
637 prefixlen_diff: An integer, the amount the prefix length
638 should be increased by. Given a /24 network and a
639 prefixlen_diff of 3, for example, 8 subnets of size /27
640 will be returned. The default value of 1 splits the
641 current network into two halves.
643 Returns:
644 A list of IPv4 objects.
646 Raises:
647 PrefixlenDiffInvalidError: The prefixlen_diff is too small
648 or too large.
651 if self._prefixlen == 32:
652 return [self]
654 if prefixlen_diff < 0:
655 raise PrefixlenDiffInvalidError('prefix length diff must be > 0')
656 new_prefixlen = self.prefixlen + prefixlen_diff
658 if not self._is_valid_netmask(str(new_prefixlen)):
659 raise PrefixlenDiffInvalidError(
660 'prefix length diff %d is invalid for netblock %s' % (
661 new_prefixlen, str(self)))
663 first = IPv4(
664 self._string_from_ip_int(self.network) + '/' +
665 str(self._prefixlen + prefixlen_diff))
666 subnets = [first]
667 current = first
668 while True:
669 broadcast = current.broadcast
670 if broadcast == self.broadcast:
671 break
672 current = IPv4(self._string_from_ip_int(broadcast + 1) + '/' +
673 str(new_prefixlen))
674 subnets.append(current)
676 return subnets
678 def supernet(self, prefixlen_diff=1):
679 """The supernet containing the current network.
681 Args:
682 prefixlen_diff: An integer, the amount the prefix length of
683 the network should be decreased by. For example, given a
684 /24 network and a prefixlen_diff of 3, a supernet with a
685 /21 netmask is returned.
687 Returns:
688 An IPv4 object.
690 Raises:
691 PrefixlenDiffInvalidError: If
692 self.prefixlen - prefixlen_diff < 0. I.e., you have a
693 negative prefix length.
696 if self.prefixlen == 0:
697 return self
698 if self.prefixlen - prefixlen_diff < 0:
699 raise PrefixlenDiffInvalidError(
700 'current prefixlen is %d, cannot have a prefixlen_diff of %d' %
701 (self.prefixlen, prefixlen_diff))
702 return IPv4(self.ip_ext + '/' + str(self.prefixlen - prefixlen_diff))
704 @property
705 def is_private(self):
706 """Test if this address is allocated for private networks.
708 Returns:
709 A boolean, True if the address is reserved per RFC 1918.
712 for network in _IPV4_RFC1918_NETWORKS:
713 if self in network:
714 return True
715 return False
717 @property
718 def is_multicast(self):
719 """Test if the address is reserved for multicast use.
721 Returns:
722 A boolean, True if the address is multicast.
723 See RFC 3171 for details.
726 return self in _IPV4_RFC3171_MULTICAST
728 @property
729 def is_loopback(self):
730 """Test if the address is a loopback adddress.
732 Returns:
733 A boolean, True if the address is a loopback per RFC 3330.
736 return self in _IPV4_RFC3330_LOOPBACK
738 @property
739 def is_link_local(self):
740 """Test if the address is reserved for link-local.
742 Returns:
743 A boolean, True if the address is link-local per RFC 3927.
746 return self in _IPV4_RFC3927_LINK_LOCAL
748 @property
749 def version(self):
750 return self._version
752 @property
753 def packed(self):
754 """The binary representation of this address."""
755 return struct.pack('!I', self.ip)
757 def _is_hostmask(self, ip_str):
758 """Test if the IP string is a hostmask (rather than a netmask).
760 Args:
761 ip_str: A string, the potential hostmask.
763 Returns:
764 A boolean, True if the IP string is a hostmask.
767 parts = [int(x) for x in ip_str.split('.')]
768 if parts[0] < parts[-1]:
769 return True
770 return False
772 def _ip_int_from_string(self, ip_str):
773 """Turn the given IP string into an integer for comparison.
775 Args:
776 ip_str: A string, the IP address.
778 Returns:
779 The IP address as an integer.
782 packed_ip = 0
783 for oc in ip_str.split('.'):
784 packed_ip = (packed_ip << 8) | int(oc)
785 return packed_ip
787 def _string_from_ip_int(self, ip_int):
788 """Turns a 32-bit integer into dotted decimal notation.
790 Args:
791 ip_int: An integer, the IP address.
793 Returns:
794 The IP address as a string in dotted decimal notation.
797 octets = []
798 for _ in xrange(4):
799 octets.insert(0, str(ip_int & 0xFF))
800 ip_int >>= 8
801 return '.'.join(octets)
803 def _is_valid_ip(self, ip_str):
804 """Validate the dotted decimal notation IP/netmask string.
806 Args:
807 ip_str: A string, the IP address.
809 Returns:
810 A boolean, True if the string is a valid dotted decimal IP
811 string.
814 octets = ip_str.split('.')
815 if len(octets) == 1:
816 # We have an integer rather than a dotted decimal IP.
817 try:
818 return int(ip_str) >= 0 and int(ip_str) <= self._ALL_ONES
819 except ValueError:
820 return False
822 if len(octets) != 4:
823 return False
825 for octet in octets:
826 try:
827 if not 0 <= int(octet) <= 255:
828 return False
829 except ValueError:
830 return False
831 return True
833 def _is_valid_netmask(self, netmask):
834 """Verify that the netmask is valid.
836 Args:
837 netmask: A string, either a prefix or dotted decimal
838 netmask.
840 Returns:
841 A boolean, True if the prefix represents a valid IPv4
842 netmask.
845 if len(netmask.split('.')) == 4:
846 return self._is_valid_ip(netmask)
847 try:
848 netmask = int(netmask)
849 except ValueError:
850 return False
851 return 0 <= netmask <= 32
854 class IPv6(BaseIP):
856 """This class respresents and manipulates 128-bit IPv6 addresses.
858 Attributes: [examples for IPv6('2001:658:22A:CAFE:200::1/64')]
859 .ip: 42540616829182469433547762482097946625L
860 .ip_ext: '2001:658:22a:cafe:200::1'
861 .ip_ext_full: '2001:0658:022a:cafe:0200:0000:0000:0001'
862 .network: 42540616829182469433403647294022090752L
863 .network_ext: '2001:658:22a:cafe::'
864 .hostmask: 18446744073709551615L
865 .hostmask_ext: '::ffff:ffff:ffff:ffff'
866 .broadcast: 42540616829182469451850391367731642367L
867 .broadcast_ext: '2001:658:22a:cafe:ffff:ffff:ffff:ffff'
868 .netmask: 340282366920938463444927863358058659840L
869 .netmask_ext: 64
870 .prefixlen: 64
874 _ALL_ONES = (2**128) - 1
875 _version = 6
877 def __init__(self, ipaddr):
878 """Instantiate a new IPv6 object.
880 Args:
881 ipaddr: A string or integer representing the IP or the IP
882 and prefix/netmask.
883 '2001:4860::/128'
884 '2001:4860:0000:0000:0000:0000:0000:0000/128'
885 '2001:4860::'
886 are all functionally the same in IPv6. That is to say,
887 failing to provide a subnetmask will create an object with
888 a mask of /128.
890 Additionally, an integer can be passed, so
891 IPv6('2001:4860::') ==
892 IPv6(42541956101370907050197289607612071936L).
893 or, more generally
894 IPv6(IPv6('2001:4860::').ip) == IPv6('2001:4860::')
896 Raises:
897 IPv6IpValidationError: If ipaddr isn't a valid IPv6 address.
898 IPv6NetmaskValidationError: If the netmask isn't valid for
899 an IPv6 address.
902 BaseIP.__init__(self)
904 # Efficient constructor from integer.
905 if isinstance(ipaddr, long) or isinstance(ipaddr, int):
906 self.ip = ipaddr
907 self._prefixlen = 128
908 self.netmask = self._ALL_ONES
909 if ipaddr < 0 or ipaddr > self._ALL_ONES:
910 raise IPv6IpValidationError(ipaddr)
911 return
913 # Assume input argument to be string or any object representation
914 # which converts into a formatted IP prefix string.
915 addr_str = str(ipaddr)
916 if not addr_str:
917 raise IPv6IpValidationError('')
918 addr = addr_str.split('/')
919 if len(addr) > 1:
920 if self._is_valid_netmask(addr[1]):
921 self._prefixlen = int(addr[1])
922 else:
923 raise IPv6NetmaskValidationError(addr[1])
924 else:
925 self._prefixlen = 128
927 self.netmask = self._ip_int_from_prefix(self._prefixlen)
929 if not self._is_valid_ip(addr[0]):
930 raise IPv6IpValidationError(addr[0])
932 self.ip = self._ip_int_from_string(addr[0])
934 @property
935 def ip_ext_full(self):
936 """Returns the expanded version of the IPv6 string."""
937 return self._explode_shorthand_ip_string(self.ip_ext)
939 def _set_prefix(self, prefixlen):
940 """Change the prefix length.
942 Args:
943 prefixlen: An integer, the new prefix length.
945 Raises:
946 IPv6NetmaskValidationError: If prefixlen is out of bounds.
949 if not 0 <= prefixlen <= 128:
950 raise IPv6NetmaskValidationError(prefixlen)
951 self._prefixlen = prefixlen
952 self.netmask = self._ip_int_from_prefix(self.prefixlen)
954 def subnet(self, prefixlen_diff=1):
955 """The subnets which join to make the current subnet.
957 In the case that self contains only one IP
958 (self._prefixlen == 128), return a list with just ourself.
960 Args:
961 prefixlen_diff: An integer, the amount the prefix length
962 should be increased by.
964 Returns:
965 A list of IPv6 objects.
967 Raises:
968 PrefixlenDiffInvalidError: The prefixlen_diff is too small
969 or too large.
972 # Preserve original functionality (return [self] if
973 # self.prefixlen == 128).
974 if self.prefixlen == 128:
975 return [self]
977 if prefixlen_diff < 0:
978 raise PrefixlenDiffInvalidError('Prefix length diff must be > 0')
979 new_prefixlen = self.prefixlen + prefixlen_diff
980 if not self._is_valid_netmask(str(new_prefixlen)):
981 raise PrefixlenDiffInvalidError(
982 'Prefix length diff %d is invalid for netblock %s' % (
983 new_prefixlen, str(self)))
984 first = IPv6(
985 self._string_from_ip_int(self.network) + '/' +
986 str(self._prefixlen + prefixlen_diff))
987 subnets = [first]
988 current = first
989 while True:
990 broadcast = current.broadcast
991 if current.broadcast == self.broadcast:
992 break
993 current = IPv6(self._string_from_ip_int(broadcast + 1) + '/' +
994 str(new_prefixlen))
995 subnets.append(current)
997 return subnets
999 def supernet(self, prefixlen_diff=1):
1000 """The supernet containing the current network.
1002 Args:
1003 prefixlen_diff: An integer, the amount the prefix length of the
1004 network should be decreased by. For example, given a /96
1005 network and a prefixlen_diff of 3, a supernet with a /93
1006 netmask is returned.
1008 Returns:
1009 An IPv6 object.
1011 Raises:
1012 PrefixlenDiffInvalidError: If
1013 self._prefixlen - prefixlen_diff < 0. I.e., you have a
1014 negative prefix length.
1017 if self.prefixlen == 0:
1018 return self
1019 if self.prefixlen - prefixlen_diff < 0:
1020 raise PrefixlenDiffInvalidError(
1021 'current prefixlen is %d, cannot have a prefixlen_diff of %d' %
1022 (self.prefixlen, prefixlen_diff))
1023 return IPv6(self.ip_ext + '/' + str(self.prefixlen - prefixlen_diff))
1025 @property
1026 def is_multicast(self):
1027 """Test if the address is reserved for multicast use.
1029 Returns:
1030 A boolean, True if the address is a multicast address.
1031 See RFC 2373 2.7 for details.
1034 return self in _IPV6_RFC2373_MULTICAST
1036 @property
1037 def is_unspecified(self):
1038 """Test if the address is unspecified.
1040 Returns:
1041 A boolean, True if this is the unspecified address as defined in
1042 RFC 2373 2.5.2.
1045 return self == _IPV6_RFC2373_UNSPECIFIED
1047 @property
1048 def is_loopback(self):
1049 """Test if the address is a loopback adddress.
1051 Returns:
1052 A boolean, True if the address is a loopback address as defined in
1053 RFC 2373 2.5.3.
1056 return self == _IPV6_RFC2373_LOOPBACK
1058 @property
1059 def is_link_local(self):
1060 """Test if the address is reserved for link-local.
1062 Returns:
1063 A boolean, True if the address is reserved per RFC 4291.
1066 return self in _IPV6_RFC4291_LINK_LOCAL
1068 @property
1069 def is_site_local(self):
1070 """Test if the address is reserved for site-local.
1072 Note that the site-local address space has been deprecated by RFC 3879.
1073 Use is_private to test if this address is in the space of unique local
1074 addresses as defined by RFC 4193.
1076 Returns:
1077 A boolean, True if the address is reserved per RFC 3513 2.5.6.
1080 return self in _IPV6_RFC3513_SITE_LOCAL
1082 @property
1083 def is_private(self):
1084 """Test if this address is allocated for private networks.
1086 Returns:
1087 A boolean, True if the address is reserved per RFC 4193.
1090 return self in _IPV6_RFC4193_PRIVATE
1092 @property
1093 def version(self):
1094 return self._version
1096 @property
1097 def packed(self):
1098 """The binary representation of this address."""
1099 return struct.pack('!QQ', self.ip >> 64, self.ip & (2**64 - 1))
1101 def _is_shorthand_ip(self, ip_str=None):
1102 """Determine if the address is shortened.
1104 Args:
1105 ip_str: A string, the IPv6 address.
1107 Returns:
1108 A boolean, True if the address is shortened.
1111 if ip_str.count('::') == 1:
1112 return True
1113 return False
1115 def _explode_shorthand_ip_string(self, ip_str):
1116 """Expand a shortened IPv6 address.
1118 Args:
1119 ip_str: A string, the IPv6 address.
1121 Returns:
1122 A string, the expanded IPv6 address.
1125 if self._is_shorthand_ip(ip_str):
1126 new_ip = []
1127 hextet = ip_str.split('::')
1128 sep = len(hextet[0].split(':')) + len(hextet[1].split(':'))
1129 new_ip = hextet[0].split(':')
1131 for _ in xrange(8 - sep):
1132 new_ip.append('0000')
1133 new_ip += hextet[1].split(':')
1135 # Now need to make sure every hextet is 4 lower case characters.
1136 # If a hextet is < 4 characters, we've got missing leading 0's.
1137 ret_ip = []
1138 for hextet in new_ip:
1139 ret_ip.append(('0' * (4 - len(hextet)) + hextet).lower())
1140 return ':'.join(ret_ip)
1141 # We've already got a longhand ip_str.
1142 return ip_str
1144 def _is_valid_ip(self, ip_str=None):
1145 """Ensure we have a valid IPv6 address.
1147 Probably not as exhaustive as it should be.
1149 Args:
1150 ip_str: A string, the IPv6 address.
1152 Returns:
1153 A boolean, True if this is a valid IPv6 address.
1156 if not ip_str:
1157 ip_str = self.ip_ext
1159 # We need to have at least one ':'.
1160 if ':' not in ip_str:
1161 return False
1163 # We can only have one '::' shortener.
1164 if ip_str.count('::') > 1:
1165 return False
1167 # '::' should be encompassed by start, digits or end.
1168 if ':::' in ip_str:
1169 return False
1171 # A single colon can neither start nor end an address.
1172 if ((ip_str.startswith(':') and not ip_str.startswith('::')) or
1173 (ip_str.endswith(':') and not ip_str.endswith('::'))):
1174 return False
1176 # If we have no concatenation, we need to have 8 fields with 7 ':'.
1177 if '::' not in ip_str and ip_str.count(':') != 7:
1178 # We might have an IPv4 mapped address.
1179 if ip_str.count('.') != 3:
1180 return False
1182 ip_str = self._explode_shorthand_ip_string(ip_str)
1184 # Now that we have that all squared away, let's check that each of the
1185 # hextets are between 0x0 and 0xFFFF.
1186 for hextet in ip_str.split(':'):
1187 if hextet.count('.') == 3:
1188 # If we have an IPv4 mapped address, the IPv4 portion has to be
1189 # at the end of the IPv6 portion.
1190 if not ip_str.split(':')[-1] == hextet:
1191 return False
1192 try:
1193 IPv4(hextet)
1194 except IPv4IpValidationError:
1195 return False
1196 elif int(hextet, 16) < 0x0 or int(hextet, 16) > 0xFFFF:
1197 return False
1198 return True
1200 def _is_valid_netmask(self, prefixlen):
1201 """Verify that the netmask/prefixlen is valid.
1203 Args:
1204 prefixlen: A string, the netmask in prefix length format.
1206 Returns:
1207 A boolean, True if the prefix represents a valid IPv6
1208 netmask.
1211 try:
1212 prefixlen = int(prefixlen)
1213 except ValueError:
1214 return False
1215 return 0 <= prefixlen <= 128
1217 def _ip_int_from_string(self, ip_str=None):
1218 """Turn an IPv6 address into an integer.
1220 Args:
1221 ip_str: A string, the IPv6 address.
1223 Returns:
1224 A long, the IPv6 address.
1227 if not ip_str:
1228 ip_str = self.ip_ext
1230 ip_int = 0
1232 fields = self._explode_shorthand_ip_string(ip_str).split(':')
1234 # Do we have an IPv4 mapped (::ffff:a.b.c.d) or compact (::a.b.c.d)
1235 # address?
1236 if fields[-1].count('.') == 3:
1237 ipv4_string = fields.pop()
1238 ipv4_int = IPv4(ipv4_string).ip
1239 octets = []
1240 for _ in xrange(2):
1241 octets.append(hex(ipv4_int & 0xFFFF).lstrip('0x').rstrip('L'))
1242 ipv4_int >>= 16
1243 fields.extend(reversed(octets))
1245 for field in fields:
1246 ip_int = (ip_int << 16) + int(field, 16)
1248 return ip_int
1250 def _compress_hextets(self, hextets):
1251 """Compresses a list of hextets.
1253 Compresses a list of strings, replacing the longest continuous
1254 sequence of "0" in the list with "" and adding empty strings at
1255 the beginning or at the end of the string such that subsequently
1256 calling ":".join(hextets) will produce the compressed version of
1257 the IPv6 address.
1259 Args:
1260 hextets: A list of strings, the hextets to compress.
1262 Returns:
1263 A list of strings.
1266 best_doublecolon_start = -1
1267 best_doublecolon_len = 0
1268 doublecolon_start = -1
1269 doublecolon_len = 0
1270 for index in range(len(hextets)):
1271 if hextets[index] == '0':
1272 doublecolon_len += 1
1273 if doublecolon_start == -1:
1274 # Start of a sequence of zeros.
1275 doublecolon_start = index
1276 if doublecolon_len > best_doublecolon_len:
1277 # This is the longest sequence of zeros so far.
1278 best_doublecolon_len = doublecolon_len
1279 best_doublecolon_start = doublecolon_start
1280 else:
1281 doublecolon_len = 0
1282 doublecolon_start = -1
1284 if best_doublecolon_len > 1:
1285 best_doublecolon_end = (best_doublecolon_start +
1286 best_doublecolon_len)
1287 # For zeros at the end of the address.
1288 if best_doublecolon_end == len(hextets):
1289 hextets += ['']
1290 hextets[best_doublecolon_start:best_doublecolon_end] = ['']
1291 # For zeros at the beginning of the address.
1292 if best_doublecolon_start == 0:
1293 hextets = [''] + hextets
1295 return hextets
1297 def _string_from_ip_int(self, ip_int=None):
1298 """Turns a 128-bit integer into hexadecimal notation.
1300 Args:
1301 ip_int: An integer, the IP address.
1303 Returns:
1304 A string, the hexadecimal representation of the address.
1306 Raises:
1307 ValueError: The address is bigger than 128 bits of all ones.
1310 if not ip_int and ip_int != 0:
1311 ip_int = self.ip
1313 if ip_int > self._ALL_ONES:
1314 raise ValueError('IPv6 address is too large')
1316 hex_str = '%032x' % ip_int
1317 hextets = []
1318 for x in range(0, 32, 4):
1319 hextets.append('%x' % int(hex_str[x:x+4], 16))
1321 hextets = self._compress_hextets(hextets)
1322 return ':'.join(hextets)
1324 @property
1325 def netmask_ext(self):
1326 """IPv6 extended netmask.
1328 We don't deal with netmasks in IPv6 like we do in IPv4. This is
1329 here strictly for IPv4 compatibility. We simply return the
1330 prefix length.
1332 Returns:
1333 An integer.
1336 return self.prefixlen
1339 # IPv4 constants.
1340 _IPV4_RFC1918_NETWORKS = (IPv4('10.0.0.0/8'),
1341 IPv4('172.16.0.0/12'),
1342 IPv4('192.168.0.0/16'))
1343 _IPV4_RFC3171_MULTICAST = IPv4('224.0.0.0/4')
1344 _IPV4_RFC3330_LOOPBACK = IPv4('127.0.0.0/8')
1345 _IPV4_RFC3927_LINK_LOCAL = IPv4('169.254.0.0/16')
1347 # IPv6 constants.
1348 _IPV6_RFC2373_MULTICAST = IPv6('ff00::/8')
1349 _IPV6_RFC2373_UNSPECIFIED = IPv6('::')
1350 _IPV6_RFC2373_LOOPBACK = IPv6('::1')
1351 _IPV6_RFC4291_LINK_LOCAL = IPv6('fe80::/10')
1352 _IPV6_RFC3513_SITE_LOCAL = IPv6('fec0::/10') # Deprecated by RFC3879.
1353 _IPV6_RFC4193_PRIVATE = IPv6('fc00::/7')