I always try to approach technical challenges with the thought that “just because something can’t be done doesn’t mean it can’t be done”. Sure enough I had a problem like this cross my desk again the other day. I wanted a simple way to get the number of active calls on a handful of MGCP PRI gateway routers. Unfortunately I couldn’t find a single SNMP data point for this information. I knew IOS routers had an HTTP interface so I started checking around to see how easy it would be to script against.
Sure enough, it really wasn’t all that difficult!
Collecting Data from the Router
Assuming the router has no other HTTP GUI of sorts installed already (such as SDM, CCP express, or CME) you should be able to connect after a few simple configuration commands are in place.
ip http authentication local ip http secure-server !(optional) ip http access-class <access list>
When you connect to the HTTP interface you will notice the option to input typical CLI commands. I simply entered a show command and saw the output I was looking for. To make things even better the browser was redirected to a new URL with the commands embedded. I refined my show command to be “show voice call status” that specifically lists the number of active calls.
I simply copied and pasted the URL and changed the host portion to point toward another voice gateway router. Sure enough (after authenticating) the same results were shown for that device as well. Essentially the URL formatting is something like this:
Host would be the hostname or IP address of the Cisco device.
Privilege level is 0-15. The user you use to access the router must have access to the commands you would like to run at his or her privilege level. It’s probably not a bad idea to make a specific user a custom privilege level that allows only access to the commands you need to run and collect data from.
Command is the command as you would type it into the CLI but with spaces replaced with slashed and a”CR” on the end for the carriage return.
The next step was to grab the web page with a script and parse the results. I did this with PHP and the CURL functions. I parsed the results with a regular expressions and used an if else to control and print the output. The organization I work for uses PRTG to monitor network health so I knew the “HTTP Content” sensor would work well to collect this data. Finally, I stepped back through the script and added a few error notification measures.
Essentially the topology will looked something like this. You could consolidate the Web/PHP server into the monitoring box as well but I chose not to in this case.
The script is listed below. While this use case was very specific it would be very easy to script almost any information out of a Cisco device with this concept. Obviously, SNMP would be easier but some data points just can’t be collected that way…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
$ip = $_GET['ip']; //The command you would like to be ran on the router $url = "https://$ip/level/15/exec/-/show/voice/call/status/CR"; //credentials on cisco device $username = 'admin'; $password = 'password'; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY); curl_setopt($ch, CURLOPT_USERPWD, "$username:$password"); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3); $out = curl_exec($ch) or die ("connection error"); curl_close($ch); //Regular expression match the information we are looking for in the routers response. preg_match_all("/([0-9]+|No)\sactive call/",$out,$array) or die("parse error"); //display output the monitoring system can understand if(is_numeric($array)) echo "[" . $array ."]"; else if($array == "No") echo ""; else echo "error";
Using the Script
With the script hosted on a web server you are now ready to pull data through it with a monitoring system. Like I said before I am using PRTG but many other systems allow you to pull data from web pages as well. To use this script as is you would form a like the one below and put it in your monitoring config:
http(s)://<web server>/<script name>.php?ip=<router ip>
Web Server is the IP or hostname of the system hosting the script. This server needs to have http(s) access to the Cisco device in order to execute the script.
Script name is simply the name you give the above script when you save it.
Router IP is the IP address of the subject Cisco device. Host name would also work but you are then dependent on the web server’s name resolution in addition to the http request processing time. It may be worth upping the timeout value in the curl config if you go this route.