diff options
author | Thomas Guyot-Sionnest <dermoth@aei.ca> | 2009-05-28 00:52:55 (GMT) |
---|---|---|
committer | Thomas Guyot-Sionnest <dermoth@aei.ca> | 2009-05-28 12:10:49 (GMT) |
commit | 7cb3ae09334796f3b54e4e6438e38c2cc679b360 (patch) | |
tree | 398eb8bf5f022b4d5d158fcf9d39be664dd4fa59 /plugins/check_snmp.c | |
parent | 34fe4d62fe79236d0cd560f06f6e93bf46a41dd0 (diff) | |
download | monitoring-plugins-7cb3ae09334796f3b54e4e6438e38c2cc679b360.tar.gz |
check_snmp: Make use of standard threshold functions
This patch makes use of standard threshold functions. This allows using
doubles as thresholds.
Since SNMP supports only integers, double precision numbers are only
printed when parsed from a STRING type.
In addition, support for printing properly Timeticks type has been added,
and the code has been thoroughly cleaned.
Diffstat (limited to 'plugins/check_snmp.c')
-rw-r--r-- | plugins/check_snmp.c | 250 |
1 files changed, 53 insertions, 197 deletions
diff --git a/plugins/check_snmp.c b/plugins/check_snmp.c index 94b75b9..dff5bcc 100644 --- a/plugins/check_snmp.c +++ b/plugins/check_snmp.c | |||
@@ -53,33 +53,14 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net"; | |||
53 | #define CRIT_PRESENT 1 | 53 | #define CRIT_PRESENT 1 |
54 | #define CRIT_STRING 2 | 54 | #define CRIT_STRING 2 |
55 | #define CRIT_REGEX 4 | 55 | #define CRIT_REGEX 4 |
56 | #define CRIT_GT 8 | 56 | #define WARN_PRESENT 8 |
57 | #define CRIT_LT 16 | 57 | #define WARN_STRING 16 |
58 | #define CRIT_GE 32 | 58 | #define WARN_REGEX 32 |
59 | #define CRIT_LE 64 | ||
60 | #define CRIT_EQ 128 | ||
61 | #define CRIT_NE 256 | ||
62 | #define CRIT_RANGE 512 | ||
63 | #define WARN_PRESENT 1024 | ||
64 | #define WARN_STRING 2048 | ||
65 | #define WARN_REGEX 4096 | ||
66 | #define WARN_GT 8192 | ||
67 | #define WARN_LT 16384 | ||
68 | #define WARN_GE 32768 | ||
69 | #define WARN_LE 65536 | ||
70 | #define WARN_EQ 131072 | ||
71 | #define WARN_NE 262144 | ||
72 | #define WARN_RANGE 524288 | ||
73 | 59 | ||
74 | #define MAX_OIDS 8 | 60 | #define MAX_OIDS 8 |
75 | #define MAX_DELIM_LENGTH 8 | ||
76 | 61 | ||
77 | int process_arguments (int, char **); | 62 | int process_arguments (int, char **); |
78 | int validate_arguments (void); | 63 | int validate_arguments (void); |
79 | char *clarify_message (char *); | ||
80 | int check_num (int); | ||
81 | int llu_getll (unsigned long long *, char *); | ||
82 | int llu_getul (unsigned long long *, char *); | ||
83 | char *thisarg (char *str); | 64 | char *thisarg (char *str); |
84 | char *nextarg (char *str); | 65 | char *nextarg (char *str); |
85 | void print_usage (void); | 66 | void print_usage (void); |
@@ -89,7 +70,6 @@ void print_help (void); | |||
89 | char regex_expect[MAX_INPUT_BUFFER] = ""; | 70 | char regex_expect[MAX_INPUT_BUFFER] = ""; |
90 | regex_t preg; | 71 | regex_t preg; |
91 | regmatch_t pmatch[10]; | 72 | regmatch_t pmatch[10]; |
92 | char timestamp[10] = ""; | ||
93 | char errbuf[MAX_INPUT_BUFFER] = ""; | 73 | char errbuf[MAX_INPUT_BUFFER] = ""; |
94 | char perfstr[MAX_INPUT_BUFFER] = "| "; | 74 | char perfstr[MAX_INPUT_BUFFER] = "| "; |
95 | int cflags = REG_EXTENDED | REG_NOSUB | REG_NEWLINE; | 75 | int cflags = REG_EXTENDED | REG_NOSUB | REG_NEWLINE; |
@@ -122,15 +102,12 @@ int numoids = 0; | |||
122 | int numauthpriv = 0; | 102 | int numauthpriv = 0; |
123 | int verbose = FALSE; | 103 | int verbose = FALSE; |
124 | int usesnmpgetnext = FALSE; | 104 | int usesnmpgetnext = FALSE; |
125 | unsigned long long lower_warn_lim[MAX_OIDS]; | 105 | char *warning_thresholds = NULL; |
126 | unsigned long long upper_warn_lim[MAX_OIDS]; | 106 | char *critical_thresholds = NULL; |
127 | unsigned long long lower_crit_lim[MAX_OIDS]; | 107 | thresholds *thlds[MAX_OIDS]; |
128 | unsigned long long upper_crit_lim[MAX_OIDS]; | 108 | double response_value[MAX_OIDS]; |
129 | unsigned long long response_value[MAX_OIDS]; | ||
130 | int check_warning_value = FALSE; | ||
131 | int check_critical_value = FALSE; | ||
132 | int retries = 0; | 109 | int retries = 0; |
133 | unsigned long long eval_method[MAX_OIDS]; | 110 | int eval_method[MAX_OIDS]; |
134 | char *delimiter; | 111 | char *delimiter; |
135 | char *output_delim; | 112 | char *output_delim; |
136 | char *miblist = NULL; | 113 | char *miblist = NULL; |
@@ -140,7 +117,7 @@ int needmibs = FALSE; | |||
140 | int | 117 | int |
141 | main (int argc, char **argv) | 118 | main (int argc, char **argv) |
142 | { | 119 | { |
143 | int i = 0; | 120 | int i; |
144 | int iresult = STATE_UNKNOWN; | 121 | int iresult = STATE_UNKNOWN; |
145 | int result = STATE_UNKNOWN; | 122 | int result = STATE_UNKNOWN; |
146 | int return_code = 0; | 123 | int return_code = 0; |
@@ -152,6 +129,8 @@ main (int argc, char **argv) | |||
152 | char *outbuff; | 129 | char *outbuff; |
153 | char *ptr = NULL; | 130 | char *ptr = NULL; |
154 | char *show = NULL; | 131 | char *show = NULL; |
132 | char *th_warn=NULL; | ||
133 | char *th_crit=NULL; | ||
155 | char type[8] = ""; | 134 | char type[8] = ""; |
156 | output chld_out, chld_err; | 135 | output chld_out, chld_err; |
157 | 136 | ||
@@ -163,7 +142,6 @@ main (int argc, char **argv) | |||
163 | unitv = malloc (unitv_size); | 142 | unitv = malloc (unitv_size); |
164 | for (i = 0; i < MAX_OIDS; i++) | 143 | for (i = 0; i < MAX_OIDS; i++) |
165 | eval_method[i] = CHECK_UNDEF; | 144 | eval_method[i] = CHECK_UNDEF; |
166 | i = 0; | ||
167 | 145 | ||
168 | label = strdup ("SNMP"); | 146 | label = strdup ("SNMP"); |
169 | units = strdup (""); | 147 | units = strdup (""); |
@@ -171,7 +149,6 @@ main (int argc, char **argv) | |||
171 | outbuff = strdup (""); | 149 | outbuff = strdup (""); |
172 | delimiter = strdup (" = "); | 150 | delimiter = strdup (" = "); |
173 | output_delim = strdup (DEFAULT_OUTPUT_DELIMITER); | 151 | output_delim = strdup (DEFAULT_OUTPUT_DELIMITER); |
174 | /* miblist = strdup (DEFAULT_MIBLIST); */ | ||
175 | timeout_interval = DEFAULT_TIMEOUT; | 152 | timeout_interval = DEFAULT_TIMEOUT; |
176 | retries = DEFAULT_RETRIES; | 153 | retries = DEFAULT_RETRIES; |
177 | 154 | ||
@@ -181,6 +158,28 @@ main (int argc, char **argv) | |||
181 | if (process_arguments (argc, argv) == ERROR) | 158 | if (process_arguments (argc, argv) == ERROR) |
182 | usage4 (_("Could not parse arguments")); | 159 | usage4 (_("Could not parse arguments")); |
183 | 160 | ||
161 | /* Populate the thresholds */ | ||
162 | th_warn=warning_thresholds; | ||
163 | th_crit=critical_thresholds; | ||
164 | for (i=0; i<numoids; i++) { | ||
165 | char *w = th_warn ? strndup(th_warn, strcspn(th_warn, ",")) : NULL; | ||
166 | char *c = th_crit ? strndup(th_crit, strcspn(th_crit, ",")) : NULL; | ||
167 | /* Skip empty thresholds, while avoiding segfault */ | ||
168 | set_thresholds(&thlds[i], | ||
169 | w ? strpbrk(w, NP_THRESHOLDS_CHARS) : NULL, | ||
170 | c ? strpbrk(c, NP_THRESHOLDS_CHARS) : NULL); | ||
171 | if (w) { | ||
172 | th_warn=strchr(th_warn, ','); | ||
173 | if (th_warn) th_warn++; | ||
174 | free(w); | ||
175 | } | ||
176 | if (c) { | ||
177 | th_crit=strchr(th_crit, ','); | ||
178 | if (th_crit) th_crit++; | ||
179 | free(c); | ||
180 | } | ||
181 | } | ||
182 | |||
184 | /* Create the command array to execute */ | 183 | /* Create the command array to execute */ |
185 | if(usesnmpgetnext == TRUE) { | 184 | if(usesnmpgetnext == TRUE) { |
186 | snmpcmd = strdup (PATH_TO_SNMPGETNEXT); | 185 | snmpcmd = strdup (PATH_TO_SNMPGETNEXT); |
@@ -251,6 +250,8 @@ main (int argc, char **argv) | |||
251 | } | 250 | } |
252 | 251 | ||
253 | for (i = 0; i < chld_out.lines; i++) { | 252 | for (i = 0; i < chld_out.lines; i++) { |
253 | const char *conv = "%.0f"; | ||
254 | |||
254 | ptr = chld_out.line[i]; | 255 | ptr = chld_out.line[i]; |
255 | oidname = strpcpy (oidname, ptr, delimiter); | 256 | oidname = strpcpy (oidname, ptr, delimiter); |
256 | response = strstr (ptr, delimiter); | 257 | response = strstr (ptr, delimiter); |
@@ -274,32 +275,25 @@ main (int argc, char **argv) | |||
274 | } | 275 | } |
275 | else if (strstr (response, "INTEGER: ")) | 276 | else if (strstr (response, "INTEGER: ")) |
276 | show = strstr (response, "INTEGER: ") + 9; | 277 | show = strstr (response, "INTEGER: ") + 9; |
277 | else if (strstr (response, "STRING: ")) | 278 | else if (strstr (response, "STRING: ")) { |
278 | show = strstr (response, "STRING: ") + 8; | 279 | show = strstr (response, "STRING: ") + 8; |
280 | conv = "%.10g"; | ||
281 | } | ||
282 | else if (strstr (response, "Timeticks: ")) | ||
283 | show = strstr (response, "Timeticks: "); | ||
279 | else | 284 | else |
280 | show = response; | 285 | show = response; |
281 | 286 | ||
282 | iresult = STATE_DEPENDENT; | 287 | iresult = STATE_DEPENDENT; |
283 | 288 | ||
284 | /* Process this block for integer comparisons */ | 289 | /* Process this block for integer comparisons */ |
285 | if (eval_method[i] & CRIT_GT || | 290 | if (thlds[i]->warning || thlds[i]->critical) { |
286 | eval_method[i] & CRIT_LT || | ||
287 | eval_method[i] & CRIT_GE || | ||
288 | eval_method[i] & CRIT_LE || | ||
289 | eval_method[i] & CRIT_EQ || | ||
290 | eval_method[i] & CRIT_NE || | ||
291 | eval_method[i] & WARN_GT || | ||
292 | eval_method[i] & WARN_LT || | ||
293 | eval_method[i] & WARN_GE || | ||
294 | eval_method[i] & WARN_LE || | ||
295 | eval_method[i] & WARN_EQ || | ||
296 | eval_method[i] & WARN_NE) { | ||
297 | ptr = strpbrk (show, "0123456789"); | 291 | ptr = strpbrk (show, "0123456789"); |
298 | if (ptr == NULL) | 292 | if (ptr == NULL) |
299 | die (STATE_UNKNOWN,_("No valid data returned")); | 293 | die (STATE_UNKNOWN,_("No valid data returned")); |
300 | response_value[i] = strtoul (ptr, NULL, 10); | 294 | response_value[i] = strtod (ptr, NULL); |
301 | iresult = check_num (i); | 295 | iresult = get_status(response_value[i], thlds[i]); |
302 | asprintf (&show, "%llu", response_value[i]); | 296 | asprintf (&show, conv, response_value[i]); |
303 | } | 297 | } |
304 | 298 | ||
305 | /* Process this block for string matching */ | 299 | /* Process this block for string matching */ |
@@ -363,9 +357,6 @@ main (int argc, char **argv) | |||
363 | } | 357 | } |
364 | } | 358 | } |
365 | 359 | ||
366 | /* if (nunits == 1 || i == 1) */ | ||
367 | /* printf ("%s %s -%s %s\n", label, state_text (result), outbuff, units); */ | ||
368 | /* else */ | ||
369 | printf ("%s %s -%s %s \n", label, state_text (result), outbuff, perfstr); | 360 | printf ("%s %s -%s %s \n", label, state_text (result), outbuff, perfstr); |
370 | 361 | ||
371 | return result; | 362 | return result; |
@@ -488,27 +479,11 @@ process_arguments (int argc, char **argv) | |||
488 | break; | 479 | break; |
489 | 480 | ||
490 | /* Test parameters */ | 481 | /* Test parameters */ |
491 | case 'c': /* critical time threshold */ | 482 | case 'c': /* critical threshold */ |
492 | if (strspn (optarg, "0123456789:,") < strlen (optarg)) | 483 | critical_thresholds = optarg; |
493 | usage2 (_("Invalid critical threshold"), optarg); | ||
494 | for (ptr = optarg; ptr && jj < MAX_OIDS; jj++) { | ||
495 | if (llu_getll (&lower_crit_lim[jj], ptr) == 1) | ||
496 | eval_method[jj] |= CRIT_LT; | ||
497 | if (llu_getul (&upper_crit_lim[jj], ptr) == 1) | ||
498 | eval_method[jj] |= CRIT_GT; | ||
499 | (ptr = index (ptr, ',')) ? ptr++ : ptr; | ||
500 | } | ||
501 | break; | 484 | break; |
502 | case 'w': /* warning time threshold */ | 485 | case 'w': /* warning threshold */ |
503 | if (strspn (optarg, "0123456789:,") < strlen (optarg)) | 486 | warning_thresholds = optarg; |
504 | usage2 (_("Invalid warning threshold"), optarg); | ||
505 | for (ptr = optarg; ptr && ii < MAX_OIDS; ii++) { | ||
506 | if (llu_getll (&lower_warn_lim[ii], ptr) == 1) | ||
507 | eval_method[ii] |= WARN_LT; | ||
508 | if (llu_getul (&upper_warn_lim[ii], ptr) == 1) | ||
509 | eval_method[ii] |= WARN_GT; | ||
510 | (ptr = index (ptr, ',')) ? ptr++ : ptr; | ||
511 | } | ||
512 | break; | 487 | break; |
513 | case 'e': /* PRELIMINARY - may change */ | 488 | case 'e': /* PRELIMINARY - may change */ |
514 | case 'E': /* PRELIMINARY - may change */ | 489 | case 'E': /* PRELIMINARY - may change */ |
@@ -758,117 +733,6 @@ validate_arguments () | |||
758 | 733 | ||
759 | 734 | ||
760 | 735 | ||
761 | char * | ||
762 | clarify_message (char *msg) | ||
763 | { | ||
764 | int i = 0; | ||
765 | int foo; | ||
766 | char tmpmsg_c[MAX_INPUT_BUFFER]; | ||
767 | char *tmpmsg = (char *) &tmpmsg_c; | ||
768 | tmpmsg = strcpy (tmpmsg, msg); | ||
769 | if (!strncmp (tmpmsg, " Hex:", 5)) { | ||
770 | tmpmsg = strtok (tmpmsg, ":"); | ||
771 | while ((tmpmsg = strtok (NULL, " "))) { | ||
772 | foo = strtol (tmpmsg, NULL, 16); | ||
773 | /* Translate chars that are not the same value in the printers | ||
774 | * character set. | ||
775 | */ | ||
776 | switch (foo) { | ||
777 | case 208: | ||
778 | { | ||
779 | foo = 197; | ||
780 | break; | ||
781 | } | ||
782 | case 216: | ||
783 | { | ||
784 | foo = 196; | ||
785 | break; | ||
786 | } | ||
787 | } | ||
788 | msg[i] = foo; | ||
789 | i++; | ||
790 | } | ||
791 | msg[i] = 0; | ||
792 | } | ||
793 | return (msg); | ||
794 | } | ||
795 | |||
796 | |||
797 | |||
798 | int | ||
799 | check_num (int i) | ||
800 | { | ||
801 | int result; | ||
802 | result = STATE_OK; | ||
803 | if (eval_method[i] & WARN_GT && eval_method[i] & WARN_LT && | ||
804 | lower_warn_lim[i] > upper_warn_lim[i]) { | ||
805 | if (response_value[i] <= lower_warn_lim[i] && | ||
806 | response_value[i] >= upper_warn_lim[i]) { | ||
807 | result = STATE_WARNING; | ||
808 | } | ||
809 | } | ||
810 | else if | ||
811 | ((eval_method[i] & WARN_GT && response_value[i] > upper_warn_lim[i]) || | ||
812 | (eval_method[i] & WARN_GE && response_value[i] >= upper_warn_lim[i]) || | ||
813 | (eval_method[i] & WARN_LT && response_value[i] < lower_warn_lim[i]) || | ||
814 | (eval_method[i] & WARN_LE && response_value[i] <= lower_warn_lim[i]) || | ||
815 | (eval_method[i] & WARN_EQ && response_value[i] == upper_warn_lim[i]) || | ||
816 | (eval_method[i] & WARN_NE && response_value[i] != upper_warn_lim[i])) { | ||
817 | result = STATE_WARNING; | ||
818 | } | ||
819 | |||
820 | if (eval_method[i] & CRIT_GT && eval_method[i] & CRIT_LT && | ||
821 | lower_crit_lim[i] > upper_crit_lim[i]) { | ||
822 | if (response_value[i] <= lower_crit_lim[i] && | ||
823 | response_value[i] >= upper_crit_lim[i]) { | ||
824 | result = STATE_CRITICAL; | ||
825 | } | ||
826 | } | ||
827 | else if | ||
828 | ((eval_method[i] & CRIT_GT && response_value[i] > upper_crit_lim[i]) || | ||
829 | (eval_method[i] & CRIT_GE && response_value[i] >= upper_crit_lim[i]) || | ||
830 | (eval_method[i] & CRIT_LT && response_value[i] < lower_crit_lim[i]) || | ||
831 | (eval_method[i] & CRIT_LE && response_value[i] <= lower_crit_lim[i]) || | ||
832 | (eval_method[i] & CRIT_EQ && response_value[i] == upper_crit_lim[i]) || | ||
833 | (eval_method[i] & CRIT_NE && response_value[i] != upper_crit_lim[i])) { | ||
834 | result = STATE_CRITICAL; | ||
835 | } | ||
836 | |||
837 | return result; | ||
838 | } | ||
839 | |||
840 | |||
841 | |||
842 | int | ||
843 | llu_getll (unsigned long long *ll, char *str) | ||
844 | { | ||
845 | char tmp[100]; | ||
846 | if (strchr (str, ':') == NULL) | ||
847 | return 0; | ||
848 | if (strchr (str, ',') != NULL && (strchr (str, ',') < strchr (str, ':'))) | ||
849 | return 0; | ||
850 | if (sscanf (str, "%llu%[:]", ll, tmp) == 2) | ||
851 | return 1; | ||
852 | return 0; | ||
853 | } | ||
854 | |||
855 | |||
856 | |||
857 | int | ||
858 | llu_getul (unsigned long long *ul, char *str) | ||
859 | { | ||
860 | char tmp[100]; | ||
861 | if (sscanf (str, "%llu%[^,]", ul, tmp) == 1) | ||
862 | return 1; | ||
863 | if (sscanf (str, ":%llu%[^,]", ul, tmp) == 1) | ||
864 | return 1; | ||
865 | if (sscanf (str, "%*u:%llu%[^,]", ul, tmp) == 1) | ||
866 | return 1; | ||
867 | return 0; | ||
868 | } | ||
869 | |||
870 | |||
871 | |||
872 | /* trim leading whitespace | 736 | /* trim leading whitespace |
873 | if there is a leading quote, make sure it balances */ | 737 | if there is a leading quote, make sure it balances */ |
874 | 738 | ||
@@ -973,10 +837,10 @@ print_help (void) | |||
973 | printf (" %s\n", _("to be the data that should be used in the evaluation.")); | 837 | printf (" %s\n", _("to be the data that should be used in the evaluation.")); |
974 | 838 | ||
975 | /* Tests Against Integers */ | 839 | /* Tests Against Integers */ |
976 | printf (" %s\n", "-w, --warning=INTEGER_RANGE(s)"); | 840 | printf (" %s\n", "-w, --warning=THRESHOLD(s)"); |
977 | printf (" %s\n", _("Range(s) which will not result in a WARNING status")); | 841 | printf (" %s\n", _("Warning threshold range(s)")); |
978 | printf (" %s\n", "-c, --critical=INTEGER_RANGE(s)"); | 842 | printf (" %s\n", "-c, --critical=THRESHOLD(s)"); |
979 | printf (" %s\n", _("Range(s) which will not result in a CRITICAL status")); | 843 | printf (" %s\n", _("Critical threshold range(s)")); |
980 | 844 | ||
981 | /* Tests Against Strings */ | 845 | /* Tests Against Strings */ |
982 | printf (" %s\n", "-s, --string=STRING"); | 846 | printf (" %s\n", "-s, --string=STRING"); |
@@ -1010,16 +874,8 @@ print_help (void) | |||
1010 | printf (" %s\n", _("- Multiple OIDs may be indicated by a comma- or space-delimited list (lists with")); | 874 | printf (" %s\n", _("- Multiple OIDs may be indicated by a comma- or space-delimited list (lists with")); |
1011 | printf (" %s\n", _("internal spaces must be quoted) [max 8 OIDs]")); | 875 | printf (" %s\n", _("internal spaces must be quoted) [max 8 OIDs]")); |
1012 | 876 | ||
1013 | printf (" %s\n", _("- Ranges are inclusive and are indicated with colons. When specified as")); | 877 | printf(" -%s", _(UT_THRESHOLDS_NOTES)); |
1014 | printf (" %s\n", _("'min:max' a STATE_OK will be returned if the result is within the indicated")); | ||
1015 | printf (" %s\n", _("range or is equal to the upper or lower bound. A non-OK state will be")); | ||
1016 | printf (" %s\n", _("returned if the result is outside the specified range.")); | ||
1017 | |||
1018 | printf (" %s\n", _("- If specified in the order 'max:min' a non-OK state will be returned if the")); | ||
1019 | printf (" %s\n", _("result is within the (inclusive) range.")); | ||
1020 | 878 | ||
1021 | printf (" %s\n", _("- Upper or lower bounds may be omitted to skip checking the respective limit.")); | ||
1022 | printf (" %s\n", _("- Bare integers are interpreted as upper limits.")); | ||
1023 | printf (" %s\n", _("- When checking multiple OIDs, separate ranges by commas like '-w 1:10,1:,:20'")); | 879 | printf (" %s\n", _("- When checking multiple OIDs, separate ranges by commas like '-w 1:10,1:,:20'")); |
1024 | printf (" %s\n", _("- Note that only one string and one regex may be checked at present")); | 880 | printf (" %s\n", _("- Note that only one string and one regex may be checked at present")); |
1025 | printf (" %s\n", _("- All evaluation methods other than PR, STR, and SUBSTR expect that the value")); | 881 | printf (" %s\n", _("- All evaluation methods other than PR, STR, and SUBSTR expect that the value")); |