git: c4ffb80ef18f - main - ping: Consistently use EX_NOHOST for DNS failures.

From: Dag-Erling Smørgrav <des_at_FreeBSD.org>
Date: Wed, 11 Oct 2023 19:45:35 UTC
The branch main has been updated by des:

URL: https://cgit.FreeBSD.org/src/commit/?id=c4ffb80ef18f6b581dc28c14bc579e0e7c73438c

commit c4ffb80ef18f6b581dc28c14bc579e0e7c73438c
Author:     Dag-Erling Smørgrav <des@FreeBSD.org>
AuthorDate: 2023-10-11 19:44:30 +0000
Commit:     Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2023-10-11 19:44:30 +0000

    ping: Consistently use EX_NOHOST for DNS failures.
    
    Traditionally, ping returned exit code EX_NOHOST if a DNS lookup failed.
    That is still the case for the legacy code in the new merged ping, but
    not for IPv6 targets, nor when a DNS lookup is performed in order to
    determine which version of the tool to invoke.
    
    While here, also make sure that the error message is consistent.
    
    Sponsored by:   NetApp, Inc.
    Sponsored by:   Klara, Inc.
    Reviewed by:    kevans
    Differential Revision:  https://reviews.freebsd.org/D42159
---
 sbin/ping/main.c             | 10 +++++++---
 sbin/ping/ping6.c            |  5 +++--
 sbin/ping/tests/ping_test.sh | 36 ++++++++++++++++++++++++++++++++++++
 3 files changed, 46 insertions(+), 5 deletions(-)

diff --git a/sbin/ping/main.c b/sbin/ping/main.c
index 686b412a19b7..65896a5dba7b 100644
--- a/sbin/ping/main.c
+++ b/sbin/ping/main.c
@@ -41,6 +41,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sysexits.h>
 #include <unistd.h>
 
 #include "main.h"
@@ -94,6 +95,7 @@ main(int argc, char *argv[])
 #endif
 #if defined(INET) && defined(INET6)
 	struct addrinfo hints, *res, *ai;
+	const char *target;
 	int error;
 #endif
 	int opt;
@@ -143,6 +145,7 @@ main(int argc, char *argv[])
 		usage();
 
 #if defined(INET) && defined(INET6)
+	target = argv[argc - 1];
 	memset(&hints, 0, sizeof(hints));
 	hints.ai_socktype = SOCK_RAW;
 	if (feature_present("inet") && !feature_present("inet6"))
@@ -151,9 +154,10 @@ main(int argc, char *argv[])
 		hints.ai_family = AF_INET6;
 	else
 		hints.ai_family = AF_UNSPEC;
-	error = getaddrinfo(argv[argc - 1], NULL, &hints, &res);
+	error = getaddrinfo(target, NULL, &hints, &res);
 	if (res == NULL)
-		errx(1, "%s", gai_strerror(error));
+		errx(EX_NOHOST, "cannot resolve %s: %s",
+		    target, gai_strerror(error));
 	for (ai = res; ai != NULL; ai = ai->ai_next) {
 		if (ai->ai_family == AF_INET) {
 			freeaddrinfo(res);
@@ -165,7 +169,7 @@ main(int argc, char *argv[])
 		}
 	}
 	freeaddrinfo(res);
-	errx(1, "Unknown host");
+	errx(EX_NOHOST, "cannot resolve %s", target);
 #endif
 #ifdef INET
 ping4:
diff --git a/sbin/ping/ping6.c b/sbin/ping/ping6.c
index a71ef8a84aee..10deb57ad6bc 100644
--- a/sbin/ping/ping6.c
+++ b/sbin/ping/ping6.c
@@ -654,14 +654,15 @@ ping6(int argc, char *argv[])
 
 	error = cap_getaddrinfo(capdns, target, NULL, &hints, &res);
 	if (error)
-		errx(1, "%s", gai_strerror(error));
+		errx(EX_NOHOST, "cannot resolve %s: %s",
+		    target, gai_strerror(error));
 	if (res->ai_canonname)
 		hostname = strdup(res->ai_canonname);
 	else
 		hostname = target;
 
 	if (!res->ai_addr)
-		errx(1, "cap_getaddrinfo failed");
+		errx(EX_NOHOST, "cannot resolve %s", target);
 
 	(void)memcpy(&dst, res->ai_addr, res->ai_addrlen);
 
diff --git a/sbin/ping/tests/ping_test.sh b/sbin/ping/tests/ping_test.sh
index 1dff25bd43a6..c30592aa7e2e 100644
--- a/sbin/ping/tests/ping_test.sh
+++ b/sbin/ping/tests/ping_test.sh
@@ -165,6 +165,39 @@ ping6_4_body()
 	    ping6 -4 localhost
 }
 
+atf_test_case ping_nohost
+ping_nohost_head()
+{
+	atf_set "descr" "ping a nonexistent host"
+}
+ping_nohost_body()
+{
+	atf_check -s exit:68 -e match:"cannot resolve" \
+	    ping nonexistent.in-addr.arpa.
+}
+
+atf_test_case ping4_nohost
+ping4_nohost_head()
+{
+	atf_set "descr" "ping -4 a nonexistent host"
+}
+ping4_nohost_body()
+{
+	atf_check -s exit:68 -e match:"cannot resolve" \
+	    ping -4 nonexistent.in-addr.arpa.
+}
+
+atf_test_case ping6_nohost
+ping6_nohost_head()
+{
+	atf_set "descr" "ping -6 a nonexistent host"
+}
+ping6_nohost_body()
+{
+	atf_check -s exit:68 -e match:"cannot resolve" \
+	    ping -6 nonexistent.in-addr.arpa.
+}
+
 atf_test_case "inject_opts" "cleanup"
 inject_opts_head()
 {
@@ -227,6 +260,9 @@ atf_init_test_cases()
 	atf_add_test_case ping_46
 	atf_add_test_case ping_64
 	atf_add_test_case ping6_4
+	atf_add_test_case ping_nohost
+	atf_add_test_case ping4_nohost
+	atf_add_test_case ping6_nohost
 	atf_add_test_case inject_opts
 	atf_add_test_case inject_pip
 	atf_add_test_case inject_reply