(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
#!/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
#!/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
});
}
+# 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');
%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
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
int lose_factor;
#endif /* DEBUG || _DEBUG */
+unsigned int fwmark = 0;
+
char *filename = NULL; /* file containing hosts to ping */
/*** forward declarations ***/
{ "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 },
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 */
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");