Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??

I currently have quite alot of cisco switches and routers that I am responsible for maintaining. I got very sick of having to log into a dozen different devices to make the same changes on everyone of them.

I started playing around with perl hoping it would get the job done. I've really never done much programming in the past, aside from very simple shell scripts.

I wrote the following piece of code to simplify my life abit and am happy with how it works. I know there are some obvious security problems with it (currently I run it as root to be able to ping my targets first to verify that they are up) and there are problem several spots where I could have been much more concise.

I am basically looking for some constructive criticism on what I've got and how to improve it. Like I wrote earlier I don't have much programming experience so don't abuse me too bad.

The script takes as its first argument the name of the file that it will feed to the device it connects to. It can take as additional arguments either the name of a file full of IPs(specified with -l as the second argument) or will accept any number of IPs as arguments.

#!/usr/bin/perl -w #********************************************************************* +** #** Written to make making the same configuration changes to a number +** #** of devices less of a pain in the ass. Written with CISCO Routers +** #** and switches in mind it should work with any devices that can be +** #** sent commands via telnet. +** #********************************************************************* +** use strict; my ($script, $i, $telnetpid); unless ( @ARGV >= 2 ) { die "usage: $0 script ip ... " }#Test to verif +y that the re is the minimum number of arguments $script = $ARGV[0]; #Take the first argument as the name of the fi +le to pull commands from shift; #Remove the first argument from the list of ar +guments #Feeding a list of IPs if ( $ARGV[0] eq '-l' ){ #If the new first argument is -l we know to l +ook for a list of IPs if ( $ARGV[1] ){ #Make sure there is a list specified on the c +ommand lin e open(IPLIST, $ARGV[1]) || die "can't open $ARGV[1]\n"; while(<IPLIST>){ feedip($script, $_); } close(IPLIST) } else { die "Need to supply a list of IPs when using $ARGV[0] + \n"; } } #Feeding IPs from the command line else { foreach $i (@ARGV ) { feedip($script, $i); } } #*************************************************************** #** Subroutines below here ** #*************************************************************** #This subroutine is based heavily on code mooched from "Learning Perl" + by Randal l Schwartz and Tom Christainsen sub telnet { use IO::Socket; my ($host, $port, $kidpid, $handle, $line); unless (@_ == 2) { die "usage: $0 host port" } $host = $_[0]; $port = $_[1]; #creates a tcp connection to the specified host and port $handle = IO::Socket::INET->new(Proto => "tcp", PeerAddr => $host, PeerPort => $port) or die "can't connect to port $port on $host: $!"; $handle->autoflush(1); # so output gets there right away print STDERR "[Connected to $host:$port]\n"; # split the program into two processes die "can't fork: $!" unless defined($kidpid = fork()); #the if{} block runs only in the parent process if ($kidpid) { #copy the socket to standard output while (defined ($line = <$handle>)) { print STDOUT $line; } kill("TERM", $kidpid); #send SIGTERM to child } #the else{} block runs only in the child process else { # copy standard input to the socket while (defined ($line = <SCRIPT>)){ print $handle $line; } } } sub feedip { my($p); use Net::Ping; $p = new Net::Ping("icmp"); unless (@_ == 2) { die "usage: $0 host port" } if ($_[1] =~ m{\d+\.\d+\.\d+\.\d+}){ #Test to see if we +were given an IP, invalid IPs can still slip through if ($p->ping($_[1])){ #Test to see that host is up $p->close(); open(SCRIPT, $_[0]) || die "Cannot open $scrip +t\n"; # Open the script file #Fork a new process for the telnet subroutine, + wait for it to finish before returning if (!defined($telnetpid = fork())) { die "Cannot fork: $!"; } elsif ($telnetpid == 0) { telnet($_[1], 23); #Options be +ing sent t o sub telnet( IP, Port) exit; } else { waitpid($telnetpid, 0); } close(SCRIPT) || die "Cannot close $script\n"; + #Close th e script file } else{ print "$_[1] does not appear to be responding, + skipping. \n"; $p->close(); } } else { warn "$_[1] did not appear to be an IP address, skippi +ng.\n "; } }
Thanks in advance for any input you can give me.

2001-05-14 Edit by Corion : Changed title to be more descriptive. Added formatting.


In reply to Peer review of Cisco switch administration utility (was: ok I know it's crap but I'm proud of it...) by fingers

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



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (4)
As of 2024-03-28 17:49 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found