Im reitryng to get some kids from some network switch and for that im using a purepyton library called pysnmp. its installed w/o problems.
Used a sample code that works.
from pysnmp.entity.rfc3413.oneliner import cmdgen
cmdGen = cmdgen.CommandGenerator()
datos = []
ip = 'theipaddress'
comunidad_snmp = 'thecomunityv2c'
errorIndication, errorStatus, errorIndex, varBinds = cmdGen.getCmd(
cmdgen.CommunityData(comunidad_snmp),
cmdgen.UdpTransportTarget((ip, 161)),
'.1.3.6.1.2.1.1.1.0', # sysDescr.0
lookupNames=True, lookupValues=True
)
if errorIndication:
print(errorIndication)
elif errorStatus:
print(errorStatus)
else:
for name, val in varBinds:
datos.append({'nombre': name.prettyPrint(), 'valor': val.prettyPrint()})
print datos
our problem is that if I copy this code(as is) inside any view the result its always
"No SNMP response received before timeout"
is there something we need to add for this to work as expected?.
the environment is cents 6
Could it be that your SNMP/UDP queries from Django host get filtered while your command-line tests do not?
Digging deeper: your code invokes pysnmp with default, asyncore-based transport. If Django (or some of its components) somehow uses asyncore in a non-cooperative way, pysnmp/django systems may somehow interfere... A way to avoid such interference would be use your own map of pysnmp I/O socket objects like this:
...
from pysnmp.carrier.asynsock.dispatch import AsynsockDispatcher
cmdGen.snmpEngine.registerTransportDispatcher(AsynsockDispatcher())
mySockMap = {}
cmdGen.snmpEngine.transportDispatcher.setSocketMap(mySockMap)
...
Another idea is to enable pysnmp debugging to see what's going on there:
import sys
from pysnmp import debug
debug.setLogger(debug.Debug('all', printer=sys.stderr.write))
There are other, less verbose pysnmp debugging flags (see pysnmp.debug).
Related
Am writing a Sample code below for fetching Cisco Switch Information through SNMP for the python pysnmp module.
after executing below code am getting 'No SNMP response received before timeout'.
from pysnmp.entity.rfc3413.oneliner import cmdgen
import time
#SNMP agent address
SNMP_AGENT_HOST = 'IPADDRESS' # IP adderess
#SNMP default port
SNMP_PORT = 161
#Add SNMP agent community here
SNMP_COMMUNITY = 'public'
cmdGen = cmdgen.CommandGenerator()
errorIndication, errorStatus, errorIndex, varBinds = cmdGen.getCmd(
cmdgen.CommunityData(SNMP_COMMUNITY),
cmdgen.UdpTransportTarget((SNMP_AGENT_HOST, SNMP_PORT)),
'1.3.6.1.4.1.9.2.1.56.0', # Cisco Switch OID
'1.3.6.1.4.1.9.2.1.57.0' #
)
# Check for errors and print out results
if errorIndication:
print(errorIndication)
else:
if errorStatus:
print('%s at %s' % (
errorStatus.prettyPrint(),
errorIndex and varBinds[int(errorIndex)-1] or '?'
)
)
else:
for name, val in varBinds:
print('%s = %s' % (name.prettyPrint(), val.prettyPrint()))
I getting the result
No SNMP response received before timeout
I want to be fetch all OID related Information through the GET call.
Your quickest way of diagnosing this is to use an EXISTING utility that you know works, and try it against that IPADDRESS with the authentication that you think should work.
If that utility, eg. NET-SNMP snmpwalk or snmpgetnext, does not work, then your problem is likely not in your code, but your understanding of how to access the SNMP agent. Eg. are you certain the community string "public" works?
It is ALWAYS better to work from success, than to interpolate from failure.
I try to use PySNMP to receive SNMPv3 Traps. I found this example code:
#!/usr/bin/env /usr/bin/python3
from pysnmp.entity import engine, config
from pysnmp.carrier.asyncore.dgram import udp
from pysnmp.entity.rfc3413 import ntfrcv
from pysnmp.proto.api import v2c
from pysnmp.smi.rfc1902 import ObjectIdentity
snmpEngine = engine.SnmpEngine()
# Transport setup
# UDP over IPv4
config.addTransport(
snmpEngine,
udp.domainName,
udp.UdpTransport().openServerMode(('0.0.0.0', 162)),
)
# SNMPv3/USM setup
config.addV3User(
snmpEngine, '<username>',
config.usmHMACMD5AuthProtocol, '<password>',
config.usmAesCfb128Protocol, '<password>',
securityEngineId=v2c.OctetString(hexValue='<engineid>')
)
def cbFun(snmpEngine, stateReference, contextEngineId, contextName,
varBinds, cbCtx):
print('Notification from ContextEngineId "%s", ContextName "%s"' (contextEngineId.prettyPrint(), contextName.prettyPrint()))
for name, val in varBinds:
print('%s = %s' % (name.prettyPrint(), val.prettyPrint()))
# Register SNMP Application at the SNMP engine
ntfrcv.NotificationReceiver(snmpEngine, cbFun)
snmpEngine.transportDispatcher.jobStarted(1) # this job would never finish
# Run I/O dispatcher which would receive queries and send confirmations
try:
snmpEngine.transportDispatcher.runDispatcher()
except:
snmpEngine.transportDispatcher.closeDispatcher()
raise
This code works for me, but i get the raw Traps. I have an vendor specific MIB File I want to use. But I can't find any documentation how to bind the mib to the snmpEngine. The examples using MIBs from the PySNMP documentation show only the usage for SNMP GET operations and are not applicable here.
Has someone tried this before and can help me?
Thanks!
If your goal is to resolve raw variable-bindings you receive into human-friendly form, then you need to process those variable-bindings through the MIB browser object.
You are right, that's exactly the same operation that command generator frequently performs in the examples.
from pysnmp.smi import builder, view, compiler, rfc1902
# Assemble MIB browser
mibBuilder = builder.MibBuilder()
mibViewController = view.MibViewController(mibBuilder)
compiler.addMibCompiler(
mibBuilder, sources=['file:///usr/share/snmp/mibs',
'http://mibs.snmplabs.com/asn1/#mib#'])
# Pre-load MIB modules that define objects we receive in TRAPs
mibBuilder.loadModules('SNMPv2-MIB', 'SNMP-COMMUNITY-MIB')
# This is what we would get in a TRAP PDU
varBinds = [
('1.3.6.1.2.1.1.3.0', 12345),
('1.3.6.1.6.3.1.1.4.1.0', '1.3.6.1.6.3.1.1.5.2'),
('1.3.6.1.6.3.18.1.3.0', '0.0.0.0'),
('1.3.6.1.6.3.18.1.4.0', ''),
('1.3.6.1.6.3.1.1.4.3.0', '1.3.6.1.4.1.20408.4.1.1.2'),
('1.3.6.1.2.1.1.1.0', 'my system')
]
# Pass raw var-binds through MIB browser
varBinds = [
rfc1902.ObjectType(rfc1902.ObjectIdentity(x[0]), x[1]).resolveWithMib(mibViewController)
for x in varBinds
]
for varBind in varBinds:
print(varBind.prettyPrint())
I'm trying to resolve the OIDs that are received on an SNMP Trap from an HP switch stack but they only resolve down to a certain level and stop. It's like the HP MIBs are not being loaded. It's unclear from all the documentation I can find on pysnmp if this is the appropriate way to add custom MIBs and resolve OIDs from a trap.
MIBs can be downloaded here.
from pysnmp.entity import engine, config
from pysnmp.carrier.asyncore.dgram import udp
from pysnmp.smi import view, builder, rfc1902
from pysnmp.entity.rfc3413 import ntfrcv, mibvar
# Create SNMP engine with autogenernated engineID and pre-bound
# to socket transport dispatcher
snmpEngine = engine.SnmpEngine()
build = snmpEngine.getMibBuilder()
build.addMibSources(builder.DirMibSource("C:/Users/t/Documents/mibs"))
viewer = view.MibViewController(build)
# Transport setup
# UDP over IPv4, first listening interface/port
config.addTransport(
snmpEngine,
udp.domainName + (1,),
udp.UdpTransport().openServerMode(('0.0.0.0', 162))
)
# SNMPv1/2c setup
# SecurityName <-> CommunityName mapping
config.addV1System(snmpEngine, '????', 'public')
# Callback function for receiving notifications
# noinspection PyUnusedLocal,PyUnusedLocal,PyUnusedLocal
def cbFun(snmpEngine, stateReference, contextEngineId, contextName, varBinds, cbCtx):
print('Notification from ContextEngineId "%s", ContextName "%s"' % (contextEngineId.prettyPrint(),
contextName.prettyPrint()))
for name, val in varBinds:
print(name)
symbol = rfc1902.ObjectIdentity(name).resolveWithMib(viewer).getMibSymbol()
print(symbol[1])
# Register SNMP Application at the SNMP engine
ntfrcv.NotificationReceiver(snmpEngine, cbFun)
snmpEngine.transportDispatcher.jobStarted(1) # this job would never finish
# Run I/O dispatcher which would receive queries and send confirmations
try:
snmpEngine.transportDispatcher.runDispatcher()
except:
snmpEngine.transportDispatcher.closeDispatcher()
raise
Output upon receiving a trap:
Notification from ContextEngineId "0x80004fb8056ed891e8", ContextName ""
1.3.6.1.2.1.1.3.0
sysUpTime
1.3.6.1.6.3.1.1.4.1.0
snmpTrapOID
1.3.6.1.6.3.18.1.3.0
snmpTrapAddress
1.3.6.1.6.3.18.1.4.0
snmpTrapCommunity
1.3.6.1.6.3.1.1.4.3.0
snmpTrapEnterprise
1.3.6.1.4.1.11.2.14.11.5.1.7.1.29.1.9
enterprises
1.3.6.1.4.1.11.2.14.11.5.1.7.1.29.1.0.1
enterprises
1.3.6.1.4.1.11.2.14.11.5.1.7.1.29.1.0.2
enterprises
1.3.6.1.4.1.11.2.14.11.5.1.7.1.29.1.0.3
enterprises
1.3.6.1.4.1.11.2.14.11.5.1.7.1.29.1.0.4
enterprises
1.3.6.1.4.1.11.2.14.11.5.1.7.1.29.1.0.5
enterprises
As you can see many distinct OIDs just resolve to "enterprises". I am using pysnmp 4.4.4.
Yes, it seems that only the core MIBs are loaded.
If you want to follow this quite low-level path, then you need to pre-compile all your ASN.1 MIBs (those you pulled from HPE site) with the mibdump tool into pysnmp format. Then put those *.py files into some directory and point pysnmp to it through build.addMibSources(builder.DirMibSource()) call.
Also, make sure to pre-load up all those MIBs at once on startup by invoking build.loadModules() (w/o arguments).
I try to get status from my printer using SNMP protocol
The problem is, I've never used the SNMP and I have trouble understanding how can I get my status like ( PAPER OUT, RIBBON OUT, etc... ).
I configured my printer to enable the SNMP protocol using the community name "public"
I presume SNMP messages are sent on the port 161
I'm using Pysnmp because I want to integrate the python script in my program to listen to my printer and display status if there is a problem with the printer.
For now I've tried this code :
import socket
import random
from struct import pack, unpack
from datetime import datetime as dt
from pysnmp.entity.rfc3413.oneliner import cmdgen
from pysnmp.proto.rfc1902 import Integer, IpAddress, OctetString
ip = '172.20.0.229'
community = 'public'
value = (1,3,6,1,2,1,25,3,5,1,2)
generator = cmdgen.CommandGenerator()
comm_data = cmdgen.CommunityData('server', community, 1) # 1 means version SNMP v2c
transport = cmdgen.UdpTransportTarget((ip, 161))
real_fun = getattr(generator, 'getCmd')
res = (errorIndication, errorStatus, errorIndex, varBinds) \
= real_fun(comm_data, transport, value)
if not errorIndication is None or errorStatus is True:
print "Error: %s %s %s %s" % res
else:
print "%s" % varBinds
The IP address is the IP of my printer
The problem is the OID: I don't know what to put in the OID field because I have trouble understanding how does OID work.
I found this page but I'm not sure it fits with all printers ==> click here
You need your printer specific MIB file in common case. E.g., printer in my office seems to be not support both oids by your link. Also you can use snmpwalk to get available oids and values on your printer and if you somehow understand which values you need, you can use it for specific instance of your printer.
I am trying to make a very simple XML RPC Server with Python that provides basic authentication + ability to obtain the connected user's IP. Let's take the example provided in http://docs.python.org/library/xmlrpclib.html :
import xmlrpclib
from SimpleXMLRPCServer import SimpleXMLRPCServer
def is_even(n):
return n%2 == 0
server = SimpleXMLRPCServer(("localhost", 8000))
server.register_function(is_even, "is_even")
server.serve_forever()
So now, the first idea behind this is to make the user supply credentials and process them before allowing him to use the functions. I need very simple authentication, for example just a code. Right now what I'm doing is to force the user to supply this code in the function call and test it with an if-statement.
The second one is to be able to get the user IP when he calls a function or either store it after he connects to the server.
Moreover, I already have an Apache Server running and it might be simpler to integrate this into it.
What do you think?
This is a related question that I found helpful:
IP address of client in Python SimpleXMLRPCServer?
What worked for me was to grab the client_address in an overridden finish_request method of the server, stash it in the server itself, and then access this in an overridden server _dispatch routine. You might be able to access the server itself from within the method, too, but I was just trying to add the IP address as an automatic first argument to all my method calls. The reason I used a dict was because I'm also going to add a session token and perhaps other metadata as well.
from xmlrpc.server import DocXMLRPCServer
from socketserver import BaseServer
class NewXMLRPCServer( DocXMLRPCServer):
def finish_request( self, request, client_address):
self.client_address = client_address
BaseServer.finish_request( self, request, client_address)
def _dispatch( self, method, params):
metadata = { 'client_address' : self.client_address[ 0] }
newParams = ( metadata, ) + params
return DocXMLRPCServer._dispatch( self, method, metadata)
Note this will BREAK introspection functions like system.listMethods() because that isn't expecting the extra argument. One idea would be to check the method name for "system." and just pass the regular params in that case.