diff --git a/NEWS b/NEWS index ee1fa5cd798..175c645e366 100644 --- a/NEWS +++ b/NEWS @@ -45,6 +45,10 @@ PHP NEWS . Fixed bug #49169 (SoapServer calls wrong function, although "SOAP action" header is correct). (nielsdos) +- Sockets: + . Added IPPROTO_ICMP/IPPROTO_ICMPV6 to create raw socket for ICMP usage. + (David Carlier) + - Standard: . Fixed crypt() tests on musl when using --with-external-libcrypt (Michael Orlitzky). diff --git a/UPGRADING b/UPGRADING index 6d6fa0030e6..7ae545929b4 100644 --- a/UPGRADING +++ b/UPGRADING @@ -129,6 +129,9 @@ PHP 8.5 UPGRADE NOTES - POSIX: . POSIX_SC_OPEN_MAX. +- Sockets: + . IPPROTO_ICMP/IPPROTO_ICMPV6. + ======================================== 11. Changes to INI File Handling ======================================== diff --git a/ext/sockets/sockets.stub.php b/ext/sockets/sockets.stub.php index f19672ecd53..b55d36429b4 100644 --- a/ext/sockets/sockets.stub.php +++ b/ext/sockets/sockets.stub.php @@ -1647,6 +1647,20 @@ const SOL_UDP = UNKNOWN; */ const SOL_UDPLITE = UNKNOWN; #endif +#if defined(IPPROTO_ICMP) || defined(PHP_WIN32) +/** + * @var int + * @cvalue IPPROTO_ICMP + */ +const IPPROTO_ICMP = UNKNOWN; +#endif +#if defined(IPPROTO_ICMPV6) || defined(PHP_WIN32) +/** + * @var int + * @cvalue IPPROTO_ICMPV6 + */ +const IPPROTO_ICMPV6 = UNKNOWN; +#endif #ifdef HAVE_IPV6 /** diff --git a/ext/sockets/sockets_arginfo.h b/ext/sockets/sockets_arginfo.h index 524bf605b56..abb6e087217 100644 --- a/ext/sockets/sockets_arginfo.h +++ b/ext/sockets/sockets_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 08677a3dd11366b55a1c539475adead74109595e */ + * Stub hash: 4fdd210a2de6f3b5df10caf5ac7fefa6aa71926c */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_socket_select, 0, 4, MAY_BE_LONG|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(1, read, IS_ARRAY, 1) @@ -945,6 +945,12 @@ static void register_sockets_symbols(int module_number) #if defined(IPPROTO_UDPLITE) REGISTER_LONG_CONSTANT("SOL_UDPLITE", IPPROTO_UDPLITE, CONST_PERSISTENT); #endif +#if defined(IPPROTO_ICMP) || defined(PHP_WIN32) + REGISTER_LONG_CONSTANT("IPPROTO_ICMP", IPPROTO_ICMP, CONST_PERSISTENT); +#endif +#if defined(IPPROTO_ICMPV6) || defined(PHP_WIN32) + REGISTER_LONG_CONSTANT("IPPROTO_ICMPV6", IPPROTO_ICMPV6, CONST_PERSISTENT); +#endif #if defined(HAVE_IPV6) REGISTER_LONG_CONSTANT("IPV6_UNICAST_HOPS", IPV6_UNICAST_HOPS, CONST_PERSISTENT); #endif diff --git a/ext/sockets/tests/socket_icmp.phpt b/ext/sockets/tests/socket_icmp.phpt new file mode 100644 index 00000000000..c6b4026c738 --- /dev/null +++ b/ext/sockets/tests/socket_icmp.phpt @@ -0,0 +1,57 @@ +--TEST-- +socket_create with IPPROTO_ICMP +--EXTENSIONS-- +sockets +--SKIPIF-- + +--FILE-- +> 16) { + $sum = ($sum & 0xFFFF) + ($sum >> 16); + } + return ~ $sum & 0xFFFF; +}; +$header = pack('C2n3a*', $type, $code, $checksum($header), $identifier, $sequence, $data); + +if (!socket_sendto($socket, $header, strlen($header), 0, $host, 0)) { + die("Unable to send packet: " . socket_strerror(socket_last_error($socket)) . "\n"); +} + +$read = [$socket]; +$write = $except = []; +$timeout = ['sec' => 4, 'usec' => 0]; +if (socket_select($read, $write, $except, $timeout['sec'], $timeout['usec']) > 0) { + $response = ''; + socket_recv($socket, $response, 65535, 0); + var_dump(bin2hex($response)); +} else { + die("Unable to read the response\n"); +} + +socket_close($socket); +?> +--EXPECTF-- +string(64) "%s"