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 @@ | |||
| 2 | # | 2 | # |
| 3 | # check_ifoperstatus.pl - nagios plugin | 3 | # check_ifoperstatus.pl - nagios plugin |
| 4 | # | 4 | # |
| 5 | # Copyright (C) 2000 Christoph Kron | 5 | # Copyright (C) 2000 Christoph Kron, |
| 6 | # Modified 5/2002 to conform to updated Nagios Plugin Guidelines | 6 | # Modified 5/2002 to conform to updated Nagios Plugin Guidelines |
| 7 | # Added support for named interfaces per Valdimir Ivaschenko (S. Ghosh) | 7 | # Added support for named interfaces per Valdimir Ivaschenko (S. Ghosh) |
| 8 | # | 8 | # |
| @@ -21,10 +21,16 @@ | |||
| 21 | # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 21 | # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| 22 | # | 22 | # |
| 23 | # | 23 | # |
| 24 | # Report bugs to: ck@zet.net, nagiosplug-help@lists.sf.net | 24 | # Report bugs to: nagiosplug-help@lists.sourceforge.net |
| 25 | # | 25 | # |
| 26 | # 11.01.2000 Version 1.0 | 26 | # 11.01.2000 Version 1.0 |
| 27 | # $Id$ | 27 | # $Id$ |
| 28 | # | ||
| 29 | # Patches from Guy Van Den Bergh to warn on ifadminstatus down interfaces | ||
| 30 | # instead of critical. | ||
| 31 | # | ||
| 32 | # Primary MIB reference - RFC 2863 | ||
| 33 | |||
| 28 | 34 | ||
| 29 | use POSIX; | 35 | use POSIX; |
| 30 | use strict; | 36 | use strict; |
| @@ -42,7 +48,8 @@ my %ifOperStatus = ('1','up', | |||
| 42 | '3','testing', | 48 | '3','testing', |
| 43 | '4','unknown', | 49 | '4','unknown', |
| 44 | '5','dormant', | 50 | '5','dormant', |
| 45 | '6','notPresent'); | 51 | '6','notPresent', |
| 52 | '7','lowerLayerDown'); # down due to the state of lower layer interface(s) | ||
| 46 | 53 | ||
| 47 | my $state = "UNKNOWN"; | 54 | my $state = "UNKNOWN"; |
| 48 | my $answer = ""; | 55 | my $answer = ""; |
| @@ -50,12 +57,16 @@ my $snmpkey = 0; | |||
| 50 | my $community = "public"; | 57 | my $community = "public"; |
| 51 | my $port = 161; | 58 | my $port = 161; |
| 52 | my @snmpoids; | 59 | my @snmpoids; |
| 53 | my $snmpIfDescr = '1.3.6.1.2.1.2.2.1.2'; | 60 | my $sysUptime = '1.3.6.1.2.1.1.3.0'; |
| 61 | my $snmpIfDescr = '1.3.6.1.2.1.2.2.1.2'; | ||
| 62 | my $snmpIfAdminStatus = '1.3.6.1.2.1.2.2.1.7'; | ||
| 54 | my $snmpIfOperStatus = '1.3.6.1.2.1.2.2.1.8'; | 63 | my $snmpIfOperStatus = '1.3.6.1.2.1.2.2.1.8'; |
| 55 | my $snmpIfName = '1.3.6.1.2.1.31.1.1.1.1'; | 64 | my $snmpIfName = '1.3.6.1.2.1.31.1.1.1.1'; |
| 56 | my $snmpIfAlias = '1.3.6.1.2.1.31.1.1.1.18'; | 65 | my $snmpIfLastChange = '1.3.6.1.2.1.2.2.1.9'; |
| 57 | my $snmpLocIfDescr = '1.3.6.1.4.1.9.2.2.1.1.28'; | 66 | my $snmpIfAlias = '1.3.6.1.2.1.31.1.1.1.18'; |
| 67 | my $snmpLocIfDescr = '1.3.6.1.4.1.9.2.2.1.1.28'; | ||
| 58 | my $hostname; | 68 | my $hostname; |
| 69 | my $ifName; | ||
| 59 | my $session; | 70 | my $session; |
| 60 | my $error; | 71 | my $error; |
| 61 | my $response; | 72 | my $response; |
| @@ -65,6 +76,9 @@ my $opt_h ; | |||
| 65 | my $opt_V ; | 76 | my $opt_V ; |
| 66 | my $ifdescr; | 77 | my $ifdescr; |
| 67 | my $key; | 78 | my $key; |
| 79 | my $lastc; | ||
| 80 | my $dormantWarn; | ||
| 81 | my $name; | ||
| 68 | 82 | ||
| 69 | 83 | ||
| 70 | 84 | ||
| @@ -76,6 +90,8 @@ $SIG{'ALRM'} = sub { | |||
| 76 | #alarm($TIMEOUT); | 90 | #alarm($TIMEOUT); |
| 77 | 91 | ||
| 78 | 92 | ||
| 93 | ### Validate Arguments | ||
| 94 | |||
| 79 | $status = GetOptions( | 95 | $status = GetOptions( |
| 80 | "V" => \$opt_V, "version" => \$opt_V, | 96 | "V" => \$opt_V, "version" => \$opt_V, |
| 81 | "h" => \$opt_h, "help" => \$opt_h, | 97 | "h" => \$opt_h, "help" => \$opt_h, |
| @@ -83,9 +99,12 @@ $status = GetOptions( | |||
| 83 | "C=s" =>\$community, "community=s" => \$community, | 99 | "C=s" =>\$community, "community=s" => \$community, |
| 84 | "k=i" =>\$snmpkey, "key=i",\$snmpkey, | 100 | "k=i" =>\$snmpkey, "key=i",\$snmpkey, |
| 85 | "d=s" =>\$ifdescr, "descr=s" => \$ifdescr, | 101 | "d=s" =>\$ifdescr, "descr=s" => \$ifdescr, |
| 102 | "l=s" => \$lastc, "lastchange=s" => \$lastc, | ||
| 86 | "p=i" =>\$port, "port=i",\$port, | 103 | "p=i" =>\$port, "port=i",\$port, |
| 87 | "H=s" => \$hostname, "hostname=s" => \$hostname, | 104 | "H=s" => \$hostname, "hostname=s" => \$hostname, |
| 88 | "I" => \$ifXTable, "ifmib" => \$ifXTable); | 105 | "I" => \$ifXTable, "ifmib" => \$ifXTable, |
| 106 | "n=s" => \$ifName, "name=s" => \$ifName, | ||
| 107 | "w=s" => \$dormantWarn, "warn=s" => \$dormantWarn ); | ||
| 89 | 108 | ||
| 90 | 109 | ||
| 91 | 110 | ||
| @@ -111,6 +130,17 @@ if (! utils::is_hostname($hostname)){ | |||
| 111 | } | 130 | } |
| 112 | 131 | ||
| 113 | 132 | ||
| 133 | unless ($snmpkey > 0 || defined $ifdescr){ | ||
| 134 | printf "Either a valid snmpkey key (-k) or a ifDescr (-d) must be provided)\n"; | ||
| 135 | usage(); | ||
| 136 | exit $ERRORS{"UNKNOWN"}; | ||
| 137 | } | ||
| 138 | |||
| 139 | |||
| 140 | if (defined $name) { | ||
| 141 | $ifXTable=1; | ||
| 142 | } | ||
| 143 | |||
| 114 | if ( $snmp_version =~ /[12]/ ) { | 144 | if ( $snmp_version =~ /[12]/ ) { |
| 115 | ($session, $error) = Net::SNMP->session( | 145 | ($session, $error) = Net::SNMP->session( |
| 116 | -hostname => $hostname, | 146 | -hostname => $hostname, |
| @@ -135,6 +165,12 @@ if ( $snmp_version =~ /[12]/ ) { | |||
| 135 | exit $ERRORS{$state}; | 165 | exit $ERRORS{$state}; |
| 136 | } | 166 | } |
| 137 | 167 | ||
| 168 | ## End validation | ||
| 169 | |||
| 170 | |||
| 171 | |||
| 172 | ## map ifdescr to ifindex - should look at being able to cache this value | ||
| 173 | |||
| 138 | if (defined $ifdescr) { | 174 | if (defined $ifdescr) { |
| 139 | # escape "/" in ifdescr - very common in the Cisco world | 175 | # escape "/" in ifdescr - very common in the Cisco world |
| 140 | $ifdescr =~ s/\//\\\//g; | 176 | $ifdescr =~ s/\//\\\//g; |
| @@ -143,31 +179,32 @@ if (defined $ifdescr) { | |||
| 143 | # recommend use of SNMP v2 (get-bulk) | 179 | # recommend use of SNMP v2 (get-bulk) |
| 144 | if ($status==0) { | 180 | if ($status==0) { |
| 145 | $state = "UNKNOWN"; | 181 | $state = "UNKNOWN"; |
| 146 | printf "$state: could not retrive ifIndex - $status-$snmpkey\n"; | 182 | printf "$state: could not retrive snmpkey - $status-$snmpkey\n"; |
| 147 | $session->close; | 183 | $session->close; |
| 148 | exit $ERRORS{$state}; | 184 | exit $ERRORS{$state}; |
| 149 | } | 185 | } |
| 150 | } | 186 | } |
| 151 | if ( $snmpkey == 0 ) { | ||
| 152 | printf "ifIndex key cannot be 0\n"; | ||
| 153 | usage(); | ||
| 154 | exit $ERRORS{'UNKNOWN'}; | ||
| 155 | } | ||
| 156 | 187 | ||
| 157 | $snmpIfOperStatus = '1.3.6.1.2.1.2.2.1.8' . "." . $snmpkey; | ||
| 158 | $snmpIfDescr = '1.3.6.1.2.1.2.2.1.2' . "." . $snmpkey; | ||
| 159 | $snmpIfAlias = '1.3.6.1.2.1.31.1.1.1.18' . "." . $snmpkey ; | ||
| 160 | 188 | ||
| 189 | ## Main function | ||
| 190 | |||
| 191 | $snmpIfAdminStatus = $snmpIfAdminStatus . "." . $snmpkey; | ||
| 192 | $snmpIfOperStatus = $snmpIfOperStatus . "." . $snmpkey; | ||
| 193 | $snmpIfDescr = $snmpIfDescr . "." . $snmpkey; | ||
| 194 | $snmpIfName = $snmpIfName . "." . $snmpkey ; | ||
| 195 | $snmpIfAlias = $snmpIfAlias . "." . $snmpkey ; | ||
| 161 | 196 | ||
| 197 | push(@snmpoids,$snmpIfAdminStatus); | ||
| 162 | push(@snmpoids,$snmpIfOperStatus); | 198 | push(@snmpoids,$snmpIfOperStatus); |
| 163 | push(@snmpoids,$snmpIfDescr); | 199 | push(@snmpoids,$snmpIfDescr); |
| 200 | push(@snmpoids,$snmpIfName) if (defined $ifXTable) ; | ||
| 164 | push(@snmpoids,$snmpIfAlias) if (defined $ifXTable) ; | 201 | push(@snmpoids,$snmpIfAlias) if (defined $ifXTable) ; |
| 165 | 202 | ||
| 166 | if (!defined($response = $session->get_request(@snmpoids))) { | 203 | if (!defined($response = $session->get_request(@snmpoids))) { |
| 167 | $answer=$session->error; | 204 | $answer=$session->error; |
| 168 | $session->close; | 205 | $session->close; |
| 169 | $state = 'CRITICAL'; | 206 | $state = 'WARNING'; |
| 170 | print ("$state: $answer for ifIndex $snmpkey\n"); | 207 | print ("$state: SNMP error: $answer\n"); |
| 171 | exit $ERRORS{$state}; | 208 | exit $ERRORS{$state}; |
| 172 | } | 209 | } |
| 173 | 210 | ||
| @@ -178,31 +215,87 @@ push(@snmpoids,$snmpIfAlias) if (defined $ifXTable) ; | |||
| 178 | $ifOperStatus{$response->{$snmpIfOperStatus}} | 215 | $ifOperStatus{$response->{$snmpIfOperStatus}} |
| 179 | ); | 216 | ); |
| 180 | 217 | ||
| 181 | $session->close; | ||
| 182 | 218 | ||
| 183 | if ( $response->{$snmpIfOperStatus} == 1 ) { | 219 | ## Check to see if ifName match is requested and it matches - exit if no match |
| 184 | $state = 'OK'; | 220 | ## not the interface we want to monitor |
| 221 | if ( defined $name && not ($response->{$snmpIfName} eq $name) ) { | ||
| 222 | $state = 'UNKNOWN'; | ||
| 223 | $answer = "Interface name ($name) doesn't match snmp value ($response->{$snmpIfName}) (index $snmpkey)"; | ||
| 224 | print ("$state: $answer"); | ||
| 225 | exit $ERRORS{$state}; | ||
| 226 | } | ||
| 227 | |||
| 228 | ## define the interface name | ||
| 229 | if (defined $ifXTable) { | ||
| 230 | $name = $response->{$snmpIfName} ." - " .$response->{$snmpIfAlias} ; | ||
| 231 | }else{ | ||
| 232 | $name = $response->{$snmpIfDescr} ; | ||
| 185 | } | 233 | } |
| 186 | else { | 234 | |
| 187 | $state = 'CRITICAL'; | 235 | ## if AdminStatus is down - some one made a consious effort to change config |
| 236 | ## | ||
| 237 | if ( not ($response->{$snmpIfAdminStatus} == 1) ) { | ||
| 238 | $state = 'WARNING'; | ||
| 239 | $answer = "Interface $name (index $snmpkey) is administratively down."; | ||
| 240 | |||
| 241 | } | ||
| 242 | ## Check operational status | ||
| 243 | elsif ( $response->{$snmpIfOperStatus} == 2 ) { | ||
| 244 | $state = 'CRITICAL'; | ||
| 245 | $answer = "Interface $name (index $snmpkey) is down."; | ||
| 246 | } elsif ( $response->{$snmpIfOperStatus} == 5 ) { | ||
| 247 | if (defined $dormantWarn ) { | ||
| 248 | if ($dormantWarn eq "w") { | ||
| 249 | $state = 'WARNNG'; | ||
| 250 | $answer = "Interface $name (index $snmpkey) is dormant."; | ||
| 251 | }elsif($dormantWarn eq "c") { | ||
| 252 | $state = 'CRITICAL'; | ||
| 253 | $answer = "Interface $name (index $snmpkey) is dormant."; | ||
| 254 | }elsif($dormantWarn eq "i") { | ||
| 255 | $state = 'OK'; | ||
| 256 | $answer = "Interface $name (index $snmpkey) is dormant."; | ||
| 257 | } | ||
| 258 | }else{ | ||
| 259 | # dormant interface - but warning/critical/ignore not requested | ||
| 260 | $state = 'CRITICAL'; | ||
| 261 | $answer = "Interface $name (index $snmpkey) is dormant."; | ||
| 262 | } | ||
| 263 | } elsif ( $response->{$snmpIfOperStatus} == 6 ) { | ||
| 264 | $state = 'CRITICAL'; | ||
| 265 | $answer = "Interface $name (index $snmpkey) notPresent - possible hotswap in progress."; | ||
| 266 | } elsif ( $response->{$snmpIfOperStatus} == 7 ) { | ||
| 267 | $state = 'CRITICAL'; | ||
| 268 | $answer = "Interface $name (index $snmpkey) down due to lower layer being down."; | ||
| 269 | |||
| 270 | } elsif ( $response->{$snmpIfOperStatus} == 3 || $response->{$snmpIfOperStatus} == 4 ) { | ||
| 271 | $state = 'CRITICAL'; | ||
| 272 | $answer = "Interface $name (index $snmpkey) down (testing/unknown)."; | ||
| 273 | |||
| 274 | } else { | ||
| 275 | $state = 'OK'; | ||
| 276 | $answer = "Interface $name (index $snmpkey) is up."; | ||
| 188 | } | 277 | } |
| 189 | 278 | ||
| 279 | |||
| 280 | |||
| 190 | print ("$state: $answer"); | 281 | print ("$state: $answer"); |
| 191 | exit $ERRORS{$state}; | 282 | exit $ERRORS{$state}; |
| 192 | 283 | ||
| 193 | 284 | ||
| 285 | ### subroutines | ||
| 286 | |||
| 194 | sub fetch_ifdescr { | 287 | sub fetch_ifdescr { |
| 195 | if (!defined ($response = $session->get_table($snmpIfDescr))) { | 288 | if (!defined ($response = $session->get_table($snmpIfDescr))) { |
| 196 | $answer=$session->error; | 289 | $answer=$session->error; |
| 197 | $session->close; | 290 | $session->close; |
| 198 | $state = 'CRITICAL'; | 291 | $state = 'CRITICAL'; |
| 199 | printf ("$state: $answer for $snmpIfDescr with snmp version $snmp_version\n"); | 292 | printf ("$state: SNMP error with snmp version $snmp_version ($answer)\n"); |
| 200 | $session->close; | 293 | $session->close; |
| 201 | exit $ERRORS{$state}; | 294 | exit $ERRORS{$state}; |
| 202 | } | 295 | } |
| 203 | 296 | ||
| 204 | foreach $key ( keys %{$response}) { | 297 | foreach $key ( keys %{$response}) { |
| 205 | if ($response->{$key} =~ /$ifdescr/) { | 298 | if ($response->{$key} =~ /^$ifdescr$/) { |
| 206 | $key =~ /.*\.(\d+)$/; | 299 | $key =~ /.*\.(\d+)$/; |
| 207 | $snmpkey = $1; | 300 | $snmpkey = $1; |
| 208 | #print "$ifdescr = $key / $snmpkey \n"; #debug | 301 | #print "$ifdescr = $key / $snmpkey \n"; #debug |
| @@ -242,14 +335,21 @@ sub print_help { | |||
| 242 | printf " 2 for SNMP v2c\n"; | 335 | printf " 2 for SNMP v2c\n"; |
| 243 | printf " SNMP v2c will use get_bulk for less overhead\n"; | 336 | printf " SNMP v2c will use get_bulk for less overhead\n"; |
| 244 | printf " if monitoring with -d\n"; | 337 | printf " if monitoring with -d\n"; |
| 245 | printf " -k (--key) SNMP ifIndex value\n"; | 338 | printf " -k (--key) SNMP IfIndex value\n"; |
| 246 | printf " -d (--descr) SNMP ifDescr value\n"; | 339 | printf " -d (--descr) SNMP ifDescr value\n"; |
| 247 | printf " -p (--port) SNMP port (default 161)\n"; | 340 | printf " -p (--port) SNMP port (default 161)\n"; |
| 248 | printf " -I (--ifmib) Agent supports IFMIB ifXTable. Do not use if\n"; | 341 | printf " -I (--ifmib) Agent supports IFMIB ifXTable. Do not use if\n"; |
| 249 | printf " you don't know what this is.\n"; | 342 | printf " you don't know what this is. \n"; |
| 343 | printf " -n (--name) the value should match the returned ifName\n"; | ||
| 344 | printf " (Implies the use of -I)\n"; | ||
| 345 | printf " -w (--warn =i|w|c) ignore|warn|crit if the interface is dormant (default critical)\n"; | ||
| 250 | printf " -V (--version) Plugin version\n"; | 346 | printf " -V (--version) Plugin version\n"; |
| 251 | printf " -h (--help) usage help \n\n"; | 347 | printf " -h (--help) usage help \n\n"; |
| 252 | printf " -k or -d must be specified\n\n"; | 348 | printf " -k or -d must be specified\n\n"; |
| 349 | printf "Note: either -k or -d must be specified and -d is much more network \n"; | ||
| 350 | printf "intensive. Use it sparingly or not at all. -n is used to match against\n"; | ||
| 351 | printf "a much more descriptive ifName value in the IfXTable to verify that the\n"; | ||
| 352 | printf "snmpkey has not changed to some other network interface after a reboot.\n\n"; | ||
| 253 | print_revision($PROGNAME, '$Revision$'); | 353 | print_revision($PROGNAME, '$Revision$'); |
| 254 | 354 | ||
| 255 | } | 355 | } |
