我使用以下简单脚本:
from pysnmp.entity.rfc3413.oneliner import cmdgen
errorIndication, errorStatus, errorIndex, \
varBindTable = cmdgen.CommandGenerator().bulkCmd(
cmdgen.CommunityData('test-agent', 'public'),
cmdgen.UdpTransportTarget(('IP.IP.IP.IP', 161)),
0,
1,
(1,3,6,1,2,1,4,24,4,1,2,169,254)
)
if errorIndication:
print errorIndication
else:
if errorStatus:
print '%s at %s\n' % (
errorStatus.prettyPrint(),
errorIndex and varBindTable[-1][int(errorIndex)-1] or '?'
)
else:
for varBindTableRow in varBindTable:
for name, val in varBindTableRow:
print '%s = %s' % (name.prettyPrint(), val.prettyPrint())
从命令行使用snmpwalk返回此设备将返回预期结果。但 脚本返回超时前未收到SNMP响应。如果我省略这个OID,那么一切正常。 所以问题在于这个OID
这里是tcpdump stats:
/usr/sbin/tcpdump -nn -vv -s0 -A host HOST and udp
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
12:15:31.494920 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto: UDP (17), length: 77) IP.IP.IP.IP.47911 > IP.IP.IP.IP.161: [bad udp cksum 4b7d!] { SNMPv2c { GetBulk(34) R=8993731 N=0 M=1 .1.3.6.1.2.1.4.24.4.1.2.169.254 } }
E..M..@.@.I..]<..]</.'...9.S0/.....public."....;.......0.0...+..........).~..
12:15:31.495666 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto: UDP (17), length: 98) IP.IP.IP.IP.161 > IP.IP.IP.IP.47911: [udp sum ok] { SNMPv2c { GetResponse(55) R=8993731 .1.3.6.1.2.1.4.24.4.1.2.169.254.0.0.0.0.255.255.0.0.0.0.0=[inetaddr len!=4]0.0.255.255.0.0.0.0 } }
E..b..@.@.I..]</.]<....'.N.\0D.....public.7....;.......0)0'..+..........).~.............@.........
12:15:32.500226 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto: UDP (17), length: 77) IP.IP.IP.IP.47911 > IP.IP.IP.IP.161: [bad udp cksum 4b7d!] { SNMPv2c { GetBulk(34) R=8993731 N=0 M=1 .1.3.6.1.2.1.4.24.4.1.2.169.254 } }
E..M..@.@.I..]<..]</.'...9.S0/.....public."....;.......0.0...+..........).~..
12:15:32.500624 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto: UDP (17), length: 98) IP.IP.IP.IP.161 > IP.IP.IP.IP.47911: [udp sum ok] { SNMPv2c { GetResponse(55) R=8993731 .1.3.6.1.2.1.4.24.4.1.2.169.254.0.0.0.0.255.255.0.0.0.0.0=[inetaddr len!=4]0.0.255.255.0.0.0.0 } }
E..b..@.@.I..]</.]<....'.N.\0D.....public.7....;.......0)0'..+..........).~.............@.........
正如我们所看到的,设备返回响应.1.3.6.1.2.1.4.24.4.1.2.169.254.0.0.0.0.255.255.0.0.0.0.0=[inetaddr len!=4]0.0.255.255.0.0.0.0
,但没有任何反应,pysnmp只是一次又一次地继续尝试此OID的值.snmpwalk将此响应识别为IP ADDRESS 0.0.255.255
答案 0 :(得分:4)
您的SNMP代理似乎会生成损坏的SNMP消息。虽然IPv4地址长度为四个八位字节,但您的代理程序报告的值为八个八位字节。
根据SNMP RFC,pysnmp丢弃格式错误的SNMP消息并重试原始请求几次,以期得到正确的响应。
要使pysnmp使用特定格式错误的IP地址值,您可以在运行时修补其IpAddress类,使其仅占用可能更长的初始化程序中的四个前导八位字节:
>>> def ipAddressPrettyIn(self, value):
... return origIpAddressPrettyIn(self, value[:4])
...
>>> origIpAddressPrettyIn = v2c.IpAddress.prettyIn
>>> v2c.IpAddress.prettyIn = ipAddressPrettyIn
>>>
>>> msg, rest = decoder.decode(wholeMsg, asn1Spec=v2c.Message())
>>> print msg.prettyPrint()
Message:
version='version-2'
community=public
data=PDUs:
response=ResponsePDU:
request-id=6564368
error-status='noError'
error-index=0
variable-bindings=VarBindList:
VarBind:
name=1.3.6.1.2.1.4.24.4.1.2.169.254.0.0.0.0.255.255.0.0.0.0.0
=_BindValue:
value=ObjectSyntax:
application-wide=ApplicationSyntax:
ipAddress-value=0.0.255.255