summaryrefslogtreecommitdiffstats
path: root/plugins/check_fping.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/check_fping.c')
-rw-r--r--plugins/check_fping.c114
1 files changed, 92 insertions, 22 deletions
diff --git a/plugins/check_fping.c b/plugins/check_fping.c
index ec7abb67..8018e06d 100644
--- a/plugins/check_fping.c
+++ b/plugins/check_fping.c
@@ -79,6 +79,24 @@ int main(int argc, char **argv) {
79 server = strscpy(server, config.server_name); 79 server = strscpy(server, config.server_name);
80 80
81 char *option_string = ""; 81 char *option_string = "";
82 char *fping_prog = NULL;
83
84 /* First determine if the target is dualstack or ipv6 only. */
85 bool server_is_inet6_addr = is_inet6_addr(server);
86
87 /*
88 * If the user requested -6 OR the user made no assertion and the address is v6 or dualstack
89 * -> we use ipv6
90 * If the user requested -4 OR the user made no assertion and the address is v4 ONLY
91 * -> we use ipv4
92 */
93 if (address_family == AF_INET6 || (address_family == AF_UNSPEC && server_is_inet6_addr)) {
94 xasprintf(&option_string, "%s-6 ", option_string);
95 } else {
96 xasprintf(&option_string, "%s-4 ", option_string);
97 }
98 fping_prog = strdup(PATH_TO_FPING);
99
82 /* compose the command */ 100 /* compose the command */
83 if (config.target_timeout) { 101 if (config.target_timeout) {
84 xasprintf(&option_string, "%s-t %d ", option_string, config.target_timeout); 102 xasprintf(&option_string, "%s-t %d ", option_string, config.target_timeout);
@@ -99,19 +117,26 @@ int main(int argc, char **argv) {
99 xasprintf(&option_string, "%s-R ", option_string); 117 xasprintf(&option_string, "%s-R ", option_string);
100 } 118 }
101 119
102 char *fping_prog = NULL; 120 if (config.fwmark_set) {
103#ifdef PATH_TO_FPING6 121 xasprintf(&option_string, "%s--fwmark %u ", option_string, config.fwmark);
104 if (address_family != AF_INET && is_inet6_addr(server)) { 122 }
105 fping_prog = strdup(PATH_TO_FPING6); 123
106 } else { 124 if (config.icmp_timestamp) {
107 fping_prog = strdup(PATH_TO_FPING); 125 xasprintf(&option_string, "%s--icmp-timestamp ", option_string);
126 }
127
128 if (config.check_source) {
129 xasprintf(&option_string, "%s--check-source ", option_string);
108 } 130 }
109#else
110 fping_prog = strdup(PATH_TO_FPING);
111#endif
112 131
113 char *command_line = NULL; 132 char *command_line = NULL;
114 xasprintf(&command_line, "%s %s-b %d -c %d %s", fping_prog, option_string, config.packet_size, config.packet_count, server); 133
134 if (config.icmp_timestamp) {
135 // no packet size settable for ICMP timestamp
136 xasprintf(&command_line, "%s %s -c %d %s", fping_prog, option_string, config.packet_count, server);
137 } else {
138 xasprintf(&command_line, "%s %s-b %d -c %d %s", fping_prog, option_string, config.packet_size, config.packet_count, server);
139 }
115 140
116 if (verbose) { 141 if (verbose) {
117 printf("%s\n", command_line); 142 printf("%s\n", command_line);
@@ -268,13 +293,38 @@ mp_state_enum textscan(char *buf, const char *server_name, bool crta_p, double c
268 293
269/* process command-line arguments */ 294/* process command-line arguments */
270check_fping_config_wrapper process_arguments(int argc, char **argv) { 295check_fping_config_wrapper process_arguments(int argc, char **argv) {
271 static struct option longopts[] = { 296 enum {
272 {"hostname", required_argument, 0, 'H'}, {"sourceip", required_argument, 0, 'S'}, {"sourceif", required_argument, 0, 'I'}, 297 FWMARK_OPT = CHAR_MAX + 1,
273 {"critical", required_argument, 0, 'c'}, {"warning", required_argument, 0, 'w'}, {"alive", no_argument, 0, 'a'}, 298 ICMP_TIMESTAMP_OPT,
274 {"bytes", required_argument, 0, 'b'}, {"number", required_argument, 0, 'n'}, {"target-timeout", required_argument, 0, 'T'}, 299 CHECK_SOURCE_OPT,
275 {"interval", required_argument, 0, 'i'}, {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, 300 };
276 {"help", no_argument, 0, 'h'}, {"use-ipv4", no_argument, 0, '4'}, {"use-ipv6", no_argument, 0, '6'}, 301 static struct option longopts[] = {{"hostname", required_argument, 0, 'H'},
277 {"dontfrag", no_argument, 0, 'M'}, {"random", no_argument, 0, 'R'}, {0, 0, 0, 0}}; 302 {"sourceip", required_argument, 0, 'S'},
303 {"sourceif", required_argument, 0, 'I'},
304 {"critical", required_argument, 0, 'c'},
305 {"warning", required_argument, 0, 'w'},
306 {"alive", no_argument, 0, 'a'},
307 {"bytes", required_argument, 0, 'b'},
308 {"number", required_argument, 0, 'n'},
309 {"target-timeout", required_argument, 0, 'T'},
310 {"interval", required_argument, 0, 'i'},
311 {"verbose", no_argument, 0, 'v'},
312 {"version", no_argument, 0, 'V'},
313 {"help", no_argument, 0, 'h'},
314 {"use-ipv4", no_argument, 0, '4'},
315 {"use-ipv6", no_argument, 0, '6'},
316 {"dontfrag", no_argument, 0, 'M'},
317 {"random", no_argument, 0, 'R'},
318#ifdef FPING_VERSION_5_2_OR_HIGHER
319 // only available with fping version >= 5.2
320 {"fwmark", required_argument, NULL, FWMARK_OPT},
321# ifdef FPING_VERSION_5_3_OR_HIGHER
322 // only available with fping version >= 5.3
323 {"icmp-timestamp", no_argument, NULL, ICMP_TIMESTAMP_OPT},
324 {"check-source", no_argument, NULL, CHECK_SOURCE_OPT},
325# endif
326#endif
327 {0, 0, 0, 0}};
278 328
279 char *rv[2]; 329 char *rv[2];
280 rv[PL] = NULL; 330 rv[PL] = NULL;
@@ -299,7 +349,7 @@ check_fping_config_wrapper process_arguments(int argc, char **argv) {
299 argc--; 349 argc--;
300 } 350 }
301 351
302 while (1) { 352 while (true) {
303 int option_index = getopt_long(argc, argv, "+hVvaH:S:c:w:b:n:T:i:I:M:R:46", longopts, &option); 353 int option_index = getopt_long(argc, argv, "+hVvaH:S:c:w:b:n:T:i:I:M:R:46", longopts, &option);
304 354
305 if (option_index == -1 || option_index == EOF || option_index == 1) { 355 if (option_index == -1 || option_index == EOF || option_index == 1) {
@@ -340,11 +390,7 @@ check_fping_config_wrapper process_arguments(int argc, char **argv) {
340 address_family = AF_INET; 390 address_family = AF_INET;
341 break; 391 break;
342 case '6': /* IPv6 only */ 392 case '6': /* IPv6 only */
343#ifdef USE_IPV6
344 address_family = AF_INET6; 393 address_family = AF_INET6;
345#else
346 usage(_("IPv6 support not available\n"));
347#endif
348 break; 394 break;
349 case 'c': 395 case 'c':
350 get_threshold(optarg, rv); 396 get_threshold(optarg, rv);
@@ -406,6 +452,20 @@ check_fping_config_wrapper process_arguments(int argc, char **argv) {
406 case 'M': 452 case 'M':
407 result.config.dontfrag = true; 453 result.config.dontfrag = true;
408 break; 454 break;
455 case FWMARK_OPT:
456 if (is_intpos(optarg)) {
457 result.config.fwmark = (unsigned int)atol(optarg);
458 result.config.fwmark_set = true;
459 } else {
460 usage(_("fwmark must be a positive integer"));
461 }
462 break;
463 case ICMP_TIMESTAMP_OPT:
464 result.config.icmp_timestamp = true;
465 break;
466 case CHECK_SOURCE_OPT:
467 result.config.check_source = true;
468 break;
409 } 469 }
410 } 470 }
411 471
@@ -493,6 +553,16 @@ void print_help(void) {
493 printf(" %s\n", _("set the Don't Fragment flag")); 553 printf(" %s\n", _("set the Don't Fragment flag"));
494 printf(" %s\n", "-R, --random"); 554 printf(" %s\n", "-R, --random");
495 printf(" %s\n", _("random packet data (to foil link data compression)")); 555 printf(" %s\n", _("random packet data (to foil link data compression)"));
556#ifdef FPING_VERSION_5_2_OR_HIGHER
557 printf(" %s\n", "--fwmark=INTEGER");
558 printf(" %s\n", _("set the routing mark to INTEGER (fping option)"));
559# ifdef FPING_VERSION_5_3_OR_HIGHER
560 printf(" %s\n", "--icmp-timestamp");
561 printf(" %s\n", _("use ICMP Timestamp instead of ICMP Echo (fping option)"));
562 printf(" %s\n", "--check-source");
563 printf(" %s\n", _("discard replies not from target address (fping option)"));
564# endif
565#endif
496 printf(UT_VERBOSE); 566 printf(UT_VERBOSE);
497 printf("\n"); 567 printf("\n");
498 printf(" %s\n", _("THRESHOLD is <rta>,<pl>%% where <rta> is the round trip average travel time (ms)")); 568 printf(" %s\n", _("THRESHOLD is <rta>,<pl>%% where <rta> is the round trip average travel time (ms)"));