X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=plugins%2Fcheck_snmp.c;h=b943379d4770bbc67d220ec258c9d6019f5abd9f;hb=831d03cd768cb4d1f96d3cabd6262a0a55f904e7;hp=7e574c5fd7b52eee334630997889117f3e1a551c;hpb=ab67f9e1d29460db3d99fe40e56c3a8f2665ad7f;p=nagiosplug.git diff --git a/plugins/check_snmp.c b/plugins/check_snmp.c index 7e574c5..b943379 100644 --- a/plugins/check_snmp.c +++ b/plugins/check_snmp.c @@ -23,7 +23,7 @@ * *****************************************************************************/ -#define PROGNAME "check_snmp" +const char *progname = "check_snmp"; #define REVISION "$Revision$" #define COPYRIGHT "1999-2002" #define AUTHOR "Ethan Galstad" @@ -34,7 +34,9 @@ -H -o [-w warn_range] [-c crit_range] \n\ [-C community] [-s string] [-r regex] [-R regexi] [-t timeout]\n\ [-l label] [-u units] [-p port-number] [-d delimiter]\n\ - [-D output-delimiter] [-m miblist]" + [-D output-delimiter] [-m miblist] [-P snmp version]\n\ + [-L seclevel] [-U secname] [-a authproto] [-A authpasswd]\n\ + [-X privpasswd]\n" #define LONGOPTIONS "\ -H, --hostname=HOST\n\ @@ -52,6 +54,18 @@ Units label(s) for output data (e.g., 'sec.').\n\ -p, --port=STRING\n\ UDP port number target is listening on. Default is \"%s\"\n\ + -P, --protocol=[1|3]\n\ + SNMP protocol version\n\ + -L, --seclevel=[noAuthNoPriv|authNoPriv|authPriv]\n\ + SNMPv3 securityLevel\n\ + -U, --secname=USERNAME\n\ + SNMPv3 username\n\ + -a, --authproto=[MD5|SHA]\n\ + SNMPv3 auth proto\n\ + -A, --authpassword=PASSWORD\n\ + SNMPv3 authentication password\n\ + -X, --privpasswd=PASSWORD\n\ + SNMPv3 crypt passwd (DES)\n\ -d, --delimiter=STRING\n\ Delimiter to use when parsing returned data. Default is \"%s\"\n\ Any data on the right hand side of the delimiter is considered\n\ @@ -100,6 +114,8 @@ This plugin gets system information on a remote server via snmp.\n" #define DEFAULT_PORT "161" #define DEFAULT_TIMEOUT 10 #define DEFAULT_MIBLIST "ALL" +#define DEFAULT_PROTOCOL "1" +#define DEFAULT_AUTH_PROTOCOL "MD5" #include "common.h" #include "utils.h" @@ -159,10 +175,17 @@ int errcode, excode; #endif char *server_address = NULL; -char *community = NULL; +char *community = DEFAULT_COMMUNITY; +char *authpriv = NULL; +char *proto = NULL; +char *seclevel = NULL; +char *secname = NULL; +char *authproto = NULL; +char *authpasswd = NULL; +char *privpasswd = NULL; char *oid = ""; -char *label = NULL; -char *units = NULL; +char *label = "SNMP"; +char *units = ""; char *port = DEFAULT_PORT; char string_value[MAX_INPUT_BUFFER] = ""; char **labels = NULL; @@ -180,9 +203,9 @@ unsigned long response_value[MAX_OIDS]; int check_warning_value = FALSE; int check_critical_value = FALSE; int eval_method[MAX_OIDS]; -char *delimiter = NULL; -char *output_delim = NULL; -char *miblist = NULL; +char *delimiter = DEFAULT_DELIMITER; +char *output_delim = DEFAULT_OUTPUT_DELIMITER; +char *miblist = DEFAULT_MIBLIST; int @@ -196,7 +219,7 @@ main (int argc, char **argv) char *command_line = NULL; char *response = NULL; char *outbuff = ""; - char *output = NULL; + char *output = ""; char *ptr = NULL; char *p2 = NULL; char *show = NULL; @@ -211,8 +234,8 @@ main (int argc, char **argv) usage ("Incorrect arguments supplied\n"); /* create the command line to execute */ - asprintf (&command_line, "%s -m %s -v 1 -c %s %s:%s %s", - PATH_TO_SNMPGET, miblist, community, server_address, port, oid); + asprintf (&command_line, "%s -m %s -v %s %s %s:%s %s", + PATH_TO_SNMPGET, miblist, proto, authpriv, server_address, port, oid); if (verbose) printf ("%s\n", command_line); @@ -228,7 +251,6 @@ main (int argc, char **argv) printf ("Could not open stderr for %s\n", command_line); } - asprintf (&output, ""); while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) asprintf (&output, "%s%s", output, input_buffer); @@ -270,40 +292,45 @@ main (int argc, char **argv) } } + /* We strip out the datatype indicator for PHBs */ if (strstr (response, "Gauge: ")) show = strstr (response, "Gauge: ") + 7; else if (strstr (response, "Gauge32: ")) show = strstr (response, "Gauge32: ") + 9; + else if (strstr (response, "Counter32: ")) + show = strstr (response, "Counter32: ") + 11; + else if (strstr (response, "INTEGER: ")) + show = strstr (response, "INTEGER: ") + 9; + else if (strstr (response, "STRING: ")) + show = strstr (response, "STRING: ") + 8; else show = response; p2 = show; iresult = STATE_DEPENDENT; - if (eval_method[i] & CRIT_PRESENT) { - iresult = STATE_CRITICAL; - } else if (eval_method[i] & WARN_PRESENT) { - iresult = STATE_WARNING; - } - + /* Process this block for integer comparisons */ if (eval_method[i] & CRIT_GT || - eval_method[i] & CRIT_LT || - eval_method[i] & CRIT_GE || - eval_method[i] & CRIT_LE || - eval_method[i] & CRIT_EQ || - eval_method[i] & CRIT_NE || - eval_method[i] & WARN_GT || - eval_method[i] & WARN_LT || - eval_method[i] & WARN_GE || - eval_method[i] & WARN_LE || - eval_method[i] & WARN_EQ || eval_method[i] & WARN_NE) { + eval_method[i] & CRIT_LT || + eval_method[i] & CRIT_GE || + eval_method[i] & CRIT_LE || + eval_method[i] & CRIT_EQ || + eval_method[i] & CRIT_NE || + eval_method[i] & WARN_GT || + eval_method[i] & WARN_LT || + eval_method[i] & WARN_GE || + eval_method[i] & WARN_LE || + eval_method[i] & WARN_EQ || + eval_method[i] & WARN_NE) { p2 = strpbrk (p2, "0123456789"); + if (p2 == NULL) + terminate (STATE_UNKNOWN,"No valid data returned"); response_value[i] = strtoul (p2, NULL, 10); iresult = check_num (i); asprintf (&show, "%lu", response_value[i]); - /*asprintf (&show, "%s", response); */ } + /* Process this block for string matching */ else if (eval_method[i] & CRIT_STRING) { if (strcmp (response, string_value)) iresult = STATE_CRITICAL; @@ -311,6 +338,7 @@ main (int argc, char **argv) iresult = STATE_OK; } + /* Process this block for regex matching */ else if (eval_method[i] & CRIT_REGEX) { #ifdef HAVE_REGEX_H excode = regexec (&preg, response, 10, pmatch, eflags); @@ -326,20 +354,25 @@ main (int argc, char **argv) iresult = STATE_CRITICAL; } #else - printf ("SNMP UNKNOWN: call for regex which was not a compiled option"); + printf ("%s UNKNOWN: call for regex which was not a compiled option", label); exit (STATE_UNKNOWN); #endif } - if (response && iresult == STATE_DEPENDENT) - iresult = STATE_OK; - else if (eval_method[i] & CRIT_PRESENT) - iresult = STATE_CRITICAL; - else - iresult = STATE_WARNING; + /* Process this block for existence-nonexistence checks */ + else { + if (eval_method[i] & CRIT_PRESENT) + iresult = STATE_CRITICAL; + else if (eval_method[i] & WARN_PRESENT) + iresult = STATE_WARNING; + else if (response && iresult == STATE_DEPENDENT) + iresult = STATE_OK; + } + /* Result is the worst outcome of all the OIDs tested */ result = max_state (result, iresult); + /* Prepend a label for this OID if there is one */ if (nlabels > 1 && i < nlabels && labels[i] != NULL) asprintf (&outbuff, "%s%s%s %s%s%s", outbuff, (i == 0) ? " " : output_delim, @@ -348,12 +381,13 @@ main (int argc, char **argv) asprintf (&outbuff, "%s%s%s%s%s", outbuff, (i == 0) ? " " : output_delim, mark (iresult), show, mark (iresult)); - if (nunits > 0 && i < nunits) + /* Append a unit string for this OID if there is one */ + if (nunits > 0 && i < nunits && unitv[i] != NULL) asprintf (&outbuff, "%s %s", outbuff, unitv[i]); i++; - } /* end while */ + } /* end while (ptr) */ if (found == 0) terminate @@ -372,10 +406,10 @@ main (int argc, char **argv) if (spclose (child_process)) result = max_state (result, STATE_WARNING); - if (nunits > 0) - printf ("%s %s -%s %s\n", label, state_text (result), outbuff, units); - else - printf ("%s %s -%s\n", label, state_text (result), outbuff); +/* if (nunits == 1 || i == 1) */ +/* printf ("%s %s -%s %s\n", label, state_text (result), outbuff, units); */ +/* else */ + printf ("%s %s -%s\n", label, state_text (result), outbuff); return result; } @@ -386,9 +420,8 @@ process_arguments (int argc, char **argv) { char *ptr; int c = 1; - int j = 0, jj = 0; + int j = 0, jj = 0, ii = 0; -#ifdef HAVE_GETOPT_H int option_index = 0; static struct option long_options[] = { STD_LONG_OPTS, @@ -404,9 +437,15 @@ process_arguments (int argc, char **argv) {"label", required_argument, 0, 'l'}, {"units", required_argument, 0, 'u'}, {"port", required_argument, 0, 'p'}, + {"miblist", required_argument, 0, 'm'}, + {"protocol", required_argument, 0, 'P'}, + {"seclevel", required_argument, 0, 'L'}, + {"secname", required_argument, 0, 'U'}, + {"authproto", required_argument, 0, 'a'}, + {"authpasswd", required_argument, 0, 'A'}, + {"privpasswd", required_argument, 0, 'X'}, {0, 0, 0, 0} }; -#endif if (argc < 2) return ERROR; @@ -422,13 +461,8 @@ process_arguments (int argc, char **argv) } while (1) { -#ifdef HAVE_GETOPT_H - c = - getopt_long (argc, argv, "hvVt:c:w:H:C:o:e:E:d:D:s:R:r:l:u:p:m:", + c = getopt_long (argc, argv, "hvVt:c:w:H:C:o:e:E:d:D:s:R:r:l:u:p:m:P:L:U:a:A:X:", long_options, &option_index); -#else - c = getopt (argc, argv, "hvVt:c:w:H:C:o:e:E:d:D:s:R:r:l:u:p:m:"); -#endif if (c == -1 || c == EOF) break; @@ -438,41 +472,59 @@ process_arguments (int argc, char **argv) usage3 ("Unknown argument", optopt); case 'h': /* help */ print_help (); - exit (STATE_OK); + exit (STATE_OK); case 'V': /* version */ - print_revision (PROGNAME, REVISION); + print_revision (progname, REVISION); exit (STATE_OK); case 'v': /* verbose */ verbose = TRUE; break; + + /* Connection info */ + case 'C': /* group or community */ + community = strscpy (community, optarg); + break; + case 'H': /* Host or server */ + server_address = strscpy (server_address, optarg); + break; + case 'p': /* TCP port number */ + port = strscpy(port, optarg); + break; + case 'm': /* List of MIBS */ + miblist = strscpy(miblist, optarg); + break; + case 'P': /* SNMP protocol version */ + proto = strscpy(proto, optarg); + break; + case 'L': /* security level */ + seclevel = strscpy(seclevel,optarg); + break; + case 'U': /* security username */ + secname = strscpy(secname, optarg); + break; + case 'a': /* auth protocol */ + asprintf (&authproto, optarg); + break; + case 'A': /* auth passwd */ + authpasswd = strscpy(authpasswd, optarg); + break; + case 'X': /* priv passwd */ + privpasswd = strscpy(privpasswd, optarg); + break; case 't': /* timeout period */ if (!is_integer (optarg)) usage2 ("Timeout Interval must be an integer", optarg); timeout_interval = atoi (optarg); break; - case 'e': /* PRELIMINARY - may change */ - eval_method[j] |= WARN_PRESENT; - for (ptr = optarg; (ptr = index (ptr, ',')); ptr++) - ptr[0] = ' '; /* relpace comma with space */ - for (ptr = optarg; (ptr = index (ptr, ' ')); ptr++) - eval_method[++j] |= WARN_PRESENT; - asprintf (&oid, "%s %s", (oid?oid:""), optarg); - break; - case 'E': /* PRELIMINARY - may change */ - eval_method[j] |= WARN_PRESENT; - for (ptr = optarg; (ptr = index (ptr, ',')); ptr++) - ptr[0] = ' '; /* relpace comma with space */ - for (ptr = optarg; (ptr = index (ptr, ' ')); ptr++) - eval_method[++j] |= CRIT_PRESENT; - asprintf (&oid, "%s %s", (oid?oid:""), optarg); - break; + + /* Test parameters */ case 'c': /* critical time threshold */ if (strspn (optarg, "0123456789:,") < strlen (optarg)) { printf ("Invalid critical threshold: %s\n", optarg); print_usage (); exit (STATE_UNKNOWN); } - for (ptr = optarg, jj = 0; ptr && jj < MAX_OIDS; jj++) { + for (ptr = optarg; ptr && jj < MAX_OIDS; jj++) { if (lu_getll (&lower_crit_lim[jj], ptr) == 1) eval_method[jj] |= CRIT_LT; if (lu_getul (&upper_crit_lim[jj], ptr) == 1) @@ -486,37 +538,36 @@ process_arguments (int argc, char **argv) print_usage (); exit (STATE_UNKNOWN); } - for (ptr = optarg, jj = 0; ptr && jj < MAX_OIDS; jj++) { - if (lu_getll (&lower_warn_lim[jj], ptr) == 1) - eval_method[jj] |= WARN_LT; - if (lu_getul (&upper_warn_lim[jj], ptr) == 1) - eval_method[jj] |= WARN_GT; + for (ptr = optarg; ptr && ii < MAX_OIDS; ii++) { + if (lu_getll (&lower_warn_lim[ii], ptr) == 1) + eval_method[ii] |= WARN_LT; + if (lu_getul (&upper_warn_lim[ii], ptr) == 1) + eval_method[ii] |= WARN_GT; (ptr = index (ptr, ',')) ? ptr++ : ptr; } break; - case 'H': /* Host or server */ - server_address = strscpy (server_address, optarg); - break; - case 'C': /* group or community */ - community = strscpy (community, optarg); - break; case 'o': /* object identifier */ + case 'e': /* PRELIMINARY - may change */ + case 'E': /* PRELIMINARY - may change */ for (ptr = optarg; (ptr = index (ptr, ',')); ptr++) ptr[0] = ' '; /* relpace comma with space */ for (ptr = optarg; (ptr = index (ptr, ' ')); ptr++) j++; /* count OIDs */ asprintf (&oid, "%s %s", (oid?oid:""), optarg); - break; - case 'd': /* delimiter */ - delimiter = strscpy (delimiter, optarg); - break; - case 'D': /* output-delimiter */ - output_delim = strscpy (output_delim, optarg); + if (c == 'E' || c == 'e') { + jj++; + ii++; + } + if (c == 'E') + eval_method[j+1] |= WARN_PRESENT; + else if (c == 'e') + eval_method[j+1] |= CRIT_PRESENT; break; case 's': /* string or substring */ strncpy (string_value, optarg, sizeof (string_value) - 1); string_value[sizeof (string_value) - 1] = 0; eval_method[jj++] = CRIT_STRING; + ii++; break; case 'R': /* regex */ #ifdef HAVE_REGEX_H @@ -534,11 +585,20 @@ process_arguments (int argc, char **argv) return ERROR; } eval_method[jj++] = CRIT_REGEX; + ii++; #else - printf ("SNMP UNKNOWN: call for regex which was not a compiled option"); + printf ("%s UNKNOWN: call for regex which was not a compiled option", label); exit (STATE_UNKNOWN); #endif break; + + /* Format */ + case 'd': /* delimiter */ + delimiter = strscpy (delimiter, optarg); + break; + case 'D': /* output-delimiter */ + output_delim = strscpy (output_delim, optarg); + break; case 'l': /* label */ label = optarg; nlabels++; @@ -601,12 +661,6 @@ process_arguments (int argc, char **argv) unitv[nunits - 1] = ptr; } break; - case 'p': /* TCP port number */ - port = strscpy(port, optarg); - break; - case 'm': /* List of MIBS */ - miblist = strscpy(miblist, optarg); - break; } } @@ -641,36 +695,66 @@ int validate_arguments () { - if (community == NULL) - asprintf (&community, DEFAULT_COMMUNITY); - - if (delimiter == NULL) - asprintf (&delimiter, DEFAULT_DELIMITER); + /* Need better checks to verify seclevel and authproto choices */ + + if (seclevel == NULL) + asprintf (&seclevel, "noAuthNoPriv"); - if (output_delim == NULL) - asprintf (&output_delim, DEFAULT_OUTPUT_DELIMITER); - if (miblist == NULL) - asprintf (&miblist, DEFAULT_MIBLIST); - - if (label == NULL) - asprintf (&label, "SNMP"); - - if (units == NULL) - asprintf (&units, ""); + if (authproto == NULL ) + asprintf(&authproto, DEFAULT_AUTH_PROTOCOL); + + + + if (proto == NULL || (strcmp(proto,DEFAULT_PROTOCOL) == 0) ) { /* default protocol version */ + asprintf(&proto, DEFAULT_PROTOCOL); + asprintf(&authpriv, "%s%s", "-c ", community); + } + else if ( strcmp (proto, "3") == 0 ) { /* snmpv3 args */ + asprintf(&proto, "%s", "3"); + + if ( (strcmp(seclevel, "noAuthNoPriv") == 0) || seclevel == NULL ) { + asprintf(&authpriv, "%s", "-l noAuthNoPriv" ); + } + else if ( strcmp(seclevel, "authNoPriv") == 0 ) { + if ( secname == NULL || authpasswd == NULL) { + printf ("Missing secname (%s) or authpassword (%s) ! \n",secname, authpasswd ); + print_usage (); + exit (STATE_UNKNOWN); + } + asprintf(&authpriv, "-l authNoPriv -a %s -u %s -A %s ", authproto, secname, authpasswd); + } + else if ( strcmp(seclevel, "authPriv") == 0 ) { + if ( secname == NULL || authpasswd == NULL || privpasswd == NULL ) { + printf ("Missing secname (%s), authpassword (%s), or privpasswd (%s)! \n",secname, authpasswd,privpasswd ); + print_usage (); + exit (STATE_UNKNOWN); + } + asprintf(&authpriv, "-l authPriv -a %s -u %s -A %s -x DES -X %s ", authproto, secname, authpasswd, privpasswd); + } + + + } + else { + printf ("Invalid SNMP version: %s\n", proto); + print_usage (); + exit (STATE_UNKNOWN); + } + + + return OK; } - + void print_help (void) { - print_revision (PROGNAME, REVISION); + print_revision (progname, REVISION); printf - ("Copyright (c) %s %s <%s>\n\n%s\n", - COPYRIGHT, AUTHOR, EMAIL, SUMMARY); + ("Copyright (c) %s %s <%s>\n\n%s\n", COPYRIGHT, AUTHOR, EMAIL, SUMMARY); print_usage (); printf ("\nOptions:\n" LONGOPTIONS "\n" DESCRIPTION "\n" NOTES "\n", @@ -685,7 +769,7 @@ print_usage (void) ("Usage:\n" " %s %s\n" " %s (-h | --help) for detailed help\n" " %s (-V | --version) for version information\n", - PROGNAME, OPTIONS, PROGNAME, PROGNAME); + progname, OPTIONS, progname, progname); }