<?php
class network_class{
	function network_class(){
	}	
	
		function ping($hostname, $as_ip = 1) { // simple ping, return 1 if ip is online, 0 otherwise
		$this->error = array();
		$this->ping_msg = array();
		$this->verbose = 1;
		$this->maxpackets  = 1;
		$total_rtt = null;
		
		if($as_ip == 1)
			$ipaddr = $hostname;
		else
			$ipaddr = gethostbyname($hostname);
 		$this->sock = null;
		$this->sock = @socket_create(AF_INET, SOCK_RAW, getprotobyname("ICMP"));
    		if ($this->sock === false) {
      			return 0;
    		}
		$conn = @socket_connect($this->sock, $ipaddr, 0);		
		//---------------------------------
		//       ty cd cksum ident seqnu data ---- 
		$data = "08 00 00 00 08 97 00 00 ".
		"65 00 00 39 8e d8 3c a1 ". 
		"e1 05 ".
		"00 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 ". //data
		"15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 ". 
		"25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34";
		//"35 36 37";
		$this->datas = explode(" ",$data);
		//$this->view_packet($data);		
		// - - - -- - - -- - - -
		$this->pktno = 0;
		$this->pktno++;		
		if (!$conn) {
				$this->error[] = "connecting to socket".socket_strerror(socket_last_error($this->sock));
		}    
		$this->datas[6]= "05"; // type (internal);
		$this->datas[7]= str_pad(dechex($this->pktno),2,"0",STR_PAD_LEFT); //seqnum
    
		$datas_aux = $this->checksum($this->datas);
		//view_packet(join(" ",$datas_aux));
		$val1 = null;
		foreach ($datas_aux as $aux) {
				$val =  hexdec($aux);
				$val2 = chr($val);
				$val1 .= $val2;
		}
		$this->times[$this->pktno] = $this->getmicrotime();
		$aux = @socket_write($this->sock,$val1,strlen($val1));
		if ($aux === false) {
			$this->error[] = "writing to socket: ".socket_strerror(socket_last_error($this->sock));
		} elseif ($this->verbose) {			
			$this->ping_msg['send'] = array('bytes'=>$aux, 'packet'=>$this->pktno);
		}	
		// - - - - -- - - - - -- 
		//#################
		if ($aux > 1) {
			$num = 0;
			$timeout = 0;
			while (($num <= 0) and ($timeout < 100))  {
				$set = array($this->sock);
				$num = socket_select($set, $s_write = NULL, $s_accept = NULL, 0, 1000);
				if ($num === false) {
			            $this->error[] = "waiting on socket: ".socket_strerror(socket_last_error());
				}
				$timeout++;
			}
			if ($num>0) {
				$aux = socket_read($this->sock,100);
				$rxtime = $this->getmicrotime();
				$len = strlen($aux)-20;
				$val3 = null;
				for ($o = 1; $o < strlen($aux) ;$o++) {
						$val = $aux[$o];
						$val1 = ord($val);		//Return ASCII value of character
						$val2 = str_pad(dechex($val1),2,"0",STR_PAD_LEFT);
						$val3 .="$val2 ";
				}
			$data_recv = explode(" ",$val3);
		    	//view_packet($val3);
		    	$src =  array_slice($data_recv,11,4); array_walk($src,"hex2dec");
		    	$dest = array_slice($data_recv,15,4); array_walk($dest,"hex2dec");
			$type = $data_recv[19];
			$seq1 = array_slice($data_recv,25,2); array_walk($seq1,"hex2dec");
			$source = join(".",$src);
			$destination = join(".",$dest);
			$seq = join(":",$seq1);
			$ttl = hexdec($data_recv[7]);
			$txtime = $this->times[$seq1[1]];
			$rtt_msec = ($rxtime - $txtime) * 1000;
			
			$total_rtt[]=$rtt_msec;
			//$this->ping_msg[] = "receive  bytes $len  address  $source  
			//packet $seq1[1]  ttl $ttl  time ".sprintf("%.2f",$rtt_msec);
			$this->ping_msg['receive'] = array(
											'bytes'=>$len, 
											'address' => $source,
											'packet' => $seq1[1],
											'ttl' => $ttl,
											'time' => sprintf("%.2f",$rtt_msec)
										);
            	} else {
			$this->ping_msg['timeout'] = 1;
		}
	    }
		//}
		$this->packetsrecv = count($total_rtt);
		socket_close($this->sock);
		$rtt_min = -1;
		$rtt_max = 0;
		$rtt_total = 0;
		if (is_array($total_rtt)) {
			foreach ($total_rtt as $rtt) {
			 	$rtt_total+=$rtt;
				if ($rtt>$rtt_max) $rtt_max = $rtt;
				if ($rtt<$rtt_min || $rtt_min<0) $rtt_min = $rtt;
			}
			$rtt_avg = round($rtt_total/$this->packetsrecv,3);
		} else {
			$rtt_total = 0;
			$rtt_avg = 0;
			$pct = 100;
		}
		$this->ping_msg['statistics'] = array(
									'hostname' => $ipaddr,
							        	'transmited' => $this->maxpackets,
							        	'received' => $this->packetsrecv,
									'loss' => (100-(($this->packetsrecv/$this->maxpackets)*100)),
									'avgtime' => sprintf("%.2f",$rtt_avg),
									'mintime' => sprintf("%.2f",$rtt_min),
									'maxtime' => sprintf("%.2f",$rtt_max)
									);
		
		
		//--------------------------------		    		
		if($this->ping_msg['statistics']['loss'] == 0)
			return 1;
		if($this->ping_msg['statistics']['loss'] == 100)
			return 0;
		return 2; //some error occured
	}
	
/* DEBUG: Dumps the contents of a packet to stdout.
*
*/
	function view_packet($data){
    $datas = explode(" ",$data);
    $i = 1;
    $show1 = null;
    $show4 = null;
    foreach ($datas as $aux) {
			$val =  hexdec($aux);	//Hexadecimal to decimal
			$val2 = chr($val);		//Return a specific character
			$val3 = decbin($val);		//Decimal to binary
			$val4 = str_pad($val3,8,"0",STR_PAD_LEFT); //bin  //string str_pad ( string input, int pad_length [, string pad_string [, int pad_type]])
			$show1.= $aux; //hex
			$show4.= $val4; //bin
	
			if ((($i%2)==0))  $show1.= " ";
			if ((($i%2)==0))  $show4.= " ";
			if ($i == 8) {
	  	  $show1.= "\n";
		    $show4.= "\n";
		    $i=1;
			} else {
		    $i++;
			}
    }
    //echo "\n------------------------------------------\n";
    echo "$show1\n\n$show4";
    //echo "$show1";
   // echo "\n------------------------------------------\n";
    flush();
	}
	
