Updated On : Feb-16,2021 Tags ip-address, network-address, interfaces
ipaddress - Simple Guide to Working with IP Addresses, Network Addresses, and Interfaces in Python

ipaddress - Simple Guide to Working with IP Addresses, Network Addresses, and Network Interfaces in Python

IP Address is a numerical address assigned to the computer when it connects to the internet to uniquely identify it. It's referred to as the host address. IP Address has two versions (IPv4 and IPv6). IPv4 is the first version that uses 32 bits numbers to represent an IP address. Due to the increasing demand of people connecting to the internet, 32-bit IPv4 address was not enough to cope up with demand, hence IPv6 was introduced. IPv6 addresses are 128 bits long.

IPv4 Representation:

IPV4 is generally represented as four numbers ranging between 0-255 separated by dots (Ex: "49.34.86.241"). A total of 32 bits are grouped into four groups each representing 8 bits. As each group has 8 bits to represent, it can hold numbers between 0-255(2^8-1).

IPv6 Representation:

IPv6 is generally represented as numbers separated by colon (Ex: "0f0f:0241:0f0f:0f0f:0f0f:0f0f:0f0f:0101"). The address has 8 groups each consisting of 16 bits. Each group has generally 4 numbers each of 4-bits hence can represent a hexadecimal number between 0-f(2^4-1). If we are not given all 4 digits for the group then we'll remaining digits will be added as "0". As the IPv6 address is quite long, it's common practice to avoid groups where digits are not present. Instead, the only double colon will be used to represent that all the groups following a particular group will have a value of "0". Ex: "0f0f:0241::" is equivalent to "0f0f:0241:0000:0000:0000:0000:0000:0000" and "::0f0f:0241" is equivalent to "0000:0000:0000:0000:0000:0000:0f0f:0241".

The network address is represented as an address followed by a number of digits of the network which is the same for all addresses present in the network. The network address and a number of bits are separated by a slash. Ex: "49.34.86.0/24". Here network consists of all addresses in the range "49.34.86.0" - "49.34.86.255". The same logic goes for the IPv6 addresses as well. We just give the number of bits that are fixed for all addresses of the network.

Network Interfaces are generally used by network administrators to identify individual computers on the network. They have the same structure as that of network address but has actual address present instead of the top-level network address. Ex- "49.34.86.212/24"

As a part of this tutorial, we'll be explaining how we can maintain IP addresses, network addresses, and network interfaces using ipaddress module of Python. We'll explain how we can maintain addresses, perform arithmetic operations with them, explain properties of addresses, list addresses in a network address, etc. We'll explain all of this with simple and easy-to-understand examples.

Please make a NOTE that it'll be helpful to easily go through this tutorial and grasp the API of the ipaddress module soon if the reader has a background of IPv4 and IPv6 address structure, network addresses, and interface addresses. We recommend that readers go through at least the intro section of these two Wikipedia articles.

Example 1: IP Address

Our first example, explains how we can create IPV4 and IPV6 addresses using ipaddress module. The ipaddress module provides us method named ip_address() and classes named IPv4Address() & IPv6Address() that can be used to create IP address in Python.


  • ip_address(address) - It takes as input a string or an integer and return instance of IPv4Address or IPv6Address. It finds out the version of the IP address based on the string representation. If an integer is given then an integer less than 2^32 will be considered IPv4 and numbers greater than it will be considered IPv6. It also checks for the validity of addresses and will raise an error in case it does not satisfy all requirements.

  • IPv4Address(address) - It accepts a string or an integer as input and returns an instance of IPv4Address which holds an IP address.

  • IPv6Address(address) - It accepts a string or an integer as input and returns an instance of IPv6Address which holds an IP address.


Our code for this part explains various ways to create IPv4 and IPv6 addresses. It also explains ways which can fail to create an address hinting at invalid addresses. We have created IP addresses from both string and integer values both. We can easily convert IP address instances to strings or integers by wrapping them into str or int constructor.

IPV4

In [1]:
import ipaddress

### IPV4
print("==================== IPV4 =========================")
print("IPV4 Address Length : {} bits\n".format(ipaddress.IPV4LENGTH))

host_address = ipaddress.ip_address("49.34.86.241")
print("Host Address Type : {}, Value : {}\n".format(type(host_address).__name__, host_address))

host_address = ipaddress.ip_address(2**32-1)
print("Host Address Type : {}, Value : {}\n".format(type(host_address).__name__, host_address))

host_address = ipaddress.IPv4Address("49.34.86.241")
print("Host Address Type : {}, Value : {}\n".format(type(host_address).__name__, host_address))

try:
    host_address = ipaddress.ip_address("49.34.86.256")
except Exception as e:
    print("ErrorType : {}, Error : {}\n".format(type(e).__name__, e))

host_address = ipaddress.IPv4Address("49.34.86.241")
print("Host Address Type : {}, Int Value : {}\n".format(type(host_address).__name__, int(host_address)))
==================== IPV4 =========================
IPV4 Address Length : 32 bits

Host Address Type : IPv4Address, Value : 49.34.86.241

Host Address Type : IPv4Address, Value : 255.255.255.255

Host Address Type : IPv4Address, Value : 49.34.86.241

ErrorType : ValueError, Error : '49.34.86.256' does not appear to be an IPv4 or IPv6 address

Host Address Type : IPv4Address, Int Value : 824334065

IPV6

In [2]:
import ipaddress

### IPV6

print("==================== IPV6 =========================")
print("IPV6 Address Length : {} bits\n".format(ipaddress.IPV6LENGTH))

host_address = ipaddress.ip_address("0f0f:0241::")
print("Host Address Type : {}, Value : {}\n".format(type(host_address).__name__, host_address))

host_address = ipaddress.ip_address(2**32)
print("Host Address Type : {}, Value : {}\n".format(type(host_address).__name__, host_address))

host_address = ipaddress.IPv6Address("0f0f:0241::")
print("Host Address Type : {}, Value : {}\n".format(type(host_address).__name__, host_address))

host_address = ipaddress.IPv6Address("::0f0f:0241")
print("Host Address Type : {}, Value : {}\n".format(type(host_address).__name__, host_address))

try:
    host_address = ipaddress.ip_address("0f0g:0::")
except Exception as e:
    print("ErrorType : {}, Error : {}\n".format(type(e).__name__, e))

try:
    host_address = ipaddress.ip_address(2**128)
