Last active
August 16, 2023 12:46
-
-
Save BirkAndMe/2b5aa89e3e7587808d68563a6c1a546d to your computer and use it in GitHub Desktop.
Native PHP ping - https://blog.birk-jensen.dk/native-php-ping
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
function computeInternetChecksum($in) { | |
// Add an empty char (8-bit). | |
// This trick leverages the way unpack() works. | |
$in .= "\x0"; | |
// The n* format splits up the data string into 16-bit pairs. | |
// It will unpack the string from the beginning, and only split | |
// whole pairs. So it will automatically leave out (or include) the | |
// odd byte added above. | |
$pairs = unpack('n*', $in); | |
// Sum the pairs. | |
$sum = array_sum($pairs); | |
// Add the hi 16 to the low 16 bits, ending in a single 16-bit int. | |
while ($sum >> 16) | |
$sum = ($sum >> 16) + ($sum & 0xffff); | |
// End with one's complement, to invert the integer. | |
// Note the ~ operator before packing the sum into a string again. | |
return pack('n', ~$sum); | |
} | |
// Prepare the package. | |
$package = [ | |
'type' => "\x08", | |
'code' => "\x00", | |
'checksum' => "\x00\x00", | |
'identifier' => "\x00\x00", | |
'seqNumber' => "\x00\x00", | |
'data' => 'phping', | |
]; | |
// Compute the checksum, so it's ready to send. | |
$package['checksum'] = computeInternetChecksum(implode('', $package)); | |
$rawPackage = implode('', $package); | |
// Create the socket. | |
// AF_INIT is the IPv4 protocol. | |
// SOCK_RAW is needed to perform ICMP requests. | |
$socket = socket_create(AF_INET, SOCK_RAW, getprotobyname('icmp')); | |
// Open up the connection to a host. | |
socket_connect($socket, 'google.com', null); | |
// Used to calculate the response time. | |
$time = microtime(true); | |
// Send the package to the target host. | |
socket_send($socket, $rawPackage, strlen($rawPackage), 0); | |
// Read the response. | |
if ($in = socket_read($socket, 1)) { | |
// Print the response time. | |
echo microtime(true) - $time . " seconds\n"; | |
} | |
// Close the socket. | |
socket_close($socket); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment