diff options
Diffstat (limited to 'bin/cssrancid.in')
-rw-r--r-- | bin/cssrancid.in | 144 |
1 files changed, 79 insertions, 65 deletions
diff --git a/bin/cssrancid.in b/bin/cssrancid.in index 27049df..294f400 100644 --- a/bin/cssrancid.in +++ b/bin/cssrancid.in @@ -1,8 +1,9 @@ #! @PERLV_PATH@ ## -## $Id: cssrancid.in,v 1.4 2004/01/11 03:49:13 heas Exp $ +## $Id: cssrancid.in,v 1.13 2006/10/05 04:27:42 heas Exp $ ## -## Copyright (C) 1997-2004 by Terrapin Communications, Inc. +## @PACKAGE@ @VERSION@ +## Copyright (C) 1997-2006 by Terrapin Communications, Inc. ## All rights reserved. ## ## This software may be freely copied, modified and redistributed @@ -21,25 +22,30 @@ # # RANCID - Really Awesome New Cisco confIg Differ # -# usage: rancid [-d] [-l] [-f filename | $host] +# usage: rancid [-dV] [-l] [-f filename | hostname] # use Getopt::Std; -getopts('dfl'); +getopts('dflV'); +if ($opt_V) { + print "@PACKAGE@ @VERSION@\n"; + exit(0); +} $log = $opt_l; $debug = $opt_d; $file = $opt_f; $host = $ARGV[0]; $clean_run = 0; $found_end = 0; -$timeo = 90; # clogin timeout in seconds +$timeo = 90; # clogin timeout in seconds -my(%filter_pwds); # password filtering mode +my(@commandtable, %commands, @commands);# command lists +my(%filter_pwds); # password filtering mode # This routine is used to print out the router configuration sub ProcessHistory { - my($new_hist_tag,$new_command,$command_string,@string)=(@_); - if((($new_hist_tag ne $hist_tag) || ($new_command ne $command)) - && defined %history) { + my($new_hist_tag,$new_command,$command_string,@string) = (@_); + if ((($new_hist_tag ne $hist_tag) || ($new_command ne $command)) + && defined %history) { print eval "$command \%history"; undef %history; } @@ -64,7 +70,7 @@ sub numerically { $a <=> $b; } # This is a sort routine that will sort numerically on the # keys of a hash as if it were a normal array. sub keynsort { - local(%lines)=@_; + local(%lines) = @_; local($i) = 0; local(@sorted_lines); foreach $key (sort numerically keys(%lines)) { @@ -77,7 +83,7 @@ sub keynsort { # This is a sort routine that will sort on the # keys of a hash as if it were a normal array. sub keysort { - local(%lines)=@_; + local(%lines) = @_; local($i) = 0; local(@sorted_lines); foreach $key (sort keys(%lines)) { @@ -90,7 +96,7 @@ sub keysort { # This is a sort routine that will sort on the # values of a hash as if it were a normal array. sub valsort{ - local(%lines)=@_; + local(%lines) = @_; local($i) = 0; local(@sorted_lines); foreach $key (sort values %lines) { @@ -102,7 +108,7 @@ sub valsort{ # This is a numerical sort routine (ascending). sub numsort { - local(%lines)=@_; + local(%lines) = @_; local($i) = 0; local(@sorted_lines); foreach $num (sort {$a <=> $b} keys %lines) { @@ -116,7 +122,7 @@ sub numsort { # ip address when the ip address is anywhere in # the strings. sub ipsort { - local(%lines)=@_; + local(%lines) = @_; local($i) = 0; local(@sorted_lines); foreach $addr (sort sortbyipaddr keys %lines) { @@ -129,7 +135,7 @@ sub ipsort { # These two routines will sort based upon IP addresses sub ipaddrval { my(@a) = ($_[0] =~ m#^(\d+)\.(\d+)\.(\d+)\.(\d+)$#); - $a[3]+256*($a[2]+256*($a[1]+256*$a[0])); + $a[3] + 256 * ($a[2] + 256 * ($a[1] +256 * $a[0])); } sub sortbyipaddr { &ipaddrval($a) <=> &ipaddrval($b); @@ -141,7 +147,6 @@ sub ShowVersion { while (<INPUT>) { tr/\015//d; - study; last if(/^$prompt/); next if(/^(\s*|\s*$cmd\s*)$/); return(-1) if (/command authorization failed/i); @@ -254,6 +259,8 @@ sub ShowVersion { sub TermLength { # Dummy subroutine.. need to set term length differently for CSS # boxes as term length 0 doesnt work correctly. POS. + print STDERR " In TermLength: $_" if ($debug); + $_ = <INPUT>; return(0); } @@ -264,6 +271,8 @@ sub CopyProfile { ## of couse breaks the interaction... strangely enough tho ## in a failover environment, only the secondary behaves this ## way.. the primary lets you log out and does not complain. + print STDERR " In CopyProfile: $_" if ($debug); + $_ = <INPUT>; return(0); } @@ -283,15 +292,16 @@ sub ShowBoot { return(1) if /Ambiguous command/i; # return(1) if /(Invalid input detected|Type help or )/; return(1) if /(Open device \S+ failed|Error opening \S+:)/; + next if (/\*\* BOOT CONFIG /); next if /CONFGEN variable/; if (!defined($H0)) { $H0=1; ProcessHistory("COMMENTS","keysort","H0","!\n"); } if ($type !~ /^(12[04]|7)/) { if ($type !~ /^(29|35)00/) { - ProcessHistory("COMMENTS","keysort","H2","!BootFlash: $_"); + ProcessHistory("COMMENTS","keysort","H2","!BootFlash: $_"); } else { - ProcessHistory("COMMENTS","keysort","H1","!Variable: $_"); + ProcessHistory("COMMENTS","keysort","H1","!Variable: $_"); } } elsif (/variable/) { ProcessHistory("COMMENTS","keysort","H1","!Variable: $_"); @@ -305,17 +315,18 @@ sub ShowBoot { # This routine processes a "show run" sub ShowRun { print STDERR " In ShowRun: $_" if ($debug); - my($lineauto) = 0; + my($lines) = 0; while (<INPUT>) { tr/\015//d; - study; - last if(/^$prompt/); + if(/^$prompt/) { + $found_end = 1 if ($lines > 4); + return(1); + } return(-1) if (/command authorization failed/i); # the pager can not be disabled per-session on the PIX s/^<-+ More -+>\s*//; /Non-Volatile memory is in use/ && return(-1); # NvRAM is locked - $lineauto = 0 if (/^[^ ]/); # skip the crap if (/^(##+$|(Building|Current) configuration)/i) { while (<INPUT>) { @@ -335,14 +346,14 @@ sub ShowRun { /^! (Last configuration|NVRAM config last)/ && next; ## CSS specific.... /Generated on/ && next; + $lines++; # Dog gone Cool matches to process the rest of the config /^tftp-server flash / && next; # kill any tftp remains /^ntp clock-period / && next; # kill ntp clock-period /^ length / && next; # kill length on serial lines /^ width / && next; # kill width on serial lines - $lineauto = 1 if /^ modem auto/; - /^ speed / && $lineauto && next; # kill speed on serial lines + /^ speed / && next; # kill speed on serial lines /^ clockrate / && next; # kill clockrate on serial interfaces if (/^(enable )?(password|passwd) / && $filter_pwds >= 1) { ProcessHistory("ENABLE","","","!$1$2 <removed>\n"); @@ -360,11 +371,9 @@ sub ShowRun { } next; } - if (/^username (\S+)(\s.*)? password ((\d) \S+|\S+)/) { - if ($filter_pwds == 2) { - ProcessHistory("USER","keysort","$1","!username $1$2 password <removed>\n"); - } elsif ($filter_pwds == 1 && $4 ne "5"){ - ProcessHistory("USER","keysort","$1","!username $1$2 password <removed>\n"); + if (/\s*username (\S+)(\s.*)? (des-password|password) (\S+|\S+)/) { + if ($filter_pwds >= 1) { + ProcessHistory("USER","keysort","$1","! username $1$2 $3 <removed>$'\n"); } else { ProcessHistory("USER","keysort","$1","$_"); } @@ -537,11 +546,6 @@ sub ShowRun { # catch anything that wasnt matched above. ProcessHistory("","","","$_"); - # end of config. the ": " game is for the PIX - if (/^(: +)?end$/ || /CSS.*#/ || /$prompt/ ) { - $found_end = 1; - return(1); - } } return(0); } @@ -550,25 +554,30 @@ sub ShowRun { sub DoNothing {print STDOUT;} # Main -%commands=( - 'term length 65535' => "TermLength", - 'copy profile user-profile' => "CopyProfile", - 'show version' => "ShowVersion", - 'show boot' => "ShowBoot", - 'show run' => "ShowRun" -); -# keys() doesnt return things in the order entered and the order of the -# cmds is important (show version first and show run last). pita -@commands=( - "term length 65535", - "copy profile user-profile", - "show version", - "show boot", - "show run" +@commandtable = ( + {'term length 65535' => 'TermLength'}, + {'copy profile user-profile' => 'CopyProfile'}, + {'show version' => 'ShowVersion'}, + {'show boot' => 'ShowBoot'}, + {'show run' => 'ShowRun'} ); +# Use an array to preserve the order of the commands and a hash for mapping +# commands to the subroutine and track commands that have been completed. +@commands = map(keys(%$_), @commandtable); +%commands = map(%$_, @commandtable); + $cisco_cmds=join(";",@commands); $cmds_regexp=join("|",@commands); +if (length($host) == 0) { + if ($file) { + print(STDERR "Too few arguments: file name required\n"); + exit(1); + } else { + print(STDERR "Too few arguments: host name required\n"); + exit(1); + } +} open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n"; select(OUTPUT); # make OUTPUT unbuffered if debugging @@ -590,7 +599,7 @@ if ($file) { } # determine password filtering mode -if ($ENV{"FILTER_PWDS"} =~ /no/i) { +if ($ENV{"FILTER_PWDS"} =~ /no/i) { $filter_pwds = 0; } elsif ($ENV{"FILTER_PWDS"} =~ /all/i) { $filter_pwds = 2; @@ -599,11 +608,12 @@ if ($ENV{"FILTER_PWDS"} =~ /no/i) { } ProcessHistory("","","","!RANCID-CONTENT-TYPE: cisco-css\n!\n"); -ProcessHistory("COMMENTS","keysort","B0","!\n"); -ProcessHistory("COMMENTS","keysort","F0","!\n"); -ProcessHistory("COMMENTS","keysort","G0","!\n"); +#ProcessHistory("COMMENTS","keysort","B0","!\n"); +#ProcessHistory("COMMENTS","keysort","F0","!\n"); +#ProcessHistory("COMMENTS","keysort","G0","!\n"); TOP: while(<INPUT>) { +NEXT: tr/\015//d; if (/\#\s?exit/) { $clean_run=1; @@ -615,23 +625,27 @@ TOP: while(<INPUT>) { $clean_run=0; last; } - while (/#\s*($cmds_regexp)\s*$/) { + if (/#\s*($cmds_regexp)\s*$/) { $cmd = $1; - if (!defined($prompt)) {$prompt = ($_ =~ /^([^#]+#)/)[0]; } + if (!defined($prompt)) { + $prompt = ($_ =~ /^([^#]+#)/)[0]; + $prompt =~ s/([][}{)(\\])/\\$1/g; + print STDERR ("PROMPT MATCH: $prompt\n") if ($debug); + } print STDERR ("HIT COMMAND:$_") if ($debug); if (! defined($commands{$cmd})) { print STDERR "$host: found unexpected command - \"$cmd\"\n"; - # $clean_run = 0; - # last TOP; - next TOP; - } else { - $rval = &{$commands{$cmd}}; - delete($commands{$cmd}); - if ($rval == -1) { - $clean_run = 0; - last TOP; - } + $clean_run = 0; + last TOP; + } + $rval = &{$commands{$cmd}}; + delete($commands{$cmd}); + if ($rval == -1) { + $clean_run = 0; + last TOP; } + # the function may have read the next prompt/cmd line + goto NEXT; } } print STDOUT "Done $logincmd: $_\n" if ($log); |