#! /usr/bin/perl -wT
# ------------------------------------------------------------------------------
# File Name:		check_sockets.pl
# Author:		Richard Mayhew - South Africa
# Date:			2000/07/11
# Version:		1.0
# Description:		This script will check to see how may open sockets
#			a server has and waron respectivly
# Email:		netsaint@splash.co.za
# ------------------------------------------------------------------------------
# Copyright 1999 (c) Richard Mayhew
# Credits go to Ethan Galstad for coding Nagios
# If any changes are made to this script, please mail me a copy of the
# changes :)
# Some code taken from Charlie Cook (check_disk.pl)
# License GPL
#
# ------------------------------------------------------------------------------
# Date		Author		Reason
# ----		------		------
# 1999/09/20	RM		Creation
# 1999/09/20	TP		Changed script to use strict, more secure by
#				specifying $ENV variables. The bind command is
#				still insecure through.  Did most of my work
#				with perl -wT and 'use strict'
#
# ------------------------------------------------------------------------------

# -----------------------------------------------------------------[ Require ]--
require 5.004;
# --------------------------------------------------------------------[ Uses ]--
use strict;
use lib utils.pm ;
use Plugin;
use Plugin::Parameter qw(:DEFAULT :thresholds);

use Socket;

use vars qw($PROGNAME $type $warn $crit $opt_t);

use utils qw(%ERRORS);
# --------------------------------------------------------------[ Enviroment ]--
$ENV{'PATH'}='/bin:/sbin:/usr/bin:/usr/sbin';
$ENV{BASH_ENV} = "";
# ------------------------------------------------------------------[ Global ]--
my $type_opt = new Plugin::Parameter(-name => "type", -flags => [ 'T', 'type' ],
				     -optional => "no", -valueoptional => "no", -type => "SOCKETTYPE",
				     -binding => \$type,
				     -description => "Type of sockets to check - TOTAL, TCP, UDP, RAW, ...");
$w_opt->default(256);
$w_opt->optional("yes");
$w_opt->binding(\$warn);
$c_opt->default(512);
$c_opt->optional("yes");
$c_opt->binding(\$crit);
my $plugin = new Plugin(-revision => '$Revision: 1.1.1.1 $',
			-copyright => "2000 Richard Mayhew, Howard Wilkinson <howard\@cohtech.com>",
			-shortcomment => "Check open sockets on a server",
			-parameterlists => [ [ $type_opt, $w_opt, $c_opt, $t_opt ] , $h_opts, $V_opts ]);
# --------------------------------------------------------------[ connection ]--
sub connection
{
	my ($in_total,$in_warn,$in_crit,$in_high) = @_;
	my $state;
	my $answer;

	$in_total =~ s/\ //g;
	if ($in_total >= 0) {

	        if ($in_total > $in_crit) {
			$state = "CRITICAL";
			$answer = "Critical Number Of Sockets Connected : $in_total (Limit = $in_crit)";
		} elsif ($in_total > $in_warn) {
			$state = "WARNING";
			$answer = "Warning Number Of Sockets Connected : $in_total (Limit = $in_warn)";
		} else {
		        $answer = "Sockets OK - Current Sockets: $in_total";
		        if (defined $in_high && $in_high ne "") {
			        $answer .= " : $in_high";
			}
			$state = "OK";
		}
	} else {
		$state = "UNKNOWN";
		$answer = "Something is Really WRONG! Sockets Is A Negative Figure!";
	}
	
	print "$PROGNAME $state: $answer\n";
	exit $ERRORS{$state};
}

# ====================================================================[ MAIN ]==
MAIN:
{
	my $data;	
	my @data;
	my $line;
	my $data1;
	my $data2;
	my $data3;
	my $junk;
	my $total1;
	my $total2;

	$plugin->init();

	$type = uc $type;
	if ($type eq "TOTAL") {
	        $type = "sockets";
	}

	$plugin->start_timeout($opt_t, "Somthing is Taking a Long Time, Increase Your TIMEOUT (Currently Set At $opt_t Seconds)");

	$data = `/bin/cat /proc/net/sockstat`;
	@data = split("\n",$data);

	my $output = "";
	my $high;

	foreach $line (@data) {
		if ($line =~ m/^($type):\s+(\w+)\s+(\d+)/i) {
		        ($data1,$data2,$data3) = ($1,$2,$3);
			if ($data3 =~ /highest/) { # Not on our linux!!
			        ($total1,$junk,$total2) = split(" ",$data3,3);	
				$output = $total1;
				$high = $total2;
			} else {
			        $output = $data3;
			}
			connection($output,$warn,$crit,$high);
			# NOT REACHED
		}
	}
# NOT REACHED except in error
	exit $ERRORS{'UNKNOWN'};
}
