|
|
|
#!/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()]
|