Add --fwmark/-k option for Linux

pull/293/head
deepkv 11 months ago committed by David Schweikert
parent a3f4c573bf
commit c8e9632150

@ -28,13 +28,14 @@ If you want to install fping from source, proceed as follows:
(see: `./configure --help`)
2. Run `make; make install`.
3. Make fping either setuid, or, if under Linux:
`sudo setcap cap_net_raw+ep fping`
`sudo setcap cap_net_raw,cap_net_admin+ep fping`
If you can't run fping as root or can't use the cap_net_raw capability, you can
also run fping in unprivileged mode. This works on MacOS and also on Linux,
provided that your GID is included in the range defined in
`/proc/sys/net/ipv4/ping_group_range`. This is particularly useful for running
fping in rootless / unprivileged containers.
fping in rootless / unprivileged containers. The --fwmark option needs root or
cap_net_admin. setuid will not work for --fwmark.
## Usage

@ -1,6 +1,6 @@
#!/bin/bash
sudo setcap cap_net_raw+ep src/fping
sudo setcap cap_net_raw,cap_net_admin+ep src/fping
if [[ ! $PATH =~ fping/src ]]; then
PATH=/home/dws/checkouts/fping/src:$PATH

@ -1,10 +1,11 @@
#!/usr/bin/perl -w
use Test::Command tests => 9;
use Test::Command tests => 12;
use Test::More;
# -i n interval between sending ping packets (in millisec) (default 25)
# -l loop sending pings forever
# -k set fwmark on ping packets
# -m ping multiple interfaces on target host
# -M don't fragment
@ -24,6 +25,17 @@ $cmd->stdout_like(qr{127\.0\.0\.1 : \[0\], 64 bytes, \d\.\d+ ms \(\d\.\d+ avg, 0
});
}
# fping -k
SKIP: {
if($^O ne 'linux') {
skip '-k option is only supported on Linux', 3;
}
my $cmd = Test::Command->new(cmd => 'sudo env "PATH=$PATH" fping -k 256 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 -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');

@ -54,8 +54,8 @@ rm -rf $RPM_BUILD_ROOT
%post
if [ -x /usr/sbin/setcap ]; then
/bin/chmod 0755 /usr/sbin/fping*
/usr/sbin/setcap cap_net_raw+ep /usr/sbin/fping
/usr/sbin/setcap cap_net_raw+ep /usr/sbin/fping6
/usr/sbin/setcap cap_net_raw,cap_net_admin+ep /usr/sbin/fping
/usr/sbin/setcap cap_net_raw,cap_net_admin+ep /usr/sbin/fping6
fi
%changelog

@ -130,6 +130,11 @@ to any target (default is 10, minimum is 1).
Set the interface (requires SO_BINDTODEVICE support).
=item B<-k>, B<--fwmark>=I<FWMARK>
Set FWMARK on ping packets for policy-based routing. Requires Linux kernel
2.6.25<=, and root privileges or cap_net_admin.
=item B<-l>, B<--loop>
Loop sending packets to each target indefinitely. Can be interrupted with

@ -363,6 +363,8 @@ int randomly_lose_flag, trace_flag, print_per_system_flag;
int lose_factor;
#endif /* DEBUG || _DEBUG */
unsigned int fwmark = 0;
char *filename = NULL; /* file containing hosts to ping */
/*** forward declarations ***/
@ -518,6 +520,9 @@ int main(int argc, char **argv)
{ "ttl", 'H', OPTPARSE_REQUIRED },
{ "interval", 'i', OPTPARSE_REQUIRED },
{ "iface", 'I', OPTPARSE_REQUIRED },
#ifdef SO_MARK
{ "fwmark", 'k', OPTPARSE_REQUIRED },
#endif
{ "loop", 'l', OPTPARSE_NONE },
{ "all", 'm', OPTPARSE_NONE },
{ "dontfrag", 'M', OPTPARSE_NONE },
@ -761,6 +766,23 @@ int main(int argc, char **argv)
case 'f':
filename = optparse_state.optarg;
break;
#ifdef SO_MARK
case 'k':
if (!(fwmark = (unsigned int)atol(optparse_state.optarg)))
usage(1);
if (socket4 >= 0)
if(-1 == setsockopt(socket4, SOL_SOCKET, SO_MARK, &fwmark, sizeof fwmark))
perror("fwmark ipv4");
#ifdef IPV6
if (socket6 >= 0)
if(-1 == setsockopt(socket6, SOL_SOCKET, SO_MARK, &fwmark, sizeof fwmark))
perror("fwmark ipv6");
#endif
break;
#endif
case 'g':
/* use IP list generation */
@ -2923,6 +2945,9 @@ void usage(int is_error)
fprintf(out, " -H, --ttl=N set the IP TTL value (Time To Live hops)\n");
#ifdef SO_BINDTODEVICE
fprintf(out, " -I, --iface=IFACE bind to a particular interface\n");
#endif
#ifdef SO_MARK
fprintf(out, " -k, --fwmark=FWMARK set the routing mark\n");
#endif
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");

Loading…
Cancel
Save