Closed Yenya closed 1 month ago
It seems as if SOCK_DGRAM
does not work as well as SOCK_RAW
for fping
when using the kernel Linux, according to the test failures.
Since this would introduce a regression (i.e., losing the functionality to ping IPv6 multicast groups), without introducing a clear improvement, I plan to close this pull request (no idea when, yet).
At least in my tests on GNU/Linux, when fping 224.0.0.1
works, it does so for both privileged SOCK_RAW
and unprivileged SOCK_DGRAM
. The reply to an Echo request to a multicast IP address uses a unicast IP address as source, i.e., it comes from a different IP address. This also holds for the iputils ping
program. Thus using SOCK_DGRAM
does not necessarily solve the identification problem on busy monitoring hosts.
The iputils ping
program shows the same problem as fping
with your pull request, i.e., it cannot ping IPv6 multicast addresses, even with privileges (cap_net_raw+ep
).
The ping
program from GNU Inetutils prefers SOCK_RAW
similar to fping
. For IPv4 multicast, the observable results are comparable to those of fping
and iputils ping
. The ping6
program from GNU Inetutils does not fall back to SOCK_DGRAM
and therefore does not show the multicast problem (but it does not work without privileges).
According to a StackExchange answer, Apple's ping
program uses a raw socket when started with root privileges, otherwise a datagram socket. This is supposedly done to allow extra functionality with root privileges.
I'd say that fping
should prefer using a raw socket if possible (e.g., started by root
, binary with set SUID bit, or binary with NET_CAP_RAW
), and only fall back to a datagram socket if it cannot open a raw socket.
ping(8) from iputils-20240117 prefers SOCK_DGRAM instead of SOCK_RAW, which has a bonus of using kernel-assigned Identification. Apart from unprivileged operations, this also avoids collisions caused by user-assigned Identification on busy monitoring hosts (see also: birthday paradox).
So let's try SOCK_DGRAM first, and only if that fails, fall back to SOCK_RAW.