0

If I try something like this, I got

ValueError: too many values to unpack (expected 4)

Can someone explain why?

from pysnmp.hlapi import *

errorIndication, errorStatus, errorIndex, varBinds =  nextCmd(
    SnmpEngine(),
    CommunityData('public', mpModel=1),
    UdpTransportTarget(('giga-int-2', 161)),
    ContextData(),
    ObjectType(ObjectIdentity('1.3.6.1.2.1.31.1.1.1.1')),
   lexicographicMode=False
)
if errorIndication:
    print(errorIndication)
elif errorStatus:
    print('%s at %s' % (errorStatus.prettyPrint(), errorIndex and varBinds[int(errorIndex) - 1][0] or '?'))
else:
    for v in varBinds:
        for name, val in v:
            print('%s = %s' % (name.prettyPrint(), val.prettyPrint()))
KenHBS
  • 6,756
  • 6
  • 37
  • 52
Celio
  • 23
  • 5
  • 1
    Possible duplicate of [Python ValueError: too many values to unpack](https://stackoverflow.com/questions/7053551/python-valueerror-too-many-values-to-unpack) – Alessandro Da Rugna Sep 22 '17 at 12:06
  • 1
    Possible duplicate of ['too many values to unpack', iterating over a dict. key=>string, value=>list](https://stackoverflow.com/questions/5466618/too-many-values-to-unpack-iterating-over-a-dict-key-string-value-list) – chrisis Sep 22 '17 at 12:22

2 Answers2

0

The nextCmd() function (as well as other pysnmp functions) returns a single Python generator object which you should iterate over:

>>> from pysnmp.hlapi import *
>>> g = nextCmd(SnmpEngine(),
...             CommunityData('public'),
...             UdpTransportTarget(('demo.snmplabs.com', 161)),
...             ContextData(),
...             ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr')))
>>> next(g)
(None, 0, 0, [ObjectType(ObjectIdentity(ObjectName('1.3.6.1.2.1.1.1.0')),
              DisplayString('SunOS zeus.snmplabs.com 4.1.3_U1 1 sun4m'))])

You can use this generator like any Python iterable, for example in a loop. Or, if you need to run just a single request/response, you can simply call next on it.

On each iteration pysnmp sends out a request (one or more depending of circumstances) asking for a single OID which is greater than the previous one. That way you "walk" the SNMP agent till you break out of the loop or exhaust OIDs on agent's side.

Your mistake here is that you are expecting pysnmp's nextCmd to run SNMP query immediately and return a value. Instead pysnmp gives you a generator-coroutine which you can use repeatedly to perform multiple queries (you can also .send() it OIDs to query).

Ilya Etingof
  • 5,440
  • 1
  • 17
  • 21
0

Thanks for the answer. I rewrote the code. Now it's doing what I wanted. It just searches through the '1.3.6.1.2.1.31.1.1.1.x' tree.

from pysnmp.hlapi import *

for errorIndication, errorStatus, errorIndex, varBinds in  nextCmd(
    SnmpEngine(),
    CommunityData('public', mpModel=1),
    UdpTransportTarget(('giga-int-2', 161)),
    ContextData(),
    ObjectType(ObjectIdentity('1.3.6.1.2.1.31.1.1.1.1')),
    lexicographicMode=False
):
    if errorIndication:
        print(errorIndication)
    elif errorStatus:
        print('%s at %s' % (errorStatus.prettyPrint(), errorIndex and varBinds[int(errorIndex) - 1][0] or '?'))
    else:
        for v in varBinds:
            print(v.prettyPrint())

SNMPv2-SMI::mib-2.31.1.1.1.1.1 = sc0
SNMPv2-SMI::mib-2.31.1.1.1.1.2 = sl0
SNMPv2-SMI::mib-2.31.1.1.1.1.3 = sc1
SNMPv2-SMI::mib-2.31.1.1.1.1.5 = VLAN-1
SNMPv2-SMI::mib-2.31.1.1.1.1.6 = VLAN-1002
...
Celio
  • 23
  • 5