diff options
Diffstat (limited to 'plugins/check_fping.c')
-rw-r--r-- | plugins/check_fping.c | 962 |
1 files changed, 471 insertions, 491 deletions
diff --git a/plugins/check_fping.c b/plugins/check_fping.c index 70d6f9f..c1d03ec 100644 --- a/plugins/check_fping.c +++ b/plugins/check_fping.c | |||
@@ -1,36 +1,36 @@ | |||
1 | /***************************************************************************** | 1 | /***************************************************************************** |
2 | * | 2 | * |
3 | * Monitoring check_fping plugin | 3 | * Monitoring check_fping 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_disk plugin | 10 | * This file contains the check_fping plugin |
11 | * | 11 | * |
12 | * This plugin will use the fping command to ping the specified host for a | 12 | * This plugin will use the fping command to ping the specified host for a |
13 | * fast check | 13 | * fast check |
14 | * | 14 | * |
15 | * | 15 | * |
16 | * This program is free software: you can redistribute it and/or modify | 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 | 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 | 18 | * the Free Software Foundation, either version 3 of the License, or |
19 | * (at your option) any later version. | 19 | * (at your option) any later version. |
20 | * | 20 | * |
21 | * This program is distributed in the hope that it will be useful, | 21 | * This program is distributed in the hope that it will be useful, |
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
24 | * GNU General Public License for more details. | 24 | * GNU General Public License for more details. |
25 | * | 25 | * |
26 | * You should have received a copy of the GNU General Public License | 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/>. | 27 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
28 | * | 28 | * |
29 | * | 29 | * |
30 | *****************************************************************************/ | 30 | *****************************************************************************/ |
31 | 31 | ||
32 | const char *progname = "check_fping"; | 32 | const char *progname = "check_fping"; |
33 | const char *copyright = "2000-2007"; | 33 | const char *copyright = "2000-2024"; |
34 | const char *email = "devel@monitoring-plugins.org"; | 34 | const char *email = "devel@monitoring-plugins.org"; |
35 | 35 | ||
36 | #include "common.h" | 36 | #include "common.h" |
@@ -40,488 +40,468 @@ const char *email = "devel@monitoring-plugins.org"; | |||
40 | #include <stdbool.h> | 40 | #include <stdbool.h> |
41 | 41 | ||
42 | enum { | 42 | enum { |
43 | PACKET_COUNT = 1, | 43 | PACKET_COUNT = 1, |
44 | PACKET_SIZE = 56, | 44 | PACKET_SIZE = 56, |
45 | PL = 0, | 45 | PL = 0, |
46 | RTA = 1 | 46 | RTA = 1 |
47 | }; | 47 | }; |
48 | 48 | ||
49 | int textscan (char *buf); | 49 | static int textscan(char *buf); |
50 | int process_arguments (int, char **); | 50 | static int process_arguments(int /*argc*/, char ** /*argv*/); |
51 | int get_threshold (char *arg, char *rv[2]); | 51 | static int get_threshold(char *arg, char *rv[2]); |
52 | void print_help (void); | 52 | static void print_help(void); |
53 | void print_usage (void); | 53 | void print_usage(void); |
54 | 54 | ||
55 | char *server_name = NULL; | 55 | static char *server_name = NULL; |
56 | char *sourceip = NULL; | 56 | static char *sourceip = NULL; |
57 | char *sourceif = NULL; | 57 | static char *sourceif = NULL; |
58 | int packet_size = PACKET_SIZE; | 58 | static int packet_size = PACKET_SIZE; |
59 | int packet_count = PACKET_COUNT; | 59 | static int packet_count = PACKET_COUNT; |
60 | int target_timeout = 0; | 60 | static int target_timeout = 0; |
61 | int packet_interval = 0; | 61 | static int packet_interval = 0; |
62 | bool verbose = false; | 62 | static bool verbose = false; |
63 | int cpl; | 63 | static bool dontfrag = false; |
64 | int wpl; | 64 | static bool randomize_packet_data = false; |
65 | double crta; | 65 | static int cpl; |
66 | double wrta; | 66 | static int wpl; |
67 | bool cpl_p = false; | 67 | static double crta; |
68 | bool wpl_p = false; | 68 | static double wrta; |
69 | bool alive_p = false; | 69 | static bool cpl_p = false; |
70 | bool crta_p = false; | 70 | static bool wpl_p = false; |
71 | bool wrta_p = false; | 71 | static bool alive_p = false; |
72 | 72 | static bool crta_p = false; | |
73 | int | 73 | static bool wrta_p = false; |
74 | main (int argc, char **argv) | 74 | |
75 | { | 75 | int main(int argc, char **argv) { |
76 | /* normally should be int result = STATE_UNKNOWN; */ | 76 | /* normally should be int result = STATE_UNKNOWN; */ |
77 | 77 | ||
78 | int status = STATE_UNKNOWN; | 78 | int status = STATE_UNKNOWN; |
79 | int result = 0; | 79 | int result = 0; |
80 | char *fping_prog = NULL; | 80 | char *fping_prog = NULL; |
81 | char *server = NULL; | 81 | char *server = NULL; |
82 | char *command_line = NULL; | 82 | char *command_line = NULL; |
83 | char *input_buffer = NULL; | 83 | char *input_buffer = NULL; |
84 | char *option_string = ""; | 84 | char *option_string = ""; |
85 | input_buffer = malloc (MAX_INPUT_BUFFER); | 85 | input_buffer = malloc(MAX_INPUT_BUFFER); |
86 | 86 | ||
87 | setlocale (LC_ALL, ""); | 87 | setlocale(LC_ALL, ""); |
88 | bindtextdomain (PACKAGE, LOCALEDIR); | 88 | bindtextdomain(PACKAGE, LOCALEDIR); |
89 | textdomain (PACKAGE); | 89 | textdomain(PACKAGE); |
90 | 90 | ||
91 | /* Parse extra opts if any */ | 91 | /* Parse extra opts if any */ |
92 | argv=np_extra_opts (&argc, argv, progname); | 92 | argv = np_extra_opts(&argc, argv, progname); |
93 | 93 | ||
94 | if (process_arguments (argc, argv) == ERROR) | 94 | if (process_arguments(argc, argv) == ERROR) |
95 | usage4 (_("Could not parse arguments")); | 95 | usage4(_("Could not parse arguments")); |
96 | 96 | ||
97 | server = strscpy (server, server_name); | 97 | server = strscpy(server, server_name); |
98 | 98 | ||
99 | /* compose the command */ | 99 | /* compose the command */ |
100 | if (target_timeout) | 100 | if (target_timeout) |
101 | xasprintf(&option_string, "%s-t %d ", option_string, target_timeout); | 101 | xasprintf(&option_string, "%s-t %d ", option_string, target_timeout); |
102 | if (packet_interval) | 102 | if (packet_interval) |
103 | xasprintf(&option_string, "%s-p %d ", option_string, packet_interval); | 103 | xasprintf(&option_string, "%s-p %d ", option_string, packet_interval); |
104 | if (sourceip) | 104 | if (sourceip) |
105 | xasprintf(&option_string, "%s-S %s ", option_string, sourceip); | 105 | xasprintf(&option_string, "%s-S %s ", option_string, sourceip); |
106 | if (sourceif) | 106 | if (sourceif) |
107 | xasprintf(&option_string, "%s-I %s ", option_string, sourceif); | 107 | xasprintf(&option_string, "%s-I %s ", option_string, sourceif); |
108 | if (dontfrag) | ||
109 | xasprintf(&option_string, "%s-M ", option_string); | ||
110 | if (randomize_packet_data) | ||
111 | xasprintf(&option_string, "%s-R ", option_string); | ||
112 | |||
108 | 113 | ||
109 | #ifdef PATH_TO_FPING6 | 114 | #ifdef PATH_TO_FPING6 |
110 | if (address_family != AF_INET && is_inet6_addr(server)) | 115 | if (address_family != AF_INET && is_inet6_addr(server)) |
111 | fping_prog = strdup(PATH_TO_FPING6); | 116 | fping_prog = strdup(PATH_TO_FPING6); |
112 | else | 117 | else |
113 | fping_prog = strdup(PATH_TO_FPING); | 118 | fping_prog = strdup(PATH_TO_FPING); |
114 | #else | 119 | #else |
115 | fping_prog = strdup(PATH_TO_FPING); | 120 | fping_prog = strdup(PATH_TO_FPING); |
116 | #endif | 121 | #endif |
117 | 122 | ||
118 | xasprintf (&command_line, "%s %s-b %d -c %d %s", fping_prog, | 123 | xasprintf(&command_line, "%s %s-b %d -c %d %s", fping_prog, option_string, packet_size, packet_count, server); |
119 | option_string, packet_size, packet_count, server); | 124 | |
120 | 125 | if (verbose) | |
121 | if (verbose) | 126 | printf("%s\n", command_line); |
122 | printf ("%s\n", command_line); | 127 | |
123 | 128 | /* run the command */ | |
124 | /* run the command */ | 129 | child_process = spopen(command_line); |
125 | child_process = spopen (command_line); | 130 | if (child_process == NULL) { |
126 | if (child_process == NULL) { | 131 | printf(_("Could not open pipe: %s\n"), command_line); |
127 | printf (_("Could not open pipe: %s\n"), command_line); | 132 | return STATE_UNKNOWN; |
128 | return STATE_UNKNOWN; | 133 | } |
129 | } | 134 | |
130 | 135 | child_stderr = fdopen(child_stderr_array[fileno(child_process)], "r"); | |
131 | child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); | 136 | if (child_stderr == NULL) { |
132 | if (child_stderr == NULL) { | 137 | printf(_("Could not open stderr for %s\n"), command_line); |
133 | printf (_("Could not open stderr for %s\n"), command_line); | 138 | } |
134 | } | 139 | |
135 | 140 | while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { | |
136 | while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { | 141 | if (verbose) |
137 | if (verbose) | 142 | printf("%s", input_buffer); |
138 | printf ("%s", input_buffer); | 143 | status = max_state(status, textscan(input_buffer)); |
139 | status = max_state (status, textscan (input_buffer)); | 144 | } |
140 | } | 145 | |
141 | 146 | /* If we get anything on STDERR, at least set warning */ | |
142 | /* If we get anything on STDERR, at least set warning */ | 147 | while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) { |
143 | while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) { | 148 | status = max_state(status, STATE_WARNING); |
144 | status = max_state (status, STATE_WARNING); | 149 | if (verbose) |
145 | if (verbose) | 150 | printf("%s", input_buffer); |
146 | printf ("%s", input_buffer); | 151 | status = max_state(status, textscan(input_buffer)); |
147 | status = max_state (status, textscan (input_buffer)); | 152 | } |
148 | } | 153 | (void)fclose(child_stderr); |
149 | (void) fclose (child_stderr); | 154 | |
150 | 155 | /* close the pipe */ | |
151 | /* close the pipe */ | 156 | result = spclose(child_process); |
152 | result = spclose (child_process); | 157 | if (result) { |
153 | if (result) { | 158 | /* need to use max_state not max */ |
154 | /* need to use max_state not max */ | 159 | status = max_state(status, STATE_WARNING); |
155 | status = max_state (status, STATE_WARNING); | 160 | } |
156 | } | 161 | |
157 | 162 | if (result > 1) { | |
158 | if (result > 1 ) { | 163 | status = max_state(status, STATE_UNKNOWN); |
159 | status = max_state (status, STATE_UNKNOWN); | 164 | if (result == 2) { |
160 | if (result == 2) { | 165 | die(STATE_UNKNOWN, _("FPING UNKNOWN - IP address not found\n")); |
161 | die (STATE_UNKNOWN, _("FPING UNKNOWN - IP address not found\n")); | 166 | } |
162 | } | 167 | if (result == 3) { |
163 | if (result == 3) { | 168 | die(STATE_UNKNOWN, _("FPING UNKNOWN - invalid commandline argument\n")); |
164 | die (STATE_UNKNOWN, _("FPING UNKNOWN - invalid commandline argument\n")); | 169 | } |
165 | } | 170 | if (result == 4) { |
166 | if (result == 4) { | 171 | die(STATE_UNKNOWN, _("FPING UNKNOWN - failed system call\n")); |
167 | die (STATE_UNKNOWN, _("FPING UNKNOWN - failed system call\n")); | 172 | } |
168 | } | 173 | } |
169 | 174 | ||
170 | } | 175 | printf("FPING %s - %s\n", state_text(status), server_name); |
171 | 176 | ||
172 | printf ("FPING %s - %s\n", state_text (status), server_name); | 177 | return status; |
173 | |||
174 | return status; | ||
175 | } | 178 | } |
176 | 179 | ||
177 | 180 | int textscan(char *buf) { | |
178 | int textscan (char *buf) { | 181 | char *rtastr = NULL; |
179 | char *rtastr = NULL; | 182 | char *losstr = NULL; |
180 | char *losstr = NULL; | 183 | char *xmtstr = NULL; |
181 | char *xmtstr = NULL; | 184 | double loss; |
182 | double loss; | 185 | double rta; |
183 | double rta; | 186 | double xmt; |
184 | double xmt; | 187 | int status = STATE_UNKNOWN; |
185 | int status = STATE_UNKNOWN; | 188 | |
186 | 189 | /* stops testing after the first successful reply. */ | |
187 | /* stops testing after the first successful reply. */ | 190 | if (alive_p && strstr(buf, "avg, 0% loss)")) { |
188 | if (alive_p && strstr(buf, "avg, 0% loss)")) { | 191 | rtastr = strstr(buf, "ms ("); |
189 | rtastr = strstr (buf, "ms ("); | 192 | rtastr = 1 + index(rtastr, '('); |
190 | rtastr = 1 + index(rtastr, '('); | 193 | rta = strtod(rtastr, NULL); |
191 | rta = strtod(rtastr, NULL); | 194 | loss = strtod("0", NULL); |
192 | loss=strtod("0",NULL); | 195 | die(STATE_OK, _("FPING %s - %s (rta=%f ms)|%s\n"), state_text(STATE_OK), server_name, rta, |
193 | die (STATE_OK, | 196 | /* No loss since we only waited for the first reply |
194 | _("FPING %s - %s (rta=%f ms)|%s\n"), | 197 | perfdata ("loss", (long int)loss, "%", wpl_p, wpl, cpl_p, cpl, true, 0, true, 100), */ |
195 | state_text (STATE_OK), server_name,rta, | 198 | fperfdata("rta", rta / 1.0e3, "s", wrta_p, wrta / 1.0e3, crta_p, crta / 1.0e3, true, 0, false, 0)); |
196 | /* No loss since we only waited for the first reply | 199 | } |
197 | perfdata ("loss", (long int)loss, "%", wpl_p, wpl, cpl_p, cpl, true, 0, true, 100), */ | 200 | |
198 | fperfdata ("rta", rta/1.0e3, "s", wrta_p, wrta/1.0e3, crta_p, crta/1.0e3, true, 0, false, 0)); | 201 | if (strstr(buf, "not found")) { |
199 | } | 202 | die(STATE_CRITICAL, _("FPING UNKNOWN - %s not found\n"), server_name); |
200 | 203 | ||
201 | if (strstr (buf, "not found")) { | 204 | } else if (strstr(buf, "is unreachable") || strstr(buf, "Unreachable")) { |
202 | die (STATE_CRITICAL, _("FPING UNKNOWN - %s not found\n"), server_name); | 205 | die(STATE_CRITICAL, _("FPING CRITICAL - %s is unreachable\n"), "host"); |
203 | 206 | ||
204 | } | 207 | } else if (strstr(buf, "Operation not permitted") || strstr(buf, "No such device")) { |
205 | else if (strstr (buf, "is unreachable") || strstr (buf, "Unreachable")) { | 208 | die(STATE_UNKNOWN, _("FPING UNKNOWN - %s parameter error\n"), "host"); |
206 | die (STATE_CRITICAL, _("FPING CRITICAL - %s is unreachable\n"), | 209 | } else if (strstr(buf, "is down")) { |
207 | "host"); | 210 | die(STATE_CRITICAL, _("FPING CRITICAL - %s is down\n"), server_name); |
208 | 211 | ||
209 | } | 212 | } else if (strstr(buf, "is alive")) { |
210 | else if (strstr (buf, "Operation not permitted") || strstr (buf, "No such device") ) { | 213 | status = STATE_OK; |
211 | die (STATE_UNKNOWN, _("FPING UNKNOWN - %s parameter error\n"), | 214 | |
212 | "host"); | 215 | } else if (strstr(buf, "xmt/rcv/%loss") && strstr(buf, "min/avg/max")) { |
213 | } | 216 | losstr = strstr(buf, "="); |
214 | else if (strstr (buf, "is down")) { | 217 | losstr = 1 + strstr(losstr, "/"); |
215 | die (STATE_CRITICAL, _("FPING CRITICAL - %s is down\n"), server_name); | 218 | losstr = 1 + strstr(losstr, "/"); |
216 | 219 | rtastr = strstr(buf, "min/avg/max"); | |
217 | } | 220 | rtastr = strstr(rtastr, "="); |
218 | else if (strstr (buf, "is alive")) { | 221 | rtastr = 1 + index(rtastr, '/'); |
219 | status = STATE_OK; | 222 | loss = strtod(losstr, NULL); |
220 | 223 | rta = strtod(rtastr, NULL); | |
221 | } | 224 | if (cpl_p && loss > cpl) |
222 | else if (strstr (buf, "xmt/rcv/%loss") && strstr (buf, "min/avg/max")) { | 225 | status = STATE_CRITICAL; |
223 | losstr = strstr (buf, "="); | 226 | else if (crta_p && rta > crta) |
224 | losstr = 1 + strstr (losstr, "/"); | 227 | status = STATE_CRITICAL; |
225 | losstr = 1 + strstr (losstr, "/"); | 228 | else if (wpl_p && loss > wpl) |
226 | rtastr = strstr (buf, "min/avg/max"); | 229 | status = STATE_WARNING; |
227 | rtastr = strstr (rtastr, "="); | 230 | else if (wrta_p && rta > wrta) |
228 | rtastr = 1 + index (rtastr, '/'); | 231 | status = STATE_WARNING; |
229 | loss = strtod (losstr, NULL); | 232 | else |
230 | rta = strtod (rtastr, NULL); | 233 | status = STATE_OK; |
231 | if (cpl_p && loss > cpl) | 234 | die(status, _("FPING %s - %s (loss=%.0f%%, rta=%f ms)|%s %s\n"), state_text(status), server_name, loss, rta, |
232 | status = STATE_CRITICAL; | 235 | perfdata("loss", (long int)loss, "%", wpl_p, wpl, cpl_p, cpl, true, 0, true, 100), |
233 | else if (crta_p && rta > crta) | 236 | fperfdata("rta", rta / 1.0e3, "s", wrta_p, wrta / 1.0e3, crta_p, crta / 1.0e3, true, 0, false, 0)); |
234 | status = STATE_CRITICAL; | 237 | |
235 | else if (wpl_p && loss > wpl) | 238 | } else if (strstr(buf, "xmt/rcv/%loss")) { |
236 | status = STATE_WARNING; | 239 | /* no min/max/avg if host was unreachable in fping v2.2.b1 */ |
237 | else if (wrta_p && rta > wrta) | 240 | /* in v2.4b2: 10.99.0.1 : xmt/rcv/%loss = 0/0/0% */ |
238 | status = STATE_WARNING; | 241 | losstr = strstr(buf, "="); |
239 | else | 242 | xmtstr = 1 + losstr; |
240 | status = STATE_OK; | 243 | xmt = strtod(xmtstr, NULL); |
241 | die (status, | 244 | if (xmt == 0) |
242 | _("FPING %s - %s (loss=%.0f%%, rta=%f ms)|%s %s\n"), | 245 | die(STATE_CRITICAL, _("FPING CRITICAL - %s is down\n"), server_name); |
243 | state_text (status), server_name, loss, rta, | 246 | losstr = 1 + strstr(losstr, "/"); |
244 | perfdata ("loss", (long int)loss, "%", wpl_p, wpl, cpl_p, cpl, true, 0, true, 100), | 247 | losstr = 1 + strstr(losstr, "/"); |
245 | fperfdata ("rta", rta/1.0e3, "s", wrta_p, wrta/1.0e3, crta_p, crta/1.0e3, true, 0, false, 0)); | 248 | loss = strtod(losstr, NULL); |
246 | 249 | if (atoi(losstr) == 100) | |
247 | } | 250 | status = STATE_CRITICAL; |
248 | else if(strstr (buf, "xmt/rcv/%loss") ) { | 251 | else if (cpl_p && loss > cpl) |
249 | /* no min/max/avg if host was unreachable in fping v2.2.b1 */ | 252 | status = STATE_CRITICAL; |
250 | /* in v2.4b2: 10.99.0.1 : xmt/rcv/%loss = 0/0/0% */ | 253 | else if (wpl_p && loss > wpl) |
251 | losstr = strstr (buf, "="); | 254 | status = STATE_WARNING; |
252 | xmtstr = 1 + losstr; | 255 | else |
253 | xmt = strtod (xmtstr, NULL); | 256 | status = STATE_OK; |
254 | if(xmt == 0) | 257 | /* loss=%.0f%%;%d;%d;0;100 */ |
255 | die (STATE_CRITICAL, _("FPING CRITICAL - %s is down\n"), server_name); | 258 | die(status, _("FPING %s - %s (loss=%.0f%% )|%s\n"), state_text(status), server_name, loss, |
256 | losstr = 1 + strstr (losstr, "/"); | 259 | perfdata("loss", (long int)loss, "%", wpl_p, wpl, cpl_p, cpl, true, 0, true, 100)); |
257 | losstr = 1 + strstr (losstr, "/"); | 260 | |
258 | loss = strtod (losstr, NULL); | 261 | } else { |
259 | if (atoi(losstr) == 100) | 262 | status = max_state(status, STATE_WARNING); |
260 | status = STATE_CRITICAL; | 263 | } |
261 | else if (cpl_p && loss > cpl) | 264 | |
262 | status = STATE_CRITICAL; | 265 | return status; |
263 | else if (wpl_p && loss > wpl) | ||
264 | status = STATE_WARNING; | ||
265 | else | ||
266 | status = STATE_OK; | ||
267 | /* loss=%.0f%%;%d;%d;0;100 */ | ||
268 | die (status, _("FPING %s - %s (loss=%.0f%% )|%s\n"), | ||
269 | state_text (status), server_name, loss , | ||
270 | perfdata ("loss", (long int)loss, "%", wpl_p, wpl, cpl_p, cpl, true, 0, true, 100)); | ||
271 | |||
272 | } | ||
273 | else { | ||
274 | status = max_state (status, STATE_WARNING); | ||
275 | } | ||
276 | |||
277 | return status; | ||
278 | } | 266 | } |
279 | 267 | ||
280 | |||
281 | |||
282 | /* process command-line arguments */ | 268 | /* process command-line arguments */ |
283 | int | 269 | int process_arguments(int argc, char **argv) { |
284 | process_arguments (int argc, char **argv) | 270 | int c; |
285 | { | 271 | char *rv[2]; |
286 | int c; | 272 | |
287 | char *rv[2]; | 273 | int option = 0; |
288 | 274 | static struct option longopts[] = {{"hostname", required_argument, 0, 'H'}, | |
289 | int option = 0; | 275 | {"sourceip", required_argument, 0, 'S'}, |
290 | static struct option longopts[] = { | 276 | {"sourceif", required_argument, 0, 'I'}, |
291 | {"hostname", required_argument, 0, 'H'}, | 277 | {"critical", required_argument, 0, 'c'}, |
292 | {"sourceip", required_argument, 0, 'S'}, | 278 | {"warning", required_argument, 0, 'w'}, |
293 | {"sourceif", required_argument, 0, 'I'}, | 279 | {"alive", no_argument, 0, 'a'}, |
294 | {"critical", required_argument, 0, 'c'}, | 280 | {"bytes", required_argument, 0, 'b'}, |
295 | {"warning", required_argument, 0, 'w'}, | 281 | {"number", required_argument, 0, 'n'}, |
296 | {"alive", no_argument, 0, 'a'}, | 282 | {"target-timeout", required_argument, 0, 'T'}, |
297 | {"bytes", required_argument, 0, 'b'}, | 283 | {"interval", required_argument, 0, 'i'}, |
298 | {"number", required_argument, 0, 'n'}, | 284 | {"verbose", no_argument, 0, 'v'}, |
299 | {"target-timeout", required_argument, 0, 'T'}, | 285 | {"version", no_argument, 0, 'V'}, |
300 | {"interval", required_argument, 0, 'i'}, | 286 | {"help", no_argument, 0, 'h'}, |
301 | {"verbose", no_argument, 0, 'v'}, | 287 | {"use-ipv4", no_argument, 0, '4'}, |
302 | {"version", no_argument, 0, 'V'}, | 288 | {"use-ipv6", no_argument, 0, '6'}, |
303 | {"help", no_argument, 0, 'h'}, | 289 | {"dontfrag", no_argument, 0, 'M'}, |
304 | {"use-ipv4", no_argument, 0, '4'}, | 290 | {"random", no_argument, 0, 'R'}, |
305 | {"use-ipv6", no_argument, 0, '6'}, | 291 | {0, 0, 0, 0}}; |
306 | {0, 0, 0, 0} | 292 | |
307 | }; | 293 | rv[PL] = NULL; |
308 | 294 | rv[RTA] = NULL; | |
309 | rv[PL] = NULL; | 295 | |
310 | rv[RTA] = NULL; | 296 | if (argc < 2) |
311 | 297 | return ERROR; | |
312 | if (argc < 2) | 298 | |
313 | return ERROR; | 299 | if (!is_option(argv[1])) { |
314 | 300 | server_name = argv[1]; | |
315 | if (!is_option (argv[1])) { | 301 | argv[1] = argv[0]; |
316 | server_name = argv[1]; | 302 | argv = &argv[1]; |
317 | argv[1] = argv[0]; | 303 | argc--; |
318 | argv = &argv[1]; | 304 | } |
319 | argc--; | 305 | |
320 | } | 306 | while (1) { |
321 | 307 | c = getopt_long(argc, argv, "+hVvaH:S:c:w:b:n:T:i:I:M:R:46", longopts, &option); | |
322 | while (1) { | 308 | |
323 | c = getopt_long (argc, argv, "+hVvaH:S:c:w:b:n:T:i:I:46", longopts, &option); | 309 | if (c == -1 || c == EOF || c == 1) |
324 | 310 | break; | |
325 | if (c == -1 || c == EOF || c == 1) | 311 | |
326 | break; | 312 | switch (c) { |
327 | 313 | case '?': /* print short usage statement if args not parsable */ | |
328 | switch (c) { | 314 | usage5(); |
329 | case '?': /* print short usage statement if args not parsable */ | 315 | case 'a': /* host alive mode */ |
330 | usage5 (); | 316 | alive_p = true; |
331 | case 'a': /* host alive mode */ | 317 | break; |
332 | alive_p = true; | 318 | case 'h': /* help */ |
333 | break; | 319 | print_help(); |
334 | case 'h': /* help */ | 320 | exit(STATE_UNKNOWN); |
335 | print_help (); | 321 | case 'V': /* version */ |
336 | exit (STATE_UNKNOWN); | 322 | print_revision(progname, NP_VERSION); |
337 | case 'V': /* version */ | 323 | exit(STATE_UNKNOWN); |
338 | print_revision (progname, NP_VERSION); | 324 | case 'v': /* verbose mode */ |
339 | exit (STATE_UNKNOWN); | 325 | verbose = true; |
340 | case 'v': /* verbose mode */ | 326 | break; |
341 | verbose = true; | 327 | case 'H': /* hostname */ |
342 | break; | 328 | if (is_host(optarg) == false) { |
343 | case 'H': /* hostname */ | 329 | usage2(_("Invalid hostname/address"), optarg); |
344 | if (is_host (optarg) == false) { | 330 | } |
345 | usage2 (_("Invalid hostname/address"), optarg); | 331 | server_name = strscpy(server_name, optarg); |
346 | } | 332 | break; |
347 | server_name = strscpy (server_name, optarg); | 333 | case 'S': /* sourceip */ |
348 | break; | 334 | if (is_host(optarg) == false) { |
349 | case 'S': /* sourceip */ | 335 | usage2(_("Invalid hostname/address"), optarg); |
350 | if (is_host (optarg) == false) { | 336 | } |
351 | usage2 (_("Invalid hostname/address"), optarg); | 337 | sourceip = strscpy(sourceip, optarg); |
352 | } | ||
353 | sourceip = strscpy (sourceip, optarg); | ||
354 | break; | ||
355 | case 'I': /* sourceip */ | ||
356 | sourceif = strscpy (sourceif, optarg); | ||
357 | break; | 338 | break; |
358 | case '4': /* IPv4 only */ | 339 | case 'I': /* sourceip */ |
359 | address_family = AF_INET; | 340 | sourceif = strscpy(sourceif, optarg); |
360 | break; | 341 | break; |
361 | case '6': /* IPv6 only */ | 342 | case '4': /* IPv4 only */ |
343 | address_family = AF_INET; | ||
344 | break; | ||
345 | case '6': /* IPv6 only */ | ||
362 | #ifdef USE_IPV6 | 346 | #ifdef USE_IPV6 |
363 | address_family = AF_INET6; | 347 | address_family = AF_INET6; |
364 | #else | 348 | #else |
365 | usage (_("IPv6 support not available\n")); | 349 | usage(_("IPv6 support not available\n")); |
366 | #endif | 350 | #endif |
367 | break; | 351 | break; |
368 | case 'c': | 352 | case 'c': |
369 | get_threshold (optarg, rv); | 353 | get_threshold(optarg, rv); |
370 | if (rv[RTA]) { | 354 | if (rv[RTA]) { |
371 | crta = strtod (rv[RTA], NULL); | 355 | crta = strtod(rv[RTA], NULL); |
372 | crta_p = true; | 356 | crta_p = true; |
373 | rv[RTA] = NULL; | 357 | rv[RTA] = NULL; |
374 | } | 358 | } |
375 | if (rv[PL]) { | 359 | if (rv[PL]) { |
376 | cpl = atoi (rv[PL]); | 360 | cpl = atoi(rv[PL]); |
377 | cpl_p = true; | 361 | cpl_p = true; |
378 | rv[PL] = NULL; | 362 | rv[PL] = NULL; |
379 | } | 363 | } |
380 | break; | 364 | break; |
381 | case 'w': | 365 | case 'w': |
382 | get_threshold (optarg, rv); | 366 | get_threshold(optarg, rv); |
383 | if (rv[RTA]) { | 367 | if (rv[RTA]) { |
384 | wrta = strtod (rv[RTA], NULL); | 368 | wrta = strtod(rv[RTA], NULL); |
385 | wrta_p = true; | 369 | wrta_p = true; |
386 | rv[RTA] = NULL; | 370 | rv[RTA] = NULL; |
387 | } | 371 | } |
388 | if (rv[PL]) { | 372 | if (rv[PL]) { |
389 | wpl = atoi (rv[PL]); | 373 | wpl = atoi(rv[PL]); |
390 | wpl_p = true; | 374 | wpl_p = true; |
391 | rv[PL] = NULL; | 375 | rv[PL] = NULL; |
392 | } | 376 | } |
393 | break; | 377 | break; |
394 | case 'b': /* bytes per packet */ | 378 | case 'b': /* bytes per packet */ |
395 | if (is_intpos (optarg)) | 379 | if (is_intpos(optarg)) |
396 | packet_size = atoi (optarg); | 380 | packet_size = atoi(optarg); |
397 | else | 381 | else |
398 | usage (_("Packet size must be a positive integer")); | 382 | usage(_("Packet size must be a positive integer")); |
399 | break; | 383 | break; |
400 | case 'n': /* number of packets */ | 384 | case 'n': /* number of packets */ |
401 | if (is_intpos (optarg)) | 385 | if (is_intpos(optarg)) |
402 | packet_count = atoi (optarg); | 386 | packet_count = atoi(optarg); |
403 | else | 387 | else |
404 | usage (_("Packet count must be a positive integer")); | 388 | usage(_("Packet count must be a positive integer")); |
405 | break; | 389 | break; |
406 | case 'T': /* timeout in msec */ | 390 | case 'T': /* timeout in msec */ |
407 | if (is_intpos (optarg)) | 391 | if (is_intpos(optarg)) |
408 | target_timeout = atoi (optarg); | 392 | target_timeout = atoi(optarg); |
409 | else | 393 | else |
410 | usage (_("Target timeout must be a positive integer")); | 394 | usage(_("Target timeout must be a positive integer")); |
411 | break; | 395 | break; |
412 | case 'i': /* interval in msec */ | 396 | case 'i': /* interval in msec */ |
413 | if (is_intpos (optarg)) | 397 | if (is_intpos(optarg)) |
414 | packet_interval = atoi (optarg); | 398 | packet_interval = atoi(optarg); |
415 | else | 399 | else |
416 | usage (_("Interval must be a positive integer")); | 400 | usage(_("Interval must be a positive integer")); |
417 | break; | 401 | break; |
418 | } | 402 | case 'R': |
419 | } | 403 | randomize_packet_data = true; |
420 | 404 | break; | |
421 | if (server_name == NULL) | 405 | case 'M': |
422 | usage4 (_("Hostname was not supplied")); | 406 | dontfrag = true; |
423 | 407 | break; | |
424 | return OK; | 408 | } |
425 | } | 409 | } |
426 | 410 | ||
411 | if (server_name == NULL) | ||
412 | usage4(_("Hostname was not supplied")); | ||
427 | 413 | ||
428 | int | 414 | return OK; |
429 | get_threshold (char *arg, char *rv[2]) | ||
430 | { | ||
431 | char *arg1 = NULL; | ||
432 | char *arg2 = NULL; | ||
433 | |||
434 | arg1 = strscpy (arg1, arg); | ||
435 | if (strpbrk (arg1, ",:")) | ||
436 | arg2 = 1 + strpbrk (arg1, ",:"); | ||
437 | |||
438 | if (arg2) { | ||
439 | arg1[strcspn (arg1, ",:")] = 0; | ||
440 | if (strstr (arg1, "%") && strstr (arg2, "%")) | ||
441 | die (STATE_UNKNOWN, | ||
442 | _("%s: Only one threshold may be packet loss (%s)\n"), progname, | ||
443 | arg); | ||
444 | if (!strstr (arg1, "%") && !strstr (arg2, "%")) | ||
445 | die (STATE_UNKNOWN, | ||
446 | _("%s: Only one threshold must be packet loss (%s)\n"), | ||
447 | progname, arg); | ||
448 | } | ||
449 | |||
450 | if (arg2 && strstr (arg2, "%")) { | ||
451 | rv[PL] = arg2; | ||
452 | rv[RTA] = arg1; | ||
453 | } | ||
454 | else if (arg2) { | ||
455 | rv[PL] = arg1; | ||
456 | rv[RTA] = arg2; | ||
457 | } | ||
458 | else if (strstr (arg1, "%")) { | ||
459 | rv[PL] = arg1; | ||
460 | } | ||
461 | else { | ||
462 | rv[RTA] = arg1; | ||
463 | } | ||
464 | |||
465 | return OK; | ||
466 | } | 415 | } |
467 | 416 | ||
468 | 417 | int get_threshold(char *arg, char *rv[2]) { | |
469 | void print_help (void) { | 418 | char *arg1 = NULL; |
470 | 419 | char *arg2 = NULL; | |
471 | print_revision (progname, NP_VERSION); | 420 | |
472 | 421 | arg1 = strscpy(arg1, arg); | |
473 | printf ("Copyright (c) 1999 Didi Rieder <adrieder@sbox.tu-graz.ac.at>\n"); | 422 | if (strpbrk(arg1, ",:")) |
474 | printf (COPYRIGHT, copyright, email); | 423 | arg2 = 1 + strpbrk(arg1, ",:"); |
475 | 424 | ||
476 | printf ("%s\n", _("This plugin will use the fping command to ping the specified host for a fast check")); | 425 | if (arg2) { |
477 | 426 | arg1[strcspn(arg1, ",:")] = 0; | |
478 | printf ("%s\n", _("Note that it is necessary to set the suid flag on fping.")); | 427 | if (strstr(arg1, "%") && strstr(arg2, "%")) |
479 | 428 | die(STATE_UNKNOWN, _("%s: Only one threshold may be packet loss (%s)\n"), progname, arg); | |
480 | printf ("\n\n"); | 429 | if (!strstr(arg1, "%") && !strstr(arg2, "%")) |
481 | 430 | die(STATE_UNKNOWN, _("%s: Only one threshold must be packet loss (%s)\n"), progname, arg); | |
482 | print_usage (); | 431 | } |
483 | 432 | ||
484 | printf (UT_HELP_VRSN); | 433 | if (arg2 && strstr(arg2, "%")) { |
485 | printf (UT_EXTRA_OPTS); | 434 | rv[PL] = arg2; |
486 | 435 | rv[RTA] = arg1; | |
487 | printf (UT_IPv46); | 436 | } else if (arg2) { |
488 | 437 | rv[PL] = arg1; | |
489 | printf (" %s\n", "-H, --hostname=HOST"); | 438 | rv[RTA] = arg2; |
490 | printf (" %s\n", _("name or IP Address of host to ping (IP Address bypasses name lookup, reducing system load)")); | 439 | } else if (strstr(arg1, "%")) { |
491 | printf (" %s\n", "-w, --warning=THRESHOLD"); | 440 | rv[PL] = arg1; |
492 | printf (" %s\n", _("warning threshold pair")); | 441 | } else { |
493 | printf (" %s\n", "-c, --critical=THRESHOLD"); | 442 | rv[RTA] = arg1; |
494 | printf (" %s\n", _("critical threshold pair")); | 443 | } |
495 | printf (" %s\n", "-a, --alive"); | 444 | |
496 | printf (" %s\n", _("Return OK after first successful reply")); | 445 | return OK; |
497 | printf (" %s\n", "-b, --bytes=INTEGER"); | ||
498 | printf (" %s (default: %d)\n", _("size of ICMP packet"),PACKET_SIZE); | ||
499 | printf (" %s\n", "-n, --number=INTEGER"); | ||
500 | printf (" %s (default: %d)\n", _("number of ICMP packets to send"),PACKET_COUNT); | ||
501 | printf (" %s\n", "-T, --target-timeout=INTEGER"); | ||
502 | printf (" %s (default: fping's default for -t)\n", _("Target timeout (ms)")); | ||
503 | printf (" %s\n", "-i, --interval=INTEGER"); | ||
504 | printf (" %s (default: fping's default for -p)\n", _("Interval (ms) between sending packets")); | ||
505 | printf (" %s\n", "-S, --sourceip=HOST"); | ||
506 | printf (" %s\n", _("name or IP Address of sourceip")); | ||
507 | printf (" %s\n", "-I, --sourceif=IF"); | ||
508 | printf (" %s\n", _("source interface name")); | ||
509 | printf (UT_VERBOSE); | ||
510 | printf ("\n"); | ||
511 | printf (" %s\n", _("THRESHOLD is <rta>,<pl>%% where <rta> is the round trip average travel time (ms)")); | ||
512 | printf (" %s\n", _("which triggers a WARNING or CRITICAL state, and <pl> is the percentage of")); | ||
513 | printf (" %s\n", _("packet loss to trigger an alarm state.")); | ||
514 | |||
515 | printf ("\n"); | ||
516 | printf (" %s\n", _("IPv4 is used by default. Specify -6 to use IPv6.")); | ||
517 | |||
518 | printf (UT_SUPPORT); | ||
519 | } | 446 | } |
520 | 447 | ||
448 | void print_help(void) { | ||
449 | |||
450 | print_revision(progname, NP_VERSION); | ||
451 | |||
452 | printf("Copyright (c) 1999 Didi Rieder <adrieder@sbox.tu-graz.ac.at>\n"); | ||
453 | printf(COPYRIGHT, copyright, email); | ||
454 | |||
455 | printf("%s\n", _("This plugin will use the fping command to ping the specified host for a fast check")); | ||
456 | |||
457 | printf("%s\n", _("Note that it is necessary to set the suid flag on fping.")); | ||
458 | |||
459 | printf("\n\n"); | ||
460 | |||
461 | print_usage(); | ||
462 | |||
463 | printf(UT_HELP_VRSN); | ||
464 | printf(UT_EXTRA_OPTS); | ||
465 | |||
466 | printf(UT_IPv46); | ||
467 | |||
468 | 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)")); | ||
470 | printf(" %s\n", "-w, --warning=THRESHOLD"); | ||
471 | printf(" %s\n", _("warning threshold pair")); | ||
472 | printf(" %s\n", "-c, --critical=THRESHOLD"); | ||
473 | printf(" %s\n", _("critical threshold pair")); | ||
474 | printf(" %s\n", "-a, --alive"); | ||
475 | printf(" %s\n", _("Return OK after first successful reply")); | ||
476 | printf(" %s\n", "-b, --bytes=INTEGER"); | ||
477 | printf(" %s (default: %d)\n", _("size of ICMP packet"), PACKET_SIZE); | ||
478 | printf(" %s\n", "-n, --number=INTEGER"); | ||
479 | printf(" %s (default: %d)\n", _("number of ICMP packets to send"), PACKET_COUNT); | ||
480 | printf(" %s\n", "-T, --target-timeout=INTEGER"); | ||
481 | printf(" %s (default: fping's default for -t)\n", _("Target timeout (ms)")); | ||
482 | printf(" %s\n", "-i, --interval=INTEGER"); | ||
483 | printf(" %s (default: fping's default for -p)\n", _("Interval (ms) between sending packets")); | ||
484 | printf(" %s\n", "-S, --sourceip=HOST"); | ||
485 | printf(" %s\n", _("name or IP Address of sourceip")); | ||
486 | printf(" %s\n", "-I, --sourceif=IF"); | ||
487 | printf(" %s\n", _("source interface name")); | ||
488 | printf(" %s\n", "-M, --dontfrag"); | ||
489 | printf(" %s\n", _("set the Don't Fragment flag")); | ||
490 | printf(" %s\n", "-R, --random"); | ||
491 | printf(" %s\n", _("random packet data (to foil link data compression)")); | ||
492 | printf(UT_VERBOSE); | ||
493 | printf("\n"); | ||
494 | printf(" %s\n", _("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")); | ||
496 | printf(" %s\n", _("packet loss to trigger an alarm state.")); | ||
497 | |||
498 | printf("\n"); | ||
499 | printf(" %s\n", _("IPv4 is used by default. Specify -6 to use IPv6.")); | ||
500 | |||
501 | printf(UT_SUPPORT); | ||
502 | } | ||
521 | 503 | ||
522 | void | 504 | void print_usage(void) { |
523 | print_usage (void) | 505 | printf("%s\n", _("Usage:")); |
524 | { | 506 | printf(" %s <host_address> -w limit -c limit [-b size] [-n number] [-T number] [-i number]\n", progname); |
525 | printf ("%s\n", _("Usage:")); | ||
526 | printf (" %s <host_address> -w limit -c limit [-b size] [-n number] [-T number] [-i number]\n", progname); | ||
527 | } | 507 | } |