diff options
author | Robin Sonefors <robin.sonefors@op5.com> | 2013-01-29 13:18:32 +0100 |
---|---|---|
committer | Robin Sonefors <robin.sonefors@op5.com> | 2013-01-29 15:30:02 +0100 |
commit | d87395ec3d4bec777ab92fc74c8370877171259f (patch) | |
tree | f9ff43b14123b51232b6d747af10e6aedba34d2e /plugins | |
parent | f4bbd88a9f91bfbfbe590b3252043392e7248988 (diff) | |
download | monitoring-plugins-d87395ec3d4bec777ab92fc74c8370877171259f.tar.gz |
check_snmp: Dynamically grow all data structures
Before this patch, there was a constant, MAX_OIDS, that determined the
amount of slots most (but not all - see labels) array data structures
would have. It was set to 8.
Some users would like to use more than that, but rather than bumping the
constant, let's use the same type of logic we already use for labels -
grow the space 8 slots at a time. This will allow us to potentially
support an infinite amount of oids - or at least as many as the
packetsize on the SNMP server allows, which is usually significantly
smaller than infinity, yet often larger than 8.
Signed-off-by: Robin Sonefors <robin.sonefors@op5.com>
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/check_snmp.c | 79 |
1 files changed, 59 insertions, 20 deletions
diff --git a/plugins/check_snmp.c b/plugins/check_snmp.c index 7c5d0ec5..28354b0d 100644 --- a/plugins/check_snmp.c +++ b/plugins/check_snmp.c | |||
@@ -57,7 +57,7 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net"; | |||
57 | #define WARN_STRING 16 | 57 | #define WARN_STRING 16 |
58 | #define WARN_REGEX 32 | 58 | #define WARN_REGEX 32 |
59 | 59 | ||
60 | #define MAX_OIDS 8 | 60 | #define OID_COUNT_STEP 8 |
61 | 61 | ||
62 | /* Longopts only arguments */ | 62 | /* Longopts only arguments */ |
63 | #define L_CALCULATE_RATE CHAR_MAX+1 | 63 | #define L_CALCULATE_RATE CHAR_MAX+1 |
@@ -111,6 +111,7 @@ char *privproto = NULL; | |||
111 | char *authpasswd = NULL; | 111 | char *authpasswd = NULL; |
112 | char *privpasswd = NULL; | 112 | char *privpasswd = NULL; |
113 | char **oids = NULL; | 113 | char **oids = NULL; |
114 | size_t oids_size = NULL; | ||
114 | char *label; | 115 | char *label; |
115 | char *units; | 116 | char *units; |
116 | char *port; | 117 | char *port; |
@@ -120,19 +121,22 @@ int invert_search=0; | |||
120 | char **labels = NULL; | 121 | char **labels = NULL; |
121 | char **unitv = NULL; | 122 | char **unitv = NULL; |
122 | size_t nlabels = 0; | 123 | size_t nlabels = 0; |
123 | size_t labels_size = 8; | 124 | size_t labels_size = OID_COUNT_STEP; |
124 | size_t nunits = 0; | 125 | size_t nunits = 0; |
125 | size_t unitv_size = 8; | 126 | size_t unitv_size = OID_COUNT_STEP; |
126 | int numoids = 0; | 127 | int numoids = 0; |
127 | int numauthpriv = 0; | 128 | int numauthpriv = 0; |
128 | int verbose = 0; | 129 | int verbose = 0; |
129 | int usesnmpgetnext = FALSE; | 130 | int usesnmpgetnext = FALSE; |
130 | char *warning_thresholds = NULL; | 131 | char *warning_thresholds = NULL; |
131 | char *critical_thresholds = NULL; | 132 | char *critical_thresholds = NULL; |
132 | thresholds *thlds[MAX_OIDS]; | 133 | thresholds **thlds; |
133 | double response_value[MAX_OIDS]; | 134 | size_t thlds_size = OID_COUNT_STEP; |
135 | double *response_value; | ||
136 | size_t response_size = OID_COUNT_STEP; | ||
134 | int retries = 0; | 137 | int retries = 0; |
135 | int eval_method[MAX_OIDS]; | 138 | int *eval_method; |
139 | size_t eval_size = OID_COUNT_STEP; | ||
136 | char *delimiter; | 140 | char *delimiter; |
137 | char *output_delim; | 141 | char *output_delim; |
138 | char *miblist = NULL; | 142 | char *miblist = NULL; |
@@ -140,7 +144,8 @@ int needmibs = FALSE; | |||
140 | int calculate_rate = 0; | 144 | int calculate_rate = 0; |
141 | int rate_multiplier = 1; | 145 | int rate_multiplier = 1; |
142 | state_data *previous_state; | 146 | state_data *previous_state; |
143 | double previous_value[MAX_OIDS]; | 147 | double *previous_value; |
148 | size_t previous_size = OID_COUNT_STEP; | ||
144 | int perf_labels = 1; | 149 | int perf_labels = 1; |
145 | 150 | ||
146 | 151 | ||
@@ -202,8 +207,11 @@ main (int argc, char **argv) | |||
202 | 207 | ||
203 | labels = malloc (labels_size * sizeof(*labels)); | 208 | labels = malloc (labels_size * sizeof(*labels)); |
204 | unitv = malloc (unitv_size * sizeof(*unitv)); | 209 | unitv = malloc (unitv_size * sizeof(*unitv)); |
205 | for (i = 0; i < MAX_OIDS; i++) | 210 | thlds = malloc (thlds_size * sizeof(*thlds)); |
206 | eval_method[i] = CHECK_UNDEF; | 211 | response_value = malloc (response_size * sizeof(*response_value)); |
212 | previous_value = malloc (previous_size * sizeof(*previous_value)); | ||
213 | eval_method = calloc (eval_size, sizeof(*eval_method)); | ||
214 | oids = calloc(oids_size, sizeof (char *)); | ||
207 | 215 | ||
208 | label = strdup ("SNMP"); | 216 | label = strdup ("SNMP"); |
209 | units = strdup (""); | 217 | units = strdup (""); |
@@ -236,6 +244,10 @@ main (int argc, char **argv) | |||
236 | while((ap = strsep(&previous_string, ":")) != NULL) { | 244 | while((ap = strsep(&previous_string, ":")) != NULL) { |
237 | if(verbose>2) | 245 | if(verbose>2) |
238 | printf("State for %d=%s\n", i, ap); | 246 | printf("State for %d=%s\n", i, ap); |
247 | while (i >= previous_size) { | ||
248 | previous_size += OID_COUNT_STEP; | ||
249 | previous_value = realloc(previous_value, previous_size * sizeof(*previous_value)); | ||
250 | } | ||
239 | previous_value[i++]=strtod(ap,NULL); | 251 | previous_value[i++]=strtod(ap,NULL); |
240 | } | 252 | } |
241 | } | 253 | } |
@@ -251,6 +263,11 @@ main (int argc, char **argv) | |||
251 | w = w ? fix_snmp_range(w) : NULL; | 263 | w = w ? fix_snmp_range(w) : NULL; |
252 | c = c ? fix_snmp_range(c) : NULL; | 264 | c = c ? fix_snmp_range(c) : NULL; |
253 | 265 | ||
266 | while (i >= thlds_size) { | ||
267 | thlds_size += OID_COUNT_STEP; | ||
268 | thlds = realloc(thlds, thlds_size * sizeof(*thlds)); | ||
269 | } | ||
270 | |||
254 | /* Skip empty thresholds, while avoiding segfault */ | 271 | /* Skip empty thresholds, while avoiding segfault */ |
255 | set_thresholds(&thlds[i], | 272 | set_thresholds(&thlds[i], |
256 | w ? strpbrk(w, NP_THRESHOLDS_CHARS) : NULL, | 273 | w ? strpbrk(w, NP_THRESHOLDS_CHARS) : NULL, |
@@ -429,6 +446,10 @@ main (int argc, char **argv) | |||
429 | ptr = strpbrk (show, "0123456789"); | 446 | ptr = strpbrk (show, "0123456789"); |
430 | if (ptr == NULL) | 447 | if (ptr == NULL) |
431 | die (STATE_UNKNOWN,_("No valid data returned (%s)\n"), show); | 448 | die (STATE_UNKNOWN,_("No valid data returned (%s)\n"), show); |
449 | while (i >= response_size) { | ||
450 | response_size += OID_COUNT_STEP; | ||
451 | response_value = realloc(response_value, response_size * sizeof(*response_value)); | ||
452 | } | ||
432 | response_value[i] = strtod (ptr, NULL); | 453 | response_value[i] = strtod (ptr, NULL); |
433 | 454 | ||
434 | if(calculate_rate) { | 455 | if(calculate_rate) { |
@@ -456,7 +477,7 @@ main (int argc, char **argv) | |||
456 | } | 477 | } |
457 | 478 | ||
458 | /* Process this block for string matching */ | 479 | /* Process this block for string matching */ |
459 | else if (eval_method[i] & CRIT_STRING) { | 480 | else if (eval_size > i && eval_method[i] & CRIT_STRING) { |
460 | if (strcmp (show, string_value)) | 481 | if (strcmp (show, string_value)) |
461 | iresult = (invert_search==0) ? STATE_CRITICAL : STATE_OK; | 482 | iresult = (invert_search==0) ? STATE_CRITICAL : STATE_OK; |
462 | else | 483 | else |
@@ -464,7 +485,7 @@ main (int argc, char **argv) | |||
464 | } | 485 | } |
465 | 486 | ||
466 | /* Process this block for regex matching */ | 487 | /* Process this block for regex matching */ |
467 | else if (eval_method[i] & CRIT_REGEX) { | 488 | else if (eval_size > i && eval_method[i] & CRIT_REGEX) { |
468 | excode = regexec (&preg, response, 10, pmatch, eflags); | 489 | excode = regexec (&preg, response, 10, pmatch, eflags); |
469 | if (excode == 0) { | 490 | if (excode == 0) { |
470 | iresult = (invert_search==0) ? STATE_OK : STATE_CRITICAL; | 491 | iresult = (invert_search==0) ? STATE_OK : STATE_CRITICAL; |
@@ -482,9 +503,9 @@ main (int argc, char **argv) | |||
482 | /* Process this block for existence-nonexistence checks */ | 503 | /* Process this block for existence-nonexistence checks */ |
483 | /* TV: Should this be outside of this else block? */ | 504 | /* TV: Should this be outside of this else block? */ |
484 | else { | 505 | else { |
485 | if (eval_method[i] & CRIT_PRESENT) | 506 | if (eval_size > i && eval_method[i] & CRIT_PRESENT) |
486 | iresult = STATE_CRITICAL; | 507 | iresult = STATE_CRITICAL; |
487 | else if (eval_method[i] & WARN_PRESENT) | 508 | else if (eval_size > i && eval_method[i] & WARN_PRESENT) |
488 | iresult = STATE_WARNING; | 509 | iresult = STATE_WARNING; |
489 | else if (response && iresult == STATE_DEPENDENT) | 510 | else if (response && iresult == STATE_DEPENDENT) |
490 | iresult = STATE_OK; | 511 | iresult = STATE_OK; |
@@ -723,23 +744,36 @@ process_arguments (int argc, char **argv) | |||
723 | */ | 744 | */ |
724 | needmibs = TRUE; | 745 | needmibs = TRUE; |
725 | } | 746 | } |
726 | if (!oids) oids = calloc(MAX_OIDS, sizeof (char *)); | 747 | for (ptr = strtok(optarg, ", "); ptr != NULL; ptr = strtok(NULL, ", "), j++) { |
727 | for (ptr = strtok(optarg, ", "); ptr != NULL && j < MAX_OIDS; ptr = strtok(NULL, ", "), j++) { | 748 | while (j >= oids_size) { |
749 | oids_size += OID_COUNT_STEP; | ||
750 | oids = realloc(oids, oids_size * sizeof (*oids)); | ||
751 | } | ||
728 | oids[j] = strdup(ptr); | 752 | oids[j] = strdup(ptr); |
729 | } | 753 | } |
730 | numoids = j; | 754 | numoids = j; |
731 | if (c == 'E' || c == 'e') { | 755 | if (c == 'E' || c == 'e') { |
732 | jj++; | 756 | jj++; |
733 | ii++; | 757 | ii++; |
758 | while (j+1 >= eval_size) { | ||
759 | eval_size += OID_COUNT_STEP; | ||
760 | eval_method = realloc(eval_method, eval_size * sizeof(*eval_method)); | ||
761 | memset(eval_method + eval_size - OID_COUNT_STEP, 0, 8); | ||
762 | } | ||
763 | if (c == 'E') | ||
764 | eval_method[j+1] |= WARN_PRESENT; | ||
765 | else if (c == 'e') | ||
766 | eval_method[j+1] |= CRIT_PRESENT; | ||
734 | } | 767 | } |
735 | if (c == 'E') | ||
736 | eval_method[j+1] |= WARN_PRESENT; | ||
737 | else if (c == 'e') | ||
738 | eval_method[j+1] |= CRIT_PRESENT; | ||
739 | break; | 768 | break; |
740 | case 's': /* string or substring */ | 769 | case 's': /* string or substring */ |
741 | strncpy (string_value, optarg, sizeof (string_value) - 1); | 770 | strncpy (string_value, optarg, sizeof (string_value) - 1); |
742 | string_value[sizeof (string_value) - 1] = 0; | 771 | string_value[sizeof (string_value) - 1] = 0; |
772 | while (jj >= eval_size) { | ||
773 | eval_size += OID_COUNT_STEP; | ||
774 | eval_method = realloc(eval_method, eval_size * sizeof(*eval_method)); | ||
775 | memset(eval_method + eval_size - OID_COUNT_STEP, 0, 8); | ||
776 | } | ||
743 | eval_method[jj++] = CRIT_STRING; | 777 | eval_method[jj++] = CRIT_STRING; |
744 | ii++; | 778 | ii++; |
745 | break; | 779 | break; |
@@ -755,6 +789,11 @@ process_arguments (int argc, char **argv) | |||
755 | printf (_("Could Not Compile Regular Expression")); | 789 | printf (_("Could Not Compile Regular Expression")); |
756 | return ERROR; | 790 | return ERROR; |
757 | } | 791 | } |
792 | while (jj >= eval_size) { | ||
793 | eval_size += OID_COUNT_STEP; | ||
794 | eval_method = realloc(eval_method, eval_size * sizeof(*eval_method)); | ||
795 | memset(eval_method + eval_size - OID_COUNT_STEP, 0, 8); | ||
796 | } | ||
758 | eval_method[jj++] = CRIT_REGEX; | 797 | eval_method[jj++] = CRIT_REGEX; |
759 | ii++; | 798 | ii++; |
760 | break; | 799 | break; |
@@ -1116,7 +1155,7 @@ print_help (void) | |||
1116 | printf ("\n"); | 1155 | printf ("\n"); |
1117 | printf ("%s\n", _("Notes:")); | 1156 | printf ("%s\n", _("Notes:")); |
1118 | printf (" %s\n", _("- Multiple OIDs (and labels) may be indicated by a comma or space-delimited ")); | 1157 | printf (" %s\n", _("- Multiple OIDs (and labels) may be indicated by a comma or space-delimited ")); |
1119 | printf (" %s %i %s\n", _("list (lists with internal spaces must be quoted). Maximum:"), MAX_OIDS, _("OIDs.")); | 1158 | printf (" %s %i %s\n", _("list (lists with internal spaces must be quoted).")); |
1120 | 1159 | ||
1121 | printf(" -%s", UT_THRESHOLDS_NOTES); | 1160 | printf(" -%s", UT_THRESHOLDS_NOTES); |
1122 | 1161 | ||