Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F137308571
D42137.id128504.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D42137.id128504.diff
View Options
diff --git a/sbin/ping/main.c b/sbin/ping/main.c
--- a/sbin/ping/main.c
+++ b/sbin/ping/main.c
@@ -62,112 +62,99 @@
int
main(int argc, char *argv[])
{
-#if defined(INET) && defined(INET6)
+#if defined(INET)
struct in_addr a;
- struct in6_addr a6;
#endif
-#if defined(INET) || defined(INET6)
- struct addrinfo hints;
+#if defined(INET6)
+ struct in6_addr a6;
#endif
- int ch;
-#ifdef INET
- bool ipv4 = false;
+#if defined(INET) && defined(INET6)
+ struct addrinfo hints, *res, *ai;
+ int error;
#endif
-#ifdef INET6
- bool ipv6 = false;
+ int opt;
+#ifdef INET6
if (strcmp(getprogname(), "ping6") == 0)
- ipv6 = true;
+ return ping6(argc, argv);
#endif
- while ((ch = getopt(argc, argv, ":" OPTSTR)) != -1) {
- switch(ch) {
+ while ((opt = getopt(argc, argv, ":" OPTSTR)) != -1) {
+ switch (opt) {
#ifdef INET
case '4':
- ipv4 = true;
- break;
+ goto ping4;
#endif
#ifdef INET6
case '6':
- ipv6 = true;
- break;
+ goto ping6;
#endif
-#if defined(INET) && defined(INET6)
case 'S':
/*
* If -S is given with a numeric parameter,
* force use of the corresponding version.
*/
+#ifdef INET
if (inet_pton(AF_INET, optarg, &a) == 1)
- ipv4 = true;
- else if (inet_pton(AF_INET6, optarg, &a6) == 1)
- ipv6 = true;
- break;
+ goto ping4;
+#endif
+#ifdef INET6
+ if (inet_pton(AF_INET6, optarg, &a6) == 1)
+ goto ping6;
#endif
+ break;
default:
break;
}
}
+ /*
+ * For IPv4, only one positional argument, the target, is allowed.
+ * For IPv6, multiple positional argument are allowed; the last
+ * one is the target, and preceding ones are intermediate hops.
+ * This nuance is lost here, but the only case where it matters is
+ * an error.
+ */
if (optind >= argc)
usage();
- optreset = 1;
- optind = 1;
#if defined(INET) && defined(INET6)
- if (ipv4 && ipv6)
- errx(1, "-4 and -6 cannot be used simultaneously");
-#endif
-
-#if defined(INET) && defined(INET6)
- if (inet_pton(AF_INET, argv[argc - 1], &a) == 1) {
- if (ipv6)
- errx(1, "IPv6 requested but IPv4 target address "
- "provided");
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_socktype = SOCK_RAW;
+ if (feature_present("inet") && !feature_present("inet6"))
hints.ai_family = AF_INET;
- }
- else if (inet_pton(AF_INET6, argv[argc - 1], &a6) == 1) {
- if (ipv4)
- errx(1, "IPv4 requested but IPv6 target address "
- "provided");
- hints.ai_family = AF_INET6;
- } else if (ipv6)
+ if (feature_present("inet6") && !feature_present("inet"))
hints.ai_family = AF_INET6;
- else if (ipv4)
- hints.ai_family = AF_INET;
- else {
- if (!feature_present("inet6"))
- hints.ai_family = AF_INET;
- else if (!feature_present("inet"))
- hints.ai_family = AF_INET6;
- else {
- struct addrinfo *res;
-
- memset(&hints, 0, sizeof(hints));
- hints.ai_socktype = SOCK_RAW;
- hints.ai_family = AF_UNSPEC;
- getaddrinfo(argv[argc - 1], NULL, &hints, &res);
- if (res != NULL) {
- hints.ai_family = res[0].ai_family;
- freeaddrinfo(res);
- }
+ else
+ hints.ai_family = AF_UNSPEC;
+ error = getaddrinfo(argv[argc - 1], NULL, &hints, &res);
+ if (res == NULL)
+ errx(1, "%s", gai_strerror(error));
+ for (ai = res; ai != NULL; ai = ai->ai_next) {
+ if (ai->ai_family == AF_INET) {
+ freeaddrinfo(res);
+ goto ping4;
+ }
+ if (ai->ai_family == AF_INET6) {
+ freeaddrinfo(res);
+ goto ping6;
}
}
-#elif defined(INET)
- hints.ai_family = AF_INET;
-#elif defined(INET6)
- hints.ai_family = AF_INET6;
+ freeaddrinfo(res);
+ errx(1, "Unknown host");
#endif
-
#ifdef INET
- if (hints.ai_family == AF_INET)
- return ping(argc, argv);
-#endif /* INET */
+ping4:
+ optreset = 1;
+ optind = 1;
+ return ping(argc, argv);
+#endif
#ifdef INET6
- if (hints.ai_family == AF_INET6)
- return ping6(argc, argv);
-#endif /* INET6 */
- errx(1, "Unknown host");
+ping6:
+ optreset = 1;
+ optind = 1;
+ return ping6(argc, argv);
+#endif
}
void
diff --git a/sbin/ping/tests/ping_test.sh b/sbin/ping/tests/ping_test.sh
--- a/sbin/ping/tests/ping_test.sh
+++ b/sbin/ping/tests/ping_test.sh
@@ -135,21 +135,34 @@
require_ipv4
require_ipv6
atf_check -s exit:1 \
- -e match:"-4 and -6 cannot be used simultaneously" \
+ -e match:"illegal option -- 6" \
ping -4 -6 localhost
}
-ping6_46_head()
+ping_64_head()
{
atf_set "descr" "-4 and -6 cannot be used simultaneously"
}
-ping6_46_body()
+ping_64_body()
{
require_ipv4
require_ipv6
atf_check -s exit:1 \
- -e match:"-4 and -6 cannot be used simultaneously" \
- ping6 -4 -6 localhost
+ -e match:"illegal option -- 4" \
+ ping -6 -4 localhost
+}
+
+ping6_4_head()
+{
+ atf_set "descr" "ping6 does not accept -4"
+}
+ping6_4_body()
+{
+ require_ipv4
+ require_ipv6
+ atf_check -s exit:1 \
+ -e match:"illegal option -- 4" \
+ ping6 -4 localhost
}
atf_test_case "inject_opts" "cleanup"
@@ -212,7 +225,8 @@
atf_add_test_case ping_c1t6
atf_add_test_case ping6_c1t4
atf_add_test_case ping_46
- atf_add_test_case ping6_46
+ atf_add_test_case ping_64
+ atf_add_test_case ping6_4
atf_add_test_case inject_opts
atf_add_test_case inject_pip
atf_add_test_case inject_reply
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Nov 23, 7:30 AM (15 h, 41 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
26008187
Default Alt Text
D42137.id128504.diff (5 KB)
Attached To
Mode
D42137: ping: Simplify protocol selection.
Attached
Detach File
Event Timeline
Log In to Comment