summaryrefslogtreecommitdiffstats
path: root/web/attachments/116583-check_snmp.c
diff options
context:
space:
mode:
Diffstat (limited to 'web/attachments/116583-check_snmp.c')
-rw-r--r--web/attachments/116583-check_snmp.c963
1 files changed, 963 insertions, 0 deletions
diff --git a/web/attachments/116583-check_snmp.c b/web/attachments/116583-check_snmp.c
new file mode 100644
index 0000000..e2695e1
--- /dev/null
+++ b/web/attachments/116583-check_snmp.c
@@ -0,0 +1,963 @@
1/******************************************************************************
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2 of the License, or
6 (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16
17 $Id: check_snmp.c,v 1.52 2004/12/30 00:41:39 opensides Exp $
18
19******************************************************************************/
20
21const char *progname = "check_snmp";
22const char *revision = "$Revision: 1.52 $";
23const char *copyright = "1999-2004";
24const char *email = "nagiosplug-devel@lists.sourceforge.net";
25
26#include "common.h"
27#include "utils.h"
28#include "popen.h"
29
30#define DEFAULT_COMMUNITY "public"
31#define DEFAULT_PORT "161"
32#define DEFAULT_MIBLIST "ALL"
33#define DEFAULT_PROTOCOL "1"
34#define DEFAULT_TIMEOUT 1
35#define DEFAULT_RETRIES 5
36#define DEFAULT_AUTH_PROTOCOL "MD5"
37#define DEFAULT_DELIMITER "="
38#define DEFAULT_OUTPUT_DELIMITER " "
39
40#define mark(a) ((a)!=0?"*":"")
41
42#define CHECK_UNDEF 0
43#define CRIT_PRESENT 1
44#define CRIT_STRING 2
45#define CRIT_REGEX 4
46#define CRIT_GT 8
47#define CRIT_LT 16
48#define CRIT_GE 32
49#define CRIT_LE 64
50#define CRIT_EQ 128
51#define CRIT_NE 256
52#define CRIT_RANGE 512
53#define WARN_PRESENT 1024
54#define WARN_STRING 2048
55#define WARN_REGEX 4096
56#define WARN_GT 8192
57#define WARN_LT 16384
58#define WARN_GE 32768
59#define WARN_LE 65536
60#define WARN_EQ 131072
61#define WARN_NE 262144
62#define WARN_RANGE 524288
63
64#define MAX_OIDS 8
65#define MAX_DELIM_LENGTH 8
66
67int process_arguments (int, char **);
68int validate_arguments (void);
69char *clarify_message (char *);
70int check_num (int);
71int lu_getll (unsigned long *, char *);
72int lu_getul (unsigned long *, char *);
73char *thisarg (char *str);
74char *nextarg (char *str);
75void print_usage (void);
76void print_help (void);
77
78#ifdef HAVE_REGEX_H
79#include <regex.h>
80char regex_expect[MAX_INPUT_BUFFER] = "";
81regex_t preg;
82regmatch_t pmatch[10];
83char timestamp[10] = "";
84char errbuf[MAX_INPUT_BUFFER];
85int cflags = REG_EXTENDED | REG_NOSUB | REG_NEWLINE;
86int eflags = 0;
87int errcode, excode;
88#endif
89
90char *server_address = NULL;
91char *community = NULL;
92char *authpriv = NULL;
93char *proto = NULL;
94char *seclevel = NULL;
95char *secname = NULL;
96char *authproto = NULL;
97char *authpasswd = NULL;
98char *privpasswd = NULL;
99char *oid;
100char *label;
101char *units;
102char *port;
103char string_value[MAX_INPUT_BUFFER] = "";
104char **labels = NULL;
105char **unitv = NULL;
106size_t nlabels = 0;
107size_t labels_size = 8;
108size_t nunits = 0;
109size_t unitv_size = 8;
110int verbose = FALSE;
111unsigned long lower_warn_lim[MAX_OIDS];
112unsigned long upper_warn_lim[MAX_OIDS];
113unsigned long lower_crit_lim[MAX_OIDS];
114unsigned long upper_crit_lim[MAX_OIDS];
115unsigned long response_value[MAX_OIDS];
116int check_warning_value = FALSE;
117int check_critical_value = FALSE;
118int retries = 0;
119unsigned long eval_method[MAX_OIDS];
120char *delimiter;
121char *output_delim;
122char *miblist;
123
124int
125main (int argc, char **argv)
126{
127 int i = 0;
128 int iresult = STATE_UNKNOWN;
129 int found = 0;
130 int result = STATE_DEPENDENT;
131 char input_buffer[MAX_INPUT_BUFFER];
132 char *command_line = NULL;
133 char *response = NULL;
134 char *outbuff;
135 char *output;
136 char *ptr = NULL;
137 char *p2 = NULL;
138 char *show = NULL;
139
140 setlocale (LC_ALL, "");
141 bindtextdomain (PACKAGE, LOCALEDIR);
142 textdomain (PACKAGE);
143
144 labels = malloc (labels_size);
145 unitv = malloc (unitv_size);
146 for (i = 0; i < MAX_OIDS; i++)
147 eval_method[i] = CHECK_UNDEF;
148 i = 0;
149
150 oid = strdup ("");
151 label = strdup ("SNMP");
152 units = strdup ("");
153 port = strdup (DEFAULT_PORT);
154 outbuff = strdup ("");
155 output = strdup ("");
156 delimiter = strdup (DEFAULT_DELIMITER);
157 output_delim = strdup (DEFAULT_OUTPUT_DELIMITER);
158 miblist = strdup (DEFAULT_MIBLIST);
159 timeout_interval = DEFAULT_TIMEOUT;
160 retries = DEFAULT_RETRIES;
161
162 if (process_arguments (argc, argv) == ERROR)
163 usage4 (_("Could not parse arguments"));
164
165 /* create the command line to execute */
166 asprintf (&command_line, "%s -t %d -r %d -m %s -v %s %s %s:%s %s",
167 PATH_TO_SNMPGET, timeout_interval, retries, miblist, proto,
168 authpriv, server_address, port, oid);
169 if (verbose)
170 printf ("%s\n", command_line);
171
172 /* run the command */
173 child_process = spopen (command_line);
174 if (child_process == NULL) {
175 printf (_("Could not open pipe: %s\n"), command_line);
176 exit (STATE_UNKNOWN);
177 }
178
179 child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r");
180 if (child_stderr == NULL) {
181 printf (_("Could not open stderr for %s\n"), command_line);
182 }
183
184 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process))
185 asprintf (&output, "%s%s", output, input_buffer);
186
187 if (verbose)
188 printf ("%s\n", output);
189
190 ptr = output;
191
192 while (ptr) {
193
194 ptr = strstr (ptr, delimiter);
195 if (ptr == NULL)
196 break;
197
198 ptr += strlen (delimiter);
199 ptr += strspn (ptr, " ");
200
201 found++;
202
203 if (ptr[0] == '"') {
204 ptr++;
205 response = strpcpy (response, ptr, "\"");
206 ptr = strpbrk (ptr, "\"");
207 ptr += strspn (ptr, "\"\n");
208 }
209 else {
210 response = strpcpy (response, ptr, "\n");
211 ptr = strpbrk (ptr, "\n");
212 ptr += strspn (ptr, "\n");
213 while
214 (strstr (ptr, delimiter) &&
215 strstr (ptr, "\n") && strstr (ptr, "\n") < strstr (ptr, delimiter)) {
216 response = strpcat (response, ptr, "\n");
217 ptr = strpbrk (ptr, "\n");
218 }
219 if (ptr && strstr (ptr, delimiter) == NULL) {
220 asprintf (&response, "%s%s", response, ptr);
221 ptr = NULL;
222 }
223 }
224
225 /* We strip out the datatype indicator for PHBs */
226 if (strstr (response, "Gauge: "))
227 show = strstr (response, "Gauge: ") + 7;
228 else if (strstr (response, "Gauge32: "))
229 show = strstr (response, "Gauge32: ") + 9;
230 else if (strstr (response, "Counter32: "))
231 show = strstr (response, "Counter32: ") + 11;
232 else if (strstr (response, "INTEGER: "))
233 show = strstr (response, "INTEGER: ") + 9;
234 else if (strstr (response, "STRING: "))
235 show = strstr (response, "STRING: ") + 8;
236 else
237 show = response;
238 p2 = show;
239
240 iresult = STATE_DEPENDENT;
241
242 /* Process this block for integer comparisons */
243 if (eval_method[i] & CRIT_GT ||
244 eval_method[i] & CRIT_LT ||
245 eval_method[i] & CRIT_GE ||
246 eval_method[i] & CRIT_LE ||
247 eval_method[i] & CRIT_EQ ||
248 eval_method[i] & CRIT_NE ||
249 eval_method[i] & WARN_GT ||
250 eval_method[i] & WARN_LT ||
251 eval_method[i] & WARN_GE ||
252 eval_method[i] & WARN_LE ||
253 eval_method[i] & WARN_EQ ||
254 eval_method[i] & WARN_NE) {
255 p2 = strpbrk (p2, "0123456789");
256 if (p2 == NULL)
257 die (STATE_UNKNOWN,_("No valid data returned"));
258 response_value[i] = strtoul (p2, NULL, 10);
259 iresult = check_num (i);
260 asprintf (&show, "%lu", response_value[i]);
261 }
262
263 /* Process this block for string matching */
264 else if (eval_method[i] & CRIT_STRING) {
265 if (strcmp (show, string_value))
266 iresult = STATE_CRITICAL;
267 else
268 iresult = STATE_OK;
269 }
270
271 /* Process this block for regex matching */
272 else if (eval_method[i] & CRIT_REGEX) {
273#ifdef HAVE_REGEX_H
274 excode = regexec (&preg, response, 10, pmatch, eflags);
275 if (excode == 0) {
276 iresult = STATE_OK;
277 }
278 else if (excode != REG_NOMATCH) {
279 regerror (excode, &preg, errbuf, MAX_INPUT_BUFFER);
280 printf (_("Execute Error: %s\n"), errbuf);
281 exit (STATE_CRITICAL);
282 }
283 else {
284 iresult = STATE_CRITICAL;
285 }
286#else
287 printf (_("Call for regex which was not a compiled option"));
288 exit (STATE_UNKNOWN);
289#endif
290 }
291
292 /* Process this block for existence-nonexistence checks */
293 else {
294 if (eval_method[i] & CRIT_PRESENT)
295 iresult = STATE_CRITICAL;
296 else if (eval_method[i] & WARN_PRESENT)
297 iresult = STATE_WARNING;
298 else if (response && iresult == STATE_DEPENDENT)
299 iresult = STATE_OK;
300 }
301
302 /* Result is the worst outcome of all the OIDs tested */
303 result = max_state (result, iresult);
304
305 /* Prepend a label for this OID if there is one */
306 if (nlabels > (size_t)1 && (size_t)i < nlabels && labels[i] != NULL)
307 asprintf (&outbuff, "%s%s%s %s%s%s", outbuff,
308 (i == 0) ? " " : output_delim,
309 labels[i], mark (iresult), show, mark (iresult));
310 else
311 asprintf (&outbuff, "%s%s%s%s%s", outbuff, (i == 0) ? " " : output_delim,
312 mark (iresult), show, mark (iresult));
313
314 /* Append a unit string for this OID if there is one */
315 if (nunits > (size_t)0 && (size_t)i < nunits && unitv[i] != NULL)
316 asprintf (&outbuff, "%s %s", outbuff, unitv[i]);
317
318 i++;
319
320 } /* end while (ptr) */
321
322 if (found == 0)
323 die (STATE_UNKNOWN,
324 _("%s problem - No data received from host\nCMD: %s\n"),
325 label,
326 command_line);
327
328 /* WARNING if output found on stderr */
329 if (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr))
330 result = max_state (result, STATE_WARNING);
331
332 /* close stderr */
333 (void) fclose (child_stderr);
334
335 /* close the pipe */
336 if (spclose (child_process))
337 result = max_state (result, STATE_WARNING);
338
339/* if (nunits == 1 || i == 1) */
340/* printf ("%s %s -%s %s\n", label, state_text (result), outbuff, units); */
341/* else */
342 printf ("%s %s -%s\n", label, state_text (result), outbuff);
343
344 return result;
345}
346
347
348
349/* process command-line arguments */
350int
351process_arguments (int argc, char **argv)
352{
353 char *ptr;
354 int c = 1;
355 int j = 0, jj = 0, ii = 0;
356
357 int option = 0;
358 static struct option longopts[] = {
359 STD_LONG_OPTS,
360 {"community", required_argument, 0, 'C'},
361 {"oid", required_argument, 0, 'o'},
362 {"object", required_argument, 0, 'o'},
363 {"delimiter", required_argument, 0, 'd'},
364 {"output-delimiter", required_argument, 0, 'D'},
365 {"string", required_argument, 0, 's'},
366 {"timeout", required_argument, 0, 't'},
367 {"regex", required_argument, 0, 'r'},
368 {"ereg", required_argument, 0, 'r'},
369 {"eregi", required_argument, 0, 'R'},
370 {"label", required_argument, 0, 'l'},
371 {"units", required_argument, 0, 'u'},
372 {"port", required_argument, 0, 'p'},
373 {"retries", required_argument, 0, 'e'},
374 {"miblist", required_argument, 0, 'm'},
375 {"protocol", required_argument, 0, 'P'},
376 {"seclevel", required_argument, 0, 'L'},
377 {"secname", required_argument, 0, 'U'},
378 {"authproto", required_argument, 0, 'a'},
379 {"authpasswd", required_argument, 0, 'A'},
380 {"privpasswd", required_argument, 0, 'X'},
381 {0, 0, 0, 0}
382 };
383
384 if (argc < 2)
385 return ERROR;
386
387 /* reverse compatibility for very old non-POSIX usage forms */
388 for (c = 1; c < argc; c++) {
389 if (strcmp ("-to", argv[c]) == 0)
390 strcpy (argv[c], "-t");
391 if (strcmp ("-wv", argv[c]) == 0)
392 strcpy (argv[c], "-w");
393 if (strcmp ("-cv", argv[c]) == 0)
394 strcpy (argv[c], "-c");
395 }
396
397 while (1) {
398 c = getopt_long (argc, argv, "hvVt:c:w:H:C:o:e:E:d:D:s:t:R:r:l:u:p:m:P:L:U:a:A:X:",
399 longopts, &option);
400
401 if (c == -1 || c == EOF)
402 break;
403
404 switch (c) {
405 case '?': /* usage */
406 usage2 (_("Unknown argument"), optarg);
407 case 'h': /* help */
408 print_help ();
409 exit (STATE_OK);
410 case 'V': /* version */
411 print_revision (progname, revision);
412 exit (STATE_OK);
413 case 'v': /* verbose */
414 verbose = TRUE;
415 break;
416
417 /* Connection info */
418 case 'C': /* group or community */
419 community = optarg;
420 break;
421 case 'H': /* Host or server */
422 server_address = optarg;
423 break;
424 case 'p': /* TCP port number */
425 port = optarg;
426 break;
427 case 'm': /* List of MIBS */
428 miblist = optarg;
429 break;
430 case 'P': /* SNMP protocol version */
431 proto = optarg;
432 break;
433 case 'L': /* security level */
434 seclevel = optarg;
435 break;
436 case 'U': /* security username */
437 secname = optarg;
438 break;
439 case 'a': /* auth protocol */
440 authproto = optarg;
441 break;
442 case 'A': /* auth passwd */
443 authpasswd = optarg;
444 break;
445 case 'X': /* priv passwd */
446 privpasswd = optarg;
447 break;
448 case 't': /* timeout period */
449 if (!is_integer (optarg))
450 usage2 (_("Timeout interval must be a positive integer"), optarg);
451 else
452 timeout_interval = atoi (optarg);
453 break;
454
455 /* Test parameters */
456 case 'c': /* critical time threshold */
457 if (strspn (optarg, "0123456789:,") < strlen (optarg))
458 usage2 (_("Invalid critical threshold: %s\n"), optarg);
459 for (ptr = optarg; ptr && jj < MAX_OIDS; jj++) {
460 if (lu_getll (&lower_crit_lim[jj], ptr) == 1)
461 eval_method[jj] |= CRIT_LT;
462 if (lu_getul (&upper_crit_lim[jj], ptr) == 1)
463 eval_method[jj] |= CRIT_GT;
464 (ptr = index (ptr, ',')) ? ptr++ : ptr;
465 }
466 break;
467 case 'w': /* warning time threshold */
468 if (strspn (optarg, "0123456789:,") < strlen (optarg))
469 usage2 (_("Invalid warning threshold: %s\n"), optarg);
470 for (ptr = optarg; ptr && ii < MAX_OIDS; ii++) {
471 if (lu_getll (&lower_warn_lim[ii], ptr) == 1)
472 eval_method[ii] |= WARN_LT;
473 if (lu_getul (&upper_warn_lim[ii], ptr) == 1)
474 eval_method[ii] |= WARN_GT;
475 (ptr = index (ptr, ',')) ? ptr++ : ptr;
476 }
477 break;
478 case 'e': /* PRELIMINARY - may change */
479 case 'E': /* PRELIMINARY - may change */
480 if (!is_integer (optarg))
481 usage2 (_("Retries interval must be a positive integer"), optarg);
482 else
483 retries = atoi(optarg);
484 break;
485 case 'o': /* object identifier */
486 for (ptr = optarg; (ptr = index (ptr, ',')); ptr++)
487 ptr[0] = ' '; /* relpace comma with space */
488 for (ptr = optarg; (ptr = index (ptr, ' ')); ptr++)
489 j++; /* count OIDs */
490 asprintf (&oid, "%s %s", (oid?oid:""), optarg);
491 if (c == 'E' || c == 'e') {
492 jj++;
493 ii++;
494 }
495 if (c == 'E')
496 eval_method[j+1] |= WARN_PRESENT;
497 else if (c == 'e')
498 eval_method[j+1] |= CRIT_PRESENT;
499 break;
500 case 's': /* string or substring */
501 strncpy (string_value, optarg, sizeof (string_value) - 1);
502 string_value[sizeof (string_value) - 1] = 0;
503 eval_method[jj++] = CRIT_STRING;
504 ii++;
505 break;
506 case 'R': /* regex */
507#ifdef HAVE_REGEX_H
508 cflags = REG_ICASE;
509#endif
510 case 'r': /* regex */
511#ifdef HAVE_REGEX_H
512 cflags |= REG_EXTENDED | REG_NOSUB | REG_NEWLINE;
513 strncpy (regex_expect, optarg, sizeof (regex_expect) - 1);
514 regex_expect[sizeof (regex_expect) - 1] = 0;
515 errcode = regcomp (&preg, regex_expect, cflags);
516 if (errcode != 0) {
517 regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER);
518 printf (_("Could Not Compile Regular Expression"));
519 return ERROR;
520 }
521 eval_method[jj++] = CRIT_REGEX;
522 ii++;
523#else
524 printf (_("call for regex which was not a compiled option"));
525 exit (STATE_UNKNOWN);
526#endif
527 break;
528
529 /* Format */
530 case 'd': /* delimiter */
531 delimiter = strscpy (delimiter, optarg);
532 break;
533 case 'D': /* output-delimiter */
534 output_delim = strscpy (output_delim, optarg);
535 break;
536 case 'l': /* label */
537 label = optarg;
538 nlabels++;
539 if (nlabels >= labels_size) {
540 labels_size += 8;
541 labels = realloc (labels, labels_size);
542 if (labels == NULL)
543 die (STATE_UNKNOWN, _("Could not reallocate labels[%d]"), nlabels);
544 }
545 labels[nlabels - 1] = optarg;
546 ptr = thisarg (optarg);
547 labels[nlabels - 1] = ptr;
548 if (strstr (ptr, "'") == ptr)
549 labels[nlabels - 1] = ptr + 1;
550 while (ptr && (ptr = nextarg (ptr))) {
551 if (nlabels >= labels_size) {
552 labels_size += 8;
553 labels = realloc (labels, labels_size);
554 if (labels == NULL)
555 die (STATE_UNKNOWN, _("Could not reallocate labels\n"));
556 }
557 labels++;
558 ptr = thisarg (ptr);
559 if (strstr (ptr, "'") == ptr)
560 labels[nlabels - 1] = ptr + 1;
561 else
562 labels[nlabels - 1] = ptr;
563 }
564 break;
565 case 'u': /* units */
566 units = optarg;
567 nunits++;
568 if (nunits >= unitv_size) {
569 unitv_size += 8;
570 unitv = realloc (unitv, unitv_size);
571 if (unitv == NULL)
572 die (STATE_UNKNOWN, _("Could not reallocate units [%d]\n"), nunits);
573 }
574 unitv[nunits - 1] = optarg;
575 ptr = thisarg (optarg);
576 unitv[nunits - 1] = ptr;
577 if (strstr (ptr, "'") == ptr)
578 unitv[nunits - 1] = ptr + 1;
579 while (ptr && (ptr = nextarg (ptr))) {
580 if (nunits >= unitv_size) {
581 unitv_size += 8;
582 unitv = realloc (unitv, unitv_size);
583 if (units == NULL)
584 die (STATE_UNKNOWN, _("Could not realloc() units\n"));
585 }
586 nunits++;
587 ptr = thisarg (ptr);
588 if (strstr (ptr, "'") == ptr)
589 unitv[nunits - 1] = ptr + 1;
590 else
591 unitv[nunits - 1] = ptr;
592 }
593 break;
594
595 }
596 }
597
598 if (server_address == NULL)
599 server_address = argv[optind];
600
601 if (community == NULL)
602 community = strdup (DEFAULT_COMMUNITY);
603
604 return validate_arguments ();
605}
606
607
608/******************************************************************************
609
610@@-
611<sect3>
612<title>validate_arguments</title>
613
614<para>&PROTO_validate_arguments;</para>
615
616<para>Given a database name, this function returns TRUE if the string
617is a valid PostgreSQL database name, and returns false if it is
618not.</para>
619
620<para>Valid PostgreSQL database names are less than &NAMEDATALEN;
621characters long and consist of letters, numbers, and underscores. The
622first character cannot be a number, however.</para>
623
624</sect3>
625-@@
626******************************************************************************/
627
628
629
630int
631validate_arguments ()
632{
633
634 /* Need better checks to verify seclevel and authproto choices */
635
636 if (seclevel == NULL)
637 asprintf (&seclevel, "noAuthNoPriv");
638
639
640 if (authproto == NULL )
641 asprintf(&authproto, DEFAULT_AUTH_PROTOCOL);
642
643
644
645 if (proto == NULL || (strcmp(proto,DEFAULT_PROTOCOL) == 0) ) { /* default protocol version */
646 asprintf(&proto, DEFAULT_PROTOCOL);
647 asprintf(&authpriv, "%s%s", "-c ", community);
648 }
649 else if ( strcmp (proto, "3") == 0 ) { /* snmpv3 args */
650 asprintf(&proto, "%s", "3");
651
652 if ( (strcmp(seclevel, "noAuthNoPriv") == 0) || seclevel == NULL ) {
653 asprintf(&authpriv, "%s", "-l noAuthNoPriv" );
654 }
655 else if ( strcmp(seclevel, "authNoPriv") == 0 ) {
656 if ( secname == NULL || authpasswd == NULL) {
657 printf (_("Missing secname (%s) or authpassword (%s) ! \n"),secname, authpasswd );
658 print_usage ();
659 exit (STATE_UNKNOWN);
660 }
661 asprintf(&authpriv, "-l authNoPriv -a %s -u %s -A %s ", authproto, secname, authpasswd);
662 }
663 else if ( strcmp(seclevel, "authPriv") == 0 ) {
664 if ( secname == NULL || authpasswd == NULL || privpasswd == NULL ) {
665 printf (_("Missing secname (%s), authpassword (%s), or privpasswd (%s)! \n"),secname, authpasswd,privpasswd );
666 print_usage ();
667 exit (STATE_UNKNOWN);
668 }
669 asprintf(&authpriv, "-l authPriv -a %s -u %s -A %s -x DES -X %s ", authproto, secname, authpasswd, privpasswd);
670 }
671
672 }
673 else {
674 usage2 (_("Invalid SNMP version"), proto);
675 }
676
677 return OK;
678}
679
680
681
682char *
683clarify_message (char *msg)
684{
685 int i = 0;
686 int foo;
687 char tmpmsg_c[MAX_INPUT_BUFFER];
688 char *tmpmsg = (char *) &tmpmsg_c;
689 tmpmsg = strcpy (tmpmsg, msg);
690 if (!strncmp (tmpmsg, " Hex:", 5)) {
691 tmpmsg = strtok (tmpmsg, ":");
692 while ((tmpmsg = strtok (NULL, " "))) {
693 foo = strtol (tmpmsg, NULL, 16);
694 /* Translate chars that are not the same value in the printers
695 * character set.
696 */
697 switch (foo) {
698 case 208:
699 {
700 foo = 197;
701 break;
702 }
703 case 216:
704 {
705 foo = 196;
706 break;
707 }
708 }
709 msg[i] = foo;
710 i++;
711 }
712 msg[i] = 0;
713 }
714 return (msg);
715}
716
717
718
719int
720check_num (int i)
721{
722 int result;
723 result = STATE_OK;
724 if (eval_method[i] & WARN_GT && eval_method[i] & WARN_LT &&
725 lower_warn_lim[i] > upper_warn_lim[i]) {
726 if (response_value[i] <= lower_warn_lim[i] &&
727 response_value[i] >= upper_warn_lim[i]) {
728 result = STATE_WARNING;
729 }
730 }
731 else if
732 ((eval_method[i] & WARN_GT && response_value[i] > upper_warn_lim[i]) ||
733 (eval_method[i] & WARN_GE && response_value[i] >= upper_warn_lim[i]) ||
734 (eval_method[i] & WARN_LT && response_value[i] < lower_warn_lim[i]) ||
735 (eval_method[i] & WARN_LE && response_value[i] <= lower_warn_lim[i]) ||
736 (eval_method[i] & WARN_EQ && response_value[i] == upper_warn_lim[i]) ||
737 (eval_method[i] & WARN_NE && response_value[i] != upper_warn_lim[i])) {
738 result = STATE_WARNING;
739 }
740
741 if (eval_method[i] & CRIT_GT && eval_method[i] & CRIT_LT &&
742 lower_crit_lim[i] > upper_crit_lim[i]) {
743 if (response_value[i] <= lower_crit_lim[i] &&
744 response_value[i] >= upper_crit_lim[i]) {
745 result = STATE_CRITICAL;
746 }
747 }
748 else if
749 ((eval_method[i] & CRIT_GT && response_value[i] > upper_crit_lim[i]) ||
750 (eval_method[i] & CRIT_GE && response_value[i] >= upper_crit_lim[i]) ||
751 (eval_method[i] & CRIT_LT && response_value[i] < lower_crit_lim[i]) ||
752 (eval_method[i] & CRIT_LE && response_value[i] <= lower_crit_lim[i]) ||
753 (eval_method[i] & CRIT_EQ && response_value[i] == upper_crit_lim[i]) ||
754 (eval_method[i] & CRIT_NE && response_value[i] != upper_crit_lim[i])) {
755 result = STATE_CRITICAL;
756 }
757
758 return result;
759}
760
761
762
763int
764lu_getll (unsigned long *ll, char *str)
765{
766 char tmp[100];
767 if (strchr (str, ':') == NULL)
768 return 0;
769 if (strchr (str, ',') != NULL && (strchr (str, ',') < strchr (str, ':')))
770 return 0;
771 if (sscanf (str, "%lu%[:]", ll, tmp) == 2)
772 return 1;
773 return 0;
774}
775
776
777
778int
779lu_getul (unsigned long *ul, char *str)
780{
781 char tmp[100];
782 if (sscanf (str, "%lu%[^,]", ul, tmp) == 1)
783 return 1;
784 if (sscanf (str, ":%lu%[^,]", ul, tmp) == 1)
785 return 1;
786 if (sscanf (str, "%*u:%lu%[^,]", ul, tmp) == 1)
787 return 1;
788 return 0;
789}
790
791
792
793/* trim leading whitespace
794 if there is a leading quote, make sure it balances */
795
796char *
797thisarg (char *str)
798{
799 str += strspn (str, " \t\r\n"); /* trim any leading whitespace */
800 if (strstr (str, "'") == str) { /* handle SIMPLE quoted strings */
801 if (strlen (str) == 1 || !strstr (str + 1, "'"))
802 die (STATE_UNKNOWN, _("Unbalanced quotes\n"));
803 }
804 return str;
805}
806
807
808
809/* if there's a leading quote, advance to the trailing quote
810 set the trailing quote to '\x0'
811 if the string continues, advance beyond the comma */
812
813char *
814nextarg (char *str)
815{
816 if (strstr (str, "'") == str) {
817 str[0] = 0;
818 if (strlen (str) > 1) {
819 str = strstr (str + 1, "'");
820 return (++str);
821 }
822 else {
823 return NULL;
824 }
825 }
826 if (strstr (str, ",") == str) {
827 str[0] = 0;
828 if (strlen (str) > 1) {
829 return (++str);
830 }
831 else {
832 return NULL;
833 }
834 }
835 if ((str = strstr (str, ",")) && strlen (str) > 1) {
836 str[0] = 0;
837 return (++str);
838 }
839 return NULL;
840}
841
842
843
844void
845print_help (void)
846{
847 print_revision (progname, revision);
848
849 printf (COPYRIGHT, copyright, email);
850
851 printf (_("\
852Check status of remote machines and obtain sustem information via SNMP\n\n"));
853
854 print_usage ();
855
856 printf (_(UT_HELP_VRSN));
857
858 printf (_(UT_HOST_PORT), 'p', DEFAULT_PORT);
859
860 /* SNMP and Authentication Protocol */
861 printf (_("\
862 -P, --protocol=[1|3]\n\
863 SNMP protocol version\n\
864 -L, --seclevel=[noAuthNoPriv|authNoPriv|authPriv]\n\
865 SNMPv3 securityLevel\n\
866 -a, --authproto=[MD5|SHA]\n\
867 SNMPv3 auth proto\n"));
868
869 /* Authentication Tokens*/
870 printf (_("\
871 -C, --community=STRING\n\
872 Optional community string for SNMP communication\n\
873 (default is \"%s\")\n\
874 -U, --secname=USERNAME\n\
875 SNMPv3 username\n\
876 -A, --authpassword=PASSWORD\n\
877 SNMPv3 authentication password\n\
878 -X, --privpasswd=PASSWORD\n\
879 SNMPv3 crypt passwd (DES)\n"), DEFAULT_COMMUNITY);
880
881 /* OID Stuff */
882 printf (_("\
883 -o, --oid=OID(s)\n\
884 Object identifier(s) whose value you wish to query\n\
885 -m, --miblist=STRING\n\
886 List of MIBS to be loaded (default = ALL)\n -d, --delimiter=STRING\n\
887 Delimiter to use when parsing returned data. Default is \"%s\"\n\
888 Any data on the right hand side of the delimiter is considered\n\
889 to be the data that should be used in the evaluation.\n"), DEFAULT_DELIMITER);
890
891 /* Tests Against Integers */
892 printf (_("\
893 -w, --warning=INTEGER_RANGE(s)\n\
894 Range(s) which will not result in a WARNING status\n\
895 -c, --critical=INTEGER_RANGE(s)\n\
896 Range(s) which will not result in a CRITICAL status\n"));
897
898 /* Tests Against Strings */
899 printf (_("\
900 -s, --string=STRING\n\
901 Return OK state (for that OID) if STRING is an exact match\n\
902 -r, --ereg=REGEX\n\
903 Return OK state (for that OID) if extended regular expression REGEX matches\n\
904 -R, --eregi=REGEX\n\
905 Return OK state (for that OID) if case-insensitive extended REGEX matches\n\
906 -l, --label=STRING\n\
907 Prefix label for output from plugin (default -s 'SNMP')\n"));
908
909 /* Output Formatting */
910 printf (_("\
911 -u, --units=STRING\n\
912 Units label(s) for output data (e.g., 'sec.').\n\
913 -D, --output-delimiter=STRING\n\
914 Separates output on multiple OID requests\n"));
915
916 printf (_(UT_TIMEOUT), DEFAULT_SOCKET_TIMEOUT);
917
918 printf (_(UT_VERBOSE));
919
920 printf (_("\n\
921- This plugin uses the 'snmpget' command included with the NET-SNMP package.\n\
922 If you don't have the package installed, you will need to download it from\n\
923 http://net-snmp.sourceforge.net before you can use this plugin.\n"));
924
925 printf (_("\
926- Multiple OIDs may be indicated by a comma- or space-delimited list (lists with\n\
927 internal spaces must be quoted) [max 8 OIDs]\n"));
928
929 printf (_("\
930- Ranges are inclusive and are indicated with colons. When specified as\n\
931 'min:max' a STATE_OK will be returned if the result is within the indicated\n\
932 range or is equal to the upper or lower bound. A non-OK state will be\n\
933 returned if the result is outside the specified range.\n"));
934
935 printf (_("\
936- If specified in the order 'max:min' a non-OK state will be returned if the\n\
937 result is within the (inclusive) range.\n"));
938
939 printf (_("\
940- Upper or lower bounds may be omitted to skip checking the respective limit.\n\
941- Bare integers are interpreted as upper limits.\n\
942- When checking multiple OIDs, separate ranges by commas like '-w 1:10,1:,:20'\n\
943- Note that only one string and one regex may be checked at present\n\
944- All evaluation methods other than PR, STR, and SUBSTR expect that the value\n\
945 returned from the SNMP query is an unsigned integer.\n"));
946
947 printf (_(UT_SUPPORT));
948}
949
950
951
952void
953print_usage (void)
954{
955 printf ("\
956Usage: %s -H <ip_address> -o <OID> [-w warn_range] [-c crit_range] \n\
957 [-C community] [-s string] [-r regex] [-R regexi]\n\
958 [-t timeout] [-e retries]\n\
959 [-l label] [-u units] [-p port-number] [-d delimiter]\n\
960 [-D output-delimiter] [-m miblist] [-P snmp version]\n\
961 [-L seclevel] [-U secname] [-a authproto] [-A authpasswd]\n\
962 [-X privpasswd]\n", progname);
963}