Работа с IP сетями средствами Python: от основ до продвинутых техник

Раздел: Сетевые технологии -> Сетевое программирование

Основы работы с IP сетями в Python

Работа с IP сетями в Python часто выполняется с помощью встроенного модуля ipaddress. Он предоставляет классы для представления IP адресов, сетей и интерфейсов, поддерживает IPv4 и IPv6, а также операции проверки вхождения, разбиения на подсети, объединения сетей и другие. Ниже рассмотрены различные подходы, от стандартного до альтернативных.

Использование модуля ipaddress (основной способ)

Модуль ipaddress входит в стандартную библиотеку Python (начиная с версии 3.3) и считается наиболее эффективным и безопасным решением.

import ipaddress

# создание сети
net = ipaddress.ip_network('192.168.1.0/24', strict=False)
print(net)  # 192.168.1.0/24

# проверка принадлежности адреса
ip = ipaddress.ip_address('192.168.1.10')
print(ip in net)  # True

# список всех адресов
for addr in net.hosts():
    print(addr)
    break  # первый адрес

Python client py (клиент на python)

192.168.1.0/24
True
192.168.1.1

Python socket (сокеты в python (socket))

Типичная ошибка: при strict=True модуль проверяет, что адрес сети является сетевым адресом (нулевой хост). Для произвольных сетей следует указывать strict=False, иначе возникнет ValueError.

ipaddress.ip_network('192.168.1.10/24', strict=True)  # ValueError

Python ipaddress ip network (модуль ipaddress в python)

Как проверить вхождение IP в подсеть без сторонних библиотек?

Вариант с использованием модуля socket и битовых масок. Полезно для понимания низкоуровневых операций.

import socket, struct

def ip_in_network(ip_str, net_str):
    ip = struct.unpack('!I', socket.inet_aton(ip_str))[0]
    net_addr, bits = net_str.split('/')
    net = struct.unpack('!I', socket.inet_aton(net_addr))[0]
    mask = (0xFFFFFFFF << (32 - int(bits))) & 0xFFFFFFFF
    return (ip & mask) == (net & mask)

print(ip_in_network('192.168.1.10', '192.168.1.0/24'))  # True

Python сети (сетевые возможности python)

True

Python network programming (сетевое программирование на python)

Проблемы: работает только с IPv4; требуется ручное преобразование; ошибка при неверном формате маски (ValueError в inet_aton). Не рекомендуется для сложных сетей.

Как работать с диапазонами и сортировкой IP адресов?

Использование библиотеки netaddr (устанавливается отдельно). Она предоставляет расширенные функции для работы с IP адресами, например, получение диапазона, сортировка, объединение смежных сетей.

from netaddr import IPNetwork, IPAddress

net = IPNetwork('10.0.0.0/24')
print(net.size)  # 256

# конвертация в диапазон
print(net.first, net.last)  # 167772160 167772415

# сортировка списка адресов
iplist = ['10.0.0.5', '10.0.0.2', '10.0.0.100']
sorted_ips = sorted(iplist, key=lambda x: IPAddress(x))
print(sorted_ips)

Ip network python (работа с ip-сетями в python)

256
167772160 167772415
['10.0.0.2', '10.0.0.5', '10.0.0.100']

Библиотека не входит в стандартную поставку, требует pip install netaddr. При работе с большими подсетями (IPv6) может потреблять много памяти.

Расширенные примеры работы с IP сетями

Приведены нестандартные сценарии, которые могут потребоваться при разработке средств мониторинга, VLAN конфигурации или анализа трафика.

1. Разбиение сети на подсети с заданным размером

Пример
import ipaddress

net = ipaddress.ip_network('10.0.0.0/24')
# разбить на 4 подсети по 64 адреса
subnets = list(net.subnets(new_prefix=26))
for sub in subnets:
    print(sub)
10.0.0.0/26
10.0.0.64/26
10.0.0.128/26
10.0.0.192/26

2. Поиск общих вышестоящих подсетей (supernet)

Пример
net1 = ipaddress.ip_network('192.168.1.0/25')
net2 = ipaddress.ip_network('192.168.1.128/25')
# объединение смежных сетей
if net1.overlaps(net2):
    supernet = net1.supernet(new_prefix=24)
    print(supernet)  # 192.168.1.0/24
192.168.1.0/24

3. Генерация случайного IP адреса внутри сети

Пример
import ipaddress, random

net = ipaddress.ip_network('10.0.0.0/28')
addr_list = list(net.hosts())  # исключаем broadcast и network
random_ip = random.choice(addr_list)
print(random_ip)  # например 10.0.0.5
10.0.0.5

4. Проверка пересечения двух IPv6 сетей

Пример
net1 = ipaddress.ip_network('2001:db8::/32')
net2 = ipaddress.ip_network('2001:db8:1000::/36')
print(net1.overlaps(net2))  # True, т.к. 2001:db8:1000:: входит в 2001:db8::/32
True

5. Конвертация IP адреса в двоичный вид и обратно

Пример
import ipaddress

def ip_to_bin(ip_str):
    ip = ipaddress.ip_address(ip_str)
    return bin(int(ip))

bin_form = ip_to_bin('192.168.1.1')
print(bin_form)
# восстановление
dec_form = int(bin_form, 2)
print(ipaddress.ip_address(dec_form))
0b11000000101010000000000100000001
192.168.1.1

Работа с IP-сетями в Python - comments

En
Ip network python (python)