Validation TcL Script (Ping/Trace)

Answered Question
Feb 11th, 2013
User Badges:

I am looking for a script that I can use to help simplify my validation steps when I am doing some work on my devices. I typcially have anywhere from 2 - 10 IP addresses that I need to validate against (typically less than 5 though). My common steps are to ping each of my IP addresses and then I run a traceroute to those IP's to validate they are first reachable and then second I need to validate the path that is being taken is correct before my work and then after my work. So far I have come acrosss a TcL script that I could use for Ping, but not for trace. Ideally it would be nice if I could runa single line command with each IP address and then when I press enter the script will do the rest.


a sample of what I would like to do is type:

Script name: validate


R1(tcl)#validate x.x.x.x y.y.y.y z.z.z.z



The Ping script I found is below. I don't quite like it because it is not dynamic enough for what I am looking for, and I cannot seem to make this work for trace.


R1#tclsh

R1(tcl)#foreach address {

+>(tcl)#172.12.23.2

+>(tcl)#172.12.23.3

+>(tcl)#172.12.23.4

+>(tcl)#172.12.23.6

+>(tcl)#172.12.23.7

+>(tcl)#} { ping $address

+>(tcl)#}



Thank you,

Toby

Correct Answer by Daniel Frey about 4 years 4 months ago

Another option is to use the "args" argument in the procedure.


proc validate {args} {

foreach address $args {

    set output [exec "ping $address"]

    puts $output

    if { [regexp {.!!!!} $output] } {

        set output [exec "traceroute $address"]

        puts $output

    }


}

}


validate 192.168.223.3 192.168.0.253

Correct Answer by mstewart100 about 4 years 4 months ago

I am learning TCL too and feel I can assist in some of this for you.


The reason why you get an invalid argument is because you are using argv which only accepts arguments when you are calling a tcl script to run from a command line and you add arguments at the end to feed into the script dynamically.


eg if you save a script called pingtest.tcl into the routers flash, then after the .tcl are your arguments that argv will soak in

in otherwors "Command line arguments are stored in the list named 'argv"


pingtest.tcl 192.168.1.1 192.168.1.2 192.168.1.3 etc etc


I would recommend for now just turning it into a proc which you can use in the interactive tcl shell on the router. After you do that then you can branch off into saving it into flash or whatever.


To turn it into a procedure you can forget about the argv stuff and just put the ip address directly into the proc argument.

This means that when you call your proc name it will execute the procedure body using the argument in the proc.


have a go at this. To make it neater you can create a placeholder variable for all the IP's you want to validate.

What this will do is, if the ping is succesfull then it will go on to execute the traceroute.

however if the ping fails then no traceroute is executed and it goes on to the next IP in the list.


eg -

set ip "192.168.1.1 192.168.1.2 192.168.1.3 192.168.1.4 192.168.11.5 192.168.12.5 192.168.1.5 192.168.1.6 184.32.33.1 192.168.1.7 192.168.1.8 192.168.1.9 192.168.1.10"


----------------------------------------------------------------------------

Copy this into your routers interactive shell

----------------------------------------------------------------------------


set ip "192.168.1.1 192.168.1.2 192.168.1.3 192.168.1.4 192.168.11.5 192.168.12.5 192.168.1.5 192.168.1.6 184.32.33.1 192.168.1.7 192.168.1.8 192.168.1.9 192.168.1.10"



proc validate {x} {

set counter 1

puts "###########################"

puts "# Running Ping Validation #"

puts "###########################\n\n"



foreach ip_address $x {

set pings [exec ping $ip_address]

if {[regexp {!!!!} $pings]} {

puts "Analysing Ping $counter to IP - $ip_address"

puts "Ping to $ip_address - \[SUCCESSFULL\]\n\n"

puts "*****Validating path to $ip_address via traceroute*****"

traceroute $ip_address

puts \n

puts "\[COMPLETED\]\n\n"

puts -----------------------------------------------------------

puts \n\n

} else {

puts "Analysing Ping $counter to IP - $ip_address"

puts "Ping to $ip_address - \[FAIL\]\n\n"

puts -----------------------------------------------------------

}

incr counter

}

}


validate $ip


----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

END

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

-also its worth to note the tcl traceroute command is finiky, if you use exec it most likely wont work and just hang until all 30 hops are done. (potentially ios version dependant as I have read a couple of Josephs posts on similar issues with it)

It would be easy to convert back into argv. Just replace to foreach ip_address $argv and get rid of the procedure.

  • 1
  • 2
  • 3
  • 4
  • 5
Overall Rating: 0 (3 ratings)
Loading.
Joe Clarke Mon, 02/11/2013 - 06:40
User Badges:
  • Cisco Employee,
  • Hall of Fame,

    Founding Member

You could make an easy modification to make it more dynamic:


foreach address $argv {

    set output [exec "ping $address"]

    puts $output

    if { [regexp {!!!!!} $output] } {

        set output [exec "traceroute $address"]

        puts $output

    }

}

