3 * the main file of drill
4 * (c) 2005-2008 NLnet Labs
6 * See the file LICENSE for the license
11 #include <ldns/ldns.h>
14 #include <openssl/err.h>
17 #define IP6_ARPA_MAX_LEN 65
19 /* query debug, 2 hex dumps */
23 usage(FILE *stream
, const char *progname
)
25 fprintf(stream
, " Usage: %s name [@server] [type] [class]\n", progname
);
26 fprintf(stream
, "\t<name> can be a domain name or an IP address (-x lookups)\n");
27 fprintf(stream
, "\t<type> defaults to A\n");
28 fprintf(stream
, "\t<class> defaults to IN\n");
29 fprintf(stream
, "\n\targuments may be placed in random order\n");
30 fprintf(stream
, "\n Options:\n");
31 fprintf(stream
, "\t-D\t\tenable DNSSEC (DO bit)\n");
33 fprintf(stream
, "\t-T\t\ttrace from the root down to <name>\n");
34 fprintf(stream
, "\t-S\t\tchase signature(s) from <name> to a know key [*]\n");
36 fprintf(stream
, "\t-V <number>\tverbosity (0-5)\n");
37 fprintf(stream
, "\t-Q\t\tquiet mode (overrules -V)\n");
38 fprintf(stream
, "\n");
39 fprintf(stream
, "\t-f file\t\tread packet from file and send it\n");
40 fprintf(stream
, "\t-i file\t\tread packet from file and print it\n");
41 fprintf(stream
, "\t-w file\t\twrite answer packet to file\n");
42 fprintf(stream
, "\t-q file\t\twrite query packet to file\n");
43 fprintf(stream
, "\t-h\t\tshow this help\n");
44 fprintf(stream
, "\t-v\t\tshow version\n");
45 fprintf(stream
, "\n Query options:\n");
46 fprintf(stream
, "\t-4\t\tstay on ip4\n");
47 fprintf(stream
, "\t-6\t\tstay on ip6\n");
48 fprintf(stream
, "\t-a\t\tfallback to EDNS0 and TCP if the answer is truncated\n");
49 fprintf(stream
, "\t-b <bufsize>\tuse <bufsize> as the buffer size (defaults to 512 b)\n");
50 fprintf(stream
, "\t-c <file>\tuse file for rescursive nameserver configuration"
51 "\n\t\t\t(/etc/resolv.conf)\n");
52 fprintf(stream
, "\t-k <file>\tspecify a file that contains a trusted DNSSEC key [**]\n");
53 fprintf(stream
, "\t\t\tUsed to verify any signatures in the current answer.\n");
54 fprintf(stream
, "\t\t\tWhen DNSSEC enabled tracing (-TD) or signature\n"
55 "\t\t\tchasing (-S) and no key files are given, keys are read\n"
57 LDNS_TRUST_ANCHOR_FILE
);
58 fprintf(stream
, "\t-o <mnemonic>\tset flags to:"
59 "\n\t\t\t[QR|qr][AA|aa][TC|tc][RD|rd][CD|cd][RA|ra][AD|ad]\n");
60 fprintf(stream
, "\t\t\tlowercase: unset bit, uppercase: set bit\n");
61 fprintf(stream
, "\t-p <port>\tuse <port> as remote port number\n");
62 fprintf(stream
, "\t-s\t\tshow the DS RR for each key in a packet\n");
63 fprintf(stream
, "\t-u\t\tsend the query with udp (the default)\n");
64 fprintf(stream
, "\t-x\t\tdo a reverse lookup\n");
65 fprintf(stream
, "\twhen doing a secure trace:\n");
66 fprintf(stream
, "\t-r <file>\tuse file as root servers hint file\n");
67 fprintf(stream
, "\t-t\t\tsend the query with tcp (connected)\n");
68 fprintf(stream
, "\t-d <domain>\tuse domain as the start point for the trace\n");
69 fprintf(stream
, "\t-y <name:key[:algo]>\tspecify named base64 tsig key, and optional an\n\t\t\talgorithm (defaults to hmac-md5.sig-alg.reg.int)\n");
70 fprintf(stream
, "\t-z\t\tdon't randomize the nameservers before use\n");
71 fprintf(stream
, "\n [*] = enables/implies DNSSEC\n");
72 fprintf(stream
, " [**] = can be given more than once\n");
73 fprintf(stream
, "\n ldns-team@nlnetlabs.nl | http://www.nlnetlabs.nl/ldns/\n");
77 * Prints the drill version to stderr
80 version(FILE *stream
, const char *progname
)
82 fprintf(stream
, "%s version %s (ldns version %s)\n", progname
, DRILL_VERSION
, ldns_version());
83 fprintf(stream
, "Written by NLnet Labs.\n");
84 fprintf(stream
, "\nCopyright (c) 2004-2008 NLnet Labs.\n");
85 fprintf(stream
, "Licensed under the revised BSD license.\n");
86 fprintf(stream
, "There is NO warranty; not even for MERCHANTABILITY or FITNESS\n");
87 fprintf(stream
, "FOR A PARTICULAR PURPOSE.\n");
92 * Main function of drill
93 * parse the arguments and prepare a query
96 main(int argc
, char *argv
[])
98 ldns_resolver
*res
= NULL
;
99 ldns_resolver
*cmdline_res
= NULL
; /* only used to resolv @name names */
100 ldns_rr_list
*cmdline_rr_list
= NULL
;
101 ldns_rdf
*cmdline_dname
= NULL
;
102 ldns_rdf
*qname
, *qname_tmp
;
109 char *query_file
= NULL
;
110 char *answer_file
= NULL
;
111 ldns_buffer
*query_buffer
= NULL
;
116 ldns_pkt_opcode opcode
= LDNS_PACKET_QUERY
;
122 char *tsig_name
= NULL
;
123 char *tsig_data
= NULL
;
124 char *tsig_algorithm
= NULL
;
125 size_t tsig_separator
;
126 size_t tsig_separator2
;
131 /* list of keys used in dnssec operations */
132 ldns_rr_list
*key_list
= ldns_rr_list_new();
133 /* what key verify the current answer */
134 ldns_rr_list
*key_verified
;
136 /* resolver options */
147 char *resolv_conf_file
= NULL
;
149 ldns_rdf
*trace_start_name
= NULL
;
158 int_type
= -1; serv
= NULL
; type
= 0;
159 int_clas
= -1; name
= NULL
; clas
= 0;
161 progname
= strdup(argv
[0]);
164 r
= WSAStartup(MAKEWORD(2,2), &wsa_data
);
166 printf("Failed WSAStartup: %d\n", r
);
167 result
= EXIT_FAILURE
;
170 #endif /* USE_WINSOCK */
173 PURPOSE
= DRILL_QUERY
;
178 qfamily
= LDNS_RESOLV_INETANY
;
186 ldns_init_random(NULL
, 0);
189 usage(stdout
, progname
);
190 result
= EXIT_FAILURE
;
194 /* string from orig drill: "i:w:I46Sk:TNp:b:DsvhVcuaq:f:xr" */
195 /* global first, query opt next, option with parm's last
196 * and sorted */ /* "46DITSVQf:i:w:q:achuvxzy:so:p:b:k:" */
198 while ((c
= getopt(argc
, argv
, "46ab:c:d:Df:hi:Ik:o:p:q:Qr:sStTuvV:w:xy:z")) != -1) {
202 qfamily
= LDNS_RESOLV_INET
;
205 qfamily
= LDNS_RESOLV_INET6
;
211 /* reserved for backward compatibility */
214 if (PURPOSE
== DRILL_CHASE
) {
215 fprintf(stderr
, "-T and -S cannot be used at the same time.\n");
218 PURPOSE
= DRILL_TRACE
;
222 if (PURPOSE
== DRILL_TRACE
) {
223 fprintf(stderr
, "-T and -S cannot be used at the same time.\n");
226 PURPOSE
= DRILL_CHASE
;
228 #endif /* HAVE_SSL */
230 if (strtok(optarg
, "0123456789") != NULL
) {
231 fprintf(stderr
, "-V expects an number as an argument.\n");
234 verbosity
= atoi(optarg
);
243 answer_file
= optarg
;
244 PURPOSE
= DRILL_AFROMFILE
;
247 answer_file
= optarg
;
251 PURPOSE
= DRILL_QTOFILE
;
254 if (global_dns_root
) {
255 fprintf(stderr
, "There was already a series of root servers set\n");
258 global_dns_root
= read_root_hints(optarg
);
259 if (!global_dns_root
) {
260 fprintf(stderr
, "Unable to read root hints file %s, aborting\n", optarg
);
269 qbuf
= (uint16_t)atoi(optarg
);
271 error("%s", "<bufsize> could not be converted");
275 resolv_conf_file
= optarg
;
281 status
= read_key_file(optarg
,
283 if (status
!= LDNS_STATUS_OK
) {
284 error("Could not parse the key file %s: %s", optarg
, ldns_get_errorstr_by_id(status
));
286 qdnssec
= true; /* enable that too */
289 /* only looks at the first hit: capital=ON, lowercase=OFF*/
290 if (strstr(optarg
, "QR")) {
291 DRILL_ON(qflags
, LDNS_QR
);
293 if (strstr(optarg
, "qr")) {
294 DRILL_OFF(qflags
, LDNS_QR
);
296 if (strstr(optarg
, "AA")) {
297 DRILL_ON(qflags
, LDNS_AA
);
299 if (strstr(optarg
, "aa")) {
300 DRILL_OFF(qflags
, LDNS_AA
);
302 if (strstr(optarg
, "TC")) {
303 DRILL_ON(qflags
, LDNS_TC
);
305 if (strstr(optarg
, "tc")) {
306 DRILL_OFF(qflags
, LDNS_TC
);
308 if (strstr(optarg
, "RD")) {
309 DRILL_ON(qflags
, LDNS_RD
);
311 if (strstr(optarg
, "rd")) {
312 DRILL_OFF(qflags
, LDNS_RD
);
314 if (strstr(optarg
, "CD")) {
315 DRILL_ON(qflags
, LDNS_CD
);
317 if (strstr(optarg
, "cd")) {
318 DRILL_OFF(qflags
, LDNS_CD
);
320 if (strstr(optarg
, "RA")) {
321 DRILL_ON(qflags
, LDNS_RA
);
323 if (strstr(optarg
, "ra")) {
324 DRILL_OFF(qflags
, LDNS_RA
);
326 if (strstr(optarg
, "AD")) {
327 DRILL_ON(qflags
, LDNS_AD
);
329 if (strstr(optarg
, "ad")) {
330 DRILL_OFF(qflags
, LDNS_AD
);
334 qport
= (uint16_t)atoi(optarg
);
336 error("%s", "<port> could not be converted");
346 version(stdout
, progname
);
347 result
= EXIT_SUCCESS
;
350 PURPOSE
= DRILL_REVERSE
;
354 if (strchr(optarg
, ':')) {
355 tsig_separator
= (size_t) (strchr(optarg
, ':') - optarg
);
356 if (strchr(optarg
+ tsig_separator
+ 1, ':')) {
357 tsig_separator2
= (size_t) (strchr(optarg
+ tsig_separator
+ 1, ':') - optarg
);
358 tsig_algorithm
= xmalloc(strlen(optarg
) - tsig_separator2
);
359 strncpy(tsig_algorithm
, optarg
+ tsig_separator2
+ 1, strlen(optarg
) - tsig_separator2
);
360 tsig_algorithm
[strlen(optarg
) - tsig_separator2
- 1] = '\0';
362 tsig_separator2
= strlen(optarg
);
363 tsig_algorithm
= xmalloc(26);
364 strncpy(tsig_algorithm
, "hmac-md5.sig-alg.reg.int.", 25);
365 tsig_algorithm
[25] = '\0';
367 tsig_name
= xmalloc(tsig_separator
+ 1);
368 tsig_data
= xmalloc(tsig_separator2
- tsig_separator
);
369 strncpy(tsig_name
, optarg
, tsig_separator
);
370 strncpy(tsig_data
, optarg
+ tsig_separator
+ 1, tsig_separator2
- tsig_separator
- 1);
371 /* strncpy does not append \0 if source is longer than n */
372 tsig_name
[tsig_separator
] = '\0';
373 tsig_data
[ tsig_separator2
- tsig_separator
- 1] = '\0';
376 fprintf(stderr
, "TSIG requested, but SSL is not supported\n");
377 result
= EXIT_FAILURE
;
379 #endif /* HAVE_SSL */
385 trace_start_name
= ldns_dname_new_frm_str(optarg
);
386 if (!trace_start_name
) {
387 fprintf(stderr
, "Unable to parse argument for -%c\n", c
);
388 result
= EXIT_FAILURE
;
393 version(stdout
, progname
);
394 usage(stdout
, progname
);
395 result
= EXIT_SUCCESS
;
399 fprintf(stderr
, "Unknown argument: -%c, use -h to see usage\n", c
);
400 result
= EXIT_FAILURE
;
407 if ((PURPOSE
== DRILL_CHASE
|| (PURPOSE
== DRILL_TRACE
&& qdnssec
)) &&
408 ldns_rr_list_rr_count(key_list
) == 0) {
410 (void) read_key_file(LDNS_TRUST_ANCHOR_FILE
, key_list
, true);
412 if (ldns_rr_list_rr_count(key_list
) > 0) {
413 printf(";; Number of trusted keys: %d\n",
414 (int) ldns_rr_list_rr_count(key_list
));
416 /* do a secure trace when requested */
417 if (PURPOSE
== DRILL_TRACE
&& qdnssec
) {
419 if (ldns_rr_list_rr_count(key_list
) == 0) {
420 warning("%s", "No trusted keys were given. Will not be able to verify authenticity!");
422 PURPOSE
= DRILL_SECTRACE
;
424 fprintf(stderr
, "ldns has not been compiled with OpenSSL support. Secure trace not available\n");
426 #endif /* HAVE_SSL */
429 /* parse the arguments, with multiple arguments, the last argument
431 for(i
= 0; i
< argc
; i
++) {
433 /* if ^@ then it's a server */
434 if (argv
[i
][0] == '@') {
435 if (strlen(argv
[i
]) == 1) {
436 warning("%s", "No nameserver given");
442 /* if has a dot, it's a name */
443 if (strchr(argv
[i
], '.')) {
447 /* if it matches a type, it's a type */
448 if (int_type
== -1) {
449 type
= ldns_get_rr_type_by_name(argv
[i
]);
455 /* if it matches a class, it's a class */
456 if (int_clas
== -1) {
457 clas
= ldns_get_rr_class_by_name(argv
[i
]);
463 /* it all fails assume it's a name */
466 /* act like dig and use for . NS */
470 type
= LDNS_RR_TYPE_NS
;
473 /* defaults if not given */
474 if (int_clas
== -1) {
475 clas
= LDNS_RR_CLASS_IN
;
477 if (int_type
== -1) {
478 if (PURPOSE
!= DRILL_REVERSE
) {
479 type
= LDNS_RR_TYPE_A
;
481 type
= LDNS_RR_TYPE_PTR
;
485 /* set the nameserver to use */
487 /* no server given make a resolver from /etc/resolv.conf */
488 status
= ldns_resolver_new_frm_file(&res
, resolv_conf_file
);
489 if (status
!= LDNS_STATUS_OK
) {
490 warning("Could not create a resolver structure: %s (%s)\n"
491 "Try drill @localhost if you have a resolver running on your machine.",
492 ldns_get_errorstr_by_id(status
), resolv_conf_file
);
493 result
= EXIT_FAILURE
;
497 res
= ldns_resolver_new();
498 if (!res
|| strlen(serv
) <= 0) {
499 warning("Could not create a resolver structure");
500 result
= EXIT_FAILURE
;
503 /* add the nameserver */
504 serv_rdf
= ldns_rdf_new_addr_frm_str(serv
);
506 /* try to resolv the name if possible */
507 status
= ldns_resolver_new_frm_file(&cmdline_res
, resolv_conf_file
);
509 if (status
!= LDNS_STATUS_OK
) {
510 error("%s", "@server ip could not be converted");
512 ldns_resolver_set_dnssec(cmdline_res
, qdnssec
);
513 ldns_resolver_set_ip6(cmdline_res
, qfamily
);
514 ldns_resolver_set_fallback(cmdline_res
, qfallback
);
515 ldns_resolver_set_usevc(cmdline_res
, qusevc
);
517 cmdline_dname
= ldns_dname_new_frm_str(serv
);
519 cmdline_rr_list
= ldns_get_rr_list_addr_by_name(
524 ldns_rdf_deep_free(cmdline_dname
);
525 if (!cmdline_rr_list
) {
526 /* This error msg is not always accurate */
527 error("%s `%s\'", "could not find any address for the name:", serv
);
529 if (ldns_resolver_push_nameserver_rr_list(
532 ) != LDNS_STATUS_OK
) {
533 error("%s", "pushing nameserver");
537 if (ldns_resolver_push_nameserver(res
, serv_rdf
) != LDNS_STATUS_OK
) {
538 error("%s", "pushing nameserver");
540 ldns_rdf_deep_free(serv_rdf
);
544 /* set the resolver options */
545 ldns_resolver_set_port(res
, qport
);
546 if (verbosity
>= 5) {
547 ldns_resolver_set_debug(res
, true);
549 ldns_resolver_set_debug(res
, false);
551 ldns_resolver_set_dnssec(res
, qdnssec
);
552 /* ldns_resolver_set_dnssec_cd(res, qdnssec);*/
553 ldns_resolver_set_ip6(res
, qfamily
);
554 ldns_resolver_set_fallback(res
, qfallback
);
555 ldns_resolver_set_usevc(res
, qusevc
);
556 ldns_resolver_set_random(res
, qrandom
);
558 ldns_resolver_set_edns_udp_size(res
, qbuf
);
562 PURPOSE
!= DRILL_AFROMFILE
&&
565 usage(stdout
, progname
);
566 result
= EXIT_FAILURE
;
570 if (tsig_name
&& tsig_data
) {
571 ldns_resolver_set_tsig_keyname(res
, tsig_name
);
572 ldns_resolver_set_tsig_keydata(res
, tsig_data
);
573 ldns_resolver_set_tsig_algorithm(res
, tsig_algorithm
);
576 /* main switching part of drill */
579 /* do a trace from the root down */
580 if (!global_dns_root
) {
583 qname
= ldns_dname_new_frm_str(name
);
585 error("%s", "parsing query name");
587 /* don't care about return packet */
588 (void)do_trace(res
, qname
, type
, clas
);
592 /* do a secure trace from the root down */
593 if (!global_dns_root
) {
596 qname
= ldns_dname_new_frm_str(name
);
598 error("%s", "making qname");
600 /* don't care about return packet */
602 result
= do_secure_trace(res
, qname
, type
, clas
, key_list
, trace_start_name
);
603 #endif /* HAVE_SSL */
607 qname
= ldns_dname_new_frm_str(name
);
609 error("%s", "making qname");
612 ldns_resolver_set_dnssec(res
, true);
613 ldns_resolver_set_dnssec_cd(res
, true);
614 /* set dnssec implies udp_size of 4096 */
615 ldns_resolver_set_edns_udp_size(res
, 4096);
616 pkt
= ldns_resolver_query(res
, qname
, type
, clas
, qflags
);
619 error("%s", "error pkt sending");
620 result
= EXIT_FAILURE
;
622 if (verbosity
>= 3) {
623 ldns_pkt_print(stdout
, pkt
);
626 if (!ldns_pkt_answer(pkt
)) {
627 mesg("No answer in packet");
630 ldns_resolver_set_dnssec_anchors(res
, ldns_rr_list_clone(key_list
));
631 result
= do_chase(res
, qname
, type
,
635 if (result
== LDNS_STATUS_OK
) {
636 if (verbosity
!= -1) {
637 mesg("Chase successful");
641 if (verbosity
!= -1) {
642 mesg("Chase failed.");
645 #endif /* HAVE_SSL */
650 case DRILL_AFROMFILE
:
651 pkt
= read_hex_pkt(answer_file
);
653 if (verbosity
!= -1) {
654 ldns_pkt_print(stdout
, pkt
);
661 qname
= ldns_dname_new_frm_str(name
);
663 error("%s", "making qname");
666 status
= ldns_resolver_prepare_query_pkt(&qpkt
, res
, qname
, type
, clas
, qflags
);
667 if(status
!= LDNS_STATUS_OK
) {
668 error("%s", "making query: %s",
669 ldns_get_errorstr_by_id(status
));
671 dump_hex(qpkt
, query_file
);
677 /* ipv4 or ipv6 addr? */
678 if (strchr(name
, ':')) {
679 if (strchr(name
, '.')) {
680 error("Syntax error: both '.' and ':' seen in address\n");
682 name2
= malloc(IP6_ARPA_MAX_LEN
+ 20);
684 for (i
=0; i
<(int)strlen(name
); i
++) {
685 if (i
>= IP6_ARPA_MAX_LEN
) {
686 error("%s", "reverse argument to long");
688 if (name
[i
] == ':') {
689 if (i
< (int) strlen(name
) && name
[i
+ 1] == ':') {
690 error("%s", ":: not supported (yet)");
692 if (i
+ 2 == (int) strlen(name
) || name
[i
+ 2] == ':') {
699 } else if (i
+ 3 == (int) strlen(name
) || name
[i
+ 3] == ':') {
704 } else if (i
+ 4 == (int) strlen(name
) || name
[i
+ 4] == ':') {
710 name2
[c
++] = name
[i
];
716 qname
= ldns_dname_new_frm_str(name2
);
717 qname_tmp
= ldns_dname_reverse(qname
);
718 ldns_rdf_deep_free(qname
);
720 qname_tmp
= ldns_dname_new_frm_str("ip6.arpa.");
721 status
= ldns_dname_cat(qname
, qname_tmp
);
722 if (status
!= LDNS_STATUS_OK
) {
723 error("%s", "could not create reverse address for ip6: %s\n", ldns_get_errorstr_by_id(status
));
725 ldns_rdf_deep_free(qname_tmp
);
729 qname
= ldns_dname_new_frm_str(name
);
730 qname_tmp
= ldns_dname_reverse(qname
);
731 ldns_rdf_deep_free(qname
);
733 qname_tmp
= ldns_dname_new_frm_str("in-addr.arpa.");
734 status
= ldns_dname_cat(qname
, qname_tmp
);
735 if (status
!= LDNS_STATUS_OK
) {
736 error("%s", "could not create reverse address for ip4: %s\n", ldns_get_errorstr_by_id(status
));
738 ldns_rdf_deep_free(qname_tmp
);
741 error("%s", "-x implies an ip address");
744 /* create a packet and set the RD flag on it */
745 pkt
= ldns_resolver_query(res
, qname
, type
, clas
, qflags
);
747 error("%s", "pkt sending");
748 result
= EXIT_FAILURE
;
750 if (verbosity
!= -1) {
751 ldns_pkt_print(stdout
, pkt
);
759 /* this old way, the query packet needed
760 to be parseable, but we want to be able
761 to send mangled packets, so we need
764 qpkt
= read_hex_pkt(query_file
);
766 status
= ldns_resolver_send_pkt(&pkt
, res
, qpkt
);
767 if (status
!= LDNS_STATUS_OK
) {
768 printf("Error: %s\n", ldns_get_errorstr_by_id(status
));
772 /* qpkt was bogus, reset pkt */
776 query_buffer
= read_hex_buffer(query_file
);
778 status
= ldns_send_buffer(&pkt
, res
, query_buffer
, NULL
);
779 ldns_buffer_free(query_buffer
);
780 if (status
!= LDNS_STATUS_OK
) {
781 printf("Error: %s\n", ldns_get_errorstr_by_id(status
));
785 printf("NO BUFFER\n");
789 qname
= ldns_dname_new_frm_str(name
);
791 error("%s", "error in making qname");
794 if (type
== LDNS_RR_TYPE_AXFR
) {
795 status
= ldns_axfr_start(res
, qname
, clas
);
796 if(status
!= LDNS_STATUS_OK
) {
797 error("Error starting axfr: %s",
798 ldns_get_errorstr_by_id(status
));
800 axfr_rr
= ldns_axfr_next(res
);
802 fprintf(stderr
, "AXFR failed.\n");
803 ldns_pkt_print(stdout
,
804 ldns_axfr_last_pkt(res
));
808 if (verbosity
!= -1) {
809 ldns_rr_print(stdout
, axfr_rr
);
811 ldns_rr_free(axfr_rr
);
812 axfr_rr
= ldns_axfr_next(res
);
817 /* create a packet and set the RD flag on it */
818 pkt
= ldns_resolver_query(res
, qname
, type
, clas
, qflags
);
823 mesg("No packet received");
824 result
= EXIT_FAILURE
;
826 if (verbosity
!= -1) {
827 ldns_pkt_print(stdout
, pkt
);
828 if (ldns_pkt_tc(pkt
)) {
830 "\n;; WARNING: The answer packet was truncated; you might want to\n");
832 ";; query again with TCP (-t argument), or EDNS0 (-b for buffer size)\n");
836 if (verbosity
!= -1) {
837 print_ds_of_keys(pkt
);
842 if (ldns_rr_list_rr_count(key_list
) > 0) {
843 /* -k's were given on the cmd line */
844 ldns_rr_list
*rrset_verified
;
847 rrset_verified
= ldns_pkt_rr_list_by_name_and_type(
849 LDNS_SECTION_ANY_NOQUESTION
);
851 if (type
== LDNS_RR_TYPE_ANY
) {
852 /* don't verify this */
856 if (verbosity
!= -1) {
858 ldns_rr_list_print(stdout
, rrset_verified
);
863 key_verified
= ldns_rr_list_new();
864 result
= ldns_pkt_verify(pkt
, type
, qname
, key_list
, NULL
, key_verified
);
866 if (result
== LDNS_STATUS_ERR
) {
867 /* is the existence denied then? */
868 result
= ldns_verify_denial(pkt
, qname
, type
, NULL
, NULL
);
869 if (result
== LDNS_STATUS_OK
) {
870 if (verbosity
!= -1) {
871 printf("Existence denied for ");
872 ldns_rdf_print(stdout
, qname
);
873 type_str
= ldns_rr_type2str(type
);
874 printf("\t%s\n", type_str
);
878 if (verbosity
!= -1) {
879 printf("Bad data; RR for name and "
880 "type not found or failed to "
881 "verify, and denial of "
882 "existence failed.\n");
885 } else if (result
== LDNS_STATUS_OK
) {
886 for(key_count
= 0; key_count
< ldns_rr_list_rr_count(key_verified
);
888 if (verbosity
!= -1) {
889 printf("; VALIDATED by id = %u, owner = ",
890 (unsigned int)ldns_calc_keytag(
891 ldns_rr_list_rr(key_verified
, key_count
)));
892 ldns_rdf_print(stdout
, ldns_rr_owner(
893 ldns_rr_list_rr(key_list
, key_count
)));
898 for(key_count
= 0; key_count
< ldns_rr_list_rr_count(key_list
);
900 if (verbosity
!= -1) {
901 printf("; %s for id = %u, owner = ",
902 ldns_get_errorstr_by_id(result
),
903 (unsigned int)ldns_calc_keytag(
904 ldns_rr_list_rr(key_list
, key_count
)));
905 ldns_rdf_print(stdout
, ldns_rr_owner(
907 ldns_rr_list_rr(key_list
,
913 ldns_rr_list_free(key_verified
);
916 #endif /* HAVE_SSL */
919 dump_hex(pkt
, answer_file
);
928 ldns_rdf_deep_free(qname
);
929 ldns_resolver_deep_free(res
);
930 ldns_resolver_deep_free(cmdline_res
);
931 ldns_rr_list_deep_free(key_list
);
932 ldns_rr_list_deep_free(cmdline_rr_list
);
933 ldns_rdf_deep_free(trace_start_name
);
937 xfree(tsig_algorithm
);
941 CRYPTO_cleanup_all_ex_data();