#!/usr/bin/perl -w
#
# Nagios host script to get the speedfan values
#
# Speedfan is an application for gathering infos like temperature, fan speed and voltage.
# for more details, visit http://www.almico.com/speedfan.php
#
# This monitor also requires the SFSNMP extension so you can fetch data by SNMP.
# You can find the latest version from the SVN section at http://code.bastart.eu.org/sfsnmp
# svn co https://code.bastart.eu.org/svn/sfsnmp
#
# Changes and Modifications
# =========================
# 26-feb-2008 - Samuel Archambault <samifruit514@hotmail.com>
# 	- version 1.0 intial release
#
#
#
# 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.

#require 5.004;
use Data::Dumper;
use Net::SNMP;
use strict;
use Switch;

my %ERRORS=('OK'=>0,'WARNING'=>1,'CRITICAL'=>2,'UNKNOWN'=>3,'DEPENDENT'=>4);
my $default_temp_warn = '(x<0 && x>-5) || (x>30 && x<35)';
my $default_temp_crit = 'x<=-5 || x>=35';

my $default_fspeed_warn = '(x<0 && x>-5) || (x>30 && x<35)';
my $default_fspeed_crit = 'x<=-5 || x>=35';

my $default_voltage_warn = '(x<0 && x>-5) || (x>30 && x<35)';
my $default_voltage_crit = 'x<=-5 || x>=35';
my $default_index = '0';
my $default_type = 'temp';
my $default_warn;
my $default_crit;
my $unit;
my $value;
my $sfan_table_stub = '.1.3.6.1.4.1.30503.1.';
my $sfan_table;
my $sfan_table_count;

my $o_timeout=  15;		# Default 5s Timeout
my $o_port = 		161; 	# port

my $type = shift || &usage();
switch($type)
{
	case 'temp'
	{
		$default_warn = $default_temp_warn;
		$default_crit = $default_temp_crit;
		$sfan_table = $sfan_table_stub.'2.';
		$sfan_table_count = $sfan_table_stub.'1.1';
		$unit = '°C';
	}

	case 'fanspeed'
	{
		$default_warn = $default_fspeed_warn;
		$default_crit = $default_fspeed_crit;
		$sfan_table = $sfan_table_stub.'3.';
		$sfan_table_count = $sfan_table_stub.'1.2';
		$unit = 'RPM';
	}

	case 'voltage'
	{
		$default_warn = $default_voltage_warn;
		$default_crit = $default_voltage_crit;
		$sfan_table = $sfan_table_stub.'4.';
		$sfan_table_count = $sfan_table_stub.'1.3';
		$unit = 'V';
	}
}

sub usage {
	print "Minimum arguments not supplied!\n";
	print "\n";
	print "Perl Check speedfan for Nagios\n";
	print "Usage: check_sfan.pl <type> <host> <community> <sensor index> [<warn_condition>] [<crit_condition>]\n";
	print "\n";
	print "<type> 		= type of sensor: 'temp','fanspeed' or 'voltage'. Defaults to $default_type\n";
	print "<host>		= host\n";
	print "<community>	= community\n";
	print "<sensor idx>	= index of the monitor sensor. Defaults to $default_index\n";
	print "<condition>  = Condition of alert in a php/java/perl format, where x is the value.\n";
	print "					For example \"x>35&&x<20\" would mean that it is considered warning below 20 and above 35\n";
	print "Example: ./check_sfan.pl temp 192.168.0.1 public 1 \"x>30||x<10\" \"x>35||x<5\"\n";
	print "A warning will be returned if temperature of the first temperature sensor is between 30°C and 35°C or between 5°C and 10°C\n";
	print "and critical if the temperature is below 5°C or above 35°C\n";
	exit 1;
}



my $host  = shift || &usage();
my $community  = shift || &usage();

if(!defined($ARGV[0]))
{
	&usage();
}
my $idx = shift;



my $warn = shift || &usage();
my $crit = shift || &usage();;
my $return_code;

my ($session,$error);
($session, $error) = Net::SNMP->session(
     -hostname  => $host,
     -community => $community,
     -port      => $o_port,
     -timeout   => $o_timeout
  );

if (!defined($session)) {
   printf("ERROR opening session: %s.\n", $error);
   exit $ERRORS{"UNKNOWN"};
}

# Get desctiption table

my @oid = ($sfan_table.$idx);
my $resultat = $session->get_request( 
	'-varbindlist' => \@oid
);

if (!defined($resultat)) {
   printf("ERROR: Description table : %s.\n", $session->error);
   $session->close;
   exit $ERRORS{"UNKNOWN"};
}
my @key_one = keys %$resultat;
$value = $$resultat{$key_one[0]};
if($type eq 'temp' || $type eq 'voltage')
{
	$value = $value /100;
}

$warn =~ s/x/$value/;
$crit =~ s/x/$value/;
if(eval($crit))
{
	print "CRITICAL";
	$return_code = 2;
}
elsif(eval($warn))
{
	print "WARNING";
	$return_code = 1;
}
else
{
	print "OK";
	$return_code = 0;
}

print " - $value$unit |check_sfan;$type;$idx;$value;$warn;$crit\n";
exit $return_code;
