summaryrefslogtreecommitdiffstats
path: root/bin
diff options
context:
space:
mode:
authorTar Committer <tar@ocjtech.us>2000-02-03 17:55:28 +0000
committerTar Committer <tar@ocjtech.us>2000-02-03 17:55:28 +0000
commitb24aa5051db5d4bf9757efe7df06cb1892898382 (patch)
tree9cdcee7bb6f7780d08f94997af4f8232b5bd0417 /bin
parent42de2e53682c49b050f19fdbaaf68451ba487303 (diff)
downloadrancid-b24aa5051db5d4bf9757efe7df06cb1892898382.tar.gz
rancid-b24aa5051db5d4bf9757efe7df06cb1892898382.tar.xz
rancid-b24aa5051db5d4bf9757efe7df06cb1892898382.zip
Imported from rancid-1.4.tar.gz.rancid-1.4
Diffstat (limited to 'bin')
-rwxr-xr-xbin/clogin181
-rwxr-xr-xbin/control_rancid107
-rwxr-xr-xbin/create_cvs32
-rw-r--r--bin/cvs_helper28
-rwxr-xr-xbin/do-diffs4
-rw-r--r--bin/env14
-rwxr-xr-xbin/flogin530
-rwxr-xr-xbin/francid383
-rwxr-xr-xbin/jrancid242
-rwxr-xr-xbin/rancid1172
-rwxr-xr-xbin/rancid-fe6
-rwxr-xr-xbin/rrancid347
-rwxr-xr-xbin/run-me35
13 files changed, 2301 insertions, 780 deletions
diff --git a/bin/clogin b/bin/clogin
index b8b693e..cad94cd 100755
--- a/bin/clogin
+++ b/bin/clogin
@@ -7,7 +7,7 @@
## This software may be freely copied, modified and redistributed without
## fee for non-commerical purposes provided that this copyright notice is
## preserved intact on all copies and modified copies.
-##
+##
## There is no warranty or other guarantee of fitness of this software.
## It is provided solely "as is". The author(s) disclaim(s) all
## responsibility and liability with respect to this software's usage
@@ -29,8 +29,8 @@
# Usage line
set usage "Usage: $argv0 \[-u user\] \[-p user-password\] \[-v vty-password\] \
\[-w enable-username\] \[-e enable-password\] \[-noenable\] \
-\[-f cloginrc-file\] \[-c command\] \[-s script-file\] \[-autoenable\] \
-\[-t timeout\] router \[router...\]\n"
+\[-f cloginrc-file\] \[-y ssh_cypher_type\] \[-c command\] \[-s script-file\] \
+\[-x command-file\] \[-autoenable\] \[-t timeout\] router \[router...\]\n"
# env(CLOGIN) may contain:
# x == do not set xterm banner or name
@@ -53,8 +53,8 @@ set do_enapasswd 1
if {[ info exists env(CISCO_USER) ] } {
set default_user $env(CISCO_USER)
} else {
- # This uses "id" which I think is portable. At least it has existed
- # (without options) on all machines/OSes I've been on recently -
+ # This uses "id" which I think is portable. At least it has existed
+ # (without options) on all machines/OSes I've been on recently -
# unlike whoami or id -nu.
regexp {\(([^)]*)} [exec id] junk default_user
}
@@ -125,6 +125,13 @@ for {set i 0} {$i < $argc} {incr i} {
exit 1
}
set do_script 1
+ # cypher type
+ } -y* -
+ -Y* {
+ if {! [ regexp .\[eE\](.+) $arg ignore cypher]} {
+ incr i
+ set cypher [ lindex $argv $i ]
+ }
# alternate cloginrc file
} -f* -
-F* {
@@ -136,17 +143,17 @@ for {set i 0} {$i < $argc} {incr i} {
-T* {
incr i
set timeout [ lindex $argv $i ]
- } -x* -
- -X {
- if {! [ regexp .\[xX\](.+) $arg ignore cmd_file]} {
- incr i
- set cmd_file [ lindex $argv $i ]
- }
- set cmd_fd [open $cmd_file r]
- set cmd_text [read $cmd_fd]
- close $cmd_fd
- set command [join [split $cmd_text \n] \;]
- set do_command 1
+ } -x* -
+ -X {
+ if {! [ regexp .\[xX\](.+) $arg ignore cmd_file]} {
+ incr i
+ set cmd_file [ lindex $argv $i ]
+ }
+ set cmd_fd [open $cmd_file r]
+ set cmd_text [read $cmd_fd]
+ close $cmd_fd
+ set command [join [split $cmd_text \n] \;]
+ set do_command 1
# Do we enable?
} -noenable {
set enable 0
@@ -192,20 +199,20 @@ proc label { host } {
if [regexp \^(xterm|vs) $env(TERM) ignore ] {
send_user "\033]1;[lindex [split $host "."] 0]\a"
send_user "\033]2;$host\a"
- }
+ }
}
}
# This is a helper function to make the password file easier to
# maintain. Using this the password file has the form:
-# add password sl* pete cow
-# add password at* steve
+# add password sl* pete cow
+# add password at* steve
# add password * hanky-pie
-proc add {var args} { global $var ;lappend $var $args}
+proc add {var args} { global $var ;lappend $var $args}
proc find {var router} {
- source_password_file
- upvar $var list
- if { [info exists list] } {
+ source_password_file
+ upvar $var list
+ if { [info exists list] } {
foreach line $list {
if { [string match [lindex $line 0] $router ] } {
return [lrange $line 1 end]
@@ -219,11 +226,11 @@ proc find {var router} {
# it is sourced, the user better know what to put in there, as it
# could install more than just password info... I will assume however,
# that a "bad guy" could just as easy put such code in the clogin
-# script, so I will leave .cloginrc as just an extention of that script
+# script, so I will leave .cloginrc as just an extention of that script
proc source_password_file { } {
global env password_file read_password_file
if { [info exists read_password_file] } { return }
- if { [info exists password_file] == 0 } {
+ if { [info exists password_file] == 0 } {
set password_file $env(HOME)/.cloginrc
}
set read_password_file 1
@@ -236,9 +243,10 @@ proc source_password_file { } {
}
# Log into the router.
-proc login { router user userpswd passwd enapasswd prompt } {
+proc login { router user userpswd passwd enapasswd prompt cyphertype } {
global spawn_id in_proc do_command do_script
set in_proc 1
+ set tryssh 1
# Telnet to the router & try to login.
if [ catch {spawn telnet $router} reason ] {
@@ -253,19 +261,19 @@ proc login { router user userpswd passwd enapasswd prompt } {
send_user "\nError: TIMEOUT reached\n"
close; wait
if { $in_proc} {
- return 1
+ return 1
} else {
- continue
+ continue
}
- } eof {
+ } eof {
send_user "\nError: EOF received\n"
close; wait
if { $in_proc} {
- return 1
+ return 1
} else {
- continue
+ continue
}
- }
+ }
}
# Here we get a little tricky. There are several possibilities:
@@ -274,12 +282,24 @@ proc login { router user userpswd passwd enapasswd prompt } {
# TACACS server is not working, then it will use the enable
# passwd. Or, the router might not have TACACS turned on,
# then it will just send the passwd.
+ # if telnet fails with connection refused, try ssh
expect {
- eof { send_user "Error: Couldn't login\n"; wait; return 1 }
- "Connection refused" {
- expect eof
- send_user "Error: Connection Refused\n"; wait; return 1
- } "Unknown host\r\n" {
+ "Connection refused" {
+ close; wait
+ if { $tryssh } {
+ if [ catch {spawn ssh -c $cyphertype -x -l $user $router} reason ] {
+ send_user "Error: failed to ssh: $reason\n"
+ exit 1
+ }
+ set tryssh 0
+ sleep 0.3
+ exp_continue
+ } else {
+ expect eof
+ send_user "Error: Connection Refused\n"; wait; return 1
+ }
+ } eof { send_user "Error: Couldn't login\n"; wait; return 1
+ } "Unknown host\r\n" {
expect eof
send_user "Error: Unknown host\n"; wait; return 1
} "Host is unreachable" {
@@ -289,32 +309,40 @@ proc login { router user userpswd passwd enapasswd prompt } {
expect eof
send_user "Error: Unknown host\n"; wait; return 1
}
+ -re "Host key not found .* \(yes\/no\)\?" {
+ send "yes\r"
+ send_user "Host $router added to the list of known hosts.\n"
+ exp_continue }
+ -re "HOST IDENTIFICATION HAS CHANGED.* \(yes\/no\)\?" {
+ send "no\r"
+ send_user "Error: The host key for $router has changed. update the known_hosts file accordingly.\n"
+ return 1 }
-re "(Username|login):" { send "$user\r"
- expect {
- eof { send_user "Error: Couldn't login\n"; wait; return 1 }
+ expect {
+ eof { send_user "Error: Couldn't login\n"; wait; return 1 }
-re "\[Pp]assword:" { send "$userpswd\r" }
"$prompt" { set in_proc 0; return 0 }
}
exp_continue
}
- "Password:" { send "$passwd\r"
- expect {
- eof { send_user "Error: Couldn't login\n"; wait; return 1 }
+ "\[Pp]assword:" { send "$passwd\r"
+ expect {
+ eof { send_user "Error: Couldn't login\n"; wait; return 1 }
"Password:" { send "$enapasswd\r" }
- "$prompt" { set in_proc 0; return 0 }
+ "$prompt" { set in_proc 0; return 0 }
}
exp_continue
}
- "$prompt" { }
- denied { send_user "Error: Check your passwd for $router\n"
- if { $do_command || $do_script } {
+ "$prompt" { }
+ denied { send_user "Error: Check your passwd for $router\n"
+ if { $do_command || $do_script } {
send "quit"
wait
return 1
} else {
return 1
}
- }
+ }
"% Bad passwords" {send_user "Error: Check your passwd for $router\n"; return 1 }
}
set in_proc 0
@@ -358,17 +386,17 @@ proc run_commands { prompt command } {
for {set i 0} {$i < $num_commands} { incr i} {
send "[subst [lindex $commands $i]]\r"
expect {
- -re "^\[^\n\r]*$prompt." { exp_continue }
+ -re "^\[^\n\r]*$prompt." { exp_continue }
-re "^\[^\n\r *]*$prompt" {}
- "\n" { exp_continue }
- }
+ -re "\[\n\r]" { exp_continue }
+ }
}
} else {
send "[subst $command]\r"
expect {
-re "^\[^\n\r]*$prompt." { exp_continue }
-re "^\[^\n\r *]*$prompt" {}
- "\n" { exp_continue }
+ -re "\[\n\r]" { exp_continue }
}
}
send "exit\r"
@@ -410,49 +438,58 @@ foreach router [lrange $argv $i end] {
if { $do_passwd || $do_enapasswd } {
set pswd [find password $router]
if { [llength $pswd] == 0 } {
- send_user "Error - no password for $router in $password_file.\n"
- continue
- }
- if { $do_enapasswd && !$autoenable && [llength $pswd] < 2 } {
+ send_user "Error - no password for $router in $password_file.\n"
+ continue
+ }
+ if { $do_enapasswd && $autoenable == 0 && [llength $pswd] < 2 } {
send_user "Error - no enable password for $router in $password_file.\n"
- continue
+ continue
}
- set passwd [lindex $pswd 0]
- set enapasswd [lindex $pswd 1]
+ set passwd [lindex $pswd 0]
+ set enapasswd [lindex $pswd 1]
}
# Figure out username
- if {[info exists username]} {
+ if {[info exists username]} {
# command line username
set ruser $username
} else {
- set ruser [find user $router]
+ set ruser [find user $router]
if { "$ruser" == "" } { set ruser $default_user }
- }
+ }
# Figure out username's password (if different from the vty password)
if {[info exists userpasswd]} {
# command line username
set userpswd $userpasswd
} else {
- set userpswd [find userpassword $router]
- if { "$userpswd" == "" } { set userpswd $passwd }
- }
-
+ set userpswd [find userpassword $router]
+ if { "$userpswd" == "" } { set userpswd $passwd }
+ }
+
# Figure out enable username
- if {[info exists enausername]} {
+ if {[info exists enausername]} {
# command line enausername
set enauser $enausername
} else {
- set enauser [find enauser $router]
- if { "$enauser" == "" } { set enauser $ruser }
- }
+ set enauser [find enauser $router]
+ if { "$enauser" == "" } { set enauser $ruser }
+ }
+
+ # Figure out cypher tpye
+ if {[info exists cypher]} {
+ # command line cypher type
+ set cyphertype $cypher
+ } else {
+ set cyphertype [find cyphertype $router]
+ if { "$cyphertype" == "" } { set cyphertype "3des" }
+ }
# Login to the router
- if {[login $router $ruser $userpswd $passwd $enapasswd $prompt]} {
+ if {[login $router $ruser $userpswd $passwd $enapasswd $prompt $cyphertype]} {
continue
}
- if { $enable } {
+ if { $enable } {
if {[do_enable $enauser $enapasswd]} {
if { $do_command || $do_script } {
close; wait
@@ -471,7 +508,7 @@ foreach router [lrange $argv $i end] {
source $sfile
close
} else {
- label $router
+ label $router
log_user 1
interact
}
diff --git a/bin/control_rancid b/bin/control_rancid
index 89ec0df..0728e7e 100755
--- a/bin/control_rancid
+++ b/bin/control_rancid
@@ -52,26 +52,58 @@ fi
# generate the list of routers we should try to fetch
cd $DIR
-rm -f $DIR/allrouters.new
+grep -v '^#' router.db > routers.db
+cut -d: -f1,2 routers.db | sort -u > routers.all.new
+diff routers.all routers.all.new > /dev/null 2>&1; RALL=$?
perl -F: -ane '{($F[0] =~ tr@A-Z@a-z@,print "$F[0]:$F[1]\n")
- if ($F[2] =~ /^up$/i);}' $DIR/router.db | sort -u > $DIR/allrouters.new
+ if ($F[2] =~ /^down$/i);}' routers.db | sort -u > routers.down.new
+diff routers.down routers.down.new > /dev/null 2>&1; RDOWN=$?
+perl -F: -ane '{($F[0] =~ tr@A-Z@a-z@,print "$F[0]:$F[1]\n")
+ if ($F[2] =~ /^up$/i);}' routers.db | sort -u > routers.up.new
+diff routers.up routers.up.new > /dev/null 2>&1; RUP=$?
-if diff $DIR/allrouters $DIR/allrouters.new > $DIR/allrouters.diffs
+if [ $RALL -ne 0 -o $RDOWN -ne 0 -o $RUP -ne 0 ]
then
- rm -f $DIR/allrouters.new
-else
(
- echo New routers:
- comm -13 $DIR/allrouters $DIR/allrouters.new | sed -e 's/^/ /' -e 's/:.*$//'
- echo
- echo Deleted routers:
- comm -23 $DIR/allrouters $DIR/allrouters.new | sed -e 's/^/ /' -e 's/:.*$//'
- ) | Mail -s "changes in $GROUP routers" rancid-admin-$GROUP
+ if [ $RUP -ne 0 ] ; then
+ if [ $RUP -eq 1 ] ; then
+ echo Routers changed to up:
+ comm -13 routers.up routers.up.new | sed -e 's/^/ /' -e 's/:.*$//'
+ echo
+ elif [ -s routers.up.new ] ; then
+ echo Routers changed to up:
+ sed -e 's/^/ /' -e 's/:.*$//' routers.up.new
+ echo
+ fi
+ fi
+ if [ $RDOWN -ne 0 ] ; then
+ if [ $RDOWN -eq 1 ] ; then
+ echo Routers changed to down:
+ comm -13 routers.down routers.down.new | sed -e 's/^/ /' -e 's/:.*$//'
+ echo
+ elif [ -s routers.down.new ] ; then
+ echo Routers changed to down:
+ sed -e 's/^/ /' -e 's/:.*$//' routers.down.new
+ echo
+ fi
+ fi
+ WC=`wc -l routers.all | sed -e 's/^ *\([^ ]*\) .*$/\1/'`
+ WCNEW=`wc -l routers.all.new | sed -e 's/^ *\([^ ]*\) .*$/\1/'`
+ if [ $RALL -eq 1 -a $WC -gt $WCNEW ] ; then
+ echo Deleted routers:
+ comm -23 routers.all routers.all.new | sed -e 's/^/ /' -e 's/:.*$//'
+ fi
+ ) > routers.mail
+
+ if [ -s routers.mail ] ; then
+ Mail -s "changes in $GROUP routers" rancid-admin-$GROUP < routers.mail
+ fi
+ rm -f routers.mail
cd $DIR/configs
# Add new routers to the CVS structure.
- for router in `comm -13 $DIR/allrouters $DIR/allrouters.new`
+ for router in `comm -13 $DIR/routers.up $DIR/routers.up.new`
do
OFS=$IFS
IFS=:
@@ -87,14 +119,31 @@ else
echo
cd $DIR
- mv $DIR/allrouters.new $DIR/allrouters
fi
-rm -f $DIR/allrouters.diffs $DIR/allrouters.new
+mv routers.all.new routers.all
+mv routers.down.new routers.down
+mv routers.up.new routers.up
+rm -f routers.db
+
+# cvs delete configs for routers not listed in routers.up.
+cd $DIR/configs
+for router in `find . \( -name \*.new -prune -o -name CVS -prune \) -o -type f -print | sed -e 's/^.\///'` ; do
+ grep "^$router:" ../router.db > /dev/null 2>&1
+ if [ $? -eq 1 ]; then
+ rm -f $router
+ cvs delete $router
+ cvs commit -m 'deleted router' $router
+ echo "Deleted $router"
+ fi
+done
+cd $DIR
# no routers, empty list or all 'down'
-if [ ! -s $DIR/allrouters ]
+if [ ! -s routers.up ]
then
- exit;
+ # commit router.db
+ cvs commit -m updates router.db > /dev/null
+ exit;
fi
# Now we can actually try to get the configs
@@ -103,22 +152,19 @@ cd $DIR/configs
# The number of processes running at any given time can be
# tailored to the specific installation.
echo "Trying to get all of the configs."
-par -q -n $PAR_COUNT -c "rancid-fe \{}" $DIR/allrouters
+par -q -n $PAR_COUNT -c "rancid-fe \{}" $DIR/routers.up
# This section will generate a list of missed routers
# and try to grab them again. It will run through
# $pass times.
pass=4
round=1
-if [ -f $DIR/allrouters.missed ]; then
- rm -f $DIR/allrouters.missed
+if [ -f $DIR/routers.up.missed ]; then
+ rm -f $DIR/routers.up.missed
fi
while [ $round -le $pass ]
do
- echo "====================================="
- echo "Getting missed routers: round $round."
-
- for router in `cat $DIR/allrouters`
+ for router in `cat $DIR/routers.up`
do
OFS=$IFS
IFS=':'
@@ -126,15 +172,17 @@ do
IFS=$OFS
router=$1; mfg=$2
- if [ ! -f $DIR/configs/$router.new ]
+ if [ ! -f $router.new ]
then
- echo "$router:$mfg" >> $DIR/allrouters.missed
+ echo "$router:$mfg" >> $DIR/routers.up.missed
fi
done
- if [ -f $DIR/allrouters.missed ]; then
- par -q -n $PAR_COUNT -c "rancid-fe \{}" $DIR/allrouters.missed
- rm -f $DIR/allrouters.missed
+ if [ -f $DIR/routers.up.missed ]; then
+ echo "====================================="
+ echo "Getting missed routers: round $round."
+ par -q -n $PAR_COUNT -c "rancid-fe \{}" $DIR/routers.up.missed
+ rm -f $DIR/routers.up.missed
round=`expr $round + 1`
else
echo "All routers sucessfully completed."
@@ -152,6 +200,7 @@ rename 's/.new$//' *.new
cd $DIR
#cvs diff -c3 >$TMP.diff
#cvs diff -C 3 >$TMP.diff
+# Change the output of a unified diff to make it a bit more readable.
cat > $TMP.sedf << EOF
/^RCS file: /d
#/^retrieving revision /d
@@ -180,7 +229,7 @@ fi
cd $DIR/configs
rm -f $DIR/routers.failed
perl -F: -ane '{$t = (stat($F[0]))[9]; print `ls -ld $F[0]`
- if (time() - $t >= 86400);}' $DIR/allrouters | sort -u > $DIR/routers.failed
+ if (time() - $t >= 86400);}' $DIR/routers.up | sort -u > $DIR/routers.failed
if [ -s $DIR/routers.failed ]
then
(
diff --git a/bin/create_cvs b/bin/create_cvs
index 675cda8..df7e56e 100755
--- a/bin/create_cvs
+++ b/bin/create_cvs
@@ -26,14 +26,21 @@ ENVFILE="`dirname $0`/env"
. $ENVFILE
+# Base dir
+if [ ! -d $BASEDIR ]; then
+ mkdir -p $BASEDIR
+fi
+
+cd $BASEDIR
+
# Top level CVS stuff
if [ ! -d $CVSROOT ]; then
cvs init
fi
# Log dir
-if [ ! -d $BASEDIR/logs ]; then
- mkdir $BASEDIR/logs
+if [ ! -d logs ]; then
+ mkdir logs
fi
# Which groups to do
@@ -57,25 +64,26 @@ do
cd $BASEDIR
cvs co $GROUP
fi
- if [ -d $DIR -a ! -d $DIR/configs ]; then
- cd $DIR
+ cd $DIR
+ if [ ! -d configs ]; then
mkdir configs
cvs add configs
cvs commit -m 'new' configs
- cd $BASEDIR
fi
# main files
- if [ ! -f $DIR/allrouters ]; then
- cd $DIR
- touch $DIR/allrouters
- cd $BASEDIR
+ if [ ! -f routers.all ]; then
+ touch routers.all
fi
- if [ ! -f $DIR/router.db ]; then
- cd $DIR
+ if [ ! -f routers.down ]; then
+ touch routers.down
+ fi
+ if [ ! -f routers.up ]; then
+ touch routers.up
+ fi
+ if [ ! -f router.db ]; then
touch router.db
cvs add router.db
cvs commit -m 'new' router.db
- cd $BASEDIR
fi
done
diff --git a/bin/cvs_helper b/bin/cvs_helper
deleted file mode 100644
index fe46435..0000000
--- a/bin/cvs_helper
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/sh
-##
-##
-## Copyright (C) 1996 by Henry Kilmer.
-## All rights reserved.
-##
-## This software may be freely copied, modified and redistributed without
-## fee for non-commerical purposes provided that this copyright notice is
-## preserved intact on all copies and modified copies.
-##
-## There is no warranty or other guarantee of fitness of this software.
-## It is provided solely "as is". The author(s) disclaim(s) all
-## responsibility and liability with respect to this software's usage
-## or its effect upon hardware, computer systems, other software, or
-## anything else.
-##
-##
-#
-# cvs_helper
-#
-
-# Remove old config
-rm <file>
-cvs remove <file>
-
-# Look at an old revision...put file in <dir>
-cvs export -d <dir> -rX.YZ
-
diff --git a/bin/do-diffs b/bin/do-diffs
index 3b5eced..88cc445 100755
--- a/bin/do-diffs
+++ b/bin/do-diffs
@@ -37,7 +37,7 @@ do
/bin/rm -f $LOCKFILE
fi
- echo ending: `date`
echo
- ) >$BASEDIR/logs/$GROUP.`date +%y%m%d.%H%M%S` 2>&1
+ echo ending: `date`
+ ) >$BASEDIR/logs/$GROUP.`date +%Y%m%d.%H%M%S` 2>&1
done
diff --git a/bin/env b/bin/env
index 14ae8a1..236ceca 100644
--- a/bin/env
+++ b/bin/env
@@ -9,13 +9,25 @@ TERM=network;export TERM
# a log directory for the logs from rancid and a directory for each group
# of routers. In addition to these directories, there will be the CVS
# repositories as well.
+# use a full path (no sym-links) for BASEDIR. some versions of CVS seemingly
+# don't take kindly to sym-links.
#
BASEDIR=$HOME/rancid; export BASEDIR
PATH=$BASEDIR/bin:/usr/local/bin:/usr/ucb:/usr/bin:/bin:/usr/lib:/usr/sbin;export PATH
CVSROOT=$BASEDIR/CVS; export CVSROOT
+#
+# if NOPIPE is set, temp files will be used instead of a cmd pipe during
+# collection from the router(s).
+#NOPIPE=YES; export NOPIPE
+#
LIST_OF_GROUPS="sl joebobisp"
-# For each group, define a list of people to receive the diffs
+#
+# For each group, define a list of people to receive the diffs.
# in a .mailrc file in the following format:
# alias rancid-$GROUP hank@rem.com pwhiting@sprint.net
+# or sendmail's /etc/aliases.
+# rancid-group: joe,moe@foo
+# rancid-group-admin: hostmaster
+# be sure to read ../README regarding aliases.
#
umask 007
diff --git a/bin/flogin b/bin/flogin
new file mode 100755
index 0000000..b168762
--- /dev/null
+++ b/bin/flogin
@@ -0,0 +1,530 @@
+#!/usr/local/bin/expect --
+##
+##
+## Copyright (C) 1997 by Henry Kilmer, Erik Sherk and Pete Whiting.
+## All rights reserved.
+##
+## This software may be freely copied, modified and redistributed without
+## fee for non-commerical purposes provided that this copyright notice is
+## preserved intact on all copies and modified copies.
+##
+## There is no warranty or other guarantee of fitness of this software.
+## It is provided solely "as is". The author(s) disclaim(s) all
+## responsibility and liability with respect to this software's usage
+## or its effect upon hardware, computer systems, other software, or
+## anything else.
+##
+##
+#
+# flogin - foundry login
+#
+# Most options are intuitive for logging into a foundry switch.
+# this should be the clogin, but foundry can't seem to dislodge
+# their heads and make the UI consistent. i think the UI
+# development has been outsourced to Fisher Price.
+# The default is to enable (thus -noenable). Some folks have
+# setup tacacs to have a user login at priv-lvl = 15 (enabled)
+# so the -autoenable flag was added for this case (don't go through
+# the process of enabling and the prompt will be the "#" prompt.
+# The default username password is the same as the vty password.
+#
+
+# Usage line
+set usage "Usage: $argv0 \[-u user\] \[-p user-password\] \[-v vty-password\] \
+\[-w enable-username\] \[-e enable-password\] \[-noenable\] \
+\[-f cloginrc-file\] \[-y ssh_cypher_type\] \[-c command\] \[-s script-file\] \
+\[-autoenable\] \[-t timeout\] router \[router...\]\n"
+
+# env(CLOGIN) may contain:
+# x == do not set xterm banner or name
+
+# Password file
+set password_file $env(HOME)/.cloginrc
+# Default is to login to the router
+set do_command 0
+set do_script 0
+# The default is to automatically enable
+set enable 1
+# The default is that you login non-enabled (tacacs can have you login already enabled)
+set autoenable 0
+# The default is to look in the password file to find the passwords. This
+# tracks if we receive them on the command line.
+set do_passwd 1
+set do_enapasswd 1
+
+# Find the user in the ENV, or use the unix userid.
+if {[ info exists env(CISCO_USER) ] } {
+ set default_user $env(CISCO_USER)
+} else {
+ # This uses "id" which I think is portable. At least it has existed
+ # (without options) on all machines/OSes I've been on recently -
+ # unlike whoami or id -nu.
+ regexp {\(([^)]*)} [exec id] junk default_user
+}
+
+# Sometimes routers take awhile to answer (the default is 10 sec)
+set timeout 45
+
+# Process the command line
+for {set i 0} {$i < $argc} {incr i} {
+ set arg [lindex $argv $i]
+
+ switch -glob -- $arg {
+ # Username
+ -u* -
+ -U* {
+ if {! [ regexp .\[uU\](.+) $arg ignore user]} {
+ incr i
+ set username [ lindex $argv $i ]
+ }
+ # VTY Password
+ } -p* -
+ -P* {
+ if {! [ regexp .\[pP\](.+) $arg ignore userpasswd]} {
+ incr i
+ set userpasswd [ lindex $argv $i ]
+ }
+ set do_passwd 0
+ # VTY Password
+ } -v* -
+ -v* {
+ if {! [ regexp .\[vV\](.+) $arg ignore passwd]} {
+ incr i
+ set passwd [ lindex $argv $i ]
+ }
+ set do_passwd 0
+ # Enable Username
+ } -w* -
+ -W* {
+ if {! [ regexp .\[wW\](.+) $arg ignore enauser]} {
+ incr i
+ set enausername [ lindex $argv $i ]
+ }
+ # Enable Password
+ } -e* -
+ -E* {
+ if {! [ regexp .\[eE\](.+) $arg ignore enapasswd]} {
+ incr i
+ set enapasswd [ lindex $argv $i ]
+ }
+ set do_enapasswd 0
+ # Command to run.
+ } -c* -
+ -C* {
+ if {! [ regexp .\[cC\](.+) $arg ignore command]} {
+ incr i
+ set command [ lindex $argv $i ]
+ }
+ set do_command 1
+ # Expect script to run.
+ } -s* -
+ -S* {
+ if {! [ regexp .\[sS\](.+) $arg ignore sfile]} {
+ incr i
+ set sfile [ lindex $argv $i ]
+ }
+ if { ! [ file readable $sfile ] } {
+ send_user "Error: Can't read $sfile\n"
+ exit 1
+ }
+ set do_script 1
+ # cypher type
+ } -y* -
+ -Y* {
+ if {! [ regexp .\[eE\](.+) $arg ignore cypher]} {
+ incr i
+ set cypher [ lindex $argv $i ]
+ }
+ # alternate cloginrc file
+ } -f* -
+ -F* {
+ if {! [ regexp .\[fF\](.+) $arg ignore password_file]} {
+ incr i
+ set password_file [ lindex $argv $i ]
+ }
+ } -t* -
+ -T* {
+ incr i
+ set timeout [ lindex $argv $i ]
+ } -x* -
+ -X {
+ if {! [ regexp .\[xX\](.+) $arg ignore cmd_file]} {
+ incr i
+ set cmd_file [ lindex $argv $i ]
+ }
+ set cmd_fd [open $cmd_file r]
+ set cmd_text [read $cmd_fd]
+ close $cmd_fd
+ set command [join [split $cmd_text \n] \;]
+ set do_command 1
+ # Do we enable?
+ } -noenable {
+ set enable 0
+ # Does tacacs automatically enable us?
+ } -autoenable {
+ set autoenable 1
+ set enable 0
+ } -* {
+ send_user "Error: Unknown argument! $arg\n"
+ send_user $usage
+ exit 1
+ } default {
+ break
+ }
+ }
+}
+# Process routers...no routers listed is an error.
+if { $i == $argc } {
+ send_user "Error: $usage"
+}
+
+# Only be quiet if we are running a script (it can log its output
+# on its own)
+if { $do_script } {
+ log_user 0
+} else {
+ log_user 1
+}
+
+#
+# Done configuration/variable setting. Now run with it...
+#
+
+# Sets Xterm title if interactive...if its an xterm and the user cares
+proc label { host } {
+ global env
+ # if CLOGIN has an 'x' in it, don't set the xterm name/banner
+ if [info exists env(CLOGIN)] {
+ if {[string first "x" $env(CLOGIN)] != -1} { return }
+ }
+ # take host from ENV(TERM)
+ if [info exists env(TERM)] {
+ if [regexp \^(xterm|vs) $env(TERM) ignore ] {
+ send_user "\033]1;[lindex [split $host "."] 0]\a"
+ send_user "\033]2;$host\a"
+ }
+ }
+}
+
+# This is a helper function to make the password file easier to
+# maintain. Using this the password file has the form:
+# add password sl* pete cow
+# add password at* steve
+# add password * hanky-pie
+proc add {var args} { global $var ;lappend $var $args}
+proc find {var router} {
+ source_password_file
+ upvar $var list
+ if { [info exists list] } {
+ foreach line $list {
+ if { [string match [lindex $line 0] $router ] } {
+ return [lrange $line 1 end]
+ }
+ }
+ }
+ return {}
+}
+
+# Loads the password file. Note that as this file is tcl, and that
+# it is sourced, the user better know what to put in there, as it
+# could install more than just password info... I will assume however,
+# that a "bad guy" could just as easy put such code in the clogin
+# script, so I will leave .cloginrc as just an extention of that script
+proc source_password_file { } {
+ global env password_file read_password_file
+ if { [info exists read_password_file] } { return }
+ if { [info exists password_file] == 0 } {
+ set password_file $env(HOME)/.cloginrc
+ }
+ set read_password_file 1
+ file stat $password_file fileinfo
+ if { [expr ($fileinfo(mode) & 007)] != 0000 } {
+ send_user "Error: $password_file must not be world readable/writable\n"
+ exit 1
+ }
+ source $password_file
+}
+
+# Log into the router.
+proc login { router user userpswd passwd enapasswd prompt cyphertype } {
+ global spawn_id in_proc do_command do_script
+ set in_proc 1
+ set tryssh 1
+
+ # Telnet to the router & try to login.
+ if [ catch {spawn telnet $router} reason ] {
+ send_user "Error: failed to telnet: $reason\n"
+ exit 1
+ }
+ sleep 0.3
+
+ # This helps cleanup each expect clause.
+ expect_after {
+ timeout {
+ send_user "\nError: TIMEOUT reached\n"
+ close; wait
+ if { $in_proc} {
+ return 1
+ } else {
+ continue
+ }
+ } eof {
+ send_user "\nError: EOF received\n"
+ close; wait
+ if { $in_proc} {
+ return 1
+ } else {
+ continue
+ }
+ }
+ }
+
+ # Here we get a little tricky. There are several possibilities:
+ # the router can ask for a username and passwd and then
+ # talk to the TACACS server to authenticate you, or if the
+ # TACACS server is not working, then it will use the enable
+ # passwd. Or, the router might not have TACACS turned on,
+ # then it will just send the passwd.
+ # if telnet fails with connection refused, try ssh
+ expect {
+ "Connection refused" {
+ close; wait
+ if { $tryssh } {
+ if [ catch {spawn ssh -c $cyphertype -x -l $user $router} reason ] {
+ send_user "Error: failed to ssh: $reason\n"
+ exit 1
+ }
+ set tryssh 0
+ sleep 0.3
+ exp_continue
+ } else {
+ expect eof
+ send_user "Error: Connection Refused\n"; wait; return 1
+ }
+ } eof { send_user "Error: Couldn't login\n"; wait; return 1
+ } "Unknown host\r\n" {
+ expect eof
+ send_user "Error: Unknown host\n"; wait; return 1
+ } "Host is unreachable" {
+ expect eof
+ send_user "Error: Host Unreachable!\n"; wait; return 1
+ } "No address associated with name" {
+ expect eof
+ send_user "Error: Unknown host\n"; wait; return 1
+ }
+ -re "Host key not found .* \(yes\/no\)\?" {
+ send "yes\r"
+ send_user "Host $router added to the list of known hosts.\n"
+ exp_continue }
+ -re "HOST IDENTIFICATION HAS CHANGED.* \(yes\/no\)\?" {
+ send "no\r"
+ send_user "Error: The host key for $router has changed. update the known_hosts file accordingly.\n"
+ return 1 }
+ -re "(Username:|login:|Name :)" {
+ sleep 1;
+ send "$user\r"
+ expect {
+ eof { send_user "Error: Couldn't login\n"; wait; return 1 }
+ -re "\[Pp]assword:" { send "$userpswd\r" }
+ "$prompt" { set in_proc 0; return 0 }
+ }
+ exp_continue
+ }
+ "\[Pp]assword:" { send "$passwd\r"
+ expect {
+ eof { send_user "Error: Couldn't login\n"; wait; return 1 }
+ "Password:" { send "$enapasswd\r" }
+ "$prompt" { set in_proc 0; return 0 }
+ }
+ exp_continue
+ }
+ "$prompt" { }
+ denied { send_user "Error: Check your passwd for $router\n"
+ if { $do_command || $do_script } {
+ send "quit"
+ wait
+ return 1
+ } else {
+ return 1
+ }
+ }
+ "% Bad passwords" {send_user "Error: Check your passwd for $router\n"; return 1 }
+ }
+ set in_proc 0
+ return 0
+}
+
+# Enable
+proc do_enable { enauser enapasswd } {
+ global prompt in_proc
+ set in_proc 1
+
+ sleep 1; # dont go too fast for it now...
+ send "enable\r"
+ expect {
+ -re "(Username|User Name):" { send "$enauser\r"; exp_continue}
+ "Password:" { send "$enapasswd\r"; exp_continue}
+ "#" { }
+ denied { send_user "Error: Check your Enable passwd\n"; return 1}
+ "% Bad passwords" { send_user "Error: Check your Enable passwd\n"
+ return 1
+ }
+ }
+ # Set the prompt variable so script files don't need to know what it is.
+ set prompt "#"
+ set in_proc 0
+ return 0
+}
+
+# Run commands given on the command line.
+proc run_commands { prompt command } {
+ global in_proc
+ set in_proc 1
+
+ send "skip-page-display\r"
+ expect $prompt {}
+
+ # Is this a multi-command?
+ if [ string match "*\;*" "$command" ] {
+ set commands [split $command \;]
+ set num_commands [llength $commands]
+
+ for {set i 0} {$i < $num_commands} { incr i} {
+ send "[subst [lindex $commands $i]]\r"
+ expect {
+ -re "^\[^\n\r]*$prompt." { exp_continue }
+ -re "^\[^\n\r *]*$prompt" {}
+ -re "\[\n\r]" { exp_continue }
+ }
+ }
+ } else {
+ send "[subst $command]\r"
+ expect {
+ -re "^\[^\n\r]*$prompt." { exp_continue }
+ -re "^\[^\n\r *]*$prompt" {}
+ -re "\[\n\r]" { exp_continue }
+ }
+ }
+ send "exit\r"
+ expect {
+ "\n" { exp_continue }
+ -re "^\[^ ]+>" {
+ send "exit\r"
+ exp_continue }
+ timeout { return 0 }
+ eof { return 0 }
+ }
+ set in_proc 0
+}
+
+#
+# For each router... (this is main loop)
+#
+set in_proc 0
+foreach router [lrange $argv $i end] {
+ set router [string tolower $router]
+ send_user "$router\n"
+
+ # Figure out prompt.
+ # Since autoenable is off by default, if we have it defined, it
+ # was done on the command line. If it is not specifically set on the
+ # command line, check the password file.
+ if $autoenable {
+ set prompt "#"
+ } else {
+ set ae [find autoenable $router]
+ if { "$ae" == "1" } {
+ set autoenable 1
+ set enable 0
+ set prompt "#"
+ } else {
+ set autoenable 0
+ set prompt ">"
+ }
+ }
+
+ # Figure out passwords
+ if { $do_passwd || $do_enapasswd } {
+ set pswd [find password $router]
+ if { [llength $pswd] == 0 } {
+ send_user "Error - no password for $router in $password_file.\n"
+ continue
+ }
+ if { $do_enapasswd && $autoenable == 0 && [llength $pswd] < 2 } {
+ send_user "Error - no enable password for $router in $password_file.\n"
+ continue
+ }
+ set passwd [lindex $pswd 0]
+ set enapasswd [lindex $pswd 1]
+ }
+
+ # Figure out username
+ if {[info exists username]} {
+ # command line username
+ set ruser $username
+ } else {
+ set ruser [find user $router]
+ if { "$ruser" == "" } { set ruser $default_user }
+ }
+
+ # Figure out username's password (if different from the vty password)
+ if {[info exists userpasswd]} {
+ # command line username
+ set userpswd $userpasswd
+ } else {
+ set userpswd [find userpassword $router]
+ if { "$userpswd" == "" } { set userpswd $passwd }
+ }
+
+ # Figure out enable username
+ if {[info exists enausername]} {
+ # command line enausername
+ set enauser $enausername
+ } else {
+ set enauser [find enauser $router]
+ if { "$enauser" == "" } { set enauser $ruser }
+ }
+
+ # Figure out cypher tpye
+ if {[info exists cypher]} {
+ # command line cypher type
+ set cyphertype $cypher
+ } else {
+ set cyphertype [find cyphertype $router]
+ if { "$cyphertype" == "" } { set cyphertype "3des" }
+ }
+
+ # Login to the router
+ if {[login $router $ruser $userpswd $passwd $enapasswd $prompt $cyphertype]} {
+ continue
+ }
+ if { $enable } {
+ if {[do_enable $enauser $enapasswd]} {
+ if { $do_command || $do_script } {
+ close; wait
+ continue
+ }
+ }
+ }
+
+ if { $do_command } {
+ if {[run_commands $prompt $command]} {
+ continue
+ }
+ } elseif { $do_script } {
+ # fucking foundry
+ send "skip-page-display\r"
+ expect $prompt {}
+ source $sfile
+ close
+ } else {
+ label $router
+ log_user 1
+ interact
+ }
+
+ # End of for each router
+ wait
+ sleep 0.3
+}
+exit 0
diff --git a/bin/francid b/bin/francid
new file mode 100755
index 0000000..3050aee
--- /dev/null
+++ b/bin/francid
@@ -0,0 +1,383 @@
+#!/usr/local/bin/perl
+##
+## Amazingly hacked version of Hank's rancid - this one tries to
+## deal with foundrys.
+##
+## Copyright (C) 1997 by Henry Kilmer.
+## All rights reserved.
+##
+## This software may be freely copied, modified and redistributed without
+## fee for non-commerical purposes provided that this copyright notice is
+## preserved intact on all copies and modified copies.
+##
+## There is no warranty or other guarantee of fitness of this software.
+## It is provided solely "as is". The author(s) disclaim(s) all
+## responsibility and liability with respect to this software's usage
+## or its effect upon hardware, computer systems, other software, or
+## anything else.
+##
+##
+#
+# RANCID - Really Awesome New Cisco confIg Differ
+#
+# usage: rancid [-d] [-l] [-f filename | $host]
+#
+use Getopt::Std;
+getopts('dflm');
+$log = $opt_l;
+$debug = $opt_d;
+$file = $opt_f;
+$host = $ARGV[0];
+$clean_run = 0;
+$found_end = 0;
+$timeo = 90; # clogin timeout in seconds
+
+# This routine is used to print out the router configuration
+sub ProcessHistory {
+ my($new_hist_tag,$new_command,$command_string,@string)=(@_);
+ if((($new_hist_tag ne $hist_tag) || ($new_command ne $command))
+ && defined %history) {
+ print eval "$command \%history";
+ undef %history;
+ }
+ if (($new_hist_tag) && ($new_command) && ($command_string)) {
+ if ($history{$command_string}) {
+ $history{$command_string} = "$history{$command_string}@string";
+ } else {
+ $history{$command_string} = "@string";
+ }
+ } elsif (($new_hist_tag) && ($new_command)) {
+ $history{++$#history} = "@string";
+ } else {
+ print "@string";
+ }
+ $hist_tag = $new_hist_tag;
+ $command = $new_command;
+ 1;
+}
+
+sub numerically { $a <=> $b; }
+
+# This is a sort routing that will sort numerically on the
+# keys of a hash as if it were a normal array.
+sub keynsort {
+ local(%lines)=@_;
+ local($i) = 0;
+ local(@sorted_lines);
+ foreach $key (sort numerically keys(%lines)) {
+ $sorted_lines[$i] = $lines{$key};
+ $i++;
+ }
+ @sorted_lines;
+}
+
+# This is a sort routing that will sort on the
+# keys of a hash as if it were a normal array.
+sub keysort {
+ local(%lines)=@_;
+ local($i) = 0;
+ local(@sorted_lines);
+ foreach $key (sort keys(%lines)) {
+ $sorted_lines[$i] = $lines{$key};
+ $i++;
+ }
+ @sorted_lines;
+}
+
+# This is a sort routing that will sort on the
+# values of a hash as if it were a normal array.
+sub valsort{
+ local(%lines)=@_;
+ local($i) = 0;
+ local(@sorted_lines);
+ foreach $key (sort values %lines) {
+ $sorted_lines[$i] = $key;
+ $i++;
+ }
+ @sorted_lines;
+}
+
+# This is a numerical sort routing (ascending).
+sub numsort {
+ local(%lines)=@_;
+ local($i) = 0;
+ local(@sorted_lines);
+ foreach $num (sort {$a <=> $b} keys %lines) {
+ $sorted_lines[$i] = $lines{$num};
+ $i++;
+ }
+ @sorted_lines;
+}
+
+# This is a sort routine that will sort on the
+# ip address when the ip address is anywhere in
+# the strings.
+sub ipsort {
+ local(%lines)=@_;
+ local($i) = 0;
+ local(@sorted_lines);
+ foreach $addr (sort sortbyipaddr keys %lines) {
+ $sorted_lines[$i] = $lines{$addr};
+ $i++;
+ }
+ @sorted_lines;
+}
+
+# These two routines will sort based upon IP addresses
+sub ipaddrval {
+ my(@a) = ($_[0] =~ m#^(\d+)\.(\d+)\.(\d+)\.(\d+)$#);
+ $a[3]+256*($a[2]+256*($a[1]+256*$a[0]));
+}
+sub sortbyipaddr {
+ &ipaddrval($a) <=> &ipaddrval($b);
+}
+
+# This routine parses "show version"
+sub ShowVersion {
+ my($slot);
+
+ print STDERR " In ShowVersion: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ next if /^\s*$/;
+ last if(/^$prompt/);
+
+ next if (/^The system /);
+
+ s/^\s*(HW|SW)/$1/;
+ s/^\s*(Compiled on)/SW: $1/;
+ #s/^(HW.*)/$1\n/;
+ if (/^SL (\d)/) {
+ $slot = "Slot $1";
+ s/^SL \d+/$slot/;
+ }
+ if (/MHz .* processor/) {
+ $slot = "MGMT";
+ }
+ s/^(\s*\d+ )/$slot:$1/;
+ s/^===*//;
+
+ ProcessHistory("VERSION","","","!$_");
+ }
+ ProcessHistory("VERSION","","","!\n");
+ return(0);
+}
+
+# This routine parses "show chassis"
+sub ShowChassis {
+ print STDERR " In ShowChassis: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ next if (/ from /);
+ ProcessHistory("CHASSIS","","","! $_");
+ }
+ ProcessHistory("CHASSIS","","","!\n");
+ return(0);
+}
+
+# This routine parses "show flash"
+sub ShowFlash {
+ print STDERR " In ShowFlash: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if(/^$prompt/);
+ next if /^\s*$/;
+ ProcessHistory("FLASH","","","!Flash: $_");
+ }
+ ProcessHistory("","","","!\n");
+ return;
+}
+
+# This routine parses "show module"
+sub ShowModule {
+ print STDERR " In ShowModule: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if(/^$prompt/);
+ next if /^\s*$/;
+ next if /:\s*$/;
+ ProcessHistory("MODULE","","","!Module: $_");
+ }
+ ProcessHistory("","","","!\n");
+ return(0);
+}
+
+# This routine processes a "write term"
+sub WriteTerm {
+ print STDERR " In WriteTerm: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if(/^$prompt/);
+
+ /Current configuration:/i && next;
+ /^ver \d+\.\d+/ && next;
+ /^module \d+ / && next;
+
+ /^ntp clock-period / && next; # kill ntp clock-period
+ /^ length / && next; # kill length on serial lines
+ /^ width / && next; # kill width on serial lines
+ # filter out any RCS/CVS tags to avoid confusing local CVS storage
+ s/\$(Revision|Id):/ $1:/;
+ # order access-lists
+ /^access-list\s+(\d+)\s+(perm|deny)\s+(\d\S+)(\/\d+)\s*$/ &&
+ ProcessHistory("PACL $1 $2","ipsort","$3","$_")
+ && next;
+ /^access-list\s+(\d\d?)\s+(\S+)\s+(\S+)/ &&
+ ProcessHistory("ACL $1 $2","ipsort","$3","$_") && next;
+ # order extended access-lists
+ /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+host\s+(\S+)/ &&
+ ProcessHistory("EACL $1 $2","ipsort","$3","$_") && next;
+ /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+(\d\S+)/ &&
+ ProcessHistory("EACL $1 $2","ipsort","$3","$_") && next;
+ /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+any/ &&
+ ProcessHistory("EACL $1 $2","ipsort","0.0.0.0","$_") && next;
+ # order arp lists
+ /^arp\s+(\d+\.\d+\.\d+\.\d+)\s+/ &&
+ ProcessHistory("ARP","ipsort","$1","$_") && next;
+ # order logging statements
+ /^logging (\d+\.\d+\.\d+\.\d+)/ &&
+ ProcessHistory("LOGGING","ipsort","$1","$_") && next;
+ # order name-server statements
+ /^ip name-server (\d+\.\d+\.\d+\.\d+)/ &&
+ ProcessHistory("NAMESERVER","ipsort","$1","$_") && next;
+ # order snmp-server host statements
+ /^snmp-server host (\d+\.\d+\.\d+\.\d+)/ &&
+ ProcessHistory("SNMPSERVERHOST","ipsort","$1","$_") && next;
+ /^snmp-server community / &&
+ ProcessHistory("SNMPSERVERCOMM","keysort","$_","$_") && next;
+
+ # order tacacs server statements
+ /^(tacacs-server key )/ &&
+ ProcessHistory("","","","! $1<removed>\n") && next;
+ /^tacacs-server host (\d+\.\d+\.\d+\.\d+)/ &&
+ ProcessHistory("TAC","ipsort","$1","$_") && next;
+
+ # delete ntp auth password
+ /^(ntp authentication-key \d+ md5) / &&
+ ProcessHistory("","","","!$1 <removed>\n") && next;
+ # order ntp peers/servers
+ if (/^ntp (server|peer) (\d+)\.(\d+)\.(\d+)\.(\d+)/) {
+ $sortkey = sprintf("$1 %03d%03d%03d%03d",$2,$3,$4,$5);
+ ProcessHistory("NTP","keysort",$sortkey,"$_");
+ next;
+ }
+ # order ip host line statements
+ /^ip host line(\d+)/ &&
+ ProcessHistory("IPHOST","numsort","$1","$_") && next;
+ # order ip nat source static statements
+ /^ip nat (\S+) source static (\S+)/ &&
+ ProcessHistory("IP NAT $1","ipsort","$2","$_") && next;
+
+ ProcessHistory("","","","$_");
+ # end of config
+ if (/^end$/) {
+ $found_end = 1;
+ return(1);
+ }
+ }
+ return(0);
+}
+
+# dummy function
+sub DoNothing {print STDOUT;}
+
+# Main
+%commands=(
+ 'show version' => "ShowVersion",
+ 'show chassis' => "ShowChassis",
+ 'show module' => "ShowModule",
+ 'show flash' => "ShowFlash",
+ 'write term' => "WriteTerm"
+);
+# keys() doesnt return things in the order entered and the order of the
+# cmds is important. pita
+@commands=(
+ "show version",
+ "show chassis",
+ "show module",
+ "show flash",
+ "write term"
+);
+$cisco_cmds=join(";",@commands);
+$cmds_regexp=join("|",@commands);
+
+open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n";
+select(OUTPUT);
+# make OUTPUT unbuffered if debugging
+if ($debug) { $| = 1; }
+
+if ($file) {
+ print STDERR "opening file $host\n" if ($debug);
+ print STDOUT "opening file $host\n" if ($log);
+ open(INPUT,"<$host") || die "open failed for $host: $!\n";
+} else {
+ print STDERR "executing flogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($debug);
+ print STDOUT "executing flogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($log);
+ if (defined($ENV{NOPIPE})) {
+ system "flogin -t $timeo -c \"$cisco_cmds\" $host </dev/null > $host.raw 2>&1" || die "flogin failed for $host: $!\n";
+ open(INPUT, "< $host.raw") || die "flogin failed for $host: $!\n";
+ } else {
+ open(INPUT,"flogin -t $timeo -c \"$cisco_cmds\" $host </dev/null |") || die "flogin failed for $host: $!\n";
+ }
+}
+
+while(<INPUT>) {
+ tr/\015//d;
+ if (/\#exit$/) {
+ $clean_run=1;
+ last;
+ }
+ if (/Error:/) {
+ s/^.*Error:/Error:/;
+ print STDOUT ("$host flogin error: $_");
+ print STDERR ("$host flogin error: $_") if ($debug);
+ $clean_run=0;
+ last;
+ }
+ while (/#\s*($cmds_regexp)\s*$/) {
+ $cmd = $1;
+ if (!defined($prompt)) {$prompt = ($_ =~ /^([^#]+#)/)[0]; }
+ print STDERR ("HIT COMMAND:$_") if ($debug);
+ if (! defined($commands{$cmd})) {
+ print STDERR "found unexpected command - \"$cmd\"\n";
+ $clean_run = 0;
+ last;
+ }
+ $rval = &{$commands{$cmd}};
+ delete($commands{$cmd});
+ if ($rval == -1) {
+ $clean_run = 0;
+ last;
+ }
+ }
+}
+print STDOUT "Done $logincmd: $_\n" if ($log);
+# Flush History
+ProcessHistory("","","","");
+# Cleanup
+close(INPUT);
+close(OUTPUT);
+
+if (defined($ENV{NOPIPE})) {
+ unlink("$host.raw") if (! $debug);
+}
+
+# check for completeness
+if (scalar(%commands) || !$clean_run || !$found_end) {
+ if (scalar(%commands)) {
+ printf(STDOUT "missed cmd(s): %s\n", join(',', keys(%commands)));
+ printf(STDERR "missed cmd(s): %s\n", join(',', keys(%commands))) if ($debug);
+ }
+ if (!$clean_run || !$found_end) {
+ print STDOUT "End of run not found\n";
+ print STDERR "End of run not found\n" if ($debug);
+ system("/usr/bin/tail -1 $host.new");
+ }
+ unlink "$host.new" if (! $debug);
+}
diff --git a/bin/jrancid b/bin/jrancid
index b5b968e..c879737 100755
--- a/bin/jrancid
+++ b/bin/jrancid
@@ -138,86 +138,162 @@ sub sortbyipaddr {
# This routine parses "show chassis clocks"
sub ShowChassisClocks {
print STDERR " In ShowChassisClocks: $_" if ($debug);
- /error: the chassis subsystem is not running/ && return;
- ProcessHistory("","","","# $_") && return;
+
+ s/^[a-z]+@//;
+ ProcessHistory("","","","# $_");
+ while (<INPUT>) {
+ tr/\015//d;
+ last if(/^$prompt/);
+
+ /error: the chassis subsystem is not running/ && return;
+ ProcessHistory("","","","# $_");
+ }
return;
}
# This routine parses "show chassis environment"
sub ShowChassisEnvironment {
print STDERR " In ShowChassisEnvironment: $_" if ($debug);
- /error: the chassis subsystem is not running/ && return;
- /Couldn\'t initiate connection/ && return;
- / backplane temperature/ && return;
- /(\s*Power supply.*), temperature/ && ProcessHistory("","","","# $1\n") && return;
- /(\s*.+) +\d+ degrees C.*$/ && ProcessHistory("","","","# $1\n") && return;
- ProcessHistory("","","","# $_") && return;
+
+ s/^[a-z]+@//;
+ ProcessHistory("","","","# $_");
+ while (<INPUT>) {
+ tr/\015//d;
+ last if(/^$prompt/);
+
+ /error: the chassis subsystem is not running/ && return;
+ /Couldn\'t initiate connection/ && return;
+ / backplane temperature/ && return;
+ /(\s*Power supply.*), temperature/ &&
+ ProcessHistory("","","","# $1\n") && next;
+ /(\s*.+) +\d+ degrees C.*$/ &&
+ ProcessHistory("","","","# $1\n") && next;
+ ProcessHistory("","","","# $_");
+ }
return;
}
# This routine parses "show chassis firmware"
sub ShowChassisFirmware {
print STDERR " In ShowChassisFirmware: $_" if ($debug);
- /error: the chassis subsystem is not running/ && return;
- ProcessHistory("","","","# $_") && return;
+
+ s/^[a-z]+@//;
+ ProcessHistory("","","","# $_");
+ while (<INPUT>) {
+ tr/\015//d;
+ last if(/^$prompt/);
+
+ /error: the chassis subsystem is not running/ && return;
+ ProcessHistory("","","","# $_");
+ }
return;
}
# This routine parses "show chassis fpc detail"
sub ShowChassisFpcDetail {
print STDERR " In ShowChassisFpcDetail: $_" if ($debug);
- /error: the chassis subsystem is not running/ && return;
- / Temperature:/ && return;
- / Start time:/ && return;
- / Uptime:/ && return;
- ProcessHistory("","","","# $_") && return;
+
+ s/^[a-z]+@//;
+ ProcessHistory("","","","# $_");
+ while (<INPUT>) {
+ tr/\015//d;
+ last if(/^$prompt/);
+
+ /error: the chassis subsystem is not running/ && return;
+ / Temperature:/ && next;
+ / Start time:/ && next;
+ / Uptime:/ && next;
+ ProcessHistory("","","","# $_");
+ }
return;
}
# This routine parses "show chassis hardware"
sub ShowChassisHardware {
print STDERR " In ShowChassisHardware: $_" if ($debug);
- /error: the chassis subsystem is not running/ && return;
- ProcessHistory("","","","# $_") && return;
+
+ s/^[a-z]+@//;
+ ProcessHistory("","","","# $_");
+ while (<INPUT>) {
+ tr/\015//d;
+ last if(/^$prompt/);
+
+ /error: the chassis subsystem is not running/ && return;
+ ProcessHistory("","","","# $_");
+ }
return;
}
# This routine parses "show chassis routing-engine"
sub ShowChassisRoutingEngine {
print STDERR " In ShowChassisRoutingEngine: $_" if ($debug);
- /^Routing Engine status:/ && ProcessHistory("","","","# $_") && return;
- / DRAM:/ && ProcessHistory("","","","# $_") && return;
- /^\s*$/ && ProcessHistory("","","","# $_") && return;
+
+ s/^[a-z]+@//;
+ ProcessHistory("","","","# $_");
+ while (<INPUT>) {
+ tr/\015//d;
+ last if(/^$prompt/);
+
+ /^Routing Engine status:/ && ProcessHistory("","","","# $_") && next;
+ / DRAM:/ && ProcessHistory("","","","# $_") && next;
+ /^\s*$/ && ProcessHistory("","","","# $_") && next;
+ }
return;
}
# This routine parses "show chassis scb"
sub ShowChassisSCB {
print STDERR " In ShowChassisSCB: $_" if ($debug);
- /error: the chassis subsystem is not running/ && return;
- / Temperature:/ && return;
- / utilization:/ && return;
- /time:/ && return;
- / (IP|MLPS) routes:/ && return;
- / used:/ && return;
- ProcessHistory("","","","# $_") && return;
+
+ s/^[a-z]+@//;
+ ProcessHistory("","","","# $_");
+ while (<INPUT>) {
+ tr/\015//d;
+ last if(/^$prompt/);
+
+ /error: the chassis subsystem is not running/ && return;
+ / Temperature:/ && next;
+ / utilization:/ && next;
+ /time:/ && next;
+ / (IP|MLPS) routes:/ && next;
+ / used:/ && next;
+ ProcessHistory("","","","# $_");
+ }
return;
}
# This routine parses "show version"
sub ShowVersion {
print STDERR " In ShowVersionAndBlame: $_" if ($debug);
- /^Juniper Networks is:/ && ProcessHistory("","","","\n$_") && return;
- ProcessHistory("","","","# $_") && return;
+
+ s/^[a-z]+@//;
+ ProcessHistory("","","","# $_");
+ while (<INPUT>) {
+ tr/\015//d;
+ last if(/^$prompt/);
+
+ /^Juniper Networks is:/ && ProcessHistory("","","","\n$_") && return;
+ ProcessHistory("","","","# $_");
+ }
return;
}
# This routine parses "show configuration"
sub ShowConfiguration {
print STDERR " In ShowConfiguration: $_" if ($debug);
- /^database header mismatch: / && return(-1);
- s/(\s*authentication-key ).*$/#$1<removed>;/;
- ProcessHistory("","","","$_") && return;
+
+ s/^[a-z]+@//;
+ ProcessHistory("","","","# $_");
+ while (<INPUT>) {
+ tr/\015//d;
+ last if(/^$prompt/);
+ next if (/^\s*$/);
+
+ /^database header mismatch: / && return(-1);
+ s/(\s*authentication-key ).*$/#$1<removed>;/;
+ s/^(.*\ssecret \")\$9\$.*(\".*)$/#$1<removed>$2/;
+ ProcessHistory("","","","$_");
+ }
return;
}
@@ -228,39 +304,37 @@ sub ShowConfiguration {
# dummy function
sub DoNothing {print STDOUT;}
-# Main subroutine that splits up the work
-# All Subs return the name of the next function to use.
-# If the sub returns a new funtion name, that name will be used
-# else the main loop keeps using the current function
-sub FlailHelplessly {
- print STDERR "Flailing: $_" if ($debug);
- print STDOUT "Flailing: $_" if ($log);
- /(show chassis clocks)/ && delete($commands{$1}) && return("ShowChassisClocks");
- /(show chassis environment)/ && delete($commands{$1}) && return("ShowChassisEnvironment");
- /(show chassis firmware)/ && delete($commands{$1}) && return("ShowChassisFirmware");
- /(show chassis fpc detail)/ && delete($commands{$1}) && return("ShowChassisFpcDetail");
- /(show chassis hardware)/ && delete($commands{$1}) && return("ShowChassisHardware");
- /(show chassis routing-engine)/ && delete($commands{$1}) && return("ShowChassisRoutingEngine");
- /(show chassis scb)/ && delete($commands{$1}) && return("ShowChassisSCB");
- /(show version)/ && delete($commands{$1}) && return("ShowVersion");
- /(show configuration)/ && delete($commands{$1}) && return("ShowConfiguration");
- return "FlailHelplessly";
-}
-
# Main
-@commands=("show chassis clocks", "show chassis environment",
- "show chassis firmware", "show chassis fpc detail",
- "show chassis hardware", "show chassis routing-engine",
- "show chassis scb", "show version", "show configuration");
+%commands=(
+ "show chassis clocks" => "ShowChassisClocks",
+ "show chassis environment" => "ShowChassisEnvironment",
+ "show chassis firmware" => "ShowChassisFirmware",
+ "show chassis fpc detail" => "ShowChassisFpcDetail",
+ "show chassis hardware" => "ShowChassisHardware",
+ "show chassis routing-engine" => "ShowChassisRoutingEngine",
+ "show chassis scb" => "ShowChassisSCB",
+ "show version" => "ShowVersion",
+ "show configuration" => "ShowConfiguration"
+);
+@commands=(
+ "show chassis clocks",
+ "show chassis environment",
+ "show chassis firmware",
+ "show chassis fpc detail",
+ "show chassis hardware",
+ "show chassis routing-engine",
+ "show chassis scb",
+ "show version",
+ "show configuration"
+);
-foreach $c (@commands) { $commands{$c} = 1; }
$jnx_commands=join(";",@commands);
$cmds_regexp=join("|",@commands);
-$func = FlailHelplessly;
open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n";
+select(OUTPUT);
# make OUTPUT unbuffered
-select(OUTPUT); $| = 1;
+if ($debug) { $| = 1; }
if ($file) {
print STDERR "opening file $host\n" if ($debug);
@@ -269,17 +343,19 @@ if ($file) {
} else {
print(STDERR "executing echo jlogin -c\"$jnx_commands\" $host\n") if ($debug);
print(STDOUT "executing echo jlogin -c\"$jnx_commands\" $host\n") if ($debug);
- open(INPUT,"jlogin -c\"$jnx_commands\" $host </dev/null |") ||
- die "jlogin failed for $host: $!\n";
+
+ if (defined($ENV{NOPIPE})) {
+ system "jlogin -c \"$jnx_commands\" $host </dev/null > $host.raw" || die "jlogin failed for $host: $!\n";
+ open(INPUT, "< $host.raw") || die "jlogin failed for $host: $!\n";
+ } else {
+ open(INPUT,"jlogin -c \"$jnx_commands\" $host </dev/null |") || die "jlogin failed for $host: $!\n";
+ }
+
}
while(<INPUT>) {
tr/\015//d;
- if (/quit/) {
- delete($commands{"quit"});
- $clean_run=1;
- last;
- }
if (/^Error:/) {
+ s/^.*Error:/Error:/;
print STDOUT ("$host jlogin error: $_");
print STDERR ("$host jlogin error: $_") if ($debug);
$clean_run=0;
@@ -291,17 +367,25 @@ while(<INPUT>) {
$clean_run = 0;
last;
}
- if (/($cmds_regexp)/) {
- ProcessHistory("","","","# $host> $1\n");
- $func = FlailHelplessly;
+ while (/>\s*($cmds_regexp)\s*$/) {
+ $cmd = $1;
+ if (!defined($prompt)) {$prompt = ($_ =~ /^([^>]+>)/)[0]; }
print STDERR ("HIT COMMAND:$_") if ($debug);
- } else {
- $rval=eval $func;
+ if (! defined($commands{$cmd})) {
+ print STDERR "found unexpected command - \"$cmd\"\n";
+ $clean_run = 0;
+ last;
+ }
+ $rval = &{$commands{$cmd}};
+ delete($commands{$cmd});
if ($rval == -1) {
$clean_run = 0;
last;
- }
- $func=$rval if ($rval);
+ }
+ }
+ if (/>\s*quit/) {
+ $clean_run=1;
+ last;
}
}
print STDOUT "Done jlogin: $_\n" if ($log);
@@ -311,17 +395,21 @@ ProcessHistory("","","","");
close(INPUT);
close(OUTPUT);
+if (defined($ENV{NOPIPE})) {
+ unlink("$host.raw") if (! $debug);
+}
+
# check for completeness
$commands = join(", ", keys(%commands));
if (scalar(%commands) || !$clean_run) {
if (scalar(%commands)) {
- print STDOUT "missed cmd(s): $commands\n";
- print STDERR "missed cmd(s): $commands[0]\n" if ($debug);
+ printf(STDOUT "missed cmd(s): %s\n", join(',', keys(%commands)));
+ printf(STDERR "missed cmd(s): %s\n", join(',', keys(%commands))) if ($debug);
}
if (!$clean_run) {
- print STDOUT "End of run not found - removing $host.new\n";
- print STDERR "End of run not found - removing $host.new\n" if ($debug);
+ print STDOUT "End of run not found\n";
+ print STDERR "End of run not found\n" if ($debug);
system("/usr/bin/tail -1 $host.new");
}
- unlink "$host.new";
+ unlink "$host.new" if (! $debug);
}
diff --git a/bin/rancid b/bin/rancid
index 9b346fe..cd0cb8c 100755
--- a/bin/rancid
+++ b/bin/rancid
@@ -28,7 +28,7 @@ $file = $opt_f;
$host = $ARGV[0];
$clean_run = 0;
$found_end = 0;
-$timeo = 90; # clogin time in seconds
+$timeo = 90; # clogin timeout in seconds
# This routine is used to print out the router configuration
sub ProcessHistory {
@@ -89,8 +89,8 @@ sub valsort{
local($i) = 0;
local(@sorted_lines);
foreach $key (sort values %lines) {
- $sorted_lines[$i] = $key;
- $i++;
+ $sorted_lines[$i] = $key;
+ $i++;
}
@sorted_lines;
}
@@ -133,113 +133,141 @@ sub sortbyipaddr {
# This routine parses "show version"
sub ShowVersion {
print STDERR " In ShowVersion: $_" if ($debug);
- if (/^Slave in slot (\d+) is running/) {
- $slave = " Slave:";
- return;
- }
- /^IOS .* Software \(([A-Za-z-0-9]*)\), .*Version\s+(.*)$/ &&
- ProcessHistory("COMMENTS","keysort","F1","!Image:$slave Software: $1, $2\n") && return;
- /^([A-Za-z-0-9_]*) Synced to mainline version: (.*)$/ &&
- ProcessHistory("COMMENTS","keysort","F2",
- "!Image:$slave $1 Synced to mainline version: $2\n") && return;
- /^Compiled (.*)$/ &&
- ProcessHistory("COMMENTS","keysort","F3","!Image:$slave Compiled: $1\n") && return;
- /^ROM: (System )?Bootstrap.*(Version.*)$/ &&
- ProcessHistory("COMMENTS","keysort","G1","!ROM Bootstrap: $2\n") && return;
- /^ROM: \d+ Bootstrap .*(Version.*)$/ &&
- ProcessHistory("COMMENTS","keysort","G2","!ROM Image: Bootstrap$1\n") &&
- return;
- /^ROM: .*(Version.*)$/ &&
- ProcessHistory("COMMENTS","keysort","G3","!ROM Image: $1\n") && return;
- /^BOOTFLASH: .*(Version.*)$/ &&
- ProcessHistory("COMMENTS","keysort","G4","!BOOTFLASH: $1\n") && return;
- /^System image file is "([^\"]*)", booted via (\S*)/ &&
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if(/^$prompt/);
+ next if(/^(\s*|\s*$cmd\s*)$/);
+ if (/^Slave in slot (\d+) is running/) {
+ $slave = " Slave:";
+ next;
+ }
+ /^IOS .* Software \(([A-Za-z-0-9]*)\), .*Version\s+(.*)$/ &&
+ ProcessHistory("COMMENTS","keysort","F1",
+ "!Image:$slave Software: $1, $2\n") && next;
+ /^([A-Za-z-0-9_]*) Synced to mainline version: (.*)$/ &&
+ ProcessHistory("COMMENTS","keysort","F2",
+ "!Image:$slave $1 Synced to mainline version: $2\n") && next;
+ /^Compiled (.*)$/ &&
+ ProcessHistory("COMMENTS","keysort","F3",
+ "!Image:$slave Compiled: $1\n") && next;
+ /^ROM: (System )?Bootstrap.*(Version.*)$/ &&
+ ProcessHistory("COMMENTS","keysort","G1",
+ "!ROM Bootstrap: $2\n") && next;
+ /^ROM: \d+ Bootstrap .*(Version.*)$/ &&
+ ProcessHistory("COMMENTS","keysort","G2",
+ "!ROM Image: Bootstrap $1\n!\n") && next;
+ /^ROM: .*(Version.*)$/ &&
+ ProcessHistory("COMMENTS","keysort","G3","!ROM Image: $1\n") && next;
+ /^BOOTFLASH: .*(Version.*)$/ &&
+ ProcessHistory("COMMENTS","keysort","G4","!BOOTFLASH: $1\n") && next;
+ /^System image file is "([^\"]*)", booted via (\S*)/ &&
# removed the booted source due to
# CSCdk28131: cycling info in 'sh ver'
# ProcessHistory("COMMENTS","keysort","F4","!Image: booted via $2, $1\n") &&
- ProcessHistory("COMMENTS","keysort","F4","!Image: booted $1\n") &&
- return;
- /^System image file is "([^\"]*)"$/ &&
- ProcessHistory("COMMENTS","keysort","F5","!Image: $1\n") &&
- return;
- if (/(\S+)\s+\((\S+)\)\s+processor.*with (\S+K) bytes/) {
- if ( $1 eq "CSC") {
- $type = "AGS";
- } elsif ( $1 eq "CSC4") {
- $type = "AGS+";
- } elsif ( $1 eq "RSP1") {
- $type = "7500";
- } elsif ( $1 eq "RSP2") {
- $type = "7500";
- } elsif ( $1 eq "RSP4") {
- $type = "7500";
- } elsif ( $1 eq "RSP7000") {
- $type = "7500";
- } elsif ( $1 eq "RP1") {
- $type = "7000";
- } elsif ( $1 eq "RP") {
- $type = "7000";
- } elsif ( $1 eq "7202" || $1 eq "7204" || $1 eq "7206") {
- $type = "7200";
- } elsif ($1 eq "12004/GRP" || $1 eq "12008/GRP" || $1 eq "12012/GRP") {
- $type = "12000";
- } else {
- $type = $1;
+ ProcessHistory("COMMENTS","keysort","F4","!Image: booted $1\n") &&
+ next;
+ /^System image file is "([^\"]*)"$/ &&
+ ProcessHistory("COMMENTS","keysort","F5","!Image: $1\n") && next;
+ if (/(\S+)\s+\((\S+)\)\s+processor.*with (\S+K) bytes/) {
+ my($proc) = $1;
+ my($cpu) = $2;
+ my($mem) = $3;
+ if ( $1 eq "CSC") {
+ $type = "AGS";
+ } elsif ( $1 eq "CSC4") {
+ $type = "AGS+";
+ } elsif ( $1 eq "RSP7000") {
+ $type = "7500";
+ } elsif ( $1 =~ /RSP\d/) {
+ $type = "7500";
+ } elsif ( $1 eq "RP1") {
+ $type = "7000";
+ } elsif ( $1 eq "RP") {
+ $type = "7000";
+ } elsif ( $1 eq "7202" || $1 eq "7204" || $1 eq "7206") {
+ $type = "7200";
+ } elsif ($1 eq "12004/GRP" || $1 eq "12008/GRP" || $1 eq "12012/GRP") {
+ $type = "12000";
+ } else {
+ $type = $1;
+ }
+ print STDERR "TYPE = $type\n" if ($debug);
+ ProcessHistory("COMMENTS","keysort","A1",
+ "!Chassis type:$slave $proc - a $type router\n");
+ ProcessHistory("COMMENTS","keysort","B1",
+ "!Memory:$slave main $mem\n");
+ ProcessHistory("COMMENTS","keysort","A3","!CPU:$slave $cpu\n");
+ next;
+ }
+ if (/(\S+) Silicon\s*Switch Processor/) {
+ if (!defined($C0)) {
+ $C0=1; ProcessHistory("COMMENTS","keysort","C0","!\n");
+ }
+ ProcessHistory("COMMENTS","keysort","C2","!SSP: $1\n");
+ $ssp = 1;
+ $sspmem = $1;
+ next;
+ }
+ /^(\d+K) bytes of multibus/ &&
+ ProcessHistory("COMMENTS","keysort","B2",
+ "!Memory: multibus $1\n") && next;
+ /^(\d+K) bytes of non-volatile/ &&
+ ProcessHistory("COMMENTS","keysort","B3",
+ "!Memory: nvram $1\n") && next;
+ /^(\d+K) bytes of flash memory/ &&
+ ProcessHistory("COMMENTS","keysort","B5","!Memory: flash $1\n") &&
+ next;
+ /^(\d+K) bytes of .*flash partition/ &&
+ ProcessHistory("COMMENTS","keysort","B6",
+ "!Memory: flash partition $1\n") && next;
+ /^(\d+K) bytes of Flash internal/ &&
+ ProcessHistory("COMMENTS","keysort","B4",
+ "!Memory: bootflash $1\n") && next;
+ if(/^(\d+K) bytes of (Flash|ATA)?.*PCMCIA .*slot ?(\d)/i) {
+ ProcessHistory("COMMENTS","keysort","B7",
+ "!Memory: pcmcia $2 slot$3 $1\n");
+ next;
+ }
+ if (/^Configuration register is (.*)$/) {
+ $config_register=$1;
+ next;
}
- print STDERR "TYPE = $type\n" if ($debug);
- ProcessHistory("COMMENTS","keysort","A1","!Chassis type:$slave $1 - a $type router\n");
- ProcessHistory("COMMENTS","keysort","B1","!Memory:$slave main $3\n");
- ProcessHistory("COMMENTS","keysort","A3","!CPU:$slave $2\n");
- return;
- }
- if (/(\S+) Silicon\s*Switch Processor/) {
- if (!defined($C0)) {$C0=1; ProcessHistory("COMMENTS","keysort","C0","!\n");}
- ProcessHistory("COMMENTS","keysort","C2","!SSP: $1\n");
- $ssp = 1;
- $sspmem = $1;
- return;
- }
- /^(\d+K) bytes of multibus/ &&
- ProcessHistory("COMMENTS","keysort","B2","!Memory: multibus $1\n") && return;
- /^(\d+K) bytes of non-volatile/ &&
- ProcessHistory("COMMENTS","keysort","B3","!Memory: nvram $1\n") && return;
- /^(\d+K) bytes of flash memory/ &&
- ProcessHistory("COMMENTS","keysort","B5","!Memory: flash $1\n") &&
- return;
- /^(\d+K) bytes of .*flash partition/ &&
- ProcessHistory("COMMENTS","keysort","B6","!Memory: flash partition $1\n") &&
- return;
- /^(\d+K) bytes of Flash internal/ &&
- ProcessHistory("COMMENTS","keysort","B4","!Memory: bootflash $1\n") &&
- return;
- /^(\d+K) bytes of Flash PCMCIA card at slot 0 / &&
- ProcessHistory("COMMENTS","keysort","B7","!Memory: pcmcia slot0 $1\n") && return;
- /^(\d+K) bytes of Flash PCMCIA card at slot 1 / &&
- ProcessHistory("COMMENTS","keysort","B8","!Memory: pcmcia slot1 $1\n") && return;
- if (/^Configuration register is (.*)$/) {
- $config_register=$1;
- return;
}
- return;
+ return(0);
}
# This routine parses "show env all"
sub ShowEnv {
# Skip if this is not a 7500 or 7000.
print STDERR " In ShowEnv: $_" if ($debug);
- return if ($type !~ /^7/);
- if (!defined($E0)) {$E0=1; ProcessHistory("COMMENTS","keysort","E0","!\n");}
- if (/^Arbiter type (\d), backplane type (\S+)/) {
- if (!defined($C0)) {$C0=1; ProcessHistory("COMMENTS","keysort","C0","!\n");}
- ProcessHistory("COMMENTS","keysort","C1","!Enviromental Arbiter Type: $1\n");
- ProcessHistory("COMMENTS","keysort","A2","!Chassis type: $2 backplane\n");
- return;
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ return(1) if ($type !~ /^7/);
+ if (!defined($E0)) {
+ $E0=1;
+ ProcessHistory("COMMENTS","keysort","E0","!\n");
+ }
+ if (/^Arbiter type (\d), backplane type (\S+)/) {
+ if (!defined($C0)) {
+ $C0=1; ProcessHistory("COMMENTS","keysort","C0","!\n");
+ }
+ ProcessHistory("COMMENTS","keysort","C1",
+ "!Enviromental Arbiter Type: $1\n");
+ ProcessHistory("COMMENTS","keysort","A2",
+ "!Chassis type: $2 backplane\n");
+ next;
+ }
+ /^\s*(Power .*)/ &&
+ ProcessHistory("COMMENTS","keysort","E1","!Power: $1\n") && next;
+ /^\s*(Lower Power .*)/i &&
+ ProcessHistory("COMMENTS","keysort","E2","!Power: $1\n") && next;
}
- /^\s*(Power .*)/ &&
- ProcessHistory("COMMENTS","keysort","E1","!Power: $1\n") && return;
- /^\s*(Lower Power .*)/i &&
- ProcessHistory("COMMENTS","keysort","E2","!Power: $1\n") && return;
- return;
+ ProcessHistory("COMMENTS","","","!\n");
+ return(0);
}
# This routine parses "show gsr chassis-info" for the gsr
@@ -247,135 +275,153 @@ sub ShowEnv {
sub ShowGSR {
# Skip if this is not a 1200n.
print STDERR " In ShowGSR: $_" if ($debug);
- return if ($type !~ /^120/);
- /^$/ && return;
- /^\s+Chassis: type (\S+) Fab Ver: (\S+)/ &&
- ProcessHistory("COMMENTS","keysort","D0","!\n") &&
- ProcessHistory("COMMENTS","keysort","D1","!GSR Chassis type: $1 Fab Ver: $2\n") && return;
- /^\s+Chassis S\/N: (.*)$/ &&
- ProcessHistory("COMMENTS","keysort","D2","!GSR Chassis S/N: $1\n") && return;
- /^\s+PCA: (\S+)\s*rev: (\S+)\s*dev: \S+\s*HW ver: (\S+)$/ &&
- ProcessHistory("COMMENTS","keysort","D3","!GSR Backplane PCA: $1, rev $2, ver $3\n") && return;
- /^\s+Backplane S\/N: (\S+)$/ &&
- ProcessHistory("COMMENTS","keysort","D4","!GSR Backplane S/N: $1\n") && return;
- return;
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ return(1) if ($type !~ /^120/);
+ /^$/ && next;
+ /^\s+Chassis: type (\S+) Fab Ver: (\S+)/ &&
+ ProcessHistory("COMMENTS","keysort","D0","!\n") &&
+ ProcessHistory("COMMENTS","keysort","D1",
+ "!GSR Chassis type: $1 Fab Ver: $2\n") &&
+ next;
+ /^\s+Chassis S\/N: (.*)$/ &&
+ ProcessHistory("COMMENTS","keysort","D2",
+ "!GSR Chassis S/N: $1\n") &&
+ next;
+ /^\s+PCA: (\S+)\s*rev: (\S+)\s*dev: \S+\s*HW ver: (\S+)$/ &&
+ ProcessHistory("COMMENTS","keysort","D3",
+ "!GSR Backplane PCA: $1, rev $2, ver $3\n") &&
+ next;
+ /^\s+Backplane S\/N: (\S+)$/ &&
+ ProcessHistory("COMMENTS","keysort","D4",
+ "!GSR Backplane S/N: $1\n") &&
+ next;
+ }
+ ProcessHistory("COMMENTS","","","!\n");
+ return(0);
}
# This routine parses "show boot"
sub ShowBoot {
# Pick up boot variables if 7000/7500/12000; otherwise pick up bootflash.
print STDERR " In ShowBoot: $_" if ($debug);
- return if /^\s*$/;
- return if /^\s*\^\s*$/;
- return if /Invalid input detected/;
- return if /(Open device \S+ failed|Error opening \S+:)/;
- if (!defined($H0)) {$H0=1; ProcessHistory("COMMENTS","keysort","H0","!\n");}
- if ($type !~ /^(1200|7)/) {
- ProcessHistory("COMMENTS","keysort","H2","!BootFlash: $_");
- } elsif (/variable/) {
- ProcessHistory("COMMENTS","keysort","H1","!Variable: $_");
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ return(1) if /^\s*\^\s*$/;
+ return(1) if /Ambiguous command/i;
+ return(1) if /Invalid input detected/;
+ return(1) if /(Open device \S+ failed|Error opening \S+:)/;
+ next if /CONFGEN variable/;
+ if (!defined($H0)) {
+ $H0=1; ProcessHistory("COMMENTS","keysort","H0","!\n");
+ }
+ if ($type !~ /^(1200|7)/) {
+ ProcessHistory("COMMENTS","keysort","H2","!BootFlash: $_");
+ } elsif (/variable/) {
+ ProcessHistory("COMMENTS","keysort","H1","!Variable: $_");
+ }
}
- return;
+ ProcessHistory("COMMENTS","","","!\n");
+ return(0);
}
# This routine parses "show flash"
sub ShowFlash {
# skip if this is 7000, 7200, 7500, or 12000.
print STDERR " In ShowFlash: $_" if ($debug);
- return if /^\s*$/;
- return if ($type =~ /^(1200|7.0)/);
- return if /^\s*\^\s*$/;
- return if /Invalid input detected/;
- ProcessHistory("FLASH","","","!Flash: $_");
- return;
-}
-
-# This routine parses "dir /all bootflash:"
-sub DirBootflash {
- # Skip if this is not a 7000, 7200, 7500, or 12000.
- print STDERR " In DirBootflash: $_" if ($debug);
- return if /^\s*$/;
- return if ($type !~ /^(1200|7.0)/);
- return if /^\s*\^\s*$/;
- return if /Invalid input detected/;
- /: device being squeezed/ && return(-1); # Flash is busy
- return if /(Open device \S+ failed|Error opening \S+:)/;
- ProcessHistory("FLASH","","","!Flash: BootFlash: $_");
- return;
-}
-# This routine parses "dir /all slot0:"
-sub DirSlot0 {
- # Skip if this is not a 3600, 7000, 7200, 7500, or 12000.
- print STDERR " In DirSlot0: $_" if ($debug);
- return if /^\s*$/;
- return if ($type !~ /^(1200|7.0|36.0)/);
- return if /^\s*\^\s*$/;
- return if /Invalid input detected/;
- /: device being squeezed/ && return(-1); # Flash is busy
- return if /(Open device \S+ failed|Error opening \S+:)/;
- ProcessHistory("FLASH","","","!Flash: Slot0: $_");
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ return(1) if ($type =~ /^(1200|7.0)/);
+ return(1) if /^\s*\^\s*$/;
+ return(1) if /Invalid input detected/;
+ ProcessHistory("FLASH","","","!Flash: $_");
+ }
+ ProcessHistory("","","","!\n");
return;
}
-# This routine parses "dir /all slot1:"
-sub DirSlot1 {
+# This routine parses "dir /all ((disk|slot)N|bootflash):"
+sub DirSlotN {
# Skip if this is not a 3600, 7000, 7200, 7500, or 12000.
- print STDERR " In DirSlot1: $_" if ($debug);
- return if /^\s*$/;
- return if ($type !~ /^(1200|7.0|36.0)/);
- return if /^\s*\^\s*$/;
- return if /Invalid input detected/;
- /: device being squeezed/ && return(-1); # Flash is busy
- return if /(Open device \S+ failed|Error opening \S+:)/;
- ProcessHistory("FLASH","","","!Flash: Slot1: $_");
- return;
+ print STDERR " In DirSlotN: $_" if ($debug);
+
+ my($dev) = (/\s([^\s]+):/);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ return(1) if ($type !~ /^(1200|7.0|36.0)/);
+ return(1) if /^\s*\^\s*$/;
+ return(1) if /Invalid input detected/;
+ return(1) if /No space information available/;
+ return(-1) if /\%Error calling/;
+ return(-1) if /: device being squeezed/; # Flash is busy
+ return(1) if /(Open device \S+ failed|Error opening \S+:)/;
+ ProcessHistory("FLASH","","","!Flash: $dev: $_");
+ }
+ ProcessHistory("","","","!\n");
+ return(0);
}
# This routine parses "show controllers"
sub ShowContAll {
# Skip if this is a 70[01]0, 7500, or 12000.
print STDERR " In ShowContAll: $_" if ($debug);
- return if ($type =~ /^(1200|7[05])/);
- if (/^Interface (\S*)$/) { $INT = "$1, "; return; }
- /^(BRI unit \d)/ &&
- ProcessHistory("INT","","","!Interface: $1\n") && return;
- /^LANCE unit \d, NIM/ &&
- ProcessHistory("INT","","","!Interface: $_") && return;
- /^(LANCE unit \d)/ &&
- ProcessHistory("INT","","","!Interface: $1\n") && return;
- /(Media Type is \S+),/ &&
- ProcessHistory("INT","","","!\t$1\n");
- if (/(M\dT:) show controller:$/) {
- my($ctlr) = $1;
- $_ = <INPUT>; tr/\015//d; s/ subunit \d,//;
- ProcessHistory("INT","","","!Interface: $ctlr $_");
- }
- /^(HD unit \d), idb/ &&
- ProcessHistory("INT","","","!Interface: $1\n") && return;
- /^HD unit \d, NIM/ &&
- ProcessHistory("INT","","","!Interface: $_") && return;
- /^buffer size \d+ HD unit \d, (.*)/ &&
- ProcessHistory("INT","","","!\t$1\n") && return;
- /^AM79970 / && ProcessHistory("INT","","","!Interface: $_") && return;
- /^buffer size \d+ (Universal Serial: .*)/ &&
- ProcessHistory("INT","","","!\t$1\n") && return;
- /^Hardware is (.*)/ &&
- ProcessHistory("INT","","","!Interface: $INT$1\n") && return;
- /^(QUICC Serial unit \d),/ &&
- ProcessHistory("INT","","","!$1\n") && return;
- /^QUICC Ethernet .*/ &&
- ProcessHistory("INT","","","!$_") && return;
- /^DTE .*\.$/ &&
- ProcessHistory("INT","","","!\t$_") && return;
- /^(cable type :.*),/ &&
- ProcessHistory("INT","","","!\t$1\n") && return;
- /^(.* cable.*), received clockrate \d+$/ &&
- ProcessHistory("INT","","","!\t$1\n") && return;
- /^.* cable.*$/ &&
- ProcessHistory("INT","","","!\t$_") && return;
- return;
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ return(1) if ($type =~ /^(1200|7[05])/);
+ if (/^Interface ([^ \n(]*)/) { $INT = "$1, "; next; }
+ /^(BRI unit \d)/ &&
+ ProcessHistory("INT","","","!Interface: $1\n") && next;
+ /^LANCE unit \d, NIM/ &&
+ ProcessHistory("INT","","","!Interface: $_") && next;
+ /^(LANCE unit \d)/ &&
+ ProcessHistory("INT","","","!Interface: $1\n") && next;
+ /(Media Type is \S+),/ &&
+ ProcessHistory("INT","","","!\t$1\n");
+ if (/(M\dT:) show controller:$/) {
+ my($ctlr) = $1;
+ $_ = <INPUT>; tr/\015//d; s/ subunit \d,//;
+ ProcessHistory("INT","","","!Interface: $ctlr $_");
+ }
+ /^(HD unit \d), idb/ &&
+ ProcessHistory("INT","","","!Interface: $1\n") && next;
+ /^HD unit \d, NIM/ &&
+ ProcessHistory("INT","","","!Interface: $_") && next;
+ /^buffer size \d+ HD unit \d, (.*)/ &&
+ ProcessHistory("INT","","","!\t$1\n") && next;
+ /^AM79970 / && ProcessHistory("INT","","","!Interface: $_") && next;
+ /^buffer size \d+ (Universal Serial: .*)/ &&
+ ProcessHistory("INT","","","!\t$1\n") && next;
+ /^Hardware is (.*)/ &&
+ ProcessHistory("INT","","","!Interface: $INT$1\n") && next;
+ /^(QUICC Serial unit \d),/ &&
+ ProcessHistory("INT","","","!$1\n") && next;
+ /^QUICC Ethernet .*/ &&
+ ProcessHistory("INT","","","!$_") && next;
+ /^DTE .*\.$/ &&
+ ProcessHistory("INT","","","!\t$_") && next;
+ /^(cable type :.*),/ &&
+ ProcessHistory("INT","","","!\t$1\n") && next;
+ /^(.* cable.*), received clockrate \d+$/ &&
+ ProcessHistory("INT","","","!\t$1\n") && next;
+ /^.* cable.*$/ &&
+ ProcessHistory("INT","","","!\t$_") && next;
+ }
+ return(0);
}
# This routine parses "show controllers cbus"
@@ -383,37 +429,43 @@ sub ShowContAll {
sub ShowContCbus {
# Skip if this is not a 7000 or 7500.
print STDERR " In ShowContCbus: $_" if ($debug);
- return if ($type !~ /^7[05]0/);
- if (/^\s*slot(\d+): ([^,]+), hw (\S+), sw (\S+), ccb/) {
- $slot = $1;
- $board{$slot} = $2;
- $hwver{$slot} = $3;
- $hwucode{$slot} = $4;
- } elsif (/^\s*(\S+) (\d+), hardware version (\S+), microcode version (\S+)/) {
- $slot = $2;
- $board{$slot} = $1;
- $hwver{$slot} = $3;
- $hwucode{$slot} = $4;
- } elsif (/(Microcode .*)/) {
- $ucode{$slot} = $1;
- } elsif (/(software loaded .*)/) {
- $ucode{$slot} = $1;
- } elsif (/(\d+) Kbytes of main memory, (\d+) Kbytes cache memory/) {
- $hwmemd{$slot} = $1;
- $hwmemc{$slot} = $2;
- } elsif (/byte buffers/) {
- chop;
- s/^\s*//;
- $hwbuf{$slot} = $_;
- } elsif (/Interface (\d+) - (\S+ \S+),/) {
- $interface = $1;
- ProcessHistory("HW","","","!\n!Int $interface: in slot $slot, named $2\n");
- return;
- } elsif (/(\d+) buffer RX queue threshold, (\d+) buffer TX queue limit, buffer size (\d+)/) {
- ProcessHistory("HW","","","!Int $interface: rxq $1, txq $2, bufsize $3\n");
- return;
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ return(1) if ($type !~ /^7[05]0/);
+ if (/^\s*slot(\d+): ([^,]+), hw (\S+), sw (\S+), ccb/) {
+ $slot = $1;
+ $board{$slot} = $2;
+ $hwver{$slot} = $3;
+ $hwucode{$slot} = $4;
+ } elsif (/^\s*(\S+) (\d+), hardware version (\S+), microcode version (\S+)/) {
+ $slot = $2;
+ $board{$slot} = $1;
+ $hwver{$slot} = $3;
+ $hwucode{$slot} = $4;
+ } elsif (/(Microcode .*)/) {
+ $ucode{$slot} = $1;
+ } elsif (/(software loaded .*)/) {
+ $ucode{$slot} = $1;
+ } elsif (/(\d+) Kbytes of main memory, (\d+) Kbytes cache memory/) {
+ $hwmemd{$slot} = $1;
+ $hwmemc{$slot} = $2;
+ } elsif (/byte buffers/) {
+ chop;
+ s/^\s*//;
+ $hwbuf{$slot} = $_;
+ } elsif (/Interface (\d+) - (\S+ \S+),/) {
+ $interface = $1;
+ ProcessHistory("HW","","",
+ "!\n!Int $interface: in slot $slot, named $2\n"); next;
+ } elsif (/(\d+) buffer RX queue threshold, (\d+) buffer TX queue limit, buffer size (\d+)/) {
+ ProcessHistory("HW","","","!Int $interface: rxq $1, txq $2, bufsize $3\n");
+ next;
+ }
}
- return;
+ return(0);
}
# This routine parses "show diagbus"
@@ -421,73 +473,84 @@ sub ShowContCbus {
sub ShowDiagbus {
# Skip if this is not a 7000, 70[01]0, or 7500.
print STDERR " In ShowDiagbus: $_" if ($debug);
- return if ($type !~ /^7[05]/);
- if (/^\s*Slot (\d+):/i) {
- $slot = $1;
- return;
- } elsif (/^\s*Slot (\d+) \(virtual\):/i) {
- $slot = $1;
- return;
- } elsif (/^\s*(.*Processor.*|.*controller|.*Chassis Interface), HW rev (\S+), board revision (\S+)/i) {
- $board = $1;
- $hwver = $2;
- $boardrev = $3;
- if ($board =~ /Processor/) {
- if ($board =~ /7000 Route\/Switch/) {
- $board = "RSP7000";
- } elsif ($board =~ /Route\/Switch Processor (\d)/) {
- $board = "RSP$1";
- } elsif ($board =~ /Route/) {
- $board = "RP";
- } elsif ($board =~ /Silicon Switch/) {
- $board = "SSP";
- } elsif ($board =~ /Switch/) {
- $board = "SP";
- $board = "SSP $sspmem" if $ssp;
- } elsif ($board =~ /ATM/) {
- $board = "AIP";
- }
- } elsif ($board =~ /(.*) controller/i) {
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ return(1) if ($type !~ /^7[05]/);
+ if (/^\s*Slot (\d+):/i) {
+ $slot = $1;
+ next;
+ } elsif (/^\s*Slot (\d+) \(virtual\):/i) {
+ $slot = $1;
+ next;
+ } elsif (/^\s*(.*Processor.*|.*controller|.*Chassis Interface), HW rev (\S+), board revision (\S+)/i) {
$board = $1;
- }
- # hwucode{$slot} defined in ShowContCbus
- if (defined $hwucode{$slot}) {
- ProcessHistory("SLOT","","","!\n!Slot $slot/$board: hvers $hwver rev $boardrev ucode $hwucode{$slot}\n");
- } else {
- ProcessHistory("SLOT","","","!\n!Slot $slot/$board: hvers $hwver rev $boardrev\n");
- }
- # These are also from the ShowContCbus
- ProcessHistory("SLOT","","","!Slot $slot/$board: $ucode{$slot}\n") if (defined $ucode{$slot});
- ProcessHistory("SLOT","","","!Slot $slot/$board: memd $hwmemd{$slot}, cache $hwmemc{$slot}\n")
+ $hwver = $2;
+ $boardrev = $3;
+ if ($board =~ /Processor/) {
+ if ($board =~ /7000 Route\/Switch/) {
+ $board = "RSP7000";
+ } elsif ($board =~ /Route\/Switch Processor (\d)/) {
+ $board = "RSP$1";
+ } elsif ($board =~ /Route/) {
+ $board = "RP";
+ } elsif ($board =~ /Silicon Switch/) {
+ $board = "SSP";
+ } elsif ($board =~ /Switch/) {
+ $board = "SP";
+ $board = "SSP $sspmem" if $ssp;
+ } elsif ($board =~ /ATM/) {
+ $board = "AIP";
+ }
+ } elsif ($board =~ /(.*) controller/i) {
+ $board = $1;
+ }
+ # hwucode{$slot} defined in ShowContCbus
+ if (defined $hwucode{$slot}) {
+ ProcessHistory("SLOT","","","!\n!Slot $slot/$board: hvers $hwver rev $boardrev ucode $hwucode{$slot}\n");
+ } else {
+ ProcessHistory("SLOT","","","!\n!Slot $slot/$board: hvers $hwver rev $boardrev\n");
+ }
+ # These are also from the ShowContCbus
+ ProcessHistory("SLOT","","","!Slot $slot/$board: $ucode{$slot}\n") if (defined $ucode{$slot});
+ ProcessHistory("SLOT","","","!Slot $slot/$board: memd $hwmemd{$slot}, cache $hwmemc{$slot}\n")
if ((defined $hwmemd{$slot}) && (defined $hwmemc{$slot}));
- ProcessHistory("SLOT","","","!Slot $slot/$board: $hwbuf{$slot}\n") if (defined $hwbuf{$slot});
- return;
- }
- /Serial number: (\S+)\s*Part number: (\S+)/ &&
- ProcessHistory("SLOT","","","!Slot $slot/$board: part $2, serial $1\n") && return;
- /^\s*Controller Memory Size: (.*)$/ &&
- ProcessHistory("SLOT","","","!Slot $slot/$board: $1\n") &&
- return;
- if (/PA Bay (\d) Information/) {
- $pano = $1;
- if ("PA" =~ /$board/) {
- ($s,$c) = split(/\//,$board);
- $board = "$s/$c/PA $pano";
- } else {
- $board =~ s/\/PA \d//;
- $board = "$board/PA $pano";
+ ProcessHistory("SLOT","","","!Slot $slot/$board: $hwbuf{$slot}\n") if (defined $hwbuf{$slot});
+ next;
}
- return;
- }
- /\s+(.*) PA, (\d) ports?, (\S+)/ &&
- ProcessHistory("SLOT","","","!Slot $slot/$board: type $3, $2 ports\n") && return;
- /\s+(.*) PA( \(\S+\))?, (\d) ports?/ &&
- ProcessHistory("SLOT","","","!Slot $slot/$board: type $1$2, $3 ports\n") && return;
- /^\s*HW rev (\S+), Board revision (\S+)/ &&
- ProcessHistory("SLOT","","","!Slot $slot/$board: hvers $1 rev $2\n") && return;
- /Serial number: (\S+)\s*Part number: (\S+)/ &&
- ProcessHistory("SLOT","","","!Slot $slot/$board: part $2, serial $1\n") && return;
- return;
+ /Serial number: (\S+)\s*Part number: (\S+)/ &&
+ ProcessHistory("SLOT","","",
+ "!Slot $slot/$board: part $2, serial $1\n") &&
+ next;
+ /^\s*Controller Memory Size: (.*)$/ &&
+ ProcessHistory("SLOT","","","!Slot $slot/$board: $1\n") &&
+ next;
+ if (/PA Bay (\d) Information/) {
+ $pano = $1;
+ if ("PA" =~ /$board/) {
+ ($s,$c) = split(/\//,$board);
+ $board = "$s/$c/PA $pano";
+ } else {
+ $board =~ s/\/PA \d//;
+ $board = "$board/PA $pano";
+ }
+ next;
+ }
+ /\s+(.*) PA, (\d) ports?, (\S+)/ &&
+ ProcessHistory("SLOT","","","!Slot $slot/$board: type $3, $2 ports\n") &&
+ next;
+ /\s+(.*) PA( \(\S+\))?, (\d) ports?/ &&
+ ProcessHistory("SLOT","","","!Slot $slot/$board: type $1$2, $3 ports\n") &&
+ next;
+ /^\s*HW rev (\S+), Board revision (\S+)/ &&
+ ProcessHistory("SLOT","","","!Slot $slot/$board: hvers $1 rev $2\n") &&
+ next;
+ /Serial number: (\S+)\s*Part number: (\S+)/ &&
+ ProcessHistory("SLOT","","","!Slot $slot/$board: part $2, serial $1\n") && next;
+ }
+ return(0);
}
# This routine parses "show diags" for the gsr, 7200, 3600
@@ -495,75 +558,84 @@ sub ShowDiagbus {
sub ShowDiags {
# Skip if this is not a 12000.
print STDERR " In ShowDiags: $_" if ($debug);
- return if ($type !~ /^(1200|720|36.0)/);
- /^$/ && return;
- if (!defined($showdiags)) {$showdiags=1; ProcessHistory("SLOT","","","!\n");}
- s/Port Packet Over SONET/POS/;
- if (/^\s*SLOT (\d+)\s+\(.*\): (.*)/) {
- $slot = $1;
- ProcessHistory("SLOT","","","!Slot $slot: $2\n");
- $board = "RP" if (/Route Processor/);
- $board = "CLK" if (/Clock Scheduler Card/);
- return;
- }
- if (/^\s+PCA:\s+(.*)/){
- local($part) = $1;
- $_ = <INPUT>;
- /^\s+HW version (\S+)\s+S\/N (\S+)/ &&
- ProcessHistory("SLOT","","","!Slot $slot/PCA: part $part, serial $2\n") &&
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ return(1) if ($type !~ /^(1200|720|36.0)/);
+ /^$/ && next;
+ if (!defined($showdiags)) {$showdiags=1; ProcessHistory("SLOT","","","!\n");}
+ s/Port Packet Over SONET/POS/;
+ if (/^\s*SLOT (\d+)\s+\(.*\): (.*)/) {
+ $slot = $1;
+ ProcessHistory("SLOT","","","!Slot $slot: $2\n");
+ $board = "RP" if (/Route Processor/);
+ $board = "CLK" if (/Clock Scheduler Card/);
+ next;
+ }
+ if (/^\s+PCA:\s+(.*)/){
+ local($part) = $1;
+ $_ = <INPUT>;
+ /^\s+HW version (\S+)\s+S\/N (\S+)/ &&
+ ProcessHistory("SLOT","","","!Slot $slot/PCA: part $part, serial $2\n") &&
ProcessHistory("SLOT","","","!Slot $slot/PCA: hvers $1\n");
- return;
- }
+ next;
+ }
- if (/^\s+MBUS: .*\)\s+(.*)/) {
- local($tmp) = "!Slot $slot/MBUS: part $1";
- $_ = <INPUT>;
- /^\s+HW version (\S+)\s+S\/N (\S+)/ &&
- ProcessHistory("SLOT","","","$tmp, serial $2\n") &&
+ if (/^\s+MBUS: .*\)\s+(.*)/) {
+ local($tmp) = "!Slot $slot/MBUS: part $1";
+ $_ = <INPUT>;
+ /^\s+HW version (\S+)\s+S\/N (\S+)/ &&
+ ProcessHistory("SLOT","","","$tmp, serial $2\n") &&
ProcessHistory("SLOT","","","!Slot $slot/MBUS: hvers $1\n");
- return;
- }
- if (/^\s+MBUS Agent Software version (.*)/) {
- local($sw) = $1;
- local($tail) = "!\n" if ($board =~ /(CLK|RP)/);
- ProcessHistory("SLOT","","","!Slot $slot/MBUS: software $sw\n$tail");
- return;
- }
- if (/^\s+DRAM size: (\d+)/) {
- local($dram) = $1 / 1048576;
- $_ = <INPUT>;
- /^\s+FrFab SDRAM size: (\d+)/ &&
- ProcessHistory("SLOT","","","!Slot $slot/MBUS: $dram Mbytes DRAM, "
+ next;
+ }
+ if (/^\s+MBUS Agent Software version (.*)/) {
+ local($sw) = $1;
+ local($tail) = "!\n" if ($board =~ /(CLK|RP)/);
+ ProcessHistory("SLOT","","","!Slot $slot/MBUS: software $sw\n$tail");
+ next;
+ }
+ if (/^\s+DRAM size: (\d+)/) {
+ local($dram) = $1 / 1048576;
+ $_ = <INPUT>;
+ /^\s+FrFab SDRAM size: (\d+)/ &&
+ ProcessHistory("SLOT","","","!Slot $slot/MBUS: $dram Mbytes DRAM, "
. $1 / 1024 . " Kbytes SDRAM\n!\n");
- return;
- }
- # 7200 and 3600 stuff
- if (/^(Slot) (\d+):/ || /^\s+(WIC) Slot (\d):/) {
- if ($1 eq "WIC") {
- $WIC = "/$2";
- } else {
- $slot = $2;
- undef($WIC);
+ next;
}
- $_ = <INPUT>; tr/\015//d;
- # clean up hideous 7200 format to look more like 7500 output
- s/Fast-ethernet on C7200 I\/O card/FE-IO/;
- s/ with MII or RJ45/-TX/;
- s/Fast-ethernet /100Base/; s/[)(]//g;
-
- /\s+(.*)\s+port adapter?,\s+(\d+)\s+/ &&
- ProcessHistory("SLOT","","","!Slot $slot: type $1, $2 ports\n");
- /\s+(.*)\s+daughter card(.*)$/ &&
- ProcessHistory("SLOT","","","!Slot $slot$WIC: type $1$2\n");
- /\s+(FT1)$/ &&
- ProcessHistory("SLOT","","","!Slot $slot$WIC: type $1\n");
- return;
- }
- /revision\s+(\S+).*revision\s+(\S+)/ &&
- ProcessHistory("SLOT","","","!Slot $slot$WIC: hvers $1 rev $2\n") && return;
- /number\s+(\S+)\s+Part number\s+(\S+)/ &&
- ProcessHistory("SLOT","","","!Slot $slot$WIC: part $2, serial $1\n!\n") && return;
- return;
+ # 7200 and 3600 stuff
+ if (/^(Slot) (\d+):/ || /^\s+(WIC) Slot (\d):/) {
+ if ($1 eq "WIC") {
+ $WIC = "/$2";
+ } else {
+ $slot = $2;
+ undef($WIC);
+ }
+ $_ = <INPUT>; tr/\015//d;
+
+ # clean up hideous 7200 format to look more like 7500 output
+ s/Fast-ethernet on C7200 I\/O card/FE-IO/;
+ s/ with MII or RJ45/-TX/;
+ s/Fast-ethernet /100Base/; s/[)(]//g;
+
+ /\s+(.*)\s+port adapter?,\s+(\d+)\s+/ &&
+ ProcessHistory("SLOT","","","!Slot $slot: type $1, $2 ports\n");
+ /\s+(.*)\s+daughter card(.*)$/ &&
+ ProcessHistory("SLOT","","","!Slot $slot$WIC: type $1$2\n");
+ /\s+(FT1)$/ &&
+ ProcessHistory("SLOT","","","!Slot $slot$WIC: type $1\n");
+ next;
+ }
+ /revision\s+(\S+).*revision\s+(\S+)/ &&
+ ProcessHistory("SLOT","","","!Slot $slot$WIC: hvers $1 rev $2\n") &&
+ next;
+ /number\s+(\S+)\s+Part number\s+(\S+)/ &&
+ ProcessHistory("SLOT","","","!Slot $slot$WIC: part $2, serial $1\n!\n") &&
+ next;
+}
+ return(0);
}
# This routine parses "show c7200" for the 7200
@@ -571,173 +643,212 @@ sub ShowDiags {
sub ShowC7200 {
# Skip if this is not a 7200.
print STDERR " In ShowC7200: $_" if ($debug);
- return if ($type !~ /^72/);
- /^$/ && return;
- if (/C7200 Midplane EEPROM:/) {
- $_ = <INPUT>;
- /revision\s+(\S+).*revision\s+(\S+)/;
- ProcessHistory("SLOT","","","!Slot Midplane: hvers $1 rev $2\n");
- $_ = <INPUT>;
- /number\s+(\S+)\s+Part number\s+(\S+)/;
- ProcessHistory("SLOT","","","!Slot Midplane: part $2, serial $1\n!\n");
- return;
- }
- if (/C7200 CPU EEPROM:/) {
- $_ = <INPUT>;
- /revision\s+(\S+).*revision\s+(\S+)/ &&
- ProcessHistory("SLOT","","","!Slot CPU: hvers $1 rev $2\n");
- $_ = <INPUT>;
- /number\s+(\S+)\s+Part number\s+(\S+)/ &&
- ProcessHistory("SLOT","","","!Slot CPU: part $2, serial $1\n!\n");
- return;
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ return(1) if ($type !~ /^72/);
+ /^$/ && next;
+ if (/C7200 Midplane EEPROM:/) {
+ $_ = <INPUT>;
+ /revision\s+(\S+).*revision\s+(\S+)/;
+ ProcessHistory("SLOT","","","!Slot Midplane: hvers $1 rev $2\n");
+ $_ = <INPUT>;
+ /number\s+(\S+)\s+Part number\s+(\S+)/;
+ ProcessHistory("SLOT","","","!Slot Midplane: part $2, serial $1\n!\n");
+ next;
+ }
+ if (/C7200 CPU EEPROM:/) {
+ $_ = <INPUT>;
+ /revision\s+(\S+).*revision\s+(\S+)/ &&
+ ProcessHistory("SLOT","","","!Slot CPU: hvers $1 rev $2\n");
+ $_ = <INPUT>;
+ /number\s+(\S+)\s+Part number\s+(\S+)/ &&
+ ProcessHistory("SLOT","","","!Slot CPU: part $2, serial $1\n!\n");
+ next;
+ }
}
- return;
+ return(0);
}
# This routine processes a "write term"
sub WriteTerm {
print STDERR " In WriteTerm: $_" if ($debug);
- /Non-Volatile memory is in use/ && return(-1); # NvRAM is locked
- # skip the crap
- if (/^(##+$|Building configuration...)/i) {
- while (<INPUT>) {
- next if (/^Current configuration:/i);
- next if (/^([%!].*|\s*)$/);
- next if (/^ip add.*ipv4:/); # band-aid for 3620 12.0S
- last;
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if(/^$prompt/);
+ /Non-Volatile memory is in use/ && return(-1); # NvRAM is locked
+ # skip the crap
+ if (/^(##+$|Building configuration...)/i) {
+ while (<INPUT>) {
+ next if (/^Current configuration:/i);
+ next if (/^([%!].*|\s*)$/);
+ next if (/^ip add.*ipv4:/); # band-aid for 3620 12.0S
+ last;
+ }
+ ProcessHistory("","","","!\nconfig-register $config_register\n");
+ tr/\015//d;
+ }
+ # some versions have other crap mixed in with the bits in the
+ # block above
+ /^! (Last configuration|NVRAM config last)/ && next;
+
+ # Dog gone Cool matches to process the rest of the config
+ /^tftp-server flash / && next; # kill any tftp remains
+ /^ntp clock-period / && next; # kill ntp clock-period
+ /^ length / && next; # kill length on serial lines
+ /^ width / && next; # kill width on serial lines
+ /^enable password / &&
+ ProcessHistory("ENABLE","","","!enable password <removed>\n") &&
+ next;
+ /^(username .*) password \d *(\S)\s*(.*)/ &&
+ ProcessHistory("USER","","","!$1 password <removed>\n") && next;
+ /^\s*password / &&
+ ProcessHistory("LINE-PASS","","","! password <removed>\n") && next;
+ /^\s*neighbor (\S*) password / &&
+ ProcessHistory("","","","! neighbor $1 password <removed>\n") &&
+ next;
+ /fair-queue individual-limit/ && next;
+ # sort route-maps
+ if (/^route-map ([^ ]+)/) {
+ my($key) = $1;
+ my($routemap) = $_;
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/ || ! /^(route-map |[ !])/);
+ if (/^route-map ([^ ]+)/) {
+ ProcessHistory("ROUTEMAP","keysort","$key","$routemap");
+ $key = $1;
+ $routemap = $_;
+ } else {
+ $routemap .= $_;
+ }
+ }
+ ProcessHistory("ROUTEMAP","keysort","$key","$routemap");
+ }
+ # filter out any RCS/CVS tags to avoid confusing local CVS storage
+ s/\$(Revision|Id):/ $1:/;
+ # order access-lists
+ /^access-list\s+(\d\d?)\s+(\S+)\s+(\S+)/ &&
+ ProcessHistory("ACL $1 $2","ipsort","$3","$_") && next;
+ # order extended access-lists
+ /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+host\s+(\S+)/ &&
+ ProcessHistory("EACL $1 $2","ipsort","$3","$_") && next;
+ /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+(\d\S+)/ &&
+ ProcessHistory("EACL $1 $2","ipsort","$3","$_") && next;
+ /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+any/ &&
+ ProcessHistory("EACL $1 $2","ipsort","0.0.0.0","$_") && next;
+ # order arp lists
+ /^arp\s+(\d+\.\d+\.\d+\.\d+)\s+/ &&
+ ProcessHistory("ARP","ipsort","$1","$_") && next;
+ /^ip prefix-list\s+(\S+)\s+seq\s+(\d+)\s+(permit|deny)\s+(\d\S+)(\/.*)$/ &&
+ ProcessHistory("PACL $1 $3","ipsort","$4","ip prefix-list $1 $3 $4$5\n")
+ && next;
+ # order logging statements
+ /^logging (\d+\.\d+\.\d+\.\d+)/ &&
+ ProcessHistory("LOGGING","ipsort","$1","$_") && next;
+ # order name-server statements
+ /^ip name-server (\d+\.\d+\.\d+\.\d+)/ &&
+ ProcessHistory("NAMESERVER","ipsort","$1","$_") && next;
+ # order snmp-server host statements
+ /^snmp-server host (\d+\.\d+\.\d+\.\d+)/ &&
+ ProcessHistory("SNMPSERVERHOST","ipsort","$1","$_") && next;
+ /^snmp-server community / &&
+ ProcessHistory("SNMPSERVERCOMM","keysort","$_","$_") && next;
+ # order tacacs server statements
+ /^(tacacs-server key )/ &&
+ ProcessHistory("","","","!$1<removed>\n") && next;
+ /^tacacs-server host (\d+\.\d+\.\d+\.\d+)/ &&
+ ProcessHistory("TAC","ipsort","$1","$_") && next;
+ # order clns host statements
+ /^clns host \S+ (\S+)/ &&
+ ProcessHistory("CLNS","keysort","$1","$_") && next;
+ # order alias statements
+ /^alias / && ProcessHistory("ALIAS","keysort","$_","$_") && next;
+ # delete ntp auth password
+ /^(ntp authentication-key \d+ md5) / &&
+ ProcessHistory("","","","!$1 <removed>\n") && next;
+ # order ntp peers/servers
+ if (/^ntp (server|peer) (\d+)\.(\d+)\.(\d+)\.(\d+)/) {
+ $sortkey = sprintf("$1 %03d%03d%03d%03d",$2,$3,$4,$5);
+ ProcessHistory("NTP","keysort",$sortkey,"$_");
+ next;
+ }
+ # order ip host line statements
+ /^ip host line(\d+)/ &&
+ ProcessHistory("IPHOST","numsort","$1","$_") && next;
+ # order ip nat source static statements
+ /^ip nat (\S+) source static (\S+)/ &&
+ ProcessHistory("IP NAT $1","ipsort","$2","$_") && next;
+ # order atm map-list statements
+ /^\s+ip\s+(\d+\.\d+\.\d+\.\d+)\s+atm-vc/ &&
+ ProcessHistory("ATM map-list","ipsort","$1","$_") && next;
+ # order ip rcmd lines
+ /^ip rcmd/ && ProcessHistory("RCMD","keysort","$_","$_") && next;
+
+ ProcessHistory("","","","$_");
+ # end of config
+ if (/^end$/) {
+ $found_end = 1;
+ return(1);
}
- ProcessHistory("","","","!\nconfig-register $config_register\n");
- tr/\015//d;
- }
- # Dog gone Cool matches to process the rest of the config
- /^tftp-server flash / && return; # kill and tftp remains
- /^ntp clock-period / && return; # kill ntp clock-period
- /^ length / && return; # kill length on serial lines
- /^ width / && return; # kill width on serial lines
- /^enable password / &&
- ProcessHistory("ENABLE","","","!enable password <removed>\n") &&
- return;
- /^(username .*) password \d *(\S)\s*(.*)/ &&
- ProcessHistory("USER","","","$1 password <removed>\n") &&
- return;
- /^\s*password / &&
- ProcessHistory("LINE-PASS","","","! password <removed>\n") &&
- return;
- /^\s*neighbor (\S*) password / &&
- ProcessHistory("","","","! neighbor $1 password <removed>\n") &&
- return;
- /fair-queue individual-limit/ && return;
- # filter out any RCS/CVS tags to avoid confusing local CVS storage
- s/\$(Revision|Id):/ $1:/;
- # order access-lists
- /^access-list\s+(\d\d?)\s+(\S+)\s+(\S+)/ &&
- ProcessHistory("ACL $1 $2","ipsort","$3","$_") && return;
- # order extended access-lists
- /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+host\s+(\S+)/ &&
- ProcessHistory("EACL $1 $2","ipsort","$3","$_") && return;
- /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+(\d\S+)/ &&
- ProcessHistory("EACL $1 $2","ipsort","$3","$_") && return;
- /^access-list\s+(\d\d\d)\s+(\S+)\s+ip\s+any/ &&
- ProcessHistory("EACL $1 $2","ipsort","0.0.0.0","$_") && return;
- /^ip prefix-list\s+(\S+)\s+seq\s+(\d+)\s+(permit|deny)\s+(\d\S+)(\/.*)$/ &&
- ProcessHistory("PACL $1 $3","ipsort","$4","ip prefix-list $1 $3 $4$5\n")
- && return;
- # order logging statements
- /^logging (\d+\.\d+\.\d+\.\d+)/ &&
- ProcessHistory("LOGGING","ipsort","$1","$_") && return;
- # order name-server statements
- /^ip name-server (\d+\.\d+\.\d+\.\d+)/ &&
- ProcessHistory("NAMESERVER","ipsort","$1","$_") && return;
- # order snmp-server host statements
- /^snmp-server host (\d+\.\d+\.\d+\.\d+)/ &&
- ProcessHistory("SNMPSERVERHOST","ipsort","$1","$_") && return;
- /^snmp-server community / &&
- ProcessHistory("SNMPSERVERCOMM","keysort","$_","$_") && return;
- # order tacacs server statements
- /^tacacs-server host (\d+\.\d+\.\d+\.\d+)/ &&
- ProcessHistory("TAC","ipsort","$1","$_") && return;
- # order clns host statements
- /^clns host \S+ (\S+)/ && ProcessHistory("CLNS","keysort","$1","$_") && return;
- # order alias statements
- /^alias / && ProcessHistory("ALIAS","keysort","$_","$_") && return;
- # delete ntp auth password
- /^(ntp authentication-key \d+ md5) / &&
- ProcessHistory("","","","!$1 <removed>\n") && return;
- # order ntp peers/servers
- if (/^ntp (server|peer) (\d+)\.(\d+)\.(\d+)\.(\d+)/) {
- $sortkey = sprintf("$1 %03d%03d%03d%03d",$2,$3,$4,$5);
- ProcessHistory("NTP","keysort",$sortkey,"$_");
- return;
- }
- # order ip host line statements
- /^ip host line(\d+)/ &&
- ProcessHistory("IPHOST","numsort","$1","$_") && return;
- # order ip nat source static statements
- /^ip nat (\S+) source static (\S+)/ &&
- ProcessHistory("IP NAT $1","ipsort","$2","$_") && return;
- # order atm map-list statements
- /^\s+ip\s+(\d+\.\d+\.\d+\.\d+)\s+atm-vc/ &&
- ProcessHistory("ATM map-list","ipsort","$1","$_") && return;
- # order ip rcmd lines
- /^ip rcmd/ && ProcessHistory("RCMD","keysort","$_","$_") && return;
- ProcessHistory("","","","$_");
- # end of config
- if (/^end$/) {
- $found_end = 1;
- return "FlailHelplessly";
}
- return;
+ return(0);
}
# dummy function
sub DoNothing {print STDOUT;}
-# Main subroutine that splits up the work
-# All Subs return the name of the next function to use.
-# If the sub returns a new funtion name, that name will be used
-# else the main loop keeps using the current function
-sub FlailHelplessly {
- print STDERR "Flailing: $_" if ($debug);
- print STDOUT "Flailing: $_" if ($log);
- /#(show version)$/ && delete($commands{$1}) && return("ShowVersion");
- /#(show env all)$/ && delete($commands{$1}) && return("ShowEnv");
- /#(show gsr chassis)$/ && delete($commands{$1}) && return("ShowGSR");
- /#(show boot.*)$/ && delete($commands{$1}) && return("ShowBoot");
- /#(show flash)$/ && delete($commands{$1}) &&
- (ProcessHistory("FLASH","","","!\n"),return("ShowFlash"));
- /#(dir \/all bootflash\:)$/ && delete($commands{$1}) &&
- (ProcessHistory("FLASH","","","!\n"), return("DirBootflash"));
- /#(dir \/all slot0\:)$/ && delete($commands{$1}) &&
- (ProcessHistory("FLASH","","","!\n"),return("DirSlot0"));
- /#(dir \/all slot1\:)$/ && delete($commands{$1}) &&
- (ProcessHistory("FLASH","","","!\n"),return("DirSlot1"));
- # These three generate a list of the hw.
- # There are a few variable created in ShowContCbus
- # That are printed out in ShowDiagbus.
- /#(show controllers cbus)$/ && delete($commands{$1}) && return("ShowContCbus");
- /#(show controllers)$/ && delete($commands{$1}) && return("ShowContAll");
- /#(show diagbus)$/ && delete($commands{$1}) && return("ShowDiagbus");
- /#(show diag)$/ && delete($commands{$1}) && return("ShowDiags");
- /#(show c7200)$/ && delete($commands{$1}) && return("ShowC7200");
- /#(write term)$/ && delete($commands{$1}) && return("WriteTerm");
- return "FlailHelplessly";
-}
-
# Main
-@commands=("show version","show env all","show gsr chassis",
- "show boot","show bootvar","show flash","dir /all bootflash:",
- "dir /all slot0:", "dir /all slot1:","show controllers",
- "show controllers cbus", "show diagbus","show diag","show c7200",
- "write term");
-
-foreach $c (@commands) { $commands{$c} = 1; }
+%commands=(
+ 'show version' => "ShowVersion",
+ 'show env all' => "ShowEnv",
+ 'show gsr chassis' => "ShowGSR",
+ 'show boot' => "ShowBoot",
+ 'show bootvar' => "ShowBoot",
+ 'show flash' => "ShowFlash",
+ 'dir /all bootflash:' => "DirSlotN",
+ 'dir /all slot0:' => "DirSlotN",
+ 'dir /all disk0:' => "DirSlotN",
+ 'dir /all slot1:' => "DirSlotN",
+ 'dir /all disk1:' => "DirSlotN",
+ 'show controllers' => "ShowContAll",
+ 'show controllers cbus' => "ShowContCbus",
+ 'show diagbus' => "ShowDiagbus",
+ 'show diag' => "ShowDiags",
+ 'show c7200' => "ShowC7200",
+ 'write term' => "WriteTerm"
+);
+# keys() doesnt return things in the order entered and the order of the
+# cmds is important (show version first and write term last). pita
+@commands=(
+ "show version",
+ "show env all",
+ "show gsr chassis",
+ "show boot",
+ "show bootvar",
+ "show flash",
+ "dir /all bootflash:",
+ "dir /all slot0:",
+ "dir /all disk0:",
+ "dir /all slot1:",
+ "dir /all disk1:",
+ "show controllers",
+ "show controllers cbus",
+ "show diagbus",
+ "show diag",
+ "show c7200",
+ "write term"
+);
$cisco_cmds=join(";",@commands);
$cmds_regexp=join("|",@commands);
-$func = FlailHelplessly;
open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n";
-# make OUTPUT unbuffered
-select(OUTPUT); $| = 1;
+select(OUTPUT);
+# make OUTPUT unbuffered if debugging
+if ($debug) { $| = 1; }
if ($file) {
print STDERR "opening file $host\n" if ($debug);
@@ -746,9 +857,12 @@ if ($file) {
} else {
print STDERR "executing clogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($debug);
print STDOUT "executing clogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($log);
- open(INPUT,"clogin -t $timeo -c\"$cisco_cmds\" $host </dev/null |") ||
- die "clogin failed for $host: $!\n";
-# open(INPUT,"-|") || exec("clogin","-c\"$cisco_cmds\"",$host);
+ if (defined($ENV{NOPIPE})) {
+ system "clogin -t $timeo -c \"$cisco_cmds\" $host </dev/null > $host.raw 2>&1" || die "clogin failed for $host: $!\n";
+ open(INPUT, "< $host.raw") || die "clogin failed for $host: $!\n";
+ } else {
+ open(INPUT,"clogin -t $timeo -c \"$cisco_cmds\" $host </dev/null |") || die "clogin failed for $host: $!\n";
+ }
}
ProcessHistory("COMMENTS","keysort","B0","!\n");
@@ -760,22 +874,28 @@ while(<INPUT>) {
$clean_run=1;
last;
}
- if (/^Error:/) {
+ if (/Error:/) {
+ s/^.*Error:/Error:/;
print STDOUT ("$host clogin error: $_");
print STDERR ("$host clogin error: $_") if ($debug);
$clean_run=0;
last;
}
- if (/#\s*($cmds_regexp)/) {
- $func = FlailHelplessly;
+ while (/#\s*($cmds_regexp)\s*$/) {
+ $cmd = $1;
+ if (!defined($prompt)) {$prompt = ($_ =~ /^([^#]+#)/)[0]; }
print STDERR ("HIT COMMAND:$_") if ($debug);
- } else {
- $rval=eval $func;
+ if (! defined($commands{$cmd})) {
+ print STDERR "found unexpected command - \"$cmd\"\n";
+ $clean_run = 0;
+ last;
+ }
+ $rval = &{$commands{$cmd}};
+ delete($commands{$cmd});
if ($rval == -1) {
$clean_run = 0;
last;
- }
- $func=$rval if ($rval);
+ }
}
}
print STDOUT "Done $logincmd: $_\n" if ($log);
@@ -785,16 +905,20 @@ ProcessHistory("","","","");
close(INPUT);
close(OUTPUT);
+if (defined($ENV{NOPIPE})) {
+ unlink("$host.raw") if (! $debug);
+}
+
# check for completeness
if (scalar(%commands) || !$clean_run || !$found_end) {
if (scalar(%commands)) {
- print STDOUT "missed cmd(s): $commands\n";
- print STDERR "missed cmd(s): $commands[0]\n" if ($debug);
+ printf(STDOUT "missed cmd(s): %s\n", join(',', keys(%commands)));
+ printf(STDERR "missed cmd(s): %s\n", join(',', keys(%commands))) if ($debug);
}
if (!$clean_run || !$found_end) {
- print STDOUT "End of run not found - removing $host.new\n";
- print STDERR "End of run not found - removing $host.new\n" if ($debug);
+ print STDOUT "End of run not found\n";
+ print STDERR "End of run not found\n" if ($debug);
system("/usr/bin/tail -1 $host.new");
}
- unlink "$host.new";
+ unlink "$host.new" if (! $debug);
}
diff --git a/bin/rancid-fe b/bin/rancid-fe
index e3dc94e..8dab8a5 100755
--- a/bin/rancid-fe
+++ b/bin/rancid-fe
@@ -21,12 +21,18 @@
# usage: rancid-fe <router>:<vendor>
#
+require 5;
+
($router, $vendor) = split('\:', $ARGV[0]);
if ($vendor =~ /^cisco$/i) {
exec('rancid', $router);
} elsif ($vendor =~ /^juniper$/i) {
exec('jrancid', $router);
+} elsif ($vendor =~ /^foundry$/i) {
+ exec('francid', $router);
+} elsif ($vendor =~ /^redback$/i) {
+ exec('rrancid', $router);
}
printf(STDERR "unknown router manufacturer for $router: $vendor\n");
diff --git a/bin/rrancid b/bin/rrancid
new file mode 100755
index 0000000..40113aa
--- /dev/null
+++ b/bin/rrancid
@@ -0,0 +1,347 @@
+#!/usr/local/bin/perl
+##
+## hacked version of Hank's rancid - this one tries to deal with redbacks.
+##
+## Copyright (C) 1997 by Henry Kilmer.
+## All rights reserved.
+##
+## This software may be freely copied, modified and redistributed without
+## fee for non-commerical purposes provided that this copyright notice is
+## preserved intact on all copies and modified copies.
+##
+## There is no warranty or other guarantee of fitness of this software.
+## It is provided solely "as is". The author(s) disclaim(s) all
+## responsibility and liability with respect to this software's usage
+## or its effect upon hardware, computer systems, other software, or
+## anything else.
+##
+##
+#
+# RANCID - Really Awesome New Cisco confIg Differ
+#
+# usage: rancid [-d] [-l] [-f filename | $host]
+#
+use Getopt::Std;
+getopts('dflm');
+$log = $opt_l;
+$debug = $opt_d;
+$file = $opt_f;
+$host = $ARGV[0];
+$clean_run = 0;
+$found_end = 0;
+$timeo = 90; # clogin timeout in seconds
+
+# This routine is used to print out the router configuration
+sub ProcessHistory {
+ my($new_hist_tag,$new_command,$command_string,@string)=(@_);
+ if((($new_hist_tag ne $hist_tag) || ($new_command ne $command))
+ && defined %history) {
+ print eval "$command \%history";
+ undef %history;
+ }
+ if (($new_hist_tag) && ($new_command) && ($command_string)) {
+ if ($history{$command_string}) {
+ $history{$command_string} = "$history{$command_string}@string";
+ } else {
+ $history{$command_string} = "@string";
+ }
+ } elsif (($new_hist_tag) && ($new_command)) {
+ $history{++$#history} = "@string";
+ } else {
+ print "@string";
+ }
+ $hist_tag = $new_hist_tag;
+ $command = $new_command;
+ 1;
+}
+
+sub numerically { $a <=> $b; }
+
+# This is a sort routing that will sort numerically on the
+# keys of a hash as if it were a normal array.
+sub keynsort {
+ local(%lines)=@_;
+ local($i) = 0;
+ local(@sorted_lines);
+ foreach $key (sort numerically keys(%lines)) {
+ $sorted_lines[$i] = $lines{$key};
+ $i++;
+ }
+ @sorted_lines;
+}
+
+# This is a sort routing that will sort on the
+# keys of a hash as if it were a normal array.
+sub keysort {
+ local(%lines)=@_;
+ local($i) = 0;
+ local(@sorted_lines);
+ foreach $key (sort keys(%lines)) {
+ $sorted_lines[$i] = $lines{$key};
+ $i++;
+ }
+ @sorted_lines;
+}
+
+# This is a sort routing that will sort on the
+# values of a hash as if it were a normal array.
+sub valsort{
+ local(%lines)=@_;
+ local($i) = 0;
+ local(@sorted_lines);
+ foreach $key (sort values %lines) {
+ $sorted_lines[$i] = $key;
+ $i++;
+ }
+ @sorted_lines;
+}
+
+# This is a numerical sort routing (ascending).
+sub numsort {
+ local(%lines)=@_;
+ local($i) = 0;
+ local(@sorted_lines);
+ foreach $num (sort {$a <=> $b} keys %lines) {
+ $sorted_lines[$i] = $lines{$num};
+ $i++;
+ }
+ @sorted_lines;
+}
+
+# This is a sort routine that will sort on the
+# ip address when the ip address is anywhere in
+# the strings.
+sub ipsort {
+ local(%lines)=@_;
+ local($i) = 0;
+ local(@sorted_lines);
+ foreach $addr (sort sortbyipaddr keys %lines) {
+ $sorted_lines[$i] = $lines{$addr};
+ $i++;
+ }
+ @sorted_lines;
+}
+
+# These two routines will sort based upon IP addresses
+sub ipaddrval {
+ my(@a) = ($_[0] =~ m#^(\d+)\.(\d+)\.(\d+)\.(\d+)$#);
+ $a[3]+256*($a[2]+256*($a[1]+256*$a[0]));
+}
+sub sortbyipaddr {
+ &ipaddrval($a) <=> &ipaddrval($b);
+}
+
+# This routine parses "dir /<fsys>"
+sub DirFlash {
+ print STDERR " In DirFlash: $_" if ($debug);
+
+ my($dev) = (/\/(.*)$/);
+ while (<INPUT>) {
+ tr/\015//d;
+ last if(/^$prompt/);
+ /^\s*$/ && next;
+
+ /(Can\'t open|No such device)/ && return;
+ ProcessHistory("FLASH","keysort",$dev,"!Flash: $dev: $_");
+ }
+ ProcessHistory("FLASH","keysort",$dev,"!\n");
+ return;
+}
+
+# This routine parses "show hardware"
+sub ShowHardware {
+ print STDERR " In ShowHardware: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if(/^$prompt/);
+ s/\s*$/\n/;
+
+ #ProcessHistory("","","","!Chassis: $_") && next;
+ ProcessHistory("COMMENTS","keysort","B1","!Chassis: $_");
+ }
+ ProcessHistory("COMMENTS","keysort","B1","!\n");
+ return;
+}
+
+# This routine parses "show version"
+sub ShowVersion {
+ print STDERR " In ShowVersion: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if(/^$prompt/);
+
+ /(uptime|restarted|^\s*$)/ && next;
+ ProcessHistory("COMMENTS","keysort","A1","!Image: $_");
+ }
+ return;
+}
+
+# This routine parses "show slot table"
+sub ShowSlotTable {
+ print STDERR " In ShowSlotTable: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if(/^$prompt/);
+
+ /(Slot Table|^$)/ && next;
+ s/^\s*//;
+ ProcessHistory("COMMENTS","keysort","D1","!Slot Table: $_");
+ }
+ ProcessHistory("COMMENTS","keysort","D1","!\n");
+ return;
+}
+
+# This routine processes a "write term"
+sub WriteTerm {
+ print STDERR " In WriteTerm: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if(/^$prompt/);
+
+# /Non-Volatile memory is in use/ && return(-1); # NvRAM is locked
+ # Dog gone Cool matches to process the rest of the config
+ /^! last updated: .*$/ && next; # kill last updated line
+ /^ length / && next; # kill length on serial lines
+ /^ width / && next; # kill width on serial lines
+ # filter out any RCS/CVS tags to avoid confusing local CVS storage
+ s/\$(Revision|Id):/ $1:/;
+ # order access-lists
+ /^access-list\s+(\d\d?)\s+(\S+)\s+(\S+)/ &&
+ ProcessHistory("ACL $1 $2","ipsort","$3","$_") && next;
+ ProcessHistory("","","","$_");
+ # end of config
+ if (/^end$/) {
+ $found_end = 1;
+ last;
+ }
+ }
+ return;
+}
+
+# dummy function
+sub DoNothing {print STDOUT;}
+
+# Main subroutine that splits up the work
+# All Subs return the name of the next function to use.
+# If the sub returns a new funtion name, that name will be used
+# else the main loop keeps using the current function
+sub FlailHelplessly {
+ print STDERR "Flailing: $_" if ($debug);
+ print STDOUT "Flailing: $_" if ($log);
+ /#(show hardware)$/ && delete($commands{$1}) && return("ShowHardware");
+ /#(show version)$/ && delete($commands{$1}) && return("ShowVersion");
+ /#(show slot table)$/ && delete($commands{$1}) && return("ShowSlotTable");
+ /#(show config)$/ && delete($commands{$1}) && return("WriteTerm");
+ return "FlailHelplessly";
+}
+
+# Main
+%commands=(
+ 'show version' => "ShowVersion",
+ "dir /flash" => "DirFlash",
+ "dir /pcmcia0" => "DirFlash",
+ "dir /pcmcia1" => "DirFlash",
+ 'show hardware' => "ShowHardware",
+ 'show slot table' => "ShowSlotTable",
+ 'show config' => "WriteTerm"
+);
+@commands=(
+ "show version",
+ "dir /flash",
+ "dir /pcmcia0",
+ "dir /pcmcia1",
+ "show hardware",
+ "show slot table",
+ "show config"
+);
+# dir /flash
+# dir /pcmcia0
+# dir /pcmcia1
+
+$redback_cmds=join(";",@commands);
+$cmds_regexp=join("|",@commands);
+
+open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n";
+select(OUTPUT);
+# make OUTPUT unbuffered
+if ($debug) { $| = 1; }
+
+if ($file) {
+ print STDERR "opening file $host\n" if ($debug);
+ print STDOUT "opening file $host\n" if ($log);
+ open(INPUT,"<$host") || die "open failed for $host: $!\n";
+} else {
+ print STDERR "executing clogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($debug);
+ print STDOUT "executing clogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($log);
+
+ if (defined($ENV{NOPIPE})) {
+ system "clogin -t $timeo -c \"$redback_cmds\" $host </dev/null > $host.raw" || die "clogin failed for $host: $!\n";
+ open(INPUT, "< $host.raw") || die "clogin failed for $host: $!\n";
+ } else {
+ open(INPUT,"clogin -t $timeo -c \"$redback_cmds\" $host </dev/null |") || die "clogin failed for $host: $!\n";
+ }
+}
+
+ProcessHistory("COMMENTS","keysort","B0","!\n");
+ProcessHistory("COMMENTS","keysort","C0","!\n");
+ProcessHistory("COMMENTS","keysort","E0","!\n");
+while(<INPUT>) {
+ tr/\015//d;
+ if (/\#exit$/) {
+ $clean_run=1;
+ last;
+ }
+ if (/^Error:/) {
+ print STDOUT ("$host clogin error: $_");
+ print STDERR ("$host clogin error: $_") if ($debug);
+ $clean_run=0;
+ last;
+ }
+ while (/#\s*($cmds_regexp)\s*$/) {
+ $cmd = $1;
+ if (!defined($prompt)) {
+ $prompt = ($_ =~ /^([^#]*#)/)[0];
+ $prompt =~ s/([][])/\\$1/g; # quote the damn []'s
+ }
+ print STDERR ("HIT COMMAND:$_") if ($debug);
+ if (! defined($commands{$cmd})) {
+ print STDERR "found unexpected command - \"$cmd\"\n";
+ $clean_run = 0;
+ last;
+ }
+ $rval = &{$commands{$cmd}};
+ delete($commands{$cmd});
+ if ($rval == -1) {
+ $clean_run = 0;
+ last;
+ }
+ }
+}
+print STDOUT "Done $logincmd: $_\n" if ($log);
+# Flush History
+ProcessHistory("","","","");
+# Cleanup
+close(INPUT);
+close(OUTPUT);
+
+if (defined($ENV{NOPIPE})) {
+ unlink("$host.raw") if (! $debug);
+}
+
+# check for completeness
+if (scalar(%commands) || !$clean_run || !$found_end) {
+ if (scalar(%commands)) {
+ printf(STDOUT "missed cmd(s): %s\n", join(',', keys(%commands)));
+ printf(STDERR "missed cmd(s): %s\n", join(',', keys(%commands))) if ($debug);
+ }
+ if (!$clean_run || !$found_end) {
+ print STDOUT "End of run not found\n";
+ print STDERR "End of run not found\n" if ($debug);
+ system("/usr/bin/tail -1 $host.new");
+ }
+ unlink "$host.new" if (! $debug);
+}
diff --git a/bin/run-me b/bin/run-me
deleted file mode 100755
index b17d850..0000000
--- a/bin/run-me
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/bin/sh
-
-ENVFILE="`dirname $0`/env"
-
-. $ENVFILE
-
-if [ $# -lt 1 ]; then
- DOME="$LIST_OF_GROUPS"
-else
- DOME="$*"
-fi
-
-for GROUP in $DOME
-do
-
- LOCKFILE=/tmp/.$GROUP.run.lock
-
- (
- echo starting: `date`
- echo
-
- if [ -f $LOCKFILE ]
- then
- echo hourly cisco diffs failed: $LOCKFILE exists
- /bin/ls -l $LOCKFILE
- else
- /usr/bin/touch $LOCKFILE
- control_rancid $GROUP
- /bin/rm -f $LOCKFILE
- fi
-
- echo
- echo ending: `date`
- ) >$BASEDIR/logs/$GROUP.`date +%Y%m%d.%H%M%S` 2>&1
-done