mirror of
https://github.com/python/cpython.git
synced 2025-12-04 16:43:27 +00:00
Issue 14814: Docs work showed some more cases of networks pretending to be addresses and highlighted the weird approach to implementing the 'is_whatever' properties. Impl now illustrates far more clearly that networks have a property if both their network and broadcast addresses have that property
This commit is contained in:
parent
d9baa8592c
commit
730f67f2fa
3 changed files with 691 additions and 337 deletions
|
|
@ -9,17 +9,26 @@
|
||||||
|
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
The :mod:`ipaddress` module provides the capabilities to create, manipulate and
|
.. note::
|
||||||
operate on IPv4 and IPv6 addresses and networks.
|
|
||||||
|
|
||||||
This is the full module API reference - for an overview and introduction,
|
The ``ipaddress`` module has been included in the standard library on a
|
||||||
see :ref:`ipaddress-howto`.
|
:term:`provisional basis <provisional package>`. Backwards incompatible
|
||||||
|
changes (up to and including removal of the package) may occur if deemed
|
||||||
|
necessary by the core developers.
|
||||||
|
|
||||||
|
:mod:`ipaddress` provides the capabilities to create, manipulate and
|
||||||
|
operate on IPv4 and IPv6 addresses and networks.
|
||||||
|
|
||||||
The functions and classes in this module make it straightforward to handle
|
The functions and classes in this module make it straightforward to handle
|
||||||
various tasks related to IP addresses, including checking whether or not two
|
various tasks related to IP addresses, including checking whether or not two
|
||||||
hosts are on the same subnet, iterating over all hosts in a particular
|
hosts are on the same subnet, iterating over all hosts in a particular
|
||||||
subnet, as well as checking whether or not a string represents a valid
|
subnet, checking whether or not a string represents a valid IP address or
|
||||||
IP address or network definition.
|
network definition, and so on.
|
||||||
|
|
||||||
|
This is the full module API reference - for an overview and introduction,
|
||||||
|
see :ref:`ipaddress-howto`.
|
||||||
|
|
||||||
|
.. versionadded:: 3.3
|
||||||
|
|
||||||
|
|
||||||
Convenience factory functions
|
Convenience factory functions
|
||||||
|
|
@ -65,15 +74,24 @@ IP addresses, networks and interfaces:
|
||||||
:exc:`ValueError` is raised if *address* does not represent a valid IPv4 or
|
:exc:`ValueError` is raised if *address* does not represent a valid IPv4 or
|
||||||
IPv6 address.
|
IPv6 address.
|
||||||
|
|
||||||
|
One downside of these convenience functions is that the need to handle both
|
||||||
|
IPv4 and IPv6 formats means that error messages provide minimal
|
||||||
|
information on the precise error, as the functions don't know whether the
|
||||||
|
IPv4 or IPv6 format was intended. More detailed error reporting can be
|
||||||
|
obtained by calling the appropriate version specific class constructors
|
||||||
|
directly.
|
||||||
|
|
||||||
|
|
||||||
|
IP Addresses
|
||||||
|
------------
|
||||||
|
|
||||||
Address objects
|
Address objects
|
||||||
---------------
|
^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
The :class:`IPv4Address` and :class:`IPv6Address` objects share a lot of common
|
The :class:`IPv4Address` and :class:`IPv6Address` objects share a lot of common
|
||||||
attributes. Some attributes that are only meaningful for IPv6 addresses are
|
attributes. Some attributes that are only meaningful for IPv6 addresses are
|
||||||
also implemented by :class:`IPv4Address` objects, in order to make it easier to
|
also implemented by :class:`IPv4Address` objects, in order to make it easier to
|
||||||
write code that handles both IP versions correctly. To avoid duplication, all
|
write code that handles both IP versions correctly.
|
||||||
common attributes will only be documented for :class:`IPv4Address`.
|
|
||||||
|
|
||||||
.. class:: IPv4Address(address)
|
.. class:: IPv4Address(address)
|
||||||
|
|
||||||
|
|
@ -84,66 +102,79 @@ common attributes will only be documented for :class:`IPv4Address`.
|
||||||
|
|
||||||
1. A string in decimal-dot notation, consisting of four decimal integers in
|
1. A string in decimal-dot notation, consisting of four decimal integers in
|
||||||
the inclusive range 0-255, separated by dots (e.g. ``192.168.0.1``). Each
|
the inclusive range 0-255, separated by dots (e.g. ``192.168.0.1``). Each
|
||||||
integer represents an octet (byte) in the address, big-endian.
|
integer represents an octet (byte) in the address. Leading zeroes are
|
||||||
|
tolerated only for values less then 8 (as there is no ambiguity
|
||||||
|
between the decimal and octal interpretations of such strings).
|
||||||
2. An integer that fits into 32 bits.
|
2. An integer that fits into 32 bits.
|
||||||
3. An integer packed into a :class:`bytes` object of length 4, big-endian.
|
3. An integer packed into a :class:`bytes` object of length 4 (most
|
||||||
|
significant octet first).
|
||||||
|
|
||||||
>>> ipaddress.IPv4Address('192.168.0.1')
|
>>> ipaddress.IPv4Address('192.168.0.1')
|
||||||
IPv4Address('192.168.0.1')
|
IPv4Address('192.168.0.1')
|
||||||
>>> ipaddress.IPv4Address('192.0.2.1') == ipaddress.IPv4Address(3221225985)
|
>>> ipaddress.IPv4Address(3221225985)
|
||||||
True
|
IPv4Address('192.168.0.1')
|
||||||
|
>>> ipaddress.IPv4Address(b'\xC0\xA8\x00\x01')
|
||||||
.. attribute:: exploded
|
IPv4Address('192.168.0.1')
|
||||||
|
|
||||||
The longhand version of the address as a string. Note: the
|
|
||||||
exploded/compressed distinction is meaningful only for IPv6 addresses.
|
|
||||||
For IPv4 addresses it is the same.
|
|
||||||
|
|
||||||
.. attribute:: compressed
|
|
||||||
|
|
||||||
The shorthand version of the address as a string.
|
|
||||||
|
|
||||||
.. attribute:: packed
|
|
||||||
|
|
||||||
The binary representation of this address - a :class:`bytes` object.
|
|
||||||
|
|
||||||
.. attribute:: version
|
.. attribute:: version
|
||||||
|
|
||||||
A numeric version number.
|
The appropriate version number: ``4`` for IPv4, ``6`` for IPv6.
|
||||||
|
|
||||||
.. attribute:: max_prefixlen
|
.. attribute:: max_prefixlen
|
||||||
|
|
||||||
Maximal length of the prefix (in bits). The prefix defines the number of
|
The total number of bits in the address representation for this
|
||||||
leading bits in an address that are compared to determine whether or not an
|
version: ``32`` for IPv4, ``128`` for IPv6.
|
||||||
address is part of a network.
|
|
||||||
|
The prefix defines the number of leading bits in an address that
|
||||||
|
are compared to determine whether or not an address is part of a
|
||||||
|
network.
|
||||||
|
|
||||||
|
.. attribute:: compressed
|
||||||
|
.. attribute:: exploded
|
||||||
|
|
||||||
|
The string representation in dotted decimal notation. Leading zeroes
|
||||||
|
are never included in the representation.
|
||||||
|
|
||||||
|
As IPv4 does not define a shorthand notation for addresses with octets
|
||||||
|
set to zero, these two attributes are always the same as ``str(addr)``
|
||||||
|
for IPv4 addresses. Exposing these attributes makes it easier to
|
||||||
|
write display code that can handle both IPv4 and IPv6 addresses.
|
||||||
|
|
||||||
|
.. attribute:: packed
|
||||||
|
|
||||||
|
The binary representation of this address - a :class:`bytes` object of
|
||||||
|
the appropriate length (most significant octet first). This is 4 bytes
|
||||||
|
for IPv4 and 16 bytes for IPv6.
|
||||||
|
|
||||||
.. attribute:: is_multicast
|
.. attribute:: is_multicast
|
||||||
|
|
||||||
``True`` if the address is reserved for multicast use. See :RFC:`3171` (for
|
``True`` if the address is reserved for multicast use. See
|
||||||
IPv4) or :RFC:`2373` (for IPv6).
|
:RFC:`3171` (for IPv4) or :RFC:`2373` (for IPv6).
|
||||||
|
|
||||||
.. attribute:: is_private
|
.. attribute:: is_private
|
||||||
|
|
||||||
``True`` if the address is allocated for private networks. See :RFC:`1918`
|
``True`` if the address is allocated for private networks. See
|
||||||
(for IPv4) or :RFC:`4193` (for IPv6).
|
:RFC:`1918` (for IPv4) or :RFC:`4193` (for IPv6).
|
||||||
|
|
||||||
.. attribute:: is_unspecified
|
.. attribute:: is_unspecified
|
||||||
|
|
||||||
``True`` if the address is unspecified. See :RFC:`5375` (for IPv4) or
|
``True`` if the address is unspecified. See :RFC:`5375` (for IPv4)
|
||||||
:RFC:`2373` (for IPv6).
|
or :RFC:`2373` (for IPv6).
|
||||||
|
|
||||||
.. attribute:: is_reserved
|
.. attribute:: is_reserved
|
||||||
|
|
||||||
``True`` if the address is otherwise IETF reserved.
|
``True`` if the address is otherwise IETF reserved.
|
||||||
|
|
||||||
.. attribute:: is_loopback
|
.. attribute:: is_loopback
|
||||||
|
|
||||||
``True`` if this is a loopback address. See :RFC:`3330` (for IPv4) or
|
``True`` if this is a loopback address. See :RFC:`3330` (for IPv4)
|
||||||
:RFC:`2373` (for IPv6).
|
or :RFC:`2373` (for IPv6).
|
||||||
|
|
||||||
.. attribute:: is_link_local
|
.. attribute:: is_link_local
|
||||||
|
|
||||||
``True`` if the address is reserved for link-local. See :RFC:`3927`.
|
``True`` if the address is reserved for link-local usage. See
|
||||||
|
:RFC:`3927`.
|
||||||
|
|
||||||
|
|
||||||
.. class:: IPv6Address(address)
|
.. class:: IPv6Address(address)
|
||||||
|
|
||||||
|
|
@ -165,31 +196,79 @@ common attributes will only be documented for :class:`IPv4Address`.
|
||||||
>>> ipaddress.IPv6Address('2001:db8::1000')
|
>>> ipaddress.IPv6Address('2001:db8::1000')
|
||||||
IPv6Address('2001:db8::1000')
|
IPv6Address('2001:db8::1000')
|
||||||
|
|
||||||
All the attributes exposed by :class:`IPv4Address` are supported. In
|
All the attributes implemented by :class:`IPv4Address` are supported. In
|
||||||
addition, the following attributs are exposed only by :class:`IPv6Address`.
|
addition, the following attributs are implemented only by
|
||||||
|
:class:`IPv6Address`.
|
||||||
|
|
||||||
|
.. attribute:: compressed
|
||||||
|
|
||||||
|
The short form of the address representation, with leading zeroes in
|
||||||
|
groups omitted and the longest sequence of groups consisting entirely of
|
||||||
|
zeroes collapsed to a single empty group.
|
||||||
|
|
||||||
|
This is also the value returned by ``str(addr)`` for IPv6 addresses.
|
||||||
|
|
||||||
|
.. attribute:: exploded
|
||||||
|
|
||||||
|
The long form of the address representation, with all leading zeroes and
|
||||||
|
groups consisting entirely of zeroes included.
|
||||||
|
|
||||||
|
.. attribute:: packed
|
||||||
|
.. attribute:: version
|
||||||
|
.. attribute:: max_prefixlen
|
||||||
|
.. attribute:: is_multicast
|
||||||
|
.. attribute:: is_private
|
||||||
|
.. attribute:: is_unspecified
|
||||||
|
.. attribute:: is_reserved
|
||||||
|
.. attribute:: is_loopback
|
||||||
|
.. attribute:: is_link_local
|
||||||
|
|
||||||
|
Refer to the corresponding attribute documentation in
|
||||||
|
:class:`IPv4Address`
|
||||||
|
|
||||||
.. attribute:: is_site_local
|
.. attribute:: is_site_local
|
||||||
|
|
||||||
``True`` if the address is reserved for site-local. Note that the site-local
|
``True`` if the address is reserved for site-local usage. Note that
|
||||||
address space has been deprecated by :RFC:`3879`. Use
|
the site-local address space has been deprecated by :RFC:`3879`. Use
|
||||||
:attr:`~IPv4Address.is_private` to test if this address is in the space of
|
:attr:`~IPv4Address.is_private` to test if this address is in the
|
||||||
unique local addresses as defined by :RFC:`4193`.
|
space of unique local addresses as defined by :RFC:`4193`.
|
||||||
|
|
||||||
.. attribute:: ipv4_mapped
|
.. attribute:: ipv4_mapped
|
||||||
|
|
||||||
If this address represents a IPv4 mapped address, return the IPv4 mapped
|
For addresses that appear to be IPv4 mapped addresses (starting with
|
||||||
address. Otherwise return ``None``.
|
``::FFFF/96``), this property will report the embedded IPv4 address.
|
||||||
|
For any other address, this property will be ``None``.
|
||||||
.. attribute:: teredo
|
|
||||||
|
|
||||||
If this address appears to be a teredo address (starts with ``2001::/32``),
|
|
||||||
return a tuple of embedded teredo IPs ``(server, client)`` pairs. Otherwise
|
|
||||||
return ``None``.
|
|
||||||
|
|
||||||
.. attribute:: sixtofour
|
.. attribute:: sixtofour
|
||||||
|
|
||||||
If this address appears to contain a 6to4 embedded address, return the
|
For addresses that appear to be 6to4 addresses (starting with
|
||||||
embedded IPv4 address. Otherwise return ``None``.
|
``2002::/16``) as defined by :RFC:`3056`, this property will report
|
||||||
|
the embedded IPv4 address. For any other address, this property will
|
||||||
|
be ``None``.
|
||||||
|
|
||||||
|
.. attribute:: teredo
|
||||||
|
|
||||||
|
For addresses that appear to be Teredo addresses (starting with
|
||||||
|
``2001::/32``) as defined by :RFC:`4380`, this property will report
|
||||||
|
the embedded ``(server, client)`` IP address pair. For any other
|
||||||
|
address, this property will be ``None``.
|
||||||
|
|
||||||
|
|
||||||
|
Conversion to Strings and Integers
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
To interoperate with networking interfaces such as the socket module,
|
||||||
|
addresses must be converted to strings or integers. This is handled using
|
||||||
|
the :func:`str` and :func:`int` builtin functions::
|
||||||
|
|
||||||
|
>>> str(ipaddress.IPv4Address('192.168.0.1'))
|
||||||
|
'192.168.0.1'
|
||||||
|
>>> int(ipaddress.IPv4Address('192.168.0.1'))
|
||||||
|
3232235521
|
||||||
|
>>> str(ipaddress.IPv6Address('::1'))
|
||||||
|
'::1'
|
||||||
|
>>> int(ipaddress.IPv6Address('::1'))
|
||||||
|
1
|
||||||
|
|
||||||
|
|
||||||
Operators
|
Operators
|
||||||
|
|
@ -199,6 +278,7 @@ Address objects support some operators. Unless stated otherwise, operators can
|
||||||
only be applied between compatible objects (i.e. IPv4 with IPv4, IPv6 with
|
only be applied between compatible objects (i.e. IPv4 with IPv4, IPv6 with
|
||||||
IPv6).
|
IPv6).
|
||||||
|
|
||||||
|
|
||||||
Logical operators
|
Logical operators
|
||||||
"""""""""""""""""
|
"""""""""""""""""
|
||||||
|
|
||||||
|
|
@ -212,6 +292,7 @@ examples::
|
||||||
>>> IPv4Address('127.0.0.2') != IPv4Address('127.0.0.1')
|
>>> IPv4Address('127.0.0.2') != IPv4Address('127.0.0.1')
|
||||||
True
|
True
|
||||||
|
|
||||||
|
|
||||||
Arithmetic operators
|
Arithmetic operators
|
||||||
""""""""""""""""""""
|
""""""""""""""""""""
|
||||||
|
|
||||||
|
|
@ -227,45 +308,274 @@ Integers can be added to or subtracted from address objects. Some examples::
|
||||||
ipaddress.AddressValueError: 4294967296 (>= 2**32) is not permitted as an IPv4 address
|
ipaddress.AddressValueError: 4294967296 (>= 2**32) is not permitted as an IPv4 address
|
||||||
|
|
||||||
|
|
||||||
|
IP Network definitions
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
The :class:`IPv4Network` and :class:`IPv6Network` objects provide a mechanism
|
||||||
|
for defining and inspecting IP network definitions. A network definition
|
||||||
|
consists of a *mask* and a *network address*, and as such defines a range of
|
||||||
|
IP addresses that equal the network address when masked (binary AND) with the
|
||||||
|
mask. For example, a network definition with the mask ``255.255.255.0`` and
|
||||||
|
the network address ``192.168.1.0`` consists of IP addresses in the inclusive
|
||||||
|
range ``192.168.1.0`` to ``192.168.1.255``.
|
||||||
|
|
||||||
|
|
||||||
|
Prefix, net mask and host mask
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
There are several equivalent ways to specify IP network masks. A *prefix*
|
||||||
|
``/<nbits>`` is a notation that denotes how many high-order bits are set in
|
||||||
|
the network mask. A *net mask* is an IP address with some number of
|
||||||
|
high-order bits set. Thus the prefix ``/24`` is equivalent to the net mask
|
||||||
|
``255.255.255.0`` in IPv4, or ``ffff:ff00::`` in IPv6. In addition, a
|
||||||
|
*host mask* is the logical inverse of a *net mask*, and is sometimes used
|
||||||
|
(for example in Cisco access control lists) to denote a network mask. The
|
||||||
|
host mask equivalent to ``/24`` in IPv4 is ``0.0.0.255``.
|
||||||
|
|
||||||
|
|
||||||
Network objects
|
Network objects
|
||||||
---------------
|
^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
All attributes implemented by address objects are implemented by network
|
||||||
|
objects as well. In addition, network objects implement additional attributes.
|
||||||
|
All of these are common between :class:`IPv4Network` and :class:`IPv6Network`,
|
||||||
|
so to avoid duplication they are only documented for :class:`IPv4Network`.
|
||||||
|
|
||||||
.. class:: IPv4Network(address, strict=True)
|
.. class:: IPv4Network(address, strict=True)
|
||||||
|
|
||||||
Construct an IPv4 network. *address* is a string or integer representing the
|
Construct an IPv4 network definition. *address* can be one of the following:
|
||||||
IP address (and optionally the network). An :exc:`AddressValueError` is
|
|
||||||
raised if *address* is not a valid IPv4 address. A :exc:`NetmaskValueError`
|
1. A string consisting of an IP address and an optional mask, separated by
|
||||||
is raised if the netmask is not valid for an IPv4 address.
|
a slash (``/``). The IP address is the network address, and the mask
|
||||||
|
can be either a single number, which means it's a *prefix*, or a string
|
||||||
|
representation of an IPv4 address. If it's the latter, the mask is
|
||||||
|
interpreted as a *net mask* if it starts with a non-zero field, or as
|
||||||
|
a *host mask* if it starts with a zero field. If no mask is provided,
|
||||||
|
it's considered to be ``/32``.
|
||||||
|
|
||||||
|
For example, the following *address* specifications are equivalent:
|
||||||
|
``192.168.1.0/24``, ``192.168.1.0/255.255.255.0`` and
|
||||||
|
``192.168.1.0/0.0.0.255``.
|
||||||
|
|
||||||
|
2. An integer that fits into 32 bits. This is equivalent to a
|
||||||
|
single-address network, with the network address being *address* and
|
||||||
|
the mask being ``/32``.
|
||||||
|
|
||||||
|
3. An integer packed into a :class:`bytes` object of length 4, big-endian.
|
||||||
|
The interpretation is similar to an integer *address*.
|
||||||
|
|
||||||
|
An :exc:`AddressValueError` is raised if *address* is not a valid IPv4
|
||||||
|
address. A :exc:`NetmaskValueError` is raised if the mask is not valid for
|
||||||
|
an IPv4 address.
|
||||||
|
|
||||||
If *strict* is ``True`` and host bits are set in the supplied address,
|
If *strict* is ``True`` and host bits are set in the supplied address,
|
||||||
then :exc:`ValueError` is raised. Otherwise, the host bits are masked out
|
then :exc:`ValueError` is raised. Otherwise, the host bits are masked out
|
||||||
to determine the appropriate network address.
|
to determine the appropriate network address.
|
||||||
|
|
||||||
>>> ipaddress.IPv4Network('192.0.2.0/27')
|
This class implements all the attributes of :class:`IPv4Address`, and also
|
||||||
IPv4Network('192.0.2.0/27')
|
the following attributes and methods. Unless stated otherwise, all methods
|
||||||
>>> ipaddress.IPv4Network('192.0.2.0/27').netmask
|
accepting other network / address objects will raise :exc:`TypeError` if
|
||||||
IPv4Address('255.255.255.224')
|
the argument's IP version is incompatible to ``self``:
|
||||||
>>> ipaddress.IPv4Network('192.0.2.5/27', strict=False)
|
|
||||||
IPv4Network('192.0.2.0/27')
|
.. attribute:: broadcast_address
|
||||||
|
|
||||||
|
The broadcast address for the network.
|
||||||
|
|
||||||
|
.. attribute:: host mask
|
||||||
|
|
||||||
|
The host mask, as a string.
|
||||||
|
|
||||||
|
.. attribute:: with_prefixlen
|
||||||
|
|
||||||
|
A string representation of the network, with the mask in prefix notation.
|
||||||
|
|
||||||
|
.. attribute:: with_netmask
|
||||||
|
|
||||||
|
A string representation of the network, with the mask in net mask notation.
|
||||||
|
|
||||||
|
.. attribute:: with_hostmask
|
||||||
|
|
||||||
|
A string representation of the network, with the mask in host mask notation.
|
||||||
|
|
||||||
|
.. attribute:: num_addresses
|
||||||
|
|
||||||
|
The total number of addresses in the network.
|
||||||
|
|
||||||
|
.. attribute:: prefixlen
|
||||||
|
|
||||||
|
Length of the prefix, in bits.
|
||||||
|
|
||||||
|
.. method:: hosts()
|
||||||
|
|
||||||
|
Generates an iterator over the usable hosts in the network. The usable hosts
|
||||||
|
are all the IP addresses that belong to the network, except the network
|
||||||
|
address itself and the network broadcast address.
|
||||||
|
|
||||||
|
>>> list(ip_network('192.0.2.0/29').hosts())
|
||||||
|
[IPv4Address('192.0.2.1'), IPv4Address('192.0.2.2'),
|
||||||
|
IPv4Address('192.0.2.3'), IPv4Address('192.0.2.4'),
|
||||||
|
IPv4Address('192.0.2.5'), IPv4Address('192.0.2.6')]
|
||||||
|
|
||||||
|
.. method:: overlaps(other)
|
||||||
|
|
||||||
|
``True`` if this network is partly contained in *other*.
|
||||||
|
|
||||||
|
.. method:: address_exclude(network)
|
||||||
|
|
||||||
|
Computes the network defintions resulting from removing the given *network*
|
||||||
|
from this one. Returns a generator. Raises :exc:`ValueError` if *network*
|
||||||
|
is not completely contained in this network.
|
||||||
|
|
||||||
|
>>> n1 = ip_network('192.0.2.0/28')
|
||||||
|
>>> n2 = ip_network('192.0.2.1/32')
|
||||||
|
>>> list(n1.address_exclude(n2))
|
||||||
|
[IPv4Network('192.0.2.8/29'), IPv4Network('192.0.2.4/30'),
|
||||||
|
IPv4Network('192.0.2.2/31'), IPv4Network('192.0.2.0/32')]
|
||||||
|
|
||||||
|
.. method:: subnets(prefixlen_diff=1, new_prefix=None)
|
||||||
|
|
||||||
|
The subnets that join to make the current network definition, depending on
|
||||||
|
the argument values. *prefixlen_diff* is the amount our prefix length
|
||||||
|
should be increased by. *new_prefix* is the desired new prefix of the
|
||||||
|
subnets; it must be larger than our prefix. One and only one of
|
||||||
|
*prefixlen_diff* and *new_prefix* must be set. Returns an iterator of
|
||||||
|
network objects.
|
||||||
|
|
||||||
|
>>> list(ip_network('192.0.2.0/24').subnets())
|
||||||
|
[IPv4Network('192.0.2.0/25'), IPv4Network('192.0.2.128/25')]
|
||||||
|
>>> list(ip_network('192.0.2.0/24').subnets(prefixlen_diff=2))
|
||||||
|
[IPv4Network('192.0.2.0/26'), IPv4Network('192.0.2.64/26'),
|
||||||
|
IPv4Network('192.0.2.128/26'), IPv4Network('192.0.2.192/26')]
|
||||||
|
>>> list(ip_network('192.0.2.0/24').subnets(new_prefix=26))
|
||||||
|
[IPv4Network('192.0.2.0/26'), IPv4Network('192.0.2.64/26'),
|
||||||
|
IPv4Network('192.0.2.128/26'), IPv4Network('192.0.2.192/26')]
|
||||||
|
>>> list(ip_network('192.0.2.0/24').subnets(new_prefix=23))
|
||||||
|
Traceback (most recent call last):
|
||||||
|
File "<stdin>", line 1, in <module>
|
||||||
|
raise ValueError('new prefix must be longer')
|
||||||
|
ValueError: new prefix must be longer
|
||||||
|
>>> list(ip_network('192.0.2.0/24').subnets(new_prefix=25))
|
||||||
|
[IPv4Network('192.0.2.0/25'), IPv4Network('192.0.2.128/25')]
|
||||||
|
>>>
|
||||||
|
|
||||||
|
.. method:: supernet(prefixlen_diff=1, new_prefix=None)
|
||||||
|
|
||||||
|
The supernet containing this network definition, depending on the argument
|
||||||
|
values. *prefixlen_diff* is the amount our prefix length should be
|
||||||
|
decreased by. *new_prefix* is the desired new prefix of the supernet; it
|
||||||
|
must be smaller than our prefix. One and only one of *prefixlen_diff* and
|
||||||
|
*new_prefix* must be set. Returns a single network object.
|
||||||
|
|
||||||
|
>>> ip_network('192.0.2.0/24').supernet()
|
||||||
|
IPv4Network('192.0.2.0/23')
|
||||||
|
>>> ip_network('192.0.2.0/24').supernet(prefixlen_diff=2)
|
||||||
|
IPv4Network('192.0.0.0/22')
|
||||||
|
>>> ip_network('192.0.2.0/24').supernet(new_prefix=20)
|
||||||
|
IPv4Network('192.0.0.0/20')
|
||||||
|
|
||||||
|
.. method:: compare_networks(other)
|
||||||
|
|
||||||
|
Compare this network to *other*. In this comparison only the network
|
||||||
|
addresses are considered; host bits aren't. Returns either ``-1``, ``0``
|
||||||
|
or ``1``.
|
||||||
|
|
||||||
|
>>> ip_network('192.0.2.1/32').compare_networks(ip_network('192.0.2.2/32'))
|
||||||
|
-1
|
||||||
|
>>> ip_network('192.0.2.1/32').compare_networks(ip_network('192.0.2.0/32'))
|
||||||
|
1
|
||||||
|
>>> ip_network('192.0.2.1/32').compare_networks(ip_network('192.0.2.1/32'))
|
||||||
|
0
|
||||||
|
|
||||||
|
|
||||||
.. class:: IPv6Network(address, strict=True)
|
.. class:: IPv6Network(address, strict=True)
|
||||||
|
|
||||||
Construct an IPv6 network. *address* is a string or integer representing the
|
Construct an IPv6 network definition. *address* can be one of the following:
|
||||||
IP address (and optionally the network). An :exc:`AddressValueError` is
|
|
||||||
raised if *address* is not a valid IPv6 address. A :exc:`NetmaskValueError`
|
1. A string consisting of an IP address and an optional mask, separated by
|
||||||
is raised if the netmask is not valid for an IPv6 address.
|
a slash (``/``). The IP addrses is the network address, and the mask
|
||||||
|
can be either a single number, which means it's a *prefix*, or a string
|
||||||
|
representation of an IPv6 address. If it's the latter, the mask is
|
||||||
|
interpreted as a *net mask*. If no mask is provided, it's considered to
|
||||||
|
be ``/128``.
|
||||||
|
|
||||||
|
For example, the following *address* specifications are equivalent:
|
||||||
|
``2001:db00::0/24`` and ``2001:db00::0/ffff:ff00::``.
|
||||||
|
|
||||||
|
2. An integer that fits into 128 bits. This is equivalent to a
|
||||||
|
single-address network, with the network address being *address* and
|
||||||
|
the mask being ``/128``.
|
||||||
|
|
||||||
|
3. An integer packed into a :class:`bytes` object of length 16, bit-endian.
|
||||||
|
The interpretation is similar to an integer *address*.
|
||||||
|
|
||||||
|
An :exc:`AddressValueError` is raised if *address* is not a valid IPv6
|
||||||
|
address. A :exc:`NetmaskValueError` is raised if the mask is not valid for
|
||||||
|
an IPv6 address.
|
||||||
|
|
||||||
If *strict* is ``True`` and host bits are set in the supplied address,
|
If *strict* is ``True`` and host bits are set in the supplied address,
|
||||||
then :exc:`ValueError` is raised. Otherwise, the host bits are masked out
|
then :exc:`ValueError` is raised. Otherwise, the host bits are masked out
|
||||||
to determine the appropriate network address.
|
to determine the appropriate network address.
|
||||||
|
|
||||||
>>> ipaddress.IPv6Network('2001:db8::/96')
|
.. describe:: Attributes and methods
|
||||||
IPv6Network('2001:db8::/96')
|
|
||||||
>>> ipaddress.IPv6Network('2001:db8::/96').netmask
|
All attributes and methods implemented by :class:`IPv4Network` and by
|
||||||
IPv6Address('ffff:ffff:ffff:ffff:ffff:ffff::')
|
:class:`IPv6Address` are also implemented by :class:`IPv6Network`.
|
||||||
>>> ipaddress.IPv6Network('2001:db8::1000/96', strict=False)
|
|
||||||
IPv6Network('2001:db8::/96')
|
|
||||||
|
Operators
|
||||||
|
^^^^^^^^^
|
||||||
|
|
||||||
|
Network objects support some operators. Unless stated otherwise, operators can
|
||||||
|
only be applied between compatible objects (i.e. IPv4 with IPv4, IPv6 with
|
||||||
|
IPv6).
|
||||||
|
|
||||||
|
Logical operators
|
||||||
|
"""""""""""""""""
|
||||||
|
|
||||||
|
Network objects can be compared with the usual set of logical operators,
|
||||||
|
similarly to address objects.
|
||||||
|
|
||||||
|
Iteration
|
||||||
|
"""""""""
|
||||||
|
|
||||||
|
Network objects can be iterated to list all the addresses belonging to the
|
||||||
|
network. For iteration, *all* hosts are returned, including unusable hosts
|
||||||
|
(for usable hosts, use the :meth:`~IPv4Network.hosts` method). An
|
||||||
|
example::
|
||||||
|
|
||||||
|
>>> for addr in IPv4Network('192.0.2.0/28'):
|
||||||
|
... addr
|
||||||
|
...
|
||||||
|
IPv4Address('192.0.2.0')
|
||||||
|
IPv4Address('192.0.2.1')
|
||||||
|
IPv4Address('192.0.2.2')
|
||||||
|
IPv4Address('192.0.2.3')
|
||||||
|
IPv4Address('192.0.2.4')
|
||||||
|
IPv4Address('192.0.2.5')
|
||||||
|
IPv4Address('192.0.2.6')
|
||||||
|
IPv4Address('192.0.2.7')
|
||||||
|
IPv4Address('192.0.2.8')
|
||||||
|
IPv4Address('192.0.2.9')
|
||||||
|
IPv4Address('192.0.2.10')
|
||||||
|
IPv4Address('192.0.2.11')
|
||||||
|
IPv4Address('192.0.2.12')
|
||||||
|
IPv4Address('192.0.2.13')
|
||||||
|
IPv4Address('192.0.2.14')
|
||||||
|
IPv4Address('192.0.2.15')
|
||||||
|
|
||||||
|
Networks as containers of addresses
|
||||||
|
"""""""""""""""""""""""""""""""""""
|
||||||
|
|
||||||
|
Network objects can act as containers of addresses. Some examples::
|
||||||
|
|
||||||
|
>>> IPv4Network('192.0.2.0/28')[0]
|
||||||
|
IPv4Address('192.0.2.0')
|
||||||
|
>>> IPv4Network('192.0.2.0/28')[15]
|
||||||
|
IPv4Address('192.0.2.15')
|
||||||
|
>>> IPv4Address('192.0.2.6') in IPv4Network('192.0.2.0/28')
|
||||||
|
True
|
||||||
|
>>> IPv4Address('192.0.3.6') in IPv4Network('192.0.2.0/28')
|
||||||
|
False
|
||||||
|
|
||||||
|
|
||||||
Interface objects
|
Interface objects
|
||||||
|
|
|
||||||
554
Lib/ipaddress.py
554
Lib/ipaddress.py
|
|
@ -497,6 +497,7 @@ class _IPAddressBase(_TotalOrderingMixin):
|
||||||
prefixlen = self._prefixlen
|
prefixlen = self._prefixlen
|
||||||
return self._string_from_ip_int(self._ip_int_from_prefix(prefixlen))
|
return self._string_from_ip_int(self._ip_int_from_prefix(prefixlen))
|
||||||
|
|
||||||
|
|
||||||
class _BaseAddress(_IPAddressBase):
|
class _BaseAddress(_IPAddressBase):
|
||||||
|
|
||||||
"""A generic IP object.
|
"""A generic IP object.
|
||||||
|
|
@ -568,9 +569,6 @@ class _BaseNetwork(_IPAddressBase):
|
||||||
def __init__(self, address):
|
def __init__(self, address):
|
||||||
self._cache = {}
|
self._cache = {}
|
||||||
|
|
||||||
def __int__(self):
|
|
||||||
return int(self.network_address)
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '%s(%r)' % (self.__class__.__name__, str(self))
|
return '%s(%r)' % (self.__class__.__name__, str(self))
|
||||||
|
|
||||||
|
|
@ -937,6 +935,76 @@ class _BaseNetwork(_IPAddressBase):
|
||||||
strict=False)
|
strict=False)
|
||||||
return t.__class__('%s/%d' % (t.network_address, t.prefixlen))
|
return t.__class__('%s/%d' % (t.network_address, t.prefixlen))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_multicast(self):
|
||||||
|
"""Test if the address is reserved for multicast use.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A boolean, True if the address is a multicast address.
|
||||||
|
See RFC 2373 2.7 for details.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return (self.network_address.is_multicast and
|
||||||
|
self.broadcast_address.is_multicast)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_reserved(self):
|
||||||
|
"""Test if the address is otherwise IETF reserved.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A boolean, True if the address is within one of the
|
||||||
|
reserved IPv6 Network ranges.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return (self.network_address.is_reserved and
|
||||||
|
self.broadcast_address.is_reserved)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_link_local(self):
|
||||||
|
"""Test if the address is reserved for link-local.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A boolean, True if the address is reserved per RFC 4291.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return (self.network_address.is_link_local and
|
||||||
|
self.broadcast_address.is_link_local)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_private(self):
|
||||||
|
"""Test if this address is allocated for private networks.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A boolean, True if the address is reserved per RFC 4193.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return (self.network_address.is_private and
|
||||||
|
self.broadcast_address.is_private)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_unspecified(self):
|
||||||
|
"""Test if the address is unspecified.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A boolean, True if this is the unspecified address as defined in
|
||||||
|
RFC 2373 2.5.2.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return (self.network_address.is_unspecified and
|
||||||
|
self.broadcast_address.is_unspecified)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_loopback(self):
|
||||||
|
"""Test if the address is a loopback address.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A boolean, True if the address is a loopback address as defined in
|
||||||
|
RFC 2373 2.5.3.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return (self.network_address.is_loopback and
|
||||||
|
self.broadcast_address.is_loopback)
|
||||||
|
|
||||||
|
|
||||||
class _BaseV4:
|
class _BaseV4:
|
||||||
|
|
||||||
|
|
@ -1094,102 +1162,6 @@ class _BaseV4:
|
||||||
def version(self):
|
def version(self):
|
||||||
return self._version
|
return self._version
|
||||||
|
|
||||||
@property
|
|
||||||
def is_reserved(self):
|
|
||||||
"""Test if the address is otherwise IETF reserved.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
A boolean, True if the address is within the
|
|
||||||
reserved IPv4 Network range.
|
|
||||||
|
|
||||||
"""
|
|
||||||
reserved_network = IPv4Network('240.0.0.0/4')
|
|
||||||
if isinstance(self, _BaseAddress):
|
|
||||||
return self in reserved_network
|
|
||||||
return (self.network_address in reserved_network and
|
|
||||||
self.broadcast_address in reserved_network)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def is_private(self):
|
|
||||||
"""Test if this address is allocated for private networks.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
A boolean, True if the address is reserved per RFC 1918.
|
|
||||||
|
|
||||||
"""
|
|
||||||
private_10 = IPv4Network('10.0.0.0/8')
|
|
||||||
private_172 = IPv4Network('172.16.0.0/12')
|
|
||||||
private_192 = IPv4Network('192.168.0.0/16')
|
|
||||||
if isinstance(self, _BaseAddress):
|
|
||||||
return (self in private_10 or self in private_172 or
|
|
||||||
self in private_192)
|
|
||||||
else:
|
|
||||||
return ((self.network_address in private_10 and
|
|
||||||
self.broadcast_address in private_10) or
|
|
||||||
(self.network_address in private_172 and
|
|
||||||
self.broadcast_address in private_172) or
|
|
||||||
(self.network_address in private_192 and
|
|
||||||
self.broadcast_address in private_192))
|
|
||||||
|
|
||||||
@property
|
|
||||||
def is_multicast(self):
|
|
||||||
"""Test if the address is reserved for multicast use.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
A boolean, True if the address is multicast.
|
|
||||||
See RFC 3171 for details.
|
|
||||||
|
|
||||||
"""
|
|
||||||
multicast_network = IPv4Network('224.0.0.0/4')
|
|
||||||
if isinstance(self, _BaseAddress):
|
|
||||||
return self in IPv4Network('224.0.0.0/4')
|
|
||||||
return (self.network_address in multicast_network and
|
|
||||||
self.broadcast_address in multicast_network)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def is_unspecified(self):
|
|
||||||
"""Test if the address is unspecified.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
A boolean, True if this is the unspecified address as defined in
|
|
||||||
RFC 5735 3.
|
|
||||||
|
|
||||||
"""
|
|
||||||
unspecified_address = IPv4Address('0.0.0.0')
|
|
||||||
if isinstance(self, _BaseAddress):
|
|
||||||
return self == unspecified_address
|
|
||||||
return (self.network_address == self.broadcast_address ==
|
|
||||||
unspecified_address)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def is_loopback(self):
|
|
||||||
"""Test if the address is a loopback address.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
A boolean, True if the address is a loopback per RFC 3330.
|
|
||||||
|
|
||||||
"""
|
|
||||||
loopback_address = IPv4Network('127.0.0.0/8')
|
|
||||||
if isinstance(self, _BaseAddress):
|
|
||||||
return self in loopback_address
|
|
||||||
|
|
||||||
return (self.network_address in loopback_address and
|
|
||||||
self.broadcast_address in loopback_address)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def is_link_local(self):
|
|
||||||
"""Test if the address is reserved for link-local.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
A boolean, True if the address is link-local per RFC 3927.
|
|
||||||
|
|
||||||
"""
|
|
||||||
linklocal_network = IPv4Network('169.254.0.0/16')
|
|
||||||
if isinstance(self, _BaseAddress):
|
|
||||||
return self in linklocal_network
|
|
||||||
return (self.network_address in linklocal_network and
|
|
||||||
self.broadcast_address in linklocal_network)
|
|
||||||
|
|
||||||
|
|
||||||
class IPv4Address(_BaseV4, _BaseAddress):
|
class IPv4Address(_BaseV4, _BaseAddress):
|
||||||
|
|
||||||
|
|
@ -1236,6 +1208,79 @@ class IPv4Address(_BaseV4, _BaseAddress):
|
||||||
"""The binary representation of this address."""
|
"""The binary representation of this address."""
|
||||||
return v4_int_to_packed(self._ip)
|
return v4_int_to_packed(self._ip)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_reserved(self):
|
||||||
|
"""Test if the address is otherwise IETF reserved.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A boolean, True if the address is within the
|
||||||
|
reserved IPv4 Network range.
|
||||||
|
|
||||||
|
"""
|
||||||
|
reserved_network = IPv4Network('240.0.0.0/4')
|
||||||
|
return self in reserved_network
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_private(self):
|
||||||
|
"""Test if this address is allocated for private networks.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A boolean, True if the address is reserved per RFC 1918.
|
||||||
|
|
||||||
|
"""
|
||||||
|
private_10 = IPv4Network('10.0.0.0/8')
|
||||||
|
private_172 = IPv4Network('172.16.0.0/12')
|
||||||
|
private_192 = IPv4Network('192.168.0.0/16')
|
||||||
|
return (self in private_10 or
|
||||||
|
self in private_172 or
|
||||||
|
self in private_192)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_multicast(self):
|
||||||
|
"""Test if the address is reserved for multicast use.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A boolean, True if the address is multicast.
|
||||||
|
See RFC 3171 for details.
|
||||||
|
|
||||||
|
"""
|
||||||
|
multicast_network = IPv4Network('224.0.0.0/4')
|
||||||
|
return self in multicast_network
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_unspecified(self):
|
||||||
|
"""Test if the address is unspecified.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A boolean, True if this is the unspecified address as defined in
|
||||||
|
RFC 5735 3.
|
||||||
|
|
||||||
|
"""
|
||||||
|
unspecified_address = IPv4Address('0.0.0.0')
|
||||||
|
return self == unspecified_address
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_loopback(self):
|
||||||
|
"""Test if the address is a loopback address.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A boolean, True if the address is a loopback per RFC 3330.
|
||||||
|
|
||||||
|
"""
|
||||||
|
loopback_network = IPv4Network('127.0.0.0/8')
|
||||||
|
return self in loopback_network
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_link_local(self):
|
||||||
|
"""Test if the address is reserved for link-local.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A boolean, True if the address is link-local per RFC 3927.
|
||||||
|
|
||||||
|
"""
|
||||||
|
linklocal_network = IPv4Network('169.254.0.0/16')
|
||||||
|
return self in linklocal_network
|
||||||
|
|
||||||
|
|
||||||
class IPv4Interface(IPv4Address):
|
class IPv4Interface(IPv4Address):
|
||||||
|
|
||||||
|
|
@ -1674,162 +1719,6 @@ class _BaseV6:
|
||||||
def version(self):
|
def version(self):
|
||||||
return self._version
|
return self._version
|
||||||
|
|
||||||
@property
|
|
||||||
def is_multicast(self):
|
|
||||||
"""Test if the address is reserved for multicast use.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
A boolean, True if the address is a multicast address.
|
|
||||||
See RFC 2373 2.7 for details.
|
|
||||||
|
|
||||||
"""
|
|
||||||
multicast_network = IPv6Network('ff00::/8')
|
|
||||||
if isinstance(self, _BaseAddress):
|
|
||||||
return self in multicast_network
|
|
||||||
return (self.network_address in multicast_network and
|
|
||||||
self.broadcast_address in multicast_network)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def is_reserved(self):
|
|
||||||
"""Test if the address is otherwise IETF reserved.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
A boolean, True if the address is within one of the
|
|
||||||
reserved IPv6 Network ranges.
|
|
||||||
|
|
||||||
"""
|
|
||||||
reserved_networks = [IPv6Network('::/8'), IPv6Network('100::/8'),
|
|
||||||
IPv6Network('200::/7'), IPv6Network('400::/6'),
|
|
||||||
IPv6Network('800::/5'), IPv6Network('1000::/4'),
|
|
||||||
IPv6Network('4000::/3'), IPv6Network('6000::/3'),
|
|
||||||
IPv6Network('8000::/3'), IPv6Network('A000::/3'),
|
|
||||||
IPv6Network('C000::/3'), IPv6Network('E000::/4'),
|
|
||||||
IPv6Network('F000::/5'), IPv6Network('F800::/6'),
|
|
||||||
IPv6Network('FE00::/9')]
|
|
||||||
|
|
||||||
if isinstance(self, _BaseAddress):
|
|
||||||
return any(self in x for x in reserved_networks)
|
|
||||||
return any(self.network_address in x and self.broadcast_address in x
|
|
||||||
for x in reserved_networks)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def is_link_local(self):
|
|
||||||
"""Test if the address is reserved for link-local.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
A boolean, True if the address is reserved per RFC 4291.
|
|
||||||
|
|
||||||
"""
|
|
||||||
linklocal_network = IPv6Network('fe80::/10')
|
|
||||||
if isinstance(self, _BaseAddress):
|
|
||||||
return self in linklocal_network
|
|
||||||
return (self.network_address in linklocal_network and
|
|
||||||
self.broadcast_address in linklocal_network)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def is_site_local(self):
|
|
||||||
"""Test if the address is reserved for site-local.
|
|
||||||
|
|
||||||
Note that the site-local address space has been deprecated by RFC 3879.
|
|
||||||
Use is_private to test if this address is in the space of unique local
|
|
||||||
addresses as defined by RFC 4193.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
A boolean, True if the address is reserved per RFC 3513 2.5.6.
|
|
||||||
|
|
||||||
"""
|
|
||||||
sitelocal_network = IPv6Network('fec0::/10')
|
|
||||||
if isinstance(self, _BaseAddress):
|
|
||||||
return self in sitelocal_network
|
|
||||||
return (self.network_address in sitelocal_network and
|
|
||||||
self.broadcast_address in sitelocal_network)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def is_private(self):
|
|
||||||
"""Test if this address is allocated for private networks.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
A boolean, True if the address is reserved per RFC 4193.
|
|
||||||
|
|
||||||
"""
|
|
||||||
private_network = IPv6Network('fc00::/7')
|
|
||||||
if isinstance(self, _BaseAddress):
|
|
||||||
return self in private_network
|
|
||||||
return (self.network_address in private_network and
|
|
||||||
self.broadcast_address in private_network)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def ipv4_mapped(self):
|
|
||||||
"""Return the IPv4 mapped address.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
If the IPv6 address is a v4 mapped address, return the
|
|
||||||
IPv4 mapped address. Return None otherwise.
|
|
||||||
|
|
||||||
"""
|
|
||||||
if (self._ip >> 32) != 0xFFFF:
|
|
||||||
return None
|
|
||||||
return IPv4Address(self._ip & 0xFFFFFFFF)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def teredo(self):
|
|
||||||
"""Tuple of embedded teredo IPs.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Tuple of the (server, client) IPs or None if the address
|
|
||||||
doesn't appear to be a teredo address (doesn't start with
|
|
||||||
2001::/32)
|
|
||||||
|
|
||||||
"""
|
|
||||||
if (self._ip >> 96) != 0x20010000:
|
|
||||||
return None
|
|
||||||
return (IPv4Address((self._ip >> 64) & 0xFFFFFFFF),
|
|
||||||
IPv4Address(~self._ip & 0xFFFFFFFF))
|
|
||||||
|
|
||||||
@property
|
|
||||||
def sixtofour(self):
|
|
||||||
"""Return the IPv4 6to4 embedded address.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
The IPv4 6to4-embedded address if present or None if the
|
|
||||||
address doesn't appear to contain a 6to4 embedded address.
|
|
||||||
|
|
||||||
"""
|
|
||||||
if (self._ip >> 112) != 0x2002:
|
|
||||||
return None
|
|
||||||
return IPv4Address((self._ip >> 80) & 0xFFFFFFFF)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def is_unspecified(self):
|
|
||||||
"""Test if the address is unspecified.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
A boolean, True if this is the unspecified address as defined in
|
|
||||||
RFC 2373 2.5.2.
|
|
||||||
|
|
||||||
"""
|
|
||||||
if isinstance(self, (IPv6Network, IPv6Interface)):
|
|
||||||
return int(self.network_address) == 0 and getattr(
|
|
||||||
self, '_prefixlen', 128) == 128
|
|
||||||
return self._ip == 0
|
|
||||||
|
|
||||||
@property
|
|
||||||
def is_loopback(self):
|
|
||||||
"""Test if the address is a loopback address.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
A boolean, True if the address is a loopback address as defined in
|
|
||||||
RFC 2373 2.5.3.
|
|
||||||
|
|
||||||
"""
|
|
||||||
if isinstance(self, IPv6Network):
|
|
||||||
return int(self) == 1 and getattr(
|
|
||||||
self, '_prefixlen', 128) == 128
|
|
||||||
elif isinstance(self, IPv6Interface):
|
|
||||||
return int(self.network.network_address) == 1 and getattr(
|
|
||||||
self, '_prefixlen', 128) == 128
|
|
||||||
return self._ip == 1
|
|
||||||
|
|
||||||
|
|
||||||
class IPv6Address(_BaseV6, _BaseAddress):
|
class IPv6Address(_BaseV6, _BaseAddress):
|
||||||
|
|
||||||
|
|
@ -1878,6 +1767,138 @@ class IPv6Address(_BaseV6, _BaseAddress):
|
||||||
"""The binary representation of this address."""
|
"""The binary representation of this address."""
|
||||||
return v6_int_to_packed(self._ip)
|
return v6_int_to_packed(self._ip)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_multicast(self):
|
||||||
|
"""Test if the address is reserved for multicast use.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A boolean, True if the address is a multicast address.
|
||||||
|
See RFC 2373 2.7 for details.
|
||||||
|
|
||||||
|
"""
|
||||||
|
multicast_network = IPv6Network('ff00::/8')
|
||||||
|
return self in multicast_network
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_reserved(self):
|
||||||
|
"""Test if the address is otherwise IETF reserved.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A boolean, True if the address is within one of the
|
||||||
|
reserved IPv6 Network ranges.
|
||||||
|
|
||||||
|
"""
|
||||||
|
reserved_networks = [IPv6Network('::/8'), IPv6Network('100::/8'),
|
||||||
|
IPv6Network('200::/7'), IPv6Network('400::/6'),
|
||||||
|
IPv6Network('800::/5'), IPv6Network('1000::/4'),
|
||||||
|
IPv6Network('4000::/3'), IPv6Network('6000::/3'),
|
||||||
|
IPv6Network('8000::/3'), IPv6Network('A000::/3'),
|
||||||
|
IPv6Network('C000::/3'), IPv6Network('E000::/4'),
|
||||||
|
IPv6Network('F000::/5'), IPv6Network('F800::/6'),
|
||||||
|
IPv6Network('FE00::/9')]
|
||||||
|
|
||||||
|
return any(self in x for x in reserved_networks)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_link_local(self):
|
||||||
|
"""Test if the address is reserved for link-local.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A boolean, True if the address is reserved per RFC 4291.
|
||||||
|
|
||||||
|
"""
|
||||||
|
linklocal_network = IPv6Network('fe80::/10')
|
||||||
|
return self in linklocal_network
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_site_local(self):
|
||||||
|
"""Test if the address is reserved for site-local.
|
||||||
|
|
||||||
|
Note that the site-local address space has been deprecated by RFC 3879.
|
||||||
|
Use is_private to test if this address is in the space of unique local
|
||||||
|
addresses as defined by RFC 4193.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A boolean, True if the address is reserved per RFC 3513 2.5.6.
|
||||||
|
|
||||||
|
"""
|
||||||
|
sitelocal_network = IPv6Network('fec0::/10')
|
||||||
|
return self in sitelocal_network
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_private(self):
|
||||||
|
"""Test if this address is allocated for private networks.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A boolean, True if the address is reserved per RFC 4193.
|
||||||
|
|
||||||
|
"""
|
||||||
|
private_network = IPv6Network('fc00::/7')
|
||||||
|
return self in private_network
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_unspecified(self):
|
||||||
|
"""Test if the address is unspecified.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A boolean, True if this is the unspecified address as defined in
|
||||||
|
RFC 2373 2.5.2.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return self._ip == 0
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_loopback(self):
|
||||||
|
"""Test if the address is a loopback address.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A boolean, True if the address is a loopback address as defined in
|
||||||
|
RFC 2373 2.5.3.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return self._ip == 1
|
||||||
|
|
||||||
|
@property
|
||||||
|
def ipv4_mapped(self):
|
||||||
|
"""Return the IPv4 mapped address.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
If the IPv6 address is a v4 mapped address, return the
|
||||||
|
IPv4 mapped address. Return None otherwise.
|
||||||
|
|
||||||
|
"""
|
||||||
|
if (self._ip >> 32) != 0xFFFF:
|
||||||
|
return None
|
||||||
|
return IPv4Address(self._ip & 0xFFFFFFFF)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def teredo(self):
|
||||||
|
"""Tuple of embedded teredo IPs.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Tuple of the (server, client) IPs or None if the address
|
||||||
|
doesn't appear to be a teredo address (doesn't start with
|
||||||
|
2001::/32)
|
||||||
|
|
||||||
|
"""
|
||||||
|
if (self._ip >> 96) != 0x20010000:
|
||||||
|
return None
|
||||||
|
return (IPv4Address((self._ip >> 64) & 0xFFFFFFFF),
|
||||||
|
IPv4Address(~self._ip & 0xFFFFFFFF))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def sixtofour(self):
|
||||||
|
"""Return the IPv4 6to4 embedded address.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The IPv4 6to4-embedded address if present or None if the
|
||||||
|
address doesn't appear to contain a 6to4 embedded address.
|
||||||
|
|
||||||
|
"""
|
||||||
|
if (self._ip >> 112) != 0x2002:
|
||||||
|
return None
|
||||||
|
return IPv4Address((self._ip >> 80) & 0xFFFFFFFF)
|
||||||
|
|
||||||
|
|
||||||
class IPv6Interface(IPv6Address):
|
class IPv6Interface(IPv6Address):
|
||||||
|
|
||||||
|
|
@ -1946,6 +1967,14 @@ class IPv6Interface(IPv6Address):
|
||||||
return '%s/%s' % (self._string_from_ip_int(self._ip),
|
return '%s/%s' % (self._string_from_ip_int(self._ip),
|
||||||
self.hostmask)
|
self.hostmask)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_unspecified(self):
|
||||||
|
return self._ip == 0 and self.network.is_unspecified
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_loopback(self):
|
||||||
|
return self._ip == 1 and self.network.is_loopback
|
||||||
|
|
||||||
|
|
||||||
class IPv6Network(_BaseV6, _BaseNetwork):
|
class IPv6Network(_BaseV6, _BaseNetwork):
|
||||||
|
|
||||||
|
|
@ -2054,3 +2083,18 @@ class IPv6Network(_BaseV6, _BaseNetwork):
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return False
|
return False
|
||||||
return 0 <= prefixlen <= self._max_prefixlen
|
return 0 <= prefixlen <= self._max_prefixlen
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_site_local(self):
|
||||||
|
"""Test if the address is reserved for site-local.
|
||||||
|
|
||||||
|
Note that the site-local address space has been deprecated by RFC 3879.
|
||||||
|
Use is_private to test if this address is in the space of unique local
|
||||||
|
addresses as defined by RFC 4193.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A boolean, True if the address is reserved per RFC 3513 2.5.6.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return (self.network_address.is_site_local and
|
||||||
|
self.broadcast_address.is_site_local)
|
||||||
|
|
|
||||||
|
|
@ -647,8 +647,8 @@ class IpaddrUnitTest(unittest.TestCase):
|
||||||
|
|
||||||
ipv4 = ipaddress.ip_network('1.2.3.4')
|
ipv4 = ipaddress.ip_network('1.2.3.4')
|
||||||
ipv6 = ipaddress.ip_network('2001:658:22a:cafe:200:0:0:1')
|
ipv6 = ipaddress.ip_network('2001:658:22a:cafe:200:0:0:1')
|
||||||
self.assertEqual(ipv4, ipaddress.ip_network(int(ipv4)))
|
self.assertEqual(ipv4, ipaddress.ip_network(int(ipv4.network_address)))
|
||||||
self.assertEqual(ipv6, ipaddress.ip_network(int(ipv6)))
|
self.assertEqual(ipv6, ipaddress.ip_network(int(ipv6.network_address)))
|
||||||
|
|
||||||
v6_int = 42540616829182469433547762482097946625
|
v6_int = 42540616829182469433547762482097946625
|
||||||
self.assertEqual(self.ipv6_interface._ip,
|
self.assertEqual(self.ipv6_interface._ip,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue