#! /usr/bin/perl -w
################################################################################
# Copyright 2004-2013 MERETHIS
# Centreon is developped by : Julien Mathis and Romain Le Merlus under
# GPL Licence 2.0.
# 
# This program is free software; you can redistribute it and/or modify it under 
# the terms of the GNU General Public License as published by the Free Software 
# Foundation ; either version 2 of the License.
# 
# This program is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 
# PARTICULAR PURPOSE. See the GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License along with 
# this program; if not, see <http://www.gnu.org/licenses>.
# 
# Linking this program statically or dynamically with other modules is making a 
# combined work based on this program. Thus, the terms and conditions of the GNU 
# General Public License cover the whole combination.
# 
# As a special exception, the copyright holders of this program give MERETHIS 
# permission to link this program with independent modules to produce an executable, 
# regardless of the license terms of these independent modules, and to copy and 
# distribute the resulting executable under terms of MERETHIS choice, provided that 
# MERETHIS also meet, for each linked independent module, the terms  and conditions 
# of the license of that module. An independent module is a module which is not 
# derived from this program. If you modify this program, you may extend this 
# exception to your version of the program, but you are not obliged to do so. If you
# do not wish to do so, delete this exception statement from your version.
# 
# For more information : contact@centreon.com
# 
# SVN : $URL: http://svn.centreon.com/trunk/plugins-2.x/src/check_centreon_snmp_string $
# SVN : $Id: check_centreon_snmp_string 12130 2011-04-19 08:57:37Z jmathis $
#
####################################################################################
#
# Script init
#

use strict;
use Getopt::Long;

require "/DBA/nagios/nagios-plugins/1.latest/plugins/Centreon/SNMP/Utils.pm";

my $PROGNAME = "$0";

my %OPTION = ("host" => undef,
    "snmp-community" => "public", "snmp-version" => 1, "snmp-port" => 161,
    "snmp-auth-key" => undef, "snmp-auth-user" => undef, "snmp-auth-password" => undef, "snmp-auth-protocol" => "MD5",
    "snmp-priv-key" => undef, "snmp-priv-password" => undef, "snmp-priv-protocol" => "DES",
    "maxrepetitions" => undef, "snmptimeout" => undef,
    "64-bits" => undef,
    'help' => undef, 
    'output' => 'The value is %f');
my %ERRORS = ('OK' => 0, 'WARNING' => 1, 'CRITICAL' => 2, 'UNKNOWN' => 3);
my $prefix = "";

sub print_help ();
sub print_usage ();

Getopt::Long::Configure('bundling');
GetOptions
    (
    "H|hostname|host=s"                 => \$OPTION{'host'},
    "C|community=s"                     => \$OPTION{'snmp-community'},
    "v|snmp|snmp-version=s"             => \$OPTION{'snmp-version'},
    "P|snmpport|snmp-port=i"            => \$OPTION{'snmp-port'},
    "u|username=s"                      => \$OPTION{'snmp-auth-user'},
    "p|authpassword|password=s"         => \$OPTION{'snmp-auth-password'},
    "k|authkey=s"                       => \$OPTION{'snmp-auth-key'},
    "authprotocol=s"                    => \$OPTION{'snmp-auth-protocol'},
    "privpassword=s"                    => \$OPTION{'snmp-priv-password'},
    "privkey=s"                         => \$OPTION{'snmp-priv-key'},
    "privprotocol=s"                    => \$OPTION{'snmp-priv-protocol'},
    "maxrepetitions=s"                  => \$OPTION{'maxrepetitions'},
    "snmp-timeout=i"                    => \$OPTION{'snmptimeout'},
    "64-bits"                           => \$OPTION{'64-bits'},
    "h"         => \$OPTION{'help'},            "help"              => \$OPTION{'help'},
    "V"         => \$OPTION{'pluginversion'},   "version"           => \$OPTION{'pluginversion'},
    "W=s"       => \$OPTION{'warning_table'},   "warning_table=s"   => \$OPTION{'warning_table'}, 
    "T=s"       => \$OPTION{'critical_table'},  "critical_table=s"  => \$OPTION{'critical_table'}, 
    "O=s"       => \$OPTION{'ok_table'},        "ok_table=s"        => \$OPTION{'ok_table'}, 
    "o=s"       => \$OPTION{'oid'},             "oid=s"             => \$OPTION{'oid'},
    "debug"     => \$OPTION{'debug'}, 
    "f=s"       => \$OPTION{'output'},          "output=s"          => \$OPTION{'output'});

my $unit = undef;
my $output = undef;

# Table used when personnal threshold are set
my @critical_table = ();
my @warning_table = ();
my @ok_table = ();

if ($OPTION{'critical_table'}) {
    @critical_table = split(/\,/, $OPTION{'critical_table'});
}
if ($OPTION{'warning_table'}) {
    @warning_table = split(/\,/, $OPTION{'warning_table'});
}
if ($OPTION{'ok_table'}) {
    @ok_table = split(/\,/, $OPTION{'ok_table'});
}
if (defined($OPTION{'pluginversion'})) {
    print("$PROGNAME  0.1");
    exit $ERRORS{'UNKNOWN'};
}
if (defined($OPTION{'help'})) {
    print_help();
    exit $ERRORS{'UNKNOWN'};
}
if (!defined($OPTION{'oid'})) {
    print "Missing parameters -o (--oid')\n";
    exit $ERRORS{'UNKNOWN'};
}

