etingof / pysnmp

Python SNMP library
http://snmplabs.com/pysnmp/
BSD 2-Clause "Simplified" License
581 stars 200 forks source link

hlapi.bulkCmd with maxRepetitions=1 or (num_results+1) reports additional "No more variables left in this MIB View" #270

Open gclinch opened 5 years ago

gclinch commented 5 years ago

This could be similar to #169.

A bulkCmd with maxRepetitions = 1 or (expected number of records+1) causes an additional result to be generated, with the value "No more variables left in this MIB View". I haven't seen this happen for any other value of maxRepetitions.

My test code is at the end, I'm using sysORID simply as a static-length table. The parameter is the maxRepetitions to send:

Problematic:

$ python3 bulk.py 1 | tail -3
SNMPv2-MIB::sysORID.9 = SNMPv2-SMI::snmpModules.13.3.1.3
SNMPv2-MIB::sysORID.10 = SNMPv2-SMI::mib-2.92
SNMPv2-MIB::sysORID.10 = No more variables left in this MIB View

$ python3 bulk.py 11 | tail -3
SNMPv2-MIB::sysORID.9 = SNMPv2-SMI::snmpModules.13.3.1.3
SNMPv2-MIB::sysORID.10 = SNMPv2-SMI::mib-2.92
SNMPv2-MIB::sysORID.10 = No more variables left in this MIB View

Fine:

$ python3 bulk.py 10 | tail -3
SNMPv2-MIB::sysORID.8 = SNMPv2-SMI::mib-2.50
SNMPv2-MIB::sysORID.9 = SNMPv2-SMI::snmpModules.13.3.1.3
SNMPv2-MIB::sysORID.10 = SNMPv2-SMI::mib-2.92

$ python3 bulk.py 12 | tail -3
SNMPv2-MIB::sysORID.8 = SNMPv2-SMI::mib-2.50
SNMPv2-MIB::sysORID.9 = SNMPv2-SMI::snmpModules.13.3.1.3
SNMPv2-MIB::sysORID.10 = SNMPv2-SMI::mib-2.92

Test code:

import sys
from pysnmp.hlapi import *

repetitions=int(sys.argv[1])

for (errorIndication,
     errorStatus,
     errorIndex,
     varBinds) in bulkCmd(SnmpEngine(),
                          CommunityData('public'),
                          UdpTransportTarget(('127.0.0.1', 161)),
                          ContextData(),
                          0, repetitions,
                          ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysORID')),
                          lexicographicMode=False):

    for varBind in varBinds:
        print(' = '.join([x.prettyPrint() for x in varBind]))
lextm commented 2 months ago

The behavior is desired if you take a look at the actual packets sent over the wire.

When you set non-repeaters to 0 and max-repetitions to 1, it means that the agent response can only contain a single variable binding. And in that case, an extra round-trip is required to determine if the end of MIB view is reached, which leads to the extra line of SNMPv2-MIB::sysORID.10 = No more variables left in this MIB View.

Of course to avoid confusion, this extra varbind should be ignored, and not returned by bulkCmd (or bulkWalkCmd in release 6.0+).

lextm commented 2 months ago

Resolved in release 7.0.2.