#! /usr/bin/perl -w
################################################################################
# Copyright 2004-2011 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_traffic $
# SVN : $Id: check_centreon_snmp_traffic 12719 2011-11-17 10:39:40Z mbersoult $
#


####################################################################################
#
# CRT INFORMATIQUE
#
# Les modifications permettent la prise en compte des interfaces ADSL (Asymetrique) 
#


####################################################################################
#
# Script init
#

use strict;
use Net::SNMP qw(:snmp oid_lex_sort);
use FindBin;
use lib "$FindBin::Bin";
use lib "/usr/local/nagios/libexec";
use utils qw($TIMEOUT %ERRORS &print_revision &support);
if (eval "require centreon" ) {
    use centreon qw(get_parameters);
    use vars qw(%centreon);
    %centreon=get_parameters();
} else {
	print "Unable to load centreon perl module\n";
    exit $ERRORS{'UNKNOWN'};
}
use vars qw($PROGNAME);
use Getopt::Long;
use vars qw($opt_V $opt_h $opt_P $opt_64bits $opt_v $opt_C $opt_b $opt_k $opt_u $opt_p $opt_H $opt_D $opt_i $opt_n $opt_w $opt_c $opt_ew $opt_ec $opt_d $opt_dl $opt_s $opt_T $opt_a $opt_r $opt_S $opt_t $opt_vrf $opt_invert);

# Plugin var init

my($proc, $proc_run, @test, $row, @laste_values, $last_check_time, $last_in_bits, $last_out_bits, $last_error_in_bits, $last_error_out_bits, @last_values, $update_time, $db_file, $in_traffic, $out_traffic, $in_usage, $out_usage, $last_status, $last_status_change);

## CRT Informatique : DSL Patch
my($adsl, $OID_ADSL, $adslSpeed, $adslfactor);
$OID_ADSL="1.3.6.1.2.1.10.94.1.1.4.1.2.";

$PROGNAME = "$0";
sub print_help ();
sub print_usage ();

Getopt::Long::Configure('bundling');
GetOptions
    ("h"   => \$opt_h, "help"         => \$opt_h,
     "u=s"   => \$opt_u, "username=s" => \$opt_u,
     "p=s"   => \$opt_p, "password=s" => \$opt_p,
     "P=s"   => \$opt_P, "--snmp-port=s" => \$opt_P,
     "k=s"   => \$opt_k, "key=s"      => \$opt_k,
     "s"   => \$opt_s, "show"         => \$opt_s,
     "V"   => \$opt_V, "version"      => \$opt_V,
     "i=s" => \$opt_i, "interface=s"  => \$opt_i,
     "64-bits" => \$opt_64bits,
     "n"   => \$opt_n, "name"         => \$opt_n,
     "v=s" => \$opt_v, "snmp=s"       => \$opt_v,
     "C=s" => \$opt_C, "community=s"  => \$opt_C,
     "b=s" => \$opt_b, "bps=s"        => \$opt_b,
     "w=s" => \$opt_w, "warning=s"    => \$opt_w,
     "c=s" => \$opt_c, "critical=s"   => \$opt_c,
     "d=s" => \$opt_d, "duration=s"   => \$opt_d,
     "e=s" => \$opt_dl, "durationlimit=s"   => \$opt_dl,
     "t=s" => \$opt_t, "time=s" => \$opt_t,
     "invert" => \$opt_invert,
     "errorw=s"    => \$opt_ew,
     "errorc=s"   => \$opt_ec,
     "T=s" => \$opt_T, "r"			  => \$opt_r,
     "z=s" => \$opt_vrf, "vrf=s"      => \$opt_vrf,
     "S" => \$opt_S,
     "a=s" => \$opt_a, "cache=s"	  => \$opt_a,
     "H=s" => \$opt_H, "hostname=s"   => \$opt_H);

if ($opt_V) {
    print_revision($PROGNAME,'$Revision: 1.2 $');
  	exit $ERRORS{'OK'};
}

if ($opt_h) {
    print_help();
    exit $ERRORS{'OK'};
	Getopt::Long::Configure('bundling');
}

##################################################
#####      Verify Options
##

if (!$opt_H) {
	print_usage();
	exit $ERRORS{'OK'};
}
($opt_v) || ($opt_v = shift) || ($opt_v = "2");
my $snmp = $1 if ($opt_v =~ /(\d)/);

