summaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/check_snmp.c289
1 files changed, 174 insertions, 115 deletions
diff --git a/plugins/check_snmp.c b/plugins/check_snmp.c
index 35d21479..38ce940b 100644
--- a/plugins/check_snmp.c
+++ b/plugins/check_snmp.c
@@ -1,19 +1,7 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * CHECK_SNMP.C
4 *
5 * Program: SNMP plugin for Nagios 3 * Program: SNMP plugin for Nagios
6 * License: GPL 4 * License: GPL
7 * Copyright (c) 1999 Ethan Galstad (nagios@nagios.org)
8 *
9 * Last Modified: $Date$
10 *
11 * Description:
12 *
13 * This plugin uses the 'snmpget' command included with the UCD-SNMP
14 * package. If you don't have the package installed you will need to
15 * download it from http://ucd-snmp.ucdavis.edu before you can use
16 * this plugin.
17 * 5 *
18 * License Information: 6 * License Information:
19 * 7 *
@@ -30,15 +18,88 @@
30 * You should have received a copy of the GNU General Public License 18 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software 19 * along with this program; if not, write to the Free Software
32 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
33 *./plugins/check_snmp 127.0.0.1 -c public -o .1.3.6.1.4.1.2021.9.1.2.1 22 *./plugins/check_snmp 127.0.0.1 -c public -o .1.3.6.1.4.1.2021.9.1.2.1
23 *
34 *****************************************************************************/ 24 *****************************************************************************/
35 25
26#define PROGNAME "check_snmp"
27#define REVISION "$Revision$"
28#define COPYRIGHT "1999-2002"
29#define AUTHOR "Ethan Galstad"
30#define EMAIL "nagios@nagios.org"
31#define SUMMARY "Check status of remote machines using SNMP.\n"
32
33#define OPTIONS "\
34-H <ip_address> -o <OID> [-w warn_range] [-c crit_range] \n\
35 [-C community] [-s string] [-r regex] [-R regexi] [-t timeout]\n\
36 [-l label] [-u units] [-p port-number] [-d delimiter]\n\
37 [-D output-delimiter]"
38
39#define LONGOPTIONS "\
40 -H, --hostname=HOST\n\
41 Name or IP address of the device you wish to query\n\
42 -o, --oid=OID(s)\n\
43 Object identifier(s) whose value you wish to query\n\
44 -w, --warning=INTEGER_RANGE(s)\n\
45 Range(s) which will not result in a WARNING status\n\
46 -c, --critical=INTEGER_RANGE(s)\n\
47 Range(s) which will not result in a CRITICAL status\n\
48 -C, --community=STRING\n\
49 Optional community string for SNMP communication\n\
50 (default is \"%s\")\n\
51 -u, --units=STRING\n\
52 Units label(s) for output data (e.g., 'sec.').\n\
53 -p, --port=STRING\n\
54 UDP port number target is listening on. Default is \"%s\"\n\
55 -d, --delimiter=STRING\n\
56 Delimiter to use when parsing returned data. Default is \"%s\"\n\
57 Any data on the right hand side of the delimiter is considered\n\
58 to be the data that should be used in the evaluation.\n\
59 -t, --timeout=INTEGER\n\
60 Seconds to wait before plugin times out (see also nagios server timeout).\n\
61 Default is %d seconds\n\
62 -D, --output-delimiter=STRING\n\
63 Separates output on multiple OID requests\n\
64 -s, --string=STRING\n\
65 Return OK state (for that OID) if STRING is an exact match\n\
66 -r, --ereg=REGEX\n\
67 Return OK state (for that OID) if extended regular expression REGEX matches\n\
68 -R, --eregi=REGEX\n\
69 Return OK state (for that OID) if case-insensitive extended REGEX matches\n\
70 -l, --label=STRING\n\
71 Prefix label for output from plugin (default -s 'SNMP')\n"
72
73#define NOTES "\
74- This plugin uses the 'snmpget' command included with the UCD-SNMP package.\n\
75 If you don't have the package installed, you will need to download it from\n\
76 http://ucd-snmp.ucdavis.edu before you can use this plugin.\n\
77- Multiple OIDs may be indicated by a comma- or space-delimited list (lists with\n\
78 internal spaces must be quoted)\n\
79- Ranges are inclusive and are indicated with colons. When specified as\n\
80 'min:max' a STATE_OK will be returned if the result is within the indicated\n\
81 range or is equal to the upper or lower bound. A non-OK state will be\n\
82 returned if the result is outside the specified range.\n\
83- If spcified in the order 'max:min' a non-OK state will be returned if the\n\
84 result is within the (inclusive) range.\n\
85- Upper or lower bounds may be omitted to skip checking the respective limit.\n\
86- Bare integers are interpreted as upper limits.\n\
87- When checking multiple OIDs, separate ranges by commas like '-w 1:10,1:,:20'\n\
88- Note that only one string and one regex may be checked at present\n\
89- All evaluation methods other than PR, STR, and SUBSTR expect that the value\n\
90 returned from the SNMP query is an unsigned integer.\n"
91
92#define DESCRIPTION "\
93This plugin gets system information on a remote server via snmp.\n"
94
95#define DEFAULT_COMMUNITY "public"
96#define DEFAULT_PORT "161"
97#define DEFAULT_TIMEOUT 10
98
36#include "common.h" 99#include "common.h"
37#include "utils.h" 100#include "utils.h"
38#include "popen.h" 101#include "popen.h"
39 102
40#define PROGNAME check_snmp
41
42#define mark(a) ((a)!=0?"*":"") 103#define mark(a) ((a)!=0?"*":"")
43 104
44#define CHECK_UNDEF 0 105#define CHECK_UNDEF 0
@@ -69,9 +130,9 @@
69#define DEFAULT_OUTPUT_DELIMITER " " 130#define DEFAULT_OUTPUT_DELIMITER " "
70 131
71void print_usage (void); 132void print_usage (void);
72void print_help (char *); 133void print_help (void);
73int process_arguments (int, char **); 134int process_arguments (int, char **);
74int call_getopt (int, char **); 135int validate_arguments (void);
75int check_num (int); 136int check_num (int);
76char *clarify_message (char *); 137char *clarify_message (char *);
77int lu_getll (unsigned long *, char *); 138int lu_getll (unsigned long *, char *);
@@ -212,6 +273,14 @@ main (int argc, char **argv)
212 show = response; 273 show = response;
213 p2 = show; 274 p2 = show;
214 275
276 iresult = STATE_DEPENDENT;
277
278 if (eval_method[i] & CRIT_PRESENT) {
279 iresult = STATE_CRITICAL;
280 } else if (eval_method[i] & WARN_PRESENT) {
281 iresult = STATE_WARNING;
282 }
283
215 if (eval_method[i] & CRIT_GT || 284 if (eval_method[i] & CRIT_GT ||
216 eval_method[i] & CRIT_LT || 285 eval_method[i] & CRIT_LT ||
217 eval_method[i] & CRIT_GE || 286 eval_method[i] & CRIT_GE ||
@@ -257,14 +326,12 @@ main (int argc, char **argv)
257#endif 326#endif
258 } 327 }
259 328
260 else { 329 if (response && iresult == STATE_DEPENDENT)
261 if (response) 330 iresult = STATE_OK;
262 iresult = STATE_OK; 331 else if (eval_method[i] & CRIT_PRESENT)
263 else if (eval_method[i] & CRIT_PRESENT) 332 iresult = STATE_CRITICAL;
264 iresult = STATE_CRITICAL; 333 else
265 else 334 iresult = STATE_WARNING;
266 iresult = STATE_WARNING;
267 }
268 335
269 result = max_state (result, iresult); 336 result = max_state (result, iresult);
270 337
@@ -313,7 +380,7 @@ int
313process_arguments (int argc, char **argv) 380process_arguments (int argc, char **argv)
314{ 381{
315 char *ptr; 382 char *ptr;
316 int c, i = 1; 383 int c = 1;
317 int j = 0, jj = 0; 384 int j = 0, jj = 0;
318 385
319#ifdef HAVE_GETOPT_H 386#ifdef HAVE_GETOPT_H
@@ -355,38 +422,48 @@ process_arguments (int argc, char **argv)
355 while (1) { 422 while (1) {
356#ifdef HAVE_GETOPT_H 423#ifdef HAVE_GETOPT_H
357 c = 424 c =
358 getopt_long (argc, argv, "+?hVt:c:w:H:C:o:d:D:s:R:r:l:u:p:", 425 getopt_long (argc, argv, "+?hVt:c:w:H:C:o:e:E:d:D:s:R:r:l:u:p:",
359 long_options, &option_index); 426 long_options, &option_index);
360#else 427#else
361 c = getopt (argc, argv, "+?hVt:c:w:H:C:o:d:D:s:R:r:l:u:p:"); 428 c = getopt (argc, argv, "+?hVt:c:w:H:C:o:e:E:d:D:s:R:r:l:u:p:");
362#endif 429#endif
363 430
364 if (c == -1 || c == EOF) 431 if (c == -1 || c == EOF)
365 break; 432 break;
366 433
367 switch (c) { 434 switch (c) {
368 case '?': /* help */ 435 case '?': /* usage */
369 printf ("%s: Unknown argument: %s\n\n", my_basename (argv[0]), optarg); 436 usage2 ("Unknown argument", optarg);
370 print_usage (); 437 case 'h': /* help */
371 exit (STATE_UNKNOWN); 438 print_help ();
372 case 'h': /* help */
373 print_help (my_basename (argv[0]));
374 exit (STATE_OK); 439 exit (STATE_OK);
375 case 'V': /* version */ 440 case 'V': /* version */
376 print_revision (my_basename (argv[0]), "$Revision$"); 441 print_revision (PROGNAME, REVISION);
377 exit (STATE_OK); 442 exit (STATE_OK);
378 case 'v': /* verbose */ 443 case 'v': /* verbose */
379 verbose = TRUE; 444 verbose = TRUE;
380 break; 445 break;
381 case 't': /* timeout period */ 446 case 't': /* timeout period */
382 if (!is_integer (optarg)) { 447 if (!is_integer (optarg))
383 printf ("%s: Timeout Interval must be an integer!\n\n", 448 usage2 ("Timeout Interval must be an integer", optarg);
384 my_basename (argv[0]));
385 print_usage ();
386 exit (STATE_UNKNOWN);
387 }
388 timeout_interval = atoi (optarg); 449 timeout_interval = atoi (optarg);
389 break; 450 break;
451 case 'e': /* PRELIMINARY - may change */
452 eval_method[j] |= WARN_PRESENT;
453 for (ptr = optarg; (ptr = index (ptr, ',')); ptr++)
454 ptr[0] = ' '; /* relpace comma with space */
455 for (ptr = optarg; (ptr = index (ptr, ' ')); ptr++)
456 eval_method[++j] |= WARN_PRESENT;
457 asprintf (&oid, "%s %s", oid, optarg);
458 break;
459 case 'E': /* PRELIMINARY - may change */
460 eval_method[j] |= WARN_PRESENT;
461 for (ptr = optarg; (ptr = index (ptr, ',')); ptr++)
462 ptr[0] = ' '; /* relpace comma with space */
463 for (ptr = optarg; (ptr = index (ptr, ' ')); ptr++)
464 eval_method[++j] |= CRIT_PRESENT;
465 asprintf (&oid, "%s %s", oid, optarg);
466 break;
390 case 'c': /* critical time threshold */ 467 case 'c': /* critical time threshold */
391 if (strspn (optarg, "0123456789:,") < strlen (optarg)) { 468 if (strspn (optarg, "0123456789:,") < strlen (optarg)) {
392 printf ("Invalid critical threshold: %s\n", optarg); 469 printf ("Invalid critical threshold: %s\n", optarg);
@@ -424,8 +501,9 @@ process_arguments (int argc, char **argv)
424 case 'o': /* object identifier */ 501 case 'o': /* object identifier */
425 for (ptr = optarg; (ptr = index (ptr, ',')); ptr++) 502 for (ptr = optarg; (ptr = index (ptr, ',')); ptr++)
426 ptr[0] = ' '; /* relpace comma with space */ 503 ptr[0] = ' '; /* relpace comma with space */
427 for (ptr = optarg, j = 1; (ptr = index (ptr, ' ')); ptr++) 504 for (ptr = optarg; (ptr = index (ptr, ' ')); ptr++) {
428 j++; /* count OIDs */ 505 j++; /* count OIDs */
506 }
429 asprintf (&oid, "%s %s", oid, optarg); 507 asprintf (&oid, "%s %s", oid, optarg);
430 break; 508 break;
431 case 'd': /* delimiter */ 509 case 'd': /* delimiter */
@@ -529,103 +607,84 @@ process_arguments (int argc, char **argv)
529 } 607 }
530 } 608 }
531 609
532 c = optind;
533 if (server_address == NULL) 610 if (server_address == NULL)
534 server_address = strscpy (NULL, argv[c++]); 611 asprintf (&server_address, argv[optind]);
612
613 return validate_arguments ();
614}
615
616/******************************************************************************
617
618@@-
619<sect3>
620<title>validate_arguments</title>
621
622<para>&PROTO_validate_arguments;</para>
623
624<para>Given a database name, this function returns TRUE if the string
625is a valid PostgreSQL database name, and returns false if it is
626not.</para>
627
628<para>Valid PostgreSQL database names are less than &NAMEDATALEN;
629characters long and consist of letters, numbers, and underscores. The
630first character cannot be a number, however.</para>
631
632</sect3>
633-@@
634******************************************************************************/
635
636int
637validate_arguments ()
638{
535 639
536 if (community == NULL) 640 if (community == NULL)
537 community = strscpy (NULL, "public"); 641 asprintf (&community, DEFAULT_COMMUNITY);
538 642
539 if (delimiter == NULL) 643 if (delimiter == NULL)
540 delimiter = strscpy (NULL, DEFAULT_DELIMITER); 644 asprintf (&delimiter, DEFAULT_DELIMITER);
541 645
542 if (output_delim == NULL) 646 if (output_delim == NULL)
543 output_delim = strscpy (NULL, DEFAULT_OUTPUT_DELIMITER); 647 asprintf (&output_delim, DEFAULT_OUTPUT_DELIMITER);
544 648
545 if (label == NULL) 649 if (label == NULL)
546 label = strscpy (NULL, "SNMP"); 650 asprintf (&label, "SNMP");
547 651
548 if (units == NULL) 652 if (units == NULL)
549 units = strscpy (NULL, ""); 653 asprintf (&units, "");
550 654
551 if (port == NULL) 655 if (port == NULL)
552 port = strscpy(NULL,"161"); 656 asprintf (&port, DEFAULT_PORT);
553 657
554 return i; 658 return OK;
555} 659}
660
661
556 662
557void 663void
558print_usage (void) 664print_help (void)
559{ 665{
666 print_revision (PROGNAME, REVISION);
667 printf
668 ("Copyright (c) %s %s <%s>\n\n%s\n",
669 COPYRIGHT, AUTHOR, EMAIL, SUMMARY);
670 print_usage ();
560 printf 671 printf
561 ("Usage: check_snmp -H <ip_address> -o <OID> [-w warn_range] [-c crit_range] \n" 672 ("\nOptions:\n" LONGOPTIONS "\n" DESCRIPTION "\n" NOTES "\n",
562 " [-C community] [-s string] [-r regex] [-R regexi] [-t timeout]\n" 673 DEFAULT_COMMUNITY, DEFAULT_PORT, DEFAULT_DELIMITER, DEFAULT_TIMEOUT);
563 " [-l label] [-u units] [-p port-number] [-d delimiter] [-D output-delimiter]\n" 674 support ();
564 " check_snmp --help\n" " check_snmp --version\n");
565} 675}
566 676
567void 677void
568print_help (char *cmd) 678print_usage (void)
569{ 679{
570 printf ("Copyright (c) 1999 Ethan Galstad (nagios@nagios.org)\n"
571 "License: GPL\n\n");
572 print_usage ();
573 printf 680 printf
574 ("\nOptions:\n" 681 ("Usage:\n" " %s %s\n"
575 " -h, --help\n" 682 " %s (-h | --help) for detailed help\n"
576 " Print detailed help screen\n" 683 " %s (-V | --version) for version information\n",
577 " -V, --version\n" 684 PROGNAME, OPTIONS, PROGNAME, PROGNAME);
578 " Print version information\n"
579 " -H, --hostname=HOST\n"
580 " Name or IP address of the device you wish to query\n"
581 " -o, --oid=OID(s)\n"
582 " Object identifier(s) whose value you wish to query\n"
583 " -w, --warning=INTEGER_RANGE(s)\n"
584 " Range(s) which will not result in a WARNING status\n"
585 " -c, --critical=INTEGER_RANGE(s)\n"
586 " Range(s) which will not result in a CRITICAL status\n"
587 " -C, --community=STRING\n"
588 " Optional community string for SNMP communication\n"
589 " (default is \"public\")\n"
590 " -u, --units=STRING\n"
591 " Units label(s) for output data (e.g., 'sec.').\n"
592 " -p, --port=STRING\n"
593 " UDP port number target is listening on.\n"
594 " -d, --delimiter=STRING\n"
595 " Delimiter to use when parsing returned data. Default is \"%s\"\n"
596 " Any data on the right hand side of the delimiter is considered\n"
597 " to be the data that should be used in the evaluation.\n"
598 " -t, --timeout=INTEGER\n"
599 " Seconds to wait before plugin times out (see also nagios server timeout)\n"
600 " -D, --output-delimiter=STRING\n"
601 " Separates output on multiple OID requests\n"
602 " -s, --string=STRING\n"
603 " Return OK state (for that OID) if STRING is an exact match\n"
604 " -r, --ereg=REGEX\n"
605 " Return OK state (for that OID) if extended regular expression REGEX matches\n"
606 " -R, --eregi=REGEX\n"
607 " Return OK state (for that OID) if case-insensitive extended REGEX matches\n"
608 " -l, --label=STRING\n"
609 " Prefix label for output from plugin (default -s 'SNMP')\n\n"
610 "- This plugin uses the 'snmpget' command included with the UCD-SNMP package.\n"
611 " If you don't have the package installed, you will need to download it from\n"
612 " http://ucd-snmp.ucdavis.edu before you can use this plugin.\n"
613 "- Multiple OIDs may be indicated by a comma- or space-delimited list (lists with\n"
614 " internal spaces must be quoted)\n"
615 "- Ranges are inclusive and are indicated with colons. When specified as\n"
616 " 'min:max' a STATE_OK will be returned if the result is within the indicated\n"
617 " range or is equal to the upper or lower bound. A non-OK state will be\n"
618 " returned if the result is outside the specified range.\n"
619 "- If spcified in the order 'max:min' a non-OK state will be returned if the\n"
620 " result is within the (inclusive) range.\n"
621 "- Upper or lower bounds may be omitted to skip checking the respective limit.\n"
622 "- Bare integers are interpreted as upper limits.\n"
623 "- When checking multiple OIDs, separate ranges by commas like '-w 1:10,1:,:20'\n"
624 "- Note that only one string and one regex may be checked at present\n"
625 "- All evaluation methods other than PR, STR, and SUBSTR expect that the value\n"
626 " returned from the SNMP query is an unsigned integer.\n\n",
627 DEFAULT_DELIMITER);
628} 685}
686
687
629 688
630char * 689char *
631clarify_message (char *msg) 690clarify_message (char *msg)