#!/bin/sh
# $Id$
# check_net - nagios plugin to monitor network
#   by Matthew Wall
#
# Copyright (c) 2009 Matthew Wall, all rights reserved
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
#
# Revision History
#   0.2 added support for openbsd (fallback to netstat)
#   0.1 initial release
#
#
# Prerequisites
#
# First try to use /proc, if that fails use netstat.
#
# TODO:
# - put the units into perfdata
# - put the warn/crit values into the perfdata
# - accept ranges for warn/crit

STATE_OK=0
STATE_WARNING=1
STATE_CRITICAL=2
STATE_UNKNOWN=3

B_PER_MB=$(( 1024 * 1024 ))
KB_PER_MB=1024

usage()
{
    echo "usage: check_net iface [-w value] [-c value]"
    echo
    exit $STATE_OK
}

while getopts c:h:p:w: OPTNAME; do
    case "$OPTNAME" in
    w)
        WARNVAL="$OPTARG"
        ;;
    c)
        CRITVAL="$OPTARG"
        ;;
    *)
        usage
        ;;
    esac
done

IFACE="$@"
while [ $OPTIND -gt 1 ]; do
    IFACE=`echo "$IFACE" | sed 's/^[^ ][^ ]* *//'`
    OPTIND=$(($OPTIND-1))
done

# default to loopback/localhost
if [ "$IFACE" = "" ]; then
    IFACE=lo
fi

if [ "$WARNVAL" != "" -a "`echo $WARNVAL | grep '^[0-9][0-9]*$'`" = "" ]; then
    echo "Error: warning_value must be a positive integer!"
    exit $STATE_UNKNOWN
fi

if [ "$CRITVAL" != "" -a "`echo $CRITVAL | grep '^[0-9][0-9]*$'`" = "" ]; then
    echo "Error: critical_value must be a positive integer!"
    exit $STATE_UNKNOWN
fi

if [ "$WARNVAL" != "" -a "$CRITVAL" != "" ]; then
    if [ $WARNVAL -ge $CRITVAL ]; then
        echo "Error: warning_value must be less than critical_value!"
        exit $STATE_UNKNOWN
    fi
fi

if [ -f /proc/net/dev ]; then
  STATS=`grep $IFACE /proc/net/dev | sed 's/^.*://'`

  BR=`echo $STATS | awk '{print $1}'`
  PR=`echo $STATS | awk '{print $2}'`
  ER=`echo $STATS | awk '{print $3}'`
  DR=`echo $STATS | awk '{print $4}'`
  CR=`echo $STATS | awk '{print $6}'`
  MR=`echo $STATS | awk '{print $8}'`

  BT=`echo $STATS | awk '{print $9}'`
  PT=`echo $STATS | awk '{print $10}'`
  ET=`echo $STATS | awk '{print $11}'`
  DT=`echo $STATS | awk '{print $12}'`
  CT=`echo $STATS | awk '{print $14}'`
  MT=`echo $STATS | awk '{print $16}'`
else
  STATS=`netstat -d -b -f inet -I $IFACE | tail -1`

  BR=`echo $STATS | awk '{print $5}'`
  BT=`echo $STATS | awk '{print $6}'`
  DR=`echo $STATS | awk '{print $7}'`

  STATS=`netstat -d -f inet -I $IFACE | tail -1`
  PR=`echo $STATS | awk '{print $5}'`
  ER=`echo $STATS | awk '{print $6}'`
  PT=`echo $STATS | awk '{print $7}'`
  ET=`echo $STATS | awk '{print $8}'`
  CR=`echo $STATS | awk '{print $9}'`
  DT=0
  CT=0

  MR=0
  MT=0
fi

CODE=0

case $CODE in
0)
    STATUS=OK
    ;;
1)
    STATUS=WARNING
    ;;
2)
    STATUS=CRITICAL
    ;;
esac

MBR=$(( $BR / $B_PER_MB ))
MBT=$(( $BT / $B_PER_MB ))
ETOT=$(( $ER + $ET ))
CTOT=$(( $CR + $CT ))

echo "$STATUS - Received: ${MBR}MB; Transmitted: ${MBT}MB; Errors: ${ETOT}; Collisons: ${CTOT} | rbyte=$BR rpacket=$PR rerr=$ER rdrop=$DR rmult=$MR tbyte=$BT tpacket=$PT terr=$ET tdrop=$DT tmult=$MT"

exit $CODE