if ($snmp eq "3") {
    if (!$opt_u) {
        print "Option -u (--username) is required for snmpV3\n";
        exit $ERRORS{'OK'};
    }
    if (!$opt_p && !$opt_k) {
        print "Option -k (--key) or -p (--password) is required for snmpV3\n";
        exit $ERRORS{'OK'};
    }elsif ($opt_p && $opt_k) {
        print "Only option -k (--key) or -p (--password) is needed for snmpV3\n";
        exit $ERRORS{'OK'};
    }
}

if ($opt_n && !$opt_i) {
    print "Option -n (--name) need option -i (--interface)\n";
    exit $ERRORS{'UNKNOWN'};
}

if (!$opt_C) {
    $opt_C = "public";
}

if (!$opt_vrf) {
    $opt_vrf = "";
} else {
    $opt_vrf = "_".$opt_vrf;
}

if (!$opt_i) {
    $opt_i = 2;
}

if (!$opt_ew) {
    $opt_ew = 0;
}

if (!$opt_ec) {
    $opt_ec = 0;
}

if (!$opt_dl) {
    $opt_dl = -1;
}

$opt_a = 3 if (!$opt_a);

if (!$opt_b) {
    $opt_b = 95;
}
if (!defined($opt_P)) {
	$opt_P = 161;
}
if ($opt_b =~ /([0-9]+)/) {
    my $bps = $1;
}
my $critical = 95;
if ($opt_c && $opt_c =~ /[0-9]+/) {
    $critical = $opt_c;
}
my $warning = 80;
if ($opt_w && $opt_w =~ /[0-9]+/) {
    $warning = $opt_w;
}
my $interface = 0;
if ($opt_i =~ /([0-9]+)/ && !$opt_n){
    $interface = $1;
} elsif (!$opt_n) {
    print "Unknown -i number expected... or it doesn't exist, try another interface - number\n";
    exit $ERRORS{'UNKNOWN'};
}

if ($critical < $warning){
    print "(--crit) must be superior to (--warn)";
    print_usage();
    exit $ERRORS{'OK'};
}
if ($opt_64bits && $snmp !~ /2/) {
        print "Error : Usage : SNMP v2 is required with option --64-bits\n";
        exit $ERRORS{'UNKNOWN'};
}
if (defined ($opt_64bits)) {
      if (eval "require bigint") {
        use bigint;
      } else  { print "ERROR : Need bigint module for 64 bit counters\n"; exit $ERRORS{"UNKNOWN"}}
}

#################################################
#####            Plugin snmp requests
##
my $OID_DESC =$centreon{MIB2}{IF_DESC};
my $OID_OPERSTATUS =$centreon{MIB2}{IF_OPERSTATUS};
my $OID_ADMINSTATUS =$centreon{MIB2}{IF_ADMINSTATUS};
my @operstatus = ("up","down","testing", "unknown", "dormant", "notPresent", "lowerLayerDown");
my @adminstatus = ("up","down","testing");

# create a SNMP session
my ($session, $error);
if ($snmp eq "1" || $snmp =~ /2/) {
	($session, $error) = Net::SNMP->session(-hostname => $opt_H, -community => $opt_C, -version => $snmp, -port => $opt_P);
	if (!defined($session)) {
	    print("UNKNOWN: SNMP Session : $error\n");
	    exit $ERRORS{'UNKNOWN'};
	}
} elsif ($opt_k) {
    ($session, $error) = Net::SNMP->session(-hostname => $opt_H, -version => $snmp, -username => $opt_u, -authkey => $opt_k, -port => $opt_P);
	if (!defined($session)) {
	    print("UNKNOWN: SNMP Session : $error\n");
	    exit $ERRORS{'UNKNOWN'};
	}
} elsif ($opt_p) {
    ($session, $error) = Net::SNMP->session(-hostname => $opt_H, -version => $snmp,  -username => $opt_u, -authpassword => $opt_p, -port => $opt_P);
	if (!defined($session)) {
	    print("UNKNOWN: SNMP Session : $error\n");
	    exit $ERRORS{'UNKNOWN'};
	}
}
$session->translate(Net::SNMP->TRANSLATE_NONE) if (defined($session));


my $cacheFile = "/var/lib/centreon/centplugins/traffic_cache_".$opt_H.$opt_vrf;
my $result;
my $mustCreateFile = 0;
#my $row;
my $countLine;

#
# Cache File exists, lets read it
#
if (-e $cacheFile) {
    open(FILE,"<".$cacheFile);
    $countLine = 0;
    while ($row = <FILE>){
        if (!$countLine) {
            my $deltaTime = time() -  $row;
            if ($deltaTime > ($opt_a * 3600)) {
                $mustCreateFile = 1;
            }
        }
        $countLine++;
    }
    close(FILE);
}
else {
    $mustCreateFile = 1;
}

if ($mustCreateFile) {
    $result = $session->get_table(Baseoid => $OID_DESC);
    if (defined($result)) {
	    unless (open(FILE,">".$cacheFile)){
	        print "Check mod for temporary file : ".$cacheFile."...\n";
	        exit $ERRORS{"UNKNOWN"};
	    }
	    my $currentTime = time();
	    print FILE $currentTime."\n";
	    foreach my $key (oid_lex_sort(keys %$result)) {
		   	my @oid_list = split (/\./,$key);
		   	my $interfaceIndex = pop (@oid_list);
	        print FILE $interfaceIndex.";".$result->{$key}."\n";
	    }
	    close(FILE);
    } else {
        if (!$result) {
           printf("ERROR: Cannot get SNMP info : %s", $session->error);
           exit $ERRORS{'UNKNOWN'};
        }
    }
}

################################################################
# Getting interface using its name instead of its oid index
my $adslSearch = $opt_i;
if(index($opt_i, '.') > -1){
	$adslSearch = substr $opt_i, 0, index($opt_i, '.');
}

if ($opt_n) {
	if ($opt_r){
	    if (!-e $cacheFile) {
            printf("ERROR: Could not open " . $cacheFile);        
            exit $ERRORS{'UNKNOWN'};
        }
        
        open(FILE,"<".$cacheFile);
        $countLine = 0;
        while ($row = <FILE>){
            if ($countLine) {
                my @resLine = split(/\;/, $row);                
                if (!$interface && $resLine[1] =~ m/$opt_i/ && $resLine[1] !~ m/atm subif/) {    	   	 	
                    $interface = $resLine[0];
                }
                ## CRT Informatique : DSL Patch  	
                if (!$adsl && $resLine[1] =~ m/$adslSearch-adsl/) {    	 	
                    $adsl = $resLine[0];
                    $adslfactor = 1;
                }
                if (!$adsl && $resLine[1] =~ m/$adslSearch-interleave/) {
                    $adsl = $resLine[0];
                    $adslfactor = 1000;
                }
            }
            $countLine++;
        }
        close(FILE);
	} else {		
		if (!-e $cacheFile) {
        	printf("ERROR: Could not open " . $cacheFile);
        	exit $ERRORS{'UNKNOWN'};
        }
        
        open(FILE,"<".$cacheFile);
        $countLine = 0;
        while ($row = <FILE>) {
            if ($countLine) {
                my @resLine = split(/\;/, $row);            
                $resLine[1] =~ s/\x00//g;
                $resLine[1] =~ s/\n//g;
                $resLine[1] =~ s/\s*$//g;
                if (!$interface && $resLine[1] eq $opt_i) {
                    $interface = $resLine[0];
                }
                ## CRT Informatique : DSL Patch
                if (!$adsl && $resLine[1] eq "$adslSearch-adsl") {
                    $adsl = $resLine[0];
                    $adslfactor = 1;
                }
                if (!$adsl && $resLine[1] =~ m/$adslSearch-interleave/) {
                    $adsl = $resLine[0];
                    $adslfactor = 1000;
                }
            }
            $countLine++;
        }
        close(FILE);
	}
}

if ($interface eq 0) {
    print("ERROR: Interface not found");
    exit $ERRORS{'UNKNOWN'};
}

my ($OID_IN, $OID_OUT, $OID_SPEED, $OID_SPEED_BASE, $OID_MYDESC, $OID_IN_ERROR, $OID_OUT_ERROR);
if ($opt_64bits) {
    $OID_IN =$centreon{MIB2}{IF_IN_OCTET_64_BITS}.".".$interface;
	$OID_OUT = $centreon{MIB2}{IF_OUT_OCTET_64_BITS}.".".$interface;
	$OID_SPEED = $centreon{MIB2}{IF_SPEED_64_BITS}.".".$interface;
	$OID_SPEED_BASE = $centreon{MIB2}{IF_SPEED_64_BITS};
} else {
    $OID_IN =$centreon{MIB2}{IF_IN_OCTET}.".".$interface;
	$OID_OUT = $centreon{MIB2}{IF_OUT_OCTET}.".".$interface;
	$OID_SPEED = $centreon{MIB2}{IF_SPEED}.".".$interface;
	$OID_SPEED_BASE = $centreon{MIB2}{IF_SPEED};
}
$OID_MYDESC = ".1.3.6.1.2.1.31.1.1.1.18.".$interface;
$OID_IN_ERROR = $centreon{MIB2}{IF_IN_ERROR}.".".$interface;
$OID_OUT_ERROR = $centreon{MIB2}{IF_OUT_ERROR}.".".$interface;

## CRT Informatique : DSL Patch
if($adsl){
	$OID_ADSL .= $adsl;
}

#######   Get desctiption table
if ($opt_s) {
    if (!-e $cacheFile) {
        $result = $session->get_table(Baseoid => $OID_DESC);
        if (defined($result)) {
            unless (open(FILE,">".$cacheFile)){
                print "Check mod for temporary file : ".$cacheFile."...\n";
                exit $ERRORS{"UNKNOWN"};
            }
            my $currentTime = time();
            print FILE $currentTime."\n";
            foreach my $key (oid_lex_sort(keys %$result)) {
                my @oid_list = split (/\./,$key);
                my $interfaceIndex = pop (@oid_list);
                print FILE $interfaceIndex.";".$result->{$key}."\n";
            }
            close(FILE);
        }
    }
    
    if (!-e $cacheFile) {
        printf("ERROR: Could not open " . $cacheFile);        
        exit $ERRORS{'UNKNOWN'};
    }
    open(FILE,"<".$cacheFile);
    $countLine = 0;
    while ($row = <FILE>){
        if ($countLine) {
            my @resLine = split(/\;/, $row);            
            my $index = $resLine[0];
            my $interface_status = $session->get_request(-varbindlist => [$OID_OPERSTATUS.".".$index]);
            $resLine[1] =~ s/\x00//g;
            $resLine[1] =~ s/\n//g;
            print "Interface ". $index . " :: " . $resLine[1] . " :: ".$operstatus[$interface_status->{$OID_OPERSTATUS.".".$index} - 1];
			if ($opt_S) {
				my $link_speed = $session->get_request(-varbindlist => [$OID_SPEED_BASE.".".$index]);
				if (!defined($link_speed)) {
					printf("ERROR: Interface Speed Request : %s", $session->error);
					exit $ERRORS{'UNKNOWN'};
				}
				my $unit = "bit/s";
				my $speed = $link_speed->{$OID_SPEED_BASE.".".$index};
				print " :: speed ".$speed." ".$unit."\n";
			} else {
				print "\n";
			}
        }
        $countLine++;
    }
    close(FILE);
	exit $ERRORS{'OK'};
}

#######  Get general informations
my $interface_status = $session->get_request(-varbindlist => [$OID_MYDESC,$OID_OPERSTATUS.".".$interface,$OID_ADMINSTATUS.".".$interface]);
if (!$interface_status) {
    printf("ERROR: Interface Status Request : %s", $session->error);
	exit $ERRORS{'UNKNOWN'};
}
my $mydesc = $interface_status->{$OID_MYDESC};
if ($adminstatus[$interface_status->{$OID_ADMINSTATUS.".".$interface} - 1] eq "down") {
    if($mydesc){
        print $mydesc . " - ";
    }
    print "Interface administratively down\n";
    exit $ERRORS{'OK'};
}
if ($operstatus[$interface_status->{$OID_OPERSTATUS.".".$interface} - 1] ne "up") {
	if($mydesc){ 
		print $mydesc . " - ";
	}
	if(!$opt_invert) {
    		print "Error : interface is not ready - status : ".$operstatus[$interface_status->{$OID_OPERSTATUS.".".$interface} - 1]."\n";
		exit $ERRORS{'CRITICAL'};
	}else{
		print "Inverted plugin ! Interface is normaly not ready - status : ".$operstatus[$interface_status->{$OID_OPERSTATUS.".".$interface} - 1]."\n";
		exit $ERRORS{'OK'};
	}
}


