#!/bin/bash
#
# Uses check_tcp to check multiple tcp ports at once
#
# By Igor Gubenko (igubenko at princeton dot edu)
#

#Usage:check_tcp -H host -p port [-w <warning time>] [-c <critical time>] [-s <send string>]
#[-e <expect string>] [-q <quit string>][-m <maximum bytes>] [-d <delay>]
#[-t <timeout seconds>] [-r <refuse state>] [-M <mismatch state>] [-v] [-4|-6] [-j]
#[-D <days to cert expiry>] [-S <use SSL>] [-E]
#
#Options:
# -h, --help
#    Print detailed help screen
# -V, --version
#    Print version information
# -H, --hostname=ADDRESS
#    Host name, IP Address, or unix socket (must be an absolute path)
# -p, --port=INTEGER
#    Port number (default: none)
# -4, --use-ipv4
#    Use IPv4 connection
# -6, --use-ipv6
#    Use IPv6 connection
# -E, --escape
#    Can use \n, \r, \t or \ in send or quit string. Must come before send or quit option
#    Default: nothing added to send, \r\n added to end of quit
# -s, --send=STRING
#    String to send to the server
# -e, --expect=STRING
#    String to expect in server response (may be repeated)
# -A, --all
#    All expect strings need to occur in server response. Default is any
# -q, --quit=STRING
#    String to send server to initiate a clean close of the connection
# -r, --refuse=ok|warn|crit
#    Accept tcp refusals with states ok, warn, crit (default: crit)
# -M, --mismatch=ok|warn|crit
#    Accept expected string mismatches with states ok, warn, crit (default: warn)
# -j, --jail
#    Hide output from TCP socket
# -m, --maxbytes=INTEGER
#    Close connection once more than this number of bytes are received
# -d, --delay=INTEGER
#    Seconds to wait between sending string and polling for response
# -D, --certificate=INTEGER
#    Minimum number of days a certificate has to be valid.
# -S, --ssl
#    Use SSL for the connection.
# -w, --warning=DOUBLE
#    Response time to result in warning status (seconds)
# -c, --critical=DOUBLE
#    Response time to result in critical status (seconds)
# -t, --timeout=INTEGER
#    Seconds before connection times out (default: 10)
# -v, --verbose
#    Show details for command-line debugging (Nagios may truncate output)
#

myname=`basename $0`
nagios_plugins='/usr/local/monitoring/nagios/libexec'
check_tcp="${nagios_plugins}/check_tcp"

usage () {
	echo "UNKNOWN: Usage: $myname <-H host_or_IP> <-p port1[,port2[...[,portN]]]> <all_other_valid_check_tcp_options>"
	exit 3
}

#Usage:check_tcp -H host -p port [-w <warning time>] [-c <critical time>] [-s <send string>]
#[-e <expect string>] [-q <quit string>][-m <maximum bytes>] [-d <delay>]
#[-t <timeout seconds>] [-r <refuse state>] [-M <mismatch state>] [-v] [-4|-6] [-j]
#[-D <days to cert expiry>] [-S <use SSL>] [-E]

warn=""
crit=""
perf="| "

while getopts ":p:H:w:c:s:e:q:m:d:t:r:M:D:46ESjvh" option
do
	case "$option" in
		H)	host="$OPTARG";;
		p)	ports="$OPTARG";;
		h)	usage;;
		w)	warn="$OPTARG"; save="$save -$option $OPTARG";;
		c)	crit="$OPTARG"; save="$save -$option $OPTARG";;
		[seqmdtrDM])	save="$save -$option $OPTARG";;
		[v46jSE])	save="$save -$option";;
		*)	usage;;
	esac
done
shift $(($OPTIND-1)); OPTIND=1

if [ "$ports" == "" -o "$host" == "" ]; then
	usage
fi

if [ ! -x $check_tcp ]; then
	echo "UNKNOWN: \"$check_tcp\" does not exist or is not executable"
	exit 3
fi

stat=0
declare -a arr_resp
arr_resp[0]="OK"
arr_resp[1]="WARNING"
arr_resp[2]="CRITICAL"
arr_resp[3]="UNKNOWN"
out=""

#echo "##$save"
OLD_IFS="$IFS"
IFS=","

for port in $ports
do
	out_tmp=`eval "$check_tcp -H $host -p $port $save"`
	stat_tmp=$?
	res_val=`echo $out_tmp | sed 's/.*- \([[:digit:]\.]\{1,\}\) .*/\1/'`
	out="$port - $res_val; $out"
	perf="${perf}'${port}'=${res_val}s;$warn;$crit;0;3600 "

	# Critical has priority to warning, warning has priority to unknown, unknown has priority to ok
	if [ "$stat" -eq "0" -a "$stat_tmp" -eq "3" ]; then
		stat="3"
	elif [ "$stat" -lt "$stat_tmp" ]; then
		stat="$stat_tmp"
	fi
done

IFS="$OLD_IFS"

echo "${arr_resp[$stat]}: Port - Response time => ${out}$perf"

exit $stat
