#!/usr/bin/ksh # # Basic UNIX networking check script. # Written by Thomas Sluyter (nagios@kilala.nl) # By request of KPN-IS, i-Provide SYS, the Netherlands # Last Modified: 22-06-2006 # # Usage: ./check_networking # # Description: # This plugin determines whether the local host's network interfaces # are all up and running like they should. It uses the following # questions to determine this. # * Does /sbin/mii-tool report any problems? (Linux only) # * Are the gateways for each subnet pingable? # # Limitations: # * I have no clue whether mii-tool is something specific to Redhat ES3, # or whether all Linii have it. # * Sudo access to mii-tool is required for the nagios account. # * Perl is required on Solaris, to do just tiny bit of math. # * KSH is required. # * The script assumes that the first available IP from a subnet is the # router. # # Output: # The script retunrs a CRIT when one of the criteria mentioned # above is not matched. # # Other notes: # I wish I'd learn Perl. I'm sure that doing all of this stuff in Perl # would have cut down on the size of this script tremendously. Ah well. # If you ever run into problems with the script, set the DEBUG variable # to 1. I'll need the output the script generates to do troubleshooting. # See below for details. # I realise that all the debugging commands strewn throughout the script # may make things a little harder to read. But in the end I'm sure it was # well worth adding them. It makes troubleshooting so much easier. :3 # # Enabling the following dumps information into DEBUGFILE at various # stages during the execution of this script. DEBUG="0" DEBUGFILE="/tmp/foobar" ### REQUISITE NAGIOS USER INTERFACE STUFF ### # You may have to change this, depending on where you installed your # Nagios plugins PATH="/usr/bin:/usr/sbin:/bin:/sbin" LIBEXEC="/usr/local/nagios/libexec" . $LIBEXEC/utils.sh [ $DEBUG -gt 0 ] && rm $DEBUGFILE print_usage() { echo "Usage: $PROGNAME" echo "Usage: $PROGNAME --help" } print_help() { echo "" print_usage echo "" echo "Basic UNIX networking check plugin for Nagios" echo "" echo "This plugin not developped by the Nagios Plugin group." echo "Please do not e-mail them for support on this plugin, since" echo "they won't know what you're talking about :P" echo "" echo "For contact info, read the plugin itself..." } while test -n "$1" do case "$1" in --help) print_help; exit $STATE_OK;; -h) print_help; exit $STATE_OK;; *) print_usage; exit $STATE_UNKNOWN;; esac done ### SETTING UP THE ENVIRONMENT ### # Host OS check and warning message MIITOOL="0" if [ -f /sbin/mii-tool ] then MIITOOL="1" sudo /sbin/mii-tool >/dev/null 2>&1 if [ $? -gt 0 ] then echo "ERROR: sudo permissions" echo "" echo "This script requires that the Nagios user account has" echo "sudo permissions for the mii-tool command. Currently it" echo "does not have these permissions. Please fix this." echo "" exit $STATE_UNKNOWN fi fi ### SUB-ROUTINE DEFINITIONS ### function convert_base { typeset -i${2:-16} x x=$1 echo $x } function subnet_router { [ $DEBUG -gt 0 ] && echo "- Starting subnet_router -" >> $DEBUGFILE first="0"; second="0"; third="0"; fourth="0" first=`echo $1 | cut -c 1-8`; FIRST=`convert_base 2#$first 10` [ $DEBUG -gt 0 ] && echo "First: $first $FIRST" >> $DEBUGFILE second=`echo $1 | cut -c 9-16`; SECOND=`convert_base 2#$second 10` [ $DEBUG -gt 0 ] && echo "Second: $second $SECOND" >> $DEBUGFILE third=`echo $1 | cut -c 17-24`; THIRD=`convert_base 2#$third 10` [ $DEBUG -gt 0 ] && echo "Third: $third $THIRD" >> $DEBUGFILE fourth=`echo $1 | cut -c 25-32` [ `echo $fourth|wc -c` -gt 1 ] || fourth="0" TEMPCOUNT=`echo $fourth | wc -c | awk '{print $1}'` let PADDING=9-$TEMPCOUNT [ $DEBUG -gt 0 ] && echo "Fourth: padding fourth with $PADDING zeroes" >> $DEBUGFILE i=1 while ((i <= $PADDING)); do fourth=$fourth"0" let i=$i+1 done FOURTH=`convert_base 2#$fourth 10`; let FOURTH=$FOURTH+1 [ $DEBUG -gt 0 ] && echo "Fourth: $fourth $FOURTH" >> $DEBUGFILE echo "$FIRST.$SECOND.$THIRD.$FOURTH" } gather_interfaces_linux() { [ $DEBUG -gt 0 ] && echo "- Starting gather_interfaces_linux -" >> $DEBUGFILE for INTF in `ifconfig -a | grep ^[a-z] | grep -v ^lo | awk '{print $1}'` do if [ `echo $INTF | grep : | wc -l` -gt 0 ] then export INTERFACES="`echo $INTF|awk -F: '{print $1}'` $INTERFACES" else export INTERFACES="$INTF $INTERFACES" fi done INTFCOUNT=`echo $INTERFACES | wc -w` [ $DEBUG -gt 0 ] && echo "Interfaces: There are $INTFCOUNT interfaces: $INTERFACES." >> $DEBUGFILE if [ $INTFCOUNT -lt 1 ] then echo "NOK - No active network interfaces." exit $STATE_CRITICAL fi } gather_interfaces_darwin() { [ $DEBUG -gt 0 ] && echo "- Starting gather_interfaces_darwin -" >> $DEBUGFILE for INTF in `ifconfig -a | grep ^[a-z] | grep -v ^gif | grep -v ^stf | grep -v ^lo | awk '{print $1}'` do [ `echo $INTF | grep : | wc -l` -gt 0 ] && INTF=`echo $INTF|awk -F: '{print $1}'` [ `ifconfig $INTF | grep "status: inactive" | wc -l` -gt 0 ] && break INTERFACES="$INTF $INTERFACES" done INTFCOUNT=`echo $INTERFACES | wc -w` [ $DEBUG -gt 0 ] && echo "Interfaces: There are $INTFCOUNT interfaces: $INTERFACES." >> $DEBUGFILE if [ $INTFCOUNT -lt 1 ] then echo "NOK - No active network interfaces." exit $STATE_CRITICAL fi } gather_gateway_linux() { [ $DEBUG -gt 0 ] && echo "- Starting gather_gateway_linux for interface $1 -" >> $DEBUGFILE MASKBIN="" MASK=`ifconfig $1 | grep Mask | awk '{print $4}' | awk -F: '{print $2}'` for PART in `echo $MASK | awk -F. '{print $1" "$2" "$3" "$4}'` do MASKBIN="$MASKBIN`convert_base $PART 2 | awk -F# '{print $2}'`" done [ $DEBUG -gt 0 ] && echo "Mask: $MASK $MASKBIN" >> $DEBUGFILE BITCOUNT=`echo $MASKBIN | grep -o 1 | wc -l | awk '{print $1}'` [ $DEBUG -gt 0 ] && echo "Bitcount: $BITCOUNT" >> $DEBUGFILE IPBIN="" IP=`ifconfig $1 | grep "inet addr" | awk '{print $2}' | awk -F: '{print $2}'` for PART in `echo $IP | awk -F. '{print $1" "$2" "$3" "$4}'` do TEMPBIN=`convert_base $PART 2 | awk -F# '{print $2}'` TEMPCOUNT=`echo $TEMPBIN | wc -c | awk '{print $1}'` let PADDING=9-$TEMPCOUNT i=1 while ((i <= $PADDING)); do IPBIN=$IPBIN"0" let i=$i+1 done IPBIN=$IPBIN$TEMPBIN done [ $DEBUG -gt 0 ] && echo "IP address: $IP $IPBIN" >> $DEBUGFILE CUT="1-$BITCOUNT" [ $DEBUG -gt 0 ] && echo "Cutting: Cutting chars $CUT" >> $DEBUGFILE NETBIN=`echo $IPBIN | cut -c $CUT` [ $DEBUG -gt 0 ] && echo "Netbin: $NETBIN" >> $DEBUGFILE ROUTER=`subnet_router $NETBIN` [ $DEBUG -gt 0 ] && echo "Router: $ROUTER" >> $DEBUGFILE echo $ROUTER } gather_gateway_darwin() { [ $DEBUG -gt 0 ] && echo "- Starting gath_gateway_darwin for interface $1 -" >> $DEBUGFILE MASKBIN="" [ `uname` == "Darwin" ] && MASK=`ifconfig $1 | grep netmask | awk '{print $4}' | awk -Fx '{print $2}'` [ `uname` == "SunOS" ] && MASK=`ifconfig $1 | grep netmask | awk '{print $4}'` for PART in `echo 1 3 5 7` do let PLUSPART=$PART+1 MASKPART=`echo $MASK | cut -c $PART-$PLUSPART` MASKBIN="$MASKBIN`convert_base 16#$MASKPART 2 | awk -F# '{print $2}'`" done [ $DEBUG -gt 0 ] && echo "Mask: $MASK $MASKBIN" >> $DEBUGFILE BITCOUNT=`echo $MASKBIN | grep -o 1 | wc -l | awk '{print $1}'` [ $DEBUG -gt 0 ] && echo "Bitcount: $BITCOUNT" >> $DEBUGFILE IPBIN="" IP=`ifconfig $1 | grep "inet " | awk '{print $2}'` for PART in `echo $IP | awk -F. '{print $1" "$2" "$3" "$4}'` do TEMPBIN=`convert_base $PART 2 | awk -F# '{print $2}'` TEMPCOUNT=`echo $TEMPBIN | wc -c | awk '{print $1}'` let PADDING=9-$TEMPCOUNT i=1 while ((i <= $PADDING)); do TEMPBIN="0"$TEMPBIN let i=$i+1 done IPBIN=$IPBIN$TEMPBIN done [ $DEBUG -gt 0 ] && echo "IP address: $IP $IPBIN" >> $DEBUGFILE CUT="1-$BITCOUNT" [ $DEBUG -gt 0 ] && echo "Cutting: cutting chars $CUT" >> $DEBUGFILE NETBIN=`echo $IPBIN | cut -c $CUT` [ $DEBUG -gt 0 ] && echo "Netbin: $NETBIN" >> $DEBUGFILE ROUTER=`subnet_router $NETBIN` [ $DEBUG -gt 0 ] && echo "Router: $ROUTER" >> $DEBUGFILE echo $ROUTER } gather_gateway_sunos() { [ $DEBUG -gt 0 ] && echo "- Starting gath_gateway_solaris for interface $1 -" >> $DEBUGFILE MASKBIN="" [ `uname` == "Darwin" ] && MASK=`ifconfig $1 | grep netmask | awk '{print $4}' | awk -Fx '{print $2}'` [ `uname` == "SunOS" ] && MASK=`ifconfig $1 | grep netmask | awk '{print $4}'` for PART in `echo 1 3 5 7` do let PLUSPART=$PART+1 MASKPART=`echo $MASK | cut -c $PART-$PLUSPART` MASKBIN="$MASKBIN`convert_base 16#$MASKPART 2 | awk -F# '{print $2}'`" done [ $DEBUG -gt 0 ] && echo "Mask: $MASK $MASKBIN" >> $DEBUGFILE # This piece of kludge also requires that all tabs are removed from the beginning of each line. # Additional character needed to trick the counter below # Shitty thing is that it doesn't work. Stupid "let" aryth engine... #MASKBIN="$MASKBIN-" #[ $DEBUG -gt 0 ] && echo "Bitcount: kludged binmask is $MASKBIN" >> $DEBUGFILE # #IFS="1" #read TEMP << EOT #echo $MASKBIN #EOT #let "BITCOUNT=(${#TEMP[@]} - 1)" #IFS=" " # The kludge above was replaced by this one line of Perl. BITCOUNT=`echo $MASKBIN | perl -ne 'while(/1/g){++$count}; print "$count"'` [ $DEBUG -gt 0 ] && echo "Bitcount: $BITCOUNT" >> $DEBUGFILE IPBIN="" IP=`ifconfig $1 | grep "inet " | awk '{print $2}'` for PART in `echo $IP | awk -F. '{print $1" "$2" "$3" "$4}'` do [ $DEBUG -gt 0 ] && echo "IP part: converting part $PART" >> $DEBUGFILE TEMPBIN=`convert_base $PART 2 | awk -F# '{print $2}'` [ $DEBUG -gt 0 ] && echo "IP part: converted part is $TEMPBIN" >> $DEBUGFILE TEMPCOUNT=`echo $TEMPBIN | wc -c | awk '{print $1}'` [ $DEBUG -gt 0 ] && echo "IP part: this part is $TEMPCOUNT chars long." >> $DEBUGFILE let PADDING=9-$TEMPCOUNT [ $DEBUG -gt 0 ] && echo "IP part: will be padded with $PADDING zeroes" >> $DEBUGFILE i=1 while ((i <= $PADDING)); do TEMPBIN="0"$TEMPBIN let i=$i+1 done IPBIN=$IPBIN$TEMPBIN done [ $DEBUG -gt 0 ] && echo "IP address: $IP $IPBIN" >> $DEBUGFILE CUT="1-$BITCOUNT" [ $DEBUG -gt 0 ] && echo "Cutting: cutting chars $CUT" >> $DEBUGFILE NETBIN=`echo $IPBIN | cut -c $CUT` [ $DEBUG -gt 0 ] && echo "Netbin: $NETBIN" >> $DEBUGFILE ROUTER=`subnet_router $NETBIN` [ $DEBUG -gt 0 ] && echo "Router: $ROUTER" >> $DEBUGFILE echo $ROUTER } check_miitool() { [ $DEBUG -gt 0 ] && echo "- Starting check_miitool -" >> $DEBUGFILE COUNT="0" for INTF in `echo $INTERFACES` do [ `sudo /sbin/mii-tool $INTF | head -1 | grep -c ok` -gt 0 ] || let COUNT=$COUNT+1 [ `sudo /sbin/mii-tool $INTF | head -1 | grep -c 100baseTx-FD` -gt 0 ] || let COUNT=$COUNT+1 [ `sudo /sbin/mii-tool $INTF | head -1 | grep -c 1000baseTx-FD` -gt 0 ] || let COUNT=$COUNT+1 done [ $COUNT -gt $INTFCOUNT ] && (echo "NOK - Problem with one of the interfaces"; exit $STATE_CRITICAL) } check_ping() { [ $DEBUG -gt 0 ] && echo "- Starting check_ping -" >> $DEBUGFILE INTF="" for INTF in `echo $INTERFACES` do case `uname` in Linux) GATEWAY=`gather_gateway_linux $INTF`;; Darwin) GATEWAY=`gather_gateway_darwin $INTF`;; SunOS) GATEWAY=`gather_gateway_sunos $INTF`;; *) echo "OS not supported by this check."; exit 1;; esac [ $DEBUG -gt 0 ] && echo "Gateway: $GATEWAY" >> $DEBUGFILE ping -c 3 $GATEWAY >/dev/null 2>&1 if [ $? -gt 0 ] then echo "NOK - Problem pinging gateway $GATEWAY"; exit $STATE_CRITICAL fi done } ### THE MAIN ROUTINE FINALLY STARTS ### case `uname` in Linux) gather_interfaces_linux;; Darwin) gather_interfaces_darwin;; #SunOS) gather_interfaces_sunos;; SunOS) gather_interfaces_linux;; *) echo "OS not supported by this check."; exit 1;; esac [ $MIITOOL -eq 1 ] && check_miitool check_ping # None of the other subroutines forced us to exit 1 before here, so let's quit with a 0. echo "OK - Everything running like it should" exit $STATE_OK