Jan 11 2012
This is something for the Cacti, Nagios, WhatsUp and what-not users in the satellite business out there…
At work, we use Cacti to graph the SNMP values of A LOT of exotic devices, among them is the very popular family of iDirect modems. Now, we like to graph the Tx (Transmit) SNR (Signal to Noise Ratio) of certain iDirect modems. To do so, you usually open a telnet connection to an iDirect modem, login with the proper user credentials and execute the command
Now, as you might know, monitoring and graphing servers like WhatsUp or Cacti cannot perform Telnet connections out of the box. They query SNMP devices through their IP addresses and request the values through their respective OIDs.
How did we solve this?
With a dedicated Linux server that runs an extended SNMP daemon.
Basically, that is a regular SNMP daemon that has some additional configuration lines in its /etc/snmp/snmpd.conf file, like this one:
extend UniqueiDirectModemName '/usr/local/bin/iDirectSNR.py -i 22.214.171.124 -u username -p password'
On this server, you can determine the assigned OID with the snmpwalk command using the -On switch:
snmpwalk localhost -c snmpcommunity -v1 .126.96.36.199.4.1.8072.1.3.2.4.1.2 -On
The following Python skript performs the telnet part to query the Tx SNR value; when it encounters an error, it returns the value “100.00000″, which is also returned when the modem is not locked for whatever reason.
Note: Usually the modem returns -100.000000 when it is not locked, but to make the graphs look a little nicer, we did not want to use negative values.
This is the file
Make sure you perform
sudo chmod a+wxr /usr/local/bin/iDirectSNR.py
to make it executable!
#!/usr/bin/python import sys import telnetlib from optparse import OptionParser parser = OptionParser() parser.add_option("-i", "--ipaddress", dest="ipaddress", help="IP address of iDirect modem", metavar="") parser.add_option("-u", "--username", dest="username", help="IP address of iDirect modem", metavar="") parser.add_option("-p", "--password", dest="password", help="IP address of iDirect modem", metavar="") (options, args) = parser.parse_args() if options.username is None or options.password is None or options.ipaddress is None: print "100.000000" exit() try: tn = telnetlib.Telnet(options.ipaddress,23,2) except Exception, e: print "100.000000" exit() tn.read_until("Username: ",1) tn.write(options.username + "\n") tn.read_until("Password: ",1) tn.write(options.password + "\n") tn.read_until("> ",1) tn.write("rx snr\n") tn.read_until("Rx SNR: ",1) result = tn.read_until("\n",1).rstrip("\n") result = result.lstrip("-") if result == "": result = "100.000000" print result tn.write("exit\n")
If you don’t know how to setup a basic SNMP daemon:
sudo apt-get install snmp
Then you need to modify the file /etc/default/snmpd. Remove the reference to localhost in the SNMPDOPTS line, otherwise the server will ONLY listen to SNMP requests its localhost IP address 127.0.0.1. Make sure that the line looks somehow like this:
SNMPDOPTS='-Lsd -Lf /dev/null -u snmp -g snmp -I -smux -p /var/run/snmpd.pid -c /etc/snmp/snmpd.conf'
Now, create a simple /etc/snmp/snmpd.conf file:
rocommunity snmpcommunity syslocation "MyCompany, MyLocation" syscontact firstname.lastname@example.org extend UniqueiDirectModemName '/usr/local/bin/iDirectSNR.py -i 188.8.131.52 -u username -p password'
Now restart the SNMP daemon:
sudo /etc/init.d/snmpd restart
And that’s it! Your Linux server will now respond to SNMP queries, and it will even return the Tx SNR value of the modems that you have added to its snmpd.conf file as if they belonged to the server itself. You can add as many devices as you want to your SNMP daemon, and with modified versions of the Python skript, of course, you can also return other values as well.