#######  Get counters
$result = $session->get_request(-varbindlist => [$OID_IN,$OID_OUT,$OID_IN_ERROR,$OID_OUT_ERROR,$OID_SPEED]);
if (!defined($result)) {
    printf("ERROR: IN Bits :  %s", $session->error);
    if ($opt_n) { print " - You must specify interface name when option -n is used";}
    print ".\n";
    $session->close;
    exit $ERRORS{'UNKNOWN'};
}
my $in_bits =  $result->{$OID_IN} * 8;
my $out_bits = $result->{$OID_OUT} * 8;
my $error_in_bits =  $result->{$OID_IN_ERROR} * 8;
my $error_out_bits = $result->{$OID_OUT_ERROR} * 8;
my $speed_card = $result->{$OID_SPEED};

if (defined($opt_T)){
	$speed_card = $opt_T * 1000000;
} else {
	if (!$speed_card && !defined($opt_T)) {
	    print "Error : Card speed is null, check command options\n";
	    exit $ERRORS{'UNKNOWN'};
	}
}

## CRT Informatique : DSL Patch
#######  Get ADSL SPEED of interface
if($adsl && !defined($opt_T)){
	$result = $session->get_request(-varbindlist => [$OID_ADSL]);
	if (!$result) {
	    printf("ERROR: Interface Speed : %s", $session->error);
	    if ($opt_n) { print " - You must specify interface name when option -n is used";}
	    print ".\n";
	    $session->close;
	    exit $ERRORS{'UNKNOWN'};
	}
	$adslSpeed = $result->{$OID_ADSL}*$adslfactor;
	if (!$adslSpeed) {
	    $adslSpeed=$speed_card;
	}
}else{
	$adslSpeed=$speed_card;
}

if ($opt_64bits) {
	$adslSpeed = $adslSpeed*1000000;
	$speed_card = $speed_card*1000000;
}

#############################################
#####          Plugin return code
##

$last_status_change = 0;
$last_status = "UNKNOWN";
$last_in_bits = 0;
$last_out_bits  = 0;
$last_error_in_bits = 0;
$last_error_out_bits  = 0;

my $flg_created = 0;
my $pathCacheFile = "/var/lib/centreon/centplugins/traffic_if".$interface."_".$opt_H.$opt_vrf;

if (-e $pathCacheFile) {
    open(FILE,"<".$pathCacheFile);
    while($row = <FILE>){
		@last_values = split(":",$row);
		$last_check_time = $last_values[0];
		$last_in_bits = $last_values[1];
		$last_out_bits = $last_values[2];
	        $last_error_in_bits = $last_values[3];
	        $last_error_out_bits = $last_values[4];
		$last_status = $last_values[5];
		$last_status_change = $last_values[6];
		$flg_created = 1;
    }
    close(FILE);
} else {
    $flg_created = 0;
}

$update_time = time();
unless (open(FILE,">".$pathCacheFile)){
    print "Check mod for temporary file : ".$pathCacheFile. " !\n";
    exit $ERRORS{"UNKNOWN"};
}

my $in_bits_orig = $in_bits;
my $out_bits_orig = $out_bits;
my $error_out_bits_orig = $error_out_bits;
my $error_in_bits_orig = $error_in_bits;

if ($flg_created == 0){
    print FILE "$update_time:$in_bits_orig:$out_bits_orig:$error_in_bits_orig:$error_out_bits_orig:$last_status:$last_status_change";
    close(FILE);
    print "First execution : Buffer in creation.... \n";
    exit($ERRORS{"UNKNOWN"});
}

## Bandwith = IN + OUT / Delta(T) = 6 Mb/s
## (100 * Bandwith) / (2(si full duplex) * Ispeed)
## Count must round at 4294967296 
##

if (($in_bits - $last_in_bits != 0) && defined($last_in_bits)) {
	my $total = 0;
	if ($in_bits - $last_in_bits < 0){
		$total = 4294967296 * 8 - $last_in_bits + $in_bits;
	} else {
		$total = $in_bits - $last_in_bits;
	}
	my $diff = time() - $last_check_time;
	if ($diff == 0){$diff = 1;}
    my $pct_in_traffic = $in_traffic = abs($total / $diff);
} else {
    $in_traffic = 0;
} 

