Category: Tcl

Display the names of the configured route-maps

I’m probably getting old … I keep forgetting the exact names (and capitalization) of route-maps I’ve configured on the router. The show route-maps command is way too verbose when I’m simply looking for the exact name of the route-map I want to use, so I wrote a Tcl script that displays the names of the route-maps configured on the router. If you add a -d switch, it also displays their descriptions (to be more precise, the first description configured in the route-map).

read more see 1 comments

Phase 2: Upload text files through a Telnet session

In a previous post, I've described how you can use Tcl shell to upload text content into router's flash if the router has no connectivity to a suitable file server (or you don't have FTP or TFTP server handy).

The trick works flawlessly, but typing the same obscure Tcl commands gets tedious after a while, so the first time I had to use this solution to develop a Tcl script, I've quickly written another script that takes file name as the parameter and hides all the other murky details.

To use it, transfer the contents of storeFile.tcl (available from my web site) to the router's flash (using the previously described trick), follow the installation instructions in the source and you're ready to go.

Note: You can adapt the Tcl script to your needs; for example, you could add instructions to re-register EEM Tcl policy every time you upload the new code.

see 1 comments

Implement “wc -l” in Cisco IOS

Sometimes it would be nice to have the full complement of Unix utilities available on Cisco IOS. That's not going to happen for a while, but we can use Tcl to make our life simpler in the meantime. Xavier Brouckaert, a regular contributor to my blog, has sent me the Tcl implementation of line counting utility (equivalent to wc -l on Unix).

First you have to define the wc Tcl procedure:
proc wc { cmd } { llength [split [exec $cmd] "\n" ] }
You can define the procedure interactively in Tclsh (but then you have to do it every time you start Tclsh) or you could store the code in a flash file and execute the file every time the Tclsh is started with the scripting tcl init filename global configuration command.

Once the wc procedure is defined, execute wc { IOS command } in Tclsh and you'll get the line count. For example, to get the number of directly connected routes use
wc { show ip route ¦ include ^C }

The include ^C filter includes all lines that start with letter C; in our case all directly connected routes

Obviously you could turn this idea into a full-blown Tclsh script that would accept CLI arguments … but I'll leave this as an exercise for the readers (you can probably tell I've been reading some academic literature lately :). However, if you find the time to write a more complete wc implementation on IOS, please do post the URL here.

see 2 comments

Copy the text files into router's flash through a Telnet session

Were you ever in a situation where a file that would have to be on the router was sitting on your laptop, but you couldn't store it into the router's flash across the Telnet session or through the console port?

If the file in question is a text file, and the router supports Tcl shell, _danshtr_ documented an interesting trick: you create the file in Tclsh interpreter, cut-and-paste the text through the telnet session into a Tcl string and write the string to the file. If you want to have a more cryptic solution here it is:
  • Start tclsh;
  • Enter puts [open "flash:filename" w+] {. Do not hit the ENTER key at the end of the line
  • Copy-paste the file contents. The contents should not include unmatched curly right brackets (every curly right bracket has to be preceded by a matching curly left bracket).
  • After the file contents have been pasted, enter } and press ENTER.
  • End the tclsh session with tclquit.
see 21 comments

Can I combine EEM applets with Tcl shell?

When I’ve been describing the limitations of kron, someone quickly asked an interesting question:

As I cannot insert extra input keystrokes with EEM applet, can I run a Tcl script from it with the action sequence cli command “tclsh script command and use the typeahead function call to get around the limitation?”

The only answer I could give at that time was “maybe” … and obviously it was time for a more thorough test. The short result is: YES, you can do it (at least in IOS release 12.4(15)T1).

read more see 16 comments

Persistent EEM variables

Someone has asked me a while ago whether it's possible to retain variable values between invocations of an EEM policy. Since a new copy of Tcl interpreter is started for each event, global variables obviously won't work; they are lost as soon as the Tcl policy is finished. A potential solution is to modify the router's configuration and save the values you wish to preserve in event manager environment, but that's a time-consuming process that interferes with whatever router configuration management process you have.

The real solution is based on the appl_setinfo and appl_reqinfo calls. They work, but like many other Tcl-related IOS features they are … well … weird.
read more add comment

Tabular display of interface MTUs

When I started exploring the details of MTU handling in Cisco IOS, I quickly got tired of analyzing various long printouts to extract the MTU sizes, so I wrote a Tcl script that display hardware, IP and MPLS MTUs in a tabular format. To install it on your router:
  1. Download it from my web site and copy it to your router's flash or NVRAM.
  2. Define an alias, for example alias exec mtu tclsh flash:displayMTU.tcl.

The script recognizes two parameters: the ip parameter displays only the interfaces that have IP configured and the mpls parameter displays only the MPLS-enabled interfaces.

read more see 2 comments

SNMP with Tcl

Looking from the outside, it looks like Tcl SNMP routines in Cisco IOS were designed by a commitee or came straight from Dilbert. The snmp_getone function that reads a single SNMP value does not return an array or a list (as one would expect), but a string representation of something that looks like an XML object (but is not, since its attributes are not properly quoted). As Tcl on Cisco IOS has no built-in XML support, parsing the return values is a pure joy (and a nice exercise in writing regular expressions).

