#!/bin/bash

# Plugin to monitor traffic rate to specific host.
#
# Requirements:
#	- tcpdump
#	- should be run as root or any other user for tcpdump
#
# Parameters supported:
#	config
#	autoconf
#
# Configurable variables
#
#	type       - monitor type. Available values: packets, bytes. Defaults to packets because it's faster
#	hostname   - mandatory. Hostname (ip) to monitor connections to. Actually just a part of tcpdump expr.
#                    Thus a hack: '1.2.3.4 and port 80' will monitor port 80 only. Bingo!
#	interface  - self-explanatory
#
# IMPORTANT! This plugin spawns 'tcpdump' process along with bash shell piping tcpdump output there
# PLEASE DO NOT FORGET TO KILL when removing plugin/stopping/etc. You can kill any of three, the others should die
#
# Revision 0.1  2011/08/06 Artem Sheremet
# Revision 0.2  2011/10/23 -

INTERVAL=300

if [ -z "$type" ]; then
        type=packets
fi

if [ -z "$hostname" ]; then
        echo "Configuration problem" >&2
        exit 1
fi

if [ "$interface" ]; then
	interface="-i $interface"
fi

TCPDUMP="tcpdump $interface -nqt host $hostname"

if [ "$1" = "config" ]; then
        echo "graph_title Number of $type for host $hostname"
        if [ "$type" == "bytes" ]; then
                echo "graph_args --base 1024"
        fi
        echo "graph_category network"
        echo "graph_vlabel $type per second"
        echo "graph_info This plugin shows number of $type within host $hostname through the tcp protocol using tcpdump"
        echo "rate.label $type within $hostname"
        exit 0
fi

TMP_DIR="/tmp/host_traffic_${hostname}_${type}"

if [ ! -d "$TMP_DIR" ]; then
	mkdir -p "$TMP_DIR"
fi

if [ -f "$TMP_DIR/pid" ]; then
	PID=`cat "$TMP_DIR/pid"`

	if [ -z "$PID" -o ! -d /proc/$PID ]; then
		unset PID
	fi
fi

if [ "$PID" ]; then
	rm -f "$TMP_DIR/value"
	# IPC: call data print & reset
	kill -USR1 $PID
	# wait 10 sec for data to arrive
	for i in {1..10}; do
		if [ -r "$TMP_DIR/value" ]; then
			VALUE=`cat "$TMP_DIR/value"`
			echo $VALUE $INTERVAL | awk '{ printf("rate.value %.3f\n", $1/$2) }'
			exit 0
		fi
		sleep 1
	done
	echo "rate.value U"
else
	$TCPDUMP 2>/dev/null | (
		COUNTER=0
		# IPC: install SIGUSR1 handler
		trap 'echo $COUNTER > "$TMP_DIR/value"; COUNTER=0' SIGUSR1
		echo $BASHPID >"$TMP_DIR/pid"
		while read line; do
			if [[ "$type" == "bytes" ]]; then
				# get the last field separated by space
				COUNTER=$(($COUNTER+${line/* /})) 2>/dev/null
			else
				COUNTER=$(($COUNTER+1))
			fi
		done
	) 2>/dev/null &
fi
