# 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.

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 =========================")

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

```
```==================== IPV4 =========================
IPV4 Address Length : 32 bits

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

```

#### IPV6¶

In [2]:
```import ipaddress

### IPV6

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

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

try:
except Exception as e:
print("ErrorType : {}, Error : {}".format(type(e).__name__, e))

```
```==================== IPV6 =========================
IPV6 Address Length : 128 bits

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

```

### 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 =========================")

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

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

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

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

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

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

print("Network Address Type : {}, Value : {}".format(type(network).__name__, network))
print("Number of Addresses on Network : {}\n".format(len(list(network))))
```
```==================== 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

```

#### IPV6¶

In [4]:
```import ipaddress

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

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

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

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

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

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

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

print("Network Address Type : {}, Value : {}".format(type(network).__name__, network))
print("Number of Addresses on Network : {}\n".format(len(list(network))))
```
```==================== 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

```

### 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 =========================")

print("Interface Type : {}, Value : {}\n".format(type(interface).__name__, interface))

print("Host Address Type : {}, Value : {}\n".format(type(interface).__name__, interface))

print("Host Address Type : {}, Value : {}\n".format(type(interface).__name__, interface))

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 =========================")

print("Host Address Type : {}, Value : {}\n".format(type(interface).__name__, interface))

print("Host Address Type : {}, Value : {}\n".format(type(interface).__name__, interface))

print("Host Address Type : {}, Value : {}\n".format(type(interface).__name__, interface))

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.

• 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

print()
```
```Host Address Type : IPv4Address, Value : 49.34.86.241

IP Address Number of Bits for Representaion : 32
IP Address Binary Representation : b'1"V\xf1'

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
```

#### IPV6¶

In [8]:
```import ipaddress

print()
```
```Host Address Type : IPv6Address, Value : f0f:241::

IP Address Number of Bits for Representaion : 128
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 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 Address 1 Type : IPv4Address, Value : 49.34.86.241

Is Address 1 greater than or equal to Address 2? : False
Is Address 1 less than or equal to Address 2? : True
```
In [10]:
```host_address3 = host_address1 + 4

```
```Host Address 3 Type : IPv4Address, Value : 49.34.86.245

Is Address 3 greater than or equal to Address 2? : True
Is Address 3 less than or equal to Address 2? : True
```
In [11]:
```host_address4 = host_address2 - 4

```
```Host Address 4 Type : IPv4Address, Value : 49.34.86.241

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

#### IPV6¶

In [12]:
```import ipaddress

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

Is Address 1 greater than or equal to Address 2? : False
Is Address 1 less than or equal to Address 2? : True
```
In [13]:
```host_address3 = host_address1 + 5

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

Is Address 3 greater than or equal to Address 2? : True
Is Address 3 less than or equal to Address 2? : True
```
In [14]:
```host_address4 = host_address2 - 5

```
```Host Address 4 Type : IPv6Address, Value : 0f0f:0241:0000:0000:0000:0000:0000:0000

Is Address 4 greater than or equal to Address 1? : True
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.

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

print("Network Address Type : {}, Value : {}".format(type(network).__name__, network))

print("Network Version : {}".format(network.version))
print("Network Number of Bits for Representaion : {}".format(network.max_prefixlen))
print("Network Compressed : {}".format(network.compressed))
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))
```
```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 With Host Mask : 49.34.86.0/0.0.0.255

Is Network Multicast? : False
Is Network Private? : False
Is Network Global? : True
Is Network Unspecified? : False
Is Network Reserved? : False
Is Network Loopback? : False
```

#### IPV6¶

In [16]:
```import ipaddress

print("Network Address Type : {}, Value : {}".format(type(network).__name__, network))

print("Network Version : {}".format(network.version))
print("Network Number of Bits for Representaion : {}".format(network.max_prefixlen))
print("Network Compressed : {}".format(network.compressed))
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))
```
```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 With Host Mask : f0f:f0f:f0f:f0f:f0f:f0f:f0f:0/::ffff

Is Network Multicast? : False
Is Network Private? : False
Is Network Global? : True
Is Network Unspecified? : False
Is Network Reserved? : True
Is Network Loopback? : 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

print("Network Address Type : {}, Value : {}".format(type(network1).__name__, network))

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

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

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

print("Network Address Type : {}, Value : {}".format(type(network1).__name__, network1))

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

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

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¶

• 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

print("Interface Type : {}, Value : {}\n".format(type(interface).__name__, interface.exploded))

print("Interface Version : {}".format(interface.version))
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 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))
```
```Interface Type : IPv4Interface, Value : 49.34.86.241/24

Interface Version : 4
Interface Number of Bits for Representaion : 32
Interface Compressed : 49.34.86.241/24
Interface Network : 49.34.86.0/24
Interface With Host Mask : 49.34.86.241/0.0.0.255
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
```

#### IPV6¶

In [20]:
```import ipaddress

print("Host Address Type : {}, Value : {}\n".format(type(interface).__name__, interface.exploded))

print("Interface Version : {}".format(interface.version))
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 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))
```
```Host Address Type : IPv6Interface, Value : 0f0f:0241:0000:0000:0000:0000:0000:0001/112

Interface Version : 6
Interface Number of Bits for Representaion : 128
Interface Compressed : f0f:241::1/112
Interface Network : f0f:241::/112
Interface With Host Mask : f0f:241::1/::ffff
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
```

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.

## Support Us to Make a Difference

Thank You for visiting our website. If you like our work, please support us so that we can keep on creating new tutorials/blogs on interesting topics (like AI, ML, Data Science, Python, Digital Marketing, SEO, etc.) that can help people learn new things faster. You can support us by clicking on the Coffee button at the bottom right corner. We would appreciate even if you can give a thumbs-up to our article in the comments section below.

## Want to Share Your Views? Have Any Suggestions?

If you want to

• provide some suggestions on topic