diff options
Diffstat (limited to 'bin/cat5rancid.in')
-rw-r--r-- | bin/cat5rancid.in | 163 |
1 files changed, 102 insertions, 61 deletions
diff --git a/bin/cat5rancid.in b/bin/cat5rancid.in index f1214a1..bd13d65 100644 --- a/bin/cat5rancid.in +++ b/bin/cat5rancid.in @@ -1,8 +1,9 @@ #! @PERLV_PATH@ ## -## $Id: cat5rancid.in,v 1.36 2004/01/11 03:49:13 heas Exp $ +## $Id: cat5rancid.in,v 1.47 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,26 +22,31 @@ # # 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 my(%modules); # module info (part from sh ver, part from sh module) # 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; } @@ -62,10 +68,10 @@ sub ProcessHistory { sub numerically { $a <=> $b; } -# This is a sort routing that will sort numerically on the +# 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)) { @@ -75,10 +81,10 @@ sub keynsort { @sorted_lines; } -# This is a sort routing that will sort on the +# 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)) { @@ -88,10 +94,10 @@ sub keysort { @sorted_lines; } -# This is a sort routing that will sort on the +# 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) { @@ -101,9 +107,9 @@ sub valsort{ @sorted_lines; } -# This is a numerical sort routing (ascending). +# 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) { @@ -117,7 +123,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) { @@ -130,7 +136,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); @@ -665,14 +671,46 @@ sub ShowDiag { return(0); } +# This routine parses "show inventory". +sub ShowInventory { + print STDERR " In ShowInventory: $_" if ($debug); + + while (<INPUT>) { + tr/\015//d; + return if (/^\s*\^$/); + last if (/^$prompt/); + next if (/^(\s*|\s*$cmd\s*)$/); + return(-1) if (/command authorization failed/i); + # the pager can not be disabled per-session on the PIX + s/^<-+ More -+>\s*//; + + chomp; + + # split PID/VID line + if (/^(NAME: ".*,) (DESCR: .*)/) { + ProcessHistory("INVENTORY","","", sprintf("!%-30s%s\n", $1, $2)); + next; + } + if (/^(PID: \w?) *, (VID: .*), (SN: .*)$/) { + ProcessHistory("INVENTORY","","", "!$1\n!$2\n!$3\n"); + next; + } + + ProcessHistory("INVENTORY","","","!$_"); + } + ProcessHistory("INVENTORY","","",""); + + return(0); +} + # This routine parses "show module" sub ShowModule { my($slot); print STDERR " In ShowModule: $_" if ($debug); OUTER:while (<INPUT>) { - tr/\015//d; - last if(/^$prompt/); + tr/\015//d; + last if(/^$prompt/); # stuff module type into %module if (/^Mod\s+Slot\s+Ports/) { <INPUT>; @@ -696,7 +734,7 @@ OUTER:while (<INPUT>) { } next; } - # one does it one way... pita + # one does it one way... pita if (/^Mod\s+Module-Name\s+Ports/) { <INPUT>; #my($slot); @@ -713,7 +751,7 @@ OUTER:while (<INPUT>) { } next; } - # daughter boards + # daughter boards if (/^Mod\s+Sub-Type/) { <INPUT>; my($slot, $board); @@ -767,7 +805,7 @@ OUTER:while (<INPUT>) { ProcessHistory("MODS","","",$model); if ($dboards) {ProcessHistory("MODS","","",$dboards);} } -} +} # This routine processes a "show port ifindex" sub ShowPortIfindex { @@ -790,7 +828,10 @@ sub ShowPortIfindex { sub WriteTerm { print STDERR " In WriteTerm: $_" if ($debug); - ProcessHistory("","","","!\n"); + if (! $found_end) { + ProcessHistory("","","","!\n"); + } + while (<INPUT>) { tr/\015//d; last if (/^$prompt/); @@ -822,9 +863,9 @@ sub WriteTerm { /^#Time: / && next; # Dog gone Cool matches to process the rest of the config - /^#time: / && next; # kill time: - /^tftp-server flash / && next; # kill any tftp remains - /^ntp clock-period / && next; # kill ntp clock-period + /^#time: / && next; # kill time: + /^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 if (/^enable password / && $filter_pwds >= 1) { @@ -925,15 +966,15 @@ sub WriteTerm { # order logging statements /^set logging server (\d+\.\d+\.\d+\.\d+)/ && ProcessHistory("LOGGING","ipsort","$1","$_") && next; - # order/prune snmp-server host statements - # we only prune lines of the form - # snmp-server host a.b.c.d <community> + # order/prune snmp-server host statements + # we only prune lines of the form + # snmp-server host a.b.c.d <community> if (/^set snmp trap (\d+\.\d+\.\d+\.\d+) /) { if (defined($ENV{'NOCOMMSTR'})) { ProcessHistory("SNMPSERVERHOST","ipsort","$1","!set snmp trap $1 <removed>\n"); } else { ProcessHistory("SNMPSERVERHOST","ipsort","$1","$_"); - } + } next; } if (/^(set snmp community) (\S+) (\S+)/) { @@ -991,39 +1032,39 @@ sub WriteTerm { sub DoNothing {print STDOUT;} # Main -%commands=( - 'show version' => "ShowVersion", - 'show boot' => "ShowBoot", - 'show flash' => "ShowFlash", - 'dir bootflash:' => "DirSlotN", - 'dir slot0:' => "DirSlotN", - 'dir slot1:' => "DirSlotN", - 'dir sup-bootflash:' => "DirSlotN", - 'dir sup-microcode:' => "DirSlotN", - 'show module' => "ShowModule", - 'show port ifindex' => "ShowPortIfindex", - 'write term all' => "WriteTerm", - 'write term' => "WriteTerm" -); -# keys() doesnt return things in the order entered and the order of the -# cmds is important (show version first and write term last). pita -@commands=( - "show version", - "show boot", - "show flash", - "dir bootflash:", - "dir slot0:", - "dir slot1:", - "dir sup-bootflash:", - "dir sup-microcode:", - "show module", - "show port ifindex", - "write term all", - "write term" +@commandtable = ( + {'show version' => 'ShowVersion'}, + {'show boot' => 'ShowBoot'}, + {'show flash' => 'ShowFlash'}, + {'dir bootflash:' => 'DirSlotN'}, + {'dir slot0:' => 'DirSlotN'}, + {'dir slot1:' => 'DirSlotN'}, + {'dir sup-bootflash:' => 'DirSlotN'}, + {'dir sup-microcode:' => 'DirSlotN'}, + {'show module' => 'ShowModule'}, + {'show inventory raw' => 'ShowInventory'}, + {'show port ifindex' => 'ShowPortIfindex'}, + {'write term all' => 'WriteTerm'}, + {'write term' => 'WriteTerm'}, + {'show running-config' => 'WriteTerm'} ); +# 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 |