#!/usr/bin/env python3 # # Zoek de eerste vrije (== niet in een wleiden.conf gedefinieerde) interlink # range. # # Maybe this should use the py-iplib module? # # Orignal: lodewijk@wirelessleiden.nl # 07/March/2012 - Rick van der Zwet # import gformat import glob import re import sys import textwrap def parseaddr(s): f = s.split('.') return (int(f[0]) << 24) + \ (int(f[1]) << 16) + \ (int(f[2]) << 8) + \ (int(f[3])) def showaddr(a): return "%d.%d.%d.%d" % ((a >> 24) & 0xff, (a >> 16) & 0xff, (a >> 8) & 0xff, a & 0xff) bezet_cache = None def make_cache(): global bezet_cache bezet = {} substs = {} def add_ip(address): if '/' not in address: address += "/32" addr, mask = address.split('/') if addr in substs: addr = substs[addr] try: addr = parseaddr(addr) mask = int(mask) addr = addr & ~((1 << (32 - mask)) - 1) for i in range(0, (1 << (32 - mask))): bezet[addr + i] = 1 except ValueError as e: print("[FOUT] in address %s node %s" % (address, node)) for node in gformat.get_hostlist(): datadump = gformat.get_yaml(node) add_ip(datadump['masterip']) for key in datadump['autogen_iface_keys']: if 'ip' in datadump[key]: add_ip(datadump[key]['ip']) # Fetching smallest in use IP # XXX: Currently not used for anything i = parseaddr("255.255.255.255") for k in bezet.keys(): if k < i: i = k bezet_cache = bezet return bezet def get_ranges(interlink, size, aantal, use_history=False): global bezet_cache numaddrs = 1 << (32 - size) if not use_history or (use_history and not bezet_cache): bezet = make_cache() else: bezet = bezet_cache # Interlinks are living in special ranges usually if interlink: i = parseaddr("172.16.3.0") else: i = parseaddr("172.17.0.0") ranges = [] for n in range(aantal): okay = False while not okay: while i in bezet: i = i + numaddrs # Assume Ok, till we find a already used IP okay = True for j in range(numaddrs): if (i + j) in bezet: i = i + numaddrs okay = False break ranges.append(i) bezet[i] = 1 bezet_cache = bezet return ranges def main(): if len(sys.argv) < 2: print(textwrap.dedent(''' Gebruik: %(prog)s [aantal] Voorbeelden: Voor drie /29 interlinks - '%(prog)s interlink 29 3' Voor een (1) /24 subnet - '%(prog)s subnet 24' ''' % { 'prog': sys.argv[0] })) exit(1) # Argument parsing interlink = sys.argv[1] == 'interlink' size = int(sys.argv[2]) try: aantal = int(sys.argv[3]) except (KeyError,IndexError): aantal = 1 ranges = get_ranges(interlink, size, aantal) numaddrs = 1 << (32 - size) for i in ranges: print("%s/%d: " % (showaddr(i), size), end='') if size > 28: print(" en ".join([showaddr(i) for i in range(i + 1, i + numaddrs - 1)])) else: print(" en ".join([showaddr(i) for i in range(i + 1, i + 4)]), end='') print("...", end='') print(" en ".join([showaddr(i) for i in range(i + numaddrs - 7, i + numaddrs - 4)])) if __name__ == "__main__": main()