Listing 2: configrouter
#!/usr/bin/expect --
# Expect script to change Cisco router's configuration
# usage: configrouter username password enablepassword
# define the timeout value
# timeout will be used to handle unexpected response from router
set timeout 90
# receives TACACS+ username, password, and router's enable password
# from command line
set username [lindex $argv 0]
set password [lindex $argv 1]
set enablepass [lindex $argv 2]
set argc [llength $argv]
# define necessary parameters and file handles
set TFTPD 10.7.2.67
set configuration /tmp/ntp
set routerlist [open "/tmp/routerlist" "r"]
set logfile [open "/tmp/ntp_config" "w"]
# turn on Expect's logging facility
log_file /tmp/configrouter.log
# code blocks for procedures
# procedure to enter router's configuration one line at a time under Cisco
# router's configuration mode from terminal
# return 1 if successful, otherwise return 0
proc config_router {config_file} {
send "config terminal\r"
expect {
"(config)#" {
set file [open $config_file "r"]
while {[gets $file buffer] != -1} {
send "$buffer\r"
}
close $file
send "end\r"
return 1
}
timeout {
send "end\r"
return 0
}
}
}
# procedures to save changed configuration to NVRAM
# return 1 if successful, otherwise return 0
proc save_config_to_nvram {} {
send "copy running-config startup-config\r"
expect {
-re "OK" {return 1}
# in case this is the first time the running configuration ever saved to
NVRAM
-re "confirm" {
send "yes\r"
expect {
-re "OK" {return 1}
timeout {return 0}
}
}
timeout {return 0}
}
}
# procedure to save the configuration to target TFTP server
# return 1 if successful, otherwise return 0
proc save_config_to_net {log router tftpd} {
send "copy running-config tftp\r"
# check to see if default TFTP server's IP address match the target TFTP
server's
# if yes, hit enter. if not, replace it with target TFTP server's IP adress
# the "\\\[" is Expect's way to interpret "[" literally
# expect_out(1,string) will capture whatever is inside the brackets
expect
-re "\\\[(.*)\\\]" {
if {[string compare $expect_out(1,string) $tftpd] == 0} {
puts $log "Saving configuration to $expect_out(1,string)\r"
send "\r"
} else {
puts $log "Saving configuration to $tftpd\r"
send "$tftpd\r"
}
}
}
# save the configuration file by the default name to TFTP server
# if there is no default name set, use router's hostname followed by
"-confg" as file name
expect {
-re "\\\[(.*)-confg\\\]" {
puts $log "save as file $expect_out(1,string) at [exec date]\r"
send "$expect_out(1,string)-confg\r"
}
timeout {
puts $log "No file name was set, set it to $router-confg\r"
send "$router-confg\r"
}
}
expect -re "\\\[confirm\\\]" {send "\r"}
expect {
-re "OK" {return 1}
-re "Access violation" {
puts $log "Access violation, check file permission on server\r"
return 0
}
-re "Failed" {
puts $log "File not found, create an file by this name first on
the server\r"
return 0
}
-re "File not found" {
puts $log "File not found, create an file by this name first on
the server\r"
return 0
}
}
}
# main program body starts here
# first check to see if the usage is correct
if { $argc < 3 } {
puts "usage: configrouter username password enablepassword\r"
exit 1
}
while {[gets $routerlist line] !=-1} {
# some report log formatting
puts $logfile "\r"
puts $logfile "===================================================\r"
spawn telnet $line
expect {
# login to router with TACACS+ in effect, router prompt for "Login:"
# expecting hostname with the format of location ID plus company name
# e.g. LAX001-ZEROONE
"ogin: " {
puts $logfile "Connect to $line at [exec date]\r"
puts $logfile "Login by using TACACS+ username and password\r"
send "$username\r"
expect "word: " { send "$password\r" }
expect {
-re "(\[a-zA-Z]+)(\[0-9]+)-ZEROONE>" {
send "enable\r"
expect "word: " { send "$password\r" }
}
}
if { [config_router $configuration ] == 1 } {
puts $logfile "Configuration entered OK\r"
puts $logfile "Saving running configuration to NVRAM...\r"
if { [save_config_to_nvram] == 1 } {
puts $logfile "Configuration saved to NVRAM OK.\r"
} else {
puts $logfile "Configuration not saved to NVRAM!\r"
puts $logfile "Check the log file\r"
puts $logfile "Router $line was configured"
puts $logfile "but configuration was not saved to NVRAM.\r"
}
if { [save_config_to_net $logfile $line $TFTPD] == 1 } {
puts $logfile "Configuration saved to TFTP server $TFTPD
OK.\r"
} else {
puts $logfile "Configuration not saved to TFTP!\r"
puts $logfile "Check the log file\r"
puts $logfile "Router $line was configured"
puts $logfile "but configuration was not saved to TFTP.\r"
}
send "exit\r"
close
wait
} else {
puts $logfile "Problem encounted, "
puts $logfile "check the log file\r"
puts $logfile "stop configuring this router!\r"
send "exit\r"
close
wait
}
}
# login to router without TACACS+ in effect, router prompt for "password: "
# enable password will be used
"word: " {
puts $logfile "Connected to $line at [exec date]\r"
puts $logfile "Not prompting for Username: ?\r"
puts $logfile "Perhaps not using TACACS+?\r"
puts $logfile "will try logging in by using enable password\r"
send "$enablepass\r"
expect {
-re "(\[a-zA-Z]+)(\[0-9]+)-ZEROONE>" {
puts $logfile "Login successfully by using enable
password\r"
}
timeout {
puts $logfile "Incorrect password, exiting...\r"
send "exit\r"
close
wait
continue
}
}
send "enable\r"
expect "word: "
send "$enablepass\r"
if { [config_router $configuration ] == 1 } {
puts $logfile "Configuration entered OK\r"
puts $logfile "Saving running configuration to NVRAM...\r"
if { [save_config_to_nvram] == 1 } {
puts $logfile "Configuration saved to NVRAM OK.\r"
} else {
puts $logfile "Configuration not saved to NVRAM!\r"
puts $logfile "Check the log file\r"
puts $logfile "Router $line was configured"
puts $logfile "but configuration was not saved to NVRAM.\r"
}
if { [save_config_to_net $logfile $line $TFTPD] == 1 } {
puts $logfile "Configuration saved to TFTP server $TFTPD
OK.\r"
} else {
puts $logfile "Configuration not saved to TFTP!\r"
puts $logfile "Check the log file\r"
puts $logfile "Router $line was configured"
puts $logfile "but configuration was not saved to TFTP.\r"
}
send "exit\r"
close
wait
} else {
puts $logfile "Problem encounted, "
puts $logfile "check the log file\r"
puts $logfile "stop configuring this router!\r"
send "exit\r"
close
wait
}
}
}
"Unable to connect" {
puts $logfile "Can't telent to $line at [exec date]\r"
close
wait
}
timeout {
puts $logfile "Can't configure $line at [exec date]\r"
puts $logfile "Perhaps the prompt format is unexpected?\r"
close
wait
}
}
}
close $logfile
# End of File
|