except Exception as e:
    print("ErrorType : {}, Error : {}".format(type(e).__name__, e))

host_address = ipaddress.IPv6Address("0f0f:0241::")
print("Host Address Type : {}, Int Value : {}\n".format(type(host_address).__name__, int(host_address)))
==================== IPV6 =========================
IPV6 Address Length : 128 bits

Host Address Type : IPv6Address, Value : f0f:241::

Host Address Type : IPv6Address, Value : ::1:0:0

Host Address Type : IPv6Address, Value : f0f:241::

Host Address Type : IPv6Address, Value : ::f0f:241

ErrorType : ValueError, Error : '0f0g:0::' does not appear to be an IPv4 or IPv6 address

ErrorType : ValueError, Error : 340282366920938463463374607431768211456 does not appear to be an IPv4 or IPv6 address
Host Address Type : IPv6Address, Int Value : 20016350104301531238507854824002813952

Example 2: IP Network

As a part of our second example, we'll demonstrate how we can maintain network addresses using ipaddress module. The ipaddress module provides us with method named ip_network() and classes named IPv4Network() & IPv6Network() for creating network addresses in Python.


  • ip_network(address, strict=True) - It accepts string or integer as input and returns an instance of IPv4Network or IPv6Network based on the address type. It determines network type based on the string representation. If we don't pass a number of bits after slash when creating an instance then it'll be considered 32 or 128 based on the address type.
    • The strict parameter will check that the network address is valid and there is no data provided for the bit beyond specified. It accepts a boolean value and raises ValueError if the address seems invalid. Ex - "49.34.86.0/24" is valid because the first 24 bits are fixed with the first 3 groups (49, 34 and 86) and the last group value is kept "0" to indicate that all possible values of that group should be used as IP addresses of the network.
  • IPv4Network(address, strict=True) - It accepts string or integer as input and returns an instance of IPv4Network representing IPv4 network.
  • IPv6Network(address, strict=True) - It accepts string or integer as input and returns an instance of IPv6Network representing IPv6 network.

Our code for this part explains in a different way how we can create IPv4 and IPv6 network addresses using the methods specified above. It also highlights cases where the methods will fail if invalid network addresses are provided. We have also explained the usage of strict parameters with examples. We have tried to cover different scenarios to explain how we can create network addresses using ipaddress. We have also explained how we can get the IP addresses of the network.

Please make a NOTE that instances of IPv4Network and IPv6Network can be treated as an iterator. We can just use it inside of a loop and it'll loop through all possible IP addresses inside of the network. We can also wrap it inside the list constructor and it'll return a list of all IP addresses present in that network.

IPV4

In [3]:
import ipaddress

#### IPV4
print("==================== IPV4 =========================")

network = ipaddress.ip_network("49.34.86.0/24")
print("Network Address Type : {}, Value : {}".format(type(network).__name__, network))
print("Number of Addresses on Network : {}\n".format(len(list(network))))

network = ipaddress.ip_network("49.34.86.0")
print("Network Address Type : {}, Value : {}".format(type(network).__name__, network))
print("Number of Addresses on Network : {}\n".format(len(list(network))))

network = ipaddress.ip_network("49.34.86.0/28")
print("Network Address Type : {}, Value : {}".format(type(network).__name__, network))
print("Number of Addresses on Network : {}\n".format(len(list(network))))

network = ipaddress.ip_network(2**32 - 256)
print("Network Address Type : {}, Value : {}".format(type(network).__name__, network))
print("Number of Addresses on Network : {}\n".format(len(list(network))))

network = ipaddress.IPv4Network("49.34.86.0/28")
print("Network Address Type : {}, Value : {}".format(type(network).__name__, network))
print("Number of Addresses on Network : {}\n".format(len(list(network))))

try:
    network = ipaddress.ip_network("49.34.86.0/16")
    print("Network Address Type : {}, Value : {}\n".format(type(network).__name__, network))
except Exception as e:
    print("ErrorType : {}, Error : {}\n".format(type(e).__name__, e))

network = ipaddress.ip_network("49.34.86.0/16", strict=False)
print("Network Address Type : {}, Value : {}".format(type(network).__name__, network))
print("Number of Addresses on Network : {}\n".format(len(list(network))))
print("\nFirst Few Addresses : {}".format(list(network)[:5]))
==================== IPV4 =========================
Network Address Type : IPv4Network, Value : 49.34.86.0/24
Number of Addresses on Network : 256

Network Address Type : IPv4Network, Value : 49.34.86.0/32
Number of Addresses on Network : 1

Network Address Type : IPv4Network, Value : 49.34.86.0/28
Number of Addresses on Network : 16

Network Address Type : IPv4Network, Value : 255.255.255.0/32
Number of Addresses on Network : 1

Network Address Type : IPv4Network, Value : 49.34.86.0/28
Number of Addresses on Network : 16

ErrorType : ValueError, Error : 49.34.86.0/16 has host bits set

Network Address Type : IPv4Network, Value : 49.34.0.0/16
Number of Addresses on Network : 65536


First Few Addresses : [IPv4Address('49.34.0.0'), IPv4Address('49.34.0.1'), IPv4Address('49.34.0.2'), IPv4Address('49.34.0.3'), IPv4Address('49.34.0.4')]

IPV6

In [4]:
import ipaddress

#### IPV6
print("==================== IPV6 =========================")

network = ipaddress.ip_network("0f0f:0f0f:0f0f:0f0f:0f0f:0f0f:0f0f:0/112")
print("Network Address Type : {}, Value : {}".format(type(network).__name__, network))
print("Number of Addresses on Network : {}\n".format(len(list(network))))

network = ipaddress.ip_network("0f0f:0f0f:0f0f:0f0f:0f0f:0f0f:0f0f:0")
print("Network Address Type : {}, Value : {}".format(type(network).__name__, network))
print("Number of Addresses on Network : {}\n".format(len(list(network))))

network = ipaddress.ip_network("0f0f:0f0f:0f0f:0f0f:0f0f:0f0f:0f0f:0/120")
print("Network Address Type : {}, Value : {}".format(type(network).__name__, network))
print("Number of Addresses on Network : {}\n".format(len(list(network))))

try:
    network = ipaddress.ip_network("0f0f:0f0f:0f0f:0f0f:0f0f:0f0f:0f0f:0f0f/112")
    print("Network Address Type : {}, Value : {}\n".format(type(network).__name__, network))
