1.. testsetup::
2
3   import ipaddress
4
5.. _ipaddress-howto:
6
7***************************************
8An introduction to the ipaddress module
9***************************************
10
11:author: Peter Moody
12:author: Nick Coghlan
13
14.. topic:: Overview
15
16   This document aims to provide a gentle introduction to the
17   :mod:`ipaddress` module. It is aimed primarily at users that aren't
18   already familiar with IP networking terminology, but may also be useful
19   to network engineers wanting an overview of how :mod:`ipaddress`
20   represents IP network addressing concepts.
21
22
23Creating Address/Network/Interface objects
24==========================================
25
26Since :mod:`ipaddress` is a module for inspecting and manipulating IP addresses,
27the first thing you'll want to do is create some objects.  You can use
28:mod:`ipaddress` to create objects from strings and integers.
29
30
31A Note on IP Versions
32---------------------
33
34For readers that aren't particularly familiar with IP addressing, it's
35important to know that the Internet Protocol is currently in the process
36of moving from version 4 of the protocol to version 6. This transition is
37occurring largely because version 4 of the protocol doesn't provide enough
38addresses to handle the needs of the whole world, especially given the
39increasing number of devices with direct connections to the internet.
40
41Explaining the details of the differences between the two versions of the
42protocol is beyond the scope of this introduction, but readers need to at
43least be aware that these two versions exist, and it will sometimes be
44necessary to force the use of one version or the other.
45
46
47IP Host Addresses
48-----------------
49
50Addresses, often referred to as "host addresses" are the most basic unit
51when working with IP addressing. The simplest way to create addresses is
52to use the :func:`ipaddress.ip_address` factory function, which automatically
53determines whether to create an IPv4 or IPv6 address based on the passed in
54value:
55
56   >>> ipaddress.ip_address('192.0.2.1')
57   IPv4Address('192.0.2.1')
58   >>> ipaddress.ip_address('2001:DB8::1')
59   IPv6Address('2001:db8::1')
60
61Addresses can also be created directly from integers. Values that will
62fit within 32 bits are assumed to be IPv4 addresses::
63
64   >>> ipaddress.ip_address(3221225985)
65   IPv4Address('192.0.2.1')
66   >>> ipaddress.ip_address(42540766411282592856903984951653826561)
67   IPv6Address('2001:db8::1')
68
69To force the use of IPv4 or IPv6 addresses, the relevant classes can be
70invoked directly. This is particularly useful to force creation of IPv6
71addresses for small integers::
72
73   >>> ipaddress.ip_address(1)
74   IPv4Address('0.0.0.1')
75   >>> ipaddress.IPv4Address(1)
76   IPv4Address('0.0.0.1')
77   >>> ipaddress.IPv6Address(1)
78   IPv6Address('::1')
79
80
81Defining Networks
82-----------------
83
84Host addresses are usually grouped together into IP networks, so
85:mod:`ipaddress` provides a way to create, inspect and manipulate network
86definitions. IP network objects are constructed from strings that define the
87range of host addresses that are part of that network. The simplest form
88for that information is a "network address/network prefix" pair, where the
89prefix defines the number of leading bits that are compared to determine
90whether or not an address is part of the network and the network address
91defines the expected value of those bits.
92
93As for addresses, a factory function is provided that determines the correct
94IP version automatically::
95
96   >>> ipaddress.ip_network('192.0.2.0/24')
97   IPv4Network('192.0.2.0/24')
98   >>> ipaddress.ip_network('2001:db8::0/96')
99   IPv6Network('2001:db8::/96')
100
101Network objects cannot have any host bits set.  The practical effect of this
102is that ``192.0.2.1/24`` does not describe a network.  Such definitions are
103referred to as interface objects since the ip-on-a-network notation is
104commonly used to describe network interfaces of a computer on a given network
105and are described further in the next section.
106
107By default, attempting to create a network object with host bits set will
108result in :exc:`ValueError` being raised. To request that the
109additional bits instead be coerced to zero, the flag ``strict=False`` can
110be passed to the constructor::
111
112   >>> ipaddress.ip_network('192.0.2.1/24')
113   Traceback (most recent call last):
114      ...
115   ValueError: 192.0.2.1/24 has host bits set
116   >>> ipaddress.ip_network('192.0.2.1/24', strict=False)
117   IPv4Network('192.0.2.0/24')
118
119While the string form offers significantly more flexibility, networks can
120also be defined with integers, just like host addresses. In this case, the
121network is considered to contain only the single address identified by the
122integer, so the network prefix includes the entire network address::
123
124   >>> ipaddress.ip_network(3221225984)
125   IPv4Network('192.0.2.0/32')
126   >>> ipaddress.ip_network(42540766411282592856903984951653826560)
127   IPv6Network('2001:db8::/128')
128
129As with addresses, creation of a particular kind of network can be forced
130by calling the class constructor directly instead of using the factory
131function.
132
133
134Host Interfaces
135---------------
136
137As mentioned just above, if you need to describe an address on a particular
138network, neither the address nor the network classes are sufficient.
139Notation like ``192.0.2.1/24`` is commonly used by network engineers and the
140people who write tools for firewalls and routers as shorthand for "the host
141``192.0.2.1`` on the network ``192.0.2.0/24``", Accordingly, :mod:`ipaddress`
142provides a set of hybrid classes that associate an address with a particular
143network. The interface for creation is identical to that for defining network
144objects, except that the address portion isn't constrained to being a network
145address.
146
147   >>> ipaddress.ip_interface('192.0.2.1/24')
148   IPv4Interface('192.0.2.1/24')
149   >>> ipaddress.ip_interface('2001:db8::1/96')
150   IPv6Interface('2001:db8::1/96')
151
152Integer inputs are accepted (as with networks), and use of a particular IP
153version can be forced by calling the relevant constructor directly.
154
155
156Inspecting Address/Network/Interface Objects
157============================================
158
159You've gone to the trouble of creating an IPv(4|6)(Address|Network|Interface)
160object, so you probably want to get information about it.  :mod:`ipaddress`
161tries to make doing this easy and intuitive.
162
163Extracting the IP version::
164
165   >>> addr4 = ipaddress.ip_address('192.0.2.1')
166   >>> addr6 = ipaddress.ip_address('2001:db8::1')
167   >>> addr6.version
168   6
169   >>> addr4.version
170   4
171
172Obtaining the network from an interface::
173
174   >>> host4 = ipaddress.ip_interface('192.0.2.1/24')
175   >>> host4.network
176   IPv4Network('192.0.2.0/24')
177   >>> host6 = ipaddress.ip_interface('2001:db8::1/96')
178   >>> host6.network
179   IPv6Network('2001:db8::/96')
180
181Finding out how many individual addresses are in a network::
182
183   >>> net4 = ipaddress.ip_network('192.0.2.0/24')
184   >>> net4.num_addresses
185   256
186   >>> net6 = ipaddress.ip_network('2001:db8::0/96')
187   >>> net6.num_addresses
188   4294967296
189
190Iterating through the "usable" addresses on a network::
191
192   >>> net4 = ipaddress.ip_network('192.0.2.0/24')
193   >>> for x in net4.hosts():
194   ...     print(x)  # doctest: +ELLIPSIS
195   192.0.2.1
196   192.0.2.2
197   192.0.2.3
198   192.0.2.4
199   ...
200   192.0.2.252
201   192.0.2.253
202   192.0.2.254
203
204
205Obtaining the netmask (i.e. set bits corresponding to the network prefix) or
206the hostmask (any bits that are not part of the netmask):
207
208   >>> net4 = ipaddress.ip_network('192.0.2.0/24')
209   >>> net4.netmask
210   IPv4Address('255.255.255.0')
211   >>> net4.hostmask
212   IPv4Address('0.0.0.255')
213   >>> net6 = ipaddress.ip_network('2001:db8::0/96')
214   >>> net6.netmask
215   IPv6Address('ffff:ffff:ffff:ffff:ffff:ffff::')
216   >>> net6.hostmask
217   IPv6Address('::ffff:ffff')
218
219
220Exploding or compressing the address::
221
222   >>> addr6.exploded
223   '2001:0db8:0000:0000:0000:0000:0000:0001'
224   >>> addr6.compressed
225   '2001:db8::1'
226   >>> net6.exploded
227   '2001:0db8:0000:0000:0000:0000:0000:0000/96'
228   >>> net6.compressed
229   '2001:db8::/96'
230
231While IPv4 doesn't support explosion or compression, the associated objects
232still provide the relevant properties so that version neutral code can
233easily ensure the most concise or most verbose form is used for IPv6
234addresses while still correctly handling IPv4 addresses.
235
236
237Networks as lists of Addresses
238==============================
239
240It's sometimes useful to treat networks as lists.  This means it is possible
241to index them like this::
242
243   >>> net4[1]
244   IPv4Address('192.0.2.1')
245   >>> net4[-1]
246   IPv4Address('192.0.2.255')
247   >>> net6[1]
248   IPv6Address('2001:db8::1')
249   >>> net6[-1]
250   IPv6Address('2001:db8::ffff:ffff')
251
252
253It also means that network objects lend themselves to using the list
254membership test syntax like this::
255
256   if address in network:
257       # do something
258
259Containment testing is done efficiently based on the network prefix::
260
261   >>> addr4 = ipaddress.ip_address('192.0.2.1')
262   >>> addr4 in ipaddress.ip_network('192.0.2.0/24')
263   True
264   >>> addr4 in ipaddress.ip_network('192.0.3.0/24')
265   False
266
267
268Comparisons
269===========
270
271:mod:`ipaddress` provides some simple, hopefully intuitive ways to compare
272objects, where it makes sense::
273
274   >>> ipaddress.ip_address('192.0.2.1') < ipaddress.ip_address('192.0.2.2')
275   True
276
277A :exc:`TypeError` exception is raised if you try to compare objects of
278different versions or different types.
279
280
281Using IP Addresses with other modules
282=====================================
283
284Other modules that use IP addresses (such as :mod:`socket`) usually won't
285accept objects from this module directly. Instead, they must be coerced to
286an integer or string that the other module will accept::
287
288   >>> addr4 = ipaddress.ip_address('192.0.2.1')
289   >>> str(addr4)
290   '192.0.2.1'
291   >>> int(addr4)
292   3221225985
293
294
295Getting more detail when instance creation fails
296================================================
297
298When creating address/network/interface objects using the version-agnostic
299factory functions, any errors will be reported as :exc:`ValueError` with
300a generic error message that simply says the passed in value was not
301recognized as an object of that type. The lack of a specific error is
302because it's necessary to know whether the value is *supposed* to be IPv4
303or IPv6 in order to provide more detail on why it has been rejected.
304
305To support use cases where it is useful to have access to this additional
306detail, the individual class constructors actually raise the
307:exc:`ValueError` subclasses :exc:`ipaddress.AddressValueError` and
308:exc:`ipaddress.NetmaskValueError` to indicate exactly which part of
309the definition failed to parse correctly.
310
311The error messages are significantly more detailed when using the
312class constructors directly. For example::
313
314   >>> ipaddress.ip_address("192.168.0.256")
315   Traceback (most recent call last):
316     ...
317   ValueError: '192.168.0.256' does not appear to be an IPv4 or IPv6 address
318   >>> ipaddress.IPv4Address("192.168.0.256")
319   Traceback (most recent call last):
320     ...
321   ipaddress.AddressValueError: Octet 256 (> 255) not permitted in '192.168.0.256'
322
323   >>> ipaddress.ip_network("192.168.0.1/64")
324   Traceback (most recent call last):
325     ...
326   ValueError: '192.168.0.1/64' does not appear to be an IPv4 or IPv6 network
327   >>> ipaddress.IPv4Network("192.168.0.1/64")
328   Traceback (most recent call last):
329     ...
330   ipaddress.NetmaskValueError: '64' is not a valid netmask
331
332However, both of the module specific exceptions have :exc:`ValueError` as their
333parent class, so if you're not concerned with the particular type of error,
334you can still write code like the following::
335
336   try:
337       network = ipaddress.IPv4Network(address)
338   except ValueError:
339       print('address/netmask is invalid for IPv4:', address)
340
341