Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 53c9200

Browse files
committed
Issue #14814: Add a basic ipaddress tutorial (thanks to Sandro Tosi for the initial conversion from Peter Moody's wiki version)
1 parent 2c58910 commit 53c9200

2 files changed

Lines changed: 292 additions & 0 deletions

File tree

Doc/howto/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,5 @@ Currently, the HOWTOs are:
2828
urllib2.rst
2929
webservers.rst
3030
argparse.rst
31+
ipaddress.rst
3132

Doc/howto/ipaddress.rst

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

0 commit comments

Comments
 (0)