The next example adds a new interface called Loopback 3 to the IOS device and queries the SNMP MIB. Adding a new interface will cause the device to modify the Interfaces Table. Therefore, the last update time will change to reflect the change:
Router(tcl)#ios_config “int Loopback 3” “end”
*Aug 10 20:23:17.987: %LINEPROTO-5-UPDOWN: Line protocol on Interface Loopback3, changed state to up
Router(tcl)#snmp_getone public ifMIB.1.5.0
{<obj oid=’ifTableLastChange.0’ val=’811373’/>}
Note To minimize locking of the configuration, use the "end" parameter as the final statement in the ios_config command.
Notice the value has changed from 121 to 811373, which indicates the Interfaces Table has been modified. Whenever this value has increased from the last time you checked it, you can be sure the Interfaces Table has been modified, indicating that an interface was either added or removed.
The sysUpTime parameter is a 32-bit numeric value that indicates the time a change was made in reference to the system uptime, with the least significant number being .01 sec-onds. You can determine the time as follows:
811373/100 = seconds 8113.73 seconds 811373/60 = minutes 135.22 minutes 135.22/60 = hours
2.25 hours
The last change was 2.25 hours after the system started.
SNMP MIB objects are kept in a particular order. It is possible to request information about the next object after the current object. You might wonder why SNMP needs this capability and why getone is insufficient? There are two reasons. The first is that there may be gaps in a particular implementation of a MIB. Certain objects are optional, and a particular vendor such as Cisco might choose to or not to implement a specific object. Objects might be left unimplemented if they are too difficult or CPU intensive to calculate. The second reason is that getone is not sufficient because of tables, as explained next.
You can query the next object after ifTableLastChange using snmp_getnext command:
Router(tcl)#snmp_getnext public ifTableLastChange.0 {<obj oid=’ifStackLastChange.0’ val=’811373’/>}
Chapter 3: Tcl Functioning in Cisco IOS 49
The ifStackLastChange is the next object after ifTableLastChange. If the process is con-tinued, the entire MIB tree can be “walked”:
Router(tcl)#snmp_getnext public ifTableLastChange.0 {<obj oid=’ifStackLastChange.0’ val=’326343004’/>}
Router(tcl)#snmp_getnext public ifStackLastChange.0
{<obj oid=’atmTrafficDescrParamEntry.2.0’ val=’mib-2.37.1.1.1’/>}
Router(tcl)#snmp_getnext public atmTrafficDescrParamEntry.2.0 {<obj oid=’atmTrafficDescrParamEntry.3.0’ val=’0’/>}
Router(tcl)#snmp_getnext public atmTrafficDescrParamEntry.3.0 {<obj oid=’atmTrafficDescrParamEntry.4.0’ val=’0’/>}
Caution Entering the snmp_getnext command in repetition through a script will essen-tially perform a “MIB walk” and might cause high CPU utilization. Exercise caution when using this command.
The following example displays every MIB variable, and yes, this will drive up the CPU:
set MIB_Object [snmp_getnext public 1.0]
set Start_Position [string first “‘“ $MIB_Object]
set Number_of_MIBS 0 set Valid_Data -1
while {$Valid_Data == -1} { puts $MIB_Object
set End_Position [string first “‘ val” $MIB_Object]
set Next_MIB [string range $MIB_Object [expr $Start_Position + 1] [expr
$End_Position - 1]]
set MIB_Object [snmp_getnext public $Next_MIB]
set Start_Position [string first “‘“ $MIB_Object]
incr Number_of_MIBS
set Valid_Data [string first “END_OF_MIB” $MIB_Object]
}
puts “This is the total number of MIB objects: $Number_of_MIBS”
...output suppressed...
{<obj oid=’internet.6.3.12.1.4.0’ val=’0’/>}
{<obj oid=’internet.6.3.12.1.5.0’ val=’0’/>}
This is the total number of MIB objects: 24759
The following shows high CPU utilization because of Tcl script:
Router#show processes cpu | exclude 0.00
CPU utilization for five seconds: 99%/1%; one minute: 56%; five minutes: 26%
PID Runtime(ms) Invoked uSecs 5Sec 1Min 5Min TTY Process 2 292 657979 0 0.08% 0.03% 0.02% 0 Load Meter 115 28460 248046 114 0.48% 0.29% 0.15% 0 IP Input
231 504916 3819 132211 97.14% 54.48% 25.01% 515 Tcl Serv- tty51
In addition to simple objects, SNMP allows for tables to be built that store data. One exam-ple is the actual Interfaces Table. If you want to get all the elements from the Interfaces Table, you can repeatedly use snmp_getnext until you have passed the last element in the table.
In the Interfaces Table definition, there is an object that stores the name of a particular interface on the router. This object is called ifDescr. The following example will “walk”
through all the objects in this table one by one, until you realize you have all of them:
Router(tcl)#snmp_getnext public ifDescr.0 {<obj oid=’ifDescr.1’ val=’Ethernet0/0’/>}
Router (tcl)#snmp_getnext public ifDescr.1 {<obj oid=’ifDescr.2’ val=’Ethernet0/1’/>}
Router (tcl)#snmp_getnext public ifDescr.2 {<obj oid=’ifDescr.3’ val=’Ethernet0/2’/>}
Router (tcl)#snmp_getnext public ifDescr.3 {<obj oid=’ifDescr.4’ val=’Ethernet0/3’/>}
Router (tcl)#snmp_getnext public ifDescr.4 {<obj oid=’ifDescr.5’ val=’VoIP-Null0’/>}
Router (tcl)#snmp_getnext public ifDescr.5 {<obj oid=’ifDescr.6’ val=’Null0’/>}
Router (tcl)#snmp_getnext public ifDescr.6 {<obj oid=’ifDescr.7’ val=’Loopback3’/>}
Router (tcl)#snmp_getnext public ifDescr.7 {<obj oid=’ifType.1’ val=’6’/>}
From the last line of the output, you see that the device returned the next object after the one you asked it for. The response coming back from the router is simply fed back into the next request. The process continues, until you realize you have walked past the objects you are interested in. When the last response came back, the router responded with ifType.1, which is past the last ifDescr object in the Interfaces Table. As you can see, there are four Ethernet interfaces in the router, plus the loopback interface created earlier.
This matches other show commands, such as show ip interface brief:
Router(tcl)#show ip interface brief
Interface IP-Address OK? Method Status Protocol Ethernet0/0 unassigned YES NVRAM administratively down down Ethernet0/1 unassigned YES NVRAM administratively down down Ethernet0/2 unassigned YES NVRAM administratively down down Ethernet0/3 unassigned YES NVRAM administratively down down Loopback3 unassigned YES NVRAM up up
You may have noticed two other interfaces: VoIP-Null0 and Null0. VoIP-Null0 is purely cosmetic and will be enabled when Cisco Express Forwarding (CEF) is turned on, and Null0 is the bit bucket or garbage can for discarding traffic.
Because of the complexity of tables in SNMP, there are other methods besides snmp_getone and snmp_getnext that can fetch multiple items at once. For convenience, there is also snmp_getbulk, which provide a particular number of MIB objects simultaneously.
Chapter 3: Tcl Functioning in Cisco IOS 51
For example:
Router(tcl)#snmp_getbulk public 0 10 ifDescr.0 {<obj oid=’ifDescr.1’ val=’Ethernet0/0’/>}
{<obj oid=’ifDescr.2’ val=’Ethernet0/1’/>}
{<obj oid=’ifDescr.3’ val=’Ethernet0/2’/>}
{<obj oid=’ifDescr.4’ val=’Ethernet0/3’/>}
{<obj oid=’ifDescr.5’ val=’VoIP-Null0’/>}
{<obj oid=’ifDescr.6’ val=’Null0’/>}
{<obj oid=’ifDescr.7’ val=’Loopback3’/>}
{<obj oid=’ifType.1’ val=’6’/>}
{<obj oid=’ifType.2’ val=’6’/>}
{<obj oid=’ifType.3’ val=’6’/>}
The output shows 10 of the objects within the Interfaces Table, starting from the first interface description. Besides the usual community string and object names, two numeric values are passed into snmp_getbulk.
The first is non_repeaters, which will be used to limit the responses and can be set to 0 or 1. The second is max_repetitions, which will also limit the number of get-next attempts that will be made within the table. Setting these values will limit how many objects will be returned in the response. In practice, when you are setting the
max_repetitions to an extremely high value, the responses are limited by the maximum SNMP packet size, which is configured using the snmp-server packetsize command.