Working with PYSNMP con’t – SNMP simple SETs

So inspired by @KirkByers blog on SNMP which I wrote about here using Python 3, I decided that I wanted to go past just reading SNMP OIDs and see how PYSNMP could be used to set SNMP OIDs as well.  As with anything, it’s best to start with the docs and apply the KISS principle.

Why SNMP?

Although RESTful APIs are definitely an easier, more human readable, way to get data in and out of a network device, not all network devices support modern APIs. For a lot of the devices out there, you’re still stuck with good ol’ SNMP.

Tools

SNMP is a horrible human readable language. We have MIBS to translate those nasty strings of digits into something that our mushy brains can make sense of. Thats known as a MIB Browser. There are a lot of MIB browsers out there, which one you use doesn’t matter much, but I would HIGHLY recommend that you get one if you’re going to start playing with SNMP.

http://www.ireasoning.com has a free version that works great on Windows and supports up to 10 MIBs loaded at the same time.

The Goal

There are a lot of powerful actions available through the SNMP interface, but I wanted to keep it simple.  For this project, I wanted to go after something simple. For this project, I wanted to use SNMP to change the SYSCONTACT and SYSLOCATION fields.

For those of you who are used to a CLI, the section of the config I’m looking after resembles this.

 snmp-agent sys-info contact contact

 snmp-agent sys-info location location

 

The Research

So I know what I want to change, but I need to know how I access those values though SNMP. For this, I’ll use the MIB Browser

 

Using the MIB Browser, I was able to find the SYSLOCATION MIB which is identified as .1.3.6.1.2.1.1.6.0

Screen Shot 2014 11 28 at 1 37 36 PM

I was also able to find the SYSCONTACT MIB which is identified as .1.3.6.1.2.1.1.4.0

Screen Shot 2014 11 28 at 1 37 14 PM

 

So now I’ve got the two OIDs that I’m looking for.

The Code

Looking through the PYSNMP documentation, there’s an example there of how to do an  SNMP SET. But they threw in a couple of options there that I didn’t want, specifically, I didn’t want to use the lookupNames option. So I changed the lookupNames option to False and then I was able to use the OIDs above directly without having to find the names of the MIBs.

So looking through the code below, you can see that I’ve created a function which will take an input syscontact and use it as the variable to set the MIB object  .1.3.6.1.2.1.1.4.0 which corresponds to the

SNMP-AGENT SYSCONTACT …  in the configuration of the device.

from pysnmp.entity.rfc3413.oneliner import Camden

cmdGen = cmdgen.CommandGenerator()

#using PYSNMP library to set the network devices SYSCONTACT field using SNMP
def SNMP_SET_SYSCONTACT(syscontact):
errorIndication, errorStatus, errorIndex, varBinds = cmdGen.setCmd(cmdgen.CommunityData(‘private’),cmdgen.UdpTransportTarget((‘10.101.0.221’, 161)),(cmdgen.MibVariable(‘.1.3.6.1.2.1.1.4.0’), syscontact), lookupNames=False, lookupValues=True)
# 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()))

 

 Running the Code

Now we run the code

>>>
>>> SNMP_SET_SYSCONTACT(‘test@lab.local’)
1.3.6.1.2.1.1.4.0 = test@lab.local
>>>

Looking back at the MIB Browser we can see that the SYSCONTACT location has been changed to the new value above.

Screen Shot 2014 11 28 at 2 24 50 PM

And when we log back into the network device

 snmp-agent sys-info contact test@lab.local

 snmp-agent sys-info location location

 

Wrap Up

This is just a small proof-of-contact code that shows, although RESTful APIs are definitely sweeter to work with, they are not the only way to programatically interface with network devices.

Comments or Questions?  Feel free to comment below

 

@netmanchris

 

 

 

Advertisements

PYSNMP with HP 5500EI Comware Switch

Inspired by @kirkbyers post over here  I wanted to stretch my python skills and see about playing around with the PYSNMP libraries as well as Kurt’s SNMP_HELPER.PY function which is available here.

Clean up the SNMP_HELPER.PY function for Python 3.x

There are some differences in Python 2 vs. Python 3. One of those differences is that the print command now requires you to actually have parans ()   around the content that you wish to print.  This was about the only thing that I had to do to get Kirk’s code working in Python 3.  If you try to run the code in the python IDLE software it will come up with this error right away.  I could also have run the py2to3  scripts, but since this was a small file, it was easy to just search for the 4 or so print statements and edit it manually as I was reading through the code to try and understand what Kirk was doing.

 

Easy Installation

