#!/usr/bin/perl -l
################################################################################
#check_stonesoft.pl
################################################################################
# TICKET: 1095998
# AUTHOR: Josiane Tarasconi josiane.tarasconi@opservices.com.br
# ORGANIZATION: OpServices
# VERSION: 1.0
# CREATED: 14/09/2015 14:00:00
################################################################################

use strict;
use warnings;
use Net::SNMP;
use Data::Dumper;
use Getopt::Long;

#################
#GLOBAL VARIABLES
#################
our ($version,$hostname,$community,$username,$authkey,$authpasswd,$authproto,$privpasswd,$privproto,$snmpversion,$varname,$security,$privkey);
our ($warning,$critical, $help, $option);
###########
#CPU OID's
###########
our $cpu_load = ".1.3.6.1.4.1.1369.5.2.1.11.1.1.3.1";
our $cpu_users_not_okay = ".1.3.6.1.4.1.1369.5.2.1.11.1.1.4.1";
our $cpu_kernel = ".1.3.6.1.4.1.1369.5.2.1.11.1.1.5.1";
our $cpu_okay = ".1.3.6.1.4.1.1369.5.2.1.11.1.1.6.1";
our $cpu_idle = ".1.3.6.1.4.1.1369.5.2.1.11.1.1.7.1";
our $cpu_IO = ".1.3.6.1.4.1.1369.5.2.1.11.1.1.8.1";
our $cpu_hardware_interrupts = ".1.3.6.1.4.1.1369.5.2.1.11.1.1.9.1";
our $cpu_software_interrupts = ".1.3.6.1.4.1.1369.5.2.1.11.1.1.10.1";
our $cpu_load_node = ".1.3.6.1.4.1.1369.6.1.1.4.0";
#################
#Physical Memory
#################
our $phymem_available = "1.3.6.1.4.1.1369.5.2.1.11.2.4.0";
our $phymem_used = "1.3.6.1.4.1.1369.5.2.1.11.2.5.0";
our $phymem_free = "1.3.6.1.4.1.1369.5.2.1.11.2.6.0";
our $phymem_buffer = "1.3.6.1.4.1.1369.5.2.1.11.2.7.0";
our $phymem_cache = "1.3.6.1.4.1.1369.5.2.1.11.2.8.0";
####################
#Current Connections
####################
our $connections = "1.3.6.1.4.1.1369.5.2.1.4.0";
######################
#Packets Informations
######################
our $allow_packets = "1.3.6.1.4.1.1369.5.2.1.5.0";
our $discard_packets = "1.3.6.1.4.1.1369.5.2.1.6.0";
our $refused_packets = "1.3.6.1.4.1.1369.5.2.1.9.0";
our $accounted_packets = "1.3.6.1.4.1.1369.5.2.1.7.0";
######################
#Disk Space and Infos
######################
our $disk_name = ".1.3.6.1.4.1.1369.5.2.1.11.3.1.2";
our $disk_mount = ".1.3.6.1.4.1.1369.5.2.1.11.3.1.3";
our $disk_size = ".1.3.6.1.4.1.1369.5.2.1.11.3.1.4";
our $disk_used = ".1.3.6.1.4.1.1369.5.2.1.11.3.1.5";
our $disk_free = ".1.3.6.1.4.1.1369.5.2.1.11.3.1.6";
#############
#Swap memory
#############
our $swap_total = ".1.3.6.1.4.1.1369.5.2.1.11.2.1.0";
our $swap_used = ".1.3.6.1.4.1.1369.5.2.1.11.2.2.0";
our $swap_free = ".1.3.6.1.4.1.1369.5.2.1.11.2.3.0";
########
#Uptime
########
our $uptime = "1.3.6.1.2.1.1.3.0";

