#!/usr/bin/perl -T ## ## Multi-Router Looking Glass use strict; use warnings; no warnings "once"; $::Version='4.2.4 Beta (IPv6)'; ## 27 NOV 2000 ## Copyright (C) 2000 John W. Fraizer III ## *All* copyright notices must remain in place to use this code. ## ## mrlg.conf modification by Stephane Bortzmeyer ## ## The latest version of this code is available at: ## ftp://ftp.enterzone.net/looking-glass/ ## ## ## This file is part of GNU Zebra. ## http://www.zebra.org/ ## ## GNU Zebra is free software; you can redistribute it and/or modify it ## under the terms of the GNU General Public License as published by the ## Free Software Foundation; either version 2, or (at your option) any ## later version. ## ## GNU Zebra is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with GNU Zebra; see the file COPYING. If not, write to the ## Free Software Foundation, Inc., 59 Temple Place - Suite 330, ## Boston, MA 02111-1307, USA. require 5.002; use POSIX; use Net::Telnet (); use Net::hostent; use Socket; require '/etc/mrlg.conf'; # Set default values if (! defined($::bgp)) { $::bgp = 1; } if (! defined($::bgp_plus)) { $::bgp_plus = 0; } if (! defined($::multicast)) { $::multicast = 0; } if (! defined($::ospf)) { $::ospf = 1; } if (! defined($::ospf_v6)) { $::ospf_v6 = 0; } if (! defined($::rip)) { $::rip = 1; } if (! defined($::ip_route)) { $::ip_route = 1; } if (! defined($::ip6_route)) { $::ip6_route = 0; } if (! defined($::interfaces)) { $::interfaces = 1; } if (! defined($::beacon)) { $::beacon = 1; } $ENV{'PATH'} = ""; my ($server, $login_pass, $pass, $bgpd, $zebra, $ospfd, $ospf6d, $ripd, $full_tables, $cisco); ############################################################ sub set_router ############################################################ { if (! $::Routers{$::Form{'router'}}) { die "Something is really wrong (no such router $::Form{'router'})"; } $server = $::Routers{$::Form{'router'}}{'server'}; if (! $server) { die "No 'server' known for router $::Form{'router'}"; } $login_pass = $::Routers{$::Form{'router'}}{'login_pass'}; if (! $login_pass) { die "No 'login_pass' known for router $::Form{'router'}"; } $pass = ($::Routers{$::Form{'router'}}{'pass'} or ''); $bgpd = ($::Routers{$::Form{'router'}}{'bgpd'} or '0'); $zebra = ($::Routers{$::Form{'router'}}{'zebra'} or '0'); $ospfd = ($::Routers{$::Form{'router'}}{'ospfd'} or '0'); $ospf6d = ($::Routers{$::Form{'router'}}{'ospf6d'} or '0'); $ripd = ($::Routers{$::Form{'router'}}{'ripd'} or '0'); $full_tables= ($::Routers{$::Form{'router'}}{'full_tables'} or '0'); $cisco= ($::Routers{$::Form{'router'}}{'cisco'} or '0'); } ############################################################ #Main ############################################################ { my ($router, $old_value, $old_query); ## Get the form results now so we can override the default router get_form(); print "Content-type: text/html\n\n"; print ' '; #print "Multi-Router Looking Glass $::Version\n"; print "$::mrlghost - Looking Glass\n"; print ' '; print " $::mrlghost - Looking Glass
A service of $::company.
Note: ALL access to this interface is logged.
"; ## Set up the address, pw and ports, etc for the selected router. set_router(); if ($::Form{'pass1'} eq $::Routers{$::Form{'router'}}{'pass'}) { if ($::output_before_menu) { ## Set up which command is to be executed (and then execute it!) set_command(); } } else { print "INVALID PASSWORD!
"; } print ' '; print "
\n"; #print "Router: # #
Password: (if required) # print "

