1 /*****************************************************************************
3 * Nagios check_fping plugin
6 * Copyright (c) 2000-2007 Nagios Plugins Development Team
10 * This file contains the check_disk plugin
12 * This plugin will use the fping command to ping the specified host for a
16 * This program is free software: you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation, either version 3 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program. If not, see <http://www.gnu.org/licenses/>.
30 *****************************************************************************/
32 const char *progname
= "check_fping";
33 const char *copyright
= "2000-2007";
34 const char *email
= "nagiosplug-devel@lists.sourceforge.net";
48 int textscan (char *buf
);
49 int process_arguments (int, char **);
50 int get_threshold (char *arg
, char *rv
[2]);
51 void print_help (void);
52 void print_usage (void);
54 char *server_name
= NULL
;
55 int packet_size
= PACKET_SIZE
;
56 int packet_count
= PACKET_COUNT
;
68 main (int argc
, char **argv
)
70 /* normaly should be int result = STATE_UNKNOWN; */
72 int status
= STATE_UNKNOWN
;
74 char *command_line
= NULL
;
75 char *input_buffer
= NULL
;
76 input_buffer
= malloc (MAX_INPUT_BUFFER
);
78 setlocale (LC_ALL
, "");
79 bindtextdomain (PACKAGE
, LOCALEDIR
);
82 /* Parse extra opts if any */
83 argv
=np_extra_opts (&argc
, argv
, progname
);
85 if (process_arguments (argc
, argv
) == ERROR
)
86 usage4 (_("Could not parse arguments"));
88 server
= strscpy (server
, server_name
);
90 /* compose the command */
91 asprintf (&command_line
, "%s -b %d -c %d %s", PATH_TO_FPING
,
92 packet_size
, packet_count
, server
);
95 printf ("%s\n", command_line
);
98 child_process
= spopen (command_line
);
99 if (child_process
== NULL
) {
100 printf (_("Could not open pipe: %s\n"), command_line
);
101 return STATE_UNKNOWN
;
104 child_stderr
= fdopen (child_stderr_array
[fileno (child_process
)], "r");
105 if (child_stderr
== NULL
) {
106 printf (_("Could not open stderr for %s\n"), command_line
);
109 while (fgets (input_buffer
, MAX_INPUT_BUFFER
- 1, child_process
)) {
111 printf ("%s", input_buffer
);
112 status
= max_state (status
, textscan (input_buffer
));
115 /* If we get anything on STDERR, at least set warning */
116 while (fgets (input_buffer
, MAX_INPUT_BUFFER
- 1, child_stderr
)) {
117 status
= max_state (status
, STATE_WARNING
);
119 printf ("%s", input_buffer
);
120 status
= max_state (status
, textscan (input_buffer
));
122 (void) fclose (child_stderr
);
125 if (spclose (child_process
))
126 /* need to use max_state not max */
127 status
= max_state (status
, STATE_WARNING
);
129 printf ("FPING %s - %s\n", state_text (status
), server_name
);
143 int status
= STATE_UNKNOWN
;
145 if (strstr (buf
, "not found")) {
146 die (STATE_CRITICAL
, _("FPING UNKNOW - %s not found\n"), server_name
);
149 else if (strstr (buf
, "is unreachable") || strstr (buf
, "Unreachable")) {
150 die (STATE_CRITICAL
, _("FPING CRITICAL - %s is unreachable\n"),
154 else if (strstr (buf
, "is down")) {
155 die (STATE_CRITICAL
, _("FPING CRITICAL - %s is down\n"), server_name
);
158 else if (strstr (buf
, "is alive")) {
162 else if (strstr (buf
, "xmt/rcv/%loss") && strstr (buf
, "min/avg/max")) {
163 losstr
= strstr (buf
, "=");
164 losstr
= 1 + strstr (losstr
, "/");
165 losstr
= 1 + strstr (losstr
, "/");
166 rtastr
= strstr (buf
, "min/avg/max");
167 rtastr
= strstr (rtastr
, "=");
168 rtastr
= 1 + index (rtastr
, '/');
169 loss
= strtod (losstr
, NULL
);
170 rta
= strtod (rtastr
, NULL
);
171 if (cpl_p
== TRUE
&& loss
> cpl
)
172 status
= STATE_CRITICAL
;
173 else if (crta_p
== TRUE
&& rta
> crta
)
174 status
= STATE_CRITICAL
;
175 else if (wpl_p
== TRUE
&& loss
> wpl
)
176 status
= STATE_WARNING
;
177 else if (wrta_p
== TRUE
&& rta
> wrta
)
178 status
= STATE_WARNING
;
182 _("FPING %s - %s (loss=%.0f%%, rta=%f ms)|%s %s\n"),
183 state_text (status
), server_name
, loss
, rta
,
184 perfdata ("loss", (long int)loss
, "%", wpl_p
, wpl
, cpl_p
, cpl
, TRUE
, 0, TRUE
, 100),
185 fperfdata ("rta", rta
/1.0e3
, "s", wrta_p
, wrta
/1.0e3
, crta_p
, crta
/1.0e3
, TRUE
, 0, FALSE
, 0));
188 else if(strstr (buf
, "xmt/rcv/%loss") ) {
189 /* no min/max/avg if host was unreachable in fping v2.2.b1 */
190 losstr
= strstr (buf
, "=");
191 losstr
= 1 + strstr (losstr
, "/");
192 losstr
= 1 + strstr (losstr
, "/");
193 loss
= strtod (losstr
, NULL
);
194 if (atoi(losstr
) == 100)
195 status
= STATE_CRITICAL
;
196 else if (cpl_p
== TRUE
&& loss
> cpl
)
197 status
= STATE_CRITICAL
;
198 else if (wpl_p
== TRUE
&& loss
> wpl
)
199 status
= STATE_WARNING
;
202 /* loss=%.0f%%;%d;%d;0;100 */
203 die (status
, _("FPING %s - %s (loss=%.0f%% )|%s\n"),
204 state_text (status
), server_name
, loss
,
205 perfdata ("loss", (long int)loss
, "%", wpl_p
, wpl
, cpl_p
, cpl
, TRUE
, 0, TRUE
, 100));
209 status
= max_state (status
, STATE_WARNING
);
217 /* process command-line arguments */
219 process_arguments (int argc
, char **argv
)
225 static struct option longopts
[] = {
226 {"hostname", required_argument
, 0, 'H'},
227 {"critical", required_argument
, 0, 'c'},
228 {"warning", required_argument
, 0, 'w'},
229 {"bytes", required_argument
, 0, 'b'},
230 {"number", required_argument
, 0, 'n'},
231 {"verbose", no_argument
, 0, 'v'},
232 {"version", no_argument
, 0, 'V'},
233 {"help", no_argument
, 0, 'h'},
243 if (!is_option (argv
[1])) {
244 server_name
= argv
[1];
251 c
= getopt_long (argc
, argv
, "+hVvH:c:w:b:n:", longopts
, &option
);
253 if (c
== -1 || c
== EOF
|| c
== 1)
257 case '?': /* print short usage statement if args not parsable */
262 case 'V': /* version */
263 print_revision (progname
, NP_VERSION
);
265 case 'v': /* verbose mode */
268 case 'H': /* hostname */
269 if (is_host (optarg
) == FALSE
) {
270 usage2 (_("Invalid hostname/address"), optarg
);
272 server_name
= strscpy (server_name
, optarg
);
275 get_threshold (optarg
, rv
);
277 crta
= strtod (rv
[RTA
], NULL
);
288 get_threshold (optarg
, rv
);
290 wrta
= strtod (rv
[RTA
], NULL
);
300 case 'b': /* bytes per packet */
301 if (is_intpos (optarg
))
302 packet_size
= atoi (optarg
);
304 usage (_("Packet size must be a positive integer"));
306 case 'n': /* number of packets */
307 if (is_intpos (optarg
))
308 packet_count
= atoi (optarg
);
310 usage (_("Packet count must be a positive integer"));
315 if (server_name
== NULL
)
316 usage4 (_("Hostname was not supplied"));
323 get_threshold (char *arg
, char *rv
[2])
328 arg1
= strscpy (arg1
, arg
);
329 if (strpbrk (arg1
, ",:"))
330 arg2
= 1 + strpbrk (arg1
, ",:");
333 arg1
[strcspn (arg1
, ",:")] = 0;
334 if (strstr (arg1
, "%") && strstr (arg2
, "%"))
336 _("%s: Only one threshold may be packet loss (%s)\n"), progname
,
338 if (!strstr (arg1
, "%") && !strstr (arg2
, "%"))
340 _("%s: Only one threshold must be packet loss (%s)\n"),
344 if (arg2
&& strstr (arg2
, "%")) {
352 else if (strstr (arg1
, "%")) {
367 print_revision (progname
, NP_VERSION
);
369 printf ("Copyright (c) 1999 Didi Rieder <adrieder@sbox.tu-graz.ac.at>\n");
370 printf (COPYRIGHT
, copyright
, email
);
372 printf ("%s\n", _("This plugin will use the fping command to ping the specified host for a fast check"));
374 printf ("%s\n", _("Note that it is necessary to set the suid flag on fping."));
380 printf (_(UT_HELP_VRSN
));
381 printf (_(UT_EXTRA_OPTS
));
383 printf (" %s\n", "-H, --hostname=HOST");
384 printf (" %s\n", _("name or IP Address of host to ping (IP Address bypasses name lookup, reducing system load)"));
385 printf (" %s\n", "-w, --warning=THRESHOLD");
386 printf (" %s\n", _("warning threshold pair"));
387 printf (" %s\n", "-c, --critical=THRESHOLD");
388 printf (" %s\n", _("critical threshold pair"));
389 printf (" %s\n", "-b, --bytes=INTEGER");
390 printf (" %s (default: %d)\n", _("size of ICMP packet"),PACKET_SIZE
);
391 printf (" %s\n", "-n, --number=INTEGER");
392 printf (" %s (default: %d)\n", _("number of ICMP packets to send"),PACKET_COUNT
);
393 printf (_(UT_VERBOSE
));
395 printf (" %s\n", _("THRESHOLD is <rta>,<pl>%% where <rta> is the round trip average travel time (ms)"));
396 printf (" %s\n", _("which triggers a WARNING or CRITICAL state, and <pl> is the percentage of"));
397 printf (" %s\n", _("packet loss to trigger an alarm state."));
401 printf ("%s\n", _("Notes:"));
402 printf (_(UT_EXTRA_OPTS_NOTES
));
405 printf (_(UT_SUPPORT
));
412 printf (_("Usage:"));
413 printf (" %s <host_address> -w limit -c limit [-b size] [-n number]\n", progname
);