-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathasroute2.py
128 lines (104 loc) · 4.45 KB
/
asroute2.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#!/usr/bin/env python3
import subprocess
import ipaddress
import sys
def fetch_routes(as_number):
"""Получение списка сетей через whois."""
try:
result = subprocess.run(
['whois', '-h', 'whois.radb.net', f' -i origin AS{as_number}'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True
)
if result.returncode != 0 or not result.stdout:
print(f"Ошибка выполнения whois: {result.stderr}")
return []
routes = []
for line in result.stdout.splitlines():
if line.lower().startswith("route:"):
network = line.split(":")[1].strip()
try:
routes.append(ipaddress.ip_network(network))
except ValueError:
print(f"Неверный формат сети: {network}")
return routes
except FileNotFoundError:
print("Команда whois не найдена. Убедитесь, что она установлена.")
return []
def merge_networks(networks, tolerance):
"""Итеративное объединение сетей с учетом допуска."""
networks = sorted(networks) # Сортируем сети
merged = networks[:]
while True:
new_merged = []
skip = set()
for i, net1 in enumerate(merged):
if i in skip:
continue
combined = False
for j, net2 in enumerate(merged[i + 1:], start=i + 1):
if j in skip:
continue
# Проверяем, можно ли объединить net1 и net2
supernet = net1.supernet(new_prefix=net1.prefixlen - 1)
if net2.subnet_of(supernet):
address_diff = abs(net2.num_addresses - net1.num_addresses)
if address_diff <= tolerance:
new_merged.append(supernet)
skip.update({i, j})
combined = True
break
if not combined:
new_merged.append(net1)
# Если после прохода ничего не изменилось, выходим
if len(new_merged) == len(merged):
break
merged = sorted(new_merged)
return merged
def filter_nested_networks(networks):
"""Удаляет сети, вложенные в более крупные."""
filtered = []
for net in networks:
if not any(net != other and net.subnet_of(other) for other in networks):
filtered.append(net)
return filtered
def print_usage():
"""Печатает инструкцию."""
usage_text = """
Инструкция:
Используйте скрипт для получения маршрутов автономной системы (AS) и их укрупнения.
Пример запуска:
asroute2 15169
asroute2 15169 --tolerance 8
Аргументы:
as_number Номер автономной системы (например, 15169).
--tolerance Допустимое количество пропущенных сетей для объединения (по умолчанию 0).
Example usage in English:
asroute2 15169
asroute2 15169 --tolerance 8
"""
print(usage_text)
def main():
import argparse
if len(sys.argv) == 1:
print_usage()
sys.exit(1)
parser = argparse.ArgumentParser(description="Получить сети для AS и укрупнить их.")
parser.add_argument("as_number", type=str, help="Номер автономной системы (AS).")
parser.add_argument(
"--tolerance", type=int, default=0,
help="Допустимое количество пропущенных сетей для объединения (по умолчанию 0)."
)
args = parser.parse_args()
print(f"Получение маршрутов для AS{args.as_number}...")
routes = fetch_routes(args.as_number)
if not routes:
print(f"Для AS{args.as_number} маршруты не найдены.")
return
print("Объединение сетей...")
merged_routes = merge_networks(routes, args.tolerance)
filtered_routes = filter_nested_networks(merged_routes)
print("Объединённые сети:")
for net in filtered_routes:
print(net)
if __name__ == "__main__":
main()