#!/usr/bin/bash
#
# Nagios NSTAT Plugin
#
# Description: Check the TCP states and count them.
#              The plugin was written and testet on Solaris 8/10
#              and RedHat Enterprise Linux 3/4/5/6
#
# Author     : Peter Tuschy
# Version    : 1.4
# Date       : 2012-08-14
# 
#
	      
LANG=C
export LANG

# where we are started
WHERE=`dirname $0`

# setting default exit values
STATE_OK=0
STATE_WARNING=1
STATE_CRITICAL=2
STATE_UNKNOWN=3
STATE_DEPENDENT=4

# import exit values from utils.sh if we found one
if   [ -f ${WHERE}/utils.sh ] ; then
    . ${WHERE}/utils.sh
elif [ -f ${WHERE}/../utils.sh ] ; then
    . ${WHERE}/../utils.sh
fi

usage() {
    echo "Usage: $0 [-w <warning established>] [-c <critical established>]"
    exit $STATE_UNKNOWN
}

# make no warning or critical default
warning=
critical=

# command line parsing
while [ "$1" != "" ];
do
        case $1 in
        -w)
	    shift
	    warning=`echo $1 | tr -d '%' 2>/dev/null`
	    ;;
        -c)
	    shift
	    critical=`echo $1 | tr -d '%' 2>/dev/null`
	    ;;
	--help|-h)
	    usage
	    ;;
        -*)
	    usage
	    ;;
        *)
	    usage
	    
        esac
        shift
done

# threshold values
if [ ! -z "${critical}" ] ; then
    if [ ${critical} -le 0 ] ; then
        echo "Critical must be a positive integer."
        exit $STATE_UNKNOWN
    fi
fi

if [ ! -z "${warning}" ] ; then
    if [ ${warning} -le 0 ] ; then
        echo "Critical must be a positive integer."
        exit $STATE_UNKNOWN
    fi
fi

if [ ! -z "${critical}" -a ! -z "${warning}" ] ; then
    if [ ${critical} -lt ${warning} ] ; then
        echo "warning must be less than critical value."
        exit $STATE_UNKNOWN
    fi
fi

# 
# 

# setting all to 0
CLOSE_WAIT=0
CLOSING=0
ESTABLISHED=0
FIN_WAIT1=0
FIN_WAIT2=0
LAST_ACK=0
SYN_RCVD=0
SYN_SENT=0
TIME_WAIT=0

PROG_USED=netstat

OS=`uname`
case "${OS}" in
    SunOS)
	FIN_WAIT_1=0
	FIN_WAIT_2=0
	eval $(netstat -an -P tcp -f inet | awk '{ print $NF }' | tail +5 | sort | uniq -c | sed -e "s|FIN_WAIT_|FIN_WAIT|g" | awk '{ print $2 "=" $1 }')
	;;
    Linux)
	SS=`which ss 2>/dev/null`
	if [ -x "${SS}" ] ; then
	    eval $(ss -ant  | awk '{ print $1 }' | sort | uniq -c | sed -e '/State.*/d' -e 's/ESTAB/ESTABLISHED/' -e 's/-/_/g' -e 's/WAIT_/WAIT/' -e 's/RECV/RCVD/'| awk '{ print $2 "=" $1 }')
	    PROG_USED=ss
	else
	    eval $(netstat -an | grep ^tcp | awk '{ print $NF }' | sort | uniq -c | awk '{ print $2 "=" $1 }')
	fi
	;;
    *)
	echo "OS ${OS} not supportet by this check"
	exit $STATE_UNKNOWN
esac

# this version is to long there is a limit in nagios, ineed to make that shorter
PERFDATA="CW=${CLOSE_WAIT} CLO=${CLOSING} EST=${ESTABLISHED} FW1=${FIN_WAIT1} FW2=${FIN_WAIT2} LA=${LAST_ACK} SR=${SYN_RCVD} SS=${SYN_SENT} TW=${TIME_WAIT};"

PLUGSTRING="all states are 0"
[ "${ESTABLISHED}" = "0" ] || PLUGSTRING="ESTABLISHED ${ESTABLISHED}"
[ "${TIME_WAIT}" = "0" ]   || PLUGSTRING="${PLUGSTRING} / TIME_WAIT ${TIME_WAIT}"
[ "${CLOSE_WAIT}" = "0" ]  || PLUGSTRING="${PLUGSTRING} / CLOSE_WAIT ${CLOSE_WAIT}"
[ "${CLOSING}" = "0" ]     || PLUGSTRING="${PLUGSTRING} / CLOSING ${CLOSING}"
[ "${FIN_WAIT1}" = "0" ]   || PLUGSTRING="${PLUGSTRING} / FIN_WAIT1 ${FIN_WAIT1}"
[ "${FIN_WAIT2}" = "0" ]   || PLUGSTRING="${PLUGSTRING} / FIN_WAIT2 ${FIN_WAIT2}"
[ "${LAST_ACK}" = "0" ]    || PLUGSTRING="${PLUGSTRING} / LAST_ACK ${LAST_ACK}"
[ "${SYN_RCVD}" = "0" ]    || PLUGSTRING="${PLUGSTRING} / SYN_RCVD ${SYN_RCVD}"
[ "${SYN_SENT}" = "0" ]    || PLUGSTRING="${PLUGSTRING} / SYN_SENT ${SYN_SENT}"


PLUGDATA="TCP ${PROG_USED} (${PLUGSTRING})"
alerting=${ESTABLISHED}
alertlabel=ESTABLISHED


if [ ! -z "${alerting}" ] ; then
    if [ ! -z "${critical}" ] ; then
        if [ ${alerting} -ge ${critical} ]; then
            echo "CRITICAL - ${alertlabel} exceeds ${critical} / ${PLUGDATA} | ${PERFDATA}"
            exit $STATE_CRITICAL
        fi
    fi
    if [ ! -z "${warning}" ] ; then
        if [ ${alerting} -ge ${warning} ]; then
            echo "WARNING - ${alertlabel} exceeds ${warning} / ${PLUGDATA} | ${PERFDATA}"
            exit $STATE_WARNING
        fi
    fi
fi

echo "OK - ${PLUGDATA} | ${PERFDATA}"
exit $STATE_OK

