initial release

This commit is contained in:
Ben Charlton 2025-01-06 23:13:46 +00:00
commit 1a2a19c7fa

79
uniqcidr.py Executable file
View file

@ -0,0 +1,79 @@
#!/usr/bin/env python3
import ipaddress
import sys
import argparse
# Default to /32 and /128 for single IP addresses
start_v4 = 32
start_v6 = 128
parser = argparse.ArgumentParser(
prog='uniqcidr',
description='Like uniq, but understands CIDR netmasks',
epilog='...but written by an idiot')
parser.add_argument('-c', '--count', action='store_true', help="count number of IPs occurring in each subnet")
parser.add_argument('-n', '--network', action='store_true', help="Enable network mode, don't require contiguous IP addresses. Sets /48 and /24 thresholds")
parser.add_argument('-6', '--v6netmask', type=int, help=f'IPv6 netmask, default: {start_v6}')
parser.add_argument('-4', '--v4netmask', type=int, help=f'IPv4 netmask, default: {start_v4}')
args = parser.parse_args()
# Network mode counts every /24 or /48
if args.network:
start_v4 = 24
start_v6 = 48
# Custom subnet thresholds. -6 64 is probably the othe most useful here.
if args.v6netmask:
start_v6 = args.v6netmask
if args.v4netmask:
start_v4 = args.v4netmask
def render_line(count, curr_network):
if args.count:
print(f"{count:>5} {curr_network}")
else:
print(curr_network)
curr_network = None
count = 0
for line in sys.stdin:
line = line.rstrip()
try:
ifa = ipaddress.ip_interface(line)
except ValueError:
print(f"Not an ip address: {line}", file=sys.stderr)
continue
prefix = start_v6
if ifa.version == 4:
prefix=start_v4
network = ifa.network.supernet(new_prefix=prefix)
if curr_network is None:
curr_network = network
continue
count = count + 1
if network.version != curr_network.version:
render_line(count, curr_network)
curr_network = network
count = 0
if curr_network != network:
if network.subnet_of(curr_network):
pass
elif network.subnet_of(curr_network.supernet()):
curr_network = curr_network.supernet()
else:
render_line(count, curr_network)
curr_network = network
count = 0
count = count + 1
render_line(count, curr_network)