The ipaddress module in Python [ Easy Examples ]

IPAddress Module In Python

Hey folks! Today we will learn about the ipaddress module in Python. So without any further ado, let’s get started.

What is an IP Address?

IP stands for internet protocol. It is used to identify a node on any network. So any device that connects to the internet, needs to possess an IP address.

There are two versions of IP addresses: IPv4 and IPv6. The IPv4 is the one in use at present whereas IPv6 is being adopted by major network providers slowly owing to the shortage of IPv4 addresses compared to the devices on the network.

To learn more about IP addresses, check out the Wiki page here.

How to use the ipaddress module in Python?

Let’s begin with using the ipaddressmodule now. To set a host address, we use ipaddress.ip_address( ).

This function automatically determines which version to be used based on the values passed. It either returns an IPv4 address or an IPv6 address.

1. How to create a valid IPv4 Address?

IPv4 validates values within the range of 0 to 255. Integer that fits into 32 bits represents an octet in the address. An integer packed into bytes object which is of length 4.

import ipaddress
ipaddress.ip_address('199.138.0.1')

Output:

IPv4Address('199.138.0.1')

2. How to create a valid IPv6 Address?

IPv6 validates values from range 0 to ffff. An integer that fits into 128 bits. An integer packed into a byte object which is of length 16.

import ipaddress
ipaddress.ip_address('2011:cb0::')
ipaddress.ip_address('FFFF:9999:2:FDE:257:0:2FAE:112D')

Output:

IPv6Address('2011:cb0::')
IPv6Address('ffff:9999:2:fde:257:0:2fae:112d')

Working with IP Addresses in Python using the ipaddress module

IP addresses are accompanied by a set of rules. Ranges of IP addresses are assigned different functions.

For example, 127.0.0.1 is a loopback address assigned to the networking module on your computer. When you send a ping packet to this IP address, you’re essentially pinging your own computer.

1. Basic IP functions

Let’s take a look at how we can verify which addresses are loopback, multicast, local links, or reserved using the ipaddress module in Python

import ipaddress

ipa = ipaddress.ip_address('199.138.0.1')
print(ipa.is_private) # Checks if address is private
print(ipa.is_global)  # Checks if address is global

#If address is a loopback address
print(ipaddress.ip_address("127.0.0.1").is_loopback) 

#If address is reserved for multiclass use
print(ipaddress.ip_address("229.100.0.23").is_multicast) 

#If address is reserved for link local usage
print(ipaddress.ip_address("169.254.0.100").is_link_local)

#True if the address is otherwise IETF reserved.
print(ipaddress.ip_address("240.10.0.1").is_reserved)

Output:

False
True
True
True
True
True

2. Reverse IP Lookups

The reverse pointer function requests the DNS to resolve the IP address added as an argument here. If the DNS is able to resolve the IP, you’ll receive an output with the name assigned.

If you ping an IP that’s assigned to a domain name, you’ll likely get the name of the server on which the domain exists. However this can change depending on the firewall setup.

ipaddress.ip_address("199.138.0.1").reverse_pointer

Output:

'1.0.138.199.in-addr.arpa'

Working with IP Networks using the ipaddress module

An IPv4Network and IPv6Network can hlep us define and inspect IP network definitions.

We can get IP network in our required format without writing a custom code.

  1. Prefix /<nbits> denotes the number of high-order bits set in the network mask.
  2. 2. A netmask is an IP address with a number of high-order bit set.
  3. 3. A hostmask is the logical inverse of the netmask and is used in the Cisco access control list.
ipn = ipaddress.ip_network("10.0.0.0/16")
print(ipn.with_prefixlen)
print(ipn.with_hostmask)
print(ipn.with_netmask)

Output:

10.0.0.0/16
10.0.0.0/0.0.255.255
10.0.0.0/255.255.0.0

1. Check if an IP address is IPv4 or IPv6

ipaddress.ip_network( ) function is used to return the type of network of the address. It confirms if an IP is in the IP4 network or IP6 network.

import ipaddress
ipaddress.ip_network('199.138.0.1')
ipaddress.ip_network('FFFF:9999:2:FDE:257:0:2FAE:112D')

Output:

IPv4Network('199.138.0.1/32')
IPv6Network('ffff:9999:2:fde:257:0:2fae:112d/128')

2. Identify hosts on an IP network

Hosts are all the IP addresses that belong to a network except the network address and network broadcast address.

host( ) returns iterator over useable hosts in the network.

Networks which have mask length of 31, the network address and network broadcast address is also included in the result and Networks which have mask length of 32 return return list of single host address.

