```
   $ 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
 
 - 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)
 ======================
 
 {
     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});
 }
 
 {
 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+
 {
 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+
 {
 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+
 
 # 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+
 
 #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;
         return 0; /* timeout */
     }
 
-    recv_len = recvmsg(s, &recv_msghdr, 0);
+    recv_len = recvmsg(s, &recv_msghdr, MSG_TRUNC);
     if (recv_len <= 0) {
         return 0;
     }
         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);
 #endif
     }
 
+
     if (reply_buf_len < hlen + ICMP_MINLEN) {
         /* too short */
         if (verbose_flag) {
             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);
         /* 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);
             break;
         }
 
-        return 0;
+        return -1;
     }
 
     *id = icp->icmp_id;
     *seq = ntohs(icp->icmp_seq);
 
-    return 1;
+    return hlen;
 }
 
 #ifdef 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;
 
     /* 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