except Exception as e:
    print("ErrorType : {}, Error : {}\n".format(type(e).__name__, e))

network = ipaddress.ip_network("0f0f:0f0f:0f0f:0f0f:0f0f:0f0f:0f0f:0f0f/112", strict=False)
print("Network Address Type : {}, Value : {}".format(type(network).__name__, network))
print("Number of Addresses on Network : {}\n".format(len(list(network))))

network = ipaddress.ip_network(2**128 - 2**16)
print("Network Address Type : {}, Value : {}".format(type(network).__name__, network))
print("Number of Addresses on Network : {}\n".format(len(list(network))))

network = ipaddress.IPv6Network("0f0f:0f0f:0f0f:0f0f:0f0f:0f0f:0f0f:0f0f/112", strict=False)
print("Network Address Type : {}, Value : {}".format(type(network).__name__, network))
print("Number of Addresses on Network : {}\n".format(len(list(network))))
print("\nFirst Few Addresses : {}".format(list(network)[:5]))
==================== IPV6 =========================
Network Address Type : IPv6Network, Value : f0f:f0f:f0f:f0f:f0f:f0f:f0f:0/112
Number of Addresses on Network : 65536

Network Address Type : IPv6Network, Value : f0f:f0f:f0f:f0f:f0f:f0f:f0f:0/128
Number of Addresses on Network : 1

Network Address Type : IPv6Network, Value : f0f:f0f:f0f:f0f:f0f:f0f:f0f:0/120
Number of Addresses on Network : 256

ErrorType : ValueError, Error : f0f:f0f:f0f:f0f:f0f:f0f:f0f:f0f/112 has host bits set

Network Address Type : IPv6Network, Value : f0f:f0f:f0f:f0f:f0f:f0f:f0f:0/112
Number of Addresses on Network : 65536

Network Address Type : IPv6Network, Value : ffff:ffff:ffff:ffff:ffff:ffff:ffff:0/128
Number of Addresses on Network : 1

Network Address Type : IPv6Network, Value : f0f:f0f:f0f:f0f:f0f:f0f:f0f:0/112
Number of Addresses on Network : 65536


First Few Addresses : [IPv6Address('f0f:f0f:f0f:f0f:f0f:f0f:f0f:0'), IPv6Address('f0f:f0f:f0f:f0f:f0f:f0f:f0f:1'), IPv6Address('f0f:f0f:f0f:f0f:f0f:f0f:f0f:2'), IPv6Address('f0f:f0f:f0f:f0f:f0f:f0f:f0f:3'), IPv6Address('f0f:f0f:f0f:f0f:f0f:f0f:f0f:4')]

Example 3: IP Interface

As a part of our third example, we'll explain how we can create interfaces using ipaddress module. The ipaddress module provides us with method named ip_interface() and classes named IPv4Interface & IPv6Interface that can be used to create interfaces. As we had discussed earlier, interfaces as used by network engineers and others as shorthand for referring individual hosts on a particular network.


  • ip_interface() - It takes as input a string or an integer and return instance of IPv4Interface or IPv6Interface. It finds out the version of the interface based on the string representation. If an integer is given then an integer less than 2^32 will be considered IPv4 and numbers greater than it will be considered IPv6. It also checks for the validity of addresses and will raise an error in case it does not satisfy all requirements.

  • IPv4Interface(address) - It accepts a string or an integer as input and returns an instance of IPv4Interface which holds the IPv4 interface.

  • IPv6Interface(address) - It accepts a string or an integer as input and returns an instance of IPv6Interface which holds the IPv6 interface.


Our code for this example explains various ways to create interfaces. It tries to explain possible scenarios of creating IPv4 and IPv6 interfaces. We have explained how we can create interfaces from string and integer both.

IPV4

In [5]:
import ipaddress

### IPV4
print("==================== IPV4 =========================")

interface = ipaddress.ip_interface("49.34.86.241/24")
print("Interface Type : {}, Value : {}\n".format(type(interface).__name__, interface))

host_address = ipaddress.ip_interface(2**32-2*8)
print("Host Address Type : {}, Value : {}\n".format(type(interface).__name__, interface))

host_address = ipaddress.ip_interface("49.34.86.241/24")
print("Host Address Type : {}, Value : {}\n".format(type(interface).__name__, interface))

host_address = ipaddress.IPv4Interface("49.34.86.241/24")
print("Host Address Type : {}, Value : {}\n".format(type(interface).__name__, interface))
==================== IPV4 =========================
Interface Type : IPv4Interface, Value : 49.34.86.241/24

Host Address Type : IPv4Interface, Value : 49.34.86.241/24

Host Address Type : IPv4Interface, Value : 49.34.86.241/24

Host Address Type : IPv4Interface, Value : 49.34.86.241/24

IPV6

In [6]:
import ipaddress

### IPV6
print("==================== IPV6 =========================")

interface = ipaddress.ip_interface("0f0f:0241::1/112")
print("Host Address Type : {}, Value : {}\n".format(type(interface).__name__, interface))

host_address = ipaddress.ip_interface("0f0f:0241:0f0f:0f0f:0f0f:0f0f:0f0f:0f0f/112")
print("Host Address Type : {}, Value : {}\n".format(type(interface).__name__, interface))

host_address = ipaddress.ip_interface(2**128 - 2**16)
print("Host Address Type : {}, Value : {}\n".format(type(interface).__name__, interface))

host_address = ipaddress.IPv6Interface("0f0f:0241:0f0f:0f0f:0f0f:0f0f:0f0f:0f0f/112")
print("Host Address Type : {}, Value : {}\n".format(type(interface).__name__, interface))
==================== IPV6 =========================
Host Address Type : IPv6Interface, Value : f0f:241::1/112

Host Address Type : IPv6Interface, Value : f0f:241::1/112

Host Address Type : IPv6Interface, Value : f0f:241::1/112

Host Address Type : IPv6Interface, Value : f0f:241::1/112

Example 4: Important Attributes of IP Address Instances

As a part of our fourth example, we'll demonstrate different attributes that are present in the instance of IPv4Address and IPv6Address.


