diff options
Diffstat (limited to 'plugins/check_dns.c')
-rw-r--r-- | plugins/check_dns.c | 119 |
1 files changed, 48 insertions, 71 deletions
diff --git a/plugins/check_dns.c b/plugins/check_dns.c index 94d4300c..d6e8ca29 100644 --- a/plugins/check_dns.c +++ b/plugins/check_dns.c | |||
@@ -27,9 +27,9 @@ const char *copyright = "2000-2004"; | |||
27 | const char *email = "nagiosplug-devel@lists.sourceforge.net"; | 27 | const char *email = "nagiosplug-devel@lists.sourceforge.net"; |
28 | 28 | ||
29 | #include "common.h" | 29 | #include "common.h" |
30 | #include "popen.h" | ||
31 | #include "utils.h" | 30 | #include "utils.h" |
32 | #include "netutils.h" | 31 | #include "netutils.h" |
32 | #include "runcmd.h" | ||
33 | 33 | ||
34 | int process_arguments (int, char **); | 34 | int process_arguments (int, char **); |
35 | int validate_arguments (void); | 35 | int validate_arguments (void); |
@@ -51,8 +51,8 @@ main (int argc, char **argv) | |||
51 | { | 51 | { |
52 | char *command_line = NULL; | 52 | char *command_line = NULL; |
53 | char input_buffer[MAX_INPUT_BUFFER]; | 53 | char input_buffer[MAX_INPUT_BUFFER]; |
54 | char *output = NULL; | ||
55 | char *address = NULL; | 54 | char *address = NULL; |
55 | char *msg = NULL; | ||
56 | char *temp_buffer = NULL; | 56 | char *temp_buffer = NULL; |
57 | int non_authoritative = FALSE; | 57 | int non_authoritative = FALSE; |
58 | int result = STATE_UNKNOWN; | 58 | int result = STATE_UNKNOWN; |
@@ -61,6 +61,8 @@ main (int argc, char **argv) | |||
61 | struct timeval tv; | 61 | struct timeval tv; |
62 | int multi_address; | 62 | int multi_address; |
63 | int parse_address = FALSE; /* This flag scans for Address: but only after Name: */ | 63 | int parse_address = FALSE; /* This flag scans for Address: but only after Name: */ |
64 | output chld_out, chld_err; | ||
65 | size_t i; | ||
64 | 66 | ||
65 | setlocale (LC_ALL, ""); | 67 | setlocale (LC_ALL, ""); |
66 | bindtextdomain (PACKAGE, LOCALEDIR); | 68 | bindtextdomain (PACKAGE, LOCALEDIR); |
@@ -68,11 +70,11 @@ main (int argc, char **argv) | |||
68 | 70 | ||
69 | /* Set signal handling and alarm */ | 71 | /* Set signal handling and alarm */ |
70 | if (signal (SIGALRM, popen_timeout_alarm_handler) == SIG_ERR) { | 72 | if (signal (SIGALRM, popen_timeout_alarm_handler) == SIG_ERR) { |
71 | usage4 (_("Cannot catch SIGALRM")); | 73 | usage_va(_("Cannot catch SIGALRM")); |
72 | } | 74 | } |
73 | 75 | ||
74 | if (process_arguments (argc, argv) == ERROR) { | 76 | if (process_arguments (argc, argv) == ERROR) { |
75 | usage4 (_("Could not parse arguments")); | 77 | usage_va(_("Could not parse arguments")); |
76 | } | 78 | } |
77 | 79 | ||
78 | /* get the command to run */ | 80 | /* get the command to run */ |
@@ -85,37 +87,31 @@ main (int argc, char **argv) | |||
85 | printf ("%s\n", command_line); | 87 | printf ("%s\n", command_line); |
86 | 88 | ||
87 | /* run the command */ | 89 | /* run the command */ |
88 | child_process = spopen (command_line); | 90 | if((np_runcmd(command_line, &chld_out, &chld_err, 0)) != 0) { |
89 | if (child_process == NULL) { | 91 | msg = (char *)_("nslookup returned error status"); |
90 | printf (_("Could not open pipe: %s\n"), command_line); | 92 | result = STATE_WARNING; |
91 | return STATE_UNKNOWN; | ||
92 | } | 93 | } |
93 | 94 | ||
94 | child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); | ||
95 | if (child_stderr == NULL) | ||
96 | printf (_("Could not open stderr for %s\n"), command_line); | ||
97 | |||
98 | /* scan stdout */ | 95 | /* scan stdout */ |
99 | while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { | 96 | for(i = 0; i < chld_out.lines; i++) { |
100 | |||
101 | if (verbose) | 97 | if (verbose) |
102 | printf ("%s", input_buffer); | 98 | puts(chld_out.line[i]); |
103 | 99 | ||
104 | if (strstr (input_buffer, ".in-addr.arpa")) { | 100 | if (strstr (chld_out.line[i], ".in-addr.arpa")) { |
105 | if ((temp_buffer = strstr (input_buffer, "name = "))) | 101 | if ((temp_buffer = strstr (chld_out.line[i], "name = "))) |
106 | address = strdup (temp_buffer + 7); | 102 | address = strdup (temp_buffer + 7); |
107 | else { | 103 | else { |
108 | output = strdup (_("Warning plugin error")); | 104 | msg = (char *)_("Warning plugin error"); |
109 | result = STATE_WARNING; | 105 | result = STATE_WARNING; |
110 | } | 106 | } |
111 | } | 107 | } |
112 | 108 | ||
113 | /* the server is responding, we just got the host name... */ | 109 | /* the server is responding, we just got the host name... */ |
114 | if (strstr (input_buffer, "Name:")) | 110 | if (strstr (chld_out.line[i], "Name:")) |
115 | parse_address = TRUE; | 111 | parse_address = TRUE; |
116 | else if (parse_address == TRUE && (strstr (input_buffer, "Address:") || | 112 | else if (parse_address == TRUE && (strstr (chld_out.line[i], "Address:") || |
117 | strstr (input_buffer, "Addresses:"))) { | 113 | strstr (chld_out.line[i], "Addresses:"))) { |
118 | temp_buffer = index (input_buffer, ':'); | 114 | temp_buffer = index (chld_out.line[i], ':'); |
119 | temp_buffer++; | 115 | temp_buffer++; |
120 | 116 | ||
121 | /* Strip leading spaces */ | 117 | /* Strip leading spaces */ |
@@ -135,59 +131,47 @@ main (int argc, char **argv) | |||
135 | asprintf(&address, "%s,%s", address, temp_buffer); | 131 | asprintf(&address, "%s,%s", address, temp_buffer); |
136 | } | 132 | } |
137 | 133 | ||
138 | else if (strstr (input_buffer, _("Non-authoritative answer:"))) { | 134 | else if (strstr (chld_out.line[i], _("Non-authoritative answer:"))) { |
139 | non_authoritative = TRUE; | 135 | non_authoritative = TRUE; |
140 | } | 136 | } |
141 | 137 | ||
142 | result = error_scan (input_buffer); | 138 | result = error_scan (chld_out.line[i]); |
143 | if (result != STATE_OK) { | 139 | if (result != STATE_OK) { |
144 | output = strdup (1 + index (input_buffer, ':')); | 140 | msg = strchr (chld_out.line[i], ':'); |
145 | strip (output); | 141 | if(msg) msg++; |
146 | break; | 142 | break; |
147 | } | 143 | } |
148 | |||
149 | } | 144 | } |
150 | 145 | ||
151 | /* scan stderr */ | 146 | /* scan stderr */ |
152 | while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) { | 147 | for(i = 0; i < chld_err.lines; i++) { |
153 | |||
154 | if (verbose) | 148 | if (verbose) |
155 | printf ("%s", input_buffer); | 149 | puts(chld_err.line[i]); |
156 | 150 | ||
157 | if (error_scan (input_buffer) != STATE_OK) { | 151 | if (error_scan (chld_err.line[i]) != STATE_OK) { |
158 | result = max_state (result, error_scan (input_buffer)); | 152 | result = max_state (result, error_scan (chld_err.line[i])); |
159 | output = strdup (1 + index (input_buffer, ':')); | 153 | msg = strchr(input_buffer, ':'); |
160 | strip (output); | 154 | if(msg) msg++; |
161 | } | 155 | } |
162 | } | 156 | } |
163 | 157 | ||
164 | /* close stderr */ | 158 | /* If we got here, we should have an address string, |
165 | (void) fclose (child_stderr); | 159 | * and we can segfault if we do not */ |
166 | |||
167 | /* close stdout */ | ||
168 | if (spclose (child_process)) { | ||
169 | result = max_state (result, STATE_WARNING); | ||
170 | if (output == NULL || !strcmp (output, "")) | ||
171 | output = strdup (_("nslookup returned error status")); | ||
172 | } | ||
173 | |||
174 | /* If we got here, we should have an address string, | ||
175 | and we can segfault if we do not */ | ||
176 | if (address==NULL || strlen(address)==0) | 160 | if (address==NULL || strlen(address)==0) |
177 | die (STATE_CRITICAL, | 161 | die (STATE_CRITICAL, |
178 | _("DNS CRITICAL - '%s' output parsing exited with no address\n"), | 162 | _("DNS CRITICAL - '%s' msg parsing exited with no address\n"), |
179 | NSLOOKUP_COMMAND); | 163 | NSLOOKUP_COMMAND); |
180 | 164 | ||
181 | /* compare to expected address */ | 165 | /* compare to expected address */ |
182 | if (result == STATE_OK && match_expected_address && strcmp(address, expected_address)) { | 166 | if (result == STATE_OK && match_expected_address && strcmp(address, expected_address)) { |
183 | result = STATE_CRITICAL; | 167 | result = STATE_CRITICAL; |
184 | asprintf(&output, _("expected %s but got %s"), expected_address, address); | 168 | asprintf(&msg, _("expected %s but got %s"), expected_address, address); |
185 | } | 169 | } |
186 | 170 | ||
187 | /* check if authoritative */ | 171 | /* check if authoritative */ |
188 | if (result == STATE_OK && expect_authority && non_authoritative) { | 172 | if (result == STATE_OK && expect_authority && non_authoritative) { |
189 | result = STATE_CRITICAL; | 173 | result = STATE_CRITICAL; |
190 | asprintf(&output, _("server %s is not authoritative for %s"), dns_server, query_address); | 174 | asprintf(&msg, _("server %s is not authoritative for %s"), dns_server, query_address); |
191 | } | 175 | } |
192 | 176 | ||
193 | microsec = deltime (tv); | 177 | microsec = deltime (tv); |
@@ -200,19 +184,19 @@ main (int argc, char **argv) | |||
200 | multi_address = TRUE; | 184 | multi_address = TRUE; |
201 | 185 | ||
202 | printf ("DNS %s: ", _("OK")); | 186 | printf ("DNS %s: ", _("OK")); |
203 | printf (ngettext("%.3f second response time ", "%.3f seconds response time ", elapsed_time), elapsed_time); | 187 | printf (ngettext("%.3f second response time", "%.3f seconds response time", elapsed_time), elapsed_time); |
204 | printf (_("%s returns %s"), query_address, address); | 188 | printf (_(". %s returns %s"), query_address, address); |
205 | printf ("|%s\n", fperfdata ("time", elapsed_time, "s", FALSE, 0, FALSE, 0, TRUE, 0, FALSE, 0)); | 189 | printf ("|%s\n", fperfdata ("time", elapsed_time, "s", FALSE, 0, FALSE, 0, TRUE, 0, FALSE, 0)); |
206 | } | 190 | } |
207 | else if (result == STATE_WARNING) | 191 | else if (result == STATE_WARNING) |
208 | printf (_("DNS WARNING - %s\n"), | 192 | printf (_("DNS WARNING - %s\n"), |
209 | !strcmp (output, "") ? _(" Probably a non-existent host/domain") : output); | 193 | !strcmp (msg, "") ? _(" Probably a non-existent host/domain") : msg); |
210 | else if (result == STATE_CRITICAL) | 194 | else if (result == STATE_CRITICAL) |
211 | printf (_("DNS CRITICAL - %s\n"), | 195 | printf (_("DNS CRITICAL - %s\n"), |
212 | !strcmp (output, "") ? _(" Probably a non-existent host/domain") : output); | 196 | !strcmp (msg, "") ? _(" Probably a non-existent host/domain") : msg); |
213 | else | 197 | else |
214 | printf (_("DNS UNKNOW - %s\n"), | 198 | printf (_("DNS UNKNOW - %s\n"), |
215 | !strcmp (output, "") ? _(" Probably a non-existent host/domain") : output); | 199 | !strcmp (msg, "") ? _(" Probably a non-existent host/domain") : msg); |
216 | 200 | ||
217 | return result; | 201 | return result; |
218 | } | 202 | } |
@@ -311,8 +295,6 @@ process_arguments (int argc, char **argv) | |||
311 | break; | 295 | break; |
312 | 296 | ||
313 | switch (c) { | 297 | switch (c) { |
314 | case '?': /* args not parsable */ | ||
315 | usage2 (_("Unknown argument"), optarg); | ||
316 | case 'h': /* help */ | 298 | case 'h': /* help */ |
317 | print_help (); | 299 | print_help (); |
318 | exit (STATE_OK); | 300 | exit (STATE_OK); |
@@ -331,20 +313,16 @@ process_arguments (int argc, char **argv) | |||
331 | strcpy (query_address, optarg); | 313 | strcpy (query_address, optarg); |
332 | break; | 314 | break; |
333 | case 's': /* server name */ | 315 | case 's': /* server name */ |
334 | /* TODO: this is_host check is probably unnecessary. */ | 316 | /* TODO: this host_or_die check is probably unnecessary. |
335 | /* Better to confirm nslookup response matches */ | 317 | * Better to confirm nslookup response matches */ |
336 | if (is_host (optarg) == FALSE) { | 318 | host_or_die(optarg); |
337 | usage2 (_("Invalid hostname/address"), optarg); | ||
338 | } | ||
339 | if (strlen (optarg) >= ADDRESS_LENGTH) | 319 | if (strlen (optarg) >= ADDRESS_LENGTH) |
340 | die (STATE_UNKNOWN, _("Input buffer overflow\n")); | 320 | die (STATE_UNKNOWN, _("Input buffer overflow\n")); |
341 | strcpy (dns_server, optarg); | 321 | strcpy (dns_server, optarg); |
342 | break; | 322 | break; |
343 | case 'r': /* reverse server name */ | 323 | case 'r': /* reverse server name */ |
344 | /* TODO: Is this is_host necessary? */ | 324 | /* TODO: Is this host_or_die necessary? */ |
345 | if (is_host (optarg) == FALSE) { | 325 | host_or_die(optarg); |
346 | usage2 (_("Invalid hostname/address"), optarg); | ||
347 | } | ||
348 | if (strlen (optarg) >= ADDRESS_LENGTH) | 326 | if (strlen (optarg) >= ADDRESS_LENGTH) |
349 | die (STATE_UNKNOWN, _("Input buffer overflow\n")); | 327 | die (STATE_UNKNOWN, _("Input buffer overflow\n")); |
350 | strcpy (ptr_server, optarg); | 328 | strcpy (ptr_server, optarg); |
@@ -358,6 +336,8 @@ process_arguments (int argc, char **argv) | |||
358 | case 'A': /* expect authority */ | 336 | case 'A': /* expect authority */ |
359 | expect_authority = TRUE; | 337 | expect_authority = TRUE; |
360 | break; | 338 | break; |
339 | default: /* args not parsable */ | ||
340 | usage_va(_("Unknown argument - %s"), optarg); | ||
361 | } | 341 | } |
362 | } | 342 | } |
363 | 343 | ||
@@ -370,10 +350,7 @@ process_arguments (int argc, char **argv) | |||
370 | 350 | ||
371 | if (strlen(dns_server)==0 && c<argc) { | 351 | if (strlen(dns_server)==0 && c<argc) { |
372 | /* TODO: See -s option */ | 352 | /* TODO: See -s option */ |
373 | if (is_host(argv[c]) == FALSE) { | 353 | host_or_die(argv[c]); |
374 | printf (_("Invalid hostname/address: %s\n\n"), argv[c]); | ||
375 | return ERROR; | ||
376 | } | ||
377 | if (strlen(argv[c]) >= ADDRESS_LENGTH) | 354 | if (strlen(argv[c]) >= ADDRESS_LENGTH) |
378 | die (STATE_UNKNOWN, _("Input buffer overflow\n")); | 355 | die (STATE_UNKNOWN, _("Input buffer overflow\n")); |
379 | strcpy (dns_server, argv[c++]); | 356 | strcpy (dns_server, argv[c++]); |
@@ -388,8 +365,8 @@ validate_arguments () | |||
388 | { | 365 | { |
389 | if (query_address[0] == 0) | 366 | if (query_address[0] == 0) |
390 | return ERROR; | 367 | return ERROR; |
391 | else | 368 | |
392 | return OK; | 369 | return OK; |
393 | } | 370 | } |
394 | 371 | ||
395 | 372 | ||