SNMP Simulator for Testing PySNMP? - python

I am looking for a way to test PySNMP scripts, since it seems like demo.snmplabs.com and snmpsim.try.thola.io are down - at least I can't get a response with the following example script from the PySNMP docs. Are there any other hosts I could try?
from pysnmp.hlapi import *
for (errorIndication,
errorStatus,
errorIndex,
varBinds) in nextCmd(SnmpEngine(),
CommunityData('public'),
UdpTransportTarget(('snmpsim.try.thola.io', 161)),
ContextData(),
ObjectType(ObjectIdentity('1.3.6.1.2.1.1.1.0')),
lookupMib=False):
if errorIndication:
print(errorIndication)
break
elif errorStatus:
print('%s at %s' % (errorStatus.prettyPrint(),
errorIndex and varBinds[int(errorIndex) - 1][0] or '?'))
break
else:
print("hello")
for varBind in varBinds:
print(' = '.join([x.prettyPrint() for x in varBind]))
Response: No SNMP response received before timeout
EDIT: I have tried snmp.live.gambitcommunications.com, demo.snmplabs.com, and snmpsim.try.thola.io so at this point I feel like I'm missing something. Any ideas?

While there were so many attempts to fill the gaps, you will find demo.pysnmp.com a more reliable option from me, as I plan to take over the whole ecosystem, https://github.com/etingof/pysnmp/issues/429

Related

Retrieving printer toner information with pysnmp

I am trying to retrieve printer toner information from networked printers.
I found the following reference record for printer supplies -> http://oidref.com/1.3.6.1.2.1.43.11 (OID = prtMarkerSupplies)
I tried integrating the OID in the following code:
from pysnmp.hlapi import *
iterator = getCmd(
SnmpEngine(),
CommunityData('public', mpModel=0),
UdpTransportTarget(('here goes ip of a printer', 161)),
ContextData(),
ObjectType(ObjectIdentity('SNMPv2-MIB', "prtMarkerSupplies", 0))
)
errorIndication, errorStatus, errorIndex, varBinds = next(iterator)
if errorIndication:
print(errorIndication)
elif errorStatus:
print('%s at %s' % (errorStatus.prettyPrint(),
errorIndex and varBinds[int(errorIndex) - 1][0] or '?'))
else:
for varBind in varBinds:
print(' = '.join([x.prettyPrint() for x in varBind]))
The above code returns:
pysnmp.smi.error.SmiError: No symbol SNMPv2-MIB::prtMarkerSupplies at <pysnmp.smi.builder.MibBuilder object at 0x000001F8D1FC3D00>
How can I retrieve toner information using the SNMP protocol and pysnmp?
Retrieving system information works as intended:
ObjectType(ObjectIdentity('SNMPv2-MIB', "sysDescr", 0))
I used the answer from the following thread -> snmpwalk with PySNMP
Instead of iterating over getCmd, I used SNMP walk to walk through all of the OIDs.

Reading OID and display its variable or name in python using pysnmp

I am trying to write a code in python to run a function that reads the OID variable and name of a device.
I managed to find out their OID's but every time I enter the OID number in my code it shows me there is no OID
here is the Python code using pysnmp:
#########################
from pysnmp.entity.rfc3413.oneliner import cmdgen
cmd_gen = cmdgen.CommandGenerator()
error_indication, error_status, error_index, var_binds = cmd_gen.getCmd(
cmdgen.CommunityData('public'),
cmdgen.UdpTransportTarget(('192.168.178.213', 161)),
'.1.3.6.1.4.1.9986.3.22.1.1.3.1.10')
for name, val in var_binds:
print('%s' % val.prettyPrint())
#################
here is the device with one of the OIDs
There is a simple way of traversing OIDs in SNMP called SNMP WALK. It can be implemented as simple as this:
def walk_mib(ipaddress, oid):
for (errorIndication, errorStatus, errorIndex, varBinds) in nextCmd(SnmpEngine(),
CommunityData('public'),
UdpTransportTarget((ipaddress, 161)),
ContextData(),
ObjectType(ObjectIdentity(oid)),
):
if not errorIndication and not errorStatus:
for varBind in varBinds:
result=' = '.join([x.prettyPrint() for x in varBind])
print(result)
walk_mib('<ip address>', start_oid)

PySNMP 4.4 with Python 2.7 bulkCmd output not including child OID's

