Manipulating IP addresses

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:

IP network objects

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')

Network interface objects

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:

Network interface objects

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 objects

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:

The IP address objects

Demonstration of the ipaddress module

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.

Planning IP addresses for your local area network

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
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.17.140