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/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 ++- 5 files changed, 281 insertions(+), 94 deletions(-) (limited to 'util/lg') 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.
  • +
+ -- cgit