diff options
Diffstat (limited to 'plugins-scripts')
-rw-r--r-- | plugins-scripts/check_ifoperstatus.pl | 156 |
1 files changed, 128 insertions, 28 deletions
diff --git a/plugins-scripts/check_ifoperstatus.pl b/plugins-scripts/check_ifoperstatus.pl index 46964677..b5d0bcd1 100644 --- a/plugins-scripts/check_ifoperstatus.pl +++ b/plugins-scripts/check_ifoperstatus.pl @@ -2,7 +2,7 @@ # # check_ifoperstatus.pl - nagios plugin # -# Copyright (C) 2000 Christoph Kron +# Copyright (C) 2000 Christoph Kron, # Modified 5/2002 to conform to updated Nagios Plugin Guidelines # Added support for named interfaces per Valdimir Ivaschenko (S. Ghosh) # @@ -21,10 +21,16 @@ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # -# Report bugs to: ck@zet.net, nagiosplug-help@lists.sf.net +# Report bugs to: nagiosplug-help@lists.sourceforge.net # # 11.01.2000 Version 1.0 # $Id$ +# +# Patches from Guy Van Den Bergh to warn on ifadminstatus down interfaces +# instead of critical. +# +# Primary MIB reference - RFC 2863 + use POSIX; use strict; @@ -42,7 +48,8 @@ my %ifOperStatus = ('1','up', '3','testing', '4','unknown', '5','dormant', - '6','notPresent'); + '6','notPresent', + '7','lowerLayerDown'); # down due to the state of lower layer interface(s) my $state = "UNKNOWN"; my $answer = ""; @@ -50,12 +57,16 @@ my $snmpkey = 0; my $community = "public"; my $port = 161; my @snmpoids; -my $snmpIfDescr = '1.3.6.1.2.1.2.2.1.2'; +my $sysUptime = '1.3.6.1.2.1.1.3.0'; +my $snmpIfDescr = '1.3.6.1.2.1.2.2.1.2'; +my $snmpIfAdminStatus = '1.3.6.1.2.1.2.2.1.7'; my $snmpIfOperStatus = '1.3.6.1.2.1.2.2.1.8'; -my $snmpIfName = '1.3.6.1.2.1.31.1.1.1.1'; -my $snmpIfAlias = '1.3.6.1.2.1.31.1.1.1.18'; -my $snmpLocIfDescr = '1.3.6.1.4.1.9.2.2.1.1.28'; +my $snmpIfName = '1.3.6.1.2.1.31.1.1.1.1'; +my $snmpIfLastChange = '1.3.6.1.2.1.2.2.1.9'; +my $snmpIfAlias = '1.3.6.1.2.1.31.1.1.1.18'; +my $snmpLocIfDescr = '1.3.6.1.4.1.9.2.2.1.1.28'; my $hostname; +my $ifName; my $session; my $error; my $response; @@ -65,6 +76,9 @@ my $opt_h ; my $opt_V ; my $ifdescr; my $key; +my $lastc; +my $dormantWarn; +my $name; @@ -76,6 +90,8 @@ $SIG{'ALRM'} = sub { #alarm($TIMEOUT); +### Validate Arguments + $status = GetOptions( "V" => \$opt_V, "version" => \$opt_V, "h" => \$opt_h, "help" => \$opt_h, @@ -83,9 +99,12 @@ $status = GetOptions( "C=s" =>\$community, "community=s" => \$community, "k=i" =>\$snmpkey, "key=i",\$snmpkey, "d=s" =>\$ifdescr, "descr=s" => \$ifdescr, + "l=s" => \$lastc, "lastchange=s" => \$lastc, "p=i" =>\$port, "port=i",\$port, "H=s" => \$hostname, "hostname=s" => \$hostname, - "I" => \$ifXTable, "ifmib" => \$ifXTable); + "I" => \$ifXTable, "ifmib" => \$ifXTable, + "n=s" => \$ifName, "name=s" => \$ifName, + "w=s" => \$dormantWarn, "warn=s" => \$dormantWarn ); @@ -111,6 +130,17 @@ if (! utils::is_hostname($hostname)){ } +unless ($snmpkey > 0 || defined $ifdescr){ + printf "Either a valid snmpkey key (-k) or a ifDescr (-d) must be provided)\n"; + usage(); + exit $ERRORS{"UNKNOWN"}; +} + + +if (defined $name) { + $ifXTable=1; +} + if ( $snmp_version =~ /[12]/ ) { ($session, $error) = Net::SNMP->session( -hostname => $hostname, @@ -135,6 +165,12 @@ if ( $snmp_version =~ /[12]/ ) { exit $ERRORS{$state}; } +## End validation + + + +## map ifdescr to ifindex - should look at being able to cache this value + if (defined $ifdescr) { # escape "/" in ifdescr - very common in the Cisco world $ifdescr =~ s/\//\\\//g; @@ -143,31 +179,32 @@ if (defined $ifdescr) { # recommend use of SNMP v2 (get-bulk) if ($status==0) { $state = "UNKNOWN"; - printf "$state: could not retrive ifIndex - $status-$snmpkey\n"; + printf "$state: could not retrive snmpkey - $status-$snmpkey\n"; $session->close; exit $ERRORS{$state}; } } -if ( $snmpkey == 0 ) { - printf "ifIndex key cannot be 0\n"; - usage(); - exit $ERRORS{'UNKNOWN'}; -} - $snmpIfOperStatus = '1.3.6.1.2.1.2.2.1.8' . "." . $snmpkey; - $snmpIfDescr = '1.3.6.1.2.1.2.2.1.2' . "." . $snmpkey; - $snmpIfAlias = '1.3.6.1.2.1.31.1.1.1.18' . "." . $snmpkey ; +## Main function + +$snmpIfAdminStatus = $snmpIfAdminStatus . "." . $snmpkey; +$snmpIfOperStatus = $snmpIfOperStatus . "." . $snmpkey; +$snmpIfDescr = $snmpIfDescr . "." . $snmpkey; +$snmpIfName = $snmpIfName . "." . $snmpkey ; +$snmpIfAlias = $snmpIfAlias . "." . $snmpkey ; +push(@snmpoids,$snmpIfAdminStatus); push(@snmpoids,$snmpIfOperStatus); push(@snmpoids,$snmpIfDescr); +push(@snmpoids,$snmpIfName) if (defined $ifXTable) ; push(@snmpoids,$snmpIfAlias) if (defined $ifXTable) ; if (!defined($response = $session->get_request(@snmpoids))) { $answer=$session->error; $session->close; - $state = 'CRITICAL'; - print ("$state: $answer for ifIndex $snmpkey\n"); + $state = 'WARNING'; + print ("$state: SNMP error: $answer\n"); exit $ERRORS{$state}; } @@ -178,31 +215,87 @@ push(@snmpoids,$snmpIfAlias) if (defined $ifXTable) ; $ifOperStatus{$response->{$snmpIfOperStatus}} ); - $session->close; - if ( $response->{$snmpIfOperStatus} == 1 ) { - $state = 'OK'; + ## Check to see if ifName match is requested and it matches - exit if no match + ## not the interface we want to monitor + if ( defined $name && not ($response->{$snmpIfName} eq $name) ) { + $state = 'UNKNOWN'; + $answer = "Interface name ($name) doesn't match snmp value ($response->{$snmpIfName}) (index $snmpkey)"; + print ("$state: $answer"); + exit $ERRORS{$state}; + } + + ## define the interface name + if (defined $ifXTable) { + $name = $response->{$snmpIfName} ." - " .$response->{$snmpIfAlias} ; + }else{ + $name = $response->{$snmpIfDescr} ; } - else { - $state = 'CRITICAL'; + + ## if AdminStatus is down - some one made a consious effort to change config + ## + if ( not ($response->{$snmpIfAdminStatus} == 1) ) { + $state = 'WARNING'; + $answer = "Interface $name (index $snmpkey) is administratively down."; + + } + ## Check operational status + elsif ( $response->{$snmpIfOperStatus} == 2 ) { + $state = 'CRITICAL'; + $answer = "Interface $name (index $snmpkey) is down."; + } elsif ( $response->{$snmpIfOperStatus} == 5 ) { + if (defined $dormantWarn ) { + if ($dormantWarn eq "w") { + $state = 'WARNNG'; + $answer = "Interface $name (index $snmpkey) is dormant."; + }elsif($dormantWarn eq "c") { + $state = 'CRITICAL'; + $answer = "Interface $name (index $snmpkey) is dormant."; + }elsif($dormantWarn eq "i") { + $state = 'OK'; + $answer = "Interface $name (index $snmpkey) is dormant."; + } + }else{ + # dormant interface - but warning/critical/ignore not requested + $state = 'CRITICAL'; + $answer = "Interface $name (index $snmpkey) is dormant."; + } + } elsif ( $response->{$snmpIfOperStatus} == 6 ) { + $state = 'CRITICAL'; + $answer = "Interface $name (index $snmpkey) notPresent - possible hotswap in progress."; + } elsif ( $response->{$snmpIfOperStatus} == 7 ) { + $state = 'CRITICAL'; + $answer = "Interface $name (index $snmpkey) down due to lower layer being down."; + + } elsif ( $response->{$snmpIfOperStatus} == 3 || $response->{$snmpIfOperStatus} == 4 ) { + $state = 'CRITICAL'; + $answer = "Interface $name (index $snmpkey) down (testing/unknown)."; + + } else { + $state = 'OK'; + $answer = "Interface $name (index $snmpkey) is up."; } + + print ("$state: $answer"); exit $ERRORS{$state}; +### subroutines + sub fetch_ifdescr { if (!defined ($response = $session->get_table($snmpIfDescr))) { $answer=$session->error; $session->close; $state = 'CRITICAL'; - printf ("$state: $answer for $snmpIfDescr with snmp version $snmp_version\n"); + printf ("$state: SNMP error with snmp version $snmp_version ($answer)\n"); $session->close; exit $ERRORS{$state}; } foreach $key ( keys %{$response}) { - if ($response->{$key} =~ /$ifdescr/) { + if ($response->{$key} =~ /^$ifdescr$/) { $key =~ /.*\.(\d+)$/; $snmpkey = $1; #print "$ifdescr = $key / $snmpkey \n"; #debug @@ -242,14 +335,21 @@ sub print_help { printf " 2 for SNMP v2c\n"; printf " SNMP v2c will use get_bulk for less overhead\n"; printf " if monitoring with -d\n"; - printf " -k (--key) SNMP ifIndex value\n"; + printf " -k (--key) SNMP IfIndex value\n"; printf " -d (--descr) SNMP ifDescr value\n"; printf " -p (--port) SNMP port (default 161)\n"; printf " -I (--ifmib) Agent supports IFMIB ifXTable. Do not use if\n"; - printf " you don't know what this is.\n"; + printf " you don't know what this is. \n"; + printf " -n (--name) the value should match the returned ifName\n"; + printf " (Implies the use of -I)\n"; + printf " -w (--warn =i|w|c) ignore|warn|crit if the interface is dormant (default critical)\n"; printf " -V (--version) Plugin version\n"; printf " -h (--help) usage help \n\n"; printf " -k or -d must be specified\n\n"; + printf "Note: either -k or -d must be specified and -d is much more network \n"; + printf "intensive. Use it sparingly or not at all. -n is used to match against\n"; + printf "a much more descriptive ifName value in the IfXTable to verify that the\n"; + printf "snmpkey has not changed to some other network interface after a reboot.\n\n"; print_revision($PROGNAME, '$Revision$'); } |