如何确认pysnmp中上下文已正确设置并启用自定义处理器?
解决pysnmp自定义上下文及处理器未生效问题
问题原因
SNMP v2c/v3请求默认不会携带上下文信息,服务器会优先匹配空上下文(b'')绑定的处理器。如果仅注册自定义上下文但保留默认空上下文,请求会走默认处理器;注销空上下文后,因无匹配上下文导致服务器无响应。
解决方案
方案1:客户端请求时指定自定义上下文
使用snmpget的-Cn参数显式指定上下文名称,让服务器匹配到你注册的mq-context:
snmpget -v2c -c public -Cn mq-context 127.0.0.1:1610 1.3.6.1.2.1.1.9.1.3.1
方案2:服务器端将自定义处理器绑定到空上下文(作为默认)
不要注销空上下文,而是将其对应的处理器替换为你的EchoMibInstrumController,这样不带上下文的请求会自动使用自定义处理器:
from pysnmp.entity import engine, config from pysnmp.entity.rfc3413 import cmdrsp, context from pysnmp.proto.api import v2c from pysnmp.smi import instrum, builder from pysnmp.carrier.asyncore.dgram import udp # 自定义MIB处理器 class EchoMibInstrumController(instrum.AbstractMibInstrumController): def readMibObjects(self, varBinds, **kwargs): # 按SNMP数据类型返回固定值,适配请求OID的类型要求 return [(oid, v2c.OctetString("Example")) for oid, _ in varBinds] # 初始化SNMP引擎 snmpEngine = engine.SnmpEngine() # 配置V2C社区字符串 config.addV2cUser(snmpEngine, 'public') # 创建MIB构建器 mibBuilder = builder.MibBuilder() # 初始化SNMP上下文 snmpContext = context.SnmpContext(snmpEngine) # 注册自定义上下文(用于需要指定上下文的请求) snmpContext.registerContextName(v2c.OctetString('mq-context'), EchoMibInstrumController(mibBuilder)) # 关键操作:将自定义处理器绑定到空上下文,作为默认处理器 snmpContext.registerContextName(v2c.OctetString(b''), EchoMibInstrumController(mibBuilder)) # 配置UDP传输监听 config.addSocketTransport( snmpEngine, udp.domainName, udp.UdpTransport().openServerMode(('127.0.0.1', 1610)) ) # 注册GET命令响应器 cmdrsp.GetCommandResponder(snmpEngine, snmpContext) # 启动服务器 snmpEngine.transportDispatcher.jobStarted(1) try: snmpEngine.transportDispatcher.runDispatcher() except KeyboardInterrupt: pass finally: snmpEngine.transportDispatcher.closeDispatcher()
方案3:自定义上下文匹配逻辑(复杂场景)
如果需要更灵活的上下文路由(比如根据请求来源动态匹配),可以继承SnmpContext类重写getMibInstrum方法,自定义上下文匹配规则:
class CustomSnmpContext(context.SnmpContext): def getMibInstrum(self, contextName): # 如果请求无上下文,返回自定义处理器 if contextName == v2c.OctetString(b''): return EchoMibInstrumController(self.mibBuilder) # 其他情况按原有逻辑匹配上下文 return super().getMibInstrum(contextName) # 使用自定义上下文类 snmpContext = CustomSnmpContext(snmpEngine) snmpContext.registerContextName(v2c.OctetString('mq-context'), EchoMibInstrumController(mibBuilder))
注意事项
- 自定义处理器的返回值必须符合SNMP数据类型要求,比如请求
sysORDescr.1(字符串类型)时,要返回v2c.OctetString而非普通字符串。 - 确保pysnmp版本与代码兼容,建议使用最新稳定版。
内容的提问来源于stack exchange,提问作者Sebastian Veliz
相关产品推荐
相关产品推荐

