how to load and walk a custom mib in pysnmp?

verboze picture verboze · Jan 31, 2013 · Viewed 9.6k times · Source

I'm new to SNMP/pysnmp and I'm trying to implement an agent that uses a custom MIB. I'm looking at the following example on the pysnmp site, but I can't seem to get it to work. Here are the steps I'm taking:

  1. convert my MIB file to a pysnmp module using build-pysnmp-mib (this succeeds without errors)
  2. set MIB source and load the MIB module using MibBuilder()
  3. use the example referenced above to set up the agent (only thing I added is the mibBuilder)
  4. use net-snmp's snmpwalk to view the loaded MIB:

The snmpwalk command is:

snmpwalk -v3 -u usr-md5-none -l authNoPriv -A authkey1 -E 8000000001020304 -n my-context 127.0.0.1 .1.3.6

snmpwalk returns a timeout error, and upon analyzing communication (by enabling I/O debug in pysnmp), I can see that the agent receives the requests, but never replies. I'm thinking this maybe has something to do with the context, which I may not correctly understand at the moment. Any pointers on where I may be doing things wrong is greatly appreciated. I'm using the following sample MIB for my tests. Code below. Thanks.

#!/usr/local/bin/python

from pysnmp.smi import builder
from pysnmp.smi import view

from pysnmp.entity import engine
from pysnmp.entity import config
from pysnmp.entity.rfc3413 import cmdrsp
from pysnmp.entity.rfc3413 import context
from pysnmp.smi import instrum
from pysnmp.carrier.asynsock.dgram import udp
from pysnmp.proto.api import v2c

from pysnmp import debug

# Create SNMP engine
snmpEngine = engine.SnmpEngine()

# Transport setup

# UDP over IPv4
config.addSocketTransport(
    snmpEngine,
    udp.domainName,
    udp.UdpTransport().openServerMode(('127.0.0.1', 161))
)

# SNMPv3/USM setup

# user: usr-md5-none, auth: MD5, priv NONE
config.addV3User(
    snmpEngine, 'usr-md5-none',
    config.usmHMACMD5AuthProtocol, 'authkey1'
)

# Allow full MIB access for each user at VACM
config.addVacmUser(snmpEngine, 3, 'usr-md5-none', 'authNoPriv',
                   (1,3,6,1,2,1), (1,3,6,1,2,1)) 

# Create an SNMP context with ContextEngineId = 8000000001020304
snmpContext = context.SnmpContext(
    snmpEngine, contextEngineId=v2c.OctetString(hexValue='8000000001020304')
)

# load mibs
MIBDIR = '/usr/local/share//mibdata'
mibBuilder = builder.MibBuilder()
mibSources = mibBuilder.getMibSources() + (builder.DirMibSource(MIBDIR),)
mibBuilder.setMibSources(*mibSources)
mibBuilder.loadModules('TOASTER-MIB')

# pass mib to Management Instrumentation Controller and register at SNMP Context
# under ContextName 'my-context'
snmpContext.registerContextName(
    v2c.OctetString('my-context'),            # Context Name
    instrum.MibInstrumController(mibBuilder)  # Managed Objects - loading my custom TOASTER-MIB
)

# Register SNMP Applications at the SNMP engine for particular SNMP context
cmdrsp.GetCommandResponder(snmpEngine, snmpContext)
cmdrsp.SetCommandResponder(snmpEngine, snmpContext)
cmdrsp.NextCommandResponder(snmpEngine, snmpContext)
cmdrsp.BulkCommandResponder(snmpEngine, snmpContext)

# Register an imaginary never-ending job to keep I/O dispatcher running forever
snmpEngine.transportDispatcher.jobStarted(1)

# Run I/O dispatcher which would receive queries and send responses
try:
    snmpEngine.transportDispatcher.runDispatcher()
except:
    snmpEngine.transportDispatcher.closeDispatcher()
    raise

Answer

Pooh picture Pooh · Jan 31, 2013

Do you really need to use non-default ContextEngineId & ContextName? If not, I'd advise using this example instead. You could load your custom MIB into default SnmpEngine's MIB tree (mibBuilder) which is available through these calls:

snmpContext = context.SnmpContext(snmpEngine)
mibBuilder = snmpContext.getMibInstrum().getMibBuilder()

Also make sure you allow Manager access to your OIDs using config.addVacmUser() function.

Another important thing to realize is that compiled pysnmp MIB in its initial state does not contain instances of MIB variables, rather it only gives hints to a Manager regarding Agent's contents. Therefore to make your Agent live you would have to add instances of Managed Objects into your MIB what is explained in another example.