summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTar Committer <tar@ocjtech.us>2002-05-02 23:08:06 +0000
committerTar Committer <tar@ocjtech.us>2002-05-02 23:08:06 +0000
commitafcac75e572bcdd3cf269b921b7e8324aa5ffd4c (patch)
treedfffbfceb4f15c22781a599d6352586c8b7ce582
parent9f2402b0d86333f5f7e9d50437036cd3124bde47 (diff)
downloadrancid-afcac75e572bcdd3cf269b921b7e8324aa5ffd4c.tar.gz
rancid-afcac75e572bcdd3cf269b921b7e8324aa5ffd4c.tar.xz
rancid-afcac75e572bcdd3cf269b921b7e8324aa5ffd4c.zip
Imported from rancid-2.2.1.tar.gz.rancid-2.2.1
-rw-r--r--CHANGES45
-rw-r--r--README3
-rw-r--r--Todo8
-rw-r--r--bin/Makefile.in14
-rw-r--r--bin/alogin.in23
-rw-r--r--bin/blogin.in12
-rwxr-xr-xbin/clogin.in12
-rwxr-xr-xbin/control_rancid.in49
-rwxr-xr-xbin/do-diffs.in27
-rwxr-xr-xbin/elogin.in8
-rwxr-xr-xbin/f10rancid.in1255
-rwxr-xr-xbin/flogin.in12
-rwxr-xr-xbin/hlogin.in18
-rw-r--r--bin/hpfilter.c2
-rwxr-xr-xbin/jlogin.in12
-rwxr-xr-xbin/rancid-fe.in1
-rwxr-xr-xbin/rancid.in102
-rwxr-xr-xbin/xrancid.in2
-rwxr-xr-xconfigure10
-rw-r--r--configure.in6
-rw-r--r--include/config.h2
-rw-r--r--include/version.h2
-rw-r--r--include/version.h.in2
-rw-r--r--man/Makefile.am6
-rw-r--r--man/Makefile.in2
-rw-r--r--man/control_rancid.118
-rw-r--r--man/do-diffs.115
-rw-r--r--man/f10rancid.11
-rw-r--r--man/rancid.12
-rw-r--r--man/rancid_intro.14
-rw-r--r--man/router.db.57
-rwxr-xr-xutil/lg/lg.cgi.in5
32 files changed, 1547 insertions, 140 deletions
diff --git a/CHANGES b/CHANGES
index b11996e..c2f9c1d 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,48 @@
+2.2.1
+ rancid: npe400 cpu eeprom info o/p format changed in 12.0.21S1 -
+ spotted by tom campbell
+
+ fix problem in *login where if there was a login failure we would try
+ to disconnect gracefully (albeit incorrectly). writing to the
+ half-closed socket would not return an error (at least on some
+ platform/expect combinations or even consistently) and expect would
+ hang.
+
+ add device name to diff mail subject when -r is specified
+
+ add -m <mail rcpt> option to do-diffs and control_rancid to allow
+ specific mail recipient. intended for use with -r to trigger diffs
+ off specific events.
+
+ router.db(5): note that PIX is a 'cisco' - thank kris gulka
+
+ *login: match openssh prompt for host key to ip key mismatch
+
+ rancid: add disk/slot2
+
+ rancid: 12.2 show c7200 o/p for midplane changed
+
+ lg: use table inet.0 terse for sh ip route on juniper instead of
+ forwarding-table destination
+
+ rancid: 12.0S(21) added "FRU" field in show diagbus output.
+ Also look for a couple more things in some show diag output
+ and sort the output a bit better. Also look for 'controler'
+ (cisco can't always spell - thanks to Terry Kennedy for
+ spotting the misspelling).
+
+ lg: filter ["`'] from args
+
+ rancid: fix username secret filtering
+
+ alogin: misplaced brace caused improper return from proc login
+
+ relax the check ping and traceroute check of hostname arguments such
+ that non-fqdn hosts are allowed. ie: just check that arg chars are
+ valid dns chars and leave the resolve errors to the router.
+
+ Add initial support for Force10.
+
2.2
rancid: filter vpdn passwords on PIX - from eric greenwood
diff --git a/README b/README
index ab8684f..cce631c 100644
--- a/README
+++ b/README
@@ -16,6 +16,7 @@ rancid-fe.in chooses between rancid/[abefhjrx]rancid/cat5rancid.
rancid.in Runs commands on cisco routers and processes the output.
brancid.in Runs commands on baynet/nortel routers and processes the output.
erancid.in Runs commands on ADC EZ-T3 muxes and processes the output.
+f10rancid.in Runs commands on Force10 routers and processes the output.
francid.in Runs commands on foundry switches and processes the output.
hrancid.in Runs commands on hp procurve switches and processes the output.
jrancid.in Runs commands on juniper routers and processes the output.
@@ -137,7 +138,7 @@ Quick Installation Guide (an example):
The file is of the form "router:mfg:state" where "router" is
the name (we use FQDN) of the router, mfg is the manufacturer
from the set of
- (alteon|baynet|cat5|cisco|extreme|ezt3|foundry|hp|juniper|redback),
+ (alteon|baynet|cat5|cisco|extreme|ezt3|force10|foundry|hp|juniper|redback),
and "state" is either up or down. Each router listed as "up"
will have the configuration grabbed. Note: manufacturer cat5
is intended only for cisco catalyst switches running catalyst (not
diff --git a/Todo b/Todo
index ed1fbcf..fd04b48 100644
--- a/Todo
+++ b/Todo
@@ -1,7 +1,15 @@
+- extreme v6.2.x need 'show configuration detail' to get full config but
+ does not work on older vers
+- hlogin (hp procurve) needs to adjust it's PATH to find hpfilter
+- hlogin hangs when the procurve is does not ask for passwords
+- util/ tool to prune cvs versions, excluding those with tags, by (all but
+ latest | keep N versions | keep N days/months/years)
- extreme collections lose when the config on the switch is in an unsaved
state, probably due to the prompt changing or rather how clogin formulates
the prompt used by expect{ -re }'s.
- extreme collection fails for tacacs-enabled boxen due to diffs in UI - blech!
+- FILTER_PWDS knob is not implemented in alteon, bay, ezt3 or redback due to
+ lack of h/w to test against. need help from the community.
- should par's -c override an input files' : cmd?
- *login should emmit "clogin error:" or "*login error:" to make matches for
login failures definitive?
diff --git a/bin/Makefile.in b/bin/Makefile.in
index 77c15a6..74652a3 100644
--- a/bin/Makefile.in
+++ b/bin/Makefile.in
@@ -122,9 +122,9 @@ BIN_DATAS = @RD_BIN_DATAS@
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = ../include/config.h
CONFIG_CLEAN_FILES = alogin arancid blogin brancid cat5rancid clogin \
-control_rancid create_cvs do-diffs elogin env erancid flogin francid \
-jlogin jrancid hlogin hrancid mrancid par rancid-fe rancid rename \
-rrancid xrancid
+control_rancid create_cvs do-diffs elogin env erancid f10rancid flogin \
+francid jlogin jrancid hlogin hrancid mrancid par rancid-fe rancid \
+rename rrancid xrancid
PROGRAMS = $(bin_PROGRAMS)
@@ -141,9 +141,9 @@ CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
DIST_COMMON = Makefile.am Makefile.in alogin.in arancid.in blogin.in \
brancid.in cat5rancid.in clogin.in control_rancid.in create_cvs.in \
-do-diffs.in elogin.in env.in erancid.in flogin.in francid.in hlogin.in \
-hrancid.in jlogin.in jrancid.in mrancid.in par.in rancid-fe.in \
-rancid.in rename.in rrancid.in xrancid.in
+do-diffs.in elogin.in env.in erancid.in f10rancid.in flogin.in \
+francid.in hlogin.in hrancid.in jlogin.in jrancid.in mrancid.in par.in \
+rancid-fe.in rancid.in rename.in rrancid.in xrancid.in
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
@@ -186,6 +186,8 @@ env: $(top_builddir)/config.status env.in
cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
erancid: $(top_builddir)/config.status erancid.in
cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+f10rancid: $(top_builddir)/config.status f10rancid.in
+ cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
flogin: $(top_builddir)/config.status flogin.in
cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
francid: $(top_builddir)/config.status francid.in
diff --git a/bin/alogin.in b/bin/alogin.in
index 9ffb9e8..dc5afaa 100644
--- a/bin/alogin.in
+++ b/bin/alogin.in
@@ -331,6 +331,19 @@ proc login { router user userpswd passwd prompt cmethod cyphertype } {
expect eof
send_user "Error: Unknown host\n"; wait; return 1
}
+ -re "(Host key not found |The authenticity of host .* be established).*\(yes\/no\)\?" {
+ send "yes\r"
+ send_user "\nHost $router added to the list of known hosts.\n"
+ exp_continue }
+ -re "HOST IDENTIFICATION HAS CHANGED.* \(yes\/no\)\?" {
+ send "no\r"
+ send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n"
+ return 1 }
+ -re "Offending key for .* \(yes\/no\)\?" {
+ send "no\r"
+ send_user "\nError: host key mismatch for $router. Update the SSH known_hosts file accordingly.\n"
+ return 1 }
+
-re "$u_prompt" {
send "$user\r"
set uprompt_seen 1
@@ -353,20 +366,14 @@ proc login { router user userpswd passwd prompt cmethod cyphertype } {
catch {close}; wait; return 1 }
-re "$prompt" { break; }
denied { send_user "Error: Check your passwd for $router\n"
- if { $do_command || $do_script } {
- send "exit\r"
- wait
- return 1
- } else {
- return 1
- }
+ catch {close}; wait; return 1
}
"\r\n" { exp_continue; }
}
+ }
set in_proc 0
return 0
}
-}
# Run commands given on the command line.
proc run_commands { prompt command } {
diff --git a/bin/blogin.in b/bin/blogin.in
index cae1bce..811a0d0 100644
--- a/bin/blogin.in
+++ b/bin/blogin.in
@@ -359,6 +359,10 @@ proc login { router user userpswd passwd enapasswd prompt cmethod cyphertype } {
send "no\r"
send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n"
return 1 }
+ -re "Offending key for .* \(yes\/no\)\?" {
+ send "no\r"
+ send_user "\nError: host key mismatch for $router. Update the SSH known_hosts file accordingly.\n"
+ return 1 }
-re "$u_prompt" { send "$user\r"
expect {
eof { send_user "\nError: Couldn't login\n"; wait; return 1 }
@@ -383,13 +387,7 @@ proc login { router user userpswd passwd enapasswd prompt cmethod cyphertype } {
}
"$prompt" { break; }
denied { send_user "\nError: Check your passwd for $router\n"
- if { $do_command || $do_script } {
- send "logout\r"
- wait
- return 1
- } else {
- return 1
- }
+ catch {close}; wait; return 1
}
"% Bad passwords" {send_user "\nError: Check your passwd for $router\n"; return 1 }
}
diff --git a/bin/clogin.in b/bin/clogin.in
index afb18e3..9fff218 100755
--- a/bin/clogin.in
+++ b/bin/clogin.in
@@ -371,15 +371,13 @@ proc login { router user userpswd passwd enapasswd cmethod cyphertype } {
send "no\r"
send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n"
return 1 }
+ -re "Offending key for .* \(yes\/no\)\?" {
+ send "no\r"
+ send_user "\nError: host key mismatch for $router. Update the SSH known_hosts file accordingly.\n"
+ return 1 }
-re "(denied|Sorry)" {
send_user "\nError: Check your passwd for $router\n"
- if { $do_command || $do_script } {
- send "exit\r"
- wait
- return 1
- } else {
- return 1
- }
+ catch {close}; wait; return 1
}
"Login failed" {
send_user "\nError: Check your passwd for $router\n"
diff --git a/bin/control_rancid.in b/bin/control_rancid.in
index 6e13f7b..dc453a0 100755
--- a/bin/control_rancid.in
+++ b/bin/control_rancid.in
@@ -19,8 +19,15 @@
# control_rancid $GROUP
#
+# print a usage message to stderr
+pr_usage() {
+ echo "usage: $0 [-r device_name] [-m mail rcpt] [group [group ...]]" >&2;
+}
+
# command-line options
# -r <device name>
+# -m <mail recipients>
+alt_mailrcpt=0
if [ $# -ge 1 ] ; then
while [ 1 ] ; do
@@ -31,11 +38,27 @@ if [ $# -ge 1 ] ; then
device="$1"
shift
;;
+ -m)
+ shift
+ # next arg is the mail recipient
+ alt_mailrcpt=1
+ if [ -z "$mailrcpt" ] ; then
+ mailrcpt="$1"
+ else
+ mailrcpt="$mailrcpt,$1"
+ fi
+ shift
+ ;;
--)
shift; break;
;;
+ -h)
+ pr_usage
+ exit
+ ;;
-*)
echo "unknown option: $1" >&2
+ pr_usage
exit 1
;;
*)
@@ -45,9 +68,6 @@ if [ $# -ge 1 ] ; then
done
fi
-# Number of things par should run in parallel.
-PAR_COUNT=${PAR_COUNT:-5}
-
# Must specify a group on which to run rancid
if [ $# -lt 1 ]; then
echo 'must specify group'; exit 1
@@ -58,6 +78,12 @@ DIR=$BASEDIR/$GROUP
TMP=${TMPDIR:=/tmp}/rancid.$GROUP.$$
trap 'rm -fr $TMP;' 1 2 15
+# the receipient(s) of diffs
+mailrcpt=${mailrcpt:-"@MAILPLUS@$GROUP"}; export mailrcpt
+
+# Number of things par should run in parallel.
+PAR_COUNT=${PAR_COUNT:-5}
+
# Bail if we do not have the necessary info to run
if [ ! -d $DIR ]
then
@@ -298,13 +324,24 @@ cd $DIR
cvs -f @DIFF_CMD@ | sed -e '/^RCS file: /d' -e '/^--- /d' \
-e '/^+++ /d' -e 's/^\([-+ ]\)/\1 /' >$TMP.diff
-cvs commit -m updates
+if [ $alt_mailrcpt -eq 1 ] ; then
+ subject="router config diffs - courtesy of $mailrcpt"
+else
+ subject="router config diffs"
+fi
+if [ "X$device" != "X" ] ; then
+ cvs commit -m "updates - courtesy of $mailrcpt"
+ subject="$GROUP/$device $subject"
+else
+ cvs commit -m updates
+ subject="$GROUP $subject"
+fi
# Mail out the diffs (if there are any).
if [ -s $TMP.diff ]; then
sendmail -t <<EMAIL
-To: @MAILPLUS@$GROUP
-Subject: $GROUP router config diffs
+To: $mailrcpt
+Subject: $subject
Precedence: bulk
`cat $TMP.diff`
diff --git a/bin/do-diffs.in b/bin/do-diffs.in
index a8d4800..874007c 100755
--- a/bin/do-diffs.in
+++ b/bin/do-diffs.in
@@ -21,6 +21,14 @@ ENVFILE="`dirname $0`/env"
TMPDIR=${TMPDIR:=/tmp}; export TMPDIR
+# control_rancid argv
+CR_ARGV=""; export CR_ARGV
+
+# print a usage message to stderr
+pr_usage() {
+ echo "usage: $0 [-r device_name] [-m mail rcpt] [group [group ...]]" >&2;
+}
+
# command-line options
# -r <device name>
if [ $# -ge 1 ] ; then
@@ -30,14 +38,25 @@ if [ $# -ge 1 ] ; then
-r)
shift
# next arg is the device name
- device="$1"
+ CR_ARGV="$CR_ARGV -r $1"; export CR_ARGV
+ shift
+ ;;
+ -m)
+ shift
+ # next arg is the mailto name
+ CR_ARGV="$CR_ARGV -m $1"; export CR_ARGV
shift
;;
--)
shift; break;
;;
+ -h)
+ pr_usage
+ exit
+ ;;
-*)
echo "unknown option: $1" >&2
+ pr_usage
exit 1
;;
*)
@@ -97,11 +116,7 @@ END
trap 'rm -fr $LOCKFILE;exit 1' 1 2 3 6 10 15
touch $LOCKFILE
if [ $? -eq 0 ] ; then
- if [ "X$device" = "X" ] ; then
- control_rancid $GROUP
- else
- control_rancid -r $device $GROUP
- fi
+ control_rancid $CR_ARGV $GROUP
rm -f $LOCKFILE
fi
trap '' 1 2 3 6 10 15
diff --git a/bin/elogin.in b/bin/elogin.in
index 56eab56..a76155d 100755
--- a/bin/elogin.in
+++ b/bin/elogin.in
@@ -346,13 +346,7 @@ proc login { router user userpswd passwd prompt cmethod cyphertype } {
}
"$prompt" { break; }
denied { send_user "\nError: Check your passwd for $router\n"
- if { $do_command || $do_script } {
- send "exit\r"
- wait
- return 1
- } else {
- return 1
- }
+ catch {close}; wait; return 1
}
"\r\n" { exp_continue; }
}
diff --git a/bin/f10rancid.in b/bin/f10rancid.in
new file mode 100755
index 0000000..54ccd74
--- /dev/null
+++ b/bin/f10rancid.in
@@ -0,0 +1,1255 @@
+#!@PERLV_PATH@
+##
+## This version of rancid tries to deal with Force10s.
+##
+## Copyright (C) 1997-2001 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
+
+my(%filter_pwds); # password filtering mode
+
+# 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 {
+ print STDERR " In ShowVersion: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ study;
+ last if(/^$prompt/);
+ next if(/^(\s*|\s*$cmd\s*)$/);
+ return(-1) if (/command authorization failed/i);
+ if (/^Slave in slot (\d+) is running/) {
+ $slave = " Slave:";
+ next;
+ }
+ /^Cisco Secure PIX /i &&
+ ProcessHistory("COMMENTS","keysort","F1", "!Image: $_") && 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;
+ if (/^Hardware:\s+(.*), (.* RAM), CPU (.*)$/) {
+ ProcessHistory("COMMENTS","keysort","A1",
+ "!Chassis type: $1 - a PIX\n");
+ ProcessHistory("COMMENTS","keysort","A2",
+ "!CPU: $3\n");
+ ProcessHistory("COMMENTS","keysort","B1", "!Memory: $2\n");
+ }
+ /^Serial Number:\s+(.*)$/ &&
+ ProcessHistory("COMMENTS","keysort","C1", "!$_") && next;
+ /^Activation Key:\s+(.*)$/ &&
+ ProcessHistory("COMMENTS","keysort","C2", "!$_") && 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;
+ /^BOOTLDR: .*(Version.*)$/ &&
+ ProcessHistory("COMMENTS","keysort","G4","!BOOTLDR: $1\n") && next;
+ /^.* Version.*$/ &&
+ ProcessHistory("COMMENTS","keysort","F1", "!Image: $_") && next;
+ /^Build .*$/ &&
+ ProcessHistory("COMMENTS","keysort","F1", "!Image: $_") && 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") &&
+ next;
+ /^System image file is "([^\"]*)"$/ &&
+ ProcessHistory("COMMENTS","keysort","F5","!Image: $1\n") && next;
+ if (/(\S+)\s+\((\S+)\)\s+processor.*with (\S+[kK]) bytes/) {
+ my($proc) = $1;
+ my($cpu) = $2;
+ my($mem) = $3;
+ my($device) = "router";
+ if ( $1 eq "CSC") {
+ $type = "AGS";
+ } elsif ( $1 eq "CSC4") {
+ $type = "AGS+";
+ } elsif ( $1 eq "2511" || $1 eq "2524" || $1 eq "AS2511-RJ") {
+ $type = "2500";
+ } elsif ( $1 =~ /261[01]/ || $1 =~ /262[01]/ ) {
+ $type = "2600";
+ } elsif ( $1 eq "3620" || $1 eq "3640") {
+ $type = "3600";
+ } 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 =~ /720[246]/) {
+ $type = "7200";
+ } elsif ( $1 =~ /1200[48]\/GRP/ || $1 =~ /1201[26]\/GRP/) {
+ $type = "12000";
+ } elsif ( $1 =~ /1201[26]-8R\/GRP/) {
+ $type = "12000";
+ } elsif ( $1 =~ /WS-C29/) {
+ $type = "2900XL";
+ $device = "switch";
+ } elsif ( $1 =~ /WS-C35/) {
+ $type = "3500XL";
+ $device = "switch";
+ } elsif ( $1 =~ /6000/) {
+ $type = "6000";
+ $device = "switch";
+ } else {
+ $type = $1;
+ }
+ print STDERR "TYPE = $type\n" if ($debug);
+ ProcessHistory("COMMENTS","keysort","A1",
+ "!Chassis type:$slave $proc - a $type $device\n");
+ ProcessHistory("COMMENTS","keysort","B1",
+ "!Memory:$slave main $mem\n");
+ ProcessHistory("COMMENTS","keysort","A3","!CPU:$slave $cpu\n");
+ next;
+ }
+ if (/^(.*)\s+processor .*with (\d+[kK]?) bytes/) {
+ my($cpu) = $1;
+ my($mem) = $2;
+ my($type) = "Buffy";
+ my($device) = "Force10";
+ ProcessHistory("COMMENTS","keysort","A1",
+ "!Chassis type:$slave - a $device $type\n");
+ ProcessHistory("COMMENTS","keysort","B1",
+ "!Memory:$slave main $mem\n");
+ ProcessHistory("COMMENTS","keysort","A3","!CPU:$slave $cpu\n");
+ next;
+ }
+ /^(\S+)\s+processor: part number (\S+), mask (\S+)/ &&
+ ProcessHistory("COMMENTS","keysort","A4","!CPU:$slave $_") && 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+[kK]) bytes of multibus/ &&
+ ProcessHistory("COMMENTS","keysort","B2",
+ "!Memory: multibus $1\n") && next;
+ /^(\d+[kK]) bytes of non-volatile/ &&
+ ProcessHistory("COMMENTS","keysort","B3",
+ "!Memory: nvram $1\n") && next;
+ /^(\d+[kK]) bytes of flash memory/ &&
+ ProcessHistory("COMMENTS","keysort","B5","!Memory: flash $1\n") &&
+ next;
+ /^(\d+[kK]) bytes of .*flash partition/ &&
+ ProcessHistory("COMMENTS","keysort","B6",
+ "!Memory: flash partition $1\n") && next;
+ /^(\d+[kK]) bytes of Flash internal/ &&
+ ProcessHistory("COMMENTS","keysort","B4",
+ "!Memory: bootflash $1\n") && next;
+ if(/^(\d+[kK]) bytes of (Flash|ATA)?.*PCMCIA .*(slot|disk) ?(\d)/i) {
+ ProcessHistory("COMMENTS","keysort","B7",
+ "!Memory: pcmcia $2 $3$4 $1\n");
+ next;
+ }
+ if(/^WARNING/) {
+ if (!defined($I0)) {
+ $I0=1;
+ ProcessHistory("COMMENTS","keysort","I0","!\n");
+ }
+ ProcessHistory("COMMENTS","keysort","I1","! $_");
+ # The line after the WARNING is what to do about it.
+ $_ = <INPUT>; tr/\015//d;
+ ProcessHistory("COMMENTS","keysort","I1","! $_");
+ }
+ if (/^Configuration register is (.*)$/) {
+ $config_register=$1;
+ next;
+ }
+ }
+ return(0);
+}
+
+# This routine parses "show install active"
+sub ShowInstallActive {
+ print STDERR " In ShowInstallActive: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ return(1) if /^\s*\^\s*$/;
+ return(1) if /(Invalid input detected|Type help or )/;
+ return(-1) if (/command authorization failed/i);
+ ProcessHistory("COMMENTS","keysort","F5","!Image: $_") && next;
+ }
+ return(0);
+}
+
+# This routine parses "show env all"
+sub ShowEnv {
+ # Skip if this is not a 7500, 7200, or 7000.
+ print STDERR " In ShowEnv: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ #return(1) if ($type !~ /^7/);
+ return(-1) if (/command authorization failed/i);
+ 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 [^:\n]+)$/ &&
+ ProcessHistory("COMMENTS","keysort","E1","!Power: $1\n") && next;
+ /^\s*(Lower Power .*)/i &&
+ ProcessHistory("COMMENTS","keysort","E2","!Power: $1\n") && next;
+ /^\s*(redundant .*)/i &&
+ ProcessHistory("COMMENTS","keysort","E2","!Power: $1\n") && next;
+ }
+ ProcessHistory("COMMENTS","","","!\n");
+ return(0);
+}
+
+# This routine parses "show gsr chassis-info" for the gsr
+# This will create arrays for hw info.
+sub ShowGSR {
+ # Skip if this is not a 1200n.
+ print STDERR " In ShowGSR: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ return(-1) if (/command authorization failed/i);
+ # return(1) if ($type !~ /^12[40]/);
+ /^$/ && 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/7200/7500/12000/2900/3500;
+ # otherwise pick up bootflash.
+ print STDERR " In ShowBoot: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ return(1) if /^\s*\^\s*$/;
+ return(-1) if (/command authorization failed/i);
+ return(1) if /Ambiguous command/i;
+ return(1) if /(Invalid input detected|Type help or )/;
+ 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 !~ /^(12[04]|7)/) {
+ if ($type !~ /^(29|35)00/) {
+ ProcessHistory("COMMENTS","keysort","H2","!BootFlash: $_");
+ } else {
+ ProcessHistory("COMMENTS","keysort","H1","!Variable: $_");
+ }
+ } elsif (/variable/) {
+ ProcessHistory("COMMENTS","keysort","H1","!Variable: $_");
+ }
+ }
+ ProcessHistory("COMMENTS","","","!\n");
+ return(0);
+}
+
+# This routine parses "show flash"
+sub ShowFlash {
+ # skip if this is 7000, 7200, 7500, or 12000; else we end up with
+ # redundant data from dir /all slot0:
+ print STDERR " In ShowFlash: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ return(1) if ($type =~ /^(12[40]|7)/);
+ return(-1) if (/command authorization failed/i);
+ return(1) if /^\s*\^\s*$/;
+ return(1) if /(Invalid input detected|Type help or )/;
+ ProcessHistory("FLASH","","","!Flash: $_");
+ }
+ ProcessHistory("","","","!\n");
+ return;
+}
+
+# This routine parses "dir /all ((disk|slot)N|bootflash|nvram):"
+sub DirSlotN {
+ # Skip if this is not a 3600, 7000, 7200, 7500, or 12000.
+ 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 !~ /^(12[40]|7|36)/);
+ return(1) if /^\s*\^\s*$/;
+ return(1) if /(Invalid input detected|Type help or )/;
+ return(1) if /No such device/i;
+ return(1) if /\%Error: No such file or directory/;
+ return(1) if /No space information available/;
+ return(-1) if /\%Error calling/;
+ return(-1) if /(: device being squeezed|ATA_Status time out)/i; # busy
+ return(-1) if (/command authorization failed/i);
+ 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);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ study;
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ # return(1) if ($type =~ /^(12[40]|7[05])/);
+ return(-1) if (/command authorization failed/i);
+ 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 $_");
+ }
+ if (/^(\S+) : 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"
+# Some of this is printed out in ShowDiagbus.
+sub ShowContCbus {
+ # Skip if this is not a 7000 or 7500.
+ print STDERR " In ShowContCbus: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ #return(1) if ($type !~ /^7[05]0/);
+ return(-1) if (/command authorization failed/i);
+ 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(0);
+}
+
+# This routine parses "show diagbus"
+# This will create arrarys for hw info.
+sub ShowDiagbus {
+ # Skip if this is not a 7000, 70[01]0, or 7500.
+ print STDERR " In ShowDiagbus: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ study;
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ #return(1) if ($type !~ /^7[05]/);
+ return(-1) if (/command authorization failed/i);
+ if (/^\s*Slot (\d+):/i) {
+ $slot = $1;
+ next;
+ } elsif (/^\s*Slot (\d+) \(virtual\):/i) {
+ $slot = $1;
+ next;
+ } elsif (/^\s*(.*Processor.*|.*controller|.*Chassis Interface)(, FRU:.*)?, HW rev (\S+), board revision (\S+)/i) {
+ $board = $1;
+ $hwver = $3;
+ $boardrev = $4;
+ 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});
+ next;
+ }
+ /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+(.*) (IP|PA), (\d) ports?,( \S+,)? (FRU: )?(\S+)/ &&
+ ProcessHistory("SLOT","","","!Slot $slot/$board: type $6, $3 ports\n") &&
+ next;
+ /\s+(.*) (IP|PA)( \(\S+\))?, (\d) ports?/ &&
+ ProcessHistory("SLOT","","","!Slot $slot/$board: type $1$3, $4 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 diag" for the gsr, 7200, 3600, 2600.
+# This will create arrarys for hw info.
+sub ShowDiag {
+ # Skip if this is not a 12000.
+ print STDERR " In ShowDiag: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ study;
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ # return(1) if ($type !~ /^(12[40]|720|36|26)/);
+ return(-1) if (/command authorization failed/i);
+ /^$/ && next;
+ s/Port Packet Over SONET/POS/;
+ if (/^\s*SLOT\s+(\d+)\s+\((.*)\): (.*)/) {
+ $slot = $1;
+ ProcessHistory("SLOT","","","!\n!Slot $slot: $3\n");
+ next;
+ }
+ if (/^\s+MAIN:\s* type \d+,\s+(.*)/) {
+ ProcessHistory("SLOT","","","!Slot $slot/MAIN: part $1\n") && next;
+ }
+ if (/ Engine:\s+(.*)/) {
+ ProcessHistory("SLOT","","","!Slot $slot/Engine: $1\n");
+ }
+ 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");
+ 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") &&
+ ProcessHistory("SLOT","","","!Slot $slot/MBUS: hvers $1\n");
+ next;
+ }
+ if (/^\s+MBUS Agent Software version (.*)/) {
+ ProcessHistory("SLOT","","","!Slot $slot/MBUS: software $1\n");
+ next;
+ }
+ if (/^\s+ROM Monitor version (.*)/) {
+ ProcessHistory("SLOT","","","!Slot $slot/ROM Monitor: version $1\n");
+ next;
+ }
+ if (/^\s+Fabric Downloader version used (.*)/) {
+ ProcessHistory("SLOT","","","!Slot $slot/Fabric Downloader: version $1\n");
+ next;
+ }
+ if (/^\s+DRAM size: (\d+)/) {
+ local($dram) = $1 / 1048576;
+ $_ = <INPUT>;
+ if (/^\s+FrFab SDRAM size: (\d+)/) {
+ ProcessHistory("SLOT","","","!Slot $slot/MBUS: $dram Mbytes DRAM, "
+ . $1 / 1024 . " Kbytes SDRAM\n");
+ } else {
+ ProcessHistory("SLOT","","","!Slot $slot/MBUS: $dram Mbytes DRAM\n");
+ }
+ next;
+ }
+ # 7200 and 3600 stuff
+ if (/^(Slot)\s+(\d+(\/\d+)?):/ || /^\s+(WIC|VIC) Slot (\d):/) {
+ if ($1 eq "WIC") {
+ $WIC = "/$2";
+ } elsif ($1 eq "VIC") {
+ $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+(.*) port adapter,?\s+(\d+)\s+/i &&
+ ProcessHistory("SLOT","","","!\n!Slot $slot: type $1, $2 ports\n");
+ # I/O controller with no interfaces
+ /\s+(.*)\s+port adapter\s*$/i &&
+ ProcessHistory("SLOT","","","!\n!Slot $slot: type $1, 0 ports\n");
+ /\s+(.*)\s+daughter card(.*)$/ &&
+ ProcessHistory("SLOT","","","!\n!Slot $slot$WIC: type $1$2\n");
+ /\s+(FT1)$/ &&
+ ProcessHistory("SLOT","","","!\n!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") &&
+ next;
+ }
+ ProcessHistory("SLOT","","","!\n");
+ return(0);
+}
+
+# This routine parses "show module".
+sub ShowModule {
+ print STDERR " In ShowModule: $_" if ($debug);
+
+ my(@lines);
+ my($slot);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ return if (/^\s*\^$/);
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ return(-1) if (/command authorization failed/i);
+
+ # match slot/card info line
+ if (/^ *(\d+)\s+(\d+)\s+(.*)\s+(\S+)\s+(\S+)\s*$/) {
+ $lines[$1] .= "!Slot $1: type $3, $2 ports\n!Slot $1: part $4, serial $5\n";
+ $lines[$1] =~ s/\s+,/,/g;
+ }
+ # now match the Revs in the second paragraph of o/p and stick it in
+ # the array with the previous bits...grumble.
+ if (/^ *(\d+)\s+\S+\s+to\s+\S+\s+(\S+)\s+(\S*)\s+(\S+)(\s+\S+)?\s*$/) {
+ $lines[$1] .= "!Slot $1: hvers $2, firmware $3, sw $4\n";
+ $lines[$1] =~ s/\s+,/,/g;
+ }
+ }
+ foreach $slot (@lines) {
+ next if ($slot =~ /^\s*$/);
+ ProcessHistory("Module","","","$slot!\n");
+ }
+
+ return(0);
+}
+
+# This routine parses "show c7200" for the 7200
+# This will create arrays for hw info.
+sub ShowC7200 {
+ # Skip if this is not a 7200.
+ print STDERR " In ShowC7200: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ #return(1) if ($type !~ /^72/);
+ return(-1) if (/command authorization failed/i);
+ /^$/ && 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 (/C720\d(VXR)? 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(0);
+}
+
+# This routine parses "show vtp status"
+sub ShowVTP {
+ print STDERR " In ShowVTP: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ return(1) if /^\s*\^\s*$/;
+ return(1) if /(Invalid input detected|Type help or )/;
+ #return(1) if ($type !~ /^(2900XL|3500XL|6000)$/);
+ return(-1) if (/command authorization failed/i);
+ next if (/^Configuration last modified by/);
+ if (/^VTP Operating Mode\s+:\s+(Transparent|Server)/) {
+ $DO_SHOW_VLAN = 1;
+ }
+ ProcessHistory("COMMENTS","keysort","I0","!VTP: $_");
+ }
+ ProcessHistory("COMMENTS","keysort","I0","!\n");
+ return(0);
+}
+
+# This routine parses "show vlan"
+sub ShowVLAN {
+ print STDERR " In ShowVLAN: $_" if ($debug);
+
+ ($_=<INPUT>,return(1)) if (!$DO_SHOW_VLAN);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ next if (/^(\s*|\s*$cmd\s*)$/);
+ return(1) if /(Invalid input detected|Type help or )/;
+ #return(1) if ($type !~ /^(2900XL|3500XL|6000)$/);
+ return(-1) if (/command authorization failed/i);
+ ProcessHistory("COMMENTS","keysort","IO","!VLAN: $_");
+ }
+ ProcessHistory("COMMENTS","keysort","IO","!\n");
+ return(0);
+}
+
+# This routine processes a "write term"
+sub WriteTerm {
+ print STDERR " In WriteTerm: $_" if ($debug);
+
+ while (<INPUT>) {
+ tr/\015//d;
+ study;
+ last if(/^$prompt/);
+ return(-1) if (/command authorization failed/i);
+ # the pager can not be disabled per-session on the PIX
+ s/^<-+ More -+>\s*//;
+ /Non-Volatile memory is in use/ && return(-1); # NvRAM is locked
+ # skip the crap
+ if (/^(##+$|(Building|Current) configuration)/i) {
+ while (<INPUT>) {
+ next if (/^Current configuration\s*:/i);
+ next if (/^:/);
+ next if (/^([%!].*|\s*)$/);
+ next if (/^ip add.*ipv4:/); # band-aid for 3620 12.0S
+ last;
+ }
+ if (defined($config_register)) {
+ 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
+ /^ clockrate / && next; # kill clockrate on serial interfaces
+ if (/^(enable )?(password|passwd) / && $filter_pwds >= 1) {
+ ProcessHistory("ENABLE","","","!$1$2 <removed>\n");
+ next;
+ }
+ if (/^(enable secret) / && $filter_pwds >= 2) {
+ ProcessHistory("ENABLE","","","!$1 <removed>\n");
+ next;
+ }
+ if (/^username (\S+)(\s.*)? secret /) {
+ if ($filter_pwds >= 2) {
+ ProcessHistory("USER","keysort","$1","!username $1$2 secret <removed>\n");
+ } else {
+ ProcessHistory("USER","keysort","$1","$_");
+ }
+ next;
+ }
+ if (/^username (\S+)(\s.*)? password ((\d) \S+|\S+)/) {
+ if ($filter_pwds == 2) {
+ ProcessHistory("USER","keysort","$1","!username $1$2 password <removed>\n");
+ } elsif ($filter_pwds == 1 && $4 ne "5"){
+ ProcessHistory("USER","keysort","$1","!username $1$2 password <removed>\n");
+ } else {
+ ProcessHistory("USER","keysort","$1","$_");
+ }
+ next;
+ }
+ if (/^(\s*)password / && $filter_pwds >= 1) {
+ ProcessHistory("LINE-PASS","","","!$1password <removed>\n");
+ next;
+ }
+ if (/^\s*neighbor (\S*) password / && $filter_pwds >= 1) {
+ ProcessHistory("","","","! neighbor $1 password <removed>\n");
+ next;
+ }
+ if (/^(ppp .* password) 7 .*/ && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>\n"); next;
+ }
+ if (/^(ip ftp password) / && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>\n"); next;
+ }
+ if (/^( ip ospf authentication-key) / && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>\n"); next;
+ }
+ # this is reversable, despite 'md5' in the cmd
+ if (/^( ip ospf message-digest-key \d+ md5) / && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>\n"); next;
+ }
+ if (/^((crypto )?isakmp key) \S+ / && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed> $'"); next;
+ }
+ # i am told these are plain-text on the PIX
+ if (/^(vpdn username \S+ password)/ && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 <removed>\n"); next;
+ }
+ /fair-queue individual-limit/ && next;
+ # sort ip explicit-paths.
+ if (/^ip explicit-path name (\S+)/) {
+ my($key) = $1;
+ my($expath) = $_;
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/);
+ last if (/^$prompt/ || ! /^(ip explicit-path name |[ !])/);
+ if (/^ip explicit-path name (\S+)/) {
+ ProcessHistory("EXPATH","keysort","$key","$expath");
+ $key = $1;
+ $expath = $_;
+ } else {
+ $expath .= $_;
+ }
+ }
+ ProcessHistory("EXPATH","keysort","$key","$expath");
+ }
+ # sort route-maps
+ if (/^route-map (\S+)/) {
+ my($key) = $1;
+ my($routemap) = $_;
+ while (<INPUT>) {
+ tr/\015//d;
+ last if (/^$prompt/ || ! /^(route-map |[ !])/);
+ if (/^route-map (\S+)/) {
+ 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/prune snmp-server host statements
+ # we only prune lines of the form
+ # snmp-server host a.b.c.d <community>
+ if (/^snmp-server host (\d+\.\d+\.\d+\.\d+) /) {
+ if (defined($ENV{'NOCOMMSTR'})) {
+ my($ip) = $1;
+ my($line) = "snmp-server host $ip";
+ my(@tokens) = split(' ', $');
+ my($token);
+ while ($token = shift(@tokens)) {
+ if ($token eq 'version') {
+ $line .= " " . join(' ', ($token, shift(@tokens)));
+ } elsif ($token =~ /^(informs?|traps?|(no)?auth)$/) {
+ $line .= " " . $token;
+ } else {
+ $line = "!$line " . join(' ', ("<removed>", join(' ',@tokens)));
+ last;
+ }
+ }
+ ProcessHistory("SNMPSERVERHOST","ipsort","$ip","$line\n");
+ } else {
+ ProcessHistory("SNMPSERVERHOST","ipsort","$1","$_");
+ }
+ next;
+ }
+ if (/^(snmp-server community) (\S+)/) {
+ if (defined($ENV{'NOCOMMSTR'})) {
+ ProcessHistory("SNMPSERVERCOMM","keysort","$_","!$1 <removed>$'") && next;
+ } else {
+ ProcessHistory("SNMPSERVERCOMM","keysort","$_","$_") && next;
+ }
+ }
+ # order/prune tacacs/radius server statements
+ if (/^(tacacs-server|radius-server) key / && $filter_pwds >= 1) {
+ ProcessHistory("","","","!$1 key <removed>\n"); 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 - this md5 is a reversable too
+ if (/^(ntp authentication-key \d+ md5) / && $filter_pwds >= 1) {
+ 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;
+
+ # system controller
+ /^syscon address (\S*) (\S*)/ &&
+ ProcessHistory("","","","!syscon address $1 <removed>\n") &&
+ next;
+ if (/^syscon password (\S*)/ && $filter_pwds >= 1) {
+ ProcessHistory("","","","!syscon password <removed>\n");
+ next;
+ }
+
+ # catch anything that wasnt matched above.
+ ProcessHistory("","","","$_");
+ # end of config. the ": " game is for the PIX
+ if (/^(: +)?end$/) {
+ $found_end = 1;
+ return(1);
+ }
+ }
+ return(0);
+}
+
+# dummy function
+sub DoNothing {print STDOUT;}
+
+# Main
+%commands=(
+ 'show version' => "ShowVersion",
+ 'show install active' => "ShowInstallActive",
+ 'show env all' => "ShowEnv",
+ 'show gsr chassis' => "ShowGSR",
+ 'show boot' => "ShowBoot",
+ 'show bootvar' => "ShowBoot",
+ 'show variables boot' => "ShowBoot",
+ 'show flash' => "ShowFlash",
+ 'dir /all nvram:' => "DirSlotN",
+ 'dir /all bootflash:' => "DirSlotN",
+ 'dir /all slot0:' => "DirSlotN",
+ 'dir /all disk0:' => "DirSlotN",
+ 'dir /all slot1:' => "DirSlotN",
+ 'dir /all disk1:' => "DirSlotN",
+ "dir /all sup-bootflash:"=> "DirSlotN", # cat 6500-ios
+ "dir /all sup-microcode:"=> "DirSlotN", # cat 6500-ios
+ 'show controllers' => "ShowContAll",
+ 'show controllers cbus' => "ShowContCbus",
+ 'show diagbus' => "ShowDiagbus",
+ 'show diag' => "ShowDiag",
+ 'show module' => "ShowModule", # cat 6500-ios
+ 'show c7200' => "ShowC7200",
+ 'show vtp status' => "ShowVTP",
+ 'show vlan' => "ShowVLAN",
+ 'show running' => "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 install active",
+ "show env all",
+ "show gsr chassis",
+ "show boot",
+ "show bootvar",
+ "show variables boot",
+ "show flash",
+ "dir /all nvram:",
+ "dir /all bootflash:",
+ "dir /all slot0:",
+ "dir /all disk0:",
+ "dir /all slot1:",
+ "dir /all disk1:",
+ "dir /all sup-bootflash:",
+ "dir /all sup-microcode:",
+ "show controllers",
+ "show controllers cbus",
+ "show diagbus",
+ "show diag",
+ "show module",
+ "show c7200",
+ "show vtp status",
+ "show vlan",
+ "show running"
+);
+$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 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 \"$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";
+ }
+}
+
+# determine password filtering mode
+if ($ENV{"FILTER_PWDS"} =~ /no/i) {
+ $filter_pwds = 0;
+} elsif ($ENV{"FILTER_PWDS"} =~ /all/i) {
+ $filter_pwds = 2;
+} else {
+ $filter_pwds = 1;
+}
+
+ProcessHistory("","","","!RANCID-CONTENT-TYPE: force10\n!\n");
+ProcessHistory("COMMENTS","keysort","B0","!\n");
+ProcessHistory("COMMENTS","keysort","F0","!\n");
+ProcessHistory("COMMENTS","keysort","G0","!\n");
+TOP: while(<INPUT>) {
+ tr/\015//d;
+ if (/\#\s?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]; }
+ print STDERR ("HIT COMMAND:$_") if ($debug);
+ if (! defined($commands{$cmd})) {
+ print STDERR "$host: found unexpected command - \"$cmd\"\n";
+ $clean_run = 0;
+ last TOP;
+ }
+ $rval = &{$commands{$cmd}};
+ delete($commands{$cmd});
+ if ($rval == -1) {
+ $clean_run = 0;
+ last TOP;
+ }
+ }
+}
+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 "$host: missed cmd(s): %s\n", join(',', keys(%commands)));
+ printf(STDERR "$host: missed cmd(s): %s\n", join(',', keys(%commands))) if ($debug);
+ }
+ if (!$clean_run || !$found_end) {
+ print STDOUT "$host: End of run not found\n";
+ print STDERR "$host: End of run not found\n" if ($debug);
+ system("/usr/bin/tail -1 $host.new");
+ }
+ unlink "$host.new" if (! $debug);
+}
diff --git a/bin/flogin.in b/bin/flogin.in
index a913b56..1e34077 100755
--- a/bin/flogin.in
+++ b/bin/flogin.in
@@ -374,14 +374,12 @@ proc login { router user userpswd passwd enapasswd prompt cmethod cyphertype } {
send "no\r"
send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n"
return 1 }
+ -re "Offending key for .* \(yes\/no\)\?" {
+ send "no\r"
+ send_user "\nError: host key mismatch for $router. Update the SSH known_hosts file accordingly.\n"
+ return 1 }
denied { send_user "\nError: Check your passwd for $router\n"
- if { $do_command || $do_script } {
- send "quit"
- wait
- return 1
- } else {
- return 1
- }
+ catch {close}; wait; return 1
}
"% Bad passwords" {send_user "\nError: Check your passwd for $router\n"; return 1 }
-re "(Username:|login:|Name :)" {
diff --git a/bin/hlogin.in b/bin/hlogin.in
index caabd31..a3c00ac 100755
--- a/bin/hlogin.in
+++ b/bin/hlogin.in
@@ -372,6 +372,10 @@ proc login { router user userpswd passwd enapasswd cmethod cyphertype } {
send "no\r"
send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n"
return 1 }
+ -re "Offending key for .* \(yes\/no\)\?" {
+ send "no\r"
+ send_user "\nError: host key mismatch for $router. Update the SSH known_hosts file accordingly.\n"
+ return 1 }
-re "$u_prompt" { send "$user\r"
expect {
eof { send_user "\nError: Couldn't login\n"; wait; return 1 }
@@ -396,19 +400,7 @@ proc login { router user userpswd passwd enapasswd cmethod cyphertype } {
}
"$prompt" { break; }
denied { send_user "\nError: Check your passwd for $router\n"
- if { $do_command || $do_script } {
- send "exit\r"
- expect {
- "Do you want to log out" {
- send "y\r"
- exp_continue
- }
- }
- wait
- return 1
- } else {
- return 1
- }
+ catch {close}; wait; return 1
}
"% Bad passwords" {send_user "\nError: Check your passwd for $router\n"; return 1 }
}
diff --git a/bin/hpfilter.c b/bin/hpfilter.c
index 7c00997..f665b6f 100644
--- a/bin/hpfilter.c
+++ b/bin/hpfilter.c
@@ -383,7 +383,7 @@ void
usage(void)
{
fprintf(stderr,
-"usage: %s [-h] <telnet|ssh> <hostname>
+"usage: %s [-hv] <telnet|ssh> <hostname>
", progname);
return;
}
diff --git a/bin/jlogin.in b/bin/jlogin.in
index 2b10558..0f005d7 100755
--- a/bin/jlogin.in
+++ b/bin/jlogin.in
@@ -350,6 +350,10 @@ proc login { router user passwd cmethod cyphertype identfile} {
send "no\r"
send_user "\nError: The host key for $router has changed. Update the SSH known_hosts file accordingly.\n"
return 1 }
+ -re "Offending key for .* \(yes\/no\)\?" {
+ send "no\r"
+ send_user "\nError: host key mismatch for $router. Update the SSH known_hosts file accordingly.\n"
+ return 1 }
-re "(Username|\[\r\n]login):" {
send "$user\r"
exp_continue
@@ -360,13 +364,7 @@ proc login { router user passwd cmethod cyphertype identfile} {
}
-re "$prompt" { break; }
denied { send_user "\nError: Check your password for $router\n"
- if { $do_command || $do_script } {
- send "quit"
- wait
- return 1
- } else {
- return 1
- }
+ catch {close}; wait; return 1
}
}
}
diff --git a/bin/rancid-fe.in b/bin/rancid-fe.in
index 98f2ebc..b25dcb1 100755
--- a/bin/rancid-fe.in
+++ b/bin/rancid-fe.in
@@ -31,6 +31,7 @@ elsif ($vendor =~ /^cat5$/i) { exec('cat5rancid', $router); }
elsif ($vendor =~ /^cisco$/i) { exec('rancid', $router); }
elsif ($vendor =~ /^extreme$/i) { exec('xrancid', $router); }
elsif ($vendor =~ /^ezt3$/i) { exec('erancid', $router); }
+elsif ($vendor =~ /^force10$/i) { exec('f10rancid', $router); }
elsif ($vendor =~ /^foundry$/i) { exec('francid', $router); }
elsif ($vendor =~ /^hp$/i) { exec('hrancid', $router); }
elsif ($vendor =~ /^juniper$/i) { exec('jrancid', $router); }
diff --git a/bin/rancid.in b/bin/rancid.in
index 0948cca..4bd7ee3 100755
--- a/bin/rancid.in
+++ b/bin/rancid.in
@@ -573,10 +573,10 @@ sub ShowDiagbus {
} elsif (/^\s*Slot (\d+) \(virtual\):/i) {
$slot = $1;
next;
- } elsif (/^\s*(.*Processor.*|.*controller|.*Chassis Interface), HW rev (\S+), board revision (\S+)/i) {
+ } elsif (/^\s*(.*Processor.*|.*controller|.*controler|.*Chassis Interface)(, FRU\s?:.*)?, HW rev (\S+), board revision (\S+)/i) {
$board = $1;
- $hwver = $2;
- $boardrev = $3;
+ $hwver = $3;
+ $boardrev = $4;
if ($board =~ /Processor/) {
if ($board =~ /7000 Route\/Switch/) {
$board = "RSP7000";
@@ -626,8 +626,8 @@ sub ShowDiagbus {
}
next;
}
- /\s+(.*) (IP|PA), (\d) ports?, (\S+)/ &&
- ProcessHistory("SLOT","","","!Slot $slot/$board: type $4, $3 ports\n") &&
+ /\s+(.*) (IP|PA), (\d) ports?,( \S+,)? (FRU\s?: )?(\S+)/ &&
+ ProcessHistory("SLOT","","","!Slot $slot/$board: type $6, $3 ports\n") &&
next;
/\s+(.*) (IP|PA)( \(\S+\))?, (\d) ports?/ &&
ProcessHistory("SLOT","","","!Slot $slot/$board: type $1$3, $4 ports\n") &&
@@ -655,53 +655,56 @@ sub ShowDiag {
# return(1) if ($type !~ /^(12[40]|720|36|26)/);
return(-1) if (/command authorization failed/i);
/^$/ && next;
- if (!defined($showdiags)) {$showdiags=1; ProcessHistory("SLOT","","","!\n");}
s/Port Packet Over SONET/POS/;
if (/^\s*SLOT\s+(\d+)\s+\((.*)\): (.*)/) {
$slot = $1;
- ProcessHistory("SLOT","","","!Slot $slot: $3\n");
- # Here we look for boards that don't have DRAM.
- $board = "Other";
- $board = "PS" if (/Power Supply/);
- $board = "RP" if (/Route Processor/);
- $board = "CLK" if (/Clock Scheduler Card/);
- $board = "SFC" if (/Switch Fabric Card/);
+ ProcessHistory("SLOT","","","!\n");
+ ProcessHistory("SLOT","keysort","A","!Slot $slot: $3\n");
next;
}
- if (/^\s+MAIN:\s+ type \d+,\s+(.*)/) {
- ProcessHistory("SLOT","","","!Slot $slot/MAIN: part $1\n") && next;
+ if (/^\s+MAIN:\s* type \d+,\s+(.*)/) {
+ ProcessHistory("SLOT","keysort","AM","!Slot $slot/MAIN: part $1\n") && next;
}
if (/ Engine:\s+(.*)/) {
- ProcessHistory("SLOT","","","!Slot $slot/Engine: $1\n");
+ ProcessHistory("SLOT","keysort","AE","!Slot $slot/Engine: $1\n");
}
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");
+ ProcessHistory("SLOT","keysort","C1","!Slot $slot/PCA: part $part, serial $2\n") &&
+ ProcessHistory("SLOT","keysort","C2","!Slot $slot/PCA: hvers $1\n");
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") &&
- ProcessHistory("SLOT","","","!Slot $slot/MBUS: hvers $1\n");
+ ProcessHistory("SLOT","keysort","MB1","$tmp, serial $2\n") &&
+ ProcessHistory("SLOT","keysort","MB2","!Slot $slot/MBUS: hvers $1\n");
next;
}
if (/^\s+MBUS Agent Software version (.*)/) {
- local($sw) = $1;
- local($tail) = "!\n" if ($board ne "Other");
- ProcessHistory("SLOT","","","!Slot $slot/MBUS: software $sw\n$tail");
+ ProcessHistory("SLOT","keysort","MB3","!Slot $slot/MBUS: software $1\n");
+ next;
+ }
+ if (/^\s+ROM Monitor version (.*)/) {
+ ProcessHistory("SLOT","keysort","R","!Slot $slot/ROM Monitor: version $1\n");
+ next;
+ }
+ if (/^\s+Fabric Downloader version used (.*)/) {
+ ProcessHistory("SLOT","keysort","Z","!Slot $slot/Fabric Downloader: version $1\n");
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");
+ if (/^\s+FrFab SDRAM size: (\d+)/) {
+ ProcessHistory("SLOT","keysort","MB4","!Slot $slot/MBUS: $dram Mbytes DRAM, "
+ . $1 / 1024 . " Kbytes SDRAM\n");
+ } else {
+ ProcessHistory("SLOT","keysort","MB4","!Slot $slot/MBUS: $dram Mbytes DRAM\n");
+ }
next;
}
# 7200 and 3600 stuff
@@ -721,24 +724,26 @@ sub ShowDiag {
s/ with MII or RJ45/-TX/;
s/Fast-ethernet /100Base/; s/[)(]//g;
+ ProcessHistory("SLOT","","","!\n");
/\s+(.*) port adapter,?\s+(\d+)\s+/i &&
- ProcessHistory("SLOT","","","!Slot $slot: type $1, $2 ports\n");
+ ProcessHistory("SLOT","keysort","B","!Slot $slot: type $1, $2 ports\n");
# I/O controller with no interfaces
/\s+(.*)\s+port adapter\s*$/i &&
- ProcessHistory("SLOT","","","!Slot $slot: type $1, 0 ports\n");
+ ProcessHistory("SLOT","keysort","B","!Slot $slot: type $1, 0 ports\n");
/\s+(.*)\s+daughter card(.*)$/ &&
- ProcessHistory("SLOT","","","!Slot $slot$WIC: type $1$2\n");
+ ProcessHistory("SLOT","keysort","B","!Slot $slot$WIC: type $1$2\n");
/\s+(FT1)$/ &&
- ProcessHistory("SLOT","","","!Slot $slot$WIC: type $1\n");
+ ProcessHistory("SLOT","keysort","B","!Slot $slot$WIC: type $1\n");
next;
}
/revision\s+(\S+).*revision\s+(\S+)/ &&
- ProcessHistory("SLOT","","","!Slot $slot$WIC: hvers $1 rev $2\n") &&
+ ProcessHistory("SLOT","keysort","C","!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") &&
+ ProcessHistory("SLOT","keysort","D","!Slot $slot$WIC: part $2, serial $1\n") &&
next;
}
+ ProcessHistory("SLOT","","","!\n");
return(0);
}
@@ -789,7 +794,7 @@ sub ShowC7200 {
#return(1) if ($type !~ /^72/);
return(-1) if (/command authorization failed/i);
/^$/ && next;
- if (/C7200 Midplane EEPROM:/) {
+ if (/^(C7200 )?Midplane EEPROM:/) {
$_ = <INPUT>;
/revision\s+(\S+).*revision\s+(\S+)/;
ProcessHistory("SLOT","","","!Slot Midplane: hvers $1 rev $2\n");
@@ -799,12 +804,21 @@ sub ShowC7200 {
next;
}
if (/C720\d(VXR)? 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");
+ my ($hvers,$rev,$part,$serial);
+ # npe400s report their cpu eeprom info differently w/ 12.0.21S
+ while (<INPUT>) {
+ /Hardware Revision\s+: (\S+)/ && ($hvers = $1) && next;
+ /Board Revision\s+: (\S+)/ && ($rev = $1) && next;
+ /Part Number\s+: (\S+)/ && ($part = $1) && next;
+ /Serial Number\s+: (\S+)/ && ($serial = $1) && next;
+ /revision\s+(\S+).*revision\s+(\S+)/ &&
+ ($hvers = $1, $rev = $2) && next;
+ /number\s+(\S+)\s+Part number\s+(\S+)/ &&
+ ($serial = $1, $part = $2) && next;
+ /^\s*$/ && last;
+ }
+ ProcessHistory("SLOT","","","!Slot CPU: hvers $hvers rev $rev\n");
+ ProcessHistory("SLOT","","","!Slot CPU: part $part, serial $serial\n!\n");
next;
}
}
@@ -904,8 +918,10 @@ sub WriteTerm {
}
next;
}
- if (/^username (\S+)(\s.*)? password /) {
- if ($filter_pwds >= 1) {
+ if (/^username (\S+)(\s.*)? password ((\d) \S+|\S+)/) {
+ if ($filter_pwds == 2) {
+ ProcessHistory("USER","keysort","$1","!username $1$2 password <removed>\n");
+ } elsif ($filter_pwds == 1 && $4 ne "5"){
ProcessHistory("USER","keysort","$1","!username $1$2 password <removed>\n");
} else {
ProcessHistory("USER","keysort","$1","$_");
@@ -1099,6 +1115,8 @@ sub DoNothing {print STDOUT;}
'dir /all disk0:' => "DirSlotN",
'dir /all slot1:' => "DirSlotN",
'dir /all disk1:' => "DirSlotN",
+ 'dir /all slot2:' => "DirSlotN",
+ 'dir /all disk2:' => "DirSlotN",
"dir /all sup-bootflash:"=> "DirSlotN", # cat 6500-ios
"dir /all sup-microcode:"=> "DirSlotN", # cat 6500-ios
'show controllers' => "ShowContAll",
@@ -1128,6 +1146,8 @@ sub DoNothing {print STDOUT;}
"dir /all disk0:",
"dir /all slot1:",
"dir /all disk1:",
+ "dir /all slot2:",
+ "dir /all disk2:",
"dir /all sup-bootflash:",
"dir /all sup-microcode:",
"show controllers",
diff --git a/bin/xrancid.in b/bin/xrancid.in
index ecc6807..06ff30b 100755
--- a/bin/xrancid.in
+++ b/bin/xrancid.in
@@ -454,7 +454,7 @@ TOP: while(<INPUT>) {
$rval = &{$commands{$cmd}};
delete($commands{$cmd});
if ($rval == -1) {
- printf STDERR "rval = -1\n" if (debug);
+ printf STDERR "rval = -1\n" if ($debug);
$clean_run = 0;
last TOP;
}
diff --git a/configure b/configure
index 1acab2c..c0fb7d1 100755
--- a/configure
+++ b/configure
@@ -2560,7 +2560,7 @@ rd_cv_rd_bin_datas=$RD_BIN_DATAS
# RD_BIN_PROGS are bin/ .in's that need to be installed with execute perms.
RD_BIN_PROGS="cat5rancid control_rancid \
alogin arancid clogin create_cvs blogin brancid do-diffs elogin erancid \
-flogin francid jlogin jrancid hlogin hrancid mrancid par rancid-fe \
+f10rancid flogin francid jlogin jrancid hlogin hrancid mrancid par rancid-fe \
rancid rename rrancid xrancid"
rd_cv_rd_bin_progs=$RD_BIN_PROGS
@@ -3105,8 +3105,8 @@ ac_given_INSTALL="$INSTALL"
trap 'rm -fr `echo " Makefile include/Makefile bin/Makefile util/Makefile \
bin/alogin bin/arancid bin/blogin bin/brancid bin/cat5rancid \
bin/clogin bin/control_rancid bin/create_cvs bin/do-diffs bin/elogin \
- bin/env bin/erancid bin/flogin bin/francid bin/jlogin bin/jrancid \
- bin/hlogin \
+ bin/env bin/erancid bin/f10rancid bin/flogin bin/francid bin/jlogin \
+ bin/jrancid bin/hlogin \
bin/hrancid bin/mrancid bin/par bin/rancid-fe bin/rancid bin/rename \
bin/rrancid bin/xrancid \
man/Makefile man/env.5 man/lg.conf.5 man/lg_intro.1 \
@@ -3235,8 +3235,8 @@ cat >> $CONFIG_STATUS <<EOF
CONFIG_FILES=\${CONFIG_FILES-"Makefile include/Makefile bin/Makefile util/Makefile \
bin/alogin bin/arancid bin/blogin bin/brancid bin/cat5rancid \
bin/clogin bin/control_rancid bin/create_cvs bin/do-diffs bin/elogin \
- bin/env bin/erancid bin/flogin bin/francid bin/jlogin bin/jrancid \
- bin/hlogin \
+ bin/env bin/erancid bin/f10rancid bin/flogin bin/francid bin/jlogin \
+ bin/jrancid bin/hlogin \
bin/hrancid bin/mrancid bin/par bin/rancid-fe bin/rancid bin/rename \
bin/rrancid bin/xrancid \
man/Makefile man/env.5 man/lg.conf.5 man/lg_intro.1 \
diff --git a/configure.in b/configure.in
index dbd4cfb..9d34f4a 100644
--- a/configure.in
+++ b/configure.in
@@ -177,7 +177,7 @@ rd_cv_rd_bin_datas=$RD_BIN_DATAS
# RD_BIN_PROGS are bin/ .in's that need to be installed with execute perms.
RD_BIN_PROGS="cat5rancid control_rancid \
alogin arancid clogin create_cvs blogin brancid do-diffs elogin erancid \
-flogin francid jlogin jrancid hlogin hrancid mrancid par rancid-fe \
+f10rancid flogin francid jlogin jrancid hlogin hrancid mrancid par rancid-fe \
rancid rename rrancid xrancid"
AC_SUBST(RD_BIN_PROGS)
rd_cv_rd_bin_progs=$RD_BIN_PROGS
@@ -236,8 +236,8 @@ AC_SUBST(ENV_PATH)
AC_OUTPUT([ Makefile include/Makefile bin/Makefile util/Makefile \
bin/alogin bin/arancid bin/blogin bin/brancid bin/cat5rancid \
bin/clogin bin/control_rancid bin/create_cvs bin/do-diffs bin/elogin \
- bin/env bin/erancid bin/flogin bin/francid bin/jlogin bin/jrancid \
- bin/hlogin \
+ bin/env bin/erancid bin/f10rancid bin/flogin bin/francid bin/jlogin \
+ bin/jrancid bin/hlogin \
bin/hrancid bin/mrancid bin/par bin/rancid-fe bin/rancid bin/rename \
bin/rrancid bin/xrancid \
man/Makefile man/env.5 man/lg.conf.5 man/lg_intro.1 \
diff --git a/include/config.h b/include/config.h
index 50a84e7..5ab2ffb 100644
--- a/include/config.h
+++ b/include/config.h
@@ -98,7 +98,7 @@
#define PACKAGE "rancid"
/* Version number of package */
-#define VERSION "2.2"
+#define VERSION "2.2.1"
/* Define if compiler has function prototypes */
#define PROTOTYPES 1
diff --git a/include/version.h b/include/version.h
index d70f183..685d3c8 100644
--- a/include/version.h
+++ b/include/version.h
@@ -4,6 +4,6 @@
/* pkg version */
char package[] = "rancid";
-char version[] = "2.2";
+char version[] = "2.2.1";
#endif
diff --git a/include/version.h.in b/include/version.h.in
index d70f183..685d3c8 100644
--- a/include/version.h.in
+++ b/include/version.h.in
@@ -4,6 +4,6 @@
/* pkg version */
char package[] = "rancid";
-char version[] = "2.2";
+char version[] = "2.2.1";
#endif
diff --git a/man/Makefile.am b/man/Makefile.am
index b9e5b04..d499951 100644
--- a/man/Makefile.am
+++ b/man/Makefile.am
@@ -9,9 +9,9 @@ man_gen_MANS = env.5 lg.conf.5 lg_intro.1
man_nogen_MANS = do-diffs.1 alogin.1 blogin.1 clogin.1 control_rancid.1 \
create_cvs.1 rancid.1 \
rancid_intro.1 cloginrc.5 router.db.5 \
- elogin.1 flogin.1 hlogin.1 hrancid.1 jlogin.1 \
- jrancid.1 francid.1 cat5rancid.1 erancid.1 mrancid.1 \
- par.1 xrancid.1
+ elogin.1 f10rancid.1 flogin.1 hlogin.1 hrancid.1 jlogin.1 \
+ jrancid.1 f10rancid.1 francid.1 cat5rancid.1 erancid.1 \
+ mrancid.1 par.1 xrancid.1
man_MANS = $(man_gen_MANS) $(man_nogen_MANS)
diff --git a/man/Makefile.in b/man/Makefile.in
index ae55555..0c9bc06 100644
--- a/man/Makefile.in
+++ b/man/Makefile.in
@@ -98,7 +98,7 @@ VERSION = @VERSION@
AUTOMAKE_OPTIONS = foreign no-dependencies
man_gen_MANS = env.5 lg.conf.5 lg_intro.1
-man_nogen_MANS = do-diffs.1 alogin.1 blogin.1 clogin.1 control_rancid.1 create_cvs.1 rancid.1 rancid_intro.1 cloginrc.5 router.db.5 elogin.1 flogin.1 hlogin.1 hrancid.1 jlogin.1 jrancid.1 francid.1 cat5rancid.1 erancid.1 mrancid.1 par.1 xrancid.1
+man_nogen_MANS = do-diffs.1 alogin.1 blogin.1 clogin.1 control_rancid.1 create_cvs.1 rancid.1 rancid_intro.1 cloginrc.5 router.db.5 elogin.1 f10rancid.1 flogin.1 hlogin.1 hrancid.1 jlogin.1 jrancid.1 f10rancid.1 francid.1 cat5rancid.1 erancid.1 mrancid.1 par.1 xrancid.1
man_MANS = $(man_gen_MANS) $(man_nogen_MANS)
diff --git a/man/control_rancid.1 b/man/control_rancid.1
index 8bd719f..e6ca10e 100644
--- a/man/control_rancid.1
+++ b/man/control_rancid.1
@@ -6,6 +6,9 @@ control_rancid \- run rancid for devices of a group
.SH SYNOPSIS
.B create_cvs
[\c
+.BI \-m\ \c
+mail_rcpt]\ \c
+[\c
.BI \-r\ \c
device_name]\ \c
group
@@ -22,14 +25,27 @@ e-mail diffs, and e-mail error reports.
.\"
The command-line options are as follows:
.TP
+.B \-m mail_rcpt
+Specify the recipient of diff mail, which is normally rancid-<group>. The
+argument may be a single address, multiple comma separated addresses, or
+.B \-m
+may be specified multiple times.
+.\"
+.TP
.B \-r device_name
Specify the name, as it appears in the router.db, of a particular device
to collect and generate diffs for. The device must be marked "up".
+.sp
+The
+.B \-r
+option alters the subject line of the diff mail. It will begin
+with <group name>/<device name> rather than just the group name alone.
.\"
.PP
.B control_rancid
is normally (and best) run via
-.BR do-diffs (1).
+.BR do-diffs (1)
+which provides a locking mechanism on a group basis.
.\"
.SH SEE ALSO
.BR do-diffs (1),
diff --git a/man/do-diffs.1 b/man/do-diffs.1
index 6202227..97b9664 100644
--- a/man/do-diffs.1
+++ b/man/do-diffs.1
@@ -6,6 +6,9 @@ do-diffs \- run rancid for each of the groups
.SH SYNOPSIS
.B do-diffs
[\c
+.BI \-m\ \c
+mail_rcpt]\ \c
+[\c
.BI \-r\ \c
device_name]\ \c
[group [group ...]]
@@ -60,11 +63,23 @@ For example:
.\"
The command-line options are as follows:
.TP
+.B \-m mail_rcpt
+Specify the recipient of diff mail, which is normally rancid-<group>. The
+argument may be a single address, multiple comma separated addresses, or
+.B \-m
+may be specified multiple times.
+.\"
+.TP
.B \-r device_name
Specify the name, as it appears in a group's router.db, of a particular
device to collect and generate diffs for. The device must be marked "up".
If a group is not specified on the command-line, rancid will be run
against any group in which the device_name appears.
+.sp
+The
+.B \-r
+option alters the subject line of the diff mail. It will begin
+with <group name>/<device name> rather than just the group name alone.
.\"
.SH ENVIRONMENT
.B do-diffs
diff --git a/man/f10rancid.1 b/man/f10rancid.1
new file mode 100644
index 0000000..b4633ee
--- /dev/null
+++ b/man/f10rancid.1
@@ -0,0 +1 @@
+.so man1/rancid.1
diff --git a/man/rancid.1 b/man/rancid.1
index 4d4ba51..fe8d618 100644
--- a/man/rancid.1
+++ b/man/rancid.1
@@ -28,6 +28,7 @@ Alteon WebOS switches,
Bay Networks (nortel),
Cisco catalyst switch,
ADC-kentrox EZ-T3 mux,
+Force10,
Foundry,
HP Procurve Switches,
Juniper,
@@ -39,6 +40,7 @@ named
.B brancid,
.B cat5rancid,
.B erancid,
+.B f10rancid,
.B francid,
.B hrancid,
.B jrancid,
diff --git a/man/rancid_intro.1 b/man/rancid_intro.1
index f392fd5..d180019 100644
--- a/man/rancid_intro.1
+++ b/man/rancid_intro.1
@@ -7,8 +7,8 @@ rancid_intro \- introduction to the Really Awesome New Cisco confIg Differ
.B rancid
is really more than just a Cisco configuration differ. It handles several
different device's configurations; currently including Alteon, Bay Networks
-(nortel), Cisco, Extreme, Foundry, HP Procurve switches, Juniper, Redback,
-MRTd daemon, and the ADC-Kentrox EZ-T3 mux.
+(Nortel), Cisco, Extreme, Force10, Foundry, HP Procurve switches,
+Juniper, Redback, MRTd daemon, and the ADC-Kentrox EZ-T3 mux.
.PP
.B rancid
uses an expect script to login to each of a list of devices and run a set of
diff --git a/man/router.db.5 b/man/router.db.5
index 2e12d14..a568243 100644
--- a/man/router.db.5
+++ b/man/router.db.5
@@ -59,8 +59,8 @@ A cisco catalyst series 5000 and 4000 switches (ie: running the catalyst OS,
not IOS).
.TP
.B cisco
-A cisco router or switch such as the 3500XL or 6000 running IOS (or IOS-like)
-OS.
+A cisco router, PIX, or switch such as the 3500XL or 6000 running IOS (or
+IOS-like) OS.
.TP
.B extreme
An Extreme switch.
@@ -68,6 +68,9 @@ An Extreme switch.
.B ezt3
An ADC-Kentrox EZ-T3 mux.
.TP
+.B force10
+A Force10 router.
+.TP
.B foundry
A Foundry router, switch, or router-switch. This includes HP
Procurve switches that are OEMs of Foundry products, such as the
diff --git a/util/lg/lg.cgi.in b/util/lg/lg.cgi.in
index 714c6cc..fe07c58 100755
--- a/util/lg/lg.cgi.in
+++ b/util/lg/lg.cgi.in
@@ -276,6 +276,7 @@ $router_param = ($query->param('router'))[0];
$remote_user = $ENV{REMOTE_USER};
$arg = ($query->param('args'))[0];
# handle multiple args
+$arg =~ s/["'`]//g; # these are BS in any arg for any query
@arg = split(' ', $arg);
# verify commands, arguments, etc.
@@ -342,7 +343,7 @@ if (!defined($type) || !defined($router)) {
mneighbor => "show bgp neighbor",
neighbor => "show bgp neighbor",
regex => "show route table inet.0 aspath-regex",
- route => "show route forwarding-table destination",
+ route => "show route table inet.0 terse",
routemap => "show policy",
ping => "ping rapid count 5",
prefix => "show route table inet.0",
@@ -457,7 +458,7 @@ if ($type eq "prefix" || $type eq "mbgp" || $type eq "route" ) {
}
} elsif ($type eq "ping" || $type eq "trace") {
if ($arg[0] !~ /^\d+\.\d+\.\d+\.\d+$/) {
- if ($arg[0] !~ /([A-Za-z0-9-]*.)*[A-Za-z0-9-]*.(com|edu|net|org)/) {
+ if ($arg[0] !~ /^[A-Za-z0-9._-]+$/) {
$results[0] = "That argument ($arg[0]) is not valid.\n";
&print_results($mfg);
}