summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS1
-rw-r--r--plugins/check_dns.c61
-rw-r--r--plugins/t/check_dns.t12
3 files changed, 56 insertions, 18 deletions
diff --git a/NEWS b/NEWS
index 4061c033..3790e8a0 100644
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,7 @@ This file documents the major additions and syntax changes between releases.
13 check_dns: Accept CIDR 13 check_dns: Accept CIDR
14 check_dns: allow unsorted addresses 14 check_dns: allow unsorted addresses
15 check_dns: allow forcing complete match of all addresses 15 check_dns: allow forcing complete match of all addresses
16 check_dns: option to expect NXDOMAIN
16 check_apt: add --only-critical switch 17 check_apt: add --only-critical switch
17 check_apt: add -l/--list option to print packages 18 check_apt: add -l/--list option to print packages
18 check_file_age: add range checking 19 check_file_age: add range checking
diff --git a/plugins/check_dns.c b/plugins/check_dns.c
index 0f2e6541..0c10f09b 100644
--- a/plugins/check_dns.c
+++ b/plugins/check_dns.c
@@ -41,7 +41,7 @@ const char *email = "devel@monitoring-plugins.org";
41 41
42int process_arguments (int, char **); 42int process_arguments (int, char **);
43int validate_arguments (void); 43int validate_arguments (void);
44int error_scan (char *); 44int error_scan (char *, int*);
45int ip_match_cidr(const char *, const char *); 45int ip_match_cidr(const char *, const char *);
46unsigned long ip2long(const char *); 46unsigned long ip2long(const char *);
47void print_help (void); 47void print_help (void);
@@ -54,6 +54,7 @@ char ptr_server[ADDRESS_LENGTH] = "";
54int verbose = FALSE; 54int verbose = FALSE;
55char **expected_address = NULL; 55char **expected_address = NULL;
56int expected_address_cnt = 0; 56int expected_address_cnt = 0;
57int expect_nxdomain = FALSE;
57 58
58int expect_authority = FALSE; 59int expect_authority = FALSE;
59int all_match = FALSE; 60int all_match = FALSE;
@@ -87,6 +88,7 @@ main (int argc, char **argv)
87 int parse_address = FALSE; /* This flag scans for Address: but only after Name: */ 88 int parse_address = FALSE; /* This flag scans for Address: but only after Name: */
88 output chld_out, chld_err; 89 output chld_out, chld_err;
89 size_t i; 90 size_t i;
91 int is_nxdomain = FALSE;
90 92
91 setlocale (LC_ALL, ""); 93 setlocale (LC_ALL, "");
92 bindtextdomain (PACKAGE, LOCALEDIR); 94 bindtextdomain (PACKAGE, LOCALEDIR);
@@ -186,7 +188,7 @@ main (int argc, char **argv)
186 } 188 }
187 189
188 190
189 result = error_scan (chld_out.line[i]); 191 result = error_scan (chld_out.line[i], &is_nxdomain);
190 if (result != STATE_OK) { 192 if (result != STATE_OK) {
191 msg = strchr (chld_out.line[i], ':'); 193 msg = strchr (chld_out.line[i], ':');
192 if(msg) msg++; 194 if(msg) msg++;
@@ -199,8 +201,8 @@ main (int argc, char **argv)
199 if (verbose) 201 if (verbose)
200 puts(chld_err.line[i]); 202 puts(chld_err.line[i]);
201 203
202 if (error_scan (chld_err.line[i]) != STATE_OK) { 204 if (error_scan (chld_err.line[i], &is_nxdomain) != STATE_OK) {
203 result = max_state (result, error_scan (chld_err.line[i])); 205 result = max_state (result, error_scan (chld_err.line[i], &is_nxdomain));
204 msg = strchr(input_buffer, ':'); 206 msg = strchr(input_buffer, ':');
205 if(msg) 207 if(msg)
206 msg++; 208 msg++;
@@ -209,6 +211,10 @@ main (int argc, char **argv)
209 } 211 }
210 } 212 }
211 213
214 if (is_nxdomain && !expect_nxdomain) {
215 die (STATE_CRITICAL, _("Domain '%s' was not found by the server\n"), query_address);
216 }
217
212 if (addresses) { 218 if (addresses) {
213 int i,slen; 219 int i,slen;
214 char *adrp; 220 char *adrp;
@@ -260,6 +266,16 @@ main (int argc, char **argv)
260 } 266 }
261 } 267 }
262 268
269 if (expect_nxdomain) {
270 if (!is_nxdomain) {
271 result = STATE_CRITICAL;
272 xasprintf(&msg, _("Domain '%s' was found by the server: '%s'\n"), query_address, address);
273 } else {
274 if (address == NULL) free(address);
275 address = "NXDOMAIN";
276 }
277 }
278
263 /* check if authoritative */ 279 /* check if authoritative */
264 if (result == STATE_OK && expect_authority && non_authoritative) { 280 if (result == STATE_OK && expect_authority && non_authoritative) {
265 result = STATE_CRITICAL; 281 result = STATE_CRITICAL;
@@ -339,9 +355,15 @@ ip2long(const char* src) {
339} 355}
340 356
341int 357int
342error_scan (char *input_buffer) 358error_scan (char *input_buffer, int* is_nxdomain)
343{ 359{
344 360
361 const int nxdomain = strstr (input_buffer, "Non-existent") ||
362 strstr (input_buffer, "** server can't find") ||
363 strstr (input_buffer, "** Can't find") ||
364 strstr (input_buffer, "NXDOMAIN");
365 if (nxdomain) *is_nxdomain = TRUE;
366
345 /* the DNS lookup timed out */ 367 /* the DNS lookup timed out */
346 if (strstr (input_buffer, _("Note: nslookup is deprecated and may be removed from future releases.")) || 368 if (strstr (input_buffer, _("Note: nslookup is deprecated and may be removed from future releases.")) ||
347 strstr (input_buffer, _("Consider using the `dig' or `host' programs instead. Run nslookup with")) || 369 strstr (input_buffer, _("Consider using the `dig' or `host' programs instead. Run nslookup with")) ||
@@ -360,7 +382,7 @@ error_scan (char *input_buffer)
360 382
361 /* Connection was refused */ 383 /* Connection was refused */
362 else if (strstr (input_buffer, "Connection refused") || 384 else if (strstr (input_buffer, "Connection refused") ||
363 strstr (input_buffer, "Couldn't find server") || 385 strstr (input_buffer, "Couldn't find server") ||
364 strstr (input_buffer, "Refused") || 386 strstr (input_buffer, "Refused") ||
365 (strstr (input_buffer, "** server can't find") && 387 (strstr (input_buffer, "** server can't find") &&
366 strstr (input_buffer, ": REFUSED"))) 388 strstr (input_buffer, ": REFUSED")))
@@ -374,13 +396,6 @@ error_scan (char *input_buffer)
374 else if (strstr (input_buffer, "No information")) 396 else if (strstr (input_buffer, "No information"))
375 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);
376 398
377 /* Host or domain name does not exist */
378 else if (strstr (input_buffer, "Non-existent") ||
379 strstr (input_buffer, "** server can't find") ||
380 strstr (input_buffer, "** Can't find") ||
381 strstr (input_buffer,"NXDOMAIN"))
382 die (STATE_CRITICAL, _("Domain %s was not found by the server\n"), query_address);
383
384 /* Network is unreachable */ 399 /* Network is unreachable */
385 else if (strstr (input_buffer, "Network is unreachable")) 400 else if (strstr (input_buffer, "Network is unreachable"))
386 die (STATE_CRITICAL, _("Network is unreachable\n")); 401 die (STATE_CRITICAL, _("Network is unreachable\n"));
@@ -417,6 +432,7 @@ process_arguments (int argc, char **argv)
417 {"server", required_argument, 0, 's'}, 432 {"server", required_argument, 0, 's'},
418 {"reverse-server", required_argument, 0, 'r'}, 433 {"reverse-server", required_argument, 0, 'r'},
419 {"expected-address", required_argument, 0, 'a'}, 434 {"expected-address", required_argument, 0, 'a'},
435 {"expect-nxdomain", no_argument, 0, 'n'},
420 {"expect-authority", no_argument, 0, 'A'}, 436 {"expect-authority", no_argument, 0, 'A'},
421 {"all", no_argument, 0, 'L'}, 437 {"all", no_argument, 0, 'L'},
422 {"warning", required_argument, 0, 'w'}, 438 {"warning", required_argument, 0, 'w'},
@@ -432,7 +448,7 @@ process_arguments (int argc, char **argv)
432 strcpy (argv[c], "-t"); 448 strcpy (argv[c], "-t");
433 449
434 while (1) { 450 while (1) {
435 c = getopt_long (argc, argv, "hVvALt:H:s:r:a:w:c:", long_opts, &opt_index); 451 c = getopt_long (argc, argv, "hVvALnt:H:s:r:a:w:c:", long_opts, &opt_index);
436 452
437 if (c == -1 || c == EOF) 453 if (c == -1 || c == EOF)
438 break; 454 break;
@@ -491,6 +507,9 @@ process_arguments (int argc, char **argv)
491 expected_address_cnt++; 507 expected_address_cnt++;
492 } 508 }
493 break; 509 break;
510 case 'n': /* expect NXDOMAIN */
511 expect_nxdomain = TRUE;
512 break;
494 case 'A': /* expect authority */ 513 case 'A': /* expect authority */
495 expect_authority = TRUE; 514 expect_authority = TRUE;
496 break; 515 break;
@@ -532,8 +551,15 @@ process_arguments (int argc, char **argv)
532int 551int
533validate_arguments () 552validate_arguments ()
534{ 553{
535 if (query_address[0] == 0) 554 if (query_address[0] == 0) {
555 printf ("missing --host argument\n");
556 return ERROR;
557 }
558
559 if (expected_address_cnt > 0 && expect_nxdomain) {
560 printf ("--expected-address and --expect-nxdomain cannot be combined\n");
536 return ERROR; 561 return ERROR;
562 }
537 563
538 return OK; 564 return OK;
539} 565}
@@ -566,6 +592,9 @@ print_help (void)
566 printf (" %s\n", _("Optional IP-ADDRESS/CIDR you expect the DNS server to return. HOST must end")); 592 printf (" %s\n", _("Optional IP-ADDRESS/CIDR you expect the DNS server to return. HOST must end"));
567 printf (" %s\n", _("with a dot (.). This option can be repeated multiple times (Returns OK if any")); 593 printf (" %s\n", _("with a dot (.). This option can be repeated multiple times (Returns OK if any"));
568 printf (" %s\n", _("value matches).")); 594 printf (" %s\n", _("value matches)."));
595 printf (" -n, --expect-nxdomain\n");
596 printf (" %s\n", _("Expect the DNS server to return NXDOMAIN (i.e. the domain was not found)"));
597 printf (" %s\n", _("Cannot be used together with -a"));
569 printf (" -A, --expect-authority\n"); 598 printf (" -A, --expect-authority\n");
570 printf (" %s\n", _("Optionally expect the DNS server to be authoritative for the lookup")); 599 printf (" %s\n", _("Optionally expect the DNS server to be authoritative for the lookup"));
571 printf (" -w, --warning=seconds\n"); 600 printf (" -w, --warning=seconds\n");
@@ -586,5 +615,5 @@ void
586print_usage (void) 615print_usage (void)
587{ 616{
588 printf ("%s\n", _("Usage:")); 617 printf ("%s\n", _("Usage:"));
589 printf ("%s -H host [-s server] [-a expected-address] [-A] [-t timeout] [-w warn] [-c crit] [-L]\n", progname); 618 printf ("%s -H host [-s server] [-a expected-address] [-n] [-A] [-t timeout] [-w warn] [-c crit] [-L]\n", progname);
590} 619}
diff --git a/plugins/t/check_dns.t b/plugins/t/check_dns.t
index cdfbe60d..1e7d5340 100644
--- a/plugins/t/check_dns.t
+++ b/plugins/t/check_dns.t
@@ -10,7 +10,7 @@ use NPTest;
10 10
11plan skip_all => "check_dns not compiled" unless (-x "check_dns"); 11plan skip_all => "check_dns not compiled" unless (-x "check_dns");
12 12
13plan tests => 19; 13plan tests => 23;
14 14
15my $successOutput = '/DNS OK: [\.0-9]+ seconds? response time/'; 15my $successOutput = '/DNS OK: [\.0-9]+ seconds? response time/';
16 16
@@ -58,7 +58,7 @@ my $dns_server = getTestParameter(
58my $host_nonresponsive = getTestParameter( 58my $host_nonresponsive = getTestParameter(
59 "NP_HOST_NONRESPONSIVE", 59 "NP_HOST_NONRESPONSIVE",
60 "The hostname of system not responsive to network requests", 60 "The hostname of system not responsive to network requests",
61 "10.0.0.1", 61 "192.0.2.0",
62 ); 62 );
63 63
64my $res; 64my $res;
@@ -105,3 +105,11 @@ cmp_ok( $res->return_code, '==', 0, "Got expected address");
105$res = NPTest->testCmd("./check_dns -H $hostname_valid -a $hostname_invalid_cidr -t 5"); 105$res = NPTest->testCmd("./check_dns -H $hostname_valid -a $hostname_invalid_cidr -t 5");
106cmp_ok( $res->return_code, '==', 2, "Got wrong address"); 106cmp_ok( $res->return_code, '==', 2, "Got wrong address");
107like ( $res->output, "/^DNS CRITICAL.*expected '$hostname_invalid_cidr' but got '$hostname_valid_ip'".'$/', "Output OK"); 107like ( $res->output, "/^DNS CRITICAL.*expected '$hostname_invalid_cidr' but got '$hostname_valid_ip'".'$/', "Output OK");
108
109$res = NPTest->testCmd("./check_dns -H $hostname_valid -n");
110cmp_ok( $res->return_code, '==', 2, "Found $hostname_valid");
111like ( $res->output, "/^DNS CRITICAL.*Domain '$hostname_valid' was found by the server:/", "Output OK");
112
113$res = NPTest->testCmd("./check_dns -H $hostname_invalid -n");
114cmp_ok( $res->return_code, '==', 0, "Did not find $hostname_invalid");
115like ( $res->output, $successOutput, "Output OK" );