如果使用 SNMPv1 找不到其中之一,则 Pysnmp 无法获取多个 oid
Pysnmp can't get multiple oids if one of them is not found using SNMPv1
当我使用 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 currently exists at this 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?
您是否尝试从包含不存在变量的 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 代理仍然 returns 一些有意义的东西,即使在报告错误状态的情况下,您可以使用 packet-level API to work with SNMPv1 PDU, as that would not invoke v1->v2c PDU translation code trashing everything in v1 response. Before trying that you may wish to enable pysnmp debugging 查看您得到的 v1 RESPONSE PDU 中的实际内容.
如果您认为此 pysnmp 行为违反 SNMP 标准,请详细说明您的观点。
当我使用 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 currently exists at this 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?
您是否尝试从包含不存在变量的 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 代理仍然 returns 一些有意义的东西,即使在报告错误状态的情况下,您可以使用 packet-level API to work with SNMPv1 PDU, as that would not invoke v1->v2c PDU translation code trashing everything in v1 response. Before trying that you may wish to enable pysnmp debugging 查看您得到的 v1 RESPONSE PDU 中的实际内容.
如果您认为此 pysnmp 行为违反 SNMP 标准,请详细说明您的观点。