1# -----------------------------------------------------------------------------
2# Copyright (c) 2008 by David P. D. Moss. All rights reserved.
3#
4# Released under the BSD license. See the LICENSE file for details.
5# -----------------------------------------------------------------------------
6"""Routines for IPv4 and IPv6 addresses, subnets and ranges."""
7
8import sys as _sys
9
10from netaddr.core import (
11 AddrFormatError,
12 AddrConversionError,
13 DictDotLookup,
14 NOHOST,
15 INET_ATON,
16 INET_PTON,
17 ZEROFILL,
18)
19
20from netaddr.strategy import ipv4 as _ipv4, ipv6 as _ipv6
21
22
23class BaseIP(object):
24 """
25 An abstract base class for common operations shared between various IP
26 related subclasses.
27
28 """
29
30 __slots__ = ('_value', '_module', '__weakref__')
31
32 def __init__(self):
33 """Constructor."""
34 self._value = None
35 self._module = None
36
37 def _set_value(self, value):
38 if not isinstance(value, int):
39 raise TypeError('int argument expected, not %s' % type(value))
40 if not 0 <= value <= self._module.max_int:
41 raise AddrFormatError(
42 'value out of bounds for an %s address!' % self._module.family_name
43 )
44 self._value = value
45
46 value = property(
47 lambda self: self._value,
48 _set_value,
49 doc='a positive integer representing the value of IP address/subnet.',
50 )
51
52 def key(self):
53 """
54 :return: a key tuple that uniquely identifies this IP address.
55 """
56 return NotImplemented
57
58 def sort_key(self):
59 """
60 :return: A key tuple used to compare and sort this `IPAddress`
61 correctly.
62 """
63 return NotImplemented
64
65 def __hash__(self):
66 """
67 :return: A hash value uniquely identifying this IP object.
68 """
69 return hash(self.key())
70
71 def __eq__(self, other):
72 """
73 :param other: an `IPAddress` or `IPNetwork` object.
74
75 :return: ``True`` if this `IPAddress` or `IPNetwork` object is
76 equivalent to ``other``, ``False`` otherwise.
77 """
78 try:
79 return self.key() == other.key()
80 except (AttributeError, TypeError):
81 return NotImplemented
82
83 def __ne__(self, other):
84 """
85 :param other: an `IPAddress` or `IPNetwork` object.
86
87 :return: ``True`` if this `IPAddress` or `IPNetwork` object is
88 not equivalent to ``other``, ``False`` otherwise.
89 """
90 try:
91 return self.key() != other.key()
92 except (AttributeError, TypeError):
93 return NotImplemented
94
95 def __lt__(self, other):
96 """
97 :param other: an `IPAddress` or `IPNetwork` object.
98
99 :return: ``True`` if this `IPAddress` or `IPNetwork` object is
100 less than ``other``, ``False`` otherwise.
101 """
102 try:
103 return self.sort_key() < other.sort_key()
104 except (AttributeError, TypeError):
105 return NotImplemented
106
107 def __le__(self, other):
108 """
109 :param other: an `IPAddress` or `IPNetwork` object.
110
111 :return: ``True`` if this `IPAddress` or `IPNetwork` object is
112 less than or equal to ``other``, ``False`` otherwise.
113 """
114 try:
115 return self.sort_key() <= other.sort_key()
116 except (AttributeError, TypeError):
117 return NotImplemented
118
119 def __gt__(self, other):
120 """
121 :param other: an `IPAddress` or `IPNetwork` object.
122
123 :return: ``True`` if this `IPAddress` or `IPNetwork` object is
124 greater than ``other``, ``False`` otherwise.
125 """
126 try:
127 return self.sort_key() > other.sort_key()
128 except (AttributeError, TypeError):
129 return NotImplemented
130
131 def __ge__(self, other):
132 """
133 :param other: an `IPAddress` or `IPNetwork` object.
134
135 :return: ``True`` if this `IPAddress` or `IPNetwork` object is
136 greater than or equal to ``other``, ``False`` otherwise.
137 """
138 try:
139 return self.sort_key() >= other.sort_key()
140 except (AttributeError, TypeError):
141 return NotImplemented
142
143 def is_unicast(self):
144 """:return: ``True`` if this IP is unicast, ``False`` otherwise"""
145 return not self.is_multicast()
146
147 def is_multicast(self):
148 """:return: ``True`` if this IP is multicast, ``False`` otherwise"""
149 if self._module == _ipv4:
150 return self in IPV4_MULTICAST
151 elif self._module == _ipv6:
152 return self in IPV6_MULTICAST
153
154 def is_loopback(self):
155 """
156 :return: ``True`` if this IP is loopback address (not for network
157 transmission), ``False`` otherwise.
158 References: RFC 3330 and 4291.
159
160 .. note:: |ipv4_in_ipv6_handling|
161 """
162 if self._module.version == 4:
163 return self in IPV4_LOOPBACK
164 elif self._module.version == 6:
165 return self in IPV6_LOOPBACK
166
167 def is_link_local(self):
168 """
169 :return: ``True`` if this IP is link-local address ``False`` otherwise.
170 Reference: RFCs 3927 and 4291.
171
172 .. note:: |ipv4_in_ipv6_handling|
173 """
174 if self._module.version == 4:
175 return self in IPV4_LINK_LOCAL
176 elif self._module.version == 6:
177 return self in IPV6_LINK_LOCAL
178
179 def is_reserved(self):
180 """
181 :return: ``True`` if this IP is in IANA reserved range, ``False``
182 otherwise. Reference: RFCs 3330 and 3171.
183
184 .. note:: |ipv4_in_ipv6_handling|
185 """
186 if self._module.version == 4:
187 for cidr in IPV4_RESERVED:
188 if self in cidr:
189 return True
190 elif self._module.version == 6:
191 for cidr in IPV6_RESERVED:
192 if self in cidr:
193 return True
194 return False
195
196 def is_ipv4_mapped(self):
197 """
198 :return: ``True`` if this IP is IPv4-mapped IPv6 address, ``False``
199 otherwise.
200 """
201 return self._module.version == 6 and (self._value >> 32) == 0xFFFF
202
203 def is_ipv4_compat(self):
204 """
205 :return: ``True`` if this IP is IPv4-compatible IPv6 address, ``False``
206 otherwise.
207 """
208 return self._module.version == 6 and (self._value >> 32) == 0
209
210 @property
211 def info(self):
212 """
213 A record dict containing IANA registration details for this IP address
214 if available, None otherwise.
215 """
216 # Lazy loading of IANA data structures.
217 from netaddr.ip.iana import query
218
219 return DictDotLookup(query(self))
220
221 @property
222 def version(self):
223 """the IP protocol version represented by this IP object."""
224 return self._module.version
225
226
227class IPAddress(BaseIP):
228 """
229 An individual IPv4 or IPv6 address without a net mask or subnet prefix.
230
231 To support these and other network based operations, see `IPNetwork`.
232
233 """
234
235 __slots__ = ()
236
237 def __init__(self, addr, version=None, flags=0):
238 """
239 Constructor.
240
241 :param addr: an IPv4 or IPv6 address which may be represented in an
242 accepted string format, as an unsigned integer or as another
243 IPAddress object (copy construction).
244
245 :param version: (optional) optimizes version detection if specified
246 and distinguishes between IPv4 and IPv6 for addresses with an
247 equivalent integer value.
248
249 :param flags: (optional) decides which rules are applied to the
250 interpretation of the addr value if passed as a string.
251
252 Matters only in IPv4 context.
253
254 Allowed flag values:
255
256 * :data:`INET_ATON`. Follows `inet_aton semantics
257 <https://www.netmeister.org/blog/inet_aton.html>`_ and allows all kinds of
258 weird-looking addresses to be parsed. For example:
259
260 >>> IPAddress('1', flags=INET_ATON)
261 IPAddress('0.0.0.1')
262 >>> IPAddress('1.0xf', flags=INET_ATON)
263 IPAddress('1.0.0.15')
264 >>> IPAddress('010.020.030.040', flags=INET_ATON)
265 IPAddress('8.16.24.32')
266
267 * ``INET_ATON | ZEROFILL`` or :data:`ZEROFILL` – like ``INET_ATON``, except leading zeros are discarded:
268
269 >>> IPAddress('010', flags=INET_ATON | ZEROFILL)
270 IPAddress('0.0.0.10')
271
272 * The default (``0``) or :data:`INET_PTON` – requires four decimal octets:
273
274 >>> IPAddress('10.0.0.1', flags=INET_PTON)
275 IPAddress('10.0.0.1')
276
277 Leading zeros may be ignored or rejected, depending on the platform.
278
279 * ``INET_PTON | ZEROFILL`` – like the default :data:`INET_PTON`, except leading
280 zeros are discarded:
281
282 >>> IPAddress('010.020.030.040', flags=INET_PTON | ZEROFILL)
283 IPAddress('10.20.30.40')
284
285 .. versionchanged:: 1.0.0
286 Changed the default IPv4 parsing mode from :data:`INET_ATON` to :data:`INET_PTON`.
287 """
288 super(IPAddress, self).__init__()
289
290 if flags & ~(INET_PTON | ZEROFILL | INET_ATON):
291 raise ValueError('Unrecognized IPAddress flags value: %s' % (flags,))
292
293 if flags & INET_ATON and flags & INET_PTON:
294 raise ValueError('INET_ATON and INET_PTON are mutually exclusive')
295
296 if isinstance(addr, BaseIP):
297 # Copy constructor.
298 if version is not None and version != addr._module.version:
299 raise ValueError('cannot switch IP versions using ' 'copy constructor!')
300 self._value = addr._value
301 self._module = addr._module
302 else:
303 # Explicit IP address version.
304 if version is not None:
305 if version == 4:
306 self._module = _ipv4
307 elif version == 6:
308 self._module = _ipv6
309 else:
310 raise ValueError('%r is an invalid IP version!' % version)
311
312 if isinstance(addr, str) and '/' in addr:
313 raise ValueError(
314 '%s() does not support netmasks or subnet'
315 ' prefixes! See documentation for details.' % self.__class__.__name__
316 )
317
318 if self._module is None:
319 # IP version is implicit, detect it from addr.
320 if isinstance(addr, int):
321 try:
322 if 0 <= int(addr) <= _ipv4.max_int:
323 self._value = int(addr)
324 self._module = _ipv4
325 elif _ipv4.max_int < int(addr) <= _ipv6.max_int:
326 self._value = int(addr)
327 self._module = _ipv6
328 except ValueError:
329 pass
330 else:
331 for module in _ipv4, _ipv6:
332 try:
333 self._value = module.str_to_int(addr, flags)
334 except AddrFormatError:
335 continue
336 else:
337 self._module = module
338 break
339
340 if self._module is None:
341 raise AddrFormatError('failed to detect a valid IP ' 'address from %r' % addr)
342 else:
343 # IP version is explicit.
344 if isinstance(addr, str):
345 try:
346 self._value = self._module.str_to_int(addr, flags)
347 except AddrFormatError:
348 raise AddrFormatError(
349 'base address %r is not IPv%d' % (addr, self._module.version)
350 )
351 else:
352 if 0 <= int(addr) <= self._module.max_int:
353 self._value = int(addr)
354 else:
355 raise AddrFormatError('bad address format: %r' % (addr,))
356
357 def __getstate__(self):
358 """:returns: Pickled state of an `IPAddress` object."""
359 return self._value, self._module.version
360
361 def __setstate__(self, state):
362 """
363 :param state: data used to unpickle a pickled `IPAddress` object.
364
365 """
366 value, version = state
367
368 self._value = value
369
370 if version == 4:
371 self._module = _ipv4
372 elif version == 6:
373 self._module = _ipv6
374 else:
375 raise ValueError('unpickling failed for object state: %s' % str(state))
376
377 def netmask_bits(self):
378 """
379 @return: If this IP is a valid netmask, the number of non-zero
380 bits are returned, otherwise it returns the width in bits for
381 the IP address version.
382 """
383 if not self.is_netmask():
384 return self._module.width
385
386 # the '0' address (e.g. 0.0.0.0 or 0000::) is a valid netmask with
387 # no bits set.
388 if self._value == 0:
389 return 0
390
391 i_val = self._value
392 numbits = 0
393
394 while i_val > 0:
395 if i_val & 1 == 1:
396 break
397 numbits += 1
398 i_val >>= 1
399
400 mask_length = self._module.width - numbits
401
402 if not 0 <= mask_length <= self._module.width:
403 raise ValueError('Unexpected mask length %d for address type!' % mask_length)
404
405 return mask_length
406
407 def is_hostmask(self):
408 """
409 :return: ``True`` if this IP address host mask, ``False`` otherwise.
410 """
411 int_val = self._value + 1
412 return int_val & (int_val - 1) == 0
413
414 def is_netmask(self):
415 """
416 :return: ``True`` if this IP address network mask, ``False`` otherwise.
417 """
418 int_val = (self._value ^ self._module.max_int) + 1
419 return int_val & (int_val - 1) == 0
420
421 def __iadd__(self, num):
422 """
423 Increases the numerical value of this IPAddress by num.
424
425 An IndexError is raised if result exceeds maximum IP address value or
426 is less than zero.
427
428 :param num: size of IP address increment.
429 """
430 new_value = int(self._value + num)
431 if 0 <= new_value <= self._module.max_int:
432 self._value = new_value
433 return self
434 raise IndexError('result outside valid IP address boundary!')
435
436 def __isub__(self, num):
437 """
438 Decreases the numerical value of this IPAddress by num.
439
440 An IndexError is raised if result is less than zero or exceeds maximum
441 IP address value.
442
443 :param num: size of IP address decrement.
444 """
445 new_value = int(self._value - num)
446 if 0 <= new_value <= self._module.max_int:
447 self._value = new_value
448 return self
449 raise IndexError('result outside valid IP address boundary!')
450
451 def __add__(self, num):
452 """
453 Add the numerical value of this IP address to num and provide the
454 result as a new IPAddress object.
455
456 :param num: size of IP address increase.
457
458 :return: a new IPAddress object with its numerical value increased by num.
459 """
460 new_value = int(self._value + num)
461 if 0 <= new_value <= self._module.max_int:
462 return self.__class__(new_value, self._module.version)
463 raise IndexError('result outside valid IP address boundary!')
464
465 __radd__ = __add__
466
467 def __sub__(self, num):
468 """
469 Subtract the numerical value of this IP address from num providing
470 the result as a new IPAddress object.
471
472 :param num: size of IP address decrease.
473
474 :return: a new IPAddress object with its numerical value decreased by num.
475 """
476 new_value = int(self._value - num)
477 if 0 <= new_value <= self._module.max_int:
478 return self.__class__(new_value, self._module.version)
479 raise IndexError('result outside valid IP address boundary!')
480
481 def __rsub__(self, num):
482 """
483 Subtract num (lvalue) from the numerical value of this IP address
484 (rvalue) providing the result as a new IPAddress object.
485
486 :param num: size of IP address decrease.
487
488 :return: a new IPAddress object with its numerical value decreased by num.
489 """
490 new_value = int(num - self._value)
491 if 0 <= new_value <= self._module.max_int:
492 return self.__class__(new_value, self._module.version)
493 raise IndexError('result outside valid IP address boundary!')
494
495 def key(self):
496 """
497 :return: a key tuple that uniquely identifies this IP address.
498 """
499 # NB - we return the value here twice because this IP Address may
500 # be sorted with a list of networks and it should still end up
501 # in the expected order.
502 return self._module.version, self._value
503
504 def sort_key(self):
505 """:return: A key tuple used to compare and sort this `IPAddress` correctly."""
506 return self._module.version, self._value, self._module.width
507
508 def __int__(self):
509 """:return: the value of this IP address as an unsigned integer"""
510 return self._value
511
512 def __index__(self):
513 """
514 :return: return the integer value of this IP address.
515 """
516 return self._value
517
518 def __bytes__(self):
519 """
520 :return: a bytes object equivalent to this IP address. In network
521 byte order, big-endian.
522 """
523 return self._value.to_bytes(self._module.width // 8, 'big')
524
525 def bits(self, word_sep=None):
526 """
527 :param word_sep: (optional) the separator to insert between words.
528 Default: None - use default separator for address type.
529
530 :return: the value of this IP address as a binary digit string."""
531 return self._module.int_to_bits(self._value, word_sep)
532
533 @property
534 def packed(self):
535 """The value of this IP address as a packed binary string."""
536 return self._module.int_to_packed(self._value)
537
538 @property
539 def words(self):
540 """
541 A list of unsigned integer words (octets for IPv4, hextets for IPv6)
542 found in this IP address.
543 """
544 return self._module.int_to_words(self._value)
545
546 @property
547 def bin(self):
548 """
549 The value of this IP address in standard Python binary
550 representational form (0bxxx). A back port of the format provided by
551 the builtin bin() function found in Python 2.6.x and higher.
552 """
553 return self._module.int_to_bin(self._value)
554
555 @property
556 def reverse_dns(self):
557 """The reverse DNS lookup record for this IP address"""
558 return self._module.int_to_arpa(self._value)
559
560 def ipv4(self):
561 """
562 Raises an `AddrConversionError` if IPv6 address cannot be converted
563 to IPv4.
564
565 :return: A numerically equivalent version 4 `IPAddress` object.
566 """
567 ip = None
568 klass = self.__class__
569
570 if self._module.version == 4:
571 ip = klass(self._value, 4)
572 elif self._module.version == 6:
573 if 0 <= self._value <= _ipv4.max_int:
574 ip = klass(self._value, 4)
575 elif _ipv4.max_int <= self._value <= 0xFFFFFFFFFFFF:
576 ip = klass(self._value - 0xFFFF00000000, 4)
577 else:
578 raise AddrConversionError(
579 'IPv6 address %s unsuitable for ' 'conversion to IPv4!' % self
580 )
581 return ip
582
583 def ipv6(self, ipv4_compatible=False):
584 """
585 .. note:: The IPv4-compatible IPv6 address format is now considered \
586 deprecated. See RFC 4291 or later for details.
587
588 :param ipv4_compatible: If ``True`` returns an IPv4-compatible address
589 (::x.x.x.x), an IPv4-mapped (::ffff:x.x.x.x) address
590 otherwise. Default: False (IPv4-mapped).
591
592 :return: A numerically equivalent version 6 `IPAddress` object.
593 """
594 ip = None
595 klass = self.__class__
596
597 if self._module.version == 6:
598 if ipv4_compatible and (0xFFFF00000000 <= self._value <= 0xFFFFFFFFFFFF):
599 ip = klass(self._value - 0xFFFF00000000, 6)
600 else:
601 ip = klass(self._value, 6)
602 elif self._module.version == 4:
603 # IPv4-Compatible IPv6 address
604 ip = klass(self._value, 6)
605 if not ipv4_compatible:
606 # IPv4-Mapped IPv6 address
607 ip = klass(0xFFFF00000000 + self._value, 6)
608
609 return ip
610
611 def format(self, dialect=None):
612 """
613 Only relevant for IPv6 addresses. Has no effect for IPv4.
614
615 :param dialect: One of the :ref:`ipv6_formatting_dialects`.
616
617 :return: an alternate string representation for this IP address.
618 """
619 if dialect is not None:
620 if not hasattr(dialect, 'word_fmt'):
621 raise TypeError('custom dialects should subclass ipv6_verbose!')
622 return self._module.int_to_str(self._value, dialect=dialect)
623
624 def __or__(self, other):
625 """
626 :param other: An `IPAddress` object (or other int-like object).
627
628 :return: bitwise OR (x | y) between the integer value of this IP
629 address and ``other``.
630 """
631 return self.__class__(self._value | int(other), self._module.version)
632
633 def __and__(self, other):
634 """
635 :param other: An `IPAddress` object (or other int-like object).
636
637 :return: bitwise AND (x & y) between the integer value of this IP
638 address and ``other``.
639 """
640 return self.__class__(self._value & int(other), self._module.version)
641
642 def __xor__(self, other):
643 """
644 :param other: An `IPAddress` object (or other int-like object).
645
646 :return: bitwise exclusive OR (x ^ y) between the integer value of
647 this IP address and ``other``.
648 """
649 return self.__class__(self._value ^ int(other), self._module.version)
650
651 def __lshift__(self, numbits):
652 """
653 :param numbits: size of bitwise shift.
654
655 :return: an `IPAddress` object based on this one with its integer
656 value left shifted by ``numbits``.
657 """
658 return self.__class__(self._value << numbits, self._module.version)
659
660 def __rshift__(self, numbits):
661 """
662 :param numbits: size of bitwise shift.
663
664 :return: an `IPAddress` object based on this one with its integer
665 value right shifted by ``numbits``.
666 """
667 return self.__class__(self._value >> numbits, self._module.version)
668
669 def __bool__(self):
670 """:return: ``True`` if the numerical value of this IP address is not \
671 zero, ``False`` otherwise."""
672 return bool(self._value)
673
674 def __str__(self):
675 """:return: IP address in presentational format"""
676 return self._module.int_to_str(self._value)
677
678 def __repr__(self):
679 """:return: Python statement to create an equivalent object"""
680 return "%s('%s')" % (self.__class__.__name__, self)
681
682 def to_canonical(self):
683 """
684 Converts the address to IPv4 if it is an IPv4-mapped IPv6 address (`RFC 4291
685 Section 2.5.5.2 <https://datatracker.ietf.org/doc/html/rfc4291.html#section-2.5.5.2>`_),
686 otherwise returns the address as-is.
687
688 >>> # IPv4-mapped IPv6
689 >>> IPAddress('::ffff:10.0.0.1').to_canonical()
690 IPAddress('10.0.0.1')
691 >>>
692 >>> # Everything else
693 >>> IPAddress('::1').to_canonical()
694 IPAddress('::1')
695 >>> IPAddress('10.0.0.1').to_canonical()
696 IPAddress('10.0.0.1')
697
698 .. versionadded:: 0.10.0
699 """
700 if not self.is_ipv4_mapped():
701 return self
702 return self.ipv4()
703
704 def is_global(self):
705 """
706 Returns ``True`` if this address is considered globally reachable, ``False`` otherwise.
707
708 An address is considered globally reachable if it's not a special-purpose address
709 or it's a special-purpose address listed as globally reachable in the relevant
710 registries:
711
712 * |iana_special_ipv4|
713 * |iana_special_ipv6|
714
715 Addresses for which the ``Globally Reachable`` value is ``N/A`` are not considered
716 globally reachable.
717
718 Address blocks with set termination date are not taken into consideration.
719
720 Whether or not an address can actually be reached in any local or global context will
721 depend on the network configuration and may differ from what this method returns.
722
723 Examples:
724
725 >>> IPAddress('1.1.1.1').is_global()
726 True
727 >>> IPAddress('::1').is_global()
728 False
729
730 .. note:: |ipv4_in_ipv6_handling|
731 """
732 if self._module.version == 4:
733 not_reachable = IPV4_NOT_GLOBALLY_REACHABLE
734 exceptions = IPV4_NOT_GLOBALLY_REACHABLE_EXCEPTIONS
735 else:
736 not_reachable = IPV6_NOT_GLOBALLY_REACHABLE
737 exceptions = IPV6_NOT_GLOBALLY_REACHABLE_EXCEPTIONS
738
739 return not any(self in net for net in not_reachable) or any(
740 self in net for net in exceptions
741 )
742
743 def is_ipv4_private_use(self):
744 """
745 Returns ``True`` if this address is an IPv4 private-use address as defined in
746 :rfc:`1918`.
747
748 The private-use address blocks:
749
750 * ``10.0.0.0/8``
751 * ``172.16.0.0/12``
752 * ``192.168.0.0/16``
753
754 .. note:: |ipv4_in_ipv6_handling|
755
756 .. versionadded:: 0.10.0
757 """
758 return self._module.version == 4 and any(self in cidr for cidr in IPV4_PRIVATE_USE)
759
760 def is_ipv6_unique_local(self):
761 """
762 Returns ``True`` if this address is an IPv6 unique local address as defined in
763 :rfc:`4193` and listed in |iana_special_ipv6|.
764
765 The IPv6 unique local address block: ``fc00::/7``.
766
767 .. versionadded:: 0.10.0
768 """
769 return self._module.version == 6 and self in IPV6_UNIQUE_LOCAL
770
771
772class IPListMixin(object):
773 """
774 A mixin class providing shared list-like functionality to classes
775 representing groups of IP addresses.
776
777 """
778
779 __slots__ = ()
780
781 def __iter__(self):
782 """
783 :return: An iterator providing access to all `IPAddress` objects
784 within range represented by this ranged IP object.
785 """
786 start_ip = IPAddress(self.first, self._module.version)
787 end_ip = IPAddress(self.last, self._module.version)
788 return iter_iprange(start_ip, end_ip)
789
790 @property
791 def size(self):
792 """
793 The total number of IP addresses within this ranged IP object.
794 """
795 return int(self.last - self.first + 1)
796
797 def __len__(self):
798 """
799 :return: the number of IP addresses in this ranged IP object. Raises
800 an `IndexError` if size > system max int (a Python 2.x
801 limitation). Use the .size property for subnets of any size.
802 """
803 size = self.size
804 if size > _sys.maxsize:
805 raise IndexError(
806 (
807 'range contains more than %d (sys.maxsize) '
808 'IP addresses! Use the .size property instead.' % _sys.maxsize
809 )
810 )
811 return size
812
813 def __getitem__(self, index):
814 """
815 :return: The IP address(es) in this `IPNetwork` object referenced by
816 index or slice. As slicing can produce large sequences of objects
817 an iterator is returned instead of the more usual `list`.
818 """
819 item = None
820
821 if hasattr(index, 'indices'):
822 if self._module.version == 6:
823 raise TypeError('IPv6 slices are not supported!')
824
825 (start, stop, step) = index.indices(self.size)
826
827 if (start + step < 0) or (step > stop):
828 # step value exceeds start and stop boundaries.
829 item = iter([IPAddress(self.first, self._module.version)])
830 else:
831 start_ip = IPAddress(self.first + start, self._module.version)
832 # We want to stop one short of stop – it depends on which way are we slicing
833 # (increasing or decreasing).
834 one_before_stop = stop + (1 if step < 0 else -1)
835 end_ip = IPAddress(self.first + one_before_stop, self._module.version)
836 item = iter_iprange(start_ip, end_ip, step)
837 else:
838 try:
839 index = int(index)
840 if (-self.size) <= index < 0:
841 # negative index.
842 item = IPAddress(self.last + index + 1, self._module.version)
843 elif 0 <= index <= (self.size - 1):
844 # Positive index or zero index.
845 item = IPAddress(self.first + index, self._module.version)
846 else:
847 raise IndexError('index out range for address range size!')
848 except ValueError:
849 raise TypeError('unsupported index type %r!' % index)
850
851 return item
852
853 def __contains__(self, other):
854 """
855 :param other: an `IPAddress` or ranged IP object.
856
857 :return: ``True`` if other falls within the boundary of this one,
858 ``False`` otherwise.
859 """
860 if isinstance(other, BaseIP):
861 if self._module.version != other._module.version:
862 return False
863 if isinstance(other, IPAddress):
864 return other._value >= self.first and other._value <= self.last
865 # Assume that we (and the other) provide .first and .last.
866 return other.first >= self.first and other.last <= self.last
867
868 # Whatever it is, try to interpret it as IPAddress.
869 return IPAddress(other) in self
870
871 def __bool__(self):
872 """
873 Ranged IP objects always represent a sequence of at least one IP
874 address and are therefore always True in the boolean context.
875 """
876 return True
877
878
879def parse_ip_network(module, addr, flags=0, *, expand_partial=False):
880 if isinstance(addr, tuple):
881 # CIDR integer tuple
882 if len(addr) != 2:
883 raise AddrFormatError('invalid %s tuple!' % module.family_name)
884 value, prefixlen = addr
885
886 if not (0 <= value <= module.max_int):
887 raise AddrFormatError('invalid address value for %s tuple!' % module.family_name)
888 if not (0 <= prefixlen <= module.width):
889 raise AddrFormatError('invalid prefix for %s tuple!' % module.family_name)
890 elif isinstance(addr, str):
891 # CIDR-like string subnet
892
893 if '/' in addr:
894 val1, val2 = addr.split('/', 1)
895 else:
896 val1 = addr
897 val2 = None
898
899 if expand_partial:
900 val1 = module.expand_partial_address(val1)
901
902 ip = IPAddress(val1, module.version, flags=INET_PTON)
903 value = ip._value
904
905 try:
906 # Integer CIDR prefix.
907 prefixlen = int(val2)
908 except TypeError:
909 if val2 is None:
910 # No prefix was specified.
911 prefixlen = module.width
912 except ValueError:
913 # Not an integer prefix, try a netmask/hostmask prefix.
914 mask = IPAddress(val2, module.version, flags=INET_PTON)
915 if mask.is_netmask():
916 prefixlen = module.netmask_to_prefix[mask._value]
917 elif mask.is_hostmask():
918 prefixlen = module.hostmask_to_prefix[mask._value]
919 else:
920 raise AddrFormatError('addr %r is not a valid IPNetwork!' % addr)
921
922 if not 0 <= prefixlen <= module.width:
923 raise AddrFormatError('invalid prefix for %s address!' % module.family_name)
924 else:
925 raise TypeError('unexpected type %s for addr arg' % type(addr))
926
927 if flags & NOHOST:
928 # Remove host bits.
929 netmask = module.prefix_to_netmask[prefixlen]
930 value = value & netmask
931
932 return value, prefixlen
933
934
935class IPNetwork(BaseIP, IPListMixin):
936 """
937 An IPv4 or IPv6 network or subnet.
938
939 A combination of an IP address and a network mask.
940
941 Accepts CIDR and several related variants :
942
943 a) Standard CIDR::
944
945 x.x.x.x/y -> 192.0.2.0/24
946 x::/y -> fe80::/10
947
948 b) Hybrid CIDR format (netmask address instead of prefix), where 'y' \
949 address represent a valid netmask::
950
951 x.x.x.x/y.y.y.y -> 192.0.2.0/255.255.255.0
952 x::/y:: -> fe80::/ffc0::
953
954 c) ACL hybrid CIDR format (hostmask address instead of prefix like \
955 Cisco's ACL bitmasks), where 'y' address represent a valid netmask::
956
957 x.x.x.x/y.y.y.y -> 192.0.2.0/0.0.0.255
958 x::/y:: -> fe80::/3f:ffff:ffff:ffff:ffff:ffff:ffff:ffff
959
960 .. versionchanged:: 1.0.0
961 Removed the ``implicit_prefix`` switch that used to enable the abbreviated CIDR
962 format support, use :func:`cidr_abbrev_to_verbose` if you need this behavior.
963
964 .. versionchanged:: 1.1.0
965 Removed partial IPv4 address support accidentally left when making 1.0.0 release.
966 Use :func:`expand_partial_ipv4_address` if you need this behavior.
967
968 .. versionchanged:: 1.3.0
969 Added the expand_partial flag, which restores the previous behavior to expand
970 partial IPv4 address
971 """
972
973 __slots__ = ('_prefixlen',)
974
975 def __init__(self, addr, version=None, flags=0, *, expand_partial=False):
976 """
977 Constructor.
978
979 :param addr: an IPv4 or IPv6 address with optional CIDR prefix,
980 netmask or hostmask. May be an IP address in presentation
981 (string) format, an tuple containing and integer address and a
982 network prefix, or another IPAddress/IPNetwork object (copy
983 construction).
984
985 :param version: (optional) optimizes version detection if specified
986 and distinguishes between IPv4 and IPv6 for addresses with an
987 equivalent integer value.
988
989 :param flags: (optional) decides which rules are applied to the
990 interpretation of the addr value. Currently only supports the
991 :data:`NOHOST` option.
992
993 :param expand_partial: (optional) decides whether partial address is
994 expanded. Currently this is only effective for IPv4 address.
995
996 >>> IPNetwork('1.2.3.4/24')
997 IPNetwork('1.2.3.4/24')
998 >>> IPNetwork('1.2.3.4/24', flags=NOHOST)
999 IPNetwork('1.2.3.0/24')
1000 >>> IPNetwork('10/24', expand_partial=True)
1001 IPNetwork('10.0.0.0/24')
1002 """
1003 super(IPNetwork, self).__init__()
1004
1005 if flags & ~NOHOST:
1006 raise ValueError('Unrecognized IPAddress flags value: %s' % (flags,))
1007
1008 value, prefixlen, module = None, None, None
1009
1010 if hasattr(addr, '_prefixlen'):
1011 # IPNetwork object copy constructor
1012 value = addr._value
1013 module = addr._module
1014 prefixlen = addr._prefixlen
1015 if flags & NOHOST:
1016 netmask = module.prefix_to_netmask[prefixlen]
1017 value = value & netmask
1018 elif hasattr(addr, '_value'):
1019 # IPAddress object copy constructor
1020 value = addr._value
1021 module = addr._module
1022 prefixlen = module.width
1023 elif version == 4:
1024 value, prefixlen = parse_ip_network(_ipv4, addr, flags, expand_partial=expand_partial)
1025 module = _ipv4
1026 elif version == 6:
1027 value, prefixlen = parse_ip_network(_ipv6, addr, flags)
1028 module = _ipv6
1029 else:
1030 if version is not None:
1031 raise ValueError('%r is an invalid IP version!' % version)
1032 try:
1033 module = _ipv4
1034 value, prefixlen = parse_ip_network(
1035 module, addr, flags, expand_partial=expand_partial
1036 )
1037 except AddrFormatError:
1038 try:
1039 module = _ipv6
1040 value, prefixlen = parse_ip_network(module, addr, flags)
1041 except AddrFormatError:
1042 pass
1043
1044 if value is None:
1045 raise AddrFormatError('invalid IPNetwork %s' % (addr,))
1046
1047 self._value = value
1048 self._prefixlen = prefixlen
1049 self._module = module
1050
1051 def __getstate__(self):
1052 """:return: Pickled state of an `IPNetwork` object."""
1053 return self._value, self._prefixlen, self._module.version
1054
1055 def __setstate__(self, state):
1056 """
1057 :param state: data used to unpickle a pickled `IPNetwork` object.
1058
1059 """
1060 value, prefixlen, version = state
1061
1062 self._value = value
1063
1064 if version == 4:
1065 self._module = _ipv4
1066 elif version == 6:
1067 self._module = _ipv6
1068 else:
1069 raise ValueError('unpickling failed for object state %s' % (state,))
1070
1071 if 0 <= prefixlen <= self._module.width:
1072 self._prefixlen = prefixlen
1073 else:
1074 raise ValueError('unpickling failed for object state %s' % (state,))
1075
1076 def _set_prefixlen(self, value):
1077 if not isinstance(value, int):
1078 raise TypeError('int argument expected, not %s' % type(value))
1079 if not 0 <= value <= self._module.width:
1080 raise AddrFormatError('invalid prefix for an %s address!' % self._module.family_name)
1081 self._prefixlen = value
1082
1083 prefixlen = property(
1084 lambda self: self._prefixlen,
1085 _set_prefixlen,
1086 doc='size of the bitmask used to separate the network from the host bits',
1087 )
1088
1089 @property
1090 def ip(self):
1091 """
1092 The IP address of this `IPNetwork` object. This is may or may not be
1093 the same as the network IP address which varies according to the value
1094 of the CIDR subnet prefix.
1095 """
1096 return IPAddress(self._value, self._module.version)
1097
1098 @property
1099 def network(self):
1100 """The network address of this `IPNetwork` object."""
1101 return IPAddress(self._value & self._netmask_int, self._module.version)
1102
1103 @property
1104 def broadcast(self):
1105 """The broadcast address of this `IPNetwork` object."""
1106 if (self._module.width - self._prefixlen) <= 1:
1107 return None
1108 else:
1109 return IPAddress(self._value | self._hostmask_int, self._module.version)
1110
1111 @property
1112 def first(self):
1113 """
1114 The integer value of first IP address found within this `IPNetwork`
1115 object.
1116 """
1117 return self._value & (self._module.max_int ^ self._hostmask_int)
1118
1119 @property
1120 def last(self):
1121 """
1122 The integer value of last IP address found within this `IPNetwork`
1123 object.
1124 """
1125 hostmask = (1 << (self._module.width - self._prefixlen)) - 1
1126 return self._value | hostmask
1127
1128 @property
1129 def netmask(self):
1130 """The subnet mask of this `IPNetwork` object."""
1131 netmask = self._module.max_int ^ self._hostmask_int
1132 return IPAddress(netmask, self._module.version)
1133
1134 @netmask.setter
1135 def netmask(self, value):
1136 """Set the prefixlen using a subnet mask"""
1137 ip = IPAddress(value)
1138
1139 if ip.version != self.version:
1140 raise ValueError('IP version mismatch: %s and %s' % (ip, self))
1141
1142 if not ip.is_netmask():
1143 raise ValueError('Invalid subnet mask specified: %s' % str(value))
1144
1145 self.prefixlen = ip.netmask_bits()
1146
1147 @property
1148 def _netmask_int(self):
1149 """Same as self.netmask, but in integer format"""
1150 return self._module.max_int ^ self._hostmask_int
1151
1152 @property
1153 def hostmask(self):
1154 """The host mask of this `IPNetwork` object."""
1155 hostmask = (1 << (self._module.width - self._prefixlen)) - 1
1156 return IPAddress(hostmask, self._module.version)
1157
1158 @property
1159 def _hostmask_int(self):
1160 """Same as self.hostmask, but in integer format"""
1161 return (1 << (self._module.width - self._prefixlen)) - 1
1162
1163 @property
1164 def cidr(self):
1165 """
1166 The true CIDR address for this `IPNetwork` object which omits any
1167 host bits to the right of the CIDR subnet prefix.
1168 """
1169 return IPNetwork(
1170 (self._value & self._netmask_int, self._prefixlen), version=self._module.version
1171 )
1172
1173 def __iadd__(self, num):
1174 """
1175 Increases the value of this `IPNetwork` object by the current size
1176 multiplied by ``num``.
1177
1178 An `IndexError` is raised if result exceeds maximum IP address value
1179 or is less than zero.
1180
1181 :param num: (optional) number of `IPNetwork` blocks to increment \
1182 this IPNetwork's value by.
1183 """
1184 new_value = int(self.network) + (self.size * num)
1185
1186 if (new_value + (self.size - 1)) > self._module.max_int:
1187 raise IndexError('increment exceeds address boundary!')
1188 if new_value < 0:
1189 raise IndexError('increment is less than zero!')
1190
1191 self._value = new_value
1192 return self
1193
1194 def __isub__(self, num):
1195 """
1196 Decreases the value of this `IPNetwork` object by the current size
1197 multiplied by ``num``.
1198
1199 An `IndexError` is raised if result is less than zero or exceeds
1200 maximum IP address value.
1201
1202 :param num: (optional) number of `IPNetwork` blocks to decrement \
1203 this IPNetwork's value by.
1204 """
1205 new_value = int(self.network) - (self.size * num)
1206
1207 if new_value < 0:
1208 raise IndexError('decrement is less than zero!')
1209 if (new_value + (self.size - 1)) > self._module.max_int:
1210 raise IndexError('decrement exceeds address boundary!')
1211
1212 self._value = new_value
1213 return self
1214
1215 def __contains__(self, other):
1216 """
1217 :param other: an `IPAddress` or ranged IP object.
1218
1219 :return: ``True`` if other falls within the boundary of this one,
1220 ``False`` otherwise.
1221 """
1222 if isinstance(other, BaseIP):
1223 if self._module.version != other._module.version:
1224 return False
1225
1226 # self_net will contain only the network bits.
1227 shiftwidth = self._module.width - self._prefixlen
1228 self_net = self._value >> shiftwidth
1229 if isinstance(other, IPRange):
1230 # IPRange has no _value.
1231 # (self_net+1)<<shiftwidth is not our last address, but the one
1232 # after the last one.
1233 return (self_net << shiftwidth) <= other._start._value and (
1234 ((self_net + 1) << shiftwidth) > other._end._value
1235 )
1236
1237 other_net = other._value >> shiftwidth
1238 if isinstance(other, IPAddress):
1239 return other_net == self_net
1240 if isinstance(other, IPNetwork):
1241 return self_net == other_net and self._prefixlen <= other._prefixlen
1242
1243 # Whatever it is, try to interpret it as IPNetwork
1244 return IPNetwork(other) in self
1245
1246 def key(self):
1247 """
1248 :return: A key tuple used to uniquely identify this `IPNetwork`.
1249 """
1250 return self._module.version, self.first, self.last
1251
1252 def sort_key(self):
1253 """
1254 :return: A key tuple used to compare and sort this `IPNetwork` correctly.
1255 """
1256 net_size_bits = self._prefixlen - 1
1257 first = self._value & (self._module.max_int ^ self._hostmask_int)
1258 host_bits = self._value - first
1259 return self._module.version, first, net_size_bits, host_bits
1260
1261 def ipv4(self):
1262 """
1263 :return: A numerically equivalent version 4 `IPNetwork` object. \
1264 Raises an `AddrConversionError` if IPv6 address cannot be \
1265 converted to IPv4.
1266 """
1267 ip = None
1268 klass = self.__class__
1269
1270 if self._module.version == 4:
1271 ip = klass('%s/%d' % (self.ip, self.prefixlen))
1272 elif self._module.version == 6:
1273 if 0 <= self._value <= _ipv4.max_int:
1274 addr = _ipv4.int_to_str(self._value)
1275 ip = klass('%s/%d' % (addr, self.prefixlen - 96))
1276 elif _ipv4.max_int <= self._value <= 0xFFFFFFFFFFFF:
1277 addr = _ipv4.int_to_str(self._value - 0xFFFF00000000)
1278 ip = klass('%s/%d' % (addr, self.prefixlen - 96))
1279 else:
1280 raise AddrConversionError(
1281 'IPv6 address %s unsuitable for ' 'conversion to IPv4!' % self
1282 )
1283 return ip
1284
1285 def ipv6(self, ipv4_compatible=False):
1286 """
1287 .. note:: the IPv4-mapped IPv6 address format is now considered \
1288 deprecated. See RFC 4291 or later for details.
1289
1290 :param ipv4_compatible: If ``True`` returns an IPv4-compatible address
1291 (::x.x.x.x), an IPv4-mapped (::ffff:x.x.x.x) address
1292 otherwise. Default: False (IPv4-mapped).
1293
1294 :return: A numerically equivalent version 6 `IPNetwork` object.
1295 """
1296 ip = None
1297 klass = self.__class__
1298
1299 if self._module.version == 6:
1300 if ipv4_compatible and (0xFFFF00000000 <= self._value <= 0xFFFFFFFFFFFF):
1301 ip = klass((self._value - 0xFFFF00000000, self._prefixlen), version=6)
1302 else:
1303 ip = klass((self._value, self._prefixlen), version=6)
1304 elif self._module.version == 4:
1305 if ipv4_compatible:
1306 # IPv4-Compatible IPv6 address
1307 ip = klass((self._value, self._prefixlen + 96), version=6)
1308 else:
1309 # IPv4-Mapped IPv6 address
1310 ip = klass((0xFFFF00000000 + self._value, self._prefixlen + 96), version=6)
1311
1312 return ip
1313
1314 def previous(self, step=1):
1315 """
1316 :param step: the number of IP subnets between this `IPNetwork` object
1317 and the expected subnet. Default: 1 (the previous IP subnet).
1318
1319 :return: The adjacent subnet preceding this `IPNetwork` object.
1320 """
1321 ip_copy = self.__class__('%s/%d' % (self.network, self.prefixlen), self._module.version)
1322 ip_copy -= step
1323 return ip_copy
1324
1325 def next(self, step=1):
1326 """
1327 :param step: the number of IP subnets between this `IPNetwork` object
1328 and the expected subnet. Default: 1 (the next IP subnet).
1329
1330 :return: The adjacent subnet succeeding this `IPNetwork` object.
1331 """
1332 ip_copy = self.__class__('%s/%d' % (self.network, self.prefixlen), self._module.version)
1333 ip_copy += step
1334 return ip_copy
1335
1336 def supernet(self, prefixlen=0):
1337 """
1338 Provides a list of supernets for this `IPNetwork` object between the
1339 size of the current prefix and (if specified) an endpoint prefix.
1340
1341 :param prefixlen: (optional) a CIDR prefix for the maximum supernet.
1342 Default: 0 - returns all possible supernets.
1343
1344 :return: a tuple of supernet `IPNetwork` objects.
1345 """
1346 if not 0 <= prefixlen <= self._module.width:
1347 raise ValueError(
1348 'CIDR prefix /%d invalid for IPv%d!' % (prefixlen, self._module.version)
1349 )
1350
1351 supernets = []
1352 # Use a copy of self as we'll be editing it.
1353 supernet = self.cidr
1354 supernet._prefixlen = prefixlen
1355 while supernet._prefixlen != self._prefixlen:
1356 supernets.append(supernet.cidr)
1357 supernet._prefixlen += 1
1358 return supernets
1359
1360 def subnet(self, prefixlen, count=None, fmt=None):
1361 """
1362 A generator that divides up this IPNetwork's subnet into smaller
1363 subnets based on a specified CIDR prefix.
1364
1365 :param prefixlen: a CIDR prefix indicating size of subnets to be
1366 returned.
1367
1368 :param count: (optional) number of consecutive IP subnets to be
1369 returned.
1370
1371 :return: an iterator containing IPNetwork subnet objects.
1372 """
1373 if not 0 <= self.prefixlen <= self._module.width:
1374 raise ValueError(
1375 'CIDR prefix /%d invalid for IPv%d!' % (prefixlen, self._module.version)
1376 )
1377
1378 if not self.prefixlen <= prefixlen:
1379 # Don't return anything.
1380 return
1381
1382 # Calculate number of subnets to be returned.
1383 width = self._module.width
1384 max_subnets = 2 ** (width - self.prefixlen) // 2 ** (width - prefixlen)
1385
1386 if count is None:
1387 count = max_subnets
1388
1389 if not 1 <= count <= max_subnets:
1390 raise ValueError('count outside of current IP subnet boundary!')
1391
1392 base_subnet = self._module.int_to_str(self.first)
1393 i = 0
1394 while i < count:
1395 subnet = self.__class__('%s/%d' % (base_subnet, prefixlen), self._module.version)
1396 subnet.value += subnet.size * i
1397 subnet.prefixlen = prefixlen
1398 i += 1
1399 yield subnet
1400
1401 def iter_hosts(self):
1402 """
1403 A generator that provides all the IP addresses that can be assigned
1404 to hosts within the range of this IP object's subnet.
1405
1406 - for IPv4, the network and broadcast addresses are excluded, excepted \
1407 when using /31 or /32 subnets as per RFC 3021.
1408
1409 - for IPv6, only Subnet-Router anycast address (first address in the \
1410 network) is excluded as per RFC 4291 section 2.6.1, excepted when using \
1411 /127 or /128 subnets as per RFC 6164.
1412
1413 :return: an IPAddress iterator
1414 """
1415 first_usable_address, last_usable_address = self._usable_range()
1416 return iter_iprange(
1417 IPAddress(first_usable_address, self._module.version),
1418 IPAddress(last_usable_address, self._module.version),
1419 )
1420
1421 def _usable_range(self):
1422 if self.size >= 4:
1423 # Common logic, first IP is always reserved.
1424 first_usable_address = self.first + 1
1425 if self._module.version == 4:
1426 # IPv4 logic, last address is reserved for broadcast.
1427 last_usable_address = self.last - 1
1428 else:
1429 # IPv6 logic, no broadcast address reserved.
1430 last_usable_address = self.last
1431 return (first_usable_address, last_usable_address)
1432 else:
1433 # If subnet has a size of less than 4, then it is a /31, /32, /127 or /128.
1434 # Handle them as per RFC 3021 (IPv4) or RFC 6164 (IPv6), and don't reserve
1435 # first or last IP address.
1436 return (self.first, self.last)
1437
1438 def __str__(self):
1439 """:return: this IPNetwork in CIDR format"""
1440 addr = self._module.int_to_str(self._value)
1441 return '%s/%s' % (addr, self.prefixlen)
1442
1443 def __repr__(self):
1444 """:return: Python statement to create an equivalent object"""
1445 return "%s('%s')" % (self.__class__.__name__, self)
1446
1447
1448class IPRange(BaseIP, IPListMixin):
1449 """
1450 An arbitrary IPv4 or IPv6 address range.
1451
1452 Formed from a lower and upper bound IP address. The upper bound IP cannot
1453 be numerically smaller than the lower bound and the IP version of both
1454 must match.
1455
1456 """
1457
1458 __slots__ = ('_start', '_end')
1459
1460 def __init__(self, start, end, flags=0):
1461 """
1462 Constructor.
1463
1464 :param start: an IPv4 or IPv6 address that forms the lower
1465 boundary of this IP range.
1466
1467 :param end: an IPv4 or IPv6 address that forms the upper
1468 boundary of this IP range.
1469
1470 :param flags: (optional) decides which rules are applied to the
1471 interpretation of the start and end values. Refer to the :meth:`IPAddress.__init__`
1472 documentation for details.
1473
1474 """
1475 self._start = IPAddress(start, flags=flags)
1476 self._module = self._start._module
1477 self._end = IPAddress(end, self._module.version, flags=flags)
1478 if int(self._start) > int(self._end):
1479 raise AddrFormatError('lower bound IP greater than upper bound!')
1480
1481 def __getstate__(self):
1482 """:return: Pickled state of an `IPRange` object."""
1483 return self._start.value, self._end.value, self._module.version
1484
1485 def __setstate__(self, state):
1486 """
1487 :param state: data used to unpickle a pickled `IPRange` object.
1488 """
1489 start, end, version = state
1490
1491 self._start = IPAddress(start, version)
1492 self._module = self._start._module
1493 self._end = IPAddress(end, version)
1494
1495 def __contains__(self, other):
1496 if isinstance(other, BaseIP):
1497 if self._module.version != other._module.version:
1498 return False
1499 if isinstance(other, IPAddress):
1500 return self._start._value <= other._value and self._end._value >= other._value
1501 if isinstance(other, IPRange):
1502 return (
1503 self._start._value <= other._start._value
1504 and self._end._value >= other._end._value
1505 )
1506 if isinstance(other, IPNetwork):
1507 shiftwidth = other._module.width - other._prefixlen
1508 other_start = (other._value >> shiftwidth) << shiftwidth
1509 other_end = other_start + (1 << shiftwidth) - 1
1510
1511 return self._start._value <= other_start and self._end._value >= other_end
1512
1513 # Whatever it is, try to interpret it as IPAddress.
1514 return IPAddress(other) in self
1515
1516 @property
1517 def first(self):
1518 """The integer value of first IP address in this `IPRange` object."""
1519 return int(self._start)
1520
1521 @property
1522 def last(self):
1523 """The integer value of last IP address in this `IPRange` object."""
1524 return int(self._end)
1525
1526 def key(self):
1527 """
1528 :return: A key tuple used to uniquely identify this `IPRange`.
1529 """
1530 return self._module.version, self.first, self.last
1531
1532 def sort_key(self):
1533 """
1534 :return: A key tuple used to compare and sort this `IPRange` correctly.
1535 """
1536 skey = self._module.width - self.size.bit_length()
1537 return self._module.version, self._start._value, skey
1538
1539 def cidrs(self):
1540 """
1541 The list of CIDR addresses found within the lower and upper bound
1542 addresses of this `IPRange`.
1543 """
1544 return iprange_to_cidrs(self._start, self._end)
1545
1546 def __str__(self):
1547 """:return: this `IPRange` in a common representational format."""
1548 return '%s-%s' % (self._start, self._end)
1549
1550 def __repr__(self):
1551 """:return: Python statement to create an equivalent object"""
1552 return "%s('%s', '%s')" % (self.__class__.__name__, self._start, self._end)
1553
1554
1555def iter_unique_ips(*args):
1556 """
1557 :param args: A list of IP addresses and subnets passed in as arguments.
1558
1559 :return: A generator that flattens out IP subnets, yielding unique
1560 individual IP addresses (no duplicates).
1561 """
1562 for cidr in cidr_merge(args):
1563 for ip in cidr:
1564 yield ip
1565
1566
1567def cidr_abbrev_to_verbose(abbrev_cidr):
1568 """
1569 A function that converts abbreviated IPv4 CIDRs to their more verbose
1570 equivalent.
1571
1572 :param abbrev_cidr: an abbreviated CIDR.
1573
1574 Uses the old-style classful IP address rules to decide on a default
1575 subnet prefix if one is not explicitly provided.
1576
1577 Only supports IPv4 addresses.
1578
1579 Examples ::
1580
1581 10 - 10.0.0.0/8
1582 10/16 - 10.0.0.0/16
1583 128 - 128.0.0.0/16
1584 128/8 - 128.0.0.0/8
1585 192.168 - 192.168.0.0/16
1586
1587 :return: A verbose CIDR from an abbreviated CIDR or old-style classful \
1588 network address. The original value if it was not recognised as a \
1589 supported abbreviation.
1590 """
1591
1592 # Internal function that returns a prefix value based on the old IPv4
1593 # classful network scheme that has been superseded (almost) by CIDR.
1594 def classful_prefix(octet):
1595 octet = int(octet)
1596 if not 0 <= octet <= 255:
1597 raise IndexError('Invalid octet: %r!' % octet)
1598 if 0 <= octet <= 127: # Legacy class 'A' classification.
1599 return 8
1600 elif 128 <= octet <= 191: # Legacy class 'B' classification.
1601 return 16
1602 elif 192 <= octet <= 223: # Legacy class 'C' classification.
1603 return 24
1604 elif 224 <= octet <= 239: # Multicast address range.
1605 return 4
1606 return 32 # Default.
1607
1608 if isinstance(abbrev_cidr, str):
1609 if ':' in abbrev_cidr or abbrev_cidr == '':
1610 return abbrev_cidr
1611
1612 try:
1613 # Single octet partial integer or string address.
1614 i = int(abbrev_cidr)
1615 return '%s.0.0.0/%s' % (i, classful_prefix(i))
1616 except ValueError:
1617 # Multi octet partial string address with optional prefix.
1618 if '/' in abbrev_cidr:
1619 part_addr, prefix = abbrev_cidr.split('/', 1)
1620
1621 # Check prefix for validity.
1622 try:
1623 if not 0 <= int(prefix) <= 32:
1624 raise ValueError(
1625 'prefixlen in address %r out of range' ' for IPv4!' % (abbrev_cidr,)
1626 )
1627 except ValueError:
1628 return abbrev_cidr
1629 else:
1630 part_addr = abbrev_cidr
1631 prefix = None
1632
1633 tokens = part_addr.split('.')
1634 if len(tokens) > 4:
1635 # Not a recognisable format.
1636 return abbrev_cidr
1637 for i in range(4 - len(tokens)):
1638 tokens.append('0')
1639
1640 if prefix is None:
1641 try:
1642 prefix = classful_prefix(tokens[0])
1643 except ValueError:
1644 return abbrev_cidr
1645
1646 return '%s/%s' % ('.'.join(tokens), prefix)
1647 except (TypeError, IndexError):
1648 # Not a recognisable format.
1649 return abbrev_cidr
1650
1651
1652def cidr_merge(ip_addrs):
1653 """
1654 A function that accepts an iterable sequence of IP addresses and subnets
1655 merging them into the smallest possible list of CIDRs. It merges adjacent
1656 subnets where possible, those contained within others and also removes
1657 any duplicates.
1658
1659 :param ip_addrs: an iterable sequence of IP addresses, subnets or ranges.
1660
1661 :return: a summarized list of `IPNetwork` objects.
1662 """
1663 # The algorithm is quite simple: For each CIDR we create an IP range.
1664 # Sort them and merge when possible. Afterwars split them again
1665 # optimally.
1666 if not hasattr(ip_addrs, '__iter__'):
1667 raise ValueError('A sequence or iterator is expected!')
1668
1669 ranges = []
1670
1671 for ip in ip_addrs:
1672 if isinstance(ip, (IPNetwork, IPRange)):
1673 net = ip
1674 else:
1675 net = IPNetwork(ip)
1676 # Since non-overlapping ranges are the common case, remember the original
1677 ranges.append((net.version, net.last, net.first, net))
1678
1679 ranges.sort()
1680 i = len(ranges) - 1
1681 while i > 0:
1682 if ranges[i][0] == ranges[i - 1][0] and ranges[i][2] - 1 <= ranges[i - 1][1]:
1683 ranges[i - 1] = (ranges[i][0], ranges[i][1], min(ranges[i - 1][2], ranges[i][2]))
1684 del ranges[i]
1685 i -= 1
1686 merged = []
1687 for range_tuple in ranges:
1688 # If this range wasn't merged we can simply use the old cidr.
1689 if len(range_tuple) == 4:
1690 original = range_tuple[3]
1691 if isinstance(original, IPRange):
1692 merged.extend(original.cidrs())
1693 else:
1694 merged.append(original)
1695 else:
1696 version = range_tuple[0]
1697 range_start = IPAddress(range_tuple[2], version=version)
1698 range_stop = IPAddress(range_tuple[1], version=version)
1699 merged.extend(iprange_to_cidrs(range_start, range_stop))
1700 return merged
1701
1702
1703def cidr_exclude(target, exclude):
1704 """
1705 Removes an exclude IP address or subnet from target IP subnet.
1706
1707 :param target: the target IP address or subnet to be divided up.
1708
1709 :param exclude: the IP address or subnet to be removed from target.
1710
1711 :return: list of `IPNetwork` objects remaining after exclusion.
1712 """
1713 left, _, right = cidr_partition(target, exclude)
1714
1715 return left + right
1716
1717
1718def cidr_partition(target, exclude):
1719 """
1720 Partitions a target IP subnet on an exclude IP address.
1721
1722 :param target: the target IP address or subnet to be divided up.
1723
1724 :param exclude: the IP address or subnet to partition on
1725
1726 :return: list of `IPNetwork` objects before, the partition and after, sorted.
1727
1728 Adding the three lists returns the equivalent of the original subnet.
1729 """
1730
1731 target = IPNetwork(target)
1732 exclude = IPNetwork(exclude)
1733
1734 if exclude.last < target.first:
1735 # Exclude subnet's upper bound address less than target
1736 # subnet's lower bound.
1737 return [], [], [target.cidr]
1738 elif target.last < exclude.first:
1739 # Exclude subnet's lower bound address greater than target
1740 # subnet's upper bound.
1741 return [target.cidr], [], []
1742
1743 if target.prefixlen >= exclude.prefixlen:
1744 # Exclude contains the target
1745 return [], [target], []
1746
1747 left = []
1748 right = []
1749
1750 new_prefixlen = target.prefixlen + 1
1751 # Some @properties that are expensive to get and don't change below.
1752 target_module_width = target._module.width
1753
1754 target_first = target.first
1755 version = exclude.version
1756 i_lower = target_first
1757 i_upper = target_first + (2 ** (target_module_width - new_prefixlen))
1758
1759 while exclude.prefixlen >= new_prefixlen:
1760 if exclude.first >= i_upper:
1761 left.append(IPNetwork((i_lower, new_prefixlen), version=version))
1762 matched = i_upper
1763 else:
1764 right.append(IPNetwork((i_upper, new_prefixlen), version=version))
1765 matched = i_lower
1766
1767 new_prefixlen += 1
1768
1769 if new_prefixlen > target_module_width:
1770 break
1771
1772 i_lower = matched
1773 i_upper = matched + (2 ** (target_module_width - new_prefixlen))
1774
1775 return left, [exclude], right[::-1]
1776
1777
1778def spanning_cidr(ip_addrs):
1779 """
1780 Function that accepts a sequence of IP addresses and subnets returning
1781 a single `IPNetwork` subnet that is large enough to span the lower and
1782 upper bound IP addresses with a possible overlap on either end.
1783
1784 :param ip_addrs: sequence of IP addresses and subnets.
1785
1786 :return: a single spanning `IPNetwork` subnet.
1787 """
1788 ip_addrs_iter = iter(ip_addrs)
1789 try:
1790 network_a = IPNetwork(next(ip_addrs_iter))
1791 network_b = IPNetwork(next(ip_addrs_iter))
1792 except StopIteration:
1793 raise ValueError('IP sequence must contain at least 2 elements!')
1794
1795 if network_a < network_b:
1796 min_network = network_a
1797 max_network = network_b
1798 else:
1799 min_network = network_b
1800 max_network = network_a
1801
1802 for ip in ip_addrs_iter:
1803 network = IPNetwork(ip)
1804 if network < min_network:
1805 min_network = network
1806 if network > max_network:
1807 max_network = network
1808
1809 if min_network.version != max_network.version:
1810 raise TypeError('IP sequence cannot contain both IPv4 and IPv6!')
1811
1812 ipnum = max_network.last
1813 prefixlen = max_network.prefixlen
1814 lowest_ipnum = min_network.first
1815 width = max_network._module.width
1816
1817 while prefixlen > 0 and ipnum > lowest_ipnum:
1818 prefixlen -= 1
1819 ipnum &= -(1 << (width - prefixlen))
1820
1821 return IPNetwork((ipnum, prefixlen), version=min_network.version)
1822
1823
1824def iter_iprange(start, end, step=1):
1825 """
1826 A generator that produces IPAddress objects between an arbitrary start
1827 and stop IP address with intervals of step between them. Sequences
1828 produce are inclusive of boundary IPs.
1829
1830 :param start: start IP address.
1831
1832 :param end: end IP address.
1833
1834 :param step: (optional) size of step between IP addresses. Default: 1
1835
1836 :return: an iterator of one or more `IPAddress` objects.
1837 """
1838 start = IPAddress(start)
1839 end = IPAddress(end)
1840
1841 if start.version != end.version:
1842 raise TypeError('start and stop IP versions do not match!')
1843 version = start.version
1844
1845 step = int(step)
1846 if step == 0:
1847 raise ValueError('step argument cannot be zero')
1848
1849 # We don't need objects from here, just integers.
1850 start = int(start)
1851 stop = int(end)
1852
1853 negative_step = False
1854
1855 if step < 0:
1856 negative_step = True
1857
1858 index = start - step
1859 while True:
1860 index += step
1861 if negative_step:
1862 if not index >= stop:
1863 break
1864 else:
1865 if not index <= stop:
1866 break
1867 yield IPAddress(index, version)
1868
1869
1870def iprange_to_cidrs(start, end):
1871 """
1872 A function that accepts an arbitrary start and end IP address or subnet
1873 and returns a list of CIDR subnets that fit exactly between the boundaries
1874 of the two with no overlap.
1875
1876 :param start: the start IP address or subnet.
1877
1878 :param end: the end IP address or subnet.
1879
1880 :return: a list of one or more IP addresses and subnets.
1881 """
1882 cidr_list = []
1883
1884 start = IPNetwork(start)
1885 end = IPNetwork(end)
1886
1887 iprange = [start.first, end.last]
1888
1889 # Get spanning CIDR covering both addresses.
1890 cidr_span = spanning_cidr([start, end])
1891 width = start._module.width
1892
1893 if cidr_span.first < iprange[0]:
1894 exclude = IPNetwork((iprange[0] - 1, width), version=start.version)
1895 cidr_list = cidr_partition(cidr_span, exclude)[2]
1896 cidr_span = cidr_list.pop()
1897 if cidr_span.last > iprange[1]:
1898 exclude = IPNetwork((iprange[1] + 1, width), version=start.version)
1899 cidr_list += cidr_partition(cidr_span, exclude)[0]
1900 else:
1901 cidr_list.append(cidr_span)
1902
1903 return cidr_list
1904
1905
1906def smallest_matching_cidr(ip, cidrs):
1907 """
1908 Matches an IP address or subnet against a given sequence of IP addresses
1909 and subnets.
1910
1911 :param ip: a single IP address or subnet.
1912
1913 :param cidrs: a sequence of IP addresses and/or subnets.
1914
1915 :return: the smallest (most specific) matching IPAddress or IPNetwork
1916 object from the provided sequence, None if there was no match.
1917 """
1918 match = None
1919
1920 if not hasattr(cidrs, '__iter__'):
1921 raise TypeError('IP address/subnet sequence expected, not %r!' % (cidrs,))
1922
1923 ip = IPAddress(ip)
1924 for cidr in sorted([IPNetwork(cidr) for cidr in cidrs]):
1925 if ip in cidr:
1926 match = cidr
1927 else:
1928 if match is not None and cidr.network not in match:
1929 break
1930
1931 return match
1932
1933
1934def largest_matching_cidr(ip, cidrs):
1935 """
1936 Matches an IP address or subnet against a given sequence of IP addresses
1937 and subnets.
1938
1939 :param ip: a single IP address or subnet.
1940
1941 :param cidrs: a sequence of IP addresses and/or subnets.
1942
1943 :return: the largest (least specific) matching IPAddress or IPNetwork
1944 object from the provided sequence, None if there was no match.
1945 """
1946 match = None
1947
1948 if not hasattr(cidrs, '__iter__'):
1949 raise TypeError('IP address/subnet sequence expected, not %r!' % (cidrs,))
1950
1951 ip = IPAddress(ip)
1952 for cidr in sorted([IPNetwork(cidr) for cidr in cidrs]):
1953 if ip in cidr:
1954 match = cidr
1955 break
1956
1957 return match
1958
1959
1960def all_matching_cidrs(ip, cidrs):
1961 """
1962 Matches an IP address or subnet against a given sequence of IP addresses
1963 and subnets.
1964
1965 :param ip: a single IP address.
1966
1967 :param cidrs: a sequence of IP addresses and/or subnets.
1968
1969 :return: all matching IPAddress and/or IPNetwork objects from the provided
1970 sequence, an empty list if there was no match.
1971 """
1972 matches = []
1973
1974 if not hasattr(cidrs, '__iter__'):
1975 raise TypeError('IP address/subnet sequence expected, not %r!' % (cidrs,))
1976
1977 ip = IPAddress(ip)
1978 for cidr in sorted([IPNetwork(cidr) for cidr in cidrs]):
1979 if ip in cidr:
1980 matches.append(cidr)
1981 else:
1982 if matches and cidr.network not in matches[-1]:
1983 break
1984
1985 return matches
1986
1987
1988# -----------------------------------------------------------------------------
1989# Cached IPv4 address range lookups.
1990# -----------------------------------------------------------------------------
1991IPV4_LOOPBACK = IPNetwork('127.0.0.0/8') # Loopback addresses (RFC 990)
1992
1993IPV4_PRIVATE_USE = [
1994 IPNetwork('10.0.0.0/8'), # Class A private network local communication (RFC 1918)
1995 IPNetwork('172.16.0.0/12'), # Private network - local communication (RFC 1918)
1996 IPNetwork('192.168.0.0/16'), # Class B private network local communication (RFC 1918)
1997]
1998
1999IPV4_LINK_LOCAL = IPNetwork('169.254.0.0/16')
2000
2001IPV4_MULTICAST = IPNetwork('224.0.0.0/4')
2002
2003IPV4_6TO4 = IPNetwork('192.88.99.0/24') # 6to4 anycast relays (RFC 3068)
2004
2005IPV4_RESERVED = (
2006 IPNetwork('0.0.0.0/8'), # Broadcast message (RFC 1700)
2007 IPNetwork('192.0.2.0/24'), # TEST-NET examples and documentation (RFC 5737)
2008 IPNetwork('240.0.0.0/4'), # Reserved for multicast assignments (RFC 5771)
2009 IPNetwork('198.51.100.0/24'), # TEST-NET-2 examples and documentation (RFC 5737)
2010 IPNetwork('203.0.113.0/24'), # TEST-NET-3 examples and documentation (RFC 5737)
2011 # Reserved multicast
2012 IPNetwork('233.252.0.0/24'), # Multicast test network
2013 IPRange('234.0.0.0', '238.255.255.255'),
2014 IPRange('225.0.0.0', '231.255.255.255'),
2015) + (IPV4_LOOPBACK, IPV4_6TO4)
2016
2017IPV4_NOT_GLOBALLY_REACHABLE = [
2018 IPNetwork(net)
2019 for net in [
2020 '0.0.0.0/8',
2021 '10.0.0.0/8',
2022 '100.64.0.0/10',
2023 '127.0.0.0/8',
2024 '169.254.0.0/16',
2025 '172.16.0.0/12',
2026 '192.0.0.0/24',
2027 '192.0.0.170/31',
2028 '192.0.2.0/24',
2029 '192.168.0.0/16',
2030 '198.18.0.0/15',
2031 '198.51.100.0/24',
2032 '203.0.113.0/24',
2033 '240.0.0.0/4',
2034 '255.255.255.255/32',
2035 ]
2036]
2037
2038IPV4_NOT_GLOBALLY_REACHABLE_EXCEPTIONS = [
2039 IPNetwork(net) for net in ['192.0.0.9/32', '192.0.0.10/32']
2040]
2041
2042# -----------------------------------------------------------------------------
2043# Cached IPv6 address range lookups.
2044# -----------------------------------------------------------------------------
2045IPV6_LOOPBACK = IPNetwork('::1/128')
2046
2047IPV6_UNIQUE_LOCAL = IPNetwork('fc00::/7')
2048
2049IPV6_LINK_LOCAL = IPNetwork('fe80::/10')
2050
2051IPV6_MULTICAST = IPNetwork('ff00::/8')
2052
2053IPV6_RESERVED = (
2054 IPNetwork('ff00::/12'),
2055 IPNetwork('::/8'),
2056 IPNetwork('0100::/8'),
2057 IPNetwork('0200::/7'),
2058 IPNetwork('0400::/6'),
2059 IPNetwork('0800::/5'),
2060 IPNetwork('1000::/4'),
2061 IPNetwork('4000::/3'),
2062 IPNetwork('6000::/3'),
2063 IPNetwork('8000::/3'),
2064 IPNetwork('A000::/3'),
2065 IPNetwork('C000::/3'),
2066 IPNetwork('E000::/4'),
2067 IPNetwork('F000::/5'),
2068 IPNetwork('F800::/6'),
2069 IPNetwork('FE00::/9'),
2070)
2071
2072IPV6_NOT_GLOBALLY_REACHABLE = [
2073 IPNetwork(net)
2074 for net in [
2075 '::1/128',
2076 '::/128',
2077 '::ffff:0:0/96',
2078 '64:ff9b:1::/48',
2079 '100::/64',
2080 '2001::/23',
2081 '2001:db8::/32',
2082 '2002::/16',
2083 'fc00::/7',
2084 'fe80::/10',
2085 ]
2086]
2087
2088IPV6_NOT_GLOBALLY_REACHABLE_EXCEPTIONS = [
2089 IPNetwork(net)
2090 for net in [
2091 '2001:1::1/128',
2092 '2001:1::2/128',
2093 '2001:3::/32',
2094 '2001:4:112::/48',
2095 '2001:20::/28',
2096 '2001:30::/28',
2097 ]
2098]