What is running on your network? (tcl and expect)
Archive - Originally posted on "The Horse's Mouth" - 2008-09-04 23:53:51 - Graham EllisEarlier this week, I gave a much-tailored Tcl course, with a strong helping of expect.
Expect adds three major extra commands to Tcl - spawn to start a new process under the control of the running Tcl/Tk code, send to send information to it and expect to await for - and decide on how to process - a particular response. It is a very clever way to automate other process which are designed for keyboard use, and otherwise very hard to automate.
Here's an example - written largely during the course, and which I ran (when I got back to base) to test our own network at Well House Manor which pings a whole series of hosts in turn, and then analyses their response to give a summary of what is up and running.
log_user 0
set iplist "67 99 134"
for {set k 210} {$k<223} {incr k} {
lappend iplist $k
}
foreach lastbit $iplist {
spawn ping -c2 192.168.200.$lastbit
puts -nonewline "testing $lastbit ... "
flush stdout
# expect is like a switch ;-)
expect {
"2 packets received" {
set between $expect_out(buffer)
regexp {time=([^\n]+)} $between all actual
puts "Present - sample timing - $actual"
set located($lastbit) $actual
}
"packets received" { puts "POOR"}
timeout { puts UNFOUND}
eof { puts GONEAWAY}
}
}
puts "--------------- System Available Summary ---------"
foreach host [lsort -integer [array names located]] {
puts "192.168.200.$host"
}
exit
--- Since Tcl is a truly interpretive language, I can
add any comments - or this sample output - below my
exit command, and it this text won't every be interpreted
testing 67 ... Present - sample timing - 2.054 ms
testing 99 ... Present - sample timing - 0.114 ms
testing 134 ... Present - sample timing - 4.521 ms
testing 210 ... UNFOUND
testing 211 ... UNFOUND
testing 212 ... UNFOUND
testing 213 ... UNFOUND
testing 214 ... UNFOUND
testing 215 ... Present - sample timing - 294.033 ms
testing 216 ... UNFOUND
testing 217 ... UNFOUND
testing 218 ... Present - sample timing - 103.647 ms
testing 219 ... UNFOUND
testing 220 ... UNFOUND
testing 221 ... UNFOUND
testing 222 ... Present - sample timing - 5.454 ms
--------------- System Available Summary ---------
192.168.200.67
192.168.200.99
192.168.200.134
192.168.200.215
192.168.200.218
192.168.200.222
Now ... that's a slow process, as each failing connection times out in series. Which is ironic, because the time at which you want a faster response is when you have systems down / network issues.
Using a list of spawn_ids, Expect can run a whole series of processes in parallel and can wait on any one of them, knowing which one has responded and processing it as appropriate. There's a complete example I've written of this available on our web site [source code link] and it's covered during our public Tcl course; the version I've linked to is for Mac OS X (ping's responses vary by operating system) - if you're looking for versions that run on various Linux distributions, you'll find links to them from the Mac page.

The default setup tests my servers (at 192.168.20.67, 99 and 222), my outbound connection (at .134) and our fleet of training systems - so that you can see that this evening we have a functioning network connection box, a server, and two "late bird" systems - "Easterton" at .215 and "Holt" at .218
I've already received a request to annotate the display ;-) .... which I will indeed do - so that the page gives a very much more graphic report of our network, with machine names and functions included and flags up whether or not we're on line, and so on. Easy to do, but it'll obfuscate the source code demonstration a little.