Search code examples
pythonlinuxsnmpnet-snmp

Python Netsnmp and snmpwalk


I am trying to use snmpwalk to gain some info and stats on some interfaces. I use this:

import netsnmp

serv = "172.16.1.1"
snmp_pass = "private"

oid = netsnmp.VarList('IF-MIB::ifName','IF-MIB::ifDescr')
snmp_res = netsnmp.snmpwalk(oid, Version=2, DestHost=serv, Community=snmp_pass)
for x in snmp_res:
    print "snmp_res:: ", x

All I get as answer is:

snmp_res:: lo
snmp_res:: EtherNet Adapter XYZ

The answer is correct but I want more info. When I do same thing from linux command with snmpwalk I get more info such as:

IF-MIB::ifDescr.1 = STRING: lo
IF-MIB::ifDescr.2 = STRING: EtherNet Adapter XYZ

The ID is 2 for "EtherNet Adapter XYZ" and I need that value as well to reference for other stats on interface. How do I get that/them with python and snmp?


Solution

  • Straight out of the documentation:

    snmpwalk(<Varbind/VarList>, <Session args>))

    Takes args of netsnmp.Session preceded by a Varbind or VarList from which the 'walk' operation will start. Returns a tuple of values retrieved from the MIB below the Varbind passed in. If a VarList is passed in it will be updated to contain a complete set of VarBinds created for the results of the walk. It is not recommended to pass in just a Varbind since you loose the ability to examine the returned OIDs. But, if only a Varbind is passed in it will be returned unaltered.

    Note that only one varbind should be contained in the VarList passed in. The code is structured to maybe handle this is the the future, but right now walking multiple trees at once is not yet supported and will produce insufficient results.

    You're already passing a VarList, so you already have what you need. You just need to examine the results properly.

    The tests have an example:

    vars = netsnmp.VarList(netsnmp.Varbind('system'))
    
    vals = sess.walk(vars)
    print "v1 sess.walk result: ", vals, "\n"
    
    for var in vars:
        print "  ",var.tag, var.iid, "=", var.val, '(',var.type,')'
    

    The key is that the input variable is modified to give you what you need. The return value is not of much value (lol) to you.

    Putting this all together it looks like you want the following:

    import netsnmp
    
    serv = "172.16.1.1"
    snmp_pass = "private"
    
    oid = netsnmp.VarList('IF-MIB::ifName','IF-MIB::ifDescr')
    snmp_res = netsnmp.snmpwalk(oid, Version=2, DestHost=serv, Community=snmp_pass)
    for x in oid:
        print "snmp_res:: ", x.iid, " = ", x.val
    

    (Disclaimer: can't test; adapt as needed)

    There's enough information about VarBind and VarList in that documentation to figure out the best stuff to get out of x.

    x.iid is the instance identifier, though, so that should give you the 1 and 2 that you're after. Don't forget to examine x.tag as well, though, which will be either IF-MIB::ifName or IF-MIB::ifDescr (or something equivalent; you'd have to experiment).