Beefy Boxes and Bandwidth Generously Provided by pair Networks Cowboy Neal with Hat
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Comment on

( #3333=superdoc: print w/ replies, xml ) Need Help??
#!/usr/bin/perl -w # cdp-n.pl # pod at tail use strict; use Net::Telnet::Cisco; use Term::ReadKey; use Tie::IxHash; ### Begin Config Parameters ### my %parm = ( tntimeout => 10, pwtimeout => 60, errmode => 'return', ); my %file = ( in => 'cdp-n.in', tmp0 => 'cdp-n.tmp0', tmp1 => 'cdp-n.tmp1', tmp2 => 'cdp-n.tmp2', tmp3 => 'cdp-n.tmp3', tmp4 => 'cdp-n.tmp4', uniqout => 'cdp-n.uniq', ); my @tmpfiles = qw( $file{tmp0} $file{tmp1} $file{tmp2} $file{tmp3} $file{tmp4} ); my @commands = ( 'term leng 0', # IOS 'set leng 0', # CatOS 'sho cdp n de', # distinguish 'details' from 'duplex' ); my @keeplines = ( # lines of text to be kept 'scrpne', # Corporate switches 'cff', # old Frozen switches at Campus 5 'pdl', # old Frozen switches at Campus 6 ); my @stripchars = ( # specific text to be stripped from what's l +eft '\.\w.*', # domain name (if present) through end-of-li +ne '^.*\(', # characters and paren before devicename '\).*$', # paren after devicename through end-of-line 'device-id:\s', # preceeds some switches, dunno why 'device id:\s', # preceeds some switches, dunno why '^.*>.*$', # command prompts '^\s+', # leading spaces ); my @striplines = ( # strip all lines containing this text '-MSFC', '-msfc', 'RSM', 'rsm', 'Password', 'password', 'unintialized value', ); ### End Config Parameters ### my ($pass, %seen); Usage() unless ((@ARGV) or (-s $file{in} && -T_)); open (TMP1, ">$file{tmp1}") or die "Error opening $file{tmp1} WO: $!"; close (TMP1) or die "Error closing $file{tmp1}: $1"; # $file{tmp1} must be present to prevent errors if first device unreac +hable print "\n", " Prompting for password\n", " (*not* echoed to screen nor written to disk)\n\n", ' Enter password:'; ReadMode('noecho'); eval { local $SIG{ALRM} = sub { die "ALARUM" }; alarm("$parm{pwtimeout}"); chomp($pass = <STDIN>); alarm(0); }; if ($@ =~ /ALARUM/) { print "\n\n", " Sorry - you waited too long before entering a password.\n", " Try again, if you want.\n\n"; ReadMode(0); exit; } ReadMode(0); unless (@ARGV) { print " using $file{in} for input\n"; @ARGV = $file{in}; chomp (@ARGV = <>); } print "\n Starting CDP neighbor check, shouldn't take long...\n"; for my $cisco (@ARGV) { if (my $cs=Net::Telnet::Cisco->new( host => $cisco, timeout => $parm{tntimeout}, errmode => $parm{errmode}, input_log => $file{tmp0}, ) ) { $cs->login('',$pass); # vty login print ' ', $cs->last_prompt, ' '; # print to cons +ole for(@commands) { my @output = $cs->cmd($_); } print $cs->last_prompt, "\n"; # print to console $cs->close; # exit session open (TMP0, "<$file{tmp0}") or die "Error opening $file{tmp0} RO: $!"; open (TMP1, ">>$file{tmp1}") or die "Error opening $file{tmp1} for append: $!"; while (<TMP0>) { print TMP1 $_; } close (TMP0) or die "Error closing $file{t +mp0}: $!"; close (TMP1) or die "Error closing $file{t +mp1}: $!"; } else { warn "Error connecting to $cisco\n"; } # if telnet connec +t fail } unlink ($file{tmp0}) or die "Error unlinking $file +{tmp0}: $!"; print " Finished CDP neighbor check.\n"; print " Extracting lines of interest...\n"; open (TMP1, "<$file{tmp1}") or die "Error opening $file{tmp1} RO: $!"; open (TMP2, ">$file{tmp2}") or die "Error opening $file{tmp2} RW: $!"; while (<TMP1>) { foreach my $keep(@keeplines) { if (/$keep/i) { print TMP2 $_; } } } close (TMP1) or die "Error closing $file{tmp1}: $!"; unlink ($file{tmp1}) or die "Error unlinking $file{tmp1}: $!"; close (TMP2) or die "Error closing $file{tmp2}: $!"; print " Stripping unwanted characters...\n"; open (TMP2, "<$file{tmp2}") or die "Error opening $file{tmp2} RO: $!"; open (TMP3, ">$file{tmp3}") or die "Error opening $file{tmp3} RW: $!"; while (<TMP2>) { foreach my $strip(@stripchars) { s/$strip//gi; } tr/A-Z/a-z/; print TMP3 $_; } close (TMP2) or die "Error closing $file{tmp2}: $!"; unlink ($file{tmp2}) or die "Error unlinking $file{tmp2}: $!"; close (TMP3) or die "Error closing $file{tmp3}: $!"; print " Stripping unwanted lines...\n"; open (TMP3, "<$file{tmp3}") or die "Error opening $file{tmp3} RO: $!" +; open (TMP4, ">$file{tmp4}") or die "Error opening $file{tmp4} RW: $!" +; while (<TMP3>) { foreach my $strip(@striplines) { s/^.*$strip.*//gi; } s/^\s+$//gi; print TMP4 $_; } close (TMP3) or die "Error closing $file{tmp3}: $!"; unlink ($file{tmp3}) or die "Error unlinking$file{tmp3}: $!"; close (TMP4) or die "Error closing $file{tmp4}: $!"; print " Stripping duplicate lines...\n"; open (TMP4, "<$file{tmp4}") or die "Error opening $file{tmp4} RO: $ +!"; open (UNIQ, ">$file{uniqout}") or die "Error opening $file{uniqout} RW +: $!"; foreach my $item (<TMP4>) { ++$seen{$item}; # parse $file{in} into a hash } # and remove duplicate keys print UNIQ sort keys %seen; # sort keys and save to $outfile close TMP4 or die "Cannot close $file{tmp4}: $!"; unlink ($file{tmp4}) or die "Error unlinking$file{tmp4}: $!"; close UNIQ or die "Cannot close $file{uniqout}: $!"; print " Finished parsing results.\n", " Output at $file{uniqout}\n\n\a"; ###################################################################### +##### sub Usage { print <<EOF; D'oh! You didn't specify any target device(s) on command-line or at +$file{in}. If you want to try again, use the following syntax: cdp-n.pl switch1 switch2 switch3 will query the 3 named (or numbered) switches for CDP neighbors cdp-n.pl with no arguments will read $file{in} for list of switches to quer +y. $file{in} would be a text file that looks like this: switch1 switch2 switch3 ASCII text file One IP address or DNS name per line FQDN if targets in different DNS domain No leading/trailing spaces No blank lines First run this program against a core switch, then recurse down, using output as next input. Review and edit .in files between recursions, and specify different outfile for each iteration also. Remember to add each recursion back into final results, then run uniq.pl to sort and extract unique entries. Net::Telnet::Cisco $Net::Telnet::Cisco::VERSION Net::Telnet $Net::Telnet::VERSION Term::Readkey $Term::ReadKey::VERSION Tie::IxHash $Tie::IxHash::VERSION Perl $] OS $^O Program $0 EOF exit; # exit instead of die, so no error to cons +ole } ###################################################################### +##### sub Pause { print "<enter> to continue, ctrl-C to quit.\n"; (<STDIN>); } ###################################################################### +##### =head1 Name cdp-n.pl =head1 Summary Generate comprehensive list of Cisco LAN switches installed. =head1 Usage cdp-n.pl switch1 switch2 switch3 will query the 3 named (or numbered) switches for CDP neighbors cdp-n.pl with no arguments will read $file{in} for list of switches to quer +y. $file{in} would be a text file that looks like this: switch1 switch2 switch3 ASCII text file One IP address or DNS name per line FQDN if targets in different DNS domain No leading/trailing spaces No blank lines First run this program against a core switch, then recurse down, using output as next input. Review and edit .in files between recursions, and move outfile for each iteration also. Remember to add each recursion back into final results, then run uniq.pl to sort and extract unique entries from combined outfile. =head1 Tested with: Perl 5.00503 on Debian 2.2r2 "Espy" against: Catalyst 2916/24, 5500, =head1 Updated 2001-04-25 14:15 Add password timeout Simplify foreach $scalar(@array) to 'for(@array)' and '$_' Hashimafy file scalars Unsubify non-redundant code Mixed-case subroutines Eliminate global vars with my(,) instead of use vars qw() Reformat to 75 chars/line max 2001-03-29 Eliminate unnecessary quotes Change double to single quotes for strings @keep case-insensitive 2000-09-20 Initial working code =head1 ToDos Use File::Slurp to append log (avoid race condition) Use File::Temp instead of multiple temp files =head1 Author Don [ybiC] Royer =head1 Credits Thanks to tilly, fastolfe, japhy, geektron and chromatic for suggestions and critique, and to tilly, mkmcconn and boo_radley for cat filename | sed -e 's/$/.subdomain.dom/' > newfilename to fully-qualify hostnames in resulting outfiles so they can be fed back in as infiles. =cut

In reply to (code) Cisco Neighbors by ybiC

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • Outside of code tags, you may need to use entities for some characters:
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?
    Username:
    Password:

    What's my password?
    Create A New User
    Chatterbox?
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others rifling through the Monastery: (13)
    As of 2014-04-16 16:21 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      April first is:







      Results (432 votes), past polls