Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Next

- New option --print-reply-dst to show the destination address of the received reply packet (#461, thanks @gsnw-sebast)
- New option --oiface for outgoing interface (#463, thanks @gsnw-sebast)
- Add --frag option to disable path MTU discovery (#476, thanks @gsnw-sebast)

## Bugfixes and other changes

Expand Down
14 changes: 13 additions & 1 deletion ci/test-03-forbidden.pl
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/perl -w

use Test::Command tests => 39;
use Test::Command tests => 42;
use Test::More;

# fping -i 0
my $cmd1 = Test::Command->new(cmd => "fping -i 0 -T10 -g 127.0.0.1/29");
Expand Down Expand Up @@ -54,6 +55,17 @@ END
$cmd10->stdout_is_eq("");
$cmd10->stderr_is_eq("fping: backoff factor 5.1 not valid, must be between 1.0 and 5.0\n");

# fping -M --frag
SKIP: {
if($^O ne 'linux') {
skip '-M option functionality is only tested on Linux', 3;
}
my $cmd11 = Test::Command->new(cmd => "fping -M --frag 127.0.0.1");
$cmd11->exit_is_num(1);
$cmd11->stdout_is_eq("");
$cmd11->stderr_is_eq("fping: --dontfrag \(-M\) and --frag cannot be used together\n");
}

# non-negative only
for my $arg (qw(i p Q t -seqmap-timeout)) {
my $cmd = Test::Command->new(cmd => "fping -$arg -1");
Expand Down
13 changes: 12 additions & 1 deletion ci/test-07-options-i-m.pl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/perl -w

use Test::Command tests => 31;
use Test::Command tests => 34;
use Test::More;

# -i n interval between sending ping packets (in millisec) (default 25)
Expand Down Expand Up @@ -153,4 +153,15 @@
$cmd->stderr_is_eq("");
}

# fping --frag
SKIP: {
if($^O eq 'darwin') {
skip '--frag option not supported on macOS', 3;
}
my $cmd = Test::Command->new(cmd => "fping --frag 127.0.0.1");
$cmd->exit_is_num(0);
$cmd->stdout_is_eq("127.0.0.1 is alive\n");
$cmd->stderr_is_eq("");
}

# fping -m -> test-14-internet-hosts
4 changes: 4 additions & 0 deletions doc/fping.pod
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,10 @@ is recommended).

Set the "Don't Fragment" bit in the IP header (used to determine/test the MTU).

=item B<--frag>

Set the "Fragment" bit in the IP header.

=item B<-n>, B<--name>

If targets are specified as IP addresses, do a reverse-DNS lookup on them
Expand Down
6 changes: 5 additions & 1 deletion src/flags.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,8 @@ int opt_oiface_on = 0;
int opt_bindiface_on = 0;
int opt_timestamp_on = 0;
int opt_timestamp_format = 0;
int opt_icmp_request_typ = 0;
int opt_icmp_request_typ = 0;
int opt_dontfrag_on = 0;
int opt_frag_on = 0;
int opt_pmtu = 0;
int opt_pmtu_ipv6 = 0;
4 changes: 4 additions & 0 deletions src/flags.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,9 @@ extern int opt_bindiface_on;
extern int opt_timestamp_on;
extern int opt_timestamp_format;
extern int opt_icmp_request_typ;
extern int opt_dontfrag_on;
extern int opt_frag_on;
extern int opt_pmtu;
extern int opt_pmtu_ipv6;

#endif
52 changes: 40 additions & 12 deletions src/fping.c
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,7 @@ int main(int argc, char **argv)
{ "loop", 'l', OPTPARSE_NONE },
{ "all", 'm', OPTPARSE_NONE },
{ "dontfrag", 'M', OPTPARSE_NONE },
{ "frag", 0, OPTPARSE_NONE },
{ "name", 'n', OPTPARSE_NONE },
{ "netdata", 'N', OPTPARSE_NONE },
{ "outage", 'o', OPTPARSE_NONE },
Expand Down Expand Up @@ -623,6 +624,17 @@ int main(int argc, char **argv)
#else
fprintf(stderr, "%s: --oiface is not supported on this platform (IP_PKTINFO unavailable)\n", prog);
exit(3);
#endif
} else if (strstr(optparse_state.optlongname, "frag") != NULL) {
opt_frag_on = 1;
#ifdef IP_MTU_DISCOVER
opt_pmtu = IP_PMTUDISC_DONT;
#ifdef IPV6
opt_pmtu_ipv6 = IPV6_PMTUDISC_DONT;
#endif
#else
fprintf(stderr, "%s: --frag option not supported on this platform\n", prog);
exit(1);
#endif
} else {
usage(1);
Expand Down Expand Up @@ -650,20 +662,11 @@ int main(int argc, char **argv)
#endif
break;
case 'M':
opt_dontfrag_on = 1;
#ifdef IP_MTU_DISCOVER
if (socket4 >= 0) {
int val = IP_PMTUDISC_DO;
if (setsockopt(socket4, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val))) {
perror("setsockopt IP_MTU_DISCOVER");
}
}
opt_pmtu = IP_PMTUDISC_DO;
#ifdef IPV6
if (socket6 >= 0) {
int val = IPV6_PMTUDISC_DO;
if (setsockopt(socket6, IPPROTO_IPV6, IPV6_MTU_DISCOVER, &val, sizeof(val))) {
perror("setsockopt IPV6_MTU_DISCOVER");
}
}
opt_pmtu_ipv6 = IPV6_PMTUDISC_DO;
#endif
#else
fprintf(stderr, "%s, -M option not supported on this platform\n", prog);
Expand Down Expand Up @@ -1009,6 +1012,11 @@ int main(int argc, char **argv)
exit(1);
}

