check_snmp: Make use of standard threshold functions
[monitoring-plugins.git] / plugins / check_snmp.c
blobdff5bccd06bd5b11995bc609adafd6f04774d0f5
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
12 * Check status of remote machines and obtain system information via SNMP
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.
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.
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/>.
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 = FALSE;
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;
118 main (int argc, char **argv)
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);
176 if (c) {
177 th_crit=strchr(th_crit, ',');
178 if (th_crit) th_crit++;
179 free(c);
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);
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];
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, 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]);
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
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]);
240 } else {
241 printf(_("External command error with no output (return code: %d)\n"), return_code);
243 exit (STATE_UNKNOWN);
246 if (verbose) {
247 for (i = 0; i < chld_out.lines; i++) {
248 printf ("%s\n", chld_out.line[i]);
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);
259 /* We strip out the datatype indicator for PHBs */
261 /* Clean up type array - Sol10 does not necessarily zero it out */
262 bzero(type, sizeof(type));
264 if (strstr (response, "Gauge: "))
265 show = strstr (response, "Gauge: ") + 7;
266 else if (strstr (response, "Gauge32: "))
267 show = strstr (response, "Gauge32: ") + 9;
268 else if (strstr (response, "Counter32: ")) {
269 show = strstr (response, "Counter32: ") + 11;
270 strcpy(type, "c");
272 else if (strstr (response, "Counter64: ")) {
273 show = strstr (response, "Counter64: ") + 11;
274 strcpy(type, "c");
276 else if (strstr (response, "INTEGER: "))
277 show = strstr (response, "INTEGER: ") + 9;
278 else if (strstr (response, "STRING: ")) {
279 show = strstr (response, "STRING: ") + 8;
280 conv = "%.10g";
282 else if (strstr (response, "Timeticks: "))
283 show = strstr (response, "Timeticks: ");
284 else
285 show = response;
287 iresult = STATE_DEPENDENT;
289 /* Process this block for integer comparisons */
290 if (thlds[i]->warning || thlds[i]->critical) {
291 ptr = strpbrk (show, "0123456789");
292 if (ptr == NULL)
293 die (STATE_UNKNOWN,_("No valid data returned"));
294 response_value[i] = strtod (ptr, NULL);
295 iresult = get_status(response_value[i], thlds[i]);
296 asprintf (&show, conv, response_value[i]);
299 /* Process this block for string matching */
300 else if (eval_method[i] & CRIT_STRING) {
301 if (strcmp (show, string_value))
302 iresult = STATE_CRITICAL;
303 else
304 iresult = STATE_OK;
307 /* Process this block for regex matching */
308 else if (eval_method[i] & CRIT_REGEX) {
309 excode = regexec (&preg, response, 10, pmatch, eflags);
310 if (excode == 0) {
311 iresult = STATE_OK;
313 else if (excode != REG_NOMATCH) {
314 regerror (excode, &preg, errbuf, MAX_INPUT_BUFFER);
315 printf (_("Execute Error: %s\n"), errbuf);
316 exit (STATE_CRITICAL);
318 else {
319 iresult = STATE_CRITICAL;
323 /* Process this block for existence-nonexistence checks */
324 else {
325 if (eval_method[i] & CRIT_PRESENT)
326 iresult = STATE_CRITICAL;
327 else if (eval_method[i] & WARN_PRESENT)
328 iresult = STATE_WARNING;
329 else if (response && iresult == STATE_DEPENDENT)
330 iresult = STATE_OK;
333 /* Result is the worst outcome of all the OIDs tested */
334 result = max_state (result, iresult);
336 /* Prepend a label for this OID if there is one */
337 if (nlabels > (size_t)1 && (size_t)i < nlabels && labels[i] != NULL)
338 asprintf (&outbuff, "%s%s%s %s%s%s", outbuff,
339 (i == 0) ? " " : output_delim,
340 labels[i], mark (iresult), show, mark (iresult));
341 else
342 asprintf (&outbuff, "%s%s%s%s%s", outbuff, (i == 0) ? " " : output_delim,
343 mark (iresult), show, mark (iresult));
345 /* Append a unit string for this OID if there is one */
346 if (nunits > (size_t)0 && (size_t)i < nunits && unitv[i] != NULL)
347 asprintf (&outbuff, "%s %s", outbuff, unitv[i]);
349 if (is_numeric(show)) {
350 strncat(perfstr, oidname, sizeof(perfstr)-strlen(perfstr)-1);
351 strncat(perfstr, "=", sizeof(perfstr)-strlen(perfstr)-1);
352 strncat(perfstr, show, sizeof(perfstr)-strlen(perfstr)-1);
354 if (type)
355 strncat(perfstr, type, sizeof(perfstr)-strlen(perfstr)-1);
356 strncat(perfstr, " ", sizeof(perfstr)-strlen(perfstr)-1);
360 printf ("%s %s -%s %s \n", label, state_text (result), outbuff, perfstr);
362 return result;
367 /* process command-line arguments */
369 process_arguments (int argc, char **argv)
371 char *ptr;
372 int c = 1;
373 int j = 0, jj = 0, ii = 0;
375 int option = 0;
376 static struct option longopts[] = {
377 STD_LONG_OPTS,
378 {"community", required_argument, 0, 'C'},
379 {"oid", required_argument, 0, 'o'},
380 {"object", required_argument, 0, 'o'},
381 {"delimiter", required_argument, 0, 'd'},
382 {"output-delimiter", required_argument, 0, 'D'},
383 {"string", required_argument, 0, 's'},
384 {"timeout", required_argument, 0, 't'},
385 {"regex", required_argument, 0, 'r'},
386 {"ereg", required_argument, 0, 'r'},
387 {"eregi", required_argument, 0, 'R'},
388 {"label", required_argument, 0, 'l'},
389 {"units", required_argument, 0, 'u'},
390 {"port", required_argument, 0, 'p'},
391 {"retries", required_argument, 0, 'e'},
392 {"miblist", required_argument, 0, 'm'},
393 {"protocol", required_argument, 0, 'P'},
394 {"seclevel", required_argument, 0, 'L'},
395 {"secname", required_argument, 0, 'U'},
396 {"authproto", required_argument, 0, 'a'},
397 {"privproto", required_argument, 0, 'x'},
398 {"authpasswd", required_argument, 0, 'A'},
399 {"privpasswd", required_argument, 0, 'X'},
400 {"next", no_argument, 0, 'n'},
401 {0, 0, 0, 0}
404 if (argc < 2)
405 return ERROR;
407 /* reverse compatibility for very old non-POSIX usage forms */
408 for (c = 1; c < argc; c++) {
409 if (strcmp ("-to", argv[c]) == 0)
410 strcpy (argv[c], "-t");
411 if (strcmp ("-wv", argv[c]) == 0)
412 strcpy (argv[c], "-w");
413 if (strcmp ("-cv", argv[c]) == 0)
414 strcpy (argv[c], "-c");
417 while (1) {
418 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:",
419 longopts, &option);
421 if (c == -1 || c == EOF)
422 break;
424 switch (c) {
425 case '?': /* usage */
426 usage5 ();
427 case 'h': /* help */
428 print_help ();
429 exit (STATE_OK);
430 case 'V': /* version */
431 print_revision (progname, NP_VERSION);
432 exit (STATE_OK);
433 case 'v': /* verbose */
434 verbose = TRUE;
435 break;
437 /* Connection info */
438 case 'C': /* group or community */
439 community = optarg;
440 break;
441 case 'H': /* Host or server */
442 server_address = optarg;
443 break;
444 case 'p': /* TCP port number */
445 port = optarg;
446 break;
447 case 'm': /* List of MIBS */
448 miblist = optarg;
449 break;
450 case 'n': /* usesnmpgetnext */
451 usesnmpgetnext = TRUE;
452 break;
453 case 'P': /* SNMP protocol version */
454 proto = optarg;
455 break;
456 case 'L': /* security level */
457 seclevel = optarg;
458 break;
459 case 'U': /* security username */
460 secname = optarg;
461 break;
462 case 'a': /* auth protocol */
463 authproto = optarg;
464 break;
465 case 'x': /* priv protocol */
466 privproto = optarg;
467 break;
468 case 'A': /* auth passwd */
469 authpasswd = optarg;
470 break;
471 case 'X': /* priv passwd */
472 privpasswd = optarg;
473 break;
474 case 't': /* timeout period */
475 if (!is_integer (optarg))
476 usage2 (_("Timeout interval must be a positive integer"), optarg);
477 else
478 timeout_interval = atoi (optarg);
479 break;
481 /* Test parameters */
482 case 'c': /* critical threshold */
483 critical_thresholds = optarg;
484 break;
485 case 'w': /* warning threshold */
486 warning_thresholds = optarg;
487 break;
488 case 'e': /* PRELIMINARY - may change */
489 case 'E': /* PRELIMINARY - may change */
490 if (!is_integer (optarg))
491 usage2 (_("Retries interval must be a positive integer"), optarg);
492 else
493 retries = atoi(optarg);
494 break;
495 case 'o': /* object identifier */
496 if ( strspn( optarg, "0123456789.," ) != strlen( optarg ) ) {
498 * we have something other than digits, periods and comas,
499 * so we have a mib variable, rather than just an SNMP OID,
500 * so we have to actually read the mib files
502 needmibs = TRUE;
504 oids = calloc(MAX_OIDS, sizeof (char *));
505 for (ptr = strtok(optarg, ", "); ptr != NULL && j < MAX_OIDS; ptr = strtok(NULL, ", "), j++) {
506 oids[j] = strdup(ptr);
508 numoids = j;
509 if (c == 'E' || c == 'e') {
510 jj++;
511 ii++;
513 if (c == 'E')
514 eval_method[j+1] |= WARN_PRESENT;
515 else if (c == 'e')
516 eval_method[j+1] |= CRIT_PRESENT;
517 break;
518 case 's': /* string or substring */
519 strncpy (string_value, optarg, sizeof (string_value) - 1);
520 string_value[sizeof (string_value) - 1] = 0;
521 eval_method[jj++] = CRIT_STRING;
522 ii++;
523 break;
524 case 'R': /* regex */
525 cflags = REG_ICASE;
526 case 'r': /* regex */
527 cflags |= REG_EXTENDED | REG_NOSUB | REG_NEWLINE;
528 strncpy (regex_expect, optarg, sizeof (regex_expect) - 1);
529 regex_expect[sizeof (regex_expect) - 1] = 0;
530 errcode = regcomp (&preg, regex_expect, cflags);
531 if (errcode != 0) {
532 regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER);
533 printf (_("Could Not Compile Regular Expression"));
534 return ERROR;
536 eval_method[jj++] = CRIT_REGEX;
537 ii++;
538 break;
540 /* Format */
541 case 'd': /* delimiter */
542 delimiter = strscpy (delimiter, optarg);
543 break;
544 case 'D': /* output-delimiter */
545 output_delim = strscpy (output_delim, optarg);
546 break;
547 case 'l': /* label */
548 label = optarg;
549 nlabels++;
550 if (nlabels >= labels_size) {
551 labels_size += 8;
552 labels = realloc (labels, labels_size);
553 if (labels == NULL)
554 die (STATE_UNKNOWN, _("Could not reallocate labels[%d]"), (int)nlabels);
556 labels[nlabels - 1] = optarg;
557 ptr = thisarg (optarg);
558 labels[nlabels - 1] = ptr;
559 if (strstr (ptr, "'") == ptr)
560 labels[nlabels - 1] = ptr + 1;
561 while (ptr && (ptr = nextarg (ptr))) {
562 if (nlabels >= labels_size) {
563 labels_size += 8;
564 labels = realloc (labels, labels_size);
565 if (labels == NULL)
566 die (STATE_UNKNOWN, _("Could not reallocate labels\n"));
568 labels++;
569 ptr = thisarg (ptr);
570 if (strstr (ptr, "'") == ptr)
571 labels[nlabels - 1] = ptr + 1;
572 else
573 labels[nlabels - 1] = ptr;
575 break;
576 case 'u': /* units */
577 units = optarg;
578 nunits++;
579 if (nunits >= unitv_size) {
580 unitv_size += 8;
581 unitv = realloc (unitv, unitv_size);
582 if (unitv == NULL)
583 die (STATE_UNKNOWN, _("Could not reallocate units [%d]\n"), (int)nunits);
585 unitv[nunits - 1] = optarg;
586 ptr = thisarg (optarg);
587 unitv[nunits - 1] = ptr;
588 if (strstr (ptr, "'") == ptr)
589 unitv[nunits - 1] = ptr + 1;
590 while (ptr && (ptr = nextarg (ptr))) {
591 if (nunits >= unitv_size) {
592 unitv_size += 8;
593 unitv = realloc (unitv, unitv_size);
594 if (units == NULL)
595 die (STATE_UNKNOWN, _("Could not realloc() units\n"));
597 nunits++;
598 ptr = thisarg (ptr);
599 if (strstr (ptr, "'") == ptr)
600 unitv[nunits - 1] = ptr + 1;
601 else
602 unitv[nunits - 1] = ptr;
604 break;
609 if (server_address == NULL)
610 server_address = argv[optind];
612 if (community == NULL)
613 community = strdup (DEFAULT_COMMUNITY);
615 return validate_arguments ();
619 /******************************************************************************
622 <sect3>
623 <title>validate_arguments</title>
625 <para>&PROTO_validate_arguments;</para>
627 <para>Checks to see if the default miblist needs to be loaded. Also verifies
628 the authentication and authorization combinations based on protocol version
629 selected.</para>
631 <para></para>
633 </sect3>
635 ******************************************************************************/
640 validate_arguments ()
642 /* check whether to load locally installed MIBS (CPU/disk intensive) */
643 if (miblist == NULL) {
644 if ( needmibs == TRUE ) {
645 miblist = strdup (DEFAULT_MIBLIST);
646 }else{
647 miblist = "''"; /* don't read any mib files for numeric oids */
651 /* Check server_address is given */
652 if (server_address == NULL)
653 die(STATE_UNKNOWN, _("No host specified\n"));
655 /* Check oid is given */
656 if (numoids == 0)
657 die(STATE_UNKNOWN, _("No OIDs specified\n"));
659 if (proto == NULL)
660 asprintf(&proto, DEFAULT_PROTOCOL);
662 if ((strcmp(proto,"1") == 0) || (strcmp(proto, "2c")==0)) { /* snmpv1 or snmpv2c */
663 numauthpriv = 2;
664 authpriv = calloc (numauthpriv, sizeof (char *));
665 authpriv[0] = strdup ("-c");
666 authpriv[1] = strdup (community);
668 else if ( strcmp (proto, "3") == 0 ) { /* snmpv3 args */
669 if (seclevel == NULL)
670 asprintf(&seclevel, "noAuthNoPriv");
672 if (strcmp(seclevel, "noAuthNoPriv") == 0) {
673 numauthpriv = 2;
674 authpriv = calloc (numauthpriv, sizeof (char *));
675 authpriv[0] = strdup ("-l");
676 authpriv[1] = strdup ("noAuthNoPriv");
677 } else {
678 if (! ( (strcmp(seclevel, "authNoPriv")==0) || (strcmp(seclevel, "authPriv")==0) ) ) {
679 usage2 (_("Invalid seclevel"), seclevel);
682 if (authproto == NULL )
683 asprintf(&authproto, DEFAULT_AUTH_PROTOCOL);
685 if (secname == NULL)
686 die(STATE_UNKNOWN, _("Required parameter: %s\n"), "secname");
688 if (authpasswd == NULL)
689 die(STATE_UNKNOWN, _("Required parameter: %s\n"), "authpasswd");
691 if ( strcmp(seclevel, "authNoPriv") == 0 ) {
692 numauthpriv = 8;
693 authpriv = calloc (numauthpriv, sizeof (char *));
694 authpriv[0] = strdup ("-l");
695 authpriv[1] = strdup ("authNoPriv");
696 authpriv[2] = strdup ("-a");
697 authpriv[3] = strdup (authproto);
698 authpriv[4] = strdup ("-u");
699 authpriv[5] = strdup (secname);
700 authpriv[6] = strdup ("-A");
701 authpriv[7] = strdup (authpasswd);
702 } else if ( strcmp(seclevel, "authPriv") == 0 ) {
703 if (privproto == NULL )
704 asprintf(&privproto, DEFAULT_PRIV_PROTOCOL);
706 if (privpasswd == NULL)
707 die(STATE_UNKNOWN, _("Required parameter: %s\n"), "privpasswd");
709 numauthpriv = 12;
710 authpriv = calloc (numauthpriv, sizeof (char *));
711 authpriv[0] = strdup ("-l");
712 authpriv[1] = strdup ("authPriv");
713 authpriv[2] = strdup ("-a");
714 authpriv[3] = strdup (authproto);
715 authpriv[4] = strdup ("-u");
716 authpriv[5] = strdup (secname);
717 authpriv[6] = strdup ("-A");
718 authpriv[7] = strdup (authpasswd);
719 authpriv[8] = strdup ("-x");
720 authpriv[9] = strdup (privproto);
721 authpriv[10] = strdup ("-X");
722 authpriv[11] = strdup (privpasswd);
727 else {
728 usage2 (_("Invalid SNMP version"), proto);
731 return OK;
736 /* trim leading whitespace
737 if there is a leading quote, make sure it balances */
739 char *
740 thisarg (char *str)
742 str += strspn (str, " \t\r\n"); /* trim any leading whitespace */
743 if (strstr (str, "'") == str) { /* handle SIMPLE quoted strings */
744 if (strlen (str) == 1 || !strstr (str + 1, "'"))
745 die (STATE_UNKNOWN, _("Unbalanced quotes\n"));
747 return str;
752 /* if there's a leading quote, advance to the trailing quote
753 set the trailing quote to '\x0'
754 if the string continues, advance beyond the comma */
756 char *
757 nextarg (char *str)
759 if (strstr (str, "'") == str) {
760 str[0] = 0;
761 if (strlen (str) > 1) {
762 str = strstr (str + 1, "'");
763 return (++str);
765 else {
766 return NULL;
769 if (strstr (str, ",") == str) {
770 str[0] = 0;
771 if (strlen (str) > 1) {
772 return (++str);
774 else {
775 return NULL;
778 if ((str = strstr (str, ",")) && strlen (str) > 1) {
779 str[0] = 0;
780 return (++str);
782 return NULL;
787 void
788 print_help (void)
790 print_revision (progname, NP_VERSION);
792 printf (COPYRIGHT, copyright, email);
794 printf ("%s\n", _("Check status of remote machines and obtain system information via SNMP"));
796 printf ("\n\n");
798 print_usage ();
800 printf (_(UT_HELP_VRSN));
801 printf (_(UT_EXTRA_OPTS));
803 printf (_(UT_HOST_PORT), 'p', DEFAULT_PORT);
805 /* SNMP and Authentication Protocol */
806 printf (" %s\n", "-n, --next");
807 printf (" %s\n", _("Use SNMP GETNEXT instead of SNMP GET"));
808 printf (" %s\n", "-P, --protocol=[1|2c|3]");
809 printf (" %s\n", _("SNMP protocol version"));
810 printf (" %s\n", "-L, --seclevel=[noAuthNoPriv|authNoPriv|authPriv]");
811 printf (" %s\n", _("SNMPv3 securityLevel"));
812 printf (" %s\n", "-a, --authproto=[MD5|SHA]");
813 printf (" %s\n", _("SNMPv3 auth proto"));
814 printf (" %s\n", "-x, --privproto=[DES|AES]");
815 printf (" %s\n", _("SNMPv3 priv proto (default DES)"));
817 /* Authentication Tokens*/
818 printf (" %s\n", "-C, --community=STRING");
819 printf (" %s ", _("Optional community string for SNMP communication"));
820 printf ("(%s \"%s\")\n", _("default is") ,DEFAULT_COMMUNITY);
821 printf (" %s\n", "-U, --secname=USERNAME");
822 printf (" %s\n", _("SNMPv3 username"));
823 printf (" %s\n", "-A, --authpassword=PASSWORD");
824 printf (" %s\n", _("SNMPv3 authentication password"));
825 printf (" %s\n", "-X, --privpasswd=PASSWORD");
826 printf (" %s\n", _("SNMPv3 privacy password"));
828 /* OID Stuff */
829 printf (" %s\n", "-o, --oid=OID(s)");
830 printf (" %s\n", _("Object identifier(s) or SNMP variables whose value you wish to query"));
831 printf (" %s\n", "-m, --miblist=STRING");
832 printf (" %s\n", _("List of MIBS to be loaded (default = none if using numeric OIDs or 'ALL'"));
833 printf (" %s\n", _("for symbolic OIDs.)"));
834 printf (" %s\n", "-d, --delimiter=STRING");
835 printf (" %s \"%s\"\n", _("Delimiter to use when parsing returned data. Default is"), DEFAULT_DELIMITER);
836 printf (" %s\n", _("Any data on the right hand side of the delimiter is considered"));
837 printf (" %s\n", _("to be the data that should be used in the evaluation."));
839 /* Tests Against Integers */
840 printf (" %s\n", "-w, --warning=THRESHOLD(s)");
841 printf (" %s\n", _("Warning threshold range(s)"));
842 printf (" %s\n", "-c, --critical=THRESHOLD(s)");
843 printf (" %s\n", _("Critical threshold range(s)"));
845 /* Tests Against Strings */
846 printf (" %s\n", "-s, --string=STRING");
847 printf (" %s\n", _("Return OK state (for that OID) if STRING is an exact match"));
848 printf (" %s\n", "-r, --ereg=REGEX");
849 printf (" %s\n", _("Return OK state (for that OID) if extended regular expression REGEX matches"));
850 printf (" %s\n", "-R, --eregi=REGEX");
851 printf (" %s\n", _("Return OK state (for that OID) if case-insensitive extended REGEX matches"));
852 printf (" %s\n", "-l, --label=STRING");
853 printf (" %s\n", _("Prefix label for output from plugin (default -s 'SNMP')"));
855 /* Output Formatting */
856 printf (" %s\n", "-u, --units=STRING");
857 printf (" %s\n", _("Units label(s) for output data (e.g., 'sec.')."));
858 printf (" %s\n", "-D, --output-delimiter=STRING");
859 printf (" %s\n", _("Separates output on multiple OID requests"));
861 printf (_(UT_TIMEOUT), DEFAULT_SOCKET_TIMEOUT);
862 printf (" %s\n", "-e, --retries=INTEGER");
863 printf (" %s\n", _("Number of retries to be used in the requests"));
865 printf (_(UT_VERBOSE));
867 printf ("\n");
868 printf ("%s\n", _("This plugin uses the 'snmpget' command included with the NET-SNMP package."));
869 printf ("%s\n", _("if you don't have the package installed, you will need to download it from"));
870 printf ("%s\n", _("http://net-snmp.sourceforge.net before you can use this plugin."));
872 printf ("\n");
873 printf ("%s\n", _("Notes:"));
874 printf (" %s\n", _("- Multiple OIDs may be indicated by a comma- or space-delimited list (lists with"));
875 printf (" %s\n", _("internal spaces must be quoted) [max 8 OIDs]"));
877 printf(" -%s", _(UT_THRESHOLDS_NOTES));
879 printf (" %s\n", _("- When checking multiple OIDs, separate ranges by commas like '-w 1:10,1:,:20'"));
880 printf (" %s\n", _("- Note that only one string and one regex may be checked at present"));
881 printf (" %s\n", _("- All evaluation methods other than PR, STR, and SUBSTR expect that the value"));
882 printf (" %s\n", _("returned from the SNMP query is an unsigned integer."));
883 #ifdef NP_EXTRA_OPTS
884 printf (" -%s", _(UT_EXTRA_OPTS_NOTES));
885 #endif
887 printf (_(UT_SUPPORT));
892 void
893 print_usage (void)
895 printf (_("Usage:"));
896 printf ("%s -H <ip_address> -o <OID> [-w warn_range] [-c crit_range]\n",progname);
897 printf ("[-C community] [-s string] [-r regex] [-R regexi] [-t timeout] [-e retries]\n");
898 printf ("[-l label] [-u units] [-p port-number] [-d delimiter] [-D output-delimiter]\n");
899 printf ("[-m miblist] [-P snmp version] [-L seclevel] [-U secname] [-a authproto]\n");
900 printf ("[-A authpasswd] [-x privproto] [-X privpasswd]\n");