import popen2 import new import sys import os import xml.dom.minidom # gegeven een adres en een netmask, geef het network en broadcast adres terug def decode_mask(addr, mask): m = ~((1 << (32 - mask)) - 1) network = addr & m broadcast = network + (1 << (32 - mask)) - 1 return (network, broadcast) # gegeven een adres en een netmask, wat zijn de niet-network en niet-broadcast # adressen daarin? def get_peer_addrs(addr, mask): print addr, mask (network, broadcast) = decode_mask(addr, mask) peers = range(network + 1, broadcast) print peers peers.remove(addr) return peers def tuple_of_addr(a): return ((a >> 24) & 0xff, (a >> 16) & 0xff, (a >> 8) & 0xff, a & 0xff) def showaddr(addr): return "%d.%d.%d.%d" % tuple_of_addr(addr) def showmask(mask): return showaddr(~((1 << (32 - mask)) - 1)) def parseaddr(s): f = s.split('.') return (long(f[0]) << 24L) + \ (long(f[1]) << 16L) + \ (long(f[2]) << 8L) + \ long(f[3]) def parse_wleiden_xml(fname): return xml.dom.minidom.parseString(open(sys.argv[1]).read()) def snarf_output(cmd): (cin, cout) = popen2.popen2(cmd) cout.close() return cin.read()[:-1] metainfo = None def gen_header(title): global metainfo if metainfo == None: hostname = snarf_output("hostname") whoami = snarf_output("whoami") date = snarf_output("date") metainfo = (date, whoami, hostname) return "# " + title + """ # # Generated on %s # by %s # on %s """ % metainfo def clear_header_cache(): global metainfo metainfo = None # dit is enigsinds zwarte magie. deze functie neemt een filenaam, en # geeft de XML hierarchie die in die file zit terug als een hierarchie # van objecten. die objecten zijn van classes die, zo nodig, dynamisch # gemaakt worden en er precies zo uitzien (en zo heten) als de XML # nodes die ze representeren. de attributen op de XML nodes worden # attributen in het object. def xml_to_obj_hierarchy(fname): dom = xml.dom.minidom.parseString(open(fname).read()) classes = {} def domnode_to_obj(node): if node.nodeType == node.TEXT_NODE: return node.nodeValue if not classes.has_key(node.nodeName): classes[node.nodeName] = new.classobj(node.nodeName.encode('latin-1'), (), {}) dict = {} if node.attributes != None: for i in range(node.attributes.length): a = node.attributes.item(i) dict[a.name] = a.value for c in node.childNodes: collectionname = c.nodeName + 's' if not dict.has_key(collectionname): dict[collectionname] = [] dict[collectionname].append(domnode_to_obj(c)) return new.instance(classes[node.nodeName], dict) return domnode_to_obj(dom.lastChild) # gegeven zo'n object hierarchy zoals gemaakt door xml_to_obj_hierarchy(), # van een file volgens nodes.dtd, patch het: # - voeg bij elke link instantie een attribuut 'peers' toe die wijst # naar de node(s) waar de link naartoe wijst # - vervang de iface attribuut, wat de naam van de interface is, # door een referentie naar het relevante object def ready_nodes_dtd_hierarchy(nodes): destdict = {} nodes.nodedict = {} def ensure_lists_exist(obj, lists): for list in lists: if not obj.__dict__.has_key(list): obj.__dict__[list] = [] for node in nodes.nodes: nodes.nodedict[node.name] = node for link in node.links: if link.type == 'interlink': destdict[parseaddr(link.ip)] = (node, link) for node in nodes.nodes: node.master_ip = parseaddr(node.master_ip) ifaces = {} ensure_lists_exist(node, ['wirelesss', 'ethernets']) for iface in node.wirelesss + node.ethernets: ifaces[iface.iface] = iface for link in node.links: link.ip = parseaddr(link.ip) ensure_lists_exist(link, ['dhcp_statics']) print node.name, link.iface link.iface = ifaces[link.iface] link.peers = [] if link.type == 'interlink': for p in get_peer_addrs(link.ip, int(link.mask)): if destdict.has_key(p): link.peers.append(destdict[p]) # is de gegeven instance van de class met de gegeven naam? def is_a(i, cn): return i.__class__.__name__ == cn # heeft de gegeven instance een attribuut met de gegeven naam? def has_attr(i, an): return i.__dict__.has_key(an) def findnode(nodes, nodename): nodename = nodename.upper() res = filter(lambda n: n.name.upper() == nodename, nodes.nodes) return res[0] def ensure_dir_exists(dir): components = dir.split('/') for i in range(1, len(components) + 1): try: os.mkdir('/'.join(components[0:i])) except: pass