PHP Ping

Started by mario, December 26, 2008, 11:59:41 PM

Previous topic - Next topic

mario


<?php

class Net_Ping
{
  var 
$icmp_socket;
  var 
$request;
  var 
$request_len;
  var 
$reply;
  var 
$errstr;
  var 
$time;
  var 
$timer_start_time;

  function 
Net_Ping()
  {
   
$this->icmp_socket socket_create(AF_INETSOCK_RAW1);
   
socket_set_block($this->icmp_socket);
  }
 
  function 
ip_checksum($data)
  {
     for(
$i=0;$i<strlen($data);$i += 2)
     {
         if(
$data[$i+1]) $bits unpack('n*',$data[$i].$data[$i+1]);
         else 
$bits unpack('C*',$data[$i]);
         
$sum += $bits[1];
     }
    
     while (
$sum>>16$sum = ($sum 0xffff) + ($sum >> 16);
     
$checksum pack('n1',~$sum);
     return 
$checksum;
  }

  function 
start_time()
  {
   
$this->timer_start_time microtime();
  }
 
  function 
get_time($acc=2)
  {
   
// format start time
   
$start_time explode (" "$this->timer_start_time);
   
$start_time $start_time[1] + $start_time[0];
   
// get and format end time
   
$end_time explode (" "microtime());
   
$end_time $end_time[1] + $end_time[0];
   return 
number_format ($end_time $start_time$acc);
  }

  function 
Build_Packet()
  {
   
$data "abcdefghijklmnopqrstuvwabcdefghi"// the actual test data
   
$type "\x08"// 8 echo message; 0 echo reply message
   
$code "\x00"// always 0 for this program
   
$chksm "\x00\x00"// generate checksum for icmp request
   
$id "\x00\x00"// we will have to work with this later
   
$sqn "\x00\x00"// we will have to work with this later

   // now we need to change the checksum to the real checksum
   
$chksm $this->ip_checksum($type.$code.$chksm.$id.$sqn.$data);

   
// now lets build the actual icmp packet
   
$this->request $type.$code.$chksm.$id.$sqn.$data;
   
$this->request_len strlen($this->request);
  }
 
  function 
Ping($dst_addr,$timeout=5,$percision=3)
  {
   
// lets catch dumb people
   
if ((int)$timeout <= 0$timeout=5;
   if ((int)
$percision <= 0$percision=3;
  
   
// set the timeout
   
socket_set_option($this->icmp_socket,
     
SOL_SOCKET,  // socket level
     
SO_RCVTIMEO// timeout option
     
array(
       
"sec"=>$timeout// Timeout in seconds
       
"usec"=>0  // I assume timeout in microseconds
       
)
     );

   if (
$dst_addr)
   {
     if (@
socket_connect($this->icmp_socket$dst_addrNULL))
     {
    
     } else {
       
$this->errstr "Cannot connect to $dst_addr";
       return 
FALSE;
     }
     
$this->Build_Packet();
     
$this->start_time();
     
socket_write($this->icmp_socket$this->request$this->request_len);
     if (@
socket_recv($this->icmp_socket$this->reply2560))
     {
       
$this->time $this->get_time($percision);
       return 
$this->time;
     } else {
       
$this->errstr "Timed out";
       return 
FALSE;
     }
   } else {
     
$this->errstr "Destination address not specified";
     return 
FALSE;
   }
  }
}

$ping = new Net_Ping;
$ping->ping("127.0.0.1");

if (
$ping->time){
  echo 
"Time: ".$ping->time;
}
else
{
  echo 
$ping->errstr;
}
?>



amntiw601

Well written, support it

mikecarmelo

Quote from: mario on December 26, 2008, 11:59:41 PM

<?php

class Net_Ping
{
  var 
$icmp_socket;
  var 
$request;
  var 
$request_len;
  var 
$reply;
  var 
$errstr;
  var 
$time;
  var 
$timer_start_time;

  function 
Net_Ping()
  {
   
$this->icmp_socket socket_create(AF_INETSOCK_RAW1);
   
socket_set_block($this->icmp_socket);
  }
 
  function 
ip_checksum($data)
  {
     for(
$i=0;$i<strlen($data);$i += 2)
     {
         if(
$data[$i+1]) $bits unpack('n*',$data[$i].$data[$i+1]);
         else 
$bits unpack('C*',$data[$i]);
         
$sum += $bits[1];
     }
    
     while (
$sum>>16$sum = ($sum 0xffff) + ($sum >> 16);
     
$checksum pack('n1',~$sum);
     return 
$checksum;
  }

  function 
start_time()
  {
   
$this->timer_start_time microtime();
  }
 
  function 
get_time($acc=2)
  {
   
// format start time
   
$start_time explode (" "$this->timer_start_time);
   
$start_time $start_time[1] + $start_time[0];
   
// get and format end time
   
$end_time explode (" "microtime());
   
$end_time $end_time[1] + $end_time[0];
   return 
number_format ($end_time $start_time$acc);
  }

  function 
Build_Packet()
  {
   
$data "abcdefghijklmnopqrstuvwabcdefghi"// the actual test data
   
$type "\x08"// 8 echo message; 0 echo reply message
   
$code "\x00"// always 0 for this program
   
$chksm "\x00\x00"// generate checksum for icmp request
   
$id "\x00\x00"// we will have to work with this later
   
$sqn "\x00\x00"// we will have to work with this later

   // now we need to change the checksum to the real checksum
   
$chksm $this->ip_checksum($type.$code.$chksm.$id.$sqn.$data);

   
// now lets build the actual icmp packet
   
$this->request $type.$code.$chksm.$id.$sqn.$data;
   
$this->request_len strlen($this->request);
  }
 
  function 
Ping($dst_addr,$timeout=5,$percision=3)
  {
   
// lets catch dumb people
   
if ((int)$timeout <= 0$timeout=5;
   if ((int)
$percision <= 0$percision=3;
  
   
// set the timeout
   
socket_set_option($this->icmp_socket,
     
SOL_SOCKET,  // socket level
     
SO_RCVTIMEO// timeout option
     
array(
       
"sec"=>$timeout// Timeout in seconds
       
"usec"=>0  // I assume timeout in microseconds
       
)
     );

   if (
$dst_addr)
   {
     if (@
socket_connect($this->icmp_socket$dst_addrNULL))
     {
    
     } else {
       
$this->errstr "Cannot connect to $dst_addr";
       return 
FALSE;
     }
     
$this->Build_Packet();
     
$this->start_time();
     
socket_write($this->icmp_socket$this->request$this->request_len);
     if (@
socket_recv($this->icmp_socket$this->reply2560))
     {
       
$this->time $this->get_time($percision);
       return 
$this->time;
     } else {
       
$this->errstr "Timed out";
       return 
FALSE;
     }
   } else {
     
$this->errstr "Destination address not specified";
     return 
FALSE;
   }
  }
}

$ping = new Net_Ping;
$ping->ping("127.0.0.1");

if (
$ping->time){
  echo 
"Time: ".$ping->time;
}
else
{
  echo 
$ping->errstr;
}
?>



Marvelous! A well written code....have you done any implementation to this code or this is the final one?
Once again great job!
keep up the good work!
thx!

mario

That is the last version