Attributes Common to Both IPv4Address & IPv6Address

  • version - It returns the version number of the address.
  • max_prefixlen It returns a number of bits it uses for representation.
  • compressed - It returns the compressed version of addresses removing groups that are zeros. Commonly used for IPv6 address.
  • exploded - It returns the full version of the address where missing groups are represented with zeros.
  • packed - It returns bytes object representing a binary representation of an address
  • reverse_pointer - It returns the name of reverse DNS PTR of IP Address.
  • is_multicast - It returns a boolean specifying whether the address is multicast or not.
  • is_private - It returns a boolean specifying whether the address is from private networks or not.
  • is_global - It returns a boolean specifying whether the address is from public networks or not.
  • is_unspecified - It returns a boolean specifying whether the address is specified or not.
  • is_reserved - It returns a boolean specifying whether the address is IETF reserved or not.
  • is_loopback - It returns a boolean specifying whether the address is a loopback address or not.
  • is_link_local - It returns a boolean specifying whether the address is reserved for link-local usage or not.

Attributes Only Present in IPv6Address

  • ipv4_mapped - It returns IPv4 address for addresses that seem to be IPv4 mapped.
  • is_site_local - It returns a boolean specifying whether the address is reserved for site-local usage or not.

Our code for this example simply creates instances of type IPv4Address and IPv6Address. It then prints all properties mentioned above for each address type to show us the value of different attributes.

IPV4

In [7]:
import ipaddress

host_address = ipaddress.ip_address("49.34.86.241")
print("Host Address Type : {}, Value : {}\n".format(type(host_address).__name__, host_address))

print("IP Address Version : {}".format(host_address.version))
print("IP Address Number of Bits for Representaion : {}".format(host_address.max_prefixlen))
print("IP Address Compressed : {}".format(host_address.compressed))
print("IP Address Exploded : {}".format(host_address.exploded))
print("IP Address Binary Representation : {}".format(host_address.packed))
print("IP Address Reverse DNS PTR Record : {}".format(host_address.reverse_pointer))
print()
print("Is IP Address Multicast? : {}".format(host_address.is_multicast))
print("Is IP Address Private? : {}".format(host_address.is_private))
print("Is IP Address Global? : {}".format(host_address.is_global))
print("Is IP Address Unspecified? : {}".format(host_address.is_unspecified))
print("Is IP Address Reserved? : {}".format(host_address.is_reserved))
print("Is IP Address Loopback? : {}".format(host_address.is_loopback))
print("Is IP Address Link-Local? : {}".format(host_address.is_link_local))
Host Address Type : IPv4Address, Value : 49.34.86.241

IP Address Version : 4
IP Address Number of Bits for Representaion : 32
IP Address Compressed : 49.34.86.241
IP Address Exploded : 49.34.86.241
IP Address Binary Representation : b'1"V\xf1'
IP Address Reverse DNS PTR Record : 241.86.34.49.in-addr.arpa

Is IP Address Multicast? : False
Is IP Address Private? : False
Is IP Address Global? : True
Is IP Address Unspecified? : False
Is IP Address Reserved? : False
Is IP Address Loopback? : False
Is IP Address Link-Local? : False

IPV6

In [8]:
import ipaddress

host_address = ipaddress.ip_address("0f0f:0241::")
print("Host Address Type : {}, Value : {}\n".format(type(host_address).__name__, host_address))

print("IP Address Version : {}".format(host_address.version))
print("IP Address Number of Bits for Representaion : {}".format(host_address.max_prefixlen))
print("IP Address Compressed : {}".format(host_address.compressed))
print("IP Address Exploded : {}".format(host_address.exploded))
print("IP Address Binary Representation : {}".format(host_address.packed))
print("IP Address Reverse DNS PTR Record : {}".format(host_address.reverse_pointer))
print("IP Address IPV4 Mapping : {}".format(host_address.ipv4_mapped))
#print("IP Address Scope ID : {}".format(host_address.scope_id))
#print("IP Address 6to4 Value : {}".format(host_address.sixtofour))
#print("IP Address Teredo Value : {}".format(host_address.teredo))
print()
print("Is IP Address Multicast? : {}".format(host_address.is_multicast))
print("Is IP Address Private? : {}".format(host_address.is_private))
print("Is IP Address Global? : {}".format(host_address.is_global))
print("Is IP Address Unspecified? : {}".format(host_address.is_unspecified))
print("Is IP Address Reserved? : {}".format(host_address.is_reserved))
print("Is IP Address Loopback? : {}".format(host_address.is_loopback))
print("Is IP Address Link-Local? : {}".format(host_address.is_link_local))
print("Is IP Address Site-Local? : {}".format(host_address.is_site_local))
Host Address Type : IPv6Address, Value : f0f:241::

IP Address Version : 6
IP Address Number of Bits for Representaion : 128
IP Address Compressed : f0f:241::
IP Address Exploded : 0f0f:0241:0000:0000:0000:0000:0000:0000
IP Address Binary Representation : b'\x0f\x0f\x02A\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
IP Address Reverse DNS PTR Record : 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.4.2.0.f.0.f.0.ip6.arpa
IP Address IPV4 Mapping : None

Is IP Address Multicast? : False
Is IP Address Private? : False
Is IP Address Global? : True
Is IP Address Unspecified? : False
Is IP Address Reserved? : True
Is IP Address Loopback? : False
Is IP Address Link-Local? : False
Is IP Address Site-Local? : False

Example 5: IP Address Comparison and Arithmetic Operations on IP Addresses

As a part of our fifth example, we'll explain how we can compare different IP addresses and perform arithmetic operations on them.

Our code for this part starts by creating instances of IPv4Address and IPv6Address. It then compares them for different comparison types like equal to, greater than, less than, etc. It then creates new addresses by adding and subtracting integers from numbers to create new addresses. It then again performs comparison operations on these newly-created addresses.

Please make a NOTE that we can easily add and subtract an integer from an instance of IP address to create a new address which we have explained in the code of this example.

IPV4

In [9]:
import ipaddress

host_address1 = ipaddress.ip_address("49.34.86.241")
print("Host Address 1 Type : {}, Value : {}\n".format(type(host_address1).__name__, host_address1))

host_address2 = ipaddress.ip_address("49.34.86.245")
print("Host Address 2 Type : {}, Value : {}\n".format(type(host_address2).__name__, host_address2))

