#!/usr/bin/perl -w
#
# ============================== SUMMARY =====================================
#
# Program : check_vutlan.pl
# Version : 0.1
# Date    : Jul 09, 2018
# Author  : Vutlan s.r.o. - vutlan.com
# Summary : This is a nagios plugin to check SNMP sensors VTxxx Vutlan modules
# Licence : ???
#
# ===================== INFORMATION ABOUT THIS PLUGIN ========================
#
# =============================== SETUP NOTES ================================
#
# ============================= SETUP EXAMPLES ===============================
#
# =================================== TODO ===================================
#
# ========================== START OF PROGRAM CODE ============================

use strict;
#use warnings;
#use diagnostics;

use Net::SNMP;
use Getopt::Long;

use lib "/usr/lib64/nagios/plugins";
use utils qw(%ERRORS $TIMEOUT);
# uncomment two lines below and comment out two above lines if you do not have nagios' utils.pm
#my $TIMEOUT = 20;
#my %ERRORS=('OK'=>0,'WARNING'=>1,'CRITICAL'=>2,'UNKNOWN'=>3,'DEPENDENT'=>4);

my $Version='0.1';

my $o_host=     undef;          # hostname
my $o_community= undef;         # community
my $o_port=     161;            # SNMP port
my $o_help=     undef;          # help option
my $o_verb=     undef;          # verbose mode
my $o_version=  undef;          # version info option
my $o_timeout=  5;              # Default 5s Timeout
my $o_version2= undef;          # use snmp v2c
# SNMPv3 specific
my $o_login=    undef;          # Login for snmpv3
my $o_passwd=   undef;          # Pass for snmpv3
my $o_id=       undef;          # Element's ID


sub print_version { print "$0: $Version\n" };

sub print_usage {
	print "Usage: $0 [-v] -H <host> -C <snmp_community> [-2] | (-l login -x passwd) -i <ID> [-P <port>] [-t <timeout>] [-V]\n";
}

sub help {
	print "\nGeneral SNMP Table Attributes Monitor for Nagios version ",$Version,"\n";
	print " by William Leibzon - william(at)leibzon.org\n\n";
	print_usage();
	print <<EOD;
-v, --verbose
	print extra debugging information
-h, --help
	print this help message
-H, --hostname=HOST
	name or IP address of host to check
-C, --community=COMMUNITY NAME
	community name for the host's SNMP agent (implies v 1 protocol)
-P, --port=PORT
	SNMPD port (Default 161)
-2, --v2c 
        use SNMP v2 (instead of SNMP v1)
-t, --timeout=INTEGER
	timeout for SNMP in seconds (Default : 5)
-V, --version
	prints version number
-i, --id=INTEGER
        element's id
EOD
}

# Return true if arg is a number
sub isnum {
	my $num = shift;
	if ( $num =~ /^([-|+]?(\d+\.?\d*)|[-|+]?(^\.\d+))$/ ) { return 1 ;}
	return 0;
}

# For verbose output - don't use it right now
sub verb { my $t=shift; print $t,"\n" if defined($o_verb) ; }

# Get the alarm signal (just in case snmp timout screws up)
$SIG{'ALRM'} = sub {
     print ("ERROR: Alarm signal (Nagios time-out)\n");
     exit $ERRORS{"UNKNOWN"};
};

