Below is the file 'plugins/cisco_ios.py' from this revision. You can also download the file.
from goatpy.snmpwrapper import snmpwalk import basic_snmp import csv import os import re # http://tools.cisco.com/Support/SNMP/do/BrowseMIB.do?local=en&step=2&mibName=CISCO-TC-V1SMI network_protocol = { '1' : 'ip', '2' : 'decnet', '3' : 'pup', '4' : 'chaos', '5' : 'xna', '6' : 'x121', '7' : 'appletalk', '8' : 'clns', '9' : 'lat', '10' : 'vines', '11' : 'cons', '12' : 'apollo', '13' : 'stun', '14' : 'novell', '15' : 'qllc', '16' : 'snapshot', '17' : 'atmIlmi', '18' : 'bstun', '19' : 'x25pvc', '20' : 'ipv6', '21' : 'cdm', '22' : 'nbf', '23' : 'bpxIgx', '24' : 'clnsPfx', '25' : 'http' } # http://tools.cisco.com/Support/SNMP/do/BrowseMIB.do?local=en&mibName=CISCO-CDP-MIB def adjacency(table_name, table_io, device): def to_ipaddr(s): if not s: return s return '.'.join([str(t) for t in map(lambda h: int(h, 16), s.split(' '))]) def to_ascii(s): if not s: return s asdigits = [int(t, 16) for t in s.split(' ')] asdigits = filter(lambda x: x >= 32 and x <= 122, asdigits) return ''.join([chr(t) for t in asdigits]) row_to_field = { 1 : ('INTEGER', 'cdpCacheIfIndex'), 3 : ('INTEGER', 'cdpCacheAddressType'), 4 : ('Hex-STRING', 'cdpCacheAddress'), 6 : ('STRING', 'cdpCacheDeviceId'), 7 : ('STRING', 'cdpCacheDevicePort') } table = {} for oid, type, value in snmpwalk(device.device_name, device.config['community'], "2c", "SNMPv2-SMI::enterprises.9.9.23.1.2.1.1", ssh_dest=device.config.get('ssh')): id, row = tuple(oid[-2:]), int(oid[-3]) if not table.has_key(id): table[id] = {} match_type, match_name = row_to_field.get(row, (None, None)) if match_name and match_type and match_type == type: table[id][match_name] = value for row in table: vals = table[row] yield (device.config['zone'], vals.get('cdpCacheDeviceId', '')[1:-1], vals.get('cdpCacheIfIndex', ''), vals.get('cdpCacheDevicePort', '')[1:-1], network_protocol.get(vals.get('cdpCacheAddressType'), 'unknown'), to_ipaddr(vals.get('cdpCacheAddress', ''))) # see: http://www.cisco.com/en/US/tech/tk648/tk362/technologies_tech_note09186a0080094a9b.shtml def ethernet_forwarding(table_name, table_io, device): vlans_file = device.get_filename('ethernet_vlans') vlans = [] if os.access(vlans_file, os.R_OK): rows = csv.reader(open(vlans_file)) header = rows.next() vlan_column = header.index('vlan') for row in rows: vlans.append(row[vlan_column]) # build the bridgeport -> ifindex table bridgeport_to_ifindex = {} for oid, type, value in snmpwalk(device.device_name, device.config['community'], "2c", "1.3.6.1.2.1.2.2.1.1", ssh_dest=device.config.get('ssh')): # dot1dBasePortIfIndex bridgeport = int(oid[-1]) ifindex = int(value) bridgeport_to_ifindex[bridgeport] = ifindex def get_uid_to_mac(vlan): rv = {} for oid, type, value in snmpwalk(device.device_name, device.config['community'] + '@' + vlan, "2c", ".1.3.6.1.2.1.17.4.3.1.1", ssh_dest=device.config.get('ssh')): # dot1dTpFdbAddress uid = tuple(oid[-6:]) mac = value rv[uid] = mac return rv def get_uid_to_bridgeport(vlan): rv = {} for oid, type, value in snmpwalk(device.device_name, device.config['community'] + '@' + vlan, "2c", ".1.3.6.1.2.1.17.4.3.1.2", ssh_dest=device.config.get('ssh')): # dot1dTpFdbAddress uid = tuple(oid[-6:]) bridgeport = int(value) rv[uid] = bridgeport return rv for vlan in vlans: log("retrieving vlan forwarding table for : %s" % (vlan)) uid_to_mac = get_uid_to_mac(vlan) uid_to_bridgeport = get_uid_to_bridgeport(vlan) for uid in uid_to_mac: mac, bridgeport = uid_to_mac.get(uid), uid_to_bridgeport.get(uid) if bridgeport and mac: ifindex = bridgeport_to_ifindex.get(bridgeport) yield device.config['zone'], vlan, mac, ifindex def ethernet_vlans(table_name, table_io, device): # walk vtpVlanName for oid, type, value in snmpwalk(device.device_name, device.config['community'], "2c", ".1.3.6.1.4.1.9.9.46.1.3.1.1.4", ssh_dest=device.config.get('ssh')): value = value[1:-1] yield device.config['zone'], int(oid[-1]), value tables = { 'adjacency' : adjacency, 'ethernet_forwarding' : ethernet_forwarding, 'ethernet_vlans' : ethernet_vlans, 'ip_addresses' : basic_snmp.ip_addresses, 'ip_arp' : basic_snmp.ip_arp, 'ip_routing' : basic_snmp.ip_routing } def init(): export['has_table'] = simple_has_table(tables) export['get_table'] = simple_get_table(tables) log("Cisco IOS initialised")