Python and SNMP Introduction

Author: Kirk Byers
Date: 2014-07-22

In this article, I briefly introduce Python and SNMP using the pysnmp library.

I assume that you already have some knowledge on SNMP including MIBs and OIDs. If not, you should be able to find this information fairly easily on the Internet. One resource that I found particularly helpful was the Cisco SNMP Object Navigator.

In order to get started, you need to install the PySNMP library. For context, I am testing on an AWS AMI server (Fedora/RedHat based).

For easy installation just use 'pip'

/* In a virtualenv */
$ pip install pysnmp

I also installed net-snmp to simplify testing and to add an easy way to perform an SNMP walk. The installation method for net-snmp will vary depending on your system.

/* As root/sudo */
# yum install net-snmp
# yum install net-snmp-utils

To keep things simple, I am only going to use SNMPv1/2c in this article. This is obviously not secure.

Now that I have the PySNMP library installed, the next step is to verify that I can communicate with my test router using SNMP. First, let's test this directly from the Linux command line:

$ snmpget -v 2c -c   .1.3.6.1.2.1.1.1.0
SNMPv2-MIB::sysDescr.0 = STRING: Cisco IOS Software, C880 Software (C880DATA-UNIVERSALK9-M), Version 15.0(1)M4, RELEASE SOFTWARE (fc1)
Technical Support: http://www.cisco.com/techsupport
Copyright (c) 1986-2010 by Cisco Systems, Inc.
Compiled Fri 29-Oct-10 00:02 by prod_rel_team

The OID .1.3.6.1.2.1.1.1.0 is the MIB-2 sysDecr object. While testing, I encountered multiple problems including ACLs and Cisco's Control Plane Policing which I had earlier enabled on the router (ooops).

At this point, I am able to communicate using SNMP from my AWS server to my test router. Now let's try the same thing except using the PySNMP library.

In order to simplify this I have created a few SNMP helper functions see:

SNMP Helper Functions

First I perform some initialization:

>>> from snmp_helper import snmp_get_oid,snmp_extract
>>> 
>>> COMMUNITY_STRING = ''
>>> SNMP_PORT = 161
>>> a_device = ('1.1.1.1', COMMUNITY_STRING, SNMP_PORT)

This code loads my two functions (snmp_get_oid and snmp_extract); it also creates a tuple named 'a_device' consisting of an IP address, the community string, and the SNMP port.

I then call my snmp_get_oid function using the MIB-2 sysDescr OID:

>>> 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='436973636f20494f5320536f6674776172652c204338383020536f667477617265202843383830444154412d554e4956455253414c4b392d4d292c2056657273696f6e2031352e302831294d342c2052454c4541534520534f4654574152452028666331290d0a546563686e6963616c20537570706f72743a20687474703a2f2f7777772e636973636f2e636f6d2f74656368737570706f72740d0a436f707972696768742028632920313938362d3230313020627920436973636f2053797374656d732c20496e632e0d0a436f6d70696c6564204672692032392d4f63742d31302030303a30322062792070726f645f72656c5f7465616d'))]

I can see that I received SNMP data back albeit in an ugly format. I can now use the snmp_extract function to display the output in a more friendly way.

>>> output = snmp_extract(snmp_data)
>>> print output
Cisco IOS Software, C880 Software (C880DATA-UNIVERSALK9-M), Version 15.0(1)M4, RELEASE SOFTWARE (fc1)
Technical Support: http://www.cisco.com/techsupport
Copyright (c) 1986-2010 by Cisco Systems, Inc.
Compiled Fri 29-Oct-10 00:02 by prod_rel_team

Now, let's repeat this process but using a different OID. Using snmpwalk on the 'interfaces' MIB and the Cisco SNMP Object Navigator, I was able to determine that the OID = .1.3.6.1.2.1.2.2.1.16.5 corresponded to the output octets on FastEthernet4. Here, I query that OID a couple of times in fairly quick succession (less than a minute between queries):

>>> snmp_data = snmp_get_oid(a_device, oid='.1.3.6.1.2.1.2.2.1.16.5', display_errors=True)
>>> output = snmp_extract(snmp_data)
>>> print output
293848947

>>> snmp_data = snmp_get_oid(a_device, oid='.1.3.6.1.2.1.2.2.1.16.5', display_errors=True)
>>> output = snmp_extract(snmp_data)
>>> print output
293849796

You can see that the output octets increased.

That was a very brief introduction to Python and SNMP in a networking context. Hopefully, this article helps you get started...

Kirk Byers

@kirkbyers

You might also be interested in: