#!/usr/bin/perl -w
#
# Nagios plugin to check a range/set of tcp ports on a host.
#

use strict;
use File::Basename;
use IO::Socket;
BEGIN {
  use lib dirname($0);
  use Nagios::Plugin 0.03;
}

my $VERSION = '0.1 [http://www.openfusion.com.au/labs/nagios/]';

my ($host, $ports);
my $BLURB = qq(This plugin tests arbitrary ranges/sets of tcp ports for a host.\n);
my $USAGE = qq(Usage: %s -H <host> -p <ports> [-v]\n);
my @SPEC = (
  "hostname|H=s" => [ \$host,
  q(-H, --hostname=ADDRESS
   Host name or IP address), 1 ],
  "ports|port|p=s" => [ \$ports, 
  q(-p, --ports=STRING
   Port numbers to check. Format: comma-separated, hyphens for ranges, no spaces 
   e.g. 8700-8705,8710-8715,8760 ), 1 ],
);

# ----------------------------------------------------------------------------
# Subroutines

sub check_tcp
{
  my ($host, $port) = @_;
  eval { IO::Socket::INET->new("$host:$port") }
}

# ----------------------------------------------------------------------------

parse_args(
  version => $VERSION,
  usage => $USAGE,
  spec => \@SPEC,
  blurb => $BLURB,
);

alarm($TIMEOUT);

my @closed = ();
my @open = ();
for my $p (map { m/-/ ? [ split /-/, $_, 2 ] : $_ } split /,/, $ports) {
  if (ref $p eq 'ARRAY') {
    for (my $i = $p->[0]; $i <= $p->[1]; $i++) {
      if (check_tcp($host, $i)) {
        push @open, $i;
      } else {
        push @closed, $i;
      }
    }
  }
  else {
    if (check_tcp($host, $p)) {
      push @open, $p;
    } else {
      push @closed, $p;
    }
  }
}

my $results = '';
$results .= 'closed ports: ' . join(',',@closed) if @closed;
$results .= ' : ' if @closed && @open;
$results .= 'open ports: '   . join(',',@open)   if @open;
exit_results(
  CRITICAL => \@closed, 
  results => $results,
);  


# arch-tag: 39277909-f754-4ede-99a6-d128d16dc07c
# vim:ft=perl:ai:sw=2
