1 /* $NetBSD: check-tool.c,v 1.7 2014/12/10 04:37:51 christos Exp $ */
4 * Copyright (C) 2004-2014 Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (C) 2000-2002 Internet Software Consortium.
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
20 /* Id: check-tool.c,v 1.44 2011/12/22 07:32:39 each Exp */
32 #include "check-tool.h"
33 #include <isc/buffer.h>
36 #include <isc/netdb.h>
38 #include <isc/region.h>
39 #include <isc/stdio.h>
40 #include <isc/string.h>
41 #include <isc/symtab.h>
42 #include <isc/types.h>
46 #include <dns/dbiterator.h>
47 #include <dns/fixedname.h>
50 #include <dns/rdata.h>
51 #include <dns/rdataclass.h>
52 #include <dns/rdataset.h>
53 #include <dns/rdatasetiter.h>
54 #include <dns/rdatatype.h>
55 #include <dns/result.h>
56 #include <dns/types.h>
59 #include <isccfg/log.h>
62 #define CHECK_SIBLING 1
70 #ifdef HAVE_GETADDRINFO
71 #ifdef HAVE_GAISTRERROR
72 #define USE_GETADDRINFO
80 if (result != ISC_R_SUCCESS) \
82 } while (/*CONSTCOND*/0)
84 #define ERR_IS_CNAME 1
85 #define ERR_NO_ADDRESSES 2
86 #define ERR_LOOKUP_FAILURE 3
88 #define ERR_EXTRA_AAAA 5
89 #define ERR_MISSING_GLUE 5
90 #define ERR_IS_MXCNAME 6
91 #define ERR_IS_SRVCNAME 7
93 static const char *dbtype
[] = { "rbt" };
96 const char *journal
= NULL
;
97 isc_boolean_t nomerge
= ISC_TRUE
;
99 isc_boolean_t docheckmx
= ISC_TRUE
;
100 isc_boolean_t dochecksrv
= ISC_TRUE
;
101 isc_boolean_t docheckns
= ISC_TRUE
;
103 isc_boolean_t docheckmx
= ISC_FALSE
;
104 isc_boolean_t dochecksrv
= ISC_FALSE
;
105 isc_boolean_t docheckns
= ISC_FALSE
;
107 unsigned int zone_options
= DNS_ZONEOPT_CHECKNS
|
108 DNS_ZONEOPT_CHECKMX
|
109 DNS_ZONEOPT_MANYERRORS
|
110 DNS_ZONEOPT_CHECKNAMES
|
111 DNS_ZONEOPT_CHECKINTEGRITY
|
113 DNS_ZONEOPT_CHECKSIBLING
|
115 DNS_ZONEOPT_CHECKWILDCARD
|
116 DNS_ZONEOPT_WARNMXCNAME
|
117 DNS_ZONEOPT_WARNSRVCNAME
;
118 unsigned int zone_options2
= 0;
121 * This needs to match the list in bin/named/log.c.
123 static isc_logcategory_t categories
[] = {
130 { "update-security", 0 },
131 { "query-errors", 0 },
135 static isc_symtab_t
*symtab
= NULL
;
136 static isc_mem_t
*sym_mctx
;
139 freekey(char *key
, unsigned int type
, isc_symvalue_t value
, void *userarg
) {
142 isc_mem_free(userarg
, key
);
146 add(char *key
, int value
) {
148 isc_symvalue_t symvalue
;
150 if (sym_mctx
== NULL
) {
151 result
= isc_mem_create(0, 0, &sym_mctx
);
152 if (result
!= ISC_R_SUCCESS
)
156 if (symtab
== NULL
) {
157 result
= isc_symtab_create(sym_mctx
, 100, freekey
, sym_mctx
,
159 if (result
!= ISC_R_SUCCESS
)
163 key
= isc_mem_strdup(sym_mctx
, key
);
167 symvalue
.as_pointer
= NULL
;
168 result
= isc_symtab_define(symtab
, key
, value
, symvalue
,
169 isc_symexists_reject
);
170 if (result
!= ISC_R_SUCCESS
)
171 isc_mem_free(sym_mctx
, key
);
175 logged(char *key
, int value
) {
181 result
= isc_symtab_lookup(symtab
, key
, value
, NULL
);
182 if (result
== ISC_R_SUCCESS
)
188 checkns(dns_zone_t
*zone
, dns_name_t
*name
, dns_name_t
*owner
,
189 dns_rdataset_t
*a
, dns_rdataset_t
*aaaa
)
191 #ifdef USE_GETADDRINFO
192 dns_rdataset_t
*rdataset
;
193 dns_rdata_t rdata
= DNS_RDATA_INIT
;
194 struct addrinfo hints
, *ai
, *cur
;
195 char namebuf
[DNS_NAME_FORMATSIZE
+ 1];
196 char ownerbuf
[DNS_NAME_FORMATSIZE
];
197 char addrbuf
[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:123.123.123.123")];
198 isc_boolean_t answer
= ISC_TRUE
;
204 REQUIRE(a
== NULL
|| !dns_rdataset_isassociated(a
) ||
205 a
->type
== dns_rdatatype_a
);
206 REQUIRE(aaaa
== NULL
|| !dns_rdataset_isassociated(aaaa
) ||
207 aaaa
->type
== dns_rdatatype_aaaa
);
209 if (a
== NULL
|| aaaa
== NULL
)
212 memset(&hints
, 0, sizeof(hints
));
213 hints
.ai_flags
= AI_CANONNAME
;
214 hints
.ai_family
= PF_UNSPEC
;
215 hints
.ai_socktype
= SOCK_STREAM
;
216 hints
.ai_protocol
= IPPROTO_TCP
;
218 dns_name_format(name
, namebuf
, sizeof(namebuf
) - 1);
222 if (dns_name_countlabels(name
) > 1U)
223 strcat(namebuf
, ".");
224 dns_name_format(owner
, ownerbuf
, sizeof(ownerbuf
));
226 result
= getaddrinfo(namebuf
, NULL
, &hints
, &ai
);
227 dns_name_format(name
, namebuf
, sizeof(namebuf
) - 1);
231 * Work around broken getaddrinfo() implementations that
232 * fail to set ai_canonname on first entry.
235 while (cur
!= NULL
&& cur
->ai_canonname
== NULL
&&
236 cur
->ai_next
!= NULL
)
238 if (cur
!= NULL
&& cur
->ai_canonname
!= NULL
&&
239 strcasecmp(cur
->ai_canonname
, namebuf
) != 0 &&
240 !logged(namebuf
, ERR_IS_CNAME
)) {
241 dns_zone_log(zone
, ISC_LOG_ERROR
,
242 "%s/NS '%s' (out of zone) "
243 "is a CNAME '%s' (illegal)",
246 /* XXX950 make fatal for 9.5.0 */
247 /* answer = ISC_FALSE; */
248 add(namebuf
, ERR_IS_CNAME
);
252 #if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME)
255 if (!logged(namebuf
, ERR_NO_ADDRESSES
)) {
256 dns_zone_log(zone
, ISC_LOG_ERROR
,
257 "%s/NS '%s' (out of zone) "
258 "has no addresses records (A or AAAA)",
260 add(namebuf
, ERR_NO_ADDRESSES
);
262 /* XXX950 make fatal for 9.5.0 */
266 if (!logged(namebuf
, ERR_LOOKUP_FAILURE
)) {
267 dns_zone_log(zone
, ISC_LOG_WARNING
,
268 "getaddrinfo(%s) failed: %s",
269 namebuf
, gai_strerror(result
));
270 add(namebuf
, ERR_LOOKUP_FAILURE
);
276 * Check that all glue records really exist.
278 if (!dns_rdataset_isassociated(a
))
280 result
= dns_rdataset_first(a
);
281 while (result
== ISC_R_SUCCESS
) {
282 dns_rdataset_current(a
, &rdata
);
284 for (cur
= ai
; cur
!= NULL
; cur
= cur
->ai_next
) {
285 if (cur
->ai_family
!= AF_INET
)
287 ptr
= &((struct sockaddr_in
*)(cur
->ai_addr
))->sin_addr
;
288 if (memcmp(ptr
, rdata
.data
, rdata
.length
) == 0) {
293 if (!match
&& !logged(namebuf
, ERR_EXTRA_A
)) {
294 dns_zone_log(zone
, ISC_LOG_ERROR
, "%s/NS '%s' "
295 "extra GLUE A record (%s)",
297 inet_ntop(AF_INET
, rdata
.data
,
298 addrbuf
, sizeof(addrbuf
)));
299 add(namebuf
, ERR_EXTRA_A
);
300 /* XXX950 make fatal for 9.5.0 */
301 /* answer = ISC_FALSE; */
303 dns_rdata_reset(&rdata
);
304 result
= dns_rdataset_next(a
);
308 if (!dns_rdataset_isassociated(aaaa
))
310 result
= dns_rdataset_first(aaaa
);
311 while (result
== ISC_R_SUCCESS
) {
312 dns_rdataset_current(aaaa
, &rdata
);
314 for (cur
= ai
; cur
!= NULL
; cur
= cur
->ai_next
) {
315 if (cur
->ai_family
!= AF_INET6
)
317 ptr
= &((struct sockaddr_in6
*)(cur
->ai_addr
))->sin6_addr
;
318 if (memcmp(ptr
, rdata
.data
, rdata
.length
) == 0) {
323 if (!match
&& !logged(namebuf
, ERR_EXTRA_AAAA
)) {
324 dns_zone_log(zone
, ISC_LOG_ERROR
, "%s/NS '%s' "
325 "extra GLUE AAAA record (%s)",
327 inet_ntop(AF_INET6
, rdata
.data
,
328 addrbuf
, sizeof(addrbuf
)));
329 add(namebuf
, ERR_EXTRA_AAAA
);
330 /* XXX950 make fatal for 9.5.0. */
331 /* answer = ISC_FALSE; */
333 dns_rdata_reset(&rdata
);
334 result
= dns_rdataset_next(aaaa
);
339 * Check that all addresses appear in the glue.
341 if (!logged(namebuf
, ERR_MISSING_GLUE
)) {
342 isc_boolean_t missing_glue
= ISC_FALSE
;
343 for (cur
= ai
; cur
!= NULL
; cur
= cur
->ai_next
) {
344 switch (cur
->ai_family
) {
347 ptr
= &((struct sockaddr_in
*)(cur
->ai_addr
))->sin_addr
;
352 ptr
= &((struct sockaddr_in6
*)(cur
->ai_addr
))->sin6_addr
;
359 if (dns_rdataset_isassociated(rdataset
))
360 result
= dns_rdataset_first(rdataset
);
362 result
= ISC_R_FAILURE
;
363 while (result
== ISC_R_SUCCESS
&& !match
) {
364 dns_rdataset_current(rdataset
, &rdata
);
365 if (memcmp(ptr
, rdata
.data
, rdata
.length
) == 0)
367 dns_rdata_reset(&rdata
);
368 result
= dns_rdataset_next(rdataset
);
371 dns_zone_log(zone
, ISC_LOG_ERROR
, "%s/NS '%s' "
372 "missing GLUE %s record (%s)",
373 ownerbuf
, namebuf
, type
,
374 inet_ntop(cur
->ai_family
, ptr
,
375 addrbuf
, sizeof(addrbuf
)));
376 /* XXX950 make fatal for 9.5.0. */
377 /* answer = ISC_FALSE; */
378 missing_glue
= ISC_TRUE
;
382 add(namebuf
, ERR_MISSING_GLUE
);
392 checkmx(dns_zone_t
*zone
, dns_name_t
*name
, dns_name_t
*owner
) {
393 #ifdef USE_GETADDRINFO
394 struct addrinfo hints
, *ai
, *cur
;
395 char namebuf
[DNS_NAME_FORMATSIZE
+ 1];
396 char ownerbuf
[DNS_NAME_FORMATSIZE
];
398 int level
= ISC_LOG_ERROR
;
399 isc_boolean_t answer
= ISC_TRUE
;
401 memset(&hints
, 0, sizeof(hints
));
402 hints
.ai_flags
= AI_CANONNAME
;
403 hints
.ai_family
= PF_UNSPEC
;
404 hints
.ai_socktype
= SOCK_STREAM
;
405 hints
.ai_protocol
= IPPROTO_TCP
;
407 dns_name_format(name
, namebuf
, sizeof(namebuf
) - 1);
411 if (dns_name_countlabels(name
) > 1U)
412 strcat(namebuf
, ".");
413 dns_name_format(owner
, ownerbuf
, sizeof(ownerbuf
));
415 result
= getaddrinfo(namebuf
, NULL
, &hints
, &ai
);
416 dns_name_format(name
, namebuf
, sizeof(namebuf
) - 1);
420 * Work around broken getaddrinfo() implementations that
421 * fail to set ai_canonname on first entry.
424 while (cur
!= NULL
&& cur
->ai_canonname
== NULL
&&
425 cur
->ai_next
!= NULL
)
427 if (cur
!= NULL
&& cur
->ai_canonname
!= NULL
&&
428 strcasecmp(cur
->ai_canonname
, namebuf
) != 0) {
429 if ((zone_options
& DNS_ZONEOPT_WARNMXCNAME
) != 0)
430 level
= ISC_LOG_WARNING
;
431 if ((zone_options
& DNS_ZONEOPT_IGNOREMXCNAME
) == 0) {
432 if (!logged(namebuf
, ERR_IS_MXCNAME
)) {
433 dns_zone_log(zone
, level
,
434 "%s/MX '%s' (out of zone)"
439 add(namebuf
, ERR_IS_MXCNAME
);
441 if (level
== ISC_LOG_ERROR
)
449 #if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME)
452 if (!logged(namebuf
, ERR_NO_ADDRESSES
)) {
453 dns_zone_log(zone
, ISC_LOG_ERROR
,
454 "%s/MX '%s' (out of zone) "
455 "has no addresses records (A or AAAA)",
457 add(namebuf
, ERR_NO_ADDRESSES
);
459 /* XXX950 make fatal for 9.5.0. */
463 if (!logged(namebuf
, ERR_LOOKUP_FAILURE
)) {
464 dns_zone_log(zone
, ISC_LOG_WARNING
,
465 "getaddrinfo(%s) failed: %s",
466 namebuf
, gai_strerror(result
));
467 add(namebuf
, ERR_LOOKUP_FAILURE
);
477 checksrv(dns_zone_t
*zone
, dns_name_t
*name
, dns_name_t
*owner
) {
478 #ifdef USE_GETADDRINFO
479 struct addrinfo hints
, *ai
, *cur
;
480 char namebuf
[DNS_NAME_FORMATSIZE
+ 1];
481 char ownerbuf
[DNS_NAME_FORMATSIZE
];
483 int level
= ISC_LOG_ERROR
;
484 isc_boolean_t answer
= ISC_TRUE
;
486 memset(&hints
, 0, sizeof(hints
));
487 hints
.ai_flags
= AI_CANONNAME
;
488 hints
.ai_family
= PF_UNSPEC
;
489 hints
.ai_socktype
= SOCK_STREAM
;
490 hints
.ai_protocol
= IPPROTO_TCP
;
492 dns_name_format(name
, namebuf
, sizeof(namebuf
) - 1);
496 if (dns_name_countlabels(name
) > 1U)
497 strcat(namebuf
, ".");
498 dns_name_format(owner
, ownerbuf
, sizeof(ownerbuf
));
500 result
= getaddrinfo(namebuf
, NULL
, &hints
, &ai
);
501 dns_name_format(name
, namebuf
, sizeof(namebuf
) - 1);
505 * Work around broken getaddrinfo() implementations that
506 * fail to set ai_canonname on first entry.
509 while (cur
!= NULL
&& cur
->ai_canonname
== NULL
&&
510 cur
->ai_next
!= NULL
)
512 if (cur
!= NULL
&& cur
->ai_canonname
!= NULL
&&
513 strcasecmp(cur
->ai_canonname
, namebuf
) != 0) {
514 if ((zone_options
& DNS_ZONEOPT_WARNSRVCNAME
) != 0)
515 level
= ISC_LOG_WARNING
;
516 if ((zone_options
& DNS_ZONEOPT_IGNORESRVCNAME
) == 0) {
517 if (!logged(namebuf
, ERR_IS_SRVCNAME
)) {
518 dns_zone_log(zone
, level
, "%s/SRV '%s'"
519 " (out of zone) is a "
520 "CNAME '%s' (illegal)",
523 add(namebuf
, ERR_IS_SRVCNAME
);
525 if (level
== ISC_LOG_ERROR
)
533 #if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME)
536 if (!logged(namebuf
, ERR_NO_ADDRESSES
)) {
537 dns_zone_log(zone
, ISC_LOG_ERROR
,
538 "%s/SRV '%s' (out of zone) "
539 "has no addresses records (A or AAAA)",
541 add(namebuf
, ERR_NO_ADDRESSES
);
543 /* XXX950 make fatal for 9.5.0. */
547 if (!logged(namebuf
, ERR_LOOKUP_FAILURE
)) {
548 dns_zone_log(zone
, ISC_LOG_WARNING
,
549 "getaddrinfo(%s) failed: %s",
550 namebuf
, gai_strerror(result
));
551 add(namebuf
, ERR_LOOKUP_FAILURE
);
561 setup_logging(isc_mem_t
*mctx
, FILE *errout
, isc_log_t
**logp
) {
562 isc_logdestination_t destination
;
563 isc_logconfig_t
*logconfig
= NULL
;
564 isc_log_t
*log
= NULL
;
566 RUNTIME_CHECK(isc_log_create(mctx
, &log
, &logconfig
) == ISC_R_SUCCESS
);
567 isc_log_registercategories(log
, categories
);
568 isc_log_setcontext(log
);
570 dns_log_setcontext(log
);
573 destination
.file
.stream
= errout
;
574 destination
.file
.name
= NULL
;
575 destination
.file
.versions
= ISC_LOG_ROLLNEVER
;
576 destination
.file
.maximum_size
= 0;
577 RUNTIME_CHECK(isc_log_createchannel(logconfig
, "stderr",
580 &destination
, 0) == ISC_R_SUCCESS
);
581 RUNTIME_CHECK(isc_log_usechannel(logconfig
, "stderr",
582 NULL
, NULL
) == ISC_R_SUCCESS
);
585 return (ISC_R_SUCCESS
);
588 /*% scan the zone for oversize TTLs */
590 check_ttls(dns_zone_t
*zone
, dns_ttl_t maxttl
) {
593 dns_dbversion_t
*version
= NULL
;
594 dns_dbnode_t
*node
= NULL
;
595 dns_dbiterator_t
*dbiter
= NULL
;
596 dns_rdatasetiter_t
*rdsiter
= NULL
;
597 dns_rdataset_t rdataset
;
598 dns_fixedname_t fname
;
600 dns_fixedname_init(&fname
);
601 name
= dns_fixedname_name(&fname
);
602 dns_rdataset_init(&rdataset
);
604 CHECK(dns_zone_getdb(zone
, &db
));
607 CHECK(dns_db_newversion(db
, &version
));
608 CHECK(dns_db_createiterator(db
, 0, &dbiter
));
610 for (result
= dns_dbiterator_first(dbiter
);
611 result
== ISC_R_SUCCESS
;
612 result
= dns_dbiterator_next(dbiter
)) {
613 result
= dns_dbiterator_current(dbiter
, &node
, name
);
614 if (result
== DNS_R_NEWORIGIN
)
615 result
= ISC_R_SUCCESS
;
618 CHECK(dns_db_allrdatasets(db
, node
, version
, 0, &rdsiter
));
619 for (result
= dns_rdatasetiter_first(rdsiter
);
620 result
== ISC_R_SUCCESS
;
621 result
= dns_rdatasetiter_next(rdsiter
)) {
622 dns_rdatasetiter_current(rdsiter
, &rdataset
);
623 if (rdataset
.ttl
> maxttl
) {
624 char nbuf
[DNS_NAME_FORMATSIZE
];
629 dns_name_format(name
, nbuf
, sizeof(nbuf
));
630 isc_buffer_init(&b
, tbuf
, sizeof(tbuf
) - 1);
631 CHECK(dns_rdatatype_totext(rdataset
.type
, &b
));
632 isc_buffer_usedregion(&b
, &r
);
633 r
.base
[r
.length
] = 0;
635 dns_zone_log(zone
, ISC_LOG_ERROR
,
636 "%s/%s TTL %d exceeds "
638 nbuf
, tbuf
, rdataset
.ttl
, maxttl
);
639 dns_rdataset_disassociate(&rdataset
);
642 dns_rdataset_disassociate(&rdataset
);
644 if (result
== ISC_R_NOMORE
)
645 result
= ISC_R_SUCCESS
;
648 dns_rdatasetiter_destroy(&rdsiter
);
649 dns_db_detachnode(db
, &node
);
652 if (result
== ISC_R_NOMORE
)
653 result
= ISC_R_SUCCESS
;
657 dns_db_detachnode(db
, &node
);
659 dns_rdatasetiter_destroy(&rdsiter
);
661 dns_dbiterator_destroy(&dbiter
);
663 dns_db_closeversion(db
, &version
, ISC_FALSE
);
672 load_zone(isc_mem_t
*mctx
, const char *zonename
, const char *filename
,
673 dns_masterformat_t fileformat
, const char *classname
,
674 dns_ttl_t maxttl
, dns_zone_t
**zonep
)
677 dns_rdataclass_t rdclass
;
678 isc_textregion_t region
;
680 dns_fixedname_t fixorigin
;
682 dns_zone_t
*zone
= NULL
;
684 REQUIRE(zonep
== NULL
|| *zonep
== NULL
);
687 fprintf(stderr
, "loading \"%s\" from \"%s\" class \"%s\"\n",
688 zonename
, filename
, classname
);
690 CHECK(dns_zone_create(&zone
, mctx
));
692 dns_zone_settype(zone
, dns_zone_master
);
694 isc_buffer_constinit(&buffer
, zonename
, strlen(zonename
));
695 isc_buffer_add(&buffer
, strlen(zonename
));
696 dns_fixedname_init(&fixorigin
);
697 origin
= dns_fixedname_name(&fixorigin
);
698 CHECK(dns_name_fromtext(origin
, &buffer
, dns_rootname
, 0, NULL
));
699 CHECK(dns_zone_setorigin(zone
, origin
));
700 CHECK(dns_zone_setdbtype(zone
, 1, (const char * const *) dbtype
));
701 CHECK(dns_zone_setfile2(zone
, filename
, fileformat
));
703 CHECK(dns_zone_setjournal(zone
, journal
));
705 DE_CONST(classname
, region
.base
);
706 region
.length
= strlen(classname
);
707 CHECK(dns_rdataclass_fromtext(&rdclass
, ®ion
));
709 dns_zone_setclass(zone
, rdclass
);
710 dns_zone_setoption(zone
, zone_options
, ISC_TRUE
);
711 dns_zone_setoption2(zone
, zone_options2
, ISC_TRUE
);
712 dns_zone_setoption(zone
, DNS_ZONEOPT_NOMERGE
, nomerge
);
714 dns_zone_setmaxttl(zone
, maxttl
);
717 dns_zone_setcheckmx(zone
, checkmx
);
719 dns_zone_setcheckns(zone
, checkns
);
721 dns_zone_setchecksrv(zone
, checksrv
);
723 CHECK(dns_zone_load(zone
));
726 * When loading map files we can't catch oversize TTLs during
727 * load, so we check for them here.
729 if (fileformat
== dns_masterformat_map
&& maxttl
!= 0) {
730 CHECK(check_ttls(zone
, maxttl
));
740 dns_zone_detach(&zone
);
746 dump_zone(const char *zonename
, dns_zone_t
*zone
, const char *filename
,
747 dns_masterformat_t fileformat
, const dns_master_style_t
*style
,
748 const isc_uint32_t rawversion
)
751 FILE *output
= stdout
;
754 flags
= (fileformat
== dns_masterformat_text
) ? "w+" : "wb+";
757 if (filename
!= NULL
&& strcmp(filename
, "-") != 0)
758 fprintf(stderr
, "dumping \"%s\" to \"%s\"\n",
761 fprintf(stderr
, "dumping \"%s\"\n", zonename
);
764 if (filename
!= NULL
&& strcmp(filename
, "-") != 0) {
765 result
= isc_stdio_open(filename
, flags
, &output
);
767 if (result
!= ISC_R_SUCCESS
) {
768 fprintf(stderr
, "could not open output "
769 "file \"%s\" for writing\n", filename
);
770 return (ISC_R_FAILURE
);
774 result
= dns_zone_dumptostream3(zone
, output
, fileformat
, style
,
776 if (output
!= stdout
)
777 (void)isc_stdio_close(output
);
785 WORD wVersionRequested
;
789 wVersionRequested
= MAKEWORD(2, 0);
791 err
= WSAStartup( wVersionRequested
, &wsaData
);
793 fprintf(stderr
, "WSAStartup() failed: %d\n", err
);
799 DestroySockets(void) {