diff options
Diffstat (limited to 'web/attachments/36739-check_dns.diff')
-rw-r--r-- | web/attachments/36739-check_dns.diff | 913 |
1 files changed, 913 insertions, 0 deletions
diff --git a/web/attachments/36739-check_dns.diff b/web/attachments/36739-check_dns.diff new file mode 100644 index 0000000..c0eb4c6 --- /dev/null +++ b/web/attachments/36739-check_dns.diff | |||
@@ -0,0 +1,913 @@ | |||
1 | --- check_dns_resolver/check_dns_resolver.c Mon Nov 25 18:01:26 2002 | ||
2 | +++ TarZip/nagiosplug-1.3-beta1/plugins/check_dns.c Thu Feb 28 01:42:57 2002 | ||
3 | @@ -1,508 +1,415 @@ | ||
4 | -/* | ||
5 | - * check_dns_resolver is a version of check_dns (for nagios) that | ||
6 | - * talks to the nameservers without using nslookup | ||
7 | - * | ||
8 | - * Author: Roy Marantz (marantz@nbcs.rutgers.edu) | ||
9 | - * no copyrite - do what you want with this. | ||
10 | - * | ||
11 | - * $Id: check_dns_resolver.c,v 1.1.1.1 2002/11/25 23:01:26 marantz Exp $ | ||
12 | - * | ||
13 | - * solaris build instructions | ||
14 | - * cc -o check_dns_resolver check_dns_resolver.c -lresolv -lsocket -lnsl | ||
15 | - * | ||
16 | - */ | ||
17 | - | ||
18 | -#include <stdio.h> | ||
19 | -#include <signal.h> | ||
20 | -#include <sys/types.h> | ||
21 | -#include <netinet/in.h> | ||
22 | -#include <arpa/nameser.h> | ||
23 | -#include <resolv.h> | ||
24 | -#include <netdb.h> | ||
25 | -#include <arpa/inet.h> | ||
26 | -#include <time.h> | ||
27 | -#include <sys/socket.h> | ||
28 | -#include <strings.h> | ||
29 | -#include <stdlib.h> | ||
30 | - | ||
31 | -#define MAXPACKET 8192 /* BIND maximum packet size */ | ||
32 | - | ||
33 | -void catch_alarm(int ignored) { | ||
34 | - printf("query timed out\n"); | ||
35 | - exit(2); | ||
36 | +/****************************************************************************** | ||
37 | + * | ||
38 | + * CHECK_DNS.C | ||
39 | + * | ||
40 | + * Program: DNS plugin for Nagios | ||
41 | + * License: GPL | ||
42 | + * Copyright (c) 1999 Ethan Galstad (nagios@nagios.org) | ||
43 | + * | ||
44 | + * Last Modified: $Date: 2002/02/28 06:42:57 $ | ||
45 | + * | ||
46 | + * Notes: | ||
47 | + * - Safe popen added by Karl DeBisschop 9-11-99 | ||
48 | + * | ||
49 | + * Command line: CHECK_DNS <query_address> [dns_server] | ||
50 | + * | ||
51 | + * Description: | ||
52 | + * | ||
53 | + * This program will use the nslookup program to obtain the IP address | ||
54 | + * for a given host name. A optional DNS server may be specified. If | ||
55 | + * no DNS server is specified, the default server(s) for the system | ||
56 | + * are used. | ||
57 | + * | ||
58 | + * Return Values: | ||
59 | + * OK The DNS query was successful (host IP address was returned). | ||
60 | + * WARNING The DNS server responded, but could not fulfill the request. | ||
61 | + * CRITICAL The DNS server is not responding or encountered an error. | ||
62 | + * | ||
63 | + * License Information: | ||
64 | + * | ||
65 | + * This program is free software; you can redistribute it and/or modify | ||
66 | + * it under the terms of the GNU General Public License as published by | ||
67 | + * the Free Software Foundation; either version 2 of the License, or | ||
68 | + * (at your option) any later version. | ||
69 | + * | ||
70 | + * This program is distributed in the hope that it will be useful, | ||
71 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
72 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
73 | + * GNU General Public License for more details. | ||
74 | + * | ||
75 | + * You should have received a copy of the GNU General Public License | ||
76 | + * along with this program; if not, write to the Free Software | ||
77 | + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
78 | + * | ||
79 | + *****************************************************************************/ | ||
80 | + | ||
81 | +#include "common.h" | ||
82 | +#include "popen.h" | ||
83 | +#include "utils.h" | ||
84 | + | ||
85 | +int process_arguments (int, char **); | ||
86 | +int call_getopt (int, char **); | ||
87 | +int validate_arguments (void); | ||
88 | +void print_usage (char *); | ||
89 | +void print_help (char *); | ||
90 | +int error_scan (char *); | ||
91 | + | ||
92 | +#define ADDRESS_LENGTH 256 | ||
93 | +char query_address[ADDRESS_LENGTH] = ""; | ||
94 | +char dns_server[ADDRESS_LENGTH] = ""; | ||
95 | +char ptr_server[ADDRESS_LENGTH] = ""; | ||
96 | +int verbose = FALSE; | ||
97 | + | ||
98 | +int | ||
99 | +main (int argc, char **argv) | ||
100 | +{ | ||
101 | + char *command_line = NULL; | ||
102 | + char input_buffer[MAX_INPUT_BUFFER]; | ||
103 | + char *output = NULL; | ||
104 | + char *address = NULL; | ||
105 | + char *temp_buffer = NULL; | ||
106 | + int result = STATE_UNKNOWN; | ||
107 | + | ||
108 | + /* Set signal handling and alarm */ | ||
109 | + if (signal (SIGALRM, popen_timeout_alarm_handler) == SIG_ERR) { | ||
110 | + printf ("Cannot catch SIGALRM"); | ||
111 | + return STATE_UNKNOWN; | ||
112 | + } | ||
113 | + | ||
114 | + if (process_arguments (argc, argv) != OK) { | ||
115 | + print_usage (my_basename (argv[0])); | ||
116 | + return STATE_UNKNOWN; | ||
117 | + } | ||
118 | + | ||
119 | + /* get the command to run */ | ||
120 | + command_line = ssprintf (command_line, "%s %s %s", NSLOOKUP_COMMAND, | ||
121 | + query_address, dns_server); | ||
122 | + | ||
123 | + alarm (timeout_interval); | ||
124 | + time (&start_time); | ||
125 | + | ||
126 | + if (verbose) | ||
127 | + printf ("%s\n", command_line); | ||
128 | + /* run the command */ | ||
129 | + child_process = spopen (command_line); | ||
130 | + if (child_process == NULL) { | ||
131 | + printf ("Could not open pipe: %s\n", command_line); | ||
132 | + return STATE_UNKNOWN; | ||
133 | + } | ||
134 | + | ||
135 | + child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r"); | ||
136 | + if (child_stderr == NULL) | ||
137 | + printf ("Could not open stderr for %s\n", command_line); | ||
138 | + | ||
139 | + /* scan stdout */ | ||
140 | + while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) { | ||
141 | + | ||
142 | + if (verbose) | ||
143 | + printf ("%s\n", input_buffer); | ||
144 | + | ||
145 | + if (strstr (input_buffer, ".in-addr.arpa")) { | ||
146 | + if ((temp_buffer = strstr (input_buffer, "name = "))) | ||
147 | + address = strscpy (address, temp_buffer + 7); | ||
148 | + else { | ||
149 | + output = strscpy (output, "Unknown error (plugin)"); | ||
150 | + result = STATE_WARNING; | ||
151 | + } | ||
152 | + } | ||
153 | + | ||
154 | + /* the server is responding, we just got the host name... */ | ||
155 | + if (strstr (input_buffer, "Name:")) { | ||
156 | + | ||
157 | + /* get the host address */ | ||
158 | + if (!fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) | ||
159 | + break; | ||
160 | + | ||
161 | + if (verbose) | ||
162 | + printf ("%s\n", input_buffer); | ||
163 | + | ||
164 | + if ((temp_buffer = index (input_buffer, ':'))) { | ||
165 | + address = strscpy (address, temp_buffer + 2); | ||
166 | + strip (address); | ||
167 | + result = STATE_OK; | ||
168 | + } | ||
169 | + else { | ||
170 | + output = strscpy (output, "Unknown error (plugin)"); | ||
171 | + result = STATE_WARNING; | ||
172 | + } | ||
173 | + | ||
174 | + break; | ||
175 | + } | ||
176 | + | ||
177 | + result = error_scan (input_buffer); | ||
178 | + if (result != STATE_OK) { | ||
179 | + output = strscpy (output, 1 + index (input_buffer, ':')); | ||
180 | + break; | ||
181 | + } | ||
182 | + | ||
183 | + } | ||
184 | + | ||
185 | + /* scan stderr */ | ||
186 | + while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) { | ||
187 | + if (error_scan (input_buffer) != STATE_OK) { | ||
188 | + result = max (result, error_scan (input_buffer)); | ||
189 | + output = strscpy (output, 1 + index (input_buffer, ':')); | ||
190 | + } | ||
191 | + } | ||
192 | + | ||
193 | + /* close stderr */ | ||
194 | + (void) fclose (child_stderr); | ||
195 | + | ||
196 | + /* close stdout */ | ||
197 | + if (spclose (child_process)) { | ||
198 | + result = max (result, STATE_WARNING); | ||
199 | + if (!strcmp (output, "")) | ||
200 | + output = strscpy (output, "nslookup returned error status"); | ||
201 | + } | ||
202 | + | ||
203 | + (void) time (&end_time); | ||
204 | + | ||
205 | + if (result == STATE_OK) | ||
206 | + printf ("DNS ok - %d seconds response time, Address(es) is/are %s\n", | ||
207 | + (int) (end_time - start_time), address); | ||
208 | + else if (result == STATE_WARNING) | ||
209 | + printf ("DNS WARNING - %s\n", | ||
210 | + !strcmp (output, "") ? " Probably a non-existent host/domain" : output); | ||
211 | + else if (result == STATE_CRITICAL) | ||
212 | + printf ("DNS CRITICAL - %s\n", | ||
213 | + !strcmp (output, "") ? " Probably a non-existent host/domain" : output); | ||
214 | + else | ||
215 | + printf ("DNS problem - %s\n", | ||
216 | + !strcmp (output, "") ? " Probably a non-existent host/domain" : output); | ||
217 | + | ||
218 | + return result; | ||
219 | } | ||
220 | |||
221 | -typedef union { | ||
222 | - HEADER hdr; | ||
223 | - u_char buf[MAXPACKET]; | ||
224 | -} querybuf; | ||
225 | - | ||
226 | -static struct hostent * | ||
227 | -getanswer(const querybuf *answer, | ||
228 | - int anslen, | ||
229 | - const char *qname, | ||
230 | - int qtype); | ||
231 | - | ||
232 | -int debugging = 0; | ||
233 | - | ||
234 | -int main (int argc, char **argv) { | ||
235 | - int n; | ||
236 | - time_t start_time, end_time; | ||
237 | - querybuf answer; | ||
238 | - struct hostent *hentry; | ||
239 | - register char **h; | ||
240 | - | ||
241 | - int norecurse = 0; | ||
242 | - int timeout = 30; | ||
243 | - char *host = NULL; | ||
244 | - char *server = NULL; | ||
245 | - | ||
246 | -/* if (process_arguments (argc, argv) != OK) { | ||
247 | - print_usage (my_basename (argv[0])); | ||
248 | - exit(1); | ||
249 | - } | ||
250 | -*/ | ||
251 | - | ||
252 | - { | ||
253 | - int c; | ||
254 | - int errflg = 0; | ||
255 | - int showversion = 0; | ||
256 | - char *pgm = argv[0]; | ||
257 | - extern char *optarg; | ||
258 | - extern int optind; | ||
259 | - | ||
260 | - while ((c = getopt(argc, argv, "dhrt:s:H:V")) != EOF) | ||
261 | - switch (c) { | ||
262 | - case 't': timeout = atoi(optarg); break; | ||
263 | - case 's': server = optarg; break; | ||
264 | - case 'H': host = optarg; break; | ||
265 | - case 'r': norecurse = 1; break; | ||
266 | - case 'd': debugging++; break; | ||
267 | - case 'V': showversion++; break; | ||
268 | - case 'h': | ||
269 | - case '?': errflg++; | ||
270 | - } | ||
271 | - if (host == NULL || errflg || optind != argc) { | ||
272 | - fprintf(stderr, "usage: %s %s\n%s %d\n%s\n%s\n%s\n%s\n%s\n", | ||
273 | - pgm, | ||
274 | - "[-d] [-V] [-r] [-t timeout] [-s server] -H host", | ||
275 | - "where: timeout is time (in seconds) to wait for dns server, default", | ||
276 | - timeout, | ||
277 | - " host is the fully qualified hostname to ask address of", | ||
278 | - " server is the IP address or hostname of the nameserver to ask, default from /etc/resolv.conf", | ||
279 | - " -r turns off recursive resolver lookups", | ||
280 | - " -d turns on resolver debugging", | ||
281 | - " -V prints program version" | ||
282 | - ); | ||
283 | - exit (2); | ||
284 | - } | ||
285 | - if (showversion) { | ||
286 | - printf("%s version $Revision: 1.1.1.1 $\n", pgm); | ||
287 | - exit(0); | ||
288 | - } | ||
289 | - } | ||
290 | - | ||
291 | - | ||
292 | - /* Set signal handling and alarm */ | ||
293 | - if (signal (SIGALRM, catch_alarm) == SIG_ERR) { | ||
294 | - printf("DNS problem - Cannot set ALRM handler"); | ||
295 | - exit(33); | ||
296 | - } | ||
297 | - | ||
298 | - /* process /etc/resolv.conf */ | ||
299 | - if (res_init() == -1) { | ||
300 | - printf("DNS problem - Cannot call res_init \n"); | ||
301 | - exit(33); | ||
302 | - } | ||
303 | - | ||
304 | - if (debugging) { | ||
305 | - _res.options |= RES_DEBUG; /* turn on resolver debugging */ | ||
306 | - } | ||
307 | - | ||
308 | - if (norecurse) { | ||
309 | - _res.options &= ~RES_RECURSE; /* turn off recursive lookup */ | ||
310 | - } | ||
311 | - | ||
312 | - if (server) { | ||
313 | - struct hostent *hp; | ||
314 | - static struct sockaddr_in *a; | ||
315 | - in_addr_t s; | ||
316 | - | ||
317 | - /* override the nameservers from resolv.conf */ | ||
318 | - _res.nscount = 1; | ||
319 | - a = &_res.nsaddr_list[0]; | ||
320 | - /* a->sin_port = ... leave the port alone */ | ||
321 | - | ||
322 | - hp = gethostbyname(server); | ||
323 | - if (hp && hp->h_addr_list[0] != NULL) { | ||
324 | - a->sin_family = hp->h_addrtype; | ||
325 | - bcopy(hp->h_addr_list[0], &a->sin_addr, hp->h_length); | ||
326 | - } else { | ||
327 | - /* assume a dotted quad address */ | ||
328 | - s = inet_addr(server); | ||
329 | - if (s == -1) { | ||
330 | - printf("DNS problem - Cannot resolve server %s\n", server); | ||
331 | - exit(33); | ||
332 | - } | ||
333 | - a->sin_family = AF_INET; | ||
334 | - bcopy(&s, &a->sin_addr, sizeof(in_addr_t)); | ||
335 | - } | ||
336 | - } | ||
337 | - | ||
338 | - time (&start_time); | ||
339 | - alarm (timeout); | ||
340 | - | ||
341 | - n = res_query(host, C_IN, T_A, answer.buf, sizeof(answer)); | ||
342 | - | ||
343 | - alarm(0); /* cancel pending alarm */ | ||
344 | - (void) time (&end_time); | ||
345 | - | ||
346 | - if (n < 0) { | ||
347 | - printf("DNS CRITICAL - query failed: %d\n", n); | ||
348 | - exit(n); | ||
349 | - } | ||
350 | - | ||
351 | - hentry = getanswer(&answer, n, host, T_A); | ||
352 | - if (hentry == NULL) { | ||
353 | - printf("DNS WARNING - no answer\n"); | ||
354 | - exit(2); | ||
355 | - } | ||
356 | - printf("DNS ok - %d seconds response time, Address(es) is/are", | ||
357 | - (int) (end_time - start_time)); | ||
358 | - for(h=hentry->h_addr_list; *h; h++) { | ||
359 | - struct in_addr a; | ||
360 | - bcopy(*h, &a, hentry->h_length); | ||
361 | - printf(" %s", inet_ntoa(a)); | ||
362 | - } | ||
363 | - printf("\n"); | ||
364 | +int | ||
365 | +error_scan (char *input_buffer) | ||
366 | +{ | ||
367 | + | ||
368 | + /* the DNS lookup timed out */ | ||
369 | + if (strstr (input_buffer, | ||
370 | + "Note: nslookup is deprecated and may be removed from future releases.") | ||
371 | + || strstr (input_buffer, | ||
372 | + "Consider using the `dig' or `host' programs instead. Run nslookup with") | ||
373 | + || strstr (input_buffer, | ||
374 | + "the `-sil[ent]' option to prevent this message from appearing.")) | ||
375 | + return STATE_OK; | ||
376 | + | ||
377 | + /* the DNS lookup timed out */ | ||
378 | + else if (strstr (input_buffer, "Timed out")) | ||
379 | + return STATE_WARNING; | ||
380 | + | ||
381 | + /* DNS server is not running... */ | ||
382 | + else if (strstr (input_buffer, "No response from server")) | ||
383 | + return STATE_CRITICAL; | ||
384 | + | ||
385 | + /* Host name is valid, but server doesn't have records... */ | ||
386 | + else if (strstr (input_buffer, "No records")) | ||
387 | + return STATE_WARNING; | ||
388 | + | ||
389 | + /* Host or domain name does not exist */ | ||
390 | + else if (strstr (input_buffer, "Non-existent")) | ||
391 | + return STATE_CRITICAL; | ||
392 | + else if (strstr (input_buffer, "** server can't find")) | ||
393 | + return STATE_CRITICAL; | ||
394 | + else if(strstr(input_buffer,"NXDOMAIN")) /* 9.x */ | ||
395 | + return STATE_CRITICAL; | ||
396 | + | ||
397 | + /* Connection was refused */ | ||
398 | + else if (strstr (input_buffer, "Connection refused")) | ||
399 | + return STATE_CRITICAL; | ||
400 | + | ||
401 | + /* Network is unreachable */ | ||
402 | + else if (strstr (input_buffer, "Network is unreachable")) | ||
403 | + return STATE_CRITICAL; | ||
404 | + | ||
405 | + /* Internal server failure */ | ||
406 | + else if (strstr (input_buffer, "Server failure")) | ||
407 | + return STATE_CRITICAL; | ||
408 | + | ||
409 | + /* DNS server refused to service request */ | ||
410 | + else if (strstr (input_buffer, "Refused")) | ||
411 | + return STATE_CRITICAL; | ||
412 | + | ||
413 | + /* Request error */ | ||
414 | + else if (strstr (input_buffer, "Format error")) | ||
415 | + return STATE_WARNING; | ||
416 | + | ||
417 | + else | ||
418 | + return STATE_OK; | ||
419 | |||
420 | - exit(0); | ||
421 | } | ||
422 | |||
423 | +/* process command-line arguments */ | ||
424 | +int | ||
425 | +process_arguments (int argc, char **argv) | ||
426 | +{ | ||
427 | + int c; | ||
428 | + | ||
429 | + if (argc < 2) | ||
430 | + return ERROR; | ||
431 | |||
432 | + for (c = 1; c < argc; c++) | ||
433 | + if (strcmp ("-to", argv[c]) == 0) | ||
434 | + strcpy (argv[c], "-t"); | ||
435 | + | ||
436 | + c = 0; | ||
437 | + while (c += (call_getopt (argc - c, &argv[c]))) { | ||
438 | + if (argc <= c) | ||
439 | + break; | ||
440 | + if (query_address[0] == 0) { | ||
441 | + if (is_host (argv[c]) == FALSE) { | ||
442 | + printf ("Invalid name/address: %s\n\n", argv[c]); | ||
443 | + return ERROR; | ||
444 | + } | ||
445 | + if (strlen (argv[c]) >= ADDRESS_LENGTH) | ||
446 | + terminate (STATE_UNKNOWN, "Input buffer overflow\n"); | ||
447 | + strcpy (query_address, argv[c]); | ||
448 | + } | ||
449 | + else if (dns_server[0] == 0) { | ||
450 | + if (is_host (argv[c]) == FALSE) { | ||
451 | + printf ("Invalid name/address: %s\n\n", argv[c]); | ||
452 | + return ERROR; | ||
453 | + } | ||
454 | + if (strlen (argv[c]) >= ADDRESS_LENGTH) | ||
455 | + terminate (STATE_UNKNOWN, "Input buffer overflow\n"); | ||
456 | + strcpy (dns_server, argv[c]); | ||
457 | + } | ||
458 | + } | ||
459 | |||
460 | -/* stripped down getanswer */ | ||
461 | + return validate_arguments (); | ||
462 | + | ||
463 | +} | ||
464 | |||
465 | -/* | ||
466 | - * Copyright (c) 1985, 1988, 1993 | ||
467 | - * The Regents of the University of California. All rights reserved. | ||
468 | - * | ||
469 | - * Redistribution and use in source and binary forms, with or without | ||
470 | - * modification, are permitted provided that the following conditions | ||
471 | - * are met: | ||
472 | - * 1. Redistributions of source code must retain the above copyright | ||
473 | - * notice, this list of conditions and the following disclaimer. | ||
474 | - * 2. Redistributions in binary form must reproduce the above copyright | ||
475 | - * notice, this list of conditions and the following disclaimer in the | ||
476 | - * documentation and/or other materials provided with the distribution. | ||
477 | - * 3. All advertising materials mentioning features or use of this software | ||
478 | - * must display the following acknowledgement: | ||
479 | - * This product includes software developed by the University of | ||
480 | - * California, Berkeley and its contributors. | ||
481 | - * 4. Neither the name of the University nor the names of its contributors | ||
482 | - * may be used to endorse or promote products derived from this software | ||
483 | - * without specific prior written permission. | ||
484 | - * | ||
485 | - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
486 | - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
487 | - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
488 | - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
489 | - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
490 | - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
491 | - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
492 | - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
493 | - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
494 | - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
495 | - * SUCH DAMAGE. | ||
496 | - * - | ||
497 | - * Portions Copyright (c) 1993 by Digital Equipment Corporation. | ||
498 | - * | ||
499 | - * Permission to use, copy, modify, and distribute this software for any | ||
500 | - * purpose with or without fee is hereby granted, provided that the above | ||
501 | - * copyright notice and this permission notice appear in all copies, and that | ||
502 | - * the name of Digital Equipment Corporation not be used in advertising or | ||
503 | - * publicity pertaining to distribution of the document or software without | ||
504 | - * specific, written prior permission. | ||
505 | - * | ||
506 | - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL | ||
507 | - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES | ||
508 | - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT | ||
509 | - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | ||
510 | - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR | ||
511 | - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS | ||
512 | - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | ||
513 | - * SOFTWARE. | ||
514 | - * - | ||
515 | - * --Copyright-- | ||
516 | - */ | ||
517 | - | ||
518 | -static const char AskedForGot[] = | ||
519 | - "gethostby*.getanswer: asked for \"%s\", got \"%s\""; | ||
520 | -static char *h_addr_ptrs[MAXADDRS + 1]; | ||
521 | - | ||
522 | -static struct hostent host; | ||
523 | -static char *host_aliases[MAXALIASES]; | ||
524 | -static char hostbuf[8*1024]; | ||
525 | -static u_char host_addr[16]; /* IPv4 or IPv6 */ | ||
526 | -static FILE *hostf = NULL; | ||
527 | -static int stayopen = 0; | ||
528 | - | ||
529 | - | ||
530 | -typedef union { | ||
531 | - int32_t al; | ||
532 | - char ac; | ||
533 | -} align; | ||
534 | - | ||
535 | -#define dprintf printf | ||
536 | - | ||
537 | -static struct hostent * | ||
538 | -getanswer(const querybuf *answer, | ||
539 | - int anslen, | ||
540 | - const char *qname, | ||
541 | - int qtype) | ||
542 | +int | ||
543 | +call_getopt (int argc, char **argv) | ||
544 | { | ||
545 | - register const HEADER *hp; | ||
546 | - register const u_char *cp; | ||
547 | - register int n; | ||
548 | - const u_char *eom; | ||
549 | - char *bp, **ap, **hap; | ||
550 | - int type, class, buflen, ancount, qdcount; | ||
551 | - int haveanswer, had_error; | ||
552 | - int toobig = 0; | ||
553 | - char tbuf[MAXDNAME]; | ||
554 | - const char *tname; | ||
555 | - int (*name_ok) __P((const char *)); | ||
556 | - | ||
557 | - tname = qname; | ||
558 | - host.h_name = NULL; | ||
559 | - host.h_length = INADDRSZ; | ||
560 | - host.h_addrtype = AF_INET; | ||
561 | - | ||
562 | - eom = answer->buf + anslen; | ||
563 | - switch (qtype) { | ||
564 | - case T_A: | ||
565 | - case T_AAAA: | ||
566 | - name_ok = res_hnok; | ||
567 | - break; | ||
568 | - case T_PTR: | ||
569 | - name_ok = res_dnok; | ||
570 | - break; | ||
571 | - default: | ||
572 | - return (NULL); /* XXX should be abort(); */ | ||
573 | - } | ||
574 | - /* | ||
575 | - * find first satisfactory answer | ||
576 | - */ | ||
577 | - hp = &answer->hdr; | ||
578 | - ancount = ntohs(hp->ancount); | ||
579 | - qdcount = ntohs(hp->qdcount); | ||
580 | - bp = hostbuf; | ||
581 | - buflen = sizeof hostbuf; | ||
582 | - cp = answer->buf + HFIXEDSZ; | ||
583 | - if (qdcount != 1) { | ||
584 | - h_errno = NO_RECOVERY; | ||
585 | - return (NULL); | ||
586 | - } | ||
587 | - n = dn_expand(answer->buf, eom, cp, bp, buflen); | ||
588 | - if ((n < 0) || !(*name_ok)(bp)) { | ||
589 | - h_errno = NO_RECOVERY; | ||
590 | - return (NULL); | ||
591 | - } | ||
592 | - cp += n + QFIXEDSZ; | ||
593 | - if (qtype == T_A || qtype == T_AAAA) { | ||
594 | - /* res_send() has already verified that the query name is the | ||
595 | - * same as the one we sent; this just gets the expanded name | ||
596 | - * (i.e., with the succeeding search-domain tacked on). | ||
597 | - */ | ||
598 | - n = strlen(bp) + 1; /* for the \0 */ | ||
599 | - host.h_name = bp; | ||
600 | - bp += n; | ||
601 | - buflen -= n; | ||
602 | - /* The qname can be abbreviated, but h_name is now absolute. */ | ||
603 | - qname = host.h_name; | ||
604 | - } | ||
605 | - ap = host_aliases; | ||
606 | - *ap = NULL; | ||
607 | - host.h_aliases = host_aliases; | ||
608 | - hap = h_addr_ptrs; | ||
609 | - *hap = NULL; | ||
610 | - host.h_addr_list = h_addr_ptrs; | ||
611 | - haveanswer = 0; | ||
612 | - had_error = 0; | ||
613 | - while (ancount-- > 0 && cp < eom && !had_error) { | ||
614 | - n = dn_expand(answer->buf, eom, cp, bp, buflen); | ||
615 | - if ((n < 0) || !(*name_ok)(bp)) { | ||
616 | - had_error++; | ||
617 | - continue; | ||
618 | - } | ||
619 | - | ||
620 | - cp += n; /* name */ | ||
621 | - type = _getshort(cp); | ||
622 | - cp += INT16SZ; /* type */ | ||
623 | - class = _getshort(cp); | ||
624 | - cp += INT16SZ + INT32SZ; /* class, TTL */ | ||
625 | - n = _getshort(cp); | ||
626 | - cp += INT16SZ; /* len */ | ||
627 | - if (class != C_IN) { | ||
628 | - /* XXX - debug? syslog? */ | ||
629 | - cp += n; | ||
630 | - continue; /* XXX - had_error++ ? */ | ||
631 | - } | ||
632 | - if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) { | ||
633 | - if (ap >= &host_aliases[MAXALIASES-1]) | ||
634 | - continue; | ||
635 | - n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf); | ||
636 | - if ((n < 0) || !(*name_ok)(tbuf)) { | ||
637 | - had_error++; | ||
638 | - continue; | ||
639 | - } | ||
640 | - cp += n; | ||
641 | - /* Store alias. */ | ||
642 | - *ap++ = bp; | ||
643 | - n = strlen(bp) + 1; /* for the \0 */ | ||
644 | - bp += n; | ||
645 | - buflen -= n; | ||
646 | - /* Get canonical name. */ | ||
647 | - n = strlen(tbuf) + 1; /* for the \0 */ | ||
648 | - if (n > buflen) { | ||
649 | - had_error++; | ||
650 | - continue; | ||
651 | - } | ||
652 | - strcpy(bp, tbuf); | ||
653 | - host.h_name = bp; | ||
654 | - bp += n; | ||
655 | - buflen -= n; | ||
656 | - continue; | ||
657 | - } | ||
658 | - | ||
659 | - if (qtype == T_PTR && type == T_CNAME) { | ||
660 | - n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf); | ||
661 | - if ((n < 0) || !res_hnok(tbuf)) { | ||
662 | - had_error++; | ||
663 | - continue; | ||
664 | - } | ||
665 | - cp += n; | ||
666 | - /* Get canonical name. */ | ||
667 | - n = strlen(tbuf) + 1; /* for the \0 */ | ||
668 | - if (n > buflen) { | ||
669 | - had_error++; | ||
670 | - continue; | ||
671 | - } | ||
672 | - strcpy(bp, tbuf); | ||
673 | - tname = bp; | ||
674 | - bp += n; | ||
675 | - buflen -= n; | ||
676 | - continue; | ||
677 | - } | ||
678 | - if (type != qtype) { | ||
679 | - dprintf("gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"", | ||
680 | - qname, p_class(C_IN), p_type(qtype), | ||
681 | - p_type(type)); | ||
682 | - cp += n; | ||
683 | - continue; /* XXX - had_error++ ? */ | ||
684 | - } | ||
685 | - switch (type) { | ||
686 | - case T_PTR: | ||
687 | - if (strcasecmp(tname, bp) != 0) { | ||
688 | - dprintf(AskedForGot, qname, bp); | ||
689 | - cp += n; | ||
690 | - continue; /* XXX - had_error++ ? */ | ||
691 | - } | ||
692 | - n = dn_expand(answer->buf, eom, cp, bp, buflen); | ||
693 | - if ((n < 0) || !res_hnok(bp)) { | ||
694 | - had_error++; | ||
695 | - break; | ||
696 | - } | ||
697 | -#if MULTI_PTRS_ARE_ALIASES | ||
698 | - cp += n; | ||
699 | - if (!haveanswer) | ||
700 | - host.h_name = bp; | ||
701 | - else if (ap < &host_aliases[MAXALIASES-1]) | ||
702 | - *ap++ = bp; | ||
703 | - else | ||
704 | - n = -1; | ||
705 | - if (n != -1) { | ||
706 | - n = strlen(bp) + 1; /* for the \0 */ | ||
707 | - bp += n; | ||
708 | - buflen -= n; | ||
709 | - } | ||
710 | - break; | ||
711 | + int c, i = 1; | ||
712 | |||
713 | +#ifdef HAVE_GETOPT_H | ||
714 | + int opt_index = 0; | ||
715 | + static struct option long_opts[] = { | ||
716 | + {"help", no_argument, 0, 'h'}, | ||
717 | + {"version", no_argument, 0, 'V'}, | ||
718 | + {"verbose", no_argument, 0, 'v'}, | ||
719 | + {"timeout", required_argument, 0, 't'}, | ||
720 | + {"hostname", required_argument, 0, 'H'}, | ||
721 | + {"server", required_argument, 0, 's'}, | ||
722 | + {"reverse-server", required_argument, 0, 'r'}, | ||
723 | + {0, 0, 0, 0} | ||
724 | + }; | ||
725 | +#endif | ||
726 | + | ||
727 | + | ||
728 | + while (1) { | ||
729 | +#ifdef HAVE_GETOPT_H | ||
730 | + c = getopt_long (argc, argv, "+?hVvt:H:s:r:", long_opts, &opt_index); | ||
731 | #else | ||
732 | - host.h_name = bp; | ||
733 | - h_errno = NETDB_SUCCESS; | ||
734 | - return (&host); | ||
735 | + c = getopt (argc, argv, "+?hVvt:H:s:r:"); | ||
736 | #endif | ||
737 | - case T_A: | ||
738 | - case T_AAAA: | ||
739 | - if (strcasecmp(host.h_name, bp) != 0) { | ||
740 | - dprintf(AskedForGot, host.h_name, bp); | ||
741 | - cp += n; | ||
742 | - continue; /* XXX - had_error++ ? */ | ||
743 | - } | ||
744 | - if (n != host.h_length) { | ||
745 | - cp += n; | ||
746 | - continue; | ||
747 | - } | ||
748 | - if (!haveanswer) { | ||
749 | - register int nn; | ||
750 | - | ||
751 | - host.h_name = bp; | ||
752 | - nn = strlen(bp) + 1; /* for the \0 */ | ||
753 | - bp += nn; | ||
754 | - buflen -= nn; | ||
755 | - } | ||
756 | - | ||
757 | - bp += sizeof(align) - ((u_long)bp % sizeof(align)); | ||
758 | - | ||
759 | - if (bp + n >= &hostbuf[sizeof hostbuf]) { | ||
760 | - dprintf("size (%d) too big\n", n); | ||
761 | - had_error++; | ||
762 | - continue; | ||
763 | - } | ||
764 | - if (hap >= &h_addr_ptrs[MAXADDRS-1]) { | ||
765 | - if (!toobig++) | ||
766 | - dprintf("Too many addresses (%d)\n", | ||
767 | - MAXADDRS); | ||
768 | - cp += n; | ||
769 | - continue; | ||
770 | - } | ||
771 | - bcopy(cp, *hap++ = bp, n); | ||
772 | - bp += n; | ||
773 | - buflen -= n; | ||
774 | - cp += n; | ||
775 | - break; | ||
776 | - default: | ||
777 | - abort(); | ||
778 | - } | ||
779 | - if (!had_error) | ||
780 | - haveanswer++; | ||
781 | - } | ||
782 | - if (haveanswer) { | ||
783 | - *ap = NULL; | ||
784 | - *hap = NULL; | ||
785 | -# if defined(RESOLVSORT) | ||
786 | - /* | ||
787 | - * Note: we sort even if host can take only one address | ||
788 | - * in its return structures - should give it the "best" | ||
789 | - * address in that case, not some random one | ||
790 | - */ | ||
791 | - if (_res.nsort && haveanswer > 1 && qtype == T_A) | ||
792 | - addrsort(h_addr_ptrs, haveanswer); | ||
793 | -# endif /*RESOLVSORT*/ | ||
794 | - if (!host.h_name) { | ||
795 | - n = strlen(qname) + 1; /* for the \0 */ | ||
796 | - if (n > buflen) | ||
797 | - goto try_again; | ||
798 | - strcpy(bp, qname); | ||
799 | - host.h_name = bp; | ||
800 | - bp += n; | ||
801 | - buflen -= n; | ||
802 | - } | ||
803 | - h_errno = NETDB_SUCCESS; | ||
804 | - return (&host); | ||
805 | - } | ||
806 | - try_again: | ||
807 | - h_errno = TRY_AGAIN; | ||
808 | - return (NULL); | ||
809 | + | ||
810 | + if (c == -1 || c == EOF) | ||
811 | + break; | ||
812 | + | ||
813 | + i++; | ||
814 | + switch (c) { | ||
815 | + case 't': | ||
816 | + case 'H': | ||
817 | + case 's': | ||
818 | + case 'r': | ||
819 | + i++; | ||
820 | + } | ||
821 | + | ||
822 | + switch (c) { | ||
823 | + case '?': /* args not parsable */ | ||
824 | + printf ("%s: Unknown argument: %s\n\n", my_basename (argv[0]), optarg); | ||
825 | + print_usage (my_basename (argv[0])); | ||
826 | + exit (STATE_UNKNOWN); | ||
827 | + case 'h': /* help */ | ||
828 | + print_help (my_basename (argv[0])); | ||
829 | + exit (STATE_OK); | ||
830 | + case 'V': /* version */ | ||
831 | + print_revision (my_basename (argv[0]), "$Revision: 1.1.1.1 $"); | ||
832 | + exit (STATE_OK); | ||
833 | + case 'v': /* version */ | ||
834 | + verbose = TRUE; | ||
835 | + break; | ||
836 | + case 't': /* timeout period */ | ||
837 | + timeout_interval = atoi (optarg); | ||
838 | + break; | ||
839 | + case 'H': /* hostname */ | ||
840 | + if (is_host (optarg) == FALSE) { | ||
841 | + printf ("Invalid host name/address\n\n"); | ||
842 | + print_usage (my_basename (argv[0])); | ||
843 | + exit (STATE_UNKNOWN); | ||
844 | + } | ||
845 | + if (strlen (optarg) >= ADDRESS_LENGTH) | ||
846 | + terminate (STATE_UNKNOWN, "Input buffer overflow\n"); | ||
847 | + strcpy (query_address, optarg); | ||
848 | + break; | ||
849 | + case 's': /* server name */ | ||
850 | + if (is_host (optarg) == FALSE) { | ||
851 | + printf ("Invalid server name/address\n\n"); | ||
852 | + print_usage (my_basename (argv[0])); | ||
853 | + exit (STATE_UNKNOWN); | ||
854 | + } | ||
855 | + if (strlen (optarg) >= ADDRESS_LENGTH) | ||
856 | + terminate (STATE_UNKNOWN, "Input buffer overflow\n"); | ||
857 | + strcpy (dns_server, optarg); | ||
858 | + break; | ||
859 | + case 'r': /* reverse server name */ | ||
860 | + if (is_host (optarg) == FALSE) { | ||
861 | + printf ("Invalid host name/address\n\n"); | ||
862 | + print_usage (my_basename (argv[0])); | ||
863 | + exit (STATE_UNKNOWN); | ||
864 | + } | ||
865 | + if (strlen (optarg) >= ADDRESS_LENGTH) | ||
866 | + terminate (STATE_UNKNOWN, "Input buffer overflow\n"); | ||
867 | + strcpy (ptr_server, optarg); | ||
868 | + break; | ||
869 | + } | ||
870 | + } | ||
871 | + return i; | ||
872 | +} | ||
873 | + | ||
874 | +int | ||
875 | +validate_arguments () | ||
876 | +{ | ||
877 | + if (query_address[0] == 0) | ||
878 | + return ERROR; | ||
879 | + else | ||
880 | + return OK; | ||
881 | +} | ||
882 | + | ||
883 | +void | ||
884 | +print_usage (char *cmd) | ||
885 | +{ | ||
886 | + printf ("Usage: %s -H host [-s server] [-t timeout]\n" " %s --help\n" | ||
887 | + " %s --version\n", cmd, cmd, cmd); | ||
888 | +} | ||
889 | + | ||
890 | +void | ||
891 | +print_help (char *cmd) | ||
892 | +{ | ||
893 | + print_revision (cmd, "$Revision: 1.1.1.1 $"); | ||
894 | + printf ("Copyright (c) 1999 Ethan Galstad (nagios@nagios.org)\n\n"); | ||
895 | + print_usage (cmd); | ||
896 | + printf ("\n"); | ||
897 | + printf | ||
898 | + ("-H, --hostname=HOST\n" | ||
899 | + " The name or address you want to query\n" | ||
900 | + "-s, --server=HOST\n" | ||
901 | + " Optional DNS server you want to use for the lookup\n" | ||
902 | + "-t, --timeout=INTEGER\n" | ||
903 | + " Seconds before connection times out (default: %d)\n" | ||
904 | + "-h, --help\n" | ||
905 | + " Print detailed help\n" | ||
906 | + "-V, --version\n" | ||
907 | + " Print version numbers and license information\n" | ||
908 | + "\n" | ||
909 | + "This plugin uses the nslookup program to obtain the IP address\n" | ||
910 | + "for the given host/domain query. A optional DNS server to use may\n" | ||
911 | + "be specified. If no DNS server is specified, the default server(s)\n" | ||
912 | + "specified in /etc/resolv.conf will be used.\n", DEFAULT_SOCKET_TIMEOUT); | ||
913 | } | ||