You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

59 lines
2.4 KiB

#!/bin/python
import ipaddress
import sys
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('-t', '--test', action='store_const', const=True, help='Тестовый режим')
parser.add_argument('-s', '--summask', type=int, help='Суммаризация по маске')
args = parser.parse_args()
def read_ips():
ip_cnt, _prefixes = 0, {}
for line in sys.stdin:
line, ip_cnt = line.strip('\n'), ip_cnt + 1
try:
if ipaddress.ip_network(line) or ipaddress.ip_address(line):
prefix = ipaddress.ip_network(line).network_address.compressed
_prefixlen = ipaddress.ip_network(line).prefixlen
if args.summask and _prefixlen > args.summask:
supernet = ipaddress.ip_network(prefix, _prefixlen).supernet(new_prefix=args.summask)
prefix = supernet.network_address.compressed
_prefixlen = supernet.prefixlen
_prefixes[prefix] = _prefixlen
except ValueError:
continue # bad subnet address
if args.test:
print('{} IP/Net -> stdin'.format(ip_cnt))
return _prefixes
def subnets_join(_prefixes, new_prefixlen):
new_prefixes = {}
for network_address, _prefixlen in _prefixes.items():
if _prefixlen == new_prefixlen + 1:
supernet = ipaddress.ip_network(network_address, _prefixlen).supernet(new_prefix=new_prefixlen)
new_network_address = supernet.network_address.compressed
subnets = list(supernet.subnets())
prefix_count = 0
for subnet in subnets:
if _prefixes.get(subnet.network_address.compressed) == subnet.prefixlen:
prefix_count += 1
if prefix_count > 1:
new_prefixes[new_network_address] = new_prefixlen
else:
new_prefixes[network_address] = _prefixlen
else:
new_prefixes[network_address] = _prefixlen
return new_prefixes
prefixes = read_ips()
maxprefixlen, start_cnt = 32, len(prefixes)
for prefixlen in range(maxprefixlen, 0, -1):
prefixes = subnets_join(prefixes, prefixlen)
if args.test:
print('/{} - {} - {}%'.format(prefixlen, len(prefixes), int(100 / start_cnt * len(prefixes))))
if not args.test:
[print('{}/{}'.format(pref, preflen)) for pref, preflen in prefixes.items()]