#!C:\Dwimperl\perl\bin 
#
# Simple SNMP memory check - version 1.0
#
# inspired by script written by  Corey Henderson
#
# it is streamlined with Nagios::Plugins it can be run from any platform 
# it was build to be run from a windows server using nsclient and nrpe 
# it used Nagios::Plugin to make it more portable.
#

use strict;
use warnings;
use Net::SNMP;
use Nagios::Plugin;
use nagios::Plugin::Getopt;
use Math::Round;


my $np;

$np=Nagios::Plugin->new(
	usage 		=> "Usage: %s -H <host> -C <community> -w <warn> -c <crit>",
	shortname	=> "SNMP Memory",
	timeout		=> 5,
	blurb 		=> "this plugin calculates the real used memory in linux which includes the cache and buffers",
	extra 		=> "
	Examples: 
	
	check_snmp_mem.pl -H 127.0.0.1 -C public -w 90 -c 95
	
	
	"
);

# plugin arguments
$np->add_arg(
	spec		=> "host|H=s",
	help		=> "ip address or hostname of device",
	required	=> 1,
);

$np->add_arg(
	spec		=> "community|C=s",
	help		=> "snmp community string",
	required	=> 1,
);

$np->add_arg(
	spec		=> "warning|w=i",
	help		=> "usage in percent, when a WARNING is returned",
	required	=> 1,
);

$np->add_arg(
	spec		=> "critical|c=i",
	help		=> " mem usage in percent, when a CRITICAL is returned",
	required	=> 1,
);

$np->getopts;

# perform sanity checking on command line options
if ( (defined $np->opts->warning) && ($np->opts->warning < 0 || $np->opts->warning > 100) )  {
    $np->nagios_die( " invalid number supplied for the -w option: enter a value between 0 and 100 " );
}

if ( (defined $np->opts->warning) && ($np->opts->critical < 0 || $np->opts->critical > 100) )  {
    $np->nagios_die( " invalid number supplied for the -c option: enter a value between 0 and 100 " );
}

if ( (defined $np->opts->warning) && ( $np->opts->warning > $np->opts->critical) ) {
	$np->nagios_die( " invalid number supplied for the -w option: warning threshold should be smaller than critical threshold " );
}

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 ($session, $error) = Net::SNMP->session(
     -hostname  => $np->opts->host,
     -community => $np->opts->community,
   );

   if (!defined $session) {
	  $np->nagios_exit (WARNING, $error)
      #printf "ERROR: %s.\n", $error;
   }

   my $memRealFree = $session->get_request(-varbindlist => [ $memRealFreeOID],);
   my $memRealTotal = $session->get_request(-varbindlist => [ $memRealTotalOID],);
   my $memRealCached = $session->get_request(-varbindlist => [ $memRealCachedOID],);
   my $memRealBuffers = $session->get_request(-varbindlist => [ $memRealBuffersOID],);

$session->close();

   my $buffers = $memRealBuffers->{$memRealBuffersOID}; 
   my $cache = $memRealCached->{$memRealCachedOID};
   my $total=  $memRealTotal->{$memRealTotalOID};
   my $free = $memRealFree->{$memRealFreeOID};
   
   my $memRealUsed = $total - $free;
   my $memRealUsedMB = round ($memRealUsed / 1024);
   my $totalMB = round($total / 1024);
  
   
  my $realTPercent = (($memRealUsed - $buffers - $cache)/ $total) * 100;
  my $realPercent = sprintf "%.2f", $realTPercent;
  
  
 
$np->add_perfdata(
	label	=>	"Free",
	value	=>	$free,
	uom		=>	"KB"
);

$np->add_perfdata(
	label	=>	"Total",
	value	=>	$total,
	uom		=>	"KB"
);

$np->add_perfdata(
	label	=>	"Cached",
	value	=>	$cache,
	uom		=>	"KB"
);

$np->add_perfdata(
	label	=>	"Buffered",
	value	=>	$buffers,
	uom		=>	"KB"
);


 ##############################################################################
# check the result against the defined warning and critical thresholds,
# output the result and exit
$np->nagios_exit( 
	 return_code => $np->check_threshold($realPercent), 
	 message => " used: $realPercent% with $memRealUsedMB MB of $totalMB MB free" 
);

