#! /usr/bin/perl -wT #---------------------------------------------------------------------- # # Author: Martin Fuerstenau, Oce Printing Systems, martin.fuerstenau_at_ops.de # Date: 01.08.2006 # # Purpose: # Checking the status of interface out errors on all network # cards and report to Nagios. This plugin is tested with Linux, Solaris, # Reliant Unix, Windows 2000 and Windows 2003. This plugin detects automatically # all network cards. # # Changes: # # - Rel 1.1 # In case of the return of nothing this is indicated as a warning. # Martin Fuerstenau, OCE Printing Systems, 14.06.2006 # # - Rel 1.2 # Functional enhancement. Warning and Critical was added. # These were omitted in version 1.0 because the errors will not # always indicate the the interface is rotten. But if there are # no threshold you will have warning with one IpOutError in Nagios. # That is scrap. # Martin Fuerstenau, OCE Printing Systems, 16.06.2006 # # - Rel 1.2.1 # Windows puts an \0 at the end of strings. This will cause porblems in the Nagios # output because the message is cutted there. # Martin Fuerstenau, OCE Printing Systems, 01.09.2006 # # Synopsis: # # check_if_out_errors -H [-C community] [-v SNMP Version] -w -c # #---------------------------------------------------------------------- use strict; use Getopt::Long; use vars qw($VERSION $HELP $hostname $host $PROGNAME %INTERFACE_ERROR); use vars qw($community @result $snmpversion $warning $critical $WHATSUP $error); use lib "/usr/lib/nagios/ops_plugins" ; use utils qw(%ERRORS &print_revision &support &usage); # Get the right package from CPAN and install it use SNMP::Util; $PROGNAME = "check_if_out_errors"; $ENV{'PATH'}=''; $ENV{'BASH_ENV'}=''; $ENV{'ENV'}=''; Getopt::Long::Configure('bundling'); GetOptions ("V" => \$VERSION, "version" => \$VERSION, "h" => \$HELP, "help" => \$HELP, "v=s" => \$snmpversion, "snmpversion=s" => \$snmpversion, "w=s" => \$warning, "warning=s" => \$warning, "c=s" => \$critical, "critical=s" => \$critical, "H=s" => \$hostname, "hostname=s" => \$hostname, "C=s" => \$community, "community=s" => \$community); if ($VERSION) { print_revision($PROGNAME,'$Revision: 1.2.1 $'); exit $ERRORS{'OK'}; } if ($HELP) { print_help(); exit $ERRORS{'OK'}; } if (!$hostname) { print_usage(); usage("Host name/address not specified\n\n"); } if ($hostname =~ /([-.A-Za-z0-9]+)/) { $host = $1; } if (!$host) { print_usage(); usage("Invalid host: $hostname\n\n"); } if (!$community) { $community = "public"; } if (!$snmpversion) { $snmpversion = "1"; } if (!$warning) { usage("Warning threshold not specified\n\n"); } if (!$critical) { print "$critical\n"; usage("Critical threshold not specified\n\n"); } else { if (!($critical > $warning)) { usage("Invalid threshold for critical: $critical! Must be bigger than threshold for warning (actual set to $warning).\n\n"); exit 2; } } if (!($snmpversion eq "1" || $snmpversion eq "2c")) { print "Error! Only SNMP V1 or 2c supported!\n"; print "Wrong version submitted.\n"; exit 2; } $WHATSUP=get_if_error_list(); if ($WHATSUP == 0 ) { print "OK! No errors on any interfaces"; exit $ERRORS{'OK'}; } if ($WHATSUP == 1 ) { exit $ERRORS{'WARNING'}; } if ($WHATSUP == 2 ) { exit $ERRORS{'CRITICAL'}; } # --------------- Begin subroutines ---------------------------------------- # We initialize the snmp connection sub get_if_error_list { my $NumElements = 0; my $NumElementsRow = 4; my $NumRows = 0; my $ROWCNT = 1; my $WARN_ME = 0; my $LOOPCNT; my $snmp = new SNMP::Util(-device => $hostname, -community => $community, -snmpversion => $snmpversion, -timeout => 5, -retry => 0, -poll => 'off', -verbose => 'off', -errmode => 'return', -delimiter => ' ', ); if (!$snmp) { print "Warning! "; print "Server $hostname not reachable!"; $WARN_ME = 1; } # Well - we get the f...ing data, but only is there is somethinf in $snmp if ($snmp) { @result = $snmp->walk(-format => 'ne', -oids =>['ifDescr','ifOutErrors'], -print => 'off'); if ($snmp->error) { print "Warning! "; $error = $snmp->errmsg; print "snmp error = $error"; $WARN_ME = 1; } else { # Now we create our coordinate system for getting the data from the array $NumElements = @result; $NumRows = $NumElements/$NumElementsRow; if ($NumElements == 0) { print "Warning! No data received from host!"; $WARN_ME = 1; } else { # Let's work with the data but omit the loopback interface for ( $LOOPCNT=0;$LOOPCNT<$NumRows;$LOOPCNT++) { # This line fixes fixes a problem with windows because windows # terminates interface names with a binary zero (\0) # Martin Fuerstenau, 01.09.2006 $result[$ROWCNT] =~ s/\0//g; if ($result[$ROWCNT] =~ /^[^lo.*]/) { if ($result[$ROWCNT + 2] > 0 ) { if ( $result[$ROWCNT + 2] >= $warning) { if ($WARN_ME == 0) { print "Warning! "; $WARN_ME = 1; } } if ( $result[$ROWCNT + 2] >= $warning && $result[$ROWCNT + 2] <= $critical) { if ($WARN_ME != 2) { print "Interface: $result[$ROWCNT] -> IpOutErrors: $result[$ROWCNT + 2] "; $WARN_ME = 1; } } if ( $result[$ROWCNT + 2] >= $critical ) { print "Interface: $result[$ROWCNT] -> IpOutErrors: $result[$ROWCNT + 2] "; $WARN_ME = 2; } } } $ROWCNT = $ROWCNT + 4; } } } } return $WARN_ME; } sub print_usage { print "\nUsage: $PROGNAME -H [-C community] [-v SNMP Version] -w -c \n\n"; print "or\n"; print "\nUsage: $PROGNAME -V for version.\n\n"; print "or\n"; print "\nUsage: $PROGNAME -h for help.\n\n"; } sub print_help { print_revision($PROGNAME,'$Revision: 1.2.1 $'); print "Copyright (c) 2006 Martin Fuerstenau - Oce Printing Systems\n"; print "This plugin reports the out errors of all network physical interfaces\n"; print_usage(); print " -H, --hostname=HOST Name or IP address of host to check\n"; print " -C, --community=community SNMPv1 community (default public)\n"; print " -v, --snmpversion=snmpversion Version (1 or 2c) of the SNMP protocol. \n"; print " -h, --help Short help message\n"; print " -V, --version Prints version of the plugin\n"; print " -w, --warning=threshold Warning threshold of interface errors\n"; print " -c, --community=threshold Critical threshold of interface errors\n\n"; print "This plugin uses the 'snmpget' command included with the NET-SNMP package.\n"; print "If you don't have the package installed, you will need to download it from\n"; print "http://net-snmp.sourceforge.net before you can use this plugin.\n\n"; print "This plugin also make use of a enhanced version the perl module SNMP::Util .\n"; print "You will find it enclosed with this plugin. Be shure it is installed.\n\n"; support(); print "\n"; }