Implement new fping options for fping 5.2 and 5.3

fping 5.2 and 5.3 add some new useful command line options
which this commit add to check_fping.

These are:

 * --fwmark - sets a firewall mark in the packages to make them
   identifiable (fping 5.2)
 * --icmp-timestamp - fping uses ICMP timestamp instead of ICMP
   Echo (fping 5.2)
 * --check-source - fping discards replies which originate not from
   the target address (fping 5.2)

The fping release notes describe theses options ( https://github.com/schweikert/fping/releases )
in a little bit more detail.
Currently the help display for those options is only shown
when fping was available in the appropriate version during
compilation.
This commit is contained in:
Lorenz Kästle 2025-06-12 11:13:59 +02:00
parent 88683af1da
commit 7247fc656a
2 changed files with 96 additions and 8 deletions

View file

@ -117,8 +117,26 @@ int main(int argc, char **argv) {
xasprintf(&option_string, "%s-R ", option_string);
}
if (config.fwmark_set) {
xasprintf(&option_string, "%s--fwmark %u ", option_string, config.fwmark);
}
if (config.icmp_timestamp) {
xasprintf(&option_string, "%s--icmp-timestamp ", option_string);
}
if (config.check_source) {
xasprintf(&option_string, "%s--check-source ", option_string);
}
char *command_line = NULL;
xasprintf(&command_line, "%s %s-b %d -c %d %s", fping_prog, option_string, config.packet_size, config.packet_count, server);
if (config.icmp_timestamp) {
// no paket size settable for ICMP timestamp
xasprintf(&command_line, "%s %s -c %d %s", fping_prog, option_string, config.packet_count, server);
} else {
xasprintf(&command_line, "%s %s-b %d -c %d %s", fping_prog, option_string, config.packet_size, config.packet_count, server);
}
if (verbose) {
printf("%s\n", command_line);
@ -275,13 +293,35 @@ mp_state_enum textscan(char *buf, const char *server_name, bool crta_p, double c
/* process command-line arguments */
check_fping_config_wrapper process_arguments(int argc, char **argv) {
static struct option longopts[] = {
{"hostname", required_argument, 0, 'H'}, {"sourceip", required_argument, 0, 'S'}, {"sourceif", required_argument, 0, 'I'},
{"critical", required_argument, 0, 'c'}, {"warning", required_argument, 0, 'w'}, {"alive", no_argument, 0, 'a'},
{"bytes", required_argument, 0, 'b'}, {"number", required_argument, 0, 'n'}, {"target-timeout", required_argument, 0, 'T'},
{"interval", required_argument, 0, 'i'}, {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'},
{"help", no_argument, 0, 'h'}, {"use-ipv4", no_argument, 0, '4'}, {"use-ipv6", no_argument, 0, '6'},
{"dontfrag", no_argument, 0, 'M'}, {"random", no_argument, 0, 'R'}, {0, 0, 0, 0}};
enum {
FWMARK_OPT = CHAR_MAX + 1,
ICMP_TIMESTAMP_OPT,
CHECK_SOURCE_OPT,
};
static struct option longopts[] = {{"hostname", required_argument, 0, 'H'},
{"sourceip", required_argument, 0, 'S'},
{"sourceif", required_argument, 0, 'I'},
{"critical", required_argument, 0, 'c'},
{"warning", required_argument, 0, 'w'},
{"alive", no_argument, 0, 'a'},
{"bytes", required_argument, 0, 'b'},
{"number", required_argument, 0, 'n'},
{"target-timeout", required_argument, 0, 'T'},
{"interval", required_argument, 0, 'i'},
{"verbose", no_argument, 0, 'v'},
{"version", no_argument, 0, 'V'},
{"help", no_argument, 0, 'h'},
{"use-ipv4", no_argument, 0, '4'},
{"use-ipv6", no_argument, 0, '6'},
{"dontfrag", no_argument, 0, 'M'},
{"random", no_argument, 0, 'R'},
// only available with fping version >= 5.3
{"fwmark", required_argument, NULL, FWMARK_OPT},
// only available with fping version >= 5.3
{"icmp-timestamp", no_argument, NULL, ICMP_TIMESTAMP_OPT},
{"check-source", no_argument, NULL, CHECK_SOURCE_OPT},
{0, 0, 0, 0}};
char *rv[2];
rv[PL] = NULL;
@ -409,6 +449,20 @@ check_fping_config_wrapper process_arguments(int argc, char **argv) {
case 'M':
result.config.dontfrag = true;
break;
case FWMARK_OPT:
if (is_intpos(optarg)) {
result.config.fwmark = (unsigned int)atol(optarg);
result.config.fwmark_set = true;
} else {
usage(_("fwmark must be a positive integer"));
}
break;
case ICMP_TIMESTAMP_OPT:
result.config.icmp_timestamp = true;
break;
case CHECK_SOURCE_OPT:
result.config.check_source = true;
break;
}
}
@ -496,6 +550,16 @@ void print_help(void) {
printf(" %s\n", _("set the Don't Fragment flag"));
printf(" %s\n", "-R, --random");
printf(" %s\n", _("random packet data (to foil link data compression)"));
#ifdef FPING_VERSION_5_2_OR_HIGHER
printf(" %s\n", "--fwmark=INTEGER");
printf(" %s\n", _("set the routing mark to INTEGER (fping option)"));
# ifdef FPING_VERSION_5_3_OR_HIGHER
printf(" %s\n", "--icmp-timestamp");
printf(" %s\n", _("use ICMP Timestamp instead of ICMP Echo (fping option)"));
printf(" %s\n", "--check-source");
printf(" %s\n", _("discard replies not from target address (fping option)"));
# endif
#endif
printf(UT_VERBOSE);
printf("\n");
printf(" %s\n", _("THRESHOLD is <rta>,<pl>%% where <rta> is the round trip average travel time (ms)"));

View file

@ -29,6 +29,21 @@ typedef struct {
bool cpl_p;
int wpl;
bool wpl_p;
// only available with fping version >= 5.2
// for a given uint _fwmark_ fping sets _fwmark_ as a firewall mark
// in the pakets
unsigned int fwmark;
bool fwmark_set;
// only available with fping version >= 5.3
// Setting icmp_timestamp tells fping to use ICMP Timestamp (ICMP type 13) instead
// of ICMP Echo
bool icmp_timestamp;
// Setting check_source lets fping discard replies which are not from the target address
bool check_source;
} check_fping_config;
check_fping_config check_fping_config_init() {
@ -53,6 +68,15 @@ check_fping_config check_fping_config_init() {
.cpl_p = false,
.wpl = 0,
.wpl_p = false,
// only available with fping version >= 5.2
.fwmark = 0,
.fwmark_set = false, // just to be deterministic
// only available with fping version >= 5.3
.icmp_timestamp = false,
.check_source = false,
};
return tmp;
}