调SNMP设备时候遇到了某厂家的奇葩输出,用命令行下的snmpwalk:
$ snmpwalk x.x.x.x -c "public" -v 2c 1.3.6.1.4.1.5105.80.6.2.1.47 SNMPv2-SMI::enterprises.5105.80.6.2.1.47.3589396343 = INTEGER: 8 SNMPv2-SMI::enterprises.5105.80.6.2.1.47.3589497833 = INTEGER: 8 SNMPv2-SMI::enterprises.5105.80.6.2.1.47.3589501999 = INTEGER: 8 SNMPv2-SMI::enterprises.5105.80.6.2.1.47.3589331126 = INTEGER: 8 Error: OID not increasing: SNMPv2-SMI::enterprises.5105.80.6.2.1.47.3589501999 >= SNMPv2-SMI::enterprises.5105.80.6.2.1.47.3589331126
查了一下,常规SNMP OID是应该在GETNEXT请求下顺序输出的,每个值是之前一个的+1,为了避免出现数值循环,snmpwalk默认检查数字是否递增;
上面例子中,显然不是如此,这个snmp agent并不使用递增识别码。
这还是好解决的,snmpwalk有个-Cc参数:
-Cc Do not check whether the returned OIDs are increasing. Some agents (LaserJets are an example) return OIDs out of order, but can complete the walk anyway. Other agents return OIDs that are out of order and can cause snmpwalk to loop indefinitely. By default, snmpwalk tries to detect this behavior and warns you when it hits an agent acting illegally. Use -Cc to turn off this check.
不过在PHP中坑就大了,首先最普通的snmp2_walk函数完全没有这些特性支持,wait,还有个snmp2_real_walk?难道之前那个是fake的?搞了半天原来real_walk返回的数组键值是全OID数值,没real那个的键值则仅仅是识别码。这命名还真是够PHP Style啊!
回到原点,把php-snmp模块的函数逐个都点过了,就没有关于OID increase的设置,看了stackoverflow上的某回答,自己实现了用snmp2_getnext来遍历,好我也实现一个,结果没几下就被设备封IP了,原来snmpwalk用的是snmpbulkget 的请求,自己的getnext,则会被设备认为请求过多封了!
还是Google帮我找到了PHP下oid_increasing_check关键字,原来藏在SNMP class(5.4+),所以好好一个snmp2_walk函数就变成这样了:
$snmp = new SNMP(SNMP::VERSION_2C, HOST, COMMUNITY); $snmp->oid_increasing_check = FALSE; $snmp->quick_print = TRUE; $snmp->valueretrieval = SNMP_VALUE_LIBRARY; $snmp->oid_output_format = SNMP_OID_OUTPUT_NUMERIC; $data = $snmp->walk($cmd, TRUE);
对了,walk()的那个TRUE参数,不TRUE就是以前的real_walk,TRUE了就是fake walk~~~~
转载请注明:爱开源 » Error: OID not increasing