diff options
Diffstat (limited to 'plugins/check_dns.c')
-rw-r--r-- | plugins/check_dns.c | 44 |
1 files changed, 38 insertions, 6 deletions
diff --git a/plugins/check_dns.c b/plugins/check_dns.c index 54ce7d1..5feafc8 100644 --- a/plugins/check_dns.c +++ b/plugins/check_dns.c | |||
@@ -42,6 +42,8 @@ const char *email = "devel@monitoring-plugins.org"; | |||
42 | int process_arguments (int, char **); | 42 | int process_arguments (int, char **); |
43 | int validate_arguments (void); | 43 | int validate_arguments (void); |
44 | int error_scan (char *); | 44 | int error_scan (char *); |
45 | int ip_match_cidr(const char *, const char *); | ||
46 | unsigned long ip2long(const char *); | ||
45 | void print_help (void); | 47 | void print_help (void); |
46 | void print_usage (void); | 48 | void print_usage (void); |
47 | 49 | ||
@@ -126,7 +128,7 @@ main (int argc, char **argv) | |||
126 | if (verbose) | 128 | if (verbose) |
127 | puts(chld_out.line[i]); | 129 | puts(chld_out.line[i]); |
128 | 130 | ||
129 | if (strcasestr (chld_out.line[i], ".in-addr.arpa")) { | 131 | 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 = "))) | 132 | if ((temp_buffer = strstr (chld_out.line[i], "name = "))) |
131 | addresses[n_addresses++] = strdup (temp_buffer + 7); | 133 | addresses[n_addresses++] = strdup (temp_buffer + 7); |
132 | else { | 134 | else { |
@@ -226,9 +228,14 @@ main (int argc, char **argv) | |||
226 | if (result == STATE_OK && expected_address_cnt > 0) { | 228 | if (result == STATE_OK && expected_address_cnt > 0) { |
227 | result = STATE_CRITICAL; | 229 | result = STATE_CRITICAL; |
228 | temp_buffer = ""; | 230 | temp_buffer = ""; |
231 | |||
229 | for (i=0; i<expected_address_cnt; i++) { | 232 | for (i=0; i<expected_address_cnt; i++) { |
230 | /* check if we get a match and prepare an error string */ | 233 | /* check if we get a match on 'raw' ip or cidr */ |
231 | if (strcmp(address, expected_address[i]) == 0) result = STATE_OK; | 234 | if ( strcmp(address, expected_address[i]) == 0 |
235 | || ip_match_cidr(address, expected_address[i]) ) | ||
236 | result = STATE_OK; | ||
237 | |||
238 | /* prepare an error string */ | ||
232 | xasprintf(&temp_buffer, "%s%s; ", temp_buffer, expected_address[i]); | 239 | xasprintf(&temp_buffer, "%s%s; ", temp_buffer, expected_address[i]); |
233 | } | 240 | } |
234 | if (result == STATE_CRITICAL) { | 241 | if (result == STATE_CRITICAL) { |
@@ -289,7 +296,32 @@ main (int argc, char **argv) | |||
289 | return result; | 296 | return result; |
290 | } | 297 | } |
291 | 298 | ||
299 | int | ||
300 | ip_match_cidr(const char *addr, const char *cidr_ro) | ||
301 | { | ||
302 | char *subnet, *mask_c, *cidr = strdup(cidr_ro); | ||
303 | int mask; | ||
304 | subnet = strtok(cidr, "/"); | ||
305 | mask_c = strtok(NULL, "\0"); | ||
306 | if (!subnet || !mask_c) | ||
307 | return FALSE; | ||
308 | mask = atoi(mask_c); | ||
309 | |||
310 | /* https://www.cryptobells.com/verifying-ips-in-a-subnet-in-php/ */ | ||
311 | return (ip2long(addr) & ~((1 << (32 - mask)) - 1)) == (ip2long(subnet) >> (32 - mask)) << (32 - mask); | ||
312 | } | ||
292 | 313 | ||
314 | unsigned long | ||
315 | ip2long(const char* src) { | ||
316 | unsigned long ip[4]; | ||
317 | /* http://computer-programming-forum.com/47-c-language/1376ffb92a12c471.htm */ | ||
318 | return (sscanf(src, "%3lu.%3lu.%3lu.%3lu", | ||
319 | &ip[0], &ip[1], &ip[2], &ip[3]) == 4 && | ||
320 | ip[0] < 256 && ip[1] < 256 && | ||
321 | ip[2] < 256 && ip[3] < 256) | ||
322 | ? ip[0] << 24 | ip[1] << 16 | ip[2] << 8 | ip[3] | ||
323 | : 0; | ||
324 | } | ||
293 | 325 | ||
294 | int | 326 | int |
295 | error_scan (char *input_buffer) | 327 | error_scan (char *input_buffer) |
@@ -494,9 +526,9 @@ print_help (void) | |||
494 | printf (" %s\n", _("The name or address you want to query")); | 526 | printf (" %s\n", _("The name or address you want to query")); |
495 | printf (" -s, --server=HOST\n"); | 527 | printf (" -s, --server=HOST\n"); |
496 | printf (" %s\n", _("Optional DNS server you want to use for the lookup")); | 528 | printf (" %s\n", _("Optional DNS server you want to use for the lookup")); |
497 | printf (" -a, --expected-address=IP-ADDRESS|HOST\n"); | 529 | printf (" -a, --expected-address=IP-ADDRESS|CIDR|HOST\n"); |
498 | printf (" %s\n", _("Optional IP-ADDRESS you expect the DNS server to return. HOST must end with")); | 530 | printf (" %s\n", _("Optional IP-ADDRESS/CIDR you expect the DNS server to return. HOST must end")); |
499 | printf (" %s\n", _("a dot (.). This option can be repeated multiple times (Returns OK if any")); | 531 | printf (" %s\n", _("with a dot (.). This option can be repeated multiple times (Returns OK if any")); |
500 | printf (" %s\n", _("value match). If multiple addresses are returned at once, you have to match")); | 532 | printf (" %s\n", _("value match). If multiple addresses are returned at once, you have to match")); |
501 | printf (" %s\n", _("the whole string of addresses separated with commas (sorted alphabetically).")); | 533 | printf (" %s\n", _("the whole string of addresses separated with commas (sorted alphabetically).")); |
502 | printf (" -A, --expect-authority\n"); | 534 | printf (" -A, --expect-authority\n"); |