#!/usr/bin/perl -w # # check_alpha_xm - nagios plugin # # by Frank Bulk # # 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, USA. # # # This plugin checks the health status of Alpha XM units via SNMP. To minimize # network and node impact, this script checks the overall health and only if # there is an error does it query more tables. # # Here is a suggested command definition: # # 'check_alpha_xm' command definition # define command { # command_name check_alpha_xm # command_line $USER1$/check_alpha_xm -H $HOSTADDRESS$ -C $ARG1$ # } # # Here is a suggested service configuration: # define service{ # use generic-service # host_name alpha-001 # service_description ALPHA # contact_groups cable-plant-admins # notification_interval 15 # check_command check_alpha_xm!AlphaGet # } # use strict; use Net::SNMP; use Getopt::Long; use File::Basename; &Getopt::Long::config('auto_abbrev'); use IO::Socket; my $version = "1.0"; my $status; my $needhelp = ''; my $TIMEOUT = 30; my %ERRORS = ( 'OK' => '0', 'WARNING' => '1', 'CRITICAL' => '2', 'UNKNOWN' => '3', ); # default return value is UNKNOWN my $state = "UNKNOWN"; # responses from script my $answer = ""; my $oidmsg = ""; my $output = ""; # external variable declarations my $hostname; my $community = "public"; my $port = 161; my $major; my $minor; my %alarmstate; $alarmstate{'1'} = "noAlarm"; $alarmstate{'2'} = "alarm"; # snmp related variables my $snmpkey; my $snmpoid; my $key; ## main program # Just in case of problems, let's not hang $SIG{'ALRM'} = sub { print ("ERROR: No snmp response from $hostname (alarm)\n"); exit $ERRORS{"UNKNOWN"}; }; alarm($TIMEOUT); # we must have -some- arguments if (scalar(@ARGV) == 0) { usage(); } # end if no options Getopt::Long::Configure("no_ignore_case"); $status = GetOptions( "h|help" => \$needhelp, "C|snmpcommunity=s" => \$community, "p|port=i" => \$port, "H|hostname=s" => \$hostname, ); if ($status == 0 || $needhelp) { usage(); } # end if getting options fails or the user wants help $major = snmp_get_request($hostname, $port, "2c", $community, "1.3.6.1.4.1.5591.1.4.2.1.25.1"); if (!defined($major)) { $major = snmp_get_request($hostname, $port, "2c", $community, "1.3.6.1.4.1.5591.1.4.2.1.25.1"); if (defined($major)) { $major = -1; } } $minor = snmp_get_request($hostname, $port, "2c", $community, "1.3.6.1.4.1.5591.1.4.2.1.26.1"); if (!defined($minor)) { $minor = snmp_get_request($hostname, $port, "2c", $community, "1.3.6.1.4.1.5591.1.4.2.1.26.1"); if (!defined($minor)) { $minor = -1; } } #print "DEBUG: major [$major]\n"; #print "DEBUG: minor [$minor]\n"; # figure out what state we're in if ($major eq 2) { $state = "CRITICAL"; } elsif ($minor eq 2) { $state = "WARNING"; } else { $state = "OK"; } # end if we have warnings or not if (($major eq 2) || ($minor eq 2)) { $answer = "critical: $alarmstate{$major}; warning: $alarmstate{$minor}"; $oidmsg = join("\n", get_alarms($hostname, $port, $community)); $output = "$state: $answer\n$oidmsg"; } else { $output = "$state"; } # setup final message print ("$output\n"); exit $ERRORS{$state}; ## subroutines ## # the usage of this program (duh) sub usage { print < Usage: check_alpha_xm (-C|--snmpcommunity) (-H|--hostname) [-p|--port] END exit $ERRORS{"UNKNOWN"}; } sub snmp_get_request { my $ip = shift; my $port = shift; my $version = shift; my $community = shift; my $sysdescr = shift; my $snmp_result = ''; my ($session, $error) = Net::SNMP->session( -hostname => $ip, -version => $version, -community => $community, -port => $port); $snmp_result = $session->get_request( -varbindlist => [$sysdescr] ); if (!defined($snmp_result)) { # print "\nERROR: Trying to obtain $sysdescr from $ip. $session->error.\n"; sleep 5; $snmp_result = $session->get_request( -varbindlist => [$sysdescr] ); if (!defined($snmp_result)) { print "\nERROR: Trying to obtain $sysdescr from $ip. $session->error.\n"; $session->close; return 0; } } $session->close; return $snmp_result->{$sysdescr}; } sub get_alarms { my $ip = shift; my $port = shift; my $community = shift; my @index_array; my @return_array; my @temp_array; my $i; my $name; my ($session, $error) = Net::SNMP->session( -hostname => $ip, -community => $community, -port => $port); my $snmp_oid = '1.3.6.1.4.1.926.1.2.1.1.1.6.12'; my $snmp_result = $session->get_table( -baseoid => $snmp_oid ); if (!defined($snmp_result)) { print "ERROR: Trying to get $snmp_oid on $ip: '" . $session->error . "'.\n"; $session->close; exit 1; } $session->close; my %bla = %{$snmp_result}; # just look at those that have alarms foreach my $key (keys %bla) { if ($bla{$key} =~ /ALARM/) { @temp_array = split (/\./, $key); # this is the key that has the description $temp_array[12] = 4; $name = snmp_get_request($hostname, $port, "2c", $community, join('.', @temp_array)); push (@return_array, $name); } } return @return_array; }