diff options
Diffstat (limited to 'bin/jrancid.in')
-rw-r--r-- | bin/jrancid.in | 339 |
1 files changed, 232 insertions, 107 deletions
diff --git a/bin/jrancid.in b/bin/jrancid.in index 2793446..252b1a3 100644 --- a/bin/jrancid.in +++ b/bin/jrancid.in @@ -1,8 +1,9 @@ #! @PERLV_PATH@ ## -## $Id: jrancid.in,v 1.58 2004/01/11 03:49:13 heas Exp $ +## $Id: jrancid.in,v 1.80 2006/12/05 17:14:27 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 @@ -24,10 +25,14 @@ # # RANCID - Really Awesome New Cisco confIg Differ # -# usage: jrancid [-d] [-l] [-f filename | $host] +# usage: jrancid [-dV] [-l] [-f filename | hostname] # use Getopt::Std; -getopts('dfl'); +getopts('dflV'); +if ($opt_V) { + print "@PACKAGE@ @VERSION@\n"; + exit(0); +} $debug = $opt_d; $log = $opt_l; $file = $opt_f; @@ -35,14 +40,17 @@ $host = $ARGV[0]; $clean_run = 0; $found_end = 0; +$timeo = 120; # clogin timeout in seconds -my(%filter_pwds); # password filtering mode +my(@commandtable, %commands, @commands);# command lists +my(%filter_pwds); # password filtering mode +my($ShowChassisSCB); # Only run ShowChassisSCB() once # 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,10 +72,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)) { @@ -77,10 +85,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)) { @@ -90,22 +98,22 @@ 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) { - $sorted_lines[$i] = $key; - $i++; + $sorted_lines[$i] = $key; + $i++; } @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) { @@ -119,7 +127,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) { @@ -132,7 +140,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); @@ -150,9 +158,9 @@ sub ShowChassisClocks { ProcessHistory("","","","# $_"); while (<INPUT>) { tr/\015//d; - last if(/^$prompt/); - next if(/^system (shutdown message from|going down )/i); - next if(/^\{(master|backup)}/); + last if (/^$prompt/); + next if (/^system (shutdown message from|going down )/i); + next if (/^\{(master|backup)}/); /error: the chassis subsystem is not running/ && return; /Couldn\'t initiate connection/ && return; @@ -162,10 +170,20 @@ sub ShowChassisClocks { /syntax error/ && return; # filter decimal places of m160 measured clock MHz - /Measured frequency/ && s/\..*MHz/ MHz/; + if (/Measured frequency/) { + s/\..*MHz/ MHz/; + } elsif (/^.+\.[0-9]+ MHz$/) { + # filter for the m160 (newer format) + s/\.[0-9]+ MHz/ MHz/; + } elsif (/^(.+)(\.[0-9]+) MHz/) { + # filter for T series + my($leadlen) = length($1); + $x = sprintf(" MHz%".length($2)."s", " "); + substr($_, $leadlen, length($2)+4, $x); + } ProcessHistory("","","","# $_"); } - return; + return(0); } # This routine parses "show chassis environment" @@ -176,9 +194,9 @@ sub ShowChassisEnvironment { ProcessHistory("","","","# $_"); while (<INPUT>) { tr/\015//d; - last if(/^$prompt/); - next if(/^system (shutdown message from|going down )/i); - next if(/^\{(master|backup)}/); + last if (/^$prompt/); + next if (/^system (shutdown message from|going down )/i); + next if (/^\{(master|backup)}/); /error: the chassis subsystem is not running/ && return; /Couldn\'t initiate connection/ && return; @@ -186,6 +204,7 @@ sub ShowChassisEnvironment { /command is not valid/ && return; /^\s+\^/ && return; /syntax error/ && return; + / backplane temperature/ && next; /(\s*Power supply.*), temperature/ && ProcessHistory("","","","# $1\n") && next; @@ -193,9 +212,11 @@ sub ShowChassisEnvironment { ProcessHistory("","","","# $1\n") && next; /(^.*\S)\s+ Spinning at .*$/ && ProcessHistory("","","","# $1\n") && next; + /(^.*\S)\s+Measurement/ && + ProcessHistory("","","","# $1\n") && next; ProcessHistory("","","","# $_"); } - return; + return(0); } # This routine parses "show chassis firmware" @@ -206,9 +227,9 @@ sub ShowChassisFirmware { ProcessHistory("","","","# $_"); while (<INPUT>) { tr/\015//d; - last if(/^$prompt/); - next if(/^system (shutdown message from|going down )/i); - next if(/^\{(master|backup)}/); + last if (/^$prompt/); + next if (/^system (shutdown message from|going down )/i); + next if (/^\{(master|backup)}/); /error: the chassis subsystem is not running/ && return; /Couldn\'t initiate connection/ && return; @@ -216,9 +237,10 @@ sub ShowChassisFirmware { /command is not valid/ && return; /^\s+\^/ && return; /syntax error/ && return; + ProcessHistory("","","","# $_"); } - return; + return(0); } # This routine parses "show chassis fpc detail" @@ -229,9 +251,9 @@ sub ShowChassisFpcDetail { ProcessHistory("","","","# $_"); while (<INPUT>) { tr/\015//d; - last if(/^$prompt/); - next if(/^system (shutdown message from|going down )/i); - next if(/^\{(master|backup)}/); + last if (/^$prompt/); + next if (/^system (shutdown message from|going down )/i); + next if (/^\{(master|backup)}/); /error: the chassis subsystem is not running/ && return; /Couldn\'t initiate connection/ && return; @@ -239,12 +261,13 @@ sub ShowChassisFpcDetail { /command is not valid/ && return; /^\s+\^/ && return; /syntax error/ && return; + / Temperature/ && next; / Start time/ && next; / Uptime/ && next; ProcessHistory("","","","# $_"); } - return; + return(0); } # This routine parses "show chassis hardware" @@ -255,9 +278,9 @@ sub ShowChassisHardware { ProcessHistory("","","","# $_"); while (<INPUT>) { tr/\015//d; - last if(/^$prompt/); - next if(/^system (shutdown message from|going down )/i); - next if(/^\{(master|backup)}/); + last if (/^$prompt/); + next if (/^system (shutdown message from|going down )/i); + next if (/^\{(master|backup)}/); /error: the chassis subsystem is not running/ && return; /Couldn\'t initiate connection/ && return; @@ -265,9 +288,10 @@ sub ShowChassisHardware { /command is not valid/ && return; /^\s+\^/ && return; /syntax error/ && return; + ProcessHistory("","","","# $_"); } - return; + return(0); } # This routine parses "show chassis routing-engine" @@ -279,9 +303,9 @@ sub ShowChassisRoutingEngine { ProcessHistory("","","","# $_"); while (<INPUT>) { tr/\015//d; - last if(/^$prompt/); - next if(/^system (shutdown message from|going down )/i); - next if(/^\{(master|backup)}/); + last if (/^$prompt/); + next if (/^system (shutdown message from|going down )/i); + next if (/^\{(master|backup)}/); /error: the chassis subsystem is not running/ && return; /Couldn\'t initiate connection/ && return; @@ -289,15 +313,17 @@ sub ShowChassisRoutingEngine { /command is not valid/ && return; /^\s+\^/ && return; /syntax error/ && return; + /^Routing Engine status:/ && ProcessHistory("","","","# $_") && next; / Slot / && ProcessHistory("","","","# $_") && next; / Current state/ && ProcessHistory("","","","# $_") && next; / Election priority/ && ProcessHistory("","","","# $_") && next; / DRAM/ && ProcessHistory("","","","# $_") && next; + / Model/ && ProcessHistory("","","","# $_") && next; / Serial ID/ && ProcessHistory("","","","# $_") && next; /^\s*$/ && ProcessHistory("","","","# $_") && next; } - return; + return(0); } # This routine parses "show chassis cfeb", "show chassis feb", "show @@ -310,9 +336,9 @@ sub ShowChassisSCB { ProcessHistory("","","","# $_"); while (<INPUT>) { tr/\015//d; - last if(/^$prompt/); - next if(/^system (shutdown message from|going down )/i); - next if(/^\{(master|backup)}/); + last if (/^$prompt/); + next if (/^system (shutdown message from|going down )/i); + next if (/^\{(master|backup)}/); return if ($ShowChassisSCB); /error: the chassis subsystem is not running/ && return; @@ -321,7 +347,9 @@ sub ShowChassisSCB { /command is not valid/ && return; /^\s+\^/ && return; /syntax error/ && return; + / Temperature/ && next; + / temperature/ && next; / utilization/ && next; / Start time/ && next; / Uptime/ && next; @@ -330,26 +358,115 @@ sub ShowChassisSCB { ProcessHistory("","","","# $_"); } $ShowChassisSCB = 1; - return; + return(0); } -# This routine parses "show system boot-messages" +# This routine parses "show chassis alarms" sub ShowChassisAlarms { print STDERR " In ShowChassisAlarms: $_" if ($debug); + s/^[a-z]+@//; + ProcessHistory("","","","# $_"); + while (<INPUT>) { + tr/\015//d; + last if (/^$prompt/); + next if (/^system (shutdown message from|going down )/i); + next if (/^\{(master|backup)}/); + + /Unrecognized command/ && return; + /command is not valid/ && return; + /^\s+\^/ && return; + /syntax error/ && return; + + ProcessHistory("","","","# $_"); + } + return(0); +} + +# This routine parses "show system autoinstallation status" +sub ShowSystemAutoinstall { + print STDERR " In ShowSystemAutoinstall: $_" if ($debug); + + s/^[a-z]+@//; ProcessHistory("","","","# $_"); while (<INPUT>) { tr/\015//d; - last if(/^$prompt/); - next if(/^system (shutdown message from|going down )/i); - next if(/^\{(master|backup)}/); + last if (/^$prompt/); + next if (/^system (shutdown message from|going down )/i); + next if (/^\{(master|backup)}/); /Unrecognized command/ && return; + /command is not valid/ && return; /^\s+\^/ && return; /syntax error/ && return; + ProcessHistory("","","","# $_"); } - return; + return(0); +} + +sub ShowSystemCoreDumps { + print STDERR " In ShowSystemCoreDumps: $_" if ($debug); + + s/^[a-z]+@//; + ProcessHistory("","","","# $_"); + while (<INPUT>) { + tr/\015//d; + last if (/^$prompt/); + + /Unrecognized command/ && return(1); + /^\s+\^/ && return(1); + /syntax error/ && return(1); + /^JUNOS / && <INPUT> && next; + /No such file or directory$/ && next; + + ProcessHistory("","","","# $_"); + } + return(0); +} + +# This routine parses "show system license" +sub ShowSystemLicense { + print STDERR " In ShowSystemLicense: $_" if ($debug); + + s/^[a-z]+@//; + ProcessHistory("","","","# $_"); + while (<INPUT>) { + tr/\015//d; + last if (/^$prompt/); + next if (/^system (shutdown message from|going down )/i); + next if (/^\{(master|backup)}/); + + /Unrecognized command/ && return; + /command is not valid/ && return; + /^\s+\^/ && return; + /syntax error/ && return; + + ProcessHistory("","","","# $_"); + } + return(0); +} + +# This routine parses "show system license keys" +sub ShowSystemLicenseKeys { + print STDERR " In ShowSystemLicenseKeys: $_" if ($debug); + + s/^[a-z]+@//; + ProcessHistory("","","","# $_"); + while (<INPUT>) { + tr/\015//d; + last if (/^$prompt/); + next if (/^system (shutdown message from|going down )/i); + next if (/^\{(master|backup)}/); + + /Unrecognized command/ && return; + /command is not valid/ && return; + /^\s+\^/ && return; + /syntax error/ && return; + + ProcessHistory("","","","# $_"); + } + return(0); } # This routine parses "show system boot-messages" @@ -360,13 +477,15 @@ sub ShowSystemBootMessages { ProcessHistory("","","","# $_"); while (<INPUT>) { tr/\015//d; - last if(/^$prompt/); - next if(/^system (shutdown message from|going down )/i); - next if(/^\{(master|backup)}/); + last if (/^$prompt/); + next if (/^system (shutdown message from|going down )/i); + next if (/^\{(master|backup)}/); /Unrecognized command/ && return; + /command is not valid/ && return; /^\s+\^/ && return; /syntax error/ && return; + /^JUNOS / && <INPUT> && next; /^Timecounter "TSC" / && next; /^real memory / && next; @@ -374,7 +493,7 @@ sub ShowSystemBootMessages { /^\/dev\// && next; ProcessHistory("","","","# $_"); } - return; + return(0); } # This routine parses "show version" @@ -385,17 +504,17 @@ sub ShowVersion { ProcessHistory("","","","# $_"); while (<INPUT>) { tr/\015//d; - last if(/^$prompt/); - next if(/^\s*$/); - next if(/^system (shutdown message from|going down )/i); - next if(/^\{(master|backup)}/); + last if (/^$prompt/); + next if (/^\s*$/); + next if (/^system (shutdown message from|going down )/i); + next if (/^\{(master|backup)}/); /^Juniper Networks is:/ && ProcessHistory("","","","# \n# $_") && next; ProcessHistory("","","","# $_"); } ProcessHistory("","","","#\n"); - return; + return(0); } # This routine parses "show configuration" @@ -409,20 +528,21 @@ sub ShowConfiguration { while (<INPUT>) { tr/\015//d; next if (/^\s*$/); - # end of config - hopefully. juniper does not have a reliable + # end of config - hopefully. juniper does not have a reliable # end-of-config tag. appears to end with "\nPROMPT>", but not sure. - if(/^$prompt/) { + if (/^$prompt/) { $found_end++; last; } - next if(/^system (shutdown message from|going down )/i); - next if(/^\{(master|backup)}/); + next if (/^system (shutdown message from|going down )/i); + next if (/^\{(master|backup)}/); $lines++; /^database header mismatch: / && return(-1); /^version .*;\d+$/ && return(-1); s/ # SECRET-DATA$//; + s/ ## SECRET-DATA$//; # filter snmp community, when in snmp { stanza } /^snmp/ && $snmp++; /^}/ && ($snmp = 0); @@ -435,6 +555,10 @@ sub ShowConfiguration { ProcessHistory("","","","#$1<removed>$'"); next; } + if (/(\s*md5 \d+ key )[^ ;]+/ && $filter_pwds >= 1) { + ProcessHistory("","","","#$1<removed>$'"); + next; + } if (/(\s*hello-authentication-key )[^ ;]+/ && $filter_pwds >= 1) { ProcessHistory("","","","#$1<removed>$'"); next; @@ -464,7 +588,7 @@ sub ShowConfiguration { return(-1); } - return; + return(0); } ### @@ -475,44 +599,45 @@ sub ShowConfiguration { sub DoNothing {print STDOUT;} # Main -%commands=( - "show chassis clocks" => "ShowChassisClocks", - "show chassis environment" => "ShowChassisEnvironment", - "show chassis firmware" => "ShowChassisFirmware", - "show chassis fpc detail" => "ShowChassisFpcDetail", - "show chassis hardware detail" => "ShowChassisHardware", - "show chassis routing-engine" => "ShowChassisRoutingEngine", - "show chassis scb" => "ShowChassisSCB", - "show chassis sfm detail" => "ShowChassisSCB", - "show chassis ssb" => "ShowChassisSCB", - "show chassis feb" => "ShowChassisSCB", - "show chassis cfeb" => "ShowChassisSCB", - "show chassis alarms" => "ShowChassisAlarms", - "show system boot-messages" => "ShowSystemBootMessages", - "show version detail" => "ShowVersion", - "show configuration" => "ShowConfiguration" -); -@commands=( - "show chassis clocks", - "show chassis environment", - "show chassis firmware", - "show chassis fpc detail", - "show chassis hardware detail", - "show chassis routing-engine", - "show chassis scb", - "show chassis sfm detail", - "show chassis ssb", - "show chassis feb", - "show chassis cfeb", - "show chassis alarms", - "show system boot-messages", - "show version detail", - "show configuration" +@commandtable = ( + {'show chassis clocks' => 'ShowChassisClocks'}, + {'show chassis environment' => 'ShowChassisEnvironment'}, + {'show chassis firmware' => 'ShowChassisFirmware'}, + {'show chassis fpc detail' => 'ShowChassisFpcDetail'}, + {'show chassis hardware detail' => 'ShowChassisHardware'}, + {'show chassis routing-engine' => 'ShowChassisRoutingEngine'}, + {'show chassis scb' => 'ShowChassisSCB'}, + {'show chassis sfm detail' => 'ShowChassisSCB'}, + {'show chassis ssb' => 'ShowChassisSCB'}, + {'show chassis feb detail' => 'ShowChassisSCB'}, + {'show chassis feb' => 'ShowChassisSCB'}, + {'show chassis cfeb' => 'ShowChassisSCB'}, + {'show chassis alarms' => 'ShowChassisAlarms'}, +# {'show system autoinstallation status' => 'ShowSystemAutoinstall'}, + {'show system license' => 'ShowSystemLicense'}, +# {'show system license keys' => 'ShowSystemLicenseKeys'}, + {'show system boot-messages' => 'ShowSystemBootMessages'}, + {'show system core-dumps' => 'ShowSystemCoreDumps'}, + {'show version detail' => 'ShowVersion'}, + {'show configuration' => 'ShowConfiguration'} ); +# 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); $jnx_commands=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 @@ -523,21 +648,21 @@ if ($file) { print STDOUT "opening file $host\n" if ($log); open(INPUT,"< $host") || die "open failed for $host: $!\n"; } else { - print(STDERR "executing echo jlogin -c\"$jnx_commands\" $host\n") if ($debug); - print(STDOUT "executing echo jlogin -c\"$jnx_commands\" $host\n") if ($debug); + print(STDERR "executing echo jlogin -t $timeo -c\"$jnx_commands\" $host\n") if ($debug); + print(STDOUT "executing echo jlogin -t $timeo -c\"$jnx_commands\" $host\n") if ($debug); if (defined($ENV{NOPIPE})) { - system "jlogin -c \"$jnx_commands\" $host </dev/null > $host.raw" || die "jlogin failed for $host: $!\n"; + system "jlogin -t $timeo -c \"$jnx_commands\" $host </dev/null > $host.raw" || die "jlogin failed for $host: $!\n"; open(INPUT, "< $host.raw") || die "jlogin failed for $host: $!\n"; } else { - open(INPUT,"jlogin -c \"$jnx_commands\" $host </dev/null |") || die "jlogin failed for $host: $!\n"; + open(INPUT,"jlogin -t $timeo -c \"$jnx_commands\" $host </dev/null |") || die "jlogin failed for $host: $!\n"; } } # determine password filtering mode if ($ENV{"FILTER_PWDS"} =~ /no/i) { - $filter_pwds = 0; + $filter_pwds = 0; } elsif ($ENV{"FILTER_PWDS"} =~ /all/i) { $filter_pwds = 2; } else { @@ -545,7 +670,7 @@ if ($ENV{"FILTER_PWDS"} =~ /no/i) { } ProcessHistory("","","","# RANCID-CONTENT-TYPE: juniper\n#\n"); -TOP: while(<INPUT>) { +TOP: while (<INPUT>) { tr/\015//d; if (/^Error:/) { print STDOUT ("$host jlogin error: $_"); |