summaryrefslogtreecommitdiffstats
path: root/util
diff options
context:
space:
mode:
Diffstat (limited to 'util')
-rw-r--r--util/Makefile.in4
-rw-r--r--util/cisco-load.exp331
-rw-r--r--util/cisco-reload.exp141
-rwxr-xr-xutil/downreport.in9
-rw-r--r--util/lg/README8
-rwxr-xr-xutil/lg/lg.cgi.in248
-rw-r--r--util/lg/lg.conf.in75
-rwxr-xr-xutil/lg/lgform.cgi.in29
-rw-r--r--util/lg/lgnotes.html15
-rw-r--r--util/rtrfilter.README2
-rwxr-xr-xutil/rtrfilter.in15
11 files changed, 776 insertions, 101 deletions
diff --git a/util/Makefile.in b/util/Makefile.in
index 511cb7f..445c86b 100644
--- a/util/Makefile.in
+++ b/util/Makefile.in
@@ -11,7 +11,7 @@ install: all
for file in $(UTIL_PROGS) ; do \
$(INSTALL) $$file $(PREFIX)/util; \
done; \
- for file in *README*; do \
+ for file in *README* *.exp; do \
$(INSTALL_DATA) $$file $(PREFIX)/util; \
done; \
cd lg; $(MAKE) -e install
@@ -27,7 +27,7 @@ distclean: clean
rm -f config.log config.status
distdir:
- for file in Makefile.in configure.in *README* ; do \
+ for file in Makefile.in configure.in *README* *.exp; do \
$(INSTALL_DATA) $$file $(distdir); \
done; \
for file in configure $(UTIL_PROGS:=.in) ; do \
diff --git a/util/cisco-load.exp b/util/cisco-load.exp
new file mode 100644
index 0000000..58277e2
--- /dev/null
+++ b/util/cisco-load.exp
@@ -0,0 +1,331 @@
+##
+## 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.
+#
+# this expect snipit is sourced by clogin (-s option) to load a configuration
+# file (named <routername>-confg into nvram from an rcp/tftp host. this is an
+# _example_ as it not guaranteed to work for all applications. PLEASE test
+# for your environment.
+#
+# it expects the following variables via the -E option:
+# rcphost ='host to rcp from' such as 'foo.org' or '192.168.0.1'
+# confgpath ='path under /tftpboot where configs are held'
+#
+# the config file is expected to be routername-confg, where routername is the
+# name as grok'd from the router's cmd-line prompt
+#
+# example usage:
+# % clogin -s ./cisco-load.exp -Ercphost=foo.shrubbery.net router
+# router
+# loading router config from foo.shrubbery.net
+#
+# keep in mind that it is important to NOT polute the global variable space.
+# particularly, do not use variables used within clogin. this may result in
+# indeterministic results. an easy way to avoid this is to use a variable
+# name prefix (like 'E' or '_').
+#
+# useful variables from clogin global space:
+# router router name as provided on the cmd-line
+# prompt cmd-line prompt as determined by clogin
+#
+# note: the tcl/expect parser is extremely stoopid. comment lines are NOT
+# completely ignored!! so, a '{' or '}' in a comment might produce
+# unexpected results.
+##
+# log_user 1
+# exp_internal 1
+
+# sometimes this is a bit slow. note: this overrides clogin -t
+set timeout 90
+
+# take rcp host from -Ercphost='foo'
+if ([info exists Ercphost]) {
+ #puts "CONFGHOST == $Ercphost"
+ set confghost [string tolower $Ercphost]
+} else {
+ send_error "ERROR: -Ercphost= was not set on the command-line.\n"
+ exit
+}
+
+#
+# logout of the router
+#
+proc logout { ecode } {
+ global prompt
+
+ send "quit\r"
+ expect {
+ "$prompt" { logout $ecode }
+ timeout { send_error "Error: timeout waiting for EOF after quit\n"}
+ eof {
+ send_user "\n"
+ exit $ecode }
+ }
+}
+
+#
+# erase the nvram
+#
+proc erase { } {
+ global prompt
+
+ send "\r"
+ expect $prompt {}
+ send "write erase\r"
+ expect {
+ -re " Continue\[^\n\]\*confirm\]" {
+ send "\r"
+ exp_continue }
+ "$prompt" { }
+ timeout {
+ send_error "Error: timeout waiting for write erase.\n"
+ logout 1 }
+ eof { logout 1 }
+ }
+}
+
+#
+# load a config via rcp into nvram
+#
+proc doload { confghost routername config retry } {
+ global prompt
+
+ # send a return just to be sure we have a prompt.
+ send "\r"
+ expect "$prompt"
+ # start the copy and send the host to load from
+ # use tftp if retry == 1
+ if { $retry == 0 } {
+ send "copy tftp startup-config\r"
+ } else {
+ send "copy rcp startup-config\r"
+ }
+ expect {
+ timeout {
+ send_error "\nError: timeout exceeded waiting for rcp/tftp host prompt\r"
+ logout 1 }
+ "mbiguous command" {
+ if { $retry == 0 } {
+ send "copy tftp: startup-config\r"
+ } else {
+ send "copy rcp: startup-config\r"
+ }
+ exp_continue }
+ -re "Host or network .*\]\?" {
+ send "host\r"
+ exp_continue }
+ "\]\?" {
+ send "$confghost\r" }
+ }
+
+ #
+ # fill in the rest of the blanks. username (12.0), filename, dest, etc.
+ #
+ expect {
+ -re "Source username .\*\]\?" {
+ send "$routername\r";
+ exp_continue }
+ -re "Source filename .\*\]\?" {
+ send "$config\r";
+ exp_continue }
+ -re "Name of configur.\*\]\?" {
+ send "$config\r";
+ exp_continue }
+ -re "Destination filename .\*\]\?" {
+ send "startup-config\r";
+ exp_continue }
+ -re "Configure using .\*confirm\]" { send "\r" }
+ "proceed\? \\\[" { send "yes\r" }
+ -re "Do you want to over write.\*confirm\]" { send "\r" }
+ -re "Accessing (rcp|tftp):" { }
+ timeout {
+ send_error "\n\tError: timeout exceeded while matching load prompts\n";
+ send "" }
+ }
+
+ expect {
+ timeout {
+ send_error "Error: timeout exceeded while loading config\n"
+ logout 1 }
+ -re "\[^\n\]*Connection refused" {
+ send_error "Error: $expect_out(0,string)\n"
+ logout 1 }
+ -re "\[^\n\]*Destination unreachable" {
+ send_error "Error: $expect_out(0,string)\n"
+ logout 1 }
+ -re "\[^\n\]*Permission denied" {
+ send_error "Error: $expect_out(0,string)\n"
+ logout 1 }
+ -re "\[^\n]*No such file or directory" {
+ send_error "Error: $expect_out(0,string)\n"
+ logout 1 }
+ -re "\[^\n]*Error copying\[^\n]*Not enough space on device\[^\n]*\r" {
+ send_error "Error: $expect_out(0,string)\n"
+ if { $retry == 2 } {
+# erase stomps ssh rsa key
+# send_user "erasing nvram\n"
+# erase
+ send_user "retrying load\n"
+ doload $confghost $routername $config 1
+ } elseif { $retry == 1 } {
+# erase stomps ssh rsa key
+# send_user "erasing nvram\n"
+# erase
+ send_user "retrying load with tftp.\n"
+ doload $confghost $routername $config 0
+ } else {
+ send_error "Error: $expect_out(0,string)\n"
+ logout 1
+ } }
+ -re "\[^\n]*.*configuration is too large.*\n" {
+ send_error "Error: $expect_out(0,string)\n"
+ expect {
+ -re "\[^\n]*Truncate config.*:" { send "no\r" }
+ }
+ logout 1 }
+ -re "\[^\n]*Error (opening|copying).*\r" {
+ send_error "Error: $expect_out(0,string)\n"
+ logout 1 }
+ -nocase -re "\[^\n]* error\[^a-z\n]+\[^\n]*" {
+ send_error "$expect_out(0,string)\n"
+ logout 1 }
+ "\n" { exp_continue }
+ -re "^\[^ ]*\#" {
+ send_user "load successful.\n"
+ }
+ }
+
+ return 0;
+}
+
+send_user "loading $router config from $confghost\n";
+
+# look for router hostname in prompt (ie: deal with fqdn)
+send "\r"
+expect {
+ timeout {
+ send_error "Error: did not receive prompt\n"
+ exit }
+ "\n" { exp_continue }
+ -re "^(\[^ ]*)\#" {
+ set routername $expect_out(1,string) }
+}
+
+# deal with config subdir? from Econfgpath
+if ([info exists confgpath]) {
+ set config "$confgpath/$routername-confg"
+} else {
+ set config "$routername-confg"
+}
+
+# load the config
+if { [doload $confghost $routername $config 1] != 0 } {
+ logout 1
+}
+
+logout 0
+
+# these were my original transcripts of performing loads. it is a useful
+# example of info you may collect to get an idea of what needs to be handled
+# in the expect{}s
+#
+# pdx-oob#
+# pdx-oob#copy rcp start
+# Address of remote host [255.255.255.255]? 205.238.52.35
+# Name of configuration file [a]? pdx-oob-confg
+# Configure using pdx-oob-confg from 205.238.52.35? [confirm]
+#
+# Connected to 205.238.52.35
+# Loading 8131 byte file pdx-oob-confg: !!!! [OK]
+# Compressing configuration from 8131 bytes to 3886 bytes
+# [OK]
+# pdx-oob#
+#
+
+# 12.0S-isms
+# pao2#cop rcp sta
+# Address or name of remote host []? eng0
+# Translating "eng0"...domain server (205.238.52.46) [OK]
+#
+# Source username [pao2]?
+# Source filename []? pao2-confg
+# Destination filename [startup-config]?
+# Warning: Copying this config directly into the nvram from a network server may
+# cause damage the the startup config. It is advisable to copy the file
+# into the running config first, and then save it using copy run start.
+# Do you wish to proceed? [no]: yes
+# Accessing rcp://pao2@eng0/pao2-confg...
+# Connected to 205.238.52.35
+# Loading 30138 byte file pao2-confg: !!!!!! [OK]
+#
+# 30138 bytes copied in 2.576 secs (15069 bytes/sec)
+# pao2#
+# OR IS IT
+# sea0#cop rcp sta
+# Address or name of remote host []? eng0
+# Source username [sea0]?
+# Source filename []? sea0-confg
+# Destination filename [startup-config]?
+# Accessing rcp://sea0@eng0/sea0-confg...!!!!!!!!!!!!!!!!!!
+# 89794 bytes copied in 0.704 secs
+# sea0#q
+# Connection closed by foreign host.
+
+# pdx-oob#copy rcp start
+# Address of remote host [255.255.255.255]? 205.238.52.35
+# Name of configuration file [a]? pdx-oob-confg
+# Configure using pdx-oob-confg from 205.238.52.35? [confirm]
+#
+# Connected to 205.238.52.35
+# Loading 8131 byte file pdx-oob-confg: !!!! [OK]
+# Compressing configuration from 8131 bytes to 3886 bytes
+# [OK]
+# pdx-oob#copy rcp start
+# Address of remote host [205.238.52.35]? 205.238.52.35
+# Name of configuration file [pdx-oob-confg]? pdx-oob-confg
+# Configure using pdx-oob-confg from 205.238.52.35? [confirm]
+#
+# Connected to 205.238.52.35
+# %rcp: /tftpboot/pdx-oob-confg: No such file or directory
+# pdx-oob#
+#
+
+# pdx-oob#copy rcp start
+# Address of remote host [205.238.52.35]? 205.238.52.35
+# Name of configuration file [pdx-oob-confg]? pdx-oob-confg
+# Configure using pdx-oob-confg from 205.238.52.35? [confirm]
+#
+# Connected to 205.238.52.35
+# %rcp: /tftpboot/pdx-oob-confg: Permission denied
+# pdx-oob#
+#
+
+# *** response from filtered pkt
+# pdx-oob#copy rcp sta
+# Address of remote host [205.238.52.35]? 205.238.1.94
+# Name of configuration file [pdx-oob-confg]?
+# Configure using pdx-oob-confg from 205.238.1.94? [confirm]
+# % Destination unreachable; gateway or host down
+#
+# pdx-oob#
+#
+
+# *** response from host w/o rcp daemon
+# pdx-oob#cop rcp sta
+# Address of remote host [205.238.52.35]? 205.238.1.66
+# Name of configuration file [pdx-oob-confg]?
+# Configure using pdx-oob-confg from 205.238.1.66? [confirm]
+# % Connection refused by remote host
+#
+# pdx-oob#
+#
diff --git a/util/cisco-reload.exp b/util/cisco-reload.exp
new file mode 100644
index 0000000..095a3b2
--- /dev/null
+++ b/util/cisco-reload.exp
@@ -0,0 +1,141 @@
+##
+## 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.
+#
+# this expect snipit is sourced by clogin (-s option) to issue a reload
+# command on a cisco router. it DOES NOT save the config if it has been
+# modified. this is an _example_ as it not guaranteed to work for all
+# applications. PLEASE test for your environment.
+#
+# it expects the following variables via the -E option:
+# reload_arg ='command argument' such as 'at 05:00' or 'cancel
+#
+# eg usage:
+# % clogin -s cisco-reload.exp -Ereload_arg='at 01:00' router
+# router
+# Reload scheduled for 01:00:00 UTC Sat Jun 23 2001 (in 7 hours and 16 minutes)
+# % clogin -s cisco-reload.exp -Ereload_arg='at cancel' router
+# router
+# % Ambiguous command: "reload at cancel"
+#
+# % clogin -s cisco-reload.exp -Ereload_arg='cancel' router
+# router
+# SHUTDOWN ABORTED
+#
+#
+# keep in mind that it is important to NOT polute the global variable space.
+# particularly, do not use variables used within clogin. this may result in
+# indeterministic results. an easy way to avoid this is to use a variable
+# name prefix (like 'E' or '_').
+#
+# useful variables from clogin global space:
+# router router name as provided on the cmd-line
+# prompt cmd-line prompt as determined by clogin
+#
+# note: the tcl/expect parser is extremely stoopid. comment lines are NOT
+# completely ignored!! so, a '{' or '}' in a comment might produce
+# unexpected results.
+##
+# exp_internal 1
+# log_user 1
+
+# take reload command from -Ereload_arg='at 05:00'
+if ([info exists Ereload_arg]) {
+ #puts "reload_arg == $Ereload_arg"
+ set reloadcmd "reload $Ereload_arg"
+} else {
+ send_error "ERROR: -Ereload_arg= was not set on the command-line.\n"
+ exit
+}
+
+#send_user "$router\n"
+
+send "\r"
+expect {
+ timeout { send_error "Error: did not receive prompt\n"
+ exit }
+ -re "^.*$prompt" { send "$reloadcmd\r"
+ expect * {} }
+}
+# look for response
+expect {
+ -re "configuration has been modified.*no.:" { send "no\r";
+ exp_continue }
+ -re "Reload scheduled .*\r" { set sched $expect_out(0,string)
+ exp_continue }
+ -re "SHUTDOWN ABORTED" { set sched $expect_out(0,string) }
+ -re "Proceed with .*confirm\]" { send "\r" }
+ -re "\n.*No reload " { set sched "no reload scheduled"
+ send "\r" }
+ -re "% Ambig\[^\n\r]*" { set sched $expect_out(0,string) }
+}
+send "\r"
+expect "$prompt"
+if ([info exists sched]) {
+ send_user "\t$sched\n"
+}
+send "quit\r"
+expect {
+ timeout { send_error "Error: timeout waiting for EOF after quit\n"}
+ eof { exit 0 }
+}
+
+## dennis#reload in ?
+## Delay before reload (mmm or hhh:mm)
+##
+## dennis#reload in 100:10
+##
+## System configuration has been modified. Save? [yes/no]: no
+## Reload scheduled in 100 hours and 9 minutes
+## Proceed with reload? [confirm]
+## dennis#reload ca
+## dennis#reload cancel
+## dennis#
+##
+##
+## ***
+## *** --- SHUTDOWN ABORTED ---
+## ***
+##
+## dennis#wr
+## Building configuration...
+## [OK]
+## dennis#reload in 100:10
+## Reload scheduled in 100 hours and 10 minutes
+## Proceed with reload? [confirm]
+## dennis#rel
+## dennis#reload can
+## dennis#reload cancel
+## dennis#
+##
+##
+## ***
+## *** --- SHUTDOWN ABORTED ---
+## ***
+## System configuration has been modified. Save? [yes/no]: no
+## Reload scheduled for 11:51:48 PST Thu Dec 10 1998 (in 299 hours and 59 minutes)
+## Proceed with reload? [confirm]
+## ultra#reload can
+## ultra#
+##
+##
+## ***
+## *** --- SHUTDOWN ABORTED ---
+## ***
+## ultra# reload at 8:10 10 dec
+##
+## System configuration has been modified. Save? [yes/no]: no
+## Reload scheduled for 08:10:00 PST Thu Dec 10 1998 (in 296 hours and 17 minutes)
+## Proceed with reload? [confirm]
+## ultra#
+##
diff --git a/util/downreport.in b/util/downreport.in
index 2926c5c..edb3ae0 100755
--- a/util/downreport.in
+++ b/util/downreport.in
@@ -3,7 +3,7 @@
# Reports the list of routers not listed as 'up'.
# Put this in your crontab to run once a day:
-# 0 0 * * * /where/rancid/lives/util/downreport
+# 0 0 * * * @prefix@/util/downreport
# It can optionally
# take a space list of groups on the command line
@@ -24,6 +24,10 @@ fi
for GROUP in $LIST_OF_GROUPS; do
(
+ echo "To: @MAILPLUS@admin-$GROUP"
+ echo "Subject: Down router report - $GROUP"
+ echo "Precedence: bulk"
+ echo ""
DIR=$BASEDIR/$GROUP
if [ -s $DIR/routers.down ]; then
(
@@ -53,7 +57,6 @@ EOM
)
fi
- ) |\
- Mail -s "Down router report - $GROUP" @MAILPLUS@admin-$GROUP
+ ) | sendmail -t
done
diff --git a/util/lg/README b/util/lg/README
index b4186b9..183dd15 100644
--- a/util/lg/README
+++ b/util/lg/README
@@ -1,9 +1,9 @@
This is a looking glass based on Ed Kern's which can be found on
-http://nitrous.digex.net/. This version supports cisco and
-juniper, uses rancid's [cj]login to login (so rcmd is not necessary,
+http://nitrous.digex.net/. This version supports cisco, juniper, and
+foundry, useing rancid's [cfj]login to login (so rcmd is not necessary,
it can use telnet, ssh, or rsh), and has some additional commands
-implemented. There are a few cisco commands where either no juniper
-exists or we have not had time to implement yet.
+implemented. There are a few cisco commands where either no juniper or
+foundry equivalent exists or we have not had time to implement yet.
packing list:
README This file.
diff --git a/util/lg/lg.cgi.in b/util/lg/lg.cgi.in
index 0900060..1e37b20 100755
--- a/util/lg/lg.cgi.in
+++ b/util/lg/lg.cgi.in
@@ -1,4 +1,20 @@
#!@PERLV_PATH@
+## The original original lookingglass s/w was written by Ed Kern. it
+## is a single script and can be found at http://nitrous.digex.net/
+#
+## 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.
+#
# Looking glass
# vars: query, router, args
@@ -76,7 +92,7 @@ sub dolog
# run commands on the router
sub DoRsh
{
- my ($router, $mfg, $type, $arg) = @_;
+ my ($router, $mfg, $cmd, $arg) = @_;
my($ctime) = time();
my($lckobj) = LockFile::Simple->make(-delay => $lock_int,
@@ -93,32 +109,38 @@ sub DoRsh
if (! $lckobj->lock("$cache_dir/$router")) {
return ("$router is busy. Try again later.\n");
}
- @results = &DoCmd($router, $mfg, $type, $arg);
+ @results = &DoCmd($router, $mfg, $cmd, $arg);
$lckobj->unlock("$cache_dir/$router");
return (@results);
}
sub DoCmd
{
- my($rtr, $mfg, $type, $arg) = @_;
+ my($rtr, $mfg, $cmd, $arg) = @_;
local(*CMD);
- if ($mfg =~ /juniper/i) {
- open(CMD, "jlogin -f $cloginrc -c \'$juniperCmd{$type} $arg\' $rtr |");
+ if ($mfg =~ /foundry/i) {
+ open(CMD, "sh -c \"flogin -f $cloginrc -c \'$cmd $arg\' $rtr\" 2>&1 |");
+ $cmd = $foundryCmd{$type};
+ } elsif ($mfg =~ /juniper/i) {
+ open(CMD, "sh -c \"jlogin -f $cloginrc -c \'$cmd $arg\' $rtr\" 2>&1 |");
$cmd = $juniperCmd{$type};
} else {
- open(CMD, "clogin -noenable -f $cloginrc -c \'$ciscoCmd{$type} $arg\' $rtr |");
+ open(CMD, "sh -c \"clogin -noenable -f $cloginrc -c \'$cmd $arg\' $rtr\" 2>&1 |");
$cmd = $ciscoCmd{$type};
}
while (<CMD>) {
tr/\015//d;
if (/^error:/i) {
dolog(LOG_ERR, $_);
- return ($_);
+ if ($LG_STRIP) { undef(@results); }
+ push(@results, $_);
+ return (@results);
}
-# push(@results, $_);
+ push(@results, $_);
if (/$cmd/) {
($prompt) = /^(\S*)[\#>]/;
# push(@results, "prompt = $prompt\n\n");
+ if ($LG_STRIP) { undef(@results); }
last;
}
}
@@ -250,41 +272,67 @@ if (!defined($type) || !defined($router)) {
# conversion of command "type" passed from lgform.cgi to the vendor's syntax.
%ciscoCmd = (
- #acl => "sh access-list",
- #aspath => "sh ip as-path-access-list",
- #communitylist => "sh ip community-list",
- damp => "sh ip bgp dampened-paths",
- framerelay => "sh frame-relay pvc",
- interface => "sh interface",
- intbrief => "sh ip interface",
- log => "sh logging",
- mbgp => "sh ip mbgp",
- mbgpsum => "sh ip mbgp summary",
- regex => "sh ip bgp regex",
- route => "sh ip route",
- #routemap => "sh route-map",
+ #acl => "show access-list",
+ #aspath => "show ip as-path-access-list",
+ #communitylist => "show ip community-list",
+ damp => "show ip bgp dampened-paths",
+ framerelay => "show frame-relay pvc",
+ interface => "show interface",
+ intbrief => "show ip interface",
+ log => "show logging",
+ mbgp => "show ip mbgp",
+ mbgpsum => "show ip mbgp summary",
+ mneighbor => "show ip bgp neighbor",
+ neighbor => "show ip bgp neighbor",
+ regex => "show ip bgp regex",
+ route => "show ip route",
+ routemap => "show route-map",
+ ping => "ping",
+ prefix => "show ip bgp",
+ prefixlist => "show ip prefix-list",
+ summary => "show ip bgp summary",
+ trace => "traceroute"
+ );
+%foundryCmd = (
+ #acl => "show access-list",
+ #aspath => "show ip as-path-access-list",
+ #communitylist => "show ip community-list",
+ damp => "show ip bgp dampened-paths",
+ #framerelay => "show frame-relay pvc", # no frame relay
+ interface => "show interface",
+ log => "show log",
+ #mbgp => "show ip mbgp",
+ #mbgpsum => "show bgp summary",
+ #mneighbor => "show ip bgp neighbor",
+ neighbor => "show ip bgp neighbor",
+ #regex => "show ip bgp aspath-regex",
+ route => "show ip route",
+ routemap => "show route-map",
ping => "ping",
- prefix => "sh ip bgp",
- prefixlist => "sh ip prefix-list",
- summary => "sh ip bgp summary",
+ prefix => "show ip bgp",
+ prefixlist => "show ip prefix-list",
+ summary => "show ip bgp summary",
trace => "traceroute"
);
%juniperCmd = (
- #acl => "sh access-list",
- #aspath => "sh ip as-path-access-list",
- #communitylist => "sh ip community-list",
+ #acl => "show access-list",
+ #aspath => "show ip as-path-access-list",
+ #communitylist => "show ip community-list",
damp => "show route damping suppressed terse table inet.0",
- interface => "sh interface",
+ framerelay => "show frame-relay pvc",
+ interface => "show interface",
log => "show log messages",
- mbgp => "sh route table inet.2 terse",
- mbgpsum => "sh bgp summary",
- #regex => "sh route table inet.0 aspath-regex",
- route => "sh route table inet.0",
- #routemap => "sh route-map",
+ mbgp => "show route table inet.2 terse",
+ mbgpsum => "show bgp summary",
+ mneighbor => "show bgp neighbor",
+ neighbor => "show bgp neighbor",
+ regex => "show route table inet.0 aspath-regex",
+ route => "show route forwarding-table destination",
+ routemap => "show policy",
ping => "ping rapid count 5",
- prefix => "sh route table inet.0",
- #prefixlist => "sh ip prefix-list",
- summary => "sh bgp summary",
+ prefix => "show route table inet.0",
+ prefixlist => "show policy",
+ summary => "show bgp summary",
trace => "traceroute"
);
%cmdDisp = (
@@ -292,12 +340,16 @@ if (!defined($type) || !defined($router)) {
#aspath => "show ip as-path-access-list",
#communitylist => "show ip community-list",
damp => "show ip bgp dampened-paths",
+ framerelay => "show frame-relay pvc",
+ interface => "show interface",
log => "show logging",
mbgp => "show ip mbgp",
mbgpsum => "show ip mbgp summary",
+ mneighbor => "show ip mbgp neighbor",
+ neighbor => "show ip bgp neighbor",
regex => "show ip bgp regex",
route => "show ip route",
- #routemap => "show route-map",
+ routemap => "show route-map",
ping => "ping",
prefix => "show ip bgp",
prefixlist => "show ip prefix-list",
@@ -306,9 +358,20 @@ if (!defined($type) || !defined($router)) {
);
# not all cmds/queries are implemented for junipers
-if ($mfg =~ /juniper/ && ! defined($juniperCmd{$type})) {
- $results[0] = "$cmdDisp{$type} not implemented for junipers. sorry.\n";
- &print_results;
+if ($mfg =~ /juniper/) {
+ if (! defined($juniperCmd{$type})) {
+ $results[0] = "$cmdDisp{$type} not implemented for junipers. sorry.\n";
+ &print_results;
+ }
+ $cmd = $foundryCmd{$type};
+} elsif ($mfg =~ /foundry/) {
+ if(! defined($foundryCmd{$type})) {
+ $results[0] = "$cmdDisp{$type} not implemented for foundrys. sorry.\n";
+ &print_results;
+ }
+ $cmd = $foundryCmd{$type};
+} else {
+ $cmd = $ciscoCmd{$type};
}
@@ -324,6 +387,11 @@ if ($type eq "prefix" || $type eq "mbgp" || $type eq "route" ) {
$arg = $arg[0] . "/" . mask2len($arg[1]);
}
} elsif ($type eq "framerelay") {
+ if ($mfg =~ /juniper/) {
+ $results[0] = "Juniper does not have a show frame-relay pvc command. ".
+ "Use show interface.\n";
+ &print_results;
+ }
if ($arg[0] > 15 && $arg[0] < 1024) {
$arg = $arg[0];
} else {
@@ -333,7 +401,7 @@ if ($type eq "prefix" || $type eq "mbgp" || $type eq "route" ) {
if ($arg[1] =~ /[-\/0-9:.]+/) {
$arg = $arg[0] . " " . $arg[1];
} else {
- if ($arg[0] =~ /^b/i && $mfg =~ /cisco/i) {
+ if ($arg[0] !~ /^b[^ ]+[0-9]/i && $arg[0] =~ /^b/i && $mfg =~ /(cisco|foundry)/i) {
$type = "intbrief";
$arg = "brief";
} else {
@@ -341,15 +409,17 @@ if ($type eq "prefix" || $type eq "mbgp" || $type eq "route" ) {
}
}
} elsif ($type eq "log") {
- $arg[0] =~ s/^\s*|//;
- if ($arg[0] =~ /^\s*$/) {
+ if ($arg[0] =~ /^\s*\|?$/) {
shift(@arg);
}
+ $arg[0] =~ s/^\s*\|?//;
if ($arg[0] !~ /^\s*$/) {
if ($mfg =~ /cisco/i) {
$arg = " | include " . join(' ', @arg);
} elsif ($mfg =~ /juniper/i) {
$arg = " | match \"" . join(' ', @arg) . "\"";
+ } else {
+ undef($arg);
}
} else {
undef($arg);
@@ -385,9 +455,11 @@ if ($type eq "prefix" || $type eq "mbgp" || $type eq "route" ) {
$arg = $arg[0];
} elsif ($type eq "regex") {
$arg = $arg[0];
- if ($#arg > 1) {
- for ($n = 1; $n <= $#arg - 1; $n++) { $arg .= " " . $arg[$n]; }
+ if ($#arg >= 1) {
+ for ($n = 1; $n <= $#arg; $n++) { $arg .= " " . $arg[$n]; }
}
+ # remove leading/trailing whitespace
+ $arg =~ s/^\s*//; $arg =~ s/\s*$//;
if ($arg !~ /^[0-9_ ^.*+?[\])\(-]*\$?$/ || $arg =~ /^\s*$/) {
$results[0] = "That argument ($arg[0]) is not valid.\n";
&print_results;
@@ -398,8 +470,86 @@ if ($type eq "prefix" || $type eq "mbgp" || $type eq "route" ) {
$results[0] = "Get real. Such a query has potential to over-burden our router.\nLook that up on your own router.\n";
&print_results;
}
- # escape any ()
+ if ($mfg =~ /juniper/) {
+ $arg =~ s/_/ /g;
+ # pre-junos 4.4 do not allow anchors
+ if ($arg =~ /\^\$/) {
+ $arg =~ "()";
+ } else {
+ $arg =~ s/[\$^]/ /g;
+ }
+ $arg = "\"$arg\"";
+ }
+ # escape any ()s
$arg =~ s/([\(\)])/\\$1/g;
+} elsif ($type eq "neighbor") {
+ if ($arg[0] !~ /^\d+\.\d+\.\d+\.\d+$/) {
+ if ($arg[0] !~ /([A-Za-z0-9-]*.)*[A-Za-z0-9-]*.(com|edu|net|org)/) {
+ $results[0] = "That argument ($arg[0]) is not valid.\n";
+ &print_results;
+ }
+ }
+ $arg = $arg[0];
+ if (defined($arg[1]) && $arg[1] =~ /^(a|ro|f|re)/) {
+ if ($mfg =~ /juniper/) {
+ if ($arg[1] =~ /^a/) {
+ if (defined($LG_BGP_RT)) {
+ $cmd = "show route table inet.0 all advertising-protocol ".
+ "bgp";
+ }
+ } elsif ($arg[1] =~ /^f/) {
+ if (defined($LG_BGP_RT)) {
+ $cmd = "show route damping table inet.0 all ".
+ "receive-protocol bgp";
+ }
+ } elsif ($arg[1] =~ /^r/) {
+ if (defined($LG_BGP_RT)) {
+ $cmd = "show route table inet.0 all receive-protocol bgp";
+ }
+ }
+ } else {
+ if ($arg[1] =~ /^a/) {
+ if (defined($LG_BGP_RT)) { $arg .= " advertised-routes"; }
+ } elsif ($arg[1] =~ /^f/) {
+ $arg .= " flap-statistics";
+ } elsif ($arg[1] =~ /^ro/) {
+ if (defined($LG_BGP_RT)) { $arg .= " routes"; }
+ } elsif ($arg[1] =~ /^re/) {
+ if (defined($LG_BGP_RT)) { $arg .= " received-routes"; }
+ }
+ }
+ }
+} elsif ($type eq "mneighbor") {
+ if ($arg[0] !~ /^\d+\.\d+\.\d+\.\d+$/) {
+ if ($arg[0] !~ /([A-Za-z0-9-]*.)*[A-Za-z0-9-]*.(com|edu|net|org)/) {
+ $results[0] = "That argument ($arg[0]) is not valid.\n";
+ &print_results;
+ }
+ }
+ $arg = $arg[0];
+ if (defined($arg[1]) && $arg[1] =~ /^(a|ro|f|re)/) {
+ if ($mfg =~ /juniper/) {
+ if ($arg[1] =~ /^a/) {
+ $cmd .= " advertised-routes";
+ } elsif ($arg[1] =~ /^f/) {
+ $cmd .= " flap-statistics";
+ } elsif ($arg[1] =~ /^ro/) {
+ $cmd .= " routes";
+ } elsif ($arg[1] =~ /^re/) {
+ $cmd .= " received-routes";
+ }
+ } else {
+ if ($arg[1] =~ /^a/) {
+ $arg .= " advertised-routes";
+ } elsif ($arg[1] =~ /^f/) {
+ $arg .= " flap-statistics";
+ } elsif ($arg[1] =~ /^ro/) {
+ $arg .= " routes";
+ } elsif ($arg[1] =~ /^re/) {
+ $arg .= " received-routes";
+ }
+ }
+ }
} elsif ($type eq "damp" || $type eq "summary" || $type eq "mbgpsum") {
undef($arg);
}
@@ -433,17 +583,17 @@ if ($type eq "summary" || $type eq "mbgpsu" || $type eq "damp" || $type eq "log"
# else, execute command and save to a new cache file
open(CACHE,">$file") || die "couldnt create cache file $file" ;
- @results = &DoRsh($router, $mfg, $type, $arg);
+ @results = &DoRsh($router, $mfg, $cmd, $arg);
print CACHE "@results";
close CACHE ;
} else {
- @results = &DoRsh($router, $mfg, $type, $arg);
+ @results = &DoRsh($router, $mfg, $cmd, $arg);
}
&print_results ;
} # end dampened-paths/flap-statistics
-@results = &DoRsh($router, $mfg, $type, $arg);
+@results = &DoRsh($router, $mfg, $cmd, $arg);
&print_results ;
exit ;
diff --git a/util/lg/lg.conf.in b/util/lg/lg.conf.in
index 7e8a96f..7b78c3f 100644
--- a/util/lg/lg.conf.in
+++ b/util/lg/lg.conf.in
@@ -2,11 +2,30 @@
#
# note: these are perl statements! mind the syntax
#
-# adjust the path to find [cj]login, telnet, ssh, rsh, etc.
+# adjust the path to find [cfj]login, telnet, ssh, rsh, etc.
#
$ENV{PATH}="@prefix@/bin:@ENV_PATH@";
#
#
+# LG_CACHE_DIR is the location of the cache directory. the LG uses this
+# to hold lock files, the default log file (lg.log), and o/p from
+# commands that can be very verbose. it defaults to "tmp",
+# ie: relative to the directory where lg.cgi runs in your
+# server's (httpd) DocumentRoot (eg: /usr/local/www/data/lg/tmp).
+#
+#$LG_CACHE_DIR="./tmp";
+#
+#
+# LG_CLOGINRC is the .cloginrc that the LG should use. it defaults to
+# <prefix>/.cloginrc. note that the .cloginrc must be readable
+# by the user or group (UID / GID) that will be running the CGI
+# and the clogin (and friends) will not allow a world readable
+# .cloginrc. this is normally the user the server (httpd) runs
+# under.
+#
+#$LG_CLOGINRC="@prefix@/.cloginrc";
+#
+#
# LG_IMAGE is the filename of an image you wish to appear at the top
# of the LG pages. it can also be other html goo, like
# the first example. this is just handed to print, so \n and
@@ -16,6 +35,17 @@ $ENV{PATH}="@prefix@/bin:@ENV_PATH@";
#$LG_IMAGE="<img src=rancid.gif hspace=0>\n";
#
#
+# LG_LOG is either a FQPN (fully qualified path name) the syslog
+# facility to use for logging. if not defined, the LG
+# will log to LG_CACHE_DIR/lg.log. possible syslog facility
+# values are from the facility codes in /usr/include/syslog.h
+# minus the 'LOG_' and lower case.
+#
+#$LG_LOG="$LG_CACHE_DIR/lg.log";
+#$LG_LOG="/tmp/lg.log";
+#$LG_LOG="local0";
+#
+#
# LG_ROUTERDB is the router.db in rancid's router.db format, listing
# the routers and their platform that should be available to
# the looking glass. if defined, the LG will use this variable
@@ -31,27 +61,19 @@ $ENV{PATH}="@prefix@/bin:@ENV_PATH@";
#$LG_ROUTERDB="@prefix@/util/lg/router.db";
#
#
-# LG_CLOGINRC is the .cloginrc that the LG should use. it defaults to
-# <prefix>/.cloginrc. note that the .cloginrc must readable
-# by the user or group (UID / GID) that will be running the CGI
-# and the clogin (and friends) will not allow a world readable
-# .cloginrc. this is normally the user the server (httpd) runs
-# under.
-#
-#$LG_CLOGINRC="@prefix@/.cloginrc";
+# Options:
#
+# LG_AS_REG *** not implemented.
#
-# LG_SINGLE *** not implemented.
-#$LG_SINGLE=0;
+#@LG_AS_REG=();
#
#
-# LG_CACHE_DIR is the location of the cache directory. the LG uses this
-# to hold lock files, lg.log log file, and o/p from commands
-# that can be very verbose. it defaults to "tmp", ie: relative
-# to the directory where lg.cgi runs in your server's (httpd's)
-# DocumentRoot (eg: /usr/local/www/data/lg/tmp).
+# LG_BGP_RT allows a few bgp commands which can produce long output (heavy
+# router load), such as sh ip bgp neighbor <ip> advertised-routes
+# for a transit customer, sh ip b neigh <ip> received-routes for
+# a transit provider.
#
-#$LG_CACHE_DIR="./tmp";
+#$LG_BGP_RT=1
#
#
# LG_CACHE_TIME is the number of seconds the LG should cache o/p from certain
@@ -62,18 +84,15 @@ $ENV{PATH}="@prefix@/bin:@ENV_PATH@";
#$LG_CACHE_TIME=600;
#
#
-# LG_LOG is either a FQPN (fully qualified path name) the syslog
-# facility to use for logging. if not defined, the LG
-# will log to LG_CACHE_DIR/lg.log. possible syslog facility
-# values are from the facility codes in /usr/include/syslog.h
-# minus the 'LOG_' and lower case.
-#
-#$LG_LOG="$LG_CACHE_DIR/lg.log";
-#$LG_LOG="/tmp/lg.log";
-#$LG_LOG="local0";
+# LG_SINGLE serializes and limits queries per-router to one at a time via
+# per-router lock files.
#
+#$LG_SINGLE=0;
#
-# LG_AS_REG *** not implemented.
+# $LG_STRIP strips login o/p from the looking glass results. Expect
+# occassionally screws up disabling echo when passwords are
+# entered (NOTE SECURITY CONCERN). However, this o/p can be
+# very useful for debugging clogin problems.
#
-#@LG_AS_REG=();
+$LG_STRIP=1;
#
diff --git a/util/lg/lgform.cgi.in b/util/lg/lgform.cgi.in
index 762c9d8..7fa7d0f 100755
--- a/util/lg/lgform.cgi.in
+++ b/util/lg/lgform.cgi.in
@@ -1,4 +1,17 @@
#!@PERLV_PATH@
+## 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.
+#
# lgform.cgi - Looking glass front-end
# produces html form for calling lg.cgi
@@ -75,7 +88,7 @@ sub readrouters
next if (/^\s*(#|$)/);
# fqdn:mfg:state
@record = split('\:', $_);
- next if ($record[2] !~ /up/i || $record[1] !~ /(cisco|juniper)/);
+ next if ($record[2] !~ /up/i || $record[1] !~ /(cisco|foundry|juniper)/);
push(@rtrlist, join(':', ($record[0], $record[1])));
$rtrlabels{join(':', ($record[0], $record[1]))} = $record[0];
}
@@ -91,7 +104,7 @@ sub readrouters
next if (/^\s*(#|$)/);
# fqdn:mfg:state
@record = split('\:', $_);
- next if ($record[2] !~ /up/i || $record[1] !~ /(cisco|juniper)/);
+ next if ($record[2] !~ /up/i || $record[1] !~ /(cisco|foundry|juniper)/);
push(@rtrlist, join(':', ($record[0], $record[1])));
$rtrlabels{join(':', ($record[0], $record[1]))} = $record[0];
}
@@ -140,14 +153,16 @@ print <<QTYPES ;
<dd><input type=radio name="query" value="framerelay">show frame-relay pvc [DLCI]</DD>
<dd><input type=radio name="query" value="interface">show interface &lt;interface&gt;</DD>
<dd><input type=radio name="query" value="prefix">show ip bgp &lt;prefix&gt; [netmask]</DD>
+<dd><input type=radio name="query" value="neighbor">show ip bgp neighbor &lt;IP_addr&gt;</DD>
<dd><input type=radio name="query" value="regex">show ip bgp regex &lt;reg_exp&gt;</DD>
<dd><input type=radio name="query" value="summary">show ip bgp summary</DD>
<dd><input type=radio name="query" value="damp">show ip bgp dampened-paths</DD>
<dd><input type=radio name="query" value="prefixlist">show ip prefix-list &lt;list_name&gt;</DD>
<dd><input type=radio name="query" value="route">show ip route &lt;prefix&gt; [netmask]</DD>
+<dd><input type=radio name="query" value="routemap">show route-map &lt;map_name&gt;</DD>
<dd><input type=radio name="query" value="mbgp">show ip mbgp &lt;prefix&gt; [netmask]</dd>
<dd><input type=radio name="query" value="mbgpsum">show ip mbgp summary</dd>
-<dd><input type=radio name="query" value="log">show logging [| &lt;match_string&gt;]</DD>
+<dd><input type=radio name="query" value="log">show logging [ | &lt;match_string&gt;]</DD>
<dd><input type=radio name="query" value="ping">ping &lt;IP_addr | FQDN&gt;</dd>
<dd><input type=radio name="query" value="trace">traceroute &lt;IP_addr | FQDN&gt;</DD>
@@ -159,14 +174,6 @@ print <<QTYPES ;
<dd>
QTYPES
-# unimplemented/disabled/removed query types.
-#
-# <dd>show ip bgp neighbor &lt;IP_addr&gt;</dd>
-# <dd>show ip bgp neighbor &lt;IP_addr&gt; advertised routes</dd>
-# <dd>show ip bgp neighbor &lt;IP_addr&gt; flap statistics</dd>
-# <dd>show ip bgp neighbor &lt;IP_addr&gt; received</dd>
-# <dd>show ip bgp neighbor &lt;IP_addr&gt; routes</dd>
-#
# <dd><input type=radio name="query" value="aspath">sh ip as-path-access-list &lt;list_number&gt;</DD>
# <dd><input type="radio" name="query" value="acl">sh access-list &lt;list_number&gt;</dd>
# <dd><input type=radio name="query" value="communitylist">sh ip community-list &lt;list_number&gt;<DD>
diff --git a/util/lg/lgnotes.html b/util/lg/lgnotes.html
index 44fb4e0..9f28ec3 100644
--- a/util/lg/lgnotes.html
+++ b/util/lg/lgnotes.html
@@ -14,13 +14,13 @@ size=+3><strong>&nbsp;&nbsp;&nbsp;Looking Glass Notes
<p>
<ul>
Just a few straight forward notes on our implementation of
-Ed Kern's looking glass. See the "real thing" at
+Ed Kern's looking glass. See the original at
<a href=http://nitrous.digex.net>http://nitrous.digex.net</a>.
</ul>
</p>
<p>
<UL>
-<li>Some items are not implemented for the junipers yet (so, as i get
+<li>Some items are not implemented for the junipers/foundrys yet (so, as i get
to it) or no equivalent command exists.
<li>If there is something which you feel is missing, feel free to ask
and/or send comments to <a href=mailto:rancid@shrubbery.net>
@@ -46,5 +46,16 @@ Ed Kern's looking glass. See the "real thing" at
and produce lots of output, such as 'sh ip bgp' or 'sh ip bgp reg '^3561'.
The looking glass attempts to deny such commands.</li>
</ul>
+<p>
+Some useful hints:
+<UL>
+<li>Show interfaces can take arguments other than an interface name, assuming
+ the router is running an O/S version with the capability. For example; a
+ cisco can take 'descriptions' or 'brief' and 'terse' for the juniper. </li>
+<li>Show ip bgp neighbor can take additional arguments (if configured to allow
+ it), such as 'advertised routes', 'flap-statistics', 'received-routes',
+ and 'routes'. The argument will be converted for the platform.</li>
+</ul>
+
</body>
</html>
diff --git a/util/rtrfilter.README b/util/rtrfilter.README
index bc98c4e..19b64c3 100644
--- a/util/rtrfilter.README
+++ b/util/rtrfilter.README
@@ -1,6 +1,6 @@
rtrfilter can be used to filter rancid diffs to avoid sending unwanted
diffs to certain recipient(s) or diffs which those recipient(s) should
-not see without the need to create a separate group(s).
+not see without the need to create separate or duplicate group(s).
/etc/aliases eg:
diff --git a/util/rtrfilter.in b/util/rtrfilter.in
index 8826047..28bd21a 100755
--- a/util/rtrfilter.in
+++ b/util/rtrfilter.in
@@ -1,5 +1,18 @@
#!@PERLV_PATH@
##
+## 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.
+#
# rtrtfilter - "| rtrfilter -x <perl regex> -i <perl regex> -f <regex file> \
# -u <From address> -s <subject> <rcpts>"
# expects to read an email message on stdin containing a diff from
@@ -25,7 +38,7 @@
# exclusion takes precedence and defaults to nothing. inclusion defaults to
# everything.
#
-# this program require the Mail::Mailer module which can be found on CPAN.
+# this program requires the Mail::Mailer module which can be found on CPAN.
##
BEGIN {
$me = $0;