summaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/check_tcp.c556
1 files changed, 261 insertions, 295 deletions
diff --git a/plugins/check_tcp.c b/plugins/check_tcp.c
index 01dd35e..78dcbd4 100644
--- a/plugins/check_tcp.c
+++ b/plugins/check_tcp.c
@@ -1,31 +1,31 @@
1/***************************************************************************** 1/*****************************************************************************
2* 2 *
3* Monitoring check_tcp plugin 3 * Monitoring check_tcp plugin
4* 4 *
5* License: GPL 5 * License: GPL
6* Copyright (c) 1999-2013 Monitoring Plugins Development Team 6 * Copyright (c) 1999-2013 Monitoring Plugins Development Team
7* 7 *
8* Description: 8 * Description:
9* 9 *
10* This file contains the check_tcp plugin 10 * This file contains the check_tcp plugin
11* 11 *
12* 12 *
13* This program is free software: you can redistribute it and/or modify 13 * This program is free software: you can redistribute it and/or modify
14* it under the terms of the GNU General Public License as published by 14 * it under the terms of the GNU General Public License as published by
15* the Free Software Foundation, either version 3 of the License, or 15 * the Free Software Foundation, either version 3 of the License, or
16* (at your option) any later version. 16 * (at your option) any later version.
17* 17 *
18* This program is distributed in the hope that it will be useful, 18 * This program is distributed in the hope that it will be useful,
19* but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21* GNU General Public License for more details. 21 * GNU General Public License for more details.
22* 22 *
23* You should have received a copy of the GNU General Public License 23 * You should have received a copy of the GNU General Public License
24* along with this program. If not, see <http://www.gnu.org/licenses/>. 24 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25* 25 *
26* $Id$ 26 * $Id$
27* 27 *
28*****************************************************************************/ 28 *****************************************************************************/
29 29
30/* progname "check_tcp" changes depending on symlink called */ 30/* progname "check_tcp" changes depending on symlink called */
31char *progname; 31char *progname;
@@ -43,17 +43,17 @@ const char *email = "devel@monitoring-plugins.org";
43#ifdef HAVE_SSL 43#ifdef HAVE_SSL
44static bool check_cert = false; 44static bool check_cert = false;
45static int days_till_exp_warn, days_till_exp_crit; 45static int days_till_exp_warn, days_till_exp_crit;
46# define my_recv(buf, len) ((flags & FLAG_SSL) ? np_net_ssl_read(buf, len) : read(sd, buf, len)) 46# define my_recv(buf, len) ((flags & FLAG_SSL) ? np_net_ssl_read(buf, len) : read(sd, buf, len))
47# define my_send(buf, len) ((flags & FLAG_SSL) ? np_net_ssl_write(buf, len) : send(sd, buf, len, 0)) 47# define my_send(buf, len) ((flags & FLAG_SSL) ? np_net_ssl_write(buf, len) : send(sd, buf, len, 0))
48#else 48#else
49# define my_recv(buf, len) read(sd, buf, len) 49# define my_recv(buf, len) read(sd, buf, len)
50# define my_send(buf, len) send(sd, buf, len, 0) 50# define my_send(buf, len) send(sd, buf, len, 0)
51#endif 51#endif
52 52
53/* int my_recv(char *, size_t); */ 53/* int my_recv(char *, size_t); */
54static int process_arguments (int, char **); 54static int process_arguments(int, char **);
55void print_help (void); 55void print_help(void);
56void print_usage (void); 56void print_usage(void);
57 57
58#define EXPECT server_expect[0] 58#define EXPECT server_expect[0]
59static char *SERVICE = "TCP"; 59static char *SERVICE = "TCP";
@@ -91,16 +91,14 @@ static char *sni = NULL;
91static bool sni_specified = false; 91static bool sni_specified = false;
92#endif 92#endif
93 93
94#define FLAG_SSL 0x01 94#define FLAG_SSL 0x01
95#define FLAG_VERBOSE 0x02 95#define FLAG_VERBOSE 0x02
96#define FLAG_TIME_WARN 0x04 96#define FLAG_TIME_WARN 0x04
97#define FLAG_TIME_CRIT 0x08 97#define FLAG_TIME_CRIT 0x08
98#define FLAG_HIDE_OUTPUT 0x10 98#define FLAG_HIDE_OUTPUT 0x10
99static size_t flags; 99static size_t flags;
100 100
101int 101int main(int argc, char **argv) {
102main (int argc, char **argv)
103{
104 int result = STATE_UNKNOWN; 102 int result = STATE_UNKNOWN;
105 char *status = NULL; 103 char *status = NULL;
106 struct timeval tv; 104 struct timeval tv;
@@ -110,19 +108,21 @@ main (int argc, char **argv)
110 108
111 FD_ZERO(&rfds); 109 FD_ZERO(&rfds);
112 110
113 setlocale (LC_ALL, ""); 111 setlocale(LC_ALL, "");
114 bindtextdomain (PACKAGE, LOCALEDIR); 112 bindtextdomain(PACKAGE, LOCALEDIR);
115 textdomain (PACKAGE); 113 textdomain(PACKAGE);
116 114
117 /* determine program- and service-name quickly */ 115 /* determine program- and service-name quickly */
118 progname = strrchr(argv[0], '/'); 116 progname = strrchr(argv[0], '/');
119 if(progname != NULL) progname++; 117 if (progname != NULL)
120 else progname = argv[0]; 118 progname++;
119 else
120 progname = argv[0];
121 121
122 size_t prog_name_len = strlen(progname); 122 size_t prog_name_len = strlen(progname);
123 if(prog_name_len > 6 && !memcmp(progname, "check_", 6)) { 123 if (prog_name_len > 6 && !memcmp(progname, "check_", 6)) {
124 SERVICE = strdup(progname + 6); 124 SERVICE = strdup(progname + 6);
125 for(size_t i = 0; i < prog_name_len - 6; i++) 125 for (size_t i = 0; i < prog_name_len - 6; i++)
126 SERVICE[i] = toupper(SERVICE[i]); 126 SERVICE[i] = toupper(SERVICE[i]);
127 } 127 }
128 128
@@ -133,23 +133,19 @@ main (int argc, char **argv)
133 /* determine defaults for this service's protocol */ 133 /* determine defaults for this service's protocol */
134 if (!strncmp(SERVICE, "UDP", 3)) { 134 if (!strncmp(SERVICE, "UDP", 3)) {
135 PROTOCOL = IPPROTO_UDP; 135 PROTOCOL = IPPROTO_UDP;
136 } 136 } else if (!strncmp(SERVICE, "FTP", 3)) {
137 else if (!strncmp(SERVICE, "FTP", 3)) {
138 EXPECT = "220"; 137 EXPECT = "220";
139 QUIT = "QUIT\r\n"; 138 QUIT = "QUIT\r\n";
140 PORT = 21; 139 PORT = 21;
141 } 140 } else if (!strncmp(SERVICE, "POP", 3) || !strncmp(SERVICE, "POP3", 4)) {
142 else if (!strncmp(SERVICE, "POP", 3) || !strncmp(SERVICE, "POP3", 4)) {
143 EXPECT = "+OK"; 141 EXPECT = "+OK";
144 QUIT = "QUIT\r\n"; 142 QUIT = "QUIT\r\n";
145 PORT = 110; 143 PORT = 110;
146 } 144 } else if (!strncmp(SERVICE, "SMTP", 4)) {
147 else if (!strncmp(SERVICE, "SMTP", 4)) {
148 EXPECT = "220"; 145 EXPECT = "220";
149 QUIT = "QUIT\r\n"; 146 QUIT = "QUIT\r\n";
150 PORT = 25; 147 PORT = 25;
151 } 148 } else if (!strncmp(SERVICE, "IMAP", 4)) {
152 else if (!strncmp(SERVICE, "IMAP", 4)) {
153 EXPECT = "* OK"; 149 EXPECT = "* OK";
154 QUIT = "a1 LOGOUT\r\n"; 150 QUIT = "a1 LOGOUT\r\n";
155 PORT = 143; 151 PORT = 143;
@@ -160,27 +156,23 @@ main (int argc, char **argv)
160 QUIT = "a1 LOGOUT\r\n"; 156 QUIT = "a1 LOGOUT\r\n";
161 flags |= FLAG_SSL; 157 flags |= FLAG_SSL;
162 PORT = 993; 158 PORT = 993;
163 } 159 } else if (!strncmp(SERVICE, "SPOP", 4)) {
164 else if (!strncmp(SERVICE, "SPOP", 4)) {
165 EXPECT = "+OK"; 160 EXPECT = "+OK";
166 QUIT = "QUIT\r\n"; 161 QUIT = "QUIT\r\n";
167 flags |= FLAG_SSL; 162 flags |= FLAG_SSL;
168 PORT = 995; 163 PORT = 995;
169 } 164 } else if (!strncmp(SERVICE, "SSMTP", 5)) {
170 else if (!strncmp(SERVICE, "SSMTP", 5)) {
171 EXPECT = "220"; 165 EXPECT = "220";
172 QUIT = "QUIT\r\n"; 166 QUIT = "QUIT\r\n";
173 flags |= FLAG_SSL; 167 flags |= FLAG_SSL;
174 PORT = 465; 168 PORT = 465;
175 } 169 } else if (!strncmp(SERVICE, "JABBER", 6)) {
176 else if (!strncmp(SERVICE, "JABBER", 6)) {
177 SEND = "<stream:stream to=\'host\' xmlns=\'jabber:client\' xmlns:stream=\'http://etherx.jabber.org/streams\'>\n"; 170 SEND = "<stream:stream to=\'host\' xmlns=\'jabber:client\' xmlns:stream=\'http://etherx.jabber.org/streams\'>\n";
178 EXPECT = "<?xml version=\'1.0\'"; 171 EXPECT = "<?xml version=\'1.0\'";
179 QUIT = "</stream:stream>\n"; 172 QUIT = "</stream:stream>\n";
180 flags |= FLAG_HIDE_OUTPUT; 173 flags |= FLAG_HIDE_OUTPUT;
181 PORT = 5222; 174 PORT = 5222;
182 } 175 } else if (!strncmp(SERVICE, "NNTPS", 5)) {
183 else if (!strncmp (SERVICE, "NNTPS", 5)) {
184 server_expect_count = 2; 176 server_expect_count = 2;
185 server_expect[0] = "200"; 177 server_expect[0] = "200";
186 server_expect[1] = "201"; 178 server_expect[1] = "201";
@@ -189,23 +181,22 @@ main (int argc, char **argv)
189 PORT = 563; 181 PORT = 563;
190 } 182 }
191#endif 183#endif
192 else if (!strncmp (SERVICE, "NNTP", 4)) { 184 else if (!strncmp(SERVICE, "NNTP", 4)) {
193 server_expect_count = 2; 185 server_expect_count = 2;
194 server_expect = malloc(sizeof(char *) * server_expect_count); 186 server_expect = malloc(sizeof(char *) * server_expect_count);
195 server_expect[0] = strdup("200"); 187 server_expect[0] = strdup("200");
196 server_expect[1] = strdup("201"); 188 server_expect[1] = strdup("201");
197 QUIT = "QUIT\r\n"; 189 QUIT = "QUIT\r\n";
198 PORT = 119; 190 PORT = 119;
199 } 191 } else if (!strncmp(SERVICE, "CLAMD", 5)) {
200 else if (!strncmp(SERVICE, "CLAMD", 5)) {
201 SEND = "PING"; 192 SEND = "PING";
202 EXPECT = "PONG"; 193 EXPECT = "PONG";
203 QUIT = NULL; 194 QUIT = NULL;
204 PORT = 3310; 195 PORT = 3310;
205 } 196 }
206 /* fallthrough check, so it's supposed to use reverse matching */ 197 /* fallthrough check, so it's supposed to use reverse matching */
207 else if (strcmp (SERVICE, "TCP")) 198 else if (strcmp(SERVICE, "TCP"))
208 usage (_("CRITICAL - Generic check_tcp called with unknown service\n")); 199 usage(_("CRITICAL - Generic check_tcp called with unknown service\n"));
209 200
210 server_address = "127.0.0.1"; 201 server_address = "127.0.0.1";
211 server_port = PORT; 202 server_port = PORT;
@@ -214,58 +205,60 @@ main (int argc, char **argv)
214 status = NULL; 205 status = NULL;
215 206
216 /* Parse extra opts if any */ 207 /* Parse extra opts if any */
217 argv=np_extra_opts (&argc, argv, progname); 208 argv = np_extra_opts(&argc, argv, progname);
218 209
219 if (process_arguments (argc, argv) == ERROR) 210 if (process_arguments(argc, argv) == ERROR)
220 usage4 (_("Could not parse arguments")); 211 usage4(_("Could not parse arguments"));
221 212
222 if(flags & FLAG_VERBOSE) { 213 if (flags & FLAG_VERBOSE) {
223 printf("Using service %s\n", SERVICE); 214 printf("Using service %s\n", SERVICE);
224 printf("Port: %d\n", server_port); 215 printf("Port: %d\n", server_port);
225 printf("flags: 0x%x\n", (int)flags); 216 printf("flags: 0x%x\n", (int)flags);
226 } 217 }
227 218
228 if(EXPECT && !server_expect_count) 219 if (EXPECT && !server_expect_count)
229 server_expect_count++; 220 server_expect_count++;
230 221
231 if(PROTOCOL==IPPROTO_UDP && !(server_expect_count && server_send)){ 222 if (PROTOCOL == IPPROTO_UDP && !(server_expect_count && server_send)) {
232 usage(_("With UDP checks, a send/expect string must be specified.")); 223 usage(_("With UDP checks, a send/expect string must be specified."));
233 } 224 }
234 225
235 /* set up the timer */ 226 /* set up the timer */
236 signal (SIGALRM, socket_timeout_alarm_handler); 227 signal(SIGALRM, socket_timeout_alarm_handler);
237 alarm (socket_timeout); 228 alarm(socket_timeout);
238 229
239 /* try to connect to the host at the given port number */ 230 /* try to connect to the host at the given port number */
240 gettimeofday (&tv, NULL); 231 gettimeofday(&tv, NULL);
241 232
242 result = np_net_connect (server_address, server_port, &sd, PROTOCOL); 233 result = np_net_connect(server_address, server_port, &sd, PROTOCOL);
243 if (result == STATE_CRITICAL) return econn_refuse_state; 234 if (result == STATE_CRITICAL)
235 return econn_refuse_state;
244 236
245#ifdef HAVE_SSL 237#ifdef HAVE_SSL
246 if (flags & FLAG_SSL){ 238 if (flags & FLAG_SSL) {
247 result = np_net_ssl_init_with_hostname(sd, (sni_specified ? sni : NULL)); 239 result = np_net_ssl_init_with_hostname(sd, (sni_specified ? sni : NULL));
248 if (result == STATE_OK && check_cert) { 240 if (result == STATE_OK && check_cert) {
249 result = np_net_ssl_check_cert(days_till_exp_warn, days_till_exp_crit); 241 result = np_net_ssl_check_cert(days_till_exp_warn, days_till_exp_crit);
250 } 242 }
251 } 243 }
252 if(result != STATE_OK){ 244 if (result != STATE_OK) {
253 if(sd) close(sd); 245 if (sd)
246 close(sd);
254 np_net_ssl_cleanup(); 247 np_net_ssl_cleanup();
255 return result; 248 return result;
256 } 249 }
257#endif /* HAVE_SSL */ 250#endif /* HAVE_SSL */
258 251
259 if (server_send != NULL) { /* Something to send? */ 252 if (server_send != NULL) { /* Something to send? */
260 my_send(server_send, strlen(server_send)); 253 my_send(server_send, strlen(server_send));
261 } 254 }
262 255
263 if (delay > 0) { 256 if (delay > 0) {
264 tv.tv_sec += delay; 257 tv.tv_sec += delay;
265 sleep (delay); 258 sleep(delay);
266 } 259 }
267 260
268 if(flags & FLAG_VERBOSE) { 261 if (flags & FLAG_VERBOSE) {
269 if (server_send) { 262 if (server_send) {
270 printf("Send string: %s\n", server_send); 263 printf("Send string: %s\n", server_send);
271 } 264 }
@@ -273,7 +266,7 @@ main (int argc, char **argv)
273 printf("Quit string: %s\n", server_quit); 266 printf("Quit string: %s\n", server_quit);
274 } 267 }
275 printf("server_expect_count: %d\n", (int)server_expect_count); 268 printf("server_expect_count: %d\n", (int)server_expect_count);
276 for(size_t i = 0; i < server_expect_count; i++) 269 for (size_t i = 0; i < server_expect_count; i++)
277 printf("\t%zd: %s\n", i, server_expect[i]); 270 printf("\t%zd: %s\n", i, server_expect[i]);
278 } 271 }
279 272
@@ -294,17 +287,14 @@ main (int argc, char **argv)
294 if (maxbytes && len >= maxbytes) 287 if (maxbytes && len >= maxbytes)
295 break; 288 break;
296 289
297 if ((match = np_expect_match(status, 290 if ((match = np_expect_match(status, server_expect, server_expect_count, match_flags)) != NP_MATCH_RETRY)
298 server_expect,
299 server_expect_count,
300 match_flags)) != NP_MATCH_RETRY)
301 break; 291 break;
302 292
303 /* some protocols wait for further input, so make sure we don't wait forever */ 293 /* some protocols wait for further input, so make sure we don't wait forever */
304 FD_SET(sd, &rfds); 294 FD_SET(sd, &rfds);
305 timeout.tv_sec = READ_TIMEOUT; 295 timeout.tv_sec = READ_TIMEOUT;
306 timeout.tv_usec = 0; 296 timeout.tv_usec = 0;
307 if(select(sd + 1, &rfds, NULL, NULL, &timeout) <= 0) 297 if (select(sd + 1, &rfds, NULL, NULL, &timeout) <= 0)
308 break; 298 break;
309 } 299 }
310 300
@@ -313,26 +303,26 @@ main (int argc, char **argv)
313 303
314 /* no data when expected, so return critical */ 304 /* no data when expected, so return critical */
315 if (len == 0) 305 if (len == 0)
316 die (STATE_CRITICAL, _("No data received from host\n")); 306 die(STATE_CRITICAL, _("No data received from host\n"));
317 307
318 /* print raw output if we're debugging */ 308 /* print raw output if we're debugging */
319 if(flags & FLAG_VERBOSE) 309 if (flags & FLAG_VERBOSE)
320 printf("received %d bytes from host\n#-raw-recv-------#\n%s\n#-raw-recv-------#\n", 310 printf("received %d bytes from host\n#-raw-recv-------#\n%s\n#-raw-recv-------#\n", (int)len + 1, status);
321 (int)len + 1, status);
322 /* strip whitespace from end of output */ 311 /* strip whitespace from end of output */
323 while(--len > 0 && isspace(status[len])) 312 while (--len > 0 && isspace(status[len]))
324 status[len] = '\0'; 313 status[len] = '\0';
325 } 314 }
326 315
327 if (server_quit != NULL) { 316 if (server_quit != NULL) {
328 my_send(server_quit, strlen(server_quit)); 317 my_send(server_quit, strlen(server_quit));
329 } 318 }
330 if (sd) close (sd); 319 if (sd)
320 close(sd);
331#ifdef HAVE_SSL 321#ifdef HAVE_SSL
332 np_net_ssl_cleanup(); 322 np_net_ssl_cleanup();
333#endif 323#endif
334 324
335 microsec = deltime (tv); 325 microsec = deltime(tv);
336 elapsed_time = (double)microsec / 1.0e6; 326 elapsed_time = (double)microsec / 1.0e6;
337 327
338 if (flags & FLAG_TIME_CRIT && elapsed_time > critical_time) 328 if (flags & FLAG_TIME_CRIT && elapsed_time > critical_time)
@@ -341,66 +331,52 @@ main (int argc, char **argv)
341 result = STATE_WARNING; 331 result = STATE_WARNING;
342 332
343 /* did we get the response we hoped? */ 333 /* did we get the response we hoped? */
344 if(match == NP_MATCH_FAILURE && result != STATE_CRITICAL) 334 if (match == NP_MATCH_FAILURE && result != STATE_CRITICAL)
345 result = expect_mismatch_state; 335 result = expect_mismatch_state;
346 336
347 /* reset the alarm */ 337 /* reset the alarm */
348 alarm (0); 338 alarm(0);
349 339
350 /* this is a bit stupid, because we don't want to print the 340 /* this is a bit stupid, because we don't want to print the
351 * response time (which can look ok to the user) if we didn't get 341 * response time (which can look ok to the user) if we didn't get
352 * the response we were looking for. if-else */ 342 * the response we were looking for. if-else */
353 printf("%s %s - ", SERVICE, state_text(result)); 343 printf("%s %s - ", SERVICE, state_text(result));
354 344
355 if(match == NP_MATCH_FAILURE && len && !(flags & FLAG_HIDE_OUTPUT)) 345 if (match == NP_MATCH_FAILURE && len && !(flags & FLAG_HIDE_OUTPUT))
356 printf("Unexpected response from host/socket: %s", status); 346 printf("Unexpected response from host/socket: %s", status);
357 else { 347 else {
358 if(match == NP_MATCH_FAILURE) 348 if (match == NP_MATCH_FAILURE)
359 printf("Unexpected response from host/socket on "); 349 printf("Unexpected response from host/socket on ");
360 else 350 else
361 printf("%.3f second response time on ", elapsed_time); 351 printf("%.3f second response time on ", elapsed_time);
362 if(server_address[0] != '/') { 352 if (server_address[0] != '/') {
363 if (host_specified) 353 if (host_specified)
364 printf("%s port %d", 354 printf("%s port %d", server_address, server_port);
365 server_address, server_port);
366 else 355 else
367 printf("port %d", server_port); 356 printf("port %d", server_port);
368 } 357 } else
369 else
370 printf("socket %s", server_address); 358 printf("socket %s", server_address);
371 } 359 }
372 360
373 if (match != NP_MATCH_FAILURE && !(flags & FLAG_HIDE_OUTPUT) && len) 361 if (match != NP_MATCH_FAILURE && !(flags & FLAG_HIDE_OUTPUT) && len)
374 printf (" [%s]", status); 362 printf(" [%s]", status);
375 363
376 /* perf-data doesn't apply when server doesn't talk properly, 364 /* perf-data doesn't apply when server doesn't talk properly,
377 * so print all zeroes on warn and crit. Use fperfdata since 365 * so print all zeroes on warn and crit. Use fperfdata since
378 * localisation settings can make different outputs */ 366 * localisation settings can make different outputs */
379 if(match == NP_MATCH_FAILURE) 367 if (match == NP_MATCH_FAILURE)
380 printf ("|%s", 368 printf("|%s", fperfdata("time", elapsed_time, "s", (flags & FLAG_TIME_WARN ? true : false), 0,
381 fperfdata ("time", elapsed_time, "s", 369 (flags & FLAG_TIME_CRIT ? true : false), 0, true, 0, true, socket_timeout));
382 (flags & FLAG_TIME_WARN ? true : false), 0,
383 (flags & FLAG_TIME_CRIT ? true : false), 0,
384 true, 0,
385 true, socket_timeout)
386 );
387 else 370 else
388 printf("|%s", 371 printf("|%s", fperfdata("time", elapsed_time, "s", (flags & FLAG_TIME_WARN ? true : false), warning_time,
389 fperfdata ("time", elapsed_time, "s", 372 (flags & FLAG_TIME_CRIT ? true : false), critical_time, true, 0, true, socket_timeout));
390 (flags & FLAG_TIME_WARN ? true : false), warning_time,
391 (flags & FLAG_TIME_CRIT ? true : false), critical_time,
392 true, 0,
393 true, socket_timeout)
394 );
395 373
396 putchar('\n'); 374 putchar('\n');
397 return result; 375 return result;
398} 376}
399 377
400
401
402/* process command-line arguments */ 378/* process command-line arguments */
403static int process_arguments (int argc, char **argv) { 379static int process_arguments(int argc, char **argv) {
404 int c; 380 int c;
405 bool escape = false; 381 bool escape = false;
406 char *temp; 382 char *temp;
@@ -410,50 +386,48 @@ static int process_arguments (int argc, char **argv) {
410 }; 386 };
411 387
412 int option = 0; 388 int option = 0;
413 static struct option longopts[] = { 389 static struct option longopts[] = {{"hostname", required_argument, 0, 'H'},
414 {"hostname", required_argument, 0, 'H'}, 390 {"critical", required_argument, 0, 'c'},
415 {"critical", required_argument, 0, 'c'}, 391 {"warning", required_argument, 0, 'w'},
416 {"warning", required_argument, 0, 'w'}, 392 {"critical-codes", required_argument, 0, 'C'},
417 {"critical-codes", required_argument, 0, 'C'}, 393 {"warning-codes", required_argument, 0, 'W'},
418 {"warning-codes", required_argument, 0, 'W'}, 394 {"timeout", required_argument, 0, 't'},
419 {"timeout", required_argument, 0, 't'}, 395 {"protocol", required_argument, 0, 'P'}, /* FIXME: Unhandled */
420 {"protocol", required_argument, 0, 'P'}, /* FIXME: Unhandled */ 396 {"port", required_argument, 0, 'p'},
421 {"port", required_argument, 0, 'p'}, 397 {"escape", no_argument, 0, 'E'},
422 {"escape", no_argument, 0, 'E'}, 398 {"all", no_argument, 0, 'A'},
423 {"all", no_argument, 0, 'A'}, 399 {"send", required_argument, 0, 's'},
424 {"send", required_argument, 0, 's'}, 400 {"expect", required_argument, 0, 'e'},
425 {"expect", required_argument, 0, 'e'}, 401 {"maxbytes", required_argument, 0, 'm'},
426 {"maxbytes", required_argument, 0, 'm'}, 402 {"quit", required_argument, 0, 'q'},
427 {"quit", required_argument, 0, 'q'}, 403 {"jail", no_argument, 0, 'j'},
428 {"jail", no_argument, 0, 'j'}, 404 {"delay", required_argument, 0, 'd'},
429 {"delay", required_argument, 0, 'd'}, 405 {"refuse", required_argument, 0, 'r'},
430 {"refuse", required_argument, 0, 'r'}, 406 {"mismatch", required_argument, 0, 'M'},
431 {"mismatch", required_argument, 0, 'M'}, 407 {"use-ipv4", no_argument, 0, '4'},
432 {"use-ipv4", no_argument, 0, '4'}, 408 {"use-ipv6", no_argument, 0, '6'},
433 {"use-ipv6", no_argument, 0, '6'}, 409 {"verbose", no_argument, 0, 'v'},
434 {"verbose", no_argument, 0, 'v'}, 410 {"version", no_argument, 0, 'V'},
435 {"version", no_argument, 0, 'V'}, 411 {"help", no_argument, 0, 'h'},
436 {"help", no_argument, 0, 'h'}, 412 {"ssl", no_argument, 0, 'S'},
437 {"ssl", no_argument, 0, 'S'}, 413 {"sni", required_argument, 0, SNI_OPTION},
438 {"sni", required_argument, 0, SNI_OPTION}, 414 {"certificate", required_argument, 0, 'D'},
439 {"certificate", required_argument, 0, 'D'}, 415 {0, 0, 0, 0}};
440 {0, 0, 0, 0}
441 };
442 416
443 if (argc < 2) 417 if (argc < 2)
444 usage4 (_("No arguments found")); 418 usage4(_("No arguments found"));
445 419
446 /* backwards compatibility */ 420 /* backwards compatibility */
447 for (c = 1; c < argc; c++) { 421 for (c = 1; c < argc; c++) {
448 if (strcmp ("-to", argv[c]) == 0) 422 if (strcmp("-to", argv[c]) == 0)
449 strcpy (argv[c], "-t"); 423 strcpy(argv[c], "-t");
450 else if (strcmp ("-wt", argv[c]) == 0) 424 else if (strcmp("-wt", argv[c]) == 0)
451 strcpy (argv[c], "-w"); 425 strcpy(argv[c], "-w");
452 else if (strcmp ("-ct", argv[c]) == 0) 426 else if (strcmp("-ct", argv[c]) == 0)
453 strcpy (argv[c], "-c"); 427 strcpy(argv[c], "-c");
454 } 428 }
455 429
456 if (!is_option (argv[1])) { 430 if (!is_option(argv[1])) {
457 server_address = argv[1]; 431 server_address = argv[1];
458 argv[1] = argv[0]; 432 argv[1] = argv[0];
459 argv = &argv[1]; 433 argv = &argv[1];
@@ -461,22 +435,21 @@ static int process_arguments (int argc, char **argv) {
461 } 435 }
462 436
463 while (1) { 437 while (1) {
464 c = getopt_long (argc, argv, "+hVv46EAH:s:e:q:m:c:w:t:p:C:W:d:Sr:jD:M:", 438 c = getopt_long(argc, argv, "+hVv46EAH:s:e:q:m:c:w:t:p:C:W:d:Sr:jD:M:", longopts, &option);
465 longopts, &option);
466 439
467 if (c == -1 || c == EOF || c == 1) 440 if (c == -1 || c == EOF || c == 1)
468 break; 441 break;
469 442
470 switch (c) { 443 switch (c) {
471 case '?': /* print short usage statement if args not parsable */ 444 case '?': /* print short usage statement if args not parsable */
472 usage5 (); 445 usage5();
473 case 'h': /* help */ 446 case 'h': /* help */
474 print_help (); 447 print_help();
475 exit (STATE_UNKNOWN); 448 exit(STATE_UNKNOWN);
476 case 'V': /* version */ 449 case 'V': /* version */
477 print_revision (progname, NP_VERSION); 450 print_revision(progname, NP_VERSION);
478 exit (STATE_UNKNOWN); 451 exit(STATE_UNKNOWN);
479 case 'v': /* verbose mode */ 452 case 'v': /* verbose mode */
480 flags |= FLAG_VERBOSE; 453 flags |= FLAG_VERBOSE;
481 match_flags |= NP_MATCH_VERBOSE; 454 match_flags |= NP_MATCH_VERBOSE;
482 break; 455 break;
@@ -487,43 +460,43 @@ static int process_arguments (int argc, char **argv) {
487#ifdef USE_IPV6 460#ifdef USE_IPV6
488 address_family = AF_INET6; 461 address_family = AF_INET6;
489#else 462#else
490 usage4 (_("IPv6 support not available")); 463 usage4(_("IPv6 support not available"));
491#endif 464#endif
492 break; 465 break;
493 case 'H': /* hostname */ 466 case 'H': /* hostname */
494 host_specified = true; 467 host_specified = true;
495 server_address = optarg; 468 server_address = optarg;
496 break; 469 break;
497 case 'c': /* critical */ 470 case 'c': /* critical */
498 critical_time = strtod (optarg, NULL); 471 critical_time = strtod(optarg, NULL);
499 flags |= FLAG_TIME_CRIT; 472 flags |= FLAG_TIME_CRIT;
500 break; 473 break;
501 case 'j': /* hide output */ 474 case 'j': /* hide output */
502 flags |= FLAG_HIDE_OUTPUT; 475 flags |= FLAG_HIDE_OUTPUT;
503 break; 476 break;
504 case 'w': /* warning */ 477 case 'w': /* warning */
505 warning_time = strtod (optarg, NULL); 478 warning_time = strtod(optarg, NULL);
506 flags |= FLAG_TIME_WARN; 479 flags |= FLAG_TIME_WARN;
507 break; 480 break;
508 case 'C': 481 case 'C':
509 crit_codes = realloc (crit_codes, ++crit_codes_count); 482 crit_codes = realloc(crit_codes, ++crit_codes_count);
510 crit_codes[crit_codes_count - 1] = optarg; 483 crit_codes[crit_codes_count - 1] = optarg;
511 break; 484 break;
512 case 'W': 485 case 'W':
513 warn_codes = realloc (warn_codes, ++warn_codes_count); 486 warn_codes = realloc(warn_codes, ++warn_codes_count);
514 warn_codes[warn_codes_count - 1] = optarg; 487 warn_codes[warn_codes_count - 1] = optarg;
515 break; 488 break;
516 case 't': /* timeout */ 489 case 't': /* timeout */
517 if (!is_intpos (optarg)) 490 if (!is_intpos(optarg))
518 usage4 (_("Timeout interval must be a positive integer")); 491 usage4(_("Timeout interval must be a positive integer"));
519 else 492 else
520 socket_timeout = atoi (optarg); 493 socket_timeout = atoi(optarg);
521 break; 494 break;
522 case 'p': /* port */ 495 case 'p': /* port */
523 if (!is_intpos (optarg)) 496 if (!is_intpos(optarg))
524 usage4 (_("Port must be a positive integer")); 497 usage4(_("Port must be a positive integer"));
525 else 498 else
526 server_port = atoi (optarg); 499 server_port = atoi(optarg);
527 break; 500 break;
528 case 'E': 501 case 'E':
529 escape = true; 502 escape = true;
@@ -537,16 +510,16 @@ static int process_arguments (int argc, char **argv) {
537 case 'e': /* expect string (may be repeated) */ 510 case 'e': /* expect string (may be repeated) */
538 match_flags &= ~NP_MATCH_EXACT; 511 match_flags &= ~NP_MATCH_EXACT;
539 if (server_expect_count == 0) 512 if (server_expect_count == 0)
540 server_expect = malloc (sizeof (char *) * (++server_expect_count)); 513 server_expect = malloc(sizeof(char *) * (++server_expect_count));
541 else 514 else
542 server_expect = realloc (server_expect, sizeof (char *) * (++server_expect_count)); 515 server_expect = realloc(server_expect, sizeof(char *) * (++server_expect_count));
543 server_expect[server_expect_count - 1] = optarg; 516 server_expect[server_expect_count - 1] = optarg;
544 break; 517 break;
545 case 'm': 518 case 'm':
546 if (!is_intpos (optarg)) 519 if (!is_intpos(optarg))
547 usage4 (_("Maxbytes must be a positive integer")); 520 usage4(_("Maxbytes must be a positive integer"));
548 else 521 else
549 maxbytes = strtol (optarg, NULL, 0); 522 maxbytes = strtol(optarg, NULL, 0);
550 break; 523 break;
551 case 'q': 524 case 'q':
552 if (escape) 525 if (escape)
@@ -555,62 +528,61 @@ static int process_arguments (int argc, char **argv) {
555 xasprintf(&server_quit, "%s\r\n", optarg); 528 xasprintf(&server_quit, "%s\r\n", optarg);
556 break; 529 break;
557 case 'r': 530 case 'r':
558 if (!strncmp(optarg,"ok",2)) 531 if (!strncmp(optarg, "ok", 2))
559 econn_refuse_state = STATE_OK; 532 econn_refuse_state = STATE_OK;
560 else if (!strncmp(optarg,"warn",4)) 533 else if (!strncmp(optarg, "warn", 4))
561 econn_refuse_state = STATE_WARNING; 534 econn_refuse_state = STATE_WARNING;
562 else if (!strncmp(optarg,"crit",4)) 535 else if (!strncmp(optarg, "crit", 4))
563 econn_refuse_state = STATE_CRITICAL; 536 econn_refuse_state = STATE_CRITICAL;
564 else 537 else
565 usage4 (_("Refuse must be one of ok, warn, crit")); 538 usage4(_("Refuse must be one of ok, warn, crit"));
566 break; 539 break;
567 case 'M': 540 case 'M':
568 if (!strncmp(optarg,"ok",2)) 541 if (!strncmp(optarg, "ok", 2))
569 expect_mismatch_state = STATE_OK; 542 expect_mismatch_state = STATE_OK;
570 else if (!strncmp(optarg,"warn",4)) 543 else if (!strncmp(optarg, "warn", 4))
571 expect_mismatch_state = STATE_WARNING; 544 expect_mismatch_state = STATE_WARNING;
572 else if (!strncmp(optarg,"crit",4)) 545 else if (!strncmp(optarg, "crit", 4))
573 expect_mismatch_state = STATE_CRITICAL; 546 expect_mismatch_state = STATE_CRITICAL;
574 else 547 else
575 usage4 (_("Mismatch must be one of ok, warn, crit")); 548 usage4(_("Mismatch must be one of ok, warn, crit"));
576 break; 549 break;
577 case 'd': 550 case 'd':
578 if (is_intpos (optarg)) 551 if (is_intpos(optarg))
579 delay = atoi (optarg); 552 delay = atoi(optarg);
580 else 553 else
581 usage4 (_("Delay must be a positive integer")); 554 usage4(_("Delay must be a positive integer"));
582 break; 555 break;
583 case 'D': /* Check SSL cert validity - days 'til certificate expiration */ 556 case 'D': /* Check SSL cert validity - days 'til certificate expiration */
584#ifdef HAVE_SSL 557#ifdef HAVE_SSL
585# ifdef USE_OPENSSL /* XXX */ 558# ifdef USE_OPENSSL /* XXX */
586 if ((temp=strchr(optarg,','))!=NULL) { 559 if ((temp = strchr(optarg, ',')) != NULL) {
587 *temp='\0'; 560 *temp = '\0';
588 if (!is_intnonneg (optarg)) 561 if (!is_intnonneg(optarg))
589 usage2 (_("Invalid certificate expiration period"), optarg); 562 usage2(_("Invalid certificate expiration period"), optarg);
590 days_till_exp_warn = atoi (optarg); 563 days_till_exp_warn = atoi(optarg);
591 *temp=','; 564 *temp = ',';
592 temp++; 565 temp++;
593 if (!is_intnonneg (temp)) 566 if (!is_intnonneg(temp))
594 usage2 (_("Invalid certificate expiration period"), temp); 567 usage2(_("Invalid certificate expiration period"), temp);
595 days_till_exp_crit = atoi (temp); 568 days_till_exp_crit = atoi(temp);
596 } 569 } else {
597 else { 570 days_till_exp_crit = 0;
598 days_till_exp_crit=0; 571 if (!is_intnonneg(optarg))
599 if (!is_intnonneg (optarg)) 572 usage2(_("Invalid certificate expiration period"), optarg);
600 usage2 (_("Invalid certificate expiration period"), optarg); 573 days_till_exp_warn = atoi(optarg);
601 days_till_exp_warn = atoi (optarg);
602 } 574 }
603 check_cert = true; 575 check_cert = true;
604 flags |= FLAG_SSL; 576 flags |= FLAG_SSL;
605 break; 577 break;
606# endif /* USE_OPENSSL */ 578# endif /* USE_OPENSSL */
607#endif 579#endif
608 /* fallthrough if we don't have ssl */ 580 /* fallthrough if we don't have ssl */
609 case 'S': 581 case 'S':
610#ifdef HAVE_SSL 582#ifdef HAVE_SSL
611 flags |= FLAG_SSL; 583 flags |= FLAG_SSL;
612#else 584#else
613 die (STATE_UNKNOWN, _("Invalid option - SSL is not available")); 585 die(STATE_UNKNOWN, _("Invalid option - SSL is not available"));
614#endif 586#endif
615 break; 587 break;
616 case SNI_OPTION: 588 case SNI_OPTION:
@@ -619,7 +591,7 @@ static int process_arguments (int argc, char **argv) {
619 sni_specified = true; 591 sni_specified = true;
620 sni = optarg; 592 sni = optarg;
621#else 593#else
622 die (STATE_UNKNOWN, _("Invalid option - SSL is not available")); 594 die(STATE_UNKNOWN, _("Invalid option - SSL is not available"));
623#endif 595#endif
624 break; 596 break;
625 case 'A': 597 case 'A':
@@ -629,86 +601,80 @@ static int process_arguments (int argc, char **argv) {
629 } 601 }
630 602
631 c = optind; 603 c = optind;
632 if(!host_specified && c < argc) 604 if (!host_specified && c < argc)
633 server_address = strdup (argv[c++]); 605 server_address = strdup(argv[c++]);
634 606
635 if (server_address == NULL) 607 if (server_address == NULL)
636 usage4 (_("You must provide a server address")); 608 usage4(_("You must provide a server address"));
637 else if (server_address[0] != '/' && !is_host(server_address)) 609 else if (server_address[0] != '/' && !is_host(server_address))
638 die (STATE_CRITICAL, "%s %s - %s: %s\n", SERVICE, state_text(STATE_CRITICAL), _("Invalid hostname, address or socket"), server_address); 610 die(STATE_CRITICAL, "%s %s - %s: %s\n", SERVICE, state_text(STATE_CRITICAL), _("Invalid hostname, address or socket"),
611 server_address);
639 612
640 return OK; 613 return OK;
641} 614}
642 615
643 616void print_help(void) {
644void 617 print_revision(progname, NP_VERSION);
645print_help (void) 618
646{ 619 printf("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n");
647 print_revision (progname, NP_VERSION); 620 printf(COPYRIGHT, copyright, email);
648 621
649 printf ("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n"); 622 printf(_("This plugin tests %s connections with the specified host (or unix socket).\n\n"), SERVICE);
650 printf (COPYRIGHT, copyright, email); 623
651 624 print_usage();
652 printf (_("This plugin tests %s connections with the specified host (or unix socket).\n\n"), 625
653 SERVICE); 626 printf(UT_HELP_VRSN);
654 627 printf(UT_EXTRA_OPTS);
655 print_usage (); 628
656 629 printf(UT_HOST_PORT, 'p', "none");
657 printf (UT_HELP_VRSN); 630
658 printf (UT_EXTRA_OPTS); 631 printf(UT_IPv46);
659 632
660 printf (UT_HOST_PORT, 'p', "none"); 633 printf(" %s\n", "-E, --escape");
661 634 printf(" %s\n", _("Can use \\n, \\r, \\t or \\\\ in send or quit string. Must come before send or quit option"));
662 printf (UT_IPv46); 635 printf(" %s\n", _("Default: nothing added to send, \\r\\n added to end of quit"));
663 636 printf(" %s\n", "-s, --send=STRING");
664 printf (" %s\n", "-E, --escape"); 637 printf(" %s\n", _("String to send to the server"));
665 printf (" %s\n", _("Can use \\n, \\r, \\t or \\\\ in send or quit string. Must come before send or quit option")); 638 printf(" %s\n", "-e, --expect=STRING");
666 printf (" %s\n", _("Default: nothing added to send, \\r\\n added to end of quit")); 639 printf(" %s %s\n", _("String to expect in server response"), _("(may be repeated)"));
667 printf (" %s\n", "-s, --send=STRING"); 640 printf(" %s\n", "-A, --all");
668 printf (" %s\n", _("String to send to the server")); 641 printf(" %s\n", _("All expect strings need to occur in server response. Default is any"));
669 printf (" %s\n", "-e, --expect=STRING"); 642 printf(" %s\n", "-q, --quit=STRING");
670 printf (" %s %s\n", _("String to expect in server response"), _("(may be repeated)")); 643 printf(" %s\n", _("String to send server to initiate a clean close of the connection"));
671 printf (" %s\n", "-A, --all"); 644 printf(" %s\n", "-r, --refuse=ok|warn|crit");
672 printf (" %s\n", _("All expect strings need to occur in server response. Default is any")); 645 printf(" %s\n", _("Accept TCP refusals with states ok, warn, crit (default: crit)"));
673 printf (" %s\n", "-q, --quit=STRING"); 646 printf(" %s\n", "-M, --mismatch=ok|warn|crit");
674 printf (" %s\n", _("String to send server to initiate a clean close of the connection")); 647 printf(" %s\n", _("Accept expected string mismatches with states ok, warn, crit (default: warn)"));
675 printf (" %s\n", "-r, --refuse=ok|warn|crit"); 648 printf(" %s\n", "-j, --jail");
676 printf (" %s\n", _("Accept TCP refusals with states ok, warn, crit (default: crit)")); 649 printf(" %s\n", _("Hide output from TCP socket"));
677 printf (" %s\n", "-M, --mismatch=ok|warn|crit"); 650 printf(" %s\n", "-m, --maxbytes=INTEGER");
678 printf (" %s\n", _("Accept expected string mismatches with states ok, warn, crit (default: warn)")); 651 printf(" %s\n", _("Close connection once more than this number of bytes are received"));
679 printf (" %s\n", "-j, --jail"); 652 printf(" %s\n", "-d, --delay=INTEGER");
680 printf (" %s\n", _("Hide output from TCP socket")); 653 printf(" %s\n", _("Seconds to wait between sending string and polling for response"));
681 printf (" %s\n", "-m, --maxbytes=INTEGER");
682 printf (" %s\n", _("Close connection once more than this number of bytes are received"));
683 printf (" %s\n", "-d, --delay=INTEGER");
684 printf (" %s\n", _("Seconds to wait between sending string and polling for response"));
685 654
686#ifdef HAVE_SSL 655#ifdef HAVE_SSL
687 printf (" %s\n", "-D, --certificate=INTEGER[,INTEGER]"); 656 printf(" %s\n", "-D, --certificate=INTEGER[,INTEGER]");
688 printf (" %s\n", _("Minimum number of days a certificate has to be valid.")); 657 printf(" %s\n", _("Minimum number of days a certificate has to be valid."));
689 printf (" %s\n", _("1st is #days for warning, 2nd is critical (if not specified - 0).")); 658 printf(" %s\n", _("1st is #days for warning, 2nd is critical (if not specified - 0)."));
690 printf (" %s\n", "-S, --ssl"); 659 printf(" %s\n", "-S, --ssl");
691 printf (" %s\n", _("Use SSL for the connection.")); 660 printf(" %s\n", _("Use SSL for the connection."));
692 printf (" %s\n", "--sni=STRING"); 661 printf(" %s\n", "--sni=STRING");
693 printf (" %s\n", _("SSL server_name")); 662 printf(" %s\n", _("SSL server_name"));
694#endif 663#endif
695 664
696 printf (UT_WARN_CRIT); 665 printf(UT_WARN_CRIT);
697 666
698 printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); 667 printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
699 668
700 printf (UT_VERBOSE); 669 printf(UT_VERBOSE);
701 670
702 printf (UT_SUPPORT); 671 printf(UT_SUPPORT);
703} 672}
704 673
705 674void print_usage(void) {
706void 675 printf("%s\n", _("Usage:"));
707print_usage (void) 676 printf("%s -H host -p port [-w <warning time>] [-c <critical time>] [-s <send string>]\n", progname);
708{ 677 printf("[-e <expect string>] [-q <quit string>][-m <maximum bytes>] [-d <delay>]\n");
709 printf ("%s\n", _("Usage:")); 678 printf("[-t <timeout seconds>] [-r <refuse state>] [-M <mismatch state>] [-v] [-4|-6] [-j]\n");
710 printf ("%s -H host -p port [-w <warning time>] [-c <critical time>] [-s <send string>]\n",progname); 679 printf("[-D <warn days cert expire>[,<crit days cert expire>]] [-S <use SSL>] [-E]\n");
711 printf ("[-e <expect string>] [-q <quit string>][-m <maximum bytes>] [-d <delay>]\n");
712 printf ("[-t <timeout seconds>] [-r <refuse state>] [-M <mismatch state>] [-v] [-4|-6] [-j]\n");
713 printf ("[-D <warn days cert expire>[,<crit days cert expire>]] [-S <use SSL>] [-E]\n");
714} 680}