# Store option values in simpler variables
if ($OPTION{'output'} eq "") {
   print "Output is not correctly set\n";
   exit $ERRORS{'UNKNOWN'};
}
#Output Verification
$output = $OPTION{'output'};

if (!($OPTION{'oid'} =~ /^[0-9\.]+$/)) {
    print "Wrong OID format\n";
    exit $ERRORS{'UNKNOWN'};
}

my ($session_params) = Centreon::SNMP::Utils::check_snmp_options($ERRORS{'UNKNOWN'}, \%OPTION);
my $session = Centreon::SNMP::Utils::connection($ERRORS{'UNKNOWN'}, $session_params);

# Get the value returned by OID
my $result = Centreon::SNMP::Utils::get_snmp_leef([$OPTION{'oid'}], $session, $ERRORS{'UNKNOWN'});
my $currentValue = $result->{$OPTION{'oid'}};

# Check if value returned is a number and then save it
if (!defined($currentValue) ||  $currentValue =~ /noSuch/){
    print "No instance on OID $OPTION{'oid'}\n";
    exit $ERRORS{'UNKNOWN'};
}

#===  Plugin return  ====
if (defined($currentValue)) {
    my $returnValue = $currentValue;
    my $status = "UNKNOWN";
    my $state= "unknownState";
    $returnValue = "warningvalue" if($OPTION{'debug'});


    #################################################################
    # If personnal thresholds are set for warning and / or critical #
    #################################################################
    if ($OPTION{'warning_table'} || $OPTION{'critical_table'} || $OPTION{'ok_table'}) {
        print "Mode personal threshold ON \n" if($OPTION{'debug'});
        if ($OPTION{'ok_table'}) {
            my $max_ok= scalar(@ok_table);
            my $i = 0;

            while ($i < $max_ok) {
                print "OK[$i]:  $ok_table[$i] / returnValue = $returnValue \n" if($OPTION{'debug'});
                if($ok_table[$i] eq $returnValue) {
                    $status = "OK";
                    $state = $ok_table[$i];
                }
                $i++;
            }
        }
        if ($OPTION{'warning_table'}) {
            my $max_warn= scalar(@warning_table);
            my $i = 0;

            while ($i < $max_warn) {
                print "Warning[$i]:  $warning_table[$i] / returnValue = $returnValue \n" if($OPTION{'debug'});
                if($warning_table[$i] eq $returnValue) {
                    $status = "WARNING";
                    $state = $warning_table[$i];
                }
                $i++;
            }
        }
        if ($OPTION{'critical_table'}) {
            my $i = 0;
            my $max_crit= scalar(@critical_table);
            while($i < $max_crit) {
                print "Critical[$i] = $critical_table[$i] / returnValue = $returnValue \n" if($OPTION{'debug'});
                if($critical_table[$i] eq $returnValue) {
                    $status = "CRITICAL";
                    $state = $critical_table[$i];
                }
                $i++;
            }
        }
        print(" Statut = $status \n ") if($OPTION{'debug'});
        printf($output."\n",$state,$returnValue);
        exit $ERRORS{$status};
    }
} else {
    print "CRITICAL Host unavailable\n";
    exit $ERRORS{'CRITICAL'};
}


sub print_usage () {
    print "Usage:";
    print "$PROGNAME\n";
    print "   -H (--hostname)   Hostname to query (required)\n";
    print "   -C (--community)  SNMP read community (defaults to public)\n";
    print "                     used with SNMP v1 and v2c\n";
    print "   -v (--snmp-version)  1 for SNMP v1 (default)\n";
    print "                        2 for SNMP v2c\n";
    print "                        3 for SNMP v3\n";
    print "   -P (--snmp-port)  SNMP port (default: 161)\n";
    print "   -k (--authkey)    snmp V3 key\n";
    print "   -u (--username)   snmp V3 username \n";
    print "   -p (--password)   snmp V3 password\n";
    print "   --authprotocol    protocol MD5/SHA  (v3)\n";
    print "   --privprotocol    encryption system (DES/AES)(v3) \n";
    print "   --privpassword    passphrase (v3) \n";
    print "   --64-bits         Use 64 bits OID\n";
    print "   --maxrepetitions  To use when you have the error: 'Message size exceeded buffer maxMsgSize'\n";
    print "                     Work only with SNMP v2c and v3 (Example: --maxrepetitions=1)\n";
    print "   --snmp-timeout    SNMP Timeout\n";
    print "   -o (--oid)                OID to check\n";
    print "   -W (--warning_table)      Personal warning threshold : -W warningstate... \n";
    print "   -T (--critical_table)     Personal critical threshold : -T criticalstate1,criticalstate2... \n";
    print "   -O (--ok_table)           Personal ok threshold : -O okstate1,okstate2... \n";
    print "   -f (--output)             Output format (ex : -f \"My metric's percentage value = %f %%\" \n";
    print "   -V (--version)            Plugin version\n";
    print "   -h (--help)               usage help\n";
}

sub print_help () {
    print "##############################################\n";
    print "#    Copyright (c) 2004-2013 Centreon        #\n";
    print "#    Bugs to http://forge.centreon.com/      #\n";
    print "##############################################\n";
    print_usage();
    print "\n";
}
