]> git.gsnw.org Git - fping.git/commitdiff
always exclude IP header in returned size
authorDavid Schweikert <david@schweikert.ch>
Sun, 2 Aug 2020 15:48:31 +0000 (17:48 +0200)
committerDavid Schweikert <david@schweikert.ch>
Sun, 2 Aug 2020 16:08:18 +0000 (18:08 +0200)
CHANGELOG.md
ci/test-01-basics.pl
ci/test-05-options-c-e.pl
ci/test-07-options-i-m.pl
src/fping.c

index 2c872ae4aba85262b7071b30a797c5c6bdb2db16..59b9ce2a47ab78b632889770b7b3533eb92f0a03 100644 (file)
@@ -8,15 +8,21 @@ fping 5.0 (unreleased)
 
   ```
   $ fping -D -c2 8.8.8.8 8.8.8.7
-  [1596092373.18423] 8.8.8.8 : [0], 84 bytes, 12.8 ms (12.8 avg, 0% loss)
+  [1596092373.18423] 8.8.8.8 : [0], 64 bytes, 12.8 ms (12.8 avg, 0% loss)
   [1596092374.18223] 8.8.8.7 : [0], timed out (NaN avg, 100% loss)
-  [1596092374.18424] 8.8.8.8 : [1], 84 bytes, 12.3 ms (12.5 avg, 0% loss)
+  [1596092374.18424] 8.8.8.8 : [1], 64 bytes, 12.3 ms (12.5 avg, 0% loss)
   [1596092375.18344] 8.8.8.7 : [1], timed out (NaN avg, 100% loss)
 
   8.8.8.8 : xmt/rcv/%loss = 2/2/0%, min/avg/max = 12.3/12.5/12.8
   8.8.8.7 : xmt/rcv/%loss = 2/0/100%
   ```
 
+- The returned size in bytes now always excludes the IP header, so if before it
+  reported '84 bytes' e.g. when using 'fping -l', now it reports '64 bytes'.
+  This is to make the reported size consistent with ping(8) from iputils and
+  also with fping when pinging a IPv6 host (which never included the IPv6
+  header size).
+
 ## New features
 
 - The number of sent pings is only counted when the pings are received or have
