def execute_cli(self, **kwargs): r = [] try: lldp = self.cli("show lldp neighbors") except self.CLISyntaxError: raise NotImplementedError for block in lldp.split("\n\n"): neighbors = [] if not block: continue n = parse_kv(self.lldp_map, block) loca_iface = n.pop("local_interface") if is_mac(n["remote_chassis_id"]): n["remote_chassis_id_subtype"] = LLDP_CHASSIS_SUBTYPE_MAC else: n["remote_chassis_id_subtype"] = LLDP_CHASSIS_SUBTYPE_LOCAL if is_mac(n["remote_port"]): n["remote_port_subtype"] = LLDP_PORT_SUBTYPE_MAC else: n["remote_port_subtype"] = LLDP_PORT_SUBTYPE_LOCAL neighbors += [n] if neighbors: r += [{"local_interface": loca_iface, "neighbors": neighbors}] return r
def execute_cli(self): r = [] v = self.cli("show lldp neighbors") for match in self.rx_local_port.finditer(v): local_interface = match.group("port") c = self.cli("show lldp neighbors interface %s" % local_interface) match1 = self.rx_remote.search(c) chassis_id = match1.group("chassis_id") if is_ipv4(chassis_id) or is_ipv6(chassis_id): chassis_id_subtype = LLDP_CHASSIS_SUBTYPE_NETWORK_ADDRESS elif is_mac(chassis_id): chassis_id_subtype = LLDP_CHASSIS_SUBTYPE_MAC else: chassis_id_subtype = LLDP_CHASSIS_SUBTYPE_LOCAL port_id = match1.group("port_id") if is_ipv4(port_id) or is_ipv6(port_id): port_id_subtype = LLDP_PORT_SUBTYPE_NETWORK_ADDRESS elif is_mac(port_id): port_id_subtype = LLDP_PORT_SUBTYPE_MAC else: port_id_subtype = LLDP_PORT_SUBTYPE_LOCAL neighbor = { "remote_chassis_id_subtype": chassis_id_subtype, "remote_chassis_id": chassis_id, "remote_port_subtype": port_id_subtype, "remote_port": port_id, } port_descr = match1.group("port_descr").strip() if port_descr and "-- not advertised" not in port_descr: neighbor["remote_port_description"] = port_descr r += [{ "local_interface": local_interface, "neighbors": [neighbor] }] return r
def execute(self): r = [] try: v = self.cli("show lldp neighbors") # This is strange behavior, but it helps us v = self.blank_line.sub("", v) except self.CLISyntaxError: raise self.NotSupportedError() t = parse_table(v, allow_wrap=True, allow_extend=True) for i in t: chassis_id = i[1] if is_ipv4(chassis_id) or is_ipv6(chassis_id): chassis_id_subtype = 5 elif is_mac(chassis_id): chassis_id_subtype = 4 else: chassis_id_subtype = 7 port_id = i[2] if is_ipv4(port_id) or is_ipv6(port_id): port_id_subtype = 4 elif is_mac(port_id): port_id_subtype = 3 else: port_id_subtype = 7 caps = 0 for c in i[4].split(","): c = c.strip() if c: caps |= { "O": 1, "P": 2, "B": 4, "W": 8, "R": 16, "T": 32, "C": 64, "S": 128 }[c] neighbor = { "remote_chassis_id": chassis_id, "remote_chassis_id_subtype": chassis_id_subtype, "remote_port": port_id, "remote_port_subtype": port_id_subtype, "remote_capabilities": caps, } if i[3]: neighbor["remote_system_name"] = i[3] s = self.cli("show lldp neighbors ethernet %s" % i[0]) match = self.rx_sysdescr.search(s) if match: neighbor["remote_system_description"] = match.group( "descr").strip() match = self.rx_portdescr.search(s) if match: neighbor["remote_port_description"] = match.group( "descr").strip() r += [{"local_interface": i[0], "neighbors": [neighbor]}] return r
def execute_cli(self): r = [] t = parse_table(self.cli("show lldp neighbor"), allow_wrap=True) for i in t: c = self.cli("show lldp neighbor %s" % i[0]) match = self.rx_neighbor.search(c) chassis_id = match.group("chassis_id") if is_ipv4(chassis_id) or is_ipv6(chassis_id): chassis_id_subtype = LLDP_CHASSIS_SUBTYPE_NETWORK_ADDRESS elif is_mac(chassis_id): chassis_id_subtype = LLDP_CHASSIS_SUBTYPE_MAC else: chassis_id_subtype = LLDP_CHASSIS_SUBTYPE_LOCAL port_id = match.group("port_id") if is_ipv4(port_id) or is_ipv6(port_id): port_id_subtype = LLDP_PORT_SUBTYPE_NETWORK_ADDRESS elif is_mac(port_id): port_id_subtype = LLDP_PORT_SUBTYPE_MAC else: port_id_subtype = LLDP_PORT_SUBTYPE_LOCAL neighbor = { "remote_chassis_id": chassis_id, "remote_chassis_id_subtype": chassis_id_subtype, "remote_port": port_id, "remote_port_subtype": port_id_subtype, } if match.group("port_descr"): port_descr = match.group("port_descr").strip() if port_descr: neighbor["remote_port_description"] = port_descr if match.group("system_name"): system_name = match.group("system_name").strip() if system_name: neighbor["remote_system_name"] = system_name if match.group("system_descr"): system_descr = match.group("system_descr").strip() if system_descr: neighbor["remote_system_description"] = system_descr caps = 0 match = self.rx_caps.search(c) if match: caps = lldp_caps_to_bits( match.group("caps").strip().split(","), { "other": LLDP_CAP_OTHER, "repeater": LLDP_CAP_REPEATER, "bridge": LLDP_CAP_BRIDGE, "access point": LLDP_CAP_WLAN_ACCESS_POINT, "router": LLDP_CAP_ROUTER, "telephone": LLDP_CAP_TELEPHONE, "cable device": LLDP_CAP_DOCSIS_CABLE_DEVICE, "station only": LLDP_CAP_STATION_ONLY, }, ) neighbor["remote_capabilities"] = caps r += [{"local_interface": i[0], "neighbors": [neighbor]}] return r
def execute_l(self, res): r = [] for line in res.splitlines(): match = self.rx_search.search(line) if not match: continue iface = self.cli("show lldp neighbors interface %s" % match.group("iface")) iface_match = self.rx_port2.search(iface) chassis_id = iface_match.group("device_id") if is_ipv4(chassis_id) or is_ipv6(chassis_id): chassis_id_subtype = 5 elif is_mac(chassis_id): chassis_id_subtype = 4 else: chassis_id_subtype = 7 port_id = iface_match.group("port_id") if is_ipv4(port_id) or is_ipv6(port_id): port_id_subtype = 4 elif is_mac(port_id): port_id_subtype = 3 else: port_id_subtype = 7 caps = 0 for c in iface_match.group("capabilities").split(): c = c.strip() if c: caps |= self.data[c] neighbor = { "remote_chassis_id": chassis_id, "remote_chassis_id_subtype": chassis_id_subtype, "remote_port": port_id, "remote_port_subtype": port_id_subtype, "remote_capabilities": caps, } if iface_match.group("system_name"): neighbor["remote_system_name"] = iface_match.group( "system_name") if iface_match.group("system_description"): neighbor["remote_system_description"] = iface_match.group( "system_description").strip() if iface_match.group("port_description"): neighbor["remote_port_description"] = iface_match.group( "port_description").strip() r += [{ "local_interface": match.group("iface"), "neighbors": [neighbor] }] return r
def execute(self): r = [] try: v = self.cli("show lldp info") except self.CLISyntaxError: raise self.NotSupportedError() for match in self.rx_line.finditer(v): chassis_id = match.group("chassis_id") if is_ipv4(chassis_id) or is_ipv6(chassis_id): chassis_id_subtype = 5 elif is_mac(chassis_id): chassis_id_subtype = 4 else: chassis_id_subtype = 7 port_id = match.group("port_id") if is_ipv4(port_id) or is_ipv6(port_id): port_id_subtype = 4 elif is_mac(port_id): port_id_subtype = 3 else: port_id_subtype = 7 caps = 0 # Need more examples if "Bridge" in match.group("caps"): caps += 4 if "Router" in match.group("caps"): caps += 16 neighbor = { "remote_chassis_id": chassis_id, "remote_chassis_id_subtype": chassis_id_subtype, "remote_port": port_id, "remote_port_subtype": port_id_subtype, "remote_capabilities": caps, } if match.group("system_name"): neighbor["remote_system_name"] = match.group( "system_name").strip() if match.group("system_description"): neighbor["remote_system_description"] = match.group( "system_description").strip() if match.group("port_description"): neighbor["remote_port_description"] = match.group( "port_description").strip() r += [{ "local_interface": match.group("port"), "neighbors": [neighbor] }] return r
def execute_snmp( self, interface=None, enable_ifindex=False, enable_interface_mac=False, enable_admin_status=False, enable_oper_status=False, ): iter_tables = [] ifindex = None if interface: ifindex = self.get_interface_ifindex(interface) iter_tables += [self.iter_interface_ifindex(interface, ifindex)] else: iter_tables += [ self.iter_iftable("name", mib[self.SNMP_NAME_TABLE]) ] if enable_interface_mac: iter_tables += [ self.iter_iftable("mac", mib[self.SNMP_MAC_TABLE], ifindex=ifindex) ] if enable_admin_status: iter_tables += [ self.iter_iftable( "admin_status", mib[self.SNMP_ADMIN_STATUS_TABLE], ifindex=ifindex, clean=self.clean_status, ) ] if enable_oper_status: iter_tables += [ self.iter_iftable( "oper_status", mib[self.SNMP_OPER_STATUS_TABLE], ifindex=ifindex, clean=self.clean_status, ) ] # Collect and merge results data = self.merge_tables(*tuple(iter_tables)) # Format result result = [] for ifindex in sorted(data): v = data[ifindex] if "name" not in v: continue item = {"interface": v["name"]} if enable_ifindex and "ifindex" in v: item["ifindex"] = v["ifindex"] if enable_interface_mac and "mac" in v and is_mac(v["mac"]): item["mac"] = v["mac"] if enable_admin_status and "admin_status" in v: item["admin_status"] = v["admin_status"] if enable_oper_status and "oper_status" in v: item["oper_status"] = v["oper_status"] result += [item] return result
def execute_cli(self): r = [] try: v = self.cli("show lldp neighbors") except self.CLISyntaxError: raise self.NotSupportedError() for match in self.rx_line.finditer(v): chassis_id = match.group("chassis_id") if is_ipv4(chassis_id) or is_ipv6(chassis_id): chassis_id_subtype = LLDP_CHASSIS_SUBTYPE_NETWORK_ADDRESS elif is_mac(chassis_id): chassis_id_subtype = LLDP_CHASSIS_SUBTYPE_MAC else: chassis_id_subtype = LLDP_CHASSIS_SUBTYPE_LOCAL port_id = match.group("port_id") if is_ipv4(port_id) or is_ipv6(port_id): port_id_subtype = LLDP_PORT_SUBTYPE_NETWORK_ADDRESS elif is_mac(port_id): port_id_subtype = LLDP_PORT_SUBTYPE_MAC else: port_id_subtype = LLDP_PORT_SUBTYPE_LOCAL caps = 0 # Need more examples if "Bridge" in match.group("caps"): caps += LLDP_CAP_BRIDGE neighbor = { "remote_chassis_id": chassis_id, "remote_chassis_id_subtype": chassis_id_subtype, "remote_port": port_id, "remote_port_subtype": port_id_subtype, "remote_capabilities": caps, } if match.group("system_name"): neighbor["remote_system_name"] = match.group( "system_name").strip() if match.group("system_description"): neighbor["remote_system_description"] = match.group( "system_description").strip() if match.group("port_description"): neighbor["remote_port_description"] = match.group( "port_description").strip() r += [{ "local_interface": match.group("port"), "neighbors": [neighbor] }] return r
def execute_n(self, res): r = [] t = parse_table(res, allow_wrap=True) for i in t: chassis_id = i[1] if is_ipv4(chassis_id) or is_ipv6(chassis_id): chassis_id_subtype = 5 elif is_mac(chassis_id): chassis_id_subtype = 4 else: chassis_id_subtype = 7 port_id = i[2] if is_ipv4(port_id) or is_ipv6(port_id): port_id_subtype = 4 elif is_mac(port_id): port_id_subtype = 3 else: port_id_subtype = 7 caps = 0 for c in i[4].split(","): c = c.strip() if c: caps |= self.data[c] neighbor = { "remote_chassis_id": chassis_id, "remote_chassis_id_subtype": chassis_id_subtype, "remote_port": port_id, "remote_port_subtype": port_id_subtype, "remote_capabilities": caps, } if i[3]: neighbor["remote_system_name"] = i[3] try: v = self.cli("show lldp neighbors %s" % i[0]) match = self.rx_port.search(v) except self.CLISyntaxError: pass if match: neighbor["remote_system_description"] = match.group( "system_description").strip() neighbor["remote_port_description"] = match.group( "port_description").strip() r += [{"local_interface": i[0], "neighbors": [neighbor]}] return r
def get_neighbor(self, n): nn = self.get_neighbor_by_hostname(n) if nn: return nn if is_ipv4(n): return self.get_neighbor_by_ip(n) elif is_mac(n): return self.get_neighbor_by_mac(n) else: return None
def execute(self): r = [] try: v = self.cli("show lldp-remote") except self.CLISyntaxError: raise self.NotSupportedError() for section in v.split("\n\n"): if not section.strip(): continue name, cfg = self.parse_section(section) # Hack. We use port_id for chassis_id if "port-id" not in cfg: r += [{"local_interface": name, "neighbors": []}] return r remote_chassis_id = cfg["chassis-id"] remote_chassis_type = self.CHASSIS_TYPES[cfg["chassis-id-subtype"]] if cfg["chassis-id-subtype"] == "network-addr" and is_mac( cfg["port-id"]): # Network address is default 192.168.0.1 remote_chassis_id = cfg["port-id"] remote_chassis_type = LLDP_CHASSIS_SUBTYPE_MAC neighbor = { "remote_chassis_id": remote_chassis_id, "remote_chassis_id_subtype": remote_chassis_type, "remote_port": cfg["port-id"], "remote_port_subtype": self.PORT_TYPES[cfg["port-id-subtype"]], } if "port-descr" in cfg: neighbor["remote_port_description"] = cfg["port-descr"] if "sys-name" in cfg: neighbor["remote_system_name"] = cfg["sys-name"] if "sys-descr" in cfg: neighbor["remote_system_description"] = cfg["sys-descr"] found = False for i in r: if i["local_interface"] == name: i["neighbors"] += [neighbor] found = True break if not found: r += [{"local_interface": name, "neighbors": [neighbor]}] return r
def execute_cli(self): match = self.rx_mac.search(self.scripts.get_switch()) mac = match.group("id") macs = [] try: v = self.cli("show fdb static", cached=True) macs = self.rx_line.findall(v) if macs: found = False for m in macs: if m == mac: found = True break if not found: macs += [mac] except self.CLISyntaxError: pass try: v = self.cli("show stack_information", cached=True) for i in parse_table(v): if not i[5] or not is_mac(i[5]): continue found = False for m in macs: if m == i[5]: found = True break if not found: macs += [i[5]] except self.CLISyntaxError: pass if macs: macs.sort() return [{ "first_chassis_mac": f, "last_chassis_mac": t } for f, t in self.macs_to_ranges(macs)] return {"first_chassis_mac": mac, "last_chassis_mac": mac}
def execute(self): r = [] # Try SNMP first """ # SNMP not working if self.has_snmp(): try: # lldpRemLocalPortNum # lldpRemChassisIdSubtype lldpRemChassisId # lldpRemPortIdSubtype lldpRemPortId # lldpRemSysName lldpRemSysCapEnabled for v in self.snmp.get_tables( ["1.0.8802.1.1.2.1.4.1.1.2", "1.0.8802.1.1.2.1.4.1.1.4", "1.0.8802.1.1.2.1.4.1.1.5", "1.0.8802.1.1.2.1.4.1.1.6", "1.0.8802.1.1.2.1.4.1.1.7", "1.0.8802.1.1.2.1.4.1.1.9", "1.0.8802.1.1.2.1.4.1.1.12" ], bulk=True): local_interface = self.snmp.get( "1.3.6.1.2.1.31.1.1.1.1." + v[1], cached=True) remote_chassis_id_subtype = v[2] remotechassisid = ":".join(["%02x" % ord(c) for c in v[3]]) remote_port_subtype = v[4] if remote_port_subtype == 7: remote_port_subtype = 5 remote_port = v[5] remote_system_name = v[6] remote_capabilities = v[7] i = {"local_interface": local_interface, "neighbors": []} n = { "remote_chassis_id_subtype": remote_chassis_id_subtype, "remote_chassis_id": remotechassisid, "remote_port_subtype": remote_port_subtype, "remote_port": remote_port, "remote_capabilities": remote_capabilities, } if remote_system_name: n["remote_system_name"] = remote_system_name i["neighbors"].append(n) r.append(i) return r except self.snmp.TimeOutError: pass """ # Fallback to CLI try: lldp = self.cli("show lldp interface") except self.CLISyntaxError: raise self.NotSupportedError() for match in self.rx_line.finditer(lldp): local_interface = match.group("interface") remote_chassis_id = match.group("chassis_id") remote_port = match.group("port_id") remote_system_name = match.group("name") system_description = match.group("system_description") port_description = match.group("port_description") # Build neighbor data # Get capability cap = 0 """ for c in match.group("capabilities").split(","): if cap: c = c.strip() if c: cap |= { "O": 1, "r": 2, "B": 4, "W": 8, "R": 16, "T": 32, "C": 64, "S": 128, "D": 256, "H": 512, "TP": 1024, }[c] """ # Get remote port subtype remote_port_subtype = 5 if is_ipv4(remote_port): # Actually networkAddress(4) remote_port_subtype = 4 elif is_mac(remote_port): # Actually macAddress(3) remote_port_subtype = 3 elif is_int(remote_port): # Actually local(7) remote_port_subtype = 7 i = {"local_interface": local_interface, "neighbors": []} n = { "remote_chassis_id": remote_chassis_id, "remote_port": remote_port, "remote_capabilities": cap, "remote_port_subtype": remote_port_subtype, } if remote_system_name and remote_system_name != "NULL": n["remote_system_name"] = remote_system_name if system_description and system_description != "NULL": n["remote_system_description"] = system_description if port_description and port_description != "NULL": n["remote_port_description"] = port_description # TODO: # n["remote_chassis_id_subtype"] = 4 i["neighbors"].append(n) r.append(i) return r
def execute_cli(self): r = [] try: v = self.cli("show lldp neighbors") except self.CLISyntaxError: raise self.NotSupportedError() t = parse_table(v, allow_wrap=True) for i in t: chassis_id = i[1] if is_ipv4(chassis_id) or is_ipv6(chassis_id): chassis_id_subtype = 5 elif is_mac(chassis_id): chassis_id_subtype = 4 else: chassis_id_subtype = 7 port_id = i[2] if is_ipv4(port_id) or is_ipv6(port_id): port_id_subtype = 4 elif is_mac(port_id): port_id_subtype = 3 else: port_id_subtype = 7 caps = 0 for c in i[4].split(","): c = c.strip() if c and c != "not": caps |= { "O": 1, "P": 2, "B": 4, "W": 8, "R": 16, "r": 16, "T": 32, "C": 64, "S": 128, }[c] """ if "O" in i[4]: caps += 1 elif "r" in i[4]: caps += 2 elif "B" in i[4]: caps += 4 elif "W" in i[4]: caps += 8 elif "R" in i[4]: caps += 16 elif "T" in i[4]: caps += 32 elif "D" in i[4]: caps += 64 elif "H" in i[4]: caps += 128 """ neighbor = { "remote_chassis_id": chassis_id, "remote_chassis_id_subtype": chassis_id_subtype, "remote_port": port_id, "remote_port_subtype": port_id_subtype, "remote_capabilities": caps, } if i[3]: neighbor["remote_system_name"] = i[3] r += [{"local_interface": i[0], "neighbors": [neighbor]}] if not t: for iface in self.scripts.get_interface_status(): c = self.cli("show lldp neighbors interface %s" % iface["interface"], ignore_errors=True) c = c.replace("\n\n", "\n") neighbors = [] for match in self.rx_neighbor.finditer(c): chassis_id = match.group("chassis_id") if is_ipv4(chassis_id) or is_ipv6(chassis_id): chassis_id_subtype = 5 elif is_mac(chassis_id): chassis_id_subtype = 4 else: chassis_id_subtype = 7 port_id = match.group("port_id") if is_ipv4(port_id) or is_ipv6(port_id): port_id_subtype = 4 elif is_mac(port_id): port_id_subtype = 3 else: port_id_subtype = 7 caps = 0 if match.group("caps").strip(): for c in match.group("caps").split(): c = c.strip() if c in {"not", "advertised"}: # not caps break if c and (c != "--"): caps |= { "O": 1, "P": 2, "B": 4, "W": 8, "R": 16, "r": 16, "T": 32, "C": 64, "S": 128, }[c] neighbor = { "remote_chassis_id": chassis_id, "remote_chassis_id_subtype": chassis_id_subtype, "remote_port": port_id, "remote_port_subtype": port_id_subtype, "remote_capabilities": caps, } port_descr = match.group("port_descr").strip() system_name = match.group("system_name").strip() system_descr = match.group("system_descr").strip() if bool(port_descr): neighbor["remote_port_description"] = port_descr if bool(system_name): neighbor["remote_system_name"] = system_name if bool(system_descr): neighbor["remote_system_description"] = system_descr neighbors += [neighbor] if neighbors: r += [{ "local_interface": iface["interface"], "neighbors": neighbors }] return r
def execute_cli(self): r = [] try: v = self.cli("show lldp neighbors") except self.CLISyntaxError: raise self.NotSupportedError() t = parse_table(v, allow_wrap=True) for i in t: local_if = i[0] v = self.cli("show lldp neighbors %s" % local_if) match = self.rx_neighbor.search(v) remote_chassis_id = match.group("remote_chassis_id") if is_ipv4(remote_chassis_id) or is_ipv6(remote_chassis_id): # Actually networkAddress(4) remote_chassis_id_subtype = 5 elif is_mac(remote_chassis_id): # Actually macAddress(3) # Convert MAC to common form remote_chassis_id_subtype = 4 else: remote_chassis_id_subtype = 7 remote_port = match.group("remote_port") if is_ipv4(remote_port) or is_ipv6(remote_port): # Actually networkAddress(4) remote_port_subtype = 4 elif is_mac(remote_port): # Actually macAddress(3) remote_port_subtype = 3 elif is_int(remote_port): # Actually local(7) remote_port_subtype = 7 else: remote_port_subtype = 5 # Get capability cap = 0 s = match.group("caps") for c in s.strip().split(", "): cap |= { "Other": 1, "Repeater": 2, "Bridge": 4, "WLAN": 8, "Router": 16, "Telephone": 32, "Cable": 64, "Station": 128, }[c] n = { "remote_chassis_id": remote_chassis_id, "remote_chassis_id_subtype": remote_chassis_id_subtype, "remote_port": remote_port, "remote_port_subtype": remote_port_subtype, "remote_capabilities": cap, } match = self.rx_system_name.search(v) if match and match.group("system_name"): n["remote_system_name"] = match.group("system_name") match = self.rx_port_descr.search(v) if match and match.group("port_descr"): n["remote_port_description"] = match.group("port_descr") i = {"local_interface": local_if, "neighbors": [n]} r += [i] return r
def execute_cli(self): r = defaultdict(list) # local_iface -> neighbors try: lldp = self.cli("show lldp neighbors") except self.CLISyntaxError: raise self.NotSupportedError() for match in self.rx_lldp_nei.finditer(lldp): local_interface = match.group("interface") remote_chassis_id = match.group("chassis_id") remote_port = match.group("port_id") # Build neighbor data # Get capability cap = 4 # Get remote port subtype remote_port_subtype = LLDP_PORT_SUBTYPE_NAME if is_ipv4(remote_port): # Actually networkAddress(4) remote_port_subtype = LLDP_PORT_SUBTYPE_NETWORK_ADDRESS elif is_mac(remote_port): # Actually macAddress(3) # Convert MAC to common form remote_port = MACAddressParameter().clean(remote_port) remote_port_subtype = LLDP_PORT_SUBTYPE_MAC elif is_int(remote_port): # Actually local(7) remote_port_subtype = LLDP_PORT_SUBTYPE_LOCAL n = { "remote_chassis_id": remote_chassis_id, "remote_port": remote_port, "remote_capabilities": cap, "remote_port_subtype": remote_port_subtype, } if is_ipv4(n["remote_chassis_id"]) or is_ipv6( n["remote_chassis_id"]): n["remote_chassis_id_subtype"] = LLDP_CHASSIS_SUBTYPE_NETWORK_ADDRESS elif is_mac(n["remote_chassis_id"]): n["remote_chassis_id_subtype"] = LLDP_CHASSIS_SUBTYPE_MAC else: n["remote_chassis_id_subtype"] = LLDP_CHASSIS_SUBTYPE_LOCAL try: c = self.cli("show lldp ports %s neighbors detailed" % local_interface) match = self.rx_lldp_detail.search(c) if match: port_descr = match.group("port_descr") if port_descr: n["remote_port_description"] = port_descr.replace( '"', "").strip() n["remote_port_description"] = re.sub( r"\\\n\s*", "", n["remote_port_description"]) n["remote_system_name"] = match.group( "system_name").replace('"', "").strip() n["remote_system_name"] = re.sub(r"\\\n\s*", "", n["remote_system_name"]) sys_descr = match.group("system_descr") if sys_descr: n["remote_system_description"] = sys_descr.replace( '"', "").strip() n["remote_system_description"] = re.sub( r"\\\n\s*", "", n["remote_system_description"]) n["remote_port_subtype"] = self.port_types[match.group( "port_id_subtype").strip()] n["remote_chassis_id_subtype"] = self.chassis_types[ match.group("chassis_id_subtype").strip()] except self.CLISyntaxError: pass r[local_interface].append(n) return [{"local_interface": x, "neighbors": r[x]} for x in r]
def execute_cli(self): r = [] try: v = self.cli("show lldp neighbors") except self.CLISyntaxError: raise self.NotSupportedError() t = parse_table(v, allow_wrap=True) for i in t: chassis_id = i[1] if is_ipv4(chassis_id) or is_ipv6(chassis_id): chassis_id_subtype = LLDP_CHASSIS_SUBTYPE_NETWORK_ADDRESS elif is_mac(chassis_id): chassis_id_subtype = LLDP_CHASSIS_SUBTYPE_MAC else: chassis_id_subtype = LLDP_CHASSIS_SUBTYPE_LOCAL port_id = i[2] if is_ipv4(port_id) or is_ipv6(port_id): port_id_subtype = LLDP_PORT_SUBTYPE_NETWORK_ADDRESS elif is_mac(port_id): port_id_subtype = LLDP_PORT_SUBTYPE_MAC else: port_id_subtype = LLDP_PORT_SUBTYPE_LOCAL caps = lldp_caps_to_bits( i[4].split(","), { "o": LLDP_CAP_OTHER, "p": LLDP_CAP_REPEATER, "b": LLDP_CAP_BRIDGE, "w": LLDP_CAP_WLAN_ACCESS_POINT, "r": LLDP_CAP_ROUTER, "t": LLDP_CAP_TELEPHONE, "c": LLDP_CAP_DOCSIS_CABLE_DEVICE, "s": LLDP_CAP_STATION_ONLY, }, ) neighbor = { "remote_chassis_id": chassis_id, "remote_chassis_id_subtype": chassis_id_subtype, "remote_port": port_id, "remote_port_subtype": port_id_subtype, "remote_capabilities": caps, } if i[3]: neighbor["remote_system_name"] = i[3] r += [{"local_interface": i[0], "neighbors": [neighbor]}] if not t: for iface in self.scripts.get_interface_status(): c = self.cli("show lldp neighbors interface %s" % iface["interface"], ignore_errors=True) c = c.replace("\n\n", "\n") neighbors = [] for match in self.rx_neighbor.finditer(c): chassis_id = match.group("chassis_id") if is_ipv4(chassis_id) or is_ipv6(chassis_id): chassis_id_subtype = 5 elif is_mac(chassis_id): chassis_id_subtype = 4 else: chassis_id_subtype = 7 port_id = match.group("port_id") if is_ipv4(port_id) or is_ipv6(port_id): port_id_subtype = 4 elif is_mac(port_id): port_id_subtype = 3 else: port_id_subtype = 7 caps = 0 if match.group("caps").strip(): for c in match.group("caps").split(): c = c.strip() if c in {"not", "advertised"}: # not caps break if c and (c != "--"): caps |= { "O": 1, "P": 2, "B": 4, "W": 8, "R": 16, "r": 16, "T": 32, "C": 64, "S": 128, }[c] neighbor = { "remote_chassis_id": chassis_id, "remote_chassis_id_subtype": chassis_id_subtype, "remote_port": port_id, "remote_port_subtype": port_id_subtype, "remote_capabilities": caps, } port_descr = match.group("port_descr").strip() system_name = match.group("system_name").strip() system_descr = match.group("system_descr").strip() if bool(port_descr): neighbor["remote_port_description"] = port_descr if bool(system_name): neighbor["remote_system_name"] = system_name if bool(system_descr): neighbor["remote_system_description"] = system_descr neighbors += [neighbor] if neighbors: r += [{ "local_interface": iface["interface"], "neighbors": neighbors }] return r
def execute_cli(self, **kwargs): r = [] # Fallback to CLI try: lldp = self.cli("show lldp interface") except self.CLISyntaxError: raise NotImplementedError for match in self.rx_line.finditer(lldp): local_interface = match.group("interface") remote_chassis_id = match.group("chassis_id") remote_port = match.group("port_id") remote_system_name = match.group("name") system_description = match.group("system_description") port_description = match.group("port_description") # Build neighbor data # Get capability cap = 0 """ for c in match.group("capabilities").split(","): if cap: c = c.strip() if c: cap |= { "O": 1, "r": 2, "B": 4, "W": 8, "R": 16, "T": 32, "C": 64, "S": 128, "D": 256, "H": 512, "TP": 1024, }[c] """ # Get remote port subtype remote_port_subtype = 5 if is_ipv4(remote_port): # Actually networkAddress(4) remote_port_subtype = 4 elif is_mac(remote_port): # Actually macAddress(3) remote_port_subtype = 3 elif is_int(remote_port): # Actually local(7) remote_port_subtype = 7 i = {"local_interface": local_interface, "neighbors": []} n = { "remote_chassis_id": remote_chassis_id, "remote_port": remote_port, "remote_capabilities": cap, "remote_port_subtype": remote_port_subtype, } if remote_system_name and remote_system_name != "NULL": n["remote_system_name"] = remote_system_name if system_description and system_description != "NULL": n["remote_system_description"] = system_description if port_description and port_description != "NULL": n["remote_port_description"] = port_description # TODO: # n["remote_chassis_id_subtype"] = 4 i["neighbors"].append(n) r.append(i) return r
def execute_cli(self): r = [] # Fallback to CLI lldp = self.cli("show lldp neighbors") for link in parse_table( lldp, allow_wrap=True, line_wrapper=None, row_wrapper=lambda x: x.strip() ): local_interface = link[0] remote_chassis_id = link[1] remote_port = link[2] remote_system_name = link[3] # Build neighbor data # Get capability cap = lldp_caps_to_bits( link[4].strip().split(","), { "O": LLDP_CAP_OTHER, "r": LLDP_CAP_REPEATER, "B": LLDP_CAP_BRIDGE, "W": LLDP_CAP_WLAN_ACCESS_POINT, "R": LLDP_CAP_ROUTER, "T": LLDP_CAP_TELEPHONE, "D": LLDP_CAP_DOCSIS_CABLE_DEVICE, "S": LLDP_CAP_STATION_ONLY, # S-VLAN "C": 256, # C-VLAN "H": 512, # Host "TP": 1024, # Two Ports MAC Relay }, ) if is_ipv4(remote_chassis_id) or is_ipv6(remote_chassis_id): remote_chassis_id_subtype = LLDP_CHASSIS_SUBTYPE_NETWORK_ADDRESS elif is_mac(remote_chassis_id): remote_chassis_id = MACAddressParameter().clean(remote_chassis_id) remote_chassis_id_subtype = LLDP_CHASSIS_SUBTYPE_MAC else: remote_chassis_id_subtype = LLDP_CHASSIS_SUBTYPE_LOCAL # Get remote port subtype remote_port_subtype = LLDP_PORT_SUBTYPE_ALIAS if is_ipv4(remote_port): # Actually networkAddress(4) remote_port_subtype = LLDP_PORT_SUBTYPE_NETWORK_ADDRESS elif is_mac(remote_port): # Actually macAddress(3) # Convert MAC to common form remote_port = MACAddressParameter().clean(remote_port) remote_port_subtype = LLDP_PORT_SUBTYPE_MAC elif is_int(remote_port): # Actually local(7) remote_port_subtype = LLDP_PORT_SUBTYPE_LOCAL i = {"local_interface": local_interface, "neighbors": []} n = { "remote_chassis_id": remote_chassis_id, "remote_chassis_id_subtype": remote_chassis_id_subtype, "remote_port": remote_port, "remote_port_subtype": remote_port_subtype, "remote_capabilities": cap, } if remote_system_name: n["remote_system_name"] = remote_system_name # # XXX: Dirty hack for older firmware. Switch rebooted. # if remote_chassis_id_subtype != LLDP_CHASSIS_SUBTYPE_LOCAL: i["neighbors"] = [n] r += [i] continue try: c = self.cli("show lldp neighbors %s" % local_interface) match = self.rx_detail.search(c) if match: remote_chassis_id = match.group("dev_id") if is_ipv4(remote_chassis_id) or is_ipv6(remote_chassis_id): remote_chassis_id_subtype = LLDP_CHASSIS_SUBTYPE_NETWORK_ADDRESS elif is_mac(remote_chassis_id): remote_chassis_id = MACAddressParameter().clean(remote_chassis_id) remote_chassis_id_subtype = LLDP_CHASSIS_SUBTYPE_MAC else: remote_chassis_id_subtype = LLDP_CHASSIS_SUBTYPE_LOCAL n["remote_chassis_id"] = remote_chassis_id n["remote_chassis_id_subtype"] = remote_chassis_id_subtype if match.group("sys_name").strip(): sys_name = match.group("sys_name").strip() n["remote_system_name"] = sys_name if match.group("sys_descr").strip(): sys_descr = match.group("sys_descr").strip() n["remote_system_description"] = sys_descr if match.group("port_descr").strip(): port_descr = match.group("port_descr").strip() n["remote_port_description"] = port_descr except Exception: pass i["neighbors"] += [n] r += [i] return r
def execute_cli(self): r = [] data = [] try: v = self.cli("show lldp neighbors") except self.CLISyntaxError: raise self.NotSupportedError() v = v.replace("\n\n", "\n") for l in parse_table(v): if not l[0]: data[-1] = [s[0] + s[1] for s in zip(data[-1], l)] continue data += [l] for d in data: try: ifname = self.profile.convert_interface_name(d[0]) except ValueError: continue v = self.cli("show lldp neighbors %s" % ifname) match = self.rx_neighbor.search(v) chassis_id = match.group("chassis_id").strip() if is_ipv4(chassis_id) or is_ipv6(chassis_id): chassis_id_subtype = LLDP_CHASSIS_SUBTYPE_NETWORK_ADDRESS elif is_mac(chassis_id): chassis_id_subtype = LLDP_CHASSIS_SUBTYPE_MAC else: chassis_id_subtype = LLDP_CHASSIS_SUBTYPE_LOCAL port_id = match.group("port_id").strip() if is_ipv4(port_id) or is_ipv6(port_id): port_id_subtype = LLDP_PORT_SUBTYPE_NETWORK_ADDRESS elif is_mac(port_id): port_id_subtype = LLDP_PORT_SUBTYPE_MAC else: port_id_subtype = LLDP_PORT_SUBTYPE_LOCAL caps = lldp_caps_to_bits( match.group("caps").strip().split(","), { "other": LLDP_CAP_OTHER, "repeater": LLDP_CAP_REPEATER, "bridge": LLDP_CAP_BRIDGE, "wlan-access-point": LLDP_CAP_WLAN_ACCESS_POINT, "router": LLDP_CAP_ROUTER, "telephone": LLDP_CAP_TELEPHONE, "d": LLDP_CAP_DOCSIS_CABLE_DEVICE, "h": LLDP_CAP_STATION_ONLY, }, ) neighbor = { "remote_chassis_id": chassis_id, "remote_chassis_id_subtype": chassis_id_subtype, "remote_port": port_id, "remote_port_subtype": port_id_subtype, "remote_capabilities": caps, } system_name = match.group("system_name").strip() if system_name: neighbor["remote_system_name"] = system_name system_descr = match.group("system_descr").strip() if system_descr: neighbor["remote_system_description"] = system_descr port_descr = match.group("port_descr").strip() if port_descr: neighbor["remote_port_description"] = port_descr r += [{"local_interface": ifname, "neighbors": [neighbor]}] return r
def test_is_mac(raw, expected): assert is_mac(raw) is expected
def execute_cli(self): r = [] try: v = self.cli("show lldp neighbors") except self.CLISyntaxError: raise self.NotSupportedError() if v.startswith("%"): # % LLDP is not enabled return [] v = self.rx_summary_split.split(v)[1] lldp_interfaces = [] # Get LLDP interfaces with neighbors for line in v.splitlines(): line = line.strip() if not line: break match = self.rx_s_line.match(line) if not match: continue lldp_interfaces += [match.group("local_if")] # Get LLDP neighbors for local_if in lldp_interfaces: i = {"local_interface": local_if, "neighbors": []} # Get neighbors details try: v = self.cli("show lldp neighbors %s detail" % local_if) except self.CLISyntaxError: # Found strange CLI syntax on Catalyst 4900 # Allow ONLY interface name or "detail" # Need testing... raise self.NotSupportedError() # Get remote port match = self.re_search(self.rx_remote_port, v) remote_port = match.group("remote_if") remote_port_subtype = 1 if is_ipv4(remote_port): # Actually networkAddress(4) remote_port = IPv4Parameter().clean(remote_port) remote_port_subtype = 4 elif is_mac(remote_port): # Actually macAddress(3) # Convert MAC to common form remote_port = MACAddressParameter().clean(remote_port) remote_port_subtype = 3 elif is_int(remote_port): # Actually local(7) remote_port_subtype = 7 n = { "remote_port": remote_port, "remote_port_subtype": remote_port_subtype, "remote_chassis_id_subtype": 4, } match = self.rx_descr.search(v) if match: n["remote_port_description"] = match.group("descr") # Get chassis id match = self.rx_chassis_id.search(v) if not match: continue n["remote_chassis_id"] = match.group("id") # Get capabilities cap = 0 match = self.rx_enabled_caps.search(v) if match: for c in match.group("caps").split(","): c = c.strip() if c: cap |= { "O": 1, "P": 2, "B": 4, "W": 8, "R": 16, "T": 32, "C": 64, "S": 128, }[c] n["remote_capabilities"] = cap # Get remote chassis id match = self.rx_system.search(v) if match: n["remote_system_name"] = match.group("name") if is_ipv4(n["remote_chassis_id"]) or is_ipv6( n["remote_chassis_id"]): n["remote_chassis_id_subtype"] = 5 elif is_mac(n["remote_chassis_id"]): pass else: n["remote_chassis_id_subtype"] = 7 i["neighbors"] += [n] r += [i] return r
def execute(self): r = [] try: v = self.cli("sh lldp info remote") except self.CLISyntaxError: raise self.NotSupportedError() v = self.rx_summary_split.split(v)[1] lldp_interfaces = [] # Get lldp interfaces for line in v.splitlines(): line = line.strip() if not line: break match = self.rx_s_line.match(line) if not match: continue lldp_interfaces += [match.group("local_if")] # Get lldp neighbors for local_if in lldp_interfaces: i = {"local_interface": local_if, "neighbors": []} # Get neighbor details try: v = self.cli("sh lldp info remote interface port-channel %s" % local_if) except self.CLISyntaxError: raise self.NotSupportedError() # Get remote port match = self.re_search(self.rx_remote_port, v) remote_port = match.group("remote_if").strip() # match = self.re_search(self.rx_remote_port_desc, v) match = self.rx_remote_port_desc.search(v) if match: remote_port_desc = match.group("remote_if_desc").strip() else: remote_port_desc = "" match = self.rx_remote_port_subtype.search(v) if match: remote_port_subtype_str = match.group( "remote_if_subtype").strip() else: remote_port_subtype_str = "" # Get remote port subtype from "Port ID Subtype" field if remote_port_subtype_str == "local-assigned": remote_port_subtype = 7 # Local else: remote_port_subtype = 5 if is_ipv4(remote_port): # Actually networkAddress(4) remote_port_subtype = 4 elif is_mac(remote_port): # Actually macAddress(3) remote_port_subtype = 3 elif is_int(remote_port): # Actually local(7) remote_port_subtype = 7 else: remote_port_subtype = 128 # PORT_SUBTYPE_UNSPECIFIED n = { "remote_port": remote_port, "remote_port_subtype": remote_port_subtype, "remote_chassis_id_subtype": 4, } if remote_port_desc: n["remote_port_description"] = remote_port_desc # Get Chassis ID match = self.rx_chassis_id.search(v) if not match: continue n["remote_chassis_id"] = match.group("id") # Get capabilities cap = 0 match = self.rx_enabled_caps.search(v) if match: for c in match.group("caps").split(): c = c.strip() if c: cap |= { "other": 1, "repeater": 2, "bridge": 4, "wlan-access-point": 8, "router": 16, "telephone": 32, "docsis-cable-device": 64, "station-only": 128, }[c.lower()] n["remote_capabilities"] = cap # Get system name match = self.rx_system.search(v) if match: n["remote_system_name"] = match.group("name") match = self.rx_system_desc.search(v) if match: n["remote_system_description"] = match.group("desc") i["neighbors"] += [n] r += [i] return r
def execute_snmp(self, interface=None, last_ifname=None): last_ifname = self.collect_ifnames() # v = self.scripts.get_interface_status_ex() index = self.scripts.get_ifindexes() # index = self.get_ifindexes() aggregated, portchannel_members = self.get_aggregated_ifaces() ifaces = dict((index[i], {"interface": i}) for i in index) # Apply ifAdminStatus self.apply_table(ifaces, "IF-MIB::ifAdminStatus", "admin_status", lambda x: x == 1) # Apply ifOperStatus self.apply_table(ifaces, "IF-MIB::ifOperStatus", "oper_status", lambda x: x == 1) # Apply PhysAddress self.apply_table(ifaces, "IF-MIB::ifPhysAddress", "mac_address") self.apply_table(ifaces, "IF-MIB::ifType", "type") self.apply_table(ifaces, "IF-MIB::ifSpeed", "speed") self.apply_table(ifaces, "IF-MIB::ifMtu", "mtu") time.sleep(10) self.apply_table(ifaces, "IF-MIB::ifAlias", "description") ip_ifaces = self.get_ip_ifaces() r = [] subs = defaultdict(list) """ IF-MIB::ifPhysAddress.1 = STRING: IF-MIB::ifPhysAddress.2 = STRING: 0:21:5e:40:c2:50 IF-MIB::ifPhysAddress.3 = STRING: 0:21:5e:40:c2:52 """ for l in ifaces: iface = ifaces[l] """ If the bug in the firmware and the number of interfaces in cli is different from the number of interfaces given through snmp, we pass the list of interfaces for reconciliation. def execute_snmp(self, interface=None, last_ifname= None): IFNAME = set(["Gi 1/0/1", "Gi 1/0/2", "Gi 1/0/3", "Gi 1/0/4", "Gi 1/0/5", "Gi 1/0/6", "Gi 1/0/7", "Gi 1/0/8", "Gi 1/0/9", "Gi 1/0/10", "Gi 1/0/11", "Gi 1/0/12", "Po 1", "Po 2", "Po 3", "Po 4", "Po 5", "Po 6","Po 7", "Po 8", "Po 9", "Po 10", "Po 11", "Po 12", "Po 13", "Po 14", "Po 15", "Po 16"]) if self.match_version(version__regex="4\.0\.8\.1$") and self.match_version(platform__regex="MES-2308P"): return super(Script, self).execute_snmp(last_ifname=IFNAME) """ if last_ifname and iface["interface"] not in last_ifname: continue i_type = self.get_interface_type(iface["type"]) if "." in iface["interface"]: s = { "name": iface["interface"], "description": self.convert_description(iface.get("description", "")), "type": i_type, "enabled_afi": ["BRIDGE"], "admin_status": iface["admin_status"], "oper_status": iface["oper_status"], "snmp_ifindex": l, } iface_name, num = iface["interface"].rsplit(".", 1) if num.isdigit(): vlan_ids = int(iface["interface"].rsplit(".", 1)[-1]) if 1 <= vlan_ids < 4095: s["vlan_ids"] = vlan_ids if l in ip_ifaces: s["ipv4_addresses"] = [IPv4(*ip_ifaces[l])] s["enabled_afi"] = ["IPv4"] if iface["mac_address"] and is_mac(iface["mac_address"]): s["mac"] = MAC(iface["mac_address"]) subs[iface_name] += [s.copy()] # r[-1]["subinterfaces"] += [s] continue i = { "name": iface["interface"], "description": self.convert_description(iface.get("description", "")), "type": i_type, "admin_status": iface["admin_status"], "oper_status": iface["oper_status"], "snmp_ifindex": l, } if i["name"] in portchannel_members: i["aggregated_interface"], lacp = portchannel_members[ i["name"]] if lacp: i["enabled_protocols"] = ["LACP"] if i["name"] in aggregated: i["type"] = "aggregated" if iface["mac_address"] and is_mac(iface["mac_address"]): i["mac"] = MAC(iface["mac_address"]) # sub = {"subinterfaces": [i.copy()]} r += [i] for l in r: if l["name"] in subs: l["subinterfaces"] = subs[l["name"]] else: l["subinterfaces"] = [{ "name": l["name"], "description": self.convert_description(l.get("description", "")), "type": "SVI", "enabled_afi": ["BRIDGE"] if l["type"] in ["physical", "aggregated"] else [], "admin_status": l["admin_status"], "oper_status": l["oper_status"], "snmp_ifindex": l["snmp_ifindex"], }] if l["snmp_ifindex"] in ip_ifaces: l["subinterfaces"][-1]["ipv4_addresses"] = [ IPv4(*ip_ifaces[l["snmp_ifindex"]]) ] l["subinterfaces"][-1]["enabled_afi"] = ["IPv4"] return [{"interfaces": r}]
def execute_cli(self): r = [] with self.profile.switch(self): lldp = self.cli("show lldp neighbors") for link in parse_table(lldp, allow_wrap=True): local_interface = link[0] remote_chassis_id = link[1] remote_port = link[2] remote_system_name = link[3] # Get capability cap = 0 for c in link[4].split(","): c = c.strip() if c: cap |= self.CAPS_MAP[c] if is_ipv4(remote_chassis_id) or is_ipv6(remote_chassis_id): remote_chassis_id_subtype = 5 elif is_mac(remote_chassis_id): remote_chassis_id = MACAddressParameter().clean( remote_chassis_id) remote_chassis_id_subtype = 4 else: remote_chassis_id_subtype = 7 # Get remote port subtype remote_port_subtype = 1 if is_ipv4(remote_port): # Actually networkAddress(4) remote_port_subtype = 4 elif is_mac(remote_port): # Actually macAddress(3) # Convert MAC to common form remote_port = MACAddressParameter().clean(remote_port) remote_port_subtype = 3 elif is_int(remote_port): # Actually local(7) remote_port_subtype = 7 i = {"local_interface": local_interface, "neighbors": []} n = { "remote_chassis_id": remote_chassis_id, "remote_chassis_id_subtype": remote_chassis_id_subtype, "remote_port": remote_port, "remote_port_subtype": remote_port_subtype, "remote_capabilities": cap, } if remote_system_name: n["remote_system_name"] = remote_system_name try: c = self.cli("show lldp neighbors interface %s" % local_interface) match = self.rx_detail.search(c) if match: if match.group("port_descr").strip(): port_descr = match.group("port_descr").strip() n["remote_port_description"] = port_descr except Exception: pass i["neighbors"] += [n] r += [i] return r
def execute(self): r = [] try: v = self.cli("show lldp neighbors") except self.CLISyntaxError: raise self.NotSupportedError() t = parse_table(v, allow_wrap=True) for i in t: chassis_id = i[1] if is_ipv4(chassis_id) or is_ipv6(chassis_id): chassis_id_subtype = 5 elif is_mac(chassis_id): chassis_id_subtype = 4 else: chassis_id_subtype = 7 port_id = i[2] if is_ipv4(port_id) or is_ipv6(port_id): port_id_subtype = 4 elif is_mac(port_id): port_id_subtype = 3 else: port_id_subtype = 7 caps = 0 for c in i[4].split(","): c = c.strip() if c: caps |= { "O": 1, "r": 2, "B": 4, "W": 8, "R": 16, "T": 32, "C": 64, "S": 128 }[c] """ if "O" in i[4]: caps += 1 elif "r" in i[4]: caps += 2 elif "B" in i[4]: caps += 4 elif "W" in i[4]: caps += 8 elif "R" in i[4]: caps += 16 elif "T" in i[4]: caps += 32 elif "D" in i[4]: caps += 64 elif "H" in i[4]: caps += 128 """ neighbor = { "remote_chassis_id": chassis_id, "remote_chassis_id_subtype": chassis_id_subtype, "remote_port": port_id, "remote_port_subtype": port_id_subtype, "remote_capabilities": caps, } if i[3]: neighbor["remote_system_name"] = i[3] try: v = self.cli("show lldp neighbors %s" % i[0]) match = self.rx_port.search(v) if match: neighbor["remote_system_description"] = match.group( "system_description").strip() neighbor["remote_port_description"] = match.group( "port_description").strip() except self.CLISyntaxError: pass r += [{"local_interface": i[0], "neighbors": [neighbor]}] return r
def clean_mac(self, mac: str): if is_mac(mac) and not self.is_ignored_mac(MAC(mac)): return mac return None
def execute_cli(self): r = [] r_rem = [] v = self.cli("show lldp remote") for match in self.rx_lldp_rem.finditer(v): chassis_id = match.group("ch_id") if is_ipv4(chassis_id) or is_ipv6(chassis_id): chassis_id_subtype = LLDP_CHASSIS_SUBTYPE_NETWORK_ADDRESS elif is_mac(chassis_id): chassis_id_subtype = LLDP_CHASSIS_SUBTYPE_MAC else: chassis_id_subtype = LLDP_CHASSIS_SUBTYPE_LOCAL r_rem += [ { "local_interface": match.group("port"), "remote_chassis_id": chassis_id, "remote_chassis_id_subtype": chassis_id_subtype, } ] v = self.cli("show lldp remote detail") # If detail command not contain ch id ext_ch_id = False lldp_iter = list(self.rx_lldp.finditer(v)) if not lldp_iter: ext_ch_id = True lldp_iter = list(self.rx_lldp_womac.finditer(v)) self.logger.debug("Not Find MAC in re") for match in lldp_iter: i = {"local_interface": match.group("port"), "neighbors": []} cap = lldp_caps_to_bits( match.group("sys_caps_enabled").strip().split(","), { "n/a": 0, "other": LLDP_CAP_OTHER, "repeater/hub": LLDP_CAP_REPEATER, "bridge/switch": LLDP_CAP_BRIDGE, "router": LLDP_CAP_ROUTER, "telephone": LLDP_CAP_TELEPHONE, "station": LLDP_CAP_STATION_ONLY, }, ) n = { "remote_chassis_id_subtype": { "macAddress": LLDP_CHASSIS_SUBTYPE_MAC, "networkAddress": LLDP_CHASSIS_SUBTYPE_NETWORK_ADDRESS, }[match.group("ch_type")], "remote_chassis_id": match.group("ch_id") if not ext_ch_id else None, "remote_port_subtype": { "ifAlias": LLDP_PORT_SUBTYPE_ALIAS, "macAddress": LLDP_PORT_SUBTYPE_MAC, "ifName": LLDP_PORT_SUBTYPE_NAME, "portComponent": LLDP_PORT_SUBTYPE_NAME, "local": LLDP_PORT_SUBTYPE_LOCAL, }[match.group("port_id_subtype")], "remote_port": match.group("port_id"), "remote_capabilities": cap, } if match.group("sys_name").strip() != "N/A": n["remote_system_name"] = match.group("sys_name").strip() if match.group("sys_descr").strip() != "N/A": sd = match.group("sys_descr").strip() if "SysDesc:" in sd: sd = sd.split()[-1] n["remote_system_description"] = re.sub("\n\s{29,30}", "", sd) if match.group("port_descr").strip() != "N/A": n["remote_port_description"] = re.sub( "\n\s{29,30}", "", match.group("port_descr").strip() ) match.group("port_descr") if n["remote_chassis_id"] is None: for j in r_rem: if i["local_interface"] == j["local_interface"]: n["remote_chassis_id"] = j["remote_chassis_id"] n["remote_chassis_id_subtype"] = j["remote_chassis_id_subtype"] break i["neighbors"] += [n] r += [i] return r
def execute_cli(self): r = [] try: v = self.cli("show lldp neighbors") except self.CLISyntaxError: raise self.NotSupportedError() if v.startswith("%"): # % LLDP is not enabled return [] v = self.rx_summary_split.split(v)[1] lldp_interfaces = [] # Get LLDP interfaces with neighbors for line in v.splitlines(): line = line.strip() if not line: break match = self.rx_s_line.match(line) if not match: continue lldp_interfaces += [match.group("local_if")] # Get LLDP neighbors for local_if in lldp_interfaces: i = {"local_interface": local_if, "neighbors": []} # Get neighbors details try: v = self.cli("show lldp neighbors %s detail" % local_if) except self.CLISyntaxError: # Found strange CLI syntax on Catalyst 4900 # Allow ONLY interface name or "detail" # Need testing... raise self.NotSupportedError() # Get remote port match = self.re_search(self.rx_remote_port, v) remote_port = match.group("remote_if") remote_port_subtype = LLDP_PORT_SUBTYPE_ALIAS if is_ipv4(remote_port): remote_port = IPv4Parameter().clean(remote_port) remote_port_subtype = LLDP_PORT_SUBTYPE_NETWORK_ADDRESS elif is_mac(remote_port): # Convert MAC to common form remote_port = MACAddressParameter().clean(remote_port) remote_port_subtype = LLDP_PORT_SUBTYPE_MAC elif is_int(remote_port): remote_port_subtype = LLDP_PORT_SUBTYPE_LOCAL n = { "remote_port": remote_port, "remote_port_subtype": remote_port_subtype, "remote_chassis_id_subtype": LLDP_CHASSIS_SUBTYPE_MAC, } match = self.rx_descr.search(v) if match: n["remote_port_description"] = match.group("descr") # Get chassis id match = self.rx_chassis_id.search(v) if not match: continue n["remote_chassis_id"] = match.group("id") # Get capabilities cap = 0 match = self.rx_enabled_caps.search(v) if match: cap = lldp_caps_to_bits( match.group("caps").strip().split(","), { "o": LLDP_CAP_OTHER, "p": LLDP_CAP_REPEATER, "b": LLDP_CAP_BRIDGE, "w": LLDP_CAP_WLAN_ACCESS_POINT, "r": LLDP_CAP_ROUTER, "t": LLDP_CAP_TELEPHONE, "c": LLDP_CAP_DOCSIS_CABLE_DEVICE, "s": LLDP_CAP_STATION_ONLY, }, ) n["remote_capabilities"] = cap # Get remote chassis id match = self.rx_system.search(v) if match: n["remote_system_name"] = match.group("name") if is_ipv4(n["remote_chassis_id"]) or is_ipv6( n["remote_chassis_id"]): n["remote_chassis_id_subtype"] = LLDP_CHASSIS_SUBTYPE_NETWORK_ADDRESS elif is_mac(n["remote_chassis_id"]): pass else: n["remote_chassis_id_subtype"] = LLDP_CHASSIS_SUBTYPE_LOCAL i["neighbors"] += [n] r += [i] return r