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 <netinet/in.h>
18 #include <ldns/ldns.h>
23 static char *progname
;
25 #define countof(array) (sizeof(array)/sizeof(*(array)))
28 die(int code
, const char *fmt
, ...) {
32 fprintf(stderr
, "%s: ", progname
);
33 vfprintf(stderr
, fmt
, args
);
34 fprintf(stderr
, "\n");
40 ndots(const char *name
) {
43 for (n
= 0; (name
= strchr(name
, '.')); n
++, name
++);
47 /* General LDNS-specific utilities.
51 ldns_resolver_new_default(ldns_resolver
**res
) {
52 if (ldns_resolver_new_frm_file(res
, NULL
) == LDNS_STATUS_OK
||
53 (*res
= ldns_resolver_new()) != NULL
)
54 return LDNS_STATUS_OK
;
55 return LDNS_STATUS_MEM_ERR
;
59 ldns_resolver_push_default_servers(ldns_resolver
*res
) {
63 if ((status
= ldns_str2rdf_a(&addr
, "127.0.0.1")) != LDNS_STATUS_OK
||
64 (status
= ldns_resolver_push_nameserver(res
, addr
)) != LDNS_STATUS_OK
)
65 return ldns_rdf_deep_free(addr
), status
;
66 ldns_rdf_deep_free(addr
);
67 if ((status
= ldns_str2rdf_aaaa(&addr
, "::1")) != LDNS_STATUS_OK
||
68 (status
= ldns_resolver_push_nameserver(res
, addr
)) != LDNS_STATUS_OK
)
69 return ldns_rdf_deep_free(addr
), status
;
70 ldns_rdf_deep_free(addr
);
71 return LDNS_STATUS_OK
;
75 ldns_rdf_new_addr_frm_str(const char *str
) {
78 if ((addr
= ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A
, str
)) == NULL
)
79 addr
= ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA
, str
);
84 ldns_resolver_remove_nameservers(ldns_resolver
*res
) {
85 while (ldns_resolver_nameserver_count(res
) > 0)
86 ldns_rdf_deep_free(ldns_resolver_pop_nameserver(res
));
90 ldns_rdf_reverse_a(ldns_rdf
*addr
, const char *base
) {
95 buf
= alloca(LDNS_IP4ADDRLEN
*4 + len
+ 1);
96 for (len
= i
= 0; i
< LDNS_IP4ADDRLEN
; i
++)
97 len
+= sprintf(&buf
[len
], "%d.",
98 (int)ldns_rdf_data(addr
)[LDNS_IP4ADDRLEN
- i
- 1]);
99 sprintf(&buf
[len
], "%s", base
);
100 return ldns_dname_new_frm_str(buf
);
104 ldns_rdf_reverse_aaaa(ldns_rdf
*addr
, const char *base
) {
109 buf
= alloca(LDNS_IP6ADDRLEN
*4 + len
+ 1);
110 for (i
= 0; i
< LDNS_IP6ADDRLEN
; i
++) {
111 uint8_t byte
= ldns_rdf_data(addr
)[LDNS_IP6ADDRLEN
- i
- 1];
112 sprintf(&buf
[i
*4], "%x.%x.", byte
& 0x0F, byte
>> 4);
114 sprintf(&buf
[LDNS_IP6ADDRLEN
*4], "%s", base
);
115 return ldns_dname_new_frm_str(buf
);
119 ldns_pkt_push_rr_soa(ldns_pkt
*pkt
, ldns_pkt_section sec
,
120 const ldns_rdf
*name
, ldns_rr_class c
, uint32_t serial
) {
125 if ((rr
= ldns_rr_new_frm_type(LDNS_RR_TYPE_SOA
)) == NULL
)
126 return LDNS_STATUS_MEM_ERR
;
127 ldns_rr_set_class(rr
, c
);
128 ldns_rr_set_owner(rr
, ldns_rdf_clone(name
));
129 ldns_rr_set_ttl(rr
, 0);
132 if ((rdf
= ldns_rdf_new_frm_data(LDNS_RDF_TYPE_DNAME
, 1, &n
)) == NULL
)
134 ldns_rr_set_rdf(rr
, rdf
, 0);
135 ldns_rr_set_rdf(rr
, ldns_rdf_clone(rdf
), 1);
138 if ((rdf
= ldns_rdf_new_frm_data(LDNS_RDF_TYPE_INT32
, 4, &n
)) == NULL
)
140 ldns_rr_set_rdf(rr
, rdf
, 2);
143 if ((rdf
= ldns_rdf_new_frm_data(LDNS_RDF_TYPE_PERIOD
, 4, &n
)) == NULL
)
145 ldns_rr_set_rdf(rr
, rdf
, 3);
146 ldns_rr_set_rdf(rr
, ldns_rdf_clone(rdf
), 4);
147 ldns_rr_set_rdf(rr
, ldns_rdf_clone(rdf
), 5);
148 ldns_rr_set_rdf(rr
, ldns_rdf_clone(rdf
), 6);
150 if (ldns_rr_rdf(rr
, 1) == NULL
|| ldns_rr_rdf(rr
, 4) == NULL
||
151 ldns_rr_rdf(rr
, 5) == NULL
|| ldns_rr_rdf(rr
, 6) == NULL
||
152 !ldns_pkt_push_rr(pkt
, sec
, rr
))
154 return LDNS_STATUS_OK
;
158 return LDNS_STATUS_MEM_ERR
;
162 ldns_resolver_send_to(ldns_pkt
**answer
, ldns_resolver
*res
,
163 const ldns_rdf
*name
, ldns_rr_type t
, ldns_rr_class c
,
164 uint16_t flags
, uint32_t ixfr_serial
, int nameserver
) {
168 int nscnt
= ldns_resolver_nameserver_count(res
);
169 ldns_rdf
**ns
= ldns_resolver_nameservers(res
);
170 size_t *rtt
= ldns_resolver_rtt(res
);
172 ldns_resolver_set_nameservers(res
, &ns
[nameserver
]);
173 ldns_resolver_set_rtt(res
, &rtt
[nameserver
]);
174 ldns_resolver_set_nameserver_count(res
, 1);
176 status
= ldns_resolver_prepare_query_pkt(&qpkt
, res
, name
, t
, c
, flags
);
177 if (status
== LDNS_STATUS_OK
&& t
== LDNS_RR_TYPE_IXFR
)
178 status
= ldns_pkt_push_rr_soa(qpkt
,
179 LDNS_SECTION_AUTHORITY
, name
, c
, ixfr_serial
);
180 if (status
== LDNS_STATUS_OK
)
181 status
= ldns_resolver_send_pkt(answer
, res
, qpkt
);
184 ldns_resolver_set_nameservers(res
, ns
);
185 ldns_resolver_set_rtt(res
, rtt
);
186 ldns_resolver_set_nameserver_count(res
, nscnt
);
191 ldns_pkt_filter_answer(ldns_pkt
*pkt
, ldns_rr_type type
) {
193 ldns_rr_list
*rrlist
;
197 rrlist
= ldns_pkt_answer(pkt
);
198 cnt
= ldns_rr_list_rr_count(rrlist
);
199 for (i
= j
= 0; i
< cnt
; i
++) {
200 rr
= ldns_rr_list_rr(rrlist
, i
);
201 rrtype
= ldns_rr_get_type(rr
);
202 if (type
== LDNS_RR_TYPE_ANY
||
204 (type
== LDNS_RR_TYPE_AXFR
&&
205 (rrtype
== LDNS_RR_TYPE_A
||
206 rrtype
== LDNS_RR_TYPE_AAAA
||
207 rrtype
== LDNS_RR_TYPE_NS
||
208 rrtype
== LDNS_RR_TYPE_PTR
)))
209 ldns_rr_list_set_rr(rrlist
, rr
, j
++);
211 ldns_rr_list_set_rr_count(rrlist
, j
);
214 /* Packet content printing.
221 {LDNS_RR_TYPE_A
, "has address"},
222 {LDNS_RR_TYPE_NS
, "name server"},
223 {LDNS_RR_TYPE_CNAME
, "is an alias for"},
224 {LDNS_RR_TYPE_WKS
, "has well known services"},
225 {LDNS_RR_TYPE_PTR
, "domain name pointer"},
226 {LDNS_RR_TYPE_HINFO
, "host information"},
227 {LDNS_RR_TYPE_MX
, "mail is handled by"},
228 {LDNS_RR_TYPE_TXT
, "descriptive text"},
229 {LDNS_RR_TYPE_X25
, "x25 address"},
230 {LDNS_RR_TYPE_ISDN
, "ISDN address"},
231 {LDNS_RR_TYPE_SIG
, "has signature"},
232 {LDNS_RR_TYPE_KEY
, "has key"},
233 {LDNS_RR_TYPE_AAAA
, "has IPv6 address"},
234 {LDNS_RR_TYPE_LOC
, "location"},
238 print_opcode(ldns_pkt_opcode opcode
) {
239 ldns_lookup_table
*lt
= ldns_lookup_by_id(ldns_opcodes
, opcode
);
242 printf("%s", lt
->name
);
244 printf("RESERVED%d", opcode
);
248 print_rcode(uint8_t rcode
) {
249 ldns_lookup_table
*lt
= ldns_lookup_by_id(ldns_rcodes
, rcode
);
252 printf("%s", lt
->name
);
254 printf("RESERVED%d", rcode
);
258 print_rr_type(ldns_rr_type type
) {
262 str
= ldns_rr_type2str(type
);
263 n
= printf("%s", str
);
269 print_rr_class(ldns_rr_class cls
) {
273 str
= ldns_rr_class2str(cls
);
274 n
= printf("%s", str
);
280 print_rdf(ldns_rdf
*rdf
) {
284 str
= ldns_rdf2str(rdf
);
285 n
= printf("%s", str
);
291 print_rdf_nodot(ldns_rdf
*rdf
) {
295 str
= ldns_rdf2str(rdf
);
297 n
= printf("%.*s", str
[len
-1] == '.' ? len
-1 : len
, str
);
303 print_padding(int fromcol
, int tocol
) {
304 int col
= fromcol
, nextcol
= fromcol
+ 8 - fromcol
%8;
306 if (fromcol
+ 1 > tocol
) tocol
= fromcol
+ 1;
307 for (; nextcol
<= tocol
; col
= nextcol
, nextcol
+= 8)
309 for (; col
< tocol
; col
++)
311 return col
- fromcol
;
315 print_rr_verbose(ldns_rr
*rr
) {
316 bool isq
= ldns_rr_is_question(rr
);
317 int rdcnt
= ldns_rr_rd_count(rr
);
320 /* bind9-host does not count the initial ';' here */
321 n
= isq
? printf(";") : 0;
322 n
= print_rdf(ldns_rr_owner(rr
));
324 n
+= print_padding(n
, 24);
325 n
+= printf("%d", ldns_rr_ttl(rr
));
327 n
+= print_padding(n
, 32);
328 n
+= print_rr_class(ldns_rr_get_class(rr
));
329 n
+= print_padding(n
, 40);
330 n
+= print_rr_type(ldns_rr_get_type(rr
));
331 for (i
= 0; i
< rdcnt
; i
++) {
332 if (i
== 0) print_padding(n
, 48);
334 print_rdf(ldns_rr_rdf(rr
, i
));
340 print_pkt_section_verbose(const char *name
, ldns_rr_list
*rrlist
) {
341 int i
, cnt
= ldns_rr_list_rr_count(rrlist
);
345 printf(";; %s SECTION:\n", name
);
346 for (i
= 0; i
< cnt
; i
++)
347 print_rr_verbose(ldns_rr_list_rr(rrlist
, i
));
352 print_pkt_verbose(ldns_pkt
*pkt
) {
355 printf(";; ->>HEADER<<- opcode: ");
356 print_opcode(ldns_pkt_get_opcode(pkt
));
357 printf(", status: ");
358 print_rcode(ldns_pkt_get_rcode(pkt
));
359 printf(", id: %u\n", ldns_pkt_id(pkt
));
361 if (ldns_pkt_qr(pkt
)) printf(" qr"), got_flags
= 1;
362 if (ldns_pkt_aa(pkt
)) printf(" aa"), got_flags
= 1;
363 if (ldns_pkt_tc(pkt
)) printf(" tc"), got_flags
= 1;
364 if (ldns_pkt_rd(pkt
)) printf(" rd"), got_flags
= 1;
365 if (ldns_pkt_ra(pkt
)) printf(" ra"), got_flags
= 1;
366 if (ldns_pkt_ad(pkt
)) printf(" ad"), got_flags
= 1;
367 if (ldns_pkt_cd(pkt
)) printf(" cd"), got_flags
= 1;
368 if (!got_flags
) printf(" ");
369 printf("; QUERY: %u, ANSWER: %u, AUTHORITY: %u, ADDITIONAL: %u\n",
370 ldns_pkt_qdcount(pkt
), ldns_pkt_ancount(pkt
),
371 ldns_pkt_nscount(pkt
), ldns_pkt_arcount(pkt
));
372 if (ldns_pkt_edns(pkt
))
373 printf(";; EDNS: version: %u, udp=%u\n",
374 ldns_pkt_edns_version(pkt
), ldns_pkt_edns_udp_size(pkt
));
376 print_pkt_section_verbose("QUESTION", ldns_pkt_question(pkt
));
377 print_pkt_section_verbose("ANSWER", ldns_pkt_answer(pkt
));
378 print_pkt_section_verbose("AUTHORITY", ldns_pkt_authority(pkt
));
379 print_pkt_section_verbose("ADDITIONAL", ldns_pkt_additional(pkt
));
383 print_rr_short(ldns_rr
*rr
) {
384 ldns_rr_type type
= ldns_rr_get_type(rr
);
385 size_t i
, rdcnt
= ldns_rr_rd_count(rr
);
387 print_rdf_nodot(ldns_rr_owner(rr
));
389 for (i
= 0; i
< countof(rr_types
); i
++) {
390 if (rr_types
[i
].type
== type
) {
391 printf("%s", rr_types
[i
].text
);
401 for (i
= 0; i
< rdcnt
; i
++) {
403 print_rdf(ldns_rr_rdf(rr
, i
));
409 print_pkt_short(ldns_pkt
*pkt
, bool print_rr_server
) {
410 ldns_rr_list
*rrlist
= ldns_pkt_answer(pkt
);
413 for (i
= 0; i
< ldns_rr_list_rr_count(rrlist
); i
++) {
414 if (print_rr_server
) {
415 printf("Nameserver ");
416 print_rdf(ldns_pkt_answerfrom(pkt
));
419 print_rr_short(ldns_rr_list_rr(rrlist
, i
));
424 print_received_line(ldns_resolver
*res
, ldns_pkt
*pkt
) {
425 char *from
= ldns_rdf2str(ldns_pkt_answerfrom(pkt
));
427 printf("Received %zu bytes from %s#%d in %d ms\n",
428 ldns_pkt_size(pkt
), from
, ldns_resolver_port(res
),
429 ldns_pkt_querytime(pkt
));
435 * Note that no memory is freed below this line by intention.
438 #define DEFAULT_TCP_TIMEOUT 10
439 #define DEFAULT_UDP_TIMEOUT 5
441 enum operation_mode
{ M_AXFR
, M_DEFAULT_Q
, M_SINGLE_Q
, M_SOA
};
443 static enum operation_mode o_mode
= M_DEFAULT_Q
;
444 static bool o_ignore_servfail
= true;
445 static bool o_ip6_int
= false;
446 static bool o_print_pkt_server
= false;
447 static bool o_print_rr_server
= false;
448 static bool o_recursive
= true;
449 static bool o_tcp
= false;
450 static bool o_verbose
= false;
451 static char *o_name
= NULL
;
452 static char *o_server
= NULL
;
453 static int o_ipversion
= LDNS_RESOLV_INETANY
;
454 static int o_ndots
= 1;
455 static int o_retries
= 1;
456 static ldns_rr_class o_rrclass
= LDNS_RR_CLASS_IN
;
457 static ldns_rr_type o_rrtype
= LDNS_RR_TYPE_A
;
458 static time_t o_timeout
= 0;
459 static uint32_t o_ixfr_serial
= 0;
464 "Usage: host [-aCdilrsTvw46] [-c class] [-N ndots] [-R number]\n"
465 " [-t type] [-W wait] name [server]\n"
466 "\t-a same as -v -t ANY\n"
467 "\t-C query SOA records from all authoritative name servers\n"
468 "\t-c use this query class (IN, CH, HS, etc)\n"
469 "\t-d produce verbose output, same as -v\n"
470 "\t-i use IP6.INT for IPv6 reverse lookups\n"
471 "\t-l list records in a zone via AXFR\n"
472 "\t-N consider names with at least this many dots as absolute\n"
473 "\t-R retry UDP queries this many times\n"
474 "\t-r disable recursive query\n"
475 "\t-s do not ignore SERVFAIL responses\n"
476 "\t-T send query via TCP\n"
477 "\t-t use this query type (A, AAAA, MX, etc)\n"
478 "\t-v produce verbose output\n"
479 "\t-w wait forever for a server reply\n"
480 "\t-W wait this many seconds for a reply\n"
481 "\t-4 use IPv4 only\n"
482 "\t-6 use IPv6 only\n",
488 parse_args(int argc
, char *argv
[]) {
492 while ((ch
= getopt(argc
, argv
, "aCdilrsTvw46c:N:R:t:W:")) != -1) {
495 if (o_mode
!= M_AXFR
)
497 o_rrtype
= LDNS_RR_TYPE_ANY
;
502 o_print_rr_server
= true;
503 o_rrclass
= LDNS_RR_CLASS_IN
;
504 o_rrtype
= LDNS_RR_TYPE_NS
;
507 /* bind9-host sets o_mode to M_SINGLE_Q here */
508 o_rrclass
= ldns_get_rr_class_by_name(optarg
);
510 die(2, "invalid class: %s\n", optarg
);
512 case 'd': o_verbose
= true; break;
513 case 'i': o_ip6_int
= true; break;
516 o_rrtype
= LDNS_RR_TYPE_AXFR
;
520 o_ndots
= atoi(optarg
);
521 if (o_ndots
< 0) o_ndots
= 0;
524 /* bind9-host accepts and ignores this option */
526 case 'r': o_recursive
= 0; break;
528 o_retries
= atoi(optarg
);
529 if (o_retries
<= 0) o_retries
= 1;
530 if (o_retries
> 255) o_retries
= 255;
532 case 's': o_ignore_servfail
= false; break;
533 case 'T': o_tcp
= true; break;
535 if (o_mode
!= M_AXFR
)
537 if (strncasecmp(optarg
, "ixfr=", 5) == 0) {
538 o_rrtype
= LDNS_RR_TYPE_IXFR
;
539 o_ixfr_serial
= atol(optarg
+ 5);
541 o_rrtype
= ldns_get_rr_type_by_name(optarg
);
543 die(2, "invalid type: %s\n", optarg
);
545 if (o_rrtype
== LDNS_RR_TYPE_AXFR
|| o_rrtype
== LDNS_RR_TYPE_IXFR
)
547 if (o_rrtype
== LDNS_RR_TYPE_AXFR
) {
549 o_rrtype
= LDNS_RR_TYPE_ANY
;
553 case 'v': o_verbose
= true; break;
555 o_timeout
= (time_t)INT_MAX
;
558 o_timeout
= atol(optarg
);
559 if (o_timeout
<= 0) o_timeout
= 1;
561 case '4': o_ipversion
= LDNS_RESOLV_INET
; break;
562 case '6': o_ipversion
= LDNS_RESOLV_INET6
; break;
569 /* bind9-host ignores arguments after the 2-nd one */
575 o_print_pkt_server
= true;
580 safe_str2rdf_dname(const char *name
) {
584 if ((status
= ldns_str2rdf_dname(&dname
, name
)) != LDNS_STATUS_OK
) {
585 die(1, "'%s' is not a legal name (%s)",
586 name
, ldns_get_errorstr_by_id(status
));
592 safe_dname_cat_clone(const ldns_rdf
*rd1
, const ldns_rdf
*rd2
) {
593 ldns_rdf
*result
= ldns_dname_cat_clone(rd1
, rd2
);
596 die(1, "not enought memory for a domain name");
597 /* Why doesn't ldns_dname_cat_clone check this condition? */
598 if (ldns_rdf_size(result
) > LDNS_MAX_DOMAINLEN
)
599 die(1, "'%s' is not a legal name (%s)\n", ldns_rdf2str(result
),
600 ldns_get_errorstr_by_id(LDNS_STATUS_DOMAINNAME_OVERFLOW
));
605 query(ldns_resolver
*res
, ldns_rdf
*domain
, ldns_pkt
**pkt
) {
607 ldns_pkt_rcode rcode
;
612 print_rdf_nodot(domain
);
615 for (cnt
= ldns_resolver_nameserver_count(res
), i
= 0; i
< cnt
; i
++) {
616 status
= ldns_resolver_send_to(pkt
, res
, domain
, o_rrtype
,
617 o_rrclass
, o_recursive
? LDNS_RD
: 0, o_ixfr_serial
, i
);
618 if (status
!= LDNS_STATUS_OK
) {
622 if (ldns_pkt_tc(*pkt
) && !ldns_resolver_usevc(res
)) {
624 printf(";; Truncated, retrying in TCP mode.\n");
625 ldns_resolver_set_usevc(res
, true);
626 status
= ldns_resolver_send_to(pkt
, res
, domain
, o_rrtype
,
627 o_rrclass
, o_recursive
? LDNS_RD
: 0, o_ixfr_serial
, i
);
628 ldns_resolver_set_usevc(res
, false);
629 if (status
!= LDNS_STATUS_OK
)
632 rcode
= ldns_pkt_get_rcode(*pkt
);
633 if (o_ignore_servfail
&& rcode
== LDNS_RCODE_SERVFAIL
&& cnt
> 1)
635 return rcode
== LDNS_RCODE_NOERROR
;
638 printf(";; connection timed out; no servers could be reached\n");
645 search(ldns_resolver
*res
, ldns_rdf
*domain
, ldns_pkt
**pkt
, bool absolute
) {
646 ldns_rdf
*dname
, **searchlist
;
649 if (absolute
&& query(res
, domain
, pkt
))
652 if ((dname
= ldns_resolver_domain(res
)) != NULL
) {
653 dname
= safe_dname_cat_clone(domain
, dname
);
654 if (query(res
, dname
, pkt
))
658 searchlist
= ldns_resolver_searchlist(res
);
659 n
= ldns_resolver_searchlist_count(res
);
660 for (i
= 0; i
< n
; i
++) {
661 dname
= safe_dname_cat_clone(domain
, searchlist
[i
]);
662 if (query(res
, dname
, pkt
))
666 if (!absolute
&& query(res
, domain
, pkt
))
673 report(ldns_resolver
*res
, ldns_rdf
*domain
, ldns_pkt
*pkt
) {
674 ldns_pkt_rcode rcode
;
676 if (o_print_pkt_server
) {
677 printf("Using domain server:\nName: %s\nAddress: ", o_server
);
678 print_rdf(ldns_pkt_answerfrom(pkt
));
679 printf("#%d\nAliases: \n\n", ldns_resolver_port(res
));
680 o_print_pkt_server
= false;
682 rcode
= ldns_pkt_get_rcode(pkt
);
683 if (rcode
!= LDNS_RCODE_NOERROR
) {
685 print_rdf_nodot(domain
);
686 printf(" not found: %d(", rcode
);
691 print_pkt_verbose(pkt
);
693 print_pkt_short(pkt
, o_print_rr_server
);
694 if (o_mode
!= M_DEFAULT_Q
&&
695 ldns_rr_list_rr_count(ldns_pkt_answer(pkt
)) == 0) {
696 print_rdf_nodot(domain
);
698 print_rr_type(o_rrtype
);
704 print_received_line(res
, pkt
);
708 doquery(ldns_resolver
*res
, ldns_rdf
*domain
) {
712 q
= query(res
, domain
, &pkt
);
713 report(res
, domain
, pkt
);
718 doquery_filtered(ldns_resolver
*res
, ldns_rdf
*domain
) {
722 q
= query(res
, domain
, &pkt
);
723 ldns_pkt_filter_answer(pkt
, o_rrtype
);
724 report(res
, domain
, pkt
);
729 dosearch(ldns_resolver
*res
, ldns_rdf
*domain
, bool absolute
) {
733 dname
= search(res
, domain
, &pkt
, absolute
);
734 report(res
, dname
!= NULL
? dname
: domain
, pkt
);
735 return o_mode
!= M_DEFAULT_Q
? (dname
!= NULL
) :
737 (o_rrtype
= LDNS_RR_TYPE_AAAA
, doquery_filtered(res
, dname
)) &&
738 (o_rrtype
= LDNS_RR_TYPE_MX
, doquery_filtered(res
, dname
));
742 doaxfr(ldns_resolver
*res
, ldns_rdf
*domain
, bool absolute
) {
748 o_rrtype
= LDNS_RR_TYPE_AXFR
;
749 dname
= search(res
, domain
, &pkt
, absolute
);
750 ldns_pkt_filter_answer(pkt
, rrtype
);
751 report(res
, dname
!= NULL
? dname
: domain
, pkt
);
752 return dname
!= NULL
;
756 dosoa(ldns_resolver
*res
, ldns_rdf
*domain
, bool absolute
) {
757 ldns_rr_list
*answer
, **nsaddrs
;
758 ldns_rdf
*dname
, *addr
;
763 if ((dname
= search(res
, domain
, &pkt
, absolute
)) == NULL
)
766 answer
= ldns_pkt_answer(pkt
);
767 cnt
= ldns_rr_list_rr_count(answer
);
768 nsaddrs
= alloca(cnt
*sizeof(*nsaddrs
));
769 for (n
= 0, i
= 0; i
< cnt
; i
++)
770 if ((addr
= ldns_rr_ns_nsdname(ldns_rr_list_rr(answer
, i
))) != NULL
)
771 nsaddrs
[n
++] = ldns_get_rr_list_addr_by_name(res
,
772 addr
, LDNS_RR_CLASS_IN
, 0);
774 o_print_pkt_server
= false;
776 o_rrtype
= LDNS_RR_TYPE_SOA
;
777 for (i
= 0; i
< n
; i
++) {
778 cnt
= ldns_rr_list_rr_count(nsaddrs
[i
]);
779 for (j
= 0; j
< cnt
; j
++) {
780 ldns_resolver_remove_nameservers(res
);
781 rr
= ldns_rr_list_rr(nsaddrs
[i
], j
);
782 if ((ldns_resolver_ip6(res
) == LDNS_RESOLV_INET
&&
783 ldns_rr_get_type(rr
) == LDNS_RR_TYPE_AAAA
) ||
784 (ldns_resolver_ip6(res
) == LDNS_RESOLV_INET6
&&
785 ldns_rr_get_type(rr
) == LDNS_RR_TYPE_A
))
787 if (ldns_resolver_push_nameserver_rr(res
, rr
) == LDNS_STATUS_OK
)
788 /* bind9-host queries for domain, not dname here */
796 resolver_set_nameserver_hostname(ldns_resolver
*res
, const char *server
) {
797 struct addrinfo hints
, *ailist
, *ai
;
802 memset(&hints
, 0, sizeof hints
);
803 switch (ldns_resolver_ip6(res
)) {
804 case LDNS_RESOLV_INET
: hints
.ai_family
= PF_INET
; break;
805 case LDNS_RESOLV_INET6
: hints
.ai_family
= PF_INET6
; break;
806 default: hints
.ai_family
= PF_UNSPEC
; break;
808 hints
.ai_socktype
= SOCK_STREAM
;
809 do err
= getaddrinfo(server
, NULL
, &hints
, &ailist
);
810 while (err
== EAI_AGAIN
);
812 die(1, "couldn't get address for '%s': %s", server
, gai_strerror(err
));
813 for (ai
= ailist
; ai
!= NULL
; ai
= ai
->ai_next
) {
814 if ((rdf
= ldns_sockaddr_storage2rdf((void*)ai
->ai_addr
, NULL
)) == NULL
)
815 die(1, "couldn't allocate an rdf: %s",
816 ldns_get_errorstr_by_id(LDNS_STATUS_MEM_ERR
));
817 status
= ldns_resolver_push_nameserver(res
, rdf
);
818 if (status
!= LDNS_STATUS_OK
)
819 die(1, "couldn't push a nameserver address: %s",
820 ldns_get_errorstr_by_id(status
));
825 resolver_set_nameserver_str(ldns_resolver
*res
, const char *server
) {
828 ldns_resolver_remove_nameservers(res
);
829 addr
= ldns_rdf_new_addr_frm_str(server
);
831 if (ldns_resolver_push_nameserver(res
, addr
) != LDNS_STATUS_OK
)
832 die(1, "couldn't push a nameserver address");
834 resolver_set_nameserver_hostname(res
, server
);
838 main(int argc
, char *argv
[]) {
839 ldns_rdf
*addr
, *dname
;
842 struct timeval restimeout
;
844 parse_args(argc
, argv
);
846 status
= ldns_resolver_new_default(&res
);
847 if (status
!= LDNS_STATUS_OK
)
848 die(1, "error creating resolver: %s", ldns_get_errorstr_by_id(status
));
849 if (ldns_resolver_nameserver_count(res
) == 0)
850 ldns_resolver_push_default_servers(res
);
852 ldns_resolver_set_usevc(res
, o_tcp
);
853 restimeout
.tv_sec
= o_timeout
> 0 ? o_timeout
:
854 o_tcp
? DEFAULT_TCP_TIMEOUT
: DEFAULT_UDP_TIMEOUT
;
855 restimeout
.tv_usec
= 0;
856 ldns_resolver_set_timeout(res
, restimeout
);
857 ldns_resolver_set_retry(res
, o_retries
+1);
858 ldns_resolver_set_ip6(res
, o_ipversion
);
859 ldns_resolver_set_defnames(res
, false);
860 ldns_resolver_set_fallback(res
, false);
863 resolver_set_nameserver_str(res
, o_server
);
865 if (ldns_str2rdf_a(&addr
, o_name
) == LDNS_STATUS_OK
) {
866 dname
= ldns_rdf_reverse_a(addr
, "in-addr.arpa");
868 die(1, "can't reverse '%s': %s", o_name
,
869 ldns_get_errorstr_by_id(LDNS_STATUS_MEM_ERR
));
871 o_rrtype
= LDNS_RR_TYPE_PTR
;
872 return !doquery(res
, dname
);
873 } else if (ldns_str2rdf_aaaa(&addr
, o_name
) == LDNS_STATUS_OK
) {
874 dname
= ldns_rdf_reverse_aaaa(addr
, o_ip6_int
? "ip6.int" : "ip6.arpa");
876 die(1, "can't reverse '%s': %s", o_name
,
877 ldns_get_errorstr_by_id(LDNS_STATUS_MEM_ERR
));
879 o_rrtype
= LDNS_RR_TYPE_PTR
;
880 return !doquery(res
, dname
);
882 return !(o_mode
== M_SOA
? dosoa
: o_mode
== M_AXFR
? doaxfr
: dosearch
)
883 (res
, safe_str2rdf_dname(o_name
), ndots(o_name
) >= o_ndots
);