Often you will need to manipulate IP addresses and perform some sort of operations on them. Python3 has a built-in ipaddress
module to help you in carrying out this task. It has convenient functions for defining the IP addresses and the IP networks and for finding lots of useful information. For example, if you would like to know how many IP addresses exist in a given subnet, for instance, 10.0.1.0/255.255.255.0
or 10.0.2.0/24
, then you can find them with the help of the code snippet shown here. This module will provide several classes and factory functions; for example, the IP address and the IP network has separate classes. Each class has a variant for both IP version 4 (IPv4) and IP version 6 (IPv6). Some of the features have been demonstrated in the following section:
Let us import the ipaddress
module and define a net4
network.
>>> import ipaddress as ip >>> net4 = ip.ip_network('10.0.1.0/24')
Now, we can find some useful information, such as netmask
, the network/broadcast address, and so on, of net4
:
>>> net4.netmask IP4Address(255.255.255.0)
The
netmask
properties of net4
will be displayed as an IP4Address
object. If you are looking for its string representation, then you can call the str()
method, as shown here:
>>> str(net4.netmask) '255.255.255.0'
Similarly, you can find the network and the broadcast addresses of net4,
by doing the following:
>>> str(net4.network_address) 10.0.1.0 >>> str(net4.broadcast_address) 10.0.1.255
How many addresses does net4
hold in total? This can be found by using the command shown here:
>>> net4.num_addresses 256
So, if we subtract the network and the broadcast addresses, then the total available IP addresses will be 254. We can call the hosts()
method on the net4
object. It will produce a Python generator, which will supply all the hosts as IPv4Adress
objects.
>>> all_hosts = list(net4.hosts()) >>> len(all_hosts) 254
You can access the individual IP addresses by following the standard Python list access notation. For example, the first IP address would be the following:
>>> all_hosts[0] IPv4Address('10.0.1.1')
You can access the last IP address by using the list notation for accessing the last item of a list, as shown here:
>>> all_hosts[-1] IPv4Address('10.0.1.1')
We can also find the subnet information from the IPv4Network
objects, as follows:
>>> subnets = list( net4.subnets()) >>> subnets [ IPv4Network('10.0.1.0/25'), IPv4Network('10.0.1.128/25') ]
Any IPv4Network
object can tell about its parent supernet, which is the opposite of the subnet.
>>> net4.supernet() IPv4Network('10.0.1.0/23')
In the ipaddress
module, a convenient class is used for representing an interface's IP configuration in detail. The IPv4 Interface class takes an arbitrary address and behaves like a network address object. Let us define and discuss our network interface eth0,
as shown in following screenshot:
As you can see in the preceding screenshot, a network interface eth0 with the IPv4Address
class has been defined. It has some interesting properties, such as IP, network address, and so on. In the same way as with the network objects, you can check if the address is private, reserved, or multicast. These address ranges have been defined in various RFC documents. The ipaddress
module's help page will show you the links to those RFC documents. You can search this information in other places as well.
The IP address classes have many more interesting properties. You can perform some arithmetic and logical operations on those objects. For example, if an IP address is greater than another IP address, then you can add numbers to the IP address objects, and this will give you a corresponding IP address. Let's see a demonstration of this in the following screenshot:
Here, the eth0
interface has been defined with a private IP address, which is 192.168.1.1,
and eth1
has been defined with another private IP address, which is 192.168.2.1
. Similarly the loopback interface lo
is defined with IP address 127.0.0.1
. As you can see, you can add numbers to the IP address and it will give you the next IP address with the same sequence.
You can check if an IP is a part of a specific network. Here, a network net has been defined by the network address, which is 192.168.1.0/24,
and the membership of eth0
and eth1
has been tested against that. A few other interesting properties, such as is_loopback
, is_private,
and so on, have also been tested here.
If you are wondering how to pick-up a suitable IP subnet, then you can experiment with the ipaddress
module. The following code snippet will show an example of how to choose a specific subnet, based on the number of necessary host IP addresses for a small private network:
#!/usr/bin/env python import ipaddress as ip CLASS_C_ADDR = '192.168.0.0' if __name__ == '__main__': not_configed = True while not_configed: prefix = input("Enter the prefixlen (24-30): ") prefix = int(prefix) if prefix not in range(23, 31): raise Exception("Prefixlen must be between 24 and 30") net_addr = CLASS_C_ADDR + '/' + str(prefix) print("Using network address:%s " %net_addr) try: network = ip.ip_network(net_addr) except: raise Exception("Failed to create network object") print("This prefix will give %s IP addresses" %(network.num_addresses)) print("The network configuration will be") print(" network address: %s" %str(network.network_address)) print(" netmask: %s" %str(network.netmask)) print(" broadcast address: %s" %str(network.broadcast_address)) first_ip, last_ip = list(network.hosts())[0], list(network.hosts())[-1] print(" host IP addresses: from %s to %s" %(first_ip, last_ip)) ok = input("Is this configuration OK [y/n]? ") ok = ok.lower() if ok.strip() == 'y': not_configed = False
If you run this script, then it will show an output similar to the following:
# python 6_2_net_ip_planner.py Enter the prefixlen (24-30): 28 Using network address:192.168.0.0/28 This prefix will give 16 IP addresses The network configuration will be network address: 192.168.0.0 netmask: 255.255.255.240 broadcast address: 192.168.0.15 host IP addresses: from 192.168.0.1 to 192.168.0.14 Is this configuration OK [y/n]? n Enter the prefixlen (24-30): 26 Using network address:192.168.0.0/26 This prefix will give 64 IP addresses The network configuration will be network address: 192.168.0.0 netmask: 255.255.255.192 broadcast address: 192.168.0.63 host IP addresses: from 192.168.0.1 to 192.168.0.62 Is this configuration OK [y/n]? y