Дополнительные инструменты (tools)
This commit is contained in:
parent
8655285b21
commit
ff4dfae6c9
110
tools/subnet-calc.sh
Normal file
110
tools/subnet-calc.sh
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
#!/bin/bash
|
||||
# ============================================================
|
||||
# Калькулятор подсетей для экзамена 09.02.06 (python3 + ipaddress)
|
||||
#
|
||||
# ЗАПУСК:
|
||||
# bash tools/subnet-calc.sh <базовая_сеть> [имя=ЧИСЛО ...]
|
||||
#
|
||||
# ЧИСЛО — это АДРЕСА, а не хосты: считаются адрес сети и broadcast.
|
||||
# Если нужен именно объём ХОСТОВ — добавьте суффикс h, например:
|
||||
# srv=30 -> 30 адресов (включая сеть и broadcast)
|
||||
# srv=28h -> 28 хостов + 2 спецадреса = 30 адресов
|
||||
#
|
||||
# ПРИМЕР (адреса подбираются последовательно из базовой сети):
|
||||
# bash tools/subnet-calc.sh 10.0.0.0/24 hq_srv=32 hq_cli=16 mgmt=8 br_srv=16 br_link=2
|
||||
#
|
||||
# Для туннеля и линка BR-FW<->BR-RTR достаточно 2 адресов хостов:
|
||||
# link=2 -> маска /30 (4 адреса: сеть, 2 хоста, broadcast)
|
||||
#
|
||||
# Пример вывода готовой таблицы — просто скопировать в отчёт (таблица 2).
|
||||
# ============================================================
|
||||
|
||||
if ! command -v python3 >/dev/null 2>&1; then
|
||||
echo "Нужен python3. Установите: dnf install -y python3"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
python3 - "$@" <<'PY'
|
||||
import sys
|
||||
import ipaddress
|
||||
|
||||
|
||||
def usage_and_exit():
|
||||
print("Использование: subnet-calc.sh <базовая_сеть> [имя=число_адресов ...]")
|
||||
print("Суффикс h означает число ХОСТОВ (например srv=28h -> 28 хостов).")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def parse_size(value):
|
||||
value = value.strip().lower()
|
||||
hosts = value.endswith("h")
|
||||
if hosts:
|
||||
value = value[:-1]
|
||||
try:
|
||||
count = int(value)
|
||||
except ValueError:
|
||||
usage_and_exit()
|
||||
if count < 1:
|
||||
usage_and_exit()
|
||||
need = count + 2 if hosts else count
|
||||
return count, need
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 2:
|
||||
usage_and_exit()
|
||||
try:
|
||||
base = ipaddress.ip_network(sys.argv[1], strict=False)
|
||||
except ValueError:
|
||||
print("Некорректная базовая сеть:", sys.argv[1])
|
||||
usage_and_exit()
|
||||
|
||||
print("Базовая сеть:", base, "| всего адресов:", base.num_addresses)
|
||||
print()
|
||||
|
||||
cursor = int(base.network_address)
|
||||
last = int(base.broadcast_address)
|
||||
rows = []
|
||||
overflow = False
|
||||
|
||||
for item in sys.argv[2:]:
|
||||
name, sep, raw = item.partition("=")
|
||||
if not sep:
|
||||
print("Ошибка: параметр без '=' ->", item)
|
||||
usage_and_exit()
|
||||
count, need = parse_size(raw)
|
||||
prefix = base.max_prefixlen - (need - 1).bit_length()
|
||||
# Выравниваем начало подсети по границе новой маски
|
||||
step = 1 << (base.max_prefixlen - prefix)
|
||||
cursor = (cursor + step - 1) // step * step
|
||||
net = ipaddress.ip_network((cursor, prefix), strict=False)
|
||||
if int(net.broadcast_address) > last:
|
||||
overflow = True
|
||||
rows.append([
|
||||
name,
|
||||
str(net.network_address) + "/" + str(prefix),
|
||||
str(net.netmask),
|
||||
str(net.network_address + 1) if need > 2 else str(net.network_address),
|
||||
str(net.broadcast_address - 1) if need > 2 else str(net.broadcast_address),
|
||||
str(net.broadcast_address),
|
||||
str(net.num_addresses),
|
||||
])
|
||||
cursor = int(net.broadcast_address) + 1
|
||||
|
||||
if overflow:
|
||||
print("ВНИМАНИЕ: подсетей не хватило внутри базовой сети!")
|
||||
print()
|
||||
|
||||
headers = ["Назначение", "Сеть", "Маска", "Первый хост", "Последний хост",
|
||||
"Broadcast", "Адресов"]
|
||||
widths = [max(len(headers[i]), max(len(r[i]) for r in rows)) for i in range(len(headers))]
|
||||
|
||||
line = "-+-".join("-" * w for w in widths)
|
||||
print(" | ".join(h.ljust(w) for h, w in zip(headers, widths)))
|
||||
print(line)
|
||||
for row in rows:
|
||||
print(" | ".join(c.ljust(w) for c, w in zip(row, widths)))
|
||||
|
||||
|
||||
main()
|
||||
PY
|
||||
Loading…
Reference in a new issue