4 * Copying and distribution of this file, with or without modification,
5 * are permitted in any medium without royalty provided the copyright
6 * notice and this notice are preserved. This file is offered as-is,
7 * without any warranty.
10 #include <ldns/ldns.h>
13 #include <netinet/in.h>
21 static char *progname;
23 #define countof(array) (sizeof(array)/sizeof(*(array)))
26 die(int code, const char *fmt, ...) {
30 fprintf(stderr, "%s: ", progname);
31 vfprintf(stderr, fmt, args);
32 fprintf(stderr, "\n");
38 ndots(const char *name) {
41 for (n = 0; (name = strchr(name, '.')); n++, name++);
45 /* General LDNS-specific utilities.
49 ldns_resolver_new_default(ldns_resolver **res) {
50 if (ldns_resolver_new_frm_file(res, NULL) == LDNS_STATUS_OK ||
51 (*res = ldns_resolver_new()) != NULL)
52 return LDNS_STATUS_OK;
53 return LDNS_STATUS_MEM_ERR;
57 ldns_resolver_push_default_servers(ldns_resolver *res) {
61 if ((status = ldns_str2rdf_a(&addr, "127.0.0.1")) != LDNS_STATUS_OK ||
62 (status = ldns_resolver_push_nameserver(res, addr)) != LDNS_STATUS_OK)
63 return ldns_rdf_deep_free(addr), status;
64 ldns_rdf_deep_free(addr);
65 if ((status = ldns_str2rdf_aaaa(&addr, "::1")) != LDNS_STATUS_OK ||
66 (status = ldns_resolver_push_nameserver(res, addr)) != LDNS_STATUS_OK)
67 return ldns_rdf_deep_free(addr), status;
68 ldns_rdf_deep_free(addr);
69 return LDNS_STATUS_OK;
73 ldns_rdf_new_addr_frm_str(const char *str) {
76 if ((addr = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A, str)) == NULL)
77 addr = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA, str);
82 ldns_resolver_remove_nameservers(ldns_resolver *res) {
83 while (ldns_resolver_nameserver_count(res) > 0)
84 ldns_rdf_deep_free(ldns_resolver_pop_nameserver(res));
88 ldns_rdf_reverse_a(ldns_rdf *addr, const char *base) {
93 buf = alloca(LDNS_IP4ADDRLEN*4 + len + 1);
94 for (len = i = 0; i < LDNS_IP4ADDRLEN; i++)
95 len += sprintf(&buf[len], "%d.",
96 (int)ldns_rdf_data(addr)[LDNS_IP4ADDRLEN - i - 1]);
97 sprintf(&buf[len], "%s", base);
98 return ldns_dname_new_frm_str(buf);
102 ldns_rdf_reverse_aaaa(ldns_rdf *addr, const char *base) {
107 buf = alloca(LDNS_IP6ADDRLEN*4 + len + 1);
108 for (i = 0; i < LDNS_IP6ADDRLEN; i++) {
109 uint8_t byte = ldns_rdf_data(addr)[LDNS_IP6ADDRLEN - i - 1];
110 sprintf(&buf[i*4], "%x.%x.", byte & 0x0F, byte >> 4);
112 sprintf(&buf[LDNS_IP6ADDRLEN*4], "%s", base);
113 return ldns_dname_new_frm_str(buf);
117 ldns_pkt_push_rr_soa(ldns_pkt *pkt, ldns_pkt_section sec,
118 const ldns_rdf *name, ldns_rr_class c, uint32_t serial) {
123 if ((rr = ldns_rr_new_frm_type(LDNS_RR_TYPE_SOA)) == NULL)
124 return LDNS_STATUS_MEM_ERR;
125 ldns_rr_set_class(rr, c);
126 ldns_rr_set_owner(rr, ldns_rdf_clone(name));
127 ldns_rr_set_ttl(rr, 0);
130 if ((rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_DNAME, 1, &n)) == NULL)
132 ldns_rr_set_rdf(rr, rdf, 0);
133 ldns_rr_set_rdf(rr, ldns_rdf_clone(rdf), 1);
136 if ((rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_INT32, 4, &n)) == NULL)
138 ldns_rr_set_rdf(rr, rdf, 2);
141 if ((rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_PERIOD, 4, &n)) == NULL)
143 ldns_rr_set_rdf(rr, rdf, 3);
144 ldns_rr_set_rdf(rr, ldns_rdf_clone(rdf), 4);
145 ldns_rr_set_rdf(rr, ldns_rdf_clone(rdf), 5);
146 ldns_rr_set_rdf(rr, ldns_rdf_clone(rdf), 6);
148 if (ldns_rr_rdf(rr, 1) == NULL || ldns_rr_rdf(rr, 4) == NULL ||
149 ldns_rr_rdf(rr, 5) == NULL || ldns_rr_rdf(rr, 6) == NULL ||
150 !ldns_pkt_push_rr(pkt, sec, rr))
152 return LDNS_STATUS_OK;
156 return LDNS_STATUS_MEM_ERR;
160 ldns_tcp_start(ldns_resolver *res, ldns_pkt *qpkt, int nameserver) {
161 /* This routine is based on ldns_axfr_start, with the major
162 * difference in that it takes a query packet explicitly.
164 struct sockaddr_storage *ns = NULL;
166 ldns_buffer *qbuf = NULL;
169 ns = ldns_rdf2native_sockaddr_storage(
170 res->_nameservers[nameserver], ldns_resolver_port(res), &ns_len);
172 status = LDNS_STATUS_MEM_ERR;
176 res->_socket = ldns_tcp_connect(
177 ns, (socklen_t)ns_len, ldns_resolver_timeout(res));
178 if (res->_socket <= 0) {
179 status = LDNS_STATUS_ADDRESS_ERR;
183 qbuf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
185 status = LDNS_STATUS_MEM_ERR;
189 status = ldns_pkt2buffer_wire(qbuf, qpkt);
190 if (status != LDNS_STATUS_OK)
193 if (ldns_tcp_send_query(qbuf, res->_socket, ns, (socklen_t)ns_len) == 0) {
194 status = LDNS_STATUS_NETWORK_ERR;
198 ldns_buffer_free(qbuf);
200 return LDNS_STATUS_OK;
203 ldns_buffer_free(qbuf);
205 if (res->_socket > 0) {
213 ldns_tcp_read(ldns_pkt **answer, ldns_resolver *res) {
215 struct timeval t1, t2;
219 if (res->_socket <= 0)
220 return LDNS_STATUS_ERR;
222 gettimeofday(&t1, NULL);
223 data = ldns_tcp_read_wire_timeout(
224 res->_socket, &size, ldns_resolver_timeout(res));
228 status = ldns_wire2pkt(answer, data, size);
230 if (status != LDNS_STATUS_OK)
233 gettimeofday(&t2, NULL);
234 ldns_pkt_set_querytime(*answer,
235 (uint32_t)((t2.tv_sec - t1.tv_sec)*1000) +
236 (t2.tv_usec - t1.tv_usec)/1000);
237 ldns_pkt_set_timestamp(*answer, t2);
243 return LDNS_STATUS_ERR;
247 ldns_tcp_close(ldns_resolver *res) {
248 if (res->_socket > 0) {
255 ldns_resolver_send_to(ldns_pkt **answer, ldns_resolver *res,
256 const ldns_rdf *name, ldns_rr_type t, ldns_rr_class c,
257 uint16_t flags, uint32_t ixfr_serial, int nameserver,
259 ldns_status status = LDNS_STATUS_OK;
263 int nscnt = ldns_resolver_nameserver_count(res);
264 ldns_rdf **ns = ldns_resolver_nameservers(res);
265 size_t *rtt = ldns_resolver_rtt(res);
267 ldns_resolver_set_nameservers(res, &ns[nameserver]);
268 ldns_resolver_set_rtt(res, &rtt[nameserver]);
269 ldns_resolver_set_nameserver_count(res, 1);
271 /* The next fragment should have been a call to
272 * ldns_resolver_prepare_query_pkt(), but starting with ldns
273 * version 1.6.17 that function tries to add it's own SOA
274 * records when rr_type is LDNS_RR_TYPE_IXFR, and we don't
277 qpkt = ldns_pkt_query_new(ldns_rdf_clone(name), t, c, flags);
279 status = LDNS_STATUS_ERR;
282 now.tv_sec = time(NULL);
284 ldns_pkt_set_timestamp(qpkt, now);
285 ldns_pkt_set_random_id(qpkt);
287 if (t == LDNS_RR_TYPE_IXFR) {
288 status = ldns_pkt_push_rr_soa(qpkt,
289 LDNS_SECTION_AUTHORITY, name, c, ixfr_serial);
290 if (status != LDNS_STATUS_OK) goto done;
293 status = ldns_resolver_send_pkt(answer, res, qpkt);
295 status = ldns_tcp_start(res, qpkt, 0);
296 if (status != LDNS_STATUS_OK) goto done;
297 status = ldns_tcp_read(answer, res);
298 if (status != LDNS_STATUS_OK) goto done;
299 ldns_pkt_set_answerfrom(*answer, ldns_rdf_clone(ns[0]));
305 ldns_resolver_set_nameservers(res, ns);
306 ldns_resolver_set_rtt(res, rtt);
307 ldns_resolver_set_nameserver_count(res, nscnt);
312 ldns_pkt_filter_answer(ldns_pkt *pkt, ldns_rr_type type) {
314 ldns_rr_list *rrlist;
318 rrlist = ldns_pkt_answer(pkt);
319 cnt = ldns_rr_list_rr_count(rrlist);
320 for (i = j = 0; i < cnt; i++) {
321 rr = ldns_rr_list_rr(rrlist, i);
322 rrtype = ldns_rr_get_type(rr);
323 if (type == LDNS_RR_TYPE_ANY ||
325 (type == LDNS_RR_TYPE_AXFR &&
326 (rrtype == LDNS_RR_TYPE_A ||
327 rrtype == LDNS_RR_TYPE_AAAA ||
328 rrtype == LDNS_RR_TYPE_NS ||
329 rrtype == LDNS_RR_TYPE_PTR)))
330 ldns_rr_list_set_rr(rrlist, rr, j++);
332 ldns_rr_list_set_rr_count(rrlist, j);
335 /* Packet content printing.
342 {LDNS_RR_TYPE_A, "has address"},
343 {LDNS_RR_TYPE_NS, "name server"},
344 {LDNS_RR_TYPE_CNAME, "is an alias for"},
345 {LDNS_RR_TYPE_WKS, "has well known services"},
346 {LDNS_RR_TYPE_PTR, "domain name pointer"},
347 {LDNS_RR_TYPE_HINFO, "host information"},
348 {LDNS_RR_TYPE_MX, "mail is handled by"},
349 {LDNS_RR_TYPE_TXT, "descriptive text"},
350 {LDNS_RR_TYPE_X25, "x25 address"},
351 {LDNS_RR_TYPE_ISDN, "ISDN address"},
352 {LDNS_RR_TYPE_SIG, "has signature"},
353 {LDNS_RR_TYPE_KEY, "has key"},
354 {LDNS_RR_TYPE_AAAA, "has IPv6 address"},
355 {LDNS_RR_TYPE_LOC, "location"},
359 print_opcode(ldns_pkt_opcode opcode) {
360 ldns_lookup_table *lt = ldns_lookup_by_id(ldns_opcodes, opcode);
363 printf("%s", lt->name);
365 printf("RESERVED%d", opcode);
369 print_rcode(uint8_t rcode) {
370 ldns_lookup_table *lt = ldns_lookup_by_id(ldns_rcodes, rcode);
373 printf("%s", lt->name);
375 printf("RESERVED%d", rcode);
379 print_rr_type(ldns_rr_type type) {
383 str = ldns_rr_type2str(type);
384 n = printf("%s", str);
390 print_rr_class(ldns_rr_class cls) {
394 str = ldns_rr_class2str(cls);
395 n = printf("%s", str);
401 print_rdf(ldns_rdf *rdf) {
405 str = ldns_rdf2str(rdf);
406 n = printf("%s", str);
412 print_rdf_nodot(ldns_rdf *rdf) {
416 str = ldns_rdf2str(rdf);
418 n = printf("%.*s", str[len-1] == '.' ? len-1 : len, str);
424 print_padding(int fromcol, int tocol) {
425 int col = fromcol, nextcol = fromcol + 8 - fromcol%8;
427 if (fromcol + 1 > tocol) tocol = fromcol + 1;
428 for (; nextcol <= tocol; col = nextcol, nextcol += 8)
430 for (; col < tocol; col++)
432 return col - fromcol;
436 print_rr_verbose(ldns_rr *rr) {
437 bool isq = ldns_rr_is_question(rr);
438 int rdcnt = ldns_rr_rd_count(rr);
441 /* bind9-host does not count the initial ';' here */
442 n = isq ? printf(";") : 0;
443 n = print_rdf(ldns_rr_owner(rr));
445 n += print_padding(n, 24);
446 n += printf("%d", ldns_rr_ttl(rr));
448 n += print_padding(n, 32);
449 n += print_rr_class(ldns_rr_get_class(rr));
450 n += print_padding(n, 40);
451 n += print_rr_type(ldns_rr_get_type(rr));
452 for (i = 0; i < rdcnt; i++) {
453 if (i == 0) print_padding(n, 48);
455 print_rdf(ldns_rr_rdf(rr, i));
461 print_pkt_section_verbose(const char *name, ldns_rr_list *rrlist) {
462 int i, cnt = ldns_rr_list_rr_count(rrlist);
466 printf(";; %s SECTION:\n", name);
467 for (i = 0; i < cnt; i++)
468 print_rr_verbose(ldns_rr_list_rr(rrlist, i));
473 print_pkt_verbose(ldns_pkt *pkt) {
476 printf(";; ->>HEADER<<- opcode: ");
477 print_opcode(ldns_pkt_get_opcode(pkt));
478 printf(", status: ");
479 print_rcode(ldns_pkt_get_rcode(pkt));
480 printf(", id: %u\n", ldns_pkt_id(pkt));
482 if (ldns_pkt_qr(pkt)) printf(" qr"), got_flags = 1;
483 if (ldns_pkt_aa(pkt)) printf(" aa"), got_flags = 1;
484 if (ldns_pkt_tc(pkt)) printf(" tc"), got_flags = 1;
485 if (ldns_pkt_rd(pkt)) printf(" rd"), got_flags = 1;
486 if (ldns_pkt_ra(pkt)) printf(" ra"), got_flags = 1;
487 if (ldns_pkt_ad(pkt)) printf(" ad"), got_flags = 1;
488 if (ldns_pkt_cd(pkt)) printf(" cd"), got_flags = 1;
489 if (!got_flags) printf(" ");
490 printf("; QUERY: %u, ANSWER: %u, AUTHORITY: %u, ADDITIONAL: %u\n",
491 ldns_pkt_qdcount(pkt), ldns_pkt_ancount(pkt),
492 ldns_pkt_nscount(pkt), ldns_pkt_arcount(pkt));
493 if (ldns_pkt_edns(pkt))
494 printf(";; EDNS: version: %u, udp=%u\n",
495 ldns_pkt_edns_version(pkt), ldns_pkt_edns_udp_size(pkt));
497 print_pkt_section_verbose("QUESTION", ldns_pkt_question(pkt));
498 print_pkt_section_verbose("ANSWER", ldns_pkt_answer(pkt));
499 print_pkt_section_verbose("AUTHORITY", ldns_pkt_authority(pkt));
500 print_pkt_section_verbose("ADDITIONAL", ldns_pkt_additional(pkt));
504 print_rr_short(ldns_rr *rr) {
505 ldns_rr_type type = ldns_rr_get_type(rr);
506 size_t i, rdcnt = ldns_rr_rd_count(rr);
508 print_rdf_nodot(ldns_rr_owner(rr));
510 for (i = 0; i < countof(rr_types); i++) {
511 if (rr_types[i].type == type) {
512 printf("%s", rr_types[i].text);
522 for (i = 0; i < rdcnt; i++) {
524 print_rdf(ldns_rr_rdf(rr, i));
530 print_pkt_short(ldns_pkt *pkt, bool print_rr_server) {
531 ldns_rr_list *rrlist = ldns_pkt_answer(pkt);
534 for (i = 0; i < ldns_rr_list_rr_count(rrlist); i++) {
535 if (print_rr_server) {
536 printf("Nameserver ");
537 print_rdf(ldns_pkt_answerfrom(pkt));
540 print_rr_short(ldns_rr_list_rr(rrlist, i));
545 print_received_line(ldns_resolver *res, ldns_pkt *pkt) {
546 char *from = ldns_rdf2str(ldns_pkt_answerfrom(pkt));
548 printf("Received %zu bytes from %s#%d in %d ms\n",
549 ldns_pkt_size(pkt), from, ldns_resolver_port(res),
550 ldns_pkt_querytime(pkt));
556 * Note that no memory is freed below this line by intention.
559 #define DEFAULT_TCP_TIMEOUT 10
560 #define DEFAULT_UDP_TIMEOUT 5
562 enum operation_mode { M_AXFR, M_IXFR, M_DEFAULT_Q, M_SINGLE_Q, M_SOA };
564 static enum operation_mode o_mode = M_DEFAULT_Q;
565 static bool o_ignore_servfail = true;
566 static bool o_ip6_int = false;
567 static bool o_print_pkt_server = false;
568 static bool o_print_rr_server = false;
569 static bool o_recursive = true;
570 static bool o_tcp = false;
571 static bool o_verbose = false;
572 static char *o_name = NULL;
573 static char *o_server = NULL;
574 static int o_ipversion = LDNS_RESOLV_INETANY;
575 static int o_ndots = 1;
576 static int o_retries = 1;
577 static ldns_rr_class o_rrclass = LDNS_RR_CLASS_IN;
578 static ldns_rr_type o_rrtype = (ldns_rr_type)-1;
579 static time_t o_timeout = 0;
580 static uint32_t o_ixfr_serial = 0;
585 "Usage: %s [-aCdilrsTvw46] [-c class] [-N ndots] [-R number]\n"
586 " %*c [-t type] [-W wait] name [server]\n"
587 "\t-a same as -v -t ANY\n"
588 "\t-C query SOA records from all authoritative name servers\n"
589 "\t-c use this query class (IN, CH, HS, etc)\n"
590 "\t-d produce verbose output, same as -v\n"
591 "\t-i use IP6.INT for IPv6 reverse lookups\n"
592 "\t-l list records in a zone via AXFR\n"
593 "\t-N consider names with at least this many dots as absolute\n"
594 "\t-R retry UDP queries this many times\n"
595 "\t-r disable recursive query\n"
596 "\t-s do not ignore SERVFAIL responses\n"
597 "\t-T send query via TCP\n"
598 "\t-t use this query type (A, AAAA, MX, etc)\n"
599 "\t-v produce verbose output\n"
600 "\t-w wait forever for a server reply\n"
601 "\t-W wait this many seconds for a reply\n"
602 "\t-4 use IPv4 only\n"
603 "\t-6 use IPv6 only\n",
604 progname, (int)strlen(progname), ' ');
609 parse_args(int argc, char *argv[]) {
613 while ((ch = getopt(argc, argv, "aCdilrsTvw46c:N:R:t:W:")) != -1) {
616 if (o_mode != M_AXFR)
618 o_rrtype = LDNS_RR_TYPE_ANY;
623 o_print_rr_server = true;
624 o_rrclass = LDNS_RR_CLASS_IN;
625 o_rrtype = LDNS_RR_TYPE_NS;
628 /* bind9-host sets o_mode to M_SINGLE_Q here */
629 o_rrclass = ldns_get_rr_class_by_name(optarg);
631 die(2, "invalid class: %s\n", optarg);
633 case 'd': o_verbose = true; break;
634 case 'i': o_ip6_int = true; break;
637 if (o_rrtype == (ldns_rr_type)-1)
638 o_rrtype = LDNS_RR_TYPE_AXFR;
642 o_ndots = atoi(optarg);
643 if (o_ndots < 0) o_ndots = 0;
646 /* bind9-host accepts and ignores this option */
648 case 'r': o_recursive = 0; break;
650 o_retries = atoi(optarg);
651 if (o_retries <= 0) o_retries = 1;
652 if (o_retries > 255) o_retries = 255;
654 case 's': o_ignore_servfail = false; break;
655 case 'T': o_tcp = true; break;
657 if (o_mode != M_AXFR)
659 if (strncasecmp(optarg, "ixfr=", 5) == 0) {
660 o_rrtype = LDNS_RR_TYPE_IXFR;
661 o_ixfr_serial = atol(optarg + 5);
663 o_rrtype = ldns_get_rr_type_by_name(optarg);
665 die(2, "invalid type: %s\n", optarg);
667 if (o_rrtype == LDNS_RR_TYPE_AXFR) {
669 o_rrtype = LDNS_RR_TYPE_ANY;
672 if (o_rrtype == LDNS_RR_TYPE_IXFR) {
674 o_rrtype = LDNS_RR_TYPE_ANY;
677 case 'v': o_verbose = true; break;
679 o_timeout = (time_t)INT_MAX;
682 o_timeout = atol(optarg);
683 if (o_timeout <= 0) o_timeout = 1;
685 case '4': o_ipversion = LDNS_RESOLV_INET; break;
686 case '6': o_ipversion = LDNS_RESOLV_INET6; break;
693 /* bind9-host ignores arguments after the 2-nd one */
699 o_print_pkt_server = true;
701 if (o_rrtype == (ldns_rr_type)-1)
702 o_rrtype = LDNS_RR_TYPE_A;
706 safe_str2rdf_dname(const char *name) {
710 if ((status = ldns_str2rdf_dname(&dname, name)) != LDNS_STATUS_OK) {
711 die(1, "'%s' is not a legal name (%s)",
712 name, ldns_get_errorstr_by_id(status));
718 safe_dname_cat_clone(const ldns_rdf *rd1, const ldns_rdf *rd2) {
719 ldns_rdf *result = ldns_dname_cat_clone(rd1, rd2);
722 die(1, "not enought memory for a domain name");
723 /* Why doesn't ldns_dname_cat_clone check this condition? */
724 if (ldns_rdf_size(result) > LDNS_MAX_DOMAINLEN)
725 die(1, "'%s' is not a legal name (%s)\n", ldns_rdf2str(result),
726 ldns_get_errorstr_by_id(LDNS_STATUS_DOMAINNAME_OVERFLOW));
731 query(ldns_resolver *res, ldns_rdf *domain, ldns_pkt **pkt, bool close_tcp) {
733 ldns_pkt_rcode rcode;
738 print_rdf_nodot(domain);
741 for (cnt = ldns_resolver_nameserver_count(res), i = 0; i < cnt; i++) {
742 status = ldns_resolver_send_to(pkt, res, domain, o_rrtype,
743 o_rrclass, o_recursive ? LDNS_RD : 0, o_ixfr_serial, i,
745 if (status != LDNS_STATUS_OK) {
749 if (ldns_pkt_tc(*pkt) && !ldns_resolver_usevc(res)) {
751 printf(";; Truncated, retrying in TCP mode.\n");
752 ldns_resolver_set_usevc(res, true);
753 status = ldns_resolver_send_to(pkt, res, domain, o_rrtype,
754 o_rrclass, o_recursive ? LDNS_RD : 0, o_ixfr_serial, i,
756 ldns_resolver_set_usevc(res, false);
757 if (status != LDNS_STATUS_OK)
760 rcode = ldns_pkt_get_rcode(*pkt);
761 if (o_ignore_servfail && rcode == LDNS_RCODE_SERVFAIL && cnt > 1)
763 return rcode == LDNS_RCODE_NOERROR;
766 printf(";; connection timed out; no servers could be reached\n");
773 search(ldns_resolver *res, ldns_rdf *domain, ldns_pkt **pkt,
774 bool absolute, bool close_tcp) {
775 ldns_rdf *dname, **searchlist;
778 if (absolute && query(res, domain, pkt, close_tcp))
781 if ((dname = ldns_resolver_domain(res)) != NULL) {
782 dname = safe_dname_cat_clone(domain, dname);
783 if (query(res, dname, pkt, close_tcp))
787 searchlist = ldns_resolver_searchlist(res);
788 n = ldns_resolver_searchlist_count(res);
789 for (i = 0; i < n; i++) {
790 dname = safe_dname_cat_clone(domain, searchlist[i]);
791 if (query(res, dname, pkt, close_tcp))
795 if (!absolute && query(res, domain, pkt, close_tcp))
802 report(ldns_resolver *res, ldns_rdf *domain, ldns_pkt *pkt) {
803 ldns_pkt_rcode rcode;
805 if (o_print_pkt_server) {
806 printf("Using domain server:\nName: %s\nAddress: ", o_server);
807 print_rdf(ldns_pkt_answerfrom(pkt));
808 printf("#%d\nAliases: \n\n", ldns_resolver_port(res));
809 o_print_pkt_server = false;
811 rcode = ldns_pkt_get_rcode(pkt);
812 if (rcode != LDNS_RCODE_NOERROR) {
814 print_rdf_nodot(domain);
815 printf(" not found: %d(", rcode);
820 print_pkt_verbose(pkt);
822 print_pkt_short(pkt, o_print_rr_server);
823 if (o_mode == M_SINGLE_Q &&
824 ldns_rr_list_rr_count(ldns_pkt_answer(pkt)) == 0) {
825 print_rdf_nodot(domain);
827 print_rr_type(o_rrtype);
833 print_received_line(res, pkt);
837 doquery(ldns_resolver *res, ldns_rdf *domain) {
841 q = query(res, domain, &pkt, true);
842 report(res, domain, pkt);
847 doquery_filtered(ldns_resolver *res, ldns_rdf *domain) {
851 q = query(res, domain, &pkt, true);
852 ldns_pkt_filter_answer(pkt, o_rrtype);
853 report(res, domain, pkt);
858 dosearch(ldns_resolver *res, ldns_rdf *domain, bool absolute) {
862 dname = search(res, domain, &pkt, absolute, true);
863 report(res, dname != NULL ? dname : domain, pkt);
864 return o_mode != M_DEFAULT_Q ? (dname != NULL) :
866 (o_rrtype = LDNS_RR_TYPE_AAAA, doquery_filtered(res, dname)) &&
867 (o_rrtype = LDNS_RR_TYPE_MX, doquery_filtered(res, dname));
871 dozonetransfer(ldns_resolver *res, ldns_rdf *domain, bool absolute) {
872 ldns_pkt *pkt, *nextpkt;
879 o_rrtype = (o_mode == M_AXFR) ? LDNS_RR_TYPE_AXFR : LDNS_RR_TYPE_IXFR;
880 dname = search(res, domain, &pkt, absolute, false);
883 rrl = ldns_pkt_answer(pkt);
884 for (i = ldns_rr_list_rr_count(rrl) - 1; i >= 0; i--) {
885 if (ldns_rr_get_type(ldns_rr_list_rr(rrl, i)) == LDNS_RR_TYPE_SOA)
888 ldns_pkt_filter_answer(pkt, rrtype);
889 report(res, dname != NULL ? dname : domain, pkt);
890 if ((dname == NULL) ||
891 (ldns_pkt_get_rcode(pkt) != LDNS_RCODE_NOERROR)) {
892 printf("; Transfer failed.\n");
900 if (ldns_tcp_read(&nextpkt, res) != LDNS_STATUS_OK) {
901 printf("; Transfer failed.\n");
904 ldns_pkt_set_answerfrom(nextpkt,
905 ldns_rdf_clone(ldns_pkt_answerfrom(pkt)));
912 dosoa(ldns_resolver *res, ldns_rdf *domain, bool absolute) {
913 ldns_rr_list *answer, **nsaddrs;
914 ldns_rdf *dname, *addr;
919 if ((dname = search(res, domain, &pkt, absolute, true)) == NULL)
922 answer = ldns_pkt_answer(pkt);
923 cnt = ldns_rr_list_rr_count(answer);
924 nsaddrs = alloca(cnt*sizeof(*nsaddrs));
925 for (n = 0, i = 0; i < cnt; i++)
926 if ((addr = ldns_rr_ns_nsdname(ldns_rr_list_rr(answer, i))) != NULL)
927 nsaddrs[n++] = ldns_get_rr_list_addr_by_name(res,
928 addr, LDNS_RR_CLASS_IN, 0);
930 o_print_pkt_server = false;
932 o_rrtype = LDNS_RR_TYPE_SOA;
933 for (i = 0; i < n; i++) {
934 cnt = ldns_rr_list_rr_count(nsaddrs[i]);
935 for (j = 0; j < cnt; j++) {
936 ldns_resolver_remove_nameservers(res);
937 rr = ldns_rr_list_rr(nsaddrs[i], j);
938 if ((ldns_resolver_ip6(res) == LDNS_RESOLV_INET &&
939 ldns_rr_get_type(rr) == LDNS_RR_TYPE_AAAA) ||
940 (ldns_resolver_ip6(res) == LDNS_RESOLV_INET6 &&
941 ldns_rr_get_type(rr) == LDNS_RR_TYPE_A))
943 if (ldns_resolver_push_nameserver_rr(res, rr) == LDNS_STATUS_OK)
944 /* bind9-host queries for domain, not dname here */
952 resolver_set_nameserver_hostname(ldns_resolver *res, const char *server) {
953 struct addrinfo hints, *ailist, *ai;
958 memset(&hints, 0, sizeof hints);
959 switch (ldns_resolver_ip6(res)) {
960 case LDNS_RESOLV_INET: hints.ai_family = PF_INET; break;
961 case LDNS_RESOLV_INET6: hints.ai_family = PF_INET6; break;
962 default: hints.ai_family = PF_UNSPEC; break;
964 hints.ai_socktype = SOCK_STREAM;
965 do err = getaddrinfo(server, NULL, &hints, &ailist);
966 while (err == EAI_AGAIN);
968 die(1, "couldn't get address for '%s': %s", server, gai_strerror(err));
969 for (ai = ailist; ai != NULL; ai = ai->ai_next) {
970 if ((rdf = ldns_sockaddr_storage2rdf((void*)ai->ai_addr, NULL)) == NULL)
971 die(1, "couldn't allocate an rdf: %s",
972 ldns_get_errorstr_by_id(LDNS_STATUS_MEM_ERR));
973 status = ldns_resolver_push_nameserver(res, rdf);
974 if (status != LDNS_STATUS_OK)
975 die(1, "couldn't push a nameserver address: %s",
976 ldns_get_errorstr_by_id(status));
981 resolver_set_nameserver_str(ldns_resolver *res, const char *server) {
984 ldns_resolver_remove_nameservers(res);
985 addr = ldns_rdf_new_addr_frm_str(server);
987 if (ldns_resolver_push_nameserver(res, addr) != LDNS_STATUS_OK)
988 die(1, "couldn't push a nameserver address");
990 resolver_set_nameserver_hostname(res, server);
994 main(int argc, char *argv[]) {
995 ldns_rdf *addr, *dname;
998 struct timeval restimeout;
1000 parse_args(argc, argv);
1002 status = ldns_resolver_new_default(&res);
1003 if (status != LDNS_STATUS_OK)
1004 die(1, "error creating resolver: %s", ldns_get_errorstr_by_id(status));
1005 if (ldns_resolver_nameserver_count(res) == 0)
1006 ldns_resolver_push_default_servers(res);
1008 ldns_resolver_set_usevc(res, o_tcp);
1009 restimeout.tv_sec = o_timeout > 0 ? o_timeout :
1010 o_tcp ? DEFAULT_TCP_TIMEOUT : DEFAULT_UDP_TIMEOUT;
1011 restimeout.tv_usec = 0;
1012 ldns_resolver_set_timeout(res, restimeout);
1013 ldns_resolver_set_retry(res, o_retries+1);
1014 ldns_resolver_set_ip6(res, o_ipversion);
1015 ldns_resolver_set_defnames(res, false);
1016 ldns_resolver_set_fallback(res, false);
1019 resolver_set_nameserver_str(res, o_server);
1021 if (ldns_str2rdf_a(&addr, o_name) == LDNS_STATUS_OK) {
1022 dname = ldns_rdf_reverse_a(addr, "in-addr.arpa");
1024 die(1, "can't reverse '%s': %s", o_name,
1025 ldns_get_errorstr_by_id(LDNS_STATUS_MEM_ERR));
1026 o_mode = M_SINGLE_Q;
1027 o_rrtype = LDNS_RR_TYPE_PTR;
1028 return !doquery(res, dname);
1029 } else if (ldns_str2rdf_aaaa(&addr, o_name) == LDNS_STATUS_OK) {
1030 dname = ldns_rdf_reverse_aaaa(addr, o_ip6_int ? "ip6.int" : "ip6.arpa");
1032 die(1, "can't reverse '%s': %s", o_name,
1033 ldns_get_errorstr_by_id(LDNS_STATUS_MEM_ERR));
1034 o_mode = M_SINGLE_Q;
1035 o_rrtype = LDNS_RR_TYPE_PTR;
1036 return !doquery(res, dname);
1038 return !(o_mode == M_SOA ? dosoa :
1039 o_mode == M_AXFR ? dozonetransfer :
1040 o_mode == M_IXFR ? dozonetransfer :
1042 (res, safe_str2rdf_dname(o_name), ndots(o_name) >= o_ndots);