summaryrefslogtreecommitdiff
path: root/forum/utils/ping.php
diff options
context:
space:
mode:
Diffstat (limited to 'forum/utils/ping.php')
-rw-r--r--forum/utils/ping.php126
1 files changed, 126 insertions, 0 deletions
diff --git a/forum/utils/ping.php b/forum/utils/ping.php
new file mode 100644
index 0000000..8977df5
--- /dev/null
+++ b/forum/utils/ping.php
@@ -0,0 +1,126 @@
+<?php
+$g_icmp_error = "No Error";
+
+// timeout in ms
+function ping($host, $timeout)
+{
+ $port = 0;
+ $datasize = 64;
+ global $g_icmp_error;
+ $g_icmp_error = "No Error";
+ $ident = array(ord('J'), ord('C'));
+ $seq = array(rand(0, 255), rand(0, 255));
+
+ $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 = icmpChecksum($packet);
+
+ $packet[2] = $chk[0]; // checksum init
+ $packet[3] = $chk[1]; // checksum init
+
+ $sock = socket_create(AF_INET, SOCK_RAW, getprotobyname('icmp'));
+ $time_start = microtime();
+ socket_sendto($sock, $packet, strlen($packet), 0, $host, $port);
+
+
+ $read = array($sock);
+ $write = NULL;
+ $except = NULL;
+
+ $select = socket_select($read, $write, $except, 0, $timeout * 1000);
+ if ($select === NULL)
+ {
+ $g_icmp_error = "Select Error";
+ socket_close($sock);
+ return -1;
+ }
+ elseif ($select === 0)
+ {
+ $g_icmp_error = "Timeout";
+ socket_close($sock);
+ return -1;
+ }
+
+ $recv = '';
+ $time_stop = microtime();
+ socket_recvfrom($sock, $recv, 65535, 0, $host, $port);
+ $recv = unpack('C*', $recv);
+
+ if ($recv[10] !== 1) // ICMP proto = 1
+ {
+ $g_icmp_error = "Not ICMP packet";
+ socket_close($sock);
+ return -1;
+ }
+
+ if ($recv[21] !== 0) // ICMP response = 0
+ {
+ $g_icmp_error = "Not ICMP response";
+ socket_close($sock);
+ return -1;
+ }
+
+ if ($ident[0] !== $recv[25] || $ident[1] !== $recv[26])
+ {
+ $g_icmp_error = "Bad identification number";
+ socket_close($sock);
+ return -1;
+ }
+
+ if ($seq[0] !== $recv[27] || $seq[1] !== $recv[28])
+ {
+ $g_icmp_error = "Bad sequence number";
+ socket_close($sock);
+ return -1;
+ }
+
+ $ms = ($time_stop - $time_start) * 1000;
+
+ if ($ms < 0)
+ {
+ $g_icmp_error = "Response too long";
+ $ms = -1;
+ }
+
+ socket_close($sock);
+
+ return $ms;
+}
+
+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);
+}
+
+function getLastIcmpError()
+{
+ global $g_icmp_error;
+ return $g_icmp_error;
+}
+
+?> \ No newline at end of file