#!/usr/bin/perl -w

use Net::SNMP;
use Getopt::Std;
use strict;

sub usage;

my %opt;



# defaults

$opt{c} = 'public';

getopts ('vc:h', \%opt);

usage if $opt{h};

my $host = shift @ARGV or usage;

my ($state, $text) = eval { check_p4000 ($host, $opt{c}) };

if ( $@ ) {
	chomp ($@);
	$text = "CRITICAL: $@";
	$state = 2;
}

print "$text\n";
exit $state;

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

sub usage {
	print "Usage: $0 [-v] [-c community] <host>\n";
	exit 0;
}

sub check_p4000 {
	my $host = shift;
	my $community = shift;
	
	my ($session, $error) = Net::SNMP->session (
		hostname	=>	$host,
		community	=>	$community,
		version		=>	'snmpv2c',
		timeout		=>	2,
	);
	
	if ( ! $session ) {
		die "$error\n";
	}
	
	my %to_check = qw (
		infoCPUCount		1.3.6.1.4.1.9804.3.1.1.2.1.14.0
		infoPowerSupplyCount	1.3.6.1.4.1.9804.3.1.1.2.1.16.0
		infoFanCount		1.3.6.1.4.1.9804.3.1.1.2.1.18.0
		infoCacheBatteryCount	1.3.6.1.4.1.9804.3.1.1.2.1.28.0
		infoModel		1.3.6.1.4.1.9804.3.1.1.2.1.30.0
		infoHostname		1.3.6.1.4.1.9804.3.1.1.2.1.31.0
		infoSerialNumber	1.3.6.1.4.1.9804.3.1.1.2.1.34.0
		infoProductName		1.3.6.1.4.1.9804.3.1.1.2.1.36.0
		infoHardwareDescription	1.3.6.1.4.1.9804.3.1.1.2.1.39.0
		infoSoftwareType	1.3.6.1.4.1.9804.3.1.1.2.1.50.0
		infoSoftwareVersion	1.3.6.1.4.1.9804.3.1.1.2.1.51.0
		networkDeviceCount	1.3.6.1.4.1.9804.3.1.1.2.2.1.0
		storageDeviceCount	1.3.6.1.4.1.9804.3.1.1.2.4.1.0
		storageRaidStatus	1.3.6.1.4.1.9804.3.1.1.2.4.12.0
		lhnNsmStatus		1.3.6.1.4.1.9804.3.1.1.2.99.1.0
	);
	
	my @oids = values %to_check;
	
	my $values = $session->get_request (
		varbindlist	=>	\@oids,
	) or die "SNMP request timed out!\n";
	
	my ($name, $oid, %v);
	
	while (($name, $oid) = each %to_check) {
		print "$name: 	" . $values->{$oid} . "\n" if $opt{v};
		$v{$name} = $values->{$oid};
	}
	
	
	
	my (@warnings, $warning, $critical);
	
	# first checks
	if ($v{lhnNsmStatus} ne 1) {
		$critical = 1;
		push @warnings, "lhnNsmStatus is $v{lhnNsmStatus}";
	}
	
	if ($v{storageRaidStatus} ne 'Normal') {
		$critical = 1;
		push @warnings, "storageRaidStatus is $v{storageRaidStatus}";
	}
	
	# process tables
	
	my $i;
	
	# CPUs
	#foreach $i (1..$v{infoCPUCount}) {
	#	$oid = "1.3.6.1.4.1.9804.3.1.1.2.1.15.1.2.$i";
	#	my $temperature = $session->get_request (
	#		varbindlist	=> [$oid],
	#	)->{$oid};
	#	print "CPU $i temperature: $temperature\n";
	#}
	
	# Power supplies
	foreach $i (1..$v{infoPowerSupplyCount}) {
		$oid = "1.3.6.1.4.1.9804.3.1.1.2.1.17.1.3.$i";
		my $state = $session->get_request (
			varbindlist	=> [$oid],
		)->{$oid} or die "SNMP request timed out!\n";
		print "Power supply $i: $state\n" if $opt{v};
		if ($state ne "normal") {
			$critical = 1;
			push @warnings, "Power supply $i is $state";
		}
	}
	
	# Fans
	foreach $i (1..$v{infoFanCount}) {
		$oid = "1.3.6.1.4.1.9804.3.1.1.2.1.19.1.3.$i";
		my $state = $session->get_request (
			varbindlist	=> [$oid],
		)->{$oid} or die "SNMP request timed out!\n";
		print "Fan $i: $state\n" if $opt{v};
		if ($state ne "normal") {
			$critical = 1;
			push @warnings, "Fan $i is $state";
		}
	}
	
	# Cache batteries
	foreach $i (1..$v{infoCacheBatteryCount}) {
		$oid = "1.3.6.1.4.1.9804.3.1.1.2.1.29.1.2.$i";
		my $state = $session->get_request (
			varbindlist	=> [$oid],
		)->{$oid} or die "SNMP request timed out!\n";
		print "Cache Battery $i: $state\n" if $opt{v};
		if ($state ne "normal" and $state ne "unknown") {
			$critical = 1;
			push @warnings, "Cache Battery $i is $state";
		}
	}
	
	# Drives
	foreach $i (1..$v{storageDeviceCount}) {
		$oid = "1.3.6.1.4.1.9804.3.1.1.2.4.2.1.5.$i";
		my $state = $session->get_request (
			varbindlist	=> [$oid],
		)->{$oid} or die "SNMP request timed out!\n";
		print "Drive $i: $state\n" if $opt{v};
		if ($state ne "Active") {
			$critical = 1;
			push @warnings, "Drive $i is $state";
		}
	}
	
	# Network devices
	foreach $i (1..$v{networkDeviceCount}) {
		$oid = "1.3.6.1.4.1.9804.3.1.1.2.2.2.1.11.$i";
		my $state = $session->get_request (
			varbindlist	=> [$oid],
		)->{$oid} or die "SNMP request timed out!\n";
		print "Network device $i: $state\n" if $opt{v};
		if ($state ne "Active") {
			$critical = 1;
			push @warnings, "Network device $i is $state";
		}
	}
	
	my ($state, $text);
	
	if ($critical) {
		$state = 2;
		$text = "CRITICAL: " . join ', ', @warnings;
	} elsif ($warning) {
		$state = 1;
		$text = "WARNING:  " . join ', ', @warnings;
	} else {
		$state = 0;
		$text = "OK: $v{infoHostname}, $v{infoModel}, $v{infoProductName}, S/N $v{infoSerialNumber}, $v{infoHardwareDescription}, $v{infoSoftwareType} $v{infoSoftwareVersion}";
	}
	
	return ($state, $text);
}