print("Is Address 1 equal to Address 2? : {}".format(host_address1 == host_address2))
print("Is Address 1 not equal to Address 2? : {}".format(host_address1 != host_address2))
print("Is Address 1 greater than Address 2? : {}".format(host_address1 > host_address2))
print("Is Address 1 greater than or equal to Address 2? : {}".format(host_address1 >= host_address2))
print("Is Address 1 less than Address 2? : {}".format(host_address1 < host_address2))
print("Is Address 1 less than or equal to Address 2? : {}".format(host_address1 <= host_address2))
Host Address 1 Type : IPv4Address, Value : 49.34.86.241

Host Address 2 Type : IPv4Address, Value : 49.34.86.245

Is Address 1 equal to Address 2? : False
Is Address 1 not equal to Address 2? : True
Is Address 1 greater than Address 2? : False
Is Address 1 greater than or equal to Address 2? : False
Is Address 1 less than Address 2? : True
Is Address 1 less than or equal to Address 2? : True
In [10]:
host_address3 = host_address1 + 4
print("Host Address 3 Type : {}, Value : {}".format(type(host_address3).__name__, host_address3))

print("\nIs Address 3 equal to Address 2? : {}".format(host_address3 == host_address2))
print("Is Address 3 not equal to Address 2? : {}".format(host_address3 != host_address2))
print("Is Address 3 greater than Address 2? : {}".format(host_address3 > host_address2))
print("Is Address 3 greater than or equal to Address 2? : {}".format(host_address3 >= host_address2))
print("Is Address 3 less than Address 2? : {}".format(host_address3 < host_address2))
print("Is Address 3 less than or equal to Address 2? : {}".format(host_address3 <= host_address2))
Host Address 3 Type : IPv4Address, Value : 49.34.86.245

Is Address 3 equal to Address 2? : True
Is Address 3 not equal to Address 2? : False
Is Address 3 greater than Address 2? : False
Is Address 3 greater than or equal to Address 2? : True
Is Address 3 less than Address 2? : False
Is Address 3 less than or equal to Address 2? : True
In [11]:
host_address4 = host_address2 - 4
print("Host Address 4 Type : {}, Value : {}".format(type(host_address3).__name__, host_address4))

print("\nIs Address 4 equal to Address 1? : {}".format(host_address4 == host_address1))
print("Is Address 4 not equal to Address 1? : {}".format(host_address4 != host_address1))
print("Is Address 4 greater than Address 1? : {}".format(host_address4 > host_address1))
print("Is Address 4 greater than or equal to Address 1? : {}".format(host_address4 >= host_address1))
print("Is Address 4 less than Address 1? : {}".format(host_address4 < host_address1))
print("Is Address 4 less than or equal to Address 1? : {}".format(host_address4 <= host_address1))
Host Address 4 Type : IPv4Address, Value : 49.34.86.241

Is Address 4 equal to Address 1? : True
Is Address 4 not equal to Address 1? : False
Is Address 4 greater than Address 1? : False
Is Address 4 greater than or equal to Address 1? : True
Is Address 4 less than Address 1? : False
Is Address 4 less than or equal to Address 1? : True

IPV6

In [12]:
import ipaddress

host_address1 = ipaddress.ip_address("0f0f:0241::")
print("Host Address Type : {}, Value : {}\n".format(type(host_address1).__name__, host_address1.exploded))

host_address2 = ipaddress.ip_address("0f0f:0241:0:0:0:0:0:0005")
print("Host Address Type : {}, Value : {}\n".format(type(host_address2).__name__, host_address2.exploded))

print("Is Address 1 equal to Address 2? : {}".format(host_address1 == host_address2))
print("Is Address 1 not equal to Address 2? : {}".format(host_address1 != host_address2))
print("Is Address 1 greater than Address 2? : {}".format(host_address1 > host_address2))
print("Is Address 1 greater than or equal to Address 2? : {}".format(host_address1 >= host_address2))
print("Is Address 1 less than Address 2? : {}".format(host_address1 < host_address2))
print("Is Address 1 less than or equal to Address 2? : {}".format(host_address1 <= host_address2))
Host Address Type : IPv6Address, Value : 0f0f:0241:0000:0000:0000:0000:0000:0000

Host Address Type : IPv6Address, Value : 0f0f:0241:0000:0000:0000:0000:0000:0005

Is Address 1 equal to Address 2? : False
Is Address 1 not equal to Address 2? : True
Is Address 1 greater than Address 2? : False
Is Address 1 greater than or equal to Address 2? : False
Is Address 1 less than Address 2? : True
Is Address 1 less than or equal to Address 2? : True
In [13]:
host_address3 = host_address1 + 5
print("Host Address 3 Type : {}, Value : {}".format(type(host_address3).__name__, host_address3.exploded))

print("\nIs Address 3 equal to Address 2? : {}".format(host_address3 == host_address2))
print("Is Address 3 not equal to Address 2? : {}".format(host_address3 != host_address2))
print("Is Address 3 greater than Address 2? : {}".format(host_address3 > host_address2))
print("Is Address 3 greater than or equal to Address 2? : {}".format(host_address3 >= host_address2))
print("Is Address 3 less than Address 2? : {}".format(host_address3 < host_address2))
print("Is Address 3 less than or equal to Address 2? : {}".format(host_address3 <= host_address2))
Host Address 3 Type : IPv6Address, Value : 0f0f:0241:0000:0000:0000:0000:0000:0005

Is Address 3 equal to Address 2? : True
Is Address 3 not equal to Address 2? : False
Is Address 3 greater than Address 2? : False
Is Address 3 greater than or equal to Address 2? : True
Is Address 3 less than Address 2? : False
Is Address 3 less than or equal to Address 2? : True
In [14]:
host_address4 = host_address2 - 5
print("Host Address 4 Type : {}, Value : {}".format(type(host_address3).__name__, host_address4.exploded))

print("\nIs Address 4 equal to Address 1? : {}".format(host_address4 == host_address1))
print("Is Address 4 not equal to Address 1? : {}".format(host_address4 != host_address1))
print("Is Address 4 greater than Address 1? : {}".format(host_address4 > host_address1))
print("Is Address 4 greater than or equal to Address 1? : {}".format(host_address4 >= host_address1))
print("Is Address 4 less than Address 1? : {}".format(host_address4 < host_address1))
print("Is Address 4 less than or equal to Address 1? : {}".format(host_address4 <= host_address1))
Host Address 4 Type : IPv6Address, Value : 0f0f:0241:0000:0000:0000:0000:0000:0000

