Below is the file 'plugins/basic_snmp.py' from this revision. You can also download the file.


#
# basic_snmp : stuff a generic managed switch should support
#

import re
from goatpy.snmpwrapper import snmpwalk
from iputils import int_to_length, ip_to_int

plugin_info = {
    'description' : '''\
A basic module, which provides as many tables as possible without
vendor specific knowledge. It aims to work with any SNMP version 1 device
that exports the required MIBs.
'''
}

def interfaces(table_name, table_io, device):
    ifaces = {}
    for oid, type, value in snmpwalk(device.device_name, device.config['community'], "2c", ".interfaces", ssh_dest=device.config.get('ssh')):
        current_row = int(oid[-1])
        row_name = oid[-2]
        colon = row_name.rfind(':')
        if colon <> -1:
            row_name = row_name[colon+1:]
        if not ifaces.has_key(current_row):
            ifaces[current_row] = {}
        ifaces[current_row][row_name] = value
    for interface in ifaces:
        yield device.config['zone'], interface, ifaces[interface].get('ifDescr'), ifaces[interface].get('ifAdminStatus'), \
                ifaces[interface].get('ifOperStatus'), ifaces[interface].get('ifMtu'), \
                normalise_ethernet_address(ifaces[interface].get('ifPhysAddress')), ifaces[interface].get('ifSpeed')

def ip_arp(table_name, table_io, device):
	for oid, type, value in snmpwalk(device.device_name, device.config['community'], "2c", "IP-MIB::ipNetToMediaPhysAddress", ssh_dest=device.config.get('ssh')):
		ip_address = '.'.join(oid[-4:])
		mac_address = value
		yield device.config['zone'], None, normalise_ethernet_address(mac_address), ip_address

def ip_routing(table_name, table_io, device):
	routes = {}
	for oid, route_type, value in snmpwalk(device.device_name, device.config['community'], "2c", "ipRouteTable", ssh_dest=device.config.get('ssh')):
		row_name = oid[0]
		colon = row_name.rfind(':')
		if colon <> -1: row_name = row_name[colon+1:]
		ip_address = '.'.join(oid[-4:])
		if not routes.has_key(ip_address): routes[ip_address] = {}
		routes[ip_address][row_name] = value
	for row in routes:
		route = routes[row]
		route_type = route.get('ipRouteType')
		if route_type:
			m = re.match(r'([a-zA-Z]+)\(', route_type)
			if m:
			    route_type = m.groups()[0]
		if route.has_key('ipRouteDest') and route.has_key('ipRouteMask'):
			network = route.get('ipRouteDest') + '/' + str(int_to_length(ip_to_int(route.get('ipRouteMask'))))
		else: network = None
		via = route.get('ipRouteNextHop')
		metric = route.get('ipRouteMetric1')
		ifindex = route.get('ipRouteIfIndex')
		if ifindex: ifindex = int(ifindex)
		yield device.config["zone"], route_type, ifindex, False, network, via, metric

def ip_addresses(table_name, table_io, device):
	addresses = {}
	for oid, type, value in snmpwalk(device.device_name, device.config['community'], "2c", "IP-MIB::ipAddrTable", ssh_dest=device.config.get('ssh')):
		current_row = tuple(oid[-4:])
		row_name = oid[-5]
		colon = row_name.rfind(':')
		if colon <> -1: row_name = row_name[colon+1:]
		if not addresses.has_key(current_row): addresses[current_row] = {}
		addresses[current_row][row_name] = value
	for row in addresses:
		ip = addresses[row].get('ipAdEntAddr')
		netmask = addresses[row].get('ipAdEntNetMask')
		interface = addresses[row].get('ipAdEntIfIndex')
		if ip != None and netmask != None: ip = ip + '/' + str(int_to_length(ip_to_int(netmask)))
		yield device.config['zone'], ip, interface

tables = {
    'interfaces' : interfaces,
    'ip_addresses' : ip_addresses,
    'ip_arp' : ip_arp,
    'ip_routing' : ip_routing,
}

def init():
    export['has_table'] = simple_has_table(tables)
    export['get_table'] = simple_get_table(tables)
    log("basic snmp initialised")