From af496d2efa0969f29a22a4236c620f513eb90287 Mon Sep 17 00:00:00 2001 From: Tar Committer Date: Fri, 3 Aug 2001 03:13:25 +0000 Subject: Imported from rancid-2.2b5.tar.gz. --- util/Makefile.in | 4 +- util/cisco-load.exp | 331 ++++++++++++++++++++++++++++++++++++++++++++++++++ util/cisco-reload.exp | 141 +++++++++++++++++++++ util/downreport.in | 9 +- util/lg/README | 8 +- util/lg/lg.cgi.in | 248 +++++++++++++++++++++++++++++-------- util/lg/lg.conf.in | 75 +++++++----- util/lg/lgform.cgi.in | 29 +++-- util/lg/lgnotes.html | 15 ++- util/rtrfilter.README | 2 +- util/rtrfilter.in | 15 ++- 11 files changed, 776 insertions(+), 101 deletions(-) create mode 100644 util/cisco-load.exp create mode 100644 util/cisco-reload.exp (limited to 'util') 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 -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 () { 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 +# /.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="\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 -# /.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 advertised-routes +# for a transit customer, sh ip b neigh 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 <show frame-relay pvc [DLCI]
show interface <interface>
show ip bgp <prefix> [netmask]
+
show ip bgp neighbor <IP_addr>
show ip bgp regex <reg_exp>
show ip bgp summary
show ip bgp dampened-paths
show ip prefix-list <list_name>
show ip route <prefix> [netmask]
+
show route-map <map_name>
show ip mbgp <prefix> [netmask]
show ip mbgp summary
-
show logging [| <match_string>]
+
show logging [ | <match_string>]
ping <IP_addr | FQDN>
traceroute <IP_addr | FQDN>
@@ -159,14 +174,6 @@ print < QTYPES -# unimplemented/disabled/removed query types. -# -#
show ip bgp neighbor <IP_addr>
-#
show ip bgp neighbor <IP_addr> advertised routes
-#
show ip bgp neighbor <IP_addr> flap statistics
-#
show ip bgp neighbor <IP_addr> received
-#
show ip bgp neighbor <IP_addr> routes
-# #
sh ip as-path-access-list <list_number>
#
sh access-list <list_number>
#
sh ip community-list <list_number>
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>   Looking Glass Notes

    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 http://nitrous.digex.net.

+

+Some useful hints: +

    +
  • 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.
  • +
  • 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.
  • +
+ 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 -i -f \ # -u -s " # 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; -- cgit