Подсети и маски: расчёт на Python
Учимся считать подсети: маску, адрес сети, broadcast, диапазон и число хостов — с живыми примерами на Python.
Маска подсети — это набор бит, который отделяет в адресе часть «сеть» от части «хост». В CIDR её задаёт префикс
/N.
Из чего состоит подсеть
В любой подсети есть несколько особых адресов:
- Адрес сети — первый адрес (все биты хоста = 0). Идентифицирует саму подсеть.
- Broadcast — последний адрес (все биты хоста = 1). Пакет на него уходит всем в подсети.
- Адреса хостов — всё между ними. Именно их можно назначать устройствам.
Поэтому полезных адресов всегда на два меньше, чем всего: первый и последний зарезервированы. Для /26 всего 64 адреса, но хостов — 62.
Считаем подсеть на Python
Вместо ручного перевода в двоичную систему используем стандартный модуль ipaddress — он есть в Python из коробки и работает в браузере. Возьмём сеть 192.168.10.0/26:
import ipaddress
net = ipaddress.ip_network('192.168.10.0/26')
print('Сеть: ', net)
print('Маска: ', net.netmask)
print('Префикс: ', '/' + str(net.prefixlen))
print('Адрес сети: ', net.network_address)
print('Broadcast: ', net.broadcast_address)
print('Всего адресов: ', net.num_addresses)
print('Доступно хостов:', net.num_addresses - 2)
hosts = list(net.hosts())
print('Первый хост: ', hosts[0])
print('Последний хост: ', hosts[-1])
Вывод:
Сеть: 192.168.10.0/26 Маска: 255.255.255.192 Префикс: /26 Адрес сети: 192.168.10.0 Broadcast: 192.168.10.63 Всего адресов: 64 Доступно хостов: 62 Первый хост: 192.168.10.1 Последний хост: 192.168.10.62
Маска /26 в десятичной форме — 255.255.255.192: 26 единиц, потом 6 нулей. Диапазон хостов 192.168.10.1 – 192.168.10.62.
Шпаргалка по префиксам
| Префикс | Маска | Всего адресов | Хостов |
| /24 | 255.255.255.0 | 256 | 254 |
| /25 | 255.255.255.128 | 128 | 126 |
| /26 | 255.255.255.192 | 64 | 62 |
| /27 | 255.255.255.224 | 32 | 30 |
| /30 | 255.255.255.252 | 4 | 2 |
Правило: при каждом увеличении префикса на 1 число адресов делится пополам.
Деление сети на подсети
Частая задача: разбить сеть на несколько равных подсетей. Делим 10.0.0.0/24 на четыре /26:
import ipaddress
base = ipaddress.ip_network('10.0.0.0/24')
print('Делим', base, 'на подсети /26:')
for sub in base.subnets(new_prefix=26):
h = list(sub.hosts())
print(f' {sub} хосты {h[0]} - {h[-1]}')
Вывод:
Делим 10.0.0.0/24 на подсети /26: 10.0.0.0/26 хосты 10.0.0.1 - 10.0.0.62 10.0.0.64/26 хосты 10.0.0.65 - 10.0.0.126 10.0.0.128/26 хосты 10.0.0.129 - 10.0.0.190 10.0.0.192/26 хосты 10.0.0.193 - 10.0.0.254
Проверка: входит ли адрес в сеть
Ещё одна типовая задача — понять, принадлежит ли IP заданной сети (так работают firewall-правила):
import ipaddress
net = ipaddress.ip_network('172.16.0.0/16')
print('Проверяем адреса в сети', net)
for ip in ['172.16.5.9', '172.17.0.1', '192.168.0.1']:
addr = ipaddress.ip_address(ip)
print(f' {ip:14} -> {"да" if addr in net else "нет"}')
Вывод:
Проверяем адреса в сети 172.16.0.0/16 172.16.5.9 -> да 172.17.0.1 -> нет 192.168.0.1 -> нет
Итог
- В подсети первый адрес — сеть, последний — broadcast; хостов на 2 меньше.
- Модуль
ipaddressсчитает маску, диапазон и число хостов за вас. .subnets(new_prefix=N)делит сеть на равные подсети.- Оператор
inпроверяет принадлежность адреса сети.