################################################################################
sub main {

  &getoption ();

  my $session = snmpsession ();
  my ($total, $used, $free, $load, $users, $kernel, $okay, $idle, $io, $hardware, $software);
  my ($node, $available , $buffer, $cache, $name, $mount, $time, $allow, $discard, $refused, $accounted);

  if ($option eq "swap") {

    $total = snmpget ($session, $swap_total);
    $used = snmpget ($session, $swap_used);
    $free = snmpget ($session, $swap_free);

    #converts B to MB
    $total = $total / 1024 / 1024;
    $used = $used / 1024 / 1024;
    $free = $free / 1024 /1024;

    #converts MB to percent
    my $percent = $used * 100;
       $percent = $percent / $total;

    #converts percent to MB
    my $mbwarn = $warning * $total;
       $mbwarn = $mbwarn / 100;
    my $mbcrit = $critical * $total;
       $mbcrit = $mbcrit / 100;

    my $code = metric ($percent, $warning, $critical);

    $used = sprintf ("%.3f", $used);
    $free = sprintf ("%.3f", $free);
    $mbwarn = sprintf ("%.3f", $mbwarn);
    $mbcrit = sprintf ("%.3f", $mbcrit);
    $percent = sprintf ("%.2f", $percent);
    $total = sprintf ("%.3f", $total);

    my $text = "Swap Memory Total: ".$total." "."Swap Memory Used: ".$used." "."Swap Memory Free: ".$free;
    my $perf = "swap_used=".$used."Mb;".$mbwarn.";".$mbcrit.";0;".$total." swap_perc=".$percent."%;".$warning.";".$critical.";0;100";

    print $text."|".$perf;

    exit($code);
  }

  if ($option eq "cpu")  {

    $load = snmpget ($session, $cpu_load);
    $users = snmpget ($session, $cpu_users_not_okay);
    $kernel = snmpget ($session, $cpu_kernel);
    $okay = snmpget ($session, $cpu_okay);
    $idle = snmpget ($session, $cpu_idle);
    $io = snmpget ($session, $cpu_IO);
    $hardware = snmpget ($session, $cpu_hardware_interrupts);
    $software = snmpget ($session, $cpu_software_interrupts);
    $node = snmpget ($session, $cpu_load_node);

    my $code = metric($load,$warning,$critical);

    my $text = "CPU Load: ".$load." "."CPU Users is not Okay: ".$users." "."CPU Kernel: ".$kernel." "."CPU Okay: ".$okay. "CPU Idle: ".$idle." "."CPU I/O: ".$io." "."CPU Hardware: ".$hardware." "."CPU Software: ".$software." "."CPU Load in Node: ".$node;

    my $perf = "cpu_load=".$load."%;".$warning.";".$critical.";0;100; cpu_idle=".$idle."; cpu_okay=".$okay."; cpu_users_not_okay=".$users."; cpu_kernel =".$kernel."; cpu_io=".$io."; cpu_hardware=".$hardware."; cpu_software=".$software."; cpu_load_node=".$node.";";

    print $text."|".$perf;

    exit($code);
  }

  if ($option eq "memory" ){
    $total = snmpget ($session, $phymem_available);
    $used = snmpget ($session, $phymem_used);
    $free = snmpget ($session, $phymem_free);
    $buffer = snmpget ($session, $phymem_buffer);
    $cache = snmpget ($session, $phymem_cache);

    #converts B to MB
    $total = $total / 1024 / 1024;
    $buffer = $buffer / 1024 / 1024;
    $used = $used / 1024 / 1024;
    $free = $free / 1024 /1024;
    $cache = $cache / 1024 /1024;

    #converts MB to percent
    my $percent = $used * 100;
       $percent = $percent / $total;

    #converts percent to MB
    my $mbwarn = $warning * $total;
       $mbwarn = $mbwarn / 100;

    my $mbcrit = $critical * $total;
       $mbcrit = $mbcrit / 100;

    my $code = metric($percent,$warning,$critical);

    $total = sprintf ("%.3f", $total);
    $buffer = sprintf ("%.3f", $buffer);
    $used = sprintf ("%.3f", $used);
    $free = sprintf ("%.3f", $free);
    $cache = sprintf ("%.3f", $cache);
    $mbwarn = sprintf ("%.2f", $mbwarn);
    $mbcrit = sprintf ("%.2f", $mbcrit);
    $percent = sprintf ("%.2f", $percent);

    my $text = "Physical Memory Total: ".$total."Mb "."Physical Memory Used: ".$used."Mb "."Physical Memory Free: ".$free."Mb "."Physical Memory Buffer: ".$buffer."Mb "."Physical Memory Cache: ".$cache."Mb";
    my $perf = "memory_used=".$used."Mb;".$mbwarn.";".$mbcrit.";0;".$total." memory_perc=".$percent."%;".$warning.";".$critical.";0;100;";

    print $text."|".$perf;

    exit($code);
  }

  if ($option eq "connections"){

    $available = snmpget ($session, $connections);

    my $code = metric ($available, $warning, $critical);

    my $text = "Current Connections: ".$available;
    my $perf = "current_connections=".$available.";".$warning.";".$critical.";0;";

    print $text."|".$perf;

    exit($code);
  }

  if ($option eq "packets"){

    $allow = snmpget ($session, $allow_packets);
    $discard = snmpget ($session, $discard_packets);
    $refused = snmpget ($session, $refused_packets);
    $accounted = snmpget ($session, $accounted_packets);

    my $code = metric($discard,$warning,$critical);

    my $text = "Allowed Packetes: ".$allow." "."Discard Packetes: ".$discard." "."Refused Packetes: ".$refused." "."Accounted Packetes: ".$accounted;
    my $perf = "discard_packets= ".$discard.";".$warning.";".$critical."; allowed_packets= ".$allow."; refused_packets= ".$refused."; acconted_packets= ".$accounted.";";

    print $text."|".$perf;

    exit($code)
  }

  if ($option eq "disk"){
    if(!defined$varname){
      print "The device name doesn't exists";
      exit 3;
    }

    my $index = snmpgettable ($session, $disk_mount);
    $name = snmpget ($session, $disk_name.$index);
    $mount = snmpget ($session, $disk_mount.$index);
    $total = snmpget ($session, $disk_size.$index);
    $used = snmpget ($session, $disk_used.$index);
    $free = snmpget ($session, $disk_free.$index);

    #converts B to MB
    $total /= 1024;
    $used /= 1024;
    $free /= 1024;

    #converts MB to percent
    my $percent = $used * 100;
       $percent = $percent / $total;

    #converts percent to MB
    my $mbwarn = $warning * $total;
       $mbwarn = $mbwarn / 100;

    my $mbcrit = $critical * $total;
       $mbcrit = $mbcrit / 100;

    my $code = metric($percent,$warning,$critical);

    $total = sprintf ("%.3f", $total);
    $used = sprintf ("%.3f", $used);
    $free = sprintf ("%.3f", $free);
    $mbwarn = sprintf ("%.2f", $mbwarn);
    $mbcrit = sprintf ("%.2f", $mbcrit);
    $percent = sprintf ("%.2f", $percent);

    my $text = "Device: ".$name." "."Disk Mount: ".$mount." "."Disk Space Size: ".$total." "."Disk Space Used: ".$used." "."Disk Space Free: ".$free;
    my $perf = "disk_used=".$used."Mb;".$mbwarn.";".$mbcrit.";0;".$total." disk_perc=".$percent."%;".$warning.";".$critical.";0;100;";

    print $text."|".$perf;

    exit($code);
  }

  if ($option eq "uptime"){

    $time = snmpget($session,$uptime);

    print "Uptime: ".$time;
  }
}
#-----------------------------------------------------------------------------------------------------
sub getoption {

  Getopt::Long::Configure('bundling');
  GetOptions(
    "version|V=s" => \$version,
    "hostname|H=s" => \$hostname,
    "community|C=s" => \$community,
    "snmpversion|P=s" => \$snmpversion,
    "securityversion|l=s" => \$security,
    "username|u=s" => \$username,
    "authpassword|A=s" => \$authpasswd,
    "authprotocol|a=s" => \$authproto,
    "privproto|x=s" => \$privproto,
    "privpassword|X=s" => \$privpasswd,
    "help|h" => \$help,
    "warning|w=s" => \$warning,
    "critical|c=s" => \$critical,
    "mode|m=s" => \$option,
    "name|n=s" => \$varname
  );

  if (!$hostname){
    printUsage();
    exit(1);
  }

  if (($snmpversion eq "1") or ($snmpversion eq "2c")) {
    if (!defined$community) {
	     printUsage();
       exit(1);
  	}
  }
  if ($help){
    printUsage();
    exit(1);
  }
}
#----------------------------------------------------------------------------------------------------
sub snmpsession {

  my ($session, $error) = (undef, undef);

	if (($snmpversion eq "1") or ($snmpversion eq "2c")) {

    ($session, $error) = Net::SNMP->session(
      -hostname => $hostname,
      -version  => $snmpversion,
	    -community => $community
		);
  } elsif ($snmpversion eq "3") {

    if($security eq "authNoPriv"){

		    ($session, $error) = Net::SNMP->session(
          -hostname     => $hostname,
          -version      => $snmpversion,
          -username     => $username,
          -authprotocol => $authproto,
          -authpassword => $authpasswd
  		  );
    }
    if ($security eq "authPriv"){

       ($session, $error) = Net::SNMP->session(
          -hostname     => $hostname,
          -version      => $snmpversion,
          -username     => $username,
          -privprotocol => $privproto,
          -privpassword => $privpasswd,
          -authprotocol => $authproto,
          -authpassword => $authpasswd
      );
    }
	} else {
    print "It's not possible open SNMP connection";
    }

	if ($error) {
		print "ERROR: ".$error;
		exit(2);
	}
	return $session;
}