if ($out_bits - $last_out_bits != 0 && defined($last_out_bits)) {
    my $total = 0;
    if ($out_bits - $last_out_bits < 0){
		$total = 4294967296 * 8 - $last_out_bits + $out_bits;
    } else {
		$total = $out_bits - $last_out_bits;
    }
    my $diff =  time() - $last_check_time;
    if ($diff == 0){$diff = 1;}
    my $pct_out_traffic = $out_traffic = abs($total / $diff);
} else {
    $out_traffic = 0;
}

if ( $speed_card != 0 ) {
    $out_usage = sprintf("%.1f",($out_traffic * 100) / $speed_card);
}
if( $adslSpeed != 0){
	$in_usage = sprintf("%.1f",($in_traffic * 100) / $adslSpeed);
}

my $in_prefix = "";
my $out_prefix = "";

my $in_perfparse_traffic = $in_traffic;
my $out_perfparse_traffic = $out_traffic;
my $error_in_perfparse_traffic = $error_in_bits - $last_error_in_bits;
my $error_out_perfparse_traffic = $error_out_bits - $last_error_out_bits;

if ($in_traffic > 1000) {
    $in_traffic = $in_traffic / 1000;
    $in_prefix = "k";
    if($in_traffic > 1000){
		$in_traffic = $in_traffic / 1000;
		$in_prefix = "M";
    }
    if($in_traffic > 1000){
		$in_traffic = $in_traffic / 1000;
		$in_prefix = "G";
    }
}

if ($out_traffic > 1000){
    $out_traffic = $out_traffic / 1000;
    $out_prefix = "k";
    if ($out_traffic > 1000){
		$out_traffic = $out_traffic / 1000;
		$out_prefix = "M";
	}
    if ($out_traffic > 1000){
		$out_traffic = $out_traffic / 1000;
		$out_prefix = "G";
    }
}

my $in_bits_unit = "";
$in_bits = $in_bits/1048576;
if ($in_bits > 1000){
    $in_bits = $in_bits / 1000;
    $in_bits_unit = "G";
} else { 
    $in_bits_unit = "M";
}

my $out_bits_unit = "";
$out_bits = $out_bits/1048576;
if ($out_bits > 1000){
    $out_bits = $out_bits / 1000;
    $out_bits_unit = "G";
} else {
    $out_bits_unit = "M";
}


if ( $speed_card == 0 ) {
    print "CRITICAL: Interface speed equal 0! Interface must be down.|traffic_in=0B/s traffic_out=0B/s error_in=0B error_out=0B\n";
    exit($ERRORS{"CRITICAL"});
}

#####################################
#####        Display result
##


my $in_perfparse_traffic_str = sprintf("%.1f",abs($in_perfparse_traffic));
my $out_perfparse_traffic_str = sprintf("%.1f",abs($out_perfparse_traffic));

$in_perfparse_traffic_str =~ s/\./,/g;
$out_perfparse_traffic_str =~ s/\./,/g;

my $status = "OK";
my $errorReason = "";

if($warning > 0 and (($in_usage > $warning) or ($out_usage > $warning))){
	$status = "WARNING";
}
if($opt_ew > 0 and ($error_in_perfparse_traffic > $opt_ew or $error_out_perfparse_traffic > $opt_ew)){
        $errorReason = "Packet errors on interface > WARNING! ";
	$status = "WARNING";
}
if ($critical > 0 and (($in_usage > $critical) or ($out_usage > $critical))){
	$status = "CRITICAL";
}
if($opt_ec > 0 and ($error_in_perfparse_traffic > $opt_ec or $error_out_perfparse_traffic > $opt_ec)){
        $errorReason = "Packet errors on interface > CRITICAL! ";
	$status = "CRITICAL";
}

#En cas de non initialisation du cache
if(!$last_status_change or $status eq "OK"){
	$last_status_change = 0;
	$last_status = $status;
}

if($last_status_change == 0 and ($status eq "WARNING" or $status eq "CRITICAL")){
	$last_status_change = $update_time;
	$last_status = $status;
}

if($opt_dl and $opt_dl > 0 and $update_time and ($status eq "WARNING" or $status eq "CRITICAL")){
    my $duration = $update_time - $last_status_change;
    my $duration_left = $opt_dl - $duration;
    if($duration < $opt_dl){
	$errorReason = "$status hold (".$duration_left."s left) ";
	 $status = "OK";
    }
}