Query:
"; if ($::bgp) { print " show ip bgp
show ip bgp summary
"; } if ($::bgp_plus) { print " show ipv6 bgp
show ipv6 bgp summary
"; } if ($::multicast) { print " show ip bgp ipv4 multicast
show ip bgp ipv4 multicast summary
"; } if ($::ospf) { print " show ip ospf
"; } if ($::ospf6) { print " show ipv6 ospf6
"; } if ($::rip) { print " show ip rip
"; } #print " #show ip protocols
#"; if ($::ip_route) { print " show ip route
"; } if ($::ip6_route) { print " show ipv6 route
"; } if ($::interfaces) { print " show interface
"; } print " show version
"; if ($::beacon) { print " trace
ping
"; } print "
"; if (defined ($::Form{'arg'})) { $old_value = $::Form{'arg'}; } else { $old_value = ""; } print "Argument: (many commands require an IP address as argument) \
"; if ($::Form{'pass1'} eq $::Routers{$::Form{'router'}}{'pass'}) { if (! $::output_before_menu) { ## Set up which command is to be executed (and then execute it!) set_command(); } } else { print "INVALID PASSWORD!
"; } ############################## ## You may NOT remove the following notice from this code. ############################## print "
$::url is running:
"; print "Multi-Router Looking Glass version $::Version
\n"; print ' © 2000-2003, John Fraizer - EnterZone, Inc
Source code: ftp://ftp.enterzone.net/looking-glass/CURRENT/
'; ## All done! exit (0); } ############################################################ sub get_form ############################################################ { my ($pair, @pairs, $buffer, $length); #read STDIN $length = ($ENV{'CONTENT_LENGTH'} or 0); read(STDIN, $buffer, $length); # Split the name-value pairs @pairs = split(/&/, $buffer); # For each name-value pair: foreach $pair (@pairs) { # Split the pair up into individual variables. my ($name, $value) = split(/=/, $pair); # Decode the form encoding on the name and value variables. $name =~ tr/+/ /; $name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; # If they try to include server side includes, erase them, so they # aren't a security risk if the html gets returned. Another # security hole plugged up. $name =~ s///g; $value =~ s///g; # Get rid of linebreaks. $name =~ s/\n//g; $value =~ s/\n//g; $::Form{$name} = $value ; } } ############################################################ sub set_command ############################################################ { if (! defined ($::Form{'query'})) { return; } if ($::Form{'query'} eq '1') { sh_ip_bgp(); } elsif ($::Form{'query'} eq '2') { sh_ip_bgp_sum(); } if ($::Form{'query'} eq '3') { sh_ip_route(); } if ($::Form{'query'} eq '4') { sh_int(); } if ($::Form{'query'} eq '5') { sh_ip_mbgp(); } if ($::Form{'query'} eq '6') { sh_ip_mbgp_sum(); } if ($::Form{'query'} eq '7') { traceroute(); } if ($::Form{'query'} eq '8') { ping(); } if ($::Form{'query'} eq '9') { sh_version(); } if ($::Form{'query'} eq '10') { sh_ip_ospf(); } if ($::Form{'query'} eq '11') { sh_ip_protocols(); } if ($::Form{'query'} eq '13') { sh_ip_bgp_plus(); } if ($::Form{'query'} eq '14') { sh_ip_bgp_plus_sum(); } if ($::Form{'query'} eq '15') { sh_ip_ospf6(); } if ($::Form{'query'} eq '16') { sh_ip6_route(); } } ############################################################ sub sh_ip_bgp ############################################################ { my $port = $bgpd; my $command = "show ip bgp $::Form{'arg'}"; if ($bgpd eq '0') { print "Sorry. The show ip bgp command is disabled for this router." } else { if ($::Form{'arg'} eq '') { if ($full_tables eq '1') { $command = "show ip bgp"; execute_command($command, $port); } else { print "Sorry. Displaying the FULL routing table would put too much load on the router!\n\n"; } } else { execute_command($command, $port); } } } ############################################################ sub sh_ip_bgp_plus ############################################################ { my $port = $bgpd; my $command = "show ipv6 bgp $::Form{'arg'}"; if ($bgpd eq '0') { print "Sorry. The show ipv6 bgp command is disabled for this router." } else { if ($::Form{'arg'} eq '') { if ($full_tables eq '1') { $command = "show ipv6 bgp"; execute_command($command, $port); } else { print "Sorry. Displaying the FULL routing table would put too much load on the router!\n\n"; } } else { execute_command($command, $port); } } } ############################################################ sub sh_ip_bgp_sum ############################################################ { if ($bgpd eq '0') { print "Sorry. The show ip bgp summary command is disabled for this router." } else { my $port = $bgpd; my $command = "show ip bgp summary"; execute_command($command, $port); } } ############################################################ sub sh_ip_bgp_plus_sum ############################################################ { if ($bgpd eq '0') { print "Sorry. The show ipv6 bgp summary command is disabled for this router." } else { my $port = $bgpd; my $command = "show ipv6 bgp summary"; execute_command($command, $port); } } ############################################################ sub sh_ip_ospf ############################################################ { if ($ospfd eq '0') { print "Sorry. The show ip ospf command is disabled for this router." } else { my $port = $ospfd; my $command = "show ip ospf $::Form{'arg'}"; execute_command($command, $port); } } ############################################################ sub sh_ip_ospf6 ############################################################ { if ($ospf6d eq '0') { print "Sorry. The show ipv6 ospf6 command is disabled for this router." } else { my $port = $ospf6d; my $command = "show ipv6 ospf6 $::Form{'arg'}"; execute_command($command, $port); } } ############################################################ sub sh_ip_route ############################################################ { if ($zebra eq '0') { print "Sorry. The show ip route command is disabled for this router." } else { my $port = $zebra; my $command = "show ip route $::Form{'arg'}"; if ($::Form{'arg'} eq '') { if ($full_tables eq '1') { execute_command($command, $port); } else { print "Sorry. Displaying the FULL routing table would put too much load on the router!\n\n"; } } else { execute_command($command, $port); } } } ############################################################ sub sh_ip6_route ############################################################ { if ($zebra eq '0') { print "Sorry. The show ipv6 route command is disabled for this router." } else { my $port = $zebra; my $command = "show ipv6 route $::Form{'arg'}"; if ($::Form{'arg'} eq '') { if ($full_tables eq '1') { execute_command($command, $port); } else { print "Sorry. Displaying the FULL routing table would put too much load on the router!\n\n"; } } else { execute_command($command, $port); } } } ############################################################ sub sh_int ############################################################ { if ($zebra eq '0') { print "Sorry. The show interface command is disabled for this router." } else { my $port = $zebra; my $command = "show interface $::Form{'arg'}"; execute_command($command, $port); } } ############################################################ sub sh_ip_mbgp ############################################################ { my $port = $bgpd; my $command; if ($cisco eq '1') { $command = "sh ip mbgp $::Form{'arg'}"; } else { $command = "show ip bgp ipv4 multicast $::Form{'arg'}"; } if ($::Form{'arg'} eq '') { if ($full_tables eq '1') { execute_command($command, $port); } else { print "Sorry. Displaying the FULL routing table would put too much load on the router!\n\n"; } } else { execute_command($command, $port); } } ############################################################ sub sh_ip_mbgp_sum ############################################################ { my $port = $bgpd; my $command; if ($cisco eq '1') { $command = "sh ip mbgp summary"; } else { $command = "show ip bgp ipv4 multicast summary"; } execute_command($command, $port); } ############################################################ sub traceroute ############################################################ { my ($ipaddress, $hostent); if ( $::Form{'arg'} =~ /^(([0-9a-zA-Z-\.]+)\.([0-9a-zA-Z-\.]+))$/ ) { my $target = $1; if ( $cisco eq '1') { my $port = $bgpd; my $command = "traceroute $target"; print "Traceroute from $::Form{'router'}.
\n\n"; execute_command($command, $port); } else { # Some traceroutes, like the NANOG one, need an IP address when # using -s :-( $hostent = gethostbyname ($::mrlghost); $ipaddress = inet_ntoa (@{$hostent->addr_list}[0]); print "Traceroute from $::mrlghost ($ipaddress).
\n\n"; print "Executing command = traceroute $target\n\n"; select(STDOUT); $| = 1; open(STDERR, '>&STDOUT');# Redirect stderr onto stdout alarm(45); print "
\n";

	
# Use this one if using standard traceroute.
#	open(TRACEROUTE,"|$::traceroute -s $ipaddress $target");


