When following the SNMPv2c example found here https://docs.lextudio.com/pysnmp/examples/v1arch/asyncio/manager/cmdgen/walking-operations I am seeing additional returned information which I haven't requested as part of the SNMPBulkWalk.
For example when running "snmpbulkwalk -v2c -c 1.3.6.1.2.1.2.2.1.2 from linux CLI I receive a list of all interface names of the device I am querying.
:~ $ snmpbulkwalk -v2c -c SNMPubliV2c 10.180.0.8 1.3.6.1.2.1.2.2.1.2
iso.3.6.1.2.1.2.2.1.2.1 = STRING: "lo"
iso.3.6.1.2.1.2.2.1.2.2 = STRING: "eth3"
iso.3.6.1.2.1.2.2.1.2.3 = STRING: "eth0"
iso.3.6.1.2.1.2.2.1.2.4 = STRING: "eth1"
iso.3.6.1.2.1.2.2.1.2.5 = STRING: "eth2"
iso.3.6.1.2.1.2.2.1.2.6 = STRING: "npi0"
iso.3.6.1.2.1.2.2.1.2.7 = STRING: "npi1"
iso.3.6.1.2.1.2.2.1.2.8 = STRING: "npi2"
iso.3.6.1.2.1.2.2.1.2.9 = STRING: "npi3"
iso.3.6.1.2.1.2.2.1.2.10 = STRING: "loop0"
iso.3.6.1.2.1.2.2.1.2.11 = STRING: "loop1"
iso.3.6.1.2.1.2.2.1.2.12 = STRING: "loop2"
iso.3.6.1.2.1.2.2.1.2.13 = STRING: "loop3"
iso.3.6.1.2.1.2.2.1.2.14 = STRING: "imq0"
iso.3.6.1.2.1.2.2.1.2.15 = STRING: "eth1.130"
iso.3.6.1.2.1.2.2.1.2.17 = STRING: "pppoe0"
Where as when I run the example code but with my and 1.3.6.1.2.1.2.2.1.2. I seem to get a whole bunch of additional data. I have copy a section of it here but there is way more being spewed out to console.
...
1.3.6.1.4.1.2021.13.15.1.1.10.12 - 0
1.3.6.1.4.1.2021.13.15.1.1.10.13 - 0
1.3.6.1.4.1.2021.13.15.1.1.10.14 - 0
1.3.6.1.4.1.2021.13.15.1.1.10.15 - 0
1.3.6.1.4.1.2021.13.15.1.1.10.16 - 0
1.3.6.1.4.1.2021.13.15.1.1.10.17 - 0
1.3.6.1.4.1.2021.13.15.1.1.10.18 - 0
1.3.6.1.4.1.2021.13.15.1.1.11.1 - 0
1.3.6.1.4.1.2021.13.15.1.1.11.2 - 0
1.3.6.1.4.1.2021.13.15.1.1.11.3 - 0
1.3.6.1.4.1.2021.13.15.1.1.11.4 - 0
1.3.6.1.4.1.2021.13.15.1.1.11.5 - 0
1.3.6.1.4.1.2021.13.15.1.1.11.6 - 0
1.3.6.1.4.1.2021.13.15.1.1.11.7 - 0
1.3.6.1.4.1.2021.13.15.1.1.11.8 - 0
1.3.6.1.4.1.2021.13.15.1.1.11.9 - 0
...
I have found if I put an exit(0) above the return wholeMsg from the SNMPv2c example. It prints only the requested information to the terminal. But then of cause the script stops...
I am pretty new to all of this and stepping through the code with print statements I couldn't really identify how additional mibs are being returned when I have only specified one value in headVars.
from pysnmp.carrier.asyncio.dispatch import AsyncioDispatcher
from pysnmp.carrier.asyncio.dgram import udp
from pyasn1.codec.ber import encoder, decoder
from pysnmp.proto.api import v2c
# SNMP table header
headVars = [v2c.ObjectIdentifier((1,3,6,1,2,1,2,2,1,2))]
# Build PDU
reqPDU = v2c.GetBulkRequestPDU()
v2c.apiBulkPDU.setDefaults(reqPDU)
v2c.apiBulkPDU.setNonRepeaters(reqPDU, 0)
v2c.apiBulkPDU.setMaxRepetitions(reqPDU, 25)
v2c.apiBulkPDU.setVarBinds(reqPDU, [(x, v2c.null) for x in headVars])
# Build message
reqMsg = v2c.Message()
v2c.apiMessage.setDefaults(reqMsg)
v2c.apiMessage.setCommunity(reqMsg, "<COMMUNITY")
v2c.apiMessage.setPDU(reqMsg, reqPDU)
# noinspection PyUnusedLocal
def cbRecvFun(
transportDispatcher,
transportDomain,
transportAddress,
wholeMsg,
reqPDU=reqPDU,
headVars=headVars,
):
while wholeMsg:
rspMsg, wholeMsg = decoder.decode(wholeMsg, asn1Spec=v2c.Message())
rspPDU = v2c.apiMessage.getPDU(rspMsg)
# Match response to request
if v2c.apiBulkPDU.getRequestID(reqPDU) == v2c.apiBulkPDU.getRequestID(rspPDU):
# Format var-binds table
varBindTable = v2c.apiBulkPDU.getVarBindTable(reqPDU, rspPDU)
# Check for SNMP errors reported
errorStatus = v2c.apiBulkPDU.getErrorStatus(rspPDU)
if errorStatus and errorStatus != 2:
errorIndex = v2c.apiBulkPDU.getErrorIndex(rspPDU)
print(
"{} at {}".format(
errorStatus.prettyPrint(),
errorIndex and varBindTable[int(errorIndex) - 1] or "?",
)
)
transportDispatcher.jobFinished(1)
break
# Report SNMP table
for tableRow in varBindTable:
for name, val in tableRow:
print(f'{name} - {val}')
# Stop on EOM
for oid, val in varBindTable[-1]:
if not isinstance(val, v2c.Null):
break
else:
transportDispatcher.jobFinished(1)
continue
# Generate request for next row
v2c.apiBulkPDU.setVarBinds(
reqPDU, [(x, v2c.null) for x, y in varBindTable[-1]]
)
v2c.apiBulkPDU.setRequestID(reqPDU, v2c.getNextRequestID())
transportDispatcher.sendMessage(
encoder.encode(reqMsg), transportDomain, transportAddress
)
# <-----Placing exit(0) here prints only the MIBS I am looking for.
return wholeMsg
transportDispatcher = AsyncioDispatcher()
transportDispatcher.registerRecvCbFun(cbRecvFun)
transportDispatcher.registerTransport(
udp.DOMAIN_NAME, udp.UdpAsyncioTransport().openClientMode()
)
transportDispatcher.sendMessage(
encoder.encode(reqMsg), udp.DOMAIN_NAME, ("<IPADDRESS>", 161)
)
transportDispatcher.jobStarted(1)
# Dispatcher will finish as job#1 counter reaches zero
transportDispatcher.runDispatcher(3)
transportDispatcher.closeDispatcher()
It looks like this library went though a period of not being managed and is now once again being managed but a lot has changed and other stackoverflow records either aren't relevant anymore or point of links which dont exist.
Any help would really be appreciated as I want to learn but I am very stumped.
This is simply because the sample script is designed to perform a complete WALK defined in IETF RFC to discover every following objects, while Net-SNMP snmpbulkwalk command performs a partial WALK and discovers only objects within the subtree of your input OID.
Nothing is wrong here, and the behavior is consistent from 4.x to 7.x.