X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=plugins%2Fcheck_snmp.c;h=2bc6024f42bab4ca06475ab69473f3d1fc64e729;hb=eaf3cb27f4b5bae479014a34c7decd3feedcf8fd;hp=bb3d295e0f31fe0a14b822a7ccfeaf5f72648d1e;hpb=1295c936519d5e84e94d2751fca5941a8fb8a850;p=nagiosplug.git diff --git a/plugins/check_snmp.c b/plugins/check_snmp.c index bb3d295..2bc6024 100644 --- a/plugins/check_snmp.c +++ b/plugins/check_snmp.c @@ -59,6 +59,25 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net"; #define MAX_OIDS 8 +/* Gobble to string - stop incrementing c when c[0] match one of the + * characters in s */ +#define GOBBLE_TOS(c, s) while(c[0]!='\0' && strchr(s, c[0])==NULL) { c++; } +/* Given c, keep track of backslashes (bk) and double-quotes (dq) + * from c[0] */ +#define COUNT_SEQ(c, bk, dq) switch(c[0]) {\ + case '\\': \ + if (bk) bk--; \ + else bk++; \ + break; \ + case '"': \ + if (!dq) { dq++; } \ + else if(!bk) { dq--; } \ + else { bk--; } \ + break; \ + } + + + int process_arguments (int, char **); int validate_arguments (void); char *thisarg (char *str); @@ -117,7 +136,8 @@ int needmibs = FALSE; int main (int argc, char **argv) { - int i; + int i, len, line; + unsigned int bk_count = 0, dq_count = 0; int iresult = STATE_UNKNOWN; int result = STATE_UNKNOWN; int return_code = 0; @@ -126,6 +146,7 @@ main (int argc, char **argv) char *cl_hidden_auth = NULL; char *oidname = NULL; char *response = NULL; + char *mult_resp = NULL; char *outbuff; char *ptr = NULL; char *show = NULL; @@ -186,7 +207,7 @@ main (int argc, char **argv) }else{ snmpcmd = strdup (PATH_TO_SNMPGET); } - + /* 9 arguments to pass before authpriv options + 1 for host and numoids. Add one for terminating NULL */ command_line = calloc (9 + numauthpriv + 1 + numoids + 1, sizeof (char *)); command_line[0] = snmpcmd; @@ -249,21 +270,23 @@ main (int argc, char **argv) } } - for (i = 0; i < chld_out.lines; i++) { + for (line=0, i=0; line < chld_out.lines; line++, i++) { const char *conv = "%.0f"; - ptr = chld_out.line[i]; + ptr = chld_out.line[line]; oidname = strpcpy (oidname, ptr, delimiter); response = strstr (ptr, delimiter); + if (response == NULL) + break; + if (verbose > 2) { - printf("Processing line %i\n oidname: %s\n response: %s\n", i+1, oidname, response); + printf("Processing oid %i (line %i)\n oidname: %s\n response: %s\n", i+1, line+1, oidname, response); } - /* We strip out the datatype indicator for PHBs */ - /* Clean up type array - Sol10 does not necessarily zero it out */ bzero(type, sizeof(type)); + /* We strip out the datatype indicator for PHBs */ if (strstr (response, "Gauge: ")) show = strstr (response, "Gauge: ") + 7; else if (strstr (response, "Gauge32: ")) @@ -281,6 +304,39 @@ main (int argc, char **argv) else if (strstr (response, "STRING: ")) { show = strstr (response, "STRING: ") + 8; conv = "%.10g"; + + /* Get the rest of the string on multi-line strings */ + ptr = show; + COUNT_SEQ(ptr, bk_count, dq_count) + while (dq_count && ptr[0] != '\n' && ptr[0] != '\0') { + ptr++; + GOBBLE_TOS(ptr, "\n\"\\") + COUNT_SEQ(ptr, bk_count, dq_count) + } + + if (dq_count) { /* unfinished line */ + /* copy show verbatim first */ + if (!mult_resp) mult_resp = strdup(""); + asprintf (&mult_resp, "%s%s:\n%s\n", mult_resp, oids[i], show); + /* then strip out unmatched double-quote from single-line output */ + if (show[0] == '"') show++; + + /* Keep reading until we match end of double-quoted string */ + for (line++; line < chld_out.lines; line++) { + ptr = chld_out.line[line]; + asprintf (&mult_resp, "%s%s\n", mult_resp, ptr); + + COUNT_SEQ(ptr, bk_count, dq_count) + while (dq_count && ptr[0] != '\n' && ptr[0] != '\0') { + ptr++; + GOBBLE_TOS(ptr, "\n\"\\") + COUNT_SEQ(ptr, bk_count, dq_count) + } + /* Break for loop before next line increment when done */ + if (!dq_count) break; + } + } + } else if (strstr (response, "Timeticks: ")) show = strstr (response, "Timeticks: "); @@ -349,10 +405,14 @@ main (int argc, char **argv) if (nunits > (size_t)0 && (size_t)i < nunits && unitv[i] != NULL) asprintf (&outbuff, "%s %s", outbuff, unitv[i]); - if (is_numeric(show)) { + /* Write perfdata with whatever can be parsed by strtod, if possible */ + ptr = NULL; + strtod(show, &ptr); + if (ptr > show) { strncat(perfstr, oidname, sizeof(perfstr)-strlen(perfstr)-1); strncat(perfstr, "=", sizeof(perfstr)-strlen(perfstr)-1); - strncat(perfstr, show, sizeof(perfstr)-strlen(perfstr)-1); + len = sizeof(perfstr)-strlen(perfstr)-1; + strncat(perfstr, show, len>ptr-show ? ptr-show : len); if (type) strncat(perfstr, type, sizeof(perfstr)-strlen(perfstr)-1); @@ -360,7 +420,8 @@ main (int argc, char **argv) } } - printf ("%s %s -%s %s \n", label, state_text (result), outbuff, perfstr); + printf ("%s %s -%s %s\n", label, state_text (result), outbuff, perfstr); + if (mult_resp) printf ("%s", mult_resp); return result; } @@ -504,7 +565,7 @@ process_arguments (int argc, char **argv) */ needmibs = TRUE; } - oids = calloc(MAX_OIDS, sizeof (char *)); + if (!oids) oids = calloc(MAX_OIDS, sizeof (char *)); for (ptr = strtok(optarg, ", "); ptr != NULL && j < MAX_OIDS; ptr = strtok(NULL, ", "), j++) { oids[j] = strdup(ptr); } @@ -800,10 +861,10 @@ print_help (void) print_usage (); - printf (_(UT_HELP_VRSN)); - printf (_(UT_EXTRA_OPTS)); + printf (UT_HELP_VRSN); + printf (UT_EXTRA_OPTS); - printf (_(UT_HOST_PORT), 'p', DEFAULT_PORT); + printf (UT_HOST_PORT, 'p', DEFAULT_PORT); /* SNMP and Authentication Protocol */ printf (" %s\n", "-n, --next"); @@ -861,11 +922,11 @@ print_help (void) printf (" %s\n", "-D, --output-delimiter=STRING"); printf (" %s\n", _("Separates output on multiple OID requests")); - printf (_(UT_TIMEOUT), DEFAULT_SOCKET_TIMEOUT); + printf (UT_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); printf (" %s\n", "-e, --retries=INTEGER"); printf (" %s\n", _("Number of retries to be used in the requests")); - printf (_(UT_VERBOSE)); + printf (UT_VERBOSE); printf ("\n"); printf ("%s\n", _("This plugin uses the 'snmpget' command included with the NET-SNMP package.")); @@ -877,17 +938,14 @@ print_help (void) printf (" %s\n", _("- Multiple OIDs may be indicated by a comma- or space-delimited list (lists with")); printf (" %s\n", _("internal spaces must be quoted) [max 8 OIDs]")); - printf(" -%s", _(UT_THRESHOLDS_NOTES)); + printf(" -%s", UT_THRESHOLDS_NOTES); printf (" %s\n", _("- When checking multiple OIDs, separate ranges by commas like '-w 1:10,1:,:20'")); printf (" %s\n", _("- Note that only one string and one regex may be checked at present")); printf (" %s\n", _("- All evaluation methods other than PR, STR, and SUBSTR expect that the value")); printf (" %s\n", _("returned from the SNMP query is an unsigned integer.")); -#ifdef NP_EXTRA_OPTS - printf (" -%s", _(UT_EXTRA_OPTS_NOTES)); -#endif - printf (_(UT_SUPPORT)); + printf (UT_SUPPORT); } @@ -895,7 +953,7 @@ print_help (void) void print_usage (void) { - printf (_("Usage:")); + printf ("%s\n", _("Usage:")); printf ("%s -H -o [-w warn_range] [-c crit_range]\n",progname); printf ("[-C community] [-s string] [-r regex] [-R regexi] [-t timeout] [-e retries]\n"); printf ("[-l label] [-u units] [-p port-number] [-d delimiter] [-D output-delimiter]\n");