Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Comment on

( #3333=superdoc: print w/ replies, xml ) Need Help??
#!/usr/bin/perl -w # switchver.pl # pod at tail use strict; use Net::Telnet::Cisco; # simplify telnet to Cisco +devices use Term::ReadKey; # disable screen echo durin +g password entry use Getopt::Long; # support command-line swit +ches use vars qw( $opt_target $opt_infile $opt_outfile @targets ); my %ntcparm = ( errmode => 'return', # bad command won't kill sc +ript ntctimeout => 20, # seconds to wait for devic +e response pwtimeout => 120, # seconds to wait for passw +ord entry from user ); my %file = ( def_out => 'switchver.csv', tmp0 => 'switchver.tmp0', tmp1 => 'switchver.tmp1', tmp2 => 'switchver.tmp2', ); my @tmpfiles = ( $file{tmp0}, $file{tmp1}, $file{tmp2} ); my @commands = ( # run these from Net::Telne +t::Cisco session 'term leng 0', # IOS 'set leng 0', # CatOS 'sho ver', # What This Program Is All +About ); my @keep = ( # whole lines of text to be + *kept* '>sho ver', # IOS device name # 'Version', # IOS # 'System serial number', # IOS # 'uptime', # IOS '> sho ver', # CatOS device name 'WS-C', # CatOS ); my @strip = ( # specific text to be *stri +pped* from what's left '\r', # CatOS bogus end-of-line ( +should be first regexp) '>sho ver', # IOS device name '> sho ver', # 2948g device name 'System Bootstrap.*$', # 2948g 'Hardware Version.*$', # 2948g 'System serial number: ', # IOS 'Model number.*$', # 3548 'cisco ', # IOS to leave model as lea +ding string in line ' \(PowerPC.*$', # IOS processor, memory, et +c following model number 'Software.*$', # CatOS sw info following m +odel number '^\d.*', # CatOS chassis blade hw in +fo '^\s+', # leading blanks ',', # first step to csv-ifying +output ); ###################################################################### +############ # preliminaries and opening message umask oct 177; # temp files viewable only +by user running this program print "\nStarting $0\n"; GetOptions( 'target=s' => \$opt_target, 'infile=s' => \$opt_infile, 'outfile=s' => \$opt_outfile, ); ###################################################################### +############ # get list of target device(s) if (defined $opt_target) { @targets = $opt_target; print " Target given at command-line switch.\n"; } elsif (defined $opt_infile) { $file{in} = $opt_infile; unless (-r $file{in} && -T _) { &USAGE("Error reading input file \"$file{in}\": \"$!\""); } print " Target list at $file{in}\n"; open (INFILE, "< $file{in}") or die "Error opening $ +file{in}: $!"; @targets = <INFILE>; close INFILE; } else { &USAGE('Error - target device or input file not specified!'); } ###################################################################### +############ # get name of output file if (defined $opt_outfile) { $file{out} = $opt_outfile; print " Output file given at command-line switch.\n"; } else { $file{out} = $file{def_out}; print " Using default output file.\n"; } ###################################################################### +######## # sanity-check target(s) list print " Validating target list...\n"; foreach my $nonsane(@targets) { chomp $nonsane; print (" $nonsane\n"); unless ($nonsane =~ (/^(\w|-|\.)+$/)) { print "\n Ack - \"$nonsane\" is an improperly formatted devic +e name.\n"; print " Only alphanumeric, underscore, dash and dot allowed.\ +n\n"; print " Edit $file{in} or re-enter targets to remove puctuati +on, blank lines and/or blank spaces.\n\n"; exit; # "exit" instead of "die" s +o no error to console } } print (" Specified target name(s) valid.\n"); ###################################################################### +############ # prompt for access password (enable pass not needed for 'show ver' co +mmand print " Enter access password (*not* echoed to screen): "; ReadMode('noecho'); # don't echo password to sc +reen eval { local $SIG{ALRM} = sub { die "ALARUM" }; alarm("$ntcparm{pwtimeout}"); chomp($ntcparm{pwinput} = <STDIN>); alarm(0); }; if ($@ =~ /ALARUM/) { print "\n\n"; print "Sorry - You waited too long before entering a password.\n"; print "Try again, if you want.\n\n"; ReadMode(0); # re-activate screen echo exit; # "exit" instead of "die" s +o no error to console } $ntcparm{password} = $ntcparm{pwinput}; ReadMode(0); # re-activate screen echo print "\n"; ###################################################################### +######## # delete existing out/tmp files print ' Unlinking prior out and temp files...'; &UNLINK($file{out}, 'quiet'); foreach my $tmpfile (@tmpfiles) { &UNLINK($tmpfile, 'quiet'); } print " *poof*\n"; ###################################################################### +############ # connect to each target device, then run command to get device info print (" Target devices queried:\n"); foreach my $target(@targets) { my $ntc; chomp $target; if ($ntc=Net::Telnet::Cisco->new( host => $target, timeout => $ntcparm{ntctimeout}, errmode => $ntcparm{errmode}, input_log => $file{tmp0}, )) { $ntc->login('',$ntcparm{password}); print " ", $ntc->last_prompt, " "; foreach my $command (@commands) { my @output = $ntc->cmd($command); } print " ", $ntc->last_prompt, "\n"; $ntc->close; # if multiple Cisco sessions, append each to same tmpfile open (TMP0, "<$file{tmp0}") or die "Can't open $file{tm +p0} RO: \"$!\""; open (TMP1, ">>$file{tmp1}") or die "Can't open $file{tm +p1} for append: \"$!\""; while (<TMP0>) { print TMP1 $_; } close (TMP0) or die "Can't close $file{t +mp0}: \"$!\""; close (TMP1) or die "Can't close $file{t +mp1}: \"$!\""; } else { warn "Can't connect to $target\n";} #: " . $ntc->errm +sg; } # if telnet connection failed my @output = $ntc->cmd(); } &UNLINK ($file{tmp0}, 'quiet'); # don't leave pw's laying a +round ###################################################################### +############ # munge temp file data # extract lines we *do* want to see open (TMP1, "<$file{tmp1}") or die "Can't open $file{tm +p1} RO: \"$!\""; open (TMP2, ">>$file{tmp2}") or die "Can't open $file{tm +p2} WO: \"$!\""; while (<TMP1>) { foreach my $keep(@keep) { print (TMP2 $_) if /$keep/; } } close (TMP1) or die "Can't close $file{t +mp1}: \"$!\""; close (TMP2) or die "Can't close $file{t +mp2}: \"$!\""; #--------------------------------------------------------------------- +---# # delete specific text don't care about open (TMP2, "<$file{tmp2}") or die "Can't open $file{tm +p2} RO: \"$!\""; open (OUT, ">>$file{out}") or die "Can't open $file{ou +t} WO: \"$!\""; while (<TMP2>) { foreach my $strip(@strip) { s/$strip//g; } s/\n/,\n/g; # second step toward csvify +ing s/\s+,/,/g; # CatOS device-type chomp unless(/WS-/); # final step to csvify print (OUT $_); } close (TMP2) or die "Can't close $file{t +mp2}: \"$!\""; close (OUT) or die "Can't close $file{o +ut}: \"$!\""; ###################################################################### +############ # turn out the lights, it's time to go print " Finished switch versions check.\n"; print ' Unlinking temp files...'; foreach my $tmpfile(@tmpfiles) { &UNLINK($tmpfile, 'quiet'); } print " *poof*\n"; print "Results at $file{out}\n\n"; ###################################################################### +######## # Subroutines start here ###################################################################### +######## # cleanup temp files when done with them sub UNLINK { my $file = $_[0]; my $echo = $_[1]; if (-e $file && -w _) { print " Unlinking $file..." if ($echo eq 'verbose'); unlink $file or die "Error unlinking $fi +le: \"$!\""; print " *poof*\n" if ($echo eq 'verbose'); } } ###################################################################### +### sub PAUSE { print " Ctrl+c to abort or <enter> to continue."; (<STDIN>); } ###################################################################### +############ # Really don't have to explain this'un, eh? sub USAGE { my $specific_err = $_[0]; print <<EOF; $specific_err Usage: getopt.pl <(-t|--target) host> <(-i|--infile) file> <(-o|--outf +ile) file> If target given, then infile switch is ignored. Target can be IP address or hostname or FQDN. Switches include: (note that "=" is optional) --target=sparky *or* -t 172.31.0.5 --outfile another_file *or* -o=another_file --infile=some_file *or* -i some_file You *must* specify either targets or infile. If no outfile given, then hardcoded $file{def_out} is used. EOF ; exit; } ###################################################################### +############ =head1 Name switchver.pl =head1 Summary Automate collection of Cisco LAN switch and router information: device name, hardware type, IOS/CatOS ver, serial number Comments or suggestions are quite welcomed. =head1 Usage Usage: getopt.pl <(-t|--target) host> <(-i|--infile) file> <(-o|--out +file) file> If target given, then infile switch is ignored. Target can be IP address or hostname or FQDN. Switches include: (note that "=" is optional) --target=sparky *or* -t 172.31.0.5 --outfile another_file *or* -o=another_file --infile=some_file *or* -i some_file You *must* specify either targets or infile. If no outfile given, then hardcoded $file{def_out} is used. =head1 Tested with: Perl 5.00503 on Debian 2.2 "Espy" against: 2916, 2924, 3548, 2948g, 4000 5000, 6000 =head1 Updated 2001-04-13 17:30 Remove unecessary Getopt::Long switch abreviations Outfile in csv format Add '\r' to @strip regexp for CatOS data >8^( 2001-04-11 Add command-line switches for target, infile, outf +ile using Getopt::Long. Submit to www.perlmonks.org. 2001-04-10 Hashamafy file and ntc variables. Sanity-check target names. Prompt for access password instead of hard-coded. 2001-04-03 Eliminate unecessary global variables. Consistant indenting. Replace double quotes with single for strings. Eliminate quotes for numbers. Replace multiple "my $tmpfile" with @tmpfile. Unlink temp files instead of overwrite. Add &USAGE(). 2000-10-05 Initial working code. =head1 ToDos Use Net::Snmp sysDescr instead of Net::Telnet::Cisco. simplify data structure simplify parsing/munging simplify program improve security Add regex so hostname with IPaddr-format not stripped by '^\d' in @st +rip Fix ntc so not die on unreachable target Print console to logfile so record of failed attempts Hashamafy Getopt::Long scalar variables Add support for multiple targets and -t switch. Use File::Temp instead of $file{tmp(0..2)}. =head1 Author ybiC =head1 Credits thanks to Petruchio, jeroenes, geektron, damian1301, crazyinsomniac, ar0n and yakko for Getopt::Long suggestions. =cut

In reply to (code) Cisco sho ver 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: (6)
    As of 2014-10-02 11:09 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      What is your favourite meta-syntactic variable name?














      Results (54 votes), past polls