#!/usr/bin/perl # # execute a command on a cisco router # # -a auto check for level 15 with 'sh priv' before issuing enable command # -d debug # -e 'enable' first # -l prompt for login # -c configfile # -x no login prompts # -t timeout # -Ln execute command on linecard n # 75XX # -An execute command on linecard n # GSR # -p Initial prompt char # -C this is CatOS # # usage rcisco [-el] router command # # maf@net.ohio-state.edu - Nov 1998 # $Id: require "getopts.pl"; require "flush.pl"; use Net::Telnet (); &Getopts('delc:xL:t:p:aC'); $opt_e = 1 if ($opt_L ne ''); $opt_t = 120 if ($opt_t == 0); $PROMPT= ($opt_p eq '') ? ">" : $opt_p; $TERMLEN1="set len 0"; # 5XXX $TERMLEN2="term len 0"; # IOS $TERMLEN3="term"; # 19XX Enterprise (broken, can't disable prompts) $ROUTER = $ARGV[0]; $ARGLEN = $#ARGV; $CMD = join ' ', splice(@ARGV, 1); $fqdn = $ROUTER; $TYPE='IOS'; die "usage: rcisco [-xeltpdcLn conf] router command $ARGLEN\n" if ($ARGLEN < 1); if ($opt_c eq '') { if (! -e "$ENV{'HOME'}/.cpass") { if (-r "/var/cisco/.cpass2") { $PASS = "/var/cisco/.cpass2"; } elsif (-r "/var/cisco/.cpass") { $PASS = "/var/cisco/.cpass"; } } else { $PASS = "$ENV{'HOME'}/.cpass"; } } else { $PASS = $opt_c; } # read the cleartext passwords if (!$opt_l && ($PASS ne '')) { @r1 = split (/\./, $ROUTER); open (PASS, "<$PASS") or die "open($PASS): $!\n"; while () { chomp; next if /^\s*#/; ($router, $user, $login, $enable) = split; if ($router eq 'DEFAULT') { $DEFAULT_SET=1; $DEFAULT_USER=$user; $DEFAULT_LOGIN=$login; $DEFAULT_ENABLE=$enable; } # try a partial match @r2 = split (/\./, $router); $match = 1; $x = 0; foreach $r (@r1) { next if ($r eq $r2[$x++]); $match = 0; last; } if ($match) { $fqdn = $router; $knowpass = $knowenable = 1; last; } # if } # PASS close PASS; } # opt_l if ($knowpass == 0 && $DEFAULT_SET == 1) { $knowpass = 1; $knowenable = 1; $user = $DEFAULT_USER; $login = $DEFAULT_LOGIN; $enable = $DEFAULT_ENABLE; } $knowpass = 0 if ($login eq '-'); $knowenable = 0 if ($enable eq '-'); # # init # if ($opt_d) { $t = new Net::Telnet(Input_log => "input.log.$ROUTER", Output_log => "output.log.$ROUTER", Timeout => $opt_t, Output_record_separator => ""); } else { $t = new Net::Telnet(Timeout => $opt_t, Output_record_separator => ""); } # # open connection to router # $t->open("$fqdn"); # # login # ($pm, $m) = $t->waitfor("/Password:|Username:|Selection:/i"); if (!$knowpass && $opt_x) { die "no recorded password\n"; } if (!$knowenable && $opt_x && $opt_e) { die "no recorded enable\n"; } if ($m =~ /username/i) { if (!$knowpass) { print STDERR "Username for $ROUTER: "; &flush(STDOUT); chomp ($user = ); } $t->print ("$user\n"); ($pm, $m) = $t->waitfor("/Password:/i"); } if ($m =~ /Password/i) { if (!$knowpass) { system ("/bin/stty -echo"); print STDERR "Password for $ROUTER: "; &flush(STDOUT); chomp ($login = ); print STDERR "\n"; system ("/bin/stty echo"); } $t->print ("$login\n"); } # 1900 if ($m =~ /Selection:/) { $t->print ("K"); $m='1900'; } # guess what type of box it is if (($m eq 'password:') || ($opt_C)) { $s = $TERMLEN1; # 55XX $TYPE='5XXX'; $t->timeout($opt_t+120); # SUP2's are slow } elsif ($m eq 'Password:') { $s = $TERMLEN2; # ios $TYPE='IOS'; } elsif ($m eq '1900') { $s = $TERMLEN3; $TYPE='1900'; } # set term length to 0 ($m, $pm) = $t->waitfor("/$PROMPT/"); $t->print ("$s\n"); # grab full prompt @lines = split(/\n/, $m); $PROMPT="\Q$lines[$#lines]$pm\E"; # check for enable if ($opt_a && !$priv && ($TYPE eq 'IOS')) { $t->waitfor("/$PROMPT/"); $t->print ("show privilege\n"); ($pm, $m) = $t->waitfor("/Current privilege level is (.*)/"); $m =~ s/Current privilege level is (\d+)//; $priv = $1; } # enable ? if ($opt_e && ($priv != 15)) { $t->waitfor("/$PROMPT/"); $t->print ("enable\n"); if (!$knowenable) { system ("/bin/stty -echo"); print STDERR "Enable for $ROUTER: "; &flush(STDOUT); chomp ($enable = ); print STDERR "\n"; system ("/bin/stty echo"); } # \r works around catios bug, doesn't harm anything else $t->waitfor("/Password/i"); $t->print ("$enable\r"); if (($TYPE eq 'IOS') || ($TYPE eq '1900')) { $PROMPT =~ s/>$/#/; } elsif ($TYPE eq '5XXX') { $PROMPT .= ' \(enable\) '; } } if ($opt_L) { $LC_PROMPT = "VIP-Slot" . $opt_L . ">"; ($pm, $m) = $t->waitfor("/$PROMPT/"); $t->print ("if-con $opt_L\n"); ($pm, $m) = $t->waitfor("/Console or Debug/"); $t->print ("C\n\n"); ($pm, $m) = $t->waitfor("/$LC_PROMPT/"); $t->print ("$TERMLEN2\n"); ($pm, $m) = $t->waitfor("/$LC_PROMPT/"); $t->print ("$CMD\n"); ($pm, $m) = $t->waitfor("/$LC_PROMPT/"); $t->print ("if-quit\n"); } else { # execute the command ($pm, $m) = $t->waitfor("/$PROMPT/"); $t->print ("$CMD\n"); if ($TYPE eq '1900') { $x = 0; while (1) { ($pm, $m) = $t->waitfor("/$PROMPT|--More--/"); if ($m eq '--More--') { $t->print (" "); if (!$x) { @lines = split(/\n/, $pm); shift @lines if ($lines[0] eq $CMD); print join "\n", @lines; print "\n"; ++$x; } else { print "$pm"; } # x } # more else { last; } # more } # while } else { # cat1900 ($pm, $m) = $t->waitfor("/$PROMPT/"); } # cat1900 } # not linecard # logout $t->print ("exit\n"); # skip the echo'd command if ($TYPE ne '1900') { @lines = split(/\n/, $pm); shift @lines if ($lines[0] eq $CMD); # output results of command print join "\n", @lines; print "\n"; } else { print "$pm"; }