from haircontrol.data import * from haircontrol.inspectors import * class Discovery: def __init__(self): #, inspector): # XXX Use only one Inspector self.linux_inspector = LinuxInspector() self.ubnt_inspector = UbntInspector() self.toughswitch_inspector = ToughSwitchInspector() self.net = EtherDomain() def discover_static_hinting(self, name_ip_tuples): for name, ip in name_ip_tuples: self.net.add_equipment(Equipment(name, ip)) def discover_lldp_hinting(self, e_lldp): self.net.add_equipment(e_lldp) self.linux_inspector.connect(e_lldp) # Learn local interfaces of e_lldp result = self.linux_inspector.command('ip-link') for (ifname, mac) in result: if ifname not in [ 'lo' ]: # XXX configurable filter e_lldp.add_iface(ifname, mac) # Create equipments and ifaces from LLDP neighbour discovery result = self.linux_inspector.command('lldpctl') for (local_ifname, local_mac, remote_name, remote_ipmgmt, ports) in result: e = Equipment(remote_name, remote_ipmgmt) self.net.add_equipment(e) # lldp returns logical port, not physicial port for remote bridges for remote_ifname in ports: if remote_ifname not in [ 'br0' ]: # XXX configurable filter e.add_seen_mac(remote_ifname, local_mac) self.linux_inspector.disconnect() def discover_from_root(self, e_root): self.net.add_equipment(e_root) self.linux_inspector.connect(e_root) # Learn root neighbours (directly or indirectly connected via trasparent bridges) result = self.linux_inspector.command('ip-neigh') for (ip, ifname, mac) in result: self.net.index_mac_ip(mac, ip) e_root.add_seen_mac(ifname, mac) self.linux_inspector.disconnect() # Create Equipment object for all neighbours (if not already previously done by hinting) for iface in e_root.ifaces.values(): local_ifname = iface.name local_mac = iface.mac for remote_mac in iface.mac_seen: remote_ip = self.net.mac2ip.get(remote_mac) if remote_ip: e = self.net.equipments.get(remote_ip) if not e: e = Equipment('?', remote_ip) e.add_iface('?', remote_mac) self.net.add_equipment(e) # Inspect all non-already inspected equipement done = False while not done: done = True for ip,e in self.net.equipments.items(): if not e.inspected: done = False # Inspect antennas bridge tables if ip.startswith('172.16.1'): # XXX Filter with OUI self.ubnt_inspector.connect(e) # Learn local interfaces result = self.ubnt_inspector.command('status.cgi') for (ifname, mac) in result: if ifname not in [ 'lo', 'wifi0', 'br0' ]: # XXX configurable filter e.add_iface(ifname, mac) # Learn bridge tables result = self.ubnt_inspector.command('brmacs.cgi') for (ifname, mac) in result: e.add_seen_mac(ifname, mac) self.ubnt_inspector.disconnect() # Inspect switches elif ip.startswith('172.16.3'): # XXX Filter with OUI self.toughswitch_inspector.connect(e) result = self.toughswitch_inspector.command('mactable_data.cgi') for (ifname, mac) in result: e.add_seen_mac(ifname, mac) self.toughswitch_inspector.disconnect() # Flag unknowns as inspected (and warn) else: e.inspected = 'cannot' print("Notice: Unimplemented inspector for %s"%e)