sub check_options {
    Getopt::Long::Configure ("bundling");
    GetOptions(
        'v'     => \$o_verb,            'verbose'       => \$o_verb,
        'V'     => \$o_version,         'version'       => \$o_version,
        'h'     => \$o_help,            'help'          => \$o_help,
        'H:s'   => \$o_host,            'hostname:s'    => \$o_host,
        'P:i'   => \$o_port,            'port:i'        => \$o_port,
        'C:s'   => \$o_community,       'community:s'   => \$o_community,
        'l:s'   => \$o_login,           'login:s'       => \$o_login,
        'p:s'   => \$o_passwd,          'passwd:s'      => \$o_passwd,
        't:i'   => \$o_timeout,         'timeout:i'     => \$o_timeout,
        '2'     => \$o_version2,        'v2c'           => \$o_version2,
        'i:i'   => \$o_id,              'id:i'          => \$o_id,
    );

    if (defined($o_version)) { print_version; exit $ERRORS{"UNKNOWN"}; }
    if (defined($o_help) ) { help(); exit $ERRORS{"UNKNOWN"}; }
    if (! defined($o_host) ) # check host
    { print "No host defined!\n";print_usage(); exit $ERRORS{"UNKNOWN"}; }
    # check snmp information
    if (!defined($o_community) && (!defined($o_login) || !defined($o_passwd)) )
    { print "Put snmp login info!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}; }
    # Check global timeout if something goes wrong
    if (defined($TIMEOUT)) {
        verb("Alarm at $TIMEOUT");
        alarm($TIMEOUT);
    } else {
        verb("no timeout defined : $o_timeout + 10");
        alarm ($o_timeout+10);
    }
    if (! defined($o_id) ) # check id
    { print "No ID defined!\n";print_usage(); exit $ERRORS{"UNKNOWN"}; }
}

########## MAIN #######

check_options();

# Parameters
my $oid_table = '1.3.6.1.4.1.39052.1.3.1'; # OID for request
my $oid_row_clas = $oid_table.'.5.'.$o_id;
my $oid_row_type = $oid_table.'.6.'.$o_id;
my $oid_row_name = $oid_table.'.7.'.$o_id;
my $oid_row_state = $oid_table.'.8.'.$o_id;
my $oid_row_value = $oid_table.'.9.'.$o_id;

my $statuscode='UNKNOWN'; # for errors and 'unknown','not connected' states

# SNMP Connection to the host
my ($session,$error);
if (defined($o_login) && defined($o_passwd)) {
  # SNMPv3 login
  verb("SNMPv3 login");
  ($session, $error) = Net::SNMP->session(
      -hostname         => $o_host,
      -version          => '3',
      -username         => $o_login,
      -authpassword     => $o_passwd,
      -authprotocol     => 'md5',
      -privpassword     => $o_passwd,
      -timeout          => $o_timeout
   );
} else {
   if (defined ($o_version2)) {
     # SNMPv2 Login
         ($session, $error) = Net::SNMP->session(
        -hostname  => $o_host,
        -version   => 2,
        -community => $o_community,
        -port      => $o_port,
        -timeout   => $o_timeout
     );
   } else {
    # SNMPV1 login
    ($session, $error) = Net::SNMP->session(
       -hostname  => $o_host,
       -community => $o_community,
       -port      => $o_port,
       -timeout   => $o_timeout
    );
  }
}

# Was the session created?
if (!defined($session)) {
    printf("ERROR: %s.\n",  $session->error());
    exit $ERRORS{"UNKNOWN"};
}



my $result = $session->get_request(
-varbindlist => [$oid_row_clas, $oid_row_type, $oid_row_state, $oid_row_name, $oid_row_value],
);

if (!defined($result)) {
   printf("ERROR: %s.\n",  $session->error());
   exit $ERRORS{"UNKNOWN"};
}

=pod
print "Class : $oid_row_name  = $result->{$oid_row_clas}\n";
print "Type  : $oid_row_value = $result->{$oid_row_type}\n";
print "Name  : $oid_row_name  = $result->{$oid_row_name}\n";
print "State : $oid_row_state = $result->{$oid_row_state}\n";
print "Value : $oid_row_value = $result->{$oid_row_value}\n";
=cut

my $clas=$result->{$oid_row_clas};
my $type=$result->{$oid_row_type};
my $name=$result->{$oid_row_name};
my $state=$result->{$oid_row_state};
my $value = $result->{$oid_row_value};

#print "$type $state $value\n";

if ($clas eq 'analog'){
    if($state eq 'normal'){
        $statuscode="OK";
    } elsif (($state eq 'warning')||($state eq 'low')||($state eq 'low warning')||($state eq 'high warning')){
        $statuscode="WARNING";
    } elsif (($state eq 'alarm')||($state eq 'low alarm')||($state eq 'high alarm')){
        $statuscode="CRITICAL";
    }
    
    print "$statuscode status - $name($o_id) = $state($value)|$name=$value;";
} 
elsif($clas eq 'discret'){
    if($state eq 'normal'){
        $statuscode="OK";
    } else {
        $statuscode="CRITICAL";
    }
    
    print "$statuscode status - $name($o_id) = $state($value)|$name=$value;";
}
elsif($clas eq 'switch'){
    $statuscode="OK";  
    print "$statuscode status - $name($o_id) = $state";
}
elsif($clas eq 'devirt'){
    if($state eq 'normal'){
        $statuscode="OK";
    } else {
        $statuscode="CRITICAL";
    }
    
    if($type eq 'ping'){
        $statuscode="OK";
        print "$statuscode status - $name($o_id) = $state($value)|$name=$value;";
    } else {
        $statuscode="CRITICAL";
        print "$statuscode status - $name($o_id) = $state";
    }
    
}
else {
    if($state eq 'normal'){
        $statuscode="OK";
    } else {
        $statuscode="CRITICAL";
    }
    
    print "$statuscode status - $name($o_id) = $state";
}

print "\n";

exit $ERRORS{$statuscode};
