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.
- Prefix /<nbits> denotes the number of high-order bits set in the network mask.
- 2. A netmask is an IP address with a number of high-order bit set.
- 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! 🙂