Files
2026-09-06 12:08:05 -04:00

153 lines
4.8 KiB
Bash
Executable File

#!/bin/bash
hostname=""
community=""
counter=""
perfName=""
iname=""
inum=""
debug=""
min=""
max=""
warn=""
crit=""
exitCode="0"
statusText="OK"
# snmpwalk -v 2c -c public 192.168.0.1 1.3.6.1.2.1.2.2.1.2 | sed -e "s/^IF-MIB::ifDescr.//" | awk '{print $NF, $1}' | while read iname inum; do echo "$iname"; for oid in 1.3.6.1.2.1.2.2.1.5 1.3.6.1.2.1.2.2.1.10 1.3.6.1.2.1.2.2.1.16 1.3.6.1.2.1.2.2.1.20; do snmpget -v 2c -c public 192.168.0.1 ${oid}.${inum}; done; done
# current bandwidth snmpwalk -v 2c -c public 192.168.1.1 1.3.6.1.2.1.2.2.1.5
# octets received snmpwalk -v 2c -c public 192.168.1.1 1.3.6.1.2.1.2.2.1.10
# octets sent snmpwalk -v 2c -c public 192.168.1.1 1.3.6.1.2.1.2.2.1.16
# error octets 1.3.6.1.2.1.2.2.1.20
do_debug() {
[ -z "$debug" ] && return
echo "DEBUG: $*" >&2
}
do_help() {
echo "Usage: $0 -H <hostname> -C <community> [-I <interface name> | -i <inum>) -t (b|r|s|e) [-w <warn>] [-c <crit>]"
# -w <warn> -c <crit> -m <min> -M <max> [-d] (kp | flux)"
exit
}
while getopts "dhC:H:I:i:t:w:c:" opt; do
case "$opt" in
H) hostname="$OPTARG";;
I) iname="$OPTARG";;
i) inum="$OPTARG";;
t) counter="$OPTARG";;
C) community="$OPTARG";;
w) warn="$OPTARG";;
c) crit="$OPTARG";;
h) do_help;;
d) debug="true";;
esac
done
shift $((OPTIND - 1))
command="$@"
do_debug "host=$hostname iname=$iname inum=$inum counter=$counter warn=$warn crit=$crit"
[ -z "$hostname" ] && echo "No hostname specified." && exit 0
[ -z "$community" ] && echo "No community specified." && exit 0
check_threshold() {
local val=$1
local range=$2
local alert_inside=0
local start=0
local end="inf"
# Handle empty thresholds safely
if [[ -z "$range" ]]; then return 0; fi
# Check for the inside-range prefix '@'
if [[ "$range" == @* ]]; then
alert_inside=1
range="${range#@}" # Strip the '@'
fi
# Parse start and end values out of the range colon (:) syntax
if [[ "$range" == *:* ]]; then
start="${range%%:*}"
end="${range#*:}"
# Handle implicit defaults
[[ -z "$start" ]] && start=0
[[ "$start" == "~" ]] && start="-inf"
[[ -z "$end" ]] && end="inf"
else
# No colon: Shorthand for 0:X
start=0
end="$range"
fi
# Evaluate logic using bc (handles floats and floating point math)
local outside=0
# Check lower boundary; inclusive of endpoints
if [[ "$start" != "-inf" ]]; then
if (( $(echo "$val < $start" | bc -l) )); then outside=1; fi
fi
# Check upper boundary; inclusive of endpoints
if [[ "$end" != "inf" ]]; then
if (( $(echo "$val > $end" | bc -l) )); then outside=1; fi
fi
# Return true/false based on whether the @ symbol inverted the logic
if [[ $alert_inside -eq 1 ]]; then
# Alert if INSIDE the range
if [[ $outside -eq 0 ]]; then return 1; else return 0; fi
else
# Alert if OUTSIDE the range (Standard Nagios Behavior)
if [[ $outside -eq 1 ]]; then return 1; else return 0; fi
fi
}
do_snmp() {
myNum="$1"
myOid="$2"
myName="$3"
do_debug "checking $hostname for $myName (inum: $myNum) on $myOid:"
output=$(snmpget -v 2c -c $community $hostname ${myOid}.${myNum} | awk '{print $NF}')
if [ -z "$output" ]; then
echo "UNKNOWN: snmpget error"
exit 3
else
echo "$output"
fi
}
do_stats() {
myNum="$1"
myName="$2"
myOid=""
do_debug "do_stats: myNum=$myNum myName=$myName myOid=$myOid"
case "$counter" in
b) counter="Bandwidth"; perfName="'bw_bytes'"; myOid="1.3.6.1.2.1.2.2.1.5";;
r) counter="Received"; perfName="'bytes_recv'"; myOid="1.3.6.1.2.1.2.2.1.10";;
s) counter="Sent"; perfName="'bytes_sent'"; myOid="1.3.6.1.2.1.2.2.1.16";;
e) counter="Errors"; perfName="'bytes_errors'"; myOid="1.3.6.1.2.1.2.2.1.20";;
*) echo "Invalid counter type specified."; exit 0;;
esac
do_debug "do_stats: do_snmp $myNum $myOid $myName"
value=$(do_snmp $myNum $myOid $myName)
# CRITICAL check must always run first to ensure it takes precedence
if ! check_threshold "$value" "$crit"; then
exitCode=2
statusText="CRITICAL"
elif ! check_threshold "$value" "$warn"; then
exitCode=1
statusText="WARNING"
fi
# [ "$value" != "?" ] && value=$(printf "%.4f" "$value")
echo "$myName $counter $statusText: $value|$perfName=${value}B;$warn;$crit;$min;$max"
exit $exitCode
}
if [ -n "$inum" ]; then
do_debug "Specified inum=$inum"
do_stats $inum
else
do_debug "Did not specify an inum"
do_debug "snmpwalk -v 2c -c $community $hostname 1.3.6.1.2.1.2.2.1.2"
snmpwalk -v 2c -c $community $hostname 1.3.6.1.2.1.2.2.1.2 | sed -e "s/^IF-MIB::ifDescr.//" | awk '{print $1, $NF}' | while read myNum myName; do
[ -z "$iname" -a -z "$inum" ] && echo "iname: $myName (inum: $myNum)" && continue # Show interfaces if we didn't specify one
[ "$iname" != "$myName" ] && continue
do_debug "Found $iname (ifnum: $myNum)"
do_stats $myNum
done
fi