#!/usr/bin/perl
#use strict;
use Net::Ping;

my $line;my $dummy;my $peer;my $ip1;my $ip2;my $ip3;my $ip4;my $p;my $field;
my $status="OK";
my $sleep=60;
my $peermissing=0;
my $peerunreach=0;
my $oldrecvpack=0;
my $recvpackets=0;

# sub performing restart of pppd and relevant process
##
sub restartppp {
	system("/etc/rc.d/init.d/adsl reload");
	system("/root/ipcheck/dyndnsupd.sh");
	system("/etc/rc.d/init.d/snortd restart");
}

# sub performing restart of usb and relevant process
##
sub restartusb {
	system("/etc/rc.d/init.d/adsl restart");
}

# sub to update number of packets received on ppp0
##
sub updatepackets {
	my $inpackets=0;
	my $line;
	my $dummy;
	$line=`ifconfig ppp0 | grep  "Paquets Re"`;
	chomp $line;
	($dummy,$inpackets)=split(":",$line);
	$line=$inpackets;
	($inpackets,$dummy)=split(" ",$line);
	return $inpackets;
}

# Start of script
##
	
#Update number of packets the first time
$recvpackets=updatepackets();
$oldrecvpack=$recvpackets;
open(LOG,">>/var/log/checkpeer.log");
print "Starting to monitor ppp0 link\n";
while ($status ne "quit"){
	#Testing if the ppp interface is OK by fetching the peer IP address
	$line=`ifconfig ppp0 | grep inet `;
	chomp $line;
	($dummy,$dummy,$field)=split (":",$line);
	($peer,$dummy)=split (" ",$field);
	($ip1,$ip2,$ip3,$ip4)=split ("\\.",$peer);
	if ($ip1<=0 || $ip1>255 || $ip2<=0 || $ip2>255 || $ip3<=0 || $ip3>255 || $ip4<=0 || $ip4>255){
		$status="peer missing";
	}
	else{
		#Test if we have received new packets on ppp0 to save pinging peer
		$recvpackets=updatepackets();
		if ($recvpackets > $oldrecvpack){
			$oldrecvpack=$recvpackets;
			$status="packets detected";
		}
		elsif ($recvpackets < $oldrecvpack){
			$oldrecvpack=$recvpackets;
			$status="interface reset";
		}
		else {# No packets received lately.Checking peer by pinging it ...
			$p = Net::Ping->new("icmp");
			if ($p->ping($peer,1)){
				$status="peer reacheable";
			}
			else{
				$status="peer unreacheable";
			}
			$p->close();	
			#Update packets count so next comparison takes the ping into account
			$recvpackets=updatepackets();
			$oldrecvpack=$recvpackets;
		}
	}

#From here, we take different actions depending on the previous results
	if ($status eq "peer missing"){
		$peermissing++;
		print  scalar(localtime()).": PPPD is being started (peer missing)\n";
		restartppp();
		#Increase sleep time each time in case pppd needs more time
		$sleep=30+$peermissing*3;
		if ($peermissing >= 3){
			print  scalar(localtime()).": USB is being restarted\n";
			restartusb();
			$peerunreach=0;
			$sleep=120;
		}
	}
	elsif ($status eq "peer unreacheable"){
		$peerunreach++;
		$sleep=5;
		print  scalar(localtime()).": PEER $peer is not reacheable ($peerunreach time(s))"."\n";
		if ($peerunreach >= 3){
			print  scalar(localtime()).": PPPD is being restarted (peer unreacheable)\n";
			restartppp();
			$peerunreach=0;
			#Increase sleep time each time in case pppd needs time to go up
			$sleep=20;
		}
	}
	elsif ($status eq "packets detected"){
		$sleep=10;
		print  scalar(localtime()).": PPP0 traffic increased to $recvpackets packets. Skipping ping"."\n";
		$peerunreach=0;
	}
	elsif ($status eq "interface reset"){
		$sleep=20;
		$peerunreach=0;
		print  scalar(localtime()).": PPP0 interface reset $recvpackets packets. Skipping ping"."\n";
	}
	elsif ($status eq "peer reacheable"){
		print  scalar(localtime()).": PEER $peer is alive"."\n";
		$sleep=60;
		$peermissing=0;
		$peerunreach=0;
	}
	print  scalar(localtime()).": SLEEP for $sleep seconds\n";
	sleep $sleep;
}
