import re import xml.etree.ElementTree from haircontrol.data import * class Discovery: IPNEIGH = re.compile("(?P[a-f0-9:.]+) dev (?P.*) lladdr (?P[a-f0-9:]*)") IPLINKSHOW = re.compile("(?P\d+):\s+(?P[^:]*):.+\s+(?:link/ether\s+(?P[a-f0-9:]*)\s+brd|link/none)") def __init__(self, inspector): self.inspector = inspector self.net = EtherDomain() def discover_hinting_from_lldp(self, e_lldp): self.net.add_equipment(e_lldp) self.inspector.connect(e_lldp) # Learn local interfaces of e_lldp fd = self.inspector.command('ip-link') for line in fd: matches = Discovery.IPLINKSHOW.match(line) if matches: ifname, mac = [ matches.group(k) for k in ['ifname','mac'] ] e_lldp.ifaces[ifname] = Interface(ifname, mac) fd.close() # Create equipments and ifaces from LLDP neighbour discovery fd = self.inspector.command('lldp') root = xml.etree.ElementTree.parse(fd).getroot() for iface in root.iter('interface'): local_ifname = iface.get('name') local_mac = e_lldp.ifaces[local_ifname].mac chassis = iface.find('chassis') remote_name = chassis.find('name').text remote_ipmgmt = chassis.find('mgmt-ip').text e = Equipment(remote_name, remote_ipmgmt) self.net.add_equipment(e) for port in iface.findall('port'): remote_ifname = port.find('id').text e.add_seen_mac(remote_ifname, local_mac) fd.close() self.inspector.disconnect() def discover_from_root(self, e_root): self.net.add_equipment(e_root) self.inspector.connect(e_root) fd = self.inspector.command('ip-neigh') for line in fd: matches = Discovery.IPNEIGH.match(line) if matches: ip, ifname, mac = [ matches.group(k) for k in ['ip','ifname','mac'] ] self.net.index_mac_ip(mac, ip) e_root.add_seen_mac(ifname, mac) fd.close() self.inspector.disconnect()