Is Address 4 equal to Address 1? : True
Is Address 4 not equal to Address 1? : False
Is Address 4 greater than Address 1? : False
Is Address 4 greater than or equal to Address 1? : True
Is Address 4 less than Address 1? : False
Is Address 4 less than or equal to Address 1? : True

Example 6: Important Attributes of IP Network Instances

As a part of our sixth example, we'll explain attributes of network instances of type IPv4Network and IPv6Network.

Please make a NOTE that many attributes have the same meaning as that of IPv4Address and IPv6Address instances hence they won't be covered here again. We'll only highlight attributes specific to instances of the network.


Attributes Common to Both IPv4Network & IPv6Network

  • num_addresses - It returns an integer representing a number of IP address that network covers.
  • network_address - - It returns network address of the network.
  • broadcast_address - It returns broadcast address for the network. The packets sent to this address will be sent to all hosts of the network.
  • hostmask - It returns a string representing hostmask.
  • netmask - It returns a string representing netmask.
  • with_hostmask - It returns a string representing network address along with hostmask.
  • with_netmask - It returns a string representing network address along with netmask.

Our code for this example simply creates and instances of IPv4Network and IPv6Network first. It then prints all the important attributes of both instances.

IPV4

In [15]:
import ipaddress

network = ipaddress.ip_network("49.34.86.0/24")
print("Network Address Type : {}, Value : {}".format(type(network).__name__, network))
print("Number of Addresses on Network : {}\n".format(network.num_addresses))

print("Network Version : {}".format(network.version))
print("Network Number of Bits for Representaion : {}".format(network.max_prefixlen))
print("Network Compressed : {}".format(network.compressed))
print("Network Address : {}".format(network.network_address))
print("Network Broadcast Address : {}".format(network.broadcast_address))
print("Network Host Mask : {}".format(network.hostmask))
print("Network Mask : {}".format(network.netmask))
print("Network With Host Mask : {}".format(network.with_hostmask))
print("Network With Mask : {}".format(network.with_netmask))
print()
print("Is Network Multicast? : {}".format(network.is_multicast))
print("Is Network Private? : {}".format(network.is_private))
print("Is Network Global? : {}".format(network.is_global))
print("Is Network Unspecified? : {}".format(network.is_unspecified))
print("Is Network Reserved? : {}".format(network.is_reserved))
print("Is Network Loopback? : {}".format(network.is_loopback))
print("Is Network Link-Local? : {}".format(network.is_link_local))
Network Address Type : IPv4Network, Value : 49.34.86.0/24
Number of Addresses on Network : 256

Network Version : 4
Network Number of Bits for Representaion : 32
Network Compressed : 49.34.86.0/24
Network Address : 49.34.86.0
Network Broadcast Address : 49.34.86.255
Network Host Mask : 0.0.0.255
Network Mask : 255.255.255.0
Network With Host Mask : 49.34.86.0/0.0.0.255
Network With Mask : 49.34.86.0/255.255.255.0

Is Network Multicast? : False
Is Network Private? : False
Is Network Global? : True
Is Network Unspecified? : False
Is Network Reserved? : False
Is Network Loopback? : False
Is Network Link-Local? : False

IPV6

In [16]:
import ipaddress

network = ipaddress.ip_network("0f0f:0f0f:0f0f:0f0f:0f0f:0f0f:0f0f:0/112")
print("Network Address Type : {}, Value : {}".format(type(network).__name__, network))
print("Number of Addresses on Network : {}\n".format(network.num_addresses))

print("Network Version : {}".format(network.version))
print("Network Number of Bits for Representaion : {}".format(network.max_prefixlen))
print("Network Compressed : {}".format(network.compressed))
print("Network Address : {}".format(network.network_address))
print("Network Broadcast Address : {}".format(network.broadcast_address))
print("Network Host Mask : {}".format(network.hostmask))
print("Network Mask : {}".format(network.netmask))
print("Network With Host Mask : {}".format(network.with_hostmask))
print("Network With Mask : {}".format(network.with_netmask))
print()
print("Is Network Multicast? : {}".format(network.is_multicast))
print("Is Network Private? : {}".format(network.is_private))
print("Is Network Global? : {}".format(network.is_global))
print("Is Network Unspecified? : {}".format(network.is_unspecified))
print("Is Network Reserved? : {}".format(network.is_reserved))
print("Is Network Loopback? : {}".format(network.is_loopback))
print("Is Network Link-Local? : {}".format(network.is_link_local))
Network Address Type : IPv6Network, Value : f0f:f0f:f0f:f0f:f0f:f0f:f0f:0/112
Number of Addresses on Network : 65536

Network Version : 6
Network Number of Bits for Representaion : 128
Network Compressed : f0f:f0f:f0f:f0f:f0f:f0f:f0f:0/112
Network Address : f0f:f0f:f0f:f0f:f0f:f0f:f0f:0
Network Broadcast Address : f0f:f0f:f0f:f0f:f0f:f0f:f0f:ffff
Network Host Mask : ::ffff
Network Mask : ffff:ffff:ffff:ffff:ffff:ffff:ffff:0
Network With Host Mask : f0f:f0f:f0f:f0f:f0f:f0f:f0f:0/::ffff
Network With Mask : f0f:f0f:f0f:f0f:f0f:f0f:f0f:0/ffff:ffff:ffff:ffff:ffff:ffff:ffff:0

Is Network Multicast? : False
Is Network Private? : False
Is Network Global? : True
Is Network Unspecified? : False
Is Network Reserved? : True
Is Network Loopback? : False
Is Network Link-Local? : False

Example 7: Useful Methods to Do Comparison of Networks

As a part of our seventh example, we are going to demonstrate useful methods of IPv4Network and IPv6Network which can help us find things like whether there are IP addresses overlap between networks, whether one network is subnet or supernet of another network, whether two networks are same or not, etc.


Methods for Network Comparison

  • hosts() - It returns an iterator that has a list of all IP addresses present in the network.
  • overlaps(other_network) - It accepts another network as input and returns a boolean telling us whether the network has some or all IP addresses overlap with another network.
  • address_exclude(other_network) - It returns a list of network definitions which are not present in network but are present in other network given as input.
  • subnets() - It returns list of subnets of the network.
  • supernet() - It returns the supernet of the network.
  • subnet_of(other_network) - It checks whether the network is the subnet of another network and returns a boolean value based on the result.
  • supernet_of(other_network) - It checks whether the network is supernet of another network and returns a boolean value based on the result.
  • compare_networks(other_network) - It compares network with other network and returns -1 (network less than another network), 0 (both are equal), and 1 (network greater than another network) as output.

