#!/usr/bin/perl -w
# nagios: +epn
# # =========================== PROGRAM LICENSE =================================
# # Copyright (c) 2008 - 2009
# # The Trustees of Columbia University in the City of New York
# # Academic Information Systems
##===============================================================================
=head1 DESCRIPTION
 This module is written to deal with issues where snmp represent the data as integer while the data should be in floating point.
 We added -f function parameter which takes only two possible values addition and multiplication.  Any subtraction can be written
 as addition and any division can be written as multiplication

=cut

BEGIN {
    use File::Basename;
    use Net::SNMP;
    use Getopt::Std;
    use Nagios::Plugin;
} # END BEGIN

my( $usagemsg ) = <<USAGE;
Usage: %s -H <hostname> [-C <community_string>] [-p <port>] [-P <protocol 1|2c|3>] [-o <oid>] [-u <unit_string>] [-w <warning>] [-c <critical>] 
USAGE
my( $blurb ) = <<BLURB;
This particular plugin has been created to deal with snmp data presentation with desired format.
BLURB
Nagios::Plugin->new(
    usage => "Usage: %s [ -v|--verbose ]  [-H <host>] "
    . "[ -C|--community_string=<community_string> ]",
);
my( $plugin ) = Nagios::Plugin->new(
    shortname   => 'check_snmp_math.pl',
    usage       => $usagemsg,
    version     => '1.0',
    blurb       => $blurb,
    plugin  => basename $0,
    timeout     => 20,
);
=head2 Plugin Metadata

Metadata is documented in L<Nagios::Plugin> and L<Nagios::Plugin::Getopt>.

=cut
$plugin->add_arg(
    spec       => 'hostname|H=s',
    help       => [
    "Hostname to query",
    "IP address to query",
    ],
    label      => [ 'HOSTNAME', 'IP' ],
    required   => 1,
);

$plugin->add_arg(
    spec       => 'community_string|C=s',
    help       => [
    "community string for snmp_querry",
    ],
    label      => [ 'COMMUNITY' ],
    required   => 1,
);
$plugin->add_arg(
    spec       => 'port|p=i',
    help       => [
    "port number for snmp_querry",
    ],
    label      => [ 'port'],
    default    => ['162'],
    required   => 0,
);
$plugin->add_arg(
    spec       => 'protocol|P=s',
    help       => [
    "snmp protocol",
    ],
    label      => [ 'protocol'],
    default    => '2c',
    required   => 0,
);
$plugin->add_arg(
    spec       => 'oid|o=s',
    help       => [
    "oid string",
    ],
    label      => [ 'oid'],
    required   => 1,
);
$plugin->add_arg(
    spec       => 'unit|u=s',
    help       => [
    "unit string",
    ],
    label      => [ 'unit'],
    required   => 0,
);
$plugin->add_arg(
    spec       => 'function|f=s',
    help       => [
    "function string",
    ],
    label      => [ 'mul', 'add'],
    required   => 0,
);
$plugin->add_arg(
    spec       => 'argument|a=s',
    help       => [
    "function string",
    ],
    label      => [ 'argument'],
    required   => 0,
);
$plugin->add_arg(
    spec => 'warning|w=s',
    help => [
    'Exit with WARNING status if less than BYTES bytes of disk are free',
    'Exit with WARNING status if less than PERCENT of disk is free',
    ],
    label => [ 'BYTES', 'PERCENT%' ],
    required => 0,
);
$plugin->add_arg(
    spec => 'critical|c=s',
    help => [
    'Exit with CRITICAL status if less than BYTES bytes of disk are free',
    'Exit with CRITICAL status if less than PERCENT of disk is free',
    ],
    label => [ 'BYTES', 'PERCENT%' ],
    required => 0,
);
$plugin->getopts;
my ( $opts ) =$plugin->opts;
my ( $ipaddress, $community, $port, $protocol, $oid, $unit, $function, $argument, $warning, $critical );

$ipaddress=$opts->get('hostname');
$community=$opts->get('community_string');
$port=$opts->get('port');
$protocol=$opts->get('protocol');
$oid=$opts->get('oid');
$unit=$opts->get('unit');
$function=$opts->get('function');
$argument=$opts->get('argument');
$warning=$opts->get('warning');
$critical=$opts->get('critical');

chomp $protocol;

$snmp_timeout=20;
my $status = 0;
my $snmpdata="";
my $returnstring = "";
my $perfdata = "";

# Create the SNMP session
my ($s, $e) = Net::SNMP->session(
    -community  =>  $community,
    -hostname   =>  $ipaddress,
    -version    => $protocol,
    #-port    =>  $port,
    -timeout    =>  $snmp_timeout,
);

main();

# Close the session
$s->close();

if ($status == 0){
    $plugin->nagios_exit (OK, "$returnstring|$perfdata");
}
elsif ($status == 1){
    $plugin->nagios_exit (WARNING, "$returnstring|$perfdata");
}
elsif ($status == 2){
    $plugin->nagios_exit (CRITICAL, "$returnstring|$perfdata");
}
else{
    $plugin->nagios_exit (UNKNOWN, "snmp is not responding");
}


####################################################################
# This is where we gather data via SNMP and return results         #
####################################################################

sub main {

    #######################################################

    if (!defined($s->get_request($oid))) {
        $returnstring = "SNMP agent not responding";
        $status = 1;
        return 1;
    }
    foreach ($s->var_bind_names()) {
        $snmpdata = $s->var_bind_list()->{$_};
        my $return_value = perform_calculation($snmpdata, $function, $argument);
        $returnstring=$return_value;
        $status=0;
    }

}

sub perform_calculation {
    my ($data, $action, $arg) =@_;
    my $return_data;

    if ($action eq 'mul') {
        $return_data=($data) * ($arg)
    }
    elsif ( $action eq 'add' ) {
        $return_data= ( ( $data ) + ( $arg ) );
    }
    else {
        print "only mul add  sub are valid function"
    } 
}
