Interacting with CUCM via SNMP

I recently had a project that required me to retrieve the IP address of each registered device of CUCM., device name and extensions  I being a former AXL regular went there to find an API, but really didn’t find anything that fit the bill.  My guess is I could have used a raw SNMP query of some kind, however through a little research I found that SNMP provided this and a bunch of other information relatively easily.

The goal of this post is to give you a starting place to query against CUCM via SNMP in order to gain some interesting knowledge about CUCM.  You could also modify this to start receiving trap events.

ftp://ftp.cisco.com/pub/mibs/v1/CISCO-CCM-MIB-V1SMI.my is the location of the Cisco CUCM MIB File.  A MIB File is basically a definition file for a components SNMP structure.  Cisco actually has a really neat browser for SNMP OID (Unique identifier for querying SNMP).  It tells you all about the OID and what type of data to expect.

You can find the browser here.  here

Please go take a look at all the OID’s we will use in this blog to familiarize yourself through the Cisco tool above

  • 1.3.6.1.4.1.9.9.156.1.2.1.1.20 – Device Name
  • 1.3.6.1.4.1.9.9.156.1.2.1.1.21 – Device IP
  • 1.3.6.1.4.1.9.9.156.1.1.2.1.7 – CUCM IP
  • 1.3.6.1.4.1.9.9.156.1.2.5.1.2 – Device Extensions

Overview

The goal is write a small program that allows us to walk an entire CUCM cluster (all of the CUCM’s) to gather useful information about the environment.  We will show how to get the IP Address of All CUCM servers by pointing to the PUB, and then how to include all of those IP’s address in further queries to get a view of the entire CUCM.

Preparation

We will need to configure an SNMP community string (Version 2C) on each of the CUCM service.  For this you will need to login to CUCM Serviceability.  Once logged in browse to SNMP -> Version V1/V2c -> Community String as shown below.

SNMP Menu

Once there we will just click Find on any server you like, and none should be found.  Click the add new button and configure it as shown below.

Add Community String

Please note that this is a read only string we are configuring, if you wanted to write, it obviously would need the appropriate permissions.  Also we are checking the ‘apply to all nodes’ checkbox.  Personally at work most of our clusters have 8-9 nodes, and would be annoying to do each node individually.

The Code

Now we are prepared to write an app to walk the OID’s shown below. I have chosen ruby but can also provide a perl example if people are interested.

 require 'snmp'
 require 'hex_string'
 snmp_string = "TestMe"
 publisher_ip = "10.10.10.10"
 
 ccmDeviceName = SNMP::ObjectId.new("1.3.6.1.4.1.9.9.156.1.2.1.1.20")
 ccmDeviceIP = SNMP::ObjectId.new("1.3.6.1.4.1.9.9.156.1.2.1.1.21")
 ccmServerIP = SNMP::ObjectId.new("1.3.6.1.4.1.9.9.156.1.1.2.1.7")
 ccmextn = SNMP::ObjectId.new("1.3.6.1.4.1.9.9.156.1.2.5.1.2")
 ccmextip = SNMP::ObjectId.new("1.3.6.1.4.1.9.9.156.1.2.5.1.5")
 @ccm_ips = []
 
 manager = SNMP::Manager.new(:host => publisher_ip, :port => 161, :community => snmp_string, :version => :SNMPv2c)
 manager.walk(ccmServerIP) do |row|
  row.each do |vb|
   puts "CUCM IP: #{vb.value.bytes.to_a.join(".")}"
   @ccm_ips < ccm, :port => 161, :community => snmp_string, :version => :SNMPv2c)
  manager.walk(ccmDeviceName) do |row|
  row.each do |vb|
   puts "Device Name: #{vb.value}"
  end
  end
  
  manager = SNMP::Manager.new(:host => ccm, :port => 161, :community => snmp_string, :version => :SNMPv2c)
  manager.walk(ccmDeviceIP) do |row|
  row.each do |vb|
   puts "Device IP: #{vb.value.bytes.to_a.join(".")}"

  end
  end
  
     manager = SNMP::Manager.new(:host => ccm, :port => 161, :community => snmp_string, :version => :SNMPv2c)
  manager.walk(ccmextn) do |row|
  row.each do |vb|
   puts "Device Extn:  #{vb.value}"
  end
  end
  
 end

The app shown does the following:

  • Queries the publisher IP with Community String “TestMe” in order to retrieve ALL the CUCM IP’s.  Note that the IP’s come back as a HEX value, and this bit of code vb.value.bytes.to_a.join(“.”) is specifically for converting this Hex to a dotted IP string.
  • Puts all of these IP’s in an array to loop through each one individually for future SNMP queries.  This is very important because when querying for a device IP for example, you will only get the devices that are registered to that CUCM.  So to see every device you must query every CUCM.
  • Queries each CUCM for Device Name, Device IP and Extensions on each Phone.

Here is a small snipper of example output..


CUCM IP: 10.234.5.28
CUCM IP: 10.234.5.27
CUCM IP: 10.234.5.26
CUCM IP: 10.234.5.25
CUCM IP: 10.234.5.24
CUCM IP: 10.123.5.23
CUCM IP: 10.123.5.22
CUCM IP: 10.123.5.21
Device Name: SEP0004F2F0E321
Device Name: SEP7CAD7442F14D
Device IP: 10.9.39.12
Device IP: 10.195.115.203
Device Extn:  8215
Device Extn:  2314331

A few other things:

  • Change the publisher IP address and SNMP Community String to what fits your environment.
  • This application ‘walks’ and SNMP OID… every value that is returned has a unique SNMP identifier.. for example a device name is actually 1.3.6.1.4.1.9.9.156.1.2.1.1.20.X where X is a different number for each device.  This X will be the same for Device Name and Device IP and Device Extension so you can match them up in tools.

Conclusion

SNMP has tons of valuable information you never would have thought CUCM would provide over it.  Be careful in the MIB as many of the values are deprecated now.  This is exactly how InformaCast and other apps harvest the devices for IP Phone service development.  I was obviously using it to write my own tool that needed this information.