Our code for this example creates instances of networks and then compares them using all the methods mentioned above. It helps us understand how methods work.

IPV4

In [17]:
import ipaddress

network1 = ipaddress.ip_network("49.34.86.0/24")
print("Network Address Type : {}, Value : {}".format(type(network1).__name__, network))
print("Number of Addresses on Network 1 : {}".format(network1.num_addresses))
print("\nFirst Few Addresses : {}".format(list(network1.hosts())[:5]))

network2 = ipaddress.ip_network("49.34.86.0/28")
print("\nNumber of Addresses on Network 2 : {}\n".format(network2.num_addresses))

print("\nDoes Network 1 and Network 2 Overlaps? : {}".format(network1.overlaps(network2)))
print("\nDoes Network 2 and Network 1 Overlaps? : {}".format(network2.overlaps(network1)))

excluded_addresses = network1.address_exclude(network2)
print("\nNetwork Definitions Not Present in Network 1 and Present in Network 2 : {}".format(list(excluded_addresses)))


print("\nNetwork Subnets : {}".format(list(network1.subnets())))

print("\nNetwork Supernets : {}".format(network1.supernet()))

print("\nIs Network 1 subnet of Network 2? : {}".format(network1.subnet_of(network2)))
print("Is Network 2 subnet of Network 1? : {}".format(network2.subnet_of(network1)))

print("\nIs Network 1 supernet of Network 2? : {}".format(network1.supernet_of(network2)))
print("Is Network 2 superbnet of Network 1? : {}".format(network2.supernet_of(network1)))

print("\nComparison of Network 1 & Network 2 : {}".format(network1.compare_networks(network2)))
print("Comparison of Network 2 & Network 1 : {}".format(network2.compare_networks(network1)))
print("Comparison of Network 1 & Network 1 : {}".format(network1.compare_networks(network1)))
print("Comparison of Network 2 & Network 2 : {}".format(network2.compare_networks(network2)))
Network Address Type : IPv4Network, Value : f0f:f0f:f0f:f0f:f0f:f0f:f0f:0/112
Number of Addresses on Network 1 : 256

First Few Addresses : [IPv4Address('49.34.86.1'), IPv4Address('49.34.86.2'), IPv4Address('49.34.86.3'), IPv4Address('49.34.86.4'), IPv4Address('49.34.86.5')]

Number of Addresses on Network 2 : 16


Does Network 1 and Network 2 Overlaps? : True

Does Network 2 and Network 1 Overlaps? : True

Network Definitions Not Present in Network 1 and Present in Network 2 : [IPv4Network('49.34.86.128/25'), IPv4Network('49.34.86.64/26'), IPv4Network('49.34.86.32/27'), IPv4Network('49.34.86.16/28')]

Network Subnets : [IPv4Network('49.34.86.0/25'), IPv4Network('49.34.86.128/25')]

Network Supernets : 49.34.86.0/23

Is Network 1 subnet of Network 2? : False
Is Network 2 subnet of Network 1? : True

Is Network 1 supernet of Network 2? : True
Is Network 2 superbnet of Network 1? : False

Comparison of Network 1 & Network 2 : -1
Comparison of Network 2 & Network 1 : 1
Comparison of Network 1 & Network 1 : 0
Comparison of Network 2 & Network 2 : 0

IPV6

In [18]:
import ipaddress

network1 = ipaddress.ip_network("0f0f:0f0f:0f0f:0f0f:0f0f:0f0f:0f0f:0/112")
print("Network Address Type : {}, Value : {}".format(type(network1).__name__, network1))
print("Number of Addresses on Network : {}".format(network1.num_addresses))
print("\nFirst Few Addresses : {}".format(list(network1.hosts())[:5]))

network2 = ipaddress.ip_network("0f0f:0f0f:0f0f:0f0f:0f0f:0f0f:0f0f:0/116")
print("\nNumber of Addresses on Network 2 : {}\n".format(network2.num_addresses))

print("\nDoes Network 1 and Network 2 Overlaps? : {}".format(network1.overlaps(network2)))
print("\nDoes Network 2 and Network 1 Overlaps? : {}".format(network2.overlaps(network1)))

excluded_addresses = network1.address_exclude(network2)
print("\nNetwork Definitions Not Present in Network 1 and Present in Network 2 : {}".format(list(excluded_addresses)))


print("\nNetwork Subnets : {}".format(list(network1.subnets())))

print("\nNetwork Supernets : {}".format(network1.supernet()))

print("\nIs Network 1 subnet of Network 2? : {}".format(network1.subnet_of(network2)))
print("Is Network 2 subnet of Network 1? : {}".format(network2.subnet_of(network1)))

print("\nIs Network 1 supernet of Network 2? : {}".format(network1.supernet_of(network2)))
print("Is Network 2 superbnet of Network 1? : {}".format(network2.supernet_of(network1)))

print("\nComparison of Network 1 & Network 2 : {}".format(network1.compare_networks(network2)))
print("Comparison of Network 2 & Network 1 : {}".format(network2.compare_networks(network1)))
print("Comparison of Network 1 & Network 1 : {}".format(network1.compare_networks(network1)))
print("Comparison of Network 2 & Network 2 : {}".format(network2.compare_networks(network2)))
Network Address Type : IPv6Network, Value : f0f:f0f:f0f:f0f:f0f:f0f:f0f:0/112
Number of Addresses on Network : 65536

First Few Addresses : [IPv6Address('f0f:f0f:f0f:f0f:f0f:f0f:f0f:1'), IPv6Address('f0f:f0f:f0f:f0f:f0f:f0f:f0f:2'), IPv6Address('f0f:f0f:f0f:f0f:f0f:f0f:f0f:3'), IPv6Address('f0f:f0f:f0f:f0f:f0f:f0f:f0f:4'), IPv6Address('f0f:f0f:f0f:f0f:f0f:f0f:f0f:5')]

Number of Addresses on Network 2 : 4096


Does Network 1 and Network 2 Overlaps? : True

Does Network 2 and Network 1 Overlaps? : True

