summaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
authorLorenz Kästle <12514511+RincewindsHat@users.noreply.github.com>2025-08-27 12:17:46 +0200
committerLorenz Kästle <12514511+RincewindsHat@users.noreply.github.com>2025-08-27 12:17:46 +0200
commita27862a9c774d3fc4a608f8593c83b11357cc6dc (patch)
treed0b86f8a6174a16ee102a1b5c37fba2f74e2882c /plugins
parentbabeb765e5725610dbf7673c91a3a5a4e5a8810f (diff)
downloadmonitoring-plugins-a27862a9c774d3fc4a608f8593c83b11357cc6dc.tar.gz
check_snmp: rebuild threshold parsing
Diffstat (limited to 'plugins')
-rw-r--r--plugins/Makefile.am1
-rw-r--r--plugins/check_snmp.c26
-rw-r--r--plugins/check_snmp.d/check_snmp_helpers.c103
-rw-r--r--plugins/check_snmp.d/check_snmp_helpers.h8
-rw-r--r--plugins/check_snmp.d/config.h52
5 files changed, 125 insertions, 65 deletions
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)
152check_procs_LDADD = $(BASEOBJS) 152check_procs_LDADD = $(BASEOBJS)
153check_radius_LDADD = $(NETLIBS) $(RADIUSLIBS) 153check_radius_LDADD = $(NETLIBS) $(RADIUSLIBS)
154check_real_LDADD = $(NETLIBS) 154check_real_LDADD = $(NETLIBS)
155check_snmp_SOURCES = check_snmp.c check_snmp.d/check_snmp_helpers.c
155check_snmp_LDADD = $(BASEOBJS) 156check_snmp_LDADD = $(BASEOBJS)
156check_snmp_LDFLAGS = $(AM_LDFLAGS) `net-snmp-config --libs` 157check_snmp_LDFLAGS = $(AM_LDFLAGS) `net-snmp-config --libs`
157check_snmp_CFLAGS = $(AM_CFLAGS) `net-snmp-config --cflags` 158check_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";
41#include "../lib/utils_base.h" 41#include "../lib/utils_base.h"
42#include "../lib/output.h" 42#include "../lib/output.h"
43#include "../lib/perfdata.h" 43#include "../lib/perfdata.h"
44#include "check_snmp.d/check_snmp_helpers.h"
44 45
45#include <bits/getopt_core.h> 46#include <bits/getopt_core.h>
46#include <bits/getopt_ext.h> 47#include <bits/getopt_ext.h>
@@ -366,8 +367,9 @@ int main(int argc, char **argv) {
366 config.test_units[loop_index].unit_value); 367 config.test_units[loop_index].unit_value);
367 } 368 }
368 369
369 if (config.thresholds.warning_is_set || config.thresholds.critical_is_set) { 370 if (config.test_units[loop_index].threshold.warning_is_set ||
370 pd_num_val = mp_pd_set_thresholds(pd_num_val, config.thresholds); 371 config.test_units[loop_index].threshold.critical_is_set) {
372 pd_num_val = mp_pd_set_thresholds(pd_num_val, config.test_units[loop_index].threshold);
371 mp_state_enum tmp_state = mp_get_pd_status(pd_num_val); 373 mp_state_enum tmp_state = mp_get_pd_status(pd_num_val);
372 374
373 if (tmp_state == STATE_WARNING) { 375 if (tmp_state == STATE_WARNING) {
@@ -660,23 +662,11 @@ static process_arguments_wrapper process_arguments(int argc, char **argv) {
660 662
661 /* Test parameters */ 663 /* Test parameters */
662 case 'c': /* critical threshold */ 664 case 'c': /* critical threshold */
663 { 665 check_snmp_set_thresholds(optarg, config.test_units, oid_counter, true);
664 mp_range_parsed tmp = mp_parse_range_string(optarg); 666 break;
665 if (tmp.error != MP_PARSING_SUCCES) {
666 die(STATE_UNKNOWN, "Unable to parse critical threshold range: %s", optarg);
667 }
668 config.thresholds.critical = tmp.range;
669 config.thresholds.critical_is_set = true;
670 } break;
671 case 'w': /* warning threshold */ 667 case 'w': /* warning threshold */
672 { 668 check_snmp_set_thresholds(optarg, config.test_units, oid_counter, false);
673 mp_range_parsed tmp = mp_parse_range_string(optarg); 669 break;
674 if (tmp.error != MP_PARSING_SUCCES) {
675 die(STATE_UNKNOWN, "Unable to parse warning threshold range: %s", optarg);
676 }
677 config.thresholds.warning = tmp.range;
678 config.thresholds.warning_is_set = true;
679 } break;
680 case 'o': /* object identifier */ 670 case 'o': /* object identifier */
681 if (strspn(optarg, "0123456789.,") != strlen(optarg)) { 671 if (strspn(optarg, "0123456789.,") != strlen(optarg)) {
682 /* 672 /*
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 @@
1#include "./check_snmp_helpers.h"
2#include <string.h>
3#include "../../lib/utils_base.h"
4
5check_snmp_test_unit check_snmp_test_unit_init() {
6 check_snmp_test_unit tmp = {
7 .threshold = mp_thresholds_init(),
8 };
9 return tmp;
10}
11
12
13int check_snmp_set_thresholds(char *threshold_string, check_snmp_test_unit tu[],
14 size_t max_test_units, bool is_critical) {
15 if (strchr(threshold_string, ',') != NULL) {
16 // Got a comma in the string, should be multiple values
17 size_t tmp_counter = 0;
18 mp_range range_buffer;
19 bool first_value = true;
20 for (char *ptr = strtok(threshold_string, ", "); ptr != NULL;
21 ptr = strtok(NULL, ", "), tmp_counter++) {
22
23 // edge case: maybe we got `,,` to skip a value
24 if (strlen(ptr) == 0) {
25 // use the previous value in this case
26 // or do not overwrite the loop value to be specific
27 if (first_value) {
28 die(STATE_UNKNOWN, "Empty threshold value");
29 }
30 } else {
31 mp_range_parsed tmp = mp_parse_range_string(ptr);
32 if (tmp.error != MP_PARSING_SUCCES) {
33 die(STATE_UNKNOWN, "Unable to parse critical threshold range: %s", ptr);
34 }
35 range_buffer = tmp.range;
36 }
37
38 if (is_critical) {
39 tu[tmp_counter].threshold.critical = range_buffer;
40 tu[tmp_counter].threshold.critical_is_set = true;
41 } else {
42 tu[tmp_counter].threshold.warning = range_buffer;
43 tu[tmp_counter].threshold.warning_is_set = true;
44 }
45 first_value = false;
46 }
47 } else {
48 // Single value
49 mp_range_parsed tmp = mp_parse_range_string(threshold_string);
50 if (tmp.error != MP_PARSING_SUCCES) {
51 die(STATE_UNKNOWN, "Unable to parse critical threshold range: %s", threshold_string);
52 }
53
54 for (size_t i = 0; i < max_test_units; i++) {
55 if (is_critical) {
56 tu[i].threshold.critical = tmp.range;
57 tu[i].threshold.critical_is_set = true;
58 } else {
59 tu[i].threshold.warning = tmp.range;
60 tu[i].threshold.warning_is_set = true;
61 }
62 }
63 }
64
65 return 0;
66}
67
68const int DEFAULT_PROTOCOL = SNMP_VERSION_1;
69const char DEFAULT_OUTPUT_DELIMITER[] = " ";
70
71const int RANDOM_STATE_DATA_LENGTH_PREDICTION = 1024;
72
73check_snmp_config check_snmp_config_init() {
74 check_snmp_config tmp = {
75 .use_getnext = false,
76
77 .ignore_mib_parsing_errors = false,
78 .need_mibs = false,
79
80 .test_units = NULL,
81 .num_of_test_units = 0,
82
83 .nulloid_result = STATE_UNKNOWN, // state to return if no result for query
84
85 .invert_search = true,
86 .regex_cmp_value = {},
87 .string_cmp_value = "",
88
89 .multiplier = 1.0,
90 .offset = 0,
91
92 .use_perf_data_labels_from_input = false,
93 };
94
95 snmp_sess_init(&tmp.snmp_session);
96
97 tmp.snmp_session.retries = DEFAULT_RETRIES;
98 tmp.snmp_session.version = DEFAULT_SNMP_VERSION;
99 tmp.snmp_session.securityLevel = SNMP_SEC_LEVEL_NOAUTH;
100 tmp.snmp_session.community = (unsigned char *)"public";
101 tmp.snmp_session.community_len = strlen("public");
102 return tmp;
103}
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 @@
1#pragma once
2
3#include "./config.h"
4
5check_snmp_test_unit check_snmp_test_unit_init();
6int check_snmp_set_thresholds(char *threshold_string, check_snmp_test_unit tu[],
7 size_t max_test_units, bool is_critical);
8check_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 @@
1#pragma once 1#pragma once
2 2
3#include "states.h"
4#include "thresholds.h" 3#include "thresholds.h"
5#include "utils_base.h" 4#include "states.h"
6#include <stdlib.h> 5#include <stdlib.h>
7#include <stdbool.h> 6#include <stdbool.h>
8#include <regex.h> 7#include <regex.h>
8#include "../common.h"
9 9
10// defines for snmp libs 10// defines for snmp libs
11#define u_char unsigned char 11#define u_char unsigned char
@@ -18,12 +18,8 @@
18#include <net-snmp/library/snmp.h> 18#include <net-snmp/library/snmp.h>
19#include <net-snmp/session_api.h> 19#include <net-snmp/session_api.h>
20 20
21const int DEFAULT_PROTOCOL = SNMP_VERSION_1; 21#define DEFAULT_PORT "161"
22const char DEFAULT_PORT[] = "161"; 22#define DEFAULT_RETRIES 5
23const char DEFAULT_OUTPUT_DELIMITER[] = " ";
24const int DEFAULT_RETRIES = 5;
25
26const int RANDOM_STATE_DATA_LENGTH_PREDICTION = 1024;
27 23
28typedef struct eval_method { 24typedef struct eval_method {
29 bool crit_string; 25 bool crit_string;
@@ -35,13 +31,9 @@ typedef struct check_snmp_test_unit {
35 char *label; 31 char *label;
36 char *unit_value; 32 char *unit_value;
37 eval_method eval_mthd; 33 eval_method eval_mthd;
34 mp_thresholds threshold;
38} check_snmp_test_unit; 35} check_snmp_test_unit;
39 36
40check_snmp_test_unit check_snmp_test_unit_init() {
41 check_snmp_test_unit tmp = {};
42 return tmp;
43}
44
45typedef struct check_snmp_config { 37typedef struct check_snmp_config {
46 // SNMP session to use 38 // SNMP session to use
47 struct snmp_session snmp_session; 39 struct snmp_session snmp_session;
@@ -55,7 +47,6 @@ typedef struct check_snmp_config {
55 47
56 check_snmp_test_unit *test_units; 48 check_snmp_test_unit *test_units;
57 size_t num_of_test_units; 49 size_t num_of_test_units;
58 mp_thresholds thresholds;
59 50
60 // State if an empty value is encountered 51 // State if an empty value is encountered
61 mp_state_enum nulloid_result; 52 mp_state_enum nulloid_result;
@@ -72,36 +63,3 @@ typedef struct check_snmp_config {
72 // Modify output 63 // Modify output
73 bool use_perf_data_labels_from_input; 64 bool use_perf_data_labels_from_input;
74} check_snmp_config; 65} check_snmp_config;
75
76check_snmp_config check_snmp_config_init() {
77 check_snmp_config tmp = {
78 .use_getnext = false,
79
80 .ignore_mib_parsing_errors = false,
81 .need_mibs = false,
82
83 .test_units = NULL,
84 .num_of_test_units = 0,
85 .thresholds = mp_thresholds_init(),
86
87 .nulloid_result = STATE_UNKNOWN, // state to return if no result for query
88
89 .invert_search = true,
90 .regex_cmp_value = {},
91 .string_cmp_value = "",
92
93 .multiplier = 1.0,
94 .offset = 0,
95
96 .use_perf_data_labels_from_input = false,
97 };
98
99 snmp_sess_init(&tmp.snmp_session);
100
101 tmp.snmp_session.retries = DEFAULT_RETRIES;
102 tmp.snmp_session.version = DEFAULT_SNMP_VERSION;
103 tmp.snmp_session.securityLevel = SNMP_SEC_LEVEL_NOAUTH;
104 tmp.snmp_session.community = (unsigned char *)"public";
105 tmp.snmp_session.community_len = strlen("public");
106 return tmp;
107}