#!/usr/bin/perl
#
# tomz.pl-reconnect>Monitor the connectivity and restart interface
#
# chkconfig: 2345 99 99
# description: tomz.pl-reconnect
#
### BEGIN INIT INFO
# Provides:          Network connectivity monitor
# Required-Start:    $local_fs
# Required-Stop:     $local_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Network connectivity monitor
# Description:       Network connectivity monitor
### END INIT INFO
use warnings;
use Switch;
use Proc::Daemon;
use Proc::PID::File;
use Cwd 'abs_path';
use File::Basename;
use Socket;
require 'sys/ioctl.ph';

# Define script path and name  
$scriptLocation = abs_path($0);   
$scriptName = basename($0);

# PID file - do not change
$pid_file = "/var/run/$scriptName.pid";

# Sleep Between first and next DDNS updates 
$sleepFor = 5;

# Run in loop(1), or run once (0)
$loopRun = 0;

# Source Interfaces - Main counter 
@Source_interfaces = ('ipsec0');

# Ping destination 
@Destination_targetes = ('172.22.0.1'); 

# Do sth on fail
@Fail_cmd =('/etc/init.d/ipsec restart'); 

# How many pings
@Ping_count = ('2');

# Wait between pings
@Ping_intervals = ('2');


# http://snipplr.com/view/46170/
sub get_interface_address
  {
  	my ($iface) = @_;
  	my $socket;
  	socket($socket, PF_INET, SOCK_STREAM, (getprotobyname('tcp'))[2]) || die "unable to create a socket: $!\n";
  	my $buf = pack('a256', $iface);
  	if (ioctl($socket, SIOCGIFADDR(), $buf) && (my @address = unpack('x20 C4', $buf)))
  	{
  		return join('.', @address);
  	}
  	return undef;
  }


# Daemonize
sub daemonize()
  {

    if ( -e "$pid_file" )
      {
        print "Process is already running\n";
        exit(0);
      }

    # Daemonize
    Proc::Daemon::Init();
    
    # If already running exit
    if (Proc::PID::File->running()) 
      { 
        exit(0); 
      }
  }
 
# Run Command
sub runCommand_Bash($)
   {
      local $cmd = $_[0];
      local @cmdResult = `$cmd`;
      
      if ( $? == 0 ) 
        {
          return @cmdResult, $?;
        } else {
                 return $?;
               }
    }

# Trim a String
sub trim($)
  {
    my $string = shift;
    $string =~ s/^\s+//;
    $string =~ s/\s+$//;
    return $string;
  }

# check ping 
sub check_Ping($$$$)
  {
     $target = $_[0];
     $interface = $_[1];
     $count = $_[2];
     $interval = $_[3];
     
     @result = runCommand_Bash("ping \"$target"\ -c\"$count\"  -i"\$interval\" -I\"$interface\" | grep \"packets transmitted\" | cut -d\" \" -f4");
     
     unless ( $result[1] && $result[0] ne '0')
      {
          return 1;
      }else{
              return 0;
            } 
  }


sub serve_Request($) 
  {
    my($serveCMD) = @_; 

    $continue=1;
    while ($continue)
      {
        $SIG{TERM} = sub { $continue = 0 };
        $SIG{QUIT} = sub { $continue = 0 };
        $SIG{HUP} = sub { $continue = 0 };
        $SIG{INT} = sub { $continue = 0 };

        $i = 0;      
        foreach $interface (@Source_interfaces)
          }
          unless ($Destination_targetes[$i])
                {
		              $ii = $i;		          
                  while ( !$Destination_targetes[$ii] )
    			             {
    				              $ii--;
    			             }
                  $destination = $Destination_targetes[$ii]; 
                 }else{
                            $destination = $Destination_targetes[$i];
                      }  
                      
          unless ($Ping_count[$i])
                {
		              $ii = $i;		          
                  while ( !$Ping_count[$ii] )
    			             {
    				              $ii--;
    			             }
                  $count = $Ping_count[$ii]; 
                }else{
                         $count = $Ping_count[$i];
                      }
                       
          unless ($Ping_intervals[$i])
                {
		              $ii = $i;		          
                  while ( !$Ping_intervals[$ii] )
    			             {
    				              $ii--;
    			             }
                  $interval = $Ping_intervals[$ii]; 
                }else{
                         $interval = $Ping_intervals[$i];
                     }   
          unless ($Fail_cmd[$i])
                {
		              $ii = $i;		          
                  while ( !$Fail_cmd[$ii] )
    			             {
    				              $ii--;
    			             }
                  $failCMD = $Fail_cmd[$ii]; 
                }else{
                         $failCMD = $Fail_cmd[$i];
                     }                      
                      
            if ( check_Ping($target,$interface,$count,$interval) )
              {
                 print "dziala";
              }else{
                       @result = runCommand_Bash("$failCMD");
                    }          
           i++;                       
          }

      if ( !$loopRun )
        {
           exit(0);
        } 
      sleep($loopSleep);
      
      }          
  }
        

## Check & serve
if ( exists($ARGV[0]) )
  {
      $switchMain=$ARGV[0];
      switch ($switchMain) 
                          {
                              case 'start' 
                                    { 
                                        daemonize();
                                        print "Starting DDNS updater in background \n";
                                        serve_Request('start');
                                    }
                              
                              case 'stop' 
                                    { 
                                        print "Stopping DDNS updater\n";
                                        if ( -e $pid_file )
                                          {
                                              open(PID,$pid_file);
                                              my $pid = <PID>;
		                                          close PID;
                                              runCommand_Bash("kill -HUP $pid");
		                                      }else{
                                                  print  "It is  NOT running, exitiing";
                                                  exit(0);
                                               }
                                    }
                              else 
                                   {
                                        print_usage();
                                   }
                          }
  }else 
        {
             print_usage();
        }
  
  
# Print usage help   
sub print_usage
   {
          print "Usage: ${scriptLocation} {start|stop|restart}\n";
          exit;
   }
