<?php
##
## -- 2016.01.06: some
## -- 2013.11.19: some
## -- 2011.07.22: new build
##
function icmp_result_print($str='')
{
  global 
$icmp_i$icmp_c$icmp_e$icmp_t$icmp_p;
  global 
$ctime;
  global 
$current_ms;

  
$avg = ($icmp_c>0) ? sprintf('%.3f',$icmp_t/$icmp_c) : '-';
  
$loss $icmp_e;
  
$cdate date('Y/m/d H:i:s',$ctime);
  
$mdev = @sprintf('%.3f',sqrt($icmp_p/$icmp_c pow($icmp_t/$icmp_c,2)));
  if(
$str$str " <=$str";
  echo 
"$cdate $icmp_i packets transmitted, $icmp_c received, $loss packets loss, ".
    
"current rtt = ${current_ms}, rtt avg = ${avg}ms, mdev = ${mdev}ms$str\n";
  
flush();
}

function 
_signo($signo)
{
  
icmp_result_print();
  if(
$signo != SIGHUP) exit(0);
}

function 
usage()
{
  
$errstr  'Usage: '.$_SERVER['argv'][0].' [-h|--help] [options] IP'."\n";
  
$errstr .= 'Options:'."\n";
  
$errstr .= '   --sleep secs : tcpping interval seconds'."\n";
  
$errstr .= '   --debug      : debug mode, all print'."\n";
  
$errstr .= '   --debug-error-only : default, only error print, if error.'."\n";
  
//error_log($errstr,0);
  
icmp::error_print($errstr);
  return;
}

require_once 
'class.icmp.php';

## ICMP ECHO: measure of lost-time(seconds)
##

set_time_limit(0);

if(
preg_match('/WIN/i',PHP_OS)) error_reporting(E_ALL E_NOTICE);
else
{
  declare(
ticks 1);
  
## 2 3 5 15 19 --> kill, 1 --> HUP
  ##
  
pcntl_signal(SIGHUP,'_signo'); // 1
  
pcntl_signal(SIGINT,'_signo'); // 2, Ctrl+C
  
pcntl_signal(SIGQUIT,'_signo'); // 3
  
pcntl_signal(SIGABRT,'_signo'); // 6
  //pcntl_signal(SIGKILL,'_signo'); // 9, it's fault
  //pcntl_signal(SIGUSR1,'_signo'); // 10, does not work
  
pcntl_signal(SIGALRM,'_signo'); // 14
  
pcntl_signal(SIGTERM,'_signo'); // 15
  //pcntl_signal(SIGSTOP,'_signo'); // 19, it's fault
}

$_debug FALSE;
$_debug_error_only FALSE;
$_usleep 1000000;
$_socket_error 0;
$_socket_error_max 3;

$argc $_SERVER['argc'];
for(
$i=1$i<$argc$i++)
{
  
$argv $_SERVER['argv'][$i];
  if(
preg_match('/^--debug$/',$argv)) $_debug TRUE;
  else if(
preg_match('/^--debug-error-only/',$argv)) $_debug_error_only TRUE;
  else if(
preg_match('/^--sleep/',$argv))
  {
    if(
preg_match('/=/',$argv)) list(,$_sleep) = explode('=',$argv);
    else 
$_sleep $_SERVER['argv'][++$i];
  }
  else if(
preg_match('/^[a-z\d.]+$/i',$argv)) $ip $argv;
  else if(
preg_match('/^--?h/',$argv))
  {
    
usage();
    exit(
1);
  }
}

if(
preg_match('/[a-z]/',$ip)) $ip gethostbyname($ip);
if(!
$ip) { usage(); exit(1); }
if(
$_debug_error_only$_debug FALSE// force debug to disable

define('__DEBUG',$_debug);
define('__DEBUG_ERROR_ONLY',$_debug_error_only);

$stime time(); // start time
$interval 60// print interval 300s

$icmp_i 0// icmp sequence idx
$icmp_t 0// icmp response OK total time
$icmp_p 0// icmp response OK total power time(for mdev)
$icmp_c 0// icmp response OK total count
$icmp_e 0// icmp error to OK count
$ms 0;
$current_ms 0;
$usleep $_sleep ? ($_sleep*1000000) : $_usleep;

while(
TRUE)
{
  if(
$ms 0)
  {
    
$sleepsec $usleep - ($ms*1000);
    if(
$sleepsec 0usleep($sleepsec);
  }
  else 
usleep($usleep);

  
$icmp_i++; // icmp sequence idx
  
$reset FALSE;
  
$printed FALSE;
  
$ctime time(); // current time

  
list($ms,$error) = icmp::ping($ip);

  if(
$error && ($ms<-1))
  {
    
icmp::error_print("ERROR: socket can not create($error). run by root");
    
$_socket_error++;
    if(
$_socket_error >= $_socket_error_max) exit(1);
    else continue;
  }

  
## for debug interval
  ##
  
if($ctime-$stime >= $interval)
  {
    
$stime $ctime;
    
$reset TRUE;
  }

  if(
$error)
  {
    
$icmp_e++; // icmp error count
    
$current_ms = -1;
    if(!
$etime// first error
    
{
        
icmp_result_print("start loss: $error");
        
$printed TRUE;
        
$etime $ctime// start error time
    
}
  }
  else
  {
    list(
$ms) = explode(' ',$ms);
    
$icmp_c++;      // icmp response OK total count
    
$icmp_t += $ms// icmp response OK total time
    
$icmp_p += $ms*$ms;
    
$current_ms $ms;
    if(
$etime// end error time
    
{
        
$dtime 'broken.time='.($ctime $etime).'sec';
        
printf("%s loss=%d %s\n",date('Y/m/d H:i:s',$ctime),$icmp_e,$dtime);
        
$printed TRUE;
        
$etime 0// reset
        
$icmp_e 0// icmp error to OK count
    
}
  }

  
// print
  
if(__DEBUG && !$printedicmp_result_print();
  if(
$reset$icmp_i $icmp_c $icmp_t $icmp_p $icmp_e 0// reset
}

exit(
0);
?>