2012-04-20 217 views
5

PySNMP无法识别响应

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的统计:

/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 } } 
[email protected]@.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 } } 
[email protected]@.I..]</.]<....'.N.\0D.....public.7....;.......0)0'..+..........)[email protected] 

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 } } 
[email protected]@.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 } } 
[email protected]@.I..]</.]<....'.N.\0D.....public.7....;.......0)0'..+..........)[email protected] 

我们可以看到,设备返回响应.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

你们能帮我吗?预先感谢并抱歉我的英语。

回答

4

您的SNMP代理似乎产生损坏的SNMP消息。虽然IPv4地址长度为四个八位字节,但您的代理报告八个八位字节的值。

根据SNMP RFC,pysnmp会丢弃格式错误的SNMP消息并重试原始请求几次,以期获得正确的响应。

为了pysnmp与具体格式不正确IP地址值的工作,你可以在运行时修补的Ip地址类,使其从一个可能更长初始化他仅用四大主导字节:

>>> 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 
+0

再次谢谢:) – 2012-04-23 06:32:24