I am trying to implement a snmp agent with two different context name.I got some sample program .This is my agent side code look like . which I got from the snmplabs. I tried to implement it and I am facing some error while doing the snmpwalk.
"""
| $ 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
""" #
from pysnmp.entity import engine, config
from pysnmp.entity.rfc3413 import cmdrsp, context
from pysnmp.carrier.asyncore.dgram import udp
from pysnmp.smi import instrum, builder
from pysnmp.proto.api import v2c
import datetime
from pysnmp.smi import exval
# Create SNMP engine
snmpEngine = engine.SnmpEngine()
# Transport setup
# UDP over IPv4
config.addTransport(
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 default ContextEngineId (same as SNMP engine ID)
snmpContext = context.SnmpContext(snmpEngine)
class EchoMibInstrumController(instrum.AbstractMibInstrumController):
def readVars(self, varBinds, acInfo=(None, None)):
retItem = []
print ('varbinds', varBinds)
for ov in varBinds:
if str(ov[0]) == '1.3.6.1.2.1.1.1.0':
currentDT = datetime.datetime.now()
retItem.extend([(ov[0], v2c.OctetString('Hello World! It\'s currently: %s' % str(currentDT)))])
elif str(ov[0]) == '1.3.6.1.2.1.1.1.1':
retItem.extend([(ov[0], v2c.OctetString('You queried walk OID %s' % ov[0]))])
else:
retItem.extend([(ov[0], v2c.OctetString('You queried readVars OID %s' % str(currentDT)))])
return retItem
def readNextVars(self, varBinds, acInfo=(None, None)):
retItem = []
print ('Next varbinds', varBinds)
for ov in varBinds:
if str(ov[0]) == '1.3.6.1.2.1.1.1.0':
currentDT = datetime.datetime.now()
retItem.extend([(ov[0], v2c.OctetString('Hello World! It\'s currently: %s' % str(currentDT)))])
elif str(ov[0]) == '1.3.6.1.2.1.1.1.1':
retItem.extend([(ov[0], v2c.OctetString('You queried walk OID %s' % ov[0]))])
else:
currentDT = datetime.datetime.now()
retItem.extend([(ov[0], v2c.OctetString('You queried readNextVars OID %s' % str(currentDT)))])
return retItem
mibBuilder = snmpContext.getMibInstrum().getMibBuilder()
# mibInstrum = instrum.MibInstrumController(mibBuilder)
MibScalar, MibScalarInstance = mibBuilder.importSymbols(
'SNMPv2-SMI', 'MibScalar', 'MibScalarInstance'
)
class MyStaticMibScalarInstance(MibScalarInstance):
def getValue(self, name, idx):
currentDT = datetime.datetime.now()
return self.getSyntax().clone(
'Hello World! It\'s currently: ' + str(currentDT)
)
mibBuilder.exportSymbols(
'__MY_MIB', MibScalar((1, 3, 6, 1, 2, 1, 1, 1), v2c.OctetString()),
MyStaticMibScalarInstance((1, 3, 6, 1, 2, 1, 1, 1), (0,), v2c.OctetString())
)
# Create multiple independent trees of MIB managed objects (empty so far)
mibTreeA = EchoMibInstrumController()
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)
oid, val = (), None
# logging.debug('done')
# 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
when I ever I do snmpwalk like
snmpwalk -v3 -u usr-md5-none -l authNoPriv -A authkey1 -n context-a 192.168.2.233 .1.3.6
It giving reply like
SNMPv2-SMI::dod = STRING: "You queried readNextVars OID 2019-11-21 19:18:22.566000"
Error: OID not increasing: SNMPv2-SMI::dod
>= SNMPv2-SMI::dod
So my doubt is what I am doing wrong and how to increase this OID ?
Your server (agent) should never return lesser or equal OIDs than arrived with GETNEXT/GETBULK commands.
With your code, make sure that readNextVars
always returns increasing OIDs.
SNMP manager has a check for that condition, otherwise manager-agent pair may engage in an endless exchange.