如果使用 SNMPv1 找不到其中一个,则 Pysnmp 无法获取多个 oid。



当我使用pysnmp并尝试在一个getCmd命令中获得多个oid时,但是其中一个oid不存在,那么我无法接收任何oid的值,除非我使用SNMPv2或SNMPv3(更改代码中的mpmodel)

from pysnmp.entity.rfc3413.oneliner import cmdgen
from pysnmp.smi import builder, view, error
def cbFun_OID(sendRequestHandle, errorIndication, errorStatus, errorIndex, varBinds, cbCtx):
    (authData, transportTarget) = cbCtx
    for oid, val in varBinds:
        print val.prettyPrint()
ip='192.168.0.101'
cmdGen = cmdgen.AsynCommandGenerator()
cmdGen.getCmd(
   cmdgen.CommunityData('public', mpModel=0),
   cmdgen.UdpTransportTarget((ip, 161)),
   ((1,3,6,1,2,1,43,10,2,1,4,1,1),(1,3,6,1,2,1,43,5,1,1,1,1,123456)),
   (cbFun_OID, (cmdgen.CommunityData('public', mpModel=0), cmdgen.UdpTransportTarget((ip, 161)))))
cmdGen.snmpEngine.transportDispatcher.runDispatcher()

如果两个oid都存在,则得到两个值。
如果OID中至少有一个不存在,那么所有的值都将是'No Such Object当前存在于此OID'。
我可以使用asyncGetCmd命令获得多个oid,但这不是我想要的。
我基本上需要为每个oid打开一个线程并单独扫描它,这是一个非常低效的方法。
例如:

from pysnmp.entity.rfc3413.oneliner import cmdgen
from pysnmp.smi import builder, view, error
def cbFun_OID(sendRequestHandle, errorIndication, errorStatus, errorIndex, varBinds, cbCtx):
(authData, transportTarget) = cbCtx
for oid, val in varBinds:
    print val.prettyPrint()
ip='192.168.0.101'
cmdGen = cmdgen.AsynCommandGenerator()
cmdGen.asyncGetCmd(
   cmdgen.CommunityData('public', mpModel=0),
   cmdgen.UdpTransportTarget((ip, 161)),
   ((1,3,6,1,2,1,43,10,2,1,4,1,1),),
   (cbFun_OID, (cmdgen.CommunityData('public', mpModel=0), cmdgen.UdpTransportTarget((ip, 161)))))
cmdGen.asyncGetCmd(
   cmdgen.CommunityData('public', mpModel=0),
   cmdgen.UdpTransportTarget((ip, 161)),
   ((1,3,6,1,2,1,43,5,1,1,1,1,123456),),
   (cbFun_OID, (cmdgen.CommunityData('public', mpModel=0), cmdgen.UdpTransportTarget((ip, 161)))))
cmdGen.snmpEngine.transportDispatcher.runDispatcher()

如何使用pysnmp获取多个oid,即使有些oid不存在?

您是否试图从包含不存在变量的SNMP v1响应中收集现有变量?在这种情况下,我不确定它是否符合SNMP标准。根据RFC 2576:

4.1.2.3.1. If the error-status is anything other than noError,
  ...
  -  The variable binding list of the response PDU SHALL be made
     exactly the same as the variable binding list that was received
     in the original request.

由于GET请求通常包含null作为值,因此无论何时至少缺少一个变量,您都无法[可靠地]从SNMP v1 Agent接收任何值。

我在这里指的是v1->v2c PDU转换,因为您使用的SNMP API在PDU API级别作为v2c实体工作,而不管SNMP版本对等体正在谈论什么。

如果您认为您的特定v1代理仍然返回一些有意义的东西,即使在报告错误状态的同时,您可以使用包级API与SNMPv1 PDU一起工作,因为这不会调用v1->v2c PDU转换代码来破坏v1响应中的所有内容。在尝试之前,您可能希望启用psnmp调试,看看您收到的v1 RESPONSE PDU中实际是什么。

如果您认为这种SNMP行为违反了SNMP标准,请详细说明您的观点。

最新更新