";错误:OID未增加“;使用php-snmpwalk


"Error: OID not increasing" with php snmpwalk

我使用PHP 5.3和SNMP在未按正确顺序返回的OID节点上执行snmpwalk。因此,我得到了错误"错误:OID未增加",我找不到忽略这一点的方法。

或者,我想我可以执行一系列snmpgetnext命令来手动执行漫游,但我不知道如何获取下一个OID值来在上发出下一个getnext命令

http://www.php.net/manual/en/ref.snmp.php

任何关于这两种解决方案的建议都将是巨大的帮助。谢谢

我试图检索的bash脚本是:

snmpwalk -c public -v 1 -Cc 10.3.1.42 1.0.8802.1.1.2.1.4.1.1.9

无序的结果是:

iso.0.8802.1.1.2.1.4.1.1.9.340550.15.15 = STRING: "Switch Name"
iso.0.8802.1.1.2.1.4.1.1.9.29566.16.16 = STRING: "Switch Name"
iso.0.8802.1.1.2.1.4.1.1.9.29486.17.17 = STRING: "Switch Name"
iso.0.8802.1.1.2.1.4.1.1.9.101547.18.18 = STRING: "Switch Name"
iso.0.8802.1.1.2.1.4.1.1.9.399668.19.19 = STRING: "Switch Name"

编辑:看起来这可能只有使用PHP 5.4或更高版本才能实现;"getnext"函数族返回实际OID的能力直到那时才被引入。

"getnext"功能的一部分神奇之处在于,它为您提供下一个OID和值。然而,您确实需要说服PHP以合理的格式将其提供给您。直观的方法最终只提供下一个OID的,而没有其他任何帮助。

然而,首先,您可以使用这些选项使PHP返回一组更有意义的信息。特别是,我们希望OID是原始的数字形式。此外,我们希望对象保存该值,这样我们就可以检查返回的值的类型并对其进行适当处理(例如,区分文本、整数、计数器等):

// Note: Prior to PHP 5.4.0, SNMP_VALUE_OBJECT implied SNMP_VALUE_PLAIN. 
snmp_set_valueretrieval( SNMP_VALUE_OBJECT | SNMP_VALUE_PLAIN );
snmp_set_quick_print( 1 );
snmp_set_enum_print( 0 );
snmp_set_oid_output_format( SNMP_OID_OUTPUT_NUMERIC );

基本上,所有这些加在一起使得输出是机器可读的,而不是相当愚蠢的默认值。

这样,您就可以让PHP为您获取下一个OID:

$result = @snmp2_getnext( $ipAddress, $communityString, [ $oidString ] );

请注意,传入的OID("$oidString")是作为数组的唯一元素传入的,这一点非常重要。这会导致PHP返回一个数组,其中该数组的索引下一个OID。因为我们告诉PHP我们想要数字输出,所以我们可以有意义地读取/解析这个OID。

$nextOid = key( $result );
$nextValue = $result[ $nextOid ];

例如,您可以尝试OID为".1.3.6.1"("internet")。在这种情况下,下一个OID可能是".1.1.3.6.1.2.1.1.1.0"("sysDescr.0")或其他OID(即,以"下一个"为准)。然后,您可以获取"$nextId"并将其反馈给用户,直到完成为止。

请注意,下一个OID不必"位于"您提供的原始OID之下。因此,您可能需要检查以确保返回的OID在您提供的第一个OID的范围内(如果您对"snmpwalk"替换感兴趣)。

此外,由于OID以文本形式返回,您可能希望使用PHP所具有的自然排序函数来确定下一个OID是否"增加"。

最后,请记住,PHP对不同版本的SNMP使用不同的函数。他们确实添加了一个可以实例化的"SNMP"类,但我还没有玩太多。

对于PHP 5.3,您可以使用:

function snmprealwalk2($host, $community, $object_id){
    exec("snmpwalk -c ".$community." -v1 -Cc ".$host." ".$object_id, $snmpWalkReturn);
    foreach($snmpWalkReturn as $value){
            $oid = explode("=", $value);
            $walk[trim($oid[0])] = trim($oid[1]);
    }
    return $walk;
}

NetSNMP的对象版本有一个标志,可以绕过有序OID的需要。

<?php
  $dataSNMP = array();  
  $ipDevice = "10.206.4.38";
  $SNMP = new SNMP(1, $ipDevice, "public");
  $SNMP->oid_increasing_check = false;
  $dataSNMP = $SNMP->walk("1.3.6.1.4.1.14988.1.1.1.3.1.8");
  $SNMP->close();
?>

使用此功能,您将在没有任何警告的情况下获得所有数据。唯一的问题是您需要PHP>=5.4.0