The following excerpt of a telnet session shows how to extract a single SNMP value in Tcl (I've used extra steps and an interactive tclsh session for illustration purposes). The SNMP community has to be configured in advance with the snmp-server community test ro configuration command.
rtr#tclsh
rtr(tcl)#set value [snmp_getone test system.3.0]
{<obj oid='sysUpTime.0' val='14886'/>}
rtr(tcl)#regexp -inline {oid='(.*)'.*val='(.*)'} $value
{oid='sysUpTime.0' val='14886'} sysUpTime.0 14886
rtr(tcl)#regexp {oid='(.*)'.*val='(.*)'} $value ignore oid result
1
rtr(tcl)#puts $result
14886
And now for a complete example: the following script prints the router uptime.
#
# Simple Tcl script to print system uptime
#
set value [snmp_getone test system.3.0]
regexp {oid='(.*)'.*val='(.*)'} $value ignore oid result
set result [expr $result / 100]
puts "Router uptime is $result seconds"
see 3 comments

Display IP packet filters attached to router's interfaces

A few days ago, Jeremy Stretch asked me whether there's a command to display packet lists attached to router's interfaces. While he got pretty far with the output filters, he would like to have a nice tabular format as well as the contents of the access lists displayed next to the interfaces. The show ip access-list interface name command comes pretty close, but it displays the information only for a single interface, so it was time to write another Tcl script. To install it on your router:
  1. Download it from my web site and copy it to your router's flash or NVRAM.
  2. Define an alias, for example alias exec filters tclsh flash:packetFilters.tcl.

The script recognizes two parameters: the all parameter displays all interfaces, including ones with no access lists and the verbose parameter displays the contents of the access list after the interface name.

read more see 4 comments

DNS resolver package for IOS Tcl

I've ported the dns package of the Tcl standard library to Cisco IOS. You can download it from my web site and install it on your router in just a few steps:
  1. Extract all the files from the ZIP archive and copy the Tcl files into a subdirectory on your router's flash (I would recommend you use flash:tcllib/dns).
  2. Configure the package initialization script with the scripting tcl init flash:tcllib/dns/pkgIndex.tcl global configuration command
To test the successful installation, start the Tcl shell from the command prompt and try to load the DNS package:
router#tclsh
router(tcl)#package require dns
1.3.1
router(tcl)#
see 2 comments

Using Tcl packages on Cisco IOS

Although it's not exactly trivial, you can use standard Tcl packages with Tcl
shell on Cisco IOS by following this procedure:

$ tclsh
% pkg_mkIndex . *.tcl
% ^Z
$
  • Edit the pkgIndex.tcl file created with the pkg_mkIndex command and set the $dir variable to the IOS directory before the first package command (for example, set dir "flash:tcl/").
  • Alternatively, add the Tcl command set dir [file dirname [info script]] in front of the first package command. This command sets the $dir variable to the path of the pkgIndex.tcl file.
  • Transfer all the source files into a directory on the router's flash (or any other local storage device).
  • Configure the execution of the pkgIndex.tcl file at tclsh startup with the scripting tcl init configuration command (for example, scripting tcl init flash:tcl/pkgIndex.tcl).

When you have completed these steps, the pkgIndex.tcl file will be executed every time the Tcl shell is started in Cisco IOS, defining all the packages you've prepared. Now you can use the package require name Tcl command to load the packages you need in your Tcl script.

see 2 comments

Reload a Router from Tcl Script

In his comment, Michal has asked about the ability to execute IOS commands with prompts from Tcl shell. I haven't found a generic solution yet, but you can reload a router from a Tcl script. First you have to define an EEM applet that reloads the router and can be triggered from command-line interface:
event manager applet forceReload
event none
action 1.0 reload
Now you can use the exec "event manager run forceReload" Tcl command in your Tcl script to run the applet (and reload the router).

Notes:

see 2 comments

Example: Tcl script with command-line parameters

In a comment to the “Execute multiple commands at once” post, Michal has asked for a complete Tcl-shell-with-parameter example. Here's a short script that shuts down the interface and displays its status:

  • Variable ifname is set to the value of the first command-line parameter (in many other programming languages, this would be written as argv[0]);
  • If the ifname is empty, the script aborts and prints the usage guidelines (again, in a more human-oriented programming language, this would be if (ifname == “”) ...);
  • The show ip interface ifname command is executed. If it fails, the interface name is not correct and the script aborts.
  • IOS configuration commands interface ifname and shutdown are executed.
  • The show ip interface brief configuration command is executed and filtered with the interface name.
#
# ifname is set to first CLI parameter (interface name)
#
set ifname [lindex $argv 0]
if {[string equal $ifname ""]} { puts "Usage: shutdown ifname"; return; }
if { [ catch { exec "show ip interface $ifname" } errmsg ] } {
puts "Invalid interface $ifname, show ip interface failed"; return}

ios_config "interface $ifname" "shutdown"
puts [ exec "show ip interface brief ¦ include $ifname" ]

If you store this Tcl script into your flash as shutdown.tcl and configure alias exec shutdown tclsh flash:shutdown.tcl, you can execute the command shutdown Serial0 to shut down the serial interface.

Notes:

  • The last show command will display the interface status only if the specified interface name exactly matches the actual IOS interface name (whereas the rest of the script accepts shortcut names). The more generic matching algorithm is left as an exercise for the reader
  • For more in-depth information on Tclsh implementation on Cisco IOS, read the IOS Tclsh resources.
  • This article is part of You've asked for it series.
see 10 comments

Update: The “show ip interface” command I've always wanted to have

After I've published the Tcl script that displays the interface IP parameters in a formatted table, cos quickly pointed out a bug: I've expected the IP addresses in the address mask format. In the meantime, I've figured out the root cause of the problem (our remote labs are set to display IP masks in decimal format for compatibility reasons) and fixed the Tcl script. It temporarily sets the terminal ip netmask-format to bit-count before executing the show command. The new script recognizes three parameters:

  • active: display only interfaces that are up/up;

  • configured: display only interfaces with configured IP addresses (unnumbered interfaces using IP address of an interface without one count as configured since IOS reports their IP address as 0.0.0.0).

  • address: displays IP address of the unnumbered interface, not the interface that it's borrowing the address from.
You can view the Tcl source or download it from my web site.
see 6 comments
Sidebar