always exclude IP header in returned size

pull/196/head
David Schweikert 4 years ago
parent 43f6e3498e
commit a136764f8c

@ -8,15 +8,21 @@ fping 5.0 (unreleased)
``` ```
$ fping -D -c2 8.8.8.8 8.8.8.7 $ 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.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) [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.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% 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 ## New features
- The number of sent pings is only counted when the pings are received or have - 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) - 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) fping 4.4 (2020-07-24)
====================== ======================

@ -27,9 +27,9 @@ SKIP: {
{ {
my $cmd = Test::Command->new(cmd => "fping -p 100 -C3 127.0.0.1"); my $cmd = Test::Command->new(cmd => "fping -p 100 -C3 127.0.0.1");
$cmd->exit_is_num(0); $cmd->exit_is_num(0);
$cmd->stdout_like(qr{127\.0\.0\.1 : \[0\], 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\], 84 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\], 84 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}); $cmd->stderr_like(qr{127\.0\.0\.1 : \d\.\d+ \d\.\d+ \d\.\d+\n});
} }

@ -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"); my $cmd = Test::Command->new(cmd => "fping -4 -c 2 -p 100 localhost 127.0.0.1");
$cmd->exit_is_num(0); $cmd->exit_is_num(0);
$cmd->stdout_like(qr{localhost : \[0\], 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\], 84 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\], 84 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\], 84 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+ $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"); my $cmd = Test::Command->new(cmd => "fping -4 -C 2 -p 100 localhost 127.0.0.1");
$cmd->exit_is_num(0); $cmd->exit_is_num(0);
$cmd->stdout_like(qr{localhost : \[0\], 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\], 84 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\], 84 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\], 84 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+ $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"); my $cmd = Test::Command->new(cmd => "fping -D -c 2 -p 100 127.0.0.1");
$cmd->exit_is_num(0); $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\) $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\], 84 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+ $cmd->stderr_like(qr{127\.0\.0\.1 : xmt/rcv/%loss = 2/2/0%, min/avg/max = \d\.\d+/\d\.\d+/\d\.\d+

@ -19,19 +19,19 @@ $cmd->stderr_is_eq("");
# fping -l # fping -l
{ {
my $cmd = Test::Command->new(cmd => '(sleep 2; pkill fping)& fping -p 900 -l 127.0.0.1'); 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\) $cmd->stdout_like(qr{127\.0\.0\.1 : \[0\], 64 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 : \[1\], 64 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
}); });
} }
# fping -l with SIGQUIT # 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'); 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\) $cmd->stdout_like(qr{127\.0\.0\.1 : \[0\], 64 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 : \[1\], 64 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 : \[2\], 64 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 : \[3\], 64 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0% loss\)
127\.0\.0\.1 : \[4\], 84 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+\] $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+ 127\.0\.0\.1 : xmt/rcv/%loss = \d+/\d+/\d+%, min/avg/max = \d+\.\d+/\d+\.\d+/\d+\.\d+

@ -95,6 +95,15 @@ extern "C" {
#define AI_UNUSABLE 0 #define AI_UNUSABLE 0
#endif #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 ***/ /*** externals ***/
extern char* optarg; extern char* optarg;
@ -1925,7 +1934,7 @@ int receive_packet(int64_t wait_time,
return 0; /* timeout */ return 0; /* timeout */
} }
recv_len = recvmsg(s, &recv_msghdr, 0); recv_len = recvmsg(s, &recv_msghdr, MSG_TRUNC);
if (recv_len <= 0) { if (recv_len <= 0) {
return 0; return 0;
} }
@ -1936,7 +1945,8 @@ int receive_packet(int64_t wait_time,
struct timespec reply_timestamp_ts; struct timespec reply_timestamp_ts;
for (cmsg = CMSG_FIRSTHDR(&recv_msghdr); for (cmsg = CMSG_FIRSTHDR(&recv_msghdr);
cmsg != NULL; 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) { if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_TIMESTAMPNS) {
memcpy(&reply_timestamp_ts, CMSG_DATA(cmsg), sizeof(reply_timestamp_ts)); memcpy(&reply_timestamp_ts, CMSG_DATA(cmsg), sizeof(reply_timestamp_ts));
*reply_timestamp = timespec_ns(&reply_timestamp_ts); *reply_timestamp = timespec_ns(&reply_timestamp_ts);
@ -2044,6 +2054,7 @@ int decode_icmp_ipv4(
#endif #endif
} }
if (reply_buf_len < hlen + ICMP_MINLEN) { if (reply_buf_len < hlen + ICMP_MINLEN) {
/* too short */ /* too short */
if (verbose_flag) { 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); 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); 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); 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) */ /* 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) { 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). */ /* 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)); sent_icmp = (struct icmp*)(reply_buf + hlen + ICMP_MINLEN + sizeof(struct ip));
if (sent_icmp->icmp_type != ICMP_ECHO || sent_icmp->icmp_id != ident4) { if (sent_icmp->icmp_type != ICMP_ECHO || sent_icmp->icmp_id != ident4) {
/* not caused by us */ /* not caused by us */
return 0; return -1;
} }
seqmap_value = seqmap_fetch(ntohs(sent_icmp->icmp_seq), current_time_ns); seqmap_value = seqmap_fetch(ntohs(sent_icmp->icmp_seq), current_time_ns);
if (seqmap_value == NULL) { if (seqmap_value == NULL) {
return 0; return -1;
} }
getnameinfo(response_addr, response_addr_len, addr_ascii, INET6_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST); getnameinfo(response_addr, response_addr_len, addr_ascii, INET6_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST);
@ -2117,13 +2128,13 @@ int decode_icmp_ipv4(
break; break;
} }
return 0; return -1;
} }
*id = icp->icmp_id; *id = icp->icmp_id;
*seq = ntohs(icp->icmp_seq); *seq = ntohs(icp->icmp_seq);
return 1; return hlen;
} }
#ifdef IPV6 #ifdef IPV6
@ -2222,7 +2233,7 @@ int decode_icmp_ipv6(
int wait_for_reply(int64_t wait_time) int wait_for_reply(int64_t wait_time)
{ {
int result; int result;
static char buffer[4096]; static char buffer[RECV_BUFSIZE];
struct sockaddr_storage response_addr; struct sockaddr_storage response_addr;
int n, avg; int n, avg;
HOST_ENTRY* h; HOST_ENTRY* h;
@ -2251,21 +2262,23 @@ int wait_for_reply(int64_t wait_time)
/* Process ICMP packet and retrieve id/seq */ /* Process ICMP packet and retrieve id/seq */
if (response_addr.ss_family == AF_INET) { if (response_addr.ss_family == AF_INET) {
if (!decode_icmp_ipv4( int ip_hlen = decode_icmp_ipv4(
(struct sockaddr*)&response_addr, (struct sockaddr*)&response_addr,
sizeof(response_addr), sizeof(response_addr),
buffer, buffer,
sizeof(buffer), sizeof(buffer),
&id, &id,
&seq)) { &seq);
if (ip_hlen < 0) {
return 1; return 1;
} }
if (id != ident4) { if (id != ident4) {
return 1; /* packet received, but not the one we are looking for! */ return 1; /* packet received, but not the one we are looking for! */
} }
if (using_sock_dgram4) { if (!using_sock_dgram4) {
/* IP header is not included in read SOCK_DGRAM ICMP responses */ /* do not include IP header in returned size, to be consistent with ping(8) and also
result += sizeof(struct ip); * with fping with IPv6 hosts */
result -= ip_hlen;
} }
} }
#ifdef IPV6 #ifdef IPV6

Loading…
Cancel
Save