So Kirk takes you through the normal PIP installation. I’m performing this on OS X Mavericks with Python 3. So for those not familiar with the differences yet. Python 2.x is natively installed on OSX. If you do a pip install …  command, this will result in you downloading and making that specific library available to the python 2.x version on your OS.  Since I’m using python 3.x, I instead need to use the pip3 install command which will, instead, make the library you’re downloading available to python 3.x on your system

$pip3 install pysnmp

 

Note: Kirk has a couple of other ways to install the pysnmp library over on his blog, so I won’t repeat them here.

Testing Out SNMP

So it’s a good idea to ensure that SNMP is running and you have the right community strings on the machine you’re going to access. For this, I’m going to use an

SNMP MIB browser that I have installed on my MBA to test this out. You could also use the net-snap utilities as shown on Kirk’s blog if you’d like to do this from the CLI. I highly recommend getting a MIB Browser installed on your system. http://www.ireasoning.com has a nice free one available.

Screen Shot 2014 11 27 at 3 51 04 PM

 

So now that we’ve confirmed this all works. on to the code.

Setting the Stage

So I’m assuming that you’re able to run the SNMP_Helper.py file in IDLE.  If you look at the code, one of the first things it does is import the cmdgen method from the pysnmp library

“from pysnmp.entity.rfc3413.oneliner import cmdgen” 

One of the ways that has really helped me learn is to go through other people’s code and try and understand exactly what they are doing. I don’t think I could have written SNMP_Helper.py on my own yet, but I can understand what it’s doing, and I can DEFINITELY use it. 🙂

Now we set up a few variables, using the exact same names that Kirk used over in his blog here

>>> COMMUNITY_STRING = ‘public’
>>> SNMP_PORT = 161
>>> a_device = (‘10.101.0.221’, COMMUNITY_STRING, SNMP_PORT)

Running the Code

Now we’ll run the exact same SNMP query against the sysDescr OID that Kirk used. And Amazingly enough, get a very similar output.

>> snmp_data = snmp_get_oid(a_device, oid=’.1.3.6.1.2.1.1.1.0′, display_errors=True)
>>> snmp_data
[(MibVariable(ObjectName(1.3.6.1.2.1.1.1.0)), DisplayString(hexValue=’485020436f6d7761726520506c6174666f726d20536f6674776172652c20536f6674776172652056657273696f6e20352e32302e39392052656c6561736520323232315030350d0a48502041353530302d3234472d506f452b204549205377697463682077697468203220496e7465726661636520536c6f74730d0a436f707972696768742028632920323031302d32303134204865776c6574742d5061636b61726420446576656c6f706d656e7420436f6d70616e792c204c2e502e’))]

 

It’s nice to see that we have gotten that same nasty output. SNMP is a standard after all and we should expect to see the same response from Cisco, HP, and other vendors devices when using standard SNMP functions, such as the MIBII sysDescr OIDs.

So now, let’s use Kirk’s cleanup function to be able to see what the data actually looks like. Again, remember Python3 needs those parens for the print statement to work properly.

>>> output = snmp_extract(snmp_data)
>>> print (output)
HP Comware Platform Software, Software Version 5.20.99 Release 2221P05
HP A5500-24G-PoE+ EI Switch with 2 Interface Slots
Copyright (c) 2010-2014 Hewlett-Packard Development Company, L.P.

Just for giggles, I also used this code against my Synology Diskstation

>>> print(output)
Linux DiskStation 2.6.32.12 #4482 Fri Apr 18 02:12:31 CST 2014 armv5tel

Then against my Server Technologies intelligent PDU

>>> print(output)
Sentry Switched CDU

Then against my DIGI console server.

>>> snmp_data = snmp_get_oid(a_device, oid=’.1.3.6.1.2.1.1.1.0′, display_errors=True)
ERROR DETECTED:
error_message No SNMP response received before timeout
error_status 0
error_index 0

The last one was working exactly as expected as I have ACL’s in place to only allow SNMP access from certain devices in my network. 🙂

Observations

It’s nice to see that standards like SNMP and widely available libraries like pysnmp can be used to access the devices regardless of the vendor they come from.

SNMP gets a bad wrap in general as there are new cooler technologies out there like NETCONF, OpenFlow, OVSDB, NetFlow, sFlow, and I’m sure a dozen others that I’m missing that can do a better job of the functions that SNMP was originally designed to go after.

But sometimes, SNMP is what we have, and the reason that it’s still around after all these years is that it’s  “good enough”

 

Questions or comments?  please post below!

@netmanchris