Category: Tcl
Predefine your own Tcl functions
If you want to have your own Tcl functions available when you start tclsh, you could use the scripting tcl init file configuration command that I've briefly mentioned in one of the previous posts. This command specifies a source file that is executed every time you start Tcl shell. The source file can contain function definitions, package declarations or any other Tcl code.
If you need to, you can specify multiple initialization files.
For example, if you'd like to implement a comfortable Tcl-based pinger (similar to the one Ethan Banks found in the Sadikhov forums, store the following Tcl code into the file flash:pinger.tcl …
proc pinger { iplist } {… and configure scripting tcl init flash:pinger.tcl. Now you can ping a number of hosts in a single operation:
foreach ip $iplist {
if { [regexp "(!!!)" [exec "ping $ip timeout 1" ]] } {
puts "$ip"
} else { puts "$ip **** failed ***" }
}
}
R1#tclsh
R1(tcl)#pinger { 10.0.0.1 10.0.0.2 10.0.0.3 10.0.0.4 }
10.0.0.1
10.0.0.2
10.0.0.3 **** failed ***
10.0.0.4 **** failed ***
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).
Phase 2: Upload text files through a Telnet session
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.
Implement “wc -l” in Cisco IOS
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.
… updated on Tuesday, November 17, 2020 11:46 UTC
Tabular Display of OSPF External Routes
I was testing OSPF external routes recently and wanted to have a comprehensive display of OSPF type-5 LSAs (not the too-verbose information IOS generates), so I created the following Tcl script to displays type-5 (external) LSAs from the OSPF database in a tabular format.
Here is a sample printout from one of my lab routers:
S1#ospfExternal
External OSPF routes for OSPF process ID 1
Prefix Cost Tag ASBR Forward addr
==================================================================
> 10.1.0.1/32 10 E1 1 10.0.0.3
10.1.0.1/32 2000 E1 1 10.0.0.11
> 10.1.0.2/32 5 E2 2 10.0.0.3
10.1.0.2/32 200 E2 2 10.0.0.11
Generate terminal escape sequences from Tcl
One of my readers (who unfortunately prefered to stay anonymous, so I cannot give credit where it’s due) figured out how to output escape sequences from IOS Tclsh: you have to execute terminal international command first.
We can use that functionality to do all sorts of interesting things, like clearing the screen and displaying red header text from a Tcl script running on Cisco IOS:
Copy the text files into router's flash through a Telnet session
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.
Any idea how to generate binary output from Tclsh?
router(tcl)#puts "\033\[2J"Any ideas how to persuade the router to display raw binary data?
^[[2J
router(tcl)#
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).
Persistent EEM variables
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.
Tabular display of interface MTUs
- Download it from my web site and copy it to your router's flash or NVRAM.
- 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.
SNMP with Tcl
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#tclshAnd now for a complete example: the following script prints the router uptime.
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
#
# 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"
Display IP packet filters attached to router's interfaces
- Download it from my web site and copy it to your router's flash or NVRAM.
- 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.
Display OSPF neighbor sorted by OSPF process ID
- It is not sorted by the OSPF process ID, so you get a mess if you have more than one OSPF process and don't specify the process ID in the show command
- It does not display the OSPF area the neighbor belongs to
- Download it from my web site.
- Copy the ospfNeighbors.tcl file to your router's flash (or NVRAM).
- Define an alias, for example alias exec ospf tclsh flash:ospfNeighbors.tcl.
DNS resolver package for IOS Tcl
- 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).
- Configure the package initialization script with the scripting tcl init flash:tcllib/dns/pkgIndex.tcl global configuration command
router#tclsh
router(tcl)#package require dns
1.3.1
router(tcl)#