Advertisement
Guest User

bnrancid

a guest
Oct 22nd, 2013
153
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 11.03 KB | None | 0 0
  1. #! /usr/bin/perl
  2. ##
  3. ## $Id: brancid.in 2279 2011-01-31 22:41:00Z heas $
  4. ## hacked version of Hank's rancid - this one tries to deal with Bay's.
  5. ##
  6. ## rancid 2.3.8
  7. ## Copyright (c) 1997-2008 by Terrapin Communications, Inc.
  8. ## All rights reserved.
  9. ##
  10. ## This code is derived from software contributed to and maintained by
  11. ## Terrapin Communications, Inc. by Henry Kilmer, John Heasley, Andrew Partan,
  12. ## Pete Whiting, Austin Schutz, and Andrew Fort.
  13. ##
  14. ## Redistribution and use in source and binary forms, with or without
  15. ## modification, are permitted provided that the following conditions
  16. ## are met:
  17. ## 1. Redistributions of source code must retain the above copyright
  18. ##    notice, this list of conditions and the following disclaimer.
  19. ## 2. Redistributions in binary form must reproduce the above copyright
  20. ##    notice, this list of conditions and the following disclaimer in the
  21. ##    documentation and/or other materials provided with the distribution.
  22. ## 3. All advertising materials mentioning features or use of this software
  23. ##    must display the following acknowledgement:
  24. ##        This product includes software developed by Terrapin Communications,
  25. ##        Inc. and its contributors for RANCID.
  26. ## 4. Neither the name of Terrapin Communications, Inc. nor the names of its
  27. ##    contributors may be used to endorse or promote products derived from
  28. ##    this software without specific prior written permission.
  29. ## 5. It is requested that non-binding fixes and modifications be contributed
  30. ##    back to Terrapin Communications, Inc.
  31. ##
  32. ## THIS SOFTWARE IS PROVIDED BY Terrapin Communications, INC. AND CONTRIBUTORS
  33. ## ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  34. ## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  35. ## PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COMPANY OR CONTRIBUTORS
  36. ## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  37. ## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  38. ## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  39. ## INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  40. ## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  41. ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  42. ## POSSIBILITY OF SUCH DAMAGE.
  43. #
  44. #  RANCID - Really Awesome New Cisco confIg Differ
  45. #
  46. # usage: rancid [-dV] [-l] [-f filename | hostname]
  47. #
  48. use Getopt::Std;
  49. getopts('dflV');
  50. if ($opt_V) {
  51.     print "rancid 2.3.8\n";
  52.     exit(0);
  53. }
  54. $log = $opt_l;
  55. $debug = $opt_d;
  56. $file = $opt_f;
  57. $host = $ARGV[0];
  58. $clean_run = 0;
  59. $found_end = 0;
  60. $timeo = 90;                            # blogin timeout in seconds
  61.  
  62. my(@commandtable, %commands, @commands);# command lists
  63. my($aclsort) = ("ipsort");              # ACL sorting mode
  64. my($filter_commstr);                    # SNMP community string filtering
  65. my($filter_pwds);                       # password filtering mode
  66.  
  67. # This routine is used to print out the router configuration
  68. sub ProcessHistory {
  69.     my($new_hist_tag,$new_command,$command_string,@string) = (@_);
  70.     if ((($new_hist_tag ne $hist_tag) || ($new_command ne $command))
  71.         && scalar(%history)) {
  72.         print eval "$command \%history";
  73.         undef %history;
  74.     }
  75.     if (($new_hist_tag) && ($new_command) && ($command_string)) {
  76.         if ($history{$command_string}) {
  77.             $history{$command_string} = "$history{$command_string}@string";
  78.         } else {
  79.             $history{$command_string} = "@string";
  80.         }
  81.     } elsif (($new_hist_tag) && ($new_command)) {
  82.         $history{++$#history} = "@string";
  83.     } else {
  84.         print "@string";
  85.     }
  86.     $hist_tag = $new_hist_tag;
  87.     $command = $new_command;
  88.     1;
  89. }
  90.  
  91. sub numerically { $a <=> $b; }
  92.  
  93. # This is a sort routine that will sort numerically on the
  94. # keys of a hash as if it were a normal array.
  95. sub keynsort {
  96.     local(%lines) = @_;
  97.     local($i) = 0;
  98.     local(@sorted_lines);
  99.     foreach $key (sort numerically keys(%lines)) {
  100.         $sorted_lines[$i] = $lines{$key};
  101.         $i++;
  102.     }
  103.     @sorted_lines;
  104. }
  105.  
  106. # This is a sort routine that will sort on the
  107. # keys of a hash as if it were a normal array.
  108. sub keysort {
  109.     local(%lines) = @_;
  110.     local($i) = 0;
  111.     local(@sorted_lines);
  112.     foreach $key (sort keys(%lines)) {
  113.         $sorted_lines[$i] = $lines{$key};
  114.         $i++;
  115.     }
  116.     @sorted_lines;
  117. }
  118.  
  119. # This is a sort routine that will sort on the
  120. # values of a hash as if it were a normal array.
  121. sub valsort{
  122.     local(%lines) = @_;
  123.     local($i) = 0;
  124.     local(@sorted_lines);
  125.     foreach $key (sort values %lines) {
  126.         $sorted_lines[$i] = $key;
  127.         $i++;
  128.     }
  129.     @sorted_lines;
  130. }
  131.  
  132. # This is a numerical sort routine (ascending).
  133. sub numsort {
  134.     local(%lines) = @_;
  135.     local($i) = 0;
  136.     local(@sorted_lines);
  137.     foreach $num (sort {$a <=> $b} keys %lines) {
  138.         $sorted_lines[$i] = $lines{$num};
  139.         $i++;
  140.     }
  141.     @sorted_lines;
  142. }
  143.  
  144. # This is a sort routine that will sort on the
  145. # ip address when the ip address is anywhere in
  146. # the strings.
  147. sub ipsort {
  148.     local(%lines) = @_;
  149.     local($i) = 0;
  150.     local(@sorted_lines);
  151.     foreach $addr (sort sortbyipaddr keys %lines) {
  152.         $sorted_lines[$i] = $lines{$addr};
  153.         $i++;
  154.     }
  155.     @sorted_lines;
  156. }
  157.  
  158. # These two routines will sort based upon IP addresses
  159. sub ipaddrval {
  160.     my(@a) = ($_[0] =~ m#^(\d+)\.(\d+)\.(\d+)\.(\d+)$#);
  161.     $a[3] + 256 * ($a[2] + 256 * ($a[1] +256 * $a[0]));
  162. }
  163. sub sortbyipaddr {
  164.     &ipaddrval($a) <=> &ipaddrval($b);
  165. }
  166.  
  167. # This routine parses "show config"
  168. sub ShowConfig {
  169.     print STDERR "    In ShowConfig: $_" if ($debug);
  170.  
  171.     while (<INPUT>) {
  172.         tr/\015//d;
  173.         last if (/^$prompt/);
  174.         next if (/^(\s*|\s*$cmd\s*)$/);
  175.         next if (/^Reading configuration information/);
  176.         next if (/^Can\'t find object or class named \"\-all\"\s*$/);
  177.         next if (/lock-address .*$/);
  178.         next if (/^\# *uptime +\d+\s*$/);
  179.         if (/community label /) {
  180.             if ($filter_commstr) {
  181.                 $_ =~ s/community label .*$/community label <removed>/;
  182.             }
  183.         }
  184.         return(1) if /(invalid command name)/;
  185.         ProcessHistory("","","","$_");
  186.     }
  187.     # ProcessHistory("","","","!$_");
  188.     if (/exit$/) {
  189.         $found_end = 1;
  190.         return(1);
  191.     }
  192.     return(0);
  193. }
  194.  
  195. # This routine parses single command's that return no required info
  196. sub RunCommand {
  197.     print STDERR "    In RunCommand: $_" if ($debug);
  198.  
  199.     while (<INPUT>) {
  200.         tr/\015//d;
  201.         last if (/^$prompt/);
  202.         next if (/^(\s*|\s*$cmd\s*)$/);
  203.         # prompt may have changed
  204.         if (/\>/) {
  205.             $prompt = ($_ =~ /^([^>#]+[>#])/)[0];
  206.             $prompt =~ s/([][])/\\$1/g;
  207.             last;
  208.         }
  209.     }
  210.     return(0)
  211. }
  212.  
  213. sub ExitCommand { while(<INPUT>) { next; } $found_end = 1; $clean_run = 1; return 0; }
  214.  
  215. # dummy function
  216. sub DoNothing {print STDOUT;}
  217.  
  218. # Main
  219. @commandtable = (
  220.         {'terminal length 0'    => 'RunCommand'},
  221.         {'show config'          => 'ShowConfig'},
  222.         {'show running-config'  => 'ShowConfig'},
  223.         {'show autosave'        => 'ShowConfig'},
  224.         {'exit'                 => 'ExitCommand'}
  225. );
  226. # Use an array to preserve the order of the commands and a hash for mapping
  227. # commands to the subroutine and track commands that have been completed.
  228. @commands = map(keys(%$_), @commandtable);
  229. %commands = map(%$_, @commandtable);
  230.  
  231. $cisco_cmds=join(";",@commands);
  232. $cmds_regexp = join("|", map quotemeta($_), @commands);
  233.  
  234. if (length($host) == 0) {
  235.     if ($file) {
  236.         print(STDERR "Too few arguments: file name required\n");
  237.         exit(1);
  238.     } else {
  239.         print(STDERR "Too few arguments: host name required\n");
  240.         exit(1);
  241.     }
  242. }
  243. open(OUTPUT,">$host.new") || die "Can't open $host.new for writing: $!\n";
  244. select(OUTPUT);
  245. # make OUTPUT unbuffered if debugging
  246. if ($debug) { $| = 1; }
  247.  
  248. if ($file) {
  249.     print STDERR "opening file $host\n" if ($debug);
  250.     print STDOUT "opening file $host\n" if ($log);
  251.     open(INPUT,"<$host") || die "open failed for $host: $!\n";
  252. } else {
  253.     print STDERR "executing bnlogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($debug);
  254.     print STDOUT "executing bnlogin -t $timeo -c\"$cisco_cmds\" $host\n" if ($log);
  255.     if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) {
  256.        system "bnlogin -t $timeo -c \"$cisco_cmds\" $host </dev/null > $host.raw 2>&1" || die "bnlogin failed for $host: $!\n";
  257.        open(INPUT, "< $host.raw") || die "bnlogin failed for $host: $!\n";
  258.     } else {
  259.         open(INPUT,"bnlogin -t $timeo -c \"$cisco_cmds\" $host </dev/null |") || die "bnlogin failed for $host: $!\n";
  260.     }
  261. }
  262.  
  263. # determine ACL sorting mode
  264. if ($ENV{"ACLSORT"} =~ /no/i) {
  265.     $aclsort = "";
  266. }
  267. # determine community string filtering mode
  268. if (defined($ENV{"NOCOMMSTR"}) &&
  269.     ($ENV{"NOCOMMSTR"} =~ /yes/i || $ENV{"NOCOMMSTR"} =~ /^$/)) {
  270.     $filter_commstr = 1;
  271. } else {
  272.     $filter_commstr = 0;
  273. }
  274. # determine password filtering mode
  275. if ($ENV{"FILTER_PWDS"} =~ /no/i) {
  276.     $filter_pwds = 0;
  277. } elsif ($ENV{"FILTER_PWDS"} =~ /all/i) {
  278.     $filter_pwds = 2;
  279. } else {
  280.     $filter_pwds = 1;
  281. }
  282.  
  283. ProcessHistory("","","","!RANCID-CONTENT-TYPE: baynortel\n!\n");
  284. TOP: while(<INPUT>) {
  285.     tr/\015//d;
  286.     if ( (/[\>#]\s*exit$/) || $found_end ) {
  287.         $clean_run=1;
  288.         last;
  289.     }
  290.     if (/^Error:/) {
  291.         print STDOUT ("$host bnlogin error: $_");
  292.         print STDERR ("$host bnlogin error: $_") if ($debug);
  293.         $clean_run=0;
  294.         last;
  295.     }
  296.     while (/[>#]\s*($cmds_regexp)\s*$/) {
  297.         $cmd = $1;
  298.         if (!defined($prompt)) {
  299.             $prompt = ($_ =~ /^([^>]+>)/)[0];
  300.             $prompt =~ s/([][}{)(\\])/\\$1/g;
  301.             print STDERR ("PROMPT MATCH: $prompt\n") if ($debug);
  302.         }
  303.         print STDERR ("HIT COMMAND:$_") if ($debug);
  304.         if (! defined($commands{$cmd})) {
  305.             print STDERR "$host: found unexpected command - \"$cmd\"\n";
  306.             $clean_run = 0;
  307.             last TOP;
  308.         }
  309.         $rval = &{$commands{$cmd}};
  310.         delete($commands{$cmd});
  311.         if ($rval == -1) {
  312.             $clean_run = 0;
  313.             last TOP;
  314.         }
  315.     }
  316. }
  317. print STDOUT "Done $logincmd: $_\n" if ($log);
  318. # Flush History
  319. ProcessHistory("","","","");
  320. # Cleanup
  321. close(INPUT);
  322. close(OUTPUT);
  323.  
  324. if (defined($ENV{NOPIPE}) && $ENV{NOPIPE} =~ /^YES/i) {
  325.     unlink("$host.raw") if (! $debug);
  326. }
  327.  
  328. # check for completeness
  329. if (scalar(%commands) || !$clean_run || !$found_end) {
  330.     if (scalar(%commands)) {
  331.         printf(STDOUT "$host: missed cmd(s): %s\n", join(',', keys(%commands)));
  332.         printf(STDERR "$host: missed cmd(s): %s\n", join(',', keys(%commands))) if ($debug);
  333.     }
  334.     if (!$clean_run || !$found_end) {
  335.         print STDOUT "$host: End of run not found\n";
  336.         print STDERR "$host: End of run not found\n" if ($debug);
  337.         system("/usr/bin/tail -1 $host.new");
  338.     }
  339.     unlink "$host.new" if (! $debug);
  340. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement