fping icon indicating copy to clipboard operation
fping copied to clipboard

No error message when `getprotobyname()` fails

Open auerswal opened this issue 4 months ago • 1 comments

As mentioned in issue #201, fping does not print an error message when getprotobyname() for icmp or ipv6-icmp fails and fping cannot create a socket. It also directly fails, because it calls the crash_and_burn() function:

$ section --with-filename --separator getprotobyname src/socket[46].c
src/socket4.c:    if ((proto = getprotobyname("icmp")) == NULL)
src/socket4.c:        crash_and_burn("icmp: unknown protocol");
--
src/socket6.c:    if ((proto = getprotobyname("ipv6-icmp")) == NULL)
src/socket6.c:        crash_and_burn("icmp: unknown protocol");
$ section --ignore-re '^[{}]?$' --with-filename 'void crash_and_burn\(.*\)$' src/fping.c
src/fping.c:void crash_and_burn(char *message)
src/fping.c:{
src/fping.c:    if (verbose_flag)
src/fping.c:        fprintf(stderr, "%s: %s\n", prog, message);
src/fping.c:
src/fping.c:    exit(4);
src/fping.c:}
src/fping.c:

While crash_and_burn() can output an error message, it does so only when the verbose_flag is non-zero. This variable is implicitly initialized to 0 at program start, then set to 1 after successful socket creation and before option parsing. Thus it is always 0 if socket creation fails, resulting in no error message.

A quick and dirty "fix" would be to set verbose_flag to 1 before socket creation.

A probably better fix could be to use fputs() or fprintf() to generate an error message, before calling exit(4), i.e., open coding a variant of the crash_and_burn() function that does not look at verbose_flag. Instead of an open coded crash_and_burn(), the crash_and_burn() function could be changed to take the verbose_flag as an additional argument (this would require adjusting all call sites, of course).

A more comprehensive approach could be to return a negative value, e.g. -1, from the socket creation function, when getprotobyname() fails. After option parsing, fping already checks if it could open at least one socket, and fails (in general with an error message) if it could not do so. But, this would require extensive testing, since it would introduce the possibility that IPv6-enabled fping would continue running with only one socket, either IPv4 or IPv6, when it currently requires both sockets to be available. Testing this is not trivial, because it would need an appropriately prepared test environment where getprotobyname("icmp") and/or getprotobyname("ipv6-icmp") fail in every possible combination.

auerswal avatar Feb 17 '24 16:02 auerswal