To start off with, I'm new to Python and PySNMP. I'm trying to pass a list of network devices to bulkCmd to obtain information on all the physical interfaces.
Currently it is only collecting the first interface and then moves on to the next network device in the list. I have made changes with lexicographic and maxCalls, repetitions but none make any difference.
I have successfully polled all interfaces when sending a single bulkCmd to single network device.
Code:
from pysnmp.hlapi import *
routers = ["router1", "router2"]
#adds routers to getCmd and bulkCmd
def snmpquery (hostip):
errorIndication, errorStatus, errorIndex, varBinds = next (
bulkCmd(SnmpEngine(),
CommunityData('communitystring'),
UdpTransportTarget((hostip, 161)),
ContextData(),
0, 50,
ObjectType(ObjectIdentity('IF-MIB', 'ifDescr')),
ObjectType(ObjectIdentity('IF-MIB', 'ifAlias')),
ObjectType(ObjectIdentity('IF-MIB', 'ifOperStatus')),
lexicographicMode=True
)
)
# Check for errors and print out results
if errorIndication:
print(errorIndication)
elif errorStatus:
print('%s at %s' % (errorStatus.prettyPrint(),
errorIndex and varBinds[int(errorIndex) - 1][0] or '?'))
else:
for varBind in varBinds:
print(' = '.join([x.prettyPrint() for x in varBind]))
# calls snmpquery for all routers in list
for router in routers:
snmpquery(router)
Output:
IF-MIB::ifDescr.1 = GigabitEthernet0/0
IF-MIB::ifAlias.1 = InterfaceDesc
IF-MIB::ifOperStatus.1 = 'up'
IF-MIB::ifDescr.1 = GigabitEthernet0/0
IF-MIB::ifAlias.1 = InterfaceDesc
IF-MIB::ifOperStatus.1 = 'up'
bulkSNMP returns an iterator and you were using next() on it which retrieves only the first of the iterations. You probably got the idea from the PySNMP documentation, which doesn't do a great job of showing how to retrieve all the results.
You should use a for loop to loop over all of the iterations, as follows:
from pysnmp.hlapi import *
routers = ["router1", "router2"]
def snmpquery (hostip):
snmp_iter = bulkCmd(SnmpEngine(),
CommunityData('communitystring'),
UdpTransportTarget((hostip, 161)),
ContextData(),
0, 50,
ObjectType(ObjectIdentity('IF-MIB', 'ifDescr')),
ObjectType(ObjectIdentity('IF-MIB', 'ifAlias')),
ObjectType(ObjectIdentity('IF-MIB', 'ifOperStatus')),
lexicographicMode=True)
for errorIndication, errorStatus, errorIndex, varBinds in snmp_iter:
# Check for errors and print out results
if errorIndication:
print(errorIndication)
elif errorStatus:
print('%s at %s' % (errorStatus.prettyPrint(),
errorIndex and varBinds[int(errorIndex) - 1][0] or '?'))
else:
for varBind in varBinds:
print(' = '.join([x.prettyPrint() for x in varBind]))
# calls snmpquery for all routers in list
for router in routers:
snmpquery(router)
Also, be careful about indentation when posting Python-related questions, as it is significant.
You need to iterate over the generator produced by the bulkCmd function to repeat SNMP queries to pull SNMP managed objects that did not fit into previous response packet(s). Just ditch the next() call and run for loop over bulkCmd().
Side note 1: you may not need lexicographicMode=True if you want to fetch managed objects that reside just under the MIB table columns (e.g. IF-MIB::ifDescr etc).
Side note 2: if you have many SNMP agents on your network, you may consider speeding up the process of data retrieval by talking to the in parallel. You'd use the same getBulk() call, it's just the underlaying network I/O that does the parallelism.

pysnmp - ValueError: too many values to unpack (expected 4)

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()))
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).
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
...

pysnmp output format issue

I am trying to get some snmp variables from cisco routers using PySNMP but I am getting a hex output using prettyprint instead of the output I get from my normal snmp browser.
I have tried multiple encode (hex, utf-8 and ascii) and without encode, always not what I was expecting.
Any ideas?
Thanks
Start discovery of 10.148.8.15
1.3.6.1.2.1.1.1.0 = 0x436973636f20494f5320536f6674776172652c20494f532d584520536f66747761726520285838365f36345f4c494e55585f494f53442d554e4956455253414c4b392d4d292c2056657273696f6e2031352e3228342953352c2052454c4541534520534f4654574152452028666331290d0a546563686e6963616c20537570706f72743a20687474703a2f2f7777772e636973636f2e636f6d2f74656368737570706f72740d0a436f707972696768742028632920313938362d3230313420627920436973636f2053797374656d732c20496e632e0d0a436f6d70696c6564205475652032352d4665622d31342031313a3336206279206d63707265
result = {'error': 1, 'value': "default"}
cmdGen = cmdgen.CommandGenerator()
errorIndication, errorStatus, errorIndex, varBinds = cmdGen.getCmd(
cmdgen.CommunityData(community),
cmdgen.UdpTransportTarget((destination, 161)),
cmdgen.MibVariable(oid)
)
# Check for errors and print out results
if errorIndication:
print(errorIndication)
else:
if errorStatus:
result['error'] = 1
# print('%s at %s' % (
# errorStatus.prettyPrint(),
# errorIndex and varBinds[int(errorIndex)-1] or '?'
# )
# )
else:
result['error'] = 0
for name, val in varBinds:
print('%s = %s' % (name.prettyPrint(), val.prettyPrint()))
result['value'] = val.prettyPrint().encode("ascii")
That is because Cisco SNMP Agent reports control characters (\n) what may potentially screw your script's output. There are several ways to handle this:
Pass lookupMib=True like shown in this example. Then pysnmp would try to look up proper output format for this particular OID at MIB. For this to work pysnmp must be able to find and load pysnmp-formatted MIB file(s).
Add some code to trigger a hex string decoder when 0x prefix is seen:
s = '436973636f...06d63707265'
print(''.join([ chr(int(s[x:x+2], 16)) for x in range(0, len(s), 2) ]))
Cisco IOS Software, IOS-XE Software ...Compiled Tue 25-Feb-14 11:36 by mcpre

Categories