unless (open(FILE,">".$pathCacheFile)){
    print "Check mod for temporary file : ".$pathCacheFile. " !\n";
    exit $ERRORS{"UNKNOWN"};
}
#print FILE "$update_time:$in_bits:$out_bits:$error_in_bits:$error_out_bits:$last_status:$last_status_change";
print FILE "$update_time:$in_bits_orig:$out_bits_orig:$error_in_bits_orig:$error_out_bits_orig:$last_status:$last_status_change";
close(FILE);

my $warningBit = $warning * $speed_card / 100;
my $criticalBit = $critical * $speed_card / 100;

my $warningInBit = $warning * $adslSpeed / 100;
my $criticaInBit = $critical * $adslSpeed / 100;

if($mydesc){
	$mydesc = $mydesc." - ";
}else{
	$mydesc = "";
}

my $sspeed = $adslSpeed;
if($sspeed >= 1000000000000.0){
        $sspeed = ($sspeed/1000000000000.0)." Tbps";
}else{
if($sspeed >= 1000000000.0){
        $sspeed = ($sspeed/1000000000.0)." Gbps";
}else{
        if($sspeed >= 1000000.0){
                $sspeed = ($sspeed/1000000)." Mbps";
        }else{
                $sspeed = ($sspeed/1000)." kbps";
        }
}
}

#Si le mode inversé est actif, ici l'interface est forcement UP donc critique
if($opt_invert){
	$errorReason = "Inverted plugin ! Interface should not be UP ! ";
	$status = "CRITICAL";
}

printf($errorReason.$mydesc."Debit = ".$sspeed." Traffic In : %.2f ".$in_prefix."b/s (".$in_usage." %%), Out : %.2f ".$out_prefix."b/s (".$out_usage." %%) ", $in_traffic, $out_traffic);

#printf($errorReason.$mydesc."Debit = ".($adslSpeed/1000000)." Mbps Traffic In : %.2f ".$in_prefix."b/s (".$in_usage." %%), Out : %.2f ".$out_prefix."b/s (".$out_usage." %%) ", $in_traffic, $out_traffic);
if ($opt_S) {
 	printf(" - Link Speed : %d", $speed_card);
}
printf("|traffic_in=".$in_perfparse_traffic_str."Bits/s;$warningInBit;$criticaInBit;0;$adslSpeed traffic_out=".$out_perfparse_traffic_str."Bits/s;$warningBit;$criticalBit;0;$speed_card error_in=".$error_in_perfparse_traffic."P;$opt_ew;$opt_ec;; error_out=".$error_out_perfparse_traffic."P;$opt_ew;$opt_ec;;\n");
exit($ERRORS{$status});

sub print_usage () {
    print "\nUsage:\n";
    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 (--key)        snmp V3 key\n";
	print "   -p (--password)   snmp V3 password\n";
	print "   -u (--username)   snmp v3 username \n";
    print "   -s (--show)       Describes all interfaces number (debug mode)\n";
    print "   -i (--interface)  Set the interface number (2 by default)\n";
    print "   -n (--name)       Allows to use interface name with option -i instead of interface oid index\n";
    print "                     (ex: -i \"eth0\" -n, -i \"VMware Virtual Ethernet Adapter for VMnet8\" -n\n";
    print "                     (choose an unique expression for each interface)\n";
    print "   -w (--warn)       Signal strength at which a warning message will be generated\n";
    print "                     (default 80)\n";
    print "   -c (--crit)       Signal strength at which a critical message will be generated\n";
    print "   --errorw          Number of packet error\n";
    print "   --errorc          Number of packet error\n";
    print "   -d (--duration)       in second\n";
    print "   -e (--durationlimit)  in second\n";
    print "   --invert		Inversion du retour, une interface down est OK\n";
    print "   -t (--time)  	Current timestamp\n";
    print "   -T                Set maximum bandwidth\n";
    print "   -S                Show link speed in output\n";
    print "   -V (--version)    Plugin version\n";
    print "   -r                Regexp Match Mode\n";
    print "   -a (--cache)      Updates cache file every n hours instead of doing snmpwalk for every check (default: 3)\n";
    print "   -h (--help)       usage help\n";
}

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