#!/usr/bin/perl -w
#
# check_redund_switch - nagios plugin 
#
# (c) 2009 D. Iwaniuk <d.iwaniuk@gmail.com>
#
#

use Net::Ping;
use Getopt::Long;
use strict;

 my($switchA,$switchB,$warn,$crit); 

 my $packet  =  5;	 # default send 5 packages	
 my $timeout =  10;	 # default timeout 10 sec
 my $proto   = "tcp";    # default tcp 	

 GetOptions(
	 "A|switchA=s"  ,   \$switchA,
	 "B|switchB=s"  ,   \$switchB,
         "P|proto=s"    ,   \$proto,
	 "T|timeout=i"  ,   \$timeout,
         "w|warn=i"     ,   \$warn,
	 "c|crit=i"     ,   \$crit,
         "s|packet=i"   ,   \$packet
 );	


 if(!defined($switchA&&$switchB&&$warn&&$crit)){ 

  print "Bad syntax! Use: check_redund_switch --switchA <name/ip> --switchB <name/ip> --warn <integer>% --crit <integer>% \n"; 
  print "[--proto <udp,tcp,icmp(root privilage)> --timeout <integer> --packet <integer>]\n"; 
  exit(3);

 }

 my $p=Net::Ping->new($proto,$timeout); 
 $p->hires(1);

 my ( $ret, $duration, $ip); 
 my $bad = 0; my $dur = 0; 

# test switch A
# --------------------------------------->

 for(1..$packet){

  ($ret, $duration, $ip) = $p->ping("$switchA");
    if( !$ret ) { $bad++; }  
    $dur += $duration;
    $p->close();  
 }

 my $LOSS_A = $bad * 100/$packet;
 my $RTA    = sprintf("%.2f",$dur * 1000/$packet);

# switch A live => return OK  
#

 if ($LOSS_A < $warn) { print "PING OK -  Packet loss = $LOSS_A%, RTA = $RTA ms|rta = $RTA ms;"; exit(0); } 

# test switch B ( only if switch A dead or loss packet ) 
# --------------------------------------->

 $bad=0;$dur=0;
 for(1..$packet){

  ($ret, $duration, $ip) = $p->ping("$switchB");
    if( !$ret ) { $bad++; }
    $dur += $duration; 
    $p->close();
 }


 my $LOSS_B = $bad * 100/$packet;
 my $RTB    = sprintf("%.2f",$dur * 1000/$packet);

# switch A dead & switch B live => WARNING 
# ----------------------------------------->

 if( ( $LOSS_A > $crit ) && ( $LOSS_B < $warn ) ) 
         {
          print "PING BAD - Packet loss $LOSS_A% [Redund]: ";
          print "$switchB PING OK - Packet loss $LOSS_B% RTA = $RTB ms|rta = $RTA ms";  
	  exit(1);  
	 }

# switch A dead | switch B dead => CRITICAL
# ----------------------------------------->
 if( ( $LOSS_A > $crit ) && ( $LOSS_B > $crit ) ) 
     	{ 
	 print "PING BAD - Packet loss $LOSS_A% [Redund]: ";
	 print "$switchB PING BAD - Packet loss $LOSS_B% RTA = $RTB ms|rta = $RTA ms"; 
	 exit(2); 
	} 

# switch A dead | switch B loss => CRITICAL
# ----------------------------------------->
 if( ( $LOSS_A > $crit ) && ( $LOSS_B > $warn ) ) 
     	{ 
	 print "PING BAD - Packet loss $LOSS_A% RTA = $RTA ms [Redund]: ";
	 print "$switchB PING BAD - Packet loss LOSS_B% RTA = $RTB ms|rta = $RTA ms "; 
	 exit(2); 
	}

# switch A loss | switch B live => WARNING
# -----------------------------------------> 
 if( ( $LOSS_A > $warn ) && ( $LOSS_B < $warn ) ) 
     	{ 
	 print "PING BAD - Packet loss $LOSS_A% RTA = $RTA ms [Redund]: ";
	 print  "$switchB PING OK - Packet loss $LOSS_B% RTA = $RTB ms|rta = $RTA ms"; 
	 exit(1); 
	} 

# switch A loss | switch B dead => CRITICAL
# -----------------------------------------> 
 if( ( $LOSS_A > $warn ) && ( $LOSS_B > $crit ) ) 
     	{ 
	 print "PING BAD - Packet loss $LOSS_A% RTA = $RTA ms [Redund]: ";
	 print "$switchB PING BAD - Packet loss $LOSS_B% RTA = $RTB ms|rta  = $RTA ms"; 
	 exit(2); 
	} 

# switch A loss | switch B loss => CRITICAL
# ----------------------------------------->
 if( ( $LOSS_A > $warn ) && ( $LOSS_B > $warn) ) 
     	{ 
	 print "PING BAD - Packet loss $LOSS_A% RTA = $RTA ms [Redund]: ";
	 print "$switchB PING BAD - Packet loss $LOSS_B% RTA = $RTB ms|rta = $RTA ms"; 
	 exit(2); 
	}