ipn= ipaddress.ip_network('192.0.2.0/29')
list(ipn.hosts())

Output:

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

3. Identifying the broadcast address for networks

With broadcast_address, we can request the DNS server to respond with the broadcast address on the network.

ipn= ipaddress.ip_network('199.1.8.0/29')
ipn.broadcast_address

Output:

IPv4Address('199.1.8.7')

4. Identifying IP network overlaps

This function tells us that if a network is partly or wholly contained in another network. It returns either true or false.

ipn1 = ipaddress.ip_network("10.10.1.32/29")
ipn2 = ipaddress.ip_network("10.10.1.32/27")
ipn3 = ipaddress.ip_network("10.10.1.48/29")
print(ipn1.overlaps(ipn2))
print(ipn1.overlaps(ipn3))
print(ipn3.overlaps(ipn2))

Output:

True
False
True

5. Subnets on IP networks

It returns an iterator of network objects. prefixlen_diff is the amount pf prefix length that should be increased, new_prefix is the new prefix of the subnets and is larger than our prefix.

ipn1 = ipaddress.ip_network("10.10.1.32/29")
print(list(ipn1.subnets()))
print(list(ipn1.subnets(prefixlen_diff=2)))
print(list(ipn1.subnets(new_prefix=30))) 

Output:

[IPv4Network('10.10.1.32/30'), IPv4Network('10.10.1.36/30')]
[IPv4Network('10.10.1.32/31'), IPv4Network('10.10.1.34/31'), IPv4Network('10.10.1.36/31'), IPv4Network('10.10.1.38/31')]
[IPv4Network('10.10.1.32/30'), IPv4Network('10.10.1.36/30')]

6. Creating supernets with the ipaddress module

Supernets are a combination of one or multiple subnets. You can learn more about supernets here. With the supernet method in the ipaddress module, you can create subnets by specifying the information as required.

  • prefixlen_diff is the amount our prefix length should be increased by
  • new_prefix is the desired new prefix of the subnets which should be larger than our prefix.
ipnn = ipaddress.ip_network("172.10.15.160/29")
print(ipnn.supernet(prefixlen_diff=3))
print(ipnn.supernet(new_prefix=20))

Output:

172.10.15.128/26
172.10.0.0/20

7. Check if an IP network is a supernet/subnet of another IP network

Returns true is a network is subnet of the other of if a network is supernet of the other. Returns either true or false.

a = ipaddress.ip_network("192.168.1.0/24")
b = ipaddress.ip_network("192.168.1.128/30")

print(b.subnet_of(a))
print(a.supernet_of(b))

Output:

True
True

8. Working with IPv4Interface objects

Interface objects can be used as keys in dictionaries as they are hashable.

IPv4Interface inherits all the attributes from IPv4Address as IPv4Interface is the subclass of IPv4Address.

Here, 199.167.1.6 IP address is in the network 199.167.1.0/24

from ipaddress import IPv4Interface
ifc = IPv4Interface("199.167.1.6/24")
print(ifc.ip)
print(ifc.network)

Output:

199.167.1.6
199.167.1.0/24

We can represent network interface in prefix notation, as a netmask and as a host mask.

interface = IPv4Interface('192.0.2.5/24')
print(interface.with_prefixlen)
print(interface.with_netmask)
print(interface.with_hostmask)

Output:

192.0.2.5/24
192.0.2.5/255.255.255.0
192.0.2.5/0.0.0.255

Miscellaneous Operations with IP Addresses

You can check how an IP address compares to another with the use of comparison operators in Python. Take a look at the below example.

ipa1=ipaddress.ip_address("127.0.0.2")
ipa2=ipaddress.ip_address("127.0.0.1")
print(ipa1>ipa2)
print(ipa1==ipa2)
print(ipa1!=ipa2)

Output:

True
False
True

We can add or subtract integers from IP address objects.

ipa = ipaddress.ip_address("10.10.1.0")
print( ipa + 9)

Output:

10.10.1.9

Addresses can be converted to strings or integers by using built-in functions str( ) and int( ).

str(ipaddress.IPv4Address('199.138.0.1'))
int(ipaddress.IPv4Address('192.198.0.1'))

Output:

'199.138.0.1'
3234201601

IPv6 addresses are converted into strings without zone ID.

str(ipaddress.IPv6Address('::8'))
int(ipaddress.IPv6Address('::100'))

Output:

'::8'
256

Conclusion

In this tutorial, we learned about IPv4 and IPv6 address, network, and interface. For more such content, stay tuned. Happy Learning! 🙂

References

IPAddress Module Official Docs