preload
File Transfer using XMLRPC, Python, & Ruby IronRuby 1.0 Released
Apr 13

This is a follow-on to my Python Connectivity Check Script that I posted a while back. It functions the same way…its just written in Perl. I use both program as part of a System Connectivity Check program I wrote in Ruby to connect to many hosts, upload one of these connectivity check programs, run it and place the results into an Excel spreadsheet with a simple red/green status. When you are installing systems with hundreds of nodes that all need to talk to 30-odd other nodes, its a huge time saver!

Here’s the code:

#!/opt/perl/bin/perl
#
# nettest.pl
#

use IO::Socket;
use Errno;
$| = 1;

$host = shift;
$port = shift;
$type = shift || "tcp";
$test = shift || "X";        ## "C" for Continuous testing
die "No Host parameter!" if !$host;
die "No Port parameter!" if !$port;

while (true) {
   my $rc = new IO::Socket::INET
         PeerAddr => $host,
         PeerPort => $port,
         Proto  => $type,
         Timeout => 2;
   if ($type eq "udp" or $type eq "UDP") {      ## UDP Socket
     my $buf;
     $rc->send("--TEST LINE--") or die "Send Error: $!\n";
     eval {
       local $SIG{ALRM} = sub { die "-Timeout-\n" };
       alarm 2;
       $rc->recv($buf,1000);
       alarm 0;
       print "Success connecting to $host on port: $port\n";
     };
     if ($@ eq "-Timeout-\n") {
       print "Cannot Connect: Timeout!\n";
     }
   } else {     ## TCP Socket
     if ($!{EISCONN}) { ## Connected!!
       print "Success connecting to $host on port: $port\n";
     } else {
        if ($!{EINVAL})  {  ## "Invalid Argument" => Connection Refused
           print "Cannot Connect: CONNECTION REFUSED!\n";
        }
        if ($!{ENOTCONN} || $!{ETIMEDOUT}) {  ## NotConnected or Timed Out, Error.
           print "Cannot Connect: -$!\n";
        }
        if ($!{EALREADY} || $!{EINPROGRESS}) { ## InProgress or Already Started, try again.
           close $rc;
           my $rc = new IO::Socket::INET
              PeerAddr => $host,
              PeerPort => $port,
              Proto  => $type,
              Timeout => 4;
           if ($!{EISCONN}) {
              print "Success connecting to $host on port: $port\n";
           }
           print "Cannot Connect to $host on port: $port\n"
        } else {
           ## Unknown Error
           print "Cannot Connect: {$!}\n";
        }
     }
   }
   close $rc;
   if ($test ne "C") {
     exit;
   }
   sleep 1;
}

If you took a look at my Python script, this should look very familiar. UDP Sockets under Perl are more of a pain in the rear to check for responses since the ‘Timeout’ value in the IO::Socket::INET call doesn’t seem to be working on my systems.
The program is run like this:

$> perl nettest.pl 10.x.x.x 80 tcp C

The first parameter is the IP address, then what port to connect to, then what protocol to use (tcp or udp), then an optional ‘C’ if you want continuous tests. The ‘C’ option attempts the connection once a second — very useful when trying to figure out why the router isn’t routing the way you think it should.

SociBook del.icio.us Digg Facebook Google Yahoo Buzz StumbleUpon

One Response to “Perl Connectivity Check Script”

  1. axman Says:

    Hey John, thanks very much for this sample script. It does help me a lot in testing the connection.

Leave a Reply