Search code examples
pythonsnmpagentpysnmpmib

How can I register a MIB module in a different (SNMPv3) context. In SNMP agent side


I am new to SNMP and I am trying to create SNMP agent in the cloud which will use the context name to distinguish the devices. I am using pysnmp in the agent side. I am also following the sample program available.

Now I want to know how to add register multiple context name in the agent side and register MIB under this context name. All using the same non-default MIB.

I tried whatever sample codes available, But when i use the context name I get Time Out or ENd Of MIB.

def __init__(self, mibObjects):

 snmpEngine = engine.SnmpEngine()

 config.addTransport(
      self._snmpEngine, udp.domainName,                              
      udp.UdpTransport().openServerMode(('127.0.0.1', 161)))

 config.addV3User(self._snmpEngine, 'User', config.usmHMACMD5AuthProtocol, 'PassCode')

 config.addVacmUser(self._snmpEngine, 3, 'User', 'authNoPriv', (1, 3, 6, 1, 4, 1, 44555), (1, 3, 6, 1, 4, 1, 44555))

 snmpContext = context.SnmpContext(snmpEngine)
        
        responder(snmpEngine,snmpContext)

 mibBuilder = snmpContext.getMibInstrum().getMibBuilder()

 loadmib(mibBuilder)

 snmpContext.registerContextName(
                 v2c.OctetString('MyContextName'),
                 instrum.MibInstrumController(mibBuilder)
        )

 MibScalarInstance, = mibBuilder.importSymbols('SNMPv2-SMI', 'MibScalarInstance')

 # export our custom mib
 for mibObject in mibObjects:
       nextVar, = mibBuilder.importSymbols(mibObject.mibName,                                
       mibObject.objectType)
       instance = createVariable(MibScalarInstance,          
                                mibObject.valueFunc,                                     
                                mibObject.objectType,                                    
                                nextVar.name, (0,),                                  
                                nextVar.syntax)
      instanceDict = {str(nextVar.name) + "Instance":instance}
      mibBuilder.exportSymbols(mibObject.mibName,
                                        **instanceDict)

I just pasted only minimal code. Please ask if need more. Is it not the right way, then what is it? Is there any good documentation or help available for this?


Solution

  • Essentially, you should have one SnmpContext object and multiple MIB trees each registered with SnmpContext under some distinct name.

    # Create an SNMP context with default ContextEngineId (same as SNMP engine ID)
    snmpContext = context.SnmpContext(snmpEngine)
    
    # Create multiple independent trees of MIB managed objects (empty so far)
    mibTreeA = instrum.MibInstrumController(builder.MibBuilder())
    mibTreeB = instrum.MibInstrumController(builder.MibBuilder())
    
    # Register MIB trees at distinct SNMP Context names
    snmpContext.registerContextName(v2c.OctetString('context-a'), mibTreeA)
    snmpContext.registerContextName(v2c.OctetString('context-b'), mibTreeB)
    
    # 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)
    

    Then you should be able to query each of the MIB trees like this:

    snmpwalk -v3 -u usr-md5-none -l authNoPriv -A authkey1 -n context-a 127.0.0.1 .1.3.6
    snmpwalk -v3 -u usr-md5-none -l authNoPriv -A authkey1 -n context-b 127.0.0.1 .1.3.6
    

    You will likely get just end-of-mib because MIB trees are empty.

    The docs site has a hopefully operational example script.

    Alternatively to implementing your own SNMP agent from the scratch, you might consider trying out SNMP Command Responder tool based on the same technology, but making it easier (hopefully).