if (opt_dontfrag_on && opt_frag_on) {
fprintf(stderr, "%s: --dontfrag (-M) and --frag cannot be used together\n", prog);
exit(1);
}

if (opt_count_on) {
if (opt_verbose_on)
opt_per_recv_on = 1;
Expand Down Expand Up @@ -1125,6 +1133,25 @@ int main(int argc, char **argv)
#endif
}

#ifdef IP_MTU_DISCOVER
if (opt_pmtu != 0) {
if (socket4 >= 0) {
if (setsockopt(socket4, IPPROTO_IP, IP_MTU_DISCOVER, &opt_pmtu, sizeof(opt_pmtu))) {
perror("setsockopt IP_MTU_DISCOVER (pmtu)");
}
}
}
#ifdef IPV6
if (opt_pmtu_ipv6 != 0) {
if (socket6 >= 0) {
if (setsockopt(socket6, IPPROTO_IPV6, IPV6_MTU_DISCOVER, &opt_pmtu_ipv6, sizeof(opt_pmtu_ipv6))) {
perror("setsockopt IPV6_MTU_DISCOVER (pmtu)");
}
}
}
#endif
#endif

#if HAVE_SO_TIMESTAMPNS
{
int opt = 1;
Expand Down Expand Up @@ -3131,6 +3158,7 @@ void usage(int is_error)
fprintf(out, " -l, --loop loop mode: send pings forever\n");
fprintf(out, " -m, --all use all IPs of provided hostnames (e.g. IPv4 and IPv6), use with -A\n");
fprintf(out, " -M, --dontfrag set the Don't Fragment flag\n");
fprintf(out, " --frag set the Fragment flag\n");
fprintf(out, " -O, --tos=N set the type of service (tos) flag on the ICMP packets\n");
fprintf(out, " -p, --period=MSEC interval between ping packets to one target (in ms)\n");
fprintf(out, " (in loop and count modes, default: %.0f ms)\n", opt_perhost_interval / 1e6);
Expand Down
Loading