diff --git a/check_iftraffic64/Makefile b/check_iftraffic64/Makefile new file mode 100644 index 0000000..cf9673d --- /dev/null +++ b/check_iftraffic64/Makefile @@ -0,0 +1,3 @@ +#/usr/bin/make -f + +include ../common.mk diff --git a/check_iftraffic64/check_iftraffic64 b/check_iftraffic64/check_iftraffic64 new file mode 100755 index 0000000..ebd446a --- /dev/null +++ b/check_iftraffic64/check_iftraffic64 @@ -0,0 +1,1113 @@ +#!/usr/bin/perl -w +# +# check_iftraffic.pl - Nagios(r) network traffic monitor plugin +# Copyright (C) 2004 Gerd Mueller / Netways GmbH +# $Id: check_iftraffic.pl 1119 2006-02-09 10:30:09Z gmueller $ +# Version: .77 +# +# mw = Markus Werner mw+nagios@wobcom.de +# Remarks (mw): +# +# I adopted as much as possible the programming style of the origin code. +# +# There should be a function to exit this program, +# instead of calling print and exit statements all over the place. +# +# minor changes by mw +# The snmp if_counters on net devices can have overflows. +# I wrote this code to address this situation. +# It has no automatic detection and which point the overflow +# occurs but it will generate a warning state and you +# can set the max value by calling this script with an additional +# arg. +# +# minor cosmetic changes by mw +# Sorry but I couldn't sustain to clean up some things. +# +# gj = Greg Frater gregATfraterfactory.com +# Remarks (gj): +# minor (gj): +# +# * fixed the performance data, formating was not to spec +# * Added a check of the interfaces status (up/down). +# If interface is down the check returns a critical status. +# * Support both textual or the numeric index values. +# * If the interface speed is not specified on the command line +# it gets it automatically from IfHighSpeed (or ifSpeed if IfHighSpeed +# counter is not available) +# * Added option to specify a second Speed parameter to allow for +# asymetrcal links such as a DSL line or cable modem where the +# download and upload speeds are different +# * Added -B option to display results in bits/sec instead of Bytes/sec +# * Added the current usage in Bytes/s (or bit/s) to the perfdata output +# * Added ability for plugin to determine interface to query by matching IP +# address of host with entry in ipAdEntIfIndex (.1.3.6.1.2.1.4.20.1.2) +# * Added -L flag to list entries found in the ipAdEntIfIndex table +# Otherwise, it works as before. +# * resorted options in help +# * Added auto detection mode (now the default), tries 64 bit counters first then uses 32 +# bit if 64 bit values are not available +# * Added force flag to force 64 or 32 bit only mode (disables auto detection) +# * Reworked the status output, tried to make it a little more readable +# * Cleaned up logic of Units designator inside script +# * Added checks for bad interface speed values (zero, error, etc.) +# * 12_09_2014 Fixed unit label issue (thanks Gerhard Mourani for catching it) +# * 12_09_2014 Changed labels from index -> interface on output when interface is not up +# * 12_09_2014 Removed spurious '
' from output +# * 12_09_2014 Changed the $suffix from 'Bs' or 'bs' to 'B' or 'b' +# * 12_10_2014 Fixed issue when using string description for interface printing extra line with interface name and OID +# * 07_06_2015 Added SNMP v3 support, base code provided by Rogerio Tomassoni de Araujo Junio +# * 12_02_2015 Set the inbandwidth and outbandwidth of the perfdata to a fixed base unit (bits or Bytes depending on switches used). +# * Thanks to Philip Ho and Fai Wong for pointing this out. +# * 12_08_2015 Fixed 'Return code of 25 is out of bounds' errors with an internal timeout setting. Thanks to Philip Ho +# for directing me to the underlying problem +# based on check_traffic from Adrian Wieczorek, +# * 05_13_2016 Changed perf data for in_ave and out_ave to always be in Bytes (no Bits allowed) to align with perf data output rules +# Thanks to Mark Rittinghaus for pointing this out and recommending a fix. +# * 05_13_2016 Changed perf data for absolute Bytes ($in_bytes_abs/$out_bytes_abs) from Bytes units to 'c' for continuous +# Thanks to Mark Rittinghaus for suggesting this change. +# * 03_27_2018 No functional changes, just some code comment cleanup. +# +# Send us bug reports, questions and comments about this plugin. +# Latest version of this software: http://exchange.nagios.org +# +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 + + +# Set Perl environ +use strict; +use Data::Dumper; +use Net::SNMP; +use Getopt::Long; +&Getopt::Long::config('bundling'); + +# Set script parameters +my $error; +my $host_address; +my $host_ip; +my $iface_descr; +my $iface_number; +my $iface_speed; +my $iface_speedOut; +my $ifspeed64; +my $ifspeed32; +my $inbytes64; +my $inbytes32; +my $outbytes64; +my $outbytes32; +my $in_ave = 0; +my $pin_ave = 0; +my $in_tot = 0; +my $index_list; +my $max_value; #added 20050614 by mw +my $max_bytes; +my $opt_h; +my $out_ave = 0; +my $pout_ave = 0; +my $port = 161; +my $out_tot = 0; +my $response; +my $session; +my @snmpoids; +my $units; + +# SNMP OIDs for Traffic +my $snmpIfOperStatus = '1.3.6.1.2.1.2.2.1.8'; # Operational state of interface (i.e. 1-up, 2-down, etc.) +my $snmpIfInOctets32 = '1.3.6.1.2.1.2.2.1.10'; # Total Octets entering interface (in) - 32 bit counter +my $snmpIfOutOctets32 = '1.3.6.1.2.1.2.2.1.16'; # Total Octets leaving interface (out) - 32 bit counter +my $snmpIfInOctets = '1.3.6.1.2.1.31.1.1.1.6'; # Total Octets entering interface (in) - 64 bit counter +my $snmpIfOutOctets = '1.3.6.1.2.1.31.1.1.1.10'; # Total Octets leaving interface (out) - 64 bit counter +my $snmpIfDescr = '1.3.6.1.2.1.2.2.1.2'; # Textual string describing interface +my $snmpIfSpeed32 = '1.3.6.1.2.1.2.2.1.5'; # bits per second +my $snmpIfSpeed = '1.3.6.1.2.1.31.1.1.1.15'; # Mbits per second +my $snmpIPAdEntIfIndex = '1.3.6.1.2.1.4.20.1.2'; # Index of interface using hosts IP addr + + + +# Path to tmp files +my $TRAFFIC_FILE = "/usr/local/nagios/libexec/traffic/"; + +# Create tmp file location if it does not exist +if ( ! -d $TRAFFIC_FILE ) { + mkdir $TRAFFIC_FILE; +} + +# changes sos 20090717 UNKNOWN must be 3 +# Set status codes +my %STATUS_CODE = + ( 'UNKNOWN' => '3', 'OK' => '0', 'WARNING' => '1', 'CRITICAL' => '2' ); + +#default values; +my $bits = undef; +my $COMMUNITY = "public"; +my $crit_usage = 98; +my $debug = 0; +my $force = undef; +my $if_status = '4'; +my ( $in_bytes, $out_bytes, $in_bytes32, $out_bytes32 ) = 0; +my $label = ""; +my $output = ""; +my $snmp_version = 2; +my $state = "UNKNOWN"; +my $suffix = "B"; +my $thirtytwo = undef; +my $use_reg = undef; # Use Regexp for name +my $warn_usage = 85; +my $timeout = 10; +my $username; +my $authpasswd; +my $authproto = 'MD5'; +my $privpasswd; +my $privproto = 'DES'; + +#cosmetic changes 20050614 by mw, see old versions for detail +# Added options for bits and second max ifspeed 20100202 by gj +# Added options for specific IP addr to match 20100405 by gj +my $status = GetOptions( + "h|help" => \$opt_h, + "authpassword=s" => \$authpasswd, + "authprotocol=s" => \$authproto, + 'B' => \$bits, + 'bits' => \$bits, + "C|community=s" => \$COMMUNITY, + "w|warning=s" => \$warn_usage, + "c|critical=s" => \$crit_usage, + "b|bandwidth|I|inBandwidth=i" => \$iface_speed, + "O|outBandwidth=i" => \$iface_speedOut, + 'f|force' => \$force, #added 20130429 by gjf + 'r' => \$use_reg, + 'noregexp' => \$use_reg, + "privpassword=s" => \$privpasswd, + "privprotocol=s" => \$privproto, + "p|port=i" => \$port, + "u|units=s" => \$units, + "i|interface=s" => \$iface_descr, + "A|address=s" => \$host_ip, + "H|hostname=s" => \$host_address, + 'L' => \$index_list, + "d|debug=i" => \$debug, + 'list' => \$index_list, + "user|username=s" => \$username, + "v|Version=s" => \$snmp_version, + "M|max=i" => \$max_value, #added 20050614 by mw + "32|32bit" => \$thirtytwo #added 20101104 by gjf +); + +# Set internal timeout to address 'Return code of 25 is out of bounds' errors +eval { + local %SIG; + $SIG{ALRM}= + sub{ + die "UKNOWN: script timeout\n"; + exit -1; + }; + alarm 15; + + +# Print help if no options given +if ( $status == 0 ) { + print_help(); + exit $STATUS_CODE{'OK'}; +} + +debugout ("DEBUG ENABLED at level: $debug", "1"); +debugout ("INTERFACE DESCR: $iface_descr", "2"), if ( defined($iface_descr) ); + +# Changed 20091214 gj +# Check for missing options +if ( !$host_address ) { + print "\nMissing host address!\n\n"; + stop(print_usage(),"OK"); +} elsif ( ( $iface_speed ) and ( !$units ) ){ + print "\nMissing units!\n\n"; + stop(print_usage(),"OK"); +} elsif ( ( $units ) and ( ( !$iface_speed ) and ( !$iface_speedOut ) ) ) { + print "\nMissing (-I or -O) interface maximum speed!\n\n"; + stop(print_usage(),"OK"); +} elsif ( ( $iface_speedOut ) and ( !$units ) ) { + print "\nMissing units (-u) for Out maximum speed!\n\n"; + stop(print_usage(),"OK"); +} elsif ( ( $max_value ) and ( !$units ) ) { + print "\nMissing units (-u) for maximum counter!\n\n"; + stop(print_usage(),"OK"); +} elsif ( ( $snmp_version == 3 ) and ( $authpasswd ) and ( !$username ) ) { + print "\nMissing version 3 username!\n\n"; + stop(print_usage(),"OK"); +} elsif ( ( $snmp_version == 3 ) and ( $privpasswd ) and ( !$authpasswd ) ) { + print "\nMissing version 3 auth password!\n\n"; + stop(print_usage(),"OK"); +} + +# Set default units if undefined +if ( !defined($units) ){ + #bits + $units = "b"; +} + +# Switch output from Bytes to bits if changed on command line +if ($bits) { + $suffix = "b" +} + +if ( $iface_speed ) { + #change 20050414 by mw + # Added iface_speedOut 20100202 by gj + # Convert interface speed to Bytes + debugout("UNIT: $units","3"); + $iface_speed = bits2bytes( $iface_speed, $units ); + if ( $iface_speedOut ) { + $iface_speedOut = bits2bytes( $iface_speedOut, $units ); + } +} + +if ( !$max_value ) { + + # If no -M Parameter was set, set it to 64Bit Overflow + $max_bytes = 18446744073709600000; # the value is (2^64) + + if ( defined($thirtytwo) ){ + # If using 32bit counters set to 32bit overflow + $max_bytes = 4294967296; # the value is (2^32) + } +} else { + # Max value specified, used given value, convert to Bytes + $max_bytes = unit2bytes( $max_value, $units ); +} + +debugout ("BYTE COUNTER max_value: $max_bytes", "2"); + +####### Can only be set after interface 'speed in' and 'out' and 'max bytes' have all been converted to Bytes +# Bytes +$units = "B"; + +# Check snmp version, set snmp parameters +if ( $snmp_version =~ /[12]/ ) { + ( $session, $error ) = Net::SNMP->session( + -hostname => $host_address, + -community => $COMMUNITY, + -port => $port, + -version => $snmp_version + ); + + if ( !defined($session) ) { + stop("UNKNOWN: $error","UNKNOWN"); + } +} elsif ( $snmp_version =~ /3/ ) { + #print "\nSNMP v3 \n\n"; + #authPriv + if ( $username and $authpasswd and $privpasswd ) { + ( $session, $error ) = Net::SNMP->session( + -hostname => $host_address, + -version => $snmp_version, + -username => $username, + -authpassword => $authpasswd, + -authprotocol => $authproto, + -privpassword => $privpasswd, + -privprotocol => $privproto, + -port => $port, + -timeout =>$timeout + + ); + #authNoPriv + } elsif ( $username and $authpasswd ) { + ( $session, $error ) = Net::SNMP->session( + -hostname => $host_address, + -version => $snmp_version, + -username => $username, + -authpassword => $authpasswd, + -authprotocol => $authproto, + -port => $port, + -timeout =>$timeout + ); + #NoauthNoPriv + } else { + ( $session, $error ) = Net::SNMP->session( + -hostname => $host_address, + -version => $snmp_version, + -username => $username, + -port => $port, + -timeout =>$timeout + ); + } + if ( !defined($session) ) { + stop("UNKNOWN: $error","UNKNOWN"); + } +} else { + $state = 'UNKNOWN'; + stop("$state: It appears you are missing one or more parameters necessary for v$snmp_version to function.\n",$state); +} + +debugout("SNMP:\n\tver: $snmp_version\n\tcommunity: $COMMUNITY\n\tport: $port", "3"); +if ( $username ) { + debugout("\n\tuser: $username", "3"); +} +if ( $authpasswd ) { + debugout("\n\tauth password: $authpasswd\n\tauth protocol: $authproto", "3"); +} +if ( $privpasswd ) { + debugout("\n\tpriv password: $privpasswd\n\tpriv protocol: $privproto", "3"); +} + +# Neither Interface Index nor Host IP address were specified +if ( !$iface_descr ) { + if ( !$host_ip ){ + # Try to resolve host name and find index from ip addr + debugout("DETECT INTERFACE start with hostname", "1"); + $iface_descr = fetch_Ip2IfIndex( $session, $host_address ); + } else { + # Use ip addr to find index + debugout("DETECT INTERFACE start with IP addr","1"); + $iface_descr = fetch_Ip2IfIndex( $session, $host_ip ); + } +} + +# Added 20091209 gj +# Detect if a string description was given or a numeric interface index number +if ( $iface_descr =~ /[^0123456789]+/ ) { + $iface_number = fetch_ifdescr( $session, $iface_descr ); + debugout("INTERFACE from text string","1"); +} else { + $iface_number = $iface_descr; +} + +debugout("USING INT#: $iface_number", "2"); +debugout("OID's:","2"); +debugout("\tIfOperStatus: $snmpIfOperStatus.$iface_number","2"); +debugout("\tIfSpeed: $snmpIfSpeed.$iface_number","2"); +debugout("\tIfSpeed32: $snmpIfSpeed32.$iface_number","2"); +debugout("\tInOctets: $snmpIfInOctets.$iface_number","2"); +debugout("\tInOctets32: $snmpIfInOctets32.$iface_number","2"); +debugout("\tOutOctets: $snmpIfOutOctets.$iface_number","2"); +debugout("\tOutOctets32: $snmpIfOutOctets32.$iface_number","2"); + +# Get SNMP values, flag errors +debugout("RESULTS:","3"); +my $res_status = $session->get_request(-varbindlist => [ $snmpIfOperStatus . "." . $iface_number ],); +if ( defined $res_status ){ + $if_status = $res_status->{ $snmpIfOperStatus . "." . $iface_number }; + debugout("\tOperational Status: $if_status","3"); +} else { + $if_status = "DNE - " . $session->error(); + debugout("\tOperational Status not defined!: $if_status","2"); +} +my $res_ifspeed64 = $session->get_request(-varbindlist => [ $snmpIfSpeed . "." . $iface_number ],); +if ( defined $res_ifspeed64 ){ + $ifspeed64 = $res_ifspeed64->{ $snmpIfSpeed . "." . $iface_number }; + debugout("\tInterface Speed (64bit): $ifspeed64 Mbits","3"); +} else { + $ifspeed64 = "DNE - " . $session->error(); + debugout("\tInterface Speed (64bit) not defined or bad value!: $ifspeed64","2"); +} +my $res_ifspeed32 = $session->get_request(-varbindlist => [ $snmpIfSpeed32 . "." . $iface_number ],); +if ( defined $res_ifspeed32 ){ + $ifspeed32 = $res_ifspeed32->{ $snmpIfSpeed32 . "." . $iface_number }; + debugout("\tInterface Speed (32bit): $ifspeed32 bits","3"); +} else { + $ifspeed32 = "DNE - " . $session->error(); + debugout("\tInterface Speed (32bit) not defined!: $ifspeed32","2"); +} +my $res_inbytes64 = $session->get_request(-varbindlist => [ $snmpIfInOctets . "." . $iface_number ],); +if ( defined $res_inbytes64 ){ + $inbytes64 = $res_inbytes64->{ $snmpIfInOctets . "." . $iface_number }; + debugout("\tIn Bytes (64bit): $inbytes64","2"); +} else { + $inbytes64 = "DNE - " . $session->error(); + debugout("\tIn Bytes (64bit) not defined!: $inbytes64","2"); +} +my $res_inbytes32 = $session->get_request(-varbindlist => [ $snmpIfInOctets32 . "." . $iface_number ],); +if ( defined $res_inbytes32 ){ + $inbytes32 = $res_inbytes32->{ $snmpIfInOctets32 . "." . $iface_number }; + debugout("\tIn Bytes (32bit): $inbytes32","3"); +} else { + $inbytes32 = "DNE - " . $session->error(); + debugout("\tIn Bytes (32bit) not defined!: $inbytes32","2"); +} +my $res_outbytes64 = $session->get_request(-varbindlist => [ $snmpIfOutOctets . "." . $iface_number ],); +if ( defined $res_outbytes64 ){ + $outbytes64 = $res_outbytes64->{ $snmpIfOutOctets . "." . $iface_number }; + debugout("\tOut Bytes (64bit): $outbytes64","3"); +} else { + $outbytes64 = "DNE - " . $session->error(); + debugout("\tOut Bytes (64bit) not defined!: $outbytes64","2"); +} +my $res_outbytes32 = $session->get_request(-varbindlist => [ $snmpIfOutOctets32 . "." . $iface_number ],); +if ( defined $res_outbytes32 ){ + $outbytes32 = $res_outbytes32->{ $snmpIfOutOctets32 . "." . $iface_number }; + debugout("\tOut Bytes (32bit): $outbytes32","3"); +} else { + $outbytes32 = "DNE - " . $session->error(); + debugout("\tOut Bytes (32bit) not defined!: $outbytes32","2"); +} + +# Check interface status, quit check if interface status is error or not '1'. +if ( defined $res_status ){ + if ( $if_status =~ /^DNE -|error|noSuchObject|noSuchInstance/i ) { + debugout("if_status is not a number\n","4"); + $state = 'UNKNOWN'; + stop("$state: Improper interface status, status received: " . $if_status . "\n",$state); + } elsif ( $if_status == 1 ) { + # No action necessary, continue on! + } elsif ($if_status == 2 ) { + # Quit, interface is down + $state = 'CRITICAL'; + stop("$state: Interface is \'down\' (interface: " . $iface_number . " status: " . $if_status . ")\n",$state); + } elsif ($if_status == 3 ) { + # Quit, interface is testing + $state = 'CRITICAL'; + stop("$state: Interface is reporting \'testing\' (interface: " . $iface_number . " status: " . $if_status . ")\n",$state); + } elsif ($if_status == 4 ) { + # Quit, interface is unknown + $state = 'CRITICAL'; + stop("$state: Interface is reporting \'unknown\' (interface: " . $iface_number . " status: " . $if_status . ")\n",$state); + } elsif ($if_status == 5 ) { + # Quit, interface is dormant + $state = 'CRITICAL'; + stop("$state: Interface is reporting \'dormant\' (interface: " . $iface_number . " status: " . $if_status . ")\n",$state); + } elsif ($if_status == 6 ) { + # Quit, interface is notPresent + $state = 'CRITICAL'; + stop("$state: Interface is reporting \'notPresent\' (interface: " . $iface_number . " status: " . $if_status . ")\n",$state); + } elsif ($if_status == 7 ) { + # Quit, interface is lowerLayerDown + $state = 'CRITICAL'; + stop("$state: Interface is reporting \'lowerLayerDown\' (interface: " . $iface_number . " status: " . $if_status . ")\n",$state); + } else { + # Interface is in an unknown state + $state = 'UNKNOWN'; + stop("$state: Interface is reporting unknown status (interface: " . $iface_number . " status: " . $if_status . ")\n",$state); + } +} else { + $state = 'UNKNOWN'; + stop("$state: Improper interface status, status received: " . $if_status . "\n",$state); +} + +# Determine which values to use +if ( !defined($force) and !defined($thirtytwo) ){ + #default - use 64 then 32 bit values + debugout("USING 64 THEN 32 bit VALUES:","4"); + + # Speed test + if ( !$iface_speed ) { + debugout("\t(Interface speed not provided on command line, determine from host)","4"); + if ( $ifspeed64 =~ /^DNE -|error|noSuchObject|noSuchInstance/i or $ifspeed64 < 1 ){ + debugout("\t\tBad 64bit speed value: $ifspeed64","3"); + if ( $ifspeed32 =~ /^DNE -|error|noSuchObject|noSuchInstance/i or $ifspeed32 < 1 or $ifspeed32 > 4294967295 ){ + debugout("\t\tBad 32bit speed value: $ifspeed32","3"); + $state = 'UNKNOWN'; + stop("$state: No usable interface speed available 64: $ifspeed64 32: $ifspeed32\n",$state); + } else { + debugout("\tUsing 32bit speed value: $ifspeed32","3"); + $iface_speed = bits2bytes( $ifspeed32, "b" ); + } + } else { + debugout("\tUsing 64bit speed value: $ifspeed64","3"); + # Convert Mbits to bits, bits to Bytes + $iface_speed = $ifspeed64 * 1000 * 1000; + $iface_speed = bits2bytes( $iface_speed, "b" ); + } + } + + # InBytes test + if ( $inbytes64 =~ /^DNE -|error|noSuchObject|noSuchInstance/i ){ + debugout("\t\tBad 64bit in bytes value: $inbytes64","3"); + if ( $inbytes32 =~ /^DNE -|error|noSuchObject|noSuchInstance/i ){ + debugout("\t\tBad 32bit in bytes value: $inbytes32","3"); + $state = 'UNKNOWN'; + stop("$state: No in bytes available 64: $inbytes64 32: $inbytes32\n",$state); + } else { + debugout("\tUsing 32bit in bytes value: $inbytes32","3"); + $in_bytes = $inbytes32; + } + } else { + debugout("\tUsing 64bit in bytes value: $inbytes64","3"); + $in_bytes = $inbytes64; + } + + # OutBytes test + if ( $outbytes64 =~ /^DNE -|error|noSuchObject|noSuchInstance/i ){ + debugout("\t\tBad 64bit out bytes value: $outbytes64","3"); + if ( $outbytes32 =~ /^DNE -|error|noSuchObject|noSuchInstance/i ){ + debugout("\t\tBad 32bit out bytes value: $outbytes32","3"); + $state = 'UNKNOWN'; + stop("$state: No out bytes available 64: $outbytes64 32: $outbytes32\n",$state); + } else { + debugout("\tUsing 32bit out bytes value: $outbytes32","3"); + $out_bytes = $outbytes32; + } + } else { + debugout("\tUsing 64bit out bytes value: $outbytes64","3"); + $out_bytes = $outbytes64; + } + +} elsif ( !defined($force) and defined($thirtytwo) ){ + debugout("USING 32 THEN 64 bit VALUES:","4"); + + # Speed test + if ( !$iface_speed ) { + debugout("\t(Interface speed not provided on command line, determine from host)","4"); + if ( $ifspeed32 =~ /^DNE -|error|noSuchObject|noSuchInstance/i or $ifspeed32 < 1 or $ifspeed32 >= 4294967295 ){ + debugout("\t\tBad 32bit speed value: $ifspeed32","3"); + if ( $ifspeed64 =~ /^DNE -|error|noSuchObject|noSuchInstance/i or $ifspeed64 < 1 ){ + debugout("\t\tBad 64bit speed value: $ifspeed64","3"); + $state = 'UNKNOWN'; + stop("$state: No usable interface speed available 64: $ifspeed64 32: $ifspeed32\n",$state); + } else { + debugout("\tUsing 64bit speed value: $ifspeed64","3"); + # Convert Mbits to bits, bits to Bytes + $iface_speed = $ifspeed64 * 1000 * 1000; + $iface_speed = bits2bytes( $iface_speed, "b" ); + } + } else { + debugout("\tUsing 32bit speed value: $ifspeed32","3"); + $iface_speed = bits2bytes( $ifspeed32, "b" ); + } + } + + # InBytes test + if ( $inbytes32 =~ /^DNE -|error|noSuchObject|noSuchInstance/i ){ + debugout("\t\tBad 32bit in bytes value: $inbytes32","3"); + if ( $inbytes64 =~ /^DNE -|error|noSuchObject|noSuchInstance/i ){ + debugout("\t\tBad 64bit in bytes value: $inbytes64","3"); + $state = 'UNKNOWN'; + stop("$state: No in bytes available 64: $inbytes64 32: $inbytes32\n",$state); + } else { + debugout("\tUsing 64bit in bytes value: $inbytes64","3"); + $in_bytes = $inbytes64; + } + } else { + debugout("\tUsing 32bit in bytes value: $inbytes32","3"); + $in_bytes = $inbytes32; + } + + # OutBytes test + if ( $outbytes32 =~ /^DNE -|error|noSuchObject|noSuchInstance/i ){ + debugout("\t\tBad 32bit out bytes value: $outbytes32","3"); + if ( $outbytes64 =~ /^DNE -|error|noSuchObject|noSuchInstance/i ){ + debugout("\t\tBad 64bit out bytes value: $outbytes64","3"); + $state = 'UNKNOWN'; + stop("$state: No out bytes available 64: $outbytes64 32: $outbytes32\n",$state); + } else { + debugout("\tUsing 64bit out bytes value: $outbytes64","3"); + $out_bytes = $outbytes64; + } + } else { + debugout("\tUsing 32bit out bytes value: $outbytes32","3"); + $out_bytes = $outbytes32; + } + +} elsif ( defined($force) and defined($thirtytwo) ){ + debugout("USING 32 bit VALUES ONLY:","4"); + + # Speed test + if ( !$iface_speed ) { + debugout("\t(Interface speed not provided on command line, determine from host)","4"); + if ( $ifspeed32 =~ /^DNE -|error|noSuchObject|noSuchInstance/i or $ifspeed32 < 1 or $ifspeed32 > 4294967295 ){ + debugout("\t\tBad 32bit speed value: $ifspeed32","3"); + $state = 'UNKNOWN'; + stop("$state: No usable interface speed available: $ifspeed32\n",$state); + } else { + debugout("\tUsing 32bit speed value: $ifspeed32","3"); + $iface_speed = bits2bytes( $ifspeed32, "b" ); + } + } + + # InBytes test + if ( $inbytes32 =~ /^DNE -|error|noSuchObject|noSuchInstance/i ){ + debugout("\t\tBad 32bit in bytes value: $inbytes32","3"); + $state = 'UNKNOWN'; + stop("$state: No in bytes available: $inbytes32\n",$state); + } else { + debugout("\tUsing 32bit in bytes value: $inbytes32","3"); + $in_bytes = $inbytes32; + } + + # OutBytes test + if ( $outbytes32 =~ /^DNE -|error|noSuchObject|noSuchInstance/i ){ + debugout("\t\tBad 32bit out bytes value: $outbytes32","3"); + $state = 'UNKNOWN'; + stop("$state: No out bytes available: $outbytes32\n",$state); + } else { + debugout("\tUsing 32bit out bytes value: $outbytes32","3"); + $out_bytes = $outbytes32; + } + +} elsif ( defined($force) and !defined($thirtytwo) ){ + debugout("USING 64 bit ONLY:","4"); + + # Speed test + if ( !$iface_speed ) { + debugout("\t(Interface speed not provided on command line, determine from host)","4"); + if ( $ifspeed64 =~ /^DNE -|error|noSuchObject|noSuchInstance/i or $ifspeed64 < 1 ){ + debugout("\t\tBad 64bit speed value: $ifspeed64","3"); + $state = 'UNKNOWN'; + stop("$state: No usable interface speed available: $ifspeed64\n",$state); + } else { + debugout("\tUsing 64bit speed value: $ifspeed64","3"); + # Convert Mbits to bits, bits to Bytes + $iface_speed = $ifspeed64 * 1000 * 1000; + $iface_speed = bits2bytes( $iface_speed, "b" ); + } + } + + # InBytes test + if ( $inbytes64 =~ /^DNE -|error|noSuchObject|noSuchInstance/i ){ + debugout("\t\tBad 64bit in bytes value: $inbytes64","3"); + $state = 'UNKNOWN'; + stop("$state: No in bytes available: $inbytes64\n",$state); + } else { + debugout("\tUsing 64bit in bytes value: $inbytes64","3"); + $in_bytes = $inbytes64; + } + + # OutBytes test + if ( $outbytes64 =~ /^DNE -|error|noSuchObject|noSuchInstance/i ){ + debugout("\t\tBad 64bit out bytes value: $outbytes64","3"); + $state = 'UNKNOWN'; + stop("$state: No out bytes available: $outbytes64\n",$state); + } else { + debugout("\tUsing 64bit out bytes value: $outbytes64","3"); + $out_bytes = $outbytes64; + } + +} + +# Added 20100201 gj +# Check if Out max speed was provided, use same IF speed for both if not +if (!$iface_speedOut) { + $iface_speedOut = $iface_speed; +} + +debugout ("UNITS: $units", "2"); +debugout ("Interface speed calculated as: $iface_speed $units", "1"); +debugout ("Interface speed OUT: $iface_speedOut $units", "4"); + +# close SNMP +$session->close; + +my $row; +my $last_check_time = time - 1; +my $last_in_bytes = $in_bytes; +my $last_out_bytes = $out_bytes; + +if ( + open( FILE, + "<" . $TRAFFIC_FILE . $host_address . "_if-" . $iface_number ) + ) +{ + while ( $row = ) { + + ( $last_check_time, $last_in_bytes, $last_out_bytes ) = + split( ":", $row ); + + ### by sos 17.07.2009 check for last_bytes + if ( ! $last_in_bytes ) { $last_in_bytes=$in_bytes; } + if ( ! $last_out_bytes ) { $last_out_bytes=$out_bytes; } + + if ($last_in_bytes !~ m/\d/) { $last_in_bytes=$in_bytes; } + if ($last_out_bytes !~ m/\d/) { $last_out_bytes=$out_bytes; } + } + close(FILE); +} + +my $update_time = time; +debugout ("CURRENT timestamp: $update_time", "1"); +debugout ("FILE PATH: $TRAFFIC_FILE" . $host_address . "_if-" . $iface_number, "1"); +debugout("READ FROM FILE:\n\tlast time: $last_check_time\n\tlast in bytes: $last_in_bytes\n\tlast out bytes: $last_out_bytes","4"); + +open( FILE, ">" . $TRAFFIC_FILE . $host_address . "_if-" . $iface_number ) + or die "Can't open $TRAFFIC_FILE for writing: $!"; + +printf FILE ( "%s:%.0ld:%.0ld\n", $update_time, $in_bytes, $out_bytes ); +close(FILE); + +debugout("WRITTEN TO FILE:\n\ttime: $update_time\n\tin_bytes: $in_bytes\n\tout bytes: $out_bytes","4"); + +#added 20050614 by mw +#Check for and correct counter overflow (if possible). +#See function counter_overflow. +$in_bytes = counter_overflow( $in_bytes, $last_in_bytes, $max_bytes ); +$out_bytes = counter_overflow( $out_bytes, $last_out_bytes, $max_bytes ); + +# Calculate traffic since last check (RX\TX) +my $in_traffic = sprintf( "%.2lf", + ( $in_bytes - $last_in_bytes ) / ( time - $last_check_time ) ); +my $out_traffic = sprintf( "%.2lf", + ( $out_bytes - $last_out_bytes ) / ( time - $last_check_time ) ); + +debugout("in_traffic: $in_traffic\nout_traffic: $out_traffic","1"); +# sos 20090717 changed because rrdtool needs bytes +my $in_bytes_abs = $in_bytes; +my $out_bytes_abs = $out_bytes; + +debugout("iface_speed: $iface_speed $units\nin_traffic: $in_traffic\nout_traffic: $out_traffic", "1"); + +# Calculate usage percentages +my $in_ave_pct = sprintf( "%.2f", ( 1.0 * $in_traffic * 100 ) / $iface_speed ); +my $out_ave_pct = sprintf( "%.2f", ( 1.0 * $out_traffic * 100 ) / $iface_speedOut ); + +# Don't scale perf data or change it to bits from bytes +$pin_ave = $in_traffic; +$pout_ave = $out_traffic; + +if ($bits) { + # Convert output from Bytes to bits + $label = "bits"; + $in_tot = $in_bytes * 8; + $out_tot = $out_bytes * 8; + $in_ave = $in_traffic * 8; + $out_ave = $out_traffic * 8; +} else { + $label = "Bytes"; + $in_tot = $in_bytes; + $out_tot = $out_bytes; + $in_ave = $in_traffic; + $out_ave = $out_traffic; +} + +debugout("OUTPUT:\n\tlabel: $label", "4"); +debugout("\tin_tot: $in_tot\n\tout_tot: $out_tot\n\tin_ave: $in_ave\n\tout_ave: $out_ave", "4"); +debugout("\tin_ave_pct: $in_ave_pct\n\tout_ave_pct: $out_ave_pct\n\tin_bytes_abs: $in_bytes_abs\n\tout_bytes_abs: $out_bytes_abs", "4"); + +# Scale ave and tot for output +$in_tot = unit2scale($in_tot); +$out_tot = unit2scale($out_tot); +$in_ave = unit2scale($in_ave); +$out_ave = unit2scale($out_ave); + +# Convert from Bytes/bits to megaBytes/bits +$in_bytes = sprintf( "%.2f", $in_bytes / (1024 * 1000) ); +$out_bytes = sprintf( "%.2f", $out_bytes / (1024 * 1000) ); + +# Changed 20091209 gj, updated 20130424 gj +# Check/Set state of service check +if ( ( $in_ave_pct < $warn_usage ) and ( $out_ave_pct < $warn_usage ) ) { + $state = 'OK'; + $output = + "$state - Average IN: " + . $in_ave . $suffix . " (" . $in_ave_pct . "%), " + . "Average OUT: " . $out_ave . $suffix . " (" . $out_ave_pct . "%)"; + $output .= "Total RX: $in_tot" . "$label, Total TX: $out_tot" . "$label"; +} elsif ( $in_ave_pct > $crit_usage ) { + $state = 'CRITICAL'; + $output = "$state - IN bandwidth ($in_ave_pct%) too high"; +} elsif ( $out_ave_pct > $crit_usage ) { + $state = 'CRITICAL'; + $output = "$state - OUT bandwidth ($out_ave_pct%) too high"; +} elsif ( $in_ave_pct > $warn_usage ) { + $state = 'WARNING'; + $output = "$state - IN bandwidth ($in_ave_pct%) too high"; +} elsif ( $out_ave_pct > $warn_usage ) { + $state = 'WARNING'; + $output = "$state - OUT bandwidth ($out_ave_pct%) too high"; +} + +# Changed 20091214 gj - commas should have been semicolons +$output .= +"|inUsage=$in_ave_pct%;$warn_usage;$crit_usage outUsage=$out_ave_pct%;$warn_usage;$crit_usage" + . " inBandwidth=" . $pin_ave . "B outBandwidth=" . $pout_ave . "B" + . " inAbsolut=$in_bytes_abs" . "c" . " outAbsolut=$out_bytes_abs" . "c"; +debugout ("",1); +stop($output, $state); + + +# end of internal timeout eval group +alarm 0; +}; + +sub fetch_Ip2IfIndex { + my $state; + my $response; + + my $snmpkey; + my $answer; + my $key; + + my ( $session, $host ) = @_; + + # Determine if we have a host name or IP addr + if ( $host =~ /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/ ){ + debugout("I found an IP address: $host","3"); + } else { + debugout("RESOLVING hostname $host","3"); + $host = get_ip ( $host ); + debugout("HOSTNAME RESOLVED to IP addr: $host","3"); + } + + # Quit if results not found + if ( !defined( $response = $session->get_table($snmpIPAdEntIfIndex) ) ) { + $answer = $session->error; + $session->close; + $state = 'CRITICAL'; + stop ("$state: Interface index not detected ERROR: $answer",$state); + } + + my %resp = %{$response}; + + if ( $index_list ){ + print ("\nInterfaces found:\n"); + print (" IP Addr\tIndex\n"); + print ("------------------------\n"); + } + # Check each returned value + foreach $key ( keys %resp ) { + + if ( $index_list ){ + my $index_addr = substr $key, 21; + print ($index_addr,"\t ",$resp{$key},"\n"); + } + + # Check for ip address match in returned index results + if ( $key =~ /$host$/ ) { + $snmpkey = $resp{$key}; + } + } + unless ( defined $snmpkey ) { + $session->close; + $state = 'CRITICAL'; + stop("$state: Could not find index matching $host",$state); + } + return $snmpkey; +} + +sub fetch_ifdescr { + my $state; + my $response; + + my $snmpkey; + my $answer; + my $key; + + my ( $session, $ifdescr ) = @_; + + if ( !defined( $response = $session->get_table($snmpIfDescr) ) ) { + $answer = $session->error; + $session->close; + $state = 'CRITICAL'; + exit $STATUS_CODE{$state}; + } + + foreach $key ( keys %{$response} ) { + + # added 20070816 by oer: remove trailing 0 Byte for Windows :-( + my $resp=$response->{$key}; + $resp =~ s/\x00//; + + + my $test = defined($use_reg) + ? $resp =~ /$ifdescr/ + : $resp eq $ifdescr; + + if ($test) { + + $key =~ /.*\.(\d+)$/; + $snmpkey = $1; + + debugout("\t$ifdescr = $key / $snmpkey","2"); + } + } + unless ( defined $snmpkey ) { + $session->close; + $state = 'CRITICAL'; + printf "$state: Could not match $ifdescr \n"; + exit $STATUS_CODE{$state}; + } + return $snmpkey; +} + +#added 20050416 by mw +#Converts an input value to value in bits +sub bits2bytes { + return unit2bytes(@_) / 8; +} + +#added 20050416 by mw +#Converts an input value to value in bytes +sub unit2bytes { + my ( $value, $unit ) = @_; + + if ( $unit eq "g" ) { + return $value * 1000 * 1000 * 1000; + } + elsif ( $unit eq "m" ) { + return $value * 1000 * 1000; + } + elsif ( $unit eq "k" ) { + return $value * 1000; + } + elsif ( $unit eq "b" ) { + return $value * 1; + } + else { + print "You have to supply a supported unit (g,m,k,b)\n"; + exit $STATUS_CODE{'UNKNOWN'}; + } +} + +sub unit2scale { + # Scale output, expecting Bits\Bytes input + my ($val) = @_; + my $prefix = ""; + + # I'm not sure which should be used here 1024 or 1000 but 1000 is easier on the + # eye when looking at the plug-in output + #if ( $val > 1024 ) { + if ( $val > 1000 ) { + # $val = sprintf( "%.2f", $val / 1024 ); + $val = sprintf( "%.2f", $val / 1000 ); + $prefix = "K"; + } + if ( $val > 1000 ) { + $val = sprintf( "%.2f", $val / 1000 ); + $prefix = "M"; + } + if ( $val > 1000 ) { + $val = sprintf( "%.2f", $val / 1000 ); + $prefix = "G"; + } + return $val . $prefix; +} + +# Convert from Bytes/bits to megaBytes/bits +# added 20050414 by mw +# This function detects if an overflow occurs. If so, it returns +# a computed value for $bytes. +# If there is no counter overflow it simply returns the original value of $bytes. +# IF there is a Counter reboot wrap, just use previous output. +sub counter_overflow { + my ( $bytes, $last_bytes, $max_bytes ) = @_; + + $bytes += $max_bytes if ( $bytes < $last_bytes ); + $bytes = $last_bytes if ( $bytes < $last_bytes ); + return $bytes; +} + +# Added 20100202 by gj +# Print results and exit script +sub stop { + my $result = shift; + my $exit_code = shift; + print $result . "\n"; + exit ( $STATUS_CODE{$exit_code} ); +} + +# Added 20100405 by gj +# Lookup hosts ip address +sub get_ip { + use Net::DNS; + + my ( $host_name ) = @_; + + my $res = Net::DNS::Resolver->new; + my $query = $res->search($host_name); + + if ($query) { + foreach my $rr ($query->answer) { + next unless $rr->type eq "A"; + return $rr->address; + } + } else { + + stop("Error: IP address not resolved","UNKNOWN"); + } +} + +sub debugout { + + my ( $text, $level ) = @_; + + if ( $level <= $debug) { + print "$text\n"; + } +} + +#cosmetic changes 20050614 by mw +#Couldn't sustain "HERE";-), either. +sub print_usage { + print < ] [ --authpassword ] [ --authprotocol MD5|SHA ] [ --privpassword ] [ --privprotocol DES|AES|3DES ] + + Example 1: check_iftraffic64.pl -H host1 -C sneaky + Example 2: check_iftraffic64.pl -H host1 -C sneaky -i "Intel Pro" -r -B + Example 3: check_iftraffic64.pl -H host1 -C sneaky -i 5 + Example 4: check_iftraffic64.pl -H host1 -C sneaky -i 5 -B -b 100 -u m --32bit + Example 5: check_iftraffic64.pl -H host1 -C sneaky -i 5 -B -I 20 -O 5 -u m + Example 6: check_iftraffic64.pl -H host1 -C sneaky -A 192.168.1.1 -B -b 100 -u m + Example 7: check_iftraffic64.pl -H host1 -C sneaky -A 192.168.1.1 --force --32bit + Example 8: check_iftraffic64.pl -H host1 --username admin --authpassword sneaky + Example 9: check_iftraffic64.pl -H host1 --username admin --authpassword sneaky123 --privpassword reallysneaky --privprotocol 3DES + + Options: + + + -b, --bandwidth INTEGER + -I, --inBandwidth INTEGER + Interface maximum speed in kilo/mega/giga/bits per second. Applied to + both IN and OUT if out (-O) max speed is not provided. Requires -u. + -O, --outBandwidth INTEGER + Interface maximum speed in kilo/mega/giga/bits per second. Applied to + OUT traffic. Uses the same units value given for -b. Requires -u. + -i, --interface STRING + Interface Name + -M, --max INTEGER + Max Counter Value (in bits) of net devices in giga/mega/kilo/bits. Requires -u. + -r, --regexp + Use regexp to match NAME in description OID + -u, --units STRING + g=gigabits/s,m=megabits/s,k=kilobits/s,b=bits/s. Required if -b, -I, -M, + or -O are used. + + -A, --address STRING (IP Address) + IP Address to use when determining the interface index to use. Can be + used when the index changes frequently or as in the case of Windows + servers the index is different depending on the NIC installed. + -C, --community STRING + SNMP Community. + -H, --host STRING or IPADDRESS + Check interface on the indicated host. + -c, --critical INTEGER + % of bandwidth usage necessary to result in critical status (default: 98%) + -w, --warning INTEGER + % of bandwidth usage necessary to result in warning status (default: 85%) + + --32bit FLAG + Set to use 32 bit counters instead of 64 bit (default: 64 bit). + -B, --bits FLAG + Display results in bits per second b/s (default: Bytes/s) + -f, --force FLAG + Set to force either 64 bit or 32 bit only checking (32 bit requires --32bit flag). + -d, --debug INTEGER + Output some debug info, not supported inside of Nagios but may be useful + from the command line. Levels 1-4 can be specified, 4 being the most information. + -h, --help + Displays this help text + -L, --list FLAG (on/off) + Tell plugin to list available interfaces. This is not supported inside + of Nagios but may be useful from the command line. + -v, --Version STRING + Set SNMP version (defaults to 2). Version 2 or 3 required for 64 bit counters. + + --authpassword STRING + Set v3 authorization password. + --authprotocol STRING + Set v3 authorization protocol (default: MD5). + --privpassword STRING + Set v3 privilege (encryption) string. + --privprotocol STRING + Set v3 privilege (encryption) protocol (default: DES). +EOU + +} + diff --git a/check_iftraffic64/control b/check_iftraffic64/control new file mode 100644 index 0000000..15f92a5 --- /dev/null +++ b/check_iftraffic64/control @@ -0,0 +1,5 @@ +Homepage: https://exchange.nagios.org/directory/Plugins/Network-Connections%2C-Stats-and-Bandwidth/check_iftraffic64/details +Uploaders: Jan Wagner +Description: plugin for checking network traffic by snmp. +Recommends: libsnmp-perl, libnet-dns-perl +Version: .77 diff --git a/check_iftraffic64/copyright b/check_iftraffic64/copyright new file mode 100644 index 0000000..9e03191 --- /dev/null +++ b/check_iftraffic64/copyright @@ -0,0 +1,7 @@ +Copyright (C) 2004 Gerd Mueller / Netways GmbH + +License: GPL+ + + On Debian systems, the complete text of the GNU General + Public License can be found in "/usr/share/common-licenses/GPL". + diff --git a/debian/patches/check_iftraffic64/fix_traffic_file b/debian/patches/check_iftraffic64/fix_traffic_file new file mode 100644 index 0000000..7828427 --- /dev/null +++ b/debian/patches/check_iftraffic64/fix_traffic_file @@ -0,0 +1,11 @@ +--- a/check_iftraffic64/check_iftraffic64 ++++ b/check_iftraffic64/check_iftraffic64 +@@ -138,7 +138,7 @@ + + + # Path to tmp files +-my $TRAFFIC_FILE = "/usr/local/nagios/libexec/traffic/"; ++my $TRAFFIC_FILE = "/tmp/traffic/"; + + # Create tmp file location if it does not exist + if ( ! -d $TRAFFIC_FILE ) { diff --git a/debian/patches/series b/debian/patches/series index fb9421a..b3899da 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -12,3 +12,4 @@ check_sieve/BareWord check_tftp/epn check_tomcat/epn check_qnap_health/fix_strPart +check_iftraffic64/fix_traffic_file