Network Definitions Not Present in Network 1 and Present in Network 2 : [IPv6Network('f0f:f0f:f0f:f0f:f0f:f0f:f0f:8000/113'), IPv6Network('f0f:f0f:f0f:f0f:f0f:f0f:f0f:4000/114'), IPv6Network('f0f:f0f:f0f:f0f:f0f:f0f:f0f:2000/115'), IPv6Network('f0f:f0f:f0f:f0f:f0f:f0f:f0f:1000/116')]

Network Subnets : [IPv6Network('f0f:f0f:f0f:f0f:f0f:f0f:f0f:0/113'), IPv6Network('f0f:f0f:f0f:f0f:f0f:f0f:f0f:8000/113')]

Network Supernets : f0f:f0f:f0f:f0f:f0f:f0f:f0e:0/111

Is Network 1 subnet of Network 2? : False
Is Network 2 subnet of Network 1? : True

Is Network 1 supernet of Network 2? : True
Is Network 2 superbnet of Network 1? : False

Comparison of Network 1 & Network 2 : -1
Comparison of Network 2 & Network 1 : 1
Comparison of Network 1 & Network 1 : 0
Comparison of Network 2 & Network 2 : 0

Example 8: Important Attributes of Network Interfaces

As a part of our eighth example, we'll be demonstrating various attributes of instances of IPv4Interface and IPv6Interface. The IPv4Interface extends IPv4Address and IPv6Interface extends IPv6Address hence majority of properties as the same as one of the IP address instances that we have explained. We'll only cover properties that were not explained earlier in this part.


Import Attributes of IPv4Interface & IPv6Interface

  • ip - It returns an IP address as instance of IPv4Address or IPv6Address.
  • network - It returns a network as an instance of IPv4Network or IPv6Network.
  • with_netmask - It returns a string representation of interface with network mask.
  • with_hostmask - It returns a string representation of interface with hostmask.

Our code for this example simply creates instances of IPv4Interface and IPv6Interface first. It then prints values of all the attributes of both instances to explain them.

IPV4

In [19]:
import ipaddress

interface = ipaddress.ip_interface("49.34.86.241/24")
print("Interface Type : {}, Value : {}\n".format(type(interface).__name__, interface.exploded))

print("Interface Version : {}".format(interface.version))
print("Interface IP Address : {}".format(interface.ip))
print("Interface Number of Bits for Representaion : {}".format(interface.max_prefixlen))
print("Interface Compressed : {}".format(interface.compressed))
print("Interface Network : {}".format(interface.network))
print("Interface Host Mask : {}".format(interface.hostmask))
print("Interface Mask : {}".format(interface.netmask))
print("Interface With Host Mask : {}".format(interface.with_hostmask))
print("Interface With Mask : {}".format(interface.with_netmask))
print("Interface With Prefix Length : {}".format(interface.with_prefixlen))
print()
print("Is Interface Multicast? : {}".format(interface.is_multicast))
print("Is Interface Private? : {}".format(interface.is_private))
print("Is Interface Global? : {}".format(interface.is_global))
print("Is Interface Unspecified? : {}".format(interface.is_unspecified))
print("Is Interface Reserved? : {}".format(interface.is_reserved))
print("Is Interface Loopback? : {}".format(interface.is_loopback))
print("Is Interface Link-Local? : {}".format(interface.is_link_local))
Interface Type : IPv4Interface, Value : 49.34.86.241/24

Interface Version : 4
Interface IP Address : 49.34.86.241
Interface Number of Bits for Representaion : 32
Interface Compressed : 49.34.86.241/24
Interface Network : 49.34.86.0/24
Interface Host Mask : 0.0.0.255
Interface Mask : 255.255.255.0
Interface With Host Mask : 49.34.86.241/0.0.0.255
Interface With Mask : 49.34.86.241/255.255.255.0
Interface With Prefix Length : 49.34.86.241/24

Is Interface Multicast? : False
Is Interface Private? : False
Is Interface Global? : True
Is Interface Unspecified? : False
Is Interface Reserved? : False
Is Interface Loopback? : False
Is Interface Link-Local? : False

IPV6

In [20]:
import ipaddress

interface = ipaddress.ip_interface("0f0f:0241::1/112")
print("Host Address Type : {}, Value : {}\n".format(type(interface).__name__, interface.exploded))

print("Interface Version : {}".format(interface.version))
print("Interface IP Address : {}".format(interface.ip))
print("Interface Number of Bits for Representaion : {}".format(interface.max_prefixlen))
print("Interface Compressed : {}".format(interface.compressed))
print("Interface Network : {}".format(interface.network))
print("Interface Host Mask : {}".format(interface.hostmask))
print("Interface Mask : {}".format(interface.netmask))
print("Interface With Host Mask : {}".format(interface.with_hostmask))
print("Interface With Mask : {}".format(interface.with_netmask))
print("Interface With Prefix Length : {}".format(interface.with_prefixlen))
print()
print("Is Interface Multicast? : {}".format(interface.is_multicast))
print("Is Interface Private? : {}".format(interface.is_private))
print("Is Interface Global? : {}".format(interface.is_global))
print("Is Interface Unspecified? : {}".format(interface.is_unspecified))
print("Is Interface Reserved? : {}".format(interface.is_reserved))
print("Is Interface Loopback? : {}".format(interface.is_loopback))
print("Is Interface Link-Local? : {}".format(interface.is_link_local))
Host Address Type : IPv6Interface, Value : 0f0f:0241:0000:0000:0000:0000:0000:0001/112

Interface Version : 6
Interface IP Address : f0f:241::1
Interface Number of Bits for Representaion : 128
Interface Compressed : f0f:241::1/112
Interface Network : f0f:241::/112
Interface Host Mask : ::ffff
Interface Mask : ffff:ffff:ffff:ffff:ffff:ffff:ffff:0
Interface With Host Mask : f0f:241::1/::ffff
Interface With Mask : f0f:241::1/ffff:ffff:ffff:ffff:ffff:ffff:ffff:0
Interface With Prefix Length : f0f:241::1/112

Is Interface Multicast? : False
Is Interface Private? : False
Is Interface Global? : True
Is Interface Unspecified? : False
Is Interface Reserved? : True
Is Interface Loopback? : False
Is Interface Link-Local? : False

This ends our small tutorial explaining the usage of the API of ipaddress module. It covers how we can work with IP address, the network address, and network interfaces in Python with simple examples. Please feel free to let us know your views in the comments section.



Sunny Solanki  Sunny Solanki