Pysnmp не може да получи множество oid, ако един от тях не е намерен с помощта на SNMPv1

Когато използвам pysnmp и се опитвам да получа множество oids в една команда getCmd, но един от oids не съществува, тогава не мога да получа нито една от стойностите на oids, освен ако не използвам 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 съществуват, получавам две стойности.
Ако поне един от oids не съществува, тогава всички стойности ще бъдат „В момента не съществува такъв обект в този OID“.
Мога да използвам asyncGetCmd команда за получаване на множество oids, но това не е това, което искам.
По принцип ще трябва да отворя нишка за всеки 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()

Как мога да използвам pysnmp, за да получа множество oids, дори ако някои от oids не съществуват?


person yuval    schedule 31.08.2015    source източник


Отговори (1)


Опитвате ли се да съберете съществуващи променливи от 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 Agent, когато поне една променлива липсва.

Имам предвид v1->v2c PDU превод тук, защото pysnmp API, който използвате, работи като v2c обект на ниво PDU API, независимо от версията на SNMP, която партньорът говори.

Ако смятате, че вашият конкретен агент v1 все още връща нещо смислено, дори когато се докладва състояние на грешка, можете да използвате API на ниво пакет за работа с SNMPv1 PDU, тъй като това няма да извика код за транслация на v1->v2c PDU, който изхвърля всичко в отговора на v1. Преди да опитате това, можете да активирате отстраняването на грешки в pysnmp, за да видите какво всъщност има в v1 RESPONSE PDU, който получавате.

Ако смятате, че това поведение на pysnmp противоречи на SNMP стандартите, моля, разяснете мнението си.

person Ilya Etingof    schedule 31.08.2015