/contrib/bind9/bin/check/check-tool.c

https://bitbucket.org/freebsd/freebsd-head/ · C · 690 lines · 558 code · 71 blank · 61 comment · 154 complexity · 269322b53fb0afaaf2cfc9ab61769835 MD5 · raw file

  1. /*
  2. * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
  3. * Copyright (C) 2000-2002 Internet Software Consortium.
  4. *
  5. * Permission to use, copy, modify, and/or distribute this software for any
  6. * purpose with or without fee is hereby granted, provided that the above
  7. * copyright notice and this permission notice appear in all copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  10. * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  11. * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  12. * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  13. * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  14. * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  15. * PERFORMANCE OF THIS SOFTWARE.
  16. */
  17. /* $Id: check-tool.c,v 1.41 2010/09/07 23:46:59 tbox Exp $ */
  18. /*! \file */
  19. #include <config.h>
  20. #include <stdio.h>
  21. #ifdef _WIN32
  22. #include <Winsock2.h>
  23. #endif
  24. #include "check-tool.h"
  25. #include <isc/buffer.h>
  26. #include <isc/log.h>
  27. #include <isc/mem.h>
  28. #include <isc/netdb.h>
  29. #include <isc/net.h>
  30. #include <isc/region.h>
  31. #include <isc/stdio.h>
  32. #include <isc/string.h>
  33. #include <isc/symtab.h>
  34. #include <isc/types.h>
  35. #include <isc/util.h>
  36. #include <dns/fixedname.h>
  37. #include <dns/log.h>
  38. #include <dns/name.h>
  39. #include <dns/rdata.h>
  40. #include <dns/rdataclass.h>
  41. #include <dns/rdataset.h>
  42. #include <dns/types.h>
  43. #include <dns/zone.h>
  44. #include <isccfg/log.h>
  45. #ifndef CHECK_SIBLING
  46. #define CHECK_SIBLING 1
  47. #endif
  48. #ifndef CHECK_LOCAL
  49. #define CHECK_LOCAL 1
  50. #endif
  51. #ifdef HAVE_ADDRINFO
  52. #ifdef HAVE_GETADDRINFO
  53. #ifdef HAVE_GAISTRERROR
  54. #define USE_GETADDRINFO
  55. #endif
  56. #endif
  57. #endif
  58. #define CHECK(r) \
  59. do { \
  60. result = (r); \
  61. if (result != ISC_R_SUCCESS) \
  62. goto cleanup; \
  63. } while (0)
  64. #define ERR_IS_CNAME 1
  65. #define ERR_NO_ADDRESSES 2
  66. #define ERR_LOOKUP_FAILURE 3
  67. #define ERR_EXTRA_A 4
  68. #define ERR_EXTRA_AAAA 5
  69. #define ERR_MISSING_GLUE 5
  70. #define ERR_IS_MXCNAME 6
  71. #define ERR_IS_SRVCNAME 7
  72. static const char *dbtype[] = { "rbt" };
  73. int debug = 0;
  74. isc_boolean_t nomerge = ISC_TRUE;
  75. #if CHECK_LOCAL
  76. isc_boolean_t docheckmx = ISC_TRUE;
  77. isc_boolean_t dochecksrv = ISC_TRUE;
  78. isc_boolean_t docheckns = ISC_TRUE;
  79. #else
  80. isc_boolean_t docheckmx = ISC_FALSE;
  81. isc_boolean_t dochecksrv = ISC_FALSE;
  82. isc_boolean_t docheckns = ISC_FALSE;
  83. #endif
  84. unsigned int zone_options = DNS_ZONEOPT_CHECKNS |
  85. DNS_ZONEOPT_CHECKMX |
  86. DNS_ZONEOPT_MANYERRORS |
  87. DNS_ZONEOPT_CHECKNAMES |
  88. DNS_ZONEOPT_CHECKINTEGRITY |
  89. #if CHECK_SIBLING
  90. DNS_ZONEOPT_CHECKSIBLING |
  91. #endif
  92. DNS_ZONEOPT_CHECKWILDCARD |
  93. DNS_ZONEOPT_WARNMXCNAME |
  94. DNS_ZONEOPT_WARNSRVCNAME;
  95. /*
  96. * This needs to match the list in bin/named/log.c.
  97. */
  98. static isc_logcategory_t categories[] = {
  99. { "", 0 },
  100. { "client", 0 },
  101. { "network", 0 },
  102. { "update", 0 },
  103. { "queries", 0 },
  104. { "unmatched", 0 },
  105. { "update-security", 0 },
  106. { "query-errors", 0 },
  107. { NULL, 0 }
  108. };
  109. static isc_symtab_t *symtab = NULL;
  110. static isc_mem_t *sym_mctx;
  111. static void
  112. freekey(char *key, unsigned int type, isc_symvalue_t value, void *userarg) {
  113. UNUSED(type);
  114. UNUSED(value);
  115. isc_mem_free(userarg, key);
  116. }
  117. static void
  118. add(char *key, int value) {
  119. isc_result_t result;
  120. isc_symvalue_t symvalue;
  121. if (sym_mctx == NULL) {
  122. result = isc_mem_create(0, 0, &sym_mctx);
  123. if (result != ISC_R_SUCCESS)
  124. return;
  125. }
  126. if (symtab == NULL) {
  127. result = isc_symtab_create(sym_mctx, 100, freekey, sym_mctx,
  128. ISC_FALSE, &symtab);
  129. if (result != ISC_R_SUCCESS)
  130. return;
  131. }
  132. key = isc_mem_strdup(sym_mctx, key);
  133. if (key == NULL)
  134. return;
  135. symvalue.as_pointer = NULL;
  136. result = isc_symtab_define(symtab, key, value, symvalue,
  137. isc_symexists_reject);
  138. if (result != ISC_R_SUCCESS)
  139. isc_mem_free(sym_mctx, key);
  140. }
  141. static isc_boolean_t
  142. logged(char *key, int value) {
  143. isc_result_t result;
  144. if (symtab == NULL)
  145. return (ISC_FALSE);
  146. result = isc_symtab_lookup(symtab, key, value, NULL);
  147. if (result == ISC_R_SUCCESS)
  148. return (ISC_TRUE);
  149. return (ISC_FALSE);
  150. }
  151. static isc_boolean_t
  152. checkns(dns_zone_t *zone, dns_name_t *name, dns_name_t *owner,
  153. dns_rdataset_t *a, dns_rdataset_t *aaaa)
  154. {
  155. #ifdef USE_GETADDRINFO
  156. dns_rdataset_t *rdataset;
  157. dns_rdata_t rdata = DNS_RDATA_INIT;
  158. struct addrinfo hints, *ai, *cur;
  159. char namebuf[DNS_NAME_FORMATSIZE + 1];
  160. char ownerbuf[DNS_NAME_FORMATSIZE];
  161. char addrbuf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:123.123.123.123")];
  162. isc_boolean_t answer = ISC_TRUE;
  163. isc_boolean_t match;
  164. const char *type;
  165. void *ptr = NULL;
  166. int result;
  167. REQUIRE(a == NULL || !dns_rdataset_isassociated(a) ||
  168. a->type == dns_rdatatype_a);
  169. REQUIRE(aaaa == NULL || !dns_rdataset_isassociated(aaaa) ||
  170. aaaa->type == dns_rdatatype_aaaa);
  171. memset(&hints, 0, sizeof(hints));
  172. hints.ai_flags = AI_CANONNAME;
  173. hints.ai_family = PF_UNSPEC;
  174. hints.ai_socktype = SOCK_STREAM;
  175. hints.ai_protocol = IPPROTO_TCP;
  176. dns_name_format(name, namebuf, sizeof(namebuf) - 1);
  177. /*
  178. * Turn off search.
  179. */
  180. if (dns_name_countlabels(name) > 1U)
  181. strcat(namebuf, ".");
  182. dns_name_format(owner, ownerbuf, sizeof(ownerbuf));
  183. result = getaddrinfo(namebuf, NULL, &hints, &ai);
  184. dns_name_format(name, namebuf, sizeof(namebuf) - 1);
  185. switch (result) {
  186. case 0:
  187. /*
  188. * Work around broken getaddrinfo() implementations that
  189. * fail to set ai_canonname on first entry.
  190. */
  191. cur = ai;
  192. while (cur != NULL && cur->ai_canonname == NULL &&
  193. cur->ai_next != NULL)
  194. cur = cur->ai_next;
  195. if (cur != NULL && cur->ai_canonname != NULL &&
  196. strcasecmp(cur->ai_canonname, namebuf) != 0 &&
  197. !logged(namebuf, ERR_IS_CNAME)) {
  198. dns_zone_log(zone, ISC_LOG_ERROR,
  199. "%s/NS '%s' (out of zone) "
  200. "is a CNAME '%s' (illegal)",
  201. ownerbuf, namebuf,
  202. cur->ai_canonname);
  203. /* XXX950 make fatal for 9.5.0 */
  204. /* answer = ISC_FALSE; */
  205. add(namebuf, ERR_IS_CNAME);
  206. }
  207. break;
  208. case EAI_NONAME:
  209. #if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME)
  210. case EAI_NODATA:
  211. #endif
  212. if (!logged(namebuf, ERR_NO_ADDRESSES)) {
  213. dns_zone_log(zone, ISC_LOG_ERROR,
  214. "%s/NS '%s' (out of zone) "
  215. "has no addresses records (A or AAAA)",
  216. ownerbuf, namebuf);
  217. add(namebuf, ERR_NO_ADDRESSES);
  218. }
  219. /* XXX950 make fatal for 9.5.0 */
  220. return (ISC_TRUE);
  221. default:
  222. if (!logged(namebuf, ERR_LOOKUP_FAILURE)) {
  223. dns_zone_log(zone, ISC_LOG_WARNING,
  224. "getaddrinfo(%s) failed: %s",
  225. namebuf, gai_strerror(result));
  226. add(namebuf, ERR_LOOKUP_FAILURE);
  227. }
  228. return (ISC_TRUE);
  229. }
  230. if (a == NULL || aaaa == NULL)
  231. return (answer);
  232. /*
  233. * Check that all glue records really exist.
  234. */
  235. if (!dns_rdataset_isassociated(a))
  236. goto checkaaaa;
  237. result = dns_rdataset_first(a);
  238. while (result == ISC_R_SUCCESS) {
  239. dns_rdataset_current(a, &rdata);
  240. match = ISC_FALSE;
  241. for (cur = ai; cur != NULL; cur = cur->ai_next) {
  242. if (cur->ai_family != AF_INET)
  243. continue;
  244. ptr = &((struct sockaddr_in *)(cur->ai_addr))->sin_addr;
  245. if (memcmp(ptr, rdata.data, rdata.length) == 0) {
  246. match = ISC_TRUE;
  247. break;
  248. }
  249. }
  250. if (!match && !logged(namebuf, ERR_EXTRA_A)) {
  251. dns_zone_log(zone, ISC_LOG_ERROR, "%s/NS '%s' "
  252. "extra GLUE A record (%s)",
  253. ownerbuf, namebuf,
  254. inet_ntop(AF_INET, rdata.data,
  255. addrbuf, sizeof(addrbuf)));
  256. add(namebuf, ERR_EXTRA_A);
  257. /* XXX950 make fatal for 9.5.0 */
  258. /* answer = ISC_FALSE; */
  259. }
  260. dns_rdata_reset(&rdata);
  261. result = dns_rdataset_next(a);
  262. }
  263. checkaaaa:
  264. if (!dns_rdataset_isassociated(aaaa))
  265. goto checkmissing;
  266. result = dns_rdataset_first(aaaa);
  267. while (result == ISC_R_SUCCESS) {
  268. dns_rdataset_current(aaaa, &rdata);
  269. match = ISC_FALSE;
  270. for (cur = ai; cur != NULL; cur = cur->ai_next) {
  271. if (cur->ai_family != AF_INET6)
  272. continue;
  273. ptr = &((struct sockaddr_in6 *)(cur->ai_addr))->sin6_addr;
  274. if (memcmp(ptr, rdata.data, rdata.length) == 0) {
  275. match = ISC_TRUE;
  276. break;
  277. }
  278. }
  279. if (!match && !logged(namebuf, ERR_EXTRA_AAAA)) {
  280. dns_zone_log(zone, ISC_LOG_ERROR, "%s/NS '%s' "
  281. "extra GLUE AAAA record (%s)",
  282. ownerbuf, namebuf,
  283. inet_ntop(AF_INET6, rdata.data,
  284. addrbuf, sizeof(addrbuf)));
  285. add(namebuf, ERR_EXTRA_AAAA);
  286. /* XXX950 make fatal for 9.5.0. */
  287. /* answer = ISC_FALSE; */
  288. }
  289. dns_rdata_reset(&rdata);
  290. result = dns_rdataset_next(aaaa);
  291. }
  292. checkmissing:
  293. /*
  294. * Check that all addresses appear in the glue.
  295. */
  296. if (!logged(namebuf, ERR_MISSING_GLUE)) {
  297. isc_boolean_t missing_glue = ISC_FALSE;
  298. for (cur = ai; cur != NULL; cur = cur->ai_next) {
  299. switch (cur->ai_family) {
  300. case AF_INET:
  301. rdataset = a;
  302. ptr = &((struct sockaddr_in *)(cur->ai_addr))->sin_addr;
  303. type = "A";
  304. break;
  305. case AF_INET6:
  306. rdataset = aaaa;
  307. ptr = &((struct sockaddr_in6 *)(cur->ai_addr))->sin6_addr;
  308. type = "AAAA";
  309. break;
  310. default:
  311. continue;
  312. }
  313. match = ISC_FALSE;
  314. if (dns_rdataset_isassociated(rdataset))
  315. result = dns_rdataset_first(rdataset);
  316. else
  317. result = ISC_R_FAILURE;
  318. while (result == ISC_R_SUCCESS && !match) {
  319. dns_rdataset_current(rdataset, &rdata);
  320. if (memcmp(ptr, rdata.data, rdata.length) == 0)
  321. match = ISC_TRUE;
  322. dns_rdata_reset(&rdata);
  323. result = dns_rdataset_next(rdataset);
  324. }
  325. if (!match) {
  326. dns_zone_log(zone, ISC_LOG_ERROR, "%s/NS '%s' "
  327. "missing GLUE %s record (%s)",
  328. ownerbuf, namebuf, type,
  329. inet_ntop(cur->ai_family, ptr,
  330. addrbuf, sizeof(addrbuf)));
  331. /* XXX950 make fatal for 9.5.0. */
  332. /* answer = ISC_FALSE; */
  333. missing_glue = ISC_TRUE;
  334. }
  335. }
  336. if (missing_glue)
  337. add(namebuf, ERR_MISSING_GLUE);
  338. }
  339. freeaddrinfo(ai);
  340. return (answer);
  341. #else
  342. return (ISC_TRUE);
  343. #endif
  344. }
  345. static isc_boolean_t
  346. checkmx(dns_zone_t *zone, dns_name_t *name, dns_name_t *owner) {
  347. #ifdef USE_GETADDRINFO
  348. struct addrinfo hints, *ai, *cur;
  349. char namebuf[DNS_NAME_FORMATSIZE + 1];
  350. char ownerbuf[DNS_NAME_FORMATSIZE];
  351. int result;
  352. int level = ISC_LOG_ERROR;
  353. isc_boolean_t answer = ISC_TRUE;
  354. memset(&hints, 0, sizeof(hints));
  355. hints.ai_flags = AI_CANONNAME;
  356. hints.ai_family = PF_UNSPEC;
  357. hints.ai_socktype = SOCK_STREAM;
  358. hints.ai_protocol = IPPROTO_TCP;
  359. dns_name_format(name, namebuf, sizeof(namebuf) - 1);
  360. /*
  361. * Turn off search.
  362. */
  363. if (dns_name_countlabels(name) > 1U)
  364. strcat(namebuf, ".");
  365. dns_name_format(owner, ownerbuf, sizeof(ownerbuf));
  366. result = getaddrinfo(namebuf, NULL, &hints, &ai);
  367. dns_name_format(name, namebuf, sizeof(namebuf) - 1);
  368. switch (result) {
  369. case 0:
  370. /*
  371. * Work around broken getaddrinfo() implementations that
  372. * fail to set ai_canonname on first entry.
  373. */
  374. cur = ai;
  375. while (cur != NULL && cur->ai_canonname == NULL &&
  376. cur->ai_next != NULL)
  377. cur = cur->ai_next;
  378. if (cur != NULL && cur->ai_canonname != NULL &&
  379. strcasecmp(cur->ai_canonname, namebuf) != 0) {
  380. if ((zone_options & DNS_ZONEOPT_WARNMXCNAME) != 0)
  381. level = ISC_LOG_WARNING;
  382. if ((zone_options & DNS_ZONEOPT_IGNOREMXCNAME) == 0) {
  383. if (!logged(namebuf, ERR_IS_MXCNAME)) {
  384. dns_zone_log(zone, level,
  385. "%s/MX '%s' (out of zone)"
  386. " is a CNAME '%s' "
  387. "(illegal)",
  388. ownerbuf, namebuf,
  389. cur->ai_canonname);
  390. add(namebuf, ERR_IS_MXCNAME);
  391. }
  392. if (level == ISC_LOG_ERROR)
  393. answer = ISC_FALSE;
  394. }
  395. }
  396. freeaddrinfo(ai);
  397. return (answer);
  398. case EAI_NONAME:
  399. #if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME)
  400. case EAI_NODATA:
  401. #endif
  402. if (!logged(namebuf, ERR_NO_ADDRESSES)) {
  403. dns_zone_log(zone, ISC_LOG_ERROR,
  404. "%s/MX '%s' (out of zone) "
  405. "has no addresses records (A or AAAA)",
  406. ownerbuf, namebuf);
  407. add(namebuf, ERR_NO_ADDRESSES);
  408. }
  409. /* XXX950 make fatal for 9.5.0. */
  410. return (ISC_TRUE);
  411. default:
  412. if (!logged(namebuf, ERR_LOOKUP_FAILURE)) {
  413. dns_zone_log(zone, ISC_LOG_WARNING,
  414. "getaddrinfo(%s) failed: %s",
  415. namebuf, gai_strerror(result));
  416. add(namebuf, ERR_LOOKUP_FAILURE);
  417. }
  418. return (ISC_TRUE);
  419. }
  420. #else
  421. return (ISC_TRUE);
  422. #endif
  423. }
  424. static isc_boolean_t
  425. checksrv(dns_zone_t *zone, dns_name_t *name, dns_name_t *owner) {
  426. #ifdef USE_GETADDRINFO
  427. struct addrinfo hints, *ai, *cur;
  428. char namebuf[DNS_NAME_FORMATSIZE + 1];
  429. char ownerbuf[DNS_NAME_FORMATSIZE];
  430. int result;
  431. int level = ISC_LOG_ERROR;
  432. isc_boolean_t answer = ISC_TRUE;
  433. memset(&hints, 0, sizeof(hints));
  434. hints.ai_flags = AI_CANONNAME;
  435. hints.ai_family = PF_UNSPEC;
  436. hints.ai_socktype = SOCK_STREAM;
  437. hints.ai_protocol = IPPROTO_TCP;
  438. dns_name_format(name, namebuf, sizeof(namebuf) - 1);
  439. /*
  440. * Turn off search.
  441. */
  442. if (dns_name_countlabels(name) > 1U)
  443. strcat(namebuf, ".");
  444. dns_name_format(owner, ownerbuf, sizeof(ownerbuf));
  445. result = getaddrinfo(namebuf, NULL, &hints, &ai);
  446. dns_name_format(name, namebuf, sizeof(namebuf) - 1);
  447. switch (result) {
  448. case 0:
  449. /*
  450. * Work around broken getaddrinfo() implementations that
  451. * fail to set ai_canonname on first entry.
  452. */
  453. cur = ai;
  454. while (cur != NULL && cur->ai_canonname == NULL &&
  455. cur->ai_next != NULL)
  456. cur = cur->ai_next;
  457. if (cur != NULL && cur->ai_canonname != NULL &&
  458. strcasecmp(cur->ai_canonname, namebuf) != 0) {
  459. if ((zone_options & DNS_ZONEOPT_WARNSRVCNAME) != 0)
  460. level = ISC_LOG_WARNING;
  461. if ((zone_options & DNS_ZONEOPT_IGNORESRVCNAME) == 0) {
  462. if (!logged(namebuf, ERR_IS_SRVCNAME)) {
  463. dns_zone_log(zone, level, "%s/SRV '%s'"
  464. " (out of zone) is a "
  465. "CNAME '%s' (illegal)",
  466. ownerbuf, namebuf,
  467. cur->ai_canonname);
  468. add(namebuf, ERR_IS_SRVCNAME);
  469. }
  470. if (level == ISC_LOG_ERROR)
  471. answer = ISC_FALSE;
  472. }
  473. }
  474. freeaddrinfo(ai);
  475. return (answer);
  476. case EAI_NONAME:
  477. #if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME)
  478. case EAI_NODATA:
  479. #endif
  480. if (!logged(namebuf, ERR_NO_ADDRESSES)) {
  481. dns_zone_log(zone, ISC_LOG_ERROR,
  482. "%s/SRV '%s' (out of zone) "
  483. "has no addresses records (A or AAAA)",
  484. ownerbuf, namebuf);
  485. add(namebuf, ERR_NO_ADDRESSES);
  486. }
  487. /* XXX950 make fatal for 9.5.0. */
  488. return (ISC_TRUE);
  489. default:
  490. if (!logged(namebuf, ERR_LOOKUP_FAILURE)) {
  491. dns_zone_log(zone, ISC_LOG_WARNING,
  492. "getaddrinfo(%s) failed: %s",
  493. namebuf, gai_strerror(result));
  494. add(namebuf, ERR_LOOKUP_FAILURE);
  495. }
  496. return (ISC_TRUE);
  497. }
  498. #else
  499. return (ISC_TRUE);
  500. #endif
  501. }
  502. isc_result_t
  503. setup_logging(isc_mem_t *mctx, FILE *errout, isc_log_t **logp) {
  504. isc_logdestination_t destination;
  505. isc_logconfig_t *logconfig = NULL;
  506. isc_log_t *log = NULL;
  507. RUNTIME_CHECK(isc_log_create(mctx, &log, &logconfig) == ISC_R_SUCCESS);
  508. isc_log_registercategories(log, categories);
  509. isc_log_setcontext(log);
  510. dns_log_init(log);
  511. dns_log_setcontext(log);
  512. cfg_log_init(log);
  513. destination.file.stream = errout;
  514. destination.file.name = NULL;
  515. destination.file.versions = ISC_LOG_ROLLNEVER;
  516. destination.file.maximum_size = 0;
  517. RUNTIME_CHECK(isc_log_createchannel(logconfig, "stderr",
  518. ISC_LOG_TOFILEDESC,
  519. ISC_LOG_DYNAMIC,
  520. &destination, 0) == ISC_R_SUCCESS);
  521. RUNTIME_CHECK(isc_log_usechannel(logconfig, "stderr",
  522. NULL, NULL) == ISC_R_SUCCESS);
  523. *logp = log;
  524. return (ISC_R_SUCCESS);
  525. }
  526. /*% load the zone */
  527. isc_result_t
  528. load_zone(isc_mem_t *mctx, const char *zonename, const char *filename,
  529. dns_masterformat_t fileformat, const char *classname,
  530. dns_zone_t **zonep)
  531. {
  532. isc_result_t result;
  533. dns_rdataclass_t rdclass;
  534. isc_textregion_t region;
  535. isc_buffer_t buffer;
  536. dns_fixedname_t fixorigin;
  537. dns_name_t *origin;
  538. dns_zone_t *zone = NULL;
  539. REQUIRE(zonep == NULL || *zonep == NULL);
  540. if (debug)
  541. fprintf(stderr, "loading \"%s\" from \"%s\" class \"%s\"\n",
  542. zonename, filename, classname);
  543. CHECK(dns_zone_create(&zone, mctx));
  544. dns_zone_settype(zone, dns_zone_master);
  545. isc_buffer_init(&buffer, zonename, strlen(zonename));
  546. isc_buffer_add(&buffer, strlen(zonename));
  547. dns_fixedname_init(&fixorigin);
  548. origin = dns_fixedname_name(&fixorigin);
  549. CHECK(dns_name_fromtext(origin, &buffer, dns_rootname, 0, NULL));
  550. CHECK(dns_zone_setorigin(zone, origin));
  551. CHECK(dns_zone_setdbtype(zone, 1, (const char * const *) dbtype));
  552. CHECK(dns_zone_setfile2(zone, filename, fileformat));
  553. DE_CONST(classname, region.base);
  554. region.length = strlen(classname);
  555. CHECK(dns_rdataclass_fromtext(&rdclass, &region));
  556. dns_zone_setclass(zone, rdclass);
  557. dns_zone_setoption(zone, zone_options, ISC_TRUE);
  558. dns_zone_setoption(zone, DNS_ZONEOPT_NOMERGE, nomerge);
  559. if (docheckmx)
  560. dns_zone_setcheckmx(zone, checkmx);
  561. if (docheckns)
  562. dns_zone_setcheckns(zone, checkns);
  563. if (dochecksrv)
  564. dns_zone_setchecksrv(zone, checksrv);
  565. CHECK(dns_zone_load(zone));
  566. if (zonep != NULL) {
  567. *zonep = zone;
  568. zone = NULL;
  569. }
  570. cleanup:
  571. if (zone != NULL)
  572. dns_zone_detach(&zone);
  573. return (result);
  574. }
  575. /*% dump the zone */
  576. isc_result_t
  577. dump_zone(const char *zonename, dns_zone_t *zone, const char *filename,
  578. dns_masterformat_t fileformat, const dns_master_style_t *style)
  579. {
  580. isc_result_t result;
  581. FILE *output = stdout;
  582. if (debug) {
  583. if (filename != NULL && strcmp(filename, "-") != 0)
  584. fprintf(stderr, "dumping \"%s\" to \"%s\"\n",
  585. zonename, filename);
  586. else
  587. fprintf(stderr, "dumping \"%s\"\n", zonename);
  588. }
  589. if (filename != NULL && strcmp(filename, "-") != 0) {
  590. result = isc_stdio_open(filename, "w+", &output);
  591. if (result != ISC_R_SUCCESS) {
  592. fprintf(stderr, "could not open output "
  593. "file \"%s\" for writing\n", filename);
  594. return (ISC_R_FAILURE);
  595. }
  596. }
  597. result = dns_zone_dumptostream2(zone, output, fileformat, style);
  598. if (output != stdout)
  599. (void)isc_stdio_close(output);
  600. return (result);
  601. }
  602. #ifdef _WIN32
  603. void
  604. InitSockets(void) {
  605. WORD wVersionRequested;
  606. WSADATA wsaData;
  607. int err;
  608. wVersionRequested = MAKEWORD(2, 0);
  609. err = WSAStartup( wVersionRequested, &wsaData );
  610. if (err != 0) {
  611. fprintf(stderr, "WSAStartup() failed: %d\n", err);
  612. exit(1);
  613. }
  614. }
  615. void
  616. DestroySockets(void) {
  617. WSACleanup();
  618. }
  619. #endif