		function checksum($buffer) {
    $cksum = 0;
    $counter = 0;
    //var_dump($buffer);
    $i = 1;
    
    foreach ($buffer as $value) {
			if ($i==0) {
	    	$value1 .=$value;
		    $buff1[] = $value1;
		    $i = 1;
		    $value1=0;
			} else {
		    $value1=$value;
	  	  $i = 0;
			}
    }    
    $buff1[] = $value1;
    
    foreach ($buff1 as $value) {
			$aux = substr($value,2,4).substr($value,0,2);
			$value1 = hexdec($aux);
			$cksum += $value1;
    }
    $aux = $this->repack(($cksum & 0xffff));
    $cksum1 = $this->repack((($cksum >> 16) + $aux));
    $cksum2 = $this->repack(($cksum1 + ($cksum1 >> 16)));
    $ans = ~$cksum2;
    $ans = $this->repack($ans);
    $csum1 = dechex($ans);
    $buffer[2] = substr($csum1,2,4);
    $buffer[3] = substr($csum1,0,2);
    return $buffer;
	}
	
	function getmicrotime() {
    list($usec, $sec) = explode(" ",microtime());
    return ((float)$usec + (float)$sec);
  }
  function repack ($var) {
    $var = pack("n",$var);
    $temp = unpack("n",$var);
    $aux = $temp[""];
    return $aux;
	}
}
?>