How to Manipulate IP Addresses in Python using ipaddress Module

Using ipaddress standard Python library to manipulate IPv4 and IPv6 addresses, networks, subnets and more.
  · 4 min read · Updated may 2024 · Python Standard Library

Unlock the secrets of your code with our AI-powered Code Explainer. Take a look!

In this tutorial, you will learn how you can use the ipaddress module to work with IP addresses in Python, network engineers and people who develop network-related software use this module so often as it provides handy functions and classes that handle various tasks that are related to IP addresses, including checking whether two hosts belong to the same subnet, iterating over all hosts of a subnet, retrieving broadcast addresses of a particular subnet, and much more.

Related: How to Make a Network Scanner using Scapy in Python.

We don't need to install anything, as this module comes built-in and it was introduced in Python 3.3, so if you have Python 3.3+ (and I'm sure you do), you're good to go!

Let's start by IPv4Address class:

import ipaddress
# initialize an IPv4 Address
ip = ipaddress.IPv4Address("192.168.1.1")

Now, this ip object represents a single IP address, we can check whether it is a global IP address (not private) and whether it is a link-local:

# print True if the IP address is global
print("Is global:", ip.is_global)

# print Ture if the IP address is Link-local
print("Is link-local:", ip.is_link_local)

Output:

Is global: False
Is link-local: False

You can also use ip.is_reserved and ip.is_multicast to check whether this IP address is in the list of reserved IP and multicast addresses respectively.

You can perform addition and subtraction on IP addresses:

# next ip address
print(ip + 1)

# previous ip address
print(ip - 1)

You guessed it, adding an IP by 1 means it is the next IP address, and subtracting by 1 means the previous IP address, here is the output:

192.168.1.2
192.168.1.0

Since I can't cover all the available methods, write dir(ip) to discover various methods and attributes you can use.

Now that you have a basic understanding of IPv4Address object, let's dive into handling IPv4Network objects:

# initialize an IPv4 Network
network = ipaddress.IPv4Network("192.168.1.0/24")

Now this network object represents an IPv4 network, the /24 thing is CIDR notation, it indicates that the leading 24 bits of the total 32 bits of the IP address are used to identify the network portion of the address, that means in this case, "192.168.1.x" is network portion (3x8 = 24 bits), and only the last octet "x.x.x.0" is the host portion.

You can retrieve the network mask of this network:

# get the network mask
print("Network mask:", network.netmask)

Output:

Network mask: 255.255.255.0

The network mask is just another format (maybe older) for expressing and representing the network portion of the address, in this case, 255.255.255.0 means that the leading 24 bits which are filled with 1's (255 is 11111111 in binary) indicate the network part of the address (same as /24 notation).

Here is how you can get the broadcast address of the network:

# get the broadcast address
print("Broadcast address:", network.broadcast_address)

Output:

Broadcast address: 192.168.1.255

Printing the number of hosts that belong to this network:

# print the number of IP addresses under this network
print("Number of hosts under", str(network), ":", network.num_addresses)

Output:

Number of hosts under 192.168.1.0/24 : 256

A total of 256 hosts (including the subnet and broadcast addresses) are available under this network, here is how you can iterate over all of them:

# iterate over all the hosts under this network
print("Hosts under", str(network), ":")
for host in network.hosts():
    print(host)

This will print all valid host IP addresses that range from 192.168.1.1 to 192.168.1.254.

You can also get the subnets of this network:

# iterate over the subnets of this network
print("Subnets:")
for subnet in network.subnets(prefixlen_diff=2):
    print(subnet)

Output:

Subnets:
192.168.1.0/26
192.168.1.64/26
192.168.1.128/26
192.168.1.192/26

network.subnets() method returns the subnets which join to make the current subnet as list of IPv4Network objects, prefixlen_diff parameter is an integer that indicates the amount the prefix length should by increased by, I set this to 2 so i can get /26 subnets.

You can also get the supernet:

# get the supernet of this network
print("Supernet:", network.supernet(prefixlen_diff=1))

This will return the supernet containing the current network, here is the output:

Supernet: 192.168.0.0/23

Finally, you can test whether a network overlaps another network:

# tell if this network is under (or overlaps) 192.168.0.0/16
print("Overlaps 192.168.0.0/16:", network.overlaps(ipaddress.IPv4Network("192.168.0.0/16")))

Output:

Overlaps 192.168.0.0/16: True

It returned True, as 192.168.1.1/24 subnet is under 192.168.0.0/16 network.

Alright, we are done with this tutorial, you can explore this module by check their official documentation for more functions and classes for IPv4 and also IPv6 addresses that are really handy for network engineers and Python programmers who wish to develop network applications.

Read Also: How to Make a DNS Spoof attack using Scapy in Python.

Happy Coding ♥

Ready for more? Dive deeper into coding with our AI-powered Code Explainer. Don't miss it!

View Full Code Improve My Code
Sharing is caring!



Read Also



Comment panel

    Got a coding query or need some guidance before you comment? Check out this Python Code Assistant for expert advice and handy tips. It's like having a coding tutor right in your fingertips!