$timeout[0], 'usec'=>$timeout[1]); ## 8 bytes of ICMP header data $packet = ''; $packet .= chr(8); // type = 8 : request $packet .= chr(0); // code = 0 $packet .= chr(0); // checksum init $packet .= chr(0); // checksum init $packet .= chr($ident[0]); // identifier $packet .= chr($ident[1]); // identifier $packet .= chr($seq[0]); // seq $packet .= chr($seq[1]); // seq for($i=0; $i<$datasize; $i++) $packet .= chr(0); $chk = icmp::icmpchecksum($packet); $packet[2] = $chk[0]; // checksum init $packet[3] = $chk[1]; // checksum init if(preg_match('/[a-z]/',$host)) $host = gethostbyname($host); // to ip if(!$sock = @socket_create(AF_INET, SOCK_RAW, getprotobyname('icmp'))) { return array(-1, socket_last_error()); } @socket_set_option($sock,SOL_SOCKET,SO_RCVTIMEO,$timeout); // good idea for blocking mode @socket_set_option($sock,SOL_SOCKET,SO_SNDTIMEO,$timeout); $time_start = microtime(); @socket_sendto($sock, $packet, strlen($packet), 0, $host, $port); $time_send = microtime(); $read = array($sock); $write = NULL; $except = NULL; $select = @socket_select($read, $write, $except, $timeout['sec'], $timeout['usec']); if($select === NULL) { @socket_close($sock); return array(-1, 'Select Error'); } else if($select === 0) { @socket_close($sock); return array(-1, 'Timeout'); } $recv = ''; @socket_recvfrom($sock, $recv, 65535, 0, $host, $port); $time_stop = microtime(); @socket_close($sock); $recv = unpack('C*', $recv); // ICMP proto = 1 if($recv[10] !== 1) return array(-1,"Not ICMP packet"); // ICMP response = 0 if($recv[21] !== 0) return array(-1,"Not ICMP response"); if($ident[0] !== $recv[25] || $ident[1] !== $recv[26]) return array(-1,"Bad identification number"); if($seq[0] !== $recv[27] || $seq[1] !== $recv[28]) return array(-1,"Bad sequence number"); $ttt = icmp::getms($time_start, $time_send); $gtt = icmp::getms($time_send, $time_stop); $rtt = icmp::getms($time_start, $time_stop); return array("$rtt $ttt $gtt",''); } private function &icmpchecksum($data) { $bit = unpack('n*', $data); $sum = array_sum($bit); if (strlen($data) % 2) { $temp = unpack('C*', $data[strlen($data) - 1]); $sum += $temp[1]; } $sum = ($sum >> 16) + ($sum & 0xffff); $sum += ($sum >> 16); return pack('n*', ~$sum); } private function &getms($_start, $_end) { $end = explode(' ', $_end); $start = explode(' ', $_start); return sprintf('%.3f',(($end[1]+$end[0])-($start[1]+$start[0])) * 1000); } private function error($errstr) { return error_log($errstr,0); } private function &socket_info($socket) { $opt = array ( 'SO_DEBUG'=>SO_DEBUG, 'SO_ACCEPTCONN'=>SO_ACCEPTCONN, 'SO_BROADCAST'=>SO_BROADCAST, 'SO_REUSEADDR'=>SO_REUSEADDR, 'SO_KEEPALIVE'=>SO_KEEPALIVE, 'SO_LINGER'=>SO_LINGER, 'SO_OOBINLINE'=>SO_OOBINLINE, 'SO_SNDBUF'=>SO_SNDBUF, 'SO_RCVBUF'=>SO_RCVBUF, 'SO_ERROR'=>SO_ERROR, 'SO_TYPE'=>SO_TYPE, 'SO_DONTROUTE'=>SO_DONTROUTE, 'SO_RCVLOWAT'=>SO_RCVLOWAT, 'SO_RCVTIMEO'=>SO_RCVTIMEO, 'SO_SNDLOWAT'=>SO_SNDLOWAT, 'SO_SNDTIMEO'=>SO_SNDTIMEO, ); foreach ($opt as $k=>$value) { $r = socket_get_option($socket, SOL_SOCKET, $value); echo "$k : \n"; print_r($r); echo "\n"; } } } // end of class ?>