#-------------------------------------------------------------------------------------------------
sub snmpget {

  my $session = shift;
	my $oid = shift;

	my $ret = $session->get_request($oid);
     $ret = $ret->{$oid};

	if (!defined$ret) {
		print "Unable to check";
		exit(3);
	}
	return $ret;
}

#----------------------------------------------------------------------------------------------------
sub snmpgettable {

  my $session = shift;
	my $oid = shift;
	my $index;

  my $ret = $session->get_table(
      -baseoid => $oid,
      );

	if (!defined$ret) {
		print "Unable to check";
		exit(3);
	}

  while (my ($key, $value) = each(%$ret)) {
    $key =~ s/$oid//g;

	  if($value eq $varname){
      $index = $key;
	  }
	}

  if (!defined$index) {
    print "The device name doesn't exists";
		exit(3);
	}

	return $index;
}
#----------------------------------------------------------------------------------------------------
sub metric {

  my $value = shift;
  my $warn = shift;
  my $crit = shift;

	if ($value >= $critical) {
		return 2;
	}
  if ($value >= $warning) {
		return 1;
	} else {
		return 0;
	}
}
#------------------------------------------------------------------------------------------------------
sub printUsage {
   print <<EOB
Usage: check_stonesoft.pl [OPTION]...

Options:
-v, --version
    Show Plugin Version
-h, --help
-v, --verbose
-H, --host
-C, --community
-P, --snmpversion=[1|2c|3]
    SNMP protocol version
-S, --securityversion=[authNoPriv|noAuthNoPriv|authPriv]
    SNMP security level
-U, --username
    SNMPv3 Version
-A, --authpassword
    SNMPv3 Version
-a, --authproto=[MD5|SHA]
    SNMPv3 Version
-w, --warning
-c, --critical
-m, --mode
    'swap' for Swap Memory informations,
        Show the following informations: Total, Used and Free in MB.
        The parameters are in percent and applies to "Used" information.
    'cpu' for Cpu Informations,
        Show the following informatios: Load, Users is not Okay, Kernel, Okay, Idle, I/O, Hardware, Software and Load in Node.
        The parameters applies to "Load" information.
    'memory' for Physical Memory informations,
        Show the following informations: Total, Used, Free, Buffer and Cache in MB.
        The parameters are in percent and applies to "Used" information.
    'connections' for show Current Connections,
        Show the following information: Current Connections.
        The parameters are the quantity of connections.
    'packets' for show Allowed, Discarded, Refused and Accounted Packets,
        Show the following informatios: Allowed, Discard, Refused and Accounted.
        The parameters are in quantity of packets and applies to Discad Packets.
    'disk' for Disk informations,
        For use that needs specify de Device name using the parameter -n.
        Show de following informations: Device Name, Size, Used, Free. If have one or more disks, need inform the disk name.
        The parameters are in percent and applies to "Used" information.
    'uptime' for Uptime.
        Show the Uptime information.
-n, --name
    For Disk Name.

Usage:
- If it is a SNMP Version 1 or 2c:
check_stonesoft.pl -H <ip_address> [-P 1|2c] [-C community] [-m Option] [-w warn_range] [-c crit_range]
- If it is a SNMP Version 3 and authNoPriv:
check_stonesoft.pl -H <ip_address> [-P 3] [-S authNoPriv] [-m Option] [-U username] [-a MD5|SHA] [-A authpassword] [-m Option][-w warn_range] [-c crit_range]
- If it is a SNMP Version 3 and authPriv:
check_stonesoft.pl -H <ip_address> [-P 3] [-S authPriv] [-m Option] [-U username] [-a MD5|SHA] [-A authpassword] [-p privpassword] [-K privkey] [-m Option][-w warn_range] [-c crit_range]

EOB
}
&main;

