Как манипулировать IP-адресами в Python с помощью модуля ipaddress
В этой статье вы узнаете, как использовать модуль ipaddress для работы с IP-адресами в Python. Сетевые инженеры и люди, разрабатывающие программное обеспечение, связанное с сетями, часто используют этот модуль, так как он предоставляет удобные функции и классы для решения различных задач, связанных с IP-адресами, включая проверку принадлежности двух хостов к одной подсети, итерацию по всем хостам подсети, получение широковещательных адресов определенной подсети и многое другое.
Нам не нужно ничего устанавливать, поскольку этот модуль является встроенным и появился в Python 3.3, так что если у вас есть Python 3.3+ (а я уверен, что у вас он есть), то все готово!
Начнем с класса IPv4Address:
import ipaddress
# initialize an IPv4 Address
ip = ipaddress.IPv4Address("192.168.1.1")
Теперь этот объект ip представляет один IP-адрес, мы можем проверить, является ли он глобальным IP-адресом (не частным) и является ли он link-local:
# print True if the IP address is global
print("Is global:", ip.is_global)
# print Ture if the IP address is Link-local
print("Is link-local:", ip.is_link_local)
Выход:
Is global: False
Is link-local: False
Вы также можете использовать ip.is_reserved и ip.is_multicast, чтобы проверить, находится ли данный IP-адрес в списке зарезервированных IP-адресов и адресов многоадресной рассылки соответственно.
Вы можете выполнять сложение и вычитание для IP-адресов:
# next ip address
print(ip + 1)
# previous ip address
print(ip - 1)
Вы угадали, прибавление IP к 1 означает, что это следующий IP-адрес, вычитание из 1 означает предыдущий IP-адрес, вот результат:
192.168.1.2
192.168.1.0
Поскольку я не могу охватить все доступные методы, напишите dir(ip), чтобы узнать различные методы и атрибуты, которые вы можете использовать.
Теперь, когда у вас есть базовое понимание объекта IPv4Address, давайте погрузимся в работу с объектами IPv4Network:
# initialize an IPv4 Network
network = ipaddress.IPv4Network("192.168.1.0/24")
Теперь этот сетевой объект представляет сеть IPv4, /24 – это нотация CIDR, она указывает, что первые 24 бита из 32 бит IP-адреса используются для идентификации сетевой части адреса, то есть в данном случае “192.168.1.x” – это сетевая часть (3×8 = 24 бита), и только последний октет “x.x.x.0” – это хостовая часть.
Вы можете получить сетевую маску этой сети:
# get the network mask
print("Network mask:", network.netmask)
Выход:
Network mask: 255.255.255.0
Маска сети – это просто другой формат (возможно, более старый) для выражения и представления сетевой части адреса, в данном случае 255.255.255.0 означает, что ведущие 24 бита, заполненные единицами (255 – это 11111111 в двоичной системе), указывают на сетевую часть адреса (то же самое, что и нотация /24).
Вот как можно получить широковещательный адрес сети:
# get the broadcast address
print("Broadcast address:", network.broadcast_address)
Выход:
Broadcast address: 192.168.1.255
Печать количества хостов, принадлежащих данной сети:
# print the number of IP addresses under this network
print("Number of hosts under", str(network), ":", network.num_addresses)
Выход:
Number of hosts under 192.168.1.0/24 : 256
Всего в этой сети доступно 256 хостов (включая подсеть и широковещательные адреса), вот как можно выполнить итерации по всем из них:
# iterate over all the hosts under this network
print("Hosts under", str(network), ":")
for host in network.hosts():
print(host)
Это выведет все действительные IP-адреса хостов в диапазоне от 192.168.1.1 до 192.168.1.254.
Вы также можете получить подсети этой сети:
# iterate over the subnets of this network
print("Subnets:")
for subnet in network.subnets(prefixlen_diff=2):
print(subnet)
Выход:
Subnets:
192.168.1.0/26
192.168.1.64/26
192.168.1.128/26
192.168.1.192/26
Метод network.subnets() возвращает подсети, которые объединяются для создания текущей подсети в виде списка объектов IPv4Network, параметр prefixlen_diff является целым числом, которое указывает, на сколько должна быть увеличена длина префикса, я установил значение 2, чтобы получить подсети /26.
Вы также можете получить суперсеть:
# get the supernet of this network
print("Supernet:", network.supernet(prefixlen_diff=1))
Это вернет суперсеть, содержащую текущую сеть, вот результат:
Supernet: 192.168.0.0/23
Наконец, можно проверить, перекрывает ли сеть другую сеть:
# tell if this network is under (or overlaps) 192.168.0.0/16
print("Overlaps 192.168.0.0/16:", network.overlaps(ipaddress.IPv4Network("192.168.0.0/16")))
Выход:
Overlaps 192.168.0.0/16: True
Он возвращает True, так как подсеть 192.168.1.1/24 находится под сетью 192.168.0.0/16.
Хорошо, мы закончили!