bb3d295e0f31fe0a14b822a7ccfeaf5f72648d1e
1 /*****************************************************************************
2 *
3 * Nagios check_snmp plugin
4 *
5 * License: GPL
6 * Copyright (c) 1999-2007 Nagios Plugins Development Team
7 *
8 * Description:
9 *
10 * This file contains the check_snmp plugin
11 *
12 * Check status of remote machines and obtain system information via SNMP
13 *
14 *
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
17 * the Free Software Foundation, either version 3 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
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/>.
27 *
28 *
29 *****************************************************************************/
31 const char *progname = "check_snmp";
32 const char *copyright = "1999-2007";
33 const char *email = "nagiosplug-devel@lists.sourceforge.net";
35 #include "common.h"
36 #include "utils.h"
37 #include "utils_cmd.h"
39 #define DEFAULT_COMMUNITY "public"
40 #define DEFAULT_PORT "161"
41 #define DEFAULT_MIBLIST "ALL"
42 #define DEFAULT_PROTOCOL "1"
43 #define DEFAULT_TIMEOUT 1
44 #define DEFAULT_RETRIES 5
45 #define DEFAULT_AUTH_PROTOCOL "MD5"
46 #define DEFAULT_PRIV_PROTOCOL "DES"
47 #define DEFAULT_DELIMITER "="
48 #define DEFAULT_OUTPUT_DELIMITER " "
50 #define mark(a) ((a)!=0?"*":"")
52 #define CHECK_UNDEF 0
53 #define CRIT_PRESENT 1
54 #define CRIT_STRING 2
55 #define CRIT_REGEX 4
56 #define WARN_PRESENT 8
57 #define WARN_STRING 16
58 #define WARN_REGEX 32
60 #define MAX_OIDS 8
62 int process_arguments (int, char **);
63 int validate_arguments (void);
64 char *thisarg (char *str);
65 char *nextarg (char *str);
66 void print_usage (void);
67 void print_help (void);
69 #include "regex.h"
70 char regex_expect[MAX_INPUT_BUFFER] = "";
71 regex_t preg;
72 regmatch_t pmatch[10];
73 char errbuf[MAX_INPUT_BUFFER] = "";
74 char perfstr[MAX_INPUT_BUFFER] = "| ";
75 int cflags = REG_EXTENDED | REG_NOSUB | REG_NEWLINE;
76 int eflags = 0;
77 int errcode, excode;
79 char *server_address = NULL;
80 char *community = NULL;
81 char **authpriv = NULL;
82 char *proto = NULL;
83 char *seclevel = NULL;
84 char *secname = NULL;
85 char *authproto = NULL;
86 char *privproto = NULL;
87 char *authpasswd = NULL;
88 char *privpasswd = NULL;
89 char **oids = NULL;
90 char *label;
91 char *units;
92 char *port;
93 char *snmpcmd;
94 char string_value[MAX_INPUT_BUFFER] = "";
95 char **labels = NULL;
96 char **unitv = NULL;
97 size_t nlabels = 0;
98 size_t labels_size = 8;
99 size_t nunits = 0;
100 size_t unitv_size = 8;
101 int numoids = 0;
102 int numauthpriv = 0;
103 int verbose = 0;
104 int usesnmpgetnext = FALSE;
105 char *warning_thresholds = NULL;
106 char *critical_thresholds = NULL;
107 thresholds *thlds[MAX_OIDS];
108 double response_value[MAX_OIDS];
109 int retries = 0;
110 int eval_method[MAX_OIDS];
111 char *delimiter;
112 char *output_delim;
113 char *miblist = NULL;
114 int needmibs = FALSE;
117 int
118 main (int argc, char **argv)
119 {
120 int i;
121 int iresult = STATE_UNKNOWN;
122 int result = STATE_UNKNOWN;
123 int return_code = 0;
124 int external_error = 0;
125 char **command_line = NULL;
126 char *cl_hidden_auth = NULL;
127 char *oidname = NULL;
128 char *response = NULL;
129 char *outbuff;
130 char *ptr = NULL;
131 char *show = NULL;
132 char *th_warn=NULL;
133 char *th_crit=NULL;
134 char type[8] = "";
135 output chld_out, chld_err;
137 setlocale (LC_ALL, "");
138 bindtextdomain (PACKAGE, LOCALEDIR);
139 textdomain (PACKAGE);
141 labels = malloc (labels_size);
142 unitv = malloc (unitv_size);
143 for (i = 0; i < MAX_OIDS; i++)
144 eval_method[i] = CHECK_UNDEF;
146 label = strdup ("SNMP");
147 units = strdup ("");
148 port = strdup (DEFAULT_PORT);
149 outbuff = strdup ("");
150 delimiter = strdup (" = ");
151 output_delim = strdup (DEFAULT_OUTPUT_DELIMITER);
152 timeout_interval = DEFAULT_TIMEOUT;
153 retries = DEFAULT_RETRIES;
155 /* Parse extra opts if any */
156 argv=np_extra_opts (&argc, argv, progname);
158 if (process_arguments (argc, argv) == ERROR)
159 usage4 (_("Could not parse arguments"));
161 /* Populate the thresholds */
162 th_warn=warning_thresholds;
163 th_crit=critical_thresholds;
164 for (i=0; i<numoids; i++) {
165 char *w = th_warn ? strndup(th_warn, strcspn(th_warn, ",")) : NULL;
166 char *c = th_crit ? strndup(th_crit, strcspn(th_crit, ",")) : NULL;
167 /* Skip empty thresholds, while avoiding segfault */
168 set_thresholds(&thlds[i],
169 w ? strpbrk(w, NP_THRESHOLDS_CHARS) : NULL,
170 c ? strpbrk(c, NP_THRESHOLDS_CHARS) : NULL);
171 if (w) {
172 th_warn=strchr(th_warn, ',');
173 if (th_warn) th_warn++;
174 free(w);
175 }
176 if (c) {
177 th_crit=strchr(th_crit, ',');
178 if (th_crit) th_crit++;
179 free(c);
180 }
181 }
183 /* Create the command array to execute */
184 if(usesnmpgetnext == TRUE) {
185 snmpcmd = strdup (PATH_TO_SNMPGETNEXT);
186 }else{
187 snmpcmd = strdup (PATH_TO_SNMPGET);
188 }
190 /* 9 arguments to pass before authpriv options + 1 for host and numoids. Add one for terminating NULL */
191 command_line = calloc (9 + numauthpriv + 1 + numoids + 1, sizeof (char *));
192 command_line[0] = snmpcmd;
193 command_line[1] = strdup ("-t");
194 asprintf (&command_line[2], "%d", timeout_interval);
195 command_line[3] = strdup ("-r");
196 asprintf (&command_line[4], "%d", retries);
197 command_line[5] = strdup ("-m");
198 command_line[6] = strdup (miblist);
199 command_line[7] = "-v";
200 command_line[8] = strdup (proto);
202 for (i = 0; i < numauthpriv; i++) {
203 command_line[9 + i] = authpriv[i];
204 }
206 asprintf (&command_line[9 + numauthpriv], "%s:%s", server_address, port);
208 /* This is just for display purposes, so it can remain a string */
209 asprintf(&cl_hidden_auth, "%s -t %d -r %d -m %s -v %s %s %s:%s",
210 snmpcmd, timeout_interval, retries, strlen(miblist) ? miblist : "''", proto, "[authpriv]",
211 server_address, port);
213 for (i = 0; i < numoids; i++) {
214 command_line[9 + numauthpriv + 1 + i] = oids[i];
215 asprintf(&cl_hidden_auth, "%s %s", cl_hidden_auth, oids[i]);
216 }
218 command_line[9 + numauthpriv + 1 + numoids] = NULL;
220 if (verbose)
221 printf ("%s\n", cl_hidden_auth);
223 /* Run the command */
224 return_code = cmd_run_array (command_line, &chld_out, &chld_err, 0);
226 /* Due to net-snmp sometimes showing stderr messages with poorly formed MIBs,
227 only return state unknown if return code is non zero or there is no stdout.
228 Do this way so that if there is stderr, will get added to output, which helps problem diagnosis
229 */
230 if (return_code != 0)
231 external_error=1;
232 if (chld_out.lines == 0)
233 external_error=1;
234 if (external_error) {
235 if (chld_err.lines > 0) {
236 printf (_("External command error: %s\n"), chld_err.line[0]);
237 for (i = 1; i < chld_err.lines; i++) {
238 printf ("%s\n", chld_err.line[i]);
239 }
240 } else {
241 printf(_("External command error with no output (return code: %d)\n"), return_code);
242 }
243 exit (STATE_UNKNOWN);
244 }
246 if (verbose) {
247 for (i = 0; i < chld_out.lines; i++) {
248 printf ("%s\n", chld_out.line[i]);
249 }
250 }
252 for (i = 0; i < chld_out.lines; i++) {
253 const char *conv = "%.0f";
255 ptr = chld_out.line[i];
256 oidname = strpcpy (oidname, ptr, delimiter);
257 response = strstr (ptr, delimiter);
258 if (verbose > 2) {
259 printf("Processing line %i\n oidname: %s\n response: %s\n", i+1, oidname, response);
260 }
262 /* We strip out the datatype indicator for PHBs */
264 /* Clean up type array - Sol10 does not necessarily zero it out */
265 bzero(type, sizeof(type));
267 if (strstr (response, "Gauge: "))
268 show = strstr (response, "Gauge: ") + 7;
269 else if (strstr (response, "Gauge32: "))
270 show = strstr (response, "Gauge32: ") + 9;
271 else if (strstr (response, "Counter32: ")) {
272 show = strstr (response, "Counter32: ") + 11;
273 strcpy(type, "c");
274 }
275 else if (strstr (response, "Counter64: ")) {
276 show = strstr (response, "Counter64: ") + 11;
277 strcpy(type, "c");
278 }
279 else if (strstr (response, "INTEGER: "))
280 show = strstr (response, "INTEGER: ") + 9;
281 else if (strstr (response, "STRING: ")) {
282 show = strstr (response, "STRING: ") + 8;
283 conv = "%.10g";
284 }
285 else if (strstr (response, "Timeticks: "))
286 show = strstr (response, "Timeticks: ");
287 else
288 show = response;
290 iresult = STATE_DEPENDENT;
292 /* Process this block for integer comparisons */
293 if (thlds[i]->warning || thlds[i]->critical) {
294 ptr = strpbrk (show, "0123456789");
295 if (ptr == NULL)
296 die (STATE_UNKNOWN,_("No valid data returned"));
297 response_value[i] = strtod (ptr, NULL);
298 iresult = get_status(response_value[i], thlds[i]);
299 asprintf (&show, conv, response_value[i]);
300 }
302 /* Process this block for string matching */
303 else if (eval_method[i] & CRIT_STRING) {
304 if (strcmp (show, string_value))
305 iresult = STATE_CRITICAL;
306 else
307 iresult = STATE_OK;
308 }
310 /* Process this block for regex matching */
311 else if (eval_method[i] & CRIT_REGEX) {
312 excode = regexec (&preg, response, 10, pmatch, eflags);
313 if (excode == 0) {
314 iresult = STATE_OK;
315 }
316 else if (excode != REG_NOMATCH) {
317 regerror (excode, &preg, errbuf, MAX_INPUT_BUFFER);
318 printf (_("Execute Error: %s\n"), errbuf);
319 exit (STATE_CRITICAL);
320 }
321 else {
322 iresult = STATE_CRITICAL;
323 }
324 }
326 /* Process this block for existence-nonexistence checks */
327 else {
328 if (eval_method[i] & CRIT_PRESENT)
329 iresult = STATE_CRITICAL;
330 else if (eval_method[i] & WARN_PRESENT)
331 iresult = STATE_WARNING;
332 else if (response && iresult == STATE_DEPENDENT)
333 iresult = STATE_OK;
334 }
336 /* Result is the worst outcome of all the OIDs tested */
337 result = max_state (result, iresult);
339 /* Prepend a label for this OID if there is one */
340 if (nlabels > (size_t)1 && (size_t)i < nlabels && labels[i] != NULL)
341 asprintf (&outbuff, "%s%s%s %s%s%s", outbuff,
342 (i == 0) ? " " : output_delim,
343 labels[i], mark (iresult), show, mark (iresult));
344 else
345 asprintf (&outbuff, "%s%s%s%s%s", outbuff, (i == 0) ? " " : output_delim,
346 mark (iresult), show, mark (iresult));
348 /* Append a unit string for this OID if there is one */
349 if (nunits > (size_t)0 && (size_t)i < nunits && unitv[i] != NULL)
350 asprintf (&outbuff, "%s %s", outbuff, unitv[i]);
352 if (is_numeric(show)) {
353 strncat(perfstr, oidname, sizeof(perfstr)-strlen(perfstr)-1);
354 strncat(perfstr, "=", sizeof(perfstr)-strlen(perfstr)-1);
355 strncat(perfstr, show, sizeof(perfstr)-strlen(perfstr)-1);
357 if (type)
358 strncat(perfstr, type, sizeof(perfstr)-strlen(perfstr)-1);
359 strncat(perfstr, " ", sizeof(perfstr)-strlen(perfstr)-1);
360 }
361 }
363 printf ("%s %s -%s %s \n", label, state_text (result), outbuff, perfstr);
365 return result;
366 }
370 /* process command-line arguments */
371 int
372 process_arguments (int argc, char **argv)
373 {
374 char *ptr;
375 int c = 1;
376 int j = 0, jj = 0, ii = 0;
378 int option = 0;
379 static struct option longopts[] = {
380 STD_LONG_OPTS,
381 {"community", required_argument, 0, 'C'},
382 {"oid", required_argument, 0, 'o'},
383 {"object", required_argument, 0, 'o'},
384 {"delimiter", required_argument, 0, 'd'},
385 {"output-delimiter", required_argument, 0, 'D'},
386 {"string", required_argument, 0, 's'},
387 {"timeout", required_argument, 0, 't'},
388 {"regex", required_argument, 0, 'r'},
389 {"ereg", required_argument, 0, 'r'},
390 {"eregi", required_argument, 0, 'R'},
391 {"label", required_argument, 0, 'l'},
392 {"units", required_argument, 0, 'u'},
393 {"port", required_argument, 0, 'p'},
394 {"retries", required_argument, 0, 'e'},
395 {"miblist", required_argument, 0, 'm'},
396 {"protocol", required_argument, 0, 'P'},
397 {"seclevel", required_argument, 0, 'L'},
398 {"secname", required_argument, 0, 'U'},
399 {"authproto", required_argument, 0, 'a'},
400 {"privproto", required_argument, 0, 'x'},
401 {"authpasswd", required_argument, 0, 'A'},
402 {"privpasswd", required_argument, 0, 'X'},
403 {"next", no_argument, 0, 'n'},
404 {0, 0, 0, 0}
405 };
407 if (argc < 2)
408 return ERROR;
410 /* reverse compatibility for very old non-POSIX usage forms */
411 for (c = 1; c < argc; c++) {
412 if (strcmp ("-to", argv[c]) == 0)
413 strcpy (argv[c], "-t");
414 if (strcmp ("-wv", argv[c]) == 0)
415 strcpy (argv[c], "-w");
416 if (strcmp ("-cv", argv[c]) == 0)
417 strcpy (argv[c], "-c");
418 }
420 while (1) {
421 c = getopt_long (argc, argv, "nhvVt:c:w:H:C:o:e:E:d:D:s:t:R:r:l:u:p:m:P:L:U:a:x:A:X:",
422 longopts, &option);
424 if (c == -1 || c == EOF)
425 break;
427 switch (c) {
428 case '?': /* usage */
429 usage5 ();
430 case 'h': /* help */
431 print_help ();
432 exit (STATE_OK);
433 case 'V': /* version */
434 print_revision (progname, NP_VERSION);
435 exit (STATE_OK);
436 case 'v': /* verbose */
437 verbose++;
438 break;
440 /* Connection info */
441 case 'C': /* group or community */
442 community = optarg;
443 break;
444 case 'H': /* Host or server */
445 server_address = optarg;
446 break;
447 case 'p': /* TCP port number */
448 port = optarg;
449 break;
450 case 'm': /* List of MIBS */
451 miblist = optarg;
452 break;
453 case 'n': /* usesnmpgetnext */
454 usesnmpgetnext = TRUE;
455 break;
456 case 'P': /* SNMP protocol version */
457 proto = optarg;
458 break;
459 case 'L': /* security level */
460 seclevel = optarg;
461 break;
462 case 'U': /* security username */
463 secname = optarg;
464 break;
465 case 'a': /* auth protocol */
466 authproto = optarg;
467 break;
468 case 'x': /* priv protocol */
469 privproto = optarg;
470 break;
471 case 'A': /* auth passwd */
472 authpasswd = optarg;
473 break;
474 case 'X': /* priv passwd */
475 privpasswd = optarg;
476 break;
477 case 't': /* timeout period */
478 if (!is_integer (optarg))
479 usage2 (_("Timeout interval must be a positive integer"), optarg);
480 else
481 timeout_interval = atoi (optarg);
482 break;
484 /* Test parameters */
485 case 'c': /* critical threshold */
486 critical_thresholds = optarg;
487 break;
488 case 'w': /* warning threshold */
489 warning_thresholds = optarg;
490 break;
491 case 'e': /* PRELIMINARY - may change */
492 case 'E': /* PRELIMINARY - may change */
493 if (!is_integer (optarg))
494 usage2 (_("Retries interval must be a positive integer"), optarg);
495 else
496 retries = atoi(optarg);
497 break;
498 case 'o': /* object identifier */
499 if ( strspn( optarg, "0123456789.," ) != strlen( optarg ) ) {
500 /*
501 * we have something other than digits, periods and comas,
502 * so we have a mib variable, rather than just an SNMP OID,
503 * so we have to actually read the mib files
504 */
505 needmibs = TRUE;
506 }
507 oids = calloc(MAX_OIDS, sizeof (char *));
508 for (ptr = strtok(optarg, ", "); ptr != NULL && j < MAX_OIDS; ptr = strtok(NULL, ", "), j++) {
509 oids[j] = strdup(ptr);
510 }
511 numoids = j;
512 if (c == 'E' || c == 'e') {
513 jj++;
514 ii++;
515 }
516 if (c == 'E')
517 eval_method[j+1] |= WARN_PRESENT;
518 else if (c == 'e')
519 eval_method[j+1] |= CRIT_PRESENT;
520 break;
521 case 's': /* string or substring */
522 strncpy (string_value, optarg, sizeof (string_value) - 1);
523 string_value[sizeof (string_value) - 1] = 0;
524 eval_method[jj++] = CRIT_STRING;
525 ii++;
526 break;
527 case 'R': /* regex */
528 cflags = REG_ICASE;
529 case 'r': /* regex */
530 cflags |= REG_EXTENDED | REG_NOSUB | REG_NEWLINE;
531 strncpy (regex_expect, optarg, sizeof (regex_expect) - 1);
532 regex_expect[sizeof (regex_expect) - 1] = 0;
533 errcode = regcomp (&preg, regex_expect, cflags);
534 if (errcode != 0) {
535 regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER);
536 printf (_("Could Not Compile Regular Expression"));
537 return ERROR;
538 }
539 eval_method[jj++] = CRIT_REGEX;
540 ii++;
541 break;
543 /* Format */
544 case 'd': /* delimiter */
545 delimiter = strscpy (delimiter, optarg);
546 break;
547 case 'D': /* output-delimiter */
548 output_delim = strscpy (output_delim, optarg);
549 break;
550 case 'l': /* label */
551 label = optarg;
552 nlabels++;
553 if (nlabels >= labels_size) {
554 labels_size += 8;
555 labels = realloc (labels, labels_size);
556 if (labels == NULL)
557 die (STATE_UNKNOWN, _("Could not reallocate labels[%d]"), (int)nlabels);
558 }
559 labels[nlabels - 1] = optarg;
560 ptr = thisarg (optarg);
561 labels[nlabels - 1] = ptr;
562 if (strstr (ptr, "'") == ptr)
563 labels[nlabels - 1] = ptr + 1;
564 while (ptr && (ptr = nextarg (ptr))) {
565 if (nlabels >= labels_size) {
566 labels_size += 8;
567 labels = realloc (labels, labels_size);
568 if (labels == NULL)
569 die (STATE_UNKNOWN, _("Could not reallocate labels\n"));
570 }
571 labels++;
572 ptr = thisarg (ptr);
573 if (strstr (ptr, "'") == ptr)
574 labels[nlabels - 1] = ptr + 1;
575 else
576 labels[nlabels - 1] = ptr;
577 }
578 break;
579 case 'u': /* units */
580 units = optarg;
581 nunits++;
582 if (nunits >= unitv_size) {
583 unitv_size += 8;
584 unitv = realloc (unitv, unitv_size);
585 if (unitv == NULL)
586 die (STATE_UNKNOWN, _("Could not reallocate units [%d]\n"), (int)nunits);
587 }
588 unitv[nunits - 1] = optarg;
589 ptr = thisarg (optarg);
590 unitv[nunits - 1] = ptr;
591 if (strstr (ptr, "'") == ptr)
592 unitv[nunits - 1] = ptr + 1;
593 while (ptr && (ptr = nextarg (ptr))) {
594 if (nunits >= unitv_size) {
595 unitv_size += 8;
596 unitv = realloc (unitv, unitv_size);
597 if (units == NULL)
598 die (STATE_UNKNOWN, _("Could not realloc() units\n"));
599 }
600 nunits++;
601 ptr = thisarg (ptr);
602 if (strstr (ptr, "'") == ptr)
603 unitv[nunits - 1] = ptr + 1;
604 else
605 unitv[nunits - 1] = ptr;
606 }
607 break;
609 }
610 }
612 if (server_address == NULL)
613 server_address = argv[optind];
615 if (community == NULL)
616 community = strdup (DEFAULT_COMMUNITY);
618 return validate_arguments ();
619 }
622 /******************************************************************************
624 @@-
625 <sect3>
626 <title>validate_arguments</title>
628 <para>&PROTO_validate_arguments;</para>
630 <para>Checks to see if the default miblist needs to be loaded. Also verifies
631 the authentication and authorization combinations based on protocol version
632 selected.</para>
634 <para></para>
636 </sect3>
637 -@@
638 ******************************************************************************/
642 int
643 validate_arguments ()
644 {
645 /* check whether to load locally installed MIBS (CPU/disk intensive) */
646 if (miblist == NULL) {
647 if ( needmibs == TRUE ) {
648 miblist = strdup (DEFAULT_MIBLIST);
649 }else{
650 miblist = ""; /* don't read any mib files for numeric oids */
651 }
652 }
654 /* Check server_address is given */
655 if (server_address == NULL)
656 die(STATE_UNKNOWN, _("No host specified\n"));
658 /* Check oid is given */
659 if (numoids == 0)
660 die(STATE_UNKNOWN, _("No OIDs specified\n"));
662 if (proto == NULL)
663 asprintf(&proto, DEFAULT_PROTOCOL);
665 if ((strcmp(proto,"1") == 0) || (strcmp(proto, "2c")==0)) { /* snmpv1 or snmpv2c */
666 numauthpriv = 2;
667 authpriv = calloc (numauthpriv, sizeof (char *));
668 authpriv[0] = strdup ("-c");
669 authpriv[1] = strdup (community);
670 }
671 else if ( strcmp (proto, "3") == 0 ) { /* snmpv3 args */
672 if (seclevel == NULL)
673 asprintf(&seclevel, "noAuthNoPriv");
675 if (strcmp(seclevel, "noAuthNoPriv") == 0) {
676 numauthpriv = 2;
677 authpriv = calloc (numauthpriv, sizeof (char *));
678 authpriv[0] = strdup ("-l");
679 authpriv[1] = strdup ("noAuthNoPriv");
680 } else {
681 if (! ( (strcmp(seclevel, "authNoPriv")==0) || (strcmp(seclevel, "authPriv")==0) ) ) {
682 usage2 (_("Invalid seclevel"), seclevel);
683 }
685 if (authproto == NULL )
686 asprintf(&authproto, DEFAULT_AUTH_PROTOCOL);
688 if (secname == NULL)
689 die(STATE_UNKNOWN, _("Required parameter: %s\n"), "secname");
691 if (authpasswd == NULL)
692 die(STATE_UNKNOWN, _("Required parameter: %s\n"), "authpasswd");
694 if ( strcmp(seclevel, "authNoPriv") == 0 ) {
695 numauthpriv = 8;
696 authpriv = calloc (numauthpriv, sizeof (char *));
697 authpriv[0] = strdup ("-l");
698 authpriv[1] = strdup ("authNoPriv");
699 authpriv[2] = strdup ("-a");
700 authpriv[3] = strdup (authproto);
701 authpriv[4] = strdup ("-u");
702 authpriv[5] = strdup (secname);
703 authpriv[6] = strdup ("-A");
704 authpriv[7] = strdup (authpasswd);
705 } else if ( strcmp(seclevel, "authPriv") == 0 ) {
706 if (privproto == NULL )
707 asprintf(&privproto, DEFAULT_PRIV_PROTOCOL);
709 if (privpasswd == NULL)
710 die(STATE_UNKNOWN, _("Required parameter: %s\n"), "privpasswd");
712 numauthpriv = 12;
713 authpriv = calloc (numauthpriv, sizeof (char *));
714 authpriv[0] = strdup ("-l");
715 authpriv[1] = strdup ("authPriv");
716 authpriv[2] = strdup ("-a");
717 authpriv[3] = strdup (authproto);
718 authpriv[4] = strdup ("-u");
719 authpriv[5] = strdup (secname);
720 authpriv[6] = strdup ("-A");
721 authpriv[7] = strdup (authpasswd);
722 authpriv[8] = strdup ("-x");
723 authpriv[9] = strdup (privproto);
724 authpriv[10] = strdup ("-X");
725 authpriv[11] = strdup (privpasswd);
726 }
727 }
729 }
730 else {
731 usage2 (_("Invalid SNMP version"), proto);
732 }
734 return OK;
735 }
739 /* trim leading whitespace
740 if there is a leading quote, make sure it balances */
742 char *
743 thisarg (char *str)
744 {
745 str += strspn (str, " \t\r\n"); /* trim any leading whitespace */
746 if (strstr (str, "'") == str) { /* handle SIMPLE quoted strings */
747 if (strlen (str) == 1 || !strstr (str + 1, "'"))
748 die (STATE_UNKNOWN, _("Unbalanced quotes\n"));
749 }
750 return str;
751 }
755 /* if there's a leading quote, advance to the trailing quote
756 set the trailing quote to '\x0'
757 if the string continues, advance beyond the comma */
759 char *
760 nextarg (char *str)
761 {
762 if (strstr (str, "'") == str) {
763 str[0] = 0;
764 if (strlen (str) > 1) {
765 str = strstr (str + 1, "'");
766 return (++str);
767 }
768 else {
769 return NULL;
770 }
771 }
772 if (strstr (str, ",") == str) {
773 str[0] = 0;
774 if (strlen (str) > 1) {
775 return (++str);
776 }
777 else {
778 return NULL;
779 }
780 }
781 if ((str = strstr (str, ",")) && strlen (str) > 1) {
782 str[0] = 0;
783 return (++str);
784 }
785 return NULL;
786 }
790 void
791 print_help (void)
792 {
793 print_revision (progname, NP_VERSION);
795 printf (COPYRIGHT, copyright, email);
797 printf ("%s\n", _("Check status of remote machines and obtain system information via SNMP"));
799 printf ("\n\n");
801 print_usage ();
803 printf (_(UT_HELP_VRSN));
804 printf (_(UT_EXTRA_OPTS));
806 printf (_(UT_HOST_PORT), 'p', DEFAULT_PORT);
808 /* SNMP and Authentication Protocol */
809 printf (" %s\n", "-n, --next");
810 printf (" %s\n", _("Use SNMP GETNEXT instead of SNMP GET"));
811 printf (" %s\n", "-P, --protocol=[1|2c|3]");
812 printf (" %s\n", _("SNMP protocol version"));
813 printf (" %s\n", "-L, --seclevel=[noAuthNoPriv|authNoPriv|authPriv]");
814 printf (" %s\n", _("SNMPv3 securityLevel"));
815 printf (" %s\n", "-a, --authproto=[MD5|SHA]");
816 printf (" %s\n", _("SNMPv3 auth proto"));
817 printf (" %s\n", "-x, --privproto=[DES|AES]");
818 printf (" %s\n", _("SNMPv3 priv proto (default DES)"));
820 /* Authentication Tokens*/
821 printf (" %s\n", "-C, --community=STRING");
822 printf (" %s ", _("Optional community string for SNMP communication"));
823 printf ("(%s \"%s\")\n", _("default is") ,DEFAULT_COMMUNITY);
824 printf (" %s\n", "-U, --secname=USERNAME");
825 printf (" %s\n", _("SNMPv3 username"));
826 printf (" %s\n", "-A, --authpassword=PASSWORD");
827 printf (" %s\n", _("SNMPv3 authentication password"));
828 printf (" %s\n", "-X, --privpasswd=PASSWORD");
829 printf (" %s\n", _("SNMPv3 privacy password"));
831 /* OID Stuff */
832 printf (" %s\n", "-o, --oid=OID(s)");
833 printf (" %s\n", _("Object identifier(s) or SNMP variables whose value you wish to query"));
834 printf (" %s\n", "-m, --miblist=STRING");
835 printf (" %s\n", _("List of MIBS to be loaded (default = none if using numeric OIDs or 'ALL'"));
836 printf (" %s\n", _("for symbolic OIDs.)"));
837 printf (" %s\n", "-d, --delimiter=STRING");
838 printf (" %s \"%s\"\n", _("Delimiter to use when parsing returned data. Default is"), DEFAULT_DELIMITER);
839 printf (" %s\n", _("Any data on the right hand side of the delimiter is considered"));
840 printf (" %s\n", _("to be the data that should be used in the evaluation."));
842 /* Tests Against Integers */
843 printf (" %s\n", "-w, --warning=THRESHOLD(s)");
844 printf (" %s\n", _("Warning threshold range(s)"));
845 printf (" %s\n", "-c, --critical=THRESHOLD(s)");
846 printf (" %s\n", _("Critical threshold range(s)"));
848 /* Tests Against Strings */
849 printf (" %s\n", "-s, --string=STRING");
850 printf (" %s\n", _("Return OK state (for that OID) if STRING is an exact match"));
851 printf (" %s\n", "-r, --ereg=REGEX");
852 printf (" %s\n", _("Return OK state (for that OID) if extended regular expression REGEX matches"));
853 printf (" %s\n", "-R, --eregi=REGEX");
854 printf (" %s\n", _("Return OK state (for that OID) if case-insensitive extended REGEX matches"));
855 printf (" %s\n", "-l, --label=STRING");
856 printf (" %s\n", _("Prefix label for output from plugin (default -s 'SNMP')"));
858 /* Output Formatting */
859 printf (" %s\n", "-u, --units=STRING");
860 printf (" %s\n", _("Units label(s) for output data (e.g., 'sec.')."));
861 printf (" %s\n", "-D, --output-delimiter=STRING");
862 printf (" %s\n", _("Separates output on multiple OID requests"));
864 printf (_(UT_TIMEOUT), DEFAULT_SOCKET_TIMEOUT);
865 printf (" %s\n", "-e, --retries=INTEGER");
866 printf (" %s\n", _("Number of retries to be used in the requests"));
868 printf (_(UT_VERBOSE));
870 printf ("\n");
871 printf ("%s\n", _("This plugin uses the 'snmpget' command included with the NET-SNMP package."));
872 printf ("%s\n", _("if you don't have the package installed, you will need to download it from"));
873 printf ("%s\n", _("http://net-snmp.sourceforge.net before you can use this plugin."));
875 printf ("\n");
876 printf ("%s\n", _("Notes:"));
877 printf (" %s\n", _("- Multiple OIDs may be indicated by a comma- or space-delimited list (lists with"));
878 printf (" %s\n", _("internal spaces must be quoted) [max 8 OIDs]"));
880 printf(" -%s", _(UT_THRESHOLDS_NOTES));
882 printf (" %s\n", _("- When checking multiple OIDs, separate ranges by commas like '-w 1:10,1:,:20'"));
883 printf (" %s\n", _("- Note that only one string and one regex may be checked at present"));
884 printf (" %s\n", _("- All evaluation methods other than PR, STR, and SUBSTR expect that the value"));
885 printf (" %s\n", _("returned from the SNMP query is an unsigned integer."));
886 #ifdef NP_EXTRA_OPTS
887 printf (" -%s", _(UT_EXTRA_OPTS_NOTES));
888 #endif
890 printf (_(UT_SUPPORT));
891 }
895 void
896 print_usage (void)
897 {
898 printf (_("Usage:"));
899 printf ("%s -H <ip_address> -o <OID> [-w warn_range] [-c crit_range]\n",progname);
900 printf ("[-C community] [-s string] [-r regex] [-R regexi] [-t timeout] [-e retries]\n");
901 printf ("[-l label] [-u units] [-p port-number] [-d delimiter] [-D output-delimiter]\n");
902 printf ("[-m miblist] [-P snmp version] [-L seclevel] [-U secname] [-a authproto]\n");
903 printf ("[-A authpasswd] [-x privproto] [-X privpasswd]\n");
904 }