# Use this one if using ztraceroute included in mrlg package.
	open(TRACEROUTE,"|$::traceroute $target");


	print ;
	close(TRACEROUTE);

	close (STDERR);

	print "
"; print "Traceroute completed...
"; } } else { print "Invalid address!"; } } ############################################################ sub ping ############################################################ { if ( $::Form{'arg'} =~ /^(([0-9a-zA-Z-\.]+)\.([0-9a-zA-Z-\.]+))$/ ) { my ($target) = $1; if ( $cisco eq '1') { my $port = $bgpd; my $command = "ping $target"; print "Ping from $::Form{'router'}.
\n\n"; execute_command($command, $port); } else { print "Ping from $::mrlghost.
\n\n"; #print "Executing command = fastping -c 100 -s 100 $target\n\n"; print "Executing command = ping -c 10 $target\n\n"; select(STDOUT); $| = 1; open(STDERR, '>&STDOUT'); alarm(45); print "
\n";

			open(PING,"|$::ping $target -c 100");
			print ;
			close(PING);


			close (STDERR);
			print "
"; print "[Finished]
"; } } else { print "Invalid address!"; } } ############################################################ sub sh_ip_rip ############################################################ { if ($ripd eq '0') { print "Sorry. The show ip rip command is disabled for this router." } else { my $port = $ripd; my $command = "show ip rip $::Form{'arg'}"; execute_command($command, $port); } } ############################################################ sub sh_ip_protocols ############################################################ { if ($ripd eq '0') { print "Sorry. The show ip protocols command is disabled for this router." } else { my $port = $ripd; my $command = "show ip protocols $::Form{'arg'}"; execute_command($command, $port); } } ############################################################ sub sh_version ############################################################ { my $port = $bgpd; my $command = "show version"; execute_command($command, $port); } ############################################################ sub execute_command ############################################################ ## This code is based on: ## ## Zebra interactive console ## Copyright (C) 2000 Vladimir B. Grebenschikov ## { my ($cmd, $port) = @_; print "Executing command = $cmd"; my ($prompt, $termlength, $timeout); if ($cisco eq '1') { $prompt='/[\>\#]$/'; $termlength='0'; $timeout='30'; } else { $prompt='/[\>\#] $/'; $termlength='0'; $timeout='15'; } my $t = new Net::Telnet (Timeout => $timeout, #Prompt => '/[\>\#] $/', Prompt => $prompt, Port => $port); $t->open ($server); $t->cmd ($login_pass); $t->cmd("terminal length $termlength"); if ($cmd) { docmd ($t, $cmd); } } ############################################################ sub docmd ############################################################ { my ($t, $cmd) = @_; my @lines = $t->cmd ($cmd); print "
\n";
  print join('', grep(!/[\>\#] $/, @lines)),"\n";
  print "
"; } ### The end. Now, isn't that special?! ###