Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
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
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            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: (11)
    As of 2015-07-30 15:12 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









      Results (271 votes), past polls