initial release
This commit is contained in:
commit
1a2a19c7fa
1 changed files with 79 additions and 0 deletions
79
uniqcidr.py
Executable file
79
uniqcidr.py
Executable 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)
|
Loading…
Add table
Add a link
Reference in a new issue