mirror of
https://github.com/apache/nuttx-apps.git
synced 2026-08-01 20:29:00 +00:00
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>
This commit is contained in:
parent
e536adaabc
commit
02153debae
1 changed files with 63 additions and 1 deletions
|
|
@ -35,6 +35,15 @@
|
|||
#include <limits.h>
|
||||
#include <fixedmath.h>
|
||||
|
||||
#if defined(CONFIG_SYSTEM_PING6) && defined(CONFIG_LIBC_EXECFUNCS)
|
||||
#define PING_ENABLE_PING6_FALLBACK
|
||||
#endif
|
||||
|
||||
#ifdef PING_ENABLE_PING6_FALLBACK
|
||||
#include <spawn.h>
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
|
||||
#include <nuttx/net/ip.h>
|
||||
|
||||
#include "netutils/icmp_ping.h"
|
||||
|
|
@ -121,8 +130,10 @@ static void ping_result(FAR const struct ping_result_s *result)
|
|||
switch (result->code)
|
||||
{
|
||||
case ICMP_E_HOSTIP:
|
||||
#ifndef PING_ENABLE_PING6_FALLBACK
|
||||
fprintf(stderr, "ERROR: ping_gethostip(%s) failed\n",
|
||||
result->info->hostname);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case ICMP_E_MEMORY:
|
||||
|
|
@ -279,6 +290,49 @@ static void ping_result(FAR const struct ping_result_s *result)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef PING_ENABLE_PING6_FALLBACK
|
||||
/****************************************************************************
|
||||
* Name: ping6_fallback
|
||||
****************************************************************************/
|
||||
|
||||
static int ping6_fallback(int argc, FAR char *argv[])
|
||||
{
|
||||
pid_t pid;
|
||||
int ret;
|
||||
int status;
|
||||
|
||||
if (argc <= 0)
|
||||
{
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
argv[0] = CONFIG_SYSTEM_PING6_PROGNAME;
|
||||
|
||||
ret = posix_spawnp(&pid, CONFIG_SYSTEM_PING6_PROGNAME, NULL, NULL,
|
||||
argv, NULL);
|
||||
if (ret != 0)
|
||||
{
|
||||
fprintf(stderr, "ERROR: posix_spawnp(%s) failed: %d\n",
|
||||
CONFIG_SYSTEM_PING6_PROGNAME, ret);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
ret = waitpid(pid, &status, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
fprintf(stderr, "ERROR: waitpid() failed: %d\n", errno);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (WIFEXITED(status))
|
||||
{
|
||||
return WEXITSTATUS(status);
|
||||
}
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
|
@ -403,7 +457,15 @@ int main(int argc, FAR char *argv[])
|
|||
|
||||
info.hostname = argv[optind];
|
||||
icmp_ping(&info);
|
||||
return priv.code < 0 ? EXIT_FAILURE: EXIT_SUCCESS;
|
||||
|
||||
#ifdef PING_ENABLE_PING6_FALLBACK
|
||||
if (priv.code == ICMP_E_HOSTIP)
|
||||
{
|
||||
return ping6_fallback(argc, argv);
|
||||
}
|
||||
#endif
|
||||
|
||||
return priv.code < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
|
||||
errout_with_usage:
|
||||
optind = 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue