diff options
-rw-r--r-- | lib/output.c | 12 | ||||
-rw-r--r-- | lib/output.h | 7 | ||||
-rw-r--r-- | plugins/Makefile.am | 9 | ||||
-rw-r--r-- | plugins/check_dns.c | 373 | ||||
-rw-r--r-- | plugins/check_dns.d/config.h | 34 | ||||
-rw-r--r-- | plugins/check_game.c | 229 | ||||
-rw-r--r-- | plugins/check_game.d/config.h | 30 | ||||
-rw-r--r-- | plugins/check_ssh.c | 210 | ||||
-rw-r--r-- | plugins/check_ssh.d/config.h | 29 | ||||
-rw-r--r-- | plugins/check_swap.c | 2 | ||||
-rw-r--r-- | plugins/netutils.c | 93 | ||||
-rw-r--r-- | plugins/t/check_http.t | 2 | ||||
-rw-r--r-- | plugins/t/check_jabber.t | 2 | ||||
-rw-r--r-- | plugins/t/check_ldap.t | 2 | ||||
-rw-r--r-- | plugins/t/check_ntp.t | 2 | ||||
-rw-r--r-- | plugins/t/check_smtp.t | 3 | ||||
-rw-r--r-- | plugins/t/check_ssh.t | 114 | ||||
-rw-r--r-- | plugins/utils.c | 243 | ||||
-rw-r--r-- | plugins/utils.h | 141 |
19 files changed, 961 insertions, 576 deletions
diff --git a/lib/output.c b/lib/output.c index 17919afc..61fbf832 100644 --- a/lib/output.c +++ b/lib/output.c | |||
@@ -11,6 +11,9 @@ | |||
11 | #include "perfdata.h" | 11 | #include "perfdata.h" |
12 | #include "states.h" | 12 | #include "states.h" |
13 | 13 | ||
14 | // == Global variables | ||
15 | static mp_output_format output_format = MP_FORMAT_DEFAULT; | ||
16 | |||
14 | // == Prototypes == | 17 | // == Prototypes == |
15 | static char *fmt_subcheck_output(mp_output_format output_format, mp_subcheck check, unsigned int indentation); | 18 | static char *fmt_subcheck_output(mp_output_format output_format, mp_subcheck check, unsigned int indentation); |
16 | static inline cJSON *json_serialize_subcheck(mp_subcheck subcheck); | 19 | static inline cJSON *json_serialize_subcheck(mp_subcheck subcheck); |
@@ -55,7 +58,6 @@ static inline char *fmt_subcheck_perfdata(mp_subcheck check) { | |||
55 | */ | 58 | */ |
56 | mp_check mp_check_init(void) { | 59 | mp_check mp_check_init(void) { |
57 | mp_check check = {0}; | 60 | mp_check check = {0}; |
58 | check.format = MP_FORMAT_DEFAULT; | ||
59 | return check; | 61 | return check; |
60 | } | 62 | } |
61 | 63 | ||
@@ -234,7 +236,7 @@ mp_state_enum mp_compute_check_state(const mp_check check) { | |||
234 | char *mp_fmt_output(mp_check check) { | 236 | char *mp_fmt_output(mp_check check) { |
235 | char *result = NULL; | 237 | char *result = NULL; |
236 | 238 | ||
237 | switch (check.format) { | 239 | switch (output_format) { |
238 | case MP_FORMAT_MULTI_LINE: { | 240 | case MP_FORMAT_MULTI_LINE: { |
239 | if (check.summary == NULL) { | 241 | if (check.summary == NULL) { |
240 | check.summary = get_subcheck_summary(check); | 242 | check.summary = get_subcheck_summary(check); |
@@ -482,7 +484,7 @@ void mp_print_output(mp_check check) { puts(mp_fmt_output(check)); } | |||
482 | */ | 484 | */ |
483 | void mp_exit(mp_check check) { | 485 | void mp_exit(mp_check check) { |
484 | mp_print_output(check); | 486 | mp_print_output(check); |
485 | if (check.format == MP_FORMAT_TEST_JSON) { | 487 | if (output_format == MP_FORMAT_TEST_JSON) { |
486 | exit(0); | 488 | exit(0); |
487 | } | 489 | } |
488 | 490 | ||
@@ -533,3 +535,7 @@ parsed_output_format mp_parse_output_format(char *format_string) { | |||
533 | 535 | ||
534 | return result; | 536 | return result; |
535 | } | 537 | } |
538 | |||
539 | void mp_set_format(mp_output_format format) { output_format = format; } | ||
540 | |||
541 | mp_output_format mp_get_format(void) { return output_format; } | ||
diff --git a/lib/output.h b/lib/output.h index ffc36f53..2bdfa074 100644 --- a/lib/output.h +++ b/lib/output.h | |||
@@ -36,13 +36,18 @@ typedef enum output_format { | |||
36 | #define MP_FORMAT_DEFAULT MP_FORMAT_MULTI_LINE | 36 | #define MP_FORMAT_DEFAULT MP_FORMAT_MULTI_LINE |
37 | 37 | ||
38 | /* | 38 | /* |
39 | * Format related functions | ||
40 | */ | ||
41 | void mp_set_format(mp_output_format format); | ||
42 | mp_output_format mp_get_format(void); | ||
43 | |||
44 | /* | ||
39 | * The main state object of a plugin. Exists only ONCE per plugin. | 45 | * The main state object of a plugin. Exists only ONCE per plugin. |
40 | * This is the "root" of a tree of singular checks. | 46 | * This is the "root" of a tree of singular checks. |
41 | * The final result is always derived from the children and the "worst" state | 47 | * The final result is always derived from the children and the "worst" state |
42 | * in the first layer of subchecks | 48 | * in the first layer of subchecks |
43 | */ | 49 | */ |
44 | typedef struct { | 50 | typedef struct { |
45 | mp_output_format format; // The output format | ||
46 | char *summary; // Overall summary, if not set a summary will be automatically generated | 51 | char *summary; // Overall summary, if not set a summary will be automatically generated |
47 | mp_subcheck_list *subchecks; | 52 | mp_subcheck_list *subchecks; |
48 | } mp_check; | 53 | } mp_check; |
diff --git a/plugins/Makefile.am b/plugins/Makefile.am index a0e9cabf..d40a0937 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am | |||
@@ -46,7 +46,14 @@ SUBDIRS = picohttpparser | |||
46 | 46 | ||
47 | np_test_scripts = tests/test_check_swap.t | 47 | np_test_scripts = tests/test_check_swap.t |
48 | 48 | ||
49 | EXTRA_DIST = t tests $(np_test_scripts) check_swap.d check_dbi.d | 49 | EXTRA_DIST = t \ |
50 | tests \ | ||
51 | $(np_test_scripts) \ | ||
52 | check_swap.d \ | ||
53 | check_game.d \ | ||
54 | check_dbi.d \ | ||
55 | check_ssh.d \ | ||
56 | check_dns.d | ||
50 | 57 | ||
51 | PLUGINHDRS = common.h | 58 | PLUGINHDRS = common.h |
52 | 59 | ||
diff --git a/plugins/check_dns.c b/plugins/check_dns.c index e1e7c00e..95f33083 100644 --- a/plugins/check_dns.c +++ b/plugins/check_dns.c | |||
@@ -39,26 +39,22 @@ const char *email = "devel@monitoring-plugins.org"; | |||
39 | #include "netutils.h" | 39 | #include "netutils.h" |
40 | #include "runcmd.h" | 40 | #include "runcmd.h" |
41 | 41 | ||
42 | static int process_arguments(int /*argc*/, char ** /*argv*/); | 42 | #include "states.h" |
43 | static int validate_arguments(void); | 43 | #include "check_dns.d/config.h" |
44 | static int error_scan(char * /*input_buffer*/, bool *); | 44 | |
45 | typedef struct { | ||
46 | int errorcode; | ||
47 | check_dns_config config; | ||
48 | } check_dns_config_wrapper; | ||
49 | static check_dns_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); | ||
50 | static check_dns_config_wrapper validate_arguments(check_dns_config_wrapper /*config_wrapper*/); | ||
51 | static mp_state_enum error_scan(char * /*input_buffer*/, bool * /*is_nxdomain*/, const char /*dns_server*/[ADDRESS_LENGTH]); | ||
45 | static bool ip_match_cidr(const char * /*addr*/, const char * /*cidr_ro*/); | 52 | static bool ip_match_cidr(const char * /*addr*/, const char * /*cidr_ro*/); |
46 | static unsigned long ip2long(const char * /*src*/); | 53 | static unsigned long ip2long(const char * /*src*/); |
47 | static void print_help(void); | 54 | static void print_help(void); |
48 | void print_usage(void); | 55 | void print_usage(void); |
49 | 56 | ||
50 | #define ADDRESS_LENGTH 256 | ||
51 | static char query_address[ADDRESS_LENGTH] = ""; | ||
52 | static char dns_server[ADDRESS_LENGTH] = ""; | ||
53 | static char ptr_server[ADDRESS_LENGTH] = ""; | ||
54 | static bool verbose = false; | 57 | static bool verbose = false; |
55 | static char **expected_address = NULL; | ||
56 | static int expected_address_cnt = 0; | ||
57 | static bool expect_nxdomain = false; | ||
58 | |||
59 | static bool expect_authority = false; | ||
60 | static bool all_match = false; | ||
61 | static thresholds *time_thresholds = NULL; | ||
62 | 58 | ||
63 | static int qstrcmp(const void *p1, const void *p2) { | 59 | static int qstrcmp(const void *p1, const void *p2) { |
64 | /* The actual arguments to this function are "pointers to | 60 | /* The actual arguments to this function are "pointers to |
@@ -68,23 +64,6 @@ static int qstrcmp(const void *p1, const void *p2) { | |||
68 | } | 64 | } |
69 | 65 | ||
70 | int main(int argc, char **argv) { | 66 | int main(int argc, char **argv) { |
71 | char *command_line = NULL; | ||
72 | char input_buffer[MAX_INPUT_BUFFER]; | ||
73 | char *address = NULL; /* comma separated str with addrs/ptrs (sorted) */ | ||
74 | char **addresses = NULL; | ||
75 | int n_addresses = 0; | ||
76 | char *msg = NULL; | ||
77 | char *temp_buffer = NULL; | ||
78 | bool non_authoritative = false; | ||
79 | int result = STATE_UNKNOWN; | ||
80 | double elapsed_time; | ||
81 | long microsec; | ||
82 | struct timeval tv; | ||
83 | bool parse_address = false; /* This flag scans for Address: but only after Name: */ | ||
84 | output chld_out; | ||
85 | output chld_err; | ||
86 | bool is_nxdomain = false; | ||
87 | |||
88 | setlocale(LC_ALL, ""); | 67 | setlocale(LC_ALL, ""); |
89 | bindtextdomain(PACKAGE, LOCALEDIR); | 68 | bindtextdomain(PACKAGE, LOCALEDIR); |
90 | textdomain(PACKAGE); | 69 | textdomain(PACKAGE); |
@@ -97,39 +76,65 @@ int main(int argc, char **argv) { | |||
97 | /* Parse extra opts if any */ | 76 | /* Parse extra opts if any */ |
98 | argv = np_extra_opts(&argc, argv, progname); | 77 | argv = np_extra_opts(&argc, argv, progname); |
99 | 78 | ||
100 | if (process_arguments(argc, argv) == ERROR) { | 79 | check_dns_config_wrapper tmp = process_arguments(argc, argv); |
80 | |||
81 | if (tmp.errorcode == ERROR) { | ||
101 | usage_va(_("Could not parse arguments")); | 82 | usage_va(_("Could not parse arguments")); |
102 | } | 83 | } |
103 | 84 | ||
85 | const check_dns_config config = tmp.config; | ||
86 | |||
87 | char *command_line = NULL; | ||
104 | /* get the command to run */ | 88 | /* get the command to run */ |
105 | xasprintf(&command_line, "%s %s %s", NSLOOKUP_COMMAND, query_address, dns_server); | 89 | xasprintf(&command_line, "%s %s %s", NSLOOKUP_COMMAND, config.query_address, config.dns_server); |
106 | 90 | ||
91 | struct timeval tv; | ||
107 | alarm(timeout_interval); | 92 | alarm(timeout_interval); |
108 | gettimeofday(&tv, NULL); | 93 | gettimeofday(&tv, NULL); |
109 | 94 | ||
110 | if (verbose) | 95 | if (verbose) { |
111 | printf("%s\n", command_line); | 96 | printf("%s\n", command_line); |
97 | } | ||
112 | 98 | ||
99 | output chld_out; | ||
100 | output chld_err; | ||
101 | char *msg = NULL; | ||
102 | mp_state_enum result = STATE_UNKNOWN; | ||
113 | /* run the command */ | 103 | /* run the command */ |
114 | if ((np_runcmd(command_line, &chld_out, &chld_err, 0)) != 0) { | 104 | if ((np_runcmd(command_line, &chld_out, &chld_err, 0)) != 0) { |
115 | msg = (char *)_("nslookup returned an error status"); | 105 | msg = (char *)_("nslookup returned an error status"); |
116 | result = STATE_WARNING; | 106 | result = STATE_WARNING; |
117 | } | 107 | } |
118 | 108 | ||
119 | /* scan stdout */ | 109 | /* ===== |
110 | * scan stdout, main results get retrieved here | ||
111 | * ===== | ||
112 | */ | ||
113 | char *address = NULL; /* comma separated str with addrs/ptrs (sorted) */ | ||
114 | char **addresses = NULL; // All addresses parsed from stdout | ||
115 | size_t n_addresses = 0; // counter for retrieved addresses | ||
116 | bool non_authoritative = false; | ||
117 | bool is_nxdomain = false; | ||
118 | bool parse_address = false; /* This flag scans for Address: but only after Name: */ | ||
120 | for (size_t i = 0; i < chld_out.lines; i++) { | 119 | for (size_t i = 0; i < chld_out.lines; i++) { |
121 | if (addresses == NULL) | 120 | if (addresses == NULL) { |
122 | addresses = malloc(sizeof(*addresses) * 10); | 121 | addresses = malloc(sizeof(*addresses) * 10); |
123 | else if (!(n_addresses % 10)) | 122 | } else if (!(n_addresses % 10)) { |
124 | addresses = realloc(addresses, sizeof(*addresses) * (n_addresses + 10)); | 123 | addresses = realloc(addresses, sizeof(*addresses) * (n_addresses + 10)); |
124 | } | ||
125 | 125 | ||
126 | if (verbose) | 126 | if (verbose) { |
127 | puts(chld_out.line[i]); | 127 | puts(chld_out.line[i]); |
128 | } | ||
128 | 129 | ||
129 | if (strcasestr(chld_out.line[i], ".in-addr.arpa") || strcasestr(chld_out.line[i], ".ip6.arpa")) { | 130 | if (strcasestr(chld_out.line[i], ".in-addr.arpa") || strcasestr(chld_out.line[i], ".ip6.arpa")) { |
130 | if ((temp_buffer = strstr(chld_out.line[i], "name = "))) | 131 | if ((strstr(chld_out.line[i], "canonical name = ") != NULL)) { |
132 | continue; | ||
133 | } | ||
134 | char *temp_buffer = NULL; | ||
135 | if ((temp_buffer = strstr(chld_out.line[i], "name = "))) { | ||
131 | addresses[n_addresses++] = strdup(temp_buffer + 7); | 136 | addresses[n_addresses++] = strdup(temp_buffer + 7); |
132 | else { | 137 | } else { |
133 | msg = (char *)_("Warning plugin error"); | 138 | msg = (char *)_("Warning plugin error"); |
134 | result = STATE_WARNING; | 139 | result = STATE_WARNING; |
135 | } | 140 | } |
@@ -137,37 +142,47 @@ int main(int argc, char **argv) { | |||
137 | 142 | ||
138 | /* bug ID: 2946553 - Older versions of bind will use all available dns | 143 | /* bug ID: 2946553 - Older versions of bind will use all available dns |
139 | servers, we have to match the one specified */ | 144 | servers, we have to match the one specified */ |
140 | if (strstr(chld_out.line[i], "Server:") && strlen(dns_server) > 0) { | 145 | if (strstr(chld_out.line[i], "Server:") && strlen(config.dns_server) > 0) { |
141 | temp_buffer = strchr(chld_out.line[i], ':'); | 146 | char *temp_buffer = strchr(chld_out.line[i], ':'); |
147 | if (temp_buffer == NULL) { | ||
148 | die(STATE_UNKNOWN, _("'%s' returned a weirdly formatted Server line\n"), NSLOOKUP_COMMAND); | ||
149 | } | ||
150 | |||
142 | temp_buffer++; | 151 | temp_buffer++; |
143 | 152 | ||
144 | /* Strip leading tabs */ | 153 | /* Strip leading tabs */ |
145 | for (; *temp_buffer != '\0' && *temp_buffer == '\t'; temp_buffer++) | 154 | for (; *temp_buffer != '\0' && *temp_buffer == '\t'; temp_buffer++) { |
146 | /* NOOP */; | 155 | /* NOOP */; |
156 | } | ||
147 | 157 | ||
148 | strip(temp_buffer); | 158 | strip(temp_buffer); |
149 | if (temp_buffer == NULL || strlen(temp_buffer) == 0) { | 159 | if (strlen(temp_buffer) == 0) { |
150 | die(STATE_CRITICAL, _("DNS CRITICAL - '%s' returned empty server string\n"), NSLOOKUP_COMMAND); | 160 | die(STATE_CRITICAL, _("DNS CRITICAL - '%s' returned empty server string\n"), NSLOOKUP_COMMAND); |
151 | } | 161 | } |
152 | 162 | ||
153 | if (strcmp(temp_buffer, dns_server) != 0) { | 163 | if (strcmp(temp_buffer, config.dns_server) != 0) { |
154 | die(STATE_CRITICAL, _("DNS CRITICAL - No response from DNS %s\n"), dns_server); | 164 | die(STATE_CRITICAL, _("DNS CRITICAL - No response from DNS %s\n"), config.dns_server); |
155 | } | 165 | } |
156 | } | 166 | } |
157 | 167 | ||
158 | /* the server is responding, we just got the host name... */ | 168 | /* the server is responding, we just got the host name... */ |
159 | if (strstr(chld_out.line[i], "Name:")) | 169 | if (strstr(chld_out.line[i], "Name:")) { |
160 | parse_address = true; | 170 | parse_address = true; |
161 | else if (parse_address && (strstr(chld_out.line[i], "Address:") || strstr(chld_out.line[i], "Addresses:"))) { | 171 | } else if (parse_address && (strstr(chld_out.line[i], "Address:") || strstr(chld_out.line[i], "Addresses:"))) { |
162 | temp_buffer = index(chld_out.line[i], ':'); | 172 | char *temp_buffer = strchr(chld_out.line[i], ':'); |
173 | if (temp_buffer == NULL) { | ||
174 | die(STATE_UNKNOWN, _("'%s' returned a weirdly formatted Address line\n"), NSLOOKUP_COMMAND); | ||
175 | } | ||
176 | |||
163 | temp_buffer++; | 177 | temp_buffer++; |
164 | 178 | ||
165 | /* Strip leading spaces */ | 179 | /* Strip leading spaces */ |
166 | while (*temp_buffer == ' ') | 180 | while (*temp_buffer == ' ') { |
167 | temp_buffer++; | 181 | temp_buffer++; |
182 | } | ||
168 | 183 | ||
169 | strip(temp_buffer); | 184 | strip(temp_buffer); |
170 | if (temp_buffer == NULL || strlen(temp_buffer) == 0) { | 185 | if (strlen(temp_buffer) == 0) { |
171 | die(STATE_CRITICAL, _("DNS CRITICAL - '%s' returned empty host name string\n"), NSLOOKUP_COMMAND); | 186 | die(STATE_CRITICAL, _("DNS CRITICAL - '%s' returned empty host name string\n"), NSLOOKUP_COMMAND); |
172 | } | 187 | } |
173 | 188 | ||
@@ -176,65 +191,71 @@ int main(int argc, char **argv) { | |||
176 | non_authoritative = true; | 191 | non_authoritative = true; |
177 | } | 192 | } |
178 | 193 | ||
179 | result = error_scan(chld_out.line[i], &is_nxdomain); | 194 | result = error_scan(chld_out.line[i], &is_nxdomain, config.dns_server); |
180 | if (result != STATE_OK) { | 195 | if (result != STATE_OK) { |
181 | msg = strchr(chld_out.line[i], ':'); | 196 | msg = strchr(chld_out.line[i], ':'); |
182 | if (msg) | 197 | if (msg) { |
183 | msg++; | 198 | msg++; |
199 | } | ||
184 | break; | 200 | break; |
185 | } | 201 | } |
186 | } | 202 | } |
187 | 203 | ||
204 | char input_buffer[MAX_INPUT_BUFFER]; | ||
188 | /* scan stderr */ | 205 | /* scan stderr */ |
189 | for (size_t i = 0; i < chld_err.lines; i++) { | 206 | for (size_t i = 0; i < chld_err.lines; i++) { |
190 | if (verbose) | 207 | if (verbose) { |
191 | puts(chld_err.line[i]); | 208 | puts(chld_err.line[i]); |
209 | } | ||
192 | 210 | ||
193 | if (error_scan(chld_err.line[i], &is_nxdomain) != STATE_OK) { | 211 | if (error_scan(chld_err.line[i], &is_nxdomain, config.dns_server) != STATE_OK) { |
194 | result = max_state(result, error_scan(chld_err.line[i], &is_nxdomain)); | 212 | result = max_state(result, error_scan(chld_err.line[i], &is_nxdomain, config.dns_server)); |
195 | msg = strchr(input_buffer, ':'); | 213 | msg = strchr(input_buffer, ':'); |
196 | if (msg) | 214 | if (msg) { |
197 | msg++; | 215 | msg++; |
198 | else | 216 | } else { |
199 | msg = input_buffer; | 217 | msg = input_buffer; |
218 | } | ||
200 | } | 219 | } |
201 | } | 220 | } |
202 | 221 | ||
203 | if (is_nxdomain && !expect_nxdomain) { | 222 | if (is_nxdomain && !config.expect_nxdomain) { |
204 | die(STATE_CRITICAL, _("Domain '%s' was not found by the server\n"), query_address); | 223 | die(STATE_CRITICAL, _("Domain '%s' was not found by the server\n"), config.query_address); |
205 | } | 224 | } |
206 | 225 | ||
207 | if (addresses) { | 226 | if (addresses) { |
208 | int i; | 227 | size_t slen = 1; |
209 | int slen; | 228 | char *adrp = NULL; |
210 | char *adrp; | ||
211 | qsort(addresses, n_addresses, sizeof(*addresses), qstrcmp); | 229 | qsort(addresses, n_addresses, sizeof(*addresses), qstrcmp); |
212 | for (i = 0, slen = 1; i < n_addresses; i++) { | 230 | for (size_t i = 0; i < n_addresses; i++) { |
213 | slen += strlen(addresses[i]) + 1; | 231 | slen += strlen(addresses[i]) + 1; |
214 | } | 232 | } |
233 | |||
234 | // Temporary pointer adrp gets moved, address stays on the beginning | ||
215 | adrp = address = malloc(slen); | 235 | adrp = address = malloc(slen); |
216 | for (i = 0; i < n_addresses; i++) { | 236 | for (size_t i = 0; i < n_addresses; i++) { |
217 | if (i) | 237 | if (i) { |
218 | *adrp++ = ','; | 238 | *adrp++ = ','; |
239 | } | ||
219 | strcpy(adrp, addresses[i]); | 240 | strcpy(adrp, addresses[i]); |
220 | adrp += strlen(addresses[i]); | 241 | adrp += strlen(addresses[i]); |
221 | } | 242 | } |
222 | *adrp = 0; | 243 | *adrp = 0; |
223 | } else | 244 | } else { |
224 | die(STATE_CRITICAL, _("DNS CRITICAL - '%s' msg parsing exited with no address\n"), NSLOOKUP_COMMAND); | 245 | die(STATE_CRITICAL, _("DNS CRITICAL - '%s' msg parsing exited with no address\n"), NSLOOKUP_COMMAND); |
246 | } | ||
225 | 247 | ||
226 | /* compare to expected address */ | 248 | /* compare to expected address */ |
227 | if (result == STATE_OK && expected_address_cnt > 0) { | 249 | if (result == STATE_OK && config.expected_address_cnt > 0) { |
228 | result = STATE_CRITICAL; | 250 | result = STATE_CRITICAL; |
229 | temp_buffer = ""; | 251 | char *temp_buffer = ""; |
230 | unsigned long expect_match = (1 << expected_address_cnt) - 1; | 252 | unsigned long expect_match = (1 << config.expected_address_cnt) - 1; |
231 | unsigned long addr_match = (1 << n_addresses) - 1; | 253 | unsigned long addr_match = (1 << n_addresses) - 1; |
232 | 254 | ||
233 | for (int i = 0; i < expected_address_cnt; i++) { | 255 | for (size_t i = 0; i < config.expected_address_cnt; i++) { |
234 | int j; | ||
235 | /* check if we get a match on 'raw' ip or cidr */ | 256 | /* check if we get a match on 'raw' ip or cidr */ |
236 | for (j = 0; j < n_addresses; j++) { | 257 | for (size_t j = 0; j < n_addresses; j++) { |
237 | if (strcmp(addresses[j], expected_address[i]) == 0 || ip_match_cidr(addresses[j], expected_address[i])) { | 258 | if (strcmp(addresses[j], config.expected_address[i]) == 0 || ip_match_cidr(addresses[j], config.expected_address[i])) { |
238 | result = STATE_OK; | 259 | result = STATE_OK; |
239 | addr_match &= ~(1 << j); | 260 | addr_match &= ~(1 << j); |
240 | expect_match &= ~(1 << i); | 261 | expect_match &= ~(1 << i); |
@@ -242,11 +263,12 @@ int main(int argc, char **argv) { | |||
242 | } | 263 | } |
243 | 264 | ||
244 | /* prepare an error string */ | 265 | /* prepare an error string */ |
245 | xasprintf(&temp_buffer, "%s%s; ", temp_buffer, expected_address[i]); | 266 | xasprintf(&temp_buffer, "%s%s; ", temp_buffer, config.expected_address[i]); |
246 | } | 267 | } |
247 | /* check if expected_address must cover all in addresses and none may be missing */ | 268 | /* check if expected_address must cover all in addresses and none may be missing */ |
248 | if (all_match && (expect_match != 0 || addr_match != 0)) | 269 | if (config.all_match && (expect_match != 0 || addr_match != 0)) { |
249 | result = STATE_CRITICAL; | 270 | result = STATE_CRITICAL; |
271 | } | ||
250 | if (result == STATE_CRITICAL) { | 272 | if (result == STATE_CRITICAL) { |
251 | /* Strip off last semicolon... */ | 273 | /* Strip off last semicolon... */ |
252 | temp_buffer[strlen(temp_buffer) - 2] = '\0'; | 274 | temp_buffer[strlen(temp_buffer) - 2] = '\0'; |
@@ -254,28 +276,29 @@ int main(int argc, char **argv) { | |||
254 | } | 276 | } |
255 | } | 277 | } |
256 | 278 | ||
257 | if (expect_nxdomain) { | 279 | if (config.expect_nxdomain) { |
258 | if (!is_nxdomain) { | 280 | if (!is_nxdomain) { |
259 | result = STATE_CRITICAL; | 281 | result = STATE_CRITICAL; |
260 | xasprintf(&msg, _("Domain '%s' was found by the server: '%s'\n"), query_address, address); | 282 | xasprintf(&msg, _("Domain '%s' was found by the server: '%s'\n"), config.query_address, address); |
261 | } else { | 283 | } else { |
262 | if (address != NULL) | 284 | if (address != NULL) { |
263 | free(address); | 285 | free(address); |
286 | } | ||
264 | address = "NXDOMAIN"; | 287 | address = "NXDOMAIN"; |
265 | } | 288 | } |
266 | } | 289 | } |
267 | 290 | ||
268 | /* check if authoritative */ | 291 | /* check if authoritative */ |
269 | if (result == STATE_OK && expect_authority && non_authoritative) { | 292 | if (result == STATE_OK && config.expect_authority && non_authoritative) { |
270 | result = STATE_CRITICAL; | 293 | result = STATE_CRITICAL; |
271 | xasprintf(&msg, _("server %s is not authoritative for %s"), dns_server, query_address); | 294 | xasprintf(&msg, _("server %s is not authoritative for %s"), config.dns_server, config.query_address); |
272 | } | 295 | } |
273 | 296 | ||
274 | microsec = deltime(tv); | 297 | long microsec = deltime(tv); |
275 | elapsed_time = (double)microsec / 1.0e6; | 298 | double elapsed_time = (double)microsec / 1.0e6; |
276 | 299 | ||
277 | if (result == STATE_OK) { | 300 | if (result == STATE_OK) { |
278 | result = get_status(elapsed_time, time_thresholds); | 301 | result = get_status(elapsed_time, config.time_thresholds); |
279 | if (result == STATE_OK) { | 302 | if (result == STATE_OK) { |
280 | printf("DNS %s: ", _("OK")); | 303 | printf("DNS %s: ", _("OK")); |
281 | } else if (result == STATE_WARNING) { | 304 | } else if (result == STATE_WARNING) { |
@@ -284,24 +307,26 @@ int main(int argc, char **argv) { | |||
284 | printf("DNS %s: ", _("CRITICAL")); | 307 | printf("DNS %s: ", _("CRITICAL")); |
285 | } | 308 | } |
286 | printf(ngettext("%.3f second response time", "%.3f seconds response time", elapsed_time), elapsed_time); | 309 | printf(ngettext("%.3f second response time", "%.3f seconds response time", elapsed_time), elapsed_time); |
287 | printf(_(". %s returns %s"), query_address, address); | 310 | printf(_(". %s returns %s"), config.query_address, address); |
288 | if ((time_thresholds->warning != NULL) && (time_thresholds->critical != NULL)) { | 311 | if ((config.time_thresholds->warning != NULL) && (config.time_thresholds->critical != NULL)) { |
289 | printf("|%s\n", fperfdata("time", elapsed_time, "s", true, time_thresholds->warning->end, true, time_thresholds->critical->end, | 312 | printf("|%s\n", fperfdata("time", elapsed_time, "s", true, config.time_thresholds->warning->end, true, |
290 | true, 0, false, 0)); | 313 | config.time_thresholds->critical->end, true, 0, false, 0)); |
291 | } else if ((time_thresholds->warning == NULL) && (time_thresholds->critical != NULL)) { | 314 | } else if ((config.time_thresholds->warning == NULL) && (config.time_thresholds->critical != NULL)) { |
292 | printf("|%s\n", fperfdata("time", elapsed_time, "s", false, 0, true, time_thresholds->critical->end, true, 0, false, 0)); | 315 | printf("|%s\n", fperfdata("time", elapsed_time, "s", false, 0, true, config.time_thresholds->critical->end, true, 0, false, 0)); |
293 | } else if ((time_thresholds->warning != NULL) && (time_thresholds->critical == NULL)) { | 316 | } else if ((config.time_thresholds->warning != NULL) && (config.time_thresholds->critical == NULL)) { |
294 | printf("|%s\n", fperfdata("time", elapsed_time, "s", true, time_thresholds->warning->end, false, 0, true, 0, false, 0)); | 317 | printf("|%s\n", fperfdata("time", elapsed_time, "s", true, config.time_thresholds->warning->end, false, 0, true, 0, false, 0)); |
295 | } else | 318 | } else { |
296 | printf("|%s\n", fperfdata("time", elapsed_time, "s", false, 0, false, 0, true, 0, false, 0)); | 319 | printf("|%s\n", fperfdata("time", elapsed_time, "s", false, 0, false, 0, true, 0, false, 0)); |
297 | } else if (result == STATE_WARNING) | 320 | } |
321 | } else if (result == STATE_WARNING) { | ||
298 | printf(_("DNS WARNING - %s\n"), !strcmp(msg, "") ? _(" Probably a non-existent host/domain") : msg); | 322 | printf(_("DNS WARNING - %s\n"), !strcmp(msg, "") ? _(" Probably a non-existent host/domain") : msg); |
299 | else if (result == STATE_CRITICAL) | 323 | } else if (result == STATE_CRITICAL) { |
300 | printf(_("DNS CRITICAL - %s\n"), !strcmp(msg, "") ? _(" Probably a non-existent host/domain") : msg); | 324 | printf(_("DNS CRITICAL - %s\n"), !strcmp(msg, "") ? _(" Probably a non-existent host/domain") : msg); |
301 | else | 325 | } else { |
302 | printf(_("DNS UNKNOWN - %s\n"), !strcmp(msg, "") ? _(" Probably a non-existent host/domain") : msg); | 326 | printf(_("DNS UNKNOWN - %s\n"), !strcmp(msg, "") ? _(" Probably a non-existent host/domain") : msg); |
327 | } | ||
303 | 328 | ||
304 | return result; | 329 | exit(result); |
305 | } | 330 | } |
306 | 331 | ||
307 | bool ip_match_cidr(const char *addr, const char *cidr_ro) { | 332 | bool ip_match_cidr(const char *addr, const char *cidr_ro) { |
@@ -329,64 +354,69 @@ unsigned long ip2long(const char *src) { | |||
329 | : 0; | 354 | : 0; |
330 | } | 355 | } |
331 | 356 | ||
332 | int error_scan(char *input_buffer, bool *is_nxdomain) { | 357 | mp_state_enum error_scan(char *input_buffer, bool *is_nxdomain, const char dns_server[ADDRESS_LENGTH]) { |
333 | 358 | ||
334 | const int nxdomain = strstr(input_buffer, "Non-existent") || strstr(input_buffer, "** server can't find") || | 359 | const int nxdomain = strstr(input_buffer, "Non-existent") || strstr(input_buffer, "** server can't find") || |
335 | strstr(input_buffer, "** Can't find") || strstr(input_buffer, "NXDOMAIN"); | 360 | strstr(input_buffer, "** Can't find") || strstr(input_buffer, "NXDOMAIN"); |
336 | if (nxdomain) | 361 | if (nxdomain) { |
337 | *is_nxdomain = true; | 362 | *is_nxdomain = true; |
363 | } | ||
338 | 364 | ||
339 | /* the DNS lookup timed out */ | 365 | /* the DNS lookup timed out */ |
340 | if (strstr(input_buffer, _("Note: nslookup is deprecated and may be removed from future releases.")) || | 366 | if (strstr(input_buffer, _("Note: nslookup is deprecated and may be removed from future releases.")) || |
341 | strstr(input_buffer, _("Consider using the `dig' or `host' programs instead. Run nslookup with")) || | 367 | strstr(input_buffer, _("Consider using the `dig' or `host' programs instead. Run nslookup with")) || |
342 | strstr(input_buffer, _("the `-sil[ent]' option to prevent this message from appearing."))) | 368 | strstr(input_buffer, _("the `-sil[ent]' option to prevent this message from appearing."))) { |
343 | return STATE_OK; | 369 | return STATE_OK; |
370 | } | ||
344 | 371 | ||
345 | /* DNS server is not running... */ | 372 | /* DNS server is not running... */ |
346 | else if (strstr(input_buffer, "No response from server")) | 373 | else if (strstr(input_buffer, "No response from server")) { |
347 | die(STATE_CRITICAL, _("No response from DNS %s\n"), dns_server); | 374 | die(STATE_CRITICAL, _("No response from DNS %s\n"), dns_server); |
348 | else if (strstr(input_buffer, "no servers could be reached")) | 375 | } else if (strstr(input_buffer, "no servers could be reached")) { |
349 | die(STATE_CRITICAL, _("No response from DNS %s\n"), dns_server); | 376 | die(STATE_CRITICAL, _("No response from DNS %s\n"), dns_server); |
377 | } | ||
350 | 378 | ||
351 | /* Host name is valid, but server doesn't have records... */ | 379 | /* Host name is valid, but server doesn't have records... */ |
352 | else if (strstr(input_buffer, "No records")) | 380 | else if (strstr(input_buffer, "No records")) { |
353 | die(STATE_CRITICAL, _("DNS %s has no records\n"), dns_server); | 381 | die(STATE_CRITICAL, _("DNS %s has no records\n"), dns_server); |
382 | } | ||
354 | 383 | ||
355 | /* Connection was refused */ | 384 | /* Connection was refused */ |
356 | else if (strstr(input_buffer, "Connection refused") || strstr(input_buffer, "Couldn't find server") || | 385 | else if (strstr(input_buffer, "Connection refused") || strstr(input_buffer, "Couldn't find server") || |
357 | strstr(input_buffer, "Refused") || (strstr(input_buffer, "** server can't find") && strstr(input_buffer, ": REFUSED"))) | 386 | strstr(input_buffer, "Refused") || (strstr(input_buffer, "** server can't find") && strstr(input_buffer, ": REFUSED"))) { |
358 | die(STATE_CRITICAL, _("Connection to DNS %s was refused\n"), dns_server); | 387 | die(STATE_CRITICAL, _("Connection to DNS %s was refused\n"), dns_server); |
388 | } | ||
359 | 389 | ||
360 | /* Query refused (usually by an ACL in the namserver) */ | 390 | /* Query refused (usually by an ACL in the namserver) */ |
361 | else if (strstr(input_buffer, "Query refused")) | 391 | else if (strstr(input_buffer, "Query refused")) { |
362 | die(STATE_CRITICAL, _("Query was refused by DNS server at %s\n"), dns_server); | 392 | die(STATE_CRITICAL, _("Query was refused by DNS server at %s\n"), dns_server); |
393 | } | ||
363 | 394 | ||
364 | /* No information (e.g. nameserver IP has two PTR records) */ | 395 | /* No information (e.g. nameserver IP has two PTR records) */ |
365 | else if (strstr(input_buffer, "No information")) | 396 | else if (strstr(input_buffer, "No information")) { |
366 | die(STATE_CRITICAL, _("No information returned by DNS server at %s\n"), dns_server); | 397 | die(STATE_CRITICAL, _("No information returned by DNS server at %s\n"), dns_server); |
398 | } | ||
367 | 399 | ||
368 | /* Network is unreachable */ | 400 | /* Network is unreachable */ |
369 | else if (strstr(input_buffer, "Network is unreachable")) | 401 | else if (strstr(input_buffer, "Network is unreachable")) { |
370 | die(STATE_CRITICAL, _("Network is unreachable\n")); | 402 | die(STATE_CRITICAL, _("Network is unreachable\n")); |
403 | } | ||
371 | 404 | ||
372 | /* Internal server failure */ | 405 | /* Internal server failure */ |
373 | else if (strstr(input_buffer, "Server failure")) | 406 | else if (strstr(input_buffer, "Server failure")) { |
374 | die(STATE_CRITICAL, _("DNS failure for %s\n"), dns_server); | 407 | die(STATE_CRITICAL, _("DNS failure for %s\n"), dns_server); |
408 | } | ||
375 | 409 | ||
376 | /* Request error or the DNS lookup timed out */ | 410 | /* Request error or the DNS lookup timed out */ |
377 | else if (strstr(input_buffer, "Format error") || strstr(input_buffer, "Timed out")) | 411 | else if (strstr(input_buffer, "Format error") || strstr(input_buffer, "Timed out")) { |
378 | return STATE_WARNING; | 412 | return STATE_WARNING; |
413 | } | ||
379 | 414 | ||
380 | return STATE_OK; | 415 | return STATE_OK; |
381 | } | 416 | } |
382 | 417 | ||
383 | /* process command-line arguments */ | 418 | /* process command-line arguments */ |
384 | int process_arguments(int argc, char **argv) { | 419 | check_dns_config_wrapper process_arguments(int argc, char **argv) { |
385 | int c; | ||
386 | char *warning = NULL; | ||
387 | char *critical = NULL; | ||
388 | |||
389 | int opt_index = 0; | ||
390 | static struct option long_opts[] = {{"help", no_argument, 0, 'h'}, | 420 | static struct option long_opts[] = {{"help", no_argument, 0, 'h'}, |
391 | {"version", no_argument, 0, 'V'}, | 421 | {"version", no_argument, 0, 'V'}, |
392 | {"verbose", no_argument, 0, 'v'}, | 422 | {"verbose", no_argument, 0, 'v'}, |
@@ -402,20 +432,34 @@ int process_arguments(int argc, char **argv) { | |||
402 | {"critical", required_argument, 0, 'c'}, | 432 | {"critical", required_argument, 0, 'c'}, |
403 | {0, 0, 0, 0}}; | 433 | {0, 0, 0, 0}}; |
404 | 434 | ||
405 | if (argc < 2) | 435 | check_dns_config_wrapper result = { |
406 | return ERROR; | 436 | .config = check_dns_config_init(), |
437 | .errorcode = OK, | ||
438 | }; | ||
407 | 439 | ||
408 | for (c = 1; c < argc; c++) | 440 | if (argc < 2) { |
409 | if (strcmp("-to", argv[c]) == 0) | 441 | result.errorcode = ERROR; |
410 | strcpy(argv[c], "-t"); | 442 | return result; |
443 | } | ||
411 | 444 | ||
412 | while (1) { | 445 | for (int index = 1; index < argc; index++) { |
413 | c = getopt_long(argc, argv, "hVvALnt:H:s:r:a:w:c:", long_opts, &opt_index); | 446 | if (strcmp("-to", argv[index]) == 0) { |
447 | strcpy(argv[index], "-t"); | ||
448 | } | ||
449 | } | ||
450 | |||
451 | char *warning = NULL; | ||
452 | char *critical = NULL; | ||
453 | int opt_index = 0; | ||
454 | int index = 0; | ||
455 | while (true) { | ||
456 | index = getopt_long(argc, argv, "hVvALnt:H:s:r:a:w:c:", long_opts, &opt_index); | ||
414 | 457 | ||
415 | if (c == -1 || c == EOF) | 458 | if (index == -1 || index == EOF) { |
416 | break; | 459 | break; |
460 | } | ||
417 | 461 | ||
418 | switch (c) { | 462 | switch (index) { |
419 | case 'h': /* help */ | 463 | case 'h': /* help */ |
420 | print_help(); | 464 | print_help(); |
421 | exit(STATE_UNKNOWN); | 465 | exit(STATE_UNKNOWN); |
@@ -429,54 +473,63 @@ int process_arguments(int argc, char **argv) { | |||
429 | timeout_interval = atoi(optarg); | 473 | timeout_interval = atoi(optarg); |
430 | break; | 474 | break; |
431 | case 'H': /* hostname */ | 475 | case 'H': /* hostname */ |
432 | if (strlen(optarg) >= ADDRESS_LENGTH) | 476 | if (strlen(optarg) >= ADDRESS_LENGTH) { |
433 | die(STATE_UNKNOWN, _("Input buffer overflow\n")); | 477 | die(STATE_UNKNOWN, _("Input buffer overflow\n")); |
434 | strcpy(query_address, optarg); | 478 | } |
479 | strcpy(result.config.query_address, optarg); | ||
435 | break; | 480 | break; |
436 | case 's': /* server name */ | 481 | case 's': /* server name */ |
437 | /* TODO: this host_or_die check is probably unnecessary. | 482 | /* TODO: this host_or_die check is probably unnecessary. |
438 | * Better to confirm nslookup response matches */ | 483 | * Better to confirm nslookup response matches */ |
439 | host_or_die(optarg); | 484 | host_or_die(optarg); |
440 | if (strlen(optarg) >= ADDRESS_LENGTH) | 485 | if (strlen(optarg) >= ADDRESS_LENGTH) { |
441 | die(STATE_UNKNOWN, _("Input buffer overflow\n")); | 486 | die(STATE_UNKNOWN, _("Input buffer overflow\n")); |
442 | strcpy(dns_server, optarg); | 487 | } |
488 | strcpy(result.config.dns_server, optarg); | ||
443 | break; | 489 | break; |
444 | case 'r': /* reverse server name */ | 490 | case 'r': /* reverse server name */ |
445 | /* TODO: Is this host_or_die necessary? */ | 491 | /* TODO: Is this host_or_die necessary? */ |
492 | // TODO This does not do anything!!! 2025-03-08 rincewind | ||
446 | host_or_die(optarg); | 493 | host_or_die(optarg); |
447 | if (strlen(optarg) >= ADDRESS_LENGTH) | 494 | if (strlen(optarg) >= ADDRESS_LENGTH) { |
448 | die(STATE_UNKNOWN, _("Input buffer overflow\n")); | 495 | die(STATE_UNKNOWN, _("Input buffer overflow\n")); |
496 | } | ||
497 | static char ptr_server[ADDRESS_LENGTH] = ""; | ||
449 | strcpy(ptr_server, optarg); | 498 | strcpy(ptr_server, optarg); |
450 | break; | 499 | break; |
451 | case 'a': /* expected address */ | 500 | case 'a': /* expected address */ |
452 | if (strlen(optarg) >= ADDRESS_LENGTH) | 501 | if (strlen(optarg) >= ADDRESS_LENGTH) { |
453 | die(STATE_UNKNOWN, _("Input buffer overflow\n")); | 502 | die(STATE_UNKNOWN, _("Input buffer overflow\n")); |
503 | } | ||
454 | if (strchr(optarg, ',') != NULL) { | 504 | if (strchr(optarg, ',') != NULL) { |
455 | char *comma = strchr(optarg, ','); | 505 | char *comma = strchr(optarg, ','); |
456 | while (comma != NULL) { | 506 | while (comma != NULL) { |
457 | expected_address = (char **)realloc(expected_address, (expected_address_cnt + 1) * sizeof(char **)); | 507 | result.config.expected_address = |
458 | expected_address[expected_address_cnt] = strndup(optarg, comma - optarg); | 508 | (char **)realloc(result.config.expected_address, (result.config.expected_address_cnt + 1) * sizeof(char **)); |
459 | expected_address_cnt++; | 509 | result.config.expected_address[result.config.expected_address_cnt] = strndup(optarg, comma - optarg); |
510 | result.config.expected_address_cnt++; | ||
460 | optarg = comma + 1; | 511 | optarg = comma + 1; |
461 | comma = strchr(optarg, ','); | 512 | comma = strchr(optarg, ','); |
462 | } | 513 | } |
463 | expected_address = (char **)realloc(expected_address, (expected_address_cnt + 1) * sizeof(char **)); | 514 | result.config.expected_address = |
464 | expected_address[expected_address_cnt] = strdup(optarg); | 515 | (char **)realloc(result.config.expected_address, (result.config.expected_address_cnt + 1) * sizeof(char **)); |
465 | expected_address_cnt++; | 516 | result.config.expected_address[result.config.expected_address_cnt] = strdup(optarg); |
517 | result.config.expected_address_cnt++; | ||
466 | } else { | 518 | } else { |
467 | expected_address = (char **)realloc(expected_address, (expected_address_cnt + 1) * sizeof(char **)); | 519 | result.config.expected_address = |
468 | expected_address[expected_address_cnt] = strdup(optarg); | 520 | (char **)realloc(result.config.expected_address, (result.config.expected_address_cnt + 1) * sizeof(char **)); |
469 | expected_address_cnt++; | 521 | result.config.expected_address[result.config.expected_address_cnt] = strdup(optarg); |
522 | result.config.expected_address_cnt++; | ||
470 | } | 523 | } |
471 | break; | 524 | break; |
472 | case 'n': /* expect NXDOMAIN */ | 525 | case 'n': /* expect NXDOMAIN */ |
473 | expect_nxdomain = true; | 526 | result.config.expect_nxdomain = true; |
474 | break; | 527 | break; |
475 | case 'A': /* expect authority */ | 528 | case 'A': /* expect authority */ |
476 | expect_authority = true; | 529 | result.config.expect_authority = true; |
477 | break; | 530 | break; |
478 | case 'L': /* all must match */ | 531 | case 'L': /* all must match */ |
479 | all_match = true; | 532 | result.config.all_match = true; |
480 | break; | 533 | break; |
481 | case 'w': | 534 | case 'w': |
482 | warning = optarg; | 535 | warning = optarg; |
@@ -489,38 +542,42 @@ int process_arguments(int argc, char **argv) { | |||
489 | } | 542 | } |
490 | } | 543 | } |
491 | 544 | ||
492 | c = optind; | 545 | index = optind; |
493 | if (strlen(query_address) == 0 && c < argc) { | 546 | if (strlen(result.config.query_address) == 0 && index < argc) { |
494 | if (strlen(argv[c]) >= ADDRESS_LENGTH) | 547 | if (strlen(argv[index]) >= ADDRESS_LENGTH) { |
495 | die(STATE_UNKNOWN, _("Input buffer overflow\n")); | 548 | die(STATE_UNKNOWN, _("Input buffer overflow\n")); |
496 | strcpy(query_address, argv[c++]); | 549 | } |
550 | strcpy(result.config.query_address, argv[index++]); | ||
497 | } | 551 | } |
498 | 552 | ||
499 | if (strlen(dns_server) == 0 && c < argc) { | 553 | if (strlen(result.config.dns_server) == 0 && index < argc) { |
500 | /* TODO: See -s option */ | 554 | /* TODO: See -s option */ |
501 | host_or_die(argv[c]); | 555 | host_or_die(argv[index]); |
502 | if (strlen(argv[c]) >= ADDRESS_LENGTH) | 556 | if (strlen(argv[index]) >= ADDRESS_LENGTH) { |
503 | die(STATE_UNKNOWN, _("Input buffer overflow\n")); | 557 | die(STATE_UNKNOWN, _("Input buffer overflow\n")); |
504 | strcpy(dns_server, argv[c++]); | 558 | } |
559 | strcpy(result.config.dns_server, argv[index++]); | ||
505 | } | 560 | } |
506 | 561 | ||
507 | set_thresholds(&time_thresholds, warning, critical); | 562 | set_thresholds(&result.config.time_thresholds, warning, critical); |
508 | 563 | ||
509 | return validate_arguments(); | 564 | return validate_arguments(result); |
510 | } | 565 | } |
511 | 566 | ||
512 | int validate_arguments(void) { | 567 | check_dns_config_wrapper validate_arguments(check_dns_config_wrapper config_wrapper) { |
513 | if (query_address[0] == 0) { | 568 | if (config_wrapper.config.query_address[0] == 0) { |
514 | printf("missing --host argument\n"); | 569 | printf("missing --host argument\n"); |
515 | return ERROR; | 570 | config_wrapper.errorcode = ERROR; |
571 | return config_wrapper; | ||
516 | } | 572 | } |
517 | 573 | ||
518 | if (expected_address_cnt > 0 && expect_nxdomain) { | 574 | if (config_wrapper.config.expected_address_cnt > 0 && config_wrapper.config.expect_nxdomain) { |
519 | printf("--expected-address and --expect-nxdomain cannot be combined\n"); | 575 | printf("--expected-address and --expect-nxdomain cannot be combined\n"); |
520 | return ERROR; | 576 | config_wrapper.errorcode = ERROR; |
577 | return config_wrapper; | ||
521 | } | 578 | } |
522 | 579 | ||
523 | return OK; | 580 | return config_wrapper; |
524 | } | 581 | } |
525 | 582 | ||
526 | void print_help(void) { | 583 | void print_help(void) { |
diff --git a/plugins/check_dns.d/config.h b/plugins/check_dns.d/config.h new file mode 100644 index 00000000..9ec4eb82 --- /dev/null +++ b/plugins/check_dns.d/config.h | |||
@@ -0,0 +1,34 @@ | |||
1 | #pragma once | ||
2 | |||
3 | #include "../../config.h" | ||
4 | #include "thresholds.h" | ||
5 | #include <stddef.h> | ||
6 | |||
7 | #define ADDRESS_LENGTH 256 | ||
8 | |||
9 | typedef struct { | ||
10 | bool all_match; | ||
11 | char dns_server[ADDRESS_LENGTH]; | ||
12 | char query_address[ADDRESS_LENGTH]; | ||
13 | bool expect_nxdomain; | ||
14 | bool expect_authority; | ||
15 | char **expected_address; | ||
16 | size_t expected_address_cnt; | ||
17 | |||
18 | thresholds *time_thresholds; | ||
19 | } check_dns_config; | ||
20 | |||
21 | check_dns_config check_dns_config_init() { | ||
22 | check_dns_config tmp = { | ||
23 | .all_match = false, | ||
24 | .dns_server = "", | ||
25 | .query_address = "", | ||
26 | .expect_nxdomain = false, | ||
27 | .expect_authority = false, | ||
28 | .expected_address = NULL, | ||
29 | .expected_address_cnt = 0, | ||
30 | |||
31 | .time_thresholds = NULL, | ||
32 | }; | ||
33 | return tmp; | ||
34 | } | ||
diff --git a/plugins/check_game.c b/plugins/check_game.c index 619277e7..c0193b03 100644 --- a/plugins/check_game.c +++ b/plugins/check_game.c | |||
@@ -36,9 +36,15 @@ const char *email = "devel@monitoring-plugins.org"; | |||
36 | #include "common.h" | 36 | #include "common.h" |
37 | #include "utils.h" | 37 | #include "utils.h" |
38 | #include "runcmd.h" | 38 | #include "runcmd.h" |
39 | #include "check_game.d/config.h" | ||
40 | #include "../lib/monitoringplug.h" | ||
39 | 41 | ||
40 | static int process_arguments(int /*argc*/, char ** /*argv*/); | 42 | typedef struct { |
41 | static int validate_arguments(void); | 43 | int errorcode; |
44 | check_game_config config; | ||
45 | } check_game_config_wrapper; | ||
46 | |||
47 | static check_game_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); | ||
42 | static void print_help(void); | 48 | static void print_help(void); |
43 | void print_usage(void); | 49 | void print_usage(void); |
44 | 50 | ||
@@ -49,26 +55,9 @@ void print_usage(void); | |||
49 | #define QSTAT_HOST_TIMEOUT "TIMEOUT" | 55 | #define QSTAT_HOST_TIMEOUT "TIMEOUT" |
50 | #define QSTAT_MAX_RETURN_ARGS 12 | 56 | #define QSTAT_MAX_RETURN_ARGS 12 |
51 | 57 | ||
52 | static char *server_ip; | ||
53 | static char *game_type; | ||
54 | static int port = 0; | ||
55 | |||
56 | static bool verbose = false; | 58 | static bool verbose = false; |
57 | 59 | ||
58 | static int qstat_game_players_max = -1; | ||
59 | static int qstat_game_players = -1; | ||
60 | static int qstat_game_field = -1; | ||
61 | static int qstat_map_field = -1; | ||
62 | static int qstat_ping_field = -1; | ||
63 | |||
64 | int main(int argc, char **argv) { | 60 | int main(int argc, char **argv) { |
65 | char *command_line; | ||
66 | int result = STATE_UNKNOWN; | ||
67 | char *p; | ||
68 | char *ret[QSTAT_MAX_RETURN_ARGS]; | ||
69 | size_t i = 0; | ||
70 | output chld_out; | ||
71 | |||
72 | setlocale(LC_ALL, ""); | 61 | setlocale(LC_ALL, ""); |
73 | bindtextdomain(PACKAGE, LOCALEDIR); | 62 | bindtextdomain(PACKAGE, LOCALEDIR); |
74 | textdomain(PACKAGE); | 63 | textdomain(PACKAGE); |
@@ -76,22 +65,31 @@ int main(int argc, char **argv) { | |||
76 | /* Parse extra opts if any */ | 65 | /* Parse extra opts if any */ |
77 | argv = np_extra_opts(&argc, argv, progname); | 66 | argv = np_extra_opts(&argc, argv, progname); |
78 | 67 | ||
79 | if (process_arguments(argc, argv) == ERROR) | 68 | check_game_config_wrapper tmp = process_arguments(argc, argv); |
69 | |||
70 | if (tmp.errorcode == ERROR) { | ||
80 | usage_va(_("Could not parse arguments")); | 71 | usage_va(_("Could not parse arguments")); |
72 | } | ||
73 | |||
74 | check_game_config config = tmp.config; | ||
81 | 75 | ||
82 | result = STATE_OK; | 76 | mp_state_enum result = STATE_OK; |
83 | 77 | ||
84 | /* create the command line to execute */ | 78 | /* create the command line to execute */ |
85 | xasprintf(&command_line, "%s -raw %s -%s %s", PATH_TO_QSTAT, QSTAT_DATA_DELIMITER, game_type, server_ip); | 79 | char *command_line = NULL; |
80 | xasprintf(&command_line, "%s -raw %s -%s %s", PATH_TO_QSTAT, QSTAT_DATA_DELIMITER, config.game_type, config.server_ip); | ||
86 | 81 | ||
87 | if (port) | 82 | if (config.port) { |
88 | xasprintf(&command_line, "%s:%-d", command_line, port); | 83 | xasprintf(&command_line, "%s:%-d", command_line, config.port); |
84 | } | ||
89 | 85 | ||
90 | if (verbose) | 86 | if (verbose) { |
91 | printf("%s\n", command_line); | 87 | printf("%s\n", command_line); |
88 | } | ||
92 | 89 | ||
93 | /* run the command. historically, this plugin ignores output on stderr, | 90 | /* run the command. historically, this plugin ignores output on stderr, |
94 | * as well as return status of the qstat program */ | 91 | * as well as return status of the qstat program */ |
92 | output chld_out = {}; | ||
95 | (void)np_runcmd(command_line, &chld_out, NULL, 0); | 93 | (void)np_runcmd(command_line, &chld_out, NULL, 0); |
96 | 94 | ||
97 | /* sanity check */ | 95 | /* sanity check */ |
@@ -104,19 +102,22 @@ int main(int argc, char **argv) { | |||
104 | In the end, I figured I'd simply let an error occur & then trap it | 102 | In the end, I figured I'd simply let an error occur & then trap it |
105 | */ | 103 | */ |
106 | 104 | ||
107 | if (!strncmp(chld_out.line[0], "unknown option", 14)) { | 105 | if (!strncmp(chld_out.line[0], "unknown option", strlen("unknown option"))) { |
108 | printf(_("CRITICAL - Host type parameter incorrect!\n")); | 106 | printf(_("CRITICAL - Host type parameter incorrect!\n")); |
109 | result = STATE_CRITICAL; | 107 | result = STATE_CRITICAL; |
110 | return result; | 108 | exit(result); |
111 | } | 109 | } |
112 | 110 | ||
113 | p = (char *)strtok(chld_out.line[0], QSTAT_DATA_DELIMITER); | 111 | char *ret[QSTAT_MAX_RETURN_ARGS]; |
114 | while (p != NULL) { | 112 | size_t i = 0; |
115 | ret[i] = p; | 113 | char *sequence = strtok(chld_out.line[0], QSTAT_DATA_DELIMITER); |
116 | p = (char *)strtok(NULL, QSTAT_DATA_DELIMITER); | 114 | while (sequence != NULL) { |
115 | ret[i] = sequence; | ||
116 | sequence = strtok(NULL, QSTAT_DATA_DELIMITER); | ||
117 | i++; | 117 | i++; |
118 | if (i >= QSTAT_MAX_RETURN_ARGS) | 118 | if (i >= QSTAT_MAX_RETURN_ARGS) { |
119 | break; | 119 | break; |
120 | } | ||
120 | } | 121 | } |
121 | 122 | ||
122 | if (strstr(ret[2], QSTAT_HOST_ERROR)) { | 123 | if (strstr(ret[2], QSTAT_HOST_ERROR)) { |
@@ -129,19 +130,20 @@ int main(int argc, char **argv) { | |||
129 | printf(_("CRITICAL - Game server timeout\n")); | 130 | printf(_("CRITICAL - Game server timeout\n")); |
130 | result = STATE_CRITICAL; | 131 | result = STATE_CRITICAL; |
131 | } else { | 132 | } else { |
132 | printf("OK: %s/%s %s (%s), Ping: %s ms|%s %s\n", ret[qstat_game_players], ret[qstat_game_players_max], ret[qstat_game_field], | 133 | printf("OK: %s/%s %s (%s), Ping: %s ms|%s %s\n", ret[config.qstat_game_players], ret[config.qstat_game_players_max], |
133 | ret[qstat_map_field], ret[qstat_ping_field], | 134 | ret[config.qstat_game_field], ret[config.qstat_map_field], ret[config.qstat_ping_field], |
134 | perfdata("players", atol(ret[qstat_game_players]), "", false, 0, false, 0, true, 0, true, atol(ret[qstat_game_players_max])), | 135 | perfdata("players", atol(ret[config.qstat_game_players]), "", false, 0, false, 0, true, 0, true, |
135 | fperfdata("ping", strtod(ret[qstat_ping_field], NULL), "", false, 0, false, 0, true, 0, false, 0)); | 136 | atol(ret[config.qstat_game_players_max])), |
137 | fperfdata("ping", strtod(ret[config.qstat_ping_field], NULL), "", false, 0, false, 0, true, 0, false, 0)); | ||
136 | } | 138 | } |
137 | 139 | ||
138 | return result; | 140 | exit(result); |
139 | } | 141 | } |
140 | 142 | ||
141 | int process_arguments(int argc, char **argv) { | 143 | #define players_field_index 129 |
142 | int c; | 144 | #define max_players_field_index 130 |
143 | 145 | ||
144 | int opt_index = 0; | 146 | check_game_config_wrapper process_arguments(int argc, char **argv) { |
145 | static struct option long_opts[] = {{"help", no_argument, 0, 'h'}, | 147 | static struct option long_opts[] = {{"help", no_argument, 0, 'h'}, |
146 | {"version", no_argument, 0, 'V'}, | 148 | {"version", no_argument, 0, 'V'}, |
147 | {"verbose", no_argument, 0, 'v'}, | 149 | {"verbose", no_argument, 0, 'v'}, |
@@ -152,29 +154,39 @@ int process_arguments(int argc, char **argv) { | |||
152 | {"map-field", required_argument, 0, 'm'}, | 154 | {"map-field", required_argument, 0, 'm'}, |
153 | {"ping-field", required_argument, 0, 'p'}, | 155 | {"ping-field", required_argument, 0, 'p'}, |
154 | {"game-field", required_argument, 0, 'g'}, | 156 | {"game-field", required_argument, 0, 'g'}, |
155 | {"players-field", required_argument, 0, 129}, | 157 | {"players-field", required_argument, 0, players_field_index}, |
156 | {"max-players-field", required_argument, 0, 130}, | 158 | {"max-players-field", required_argument, 0, max_players_field_index}, |
157 | {0, 0, 0, 0}}; | 159 | {0, 0, 0, 0}}; |
158 | 160 | ||
159 | if (argc < 2) | 161 | check_game_config_wrapper result = { |
160 | return ERROR; | 162 | .config = check_game_config_init(), |
163 | .errorcode = OK, | ||
164 | }; | ||
165 | |||
166 | if (argc < 2) { | ||
167 | result.errorcode = ERROR; | ||
168 | return result; | ||
169 | } | ||
161 | 170 | ||
162 | for (c = 1; c < argc; c++) { | 171 | for (int option_counter = 1; option_counter < argc; option_counter++) { |
163 | if (strcmp("-mf", argv[c]) == 0) | 172 | if (strcmp("-mf", argv[option_counter]) == 0) { |
164 | strcpy(argv[c], "-m"); | 173 | strcpy(argv[option_counter], "-m"); |
165 | else if (strcmp("-pf", argv[c]) == 0) | 174 | } else if (strcmp("-pf", argv[option_counter]) == 0) { |
166 | strcpy(argv[c], "-p"); | 175 | strcpy(argv[option_counter], "-p"); |
167 | else if (strcmp("-gf", argv[c]) == 0) | 176 | } else if (strcmp("-gf", argv[option_counter]) == 0) { |
168 | strcpy(argv[c], "-g"); | 177 | strcpy(argv[option_counter], "-g"); |
178 | } | ||
169 | } | 179 | } |
170 | 180 | ||
171 | while (1) { | 181 | int opt_index = 0; |
172 | c = getopt_long(argc, argv, "hVvt:H:P:G:g:p:m:", long_opts, &opt_index); | 182 | while (true) { |
183 | int option_index = getopt_long(argc, argv, "hVvt:H:P:G:g:p:m:", long_opts, &opt_index); | ||
173 | 184 | ||
174 | if (c == -1 || c == EOF) | 185 | if (option_index == -1 || option_index == EOF) { |
175 | break; | 186 | break; |
187 | } | ||
176 | 188 | ||
177 | switch (c) { | 189 | switch (option_index) { |
178 | case 'h': /* help */ | 190 | case 'h': /* help */ |
179 | print_help(); | 191 | print_help(); |
180 | exit(STATE_UNKNOWN); | 192 | exit(STATE_UNKNOWN); |
@@ -188,79 +200,75 @@ int process_arguments(int argc, char **argv) { | |||
188 | timeout_interval = atoi(optarg); | 200 | timeout_interval = atoi(optarg); |
189 | break; | 201 | break; |
190 | case 'H': /* hostname */ | 202 | case 'H': /* hostname */ |
191 | if (strlen(optarg) >= MAX_HOST_ADDRESS_LENGTH) | 203 | if (strlen(optarg) >= MAX_HOST_ADDRESS_LENGTH) { |
192 | die(STATE_UNKNOWN, _("Input buffer overflow\n")); | 204 | die(STATE_UNKNOWN, _("Input buffer overflow\n")); |
193 | server_ip = optarg; | 205 | } |
206 | result.config.server_ip = optarg; | ||
194 | break; | 207 | break; |
195 | case 'P': /* port */ | 208 | case 'P': /* port */ |
196 | port = atoi(optarg); | 209 | result.config.port = atoi(optarg); |
197 | break; | 210 | break; |
198 | case 'G': /* hostname */ | 211 | case 'G': /* hostname */ |
199 | if (strlen(optarg) >= MAX_INPUT_BUFFER) | 212 | if (strlen(optarg) >= MAX_INPUT_BUFFER) { |
200 | die(STATE_UNKNOWN, _("Input buffer overflow\n")); | 213 | die(STATE_UNKNOWN, _("Input buffer overflow\n")); |
201 | game_type = optarg; | 214 | } |
215 | result.config.game_type = optarg; | ||
202 | break; | 216 | break; |
203 | case 'p': /* index of ping field */ | 217 | case 'p': /* index of ping field */ |
204 | qstat_ping_field = atoi(optarg); | 218 | result.config.qstat_ping_field = atoi(optarg); |
205 | if (qstat_ping_field < 0 || qstat_ping_field > QSTAT_MAX_RETURN_ARGS) | 219 | if (result.config.qstat_ping_field < 0 || result.config.qstat_ping_field > QSTAT_MAX_RETURN_ARGS) { |
206 | return ERROR; | 220 | result.errorcode = ERROR; |
221 | return result; | ||
222 | } | ||
207 | break; | 223 | break; |
208 | case 'm': /* index on map field */ | 224 | case 'm': /* index on map field */ |
209 | qstat_map_field = atoi(optarg); | 225 | result.config.qstat_map_field = atoi(optarg); |
210 | if (qstat_map_field < 0 || qstat_map_field > QSTAT_MAX_RETURN_ARGS) | 226 | if (result.config.qstat_map_field < 0 || result.config.qstat_map_field > QSTAT_MAX_RETURN_ARGS) { |
211 | return ERROR; | 227 | result.errorcode = ERROR; |
228 | return result; | ||
229 | } | ||
212 | break; | 230 | break; |
213 | case 'g': /* index of game field */ | 231 | case 'g': /* index of game field */ |
214 | qstat_game_field = atoi(optarg); | 232 | result.config.qstat_game_field = atoi(optarg); |
215 | if (qstat_game_field < 0 || qstat_game_field > QSTAT_MAX_RETURN_ARGS) | 233 | if (result.config.qstat_game_field < 0 || result.config.qstat_game_field > QSTAT_MAX_RETURN_ARGS) { |
216 | return ERROR; | 234 | result.errorcode = ERROR; |
235 | return result; | ||
236 | } | ||
217 | break; | 237 | break; |
218 | case 129: /* index of player count field */ | 238 | case players_field_index: /* index of player count field */ |
219 | qstat_game_players = atoi(optarg); | 239 | result.config.qstat_game_players = atoi(optarg); |
220 | if (qstat_game_players_max == 0) | 240 | if (result.config.qstat_game_players_max == 0) { |
221 | qstat_game_players_max = qstat_game_players - 1; | 241 | result.config.qstat_game_players_max = result.config.qstat_game_players - 1; |
222 | if (qstat_game_players < 0 || qstat_game_players > QSTAT_MAX_RETURN_ARGS) | 242 | } |
223 | return ERROR; | 243 | if (result.config.qstat_game_players < 0 || result.config.qstat_game_players > QSTAT_MAX_RETURN_ARGS) { |
244 | result.errorcode = ERROR; | ||
245 | return result; | ||
246 | } | ||
224 | break; | 247 | break; |
225 | case 130: /* index of max players field */ | 248 | case max_players_field_index: /* index of max players field */ |
226 | qstat_game_players_max = atoi(optarg); | 249 | result.config.qstat_game_players_max = atoi(optarg); |
227 | if (qstat_game_players_max < 0 || qstat_game_players_max > QSTAT_MAX_RETURN_ARGS) | 250 | if (result.config.qstat_game_players_max < 0 || result.config.qstat_game_players_max > QSTAT_MAX_RETURN_ARGS) { |
228 | return ERROR; | 251 | result.errorcode = ERROR; |
252 | return result; | ||
253 | } | ||
229 | break; | 254 | break; |
230 | default: /* args not parsable */ | 255 | default: /* args not parsable */ |
231 | usage5(); | 256 | usage5(); |
232 | } | 257 | } |
233 | } | 258 | } |
234 | 259 | ||
235 | c = optind; | 260 | int option_counter = optind; |
236 | /* first option is the game type */ | 261 | /* first option is the game type */ |
237 | if (!game_type && c < argc) | 262 | if (!result.config.game_type && option_counter < argc) { |
238 | game_type = strdup(argv[c++]); | 263 | result.config.game_type = strdup(argv[option_counter++]); |
264 | } | ||
239 | 265 | ||
240 | /* Second option is the server name */ | 266 | /* Second option is the server name */ |
241 | if (!server_ip && c < argc) | 267 | if (!result.config.server_ip && option_counter < argc) { |
242 | server_ip = strdup(argv[c++]); | 268 | result.config.server_ip = strdup(argv[option_counter++]); |
243 | 269 | } | |
244 | return validate_arguments(); | ||
245 | } | ||
246 | |||
247 | int validate_arguments(void) { | ||
248 | if (qstat_game_players_max < 0) | ||
249 | qstat_game_players_max = 4; | ||
250 | |||
251 | if (qstat_game_players < 0) | ||
252 | qstat_game_players = 5; | ||
253 | |||
254 | if (qstat_game_field < 0) | ||
255 | qstat_game_field = 2; | ||
256 | |||
257 | if (qstat_map_field < 0) | ||
258 | qstat_map_field = 3; | ||
259 | |||
260 | if (qstat_ping_field < 0) | ||
261 | qstat_ping_field = 5; | ||
262 | 270 | ||
263 | return OK; | 271 | return result; |
264 | } | 272 | } |
265 | 273 | ||
266 | void print_help(void) { | 274 | void print_help(void) { |
@@ -277,14 +285,15 @@ void print_help(void) { | |||
277 | 285 | ||
278 | printf(UT_HELP_VRSN); | 286 | printf(UT_HELP_VRSN); |
279 | printf(UT_EXTRA_OPTS); | 287 | printf(UT_EXTRA_OPTS); |
280 | 288 | printf(" -H, --hostname=ADDRESS\n" | |
281 | printf(" %s\n", "-p"); | 289 | " Host name, IP Address, or unix socket (must be an absolute path)\n"); |
282 | printf(" %s\n", _("Optional port of which to connect")); | 290 | printf(" %s\n", "-P"); |
283 | printf(" %s\n", "gf"); | 291 | printf(" %s\n", _("Optional port to connect to")); |
292 | printf(" %s\n", "-g"); | ||
284 | printf(" %s\n", _("Field number in raw qstat output that contains game name")); | 293 | printf(" %s\n", _("Field number in raw qstat output that contains game name")); |
285 | printf(" %s\n", "-mf"); | 294 | printf(" %s\n", "-m"); |
286 | printf(" %s\n", _("Field number in raw qstat output that contains map name")); | 295 | printf(" %s\n", _("Field number in raw qstat output that contains map name")); |
287 | printf(" %s\n", "-pf"); | 296 | printf(" %s\n", "-p"); |
288 | printf(" %s\n", _("Field number in raw qstat output that contains ping time")); | 297 | printf(" %s\n", _("Field number in raw qstat output that contains ping time")); |
289 | 298 | ||
290 | printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); | 299 | printf(UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); |
diff --git a/plugins/check_game.d/config.h b/plugins/check_game.d/config.h new file mode 100644 index 00000000..c95a1ced --- /dev/null +++ b/plugins/check_game.d/config.h | |||
@@ -0,0 +1,30 @@ | |||
1 | #pragma once | ||
2 | #include "../../config.h" | ||
3 | #include <stddef.h> | ||
4 | |||
5 | typedef struct { | ||
6 | char *server_ip; | ||
7 | char *game_type; | ||
8 | int port; | ||
9 | |||
10 | int qstat_game_players_max; | ||
11 | int qstat_game_players; | ||
12 | int qstat_game_field; | ||
13 | int qstat_map_field; | ||
14 | int qstat_ping_field; | ||
15 | } check_game_config; | ||
16 | |||
17 | check_game_config check_game_config_init() { | ||
18 | check_game_config tmp = { | ||
19 | .server_ip = NULL, | ||
20 | .game_type = NULL, | ||
21 | .port = 0, | ||
22 | |||
23 | .qstat_game_players_max = 4, | ||
24 | .qstat_game_players = 5, | ||
25 | .qstat_map_field = 3, | ||
26 | .qstat_game_field = 2, | ||
27 | .qstat_ping_field = 5, | ||
28 | }; | ||
29 | return tmp; | ||
30 | } | ||
diff --git a/plugins/check_ssh.c b/plugins/check_ssh.c index 42a88cf9..9d0d7cde 100644 --- a/plugins/check_ssh.c +++ b/plugins/check_ssh.c | |||
@@ -28,6 +28,9 @@ | |||
28 | * | 28 | * |
29 | *****************************************************************************/ | 29 | *****************************************************************************/ |
30 | 30 | ||
31 | #include "output.h" | ||
32 | #include "perfdata.h" | ||
33 | #include "states.h" | ||
31 | const char *progname = "check_ssh"; | 34 | const char *progname = "check_ssh"; |
32 | const char *copyright = "2000-2024"; | 35 | const char *copyright = "2000-2024"; |
33 | const char *email = "devel@monitoring-plugins.org"; | 36 | const char *email = "devel@monitoring-plugins.org"; |
@@ -35,26 +38,26 @@ const char *email = "devel@monitoring-plugins.org"; | |||
35 | #include "./common.h" | 38 | #include "./common.h" |
36 | #include "./netutils.h" | 39 | #include "./netutils.h" |
37 | #include "utils.h" | 40 | #include "utils.h" |
41 | #include "./check_ssh.d/config.h" | ||
38 | 42 | ||
39 | #ifndef MSG_DONTWAIT | 43 | #ifndef MSG_DONTWAIT |
40 | # define MSG_DONTWAIT 0 | 44 | # define MSG_DONTWAIT 0 |
41 | #endif | 45 | #endif |
42 | 46 | ||
43 | #define SSH_DFL_PORT 22 | 47 | #define BUFF_SZ 256 |
44 | #define BUFF_SZ 256 | ||
45 | 48 | ||
46 | static int port = -1; | ||
47 | static char *server_name = NULL; | ||
48 | static char *remote_version = NULL; | ||
49 | static char *remote_protocol = NULL; | ||
50 | static bool verbose = false; | 49 | static bool verbose = false; |
51 | 50 | ||
52 | static int process_arguments(int /*argc*/, char ** /*argv*/); | 51 | typedef struct process_arguments_wrapper { |
53 | static int validate_arguments(void); | 52 | int errorcode; |
53 | check_ssh_config config; | ||
54 | } process_arguments_wrapper; | ||
55 | |||
56 | static process_arguments_wrapper process_arguments(int /*argc*/, char ** /*argv*/); | ||
54 | static void print_help(void); | 57 | static void print_help(void); |
55 | void print_usage(void); | 58 | void print_usage(void); |
56 | 59 | ||
57 | static int ssh_connect(char *haddr, int hport, char *remote_version, char *remote_protocol); | 60 | static int ssh_connect(mp_check *overall, char *haddr, int hport, char *remote_version, char *remote_protocol); |
58 | 61 | ||
59 | int main(int argc, char **argv) { | 62 | int main(int argc, char **argv) { |
60 | setlocale(LC_ALL, ""); | 63 | setlocale(LC_ALL, ""); |
@@ -64,24 +67,35 @@ int main(int argc, char **argv) { | |||
64 | /* Parse extra opts if any */ | 67 | /* Parse extra opts if any */ |
65 | argv = np_extra_opts(&argc, argv, progname); | 68 | argv = np_extra_opts(&argc, argv, progname); |
66 | 69 | ||
67 | if (process_arguments(argc, argv) == ERROR) | 70 | process_arguments_wrapper tmp_config = process_arguments(argc, argv); |
71 | |||
72 | if (tmp_config.errorcode == ERROR) { | ||
68 | usage4(_("Could not parse arguments")); | 73 | usage4(_("Could not parse arguments")); |
74 | } | ||
75 | |||
76 | check_ssh_config config = tmp_config.config; | ||
77 | |||
78 | mp_check overall = mp_check_init(); | ||
79 | if (config.output_format_is_set) { | ||
80 | mp_set_format(config.output_format); | ||
81 | } | ||
69 | 82 | ||
70 | /* initialize alarm signal handling */ | 83 | /* initialize alarm signal handling */ |
71 | signal(SIGALRM, socket_timeout_alarm_handler); | 84 | signal(SIGALRM, socket_timeout_alarm_handler); |
72 | |||
73 | alarm(socket_timeout); | 85 | alarm(socket_timeout); |
74 | 86 | ||
75 | /* ssh_connect exits if error is found */ | 87 | /* ssh_connect exits if error is found */ |
76 | int result = ssh_connect(server_name, port, remote_version, remote_protocol); | 88 | ssh_connect(&overall, config.server_name, config.port, config.remote_version, config.remote_protocol); |
77 | 89 | ||
78 | alarm(0); | 90 | alarm(0); |
79 | 91 | ||
80 | return (result); | 92 | mp_exit(overall); |
81 | } | 93 | } |
82 | 94 | ||
95 | #define output_format_index CHAR_MAX + 1 | ||
96 | |||
83 | /* process command-line arguments */ | 97 | /* process command-line arguments */ |
84 | int process_arguments(int argc, char **argv) { | 98 | process_arguments_wrapper process_arguments(int argc, char **argv) { |
85 | static struct option longopts[] = {{"help", no_argument, 0, 'h'}, | 99 | static struct option longopts[] = {{"help", no_argument, 0, 'h'}, |
86 | {"version", no_argument, 0, 'V'}, | 100 | {"version", no_argument, 0, 'V'}, |
87 | {"host", required_argument, 0, 'H'}, /* backward compatibility */ | 101 | {"host", required_argument, 0, 'H'}, /* backward compatibility */ |
@@ -93,22 +107,33 @@ int process_arguments(int argc, char **argv) { | |||
93 | {"verbose", no_argument, 0, 'v'}, | 107 | {"verbose", no_argument, 0, 'v'}, |
94 | {"remote-version", required_argument, 0, 'r'}, | 108 | {"remote-version", required_argument, 0, 'r'}, |
95 | {"remote-protocol", required_argument, 0, 'P'}, | 109 | {"remote-protocol", required_argument, 0, 'P'}, |
110 | {"output-format", required_argument, 0, output_format_index}, | ||
96 | {0, 0, 0, 0}}; | 111 | {0, 0, 0, 0}}; |
97 | 112 | ||
98 | if (argc < 2) | 113 | process_arguments_wrapper result = { |
99 | return ERROR; | 114 | .config = check_ssh_config_init(), |
115 | .errorcode = OK, | ||
116 | }; | ||
117 | |||
118 | if (argc < 2) { | ||
119 | result.errorcode = ERROR; | ||
120 | return result; | ||
121 | } | ||
100 | 122 | ||
101 | for (int i = 1; i < argc; i++) | 123 | for (int i = 1; i < argc; i++) { |
102 | if (strcmp("-to", argv[i]) == 0) | 124 | if (strcmp("-to", argv[i]) == 0) { |
103 | strcpy(argv[i], "-t"); | 125 | strcpy(argv[i], "-t"); |
126 | } | ||
127 | } | ||
104 | 128 | ||
105 | int option_char; | 129 | int option_char; |
106 | while (true) { | 130 | while (true) { |
107 | int option = 0; | 131 | int option = 0; |
108 | option_char = getopt_long(argc, argv, "+Vhv46t:r:H:p:P:", longopts, &option); | 132 | option_char = getopt_long(argc, argv, "+Vhv46t:r:H:p:P:", longopts, &option); |
109 | 133 | ||
110 | if (option_char == -1 || option_char == EOF) | 134 | if (option_char == -1 || option_char == EOF) { |
111 | break; | 135 | break; |
136 | } | ||
112 | 137 | ||
113 | switch (option_char) { | 138 | switch (option_char) { |
114 | case '?': /* help */ | 139 | case '?': /* help */ |
@@ -123,10 +148,11 @@ int process_arguments(int argc, char **argv) { | |||
123 | verbose = true; | 148 | verbose = true; |
124 | break; | 149 | break; |
125 | case 't': /* timeout period */ | 150 | case 't': /* timeout period */ |
126 | if (!is_integer(optarg)) | 151 | if (!is_intpos(optarg)) { |
127 | usage2(_("Timeout interval must be a positive integer"), optarg); | 152 | usage2(_("Timeout interval must be a positive integer"), optarg); |
128 | else | 153 | } else { |
129 | socket_timeout = atoi(optarg); | 154 | socket_timeout = (unsigned int)atoi(optarg); |
155 | } | ||
130 | break; | 156 | break; |
131 | case '4': | 157 | case '4': |
132 | address_family = AF_INET; | 158 | address_family = AF_INET; |
@@ -139,50 +165,61 @@ int process_arguments(int argc, char **argv) { | |||
139 | #endif | 165 | #endif |
140 | break; | 166 | break; |
141 | case 'r': /* remote version */ | 167 | case 'r': /* remote version */ |
142 | remote_version = optarg; | 168 | result.config.remote_version = optarg; |
143 | break; | 169 | break; |
144 | case 'P': /* remote version */ | 170 | case 'P': /* remote version */ |
145 | remote_protocol = optarg; | 171 | result.config.remote_protocol = optarg; |
146 | break; | 172 | break; |
147 | case 'H': /* host */ | 173 | case 'H': /* host */ |
148 | if (!is_host(optarg)) | 174 | if (!is_host(optarg)) { |
149 | usage2(_("Invalid hostname/address"), optarg); | 175 | usage2(_("Invalid hostname/address"), optarg); |
150 | server_name = optarg; | 176 | } |
177 | result.config.server_name = optarg; | ||
151 | break; | 178 | break; |
152 | case 'p': /* port */ | 179 | case 'p': /* port */ |
153 | if (is_intpos(optarg)) { | 180 | if (is_intpos(optarg)) { |
154 | port = atoi(optarg); | 181 | result.config.port = atoi(optarg); |
155 | } else { | 182 | } else { |
156 | usage2(_("Port number must be a positive integer"), optarg); | 183 | usage2(_("Port number must be a positive integer"), optarg); |
157 | } | 184 | } |
185 | break; | ||
186 | case output_format_index: { | ||
187 | parsed_output_format parser = mp_parse_output_format(optarg); | ||
188 | if (!parser.parsing_success) { | ||
189 | // TODO List all available formats here, maybe add anothoer usage function | ||
190 | printf("Invalid output format: %s\n", optarg); | ||
191 | exit(STATE_UNKNOWN); | ||
192 | } | ||
193 | |||
194 | result.config.output_format_is_set = true; | ||
195 | result.config.output_format = parser.output_format; | ||
196 | break; | ||
197 | } | ||
158 | } | 198 | } |
159 | } | 199 | } |
160 | 200 | ||
161 | option_char = optind; | 201 | option_char = optind; |
162 | if (server_name == NULL && option_char < argc) { | 202 | if (result.config.server_name == NULL && option_char < argc) { |
163 | if (is_host(argv[option_char])) { | 203 | if (is_host(argv[option_char])) { |
164 | server_name = argv[option_char++]; | 204 | result.config.server_name = argv[option_char++]; |
165 | } | 205 | } |
166 | } | 206 | } |
167 | 207 | ||
168 | if (port == -1 && option_char < argc) { | 208 | if (result.config.port == -1 && option_char < argc) { |
169 | if (is_intpos(argv[option_char])) { | 209 | if (is_intpos(argv[option_char])) { |
170 | port = atoi(argv[option_char++]); | 210 | result.config.port = atoi(argv[option_char++]); |
171 | } else { | 211 | } else { |
172 | print_usage(); | 212 | print_usage(); |
173 | exit(STATE_UNKNOWN); | 213 | exit(STATE_UNKNOWN); |
174 | } | 214 | } |
175 | } | 215 | } |
176 | 216 | ||
177 | return validate_arguments(); | 217 | if (result.config.server_name == NULL) { |
178 | } | 218 | result.errorcode = ERROR; |
219 | return result; | ||
220 | } | ||
179 | 221 | ||
180 | int validate_arguments(void) { | 222 | return result; |
181 | if (server_name == NULL) | ||
182 | return ERROR; | ||
183 | if (port == -1) /* funky, but allows -p to override stray integer in args */ | ||
184 | port = SSH_DFL_PORT; | ||
185 | return OK; | ||
186 | } | 223 | } |
187 | 224 | ||
188 | /************************************************************************ | 225 | /************************************************************************ |
@@ -191,28 +228,34 @@ int validate_arguments(void) { | |||
191 | * | 228 | * |
192 | *-----------------------------------------------------------------------*/ | 229 | *-----------------------------------------------------------------------*/ |
193 | 230 | ||
194 | int ssh_connect(char *haddr, int hport, char *remote_version, char *remote_protocol) { | 231 | int ssh_connect(mp_check *overall, char *haddr, int hport, char *desired_remote_version, char *desired_remote_protocol) { |
195 | struct timeval tv; | 232 | struct timeval tv; |
196 | gettimeofday(&tv, NULL); | 233 | gettimeofday(&tv, NULL); |
197 | 234 | ||
198 | int socket; | 235 | int socket; |
199 | int result = my_tcp_connect(haddr, hport, &socket); | 236 | int result = my_tcp_connect(haddr, hport, &socket); |
200 | 237 | ||
201 | if (result != STATE_OK) | 238 | mp_subcheck connection_sc = mp_subcheck_init(); |
239 | if (result != STATE_OK) { | ||
240 | connection_sc = mp_set_subcheck_state(connection_sc, STATE_CRITICAL); | ||
241 | xasprintf(&connection_sc.output, "Failed to establish TCP connection to Host %s and Port %d", haddr, hport); | ||
242 | mp_add_subcheck_to_check(overall, connection_sc); | ||
202 | return result; | 243 | return result; |
244 | } | ||
203 | 245 | ||
204 | char *output = (char *)calloc(BUFF_SZ + 1, sizeof(char)); | 246 | char *output = (char *)calloc(BUFF_SZ + 1, sizeof(char)); |
205 | char *buffer = NULL; | 247 | char *buffer = NULL; |
206 | ssize_t recv_ret = 0; | 248 | size_t recv_ret = 0; |
207 | char *version_control_string = NULL; | 249 | char *version_control_string = NULL; |
208 | ssize_t byte_offset = 0; | 250 | size_t byte_offset = 0; |
209 | while ((version_control_string == NULL) && (recv_ret = recv(socket, output + byte_offset, BUFF_SZ - byte_offset, 0) > 0)) { | 251 | while ((version_control_string == NULL) && |
252 | (recv_ret = recv(socket, output + byte_offset, (unsigned long)(BUFF_SZ - byte_offset), 0) > 0)) { | ||
210 | 253 | ||
211 | if (strchr(output, '\n')) { /* we've got at least one full line, start parsing*/ | 254 | if (strchr(output, '\n')) { /* we've got at least one full line, start parsing*/ |
212 | byte_offset = 0; | 255 | byte_offset = 0; |
213 | 256 | ||
214 | char *index = NULL; | 257 | char *index = NULL; |
215 | int len = 0; | 258 | unsigned long len = 0; |
216 | while ((index = strchr(output + byte_offset, '\n')) != NULL) { | 259 | while ((index = strchr(output + byte_offset, '\n')) != NULL) { |
217 | /*Partition the buffer so that this line is a separate string, | 260 | /*Partition the buffer so that this line is a separate string, |
218 | * by replacing the newline with NUL*/ | 261 | * by replacing the newline with NUL*/ |
@@ -243,14 +286,23 @@ int ssh_connect(char *haddr, int hport, char *remote_version, char *remote_proto | |||
243 | } | 286 | } |
244 | 287 | ||
245 | if (recv_ret < 0) { | 288 | if (recv_ret < 0) { |
246 | printf("SSH CRITICAL - %s", strerror(errno)); | 289 | connection_sc = mp_set_subcheck_state(connection_sc, STATE_CRITICAL); |
247 | exit(STATE_CRITICAL); | 290 | xasprintf(&connection_sc.output, "%s", "SSH CRITICAL - %s", strerror(errno)); |
291 | mp_add_subcheck_to_check(overall, connection_sc); | ||
292 | return OK; | ||
248 | } | 293 | } |
249 | 294 | ||
250 | if (version_control_string == NULL) { | 295 | if (version_control_string == NULL) { |
251 | printf("SSH CRITICAL - No version control string received"); | 296 | connection_sc = mp_set_subcheck_state(connection_sc, STATE_CRITICAL); |
252 | exit(STATE_CRITICAL); | 297 | xasprintf(&connection_sc.output, "%s", "SSH CRITICAL - No version control string received"); |
298 | mp_add_subcheck_to_check(overall, connection_sc); | ||
299 | return OK; | ||
253 | } | 300 | } |
301 | |||
302 | connection_sc = mp_set_subcheck_state(connection_sc, STATE_OK); | ||
303 | xasprintf(&connection_sc.output, "%s", "Initial connection succeeded"); | ||
304 | mp_add_subcheck_to_check(overall, connection_sc); | ||
305 | |||
254 | /* | 306 | /* |
255 | * "When the connection has been established, both sides MUST send an | 307 | * "When the connection has been established, both sides MUST send an |
256 | * identification string. This identification string MUST be | 308 | * identification string. This identification string MUST be |
@@ -259,8 +311,9 @@ int ssh_connect(char *haddr, int hport, char *remote_version, char *remote_proto | |||
259 | * - RFC 4253:4.2 | 311 | * - RFC 4253:4.2 |
260 | */ | 312 | */ |
261 | strip(version_control_string); | 313 | strip(version_control_string); |
262 | if (verbose) | 314 | if (verbose) { |
263 | printf("%s\n", version_control_string); | 315 | printf("%s\n", version_control_string); |
316 | } | ||
264 | 317 | ||
265 | char *ssh_proto = version_control_string + 4; | 318 | char *ssh_proto = version_control_string + 4; |
266 | 319 | ||
@@ -288,41 +341,65 @@ int ssh_connect(char *haddr, int hport, char *remote_version, char *remote_proto | |||
288 | if (tmp) { | 341 | if (tmp) { |
289 | ssh_server[tmp - ssh_server] = '\0'; | 342 | ssh_server[tmp - ssh_server] = '\0'; |
290 | } | 343 | } |
344 | |||
345 | mp_subcheck protocol_validity_sc = mp_subcheck_init(); | ||
291 | if (strlen(ssh_proto) == 0 || strlen(ssh_server) == 0) { | 346 | if (strlen(ssh_proto) == 0 || strlen(ssh_server) == 0) { |
292 | printf(_("SSH CRITICAL - Invalid protocol version control string %s\n"), version_control_string); | 347 | protocol_validity_sc = mp_set_subcheck_state(protocol_validity_sc, STATE_CRITICAL); |
293 | exit(STATE_CRITICAL); | 348 | xasprintf(&protocol_validity_sc.output, "Invalid protocol version control string %s", version_control_string); |
349 | mp_add_subcheck_to_check(overall, protocol_validity_sc); | ||
350 | return OK; | ||
294 | } | 351 | } |
352 | |||
353 | protocol_validity_sc = mp_set_subcheck_state(protocol_validity_sc, STATE_OK); | ||
354 | xasprintf(&protocol_validity_sc.output, "Valid protocol version control string %s", version_control_string); | ||
355 | mp_add_subcheck_to_check(overall, protocol_validity_sc); | ||
356 | |||
295 | ssh_proto[strspn(ssh_proto, "0123456789. ")] = 0; | 357 | ssh_proto[strspn(ssh_proto, "0123456789. ")] = 0; |
296 | 358 | ||
297 | static char *rev_no = VERSION; | 359 | static char *rev_no = VERSION; |
298 | xasprintf(&buffer, "SSH-%s-check_ssh_%s\r\n", ssh_proto, rev_no); | 360 | xasprintf(&buffer, "SSH-%s-check_ssh_%s\r\n", ssh_proto, rev_no); |
299 | send(socket, buffer, strlen(buffer), MSG_DONTWAIT); | 361 | send(socket, buffer, strlen(buffer), MSG_DONTWAIT); |
300 | if (verbose) | 362 | if (verbose) { |
301 | printf("%s\n", buffer); | 363 | printf("%s\n", buffer); |
364 | } | ||
302 | 365 | ||
303 | if (remote_version && strcmp(remote_version, ssh_server)) { | 366 | if (desired_remote_version && strcmp(desired_remote_version, ssh_server)) { |
304 | printf(_("SSH CRITICAL - %s (protocol %s) version mismatch, expected '%s'\n"), ssh_server, ssh_proto, remote_version); | 367 | mp_subcheck remote_version_sc = mp_subcheck_init(); |
368 | remote_version_sc = mp_set_subcheck_state(remote_version_sc, STATE_CRITICAL); | ||
369 | xasprintf(&remote_version_sc.output, _("%s (protocol %s) version mismatch, expected '%s'"), ssh_server, ssh_proto, | ||
370 | desired_remote_version); | ||
305 | close(socket); | 371 | close(socket); |
306 | exit(STATE_CRITICAL); | 372 | mp_add_subcheck_to_check(overall, remote_version_sc); |
373 | return OK; | ||
307 | } | 374 | } |
308 | 375 | ||
309 | double elapsed_time = (double)deltime(tv) / 1.0e6; | 376 | double elapsed_time = (double)deltime(tv) / 1.0e6; |
310 | if (remote_protocol && strcmp(remote_protocol, ssh_proto)) { | 377 | mp_perfdata time_pd = perfdata_init(); |
311 | printf(_("SSH CRITICAL - %s (protocol %s) protocol version mismatch, expected '%s' | %s\n"), ssh_server, ssh_proto, remote_protocol, | 378 | time_pd.value = mp_create_pd_value(elapsed_time); |
312 | fperfdata("time", elapsed_time, "s", false, 0, false, 0, true, 0, true, (int)socket_timeout)); | 379 | time_pd.label = "time"; |
313 | close(socket); | 380 | time_pd.max_present = true; |
314 | exit(STATE_CRITICAL); | 381 | time_pd.max = mp_create_pd_value(socket_timeout); |
382 | |||
383 | mp_subcheck protocol_version_sc = mp_subcheck_init(); | ||
384 | mp_add_perfdata_to_subcheck(&protocol_version_sc, time_pd); | ||
385 | |||
386 | if (desired_remote_protocol && strcmp(desired_remote_protocol, ssh_proto)) { | ||
387 | protocol_version_sc = mp_set_subcheck_state(protocol_version_sc, STATE_CRITICAL); | ||
388 | xasprintf(&protocol_version_sc.output, _("%s (protocol %s) protocol version mismatch, expected '%s'"), ssh_server, ssh_proto, | ||
389 | desired_remote_protocol); | ||
390 | } else { | ||
391 | protocol_version_sc = mp_set_subcheck_state(protocol_version_sc, STATE_OK); | ||
392 | xasprintf(&protocol_version_sc.output, "SSH server version: %s (protocol version: %s)", ssh_server, ssh_proto); | ||
315 | } | 393 | } |
316 | 394 | ||
317 | printf(_("SSH OK - %s (protocol %s) | %s\n"), ssh_server, ssh_proto, | 395 | mp_add_subcheck_to_check(overall, protocol_version_sc); |
318 | fperfdata("time", elapsed_time, "s", false, 0, false, 0, true, 0, true, (int)socket_timeout)); | ||
319 | close(socket); | 396 | close(socket); |
320 | exit(STATE_OK); | 397 | return OK; |
321 | } | 398 | } |
322 | 399 | ||
323 | void print_help(void) { | 400 | void print_help(void) { |
324 | char *myport; | 401 | char *myport; |
325 | xasprintf(&myport, "%d", SSH_DFL_PORT); | 402 | xasprintf(&myport, "%d", default_ssh_port); |
326 | 403 | ||
327 | print_revision(progname, NP_VERSION); | 404 | print_revision(progname, NP_VERSION); |
328 | 405 | ||
@@ -349,6 +426,7 @@ void print_help(void) { | |||
349 | 426 | ||
350 | printf(" %s\n", "-P, --remote-protocol=STRING"); | 427 | printf(" %s\n", "-P, --remote-protocol=STRING"); |
351 | printf(" %s\n", _("Alert if protocol doesn't match expected protocol version (ex: 2.0)")); | 428 | printf(" %s\n", _("Alert if protocol doesn't match expected protocol version (ex: 2.0)")); |
429 | printf(UT_OUTPUT_FORMAT); | ||
352 | 430 | ||
353 | printf(UT_VERBOSE); | 431 | printf(UT_VERBOSE); |
354 | 432 | ||
@@ -357,5 +435,5 @@ void print_help(void) { | |||
357 | 435 | ||
358 | void print_usage(void) { | 436 | void print_usage(void) { |
359 | printf("%s\n", _("Usage:")); | 437 | printf("%s\n", _("Usage:")); |
360 | printf("%s [-4|-6] [-t <timeout>] [-r <remote version>] [-p <port>] <host>\n", progname); | 438 | printf("%s [-4|-6] [-t <timeout>] [-r <remote version>] [-p <port>] --hostname <host>\n", progname); |
361 | } | 439 | } |
diff --git a/plugins/check_ssh.d/config.h b/plugins/check_ssh.d/config.h new file mode 100644 index 00000000..c150fd30 --- /dev/null +++ b/plugins/check_ssh.d/config.h | |||
@@ -0,0 +1,29 @@ | |||
1 | #pragma once | ||
2 | |||
3 | #include <stddef.h> | ||
4 | #include "../../lib/monitoringplug.h" | ||
5 | |||
6 | const int default_ssh_port = 22; | ||
7 | |||
8 | typedef struct check_ssh_config { | ||
9 | int port; | ||
10 | char *server_name; | ||
11 | char *remote_version; | ||
12 | char *remote_protocol; | ||
13 | |||
14 | bool output_format_is_set; | ||
15 | mp_output_format output_format; | ||
16 | } check_ssh_config; | ||
17 | |||
18 | check_ssh_config check_ssh_config_init(void) { | ||
19 | check_ssh_config tmp = { | ||
20 | .port = default_ssh_port, | ||
21 | .server_name = NULL, | ||
22 | .remote_version = NULL, | ||
23 | .remote_protocol = NULL, | ||
24 | |||
25 | .output_format_is_set = false, | ||
26 | }; | ||
27 | |||
28 | return tmp; | ||
29 | } | ||
diff --git a/plugins/check_swap.c b/plugins/check_swap.c index 4d3b6099..cb95949a 100644 --- a/plugins/check_swap.c +++ b/plugins/check_swap.c | |||
@@ -93,7 +93,7 @@ int main(int argc, char **argv) { | |||
93 | double percent_used; | 93 | double percent_used; |
94 | mp_check overall = mp_check_init(); | 94 | mp_check overall = mp_check_init(); |
95 | if (config.output_format_is_set) { | 95 | if (config.output_format_is_set) { |
96 | overall.format = config.output_format; | 96 | mp_set_format(config.output_format); |
97 | } | 97 | } |
98 | mp_subcheck sc1 = mp_subcheck_init(); | 98 | mp_subcheck sc1 = mp_subcheck_init(); |
99 | sc1 = mp_set_subcheck_default_state(sc1, STATE_OK); | 99 | sc1 = mp_set_subcheck_default_state(sc1, STATE_OK); |
diff --git a/plugins/netutils.c b/plugins/netutils.c index ee81912a..e2916c65 100644 --- a/plugins/netutils.c +++ b/plugins/netutils.c | |||
@@ -28,6 +28,8 @@ | |||
28 | *****************************************************************************/ | 28 | *****************************************************************************/ |
29 | 29 | ||
30 | #include "common.h" | 30 | #include "common.h" |
31 | #include "output.h" | ||
32 | #include "states.h" | ||
31 | #include "netutils.h" | 33 | #include "netutils.h" |
32 | 34 | ||
33 | unsigned int socket_timeout = DEFAULT_SOCKET_TIMEOUT; | 35 | unsigned int socket_timeout = DEFAULT_SOCKET_TIMEOUT; |
@@ -43,12 +45,19 @@ int address_family = AF_INET; | |||
43 | 45 | ||
44 | /* handles socket timeouts */ | 46 | /* handles socket timeouts */ |
45 | void socket_timeout_alarm_handler(int sig) { | 47 | void socket_timeout_alarm_handler(int sig) { |
46 | if (sig == SIGALRM) | 48 | mp_subcheck timeout_sc = mp_subcheck_init(); |
47 | printf(_("%s - Socket timeout after %d seconds\n"), state_text(socket_timeout_state), socket_timeout); | 49 | timeout_sc = mp_set_subcheck_state(timeout_sc, socket_timeout_state); |
48 | else | ||
49 | printf(_("%s - Abnormal timeout after %d seconds\n"), state_text(socket_timeout_state), socket_timeout); | ||
50 | 50 | ||
51 | exit(socket_timeout_state); | 51 | if (sig == SIGALRM) { |
52 | xasprintf(&timeout_sc.output, _("Socket timeout after %d seconds\n"), socket_timeout); | ||
53 | } else { | ||
54 | xasprintf(&timeout_sc.output, _("Abnormal timeout after %d seconds\n"), socket_timeout); | ||
55 | } | ||
56 | |||
57 | mp_check overall = mp_check_init(); | ||
58 | mp_add_subcheck_to_check(&overall, timeout_sc); | ||
59 | |||
60 | mp_exit(overall); | ||
52 | } | 61 | } |
53 | 62 | ||
54 | /* connects to a host on a specified tcp port, sends a string, and gets a | 63 | /* connects to a host on a specified tcp port, sends a string, and gets a |
@@ -65,12 +74,13 @@ int process_tcp_request2(const char *server_address, int server_port, const char | |||
65 | int recv_length = 0; | 74 | int recv_length = 0; |
66 | 75 | ||
67 | result = np_net_connect(server_address, server_port, &sd, IPPROTO_TCP); | 76 | result = np_net_connect(server_address, server_port, &sd, IPPROTO_TCP); |
68 | if (result != STATE_OK) | 77 | if (result != STATE_OK) { |
69 | return STATE_CRITICAL; | 78 | return STATE_CRITICAL; |
79 | } | ||
70 | 80 | ||
71 | send_result = send(sd, send_buffer, strlen(send_buffer), 0); | 81 | send_result = send(sd, send_buffer, strlen(send_buffer), 0); |
72 | if (send_result < 0 || (size_t)send_result != strlen(send_buffer)) { | 82 | if (send_result < 0 || (size_t)send_result != strlen(send_buffer)) { |
73 | printf("%s\n", _("Send failed")); | 83 | // printf("%s\n", _("Send failed")); |
74 | result = STATE_WARNING; | 84 | result = STATE_WARNING; |
75 | } | 85 | } |
76 | 86 | ||
@@ -87,7 +97,7 @@ int process_tcp_request2(const char *server_address, int server_port, const char | |||
87 | if (!FD_ISSET(sd, &readfds)) { /* it hasn't */ | 97 | if (!FD_ISSET(sd, &readfds)) { /* it hasn't */ |
88 | if (!recv_length) { | 98 | if (!recv_length) { |
89 | strcpy(recv_buffer, ""); | 99 | strcpy(recv_buffer, ""); |
90 | printf("%s\n", _("No data was received from host!")); | 100 | // printf("%s\n", _("No data was received from host!")); |
91 | result = STATE_WARNING; | 101 | result = STATE_WARNING; |
92 | } else { /* this one failed, but previous ones worked */ | 102 | } else { /* this one failed, but previous ones worked */ |
93 | recv_buffer[recv_length] = 0; | 103 | recv_buffer[recv_length] = 0; |
@@ -130,8 +140,9 @@ int process_request(const char *server_address, int server_port, int proto, cons | |||
130 | result = STATE_OK; | 140 | result = STATE_OK; |
131 | 141 | ||
132 | result = np_net_connect(server_address, server_port, &sd, proto); | 142 | result = np_net_connect(server_address, server_port, &sd, proto); |
133 | if (result != STATE_OK) | 143 | if (result != STATE_OK) { |
134 | return STATE_CRITICAL; | 144 | return STATE_CRITICAL; |
145 | } | ||
135 | 146 | ||
136 | result = send_request(sd, proto, send_buffer, recv_buffer, recv_size); | 147 | result = send_request(sd, proto, send_buffer, recv_buffer, recv_size); |
137 | 148 | ||
@@ -169,15 +180,16 @@ int np_net_connect(const char *host_name, int port, int *sd, int proto) { | |||
169 | host_name++; | 180 | host_name++; |
170 | len -= 2; | 181 | len -= 2; |
171 | } | 182 | } |
172 | if (len >= sizeof(host)) | 183 | if (len >= sizeof(host)) { |
173 | return STATE_UNKNOWN; | 184 | return STATE_UNKNOWN; |
185 | } | ||
174 | memcpy(host, host_name, len); | 186 | memcpy(host, host_name, len); |
175 | host[len] = '\0'; | 187 | host[len] = '\0'; |
176 | snprintf(port_str, sizeof(port_str), "%d", port); | 188 | snprintf(port_str, sizeof(port_str), "%d", port); |
177 | result = getaddrinfo(host, port_str, &hints, &res); | 189 | result = getaddrinfo(host, port_str, &hints, &res); |
178 | 190 | ||
179 | if (result != 0) { | 191 | if (result != 0) { |
180 | printf("%s\n", gai_strerror(result)); | 192 | // printf("%s\n", gai_strerror(result)); |
181 | return STATE_UNKNOWN; | 193 | return STATE_UNKNOWN; |
182 | } | 194 | } |
183 | 195 | ||
@@ -187,7 +199,7 @@ int np_net_connect(const char *host_name, int port, int *sd, int proto) { | |||
187 | *sd = socket(r->ai_family, socktype, r->ai_protocol); | 199 | *sd = socket(r->ai_family, socktype, r->ai_protocol); |
188 | 200 | ||
189 | if (*sd < 0) { | 201 | if (*sd < 0) { |
190 | printf("%s\n", _("Socket creation failed")); | 202 | // printf("%s\n", _("Socket creation failed")); |
191 | freeaddrinfo(r); | 203 | freeaddrinfo(r); |
192 | return STATE_UNKNOWN; | 204 | return STATE_UNKNOWN; |
193 | } | 205 | } |
@@ -226,21 +238,23 @@ int np_net_connect(const char *host_name, int port, int *sd, int proto) { | |||
226 | die(STATE_UNKNOWN, _("Socket creation failed")); | 238 | die(STATE_UNKNOWN, _("Socket creation failed")); |
227 | } | 239 | } |
228 | result = connect(*sd, (struct sockaddr *)&su, sizeof(su)); | 240 | result = connect(*sd, (struct sockaddr *)&su, sizeof(su)); |
229 | if (result < 0 && errno == ECONNREFUSED) | 241 | if (result < 0 && errno == ECONNREFUSED) { |
230 | was_refused = true; | 242 | was_refused = true; |
243 | } | ||
231 | } | 244 | } |
232 | 245 | ||
233 | if (result == 0) | 246 | if (result == 0) { |
234 | return STATE_OK; | 247 | return STATE_OK; |
235 | else if (was_refused) { | 248 | } else if (was_refused) { |
236 | switch (econn_refuse_state) { /* a user-defined expected outcome */ | 249 | switch (econn_refuse_state) { /* a user-defined expected outcome */ |
237 | case STATE_OK: | 250 | case STATE_OK: |
238 | case STATE_WARNING: /* user wants WARN or OK on refusal, or... */ | 251 | case STATE_WARNING: /* user wants WARN or OK on refusal, or... */ |
239 | case STATE_CRITICAL: /* user did not set econn_refuse_state, or wanted critical */ | 252 | case STATE_CRITICAL: /* user did not set econn_refuse_state, or wanted critical */ |
240 | if (is_socket) | 253 | if (is_socket) { |
241 | printf("connect to file socket %s: %s\n", host_name, strerror(errno)); | 254 | // printf("connect to file socket %s: %s\n", host_name, strerror(errno)); |
242 | else | 255 | } else { |
243 | printf("connect to address %s and port %d: %s\n", host_name, port, strerror(errno)); | 256 | // printf("connect to address %s and port %d: %s\n", host_name, port, strerror(errno)); |
257 | } | ||
244 | return STATE_CRITICAL; | 258 | return STATE_CRITICAL; |
245 | break; | 259 | break; |
246 | default: /* it's a logic error if we do not end up in STATE_(OK|WARNING|CRITICAL) */ | 260 | default: /* it's a logic error if we do not end up in STATE_(OK|WARNING|CRITICAL) */ |
@@ -248,10 +262,11 @@ int np_net_connect(const char *host_name, int port, int *sd, int proto) { | |||
248 | break; | 262 | break; |
249 | } | 263 | } |
250 | } else { | 264 | } else { |
251 | if (is_socket) | 265 | if (is_socket) { |
252 | printf("connect to file socket %s: %s\n", host_name, strerror(errno)); | 266 | // printf("connect to file socket %s: %s\n", host_name, strerror(errno)); |
253 | else | 267 | } else { |
254 | printf("connect to address %s and port %d: %s\n", host_name, port, strerror(errno)); | 268 | // printf("connect to address %s and port %d: %s\n", host_name, port, strerror(errno)); |
269 | } | ||
255 | return STATE_CRITICAL; | 270 | return STATE_CRITICAL; |
256 | } | 271 | } |
257 | } | 272 | } |
@@ -265,7 +280,7 @@ int send_request(int sd, int proto, const char *send_buffer, char *recv_buffer, | |||
265 | 280 | ||
266 | send_result = send(sd, send_buffer, strlen(send_buffer), 0); | 281 | send_result = send(sd, send_buffer, strlen(send_buffer), 0); |
267 | if (send_result < 0 || (size_t)send_result != strlen(send_buffer)) { | 282 | if (send_result < 0 || (size_t)send_result != strlen(send_buffer)) { |
268 | printf("%s\n", _("Send failed")); | 283 | // printf("%s\n", _("Send failed")); |
269 | result = STATE_WARNING; | 284 | result = STATE_WARNING; |
270 | } | 285 | } |
271 | 286 | ||
@@ -280,7 +295,7 @@ int send_request(int sd, int proto, const char *send_buffer, char *recv_buffer, | |||
280 | /* make sure some data has arrived */ | 295 | /* make sure some data has arrived */ |
281 | if (!FD_ISSET(sd, &readfds)) { | 296 | if (!FD_ISSET(sd, &readfds)) { |
282 | strcpy(recv_buffer, ""); | 297 | strcpy(recv_buffer, ""); |
283 | printf("%s\n", _("No data was received from host!")); | 298 | // printf("%s\n", _("No data was received from host!")); |
284 | result = STATE_WARNING; | 299 | result = STATE_WARNING; |
285 | } | 300 | } |
286 | 301 | ||
@@ -288,11 +303,13 @@ int send_request(int sd, int proto, const char *send_buffer, char *recv_buffer, | |||
288 | recv_result = recv(sd, recv_buffer, (size_t)recv_size - 1, 0); | 303 | recv_result = recv(sd, recv_buffer, (size_t)recv_size - 1, 0); |
289 | if (recv_result == -1) { | 304 | if (recv_result == -1) { |
290 | strcpy(recv_buffer, ""); | 305 | strcpy(recv_buffer, ""); |
291 | if (proto != IPPROTO_TCP) | 306 | if (proto != IPPROTO_TCP) { |
292 | printf("%s\n", _("Receive failed")); | 307 | // printf("%s\n", _("Receive failed")); |
308 | } | ||
293 | result = STATE_WARNING; | 309 | result = STATE_WARNING; |
294 | } else | 310 | } else { |
295 | recv_buffer[recv_result] = 0; | 311 | recv_buffer[recv_result] = 0; |
312 | } | ||
296 | 313 | ||
297 | /* die returned string */ | 314 | /* die returned string */ |
298 | recv_buffer[recv_size - 1] = 0; | 315 | recv_buffer[recv_size - 1] = 0; |
@@ -301,26 +318,30 @@ int send_request(int sd, int proto, const char *send_buffer, char *recv_buffer, | |||
301 | } | 318 | } |
302 | 319 | ||
303 | bool is_host(const char *address) { | 320 | bool is_host(const char *address) { |
304 | if (is_addr(address) || is_hostname(address)) | 321 | if (is_addr(address) || is_hostname(address)) { |
305 | return (true); | 322 | return (true); |
323 | } | ||
306 | 324 | ||
307 | return (false); | 325 | return (false); |
308 | } | 326 | } |
309 | 327 | ||
310 | void host_or_die(const char *str) { | 328 | void host_or_die(const char *str) { |
311 | if (!str || (!is_addr(str) && !is_hostname(str))) | 329 | if (!str || (!is_addr(str) && !is_hostname(str))) { |
312 | usage_va(_("Invalid hostname/address - %s"), str); | 330 | usage_va(_("Invalid hostname/address - %s"), str); |
331 | } | ||
313 | } | 332 | } |
314 | 333 | ||
315 | bool is_addr(const char *address) { | 334 | bool is_addr(const char *address) { |
316 | #ifdef USE_IPV6 | 335 | #ifdef USE_IPV6 |
317 | if (address_family == AF_INET && is_inet_addr(address)) | 336 | if (address_family == AF_INET && is_inet_addr(address)) { |
318 | return true; | 337 | return true; |
319 | else if (address_family == AF_INET6 && is_inet6_addr(address)) | 338 | } else if (address_family == AF_INET6 && is_inet6_addr(address)) { |
320 | return true; | 339 | return true; |
340 | } | ||
321 | #else | 341 | #else |
322 | if (is_inet_addr(address)) | 342 | if (is_inet_addr(address)) { |
323 | return (true); | 343 | return (true); |
344 | } | ||
324 | #endif | 345 | #endif |
325 | 346 | ||
326 | return (false); | 347 | return (false); |
@@ -335,11 +356,13 @@ int dns_lookup(const char *in, struct sockaddr_storage *ss, int family) { | |||
335 | hints.ai_family = family; | 356 | hints.ai_family = family; |
336 | 357 | ||
337 | retval = getaddrinfo(in, NULL, &hints, &res); | 358 | retval = getaddrinfo(in, NULL, &hints, &res); |
338 | if (retval != 0) | 359 | if (retval != 0) { |
339 | return false; | 360 | return false; |
361 | } | ||
340 | 362 | ||
341 | if (ss != NULL) | 363 | if (ss != NULL) { |
342 | memcpy(ss, res->ai_addr, res->ai_addrlen); | 364 | memcpy(ss, res->ai_addr, res->ai_addrlen); |
365 | } | ||
343 | freeaddrinfo(res); | 366 | freeaddrinfo(res); |
344 | return true; | 367 | return true; |
345 | } | 368 | } |
diff --git a/plugins/t/check_http.t b/plugins/t/check_http.t index 6ab4a5b6..bb1fd27d 100644 --- a/plugins/t/check_http.t +++ b/plugins/t/check_http.t | |||
@@ -45,7 +45,7 @@ $res = NPTest->testCmd( | |||
45 | "./$plugin $host_nonresponsive -wt 1 -ct 2 -t 3" | 45 | "./$plugin $host_nonresponsive -wt 1 -ct 2 -t 3" |
46 | ); | 46 | ); |
47 | cmp_ok( $res->return_code, '==', 2, "Webserver $host_nonresponsive not responding" ); | 47 | cmp_ok( $res->return_code, '==', 2, "Webserver $host_nonresponsive not responding" ); |
48 | cmp_ok( $res->output, 'eq', "CRITICAL - Socket timeout after 3 seconds", "Output OK"); | 48 | like( $res->output, "/Socket timeout after/", "Output OK"); |
49 | 49 | ||
50 | $res = NPTest->testCmd( | 50 | $res = NPTest->testCmd( |
51 | "./$plugin $hostname_invalid -wt 1 -ct 2" | 51 | "./$plugin $hostname_invalid -wt 1 -ct 2" |
diff --git a/plugins/t/check_jabber.t b/plugins/t/check_jabber.t index fcdae179..08cadcbd 100644 --- a/plugins/t/check_jabber.t +++ b/plugins/t/check_jabber.t | |||
@@ -17,7 +17,7 @@ my $hostname_invalid = getTestParameter("NP_HOSTNAME_INVALID", "An invalid (no | |||
17 | 17 | ||
18 | my $jabberOK = '/JABBER OK\s-\s\d+\.\d+\ssecond response time on '.$host_tcp_jabber.' port 5222/'; | 18 | my $jabberOK = '/JABBER OK\s-\s\d+\.\d+\ssecond response time on '.$host_tcp_jabber.' port 5222/'; |
19 | 19 | ||
20 | my $jabberUnresponsive = '/CRITICAL\s-\sSocket timeout after\s\d+\sseconds/'; | 20 | my $jabberUnresponsive = '/Socket timeout after\s\d+\sseconds/'; |
21 | 21 | ||
22 | my $jabberInvalid = '/JABBER CRITICAL - Invalid hostname, address or socket:\s.+/'; | 22 | my $jabberInvalid = '/JABBER CRITICAL - Invalid hostname, address or socket:\s.+/'; |
23 | 23 | ||
diff --git a/plugins/t/check_ldap.t b/plugins/t/check_ldap.t index b8a4a766..fcba0393 100644 --- a/plugins/t/check_ldap.t +++ b/plugins/t/check_ldap.t | |||
@@ -24,7 +24,7 @@ SKIP: { | |||
24 | 24 | ||
25 | $result = NPTest->testCmd("$command -H $host_nonresponsive -b ou=blah -t 2 -w 1 -c 1"); | 25 | $result = NPTest->testCmd("$command -H $host_nonresponsive -b ou=blah -t 2 -w 1 -c 1"); |
26 | is( $result->return_code, 2, "$command -H $host_nonresponsive -b ou=blah -t 5 -w 2 -c 3" ); | 26 | is( $result->return_code, 2, "$command -H $host_nonresponsive -b ou=blah -t 5 -w 2 -c 3" ); |
27 | is( $result->output, 'CRITICAL - Socket timeout after 2 seconds', "output ok" ); | 27 | like($result->output, '/Socket timeout after \d+ seconds/', "output ok" ); |
28 | }; | 28 | }; |
29 | 29 | ||
30 | SKIP: { | 30 | SKIP: { |
diff --git a/plugins/t/check_ntp.t b/plugins/t/check_ntp.t index b8fc8fdf..a8ac7bb8 100644 --- a/plugins/t/check_ntp.t +++ b/plugins/t/check_ntp.t | |||
@@ -37,7 +37,7 @@ my $ntp_critmatch1 = '/^NTP\sCRITICAL:\sOffset\s-?[0-9]+(\.[0-9]+)?(e-[0-9]{2})? | |||
37 | my $ntp_okmatch2 = '/^NTP\sOK:\sOffset\s-?[0-9]+(\.[0-9]+)?(e-[0-9]{2})?\ssecs,\sjitter=[0-9]+\.[0-9]+,\sstratum=[0-9]{1,2},\struechimers=[0-9]+/'; | 37 | my $ntp_okmatch2 = '/^NTP\sOK:\sOffset\s-?[0-9]+(\.[0-9]+)?(e-[0-9]{2})?\ssecs,\sjitter=[0-9]+\.[0-9]+,\sstratum=[0-9]{1,2},\struechimers=[0-9]+/'; |
38 | my $ntp_warnmatch2 = '/^NTP\sWARNING:\sOffset\s-?[0-9]+(\.[0-9]+)?(e-[0-9]{2})?\ssecs,\sjitter=[0-9]+\.[0-9]+,\sstratum=[0-9]{1,2}\s\(WARNING\),\struechimers=[0-9]+/'; | 38 | my $ntp_warnmatch2 = '/^NTP\sWARNING:\sOffset\s-?[0-9]+(\.[0-9]+)?(e-[0-9]{2})?\ssecs,\sjitter=[0-9]+\.[0-9]+,\sstratum=[0-9]{1,2}\s\(WARNING\),\struechimers=[0-9]+/'; |
39 | my $ntp_critmatch2 = '/^NTP\sCRITICAL:\sOffset\s-?[0-9]+(\.[0-9]+)?(e-[0-9]{2})?\ssecs,\sjitter=[0-9]+\.[0-9]+\s\(CRITICAL\),\sstratum=[0-9]{1,2},\struechimers=[0-9]+/'; | 39 | my $ntp_critmatch2 = '/^NTP\sCRITICAL:\sOffset\s-?[0-9]+(\.[0-9]+)?(e-[0-9]{2})?\ssecs,\sjitter=[0-9]+\.[0-9]+\s\(CRITICAL\),\sstratum=[0-9]{1,2},\struechimers=[0-9]+/'; |
40 | my $ntp_noresponse = '/^(CRITICAL - Socket timeout after 3 seconds)|(NTP CRITICAL: No response from NTP server)$/'; | 40 | my $ntp_noresponse = '/(.*Socket timeout after \d+ seconds.*)|(.*No response from NTP server.*)/'; |
41 | my $ntp_nosuchhost = '/^check_ntp.*: Invalid hostname/address - ' . $hostname_invalid . '/'; | 41 | my $ntp_nosuchhost = '/^check_ntp.*: Invalid hostname/address - ' . $hostname_invalid . '/'; |
42 | 42 | ||
43 | 43 | ||
diff --git a/plugins/t/check_smtp.t b/plugins/t/check_smtp.t index 1a1ebe3e..73b4a1fd 100644 --- a/plugins/t/check_smtp.t +++ b/plugins/t/check_smtp.t | |||
@@ -24,7 +24,7 @@ my $hostname_invalid = getTestParameter( "NP_HOSTNAME_INVALID", | |||
24 | "An invalid (not known to DNS) hostname", "nosuchhost" ); | 24 | "An invalid (not known to DNS) hostname", "nosuchhost" ); |
25 | my $res; | 25 | my $res; |
26 | 26 | ||
27 | plan tests => 16; | 27 | plan tests => 15; |
28 | 28 | ||
29 | SKIP: { | 29 | SKIP: { |
30 | skip "No SMTP server defined", 4 unless $host_tcp_smtp; | 30 | skip "No SMTP server defined", 4 unless $host_tcp_smtp; |
@@ -73,7 +73,6 @@ SKIP: { | |||
73 | my $unused_port = 4465; | 73 | my $unused_port = 4465; |
74 | $res = NPTest->testCmd( "./check_smtp -H $host_tcp_smtp_tls -p $unused_port --ssl" ); | 74 | $res = NPTest->testCmd( "./check_smtp -H $host_tcp_smtp_tls -p $unused_port --ssl" ); |
75 | is ($res->return_code, 2, "Check rc of connecting to $host_tcp_smtp_tls with TLS on unused port $unused_port" ); | 75 | is ($res->return_code, 2, "Check rc of connecting to $host_tcp_smtp_tls with TLS on unused port $unused_port" ); |
76 | like ($res->output, qr/^connect to address $host_tcp_smtp_tls and port $unused_port: Connection refused/, "Check output of connecting to $host_tcp_smtp_tls with TLS on unused port $unused_port"); | ||
77 | } | 76 | } |
78 | 77 | ||
79 | $res = NPTest->testCmd( "./check_smtp $host_nonresponsive" ); | 78 | $res = NPTest->testCmd( "./check_smtp $host_nonresponsive" ); |
diff --git a/plugins/t/check_ssh.t b/plugins/t/check_ssh.t index 907d33a8..8a20782e 100644 --- a/plugins/t/check_ssh.t +++ b/plugins/t/check_ssh.t | |||
@@ -5,10 +5,10 @@ | |||
5 | # | 5 | # |
6 | 6 | ||
7 | use strict; | 7 | use strict; |
8 | use warnings; | ||
8 | use Test::More; | 9 | use Test::More; |
9 | use NPTest; | 10 | use NPTest; |
10 | 11 | use JSON; | |
11 | my $res; | ||
12 | 12 | ||
13 | # Required parameters | 13 | # Required parameters |
14 | my $ssh_host = getTestParameter("NP_SSH_HOST", | 14 | my $ssh_host = getTestParameter("NP_SSH_HOST", |
@@ -23,30 +23,38 @@ my $hostname_invalid = getTestParameter("NP_HOSTNAME_INVALID", | |||
23 | "An invalid (not known to DNS) hostname", | 23 | "An invalid (not known to DNS) hostname", |
24 | "nosuchhost" ); | 24 | "nosuchhost" ); |
25 | 25 | ||
26 | my $outputFormat = '--output-format mp-test-json'; | ||
27 | |||
28 | plan tests => 24; | ||
26 | 29 | ||
27 | plan tests => 14 + 6; | 30 | my $output; |
31 | my $result; | ||
28 | 32 | ||
29 | SKIP: { | 33 | SKIP: { |
30 | skip "SSH_HOST must be defined", 6 unless $ssh_host; | 34 | skip "SSH_HOST must be defined", 6 unless $ssh_host; |
35 | |||
36 | |||
31 | my $result = NPTest->testCmd( | 37 | my $result = NPTest->testCmd( |
32 | "./check_ssh -H $ssh_host" | 38 | "./check_ssh -H $ssh_host" ." ". $outputFormat |
33 | ); | 39 | ); |
34 | cmp_ok($result->return_code, '==', 0, "Exit with return code 0 (OK)"); | 40 | cmp_ok($result->return_code, '==', 0, "Exit with return code 0 (OK)"); |
35 | like($result->output, '/^SSH OK - /', "Status text if command returned none (OK)"); | 41 | $output = decode_json($result->output); |
42 | is($output->{'state'}, "OK", "State was correct"); | ||
36 | 43 | ||
37 | 44 | ||
38 | $result = NPTest->testCmd( | 45 | $result = NPTest->testCmd( |
39 | "./check_ssh -H $host_nonresponsive -t 2" | 46 | "./check_ssh -H $host_nonresponsive -t 2" ." ". $outputFormat |
40 | ); | 47 | ); |
41 | cmp_ok($result->return_code, '==', 2, "Exit with return code 0 (OK)"); | 48 | cmp_ok($result->return_code, '==', 0, "Exit with return code 0 (OK)"); |
42 | like($result->output, '/^CRITICAL - Socket timeout after 2 seconds/', "Status text if command returned none (OK)"); | 49 | $output = decode_json($result->output); |
50 | is($output->{'state'}, "CRITICAL", "State was correct"); | ||
43 | 51 | ||
44 | 52 | ||
45 | 53 | ||
46 | $result = NPTest->testCmd( | 54 | $result = NPTest->testCmd( |
47 | "./check_ssh -H $hostname_invalid -t 2" | 55 | "./check_ssh -H $hostname_invalid -t 2" ." ". $outputFormat |
48 | ); | 56 | ); |
49 | cmp_ok($result->return_code, '==', 3, "Exit with return code 0 (OK)"); | 57 | cmp_ok($result->return_code, '==', 3, "Exit with return code 3 (UNKNOWN)"); |
50 | like($result->output, '/^check_ssh: Invalid hostname/', "Status text if command returned none (OK)"); | 58 | like($result->output, '/^check_ssh: Invalid hostname/', "Status text if command returned none (OK)"); |
51 | 59 | ||
52 | 60 | ||
@@ -63,46 +71,80 @@ SKIP: { | |||
63 | # | 71 | # |
64 | # where `comments` is optional, protoversion is the SSH protocol version and | 72 | # where `comments` is optional, protoversion is the SSH protocol version and |
65 | # softwareversion is an arbitrary string representing the server software version | 73 | # softwareversion is an arbitrary string representing the server software version |
74 | |||
75 | my $found_version = 0; | ||
76 | |||
66 | open(NC, "echo 'SSH-2.0-nagiosplug.ssh.0.1' | nc ${nc_flags}|"); | 77 | open(NC, "echo 'SSH-2.0-nagiosplug.ssh.0.1' | nc ${nc_flags}|"); |
67 | sleep 0.1; | 78 | sleep 0.1; |
68 | $res = NPTest->testCmd( "./check_ssh -H localhost -p 5003" ); | 79 | $result = NPTest->testCmd( "./check_ssh -H localhost -p 5003" ." ". $outputFormat); |
69 | cmp_ok( $res->return_code, '==', 0, "Got SSH protocol version control string"); | 80 | cmp_ok($result->return_code, '==', 0, "Exit with return code 0 (OK)"); |
70 | like( $res->output, '/^SSH OK - nagiosplug.ssh.0.1 \(protocol 2.0\)/', "Output OK"); | 81 | $output = decode_json($result->output); |
82 | is($output->{'state'}, "OK", "State was correct"); | ||
83 | |||
84 | # looking for the version | ||
85 | for my $subcheck (@{$output->{'checks'}}) { | ||
86 | if ($subcheck->{'output'} =~ /.*nagiosplug.ssh.0.1 \(protocol version: 2.0\).*/ ){ | ||
87 | $found_version = 1; | ||
88 | } | ||
89 | } | ||
90 | cmp_ok($found_version, '==', 1, "Output OK"); | ||
71 | close NC; | 91 | close NC; |
72 | 92 | ||
73 | open(NC, "echo 'SSH-2.0-3.2.9.1' | nc ${nc_flags}|"); | 93 | open(NC, "echo 'SSH-2.0-3.2.9.1' | nc ${nc_flags}|"); |
74 | sleep 0.1; | 94 | sleep 0.1; |
75 | $res = NPTest->testCmd( "./check_ssh -H localhost -p 5003" ); | 95 | $result = NPTest->testCmd( "./check_ssh -H localhost -p 5003" ." ". $outputFormat); |
76 | cmp_ok( $res->return_code, "==", 0, "Got SSH protocol version control string with non-alpha softwareversion string"); | 96 | cmp_ok($result->return_code, '==', 0, "Exit with return code 0 (OK)"); |
77 | like( $res->output, '/^SSH OK - 3.2.9.1 \(protocol 2.0\)/', "Output OK for non-alpha softwareversion string"); | 97 | $output = decode_json($result->output); |
98 | is($output->{'state'}, "OK", "State was correct"); | ||
99 | |||
100 | $found_version = 0; | ||
101 | for my $subcheck (@{$output->{'checks'}}) { | ||
102 | if ($subcheck->{'output'} =~ /3.2.9.1 \(protocol version: 2.0\)/ ){ | ||
103 | $found_version = 1; | ||
104 | } | ||
105 | } | ||
106 | cmp_ok($found_version, '==', 1, "Output OK"); | ||
78 | close NC; | 107 | close NC; |
79 | 108 | ||
80 | open(NC, "echo 'SSH-2.0-nagiosplug.ssh.0.1 this is a comment' | nc ${nc_flags} |"); | 109 | open(NC, "echo 'SSH-2.0-nagiosplug.ssh.0.1 this is a comment' | nc ${nc_flags} |"); |
81 | sleep 0.1; | 110 | sleep 0.1; |
82 | $res = NPTest->testCmd( "./check_ssh -H localhost -p 5003 -r nagiosplug.ssh.0.1" ); | 111 | $result = NPTest->testCmd( "./check_ssh -H localhost -p 5003 -r nagiosplug.ssh.0.1" ." ". $outputFormat); |
83 | cmp_ok( $res->return_code, '==', 0, "Got SSH protocol version control string, and parsed comment appropriately"); | 112 | cmp_ok($result->return_code, '==', 0, "Exit with return code 0 (OK)"); |
84 | like( $res->output, '/^SSH OK - nagiosplug.ssh.0.1 \(protocol 2.0\)/', "Output OK"); | 113 | $output = decode_json($result->output); |
114 | is($output->{'state'}, "OK", "State was correct"); | ||
115 | |||
116 | # looking for the version | ||
117 | $found_version = 0; | ||
118 | for my $subcheck (@{$output->{'checks'}}) { | ||
119 | if ($subcheck->{'output'} =~ /nagiosplug.ssh.0.1 \(protocol version: 2.0\)/ ){ | ||
120 | $found_version = 1; | ||
121 | } | ||
122 | } | ||
123 | cmp_ok($found_version, '==', 1, "Output OK"); | ||
85 | close NC; | 124 | close NC; |
86 | 125 | ||
87 | open(NC, "echo 'SSH-' | nc ${nc_flags}|"); | 126 | open(NC, "echo 'SSH-' | nc ${nc_flags}|"); |
88 | sleep 0.1; | 127 | sleep 0.1; |
89 | $res = NPTest->testCmd( "./check_ssh -H localhost -p 5003" ); | 128 | $result = NPTest->testCmd( "./check_ssh -H localhost -p 5003" ." ". $outputFormat); |
90 | cmp_ok( $res->return_code, '==', 2, "Got invalid SSH protocol version control string"); | 129 | cmp_ok($result->return_code, '==', 0, "Exit with return code 0 (OK)"); |
91 | like( $res->output, '/^SSH CRITICAL/', "Output OK"); | 130 | $output = decode_json($result->output); |
131 | is($output->{'state'}, "CRITICAL", "Got invalid SSH protocol version control string"); | ||
92 | close NC; | 132 | close NC; |
93 | 133 | ||
94 | open(NC, "echo '' | nc ${nc_flags}|"); | 134 | open(NC, "echo '' | nc ${nc_flags}|"); |
95 | sleep 0.1; | 135 | sleep 0.1; |
96 | $res = NPTest->testCmd( "./check_ssh -H localhost -p 5003" ); | 136 | $result = NPTest->testCmd( "./check_ssh -H localhost -p 5003" ." ". $outputFormat); |
97 | cmp_ok( $res->return_code, '==', 2, "No version control string received"); | 137 | cmp_ok($result->return_code, '==', 0, "Exit with return code 0 (OK)"); |
98 | like( $res->output, '/^SSH CRITICAL - No version control string received/', "Output OK"); | 138 | $output = decode_json($result->output); |
139 | is($output->{'state'}, "CRITICAL", "No version control string received"); | ||
99 | close NC; | 140 | close NC; |
100 | 141 | ||
101 | open(NC, "echo 'Not a version control string' | nc ${nc_flags}|"); | 142 | open(NC, "echo 'Not a version control string' | nc ${nc_flags}|"); |
102 | sleep 0.1; | 143 | sleep 0.1; |
103 | $res = NPTest->testCmd( "./check_ssh -H localhost -p 5003" ); | 144 | $result = NPTest->testCmd( "./check_ssh -H localhost -p 5003" ." ". $outputFormat); |
104 | cmp_ok( $res->return_code, '==', 2, "No version control string received"); | 145 | cmp_ok($result->return_code, '==', 0, "Exit with return code 0 (OK)"); |
105 | like( $res->output, '/^SSH CRITICAL - No version control string received/', "Output OK"); | 146 | $output = decode_json($result->output); |
147 | is($output->{'state'}, "CRITICAL", "No version control string received"); | ||
106 | close NC; | 148 | close NC; |
107 | 149 | ||
108 | 150 | ||
@@ -116,8 +158,18 @@ SKIP: { | |||
116 | echo 'Some\nPrepended\nData\nLines\n'; sleep 0.2; | 158 | echo 'Some\nPrepended\nData\nLines\n'; sleep 0.2; |
117 | echo 'SSH-2.0-nagiosplug.ssh.0.2';} | nc ${nc_flags}|"); | 159 | echo 'SSH-2.0-nagiosplug.ssh.0.2';} | nc ${nc_flags}|"); |
118 | sleep 0.1; | 160 | sleep 0.1; |
119 | $res = NPTest->testCmd( "./check_ssh -H localhost -p 5003" ); | 161 | $result = NPTest->testCmd( "./check_ssh -H localhost -p 5003" ." ". $outputFormat); |
120 | cmp_ok( $res->return_code, '==', 0, "Got delayed SSH protocol version control string"); | 162 | cmp_ok($result->return_code, '==', 0, "Exit with return code 0 (OK)"); |
121 | like( $res->output, '/^SSH OK - nagiosplug.ssh.0.2 \(protocol 2.0\)/', "Output OK"); | 163 | $output = decode_json($result->output); |
164 | is($output->{'state'}, "OK", "State was correct"); | ||
165 | |||
166 | # looking for the version | ||
167 | $found_version = 0; | ||
168 | for my $subcheck (@{$output->{'checks'}}) { | ||
169 | if ($subcheck->{'output'} =~ /nagiosplug.ssh.0.2 \(protocol version: 2.0\)/ ){ | ||
170 | $found_version = 1; | ||
171 | } | ||
172 | } | ||
173 | cmp_ok($found_version, '==', 1, "Output OK"); | ||
122 | close NC; | 174 | close NC; |
123 | } | 175 | } |
diff --git a/plugins/utils.c b/plugins/utils.c index 09649429..34335c89 100644 --- a/plugins/utils.c +++ b/plugins/utils.c | |||
@@ -89,41 +89,46 @@ bool is_numeric(char *number) { | |||
89 | char tmp[1]; | 89 | char tmp[1]; |
90 | float x; | 90 | float x; |
91 | 91 | ||
92 | if (!number) | 92 | if (!number) { |
93 | return false; | 93 | return false; |
94 | else if (sscanf(number, "%f%c", &x, tmp) == 1) | 94 | } else if (sscanf(number, "%f%c", &x, tmp) == 1) { |
95 | return true; | 95 | return true; |
96 | else | 96 | } else { |
97 | return false; | 97 | return false; |
98 | } | ||
98 | } | 99 | } |
99 | 100 | ||
100 | bool is_positive(char *number) { | 101 | bool is_positive(char *number) { |
101 | if (is_numeric(number) && atof(number) > 0.0) | 102 | if (is_numeric(number) && atof(number) > 0.0) { |
102 | return true; | 103 | return true; |
103 | else | 104 | } else { |
104 | return false; | 105 | return false; |
106 | } | ||
105 | } | 107 | } |
106 | 108 | ||
107 | bool is_negative(char *number) { | 109 | bool is_negative(char *number) { |
108 | if (is_numeric(number) && atof(number) < 0.0) | 110 | if (is_numeric(number) && atof(number) < 0.0) { |
109 | return true; | 111 | return true; |
110 | else | 112 | } else { |
111 | return false; | 113 | return false; |
114 | } | ||
112 | } | 115 | } |
113 | 116 | ||
114 | bool is_nonnegative(char *number) { | 117 | bool is_nonnegative(char *number) { |
115 | if (is_numeric(number) && atof(number) >= 0.0) | 118 | if (is_numeric(number) && atof(number) >= 0.0) { |
116 | return true; | 119 | return true; |
117 | else | 120 | } else { |
118 | return false; | 121 | return false; |
122 | } | ||
119 | } | 123 | } |
120 | 124 | ||
121 | bool is_percentage(char *number) { | 125 | bool is_percentage(char *number) { |
122 | int x; | 126 | int x; |
123 | if (is_numeric(number) && (x = atof(number)) >= 0 && x <= 100) | 127 | if (is_numeric(number) && (x = atof(number)) >= 0 && x <= 100) { |
124 | return true; | 128 | return true; |
125 | else | 129 | } else { |
126 | return false; | 130 | return false; |
131 | } | ||
127 | } | 132 | } |
128 | 133 | ||
129 | bool is_percentage_expression(const char str[]) { | 134 | bool is_percentage_expression(const char str[]) { |
@@ -156,36 +161,41 @@ bool is_percentage_expression(const char str[]) { | |||
156 | bool is_integer(char *number) { | 161 | bool is_integer(char *number) { |
157 | long int n; | 162 | long int n; |
158 | 163 | ||
159 | if (!number || (strspn(number, "-0123456789 ") != strlen(number))) | 164 | if (!number || (strspn(number, "-0123456789 ") != strlen(number))) { |
160 | return false; | 165 | return false; |
166 | } | ||
161 | 167 | ||
162 | n = strtol(number, NULL, 10); | 168 | n = strtol(number, NULL, 10); |
163 | 169 | ||
164 | if (errno != ERANGE && n >= INT_MIN && n <= INT_MAX) | 170 | if (errno != ERANGE && n >= INT_MIN && n <= INT_MAX) { |
165 | return true; | 171 | return true; |
166 | else | 172 | } else { |
167 | return false; | 173 | return false; |
174 | } | ||
168 | } | 175 | } |
169 | 176 | ||
170 | bool is_intpos(char *number) { | 177 | bool is_intpos(char *number) { |
171 | if (is_integer(number) && atoi(number) > 0) | 178 | if (is_integer(number) && atoi(number) > 0) { |
172 | return true; | 179 | return true; |
173 | else | 180 | } else { |
174 | return false; | 181 | return false; |
182 | } | ||
175 | } | 183 | } |
176 | 184 | ||
177 | bool is_intneg(char *number) { | 185 | bool is_intneg(char *number) { |
178 | if (is_integer(number) && atoi(number) < 0) | 186 | if (is_integer(number) && atoi(number) < 0) { |
179 | return true; | 187 | return true; |
180 | else | 188 | } else { |
181 | return false; | 189 | return false; |
190 | } | ||
182 | } | 191 | } |
183 | 192 | ||
184 | bool is_intnonneg(char *number) { | 193 | bool is_intnonneg(char *number) { |
185 | if (is_integer(number) && atoi(number) >= 0) | 194 | if (is_integer(number) && atoi(number) >= 0) { |
186 | return true; | 195 | return true; |
187 | else | 196 | } else { |
188 | return false; | 197 | return false; |
198 | } | ||
189 | } | 199 | } |
190 | 200 | ||
191 | /* | 201 | /* |
@@ -247,19 +257,21 @@ bool is_uint64(char *number, uint64_t *target) { | |||
247 | 257 | ||
248 | bool is_intpercent(char *number) { | 258 | bool is_intpercent(char *number) { |
249 | int i; | 259 | int i; |
250 | if (is_integer(number) && (i = atoi(number)) >= 0 && i <= 100) | 260 | if (is_integer(number) && (i = atoi(number)) >= 0 && i <= 100) { |
251 | return true; | 261 | return true; |
252 | else | 262 | } else { |
253 | return false; | 263 | return false; |
264 | } | ||
254 | } | 265 | } |
255 | 266 | ||
256 | bool is_option(char *str) { | 267 | bool is_option(char *str) { |
257 | if (!str) | 268 | if (!str) { |
258 | return false; | 269 | return false; |
259 | else if (strspn(str, "-") == 1 || strspn(str, "-") == 2) | 270 | } else if (strspn(str, "-") == 1 || strspn(str, "-") == 2) { |
260 | return true; | 271 | return true; |
261 | else | 272 | } else { |
262 | return false; | 273 | return false; |
274 | } | ||
263 | } | 275 | } |
264 | 276 | ||
265 | #ifdef NEED_GETTIMEOFDAY | 277 | #ifdef NEED_GETTIMEOFDAY |
@@ -288,10 +300,11 @@ void strip(char *buffer) { | |||
288 | 300 | ||
289 | for (x = strlen(buffer); x >= 1; x--) { | 301 | for (x = strlen(buffer); x >= 1; x--) { |
290 | i = x - 1; | 302 | i = x - 1; |
291 | if (buffer[i] == ' ' || buffer[i] == '\r' || buffer[i] == '\n' || buffer[i] == '\t') | 303 | if (buffer[i] == ' ' || buffer[i] == '\r' || buffer[i] == '\n' || buffer[i] == '\t') { |
292 | buffer[i] = '\0'; | 304 | buffer[i] = '\0'; |
293 | else | 305 | } else { |
294 | break; | 306 | break; |
307 | } | ||
295 | } | 308 | } |
296 | return; | 309 | return; |
297 | } | 310 | } |
@@ -309,8 +322,9 @@ void strip(char *buffer) { | |||
309 | *****************************************************************************/ | 322 | *****************************************************************************/ |
310 | 323 | ||
311 | char *strscpy(char *dest, const char *src) { | 324 | char *strscpy(char *dest, const char *src) { |
312 | if (src == NULL) | 325 | if (src == NULL) { |
313 | return NULL; | 326 | return NULL; |
327 | } | ||
314 | 328 | ||
315 | xasprintf(&dest, "%s", src); | 329 | xasprintf(&dest, "%s", src); |
316 | 330 | ||
@@ -369,17 +383,21 @@ char *strscpy(char *dest, const char *src) { | |||
369 | 383 | ||
370 | char *strnl(char *str) { | 384 | char *strnl(char *str) { |
371 | size_t len; | 385 | size_t len; |
372 | if (str == NULL) | 386 | if (str == NULL) { |
373 | return NULL; | 387 | return NULL; |
388 | } | ||
374 | str = strpbrk(str, "\r\n"); | 389 | str = strpbrk(str, "\r\n"); |
375 | if (str == NULL) | 390 | if (str == NULL) { |
376 | return NULL; | 391 | return NULL; |
392 | } | ||
377 | len = strspn(str, "\r\n"); | 393 | len = strspn(str, "\r\n"); |
378 | if (str[len] == '\0') | 394 | if (str[len] == '\0') { |
379 | return NULL; | 395 | return NULL; |
396 | } | ||
380 | str += len; | 397 | str += len; |
381 | if (strlen(str) == 0) | 398 | if (strlen(str) == 0) { |
382 | return NULL; | 399 | return NULL; |
400 | } | ||
383 | return str; | 401 | return str; |
384 | } | 402 | } |
385 | 403 | ||
@@ -402,15 +420,18 @@ char *strnl(char *str) { | |||
402 | char *strpcpy(char *dest, const char *src, const char *str) { | 420 | char *strpcpy(char *dest, const char *src, const char *str) { |
403 | size_t len; | 421 | size_t len; |
404 | 422 | ||
405 | if (src) | 423 | if (src) { |
406 | len = strcspn(src, str); | 424 | len = strcspn(src, str); |
407 | else | 425 | } else { |
408 | return NULL; | 426 | return NULL; |
427 | } | ||
409 | 428 | ||
410 | if (dest == NULL || strlen(dest) < len) | 429 | if (dest == NULL || strlen(dest) < len) { |
411 | dest = realloc(dest, len + 1); | 430 | dest = realloc(dest, len + 1); |
412 | if (dest == NULL) | 431 | } |
432 | if (dest == NULL) { | ||
413 | die(STATE_UNKNOWN, _("failed realloc in strpcpy\n")); | 433 | die(STATE_UNKNOWN, _("failed realloc in strpcpy\n")); |
434 | } | ||
414 | 435 | ||
415 | strncpy(dest, src, len); | 436 | strncpy(dest, src, len); |
416 | dest[len] = '\0'; | 437 | dest[len] = '\0'; |
@@ -434,10 +455,11 @@ char *strpcpy(char *dest, const char *src, const char *str) { | |||
434 | char *strpcat(char *dest, const char *src, const char *str) { | 455 | char *strpcat(char *dest, const char *src, const char *str) { |
435 | size_t len, l2; | 456 | size_t len, l2; |
436 | 457 | ||
437 | if (dest) | 458 | if (dest) { |
438 | len = strlen(dest); | 459 | len = strlen(dest); |
439 | else | 460 | } else { |
440 | len = 0; | 461 | len = 0; |
462 | } | ||
441 | 463 | ||
442 | if (src) { | 464 | if (src) { |
443 | l2 = strcspn(src, str); | 465 | l2 = strcspn(src, str); |
@@ -446,8 +468,9 @@ char *strpcat(char *dest, const char *src, const char *str) { | |||
446 | } | 468 | } |
447 | 469 | ||
448 | dest = realloc(dest, len + l2 + 1); | 470 | dest = realloc(dest, len + l2 + 1); |
449 | if (dest == NULL) | 471 | if (dest == NULL) { |
450 | die(STATE_UNKNOWN, _("failed malloc in strscat\n")); | 472 | die(STATE_UNKNOWN, _("failed malloc in strscat\n")); |
473 | } | ||
451 | 474 | ||
452 | strncpy(dest + len, src, l2); | 475 | strncpy(dest + len, src, l2); |
453 | dest[len + l2] = '\0'; | 476 | dest[len + l2] = '\0'; |
@@ -463,8 +486,9 @@ char *strpcat(char *dest, const char *src, const char *str) { | |||
463 | 486 | ||
464 | int xvasprintf(char **strp, const char *fmt, va_list ap) { | 487 | int xvasprintf(char **strp, const char *fmt, va_list ap) { |
465 | int result = vasprintf(strp, fmt, ap); | 488 | int result = vasprintf(strp, fmt, ap); |
466 | if (result == -1 || *strp == NULL) | 489 | if (result == -1 || *strp == NULL) { |
467 | die(STATE_UNKNOWN, _("failed malloc in xvasprintf\n")); | 490 | die(STATE_UNKNOWN, _("failed malloc in xvasprintf\n")); |
491 | } | ||
468 | return result; | 492 | return result; |
469 | } | 493 | } |
470 | 494 | ||
@@ -483,126 +507,145 @@ int xasprintf(char **strp, const char *fmt, ...) { | |||
483 | * | 507 | * |
484 | ******************************************************************************/ | 508 | ******************************************************************************/ |
485 | 509 | ||
486 | char *perfdata(const char *label, long int val, const char *uom, int warnp, long int warn, int critp, long int crit, int minp, | 510 | char *perfdata(const char *label, long int val, const char *uom, bool warnp, long int warn, bool critp, long int crit, bool minp, |
487 | long int minv, int maxp, long int maxv) { | 511 | long int minv, bool maxp, long int maxv) { |
488 | char *data = NULL; | 512 | char *data = NULL; |
489 | 513 | ||
490 | if (strpbrk(label, "'= ")) | 514 | if (strpbrk(label, "'= ")) { |
491 | xasprintf(&data, "'%s'=%ld%s;", label, val, uom); | 515 | xasprintf(&data, "'%s'=%ld%s;", label, val, uom); |
492 | else | 516 | } else { |
493 | xasprintf(&data, "%s=%ld%s;", label, val, uom); | 517 | xasprintf(&data, "%s=%ld%s;", label, val, uom); |
518 | } | ||
494 | 519 | ||
495 | if (warnp) | 520 | if (warnp) { |
496 | xasprintf(&data, "%s%ld;", data, warn); | 521 | xasprintf(&data, "%s%ld;", data, warn); |
497 | else | 522 | } else { |
498 | xasprintf(&data, "%s;", data); | 523 | xasprintf(&data, "%s;", data); |
524 | } | ||
499 | 525 | ||
500 | if (critp) | 526 | if (critp) { |
501 | xasprintf(&data, "%s%ld;", data, crit); | 527 | xasprintf(&data, "%s%ld;", data, crit); |
502 | else | 528 | } else { |
503 | xasprintf(&data, "%s;", data); | 529 | xasprintf(&data, "%s;", data); |
530 | } | ||
504 | 531 | ||
505 | if (minp) | 532 | if (minp) { |
506 | xasprintf(&data, "%s%ld;", data, minv); | 533 | xasprintf(&data, "%s%ld;", data, minv); |
507 | else | 534 | } else { |
508 | xasprintf(&data, "%s;", data); | 535 | xasprintf(&data, "%s;", data); |
536 | } | ||
509 | 537 | ||
510 | if (maxp) | 538 | if (maxp) { |
511 | xasprintf(&data, "%s%ld", data, maxv); | 539 | xasprintf(&data, "%s%ld", data, maxv); |
540 | } | ||
512 | 541 | ||
513 | return data; | 542 | return data; |
514 | } | 543 | } |
515 | 544 | ||
516 | char *perfdata_uint64(const char *label, uint64_t val, const char *uom, int warnp, /* Warning present */ | 545 | char *perfdata_uint64(const char *label, uint64_t val, const char *uom, bool warnp, /* Warning present */ |
517 | uint64_t warn, int critp, /* Critical present */ | 546 | uint64_t warn, bool critp, /* Critical present */ |
518 | uint64_t crit, int minp, /* Minimum present */ | 547 | uint64_t crit, bool minp, /* Minimum present */ |
519 | uint64_t minv, int maxp, /* Maximum present */ | 548 | uint64_t minv, bool maxp, /* Maximum present */ |
520 | uint64_t maxv) { | 549 | uint64_t maxv) { |
521 | char *data = NULL; | 550 | char *data = NULL; |
522 | 551 | ||
523 | if (strpbrk(label, "'= ")) | 552 | if (strpbrk(label, "'= ")) { |
524 | xasprintf(&data, "'%s'=%" PRIu64 "%s;", label, val, uom); | 553 | xasprintf(&data, "'%s'=%" PRIu64 "%s;", label, val, uom); |
525 | else | 554 | } else { |
526 | xasprintf(&data, "%s=%" PRIu64 "%s;", label, val, uom); | 555 | xasprintf(&data, "%s=%" PRIu64 "%s;", label, val, uom); |
556 | } | ||
527 | 557 | ||
528 | if (warnp) | 558 | if (warnp) { |
529 | xasprintf(&data, "%s%" PRIu64 ";", data, warn); | 559 | xasprintf(&data, "%s%" PRIu64 ";", data, warn); |
530 | else | 560 | } else { |
531 | xasprintf(&data, "%s;", data); | 561 | xasprintf(&data, "%s;", data); |
562 | } | ||
532 | 563 | ||
533 | if (critp) | 564 | if (critp) { |
534 | xasprintf(&data, "%s%" PRIu64 ";", data, crit); | 565 | xasprintf(&data, "%s%" PRIu64 ";", data, crit); |
535 | else | 566 | } else { |
536 | xasprintf(&data, "%s;", data); | 567 | xasprintf(&data, "%s;", data); |
568 | } | ||
537 | 569 | ||
538 | if (minp) | 570 | if (minp) { |
539 | xasprintf(&data, "%s%" PRIu64 ";", data, minv); | 571 | xasprintf(&data, "%s%" PRIu64 ";", data, minv); |
540 | else | 572 | } else { |
541 | xasprintf(&data, "%s;", data); | 573 | xasprintf(&data, "%s;", data); |
574 | } | ||
542 | 575 | ||
543 | if (maxp) | 576 | if (maxp) { |
544 | xasprintf(&data, "%s%" PRIu64, data, maxv); | 577 | xasprintf(&data, "%s%" PRIu64, data, maxv); |
578 | } | ||
545 | 579 | ||
546 | return data; | 580 | return data; |
547 | } | 581 | } |
548 | 582 | ||
549 | char *perfdata_int64(const char *label, int64_t val, const char *uom, int warnp, /* Warning present */ | 583 | char *perfdata_int64(const char *label, int64_t val, const char *uom, bool warnp, /* Warning present */ |
550 | int64_t warn, int critp, /* Critical present */ | 584 | int64_t warn, bool critp, /* Critical present */ |
551 | int64_t crit, int minp, /* Minimum present */ | 585 | int64_t crit, bool minp, /* Minimum present */ |
552 | int64_t minv, int maxp, /* Maximum present */ | 586 | int64_t minv, bool maxp, /* Maximum present */ |
553 | int64_t maxv) { | 587 | int64_t maxv) { |
554 | char *data = NULL; | 588 | char *data = NULL; |
555 | 589 | ||
556 | if (strpbrk(label, "'= ")) | 590 | if (strpbrk(label, "'= ")) { |
557 | xasprintf(&data, "'%s'=%" PRId64 "%s;", label, val, uom); | 591 | xasprintf(&data, "'%s'=%" PRId64 "%s;", label, val, uom); |
558 | else | 592 | } else { |
559 | xasprintf(&data, "%s=%" PRId64 "%s;", label, val, uom); | 593 | xasprintf(&data, "%s=%" PRId64 "%s;", label, val, uom); |
594 | } | ||
560 | 595 | ||
561 | if (warnp) | 596 | if (warnp) { |
562 | xasprintf(&data, "%s%" PRId64 ";", data, warn); | 597 | xasprintf(&data, "%s%" PRId64 ";", data, warn); |
563 | else | 598 | } else { |
564 | xasprintf(&data, "%s;", data); | 599 | xasprintf(&data, "%s;", data); |
600 | } | ||
565 | 601 | ||
566 | if (critp) | 602 | if (critp) { |
567 | xasprintf(&data, "%s%" PRId64 ";", data, crit); | 603 | xasprintf(&data, "%s%" PRId64 ";", data, crit); |
568 | else | 604 | } else { |
569 | xasprintf(&data, "%s;", data); | 605 | xasprintf(&data, "%s;", data); |
606 | } | ||
570 | 607 | ||
571 | if (minp) | 608 | if (minp) { |
572 | xasprintf(&data, "%s%" PRId64 ";", data, minv); | 609 | xasprintf(&data, "%s%" PRId64 ";", data, minv); |
573 | else | 610 | } else { |
574 | xasprintf(&data, "%s;", data); | 611 | xasprintf(&data, "%s;", data); |
612 | } | ||
575 | 613 | ||
576 | if (maxp) | 614 | if (maxp) { |
577 | xasprintf(&data, "%s%" PRId64, data, maxv); | 615 | xasprintf(&data, "%s%" PRId64, data, maxv); |
616 | } | ||
578 | 617 | ||
579 | return data; | 618 | return data; |
580 | } | 619 | } |
581 | 620 | ||
582 | char *fperfdata(const char *label, double val, const char *uom, int warnp, double warn, int critp, double crit, int minp, double minv, | 621 | char *fperfdata(const char *label, double val, const char *uom, bool warnp, double warn, bool critp, double crit, bool minp, double minv, |
583 | int maxp, double maxv) { | 622 | bool maxp, double maxv) { |
584 | char *data = NULL; | 623 | char *data = NULL; |
585 | 624 | ||
586 | if (strpbrk(label, "'= ")) | 625 | if (strpbrk(label, "'= ")) { |
587 | xasprintf(&data, "'%s'=", label); | 626 | xasprintf(&data, "'%s'=", label); |
588 | else | 627 | } else { |
589 | xasprintf(&data, "%s=", label); | 628 | xasprintf(&data, "%s=", label); |
629 | } | ||
590 | 630 | ||
591 | xasprintf(&data, "%s%f", data, val); | 631 | xasprintf(&data, "%s%f", data, val); |
592 | xasprintf(&data, "%s%s;", data, uom); | 632 | xasprintf(&data, "%s%s;", data, uom); |
593 | 633 | ||
594 | if (warnp) | 634 | if (warnp) { |
595 | xasprintf(&data, "%s%f", data, warn); | 635 | xasprintf(&data, "%s%f", data, warn); |
636 | } | ||
596 | 637 | ||
597 | xasprintf(&data, "%s;", data); | 638 | xasprintf(&data, "%s;", data); |
598 | 639 | ||
599 | if (critp) | 640 | if (critp) { |
600 | xasprintf(&data, "%s%f", data, crit); | 641 | xasprintf(&data, "%s%f", data, crit); |
642 | } | ||
601 | 643 | ||
602 | xasprintf(&data, "%s;", data); | 644 | xasprintf(&data, "%s;", data); |
603 | 645 | ||
604 | if (minp) | 646 | if (minp) { |
605 | xasprintf(&data, "%s%f", data, minv); | 647 | xasprintf(&data, "%s%f", data, minv); |
648 | } | ||
606 | 649 | ||
607 | if (maxp) { | 650 | if (maxp) { |
608 | xasprintf(&data, "%s;", data); | 651 | xasprintf(&data, "%s;", data); |
@@ -612,28 +655,32 @@ char *fperfdata(const char *label, double val, const char *uom, int warnp, doubl | |||
612 | return data; | 655 | return data; |
613 | } | 656 | } |
614 | 657 | ||
615 | char *sperfdata(const char *label, double val, const char *uom, char *warn, char *crit, int minp, double minv, int maxp, double maxv) { | 658 | char *sperfdata(const char *label, double val, const char *uom, char *warn, char *crit, bool minp, double minv, bool maxp, double maxv) { |
616 | char *data = NULL; | 659 | char *data = NULL; |
617 | if (strpbrk(label, "'= ")) | 660 | if (strpbrk(label, "'= ")) { |
618 | xasprintf(&data, "'%s'=", label); | 661 | xasprintf(&data, "'%s'=", label); |
619 | else | 662 | } else { |
620 | xasprintf(&data, "%s=", label); | 663 | xasprintf(&data, "%s=", label); |
664 | } | ||
621 | 665 | ||
622 | xasprintf(&data, "%s%f", data, val); | 666 | xasprintf(&data, "%s%f", data, val); |
623 | xasprintf(&data, "%s%s;", data, uom); | 667 | xasprintf(&data, "%s%s;", data, uom); |
624 | 668 | ||
625 | if (warn != NULL) | 669 | if (warn != NULL) { |
626 | xasprintf(&data, "%s%s", data, warn); | 670 | xasprintf(&data, "%s%s", data, warn); |
671 | } | ||
627 | 672 | ||
628 | xasprintf(&data, "%s;", data); | 673 | xasprintf(&data, "%s;", data); |
629 | 674 | ||
630 | if (crit != NULL) | 675 | if (crit != NULL) { |
631 | xasprintf(&data, "%s%s", data, crit); | 676 | xasprintf(&data, "%s%s", data, crit); |
677 | } | ||
632 | 678 | ||
633 | xasprintf(&data, "%s;", data); | 679 | xasprintf(&data, "%s;", data); |
634 | 680 | ||
635 | if (minp) | 681 | if (minp) { |
636 | xasprintf(&data, "%s%f", data, minv); | 682 | xasprintf(&data, "%s%f", data, minv); |
683 | } | ||
637 | 684 | ||
638 | if (maxp) { | 685 | if (maxp) { |
639 | xasprintf(&data, "%s;", data); | 686 | xasprintf(&data, "%s;", data); |
@@ -643,28 +690,32 @@ char *sperfdata(const char *label, double val, const char *uom, char *warn, char | |||
643 | return data; | 690 | return data; |
644 | } | 691 | } |
645 | 692 | ||
646 | char *sperfdata_int(const char *label, int val, const char *uom, char *warn, char *crit, int minp, int minv, int maxp, int maxv) { | 693 | char *sperfdata_int(const char *label, int val, const char *uom, char *warn, char *crit, bool minp, int minv, bool maxp, int maxv) { |
647 | char *data = NULL; | 694 | char *data = NULL; |
648 | if (strpbrk(label, "'= ")) | 695 | if (strpbrk(label, "'= ")) { |
649 | xasprintf(&data, "'%s'=", label); | 696 | xasprintf(&data, "'%s'=", label); |
650 | else | 697 | } else { |
651 | xasprintf(&data, "%s=", label); | 698 | xasprintf(&data, "%s=", label); |
699 | } | ||
652 | 700 | ||
653 | xasprintf(&data, "%s%d", data, val); | 701 | xasprintf(&data, "%s%d", data, val); |
654 | xasprintf(&data, "%s%s;", data, uom); | 702 | xasprintf(&data, "%s%s;", data, uom); |
655 | 703 | ||
656 | if (warn != NULL) | 704 | if (warn != NULL) { |
657 | xasprintf(&data, "%s%s", data, warn); | 705 | xasprintf(&data, "%s%s", data, warn); |
706 | } | ||
658 | 707 | ||
659 | xasprintf(&data, "%s;", data); | 708 | xasprintf(&data, "%s;", data); |
660 | 709 | ||
661 | if (crit != NULL) | 710 | if (crit != NULL) { |
662 | xasprintf(&data, "%s%s", data, crit); | 711 | xasprintf(&data, "%s%s", data, crit); |
712 | } | ||
663 | 713 | ||
664 | xasprintf(&data, "%s;", data); | 714 | xasprintf(&data, "%s;", data); |
665 | 715 | ||
666 | if (minp) | 716 | if (minp) { |
667 | xasprintf(&data, "%s%d", data, minv); | 717 | xasprintf(&data, "%s%d", data, minv); |
718 | } | ||
668 | 719 | ||
669 | if (maxp) { | 720 | if (maxp) { |
670 | xasprintf(&data, "%s;", data); | 721 | xasprintf(&data, "%s;", data); |
diff --git a/plugins/utils.h b/plugins/utils.h index 029ae5a6..92a6c115 100644 --- a/plugins/utils.h +++ b/plugins/utils.h | |||
@@ -21,43 +21,43 @@ suite of plugins. */ | |||
21 | 21 | ||
22 | #ifdef NP_EXTRA_OPTS | 22 | #ifdef NP_EXTRA_OPTS |
23 | /* Include extra-opts functions if compiled in */ | 23 | /* Include extra-opts functions if compiled in */ |
24 | #include "extra_opts.h" | 24 | # include "extra_opts.h" |
25 | #else | 25 | #else |
26 | /* else, fake np_extra_opts */ | 26 | /* else, fake np_extra_opts */ |
27 | #define np_extra_opts(acptr,av,pr) av | 27 | # define np_extra_opts(acptr, av, pr) av |
28 | #endif | 28 | #endif |
29 | 29 | ||
30 | /* Standardize version information, termination */ | 30 | /* Standardize version information, termination */ |
31 | 31 | ||
32 | void support (void); | 32 | void support(void); |
33 | void print_revision (const char *, const char *); | 33 | void print_revision(const char *, const char *); |
34 | 34 | ||
35 | extern time_t start_time, end_time; | 35 | extern time_t start_time, end_time; |
36 | 36 | ||
37 | /* Test input types */ | 37 | /* Test input types */ |
38 | 38 | ||
39 | bool is_integer (char *); | 39 | bool is_integer(char *); |
40 | bool is_intpos (char *); | 40 | bool is_intpos(char *); |
41 | bool is_intneg (char *); | 41 | bool is_intneg(char *); |
42 | bool is_intnonneg (char *); | 42 | bool is_intnonneg(char *); |
43 | bool is_intpercent (char *); | 43 | bool is_intpercent(char *); |
44 | bool is_uint64(char *number, uint64_t *target); | 44 | bool is_uint64(char *number, uint64_t *target); |
45 | bool is_int64(char *number, int64_t *target); | 45 | bool is_int64(char *number, int64_t *target); |
46 | 46 | ||
47 | bool is_numeric (char *); | 47 | bool is_numeric(char *); |
48 | bool is_positive (char *); | 48 | bool is_positive(char *); |
49 | bool is_negative (char *); | 49 | bool is_negative(char *); |
50 | bool is_nonnegative (char *); | 50 | bool is_nonnegative(char *); |
51 | bool is_percentage (char *); | 51 | bool is_percentage(char *); |
52 | bool is_percentage_expression (const char[]); | 52 | bool is_percentage_expression(const char[]); |
53 | 53 | ||
54 | bool is_option (char *); | 54 | bool is_option(char *); |
55 | 55 | ||
56 | /* Generalized timer that will do milliseconds if available */ | 56 | /* Generalized timer that will do milliseconds if available */ |
57 | #ifndef HAVE_STRUCT_TIMEVAL | 57 | #ifndef HAVE_STRUCT_TIMEVAL |
58 | struct timeval { | 58 | struct timeval { |
59 | long tv_sec; /* seconds */ | 59 | long tv_sec; /* seconds */ |
60 | long tv_usec; /* microseconds */ | 60 | long tv_usec; /* microseconds */ |
61 | }; | 61 | }; |
62 | #endif | 62 | #endif |
63 | 63 | ||
@@ -65,137 +65,142 @@ struct timeval { | |||
65 | int gettimeofday(struct timeval *, struct timezone *); | 65 | int gettimeofday(struct timeval *, struct timezone *); |
66 | #endif | 66 | #endif |
67 | 67 | ||
68 | double delta_time (struct timeval tv); | 68 | double delta_time(struct timeval tv); |
69 | long deltime (struct timeval tv); | 69 | long deltime(struct timeval tv); |
70 | 70 | ||
71 | /* Handle strings safely */ | 71 | /* Handle strings safely */ |
72 | 72 | ||
73 | void strip (char *); | 73 | void strip(char *); |
74 | char *strscpy (char *, const char *); | 74 | char *strscpy(char *, const char *); |
75 | char *strnl (char *); | 75 | char *strnl(char *); |
76 | char *strpcpy (char *, const char *, const char *); | 76 | char *strpcpy(char *, const char *, const char *); |
77 | char *strpcat (char *, const char *, const char *); | 77 | char *strpcat(char *, const char *, const char *); |
78 | int xvasprintf (char **strp, const char *fmt, va_list ap); | 78 | int xvasprintf(char **strp, const char *fmt, va_list ap); |
79 | int xasprintf (char **strp, const char *fmt, ...); | 79 | int xasprintf(char **strp, const char *fmt, ...); |
80 | 80 | ||
81 | void usage (const char *) __attribute__((noreturn)); | 81 | void usage(const char *) __attribute__((noreturn)); |
82 | void usage2(const char *, const char *) __attribute__((noreturn)); | 82 | void usage2(const char *, const char *) __attribute__((noreturn)); |
83 | void usage3(const char *, int) __attribute__((noreturn)); | 83 | void usage3(const char *, int) __attribute__((noreturn)); |
84 | void usage4(const char *) __attribute__((noreturn)); | 84 | void usage4(const char *) __attribute__((noreturn)); |
85 | void usage5(void) __attribute__((noreturn)); | 85 | void usage5(void) __attribute__((noreturn)); |
86 | void usage_va(const char *fmt, ...) __attribute__((noreturn)); | 86 | void usage_va(const char *fmt, ...) __attribute__((noreturn)); |
87 | 87 | ||
88 | #define max(a,b) (((a)>(b))?(a):(b)) | 88 | #define max(a, b) (((a) > (b)) ? (a) : (b)) |
89 | #define min(a,b) (((a)<(b))?(a):(b)) | 89 | #define min(a, b) (((a) < (b)) ? (a) : (b)) |
90 | 90 | ||
91 | char *perfdata (const char *, long int, const char *, int, long int, | 91 | char *perfdata(const char *, long int, const char *, bool, long int, bool, long int, bool, long int, bool, long int); |
92 | int, long int, int, long int, int, long int); | ||
93 | 92 | ||
94 | char *perfdata_uint64 (const char *, uint64_t , const char *, int, uint64_t, | 93 | char *perfdata_uint64(const char *, uint64_t, const char *, bool, uint64_t, bool, uint64_t, bool, uint64_t, bool, uint64_t); |
95 | int, uint64_t, int, uint64_t, int, uint64_t); | ||
96 | 94 | ||
97 | char *perfdata_int64 (const char *, int64_t, const char *, int, int64_t, | 95 | char *perfdata_int64(const char *, int64_t, const char *, bool, int64_t, bool, int64_t, bool, int64_t, bool, int64_t); |
98 | int, int64_t, int, int64_t, int, int64_t); | ||
99 | 96 | ||
100 | char *fperfdata (const char *, double, const char *, int, double, | 97 | char *fperfdata(const char *, double, const char *, bool, double, bool, double, bool, double, bool, double); |
101 | int, double, int, double, int, double); | ||
102 | 98 | ||
103 | char *sperfdata (const char *, double, const char *, char *, char *, | 99 | char *sperfdata(const char *, double, const char *, char *, char *, bool, double, bool, double); |
104 | int, double, int, double); | ||
105 | 100 | ||
106 | char *sperfdata_int (const char *, int, const char *, char *, char *, | 101 | char *sperfdata_int(const char *, int, const char *, char *, char *, bool, int, bool, int); |
107 | int, int, int, int); | ||
108 | 102 | ||
109 | /* The idea here is that, although not every plugin will use all of these, | 103 | /* The idea here is that, although not every plugin will use all of these, |
110 | most will or should. Therefore, for consistency, these very common | 104 | most will or should. Therefore, for consistency, these very common |
111 | options should have only these meanings throughout the overall suite */ | 105 | options should have only these meanings throughout the overall suite */ |
112 | 106 | ||
113 | #define STD_LONG_OPTS \ | 107 | #define STD_LONG_OPTS \ |
114 | {"version",no_argument,0,'V'},\ | 108 | {"version", no_argument, 0, 'V'}, {"verbose", no_argument, 0, 'v'}, {"help", no_argument, 0, 'h'}, \ |
115 | {"verbose",no_argument,0,'v'},\ | 109 | {"timeout", required_argument, 0, 't'}, {"critical", required_argument, 0, 'c'}, {"warning", required_argument, 0, 'w'}, \ |
116 | {"help",no_argument,0,'h'},\ | 110 | {"hostname", required_argument, 0, 'H'} |
117 | {"timeout",required_argument,0,'t'},\ | ||
118 | {"critical",required_argument,0,'c'},\ | ||
119 | {"warning",required_argument,0,'w'},\ | ||
120 | {"hostname",required_argument,0,'H'} | ||
121 | 111 | ||
122 | #define COPYRIGHT "Copyright (c) %s Monitoring Plugins Development Team\n\ | 112 | #define COPYRIGHT \ |
113 | "Copyright (c) %s Monitoring Plugins Development Team\n\ | ||
123 | \t<%s>\n\n" | 114 | \t<%s>\n\n" |
124 | 115 | ||
125 | #define UT_HLP_VRS _("\ | 116 | #define UT_HLP_VRS \ |
117 | _("\ | ||
126 | %s (-h | --help) for detailed help\n\ | 118 | %s (-h | --help) for detailed help\n\ |
127 | %s (-V | --version) for version information\n") | 119 | %s (-V | --version) for version information\n") |
128 | 120 | ||
129 | #define UT_HELP_VRSN _("\ | 121 | #define UT_HELP_VRSN \ |
122 | _("\ | ||
130 | \nOptions:\n\ | 123 | \nOptions:\n\ |
131 | -h, --help\n\ | 124 | -h, --help\n\ |
132 | Print detailed help screen\n\ | 125 | Print detailed help screen\n\ |
133 | -V, --version\n\ | 126 | -V, --version\n\ |
134 | Print version information\n") | 127 | Print version information\n") |
135 | 128 | ||
136 | #define UT_HOST_PORT _("\ | 129 | #define UT_HOST_PORT \ |
130 | _("\ | ||
137 | -H, --hostname=ADDRESS\n\ | 131 | -H, --hostname=ADDRESS\n\ |
138 | Host name, IP Address, or unix socket (must be an absolute path)\n\ | 132 | Host name, IP Address, or unix socket (must be an absolute path)\n\ |
139 | -%c, --port=INTEGER\n\ | 133 | -%c, --port=INTEGER\n\ |
140 | Port number (default: %s)\n") | 134 | Port number (default: %s)\n") |
141 | 135 | ||
142 | #define UT_IPv46 _("\ | 136 | #define UT_IPv46 \ |
137 | _("\ | ||
143 | -4, --use-ipv4\n\ | 138 | -4, --use-ipv4\n\ |
144 | Use IPv4 connection\n\ | 139 | Use IPv4 connection\n\ |
145 | -6, --use-ipv6\n\ | 140 | -6, --use-ipv6\n\ |
146 | Use IPv6 connection\n") | 141 | Use IPv6 connection\n") |
147 | 142 | ||
148 | #define UT_VERBOSE _("\ | 143 | #define UT_VERBOSE \ |
144 | _("\ | ||
149 | -v, --verbose\n\ | 145 | -v, --verbose\n\ |
150 | Show details for command-line debugging (output may be truncated by\n\ | 146 | Show details for command-line debugging (output may be truncated by\n\ |
151 | the monitoring system)\n") | 147 | the monitoring system)\n") |
152 | 148 | ||
153 | #define UT_WARN_CRIT _("\ | 149 | #define UT_WARN_CRIT \ |
150 | _("\ | ||
154 | -w, --warning=DOUBLE\n\ | 151 | -w, --warning=DOUBLE\n\ |
155 | Response time to result in warning status (seconds)\n\ | 152 | Response time to result in warning status (seconds)\n\ |
156 | -c, --critical=DOUBLE\n\ | 153 | -c, --critical=DOUBLE\n\ |
157 | Response time to result in critical status (seconds)\n") | 154 | Response time to result in critical status (seconds)\n") |
158 | 155 | ||
159 | #define UT_WARN_CRIT_RANGE _("\ | 156 | #define UT_WARN_CRIT_RANGE \ |
157 | _("\ | ||
160 | -w, --warning=RANGE\n\ | 158 | -w, --warning=RANGE\n\ |
161 | Warning range (format: start:end). Alert if outside this range\n\ | 159 | Warning range (format: start:end). Alert if outside this range\n\ |
162 | -c, --critical=RANGE\n\ | 160 | -c, --critical=RANGE\n\ |
163 | Critical range\n") | 161 | Critical range\n") |
164 | 162 | ||
165 | #define UT_CONN_TIMEOUT _("\ | 163 | #define UT_CONN_TIMEOUT \ |
164 | _("\ | ||
166 | -t, --timeout=INTEGER\n\ | 165 | -t, --timeout=INTEGER\n\ |
167 | Seconds before connection times out (default: %d)\n") | 166 | Seconds before connection times out (default: %d)\n") |
168 | 167 | ||
169 | #define UT_PLUG_TIMEOUT _("\ | 168 | #define UT_PLUG_TIMEOUT \ |
169 | _("\ | ||
170 | -t, --timeout=INTEGER\n\ | 170 | -t, --timeout=INTEGER\n\ |
171 | Seconds before plugin times out (default: %d)\n") | 171 | Seconds before plugin times out (default: %d)\n") |
172 | 172 | ||
173 | #ifdef NP_EXTRA_OPTS | 173 | #ifdef NP_EXTRA_OPTS |
174 | #define UT_EXTRA_OPTS _("\ | 174 | # define UT_EXTRA_OPTS \ |
175 | _("\ | ||
175 | --extra-opts=[section][@file]\n\ | 176 | --extra-opts=[section][@file]\n\ |
176 | Read options from an ini file. See\n\ | 177 | Read options from an ini file. See\n\ |
177 | https://www.monitoring-plugins.org/doc/extra-opts.html\n\ | 178 | https://www.monitoring-plugins.org/doc/extra-opts.html\n\ |
178 | for usage and examples.\n") | 179 | for usage and examples.\n") |
179 | #else | 180 | #else |
180 | #define UT_EXTRA_OPTS " \b" | 181 | # define UT_EXTRA_OPTS " \b" |
181 | #endif | 182 | #endif |
182 | 183 | ||
183 | #define UT_THRESHOLDS_NOTES _("\ | 184 | #define UT_THRESHOLDS_NOTES \ |
185 | _("\ | ||
184 | See:\n\ | 186 | See:\n\ |
185 | https://www.monitoring-plugins.org/doc/guidelines.html#THRESHOLDFORMAT\n\ | 187 | https://www.monitoring-plugins.org/doc/guidelines.html#THRESHOLDFORMAT\n\ |
186 | for THRESHOLD format and examples.\n") | 188 | for THRESHOLD format and examples.\n") |
187 | 189 | ||
188 | #define UT_SUPPORT _("\n\ | 190 | #define UT_SUPPORT \ |
191 | _("\n\ | ||
189 | Send email to help@monitoring-plugins.org if you have questions regarding\n\ | 192 | Send email to help@monitoring-plugins.org if you have questions regarding\n\ |
190 | use of this software. To submit patches or suggest improvements, send email\n\ | 193 | use of this software. To submit patches or suggest improvements, send email\n\ |
191 | to devel@monitoring-plugins.org\n\n") | 194 | to devel@monitoring-plugins.org\n\n") |
192 | 195 | ||
193 | #define UT_NOWARRANTY _("\n\ | 196 | #define UT_NOWARRANTY \ |
197 | _("\n\ | ||
194 | The Monitoring Plugins come with ABSOLUTELY NO WARRANTY. You may redistribute\n\ | 198 | The Monitoring Plugins come with ABSOLUTELY NO WARRANTY. You may redistribute\n\ |
195 | copies of the plugins under the terms of the GNU General Public License.\n\ | 199 | copies of the plugins under the terms of the GNU General Public License.\n\ |
196 | For more information about these matters, see the file named COPYING.\n") | 200 | For more information about these matters, see the file named COPYING.\n") |
197 | 201 | ||
198 | #define UT_OUTPUT_FORMAT _("\ | 202 | #define UT_OUTPUT_FORMAT \ |
203 | _("\ | ||
199 | --output-format=OUTPUT_FORMAT\n\ | 204 | --output-format=OUTPUT_FORMAT\n\ |
200 | Select output format. Valid values: \"multi-line\", \"mp-test-json\"\n") | 205 | Select output format. Valid values: \"multi-line\", \"mp-test-json\"\n") |
201 | 206 | ||