tobyarnett Mon, 02/11/2013 - 09:16
User Badges:

Joseph,


Thanks for the reply. That is good information, but I think I am still stuck on something. I am not sure what how to get this to run the way I want. I put in the script you listed, then I tried to initiate this by doing the


R1(tcl)#address 10.1.1.1


command, but I got an invalid argument. I was hoping that I could create this file that would allow me to go in at the start of a change and end of a change and run a simple command (such as "address 10.1.1.1", or even something like "address 10.1.1.1 10.2.1.1 10.3.1.1" and have it run the command on all three addresses in one statement.


I was reading that I could use the proc command to and input my values below, but I am still learning this stuff and am just missing how this is to be called:


So using what you listed I got this below - please tell me where I am going completely off base on this stuff. Thank you again!


R1(tcl)#proc validate {address} {

foreach address $argv {

    set output [exec "ping $address"]

    puts $output

    if { [regexp {!!!!!} $output] } {

        set output [exec "traceroute $address"]

        puts $output

    }

}



After script is entered i can then go in an check my IP's using the single line command:


R1(tcl)#validate 10.1.1.1 10.2.1.1

Correct Answer
mstewart100 Wed, 02/13/2013 - 04:03
User Badges:

I am learning TCL too and feel I can assist in some of this for you.


The reason why you get an invalid argument is because you are using argv which only accepts arguments when you are calling a tcl script to run from a command line and you add arguments at the end to feed into the script dynamically.


eg if you save a script called pingtest.tcl into the routers flash, then after the .tcl are your arguments that argv will soak in

in otherwors "Command line arguments are stored in the list named 'argv"


pingtest.tcl 192.168.1.1 192.168.1.2 192.168.1.3 etc etc


I would recommend for now just turning it into a proc which you can use in the interactive tcl shell on the router. After you do that then you can branch off into saving it into flash or whatever.


To turn it into a procedure you can forget about the argv stuff and just put the ip address directly into the proc argument.

This means that when you call your proc name it will execute the procedure body using the argument in the proc.


have a go at this. To make it neater you can create a placeholder variable for all the IP's you want to validate.

What this will do is, if the ping is succesfull then it will go on to execute the traceroute.

however if the ping fails then no traceroute is executed and it goes on to the next IP in the list.


eg -

set ip "192.168.1.1 192.168.1.2 192.168.1.3 192.168.1.4 192.168.11.5 192.168.12.5 192.168.1.5 192.168.1.6 184.32.33.1 192.168.1.7 192.168.1.8 192.168.1.9 192.168.1.10"


----------------------------------------------------------------------------

Copy this into your routers interactive shell

----------------------------------------------------------------------------


set ip "192.168.1.1 192.168.1.2 192.168.1.3 192.168.1.4 192.168.11.5 192.168.12.5 192.168.1.5 192.168.1.6 184.32.33.1 192.168.1.7 192.168.1.8 192.168.1.9 192.168.1.10"



proc validate {x} {

set counter 1

puts "###########################"

puts "# Running Ping Validation #"

puts "###########################\n\n"



foreach ip_address $x {

set pings [exec ping $ip_address]

if {[regexp {!!!!} $pings]} {

puts "Analysing Ping $counter to IP - $ip_address"

puts "Ping to $ip_address - \[SUCCESSFULL\]\n\n"

puts "*****Validating path to $ip_address via traceroute*****"

traceroute $ip_address

puts \n

puts "\[COMPLETED\]\n\n"

puts -----------------------------------------------------------

puts \n\n

} else {

puts "Analysing Ping $counter to IP - $ip_address"

puts "Ping to $ip_address - \[FAIL\]\n\n"

puts -----------------------------------------------------------

}

incr counter

}

}


validate $ip


----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

END

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

-also its worth to note the tcl traceroute command is finiky, if you use exec it most likely wont work and just hang until all 30 hops are done. (potentially ios version dependant as I have read a couple of Josephs posts on similar issues with it)

It would be easy to convert back into argv. Just replace to foreach ip_address $argv and get rid of the procedure.

Correct Answer
Daniel Frey Wed, 02/13/2013 - 05:13
User Badges:
  • Cisco Employee,

Another option is to use the "args" argument in the procedure.


proc validate {args} {

foreach address $args {

    set output [exec "ping $address"]

    puts $output

    if { [regexp {.!!!!} $output] } {

        set output [exec "traceroute $address"]

        puts $output

    }


}

}


validate 192.168.223.3 192.168.0.253

tobyarnett Wed, 02/13/2013 - 11:08
User Badges:

Matt,


Thank you very much. This was a lot more than I was looking for, but I actually like the way this resolves. Thank you for listing out the steps in order so I could enter them in. This really helps with the learning process. I will take this and examine the code to help further understanding what I need to do.



Dafrey,


Thank you also. This is a simpler versiona and I appreciate the reply to have an alternate method of action. I am going to review both and see what will work best. Thank you all for the help!!!


-Toby

Actions

This Discussion

Related Content