#!/usr/bin/perl

#
# Check Memory by SNMP
#

use Getopt::Long qw(:config no_ignore_case bundling) ;

use constant STATUS_OK => 0;
use constant STATUS_WARN => 1;
use constant STATUS_CRITICAL => 2;
use constant STATUS_UNKNOWN => 3;

my $snmpwalk = '/usr/bin/snmpwalk';

my $host;
my $swap;
my $check;
my $status;
my $version;
my $warning;
my $critical;
my $community;
my $exit_code;
my $status_str;
my $realPercent;

sub parse_args{
	GetOptions(
		"H|host=s" => \$host,
		"v|version=s" => \$version,
		"c|community=s" => \$community,
		"C|critical=i" => \$critical,
		"W|warning=i" => \$warning,
		"s" => \$swap
	);
	if (!$warning or !$critical 
		or ($warning and ($warning !~ /^[0-9]+$/ or $warning < 0 or $warning > 100)) 
		or ($critical and ($critical !~ /^[0-9]+$/ or $critical < 0 or $critical > 100)))
	{
	    	print "Unknown - Favor informar um valor inteiro para os paramentros -w e -c, entre 0 e 100\n";
                PrintHelp();
        }
} 

sub PrintHelp {
	print "Usage: $0 -H IP -W NUM -C NUM -v <community_version> -c <community_name>\n";
	print "\t-H\tip address\n";
	print "\t-W\twarning threshhold\n";
	print "\t-C\tcritical threshhold\n";
	print "\t-v\tcommunity version\n";
	print "\t-c\tcommunity name\n";
	print "\t-s\tcheck swap of memory\n";
	print "EXAMPLES:\n";
	print "\tMemory:\n";
	print "\t$0 -H 127.0.0.1 -W 85 -C 95 -v 2c -c public\n";
	print "\tSWAP:\n";
	print "\t$0 -H 127.0.0.1 -W 85 -C 95 -v 2c -c public -s\n";
	exit STATUS_UNKNOWN;
}

sub do_snmp {
	my ($OID) = @_;
	my $cmd = "$snmpwalk -c $community -v $version $host $OID" ;
	chomp(my $out = `$cmd 2> /dev/null`);
	if ($? != 0) {
		print "Unknown - SNMP problem - no value returned\n";
		exit STATUS_UNKNOWN;
	}
	my $type;
	my ($jnk, $x) = split / = /, $out, 2;
	if ($x =~ /([a-zA-Z0-9]+):\s(\d+)\s.*$/){
		$type = $1;
		$x = $2;
	}
	return $x;
}


parse_args();

if ($swap) {
	$check = "SWAP";
	my $swapFreeOID = '.1.3.6.1.4.1.2021.4.4.0';
	my $swapTotalOID = '.1.3.6.1.4.1.2021.4.3.0';
	my $swapTotal = do_snmp($swapTotalOID);
	if (0 == $swapTotal) {
		print "SNMP problem - total swap is zero, is swap enabled on this host?\n";
		exit STATUS_UNKNOWN;
	}
	my $swapFree = do_snmp($swapFreeOID);
	$realPercent = (($swapTotal - $swapFree) / $swapTotal) * 100;
	$realPercent = sprintf("%.2f", $realPercent);
	$status_str = "usage%=". $realPercent.";".$critical.";".$warning.";0;100" # 
	# values in Kbytes ----> $status_str = "free=".$swapFree."Kb total=".$swapTotal."Kb";
} else {
	$check = "MEMORY";
	my $memRealTotalOID = '.1.3.6.1.4.1.2021.4.5.0';
	my $memRealFreeOID = '.1.3.6.1.4.1.2021.4.6.0';
	my $memRealCachedOID = '.1.3.6.1.4.1.2021.4.15.0';
	my $memRealBuffersOID = '.1.3.6.1.4.1.2021.4.14.0';
	my $memRealTotal = do_snmp($memRealTotalOID);
	if (0 == $memRealTotal) {
		print "SNMP problem - no value returned\n";
		exit STATUS_UNKNOWN;
	}
	my $memRealFree = do_snmp($memRealFreeOID);
	my $memRealCached = do_snmp($memRealCachedOID);
	my $memRealBuffers = do_snmp($memRealBuffersOID);
	my $memRealUsed = $memRealTotal - $memRealFree;
	$realPercent = (($memRealUsed - $memRealBuffers - $memRealCached )/ $memRealTotal) * 100;
	$realPercentFree = sprintf("%.2f", (100 - $realPercent)) ;
	$realPercent = sprintf("%.2f", $realPercent); 
	$status_str = "usage%=".$realPercent.";".$warning.";".$critical.";0;100" # 
	# valor de percentual free --> free%=". $realPercentFree.";". (100 - $critical).";". (100 - $warning) .";0;100"; 
	# valores em Kbytes ---------> free%=".$realPercentFree.";;;; free=".$memRealFree."Kb total=".$memRealTotal."KB cached=".$memRealCached."KB buffered=".$memRealBuffers."KB";
}


if ($realPercent >= $critical) {
	print "CRITICAL";
	$exit_code = 2; 
} elsif ($realPercent >= $warning) {
	print "WARNING";
	$exit_code = 1; 
} else {
	print "OK";
	$exit_code = 0; 
}

print " - $check"; print ": ".$realPercent." % used | ".$status_str."\n"; exit $exit_code ;

