[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 #! /usr/bin/perl -w 2 # 3 # check_ifoperstatus.pl - nagios plugin 4 # 5 # Copyright (C) 2000 Christoph Kron, 6 # Modified 5/2002 to conform to updated Nagios Plugin Guidelines 7 # Added support for named interfaces per Valdimir Ivaschenko (S. Ghosh) 8 # Added SNMPv3 support (10/2003) 9 # 10 # This program is free software; you can redistribute it and/or 11 # modify it under the terms of the GNU General Public License 12 # as published by the Free Software Foundation; either version 2 13 # of the License, or (at your option) any later version. 14 # 15 # This program is distributed in the hope that it will be useful, 16 # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 # GNU General Public License for more details. 19 # 20 # You should have received a copy of the GNU General Public License 21 # along with this program; if not, write to the Free Software 22 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 23 # 24 # 25 # Report bugs to: nagiosplug-help@lists.sourceforge.net 26 # 27 # 11.01.2000 Version 1.0 28 # $Id: check_ifoperstatus.pl,v 1.6 2004/12/07 03:13:14 mattkent Exp $ 29 # 30 # Patches from Guy Van Den Bergh to warn on ifadminstatus down interfaces 31 # instead of critical. 32 # 33 # Primary MIB reference - RFC 2863 34 35 36 use POSIX; 37 use strict; 38 use lib "/usr/lib/nagios/plugins" ; 39 use utils qw($TIMEOUT %ERRORS &print_revision &support); 40 41 use Net::SNMP; 42 use Getopt::Long; 43 &Getopt::Long::config('bundling'); 44 45 my $PROGNAME = "check_ifoperstatus"; 46 sub print_help (); 47 sub usage (); 48 sub process_arguments (); 49 50 my $timeout; 51 my $status; 52 my %ifOperStatus = ('1','up', 53 '2','down', 54 '3','testing', 55 '4','unknown', 56 '5','dormant', 57 '6','notPresent', 58 '7','lowerLayerDown'); # down due to the state of lower layer interface(s) 59 60 my $state = "UNKNOWN"; 61 my $answer = ""; 62 my $snmpkey = 0; 63 my $community = "public"; 64 my $maxmsgsize = 1472 ; # Net::SNMP default is 1472 65 my ($seclevel, $authproto, $secname, $authpass, $privpass, $auth, $priv, $context); 66 my $port = 161; 67 my @snmpoids; 68 my $sysUptime = '1.3.6.1.2.1.1.3.0'; 69 my $snmpIfDescr = '1.3.6.1.2.1.2.2.1.2'; 70 my $snmpIfAdminStatus = '1.3.6.1.2.1.2.2.1.7'; 71 my $snmpIfOperStatus = '1.3.6.1.2.1.2.2.1.8'; 72 my $snmpIfName = '1.3.6.1.2.1.31.1.1.1.1'; 73 my $snmpIfLastChange = '1.3.6.1.2.1.2.2.1.9'; 74 my $snmpIfAlias = '1.3.6.1.2.1.31.1.1.1.18'; 75 my $snmpLocIfDescr = '1.3.6.1.4.1.9.2.2.1.1.28'; 76 my $hostname; 77 my $ifName; 78 my $session; 79 my $error; 80 my $response; 81 my $snmp_version = 1 ; 82 my $ifXTable; 83 my $opt_h ; 84 my $opt_V ; 85 my $ifdescr; 86 my $key; 87 my $lastc; 88 my $dormantWarn; 89 my $adminWarn; 90 my $name; 91 92 ### Validate Arguments 93 94 $status = process_arguments(); 95 96 97 # Just in case of problems, let's not hang Nagios 98 $SIG{'ALRM'} = sub { 99 print ("ERROR: No snmp response from $hostname (alarm)\n"); 100 exit $ERRORS{"UNKNOWN"}; 101 }; 102 103 alarm($timeout); 104 105 106 ## map ifdescr to ifindex - should look at being able to cache this value 107 108 if (defined $ifdescr) { 109 # escape "/" in ifdescr - very common in the Cisco world 110 $ifdescr =~ s/\//\\\//g; 111 112 $status=fetch_ifdescr(); # if using on device with large number of interfaces 113 # recommend use of SNMP v2 (get-bulk) 114 if ($status==0) { 115 $state = "UNKNOWN"; 116 printf "$state: could not retrive ifdescr snmpkey - $status-$snmpkey\n"; 117 $session->close; 118 exit $ERRORS{$state}; 119 } 120 } 121 122 123 ## Main function 124 125 $snmpIfAdminStatus = $snmpIfAdminStatus . "." . $snmpkey; 126 $snmpIfOperStatus = $snmpIfOperStatus . "." . $snmpkey; 127 $snmpIfDescr = $snmpIfDescr . "." . $snmpkey; 128 $snmpIfName = $snmpIfName . "." . $snmpkey ; 129 $snmpIfAlias = $snmpIfAlias . "." . $snmpkey ; 130 131 push(@snmpoids,$snmpIfAdminStatus); 132 push(@snmpoids,$snmpIfOperStatus); 133 push(@snmpoids,$snmpIfDescr); 134 push(@snmpoids,$snmpIfName) if (defined $ifXTable) ; 135 push(@snmpoids,$snmpIfAlias) if (defined $ifXTable) ; 136 137 if (!defined($response = $session->get_request(@snmpoids))) { 138 $answer=$session->error; 139 $session->close; 140 $state = 'WARNING'; 141 print ("$state: SNMP error: $answer\n"); 142 exit $ERRORS{$state}; 143 } 144 145 $answer = sprintf("host '%s', %s(%s) is %s\n", 146 $hostname, 147 $response->{$snmpIfDescr}, 148 $snmpkey, 149 $ifOperStatus{$response->{$snmpIfOperStatus}} 150 ); 151 152 153 ## Check to see if ifName match is requested and it matches - exit if no match 154 ## not the interface we want to monitor 155 if ( defined $name && not ($response->{$snmpIfName} eq $name) ) { 156 $state = 'UNKNOWN'; 157 $answer = "Interface name ($name) doesn't match snmp value ($response->{$snmpIfName}) (index $snmpkey)"; 158 print ("$state: $answer"); 159 exit $ERRORS{$state}; 160 } 161 162 ## define the interface name 163 if (defined $ifXTable) { 164 $name = $response->{$snmpIfName} ." - " .$response->{$snmpIfAlias} ; 165 }else{ 166 $name = $response->{$snmpIfDescr} ; 167 } 168 169 ## if AdminStatus is down - some one made a consious effort to change config 170 ## 171 if ( not ($response->{$snmpIfAdminStatus} == 1) ) { 172 $answer = "Interface $name (index $snmpkey) is administratively down."; 173 if ( not defined $adminWarn or $adminWarn eq "w" ) { 174 $state = 'WARNING'; 175 } elsif ( $adminWarn eq "i" ) { 176 $state = 'OK'; 177 } elsif ( $adminWarn eq "c" ) { 178 $state = 'CRITICAL'; 179 } else { # If wrong value for -a, say warning 180 $state = 'WARNING'; 181 } 182 } 183 ## Check operational status 184 elsif ( $response->{$snmpIfOperStatus} == 2 ) { 185 $state = 'CRITICAL'; 186 $answer = "Interface $name (index $snmpkey) is down."; 187 } elsif ( $response->{$snmpIfOperStatus} == 5 ) { 188 if (defined $dormantWarn ) { 189 if ($dormantWarn eq "w") { 190 $state = 'WARNING'; 191 $answer = "Interface $name (index $snmpkey) is dormant."; 192 }elsif($dormantWarn eq "c") { 193 $state = 'CRITICAL'; 194 $answer = "Interface $name (index $snmpkey) is dormant."; 195 }elsif($dormantWarn eq "i") { 196 $state = 'OK'; 197 $answer = "Interface $name (index $snmpkey) is dormant."; 198 } 199 }else{ 200 # dormant interface - but warning/critical/ignore not requested 201 $state = 'CRITICAL'; 202 $answer = "Interface $name (index $snmpkey) is dormant."; 203 } 204 } elsif ( $response->{$snmpIfOperStatus} == 6 ) { 205 $state = 'CRITICAL'; 206 $answer = "Interface $name (index $snmpkey) notPresent - possible hotswap in progress."; 207 } elsif ( $response->{$snmpIfOperStatus} == 7 ) { 208 $state = 'CRITICAL'; 209 $answer = "Interface $name (index $snmpkey) down due to lower layer being down."; 210 211 } elsif ( $response->{$snmpIfOperStatus} == 3 || $response->{$snmpIfOperStatus} == 4 ) { 212 $state = 'CRITICAL'; 213 $answer = "Interface $name (index $snmpkey) down (testing/unknown)."; 214 215 } else { 216 $state = 'OK'; 217 $answer = "Interface $name (index $snmpkey) is up."; 218 } 219 220 221 222 print ("$state: $answer"); 223 exit $ERRORS{$state}; 224 225 226 ### subroutines 227 228 sub fetch_ifdescr { 229 if (!defined ($response = $session->get_table($snmpIfDescr))) { 230 $answer=$session->error; 231 $session->close; 232 $state = 'CRITICAL'; 233 printf ("$state: SNMP error with snmp version $snmp_version ($answer)\n"); 234 $session->close; 235 exit $ERRORS{$state}; 236 } 237 238 foreach $key ( keys %{$response}) { 239 if ($response->{$key} =~ /^$ifdescr$/) { 240 $key =~ /.*\.(\d+)$/; 241 $snmpkey = $1; 242 #print "$ifdescr = $key / $snmpkey \n"; #debug 243 } 244 } 245 unless (defined $snmpkey) { 246 $session->close; 247 $state = 'CRITICAL'; 248 printf "$state: Could not match $ifdescr on $hostname\n"; 249 exit $ERRORS{$state}; 250 } 251 252 return $snmpkey; 253 } 254 255 sub usage() { 256 printf "\nMissing arguments!\n"; 257 printf "\n"; 258 printf "usage: \n"; 259 printf "check_ifoperstatus -k <IF_KEY> -H <HOSTNAME> [-C <community>]\n"; 260 printf "Copyright (C) 2000 Christoph Kron\n"; 261 printf "check_ifoperstatus.pl comes with ABSOLUTELY NO WARRANTY\n"; 262 printf "This programm is licensed under the terms of the "; 263 printf "GNU General Public License\n(check source code for details)\n"; 264 printf "\n\n"; 265 exit $ERRORS{"UNKNOWN"}; 266 } 267 268 sub print_help() { 269 printf "check_ifoperstatus plugin for Nagios monitors operational \n"; 270 printf "status of a particular network interface on the target host\n"; 271 printf "\nUsage:\n"; 272 printf " -H (--hostname) Hostname to query - (required)\n"; 273 printf " -C (--community) SNMP read community (defaults to public,\n"; 274 printf " used with SNMP v1 and v2c\n"; 275 printf " -v (--snmp_version) 1 for SNMP v1 (default)\n"; 276 printf " 2 for SNMP v2c\n"; 277 printf " SNMP v2c will use get_bulk for less overhead\n"; 278 printf " if monitoring with -d\n"; 279 printf " -L (--seclevel) choice of \"noAuthNoPriv\", \"authNoPriv\", or \"authPriv\"\n"; 280 printf " -U (--secname) username for SNMPv3 context\n"; 281 printf " -c (--context) SNMPv3 context name (default is empty string)"; 282 printf " -A (--authpass) authentication password (cleartext ascii or localized key\n"; 283 printf " in hex with 0x prefix generated by using \"snmpkey\" utility\n"; 284 printf " auth password and authEngineID\n"; 285 printf " -a (--authproto) Authentication protocol ( MD5 or SHA1)\n"; 286 printf " -X (--privpass) privacy password (cleartext ascii or localized key\n"; 287 printf " in hex with 0x prefix generated by using \"snmpkey\" utility\n"; 288 printf " privacy password and authEngineID\n"; 289 printf " -k (--key) SNMP IfIndex value\n"; 290 printf " -d (--descr) SNMP ifDescr value\n"; 291 printf " -p (--port) SNMP port (default 161)\n"; 292 printf " -I (--ifmib) Agent supports IFMIB ifXTable. Do not use if\n"; 293 printf " you don't know what this is. \n"; 294 printf " -n (--name) the value should match the returned ifName\n"; 295 printf " (Implies the use of -I)\n"; 296 printf " -w (--warn =i|w|c) ignore|warn|crit if the interface is dormant (default critical)\n"; 297 printf " -D (--admin-down =i|w|c) same for administratively down interfaces (default warning)\n"; 298 printf " -M (--maxmsgsize) Max message size - usefull only for v1 or v2c\n"; 299 printf " -t (--timeout) seconds before the plugin times out (default=$TIMEOUT)\n"; 300 printf " -V (--version) Plugin version\n"; 301 printf " -h (--help) usage help \n\n"; 302 printf " -k or -d must be specified\n\n"; 303 printf "Note: either -k or -d must be specified and -d is much more network \n"; 304 printf "intensive. Use it sparingly or not at all. -n is used to match against\n"; 305 printf "a much more descriptive ifName value in the IfXTable to verify that the\n"; 306 printf "snmpkey has not changed to some other network interface after a reboot.\n\n"; 307 print_revision($PROGNAME, '$Revision: 1.6 $'); 308 309 } 310 311 sub process_arguments() { 312 $status = GetOptions( 313 "V" => \$opt_V, "version" => \$opt_V, 314 "h" => \$opt_h, "help" => \$opt_h, 315 "v=i" => \$snmp_version, "snmp_version=i" => \$snmp_version, 316 "C=s" => \$community, "community=s" => \$community, 317 "L=s" => \$seclevel, "seclevel=s" => \$seclevel, 318 "a=s" => \$authproto, "authproto=s" => \$authproto, 319 "U=s" => \$secname, "secname=s" => \$secname, 320 "A=s" => \$authpass, "authpass=s" => \$authpass, 321 "X=s" => \$privpass, "privpass=s" => \$privpass, 322 "c=s" => \$context, "context=s" => \$context, 323 "k=i" => \$snmpkey, "key=i",\$snmpkey, 324 "d=s" => \$ifdescr, "descr=s" => \$ifdescr, 325 "l=s" => \$lastc, "lastchange=s" => \$lastc, 326 "p=i" => \$port, "port=i" =>\$port, 327 "H=s" => \$hostname, "hostname=s" => \$hostname, 328 "I" => \$ifXTable, "ifmib" => \$ifXTable, 329 "n=s" => \$ifName, "name=s" => \$ifName, 330 "w=s" => \$dormantWarn, "warn=s" => \$dormantWarn, 331 "D=s" => \$adminWarn, "admin-down=s" => \$adminWarn, 332 "M=i" => \$maxmsgsize, "maxmsgsize=i" => \$maxmsgsize, 333 "t=i" => \$timeout, "timeout=i" => \$timeout, 334 ); 335 336 337 338 if ($status == 0){ 339 print_help(); 340 exit $ERRORS{'OK'}; 341 } 342 343 if ($opt_V) { 344 print_revision($PROGNAME,'$Revision: 1.6 $ '); 345 exit $ERRORS{'OK'}; 346 } 347 348 if ($opt_h) { 349 print_help(); 350 exit $ERRORS{'OK'}; 351 } 352 353 if (! utils::is_hostname($hostname)){ 354 usage(); 355 exit $ERRORS{"UNKNOWN"}; 356 } 357 358 359 unless ($snmpkey > 0 || defined $ifdescr){ 360 printf "Either a valid snmpkey key (-k) or a ifDescr (-d) must be provided)\n"; 361 usage(); 362 exit $ERRORS{"UNKNOWN"}; 363 } 364 365 366 if (defined $name) { 367 $ifXTable=1; 368 } 369 370 if (defined $dormantWarn) { 371 unless ($dormantWarn =~ /^(w|c|i)$/ ) { 372 printf "Dormant alerts must be one of w|c|i \n"; 373 exit $ERRORS{'UNKNOWN'}; 374 } 375 } 376 377 unless (defined $timeout) { 378 $timeout = $TIMEOUT; 379 } 380 381 if ($snmp_version =~ /3/ ) { 382 # Must define a security level even though default is noAuthNoPriv 383 # v3 requires a security username 384 if (defined $seclevel && defined $secname) { 385 386 # Must define a security level even though defualt is noAuthNoPriv 387 unless ($seclevel eq ('noAuthNoPriv' || 'authNoPriv' || 'authPriv' ) ) { 388 usage(); 389 exit $ERRORS{"UNKNOWN"}; 390 } 391 392 # Authentication wanted 393 if ($seclevel eq ('authNoPriv' || 'authPriv') ) { 394 395 unless ($authproto eq ('MD5' || 'SHA1') ) { 396 usage(); 397 exit $ERRORS{"UNKNOWN"}; 398 } 399 400 if ( !defined $authpass) { 401 usage(); 402 exit $ERRORS{"UNKNOWN"}; 403 }else{ 404 if ($authpass =~ /^0x/ ) { 405 $auth = "-authkey => $authpass" ; 406 }else{ 407 $auth = "-authpassword => $authpass"; 408 } 409 } 410 411 } 412 413 # Privacy (DES encryption) wanted 414 if ($seclevel eq 'authPriv' ) { 415 if (! defined $privpass) { 416 usage(); 417 exit $ERRORS{"UNKNOWN"}; 418 }else{ 419 if ($privpass =~ /^0x/){ 420 $priv = "-privkey => $privpass"; 421 }else{ 422 $priv = "-privpassword => $privpass"; 423 } 424 } 425 } 426 427 # Context name defined or default 428 429 unless ( defined $context) { 430 $context = ""; 431 } 432 433 434 435 }else { 436 usage(); 437 exit $ERRORS{'UNKNOWN'}; ; 438 } 439 } # end snmpv3 440 441 442 if ( $snmp_version =~ /[12]/ ) { 443 ($session, $error) = Net::SNMP->session( 444 -hostname => $hostname, 445 -community => $community, 446 -port => $port, 447 -version => $snmp_version, 448 -maxmsgsize => $maxmsgsize 449 ); 450 451 if (!defined($session)) { 452 $state='UNKNOWN'; 453 $answer=$error; 454 print ("$state: $answer"); 455 exit $ERRORS{$state}; 456 } 457 458 }elsif ( $snmp_version =~ /3/ ) { 459 460 if ($seclevel eq 'noAuthNoPriv') { 461 ($session, $error) = Net::SNMP->session( 462 -hostname => $hostname, 463 -port => $port, 464 -version => $snmp_version, 465 -username => $secname, 466 ); 467 468 }elsif ( $seclevel eq 'authNoPriv' ) { 469 ($session, $error) = Net::SNMP->session( 470 -hostname => $hostname, 471 -port => $port, 472 -version => $snmp_version, 473 -username => $secname, 474 $auth, 475 -authprotocol => $authproto, 476 ); 477 }elsif ($seclevel eq 'authPriv' ) { 478 ($session, $error) = Net::SNMP->session( 479 -hostname => $hostname, 480 -port => $port, 481 -version => $snmp_version, 482 -username => $secname, 483 $auth, 484 -authprotocol => $authproto, 485 $priv 486 ); 487 } 488 489 490 if (!defined($session)) { 491 $state='UNKNOWN'; 492 $answer=$error; 493 print ("$state: $answer"); 494 exit $ERRORS{$state}; 495 } 496 497 }else{ 498 $state='UNKNOWN'; 499 print ("$state: No support for SNMP v$snmp_version yet\n"); 500 exit $ERRORS{$state}; 501 } 502 503 } 504 ## End validation 505
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Tue Mar 17 22:47:18 2015 | Cross-referenced by PHPXref 0.7.1 |