Testing for port connectivity
Anonymous Monk
created: 2006-09-04 08:08:39
I am trying to cook up something to check the availability of the following ports on a list of hosts:

22
13724
1556
30031
30032
13720
13782

I want to run through a list and check that all of the IP addresses list can be reached via IP on all of the ports listed above. The script needs to run all the way through whether an individual command passes or fails and needs to report something like:

Hostname
22 - yes
13724 - yes
1556 - yes
30031 - no
30032 - yes

I know I can use IO::Socket::PortState
use strict;
   use warnings;
   use IO::Socket::PortState qw(check_ports);

   my %porthash = ( ... );

   check_ports($host,$timeout,\%porthash);

   for my $proto (keys %porthash) {
      for(keys %{ $porthash{$proto} }) {
         print "$proto $_ is not open ($porthash{$proto}->{$_}->{name}) if !$porthash{$proto}->{$_}->{open};
      }
   }
But I want it to run thru a list and jump to different machines like so
#!/usr/bin/perl -w

open  (IN,  ") {
  chomp;
  system("telnet  $_");  ### get return status here??
}
Re: Testing for port connectivity
created: 2006-09-04 08:20:30
I think you mean open (IN, "hostnames.txt";

Try something more like this?

#!/usr/bin/perl -w
use strict;

use IO::Socket::PortState qw(check_ports);

my $proto = 'tcp';
my $port = '23';
my $service = 'telnet port';
my $address = '70.114.230.116'; 
my $porthash{$proto}->{$port}->{'name'} = $section;
check_ports( $address, $ping_timeout, \%porthash );
my $open = $porthash{$proto}->{$port}->{'open'};
if ($open) {
        print "alive\n";
}
else {
        print "dead\n";
}

Cheers -

Jeffery
Re: Testing for port connectivity
created: 2006-09-04 08:30:22
Erm, you pretty much answered your own question (although I'm not quite sure where you cooked up the system("telnet $_") from).
open HOSTS, '<', 'hostnames.txt' or die "Cant open hostnames.txt\n";

while (my $host = ) {
    chomp($host);
    check_ports($host,$timeout,\%porthash);
    # Do other processing stuff here
}

Cheers,
Darren :)

I strongly suspect that you are going to ask next how to use [mod://IO::Socket::PortState], given that you appear to have simply copy/pasted the example code from the documentation - but I may be wrong :)

Update: Okay, since [Corion|somebody] suggested that my initial response to your question may have been a bit mean (and because deep down I really am a very nice guy™), here is some tested and working code that gives the output you are looking for:

#!/usr/bin/perl -w
use strict;
use IO::Socket::PortState qw(check_ports);

my $hostfile = 'hosts.txt';

my %port_hash = (
        tcp => {
            22      => {},
            443     => {},
            80      => {},
            53      => {},
            30032   => {},
            13720   => {},
            13782   => {},
            }
        );

my $timeout = 5;

open HOSTS, '<', $hostfile or die "Cannot open $hostfile:$!\n";

while (my $host = ) {
    chomp($host);
    my $host_hr = check_ports($host,$timeout,\%port_hash);
    print "Host - $host\n";
    for my $port (sort {$a <=> $b} keys %{$host_hr->{tcp}}) {
        my $yesno = $host_hr->{tcp}{$port}{open} ? "yes" : "no";
        print "$port - $yesno\n";
    }
    print "\n";
}

close HOSTS;

The above gives the following output:

Host - 1.2.3.4
22 - no
53 - no
80 - yes
443 - yes
13720 - no
13782 - no
30032 - no

Host - 5.6.7.8
22 - yes
53 - no
80 - yes
443 - yes
13720 - no
13782 - no
30032 - no

Note that I changed a few of the port numbers to those that I knew would be open on the hosts I tested against, and (obviously) altered the ouput to protect the innocent :)

Re^2: Testing for port connectivity
created: 2006-09-04 12:43:19
Thanks McDarren You really helped me out much appreciated!!! Works like a champ!
Re: Testing for port connectivity
brd
created: 2006-09-05 12:25:18
Just in case you don't know, nmap can do exactly what you are doing. `nmap -p 22,13724,etc '
Re^2: Testing for port connectivity
created: 2006-09-05 18:29:18
As brd said, nmap does that and much more, if that is a tool which is available to you. If you aren't familiar with nmap, it will write output files in several different formats, including:
  • normal (-oN)
  • XML (-oX)
  • "s| grepable format (-oG)
  • perlmonks.org content © perlmonks.org and Anonymous Monk, brd, JSchmitz, McDarren, RobPayne

    prlmnks.org © 2006 edmund von der burg (eccles & toad)

    v 0.03