Python and SNMP Introduction

By Kirk Byers
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' (assuming that you have it installed):

# As root/sudo (or vitualenv)
$ pip install pysnmp 

Alternatively, you can manually install the library:

$ wget http://downloads.sourceforge.net/project/pysnmp/pysnmp/4.2.5/pysnmp-4.2.5.tar.gz
$ gunzip pysnmp-4.2.5.tar.gz
$ tar -xvpf pysnmp-4.2.5.tar
$ cd pysnmp-4.2.5
$ python setup.py install 

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 (or vitualenv)
$ 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 <community> <ip_addr> .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 = '<community>'
>>> 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.

Hopefully, this article helps you get started with Python and SNMP.

If you are interested in receiving future content from me, you can join my email-list or you can follow me on Twitter (@kirkbyers).

Kirk Byers
CCIE #6243 emeritus
Twitter: @kirkbyers

Python and SNMP Introduction

By Kirk Byers
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' (assuming that you have it installed):

# As root/sudo (or vitualenv)
$ pip install pysnmp 

Alternatively, you can manually install the library:

$ wget http://downloads.sourceforge.net/project/pysnmp/pysnmp/4.2.5/pysnmp-4.2.5.tar.gz
$ gunzip pysnmp-4.2.5.tar.gz
$ tar -xvpf pysnmp-4.2.5.tar
$ cd pysnmp-4.2.5
$ python setup.py install 

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 (or vitualenv)
$ 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 <community> <ip_addr> .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 = '<community>'
>>> 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.

Hopefully, this article helps you get started with Python and SNMP.

If you are interested in receiving future content from me, you can join my email-list or you can follow me on Twitter (@kirkbyers).

Kirk Byers
CCIE #6243 emeritus
Twitter: @kirkbyers