diff options
| -rw-r--r-- | plugins/check_snmp.c | 125 |
1 files changed, 113 insertions, 12 deletions
diff --git a/plugins/check_snmp.c b/plugins/check_snmp.c index 2bc6024f..82d77c4c 100644 --- a/plugins/check_snmp.c +++ b/plugins/check_snmp.c | |||
| @@ -131,12 +131,15 @@ char *delimiter; | |||
| 131 | char *output_delim; | 131 | char *output_delim; |
| 132 | char *miblist = NULL; | 132 | char *miblist = NULL; |
| 133 | int needmibs = FALSE; | 133 | int needmibs = FALSE; |
| 134 | int calculate_rate = 0; | ||
| 135 | state_data *previous_state; | ||
| 136 | double previous_value[MAX_OIDS]; | ||
| 134 | 137 | ||
| 135 | 138 | ||
| 136 | int | 139 | int |
| 137 | main (int argc, char **argv) | 140 | main (int argc, char **argv) |
| 138 | { | 141 | { |
| 139 | int i, len, line; | 142 | int i, len, line, total_oids; |
| 140 | unsigned int bk_count = 0, dq_count = 0; | 143 | unsigned int bk_count = 0, dq_count = 0; |
| 141 | int iresult = STATE_UNKNOWN; | 144 | int iresult = STATE_UNKNOWN; |
| 142 | int result = STATE_UNKNOWN; | 145 | int result = STATE_UNKNOWN; |
| @@ -154,6 +157,15 @@ main (int argc, char **argv) | |||
| 154 | char *th_crit=NULL; | 157 | char *th_crit=NULL; |
| 155 | char type[8] = ""; | 158 | char type[8] = ""; |
| 156 | output chld_out, chld_err; | 159 | output chld_out, chld_err; |
| 160 | char *previous_string=NULL; | ||
| 161 | char *ap=NULL; | ||
| 162 | char *state_string=NULL; | ||
| 163 | size_t response_length, current_length, string_length; | ||
| 164 | char *temp_string=NULL; | ||
| 165 | int is_numeric=0; | ||
| 166 | time_t current_time; | ||
| 167 | double temp_double; | ||
| 168 | time_t duration; | ||
| 157 | 169 | ||
| 158 | setlocale (LC_ALL, ""); | 170 | setlocale (LC_ALL, ""); |
| 159 | bindtextdomain (PACKAGE, LOCALEDIR); | 171 | bindtextdomain (PACKAGE, LOCALEDIR); |
| @@ -173,12 +185,33 @@ main (int argc, char **argv) | |||
| 173 | timeout_interval = DEFAULT_TIMEOUT; | 185 | timeout_interval = DEFAULT_TIMEOUT; |
| 174 | retries = DEFAULT_RETRIES; | 186 | retries = DEFAULT_RETRIES; |
| 175 | 187 | ||
| 188 | np_init( (char *) progname, argc, argv ); | ||
| 189 | |||
| 176 | /* Parse extra opts if any */ | 190 | /* Parse extra opts if any */ |
| 177 | argv=np_extra_opts (&argc, argv, progname); | 191 | argv=np_extra_opts (&argc, argv, progname); |
| 178 | 192 | ||
| 193 | np_set_args(argc, argv); | ||
| 194 | |||
| 179 | if (process_arguments (argc, argv) == ERROR) | 195 | if (process_arguments (argc, argv) == ERROR) |
| 180 | usage4 (_("Could not parse arguments")); | 196 | usage4 (_("Could not parse arguments")); |
| 181 | 197 | ||
| 198 | if(calculate_rate) { | ||
| 199 | if (!strcmp(label, "SNMP")) | ||
| 200 | label = strdup("SNMP RATE"); | ||
| 201 | time(¤t_time); | ||
| 202 | i=0; | ||
| 203 | previous_state = np_state_read(); | ||
| 204 | if(previous_state!=NULL) { | ||
| 205 | /* Split colon separated values */ | ||
| 206 | previous_string = strdup((char *) previous_state->data); | ||
| 207 | while((ap = strsep(&previous_string, ":")) != NULL) { | ||
| 208 | if(verbose>2) | ||
| 209 | printf("State for %d=%s\n", i, ap); | ||
| 210 | previous_value[i++]=strtod(ap,NULL); | ||
| 211 | } | ||
| 212 | } | ||
| 213 | } | ||
| 214 | |||
| 182 | /* Populate the thresholds */ | 215 | /* Populate the thresholds */ |
| 183 | th_warn=warning_thresholds; | 216 | th_warn=warning_thresholds; |
| 184 | th_crit=critical_thresholds; | 217 | th_crit=critical_thresholds; |
| @@ -287,20 +320,30 @@ main (int argc, char **argv) | |||
| 287 | bzero(type, sizeof(type)); | 320 | bzero(type, sizeof(type)); |
| 288 | 321 | ||
| 289 | /* We strip out the datatype indicator for PHBs */ | 322 | /* We strip out the datatype indicator for PHBs */ |
| 290 | if (strstr (response, "Gauge: ")) | 323 | if (strstr (response, "Gauge: ")) { |
| 291 | show = strstr (response, "Gauge: ") + 7; | 324 | show = strstr (response, "Gauge: ") + 7; |
| 292 | else if (strstr (response, "Gauge32: ")) | 325 | is_numeric++; |
| 326 | } | ||
| 327 | else if (strstr (response, "Gauge32: ")) { | ||
| 293 | show = strstr (response, "Gauge32: ") + 9; | 328 | show = strstr (response, "Gauge32: ") + 9; |
| 329 | is_numeric++; | ||
| 330 | } | ||
| 294 | else if (strstr (response, "Counter32: ")) { | 331 | else if (strstr (response, "Counter32: ")) { |
| 295 | show = strstr (response, "Counter32: ") + 11; | 332 | show = strstr (response, "Counter32: ") + 11; |
| 296 | strcpy(type, "c"); | 333 | is_numeric++; |
| 334 | if(!calculate_rate) | ||
| 335 | strcpy(type, "c"); | ||
| 297 | } | 336 | } |
| 298 | else if (strstr (response, "Counter64: ")) { | 337 | else if (strstr (response, "Counter64: ")) { |
| 299 | show = strstr (response, "Counter64: ") + 11; | 338 | show = strstr (response, "Counter64: ") + 11; |
| 300 | strcpy(type, "c"); | 339 | is_numeric++; |
| 340 | if(!calculate_rate) | ||
| 341 | strcpy(type, "c"); | ||
| 301 | } | 342 | } |
| 302 | else if (strstr (response, "INTEGER: ")) | 343 | else if (strstr (response, "INTEGER: ")) { |
| 303 | show = strstr (response, "INTEGER: ") + 9; | 344 | show = strstr (response, "INTEGER: ") + 9; |
| 345 | is_numeric++; | ||
| 346 | } | ||
| 304 | else if (strstr (response, "STRING: ")) { | 347 | else if (strstr (response, "STRING: ")) { |
| 305 | show = strstr (response, "STRING: ") + 8; | 348 | show = strstr (response, "STRING: ") + 8; |
| 306 | conv = "%.10g"; | 349 | conv = "%.10g"; |
| @@ -345,14 +388,26 @@ main (int argc, char **argv) | |||
| 345 | 388 | ||
| 346 | iresult = STATE_DEPENDENT; | 389 | iresult = STATE_DEPENDENT; |
| 347 | 390 | ||
| 348 | /* Process this block for integer comparisons */ | 391 | /* Process this block for numeric comparisons */ |
| 349 | if (thlds[i]->warning || thlds[i]->critical) { | 392 | if (is_numeric) { |
| 350 | ptr = strpbrk (show, "0123456789"); | 393 | ptr = strpbrk (show, "0123456789"); |
| 351 | if (ptr == NULL) | 394 | if (ptr == NULL) |
| 352 | die (STATE_UNKNOWN,_("No valid data returned")); | 395 | die (STATE_UNKNOWN,_("No valid data returned")); |
| 353 | response_value[i] = strtod (ptr, NULL); | 396 | response_value[i] = strtod (ptr, NULL); |
| 354 | iresult = get_status(response_value[i], thlds[i]); | 397 | |
| 355 | asprintf (&show, conv, response_value[i]); | 398 | if(calculate_rate) { |
| 399 | if (previous_state!=NULL) { | ||
| 400 | duration = current_time-previous_state->time; | ||
| 401 | if(duration<=0) | ||
| 402 | die(STATE_UNKNOWN,_("Time duration between plugin calls is invalid")); | ||
| 403 | temp_double = (response_value[i]-previous_value[i])/duration; | ||
| 404 | iresult = get_status(temp_double, thlds[i]); | ||
| 405 | asprintf (&show, conv, temp_double); | ||
| 406 | } | ||
| 407 | } else { | ||
| 408 | iresult = get_status(response_value[i], thlds[i]); | ||
| 409 | asprintf (&show, conv, response_value[i]); | ||
| 410 | } | ||
| 356 | } | 411 | } |
| 357 | 412 | ||
| 358 | /* Process this block for string matching */ | 413 | /* Process this block for string matching */ |
| @@ -380,6 +435,7 @@ main (int argc, char **argv) | |||
| 380 | } | 435 | } |
| 381 | 436 | ||
| 382 | /* Process this block for existence-nonexistence checks */ | 437 | /* Process this block for existence-nonexistence checks */ |
| 438 | /* TV: Should this be outside of this else block? */ | ||
| 383 | else { | 439 | else { |
| 384 | if (eval_method[i] & CRIT_PRESENT) | 440 | if (eval_method[i] & CRIT_PRESENT) |
| 385 | iresult = STATE_CRITICAL; | 441 | iresult = STATE_CRITICAL; |
| @@ -419,6 +475,44 @@ main (int argc, char **argv) | |||
| 419 | strncat(perfstr, " ", sizeof(perfstr)-strlen(perfstr)-1); | 475 | strncat(perfstr, " ", sizeof(perfstr)-strlen(perfstr)-1); |
| 420 | } | 476 | } |
| 421 | } | 477 | } |
| 478 | total_oids=i; | ||
| 479 | |||
| 480 | /* Save state data, as all data collected now */ | ||
| 481 | if(calculate_rate) { | ||
| 482 | string_length=1024; | ||
| 483 | state_string=malloc(string_length); | ||
| 484 | if(state_string==NULL) | ||
| 485 | die(STATE_UNKNOWN, _("Cannot malloc")); | ||
| 486 | |||
| 487 | current_length=0; | ||
| 488 | for(i=0; i<total_oids; i++) { | ||
| 489 | asprintf(&temp_string,"%.0f",response_value[i]); | ||
| 490 | if(temp_string==NULL) | ||
| 491 | die(STATE_UNKNOWN,_("Cannot asprintf()")); | ||
| 492 | response_length = strlen(temp_string); | ||
| 493 | if(current_length+response_length>string_length) { | ||
| 494 | string_length=current_length+1024; | ||
| 495 | state_string=realloc(state_string,string_length); | ||
| 496 | if(state_string==NULL) | ||
| 497 | die(STATE_UNKNOWN, _("Cannot realloc()")); | ||
| 498 | } | ||
| 499 | strcpy(&state_string[current_length],temp_string); | ||
| 500 | current_length=current_length+response_length; | ||
| 501 | state_string[current_length]=':'; | ||
| 502 | current_length++; | ||
| 503 | free(temp_string); | ||
| 504 | } | ||
| 505 | state_string[--current_length]='\0'; | ||
| 506 | if (verbose > 2) | ||
| 507 | printf("State string=%s\n",state_string); | ||
| 508 | |||
| 509 | /* This is not strictly the same as time now, but any subtle variations will cancel out */ | ||
| 510 | np_state_write_string(current_time, state_string ); | ||
| 511 | if(previous_state==NULL) { | ||
| 512 | /* Or should this be highest state? */ | ||
| 513 | die( STATE_OK, _("No previous data to calculate rate - assume okay" ) ); | ||
| 514 | } | ||
| 515 | } | ||
| 422 | 516 | ||
| 423 | printf ("%s %s -%s %s\n", label, state_text (result), outbuff, perfstr); | 517 | printf ("%s %s -%s %s\n", label, state_text (result), outbuff, perfstr); |
| 424 | if (mult_resp) printf ("%s", mult_resp); | 518 | if (mult_resp) printf ("%s", mult_resp); |
| @@ -462,6 +556,7 @@ process_arguments (int argc, char **argv) | |||
| 462 | {"authpasswd", required_argument, 0, 'A'}, | 556 | {"authpasswd", required_argument, 0, 'A'}, |
| 463 | {"privpasswd", required_argument, 0, 'X'}, | 557 | {"privpasswd", required_argument, 0, 'X'}, |
| 464 | {"next", no_argument, 0, 'n'}, | 558 | {"next", no_argument, 0, 'n'}, |
| 559 | {"calculate-rate", no_argument, 0, CHAR_MAX+1}, | ||
| 465 | {0, 0, 0, 0} | 560 | {0, 0, 0, 0} |
| 466 | }; | 561 | }; |
| 467 | 562 | ||
| @@ -666,7 +761,11 @@ process_arguments (int argc, char **argv) | |||
| 666 | unitv[nunits - 1] = ptr; | 761 | unitv[nunits - 1] = ptr; |
| 667 | } | 762 | } |
| 668 | break; | 763 | break; |
| 669 | 764 | case CHAR_MAX+1: | |
| 765 | if(calculate_rate==0) | ||
| 766 | np_enable_state(NULL, 1); | ||
| 767 | calculate_rate = 1; | ||
| 768 | break; | ||
| 670 | } | 769 | } |
| 671 | } | 770 | } |
| 672 | 771 | ||
| @@ -905,6 +1004,8 @@ print_help (void) | |||
| 905 | printf (" %s\n", _("Warning threshold range(s)")); | 1004 | printf (" %s\n", _("Warning threshold range(s)")); |
| 906 | printf (" %s\n", "-c, --critical=THRESHOLD(s)"); | 1005 | printf (" %s\n", "-c, --critical=THRESHOLD(s)"); |
| 907 | printf (" %s\n", _("Critical threshold range(s)")); | 1006 | printf (" %s\n", _("Critical threshold range(s)")); |
| 1007 | printf (" %s\n", "--calculate-rate"); | ||
| 1008 | printf (" %s\n", _("Values will be converted to rate per second")); | ||
| 908 | 1009 | ||
| 909 | /* Tests Against Strings */ | 1010 | /* Tests Against Strings */ |
| 910 | printf (" %s\n", "-s, --string=STRING"); | 1011 | printf (" %s\n", "-s, --string=STRING"); |
| @@ -914,7 +1015,7 @@ print_help (void) | |||
| 914 | printf (" %s\n", "-R, --eregi=REGEX"); | 1015 | printf (" %s\n", "-R, --eregi=REGEX"); |
| 915 | printf (" %s\n", _("Return OK state (for that OID) if case-insensitive extended REGEX matches")); | 1016 | printf (" %s\n", _("Return OK state (for that OID) if case-insensitive extended REGEX matches")); |
| 916 | printf (" %s\n", "-l, --label=STRING"); | 1017 | printf (" %s\n", "-l, --label=STRING"); |
| 917 | printf (" %s\n", _("Prefix label for output from plugin (default -s 'SNMP')")); | 1018 | printf (" %s\n", _("Prefix label for output from plugin (default -l 'SNMP')")); |
| 918 | 1019 | ||
| 919 | /* Output Formatting */ | 1020 | /* Output Formatting */ |
| 920 | printf (" %s\n", "-u, --units=STRING"); | 1021 | printf (" %s\n", "-u, --units=STRING"); |
