]> git.gsnw.org Git - fping.git/commitdiff
check address family consistency in generator
authorErik Auerswald <auerswal@unix-ag.uni-kl.de>
Sun, 12 Jan 2025 09:37:55 +0000 (10:37 +0100)
committerErik Auerswald <auerswal@unix-ag.uni-kl.de>
Sat, 15 Feb 2025 19:02:58 +0000 (20:02 +0100)
Before, "fping -6 -g IPv4_ADDR_SPEC" would generate all requested
IPv4 addresses and try to add them to the host table, but that
would fail because of address family mismatch.

Now, "fping -6 -g IPv4_ADDR_SPEC" detects the problem before
generating any addresses, and fails early.

Mixing IPv4 and IPv6 addresses when using -g START END is detected
before generating any addresses and fails early, too.

ci/test-06-options-f-h.pl
src/fping.c

index c9b520a0276f1e276d896d6c34c475b794decc38..a354ae58977631c8258849d242fa5d76eb9ec039 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/perl -w
 
-use Test::Command tests => 75;
+use Test::Command tests => 102;
 use Test::More;
 use File::Temp;
 
@@ -114,6 +114,14 @@ $cmd->stdout_is_eq("127.0.0.1 is alive\n127.0.0.2 is alive\n127.0.0.3 is alive\n
 $cmd->stderr_is_eq("");
 }
 
+# fping -4 -g (range)
+{
+my $cmd = Test::Command->new(cmd => "fping -4 -g 127.0.0.1 127.0.0.5");
+$cmd->exit_is_num(0);
+$cmd->stdout_is_eq("127.0.0.1 is alive\n127.0.0.2 is alive\n127.0.0.3 is alive\n127.0.0.4 is alive\n127.0.0.5 is alive\n");
+$cmd->stderr_is_eq("");
+}
+
 # fping -g (empty range)
 {
 my $cmd = Test::Command->new(cmd => "fping -g 127.0.0.2 127.0.0.1");
@@ -178,7 +186,51 @@ $cmd->stdout_is_eq("");
 $cmd->stderr_is_eq("fping: -g parameter generates too many addresses\n");
 }
 
