summaryrefslogtreecommitdiffstats
path: root/plugins/check_ping.c
diff options
context:
space:
mode:
authorLorenz Kästle <12514511+RincewindsHat@users.noreply.github.com>2024-10-31 13:57:43 (GMT)
committerGitHub <noreply@github.com>2024-10-31 13:57:43 (GMT)
commitb1d260a821b7d4916d6bf1a026fbc9b4f2b268ae (patch)
tree84a3fc6b26b181a1ed10d7ca55c32ac9170efbd4 /plugins/check_ping.c
parentb4c5956591e9741ce9b190210e7b10940a6adbdd (diff)
parent8955f56de355403941bc8f02a4edb2bc72d1397a (diff)
downloadmonitoring-plugins-b1d260a821b7d4916d6bf1a026fbc9b4f2b268ae.tar.gz
Merge pull request #2035 from RincewindsHat/cleanup/rest-of-plugins
Cleanup for some more plugins
Diffstat (limited to 'plugins/check_ping.c')
-rw-r--r--plugins/check_ping.c603
1 files changed, 274 insertions, 329 deletions
diff --git a/plugins/check_ping.c b/plugins/check_ping.c
index 6e162e6..4aafaf4 100644
--- a/plugins/check_ping.c
+++ b/plugins/check_ping.c
@@ -1,35 +1,35 @@
1/***************************************************************************** 1/*****************************************************************************
2* 2 *
3* Monitoring check_ping plugin 3 * Monitoring check_ping plugin
4* 4 *
5* License: GPL 5 * License: GPL
6* Copyright (c) 2000-2007 Monitoring Plugins Development Team 6 * Copyright (c) 2000-2024 Monitoring Plugins Development Team
7* 7 *
8* Description: 8 * Description:
9* 9 *
10* This file contains the check_ping plugin 10 * This file contains the check_ping plugin
11* 11 *
12* Use the ping program to check connection statistics for a remote host. 12 * Use the ping program to check connection statistics for a remote host.
13* 13 *
14* 14 *
15* This program is free software: you can redistribute it and/or modify 15 * This program is free software: you can redistribute it and/or modify
16* it under the terms of the GNU General Public License as published by 16 * it under the terms of the GNU General Public License as published by
17* the Free Software Foundation, either version 3 of the License, or 17 * the Free Software Foundation, either version 3 of the License, or
18* (at your option) any later version. 18 * (at your option) any later version.
19* 19 *
20* This program is distributed in the hope that it will be useful, 20 * This program is distributed in the hope that it will be useful,
21* but WITHOUT ANY WARRANTY; without even the implied warranty of 21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23* GNU General Public License for more details. 23 * GNU General Public License for more details.
24* 24 *
25* You should have received a copy of the GNU General Public License 25 * You should have received a copy of the GNU General Public License
26* along with this program. If not, see <http://www.gnu.org/licenses/>. 26 * along with this program. If not, see <http://www.gnu.org/licenses/>.
27* 27 *
28* 28 *
29*****************************************************************************/ 29 *****************************************************************************/
30 30
31const char *progname = "check_ping"; 31const char *progname = "check_ping";
32const char *copyright = "2000-2007"; 32const char *copyright = "2000-2024";
33const char *email = "devel@monitoring-plugins.org"; 33const char *email = "devel@monitoring-plugins.org";
34 34
35#include "common.h" 35#include "common.h"
@@ -39,77 +39,73 @@ const char *email = "devel@monitoring-plugins.org";
39 39
40#include <signal.h> 40#include <signal.h>
41 41
42#define WARN_DUPLICATES "DUPLICATES FOUND! " 42#define WARN_DUPLICATES "DUPLICATES FOUND! "
43#define UNKNOWN_TRIP_TIME -1.0 /* -1 seconds */ 43#define UNKNOWN_TRIP_TIME -1.0 /* -1 seconds */
44 44
45enum { 45enum {
46 UNKNOWN_PACKET_LOSS = 200, /* 200% */ 46 UNKNOWN_PACKET_LOSS = 200, /* 200% */
47 DEFAULT_MAX_PACKETS = 5 /* default no. of ICMP ECHO packets */ 47 DEFAULT_MAX_PACKETS = 5 /* default no. of ICMP ECHO packets */
48}; 48};
49 49
50int process_arguments (int, char **); 50static int process_arguments(int /*argc*/, char ** /*argv*/);
51int get_threshold (char *, float *, int *); 51static int get_threshold(char * /*arg*/, float * /*trta*/, int * /*tpl*/);
52int validate_arguments (void); 52static int validate_arguments(void);
53int run_ping (const char *cmd, const char *addr); 53static int run_ping(const char *cmd, const char *addr);
54int error_scan (char buf[MAX_INPUT_BUFFER], const char *addr); 54static int error_scan(char buf[MAX_INPUT_BUFFER], const char *addr);
55void print_usage (void); 55static void print_help(void);
56void print_help (void); 56void print_usage(void);
57 57
58bool display_html = false; 58static bool display_html = false;
59int wpl = UNKNOWN_PACKET_LOSS; 59static int wpl = UNKNOWN_PACKET_LOSS;
60int cpl = UNKNOWN_PACKET_LOSS; 60static int cpl = UNKNOWN_PACKET_LOSS;
61float wrta = UNKNOWN_TRIP_TIME; 61static float wrta = UNKNOWN_TRIP_TIME;
62float crta = UNKNOWN_TRIP_TIME; 62static float crta = UNKNOWN_TRIP_TIME;
63char **addresses = NULL; 63static char **addresses = NULL;
64int n_addresses = 0; 64static int n_addresses = 0;
65int max_addr = 1; 65static int max_addr = 1;
66int max_packets = -1; 66static int max_packets = -1;
67int verbose = 0; 67static int verbose = 0;
68 68
69float rta = UNKNOWN_TRIP_TIME; 69static float rta = UNKNOWN_TRIP_TIME;
70int pl = UNKNOWN_PACKET_LOSS; 70static int pl = UNKNOWN_PACKET_LOSS;
71 71
72char *warn_text; 72static char *warn_text;
73 73
74 74int main(int argc, char **argv) {
75
76int
77main (int argc, char **argv)
78{
79 char *cmd = NULL; 75 char *cmd = NULL;
80 char *rawcmd = NULL; 76 char *rawcmd = NULL;
81 int result = STATE_UNKNOWN; 77 int result = STATE_UNKNOWN;
82 int this_result = STATE_UNKNOWN; 78 int this_result = STATE_UNKNOWN;
83 int i; 79 int i;
84 80
85 setlocale (LC_ALL, ""); 81 setlocale(LC_ALL, "");
86 setlocale (LC_NUMERIC, "C"); 82 setlocale(LC_NUMERIC, "C");
87 bindtextdomain (PACKAGE, LOCALEDIR); 83 bindtextdomain(PACKAGE, LOCALEDIR);
88 textdomain (PACKAGE); 84 textdomain(PACKAGE);
89 85
90 addresses = malloc (sizeof(char*) * max_addr); 86 addresses = malloc(sizeof(char *) * max_addr);
91 addresses[0] = NULL; 87 addresses[0] = NULL;
92 88
93 /* Parse extra opts if any */ 89 /* Parse extra opts if any */
94 argv=np_extra_opts (&argc, argv, progname); 90 argv = np_extra_opts(&argc, argv, progname);
95 91
96 if (process_arguments (argc, argv) == ERROR) 92 if (process_arguments(argc, argv) == ERROR)
97 usage4 (_("Could not parse arguments")); 93 usage4(_("Could not parse arguments"));
98 94
99 /* Set signal handling and alarm */ 95 /* Set signal handling and alarm */
100 if (signal (SIGALRM, popen_timeout_alarm_handler) == SIG_ERR) { 96 if (signal(SIGALRM, popen_timeout_alarm_handler) == SIG_ERR) {
101 usage4 (_("Cannot catch SIGALRM")); 97 usage4(_("Cannot catch SIGALRM"));
102 } 98 }
103 99
104 /* If ./configure finds ping has timeout values, set plugin alarm slightly 100 /* If ./configure finds ping has timeout values, set plugin alarm slightly
105 * higher so that we can use response from command line ping */ 101 * higher so that we can use response from command line ping */
106#if defined(PING_PACKETS_FIRST) && defined(PING_HAS_TIMEOUT) 102#if defined(PING_PACKETS_FIRST) && defined(PING_HAS_TIMEOUT)
107 alarm (timeout_interval + 1); 103 alarm(timeout_interval + 1);
108#else 104#else
109 alarm (timeout_interval); 105 alarm(timeout_interval);
110#endif 106#endif
111 107
112 for (i = 0 ; i < n_addresses ; i++) { 108 for (i = 0; i < n_addresses; i++) {
113 109
114#ifdef PING6_COMMAND 110#ifdef PING6_COMMAND
115 if (address_family != AF_INET && is_inet6_addr(addresses[i])) 111 if (address_family != AF_INET && is_inet6_addr(addresses[i]))
@@ -120,27 +116,26 @@ main (int argc, char **argv)
120 rawcmd = strdup(PING_COMMAND); 116 rawcmd = strdup(PING_COMMAND);
121#endif 117#endif
122 118
123 /* does the host address of number of packets argument come first? */ 119 /* does the host address of number of packets argument come first? */
124#ifdef PING_PACKETS_FIRST 120#ifdef PING_PACKETS_FIRST
125# ifdef PING_HAS_TIMEOUT 121# ifdef PING_HAS_TIMEOUT
126 xasprintf (&cmd, rawcmd, timeout_interval, max_packets, addresses[i]); 122 xasprintf(&cmd, rawcmd, timeout_interval, max_packets, addresses[i]);
127# else 123# else
128 xasprintf (&cmd, rawcmd, max_packets, addresses[i]); 124 xasprintf(&cmd, rawcmd, max_packets, addresses[i]);
129# endif 125# endif
130#else 126#else
131 xasprintf (&cmd, rawcmd, addresses[i], max_packets); 127 xasprintf(&cmd, rawcmd, addresses[i], max_packets);
132#endif 128#endif
133 129
134 if (verbose >= 2) 130 if (verbose >= 2)
135 printf ("CMD: %s\n", cmd); 131 printf("CMD: %s\n", cmd);
136 132
137 /* run the command */ 133 /* run the command */
138 this_result = run_ping (cmd, addresses[i]); 134 this_result = run_ping(cmd, addresses[i]);
139 135
140 if (pl == UNKNOWN_PACKET_LOSS || rta < 0.0) { 136 if (pl == UNKNOWN_PACKET_LOSS || rta < 0.0) {
141 printf ("%s\n", cmd); 137 printf("%s\n", cmd);
142 die (STATE_UNKNOWN, 138 die(STATE_UNKNOWN, _("CRITICAL - Could not interpret output from ping command\n"));
143 _("CRITICAL - Could not interpret output from ping command\n"));
144 } 139 }
145 140
146 if (pl >= cpl || rta >= crta || rta < 0) 141 if (pl >= cpl || rta >= crta || rta < 0)
@@ -148,267 +143,241 @@ main (int argc, char **argv)
148 else if (pl >= wpl || rta >= wrta) 143 else if (pl >= wpl || rta >= wrta)
149 this_result = STATE_WARNING; 144 this_result = STATE_WARNING;
150 else if (pl >= 0 && rta >= 0) 145 else if (pl >= 0 && rta >= 0)
151 this_result = max_state (STATE_OK, this_result); 146 this_result = max_state(STATE_OK, this_result);
152 147
153 if (n_addresses > 1 && this_result != STATE_UNKNOWN) 148 if (n_addresses > 1 && this_result != STATE_UNKNOWN)
154 die (STATE_OK, "%s is alive\n", addresses[i]); 149 die(STATE_OK, "%s is alive\n", addresses[i]);
155 150
156 if (display_html == true) 151 if (display_html == true)
157 printf ("<A HREF='%s/traceroute.cgi?%s'>", CGIURL, addresses[i]); 152 printf("<A HREF='%s/traceroute.cgi?%s'>", CGIURL, addresses[i]);
158 if (pl == 100) 153 if (pl == 100)
159 printf (_("PING %s - %sPacket loss = %d%%"), state_text (this_result), warn_text, 154 printf(_("PING %s - %sPacket loss = %d%%"), state_text(this_result), warn_text, pl);
160 pl);
161 else 155 else
162 printf (_("PING %s - %sPacket loss = %d%%, RTA = %2.2f ms"), 156 printf(_("PING %s - %sPacket loss = %d%%, RTA = %2.2f ms"), state_text(this_result), warn_text, pl, rta);
163 state_text (this_result), warn_text, pl, rta);
164 if (display_html == true) 157 if (display_html == true)
165 printf ("</A>"); 158 printf("</A>");
166 159
167 /* Print performance data */ 160 /* Print performance data */
168 if (pl != 100) { 161 if (pl != 100) {
169 printf("|%s", fperfdata ("rta", (double) rta, "ms", 162 printf("|%s",
170 wrta>0?true:false, wrta, 163 fperfdata("rta", (double)rta, "ms", wrta > 0 ? true : false, wrta, crta > 0 ? true : false, crta, true, 0, false, 0));
171 crta>0?true:false, crta,
172 true, 0, false, 0));
173 } else { 164 } else {
174 printf("| rta=U;%f;%f;;", wrta, crta); 165 printf("| rta=U;%f;%f;;", wrta, crta);
175 } 166 }
176 printf(" %s\n", perfdata ("pl", (long) pl, "%", 167 printf(" %s\n", perfdata("pl", (long)pl, "%", wpl > 0 ? true : false, wpl, cpl > 0 ? true : false, cpl, true, 0, false, 0));
177 wpl>0?true:false, wpl,
178 cpl>0?true:false, cpl,
179 true, 0, false, 0));
180 168
181 if (verbose >= 2) 169 if (verbose >= 2)
182 printf ("%f:%d%% %f:%d%%\n", wrta, wpl, crta, cpl); 170 printf("%f:%d%% %f:%d%%\n", wrta, wpl, crta, cpl);
183 171
184 result = max_state (result, this_result); 172 result = max_state(result, this_result);
185 free (rawcmd); 173 free(rawcmd);
186 free (cmd); 174 free(cmd);
187 } 175 }
188 176
189 return result; 177 return result;
190} 178}
191 179
192
193
194/* process command-line arguments */ 180/* process command-line arguments */
195int 181int process_arguments(int argc, char **argv) {
196process_arguments (int argc, char **argv)
197{
198 int c = 1; 182 int c = 1;
199 char *ptr; 183 char *ptr;
200 184
201 int option = 0; 185 int option = 0;
202 static struct option longopts[] = { 186 static struct option longopts[] = {STD_LONG_OPTS,
203 STD_LONG_OPTS, 187 {"packets", required_argument, 0, 'p'},
204 {"packets", required_argument, 0, 'p'}, 188 {"nohtml", no_argument, 0, 'n'},
205 {"nohtml", no_argument, 0, 'n'}, 189 {"link", no_argument, 0, 'L'},
206 {"link", no_argument, 0, 'L'}, 190 {"use-ipv4", no_argument, 0, '4'},
207 {"use-ipv4", no_argument, 0, '4'}, 191 {"use-ipv6", no_argument, 0, '6'},
208 {"use-ipv6", no_argument, 0, '6'}, 192 {0, 0, 0, 0}};
209 {0, 0, 0, 0}
210 };
211 193
212 if (argc < 2) 194 if (argc < 2)
213 return ERROR; 195 return ERROR;
214 196
215 for (c = 1; c < argc; c++) { 197 for (c = 1; c < argc; c++) {
216 if (strcmp ("-to", argv[c]) == 0) 198 if (strcmp("-to", argv[c]) == 0)
217 strcpy (argv[c], "-t"); 199 strcpy(argv[c], "-t");
218 if (strcmp ("-nohtml", argv[c]) == 0) 200 if (strcmp("-nohtml", argv[c]) == 0)
219 strcpy (argv[c], "-n"); 201 strcpy(argv[c], "-n");
220 } 202 }
221 203
222 while (1) { 204 while (1) {
223 c = getopt_long (argc, argv, "VvhnL46t:c:w:H:p:", longopts, &option); 205 c = getopt_long(argc, argv, "VvhnL46t:c:w:H:p:", longopts, &option);
224 206
225 if (c == -1 || c == EOF) 207 if (c == -1 || c == EOF)
226 break; 208 break;
227 209
228 switch (c) { 210 switch (c) {
229 case '?': /* usage */ 211 case '?': /* usage */
230 usage5 (); 212 usage5();
231 case 'h': /* help */ 213 case 'h': /* help */
232 print_help (); 214 print_help();
233 exit (STATE_UNKNOWN); 215 exit(STATE_UNKNOWN);
234 break; 216 break;
235 case 'V': /* version */ 217 case 'V': /* version */
236 print_revision (progname, NP_VERSION); 218 print_revision(progname, NP_VERSION);
237 exit (STATE_UNKNOWN); 219 exit(STATE_UNKNOWN);
238 break; 220 break;
239 case 't': /* timeout period */ 221 case 't': /* timeout period */
240 timeout_interval = atoi (optarg); 222 timeout_interval = atoi(optarg);
241 break; 223 break;
242 case 'v': /* verbose mode */ 224 case 'v': /* verbose mode */
243 verbose++; 225 verbose++;
244 break; 226 break;
245 case '4': /* IPv4 only */ 227 case '4': /* IPv4 only */
246 address_family = AF_INET; 228 address_family = AF_INET;
247 break; 229 break;
248 case '6': /* IPv6 only */ 230 case '6': /* IPv6 only */
249#ifdef USE_IPV6 231#ifdef USE_IPV6
250 address_family = AF_INET6; 232 address_family = AF_INET6;
251#else 233#else
252 usage (_("IPv6 support not available\n")); 234 usage(_("IPv6 support not available\n"));
253#endif 235#endif
254 break; 236 break;
255 case 'H': /* hostname */ 237 case 'H': /* hostname */
256 ptr=optarg; 238 ptr = optarg;
257 while (1) { 239 while (1) {
258 n_addresses++; 240 n_addresses++;
259 if (n_addresses > max_addr) { 241 if (n_addresses > max_addr) {
260 max_addr *= 2; 242 max_addr *= 2;
261 addresses = realloc (addresses, sizeof(char*) * max_addr); 243 addresses = realloc(addresses, sizeof(char *) * max_addr);
262 if (addresses == NULL) 244 if (addresses == NULL)
263 die (STATE_UNKNOWN, _("Could not realloc() addresses\n")); 245 die(STATE_UNKNOWN, _("Could not realloc() addresses\n"));
264 } 246 }
265 addresses[n_addresses-1] = ptr; 247 addresses[n_addresses - 1] = ptr;
266 if ((ptr = index (ptr, ','))) { 248 if ((ptr = index(ptr, ','))) {
267 strcpy (ptr, ""); 249 strcpy(ptr, "");
268 ptr += sizeof(char); 250 ptr += sizeof(char);
269 } else { 251 } else {
270 break; 252 break;
271 } 253 }
272 } 254 }
273 break; 255 break;
274 case 'p': /* number of packets to send */ 256 case 'p': /* number of packets to send */
275 if (is_intnonneg (optarg)) 257 if (is_intnonneg(optarg))
276 max_packets = atoi (optarg); 258 max_packets = atoi(optarg);
277 else 259 else
278 usage2 (_("<max_packets> (%s) must be a non-negative number\n"), optarg); 260 usage2(_("<max_packets> (%s) must be a non-negative number\n"), optarg);
279 break; 261 break;
280 case 'n': /* no HTML */ 262 case 'n': /* no HTML */
281 display_html = false; 263 display_html = false;
282 break; 264 break;
283 case 'L': /* show HTML */ 265 case 'L': /* show HTML */
284 display_html = true; 266 display_html = true;
285 break; 267 break;
286 case 'c': 268 case 'c':
287 get_threshold (optarg, &crta, &cpl); 269 get_threshold(optarg, &crta, &cpl);
288 break; 270 break;
289 case 'w': 271 case 'w':
290 get_threshold (optarg, &wrta, &wpl); 272 get_threshold(optarg, &wrta, &wpl);
291 break; 273 break;
292 } 274 }
293 } 275 }
294 276
295 c = optind; 277 c = optind;
296 if (c == argc) 278 if (c == argc)
297 return validate_arguments (); 279 return validate_arguments();
298 280
299 if (addresses[0] == NULL) { 281 if (addresses[0] == NULL) {
300 if (!is_host (argv[c])) { 282 if (!is_host(argv[c])) {
301 usage2 (_("Invalid hostname/address"), argv[c]); 283 usage2(_("Invalid hostname/address"), argv[c]);
302 } else { 284 } else {
303 addresses[0] = argv[c++]; 285 addresses[0] = argv[c++];
304 n_addresses++; 286 n_addresses++;
305 if (c == argc) 287 if (c == argc)
306 return validate_arguments (); 288 return validate_arguments();
307 } 289 }
308 } 290 }
309 291
310 if (wpl == UNKNOWN_PACKET_LOSS) { 292 if (wpl == UNKNOWN_PACKET_LOSS) {
311 if (!is_intpercent (argv[c])) { 293 if (!is_intpercent(argv[c])) {
312 printf (_("<wpl> (%s) must be an integer percentage\n"), argv[c]); 294 printf(_("<wpl> (%s) must be an integer percentage\n"), argv[c]);
313 return ERROR; 295 return ERROR;
314 } else { 296 } else {
315 wpl = atoi (argv[c++]); 297 wpl = atoi(argv[c++]);
316 if (c == argc) 298 if (c == argc)
317 return validate_arguments (); 299 return validate_arguments();
318 } 300 }
319 } 301 }
320 302
321 if (cpl == UNKNOWN_PACKET_LOSS) { 303 if (cpl == UNKNOWN_PACKET_LOSS) {
322 if (!is_intpercent (argv[c])) { 304 if (!is_intpercent(argv[c])) {
323 printf (_("<cpl> (%s) must be an integer percentage\n"), argv[c]); 305 printf(_("<cpl> (%s) must be an integer percentage\n"), argv[c]);
324 return ERROR; 306 return ERROR;
325 } else { 307 } else {
326 cpl = atoi (argv[c++]); 308 cpl = atoi(argv[c++]);
327 if (c == argc) 309 if (c == argc)
328 return validate_arguments (); 310 return validate_arguments();
329 } 311 }
330 } 312 }
331 313
332 if (wrta < 0.0) { 314 if (wrta < 0.0) {
333 if (is_negative (argv[c])) { 315 if (is_negative(argv[c])) {
334 printf (_("<wrta> (%s) must be a non-negative number\n"), argv[c]); 316 printf(_("<wrta> (%s) must be a non-negative number\n"), argv[c]);
335 return ERROR; 317 return ERROR;
336 } else { 318 } else {
337 wrta = atof (argv[c++]); 319 wrta = atof(argv[c++]);
338 if (c == argc) 320 if (c == argc)
339 return validate_arguments (); 321 return validate_arguments();
340 } 322 }
341 } 323 }
342 324
343 if (crta < 0.0) { 325 if (crta < 0.0) {
344 if (is_negative (argv[c])) { 326 if (is_negative(argv[c])) {
345 printf (_("<crta> (%s) must be a non-negative number\n"), argv[c]); 327 printf(_("<crta> (%s) must be a non-negative number\n"), argv[c]);
346 return ERROR; 328 return ERROR;
347 } else { 329 } else {
348 crta = atof (argv[c++]); 330 crta = atof(argv[c++]);
349 if (c == argc) 331 if (c == argc)
350 return validate_arguments (); 332 return validate_arguments();
351 } 333 }
352 } 334 }
353 335
354 if (max_packets == -1) { 336 if (max_packets == -1) {
355 if (is_intnonneg (argv[c])) { 337 if (is_intnonneg(argv[c])) {
356 max_packets = atoi (argv[c++]); 338 max_packets = atoi(argv[c++]);
357 } else { 339 } else {
358 printf (_("<max_packets> (%s) must be a non-negative number\n"), argv[c]); 340 printf(_("<max_packets> (%s) must be a non-negative number\n"), argv[c]);
359 return ERROR; 341 return ERROR;
360 } 342 }
361 } 343 }
362 344
363 return validate_arguments (); 345 return validate_arguments();
364} 346}
365 347
366 348int get_threshold(char *arg, float *trta, int *tpl) {
367 349 if (is_intnonneg(arg) && sscanf(arg, "%f", trta) == 1)
368int
369get_threshold (char *arg, float *trta, int *tpl)
370{
371 if (is_intnonneg (arg) && sscanf (arg, "%f", trta) == 1)
372 return OK; 350 return OK;
373 else if (strpbrk (arg, ",:") && strstr (arg, "%") && sscanf (arg, "%f%*[:,]%d%%", trta, tpl) == 2) 351 else if (strpbrk(arg, ",:") && strstr(arg, "%") && sscanf(arg, "%f%*[:,]%d%%", trta, tpl) == 2)
374 return OK; 352 return OK;
375 else if (strstr (arg, "%") && sscanf (arg, "%d%%", tpl) == 1) 353 else if (strstr(arg, "%") && sscanf(arg, "%d%%", tpl) == 1)
376 return OK; 354 return OK;
377 355
378 usage2 (_("%s: Warning threshold must be integer or percentage!\n\n"), arg); 356 usage2(_("%s: Warning threshold must be integer or percentage!\n\n"), arg);
379 return STATE_UNKNOWN; 357 return STATE_UNKNOWN;
380} 358}
381 359
382 360int validate_arguments() {
383
384int
385validate_arguments ()
386{
387 float max_seconds; 361 float max_seconds;
388 int i; 362 int i;
389 363
390 if (wrta < 0.0) { 364 if (wrta < 0.0) {
391 printf (_("<wrta> was not set\n")); 365 printf(_("<wrta> was not set\n"));
392 return ERROR; 366 return ERROR;
393 } 367 } else if (crta < 0.0) {
394 else if (crta < 0.0) { 368 printf(_("<crta> was not set\n"));
395 printf (_("<crta> was not set\n"));
396 return ERROR; 369 return ERROR;
397 } 370 } else if (wpl == UNKNOWN_PACKET_LOSS) {
398 else if (wpl == UNKNOWN_PACKET_LOSS) { 371 printf(_("<wpl> was not set\n"));
399 printf (_("<wpl> was not set\n"));
400 return ERROR; 372 return ERROR;
401 } 373 } else if (cpl == UNKNOWN_PACKET_LOSS) {
402 else if (cpl == UNKNOWN_PACKET_LOSS) { 374 printf(_("<cpl> was not set\n"));
403 printf (_("<cpl> was not set\n"));
404 return ERROR; 375 return ERROR;
405 } 376 } else if (wrta > crta) {
406 else if (wrta > crta) { 377 printf(_("<wrta> (%f) cannot be larger than <crta> (%f)\n"), wrta, crta);
407 printf (_("<wrta> (%f) cannot be larger than <crta> (%f)\n"), wrta, crta);
408 return ERROR; 378 return ERROR;
409 } 379 } else if (wpl > cpl) {
410 else if (wpl > cpl) { 380 printf(_("<wpl> (%d) cannot be larger than <cpl> (%d)\n"), wpl, cpl);
411 printf (_("<wpl> (%d) cannot be larger than <cpl> (%d)\n"), wpl, cpl);
412 return ERROR; 381 return ERROR;
413 } 382 }
414 383
@@ -419,68 +388,61 @@ validate_arguments ()
419 if (max_seconds > timeout_interval) 388 if (max_seconds > timeout_interval)
420 timeout_interval = (int)max_seconds; 389 timeout_interval = (int)max_seconds;
421 390
422 for (i=0; i<n_addresses; i++) { 391 for (i = 0; i < n_addresses; i++) {
423 if (!is_host(addresses[i])) 392 if (!is_host(addresses[i]))
424 usage2 (_("Invalid hostname/address"), addresses[i]); 393 usage2(_("Invalid hostname/address"), addresses[i]);
425 } 394 }
426 395
427 if (n_addresses == 0) { 396 if (n_addresses == 0) {
428 usage (_("You must specify a server address or host name")); 397 usage(_("You must specify a server address or host name"));
429 } 398 }
430 399
431 return OK; 400 return OK;
432} 401}
433 402
434 403int run_ping(const char *cmd, const char *addr) {
435
436int
437run_ping (const char *cmd, const char *addr)
438{
439 char buf[MAX_INPUT_BUFFER]; 404 char buf[MAX_INPUT_BUFFER];
440 int result = STATE_UNKNOWN; 405 int result = STATE_UNKNOWN;
441 int match; 406 int match;
442 407
443 if ((child_process = spopen (cmd)) == NULL) 408 if ((child_process = spopen(cmd)) == NULL)
444 die (STATE_UNKNOWN, _("Could not open pipe: %s\n"), cmd); 409 die(STATE_UNKNOWN, _("Could not open pipe: %s\n"), cmd);
445 410
446 child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); 411 child_stderr = fdopen(child_stderr_array[fileno(child_process)], "r");
447 if (child_stderr == NULL) 412 if (child_stderr == NULL)
448 printf (_("Cannot open stderr for %s\n"), cmd); 413 printf(_("Cannot open stderr for %s\n"), cmd);
449 414
450 while (fgets (buf, MAX_INPUT_BUFFER - 1, child_process)) { 415 while (fgets(buf, MAX_INPUT_BUFFER - 1, child_process)) {
451 416
452 if (verbose >= 3) 417 if (verbose >= 3)
453 printf("Output: %s", buf); 418 printf("Output: %s", buf);
454 419
455 result = max_state (result, error_scan (buf, addr)); 420 result = max_state(result, error_scan(buf, addr));
456 421
457 /* get the percent loss statistics */ 422 /* get the percent loss statistics */
458 match = 0; 423 match = 0;
459 if((sscanf(buf,"%*d packets transmitted, %*d packets received, +%*d errors, %d%% packet loss%n",&pl,&match) && match) || 424 if ((sscanf(buf, "%*d packets transmitted, %*d packets received, +%*d errors, %d%% packet loss%n", &pl, &match) && match) ||
460 (sscanf(buf,"%*d packets transmitted, %*d packets received, +%*d duplicates, %d%% packet loss%n",&pl,&match) && match) || 425 (sscanf(buf, "%*d packets transmitted, %*d packets received, +%*d duplicates, %d%% packet loss%n", &pl, &match) && match) ||
461 (sscanf(buf,"%*d packets transmitted, %*d received, +%*d duplicates, %d%% packet loss%n",&pl,&match) && match) || 426 (sscanf(buf, "%*d packets transmitted, %*d received, +%*d duplicates, %d%% packet loss%n", &pl, &match) && match) ||
462 (sscanf(buf,"%*d packets transmitted, %*d packets received, %d%% packet loss%n",&pl,&match) && match) || 427 (sscanf(buf, "%*d packets transmitted, %*d packets received, %d%% packet loss%n", &pl, &match) && match) ||
463 (sscanf(buf,"%*d packets transmitted, %*d packets received, %d%% loss, time%n",&pl,&match) && match) || 428 (sscanf(buf, "%*d packets transmitted, %*d packets received, %d%% loss, time%n", &pl, &match) && match) ||
464 (sscanf(buf,"%*d packets transmitted, %*d received, %d%% loss, time%n",&pl,&match) && match) || 429 (sscanf(buf, "%*d packets transmitted, %*d received, %d%% loss, time%n", &pl, &match) && match) ||
465 (sscanf(buf,"%*d packets transmitted, %*d received, %d%% packet loss, time%n",&pl,&match) && match) || 430 (sscanf(buf, "%*d packets transmitted, %*d received, %d%% packet loss, time%n", &pl, &match) && match) ||
466 (sscanf(buf,"%*d packets transmitted, %*d received, +%*d errors, %d%% packet loss%n",&pl,&match) && match) || 431 (sscanf(buf, "%*d packets transmitted, %*d received, +%*d errors, %d%% packet loss%n", &pl, &match) && match) ||
467 (sscanf(buf,"%*d packets transmitted %*d received, +%*d errors, %d%% packet loss%n",&pl,&match) && match) || 432 (sscanf(buf, "%*d packets transmitted %*d received, +%*d errors, %d%% packet loss%n", &pl, &match) && match) ||
468 (sscanf(buf,"%*[^(](%d%% %*[^)])%n",&pl,&match) && match) 433 (sscanf(buf, "%*[^(](%d%% %*[^)])%n", &pl, &match) && match))
469 )
470 continue; 434 continue;
471 435
472 /* get the round trip average */ 436 /* get the round trip average */
473 else 437 else if ((sscanf(buf, "round-trip min/avg/max = %*f/%f/%*f%n", &rta, &match) && match) ||
474 if((sscanf(buf,"round-trip min/avg/max = %*f/%f/%*f%n",&rta,&match) && match) || 438 (sscanf(buf, "round-trip min/avg/max/mdev = %*f/%f/%*f/%*f%n", &rta, &match) && match) ||
475 (sscanf(buf,"round-trip min/avg/max/mdev = %*f/%f/%*f/%*f%n",&rta,&match) && match) || 439 (sscanf(buf, "round-trip min/avg/max/sdev = %*f/%f/%*f/%*f%n", &rta, &match) && match) ||
476 (sscanf(buf,"round-trip min/avg/max/sdev = %*f/%f/%*f/%*f%n",&rta,&match) && match) || 440 (sscanf(buf, "round-trip min/avg/max/stddev = %*f/%f/%*f/%*f%n", &rta, &match) && match) ||
477 (sscanf(buf,"round-trip min/avg/max/stddev = %*f/%f/%*f/%*f%n",&rta,&match) && match) || 441 (sscanf(buf, "round-trip min/avg/max/std-dev = %*f/%f/%*f/%*f%n", &rta, &match) && match) ||
478 (sscanf(buf,"round-trip min/avg/max/std-dev = %*f/%f/%*f/%*f%n",&rta,&match) && match) || 442 (sscanf(buf, "round-trip (ms) min/avg/max = %*f/%f/%*f%n", &rta, &match) && match) ||
479 (sscanf(buf,"round-trip (ms) min/avg/max = %*f/%f/%*f%n",&rta,&match) && match) || 443 (sscanf(buf, "round-trip (ms) min/avg/max/stddev = %*f/%f/%*f/%*f%n", &rta, &match) && match) ||
480 (sscanf(buf,"round-trip (ms) min/avg/max/stddev = %*f/%f/%*f/%*f%n",&rta,&match) && match) || 444 (sscanf(buf, "rtt min/avg/max/mdev = %*f/%f/%*f/%*f ms%n", &rta, &match) && match) ||
481 (sscanf(buf,"rtt min/avg/max/mdev = %*f/%f/%*f/%*f ms%n",&rta,&match) && match) || 445 (sscanf(buf, "%*[^=] = %*fms, %*[^=] = %*fms, %*[^=] = %fms%n", &rta, &match) && match))
482 (sscanf(buf, "%*[^=] = %*fms, %*[^=] = %*fms, %*[^=] = %fms%n", &rta, &match) && match)
483 )
484 continue; 446 continue;
485 } 447 }
486 448
@@ -490,16 +452,14 @@ run_ping (const char *cmd, const char *addr)
490 452
491 /* check stderr, setting at least WARNING if there is output here */ 453 /* check stderr, setting at least WARNING if there is output here */
492 /* Add warning into warn_text */ 454 /* Add warning into warn_text */
493 while (fgets (buf, MAX_INPUT_BUFFER - 1, child_stderr)) { 455 while (fgets(buf, MAX_INPUT_BUFFER - 1, child_stderr)) {
494 if ( 456 if (!strstr(buf, "WARNING - no SO_TIMESTAMP support, falling back to SIOCGSTAMP") && !strstr(buf, "Warning: time of day goes back")
495 ! strstr(buf,"WARNING - no SO_TIMESTAMP support, falling back to SIOCGSTAMP")
496 && ! strstr(buf,"Warning: time of day goes back")
497 457
498 ) { 458 ) {
499 if (verbose >= 3) { 459 if (verbose >= 3) {
500 printf("Got stderr: %s", buf); 460 printf("Got stderr: %s", buf);
501 } 461 }
502 if ((result=error_scan(buf, addr)) == STATE_OK) { 462 if ((result = error_scan(buf, addr)) == STATE_OK) {
503 result = STATE_WARNING; 463 result = STATE_WARNING;
504 if (warn_text == NULL) { 464 if (warn_text == NULL) {
505 warn_text = strdup(_("System call sent warnings to stderr ")); 465 warn_text = strdup(_("System call sent warnings to stderr "));
@@ -510,10 +470,9 @@ run_ping (const char *cmd, const char *addr)
510 } 470 }
511 } 471 }
512 472
513 (void) fclose (child_stderr); 473 (void)fclose(child_stderr);
514
515 474
516 spclose (child_process); 475 spclose(child_process);
517 476
518 if (warn_text == NULL) 477 if (warn_text == NULL)
519 warn_text = strdup(""); 478 warn_text = strdup("");
@@ -521,100 +480,86 @@ run_ping (const char *cmd, const char *addr)
521 return result; 480 return result;
522} 481}
523 482
524 483int error_scan(char buf[MAX_INPUT_BUFFER], const char *addr) {
525 484 if (strstr(buf, "Network is unreachable") || strstr(buf, "Destination Net Unreachable") || strstr(buf, "No route"))
526int 485 die(STATE_CRITICAL, _("CRITICAL - Network Unreachable (%s)\n"), addr);
527error_scan (char buf[MAX_INPUT_BUFFER], const char *addr) 486 else if (strstr(buf, "Destination Host Unreachable") || strstr(buf, "Address unreachable"))
528{ 487 die(STATE_CRITICAL, _("CRITICAL - Host Unreachable (%s)\n"), addr);
529 if (strstr (buf, "Network is unreachable") || 488 else if (strstr(buf, "Destination Port Unreachable") || strstr(buf, "Port unreachable"))
530 strstr (buf, "Destination Net Unreachable") || 489 die(STATE_CRITICAL, _("CRITICAL - Bogus ICMP: Port Unreachable (%s)\n"), addr);
531 strstr (buf, "No route") 490 else if (strstr(buf, "Destination Protocol Unreachable"))
532 ) 491 die(STATE_CRITICAL, _("CRITICAL - Bogus ICMP: Protocol Unreachable (%s)\n"), addr);
533 die (STATE_CRITICAL, _("CRITICAL - Network Unreachable (%s)\n"), addr); 492 else if (strstr(buf, "Destination Net Prohibited"))
534 else if (strstr (buf, "Destination Host Unreachable") || strstr(buf, "Address unreachable")) 493 die(STATE_CRITICAL, _("CRITICAL - Network Prohibited (%s)\n"), addr);
535 die (STATE_CRITICAL, _("CRITICAL - Host Unreachable (%s)\n"), addr); 494 else if (strstr(buf, "Destination Host Prohibited"))
536 else if (strstr (buf, "Destination Port Unreachable") || strstr(buf, "Port unreachable")) 495 die(STATE_CRITICAL, _("CRITICAL - Host Prohibited (%s)\n"), addr);
537 die (STATE_CRITICAL, _("CRITICAL - Bogus ICMP: Port Unreachable (%s)\n"), addr); 496 else if (strstr(buf, "Packet filtered") || strstr(buf, "Administratively prohibited"))
538 else if (strstr (buf, "Destination Protocol Unreachable")) 497 die(STATE_CRITICAL, _("CRITICAL - Packet Filtered (%s)\n"), addr);
539 die (STATE_CRITICAL, _("CRITICAL - Bogus ICMP: Protocol Unreachable (%s)\n"), addr); 498 else if (strstr(buf, "unknown host"))
540 else if (strstr (buf, "Destination Net Prohibited")) 499 die(STATE_CRITICAL, _("CRITICAL - Host not found (%s)\n"), addr);
541 die (STATE_CRITICAL, _("CRITICAL - Network Prohibited (%s)\n"), addr); 500 else if (strstr(buf, "Time to live exceeded") || strstr(buf, "Time exceeded"))
542 else if (strstr (buf, "Destination Host Prohibited")) 501 die(STATE_CRITICAL, _("CRITICAL - Time to live exceeded (%s)\n"), addr);
543 die (STATE_CRITICAL, _("CRITICAL - Host Prohibited (%s)\n"), addr); 502 else if (strstr(buf, "Destination unreachable: "))
544 else if (strstr (buf, "Packet filtered") || strstr(buf, "Administratively prohibited")) 503 die(STATE_CRITICAL, _("CRITICAL - Destination Unreachable (%s)\n"), addr);
545 die (STATE_CRITICAL, _("CRITICAL - Packet Filtered (%s)\n"), addr); 504
546 else if (strstr (buf, "unknown host" )) 505 if (strstr(buf, "(DUP!)") || strstr(buf, "DUPLICATES FOUND")) {
547 die (STATE_CRITICAL, _("CRITICAL - Host not found (%s)\n"), addr);
548 else if (strstr (buf, "Time to live exceeded") || strstr(buf, "Time exceeded"))
549 die (STATE_CRITICAL, _("CRITICAL - Time to live exceeded (%s)\n"), addr);
550 else if (strstr (buf, "Destination unreachable: "))
551 die (STATE_CRITICAL, _("CRITICAL - Destination Unreachable (%s)\n"), addr);
552
553 if (strstr (buf, "(DUP!)") || strstr (buf, "DUPLICATES FOUND")) {
554 if (warn_text == NULL) 506 if (warn_text == NULL)
555 warn_text = strdup (_(WARN_DUPLICATES)); 507 warn_text = strdup(_(WARN_DUPLICATES));
556 else if (! strstr (warn_text, _(WARN_DUPLICATES)) && 508 else if (!strstr(warn_text, _(WARN_DUPLICATES)) && xasprintf(&warn_text, "%s %s", warn_text, _(WARN_DUPLICATES)) == -1)
557 xasprintf (&warn_text, "%s %s", warn_text, _(WARN_DUPLICATES)) == -1) 509 die(STATE_UNKNOWN, _("Unable to realloc warn_text\n"));
558 die (STATE_UNKNOWN, _("Unable to realloc warn_text\n"));
559 return (STATE_WARNING); 510 return (STATE_WARNING);
560 } 511 }
561 512
562 return (STATE_OK); 513 return (STATE_OK);
563} 514}
564 515
516void print_help(void) {
517 print_revision(progname, NP_VERSION);
565 518
519 printf("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n");
520 printf(COPYRIGHT, copyright, email);
566 521
567void 522 printf(_("Use ping to check connection statistics for a remote host."));
568print_help (void)
569{
570 print_revision (progname, NP_VERSION);
571
572 printf ("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n");
573 printf (COPYRIGHT, copyright, email);
574
575 printf (_("Use ping to check connection statistics for a remote host."));
576 523
577 printf ("\n\n"); 524 printf("\n\n");
578 525
579 print_usage (); 526 print_usage();
580 527
581 printf (UT_HELP_VRSN); 528 printf(UT_HELP_VRSN);
582 printf (UT_EXTRA_OPTS); 529 printf(UT_EXTRA_OPTS);
583 530
584 printf (UT_IPv46); 531 printf(UT_IPv46);
585 532
586 printf (" %s\n", "-H, --hostname=HOST"); 533 printf(" %s\n", "-H, --hostname=HOST");
587 printf (" %s\n", _("host to ping")); 534 printf(" %s\n", _("host to ping"));
588 printf (" %s\n", "-w, --warning=THRESHOLD"); 535 printf(" %s\n", "-w, --warning=THRESHOLD");
589 printf (" %s\n", _("warning threshold pair")); 536 printf(" %s\n", _("warning threshold pair"));
590 printf (" %s\n", "-c, --critical=THRESHOLD"); 537 printf(" %s\n", "-c, --critical=THRESHOLD");
591 printf (" %s\n", _("critical threshold pair")); 538 printf(" %s\n", _("critical threshold pair"));
592 printf (" %s\n", "-p, --packets=INTEGER"); 539 printf(" %s\n", "-p, --packets=INTEGER");
593 printf (" %s ", _("number of ICMP ECHO packets to send")); 540 printf(" %s ", _("number of ICMP ECHO packets to send"));
594 printf (_("(Default: %d)\n"), DEFAULT_MAX_PACKETS); 541 printf(_("(Default: %d)\n"), DEFAULT_MAX_PACKETS);
595 printf (" %s\n", "-L, --link"); 542 printf(" %s\n", "-L, --link");
596 printf (" %s\n", _("show HTML in the plugin output (obsoleted by urlize)")); 543 printf(" %s\n", _("show HTML in the plugin output (obsoleted by urlize)"));
597 544
598 printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); 545 printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
599 546
600 printf ("\n"); 547 printf("\n");
601 printf ("%s\n", _("THRESHOLD is <rta>,<pl>% where <rta> is the round trip average travel")); 548 printf("%s\n", _("THRESHOLD is <rta>,<pl>% where <rta> is the round trip average travel"));
602 printf ("%s\n", _("time (ms) which triggers a WARNING or CRITICAL state, and <pl> is the")); 549 printf("%s\n", _("time (ms) which triggers a WARNING or CRITICAL state, and <pl> is the"));
603 printf ("%s\n", _("percentage of packet loss to trigger an alarm state.")); 550 printf("%s\n", _("percentage of packet loss to trigger an alarm state."));
604 551
605 printf ("\n"); 552 printf("\n");
606 printf ("%s\n", _("This plugin uses the ping command to probe the specified host for packet loss")); 553 printf("%s\n", _("This plugin uses the ping command to probe the specified host for packet loss"));
607 printf ("%s\n", _("(percentage) and round trip average (milliseconds). It can produce HTML output")); 554 printf("%s\n", _("(percentage) and round trip average (milliseconds). It can produce HTML output"));
608 printf ("%s\n", _("linking to a traceroute CGI contributed by Ian Cass. The CGI can be found in")); 555 printf("%s\n", _("linking to a traceroute CGI contributed by Ian Cass. The CGI can be found in"));
609 printf ("%s\n", _("the contrib area of the downloads section at http://www.nagios.org/")); 556 printf("%s\n", _("the contrib area of the downloads section at http://www.nagios.org/"));
610 557
611 printf (UT_SUPPORT); 558 printf(UT_SUPPORT);
612} 559}
613 560
614void 561void print_usage(void) {
615print_usage (void) 562 printf("%s\n", _("Usage:"));
616{ 563 printf("%s -H <host_address> -w <wrta>,<wpl>%% -c <crta>,<cpl>%%\n", progname);
617 printf ("%s\n", _("Usage:")); 564 printf(" [-p packets] [-t timeout] [-4|-6]\n");
618 printf ("%s -H <host_address> -w <wrta>,<wpl>%% -c <crta>,<cpl>%%\n", progname);
619 printf (" [-p packets] [-t timeout] [-4|-6]\n");
620} 565}