#!/usr/bin/perl
#
# Nagios PLugin:
# Checks (via SNMP tcpConnTable) if a given machine has exactly <n> tcp connections (in State 5 "connected") on a given 
# port <p> to a second machine <m>
#

use strict;
use Net::SNMP::HostInfo;
use Nagios::Plugin;
use Socket;


my $np = Nagios::Plugin->new(
	usage => "Usage: %s [-H |--host <host>] [-p|--remoteport <port>] [-n|--numconnects] [-r|--remotehost] [-V|--snmpversion <version>] [-C|snmpcommunity <community>] [-h|--help]",
	version => "1.00",
	shortname => "TCPCONCHECK",
	url => "http://members.financial.com/~cmr/nagios/",
	blurb => "Checks (via SNMP tcpConnTable)  if a given machine has exactly <n> tcp connections (in State 5 \"connected\") on a given port <p> to a second machine <m>");




$np->add_arg( spec => 'host|H=s',  help => "-h, --host\n  hostname ", required => 1);
$np->add_arg( spec => 'remoteport|p=s',  help => "-p, --remoteport\n  remote port number to check", required => 1);
$np->add_arg( spec => 'numconnects|n=s',  help => "-n, --numconnects\n  number of established TCP connections to check for", required => 1);
$np->add_arg( spec => 'remotehost|r=s',  help => "-r, --numconnects\n  remote host (name or IP) to check for", required => 1);
$np->add_arg( spec => 'snmpversion|V=s',  help => "-V, --snmpversion\n  SNMP version to use (1 or 2, default: 2)", default => "2", required => 0);
$np->add_arg( spec => 'snmpcommunity|C=s',  help => "-C, --snmpcommunmity\n  SNMP comunity string (default: public)", default => "public", required => 0);

$np->getopts();

my $opts = $np->opts();

# if remotehost is a name resolve it
my @addrs = gethostbyname($opts->remotehost);
@addrs = map { inet_ntoa($_) } @addrs[4 .. $#addrs];
print "Remotehost is  @addrs\n" if $opts->verbose;
my $remotehost=$addrs[0];

my ($session, $error) = Net::SNMP->session(-hostname => $opts->host,
				-community => $opts->snmpcommunity,
				-version => $opts->snmpversion);

if (!defined($session)) {
   my $err=sprintf("ERROR opening session: %s.\n", $error);
   $np->nagios_exit(CRITICAL,$err)
}

my $hostinfo = Net::SNMP::HostInfo->new(Session => $session, Decode => 0);
my $counter = 0;
    # walk through table
    for my $entry ($hostinfo->tcpConnTable) {
	# debug
	if ($opts->verbose) {
		printf "%-15s %-5s %-15s %-5s %s\n",
                $entry->tcpConnLocalAddress,
                $entry->tcpConnLocalPort,
                $entry->tcpConnRemAddress,
                $entry->tcpConnRemPort,
                $entry->tcpConnState;
        }
	# matching entries
	if ( ($entry->tcpConnRemPort eq $opts->remoteport) and ($entry->tcpConnRemAddress eq $remotehost)  and ($entry->tcpConnState eq "5")  ) {
		if ($opts->verbose) { print "^ Counting\n"; }
		$counter++;		
	}
    }

my $text = sprintf("Found %s connections on port %s to host %s (should be %s)", $counter, $opts->remoteport, $remotehost, $opts->numconnects);
if ($counter == $opts->numconnects) {
	$np->nagios_exit(OK,$text)
} else {
	$np->nagios_exit(CRITICAL,$text)
}