+# fping -4 -g (range, wrong address family)
+SKIP: {
+    if($ENV{SKIP_IPV6}) {
+        skip 'Skip IPv6 tests', 3;
+    }
+    my $cmd = Test::Command->new(cmd => "fping -4 -g ::1 ::1");
+    $cmd->exit_is_num(1);
+    $cmd->stdout_is_eq("");
+    $cmd->stderr_like(qr{can't parse address ::1:.*(not supported|not known)});
+}
+
+# fping -6 -g (range, wrong address family)
+SKIP: {
+    if($ENV{SKIP_IPV6}) {
+        skip 'Skip IPv6 tests', 3;
+    }
+    my $cmd = Test::Command->new(cmd => "fping -6 -g 127.0.0.1 127.0.0.1");
+    $cmd->exit_is_num(1);
+    $cmd->stdout_is_eq("");
+    $cmd->stderr_like(qr{can't parse address 127\.0\.0\.1:.*(not supported|not known)});
+}
+
 # fping -g (range - no IPv6 generator)
+SKIP: {
+    if($ENV{SKIP_IPV6}) {
+        skip 'Skip IPv6 tests', 3;
+    }
+    my $cmd = Test::Command->new(cmd => "fping -g ::1 ::1");
+    $cmd->exit_is_num(1);
+    $cmd->stdout_is_eq("");
+    $cmd->stderr_is_eq("fping: -g works only with IPv4 addresses\n");
+}
+
+# fping -g (empty range - no IPv6 generator)
+SKIP: {
+    if($ENV{SKIP_IPV6}) {
+        skip 'Skip IPv6 tests', 3;
+    }
+    my $cmd = Test::Command->new(cmd => "fping -g ::1 ::");
+    $cmd->exit_is_num(1);
+    $cmd->stdout_is_eq("");
+    $cmd->stderr_is_eq("fping: -g works only with IPv4 addresses\n");
+}
+
+# fping -6 -g (range - no IPv6 generator)
 SKIP: {
     if($ENV{SKIP_IPV6}) {
         skip 'Skip IPv6 tests', 3;
@@ -189,7 +241,7 @@ SKIP: {
     $cmd->stderr_is_eq("fping: -g works only with IPv4 addresses\n");
 }
 
-# fping -g (range - no IPv6 generator - start address IPv6)
+# fping -6 -g (range - no IPv6 generator - start address IPv6)
 SKIP: {
     if($ENV{SKIP_IPV6}) {
         skip 'Skip IPv6 tests', 3;
@@ -201,6 +253,17 @@ SKIP: {
 }
 
 # fping -g (range - no IPv6 generator - end address IPv6)
+SKIP: {
+    if($ENV{SKIP_IPV6}) {
+        skip 'Skip IPv6 tests', 3;
+    }
+    my $cmd = Test::Command->new(cmd => "fping -g 127.0.0.1 ::1");
+    $cmd->exit_is_num(1);
+    $cmd->stdout_is_eq("");
+    $cmd->stderr_like(qr{fping: can't parse address ::1: .*\n});
+}
+
+# fping -6 -g (range - no IPv6 generator - end address IPv6)
 SKIP: {
     if($ENV{SKIP_IPV6}) {
         skip 'Skip IPv6 tests', 3;
@@ -208,10 +271,43 @@ SKIP: {
     my $cmd = Test::Command->new(cmd => "fping -6 -g 127.0.0.1 ::1");
     $cmd->exit_is_num(1);
     $cmd->stdout_is_eq("");
-    $cmd->stderr_is_eq("fping: -g works only with IPv4 addresses\n");
+    $cmd->stderr_like(qr{fping: can't parse address 127\.0\.0\.1: .*\n});
+}
+
+# fping -4 -g (cidr, wrong address family)
+SKIP: {
+    if($ENV{SKIP_IPV6}) {
+        skip 'Skip IPv6 tests', 3;
+    }
+    my $cmd = Test::Command->new(cmd => "fping -4 -g ::1/128");
+    $cmd->exit_is_num(1);
+    $cmd->stdout_is_eq("");
+    $cmd->stderr_like(qr{can't parse address ::1:.*(not supported|not known)});
+}
+
+# fping -6 -g (cidr, wrong address family)
+SKIP: {
+    if($ENV{SKIP_IPV6}) {
+        skip 'Skip IPv6 tests', 3;
+    }
+    my $cmd = Test::Command->new(cmd => "fping -6 -g 127.0.0.1/32");
+    $cmd->exit_is_num(1);
+    $cmd->stdout_is_eq("");
+    $cmd->stderr_like(qr{can't parse address 127\.0\.0\.1:.*(not supported|not known)});
 }
 
 # fping -g (CIDR - no IPv6 generator)
+SKIP: {
+    if($ENV{SKIP_IPV6}) {
+        skip 'Skip IPv6 tests', 3;
+    }
+    my $cmd = Test::Command->new(cmd => "fping -g ::1/128");
+    $cmd->exit_is_num(1);
+    $cmd->stdout_is_eq("");
+    $cmd->stderr_is_eq("fping: -g works only with IPv4 addresses\n");
+}
+
+# fping -6 -g (CIDR - no IPv6 generator)
 SKIP: {
     if($ENV{SKIP_IPV6}) {
         skip 'Skip IPv6 tests', 3;
index 01cfc17cf96ace12e6f614538f0c247875e720cd..53ed3823cd262f8f0ec8c0966f32764c2460bbef 100644 (file)
@@ -1315,7 +1315,7 @@ void add_cidr(char *addr)
 
     /* parse address (IPv4 only) */
     memset(&addr_hints, 0, sizeof(struct addrinfo));
-    addr_hints.ai_family = AF_UNSPEC;
+    addr_hints.ai_family = hints_ai_family;
     addr_hints.ai_flags = AI_NUMERICHOST;
     ret = getaddrinfo(addr, NULL, &addr_hints, &addr_res);
     if (ret) {
@@ -1362,7 +1362,7 @@ void add_range(char *start, char *end)
 
     /* parse start address (IPv4 only) */
     memset(&addr_hints, 0, sizeof(struct addrinfo));
-    addr_hints.ai_family = AF_UNSPEC;
+    addr_hints.ai_family = hints_ai_family;
     addr_hints.ai_flags = AI_NUMERICHOST;
     ret = getaddrinfo(start, NULL, &addr_hints, &addr_res);
     if (ret) {
@@ -1374,11 +1374,12 @@ void add_range(char *start, char *end)
         fprintf(stderr, "%s: -g works only with IPv4 addresses\n", prog);
         exit(1);
     }
+    hints_ai_family = addr_res->ai_family;
     start_long = ntohl(((struct sockaddr_in *)addr_res->ai_addr)->sin_addr.s_addr);
 
     /* parse end address (IPv4 only) */
     memset(&addr_hints, 0, sizeof(struct addrinfo));
-    addr_hints.ai_family = AF_UNSPEC;
+    addr_hints.ai_family = hints_ai_family;
     addr_hints.ai_flags = AI_NUMERICHOST;
     ret = getaddrinfo(end, NULL, &addr_hints, &addr_res);
     if (ret) {