Skip to content

Commit 3e93bf7

Browse files
ankohuumasc2008
authored andcommitted
system/ping: Fallback to ping6 for gethost error handling.
When ping only receives an IPv6 DNS response, the current command reports "ping_gethostip" and exits even though ping6 can still handle the target. Keep the existing ping and ping6 netutils interfaces unchanged and add a one-way fallback in the ping command. If IPv4 name resolution fails, ping will spawn ping6 with the same arguments and let ping6 report the final result. Signed-off-by: Shunchao Hu <ankohuu@gmail.com>
1 parent 96a0030 commit 3e93bf7

File tree

1 file changed

+70
-1
lines changed

1 file changed

+70
-1
lines changed

system/ping/ping.c

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@
3535
#include <limits.h>
3636
#include <fixedmath.h>
3737

38+
#if defined(CONFIG_SYSTEM_PING6) && defined(CONFIG_LIBC_EXECFUNCS)
39+
#include <spawn.h>
40+
#include <sys/wait.h>
41+
#endif
42+
3843
#include <nuttx/net/ip.h>
3944

4045
#include "netutils/icmp_ping.h"
@@ -121,8 +126,10 @@ static void ping_result(FAR const struct ping_result_s *result)
121126
switch (result->code)
122127
{
123128
case ICMP_E_HOSTIP:
129+
#ifndef CONFIG_SYSTEM_PING6
124130
fprintf(stderr, "ERROR: ping_gethostip(%s) failed\n",
125131
result->info->hostname);
132+
#endif
126133
break;
127134

128135
case ICMP_E_MEMORY:
@@ -279,6 +286,60 @@ static void ping_result(FAR const struct ping_result_s *result)
279286
}
280287
}
281288

289+
#if defined(CONFIG_SYSTEM_PING6) && defined(CONFIG_LIBC_EXECFUNCS)
290+
/****************************************************************************
291+
* Name: ping6_fallback
292+
****************************************************************************/
293+
294+
static int ping6_fallback(int argc, FAR char *argv[])
295+
{
296+
FAR char **child_argv;
297+
pid_t pid;
298+
int ret;
299+
int status;
300+
int i;
301+
302+
child_argv = malloc(sizeof(FAR char *) * (argc + 1));
303+
if (child_argv == NULL)
304+
{
305+
fprintf(stderr, "ERROR: Failed to allocate fallback argv\n");
306+
return EXIT_FAILURE;
307+
}
308+
309+
child_argv[0] = CONFIG_SYSTEM_PING6_PROGNAME;
310+
for (i = 1; i < argc; i++)
311+
{
312+
child_argv[i] = argv[i];
313+
}
314+
315+
child_argv[argc] = NULL;
316+
317+
ret = posix_spawnp(&pid, CONFIG_SYSTEM_PING6_PROGNAME, NULL, NULL,
318+
child_argv, NULL);
319+
free(child_argv);
320+
if (ret != 0)
321+
{
322+
fprintf(stderr, "ERROR: posix_spawnp(%s) failed: %d\n",
323+
CONFIG_SYSTEM_PING6_PROGNAME, ret);
324+
return EXIT_FAILURE;
325+
}
326+
327+
ret = waitpid(pid, &status, 0);
328+
if (ret < 0)
329+
{
330+
fprintf(stderr, "ERROR: waitpid() failed: %d\n", errno);
331+
return EXIT_FAILURE;
332+
}
333+
334+
if (WIFEXITED(status))
335+
{
336+
return WEXITSTATUS(status);
337+
}
338+
339+
return EXIT_FAILURE;
340+
}
341+
#endif
342+
282343
/****************************************************************************
283344
* Public Functions
284345
****************************************************************************/
@@ -403,7 +464,15 @@ int main(int argc, FAR char *argv[])
403464

404465
info.hostname = argv[optind];
405466
icmp_ping(&info);
406-
return priv.code < 0 ? EXIT_FAILURE: EXIT_SUCCESS;
467+
468+
#if defined(CONFIG_SYSTEM_PING6) && defined(CONFIG_LIBC_EXECFUNCS)
469+
if (priv.code == ICMP_E_HOSTIP)
470+
{
471+
return ping6_fallback(argc, argv);
472+
}
473+
#endif
474+
475+
return priv.code < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
407476

408477
errout_with_usage:
409478
optind = 0;

0 commit comments

Comments
 (0)