SNMP is a ubiquitous network protocol that is used by the network routers, such as switches, servers, and so on, for communicating the device's configuration, performance data, and the commands that are meant for the control devices. Although SNMP starts with the word simple, it's not a simple protocol. Internally, each device's information is stored in a sort of a database of information called the management information base (MIB). The SNMP protocol offers varying levels of security depending on the protocol version number. In SNMP v1
and v2c
, the data is protected by a pass phrase known as the community string. In SNMP v3
, a username and a password are required for storing the data. And, the data can be encrypted with the help of SSL. In our example, we will use the v1
and v2c
versions of the SNMP protocol.
SNMP is a client/server-based network protocol. The server daemon provides the requested information to the clients. In your machine, if SNMP has been installed and configured properly, then you can use the snmpwalk
utility command to query the basic system information by using the following syntax:
# snmpwalk -v2c -c public localhost iso.3.6.1.2.1.1.1.0 = STRING: "Linux debian6box 2.6.32-5-686 #1 SMP Tue May 13 16:33:32 UTC 2014 i686" iso.3.6.1.2.1.1.2.0 = OID: iso.3.6.1.4.1.8072.3.2.10 iso.3.6.1.2.1.1.3.0 = Timeticks: (88855240) 10 days, 6:49:12.40 iso.3.6.1.2.1.1.4.0 = STRING: "Me <[email protected]>" iso.3.6.1.2.1.1.5.0 = STRING: "debian6box" iso.3.6.1.2.1.1.6.0 = STRING: "Sitting on the Dock of the Bay"
The output of the preceding command will show the MIB number and its values. For example, the MIB number iso.3.6.1.2.1.1.1.0
shows that it's a string type value, such as Linux debian6box 2.6.32-5-686 #1 SMP Tue May 13 16:33:32 UTC 2014 i686
.
In Python, you can use a third-party library called pysnmp
for interfacing with the snmp
daemon. You can install the pysnmp
module by using pip.
$ pip install pysnmp
This module provides a useful wrapper for the snmp
commands. Let's learn how to create an snmpwalk
command. To begin, import a command generator.
from pysnmp.entity.rfc3413.oneliner import cmdgen cmd_generator = cmdgen.CommandGenerator()
Then define the necessary default values for the connection assuming that the snmpd
daemon has been running on port 161
of the local machine and the community string has been set to public.
SNMP_HOST = 'localhost' SNMP_PORT = 161 SNMP_COMMUNITY = 'public'
Now invoke the getCmd()
method with the help of the necessary data.
error_notify, error_status, error_index, var_binds = cmd_generator.getCmd( cmdgen.CommunityData(SNMP_COMMUNITY), cmdgen.UdpTransportTarget((SNMP_HOST, SNMP_PORT)), cmdgen.MibVariable('SNMPv2-MIB', 'sysDescr', 0), lookupNames=True, lookupValues=True )
You can see that cmdgen
takes the following parameters:
CommunityData()
: Set the community string as public.UdpTransportTarget()
: This is the host target, where the snmp
agent is running. This is specified in a pair of the hostname and the UDP port.MibVariable
: This is a tuple of values that includes the MIB version number and the MIB target string (which in this case is sysDescr
; this refers to the description of the system).The output of this command consists of a four-value tuple. Out of those, three are related to the errors returned by the command generator, and the fourth one is related to the actual variables that bind the returned data.
The following example shows how the preceding method can be used for fetching the SNMP host description string from a running SNMP daemon:
from pysnmp.entity.rfc3413.oneliner import cmdgen SNMP_HOST = 'localhost' SNMP_PORT = 161 SNMP_COMMUNITY = 'public' if __name__ == '__manin__': cmd_generator = cmdgen.CommandGenerator() error_notify, error_status, error_index, var_binds = cmd_generator.getCmd( cmdgen.CommunityData(SNMP_COMMUNITY), cmdgen.UdpTransportTarget((SNMP_HOST, SNMP_PORT)), cmdgen.MibVariable('SNMPv2-MIB', 'sysDescr', 0), lookupNames=True, lookupValues=True ) # Check for errors and print out results if error_notify: print(error_notify) elif error_status: print(error_status) else: for name, val in var_binds: print('%s = %s' % (name.prettyPrint(), val.prettyPrint()))
After running the preceding example, an output similar to the following will appear:
$ python 5_4_snmp_read.py SNMPv2-MIB::sysDescr."0" = Linux debian6box 2.6.32-5-686 #1 SMP Tue May 13 16:33:32 UTC 2014 i686
We can inspect the SNMP packet by capturing the packets on port 161 of your network interface. If the server is running locally, then listening on the loopbook
interface is sufficient. The snmp-get
request format and the snmp-get
response packet formats, which are produced by Wireshak, is shown in the following screenshot:
In response to the SNMP get request from the client, an SNMP get response will be generated by the server. This can be seen in the following screenshot: