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

时间:2015-08-31 07:23:17

标签: python snmp pysnmp

当我使用pysnmp并尝试在一个getCmd命令中获取多个oid,但其中一个oids不存在时,我无法接收任何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()

如果两个oids都存在,我会得到两个值 如果至少有一个oid不存在,那么所有值都将是“此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()

即使某些oid不存在,我怎样才能使用pysnmp获取多个oid?

1 个答案:

答案 0 :(得分:3)

您是否尝试从包含不存在变量的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代理接收任何值。

我指的是这里的v1-> v2c PDU转换,因为您使用的pysnmp API在PDU API级别充当v2c实体,无论同级正在谈论的SNMP版本。

如果您认为您的特定v1代理仍会返回一些有意义的内容,即使报告了错误状态,您也可以使用packet-level API来处理SNMPv1 PDU,因为它不会调用v1-> v2c PDU转换代码废弃v1响应中的所有内容。在尝试之前,您可能希望enable pysnmp debugging查看您所获得的v1 RESPONSE PDU中的实际内容。

如果您认为此pysnmp行为符合SNMP标准,请详细说明您的观点。