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.c376
1 files changed, 233 insertions, 143 deletions
diff --git a/plugins/check_fping.c b/plugins/check_fping.c
index c1d03ece..6160c2cb 100644
--- a/plugins/check_fping.c
+++ b/plugins/check_fping.c
@@ -38,52 +38,30 @@ const char *email = "devel@monitoring-plugins.org";
38#include "netutils.h" 38#include "netutils.h"
39#include "utils.h" 39#include "utils.h"
40#include <stdbool.h> 40#include <stdbool.h>
41#include "check_fping.d/config.h"
42#include "states.h"
41 43
42enum { 44enum {
43 PACKET_COUNT = 1,
44 PACKET_SIZE = 56,
45 PL = 0, 45 PL = 0,
46 RTA = 1 46 RTA = 1
47}; 47};
48 48
49static int textscan(char *buf); 49static mp_state_enum textscan(char *buf, const char * /*server_name*/, bool /*crta_p*/,
50static int process_arguments(int /*argc*/, char ** /*argv*/); 50 double /*crta*/, bool /*wrta_p*/, double /*wrta*/, bool /*cpl_p*/,
51 int /*cpl*/, bool /*wpl_p*/, int /*wpl*/, bool /*alive_p*/);
52
53typedef struct {
54 int errorcode;
55 check_fping_config config;
56} check_fping_config_wrapper;
57static check_fping_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/);
51static int get_threshold(char *arg, char *rv[2]); 58static int get_threshold(char *arg, char *rv[2]);
52static void print_help(void); 59static void print_help(void);
53void print_usage(void); 60void print_usage(void);
54 61
55static char *server_name = NULL;
56static char *sourceip = NULL;
57static char *sourceif = NULL;
58static int packet_size = PACKET_SIZE;
59static int packet_count = PACKET_COUNT;
60static int target_timeout = 0;
61static int packet_interval = 0;
62static bool verbose = false; 62static bool verbose = false;
63static bool dontfrag = false;
64static bool randomize_packet_data = false;
65static int cpl;
66static int wpl;
67static double crta;
68static double wrta;
69static bool cpl_p = false;
70static bool wpl_p = false;
71static bool alive_p = false;
72static bool crta_p = false;
73static bool wrta_p = false;
74 63
75int main(int argc, char **argv) { 64int main(int argc, char **argv) {
76 /* normally should be int result = STATE_UNKNOWN; */
77
78 int status = STATE_UNKNOWN;
79 int result = 0;
80 char *fping_prog = NULL;
81 char *server = NULL;
82 char *command_line = NULL;
83 char *input_buffer = NULL;
84 char *option_string = "";
85 input_buffer = malloc(MAX_INPUT_BUFFER);
86
87 setlocale(LC_ALL, ""); 65 setlocale(LC_ALL, "");
88 bindtextdomain(PACKAGE, LOCALEDIR); 66 bindtextdomain(PACKAGE, LOCALEDIR);
89 textdomain(PACKAGE); 67 textdomain(PACKAGE);
@@ -91,39 +69,81 @@ int main(int argc, char **argv) {
91 /* Parse extra opts if any */ 69 /* Parse extra opts if any */
92 argv = np_extra_opts(&argc, argv, progname); 70 argv = np_extra_opts(&argc, argv, progname);
93 71
94 if (process_arguments(argc, argv) == ERROR) 72 check_fping_config_wrapper tmp_config = process_arguments(argc, argv);
73 if (tmp_config.errorcode == ERROR) {
95 usage4(_("Could not parse arguments")); 74 usage4(_("Could not parse arguments"));
75 }
76
77 const check_fping_config config = tmp_config.config;
78
79 char *server = NULL;
80 server = strscpy(server, config.server_name);
96 81
97 server = strscpy(server, server_name); 82 char *option_string = "";
83 char *fping_prog = NULL;
84
85 /* First determine if the target is dualstack or ipv6 only. */
86 bool server_is_inet6_addr = is_inet6_addr(server);
87
88 /*
89 * If the user requested -6 OR the user made no assertion and the address is v6 or dualstack
90 * -> we use ipv6
91 * If the user requested -4 OR the user made no assertion and the address is v4 ONLY
92 * -> we use ipv4
93 */
94 if (address_family == AF_INET6 || (address_family == AF_UNSPEC && server_is_inet6_addr)) {
95 xasprintf(&option_string, "%s-6 ", option_string);
96 } else {
97 xasprintf(&option_string, "%s-4 ", option_string);
98 }
99 fping_prog = strdup(PATH_TO_FPING);
98 100
99 /* compose the command */ 101 /* compose the command */
100 if (target_timeout) 102 if (config.target_timeout) {
101 xasprintf(&option_string, "%s-t %d ", option_string, target_timeout); 103 xasprintf(&option_string, "%s-t %d ", option_string, config.target_timeout);
102 if (packet_interval) 104 }
103 xasprintf(&option_string, "%s-p %d ", option_string, packet_interval); 105 if (config.packet_interval) {
104 if (sourceip) 106 xasprintf(&option_string, "%s-p %d ", option_string, config.packet_interval);
105 xasprintf(&option_string, "%s-S %s ", option_string, sourceip); 107 }
106 if (sourceif) 108 if (config.sourceip) {
107 xasprintf(&option_string, "%s-I %s ", option_string, sourceif); 109 xasprintf(&option_string, "%s-S %s ", option_string, config.sourceip);
108 if (dontfrag) 110 }
111 if (config.sourceif) {
112 xasprintf(&option_string, "%s-I %s ", option_string, config.sourceif);
113 }
114 if (config.dontfrag) {
109 xasprintf(&option_string, "%s-M ", option_string); 115 xasprintf(&option_string, "%s-M ", option_string);
110 if (randomize_packet_data) 116 }
117 if (config.randomize_packet_data) {
111 xasprintf(&option_string, "%s-R ", option_string); 118 xasprintf(&option_string, "%s-R ", option_string);
119 }
112 120
121 if (config.fwmark_set) {
122 xasprintf(&option_string, "%s--fwmark %u ", option_string, config.fwmark);
123 }
113 124
114#ifdef PATH_TO_FPING6 125 if (config.icmp_timestamp) {
115 if (address_family != AF_INET && is_inet6_addr(server)) 126 xasprintf(&option_string, "%s--icmp-timestamp ", option_string);
116 fping_prog = strdup(PATH_TO_FPING6); 127 }
117 else
118 fping_prog = strdup(PATH_TO_FPING);
119#else
120 fping_prog = strdup(PATH_TO_FPING);
121#endif
122 128
123 xasprintf(&command_line, "%s %s-b %d -c %d %s", fping_prog, option_string, packet_size, packet_count, server); 129 if (config.check_source) {
130 xasprintf(&option_string, "%s--check-source ", option_string);
131 }
132
133 char *command_line = NULL;
124 134
125 if (verbose) 135 if (config.icmp_timestamp) {
136 // no packet size settable for ICMP timestamp
137 xasprintf(&command_line, "%s %s -c %d %s", fping_prog, option_string, config.packet_count,
138 server);
139 } else {
140 xasprintf(&command_line, "%s %s-b %d -c %d %s", fping_prog, option_string,
141 config.packet_size, config.packet_count, server);
142 }
143
144 if (verbose) {
126 printf("%s\n", command_line); 145 printf("%s\n", command_line);
146 }
127 147
128 /* run the command */ 148 /* run the command */
129 child_process = spopen(command_line); 149 child_process = spopen(command_line);
@@ -137,23 +157,31 @@ int main(int argc, char **argv) {
137 printf(_("Could not open stderr for %s\n"), command_line); 157 printf(_("Could not open stderr for %s\n"), command_line);
138 } 158 }
139 159
160 char *input_buffer = malloc(MAX_INPUT_BUFFER);
161 mp_state_enum status = STATE_UNKNOWN;
140 while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { 162 while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_process)) {
141 if (verbose) 163 if (verbose) {
142 printf("%s", input_buffer); 164 printf("%s", input_buffer);
143 status = max_state(status, textscan(input_buffer)); 165 }
166 status = max_state(status, textscan(input_buffer, config.server_name, config.crta_p,
167 config.crta, config.wrta_p, config.wrta, config.cpl_p,
168 config.cpl, config.wpl_p, config.wpl, config.alive_p));
144 } 169 }
145 170
146 /* If we get anything on STDERR, at least set warning */ 171 /* If we get anything on STDERR, at least set warning */
147 while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) { 172 while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) {
148 status = max_state(status, STATE_WARNING); 173 status = max_state(status, STATE_WARNING);
149 if (verbose) 174 if (verbose) {
150 printf("%s", input_buffer); 175 printf("%s", input_buffer);
151 status = max_state(status, textscan(input_buffer)); 176 }
177 status = max_state(status, textscan(input_buffer, config.server_name, config.crta_p,
178 config.crta, config.wrta_p, config.wrta, config.cpl_p,
179 config.cpl, config.wpl_p, config.wpl, config.alive_p));
152 } 180 }
153 (void)fclose(child_stderr); 181 (void)fclose(child_stderr);
154 182
155 /* close the pipe */ 183 /* close the pipe */
156 result = spclose(child_process); 184 int result = spclose(child_process);
157 if (result) { 185 if (result) {
158 /* need to use max_state not max */ 186 /* need to use max_state not max */
159 status = max_state(status, STATE_WARNING); 187 status = max_state(status, STATE_WARNING);
@@ -172,21 +200,17 @@ int main(int argc, char **argv) {
172 } 200 }
173 } 201 }
174 202
175 printf("FPING %s - %s\n", state_text(status), server_name); 203 printf("FPING %s - %s\n", state_text(status), config.server_name);
176 204
177 return status; 205 return status;
178} 206}
179 207
180int textscan(char *buf) { 208mp_state_enum textscan(char *buf, const char *server_name, bool crta_p, double crta, bool wrta_p,
181 char *rtastr = NULL; 209 double wrta, bool cpl_p, int cpl, bool wpl_p, int wpl, bool alive_p) {
182 char *losstr = NULL;
183 char *xmtstr = NULL;
184 double loss;
185 double rta;
186 double xmt;
187 int status = STATE_UNKNOWN;
188
189 /* stops testing after the first successful reply. */ 210 /* stops testing after the first successful reply. */
211 double rta;
212 double loss;
213 char *rtastr = NULL;
190 if (alive_p && strstr(buf, "avg, 0% loss)")) { 214 if (alive_p && strstr(buf, "avg, 0% loss)")) {
191 rtastr = strstr(buf, "ms ("); 215 rtastr = strstr(buf, "ms (");
192 rtastr = 1 + index(rtastr, '('); 216 rtastr = 1 + index(rtastr, '(');
@@ -195,9 +219,14 @@ int textscan(char *buf) {
195 die(STATE_OK, _("FPING %s - %s (rta=%f ms)|%s\n"), state_text(STATE_OK), server_name, rta, 219 die(STATE_OK, _("FPING %s - %s (rta=%f ms)|%s\n"), state_text(STATE_OK), server_name, rta,
196 /* No loss since we only waited for the first reply 220 /* No loss since we only waited for the first reply
197 perfdata ("loss", (long int)loss, "%", wpl_p, wpl, cpl_p, cpl, true, 0, true, 100), */ 221 perfdata ("loss", (long int)loss, "%", wpl_p, wpl, cpl_p, cpl, true, 0, true, 100), */
198 fperfdata("rta", rta / 1.0e3, "s", wrta_p, wrta / 1.0e3, crta_p, crta / 1.0e3, true, 0, false, 0)); 222 fperfdata("rta", rta / 1.0e3, "s", wrta_p, wrta / 1.0e3, crta_p, crta / 1.0e3, true, 0,
223 false, 0));
199 } 224 }
200 225
226 mp_state_enum status = STATE_UNKNOWN;
227 char *xmtstr = NULL;
228 double xmt;
229 char *losstr = NULL;
201 if (strstr(buf, "not found")) { 230 if (strstr(buf, "not found")) {
202 die(STATE_CRITICAL, _("FPING UNKNOWN - %s not found\n"), server_name); 231 die(STATE_CRITICAL, _("FPING UNKNOWN - %s not found\n"), server_name);
203 232
@@ -221,19 +250,22 @@ int textscan(char *buf) {
221 rtastr = 1 + index(rtastr, '/'); 250 rtastr = 1 + index(rtastr, '/');
222 loss = strtod(losstr, NULL); 251 loss = strtod(losstr, NULL);
223 rta = strtod(rtastr, NULL); 252 rta = strtod(rtastr, NULL);
224 if (cpl_p && loss > cpl) 253 if (cpl_p && loss > cpl) {
225 status = STATE_CRITICAL; 254 status = STATE_CRITICAL;
226 else if (crta_p && rta > crta) 255 } else if (crta_p && rta > crta) {
227 status = STATE_CRITICAL; 256 status = STATE_CRITICAL;
228 else if (wpl_p && loss > wpl) 257 } else if (wpl_p && loss > wpl) {
229 status = STATE_WARNING; 258 status = STATE_WARNING;
230 else if (wrta_p && rta > wrta) 259 } else if (wrta_p && rta > wrta) {
231 status = STATE_WARNING; 260 status = STATE_WARNING;
232 else 261 } else {
233 status = STATE_OK; 262 status = STATE_OK;
234 die(status, _("FPING %s - %s (loss=%.0f%%, rta=%f ms)|%s %s\n"), state_text(status), server_name, loss, rta, 263 }
235 perfdata("loss", (long int)loss, "%", wpl_p, wpl, cpl_p, cpl, true, 0, true, 100), 264 die(status, _("FPING %s - %s (loss=%.0f%%, rta=%f ms)|%s %s\n"), state_text(status),
236 fperfdata("rta", rta / 1.0e3, "s", wrta_p, wrta / 1.0e3, crta_p, crta / 1.0e3, true, 0, false, 0)); 265 server_name, loss, rta,
266 perfdata("loss", (long int)loss, "%", wpl_p, wpl, cpl_p, cpl, false, 0, false, 0),
267 fperfdata("rta", rta / 1.0e3, "s", wrta_p, wrta / 1.0e3, crta_p, crta / 1.0e3, true, 0,
268 false, 0));
237 269
238 } else if (strstr(buf, "xmt/rcv/%loss")) { 270 } else if (strstr(buf, "xmt/rcv/%loss")) {
239 /* no min/max/avg if host was unreachable in fping v2.2.b1 */ 271 /* no min/max/avg if host was unreachable in fping v2.2.b1 */
@@ -241,22 +273,24 @@ int textscan(char *buf) {
241 losstr = strstr(buf, "="); 273 losstr = strstr(buf, "=");
242 xmtstr = 1 + losstr; 274 xmtstr = 1 + losstr;
243 xmt = strtod(xmtstr, NULL); 275 xmt = strtod(xmtstr, NULL);
244 if (xmt == 0) 276 if (xmt == 0) {
245 die(STATE_CRITICAL, _("FPING CRITICAL - %s is down\n"), server_name); 277 die(STATE_CRITICAL, _("FPING CRITICAL - %s is down\n"), server_name);
278 }
246 losstr = 1 + strstr(losstr, "/"); 279 losstr = 1 + strstr(losstr, "/");
247 losstr = 1 + strstr(losstr, "/"); 280 losstr = 1 + strstr(losstr, "/");
248 loss = strtod(losstr, NULL); 281 loss = strtod(losstr, NULL);
249 if (atoi(losstr) == 100) 282 if (atoi(losstr) == 100) {
250 status = STATE_CRITICAL; 283 status = STATE_CRITICAL;
251 else if (cpl_p && loss > cpl) 284 } else if (cpl_p && loss > cpl) {
252 status = STATE_CRITICAL; 285 status = STATE_CRITICAL;
253 else if (wpl_p && loss > wpl) 286 } else if (wpl_p && loss > wpl) {
254 status = STATE_WARNING; 287 status = STATE_WARNING;
255 else 288 } else {
256 status = STATE_OK; 289 status = STATE_OK;
290 }
257 /* loss=%.0f%%;%d;%d;0;100 */ 291 /* loss=%.0f%%;%d;%d;0;100 */
258 die(status, _("FPING %s - %s (loss=%.0f%% )|%s\n"), state_text(status), server_name, loss, 292 die(status, _("FPING %s - %s (loss=%.0f%% )|%s\n"), state_text(status), server_name, loss,
259 perfdata("loss", (long int)loss, "%", wpl_p, wpl, cpl_p, cpl, true, 0, true, 100)); 293 perfdata("loss", (long int)loss, "%", wpl_p, wpl, cpl_p, cpl, false, 0, false, 0));
260 294
261 } else { 295 } else {
262 status = max_state(status, STATE_WARNING); 296 status = max_state(status, STATE_WARNING);
@@ -266,11 +300,12 @@ int textscan(char *buf) {
266} 300}
267 301
268/* process command-line arguments */ 302/* process command-line arguments */
269int process_arguments(int argc, char **argv) { 303check_fping_config_wrapper process_arguments(int argc, char **argv) {
270 int c; 304 enum {
271 char *rv[2]; 305 FWMARK_OPT = CHAR_MAX + 1,
272 306 ICMP_TIMESTAMP_OPT,
273 int option = 0; 307 CHECK_SOURCE_OPT,
308 };
274 static struct option longopts[] = {{"hostname", required_argument, 0, 'H'}, 309 static struct option longopts[] = {{"hostname", required_argument, 0, 'H'},
275 {"sourceip", required_argument, 0, 'S'}, 310 {"sourceip", required_argument, 0, 'S'},
276 {"sourceif", required_argument, 0, 'I'}, 311 {"sourceif", required_argument, 0, 'I'},
@@ -288,32 +323,53 @@ int process_arguments(int argc, char **argv) {
288 {"use-ipv6", no_argument, 0, '6'}, 323 {"use-ipv6", no_argument, 0, '6'},
289 {"dontfrag", no_argument, 0, 'M'}, 324 {"dontfrag", no_argument, 0, 'M'},
290 {"random", no_argument, 0, 'R'}, 325 {"random", no_argument, 0, 'R'},
326#ifdef FPING_VERSION_5_2_OR_HIGHER
327 // only available with fping version >= 5.2
328 {"fwmark", required_argument, NULL, FWMARK_OPT},
329# ifdef FPING_VERSION_5_3_OR_HIGHER
330 // only available with fping version >= 5.3
331 {"icmp-timestamp", no_argument, NULL, ICMP_TIMESTAMP_OPT},
332 {"check-source", no_argument, NULL, CHECK_SOURCE_OPT},
333# endif
334#endif
291 {0, 0, 0, 0}}; 335 {0, 0, 0, 0}};
292 336
337 char *rv[2];
293 rv[PL] = NULL; 338 rv[PL] = NULL;
294 rv[RTA] = NULL; 339 rv[RTA] = NULL;
295 340
296 if (argc < 2) 341 int option = 0;
297 return ERROR; 342
343 check_fping_config_wrapper result = {
344 .errorcode = OK,
345 .config = check_fping_config_init(),
346 };
347
348 if (argc < 2) {
349 result.errorcode = ERROR;
350 return result;
351 }
298 352
299 if (!is_option(argv[1])) { 353 if (!is_option(argv[1])) {
300 server_name = argv[1]; 354 result.config.server_name = argv[1];
301 argv[1] = argv[0]; 355 argv[1] = argv[0];
302 argv = &argv[1]; 356 argv = &argv[1];
303 argc--; 357 argc--;
304 } 358 }
305 359
306 while (1) { 360 while (true) {
307 c = getopt_long(argc, argv, "+hVvaH:S:c:w:b:n:T:i:I:M:R:46", longopts, &option); 361 int option_index =
362 getopt_long(argc, argv, "+hVvaH:S:c:w:b:n:T:i:I:M:R:46", longopts, &option);
308 363
309 if (c == -1 || c == EOF || c == 1) 364 if (option_index == -1 || option_index == EOF || option_index == 1) {
310 break; 365 break;
366 }
311 367
312 switch (c) { 368 switch (option_index) {
313 case '?': /* print short usage statement if args not parsable */ 369 case '?': /* print short usage statement if args not parsable */
314 usage5(); 370 usage5();
315 case 'a': /* host alive mode */ 371 case 'a': /* host alive mode */
316 alive_p = true; 372 result.config.alive_p = true;
317 break; 373 break;
318 case 'h': /* help */ 374 case 'h': /* help */
319 print_help(); 375 print_help();
@@ -325,109 +381,128 @@ int process_arguments(int argc, char **argv) {
325 verbose = true; 381 verbose = true;
326 break; 382 break;
327 case 'H': /* hostname */ 383 case 'H': /* hostname */
328 if (is_host(optarg) == false) { 384 if (!is_host(optarg)) {
329 usage2(_("Invalid hostname/address"), optarg); 385 usage2(_("Invalid hostname/address"), optarg);
330 } 386 }
331 server_name = strscpy(server_name, optarg); 387 result.config.server_name = optarg;
332 break; 388 break;
333 case 'S': /* sourceip */ 389 case 'S': /* sourceip */
334 if (is_host(optarg) == false) { 390 if (!is_host(optarg)) {
335 usage2(_("Invalid hostname/address"), optarg); 391 usage2(_("Invalid hostname/address"), optarg);
336 } 392 }
337 sourceip = strscpy(sourceip, optarg); 393 result.config.sourceip = optarg;
338 break; 394 break;
339 case 'I': /* sourceip */ 395 case 'I': /* sourceip */
340 sourceif = strscpy(sourceif, optarg); 396 result.config.sourceif = optarg;
341 break; 397 break;
342 case '4': /* IPv4 only */ 398 case '4': /* IPv4 only */
343 address_family = AF_INET; 399 address_family = AF_INET;
344 break; 400 break;
345 case '6': /* IPv6 only */ 401 case '6': /* IPv6 only */
346#ifdef USE_IPV6
347 address_family = AF_INET6; 402 address_family = AF_INET6;
348#else
349 usage(_("IPv6 support not available\n"));
350#endif
351 break; 403 break;
352 case 'c': 404 case 'c':
353 get_threshold(optarg, rv); 405 get_threshold(optarg, rv);
354 if (rv[RTA]) { 406 if (rv[RTA]) {
355 crta = strtod(rv[RTA], NULL); 407 result.config.crta = strtod(rv[RTA], NULL);
356 crta_p = true; 408 result.config.crta_p = true;
357 rv[RTA] = NULL; 409 rv[RTA] = NULL;
358 } 410 }
359 if (rv[PL]) { 411 if (rv[PL]) {
360 cpl = atoi(rv[PL]); 412 result.config.cpl = atoi(rv[PL]);
361 cpl_p = true; 413 result.config.cpl_p = true;
362 rv[PL] = NULL; 414 rv[PL] = NULL;
363 } 415 }
364 break; 416 break;
365 case 'w': 417 case 'w':
366 get_threshold(optarg, rv); 418 get_threshold(optarg, rv);
367 if (rv[RTA]) { 419 if (rv[RTA]) {
368 wrta = strtod(rv[RTA], NULL); 420 result.config.wrta = strtod(rv[RTA], NULL);
369 wrta_p = true; 421 result.config.wrta_p = true;
370 rv[RTA] = NULL; 422 rv[RTA] = NULL;
371 } 423 }
372 if (rv[PL]) { 424 if (rv[PL]) {
373 wpl = atoi(rv[PL]); 425 result.config.wpl = atoi(rv[PL]);
374 wpl_p = true; 426 result.config.wpl_p = true;
375 rv[PL] = NULL; 427 rv[PL] = NULL;
376 } 428 }
377 break; 429 break;
378 case 'b': /* bytes per packet */ 430 case 'b': /* bytes per packet */
379 if (is_intpos(optarg)) 431 if (is_intpos(optarg)) {
380 packet_size = atoi(optarg); 432 result.config.packet_size = atoi(optarg);
381 else 433 } else {
382 usage(_("Packet size must be a positive integer")); 434 usage(_("Packet size must be a positive integer"));
435 }
383 break; 436 break;
384 case 'n': /* number of packets */ 437 case 'n': /* number of packets */
385 if (is_intpos(optarg)) 438 if (is_intpos(optarg)) {
386 packet_count = atoi(optarg); 439 result.config.packet_count = atoi(optarg);
387 else 440 } else {
388 usage(_("Packet count must be a positive integer")); 441 usage(_("Packet count must be a positive integer"));
442 }
389 break; 443 break;
390 case 'T': /* timeout in msec */ 444 case 'T': /* timeout in msec */
391 if (is_intpos(optarg)) 445 if (is_intpos(optarg)) {
392 target_timeout = atoi(optarg); 446 result.config.target_timeout = atoi(optarg);
393 else 447 } else {
394 usage(_("Target timeout must be a positive integer")); 448 usage(_("Target timeout must be a positive integer"));
449 }
395 break; 450 break;
396 case 'i': /* interval in msec */ 451 case 'i': /* interval in msec */
397 if (is_intpos(optarg)) 452 if (is_intpos(optarg)) {
398 packet_interval = atoi(optarg); 453 result.config.packet_interval = atoi(optarg);
399 else 454 } else {
400 usage(_("Interval must be a positive integer")); 455 usage(_("Interval must be a positive integer"));
456 }
401 break; 457 break;
402 case 'R': 458 case 'R':
403 randomize_packet_data = true; 459 result.config.randomize_packet_data = true;
404 break; 460 break;
405 case 'M': 461 case 'M':
406 dontfrag = true; 462 result.config.dontfrag = true;
463 break;
464 case FWMARK_OPT:
465 if (is_intpos(optarg)) {
466 result.config.fwmark = (unsigned int)atol(optarg);
467 result.config.fwmark_set = true;
468 } else {
469 usage(_("fwmark must be a positive integer"));
470 }
471 break;
472 case ICMP_TIMESTAMP_OPT:
473 result.config.icmp_timestamp = true;
474 break;
475 case CHECK_SOURCE_OPT:
476 result.config.check_source = true;
407 break; 477 break;
408 } 478 }
409 } 479 }
410 480
411 if (server_name == NULL) 481 if (result.config.server_name == NULL) {
412 usage4(_("Hostname was not supplied")); 482 usage4(_("Hostname was not supplied"));
483 }
413 484
414 return OK; 485 return result;
415} 486}
416 487
417int get_threshold(char *arg, char *rv[2]) { 488int get_threshold(char *arg, char *rv[2]) {
418 char *arg1 = NULL;
419 char *arg2 = NULL; 489 char *arg2 = NULL;
420 490
421 arg1 = strscpy(arg1, arg); 491 char *arg1 = strdup(arg);
422 if (strpbrk(arg1, ",:")) 492 if (strpbrk(arg1, ",:")) {
423 arg2 = 1 + strpbrk(arg1, ",:"); 493 arg2 = 1 + strpbrk(arg1, ",:");
494 }
424 495
425 if (arg2) { 496 if (arg2) {
426 arg1[strcspn(arg1, ",:")] = 0; 497 arg1[strcspn(arg1, ",:")] = 0;
427 if (strstr(arg1, "%") && strstr(arg2, "%")) 498 if (strstr(arg1, "%") && strstr(arg2, "%")) {
428 die(STATE_UNKNOWN, _("%s: Only one threshold may be packet loss (%s)\n"), progname, arg); 499 die(STATE_UNKNOWN, _("%s: Only one threshold may be packet loss (%s)\n"), progname,
429 if (!strstr(arg1, "%") && !strstr(arg2, "%")) 500 arg);
430 die(STATE_UNKNOWN, _("%s: Only one threshold must be packet loss (%s)\n"), progname, arg); 501 }
502 if (!strstr(arg1, "%") && !strstr(arg2, "%")) {
503 die(STATE_UNKNOWN, _("%s: Only one threshold must be packet loss (%s)\n"), progname,
504 arg);
505 }
431 } 506 }
432 507
433 if (arg2 && strstr(arg2, "%")) { 508 if (arg2 && strstr(arg2, "%")) {
@@ -452,7 +527,8 @@ void print_help(void) {
452 printf("Copyright (c) 1999 Didi Rieder <adrieder@sbox.tu-graz.ac.at>\n"); 527 printf("Copyright (c) 1999 Didi Rieder <adrieder@sbox.tu-graz.ac.at>\n");
453 printf(COPYRIGHT, copyright, email); 528 printf(COPYRIGHT, copyright, email);
454 529
455 printf("%s\n", _("This plugin will use the fping command to ping the specified host for a fast check")); 530 printf("%s\n",
531 _("This plugin will use the fping command to ping the specified host for a fast check"));
456 532
457 printf("%s\n", _("Note that it is necessary to set the suid flag on fping.")); 533 printf("%s\n", _("Note that it is necessary to set the suid flag on fping."));
458 534
@@ -466,7 +542,8 @@ void print_help(void) {
466 printf(UT_IPv46); 542 printf(UT_IPv46);
467 543
468 printf(" %s\n", "-H, --hostname=HOST"); 544 printf(" %s\n", "-H, --hostname=HOST");
469 printf(" %s\n", _("name or IP Address of host to ping (IP Address bypasses name lookup, reducing system load)")); 545 printf(" %s\n", _("name or IP Address of host to ping (IP Address bypasses name lookup, "
546 "reducing system load)"));
470 printf(" %s\n", "-w, --warning=THRESHOLD"); 547 printf(" %s\n", "-w, --warning=THRESHOLD");
471 printf(" %s\n", _("warning threshold pair")); 548 printf(" %s\n", _("warning threshold pair"));
472 printf(" %s\n", "-c, --critical=THRESHOLD"); 549 printf(" %s\n", "-c, --critical=THRESHOLD");
@@ -480,7 +557,8 @@ void print_help(void) {
480 printf(" %s\n", "-T, --target-timeout=INTEGER"); 557 printf(" %s\n", "-T, --target-timeout=INTEGER");
481 printf(" %s (default: fping's default for -t)\n", _("Target timeout (ms)")); 558 printf(" %s (default: fping's default for -t)\n", _("Target timeout (ms)"));
482 printf(" %s\n", "-i, --interval=INTEGER"); 559 printf(" %s\n", "-i, --interval=INTEGER");
483 printf(" %s (default: fping's default for -p)\n", _("Interval (ms) between sending packets")); 560 printf(" %s (default: fping's default for -p)\n",
561 _("Interval (ms) between sending packets"));
484 printf(" %s\n", "-S, --sourceip=HOST"); 562 printf(" %s\n", "-S, --sourceip=HOST");
485 printf(" %s\n", _("name or IP Address of sourceip")); 563 printf(" %s\n", _("name or IP Address of sourceip"));
486 printf(" %s\n", "-I, --sourceif=IF"); 564 printf(" %s\n", "-I, --sourceif=IF");
@@ -489,9 +567,20 @@ void print_help(void) {
489 printf(" %s\n", _("set the Don't Fragment flag")); 567 printf(" %s\n", _("set the Don't Fragment flag"));
490 printf(" %s\n", "-R, --random"); 568 printf(" %s\n", "-R, --random");
491 printf(" %s\n", _("random packet data (to foil link data compression)")); 569 printf(" %s\n", _("random packet data (to foil link data compression)"));
570#ifdef FPING_VERSION_5_2_OR_HIGHER
571 printf(" %s\n", "--fwmark=INTEGER");
572 printf(" %s\n", _("set the routing mark to INTEGER (fping option)"));
573# ifdef FPING_VERSION_5_3_OR_HIGHER
574 printf(" %s\n", "--icmp-timestamp");
575 printf(" %s\n", _("use ICMP Timestamp instead of ICMP Echo (fping option)"));
576 printf(" %s\n", "--check-source");
577 printf(" %s\n", _("discard replies not from target address (fping option)"));
578# endif
579#endif
492 printf(UT_VERBOSE); 580 printf(UT_VERBOSE);
493 printf("\n"); 581 printf("\n");
494 printf(" %s\n", _("THRESHOLD is <rta>,<pl>%% where <rta> is the round trip average travel time (ms)")); 582 printf(" %s\n",
583 _("THRESHOLD is <rta>,<pl>%% where <rta> is the round trip average travel time (ms)"));
495 printf(" %s\n", _("which triggers a WARNING or CRITICAL state, and <pl> is the percentage of")); 584 printf(" %s\n", _("which triggers a WARNING or CRITICAL state, and <pl> is the percentage of"));
496 printf(" %s\n", _("packet loss to trigger an alarm state.")); 585 printf(" %s\n", _("packet loss to trigger an alarm state."));
497 586
@@ -503,5 +592,6 @@ void print_help(void) {
503 592
504void print_usage(void) { 593void print_usage(void) {
505 printf("%s\n", _("Usage:")); 594 printf("%s\n", _("Usage:"));
506 printf(" %s <host_address> -w limit -c limit [-b size] [-n number] [-T number] [-i number]\n", progname); 595 printf(" %s <host_address> -w limit -c limit [-b size] [-n number] [-T number] [-i number]\n",
596 progname);
507} 597}