#!/usr/bin/perl
#Author: Wallace Liu
#This script is to use ethtools to check the NICs status and report to Nagios
#Prerequsite:
#"nagios  ALL=(ALL) NOPASSWD:/sbin/ethtool" is defined into visudo
#It is better to create /homr/nagios directory
my $SUDO="/usr/bin/sudo";
my $ETHTOOL="/sbin/ethtool";
my $GLOBAL_CHECK_STATUS;
my $FINE_IFACE_GLOBAL_OUTPUT;
my $ERROR_IFACE_GLOBAL_OUTPUT;
my $index_loop=0;
my @IFACE_LIST=("eth0","eth1","eth3");
my %BENCHMARK_MATRIX=(
eth0 => "Link detected: yes,Speed: 1000Mb/s,Duplex: Full,Auto-negotiation: on",
eth1 => "Link detected: yes,Speed: 1000Mb/s,Duplex: Full,Auto-negotiation: on",
eth2 => "Link detected: yes,Speed: 1000Mb/s,Duplex: Full,Auto-negotiation: on",
eth3 => "Link detected: yes,Speed: 1000Mb/s,Duplex: Full,Auto-negotiation: on",
);
sub check_iface
{
#The rerurn code for this sub:
#0 the interface is fine;
#1 The interface is is Critical for the first found criteria
#2 The script needs change to incorporate the right BENCHMARK_MATRIX;

my $IFACE=shift @_;
my @IFACE_POLL;
my $TOTAL_POLL_LINE;
my $TOTOL_CRITERIA_LINE;
my @CRITERIA;
my $index_loop=0;
my $temp_i=0;
my $temp_j=0;
my $temp_k=0;

#print "Required benchmark for interface $IFACE", $BENCHMARK_MATRIX{$IFACE}, "\n";
if ( $BENCHMARK_MATRIX{$IFACE} =~ /^$/) {$GLOBAL_CHECK_STATUS="Script $0 does not have criteria for $IFACE,change the script $0 accordingly."; return 2;}

open(IFACE_HANDLE, "$SUDO  $ETHTOOL  $IFACE |" ) or die "Command  $0 failed, $!" ;
@IFACE_POLL=<IFACE_HANDLE>;
$TOTAL_POLL_LINE=@IFACE_POLL;

#Create two demension CRITERIA array
$index_loop=0;
foreach (split(/,/,$BENCHMARK_MATRIX{$IFACE}))
{ 
  $CRITERIA[$index_loop]= [split(/: /, $_)]; 
 $index_loop++;
}

$TOTOL_CRITERIA_LINE=$index_loop;

for ($temp_i=0; $temp_i<@CRITERIA;$temp_i++)
{
####For each key in the CRITERIA array, default set benchmark_key_exist=0 means this key does not exist in the polled IFACE report
my $benchmark_key_exist=0;
# If this key really does not exist in the polled result, than this script must be modified

    for ($index_loop=0;$index_loop<$TOTAL_POLL_LINE; $index_loop++)
    {
      #print "Line number is $index_loop; Key is $CRITERIA[$temp_i][0]; Key value is $CRITERIA[$temp_i][1].\n";
      if ($IFACE_POLL[$index_loop] =~ /(^\s+$CRITERIA[$temp_i][0]): +(.*)/ )  
       {$benchmark_key_exist=1;
        #print "Criteria key and value--",$CRITERIA[$temp_i][0],"--",$CRITERIA[$temp_i][1],"==\n";
        # if the key value is found identicle, then  jump to check next key value; otherwise simply report crotical failure and quit the sub-procedure.
        if ($2 eq $CRITERIA[$temp_i][1]) 
         {
          last;
         }
        else
         {
          my $temp_s=$IFACE_POLL[$index_loop];
          chomp($temp_s);
          $temp_s =~ /^\s+(.*)/;
          $temp_s =$1;
          $GLOBAL_CHECK_STATUS="NIC $IFACE is $temp_s,should be $CRITERIA[$temp_i][1].";
          return 1;
         }
       }
    }
    if ($benchmark_key_exist == 0 ) 
     { 
       # This key is no longer used by ethtool command
       $GLOBAL_CHECK_STATUS="Benchmark key $CRITERIA[$temp_i][0] does not exist in the ethtool report for $IFACE, change the script $0 accordingly.";
       return 2;};
}
$GLOBAL_CHECK_STATUS="NIC $IFACE:$CRITERIA[1][1],$CRITERIA[2][1],$CRITERIA[3][0] is $CRITERIA[3][1].";
return 0;
}

my $check_return_value;
my $uptonow_result=0;
# uptonow_result=0 means every interface is fine;
for ($index_loop=0; $index_loop<=$#IFACE_LIST; $index_loop++)
{
 $check_return_value=check_iface($IFACE_LIST[$index_loop]);
 ##print "return value is $check_return_value \n";
 if ($check_return_value==0)
  { $FINE_IFACE_GLOBAL_OUTPUT=$FINE_IFACE_GLOBAL_OUTPUT  . $GLOBAL_CHECK_STATUS  . "\n" ;}
 else 
  { #check_return_value is 1 or 2
   $uptonow_result=1;
   $ERROR_IFACE_GLOBAL_OUTPUT=$ERROR_IFACE_GLOBAL_OUTPUT . $GLOBAL_CHECK_STATUS . "\n" ;
  }
}
#For Nagios check
#0 OK
#1 Warning
#2 Critical
if ($uptonow_result == 0 )
{print "OK - ALL NICs are working fine.\n$FINE_IFACE_GLOBAL_OUTPUT"; exit 0;}
else
{print "CRITICAL - $ERROR_IFACE_GLOBAL_OUTPUT \n $FINE_IFACE_GLOBAL_OUTPUT"; exit 2;}
