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.c633
1 files changed, 334 insertions, 299 deletions
diff --git a/plugins/check_fping.c b/plugins/check_fping.c
index 5ffcd16e..49615d13 100644
--- a/plugins/check_fping.c
+++ b/plugins/check_fping.c
@@ -29,10 +29,10 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net";
29#include "utils.h" 29#include "utils.h"
30 30
31enum { 31enum {
32 PACKET_COUNT = 1, 32 PACKET_COUNT = 1,
33 PACKET_SIZE = 56, 33 PACKET_SIZE = 56,
34 PL = 0, 34 PL = 0,
35 RTA = 1 35 RTA = 1
36}; 36};
37 37
38int textscan (char *buf); 38int textscan (char *buf);
@@ -57,65 +57,65 @@ int wrta_p = FALSE;
57int 57int
58main (int argc, char **argv) 58main (int argc, char **argv)
59{ 59{
60/* normaly should be int result = STATE_UNKNOWN; */ 60/* normaly should be int result = STATE_UNKNOWN; */
61 61
62 int status = STATE_UNKNOWN; 62 int status = STATE_UNKNOWN;
63 char *server = NULL; 63 char *server = NULL;
64 char *command_line = NULL; 64 char *command_line = NULL;
65 char *input_buffer = NULL; 65 char *input_buffer = NULL;
66 input_buffer = malloc (MAX_INPUT_BUFFER); 66 input_buffer = malloc (MAX_INPUT_BUFFER);
67 67
68 setlocale (LC_ALL, ""); 68 setlocale (LC_ALL, "");
69 bindtextdomain (PACKAGE, LOCALEDIR); 69 bindtextdomain (PACKAGE, LOCALEDIR);
70 textdomain (PACKAGE); 70 textdomain (PACKAGE);
71 71
72 if (process_arguments (argc, argv) == ERROR) 72 if (process_arguments (argc, argv) == ERROR)
73 usage4 (_("Could not parse arguments")); 73 usage4 (_("Could not parse arguments"));
74 74
75 server = strscpy (server, server_name); 75 server = strscpy (server, server_name);
76 76
77 /* compose the command */ 77 /* compose the command */
78 asprintf (&command_line, "%s -b %d -c %d %s", PATH_TO_FPING, 78 asprintf (&command_line, "%s -b %d -c %d %s", PATH_TO_FPING,
79 packet_size, packet_count, server); 79 packet_size, packet_count, server);
80 80
81 if (verbose) 81 if (verbose)
82 printf ("%s\n", command_line); 82 printf ("%s\n", command_line);
83 83
84 /* run the command */ 84 /* run the command */
85 child_process = spopen (command_line); 85 child_process = spopen (command_line);
86 if (child_process == NULL) { 86 if (child_process == NULL) {
87 printf (_("Could not open pipe: %s\n"), command_line); 87 printf (_("Could not open pipe: %s\n"), command_line);
88 return STATE_UNKNOWN; 88 return STATE_UNKNOWN;
89 } 89 }
90 90
91 child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); 91 child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r");
92 if (child_stderr == NULL) { 92 if (child_stderr == NULL) {
93 printf (_("Could not open stderr for %s\n"), command_line); 93 printf (_("Could not open stderr for %s\n"), command_line);
94 } 94 }
95 95
96 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { 96 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) {
97 if (verbose) 97 if (verbose)
98 printf ("%s", input_buffer); 98 printf ("%s", input_buffer);
99 status = max_state (status, textscan (input_buffer)); 99 status = max_state (status, textscan (input_buffer));
100 } 100 }
101 101
102 /* If we get anything on STDERR, at least set warning */ 102 /* If we get anything on STDERR, at least set warning */
103 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) { 103 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) {
104 status = max_state (status, STATE_WARNING); 104 status = max_state (status, STATE_WARNING);
105 if (verbose) 105 if (verbose)
106 printf ("%s", input_buffer); 106 printf ("%s", input_buffer);
107 status = max_state (status, textscan (input_buffer)); 107 status = max_state (status, textscan (input_buffer));
108 } 108 }
109 (void) fclose (child_stderr); 109 (void) fclose (child_stderr);
110 110
111 /* close the pipe */ 111 /* close the pipe */
112 if (spclose (child_process)) 112 if (spclose (child_process))
113 /* need to use max_state not max */ 113 /* need to use max_state not max */
114 status = max_state (status, STATE_WARNING); 114 status = max_state (status, STATE_WARNING);
115 115
116 printf ("FPING %s - %s\n", state_text (status), server_name); 116 printf ("FPING %s - %s\n", state_text (status), server_name);
117 117
118 return status; 118 return status;
119} 119}
120 120
121 121
@@ -123,80 +123,80 @@ main (int argc, char **argv)
123int 123int
124textscan (char *buf) 124textscan (char *buf)
125{ 125{
126 char *rtastr = NULL; 126 char *rtastr = NULL;
127 char *losstr = NULL; 127 char *losstr = NULL;
128 double loss; 128 double loss;
129 double rta; 129 double rta;
130 int status = STATE_UNKNOWN; 130 int status = STATE_UNKNOWN;
131 131
132 if (strstr (buf, "not found")) { 132 if (strstr (buf, "not found")) {
133 die (STATE_CRITICAL, _("FPING UNKNOW - %s not found\n"), server_name); 133 die (STATE_CRITICAL, _("FPING UNKNOW - %s not found\n"), server_name);
134 134
135 } 135 }
136 else if (strstr (buf, "is unreachable") || strstr (buf, "Unreachable")) { 136 else if (strstr (buf, "is unreachable") || strstr (buf, "Unreachable")) {
137 die (STATE_CRITICAL, _("FPING CRITICAL - %s is unreachable\n"), 137 die (STATE_CRITICAL, _("FPING CRITICAL - %s is unreachable\n"),
138 "host"); 138 "host");
139 139
140 } 140 }
141 else if (strstr (buf, "is down")) { 141 else if (strstr (buf, "is down")) {
142 die (STATE_CRITICAL, _("FPING CRITICAL - %s is down\n"), server_name); 142 die (STATE_CRITICAL, _("FPING CRITICAL - %s is down\n"), server_name);
143 143
144 } 144 }
145 else if (strstr (buf, "is alive")) { 145 else if (strstr (buf, "is alive")) {
146 status = STATE_OK; 146 status = STATE_OK;
147 147
148 } 148 }
149 else if (strstr (buf, "xmt/rcv/%loss") && strstr (buf, "min/avg/max")) { 149 else if (strstr (buf, "xmt/rcv/%loss") && strstr (buf, "min/avg/max")) {
150 losstr = strstr (buf, "="); 150 losstr = strstr (buf, "=");
151 losstr = 1 + strstr (losstr, "/"); 151 losstr = 1 + strstr (losstr, "/");
152 losstr = 1 + strstr (losstr, "/"); 152 losstr = 1 + strstr (losstr, "/");
153 rtastr = strstr (buf, "min/avg/max"); 153 rtastr = strstr (buf, "min/avg/max");
154 rtastr = strstr (rtastr, "="); 154 rtastr = strstr (rtastr, "=");
155 rtastr = 1 + index (rtastr, '/'); 155 rtastr = 1 + index (rtastr, '/');
156 loss = strtod (losstr, NULL); 156 loss = strtod (losstr, NULL);
157 rta = strtod (rtastr, NULL); 157 rta = strtod (rtastr, NULL);
158 if (cpl_p == TRUE && loss > cpl) 158 if (cpl_p == TRUE && loss > cpl)
159 status = STATE_CRITICAL; 159 status = STATE_CRITICAL;
160 else if (crta_p == TRUE && rta > crta) 160 else if (crta_p == TRUE && rta > crta)
161 status = STATE_CRITICAL; 161 status = STATE_CRITICAL;
162 else if (wpl_p == TRUE && loss > wpl) 162 else if (wpl_p == TRUE && loss > wpl)
163 status = STATE_WARNING; 163 status = STATE_WARNING;
164 else if (wrta_p == TRUE && rta > wrta) 164 else if (wrta_p == TRUE && rta > wrta)
165 status = STATE_WARNING; 165 status = STATE_WARNING;
166 else 166 else
167 status = STATE_OK; 167 status = STATE_OK;
168 die (status, 168 die (status,
169 _("FPING %s - %s (loss=%.0f%%, rta=%f ms)|%s %s\n"), 169 _("FPING %s - %s (loss=%.0f%%, rta=%f ms)|%s %s\n"),
170 state_text (status), server_name, loss, rta, 170 state_text (status), server_name, loss, rta,
171 perfdata ("loss", (long int)loss, "%", wpl_p, wpl, cpl_p, cpl, TRUE, 0, TRUE, 100), 171 perfdata ("loss", (long int)loss, "%", wpl_p, wpl, cpl_p, cpl, TRUE, 0, TRUE, 100),
172 fperfdata ("rta", rta/1.0e3, "s", wrta_p, wrta/1.0e3, crta_p, crta/1.0e3, TRUE, 0, FALSE, 0)); 172 fperfdata ("rta", rta/1.0e3, "s", wrta_p, wrta/1.0e3, crta_p, crta/1.0e3, TRUE, 0, FALSE, 0));
173 173
174 } 174 }
175 else if(strstr (buf, "xmt/rcv/%loss") ) { 175 else if(strstr (buf, "xmt/rcv/%loss") ) {
176 /* no min/max/avg if host was unreachable in fping v2.2.b1 */ 176 /* no min/max/avg if host was unreachable in fping v2.2.b1 */
177 losstr = strstr (buf, "="); 177 losstr = strstr (buf, "=");
178 losstr = 1 + strstr (losstr, "/"); 178 losstr = 1 + strstr (losstr, "/");
179 losstr = 1 + strstr (losstr, "/"); 179 losstr = 1 + strstr (losstr, "/");
180 loss = strtod (losstr, NULL); 180 loss = strtod (losstr, NULL);
181 if (atoi(losstr) == 100) 181 if (atoi(losstr) == 100)
182 status = STATE_CRITICAL; 182 status = STATE_CRITICAL;
183 else if (cpl_p == TRUE && loss > cpl) 183 else if (cpl_p == TRUE && loss > cpl)
184 status = STATE_CRITICAL; 184 status = STATE_CRITICAL;
185 else if (wpl_p == TRUE && loss > wpl) 185 else if (wpl_p == TRUE && loss > wpl)
186 status = STATE_WARNING; 186 status = STATE_WARNING;
187 else 187 else
188 status = STATE_OK; 188 status = STATE_OK;
189 /* loss=%.0f%%;%d;%d;0;100 */ 189 /* loss=%.0f%%;%d;%d;0;100 */
190 die (status, _("FPING %s - %s (loss=%.0f%% )|%s\n"), 190 die (status, _("FPING %s - %s (loss=%.0f%% )|%s\n"),
191 state_text (status), server_name, loss , 191 state_text (status), server_name, loss ,
192 perfdata ("loss", (long int)loss, "%", wpl_p, wpl, cpl_p, cpl, TRUE, 0, TRUE, 100)); 192 perfdata ("loss", (long int)loss, "%", wpl_p, wpl, cpl_p, cpl, TRUE, 0, TRUE, 100));
193 193
194 } 194 }
195 else { 195 else {
196 status = max_state (status, STATE_WARNING); 196 status = max_state (status, STATE_WARNING);
197 } 197 }
198 198
199 return status; 199 return status;
200} 200}
201 201
202 202
@@ -205,145 +205,145 @@ textscan (char *buf)
205int 205int
206process_arguments (int argc, char **argv) 206process_arguments (int argc, char **argv)
207{ 207{
208 int c; 208 int c;
209 char *rv[2]; 209 char *rv[2];
210 210
211 int option = 0; 211 int option = 0;
212 static struct option longopts[] = { 212 static struct option longopts[] = {
213 {"hostname", required_argument, 0, 'H'}, 213 {"hostname", required_argument, 0, 'H'},
214 {"critical", required_argument, 0, 'c'}, 214 {"critical", required_argument, 0, 'c'},
215 {"warning", required_argument, 0, 'w'}, 215 {"warning", required_argument, 0, 'w'},
216 {"bytes", required_argument, 0, 'b'}, 216 {"bytes", required_argument, 0, 'b'},
217 {"number", required_argument, 0, 'n'}, 217 {"number", required_argument, 0, 'n'},
218 {"verbose", no_argument, 0, 'v'}, 218 {"verbose", no_argument, 0, 'v'},
219 {"version", no_argument, 0, 'V'}, 219 {"version", no_argument, 0, 'V'},
220 {"help", no_argument, 0, 'h'}, 220 {"help", no_argument, 0, 'h'},
221 {0, 0, 0, 0} 221 {0, 0, 0, 0}
222 }; 222 };
223 223
224 rv[PL] = NULL; 224 rv[PL] = NULL;
225 rv[RTA] = NULL; 225 rv[RTA] = NULL;
226 226
227 if (argc < 2) 227 if (argc < 2)
228 return ERROR; 228 return ERROR;
229 229
230 if (!is_option (argv[1])) { 230 if (!is_option (argv[1])) {
231 server_name = argv[1]; 231 server_name = argv[1];
232 argv[1] = argv[0]; 232 argv[1] = argv[0];
233 argv = &argv[1]; 233 argv = &argv[1];
234 argc--; 234 argc--;
235 } 235 }
236 236
237 while (1) { 237 while (1) {
238 c = getopt_long (argc, argv, "+hVvH:c:w:b:n:", longopts, &option); 238 c = getopt_long (argc, argv, "+hVvH:c:w:b:n:", longopts, &option);
239 239
240 if (c == -1 || c == EOF || c == 1) 240 if (c == -1 || c == EOF || c == 1)
241 break; 241 break;
242 242
243 switch (c) { 243 switch (c) {
244 case '?': /* print short usage statement if args not parsable */ 244 case '?': /* print short usage statement if args not parsable */
245 usage2 (_("Unknown argument"), optarg); 245 usage2 (_("Unknown argument"), optarg);
246 case 'h': /* help */ 246 case 'h': /* help */
247 print_help (); 247 print_help ();
248 exit (STATE_OK); 248 exit (STATE_OK);
249 case 'V': /* version */ 249 case 'V': /* version */
250 print_revision (progname, revision); 250 print_revision (progname, revision);
251 exit (STATE_OK); 251 exit (STATE_OK);
252 case 'v': /* verbose mode */ 252 case 'v': /* verbose mode */
253 verbose = TRUE; 253 verbose = TRUE;
254 break; 254 break;
255 case 'H': /* hostname */ 255 case 'H': /* hostname */
256 if (is_host (optarg) == FALSE) { 256 if (is_host (optarg) == FALSE) {
257 usage2 (_("Invalid hostname/address"), optarg); 257 usage2 (_("Invalid hostname/address"), optarg);
258 } 258 }
259 server_name = strscpy (server_name, optarg); 259 server_name = strscpy (server_name, optarg);
260 break; 260 break;
261 case 'c': 261 case 'c':
262 get_threshold (optarg, rv); 262 get_threshold (optarg, rv);
263 if (rv[RTA]) { 263 if (rv[RTA]) {
264 crta = strtod (rv[RTA], NULL); 264 crta = strtod (rv[RTA], NULL);
265 crta_p = TRUE; 265 crta_p = TRUE;
266 rv[RTA] = NULL; 266 rv[RTA] = NULL;
267 } 267 }
268 if (rv[PL]) { 268 if (rv[PL]) {
269 cpl = atoi (rv[PL]); 269 cpl = atoi (rv[PL]);
270 cpl_p = TRUE; 270 cpl_p = TRUE;
271 rv[PL] = NULL; 271 rv[PL] = NULL;
272 } 272 }
273 break; 273 break;
274 case 'w': 274 case 'w':
275 get_threshold (optarg, rv); 275 get_threshold (optarg, rv);
276 if (rv[RTA]) { 276 if (rv[RTA]) {
277 wrta = strtod (rv[RTA], NULL); 277 wrta = strtod (rv[RTA], NULL);
278 wrta_p = TRUE; 278 wrta_p = TRUE;
279 rv[RTA] = NULL; 279 rv[RTA] = NULL;
280 } 280 }
281 if (rv[PL]) { 281 if (rv[PL]) {
282 wpl = atoi (rv[PL]); 282 wpl = atoi (rv[PL]);
283 wpl_p = TRUE; 283 wpl_p = TRUE;
284 rv[PL] = NULL; 284 rv[PL] = NULL;
285 } 285 }
286 break; 286 break;
287 case 'b': /* bytes per packet */ 287 case 'b': /* bytes per packet */
288 if (is_intpos (optarg)) 288 if (is_intpos (optarg))
289 packet_size = atoi (optarg); 289 packet_size = atoi (optarg);
290 else 290 else
291 usage (_("Packet size must be a positive integer")); 291 usage (_("Packet size must be a positive integer"));
292 break; 292 break;
293 case 'n': /* number of packets */ 293 case 'n': /* number of packets */
294 if (is_intpos (optarg)) 294 if (is_intpos (optarg))
295 packet_count = atoi (optarg); 295 packet_count = atoi (optarg);
296 else 296 else
297 usage (_("Packet count must be a positive integer")); 297 usage (_("Packet count must be a positive integer"));
298 break; 298 break;
299 } 299 }
300 } 300 }
301 301
302 if (server_name == NULL) 302 if (server_name == NULL)
303 usage4 (_("Hostname was not supplied")); 303 usage4 (_("Hostname was not supplied"));
304 304
305 return OK; 305 return OK;
306} 306}
307 307
308 308
309int 309int
310get_threshold (char *arg, char *rv[2]) 310get_threshold (char *arg, char *rv[2])
311{ 311{
312 char *arg1 = NULL; 312 char *arg1 = NULL;
313 char *arg2 = NULL; 313 char *arg2 = NULL;
314 314
315 arg1 = strscpy (arg1, arg); 315 arg1 = strscpy (arg1, arg);
316 if (strpbrk (arg1, ",:")) 316 if (strpbrk (arg1, ",:"))
317 arg2 = 1 + strpbrk (arg1, ",:"); 317 arg2 = 1 + strpbrk (arg1, ",:");
318 318
319 if (arg2) { 319 if (arg2) {
320 arg1[strcspn (arg1, ",:")] = 0; 320 arg1[strcspn (arg1, ",:")] = 0;
321 if (strstr (arg1, "%") && strstr (arg2, "%")) 321 if (strstr (arg1, "%") && strstr (arg2, "%"))
322 die (STATE_UNKNOWN, 322 die (STATE_UNKNOWN,
323 _("%s: Only one threshold may be packet loss (%s)\n"), progname, 323 _("%s: Only one threshold may be packet loss (%s)\n"), progname,
324 arg); 324 arg);
325 if (!strstr (arg1, "%") && !strstr (arg2, "%")) 325 if (!strstr (arg1, "%") && !strstr (arg2, "%"))
326 die (STATE_UNKNOWN, 326 die (STATE_UNKNOWN,
327 _("%s: Only one threshold must be packet loss (%s)\n"), 327 _("%s: Only one threshold must be packet loss (%s)\n"),
328 progname, arg); 328 progname, arg);
329 } 329 }
330 330
331 if (arg2 && strstr (arg2, "%")) { 331 if (arg2 && strstr (arg2, "%")) {
332 rv[PL] = arg2; 332 rv[PL] = arg2;
333 rv[RTA] = arg1; 333 rv[RTA] = arg1;
334 } 334 }
335 else if (arg2) { 335 else if (arg2) {
336 rv[PL] = arg1; 336 rv[PL] = arg1;
337 rv[RTA] = arg2; 337 rv[RTA] = arg2;
338 } 338 }
339 else if (strstr (arg1, "%")) { 339 else if (strstr (arg1, "%")) {
340 rv[PL] = arg1; 340 rv[PL] = arg1;
341 } 341 }
342 else { 342 else {
343 rv[RTA] = arg1; 343 rv[RTA] = arg1;
344 } 344 }
345 345
346 return OK; 346 return OK;
347} 347}
348 348
349 349
@@ -351,47 +351,82 @@ void
351print_help (void) 351print_help (void)
352{ 352{
353 353
354 print_revision (progname, revision); 354 print_revision (progname, revision);
355 355
356 printf ("Copyright (c) 1999 Didi Rieder <adrieder@sbox.tu-graz.ac.at>\n"); 356 printf ("Copyright (c) 1999 Didi Rieder <adrieder@sbox.tu-graz.ac.at>\n");
357 printf (COPYRIGHT, copyright, email); 357 printf (COPYRIGHT, copyright, email);
358 358
359 printf (_("\ 359 printf (_("This plugin will use the fping command to ping the specified host for a fast check"));
360This plugin will use the /bin/fping command to ping the specified host\n\ 360
361for a fast check if the host is alive.\n\ 361 printf ("\n");
362Note that it is necessary to set the suid flag on fping.\n\n")); 362
363 printf (_("Note that it is necessary to set the suid flag on fping."));
363 364
364 print_usage (); 365 printf ("\n\n");
366
367 print_usage ();
365 368
366 printf (_(UT_HELP_VRSN)); 369 printf (_(UT_HELP_VRSN));
367 370
368 printf (_("\ 371 printf (" -H, --hostname=HOST");
369 -H, --hostname=HOST\n\ 372
370 Name or IP Address of host to ping (IP Address bypasses name lookup,\n\ 373 printf (_("name or IP Address of host to ping (IP Address bypasses name lookup, reducing system load)"));
371 reducing system load)\n\ 374
372 -w, --warning=THRESHOLD\n\ 375 printf ("\n");
373 warning threshold pair\n\ 376
374 -c, --critical=THRESHOLD\n\ 377 printf ("-w, --warning=THRESHOLD");
375 critical threshold pair\n\ 378
376 -b, --bytes=INTEGER\n\ 379 printf ("\n");
377 Size of ICMP packet (default: %d)\n\ 380
378 -n, --number=INTEGER\n\ 381 printf (_("warning threshold pair"));
379 Number of ICMP packets to send (default: %d)\n"), 382
380 PACKET_SIZE, PACKET_COUNT); 383 printf ("\n");
381 384
382 printf (_(UT_VERBOSE)); 385 printf (" -c, --critical=THRESHOLD");
386
387 printf ("\n");
383 388
384 printf (_("\n\ 389 printf (_("critical threshold pair"));
385THRESHOLD is <rta>,<pl>%% where <rta> is the round trip average travel\n\ 390
386time (ms) which triggers a WARNING or CRITICAL state, and <pl> is the\n\ 391 printf ("\n");
387percentage of packet loss to trigger an alarm state.\n"));
388 392
389 printf (_(UT_SUPPORT)); 393 printf (" -b, --bytes=INTEGER");
394
395 printf (_("size of ICMP packet (default: %d)"),PACKET_SIZE);
396
397 printf ("\n");
398
399 printf (" -n, --number=INTEGER");
400
401 printf ("\n");
402
403 printf (_("number of ICMP packets to send (default: %d)"),PACKET_COUNT);
404
405 printf ("\n");
406
407 printf (_(UT_VERBOSE));
408
409 printf ("\n");
410
411 printf (_("THRESHOLD is <rta>,<pl>%% where <rta> is the round trip average travel time (ms)"));
412
413 printf ("\n");
414
415 printf (_("which triggers a WARNING or CRITICAL state, and <pl> is the percentage of"));
416
417 printf ("\n");
418
419 printf (_("packet loss to trigger an alarm state."));
420
421 printf ("\n");
422
423 printf (_(UT_SUPPORT));
390} 424}
391 425
392 426
393void 427void
394print_usage (void) 428print_usage (void)
395{ 429{
396 printf ("Usage: %s <host_address>\n", progname); 430 printf (_("Usage:"));
431 printf (" %s <host_address>\n", progname);
397} 432}