From a27862a9c774d3fc4a608f8593c83b11357cc6dc Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Wed, 27 Aug 2025 12:17:46 +0200 Subject: check_snmp: rebuild threshold parsing --- plugins/Makefile.am | 1 + plugins/check_snmp.c | 26 +++----- plugins/check_snmp.d/check_snmp_helpers.c | 103 ++++++++++++++++++++++++++++++ plugins/check_snmp.d/check_snmp_helpers.h | 8 +++ plugins/check_snmp.d/config.h | 52 ++------------- 5 files changed, 125 insertions(+), 65 deletions(-) create mode 100644 plugins/check_snmp.d/check_snmp_helpers.c create mode 100644 plugins/check_snmp.d/check_snmp_helpers.h (limited to 'plugins') diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 765e2687..38668348 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -152,6 +152,7 @@ check_ping_LDADD = $(NETLIBS) check_procs_LDADD = $(BASEOBJS) check_radius_LDADD = $(NETLIBS) $(RADIUSLIBS) check_real_LDADD = $(NETLIBS) +check_snmp_SOURCES = check_snmp.c check_snmp.d/check_snmp_helpers.c check_snmp_LDADD = $(BASEOBJS) check_snmp_LDFLAGS = $(AM_LDFLAGS) `net-snmp-config --libs` check_snmp_CFLAGS = $(AM_CFLAGS) `net-snmp-config --cflags` diff --git a/plugins/check_snmp.c b/plugins/check_snmp.c index 6c9ed959..b71ee4fd 100644 --- a/plugins/check_snmp.c +++ b/plugins/check_snmp.c @@ -41,6 +41,7 @@ const char *email = "devel@monitoring-plugins.org"; #include "../lib/utils_base.h" #include "../lib/output.h" #include "../lib/perfdata.h" +#include "check_snmp.d/check_snmp_helpers.h" #include #include @@ -366,8 +367,9 @@ int main(int argc, char **argv) { config.test_units[loop_index].unit_value); } - if (config.thresholds.warning_is_set || config.thresholds.critical_is_set) { - pd_num_val = mp_pd_set_thresholds(pd_num_val, config.thresholds); + if (config.test_units[loop_index].threshold.warning_is_set || + config.test_units[loop_index].threshold.critical_is_set) { + pd_num_val = mp_pd_set_thresholds(pd_num_val, config.test_units[loop_index].threshold); mp_state_enum tmp_state = mp_get_pd_status(pd_num_val); if (tmp_state == STATE_WARNING) { @@ -660,23 +662,11 @@ static process_arguments_wrapper process_arguments(int argc, char **argv) { /* Test parameters */ case 'c': /* critical threshold */ - { - mp_range_parsed tmp = mp_parse_range_string(optarg); - if (tmp.error != MP_PARSING_SUCCES) { - die(STATE_UNKNOWN, "Unable to parse critical threshold range: %s", optarg); - } - config.thresholds.critical = tmp.range; - config.thresholds.critical_is_set = true; - } break; + check_snmp_set_thresholds(optarg, config.test_units, oid_counter, true); + break; case 'w': /* warning threshold */ - { - mp_range_parsed tmp = mp_parse_range_string(optarg); - if (tmp.error != MP_PARSING_SUCCES) { - die(STATE_UNKNOWN, "Unable to parse warning threshold range: %s", optarg); - } - config.thresholds.warning = tmp.range; - config.thresholds.warning_is_set = true; - } break; + check_snmp_set_thresholds(optarg, config.test_units, oid_counter, false); + break; case 'o': /* object identifier */ if (strspn(optarg, "0123456789.,") != strlen(optarg)) { /* diff --git a/plugins/check_snmp.d/check_snmp_helpers.c b/plugins/check_snmp.d/check_snmp_helpers.c new file mode 100644 index 00000000..9db1d9f4 --- /dev/null +++ b/plugins/check_snmp.d/check_snmp_helpers.c @@ -0,0 +1,103 @@ +#include "./check_snmp_helpers.h" +#include +#include "../../lib/utils_base.h" + +check_snmp_test_unit check_snmp_test_unit_init() { + check_snmp_test_unit tmp = { + .threshold = mp_thresholds_init(), + }; + return tmp; +} + + +int check_snmp_set_thresholds(char *threshold_string, check_snmp_test_unit tu[], + size_t max_test_units, bool is_critical) { + if (strchr(threshold_string, ',') != NULL) { + // Got a comma in the string, should be multiple values + size_t tmp_counter = 0; + mp_range range_buffer; + bool first_value = true; + for (char *ptr = strtok(threshold_string, ", "); ptr != NULL; + ptr = strtok(NULL, ", "), tmp_counter++) { + + // edge case: maybe we got `,,` to skip a value + if (strlen(ptr) == 0) { + // use the previous value in this case + // or do not overwrite the loop value to be specific + if (first_value) { + die(STATE_UNKNOWN, "Empty threshold value"); + } + } else { + mp_range_parsed tmp = mp_parse_range_string(ptr); + if (tmp.error != MP_PARSING_SUCCES) { + die(STATE_UNKNOWN, "Unable to parse critical threshold range: %s", ptr); + } + range_buffer = tmp.range; + } + + if (is_critical) { + tu[tmp_counter].threshold.critical = range_buffer; + tu[tmp_counter].threshold.critical_is_set = true; + } else { + tu[tmp_counter].threshold.warning = range_buffer; + tu[tmp_counter].threshold.warning_is_set = true; + } + first_value = false; + } + } else { + // Single value + mp_range_parsed tmp = mp_parse_range_string(threshold_string); + if (tmp.error != MP_PARSING_SUCCES) { + die(STATE_UNKNOWN, "Unable to parse critical threshold range: %s", threshold_string); + } + + for (size_t i = 0; i < max_test_units; i++) { + if (is_critical) { + tu[i].threshold.critical = tmp.range; + tu[i].threshold.critical_is_set = true; + } else { + tu[i].threshold.warning = tmp.range; + tu[i].threshold.warning_is_set = true; + } + } + } + + return 0; +} + +const int DEFAULT_PROTOCOL = SNMP_VERSION_1; +const char DEFAULT_OUTPUT_DELIMITER[] = " "; + +const int RANDOM_STATE_DATA_LENGTH_PREDICTION = 1024; + +check_snmp_config check_snmp_config_init() { + check_snmp_config tmp = { + .use_getnext = false, + + .ignore_mib_parsing_errors = false, + .need_mibs = false, + + .test_units = NULL, + .num_of_test_units = 0, + + .nulloid_result = STATE_UNKNOWN, // state to return if no result for query + + .invert_search = true, + .regex_cmp_value = {}, + .string_cmp_value = "", + + .multiplier = 1.0, + .offset = 0, + + .use_perf_data_labels_from_input = false, + }; + + snmp_sess_init(&tmp.snmp_session); + + tmp.snmp_session.retries = DEFAULT_RETRIES; + tmp.snmp_session.version = DEFAULT_SNMP_VERSION; + tmp.snmp_session.securityLevel = SNMP_SEC_LEVEL_NOAUTH; + tmp.snmp_session.community = (unsigned char *)"public"; + tmp.snmp_session.community_len = strlen("public"); + return tmp; +} diff --git a/plugins/check_snmp.d/check_snmp_helpers.h b/plugins/check_snmp.d/check_snmp_helpers.h new file mode 100644 index 00000000..74e7d0cd --- /dev/null +++ b/plugins/check_snmp.d/check_snmp_helpers.h @@ -0,0 +1,8 @@ +#pragma once + +#include "./config.h" + +check_snmp_test_unit check_snmp_test_unit_init(); +int check_snmp_set_thresholds(char *threshold_string, check_snmp_test_unit tu[], + size_t max_test_units, bool is_critical); +check_snmp_config check_snmp_config_init(); diff --git a/plugins/check_snmp.d/config.h b/plugins/check_snmp.d/config.h index e2e1d6c2..ca624a81 100644 --- a/plugins/check_snmp.d/config.h +++ b/plugins/check_snmp.d/config.h @@ -1,11 +1,11 @@ #pragma once -#include "states.h" #include "thresholds.h" -#include "utils_base.h" +#include "states.h" #include #include #include +#include "../common.h" // defines for snmp libs #define u_char unsigned char @@ -18,12 +18,8 @@ #include #include -const int DEFAULT_PROTOCOL = SNMP_VERSION_1; -const char DEFAULT_PORT[] = "161"; -const char DEFAULT_OUTPUT_DELIMITER[] = " "; -const int DEFAULT_RETRIES = 5; - -const int RANDOM_STATE_DATA_LENGTH_PREDICTION = 1024; +#define DEFAULT_PORT "161" +#define DEFAULT_RETRIES 5 typedef struct eval_method { bool crit_string; @@ -35,13 +31,9 @@ typedef struct check_snmp_test_unit { char *label; char *unit_value; eval_method eval_mthd; + mp_thresholds threshold; } check_snmp_test_unit; -check_snmp_test_unit check_snmp_test_unit_init() { - check_snmp_test_unit tmp = {}; - return tmp; -} - typedef struct check_snmp_config { // SNMP session to use struct snmp_session snmp_session; @@ -55,7 +47,6 @@ typedef struct check_snmp_config { check_snmp_test_unit *test_units; size_t num_of_test_units; - mp_thresholds thresholds; // State if an empty value is encountered mp_state_enum nulloid_result; @@ -72,36 +63,3 @@ typedef struct check_snmp_config { // Modify output bool use_perf_data_labels_from_input; } check_snmp_config; - -check_snmp_config check_snmp_config_init() { - check_snmp_config tmp = { - .use_getnext = false, - - .ignore_mib_parsing_errors = false, - .need_mibs = false, - - .test_units = NULL, - .num_of_test_units = 0, - .thresholds = mp_thresholds_init(), - - .nulloid_result = STATE_UNKNOWN, // state to return if no result for query - - .invert_search = true, - .regex_cmp_value = {}, - .string_cmp_value = "", - - .multiplier = 1.0, - .offset = 0, - - .use_perf_data_labels_from_input = false, - }; - - snmp_sess_init(&tmp.snmp_session); - - tmp.snmp_session.retries = DEFAULT_RETRIES; - tmp.snmp_session.version = DEFAULT_SNMP_VERSION; - tmp.snmp_session.securityLevel = SNMP_SEC_LEVEL_NOAUTH; - tmp.snmp_session.community = (unsigned char *)"public"; - tmp.snmp_session.community_len = strlen("public"); - return tmp; -} -- cgit v1.2.3-74-g34f1