#!/usr/bin/perl -wT
#
# (c)2002 Michael Markstaller, Elaborated Networks GmbH
# send bug reports to <mm@elabnet.de>
# 
# 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 (or with Nagios);  if not, write to the
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA
#
#
# Check Comapq Insight Management Agents Systems Status by SNMP
# based on the spong-plugin check_insight from:
# http://spong.sourceforge.net/downloads/plugins/spong-network/check_insight
#
# Usage:
# check_insight -H <host> -C community
#

require 5.004;
use strict;
use lib utils.pm ;
use Plugin;
use Plugin::Parameter qw($helpparameterlist $versionparameterlist $hostnameparameter
			 $communityparameter $portparameter $timeoutparameter
			 $verboseparameter);

use Net::SNMP;

use vars qw($opt_w $opt_c $opt_H $opt_C $opt_v $opt_p $opt_t $xml $PROGNAME);
use utils qw(%ERRORS &usage);

$ENV{'PATH'}='';
$ENV{'BASH_ENV'}='';
$ENV{'ENV'}='';

sub escalate_status ($$);

$portparameter->default(161);

my @commandparameterlist = ( $hostnameparameter,
			     $communityparameter,
			     $portparameter,
			     $timeoutparameter,
			     $verboseparameter );

my $plugin = new Plugin(-revision => '$Revision: 1.1 $',
			copyright => "2002 Michael Markstaller, Elaborated Networks GmbH, 2004 Howard Wilkinson <howard\@cohtech.com>",
			-shortcomment => "This plugin checks the Compaq Insight Management agents system status via SNMP on the specified host.",
			-parameterlists => [ \@commandparameterlist, $helpparameterlist, $versionparameterlist ] );


$plugin->init();

#
#              now we set things up for the real work
#              and fire up the request
#

########################################################################

my ($status, $summary, $message ) = ( 'OK', "", "" );

# We use some look up tables for checking some config options.
my @State = ("Not Available", "Other", "OK", "Degraded", "Failed");

my @MIBName = ("",
	       "Std",
	       "Unknown",
	       "Array",
	       "Netware",
	       "SCSI",
	       "Health",
	       "Unknown",
	       "Store",
	       "SM2",
	       "Thresh",
	       "OS",
	       "UPS",
	       "Unknown",
	       "IDE",
	       "Clusters",
	       "Fibre",
	       "MIB",
	       "NIC");

# These are the positions within the table to actually look at.
my @MIBs = (1, 2, 3, 5, 6, 10, 11, 14, 18);

my $oid = "1.3.6.1.4.1.232.11.2.10.1.0";	# SysArray

# Open the connection.
my ($session, $error) = Net::SNMP->session(-hostname  => $opt_H,
					   -community => $opt_C,
					   -timeout   => $opt_t,
					   -port      => $opt_p,
					   -version   => "snmpv1");

# If we can't open a connection, just return red straight away.
if (! defined $session) {
  print ("$PROGNAME UNKNOWN: Unable to contact server '$opt_H' $error\n");
  exit $ERRORS{"UNKNOWN"};
}

$session->translate;

my ($response) = $session->get_request($oid);

if (!defined $response) {
  # If there's no response, something screwy is going on, give up.
  $summary = $session->error;
  print ("$PROGNAME UNKNOWN: $summary\n");
  exit $ERRORS{"UNKNOWN"};
}

$session->close;

# I'm not convinced that this is the easiest way to go about this, this is
# from some code which I've inherited and I've modified for use in here.
# Hi George!
my $d = $response->{$oid};

my @list = ();

# Gobble the first two char's.
$d = substr $d,2;

while (length($d) > 0) {
  my $v = substr($d,0,2);
  $v = hex($v);
  $d = substr $d,2;
  push @list, $v;
}

# Value in $MIBs[1] is the overall status of the machine...
my $cond = $MIBs[1];
$message .= "Status: $State[$cond]";

foreach my $v (@MIBs) {
  if (($v*4)+1 > scalar @list) { next; }
  $cond = $list[($v*4)+1];  # A little bit of magic

  # We only bother printing the status out if it's actually available,
  # as if it's N/A or Unknown then it's probably because the machine
  # isn't available.
  next if ($cond < 2);
  $message .= ", $MIBName[$v] is $State[$cond]" if $cond > 1;

  # What follows is some trickery to try and not to override a previous
  # message at the same or lower color.
  if ($cond == 4) {
    escalate_status('CRITICAL', "$MIBName[$v] is failed");
  } elsif ($cond == 3) {
    escalate_status('WARNING', "$MIBName[$v] is degraded");
  }
}

$summary = "Ok" if $summary eq "";

#  return ($color, $summary, $message);

print "$PROGNAME $status: $summary - $message\n";

exit $ERRORS{$status};

sub escalate_status($$) {
  my ($st, $su) = @_;
  if ($ERRORS{$status} < $ERRORS{$st}) {
    $status = $st;
    $summary = $su;
  }
}
