named-checkzone.c revision 216175
1135446Strhodes/*
2216175Sdougb * Copyright (C) 2004-2010  Internet Systems Consortium, Inc. ("ISC")
3135446Strhodes * Copyright (C) 1999-2003  Internet Software Consortium.
4135446Strhodes *
5174187Sdougb * Permission to use, copy, modify, and/or distribute this software for any
6135446Strhodes * purpose with or without fee is hereby granted, provided that the above
7135446Strhodes * copyright notice and this permission notice appear in all copies.
8135446Strhodes *
9135446Strhodes * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10135446Strhodes * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11135446Strhodes * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12135446Strhodes * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13135446Strhodes * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14135446Strhodes * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15135446Strhodes * PERFORMANCE OF THIS SOFTWARE.
16135446Strhodes */
17135446Strhodes
18216175Sdougb/* $Id: named-checkzone.c,v 1.51.34.4.10.2 2010/09/07 23:46:26 tbox Exp $ */
19135446Strhodes
20170222Sdougb/*! \file */
21170222Sdougb
22135446Strhodes#include <config.h>
23135446Strhodes
24135446Strhodes#include <stdlib.h>
25135446Strhodes
26135446Strhodes#include <isc/app.h>
27135446Strhodes#include <isc/commandline.h>
28135446Strhodes#include <isc/dir.h>
29143731Sdougb#include <isc/entropy.h>
30143731Sdougb#include <isc/hash.h>
31135446Strhodes#include <isc/log.h>
32135446Strhodes#include <isc/mem.h>
33135446Strhodes#include <isc/socket.h>
34135446Strhodes#include <isc/string.h>
35135446Strhodes#include <isc/task.h>
36135446Strhodes#include <isc/timer.h>
37135446Strhodes#include <isc/util.h>
38135446Strhodes
39135446Strhodes#include <dns/db.h>
40135446Strhodes#include <dns/fixedname.h>
41135446Strhodes#include <dns/log.h>
42170222Sdougb#include <dns/masterdump.h>
43170222Sdougb#include <dns/name.h>
44135446Strhodes#include <dns/rdataclass.h>
45135446Strhodes#include <dns/rdataset.h>
46135446Strhodes#include <dns/result.h>
47170222Sdougb#include <dns/types.h>
48135446Strhodes#include <dns/zone.h>
49135446Strhodes
50135446Strhodes#include "check-tool.h"
51135446Strhodes
52135446Strhodesstatic int quiet = 0;
53135446Strhodesstatic isc_mem_t *mctx = NULL;
54143731Sdougbstatic isc_entropy_t *ectx = NULL;
55135446Strhodesdns_zone_t *zone = NULL;
56135446Strhodesdns_zonetype_t zonetype = dns_zone_master;
57135446Strhodesstatic int dumpzone = 0;
58135446Strhodesstatic const char *output_filename;
59170222Sdougbstatic char *prog_name = NULL;
60170222Sdougbstatic const dns_master_style_t *outputstyle = NULL;
61170222Sdougbstatic enum { progmode_check, progmode_compile } progmode;
62135446Strhodes
63135446Strhodes#define ERRRET(result, function) \
64135446Strhodes	do { \
65135446Strhodes		if (result != ISC_R_SUCCESS) { \
66135446Strhodes			if (!quiet) \
67135446Strhodes				fprintf(stderr, "%s() returned %s\n", \
68135446Strhodes					function, dns_result_totext(result)); \
69135446Strhodes			return (result); \
70135446Strhodes		} \
71135446Strhodes	} while (0)
72135446Strhodes
73135446Strhodesstatic void
74135446Strhodesusage(void) {
75135446Strhodes	fprintf(stderr,
76204619Sdougb		"usage: %s [-djqvD] [-c class] "
77170222Sdougb		"[-f inputformat] [-F outputformat] "
78143731Sdougb		"[-t directory] [-w directory] [-k (ignore|warn|fail)] "
79170222Sdougb		"[-n (ignore|warn|fail)] [-m (ignore|warn|fail)] "
80186462Sdougb		"[-i (full|full-sibling|local|local-sibling|none)] "
81186462Sdougb		"[-M (ignore|warn|fail)] [-S (ignore|warn|fail)] "
82186462Sdougb		"[-W (ignore|warn)] "
83204619Sdougb		"%s zonename filename\n",
84204619Sdougb		prog_name,
85204619Sdougb		progmode == progmode_check ? "[-o filename]" : "{-o filename}");
86135446Strhodes	exit(1);
87135446Strhodes}
88135446Strhodes
89135446Strhodesstatic void
90135446Strhodesdestroy(void) {
91135446Strhodes	if (zone != NULL)
92135446Strhodes		dns_zone_detach(&zone);
93170222Sdougb	dns_name_destroy();
94135446Strhodes}
95135446Strhodes
96170222Sdougb/*% main processing routine */
97135446Strhodesint
98135446Strhodesmain(int argc, char **argv) {
99135446Strhodes	int c;
100135446Strhodes	char *origin = NULL;
101135446Strhodes	char *filename = NULL;
102135446Strhodes	isc_log_t *lctx = NULL;
103135446Strhodes	isc_result_t result;
104135446Strhodes	char classname_in[] = "IN";
105135446Strhodes	char *classname = classname_in;
106135446Strhodes	const char *workdir = NULL;
107170222Sdougb	const char *inputformatstr = NULL;
108170222Sdougb	const char *outputformatstr = NULL;
109170222Sdougb	dns_masterformat_t inputformat = dns_masterformat_text;
110170222Sdougb	dns_masterformat_t outputformat = dns_masterformat_text;
111193149Sdougb	FILE *errout = stdout;
112135446Strhodes
113170222Sdougb	outputstyle = &dns_master_style_full;
114170222Sdougb
115170222Sdougb	prog_name = strrchr(argv[0], '/');
116174187Sdougb	if (prog_name == NULL)
117174187Sdougb		prog_name = strrchr(argv[0], '\\');
118170222Sdougb	if (prog_name != NULL)
119170222Sdougb		prog_name++;
120170222Sdougb	else
121170222Sdougb		prog_name = argv[0];
122170222Sdougb	/*
123170222Sdougb	 * Libtool doesn't preserve the program name prior to final
124170222Sdougb	 * installation.  Remove the libtool prefix ("lt-").
125170222Sdougb	 */
126170222Sdougb	if (strncmp(prog_name, "lt-", 3) == 0)
127170222Sdougb		prog_name += 3;
128194995Sdougb
129194995Sdougb#define PROGCMP(X) \
130194995Sdougb	(strcasecmp(prog_name, X) == 0 || strcasecmp(prog_name, X ".exe") == 0)
131194995Sdougb
132194995Sdougb	if (PROGCMP("named-checkzone"))
133170222Sdougb		progmode = progmode_check;
134194995Sdougb	else if (PROGCMP("named-compilezone"))
135170222Sdougb		progmode = progmode_compile;
136170222Sdougb	else
137170222Sdougb		INSIST(0);
138170222Sdougb
139170222Sdougb	/* Compilation specific defaults */
140170222Sdougb	if (progmode == progmode_compile) {
141170222Sdougb		zone_options |= (DNS_ZONEOPT_CHECKNS |
142170222Sdougb				 DNS_ZONEOPT_FATALNS |
143170222Sdougb				 DNS_ZONEOPT_CHECKNAMES |
144170222Sdougb				 DNS_ZONEOPT_CHECKNAMESFAIL |
145170222Sdougb				 DNS_ZONEOPT_CHECKWILDCARD);
146170222Sdougb	}
147170222Sdougb
148170222Sdougb#define ARGCMP(X) (strcmp(isc_commandline_argument, X) == 0)
149170222Sdougb
150193149Sdougb	isc_commandline_errprint = ISC_FALSE;
151193149Sdougb
152170222Sdougb	while ((c = isc_commandline_parse(argc, argv,
153193149Sdougb					 "c:df:hi:jk:m:n:qs:t:o:vw:DF:M:S:W:"))
154170222Sdougb	       != EOF) {
155135446Strhodes		switch (c) {
156135446Strhodes		case 'c':
157135446Strhodes			classname = isc_commandline_argument;
158135446Strhodes			break;
159135446Strhodes
160135446Strhodes		case 'd':
161135446Strhodes			debug++;
162135446Strhodes			break;
163135446Strhodes
164170222Sdougb		case 'i':
165170222Sdougb			if (ARGCMP("full")) {
166170222Sdougb				zone_options |= DNS_ZONEOPT_CHECKINTEGRITY |
167170222Sdougb						DNS_ZONEOPT_CHECKSIBLING;
168170222Sdougb				docheckmx = ISC_TRUE;
169170222Sdougb				docheckns = ISC_TRUE;
170170222Sdougb				dochecksrv = ISC_TRUE;
171170222Sdougb			} else if (ARGCMP("full-sibling")) {
172170222Sdougb				zone_options |= DNS_ZONEOPT_CHECKINTEGRITY;
173170222Sdougb				zone_options &= ~DNS_ZONEOPT_CHECKSIBLING;
174170222Sdougb				docheckmx = ISC_TRUE;
175170222Sdougb				docheckns = ISC_TRUE;
176170222Sdougb				dochecksrv = ISC_TRUE;
177170222Sdougb			} else if (ARGCMP("local")) {
178170222Sdougb				zone_options |= DNS_ZONEOPT_CHECKINTEGRITY;
179170222Sdougb				zone_options |= DNS_ZONEOPT_CHECKSIBLING;
180170222Sdougb				docheckmx = ISC_FALSE;
181170222Sdougb				docheckns = ISC_FALSE;
182170222Sdougb				dochecksrv = ISC_FALSE;
183170222Sdougb			} else if (ARGCMP("local-sibling")) {
184170222Sdougb				zone_options |= DNS_ZONEOPT_CHECKINTEGRITY;
185170222Sdougb				zone_options &= ~DNS_ZONEOPT_CHECKSIBLING;
186170222Sdougb				docheckmx = ISC_FALSE;
187170222Sdougb				docheckns = ISC_FALSE;
188170222Sdougb				dochecksrv = ISC_FALSE;
189170222Sdougb			} else if (ARGCMP("none")) {
190170222Sdougb				zone_options &= ~DNS_ZONEOPT_CHECKINTEGRITY;
191170222Sdougb				zone_options &= ~DNS_ZONEOPT_CHECKSIBLING;
192170222Sdougb				docheckmx = ISC_FALSE;
193170222Sdougb				docheckns = ISC_FALSE;
194170222Sdougb				dochecksrv = ISC_FALSE;
195170222Sdougb			} else {
196170222Sdougb				fprintf(stderr, "invalid argument to -i: %s\n",
197170222Sdougb					isc_commandline_argument);
198170222Sdougb				exit(1);
199170222Sdougb			}
200170222Sdougb			break;
201170222Sdougb
202170222Sdougb		case 'f':
203170222Sdougb			inputformatstr = isc_commandline_argument;
204170222Sdougb			break;
205170222Sdougb
206170222Sdougb		case 'F':
207170222Sdougb			outputformatstr = isc_commandline_argument;
208170222Sdougb			break;
209170222Sdougb
210135446Strhodes		case 'j':
211135446Strhodes			nomerge = ISC_FALSE;
212135446Strhodes			break;
213135446Strhodes
214170222Sdougb		case 'k':
215170222Sdougb			if (ARGCMP("warn")) {
216170222Sdougb				zone_options |= DNS_ZONEOPT_CHECKNAMES;
217170222Sdougb				zone_options &= ~DNS_ZONEOPT_CHECKNAMESFAIL;
218170222Sdougb			} else if (ARGCMP("fail")) {
219170222Sdougb				zone_options |= DNS_ZONEOPT_CHECKNAMES |
220170222Sdougb						DNS_ZONEOPT_CHECKNAMESFAIL;
221170222Sdougb			} else if (ARGCMP("ignore")) {
222170222Sdougb				zone_options &= ~(DNS_ZONEOPT_CHECKNAMES |
223170222Sdougb						  DNS_ZONEOPT_CHECKNAMESFAIL);
224170222Sdougb			} else {
225170222Sdougb				fprintf(stderr, "invalid argument to -k: %s\n",
226170222Sdougb					isc_commandline_argument);
227170222Sdougb				exit(1);
228170222Sdougb			}
229170222Sdougb			break;
230170222Sdougb
231135446Strhodes		case 'n':
232170222Sdougb			if (ARGCMP("ignore")) {
233135446Strhodes				zone_options &= ~(DNS_ZONEOPT_CHECKNS|
234135446Strhodes						  DNS_ZONEOPT_FATALNS);
235170222Sdougb			} else if (ARGCMP("warn")) {
236135446Strhodes				zone_options |= DNS_ZONEOPT_CHECKNS;
237135446Strhodes				zone_options &= ~DNS_ZONEOPT_FATALNS;
238170222Sdougb			} else if (ARGCMP("fail")) {
239135446Strhodes				zone_options |= DNS_ZONEOPT_CHECKNS|
240186462Sdougb						DNS_ZONEOPT_FATALNS;
241170222Sdougb			} else {
242170222Sdougb				fprintf(stderr, "invalid argument to -n: %s\n",
243170222Sdougb					isc_commandline_argument);
244170222Sdougb				exit(1);
245170222Sdougb			}
246135446Strhodes			break;
247135446Strhodes
248170222Sdougb		case 'm':
249170222Sdougb			if (ARGCMP("warn")) {
250170222Sdougb				zone_options |= DNS_ZONEOPT_CHECKMX;
251170222Sdougb				zone_options &= ~DNS_ZONEOPT_CHECKMXFAIL;
252170222Sdougb			} else if (ARGCMP("fail")) {
253170222Sdougb				zone_options |= DNS_ZONEOPT_CHECKMX |
254170222Sdougb						DNS_ZONEOPT_CHECKMXFAIL;
255170222Sdougb			} else if (ARGCMP("ignore")) {
256170222Sdougb				zone_options &= ~(DNS_ZONEOPT_CHECKMX |
257170222Sdougb						  DNS_ZONEOPT_CHECKMXFAIL);
258170222Sdougb			} else {
259170222Sdougb				fprintf(stderr, "invalid argument to -m: %s\n",
260170222Sdougb					isc_commandline_argument);
261170222Sdougb				exit(1);
262135446Strhodes			}
263135446Strhodes			break;
264135446Strhodes
265135446Strhodes		case 'q':
266135446Strhodes			quiet++;
267135446Strhodes			break;
268135446Strhodes
269135446Strhodes		case 't':
270135446Strhodes			result = isc_dir_chroot(isc_commandline_argument);
271135446Strhodes			if (result != ISC_R_SUCCESS) {
272135446Strhodes				fprintf(stderr, "isc_dir_chroot: %s: %s\n",
273135446Strhodes					isc_commandline_argument,
274135446Strhodes					isc_result_totext(result));
275135446Strhodes				exit(1);
276135446Strhodes			}
277135446Strhodes			break;
278135446Strhodes
279170222Sdougb		case 's':
280170222Sdougb			if (ARGCMP("full"))
281170222Sdougb				outputstyle = &dns_master_style_full;
282170222Sdougb			else if (ARGCMP("relative")) {
283170222Sdougb				outputstyle = &dns_master_style_default;
284170222Sdougb			} else {
285170222Sdougb				fprintf(stderr,
286170222Sdougb					"unknown or unsupported style: %s\n",
287170222Sdougb					isc_commandline_argument);
288170222Sdougb				exit(1);
289170222Sdougb			}
290170222Sdougb			break;
291170222Sdougb
292135446Strhodes		case 'o':
293135446Strhodes			output_filename = isc_commandline_argument;
294135446Strhodes			break;
295135446Strhodes
296135446Strhodes		case 'v':
297135446Strhodes			printf(VERSION "\n");
298135446Strhodes			exit(0);
299135446Strhodes
300135446Strhodes		case 'w':
301135446Strhodes			workdir = isc_commandline_argument;
302135446Strhodes			break;
303135446Strhodes
304135446Strhodes		case 'D':
305135446Strhodes			dumpzone++;
306135446Strhodes			break;
307135446Strhodes
308170222Sdougb		case 'M':
309170222Sdougb			if (ARGCMP("fail")) {
310170222Sdougb				zone_options &= ~DNS_ZONEOPT_WARNMXCNAME;
311170222Sdougb				zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME;
312170222Sdougb			} else if (ARGCMP("warn")) {
313170222Sdougb				zone_options |= DNS_ZONEOPT_WARNMXCNAME;
314170222Sdougb				zone_options &= ~DNS_ZONEOPT_IGNOREMXCNAME;
315170222Sdougb			} else if (ARGCMP("ignore")) {
316170222Sdougb				zone_options |= DNS_ZONEOPT_WARNMXCNAME;
317170222Sdougb				zone_options |= DNS_ZONEOPT_IGNOREMXCNAME;
318170222Sdougb			} else {
319170222Sdougb				fprintf(stderr, "invalid argument to -M: %s\n",
320170222Sdougb					isc_commandline_argument);
321170222Sdougb				exit(1);
322170222Sdougb			}
323170222Sdougb			break;
324170222Sdougb
325170222Sdougb		case 'S':
326170222Sdougb			if (ARGCMP("fail")) {
327170222Sdougb				zone_options &= ~DNS_ZONEOPT_WARNSRVCNAME;
328170222Sdougb				zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME;
329170222Sdougb			} else if (ARGCMP("warn")) {
330170222Sdougb				zone_options |= DNS_ZONEOPT_WARNSRVCNAME;
331170222Sdougb				zone_options &= ~DNS_ZONEOPT_IGNORESRVCNAME;
332170222Sdougb			} else if (ARGCMP("ignore")) {
333170222Sdougb				zone_options |= DNS_ZONEOPT_WARNSRVCNAME;
334170222Sdougb				zone_options |= DNS_ZONEOPT_IGNORESRVCNAME;
335170222Sdougb			} else {
336170222Sdougb				fprintf(stderr, "invalid argument to -S: %s\n",
337170222Sdougb					isc_commandline_argument);
338170222Sdougb				exit(1);
339170222Sdougb			}
340170222Sdougb			break;
341170222Sdougb
342170222Sdougb		case 'W':
343170222Sdougb			if (ARGCMP("warn"))
344170222Sdougb				zone_options |= DNS_ZONEOPT_CHECKWILDCARD;
345170222Sdougb			else if (ARGCMP("ignore"))
346170222Sdougb				zone_options &= ~DNS_ZONEOPT_CHECKWILDCARD;
347170222Sdougb			break;
348170222Sdougb
349193149Sdougb		case '?':
350193149Sdougb			if (isc_commandline_option != '?')
351193149Sdougb				fprintf(stderr, "%s: invalid argument -%c\n",
352193149Sdougb					prog_name, isc_commandline_option);
353193149Sdougb		case 'h':
354135446Strhodes			usage();
355135446Strhodes
356193149Sdougb		default:
357193149Sdougb			fprintf(stderr, "%s: unhandled option -%c\n",
358193149Sdougb				prog_name, isc_commandline_option);
359193149Sdougb			exit(1);
360170222Sdougb		}
361170222Sdougb	}
362170222Sdougb
363135446Strhodes	if (workdir != NULL) {
364135446Strhodes		result = isc_dir_chdir(workdir);
365135446Strhodes		if (result != ISC_R_SUCCESS) {
366135446Strhodes			fprintf(stderr, "isc_dir_chdir: %s: %s\n",
367135446Strhodes				workdir, isc_result_totext(result));
368135446Strhodes			exit(1);
369135446Strhodes		}
370135446Strhodes	}
371135446Strhodes
372170222Sdougb	if (inputformatstr != NULL) {
373170222Sdougb		if (strcasecmp(inputformatstr, "text") == 0)
374170222Sdougb			inputformat = dns_masterformat_text;
375170222Sdougb		else if (strcasecmp(inputformatstr, "raw") == 0)
376170222Sdougb			inputformat = dns_masterformat_raw;
377170222Sdougb		else {
378170222Sdougb			fprintf(stderr, "unknown file format: %s\n",
379170222Sdougb			    inputformatstr);
380170222Sdougb			exit(1);
381170222Sdougb		}
382170222Sdougb	}
383170222Sdougb
384170222Sdougb	if (outputformatstr != NULL) {
385170222Sdougb		if (strcasecmp(outputformatstr, "text") == 0)
386170222Sdougb			outputformat = dns_masterformat_text;
387170222Sdougb		else if (strcasecmp(outputformatstr, "raw") == 0)
388170222Sdougb			outputformat = dns_masterformat_raw;
389170222Sdougb		else {
390170222Sdougb			fprintf(stderr, "unknown file format: %s\n",
391170222Sdougb				outputformatstr);
392170222Sdougb			exit(1);
393170222Sdougb		}
394170222Sdougb	}
395170222Sdougb
396193149Sdougb	if (progmode == progmode_compile) {
397193149Sdougb		dumpzone = 1;	/* always dump */
398193149Sdougb		if (output_filename == NULL) {
399193149Sdougb			fprintf(stderr,
400193149Sdougb				"output file required, but not specified\n");
401193149Sdougb			usage();
402193149Sdougb		}
403193149Sdougb	}
404193149Sdougb
405193149Sdougb	if (output_filename != NULL)
406193149Sdougb		dumpzone = 1;
407193149Sdougb
408193149Sdougb	/*
409193149Sdougb	 * If we are outputing to stdout then send the informational
410193149Sdougb	 * output to stderr.
411193149Sdougb	 */
412193149Sdougb	if (dumpzone &&
413193149Sdougb	    (output_filename == NULL ||
414193149Sdougb	     strcmp(output_filename, "-") == 0 ||
415193149Sdougb	     strcmp(output_filename, "/dev/fd/1") == 0 ||
416193149Sdougb	     strcmp(output_filename, "/dev/stdout") == 0))
417193149Sdougb		errout = stderr;
418193149Sdougb
419193149Sdougb	if (isc_commandline_index + 2 != argc)
420135446Strhodes		usage();
421135446Strhodes
422216175Sdougb#ifdef _WIN32
423216175Sdougb	InitSockets();
424216175Sdougb#endif
425216175Sdougb
426135446Strhodes	RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
427170222Sdougb	if (!quiet)
428193149Sdougb		RUNTIME_CHECK(setup_logging(mctx, errout, &lctx)
429193149Sdougb			      == ISC_R_SUCCESS);
430143731Sdougb	RUNTIME_CHECK(isc_entropy_create(mctx, &ectx) == ISC_R_SUCCESS);
431143731Sdougb	RUNTIME_CHECK(isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE)
432143731Sdougb		      == ISC_R_SUCCESS);
433135446Strhodes
434135446Strhodes	dns_result_register();
435135446Strhodes
436135446Strhodes	origin = argv[isc_commandline_index++];
437135446Strhodes	filename = argv[isc_commandline_index++];
438170222Sdougb	result = load_zone(mctx, origin, filename, inputformat, classname,
439170222Sdougb			   &zone);
440135446Strhodes
441135446Strhodes	if (result == ISC_R_SUCCESS && dumpzone) {
442170222Sdougb		if (!quiet && progmode == progmode_compile) {
443193149Sdougb			fprintf(errout, "dump zone to %s...", output_filename);
444193149Sdougb			fflush(errout);
445170222Sdougb		}
446170222Sdougb		result = dump_zone(origin, zone, output_filename,
447170222Sdougb				   outputformat, outputstyle);
448170222Sdougb		if (!quiet && progmode == progmode_compile)
449193149Sdougb			fprintf(errout, "done\n");
450135446Strhodes	}
451135446Strhodes
452135446Strhodes	if (!quiet && result == ISC_R_SUCCESS)
453193149Sdougb		fprintf(errout, "OK\n");
454135446Strhodes	destroy();
455135446Strhodes	if (lctx != NULL)
456135446Strhodes		isc_log_destroy(&lctx);
457143731Sdougb	isc_hash_destroy();
458143731Sdougb	isc_entropy_detach(&ectx);
459135446Strhodes	isc_mem_destroy(&mctx);
460216175Sdougb#ifdef _WIN32
461216175Sdougb	DestroySockets();
462216175Sdougb#endif
463135446Strhodes	return ((result == ISC_R_SUCCESS) ? 0 : 1);
464135446Strhodes}
465