@@ -27,6 +33,10 @@ fping 5.0 (unreleased)
 
 - Improved precision of measurements from 10us to 1us (#136, thanks @tycho)
 
+## Bugfixes and other changes
+
+- The reported size of received packets is now always correct on Linux even for
+  packets > 4096 bytes.
 
 fping 4.4 (2020-07-24)
 ======================
index d3499f34209fcbf9d3243ff9b47edd3eddfe82a7..47f1910131e8fa52e7a941b66c3cb8b9ec1a1530 100755 (executable)
@@ -27,9 +27,9 @@ SKIP: {
 {
     my $cmd = Test::Command->new(cmd => "fping -p 100 -C3 127.0.0.1");
     $cmd->exit_is_num(0);
-    $cmd->stdout_like(qr{127\.0\.0\.1 : \[0\], 84 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
-127\.0\.0\.1 : \[1\], 84 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
-127\.0\.0\.1 : \[2\], 84 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
+    $cmd->stdout_like(qr{127\.0\.0\.1 : \[0\], 64 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
+127\.0\.0\.1 : \[1\], 64 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
+127\.0\.0\.1 : \[2\], 64 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
 });
     $cmd->stderr_like(qr{127\.0\.0\.1 : \d\.\d+ \d\.\d+ \d\.\d+\n});
 }
index 536f3adb622f5a1a26c9afeb9f7f88d89192c169..7c3b0ac1d4cc99f9c4677a37a02ddef6efa8dca1 100755 (executable)
@@ -11,10 +11,10 @@ use Test::Command tests => 12;
 {
 my $cmd = Test::Command->new(cmd => "fping -4 -c 2 -p 100 localhost 127.0.0.1");
 $cmd->exit_is_num(0);
-$cmd->stdout_like(qr{localhost : \[0\], 84 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
-127\.0\.0\.1 : \[0\], 84 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
-localhost : \[1\], 84 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
-127\.0\.0\.1 : \[1\], 84 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
+$cmd->stdout_like(qr{localhost : \[0\], 64 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
+127\.0\.0\.1 : \[0\], 64 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
+localhost : \[1\], 64 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
+127\.0\.0\.1 : \[1\], 64 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
 });
 
 $cmd->stderr_like(qr{localhost : xmt/rcv/%loss = 2/2/0%, min/avg/max = \d\.\d+/\d\.\d+/\d\.\d+
@@ -26,10 +26,10 @@ $cmd->stderr_like(qr{localhost : xmt/rcv/%loss = 2/2/0%, min/avg/max = \d\.\d+/\
 {
 my $cmd = Test::Command->new(cmd => "fping -4 -C 2 -p 100 localhost 127.0.0.1");
 $cmd->exit_is_num(0);
-$cmd->stdout_like(qr{localhost : \[0\], 84 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
-127\.0\.0\.1 : \[0\], 84 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
-localhost : \[1\], 84 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
-127\.0\.0\.1 : \[1\], 84 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
+$cmd->stdout_like(qr{localhost : \[0\], 64 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
+127\.0\.0\.1 : \[0\], 64 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
+localhost : \[1\], 64 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
+127\.0\.0\.1 : \[1\], 64 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
 });
 
 $cmd->stderr_like(qr{localhost : \d\.\d+ \d\.\d+
@@ -41,8 +41,8 @@ $cmd->stderr_like(qr{localhost : \d\.\d+ \d\.\d+
 {
 my $cmd = Test::Command->new(cmd => "fping -D -c 2 -p 100 127.0.0.1");
 $cmd->exit_is_num(0);
-$cmd->stdout_like(qr{\[\d+\.\d+\] 127\.0\.0\.1 : \[0\], 84 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
-\[\d+\.\d+\] 127\.0\.0\.1 : \[1\], 84 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
+$cmd->stdout_like(qr{\[\d+\.\d+\] 127\.0\.0\.1 : \[0\], 64 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
+\[\d+\.\d+\] 127\.0\.0\.1 : \[1\], 64 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
 });
 
 $cmd->stderr_like(qr{127\.0\.0\.1 : xmt/rcv/%loss = 2/2/0%, min/avg/max = \d\.\d+/\d\.\d+/\d\.\d+
index 6ba20de1e7748e51dd310678f3f54cdbec4784b0..781377fc6af46b60c9a32589409fafad93869c7f 100755 (executable)
@@ -19,19 +19,19 @@ $cmd->stderr_is_eq("");
 # fping -l
 {
 my $cmd = Test::Command->new(cmd => '(sleep 2; pkill fping)& fping -p 900 -l 127.0.0.1');
-$cmd->stdout_like(qr{127\.0\.0\.1 : \[0\], 84 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
-127\.0\.0\.1 : \[1\], 84 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
+$cmd->stdout_like(qr{127\.0\.0\.1 : \[0\], 64 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
+127\.0\.0\.1 : \[1\], 64 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
 });
 }
 
 # fping -l with SIGQUIT
 {
 my $cmd = Test::Command->new(cmd => '(sleep 2; pkill -QUIT fping; sleep 2; pkill fping)& fping -p 900 -l 127.0.0.1');
-$cmd->stdout_like(qr{127\.0\.0\.1 : \[0\], 84 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
-127\.0\.0\.1 : \[1\], 84 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
-127\.0\.0\.1 : \[2\], 84 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
-127\.0\.0\.1 : \[3\], 84 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
-127\.0\.0\.1 : \[4\], 84 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
+$cmd->stdout_like(qr{127\.0\.0\.1 : \[0\], 64 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
+127\.0\.0\.1 : \[1\], 64 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
+127\.0\.0\.1 : \[2\], 64 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
+127\.0\.0\.1 : \[3\], 64 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
+127\.0\.0\.1 : \[4\], 64 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
 });
 $cmd->stderr_like(qr{\[\d+:\d+:\d+\]
 127\.0\.0\.1 : xmt/rcv/%loss = \d+/\d+/\d+%, min/avg/max = \d+\.\d+/\d+\.\d+/\d+\.\d+
index cab4af1ecf340c6ab3472bed3fb9059505568062..0b8d780db1df469d4cd6d03c4bf123292ccccb06 100644 (file)
@@ -95,6 +95,15 @@ extern "C" {
 #define AI_UNUSABLE 0
 #endif
 
+/* MSG_TRUNC available on Linux kernel 2.2+, makes recvmsg return the full
+ * length of the raw packet received, even if the buffer is smaller */
+#ifndef MSG_TRUNC
+#define MSG_TRUNC 0
+#define RECV_BUFSIZE 4096
+#else
+#define RECV_BUFSIZE 128
+#endif
+
 /*** externals ***/
 
 extern char* optarg;
@@ -1925,7 +1934,7 @@ int receive_packet(int64_t wait_time,
         return 0; /* timeout */
     }
 
-    recv_len = recvmsg(s, &recv_msghdr, 0);
+    recv_len = recvmsg(s, &recv_msghdr, MSG_TRUNC);
     if (recv_len <= 0) {
         return 0;
     }
@@ -1936,7 +1945,8 @@ int receive_packet(int64_t wait_time,
         struct timespec reply_timestamp_ts;
         for (cmsg = CMSG_FIRSTHDR(&recv_msghdr);
              cmsg != NULL;
-             cmsg = CMSG_NXTHDR(&recv_msghdr, cmsg)) {
+             cmsg = CMSG_NXTHDR(&recv_msghdr, cmsg))
+        {
             if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_TIMESTAMPNS) {
                 memcpy(&reply_timestamp_ts, CMSG_DATA(cmsg), sizeof(reply_timestamp_ts));
                 *reply_timestamp = timespec_ns(&reply_timestamp_ts);
@@ -2044,6 +2054,7 @@ int decode_icmp_ipv4(
 #endif
     }
 
+
     if (reply_buf_len < hlen + ICMP_MINLEN) {
         /* too short */
         if (verbose_flag) {
@@ -2051,7 +2062,7 @@ int decode_icmp_ipv4(
             getnameinfo((struct sockaddr*)&response_addr, sizeof(response_addr), buf, INET6_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST);
             printf("received packet too short for ICMP (%d bytes from %s)\n", (int)reply_buf_len, buf);
         }
-        return 0;
+        return -1;
     }
 
     icp = (struct icmp*)(reply_buf + hlen);
@@ -2066,19 +2077,19 @@ int decode_icmp_ipv4(
         /* reply icmp packet (hlen + ICMP_MINLEN) followed by "sent packet" (ip + icmp headers) */
         if (reply_buf_len < hlen + ICMP_MINLEN + sizeof(struct ip) + ICMP_MINLEN) {
             /* discard ICMP message if we can't tell that it was caused by us (i.e. if the "sent packet" is not included). */
-            return 0;
+            return -1;
         }
 
         sent_icmp = (struct icmp*)(reply_buf + hlen + ICMP_MINLEN + sizeof(struct ip));
 
         if (sent_icmp->icmp_type != ICMP_ECHO || sent_icmp->icmp_id != ident4) {
             /* not caused by us */
-            return 0;
+            return -1;
         }
 
         seqmap_value = seqmap_fetch(ntohs(sent_icmp->icmp_seq), current_time_ns);
         if (seqmap_value == NULL) {
-            return 0;
+            return -1;
         }
 
         getnameinfo(response_addr, response_addr_len, addr_ascii, INET6_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST);
@@ -2117,13 +2128,13 @@ int decode_icmp_ipv4(
             break;
         }
 
-        return 0;
+        return -1;
     }
 
     *id = icp->icmp_id;
     *seq = ntohs(icp->icmp_seq);
 
-    return 1;
+    return hlen;
 }
 
 #ifdef IPV6
@@ -2222,7 +2233,7 @@ int decode_icmp_ipv6(
 int wait_for_reply(int64_t wait_time)
 {
     int result;
-    static char buffer[4096];
+    static char buffer[RECV_BUFSIZE];
     struct sockaddr_storage response_addr;
     int n, avg;
     HOST_ENTRY* h;
@@ -2251,21 +2262,23 @@ int wait_for_reply(int64_t wait_time)
 
     /* Process ICMP packet and retrieve id/seq */
     if (response_addr.ss_family == AF_INET) {
-        if (!decode_icmp_ipv4(
+        int ip_hlen = decode_icmp_ipv4(
                 (struct sockaddr*)&response_addr,
                 sizeof(response_addr),
                 buffer,
                 sizeof(buffer),
                 &id,
-                &seq)) {
+                &seq);
+        if (ip_hlen < 0) {
             return 1;
         }
         if (id != ident4) {
             return 1; /* packet received, but not the one we are looking for! */
         }
-        if (using_sock_dgram4) {
-            /* IP header is not included in read SOCK_DGRAM ICMP responses */
-            result += sizeof(struct ip);
+        if (!using_sock_dgram4) {
+            /* do not include IP header in returned size, to be consistent with ping(8) and also
+             * with fping with IPv6 hosts */
+            result -= ip_hlen;
         }
     }
 #ifdef IPV6