diff --git a/Doc/library/ipaddress.rst b/Doc/library/ipaddress.rst --- a/Doc/library/ipaddress.rst +++ b/Doc/library/ipaddress.rst @@ -9,17 +9,26 @@ -------------- -The :mod:`ipaddress` module provides the capabilities to create, manipulate and +.. note:: + + The ``ipaddress`` module has been included in the standard library on a + :term:`provisional basis `. 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 +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 +subnet, checking whether or not a string represents a valid IP address or +network definition, and so on. + This is the full module API reference - for an overview and introduction, see :ref:`ipaddress-howto`. -The functions and classes in this module make it straightforward to handle -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 -subnet, as well as checking whether or not a string represents a valid -IP address or network definition. +.. versionadded:: 3.3 Convenience factory functions @@ -66,8 +75,11 @@ IPv6 address. +IP Addresses +------------ + Address objects ---------------- +^^^^^^^^^^^^^^^ The :class:`IPv4Address` and :class:`IPv6Address` objects share a lot of common attributes. Some attributes that are only meaningful for IPv6 addresses are @@ -165,8 +177,9 @@ >>> ipaddress.IPv6Address('2001:db8::1000') IPv6Address('2001:db8::1000') - All the attributes exposed by :class:`IPv4Address` are supported. In - addition, the following attributs are exposed only by :class:`IPv6Address`. + All the attributes implemented by :class:`IPv4Address` are supported. In + addition, the following attributs are implemented only by + :class:`IPv6Address`. .. attribute:: is_site_local @@ -227,45 +240,274 @@ 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* +``/`` 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 ---------------- +^^^^^^^^^^^^^^^ + +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) - Construct an IPv4 network. *address* is a string or integer representing the - IP address (and optionally the network). An :exc:`AddressValueError` is - raised if *address* is not a valid IPv4 address. A :exc:`NetmaskValueError` - is raised if the netmask is not valid for an IPv4 address. + Construct an IPv4 network definition. *address* can be one of the following: + + 1. A string consisting of an IP address and an optional mask, separated by + 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, - 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. - >>> ipaddress.IPv4Network('192.0.2.0/27') - IPv4Network('192.0.2.0/27') - >>> ipaddress.IPv4Network('192.0.2.0/27').netmask - IPv4Address('255.255.255.224') - >>> ipaddress.IPv4Network('192.0.2.5/27', strict=False) - IPv4Network('192.0.2.0/27') + This class implements all the attributes of :class:`IPv4Address`, and also + the following attributes and methods. Unless stated otherwise, all methods + accepting other network / address objects will raise :exc:`TypeError` if + the argument's IP version is incompatible to ``self``: + + .. 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 "", line 1, in + 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) - Construct an IPv6 network. *address* is a string or integer representing the - IP address (and optionally the network). An :exc:`AddressValueError` is - raised if *address* is not a valid IPv6 address. A :exc:`NetmaskValueError` - is raised if the netmask is not valid for an IPv6 address. + Construct an IPv6 network definition. *address* can be one of the following: + + 1. A string consisting of an IP address and an optional mask, separated by + 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, - 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. - >>> ipaddress.IPv6Network('2001:db8::/96') - IPv6Network('2001:db8::/96') - >>> ipaddress.IPv6Network('2001:db8::/96').netmask - IPv6Address('ffff:ffff:ffff:ffff:ffff:ffff::') - >>> ipaddress.IPv6Network('2001:db8::1000/96', strict=False) - IPv6Network('2001:db8::/96') + .. describe:: Attributes and methods + + All attributes and methods implemented by :class:`IPv4Network` and by + :class:`IPv6Address` are also implemented by :class:`IPv6Network`. + + +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