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-I <address>\tsource address to query from\n");
37 fprintf(stream, "\t-V <number>\tverbosity (0-5)\n");
38 fprintf(stream, "\t-Q\t\tquiet mode (overrules -V)\n");
39 fprintf(stream, "\n");
40 fprintf(stream, "\t-f file\t\tread packet from file and send it\n");
41 fprintf(stream, "\t-i file\t\tread packet from file and print it\n");
42 fprintf(stream, "\t-w file\t\twrite answer packet to file\n");
43 fprintf(stream, "\t-q file\t\twrite query packet to file\n");
44 fprintf(stream, "\t-h\t\tshow this help\n");
45 fprintf(stream, "\t-v\t\tshow version\n");
46 fprintf(stream, "\n Query options:\n");
47 fprintf(stream, "\t-4\t\tstay on ip4\n");
48 fprintf(stream, "\t-6\t\tstay on ip6\n");
49 fprintf(stream, "\t-a\t\tfallback to EDNS0 and TCP if the answer is truncated\n");
50 fprintf(stream, "\t-b <bufsize>\tuse <bufsize> as the buffer size (defaults to 512 b)\n");
51 fprintf(stream, "\t-c <file>\tuse file for rescursive nameserver configuration"
52 "\n\t\t\t(/etc/resolv.conf)\n");
53 fprintf(stream, "\t-k <file>\tspecify a file that contains a trusted DNSSEC key [**]\n");
54 fprintf(stream, "\t\t\tUsed to verify any signatures in the current answer.\n");
55 fprintf(stream, "\t\t\tWhen DNSSEC enabled tracing (-TD) or signature\n"
56 "\t\t\tchasing (-S) and no key files are given, keys are read\n"
58 LDNS_TRUST_ANCHOR_FILE);
59 fprintf(stream, "\t-o <mnemonic>\tset flags to:"
60 "\n\t\t\t[QR|qr][AA|aa][TC|tc][RD|rd][CD|cd][RA|ra][AD|ad]\n");
61 fprintf(stream, "\t\t\tlowercase: unset bit, uppercase: set bit\n");
62 fprintf(stream, "\t-p <port>\tuse <port> as remote port number\n");
63 fprintf(stream, "\t-s\t\tshow the DS RR for each key in a packet\n");
64 fprintf(stream, "\t-u\t\tsend the query with udp (the default)\n");
65 fprintf(stream, "\t-x\t\tdo a reverse lookup\n");
66 fprintf(stream, "\twhen doing a secure trace:\n");
67 fprintf(stream, "\t-r <file>\tuse file as root servers hint file\n");
68 fprintf(stream, "\t-t\t\tsend the query with tcp (connected)\n");
69 fprintf(stream, "\t-d <domain>\tuse domain as the start point for the trace\n");
70 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");
71 fprintf(stream, "\t-z\t\tdon't randomize the nameservers before use\n");
72 fprintf(stream, "\n [*] = enables/implies DNSSEC\n");
73 fprintf(stream, " [**] = can be given more than once\n");
74 fprintf(stream, "\n ldns-team@nlnetlabs.nl | http://www.nlnetlabs.nl/ldns/\n");
78 * Prints the drill version to stderr
81 version(FILE *stream, const char *progname)
83 fprintf(stream, "%s version %s (ldns version %s)\n", progname, DRILL_VERSION, ldns_version());
84 fprintf(stream, "Written by NLnet Labs.\n");
85 fprintf(stream, "\nCopyright (c) 2004-2008 NLnet Labs.\n");
86 fprintf(stream, "Licensed under the revised BSD license.\n");
87 fprintf(stream, "There is NO warranty; not even for MERCHANTABILITY or FITNESS\n");
88 fprintf(stream, "FOR A PARTICULAR PURPOSE.\n");
93 * Main function of drill
94 * parse the arguments and prepare a query
97 main(int argc, char *argv[])
99 ldns_resolver *res = NULL;
100 ldns_resolver *cmdline_res = NULL; /* only used to resolv @name names */
101 ldns_rr_list *cmdline_rr_list = NULL;
102 ldns_rdf *cmdline_dname = NULL;
103 ldns_rdf *qname, *qname_tmp;
111 char *query_file = NULL;
112 char *answer_file = NULL;
113 ldns_buffer *query_buffer = NULL;
115 ldns_rdf *src_rdf = NULL;
119 ldns_pkt_opcode opcode = LDNS_PACKET_QUERY;
125 char *tsig_name = NULL;
126 char *tsig_data = NULL;
127 char *tsig_algorithm = NULL;
128 size_t tsig_separator;
129 size_t tsig_separator2;
134 /* list of keys used in dnssec operations */
135 ldns_rr_list *key_list = ldns_rr_list_new();
136 /* what key verify the current answer */
137 ldns_rr_list *key_verified;
139 /* resolver options */
150 char *resolv_conf_file = NULL;
152 ldns_rdf *trace_start_name = NULL;
161 int_type = -1; serv = NULL; type = 0;
162 int_clas = -1; name = NULL; clas = 0;
163 qname = NULL; src = NULL;
164 progname = strdup(argv[0]);
167 r = WSAStartup(MAKEWORD(2,2), &wsa_data);
169 printf("Failed WSAStartup: %d\n", r);
170 result = EXIT_FAILURE;
173 #endif /* USE_WINSOCK */
176 PURPOSE = DRILL_QUERY;
181 qfamily = LDNS_RESOLV_INETANY;
189 ldns_init_random(NULL, 0);
192 usage(stdout, progname);
193 result = EXIT_FAILURE;
197 /* string from orig drill: "i:w:I46Sk:TNp:b:DsvhVcuaq:f:xr" */
198 /* global first, query opt next, option with parm's last
199 * and sorted */ /* "46DITSVQf:i:w:q:achuvxzy:so:p:b:k:" */
201 while ((c = getopt(argc, argv, "46ab:c:d:Df:hi:I:k:o:p:q:Qr:sStTuvV:w:xy:z")) != -1) {
205 qfamily = LDNS_RESOLV_INET;
208 qfamily = LDNS_RESOLV_INET6;
217 if (PURPOSE == DRILL_CHASE) {
218 fprintf(stderr, "-T and -S cannot be used at the same time.\n");
221 PURPOSE = DRILL_TRACE;
225 if (PURPOSE == DRILL_TRACE) {
226 fprintf(stderr, "-T and -S cannot be used at the same time.\n");
229 PURPOSE = DRILL_CHASE;
231 #endif /* HAVE_SSL */
233 if (strtok(optarg, "0123456789") != NULL) {
234 fprintf(stderr, "-V expects an number as an argument.\n");
237 verbosity = atoi(optarg);
246 answer_file = optarg;
247 PURPOSE = DRILL_AFROMFILE;
250 answer_file = optarg;
254 PURPOSE = DRILL_QTOFILE;
257 if (global_dns_root) {
258 fprintf(stderr, "There was already a series of root servers set\n");
261 global_dns_root = read_root_hints(optarg);
262 if (!global_dns_root) {
263 fprintf(stderr, "Unable to read root hints file %s, aborting\n", optarg);
272 qbuf = (uint16_t)atoi(optarg);
274 error("%s", "<bufsize> could not be converted");
278 resolv_conf_file = optarg;
284 status = read_key_file(optarg,
286 if (status != LDNS_STATUS_OK) {
287 error("Could not parse the key file %s: %s", optarg, ldns_get_errorstr_by_id(status));
289 qdnssec = true; /* enable that too */
292 /* only looks at the first hit: capital=ON, lowercase=OFF*/
293 if (strstr(optarg, "QR")) {
294 DRILL_ON(qflags, LDNS_QR);
296 if (strstr(optarg, "qr")) {
297 DRILL_OFF(qflags, LDNS_QR);
299 if (strstr(optarg, "AA")) {
300 DRILL_ON(qflags, LDNS_AA);
302 if (strstr(optarg, "aa")) {
303 DRILL_OFF(qflags, LDNS_AA);
305 if (strstr(optarg, "TC")) {
306 DRILL_ON(qflags, LDNS_TC);
308 if (strstr(optarg, "tc")) {
309 DRILL_OFF(qflags, LDNS_TC);
311 if (strstr(optarg, "RD")) {
312 DRILL_ON(qflags, LDNS_RD);
314 if (strstr(optarg, "rd")) {
315 DRILL_OFF(qflags, LDNS_RD);
317 if (strstr(optarg, "CD")) {
318 DRILL_ON(qflags, LDNS_CD);
320 if (strstr(optarg, "cd")) {
321 DRILL_OFF(qflags, LDNS_CD);
323 if (strstr(optarg, "RA")) {
324 DRILL_ON(qflags, LDNS_RA);
326 if (strstr(optarg, "ra")) {
327 DRILL_OFF(qflags, LDNS_RA);
329 if (strstr(optarg, "AD")) {
330 DRILL_ON(qflags, LDNS_AD);
332 if (strstr(optarg, "ad")) {
333 DRILL_OFF(qflags, LDNS_AD);
337 qport = (uint16_t)atoi(optarg);
339 error("%s", "<port> could not be converted");
349 version(stdout, progname);
350 result = EXIT_SUCCESS;
353 PURPOSE = DRILL_REVERSE;
357 if (strchr(optarg, ':')) {
358 tsig_separator = (size_t) (strchr(optarg, ':') - optarg);
359 if (strchr(optarg + tsig_separator + 1, ':')) {
360 tsig_separator2 = (size_t) (strchr(optarg + tsig_separator + 1, ':') - optarg);
361 tsig_algorithm = xmalloc(strlen(optarg) - tsig_separator2);
362 strncpy(tsig_algorithm, optarg + tsig_separator2 + 1, strlen(optarg) - tsig_separator2);
363 tsig_algorithm[strlen(optarg) - tsig_separator2 - 1] = '\0';
365 tsig_separator2 = strlen(optarg);
366 tsig_algorithm = xmalloc(26);
367 strncpy(tsig_algorithm, "hmac-md5.sig-alg.reg.int.", 25);
368 tsig_algorithm[25] = '\0';
370 tsig_name = xmalloc(tsig_separator + 1);
371 tsig_data = xmalloc(tsig_separator2 - tsig_separator);
372 strncpy(tsig_name, optarg, tsig_separator);
373 strncpy(tsig_data, optarg + tsig_separator + 1, tsig_separator2 - tsig_separator - 1);
374 /* strncpy does not append \0 if source is longer than n */
375 tsig_name[tsig_separator] = '\0';
376 tsig_data[ tsig_separator2 - tsig_separator - 1] = '\0';
379 fprintf(stderr, "TSIG requested, but SSL is not supported\n");
380 result = EXIT_FAILURE;
382 #endif /* HAVE_SSL */
388 trace_start_name = ldns_dname_new_frm_str(optarg);
389 if (!trace_start_name) {
390 fprintf(stderr, "Unable to parse argument for -%c\n", c);
391 result = EXIT_FAILURE;
396 version(stdout, progname);
397 usage(stdout, progname);
398 result = EXIT_SUCCESS;
402 fprintf(stderr, "Unknown argument: -%c, use -h to see usage\n", c);
403 result = EXIT_FAILURE;
410 if ((PURPOSE == DRILL_CHASE || (PURPOSE == DRILL_TRACE && qdnssec)) &&
411 ldns_rr_list_rr_count(key_list) == 0) {
413 (void) read_key_file(LDNS_TRUST_ANCHOR_FILE, key_list, true);
415 if (ldns_rr_list_rr_count(key_list) > 0) {
416 printf(";; Number of trusted keys: %d\n",
417 (int) ldns_rr_list_rr_count(key_list));
419 /* do a secure trace when requested */
420 if (PURPOSE == DRILL_TRACE && qdnssec) {
422 if (ldns_rr_list_rr_count(key_list) == 0) {
423 warning("%s", "No trusted keys were given. Will not be able to verify authenticity!");
425 PURPOSE = DRILL_SECTRACE;
427 fprintf(stderr, "ldns has not been compiled with OpenSSL support. Secure trace not available\n");
429 #endif /* HAVE_SSL */
432 /* parse the arguments, with multiple arguments, the last argument
434 for(i = 0; i < argc; i++) {
436 /* if ^@ then it's a server */
437 if (argv[i][0] == '@') {
438 if (strlen(argv[i]) == 1) {
439 warning("%s", "No nameserver given");
445 /* if has a dot, it's a name */
446 if (strchr(argv[i], '.')) {
450 /* if it matches a type, it's a type */
451 if (int_type == -1) {
452 type = ldns_get_rr_type_by_name(argv[i]);
458 /* if it matches a class, it's a class */
459 if (int_clas == -1) {
460 clas = ldns_get_rr_class_by_name(argv[i]);
466 /* it all fails assume it's a name */
469 /* act like dig and use for . NS */
473 type = LDNS_RR_TYPE_NS;
476 /* defaults if not given */
477 if (int_clas == -1) {
478 clas = LDNS_RR_CLASS_IN;
480 if (int_type == -1) {
481 if (PURPOSE != DRILL_REVERSE) {
482 type = LDNS_RR_TYPE_A;
484 type = LDNS_RR_TYPE_PTR;
489 src_rdf = ldns_rdf_new_addr_frm_str(src);
491 fprintf(stderr, "-I must be (or resolve) to a valid IP[v6] address.\n");
496 /* set the nameserver to use */
498 /* no server given make a resolver from /etc/resolv.conf */
499 status = ldns_resolver_new_frm_file(&res, resolv_conf_file);
500 if (status != LDNS_STATUS_OK) {
501 warning("Could not create a resolver structure: %s (%s)\n"
502 "Try drill @localhost if you have a resolver running on your machine.",
503 ldns_get_errorstr_by_id(status), resolv_conf_file);
504 result = EXIT_FAILURE;
508 res = ldns_resolver_new();
509 if (!res || strlen(serv) <= 0) {
510 warning("Could not create a resolver structure");
511 result = EXIT_FAILURE;
514 /* add the nameserver */
515 serv_rdf = ldns_rdf_new_addr_frm_str(serv);
517 /* try to resolv the name if possible */
518 status = ldns_resolver_new_frm_file(&cmdline_res, resolv_conf_file);
520 if (status != LDNS_STATUS_OK) {
521 error("%s", "@server ip could not be converted");
523 ldns_resolver_set_dnssec(cmdline_res, qdnssec);
524 ldns_resolver_set_ip6(cmdline_res, qfamily);
525 ldns_resolver_set_fallback(cmdline_res, qfallback);
526 ldns_resolver_set_usevc(cmdline_res, qusevc);
527 ldns_resolver_set_source(cmdline_res, src_rdf);
529 cmdline_dname = ldns_dname_new_frm_str(serv);
531 cmdline_rr_list = ldns_get_rr_list_addr_by_name(
536 ldns_rdf_deep_free(cmdline_dname);
537 if (!cmdline_rr_list) {
538 /* This error msg is not always accurate */
539 error("%s `%s\'", "could not find any address for the name:", serv);
541 if (ldns_resolver_push_nameserver_rr_list(
544 ) != LDNS_STATUS_OK) {
545 error("%s", "pushing nameserver");
549 if (ldns_resolver_push_nameserver(res, serv_rdf) != LDNS_STATUS_OK) {
550 error("%s", "pushing nameserver");
552 ldns_rdf_deep_free(serv_rdf);
556 /* set the resolver options */
557 ldns_resolver_set_port(res, qport);
558 ldns_resolver_set_source(res, src_rdf);
559 if (verbosity >= 5) {
560 ldns_resolver_set_debug(res, true);
562 ldns_resolver_set_debug(res, false);
564 ldns_resolver_set_dnssec(res, qdnssec);
565 /* ldns_resolver_set_dnssec_cd(res, qdnssec);*/
566 ldns_resolver_set_ip6(res, qfamily);
567 ldns_resolver_set_fallback(res, qfallback);
568 ldns_resolver_set_usevc(res, qusevc);
569 ldns_resolver_set_random(res, qrandom);
571 ldns_resolver_set_edns_udp_size(res, qbuf);
575 PURPOSE != DRILL_AFROMFILE &&
578 usage(stdout, progname);
579 result = EXIT_FAILURE;
583 if (tsig_name && tsig_data) {
584 ldns_resolver_set_tsig_keyname(res, tsig_name);
585 ldns_resolver_set_tsig_keydata(res, tsig_data);
586 ldns_resolver_set_tsig_algorithm(res, tsig_algorithm);
589 /* main switching part of drill */
592 /* do a trace from the root down */
593 if (!global_dns_root) {
596 qname = ldns_dname_new_frm_str(name);
598 error("%s", "parsing query name");
600 /* don't care about return packet */
601 (void)do_trace(res, qname, type, clas);
605 /* do a secure trace from the root down */
606 if (!global_dns_root) {
609 qname = ldns_dname_new_frm_str(name);
611 error("%s", "making qname");
613 /* don't care about return packet */
615 result = do_secure_trace(res, qname, type, clas, key_list, trace_start_name);
616 #endif /* HAVE_SSL */
620 qname = ldns_dname_new_frm_str(name);
622 error("%s", "making qname");
625 ldns_resolver_set_dnssec(res, true);
626 ldns_resolver_set_dnssec_cd(res, true);
627 /* set dnssec implies udp_size of 4096 */
628 ldns_resolver_set_edns_udp_size(res, 4096);
630 status = ldns_resolver_query_status(
631 &pkt, res, qname, type, clas, qflags);
632 if (status != LDNS_STATUS_OK) {
633 error("error sending query: %s",
634 ldns_get_errorstr_by_id(status));
637 if (status == LDNS_STATUS_OK) {
638 error("%s", "error pkt sending");
640 result = EXIT_FAILURE;
642 if (verbosity >= 3) {
643 ldns_pkt_print(stdout, pkt);
646 if (!ldns_pkt_answer(pkt)) {
647 mesg("No answer in packet");
650 ldns_resolver_set_dnssec_anchors(res, ldns_rr_list_clone(key_list));
651 result = do_chase(res, qname, type,
655 if (result == LDNS_STATUS_OK) {
656 if (verbosity != -1) {
657 mesg("Chase successful");
661 if (verbosity != -1) {
662 mesg("Chase failed.");
665 #endif /* HAVE_SSL */
670 case DRILL_AFROMFILE:
671 pkt = read_hex_pkt(answer_file);
673 if (verbosity != -1) {
674 ldns_pkt_print(stdout, pkt);
681 qname = ldns_dname_new_frm_str(name);
683 error("%s", "making qname");
686 status = ldns_resolver_prepare_query_pkt(&qpkt, res, qname, type, clas, qflags);
687 if(status != LDNS_STATUS_OK) {
688 error("%s", "making query: %s",
689 ldns_get_errorstr_by_id(status));
691 dump_hex(qpkt, query_file);
697 /* ipv4 or ipv6 addr? */
698 if (strchr(name, ':')) {
699 if (strchr(name, '.')) {
700 error("Syntax error: both '.' and ':' seen in address\n");
702 name2 = malloc(IP6_ARPA_MAX_LEN + 20);
704 for (i=0; i<(int)strlen(name); i++) {
705 if (i >= IP6_ARPA_MAX_LEN) {
706 error("%s", "reverse argument to long");
708 if (name[i] == ':') {
709 if (i < (int) strlen(name) && name[i + 1] == ':') {
710 error("%s", ":: not supported (yet)");
712 if (i + 2 == (int) strlen(name) || name[i + 2] == ':') {
719 } else if (i + 3 == (int) strlen(name) || name[i + 3] == ':') {
724 } else if (i + 4 == (int) strlen(name) || name[i + 4] == ':') {
730 name2[c++] = name[i];
736 qname = ldns_dname_new_frm_str(name2);
737 qname_tmp = ldns_dname_reverse(qname);
738 ldns_rdf_deep_free(qname);
740 qname_tmp = ldns_dname_new_frm_str("ip6.arpa.");
741 status = ldns_dname_cat(qname, qname_tmp);
742 if (status != LDNS_STATUS_OK) {
743 error("%s", "could not create reverse address for ip6: %s\n", ldns_get_errorstr_by_id(status));
745 ldns_rdf_deep_free(qname_tmp);
749 qname = ldns_dname_new_frm_str(name);
750 qname_tmp = ldns_dname_reverse(qname);
751 ldns_rdf_deep_free(qname);
753 qname_tmp = ldns_dname_new_frm_str("in-addr.arpa.");
754 status = ldns_dname_cat(qname, qname_tmp);
755 if (status != LDNS_STATUS_OK) {
756 error("%s", "could not create reverse address for ip4: %s\n", ldns_get_errorstr_by_id(status));
758 ldns_rdf_deep_free(qname_tmp);
761 error("%s", "-x implies an ip address");
764 /* create a packet and set the RD flag on it */
766 status = ldns_resolver_query_status(
767 &pkt, res, qname, type, clas, qflags);
768 if (status != LDNS_STATUS_OK) {
769 error("error sending query: %s",
770 ldns_get_errorstr_by_id(status));
773 if (status == LDNS_STATUS_OK) {
774 error("%s", "pkt sending");
776 result = EXIT_FAILURE;
778 if (verbosity != -1) {
779 ldns_pkt_print(stdout, pkt);
787 /* this old way, the query packet needed
788 to be parseable, but we want to be able
789 to send mangled packets, so we need
792 qpkt = read_hex_pkt(query_file);
794 status = ldns_resolver_send_pkt(&pkt, res, qpkt);
795 if (status != LDNS_STATUS_OK) {
796 printf("Error: %s\n", ldns_get_errorstr_by_id(status));
800 /* qpkt was bogus, reset pkt */
804 query_buffer = read_hex_buffer(query_file);
806 status = ldns_send_buffer(&pkt, res, query_buffer, NULL);
807 ldns_buffer_free(query_buffer);
808 if (status != LDNS_STATUS_OK) {
809 printf("Error: %s\n", ldns_get_errorstr_by_id(status));
813 printf("NO BUFFER\n");
817 qname = ldns_dname_new_frm_str(name);
819 error("%s", "error in making qname");
822 if (type == LDNS_RR_TYPE_AXFR) {
823 status = ldns_axfr_start(res, qname, clas);
824 if(status != LDNS_STATUS_OK) {
825 error("Error starting axfr: %s",
826 ldns_get_errorstr_by_id(status));
828 axfr_rr = ldns_axfr_next(res);
830 fprintf(stderr, "AXFR failed.\n");
831 ldns_pkt_print(stdout,
832 ldns_axfr_last_pkt(res));
836 if (verbosity != -1) {
837 ldns_rr_print(stdout, axfr_rr);
839 ldns_rr_free(axfr_rr);
840 axfr_rr = ldns_axfr_next(res);
845 /* create a packet and set the RD flag on it */
847 status = ldns_resolver_query_status(
850 if (status != LDNS_STATUS_OK) {
851 error("error sending query: %s"
852 , ldns_get_errorstr_by_id(
859 mesg("No packet received");
860 result = EXIT_FAILURE;
862 if (verbosity != -1) {
863 ldns_pkt_print(stdout, pkt);
864 if (ldns_pkt_tc(pkt)) {
866 "\n;; WARNING: The answer packet was truncated; you might want to\n");
868 ";; query again with TCP (-t argument), or EDNS0 (-b for buffer size)\n");
872 if (verbosity != -1) {
873 print_ds_of_keys(pkt);
878 if (ldns_rr_list_rr_count(key_list) > 0) {
879 /* -k's were given on the cmd line */
880 ldns_rr_list *rrset_verified;
883 rrset_verified = ldns_pkt_rr_list_by_name_and_type(
885 LDNS_SECTION_ANY_NOQUESTION);
887 if (type == LDNS_RR_TYPE_ANY) {
888 /* don't verify this */
892 if (verbosity != -1) {
894 ldns_rr_list_print(stdout, rrset_verified);
899 key_verified = ldns_rr_list_new();
900 result = ldns_pkt_verify(pkt, type, qname, key_list, NULL, key_verified);
902 if (result == LDNS_STATUS_ERR) {
903 /* is the existence denied then? */
904 result = ldns_verify_denial(pkt, qname, type, NULL, NULL);
905 if (result == LDNS_STATUS_OK) {
906 if (verbosity != -1) {
907 printf("Existence denied for ");
908 ldns_rdf_print(stdout, qname);
909 type_str = ldns_rr_type2str(type);
910 printf("\t%s\n", type_str);
914 if (verbosity != -1) {
915 printf("Bad data; RR for name and "
916 "type not found or failed to "
917 "verify, and denial of "
918 "existence failed.\n");
921 } else if (result == LDNS_STATUS_OK) {
922 for(key_count = 0; key_count < ldns_rr_list_rr_count(key_verified);
924 if (verbosity != -1) {
925 printf("; VALIDATED by id = %u, owner = ",
926 (unsigned int)ldns_calc_keytag(
927 ldns_rr_list_rr(key_verified, key_count)));
928 ldns_rdf_print(stdout, ldns_rr_owner(
929 ldns_rr_list_rr(key_list, key_count)));
934 for(key_count = 0; key_count < ldns_rr_list_rr_count(key_list);
936 if (verbosity != -1) {
937 printf("; %s for id = %u, owner = ",
938 ldns_get_errorstr_by_id(result),
939 (unsigned int)ldns_calc_keytag(
940 ldns_rr_list_rr(key_list, key_count)));
941 ldns_rdf_print(stdout, ldns_rr_owner(
943 ldns_rr_list_rr(key_list,
949 ldns_rr_list_free(key_verified);
952 #endif /* HAVE_SSL */
955 dump_hex(pkt, answer_file);
964 ldns_rdf_deep_free(qname);
965 ldns_rdf_deep_free(src_rdf);
966 ldns_resolver_deep_free(res);
967 ldns_resolver_deep_free(cmdline_res);
968 ldns_rr_list_deep_free(key_list);
969 ldns_rr_list_deep_free(cmdline_rr_list);
970 ldns_rdf_deep_free(trace_start_name);
974 xfree(tsig_algorithm);
978 CRYPTO_cleanup_all_ex_data();