xref: /freebsd/contrib/ldns/drill/drill.c (revision 17d15b251108ff09e632ed4812f7c66999a6b69b)
17b5038d7SDag-Erling Smørgrav /*
27b5038d7SDag-Erling Smørgrav  * drill.c
37b5038d7SDag-Erling Smørgrav  * the main file of drill
47b5038d7SDag-Erling Smørgrav  * (c) 2005-2008 NLnet Labs
57b5038d7SDag-Erling Smørgrav  *
67b5038d7SDag-Erling Smørgrav  * See the file LICENSE for the license
77b5038d7SDag-Erling Smørgrav  *
87b5038d7SDag-Erling Smørgrav  */
97b5038d7SDag-Erling Smørgrav 
107b5038d7SDag-Erling Smørgrav #include "drill.h"
117b5038d7SDag-Erling Smørgrav #include <ldns/ldns.h>
127b5038d7SDag-Erling Smørgrav 
137b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
147b5038d7SDag-Erling Smørgrav #include <openssl/err.h>
157b5038d7SDag-Erling Smørgrav #endif
167b5038d7SDag-Erling Smørgrav 
177b5038d7SDag-Erling Smørgrav #define IP6_ARPA_MAX_LEN 65
187b5038d7SDag-Erling Smørgrav 
197b5038d7SDag-Erling Smørgrav /* query debug, 2 hex dumps */
207b5038d7SDag-Erling Smørgrav int		verbosity;
217b5038d7SDag-Erling Smørgrav 
227b5038d7SDag-Erling Smørgrav static void
237b5038d7SDag-Erling Smørgrav usage(FILE *stream, const char *progname)
247b5038d7SDag-Erling Smørgrav {
257b5038d7SDag-Erling Smørgrav 	fprintf(stream, "  Usage: %s name [@server] [type] [class]\n", progname);
267b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t<name>  can be a domain name or an IP address (-x lookups)\n");
277b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t<type>  defaults to A\n");
287b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t<class> defaults to IN\n");
297b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\n\targuments may be placed in random order\n");
307b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\n  Options:\n");
317b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-D\t\tenable DNSSEC (DO bit)\n");
327b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
337b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-T\t\ttrace from the root down to <name>\n");
347b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-S\t\tchase signature(s) from <name> to a know key [*]\n");
357b5038d7SDag-Erling Smørgrav #endif /*HAVE_SSL*/
36*17d15b25SDag-Erling Smørgrav 	fprintf(stream, "\t-I <address>\tsource address to query from\n");
377b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-V <number>\tverbosity (0-5)\n");
387b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-Q\t\tquiet mode (overrules -V)\n");
397b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\n");
407b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-f file\t\tread packet from file and send it\n");
417b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-i file\t\tread packet from file and print it\n");
427b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-w file\t\twrite answer packet to file\n");
437b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-q file\t\twrite query packet to file\n");
447b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-h\t\tshow this help\n");
457b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-v\t\tshow version\n");
467b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\n  Query options:\n");
477b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-4\t\tstay on ip4\n");
487b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-6\t\tstay on ip6\n");
497b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-a\t\tfallback to EDNS0 and TCP if the answer is truncated\n");
507b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-b <bufsize>\tuse <bufsize> as the buffer size (defaults to 512 b)\n");
512787e39aSDag-Erling Smørgrav 	fprintf(stream, "\t-c <file>\tuse file for rescursive nameserver configuration"
522787e39aSDag-Erling Smørgrav 			"\n\t\t\t(/etc/resolv.conf)\n");
532787e39aSDag-Erling Smørgrav 	fprintf(stream, "\t-k <file>\tspecify a file that contains a trusted DNSSEC key [**]\n");
542787e39aSDag-Erling Smørgrav 	fprintf(stream, "\t\t\tUsed to verify any signatures in the current answer.\n");
552787e39aSDag-Erling Smørgrav 	fprintf(stream, "\t\t\tWhen DNSSEC enabled tracing (-TD) or signature\n"
562787e39aSDag-Erling Smørgrav 			"\t\t\tchasing (-S) and no key files are given, keys are read\n"
572787e39aSDag-Erling Smørgrav 			"\t\t\tfrom: %s\n",
582787e39aSDag-Erling Smørgrav 			LDNS_TRUST_ANCHOR_FILE);
592787e39aSDag-Erling Smørgrav 	fprintf(stream, "\t-o <mnemonic>\tset flags to:"
602787e39aSDag-Erling Smørgrav 			"\n\t\t\t[QR|qr][AA|aa][TC|tc][RD|rd][CD|cd][RA|ra][AD|ad]\n");
617b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t\t\tlowercase: unset bit, uppercase: set bit\n");
627b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-p <port>\tuse <port> as remote port number\n");
637b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-s\t\tshow the DS RR for each key in a packet\n");
647b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-u\t\tsend the query with udp (the default)\n");
657b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-x\t\tdo a reverse lookup\n");
667b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\twhen doing a secure trace:\n");
672787e39aSDag-Erling Smørgrav 	fprintf(stream, "\t-r <file>\tuse file as root servers hint file\n");
687b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-t\t\tsend the query with tcp (connected)\n");
692787e39aSDag-Erling Smørgrav 	fprintf(stream, "\t-d <domain>\tuse domain as the start point for the trace\n");
707b5038d7SDag-Erling Smørgrav     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");
717b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-z\t\tdon't randomize the nameservers before use\n");
727b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\n  [*] = enables/implies DNSSEC\n");
737b5038d7SDag-Erling Smørgrav 	fprintf(stream, "  [**] = can be given more than once\n");
747b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\n  ldns-team@nlnetlabs.nl | http://www.nlnetlabs.nl/ldns/\n");
757b5038d7SDag-Erling Smørgrav }
767b5038d7SDag-Erling Smørgrav 
777b5038d7SDag-Erling Smørgrav /**
787b5038d7SDag-Erling Smørgrav  * Prints the drill version to stderr
797b5038d7SDag-Erling Smørgrav  */
807b5038d7SDag-Erling Smørgrav static void
817b5038d7SDag-Erling Smørgrav version(FILE *stream, const char *progname)
827b5038d7SDag-Erling Smørgrav {
837b5038d7SDag-Erling Smørgrav         fprintf(stream, "%s version %s (ldns version %s)\n", progname, DRILL_VERSION, ldns_version());
847b5038d7SDag-Erling Smørgrav         fprintf(stream, "Written by NLnet Labs.\n");
857b5038d7SDag-Erling Smørgrav         fprintf(stream, "\nCopyright (c) 2004-2008 NLnet Labs.\n");
867b5038d7SDag-Erling Smørgrav         fprintf(stream, "Licensed under the revised BSD license.\n");
877b5038d7SDag-Erling Smørgrav         fprintf(stream, "There is NO warranty; not even for MERCHANTABILITY or FITNESS\n");
887b5038d7SDag-Erling Smørgrav         fprintf(stream, "FOR A PARTICULAR PURPOSE.\n");
897b5038d7SDag-Erling Smørgrav }
907b5038d7SDag-Erling Smørgrav 
917b5038d7SDag-Erling Smørgrav 
927b5038d7SDag-Erling Smørgrav /**
937b5038d7SDag-Erling Smørgrav  * Main function of drill
947b5038d7SDag-Erling Smørgrav  * parse the arguments and prepare a query
957b5038d7SDag-Erling Smørgrav  */
967b5038d7SDag-Erling Smørgrav int
977b5038d7SDag-Erling Smørgrav main(int argc, char *argv[])
987b5038d7SDag-Erling Smørgrav {
997b5038d7SDag-Erling Smørgrav         ldns_resolver	*res = NULL;
1007b5038d7SDag-Erling Smørgrav         ldns_resolver   *cmdline_res = NULL; /* only used to resolv @name names */
1017b5038d7SDag-Erling Smørgrav 	ldns_rr_list	*cmdline_rr_list = NULL;
1027b5038d7SDag-Erling Smørgrav 	ldns_rdf	*cmdline_dname = NULL;
1037b5038d7SDag-Erling Smørgrav         ldns_rdf 	*qname, *qname_tmp;
1047b5038d7SDag-Erling Smørgrav         ldns_pkt	*pkt;
1057b5038d7SDag-Erling Smørgrav         ldns_pkt	*qpkt;
1067b5038d7SDag-Erling Smørgrav         char 		*serv;
107*17d15b25SDag-Erling Smørgrav         char 		*src = NULL;
1087b5038d7SDag-Erling Smørgrav         const char 	*name;
1097b5038d7SDag-Erling Smørgrav         char 		*name2;
1107b5038d7SDag-Erling Smørgrav 	char		*progname;
1117b5038d7SDag-Erling Smørgrav 	char 		*query_file = NULL;
1127b5038d7SDag-Erling Smørgrav 	char		*answer_file = NULL;
1137b5038d7SDag-Erling Smørgrav 	ldns_buffer	*query_buffer = NULL;
1147b5038d7SDag-Erling Smørgrav 	ldns_rdf 	*serv_rdf;
115*17d15b25SDag-Erling Smørgrav 	ldns_rdf 	*src_rdf = NULL;
1167b5038d7SDag-Erling Smørgrav         ldns_rr_type 	type;
1177b5038d7SDag-Erling Smørgrav         ldns_rr_class	clas;
1187b5038d7SDag-Erling Smørgrav #if 0
1197b5038d7SDag-Erling Smørgrav 	ldns_pkt_opcode opcode = LDNS_PACKET_QUERY;
1207b5038d7SDag-Erling Smørgrav #endif
1217b5038d7SDag-Erling Smørgrav 	int 		i, c;
1227b5038d7SDag-Erling Smørgrav 	int 		int_type;
1237b5038d7SDag-Erling Smørgrav 	int		int_clas;
1247b5038d7SDag-Erling Smørgrav 	int		PURPOSE;
1257b5038d7SDag-Erling Smørgrav 	char		*tsig_name = NULL;
1267b5038d7SDag-Erling Smørgrav 	char		*tsig_data = NULL;
1277b5038d7SDag-Erling Smørgrav 	char 		*tsig_algorithm = NULL;
1287b5038d7SDag-Erling Smørgrav 	size_t		tsig_separator;
1297b5038d7SDag-Erling Smørgrav 	size_t		tsig_separator2;
1307b5038d7SDag-Erling Smørgrav 	ldns_rr		*axfr_rr;
1317b5038d7SDag-Erling Smørgrav 	ldns_status	status;
1327b5038d7SDag-Erling Smørgrav 	char *type_str;
1337b5038d7SDag-Erling Smørgrav 
1347b5038d7SDag-Erling Smørgrav 	/* list of keys used in dnssec operations */
1357b5038d7SDag-Erling Smørgrav 	ldns_rr_list	*key_list = ldns_rr_list_new();
1367b5038d7SDag-Erling Smørgrav 	/* what key verify the current answer */
1377b5038d7SDag-Erling Smørgrav 	ldns_rr_list 	*key_verified;
1387b5038d7SDag-Erling Smørgrav 
1397b5038d7SDag-Erling Smørgrav 	/* resolver options */
1407b5038d7SDag-Erling Smørgrav 	uint16_t	qflags;
1417b5038d7SDag-Erling Smørgrav 	uint16_t 	qbuf;
1427b5038d7SDag-Erling Smørgrav 	uint16_t	qport;
1437b5038d7SDag-Erling Smørgrav 	uint8_t		qfamily;
1447b5038d7SDag-Erling Smørgrav 	bool		qdnssec;
1457b5038d7SDag-Erling Smørgrav 	bool		qfallback;
1467b5038d7SDag-Erling Smørgrav 	bool		qds;
1477b5038d7SDag-Erling Smørgrav 	bool		qusevc;
1487b5038d7SDag-Erling Smørgrav 	bool 		qrandom;
1497b5038d7SDag-Erling Smørgrav 
1507b5038d7SDag-Erling Smørgrav 	char		*resolv_conf_file = NULL;
1517b5038d7SDag-Erling Smørgrav 
1527b5038d7SDag-Erling Smørgrav 	ldns_rdf *trace_start_name = NULL;
1537b5038d7SDag-Erling Smørgrav 
1547b5038d7SDag-Erling Smørgrav 	int		result = 0;
1557b5038d7SDag-Erling Smørgrav 
1567b5038d7SDag-Erling Smørgrav #ifdef USE_WINSOCK
1577b5038d7SDag-Erling Smørgrav 	int r;
1587b5038d7SDag-Erling Smørgrav 	WSADATA wsa_data;
1597b5038d7SDag-Erling Smørgrav #endif
1607b5038d7SDag-Erling Smørgrav 
1617b5038d7SDag-Erling Smørgrav 	int_type = -1; serv = NULL; type = 0;
1627b5038d7SDag-Erling Smørgrav 	int_clas = -1; name = NULL; clas = 0;
163*17d15b25SDag-Erling Smørgrav 	qname = NULL; src = NULL;
1647b5038d7SDag-Erling Smørgrav 	progname = strdup(argv[0]);
1657b5038d7SDag-Erling Smørgrav 
1667b5038d7SDag-Erling Smørgrav #ifdef USE_WINSOCK
1677b5038d7SDag-Erling Smørgrav 	r = WSAStartup(MAKEWORD(2,2), &wsa_data);
1687b5038d7SDag-Erling Smørgrav 	if(r != 0) {
1697b5038d7SDag-Erling Smørgrav 		printf("Failed WSAStartup: %d\n", r);
1707b5038d7SDag-Erling Smørgrav 		result = EXIT_FAILURE;
1717b5038d7SDag-Erling Smørgrav 		goto exit;
1727b5038d7SDag-Erling Smørgrav 	}
1737b5038d7SDag-Erling Smørgrav #endif /* USE_WINSOCK */
1747b5038d7SDag-Erling Smørgrav 
1757b5038d7SDag-Erling Smørgrav 
1767b5038d7SDag-Erling Smørgrav 	PURPOSE = DRILL_QUERY;
1777b5038d7SDag-Erling Smørgrav 	qflags = LDNS_RD;
1787b5038d7SDag-Erling Smørgrav 	qport = LDNS_PORT;
1797b5038d7SDag-Erling Smørgrav 	verbosity = 2;
1807b5038d7SDag-Erling Smørgrav 	qdnssec = false;
1817b5038d7SDag-Erling Smørgrav 	qfamily = LDNS_RESOLV_INETANY;
1827b5038d7SDag-Erling Smørgrav 	qfallback = false;
1837b5038d7SDag-Erling Smørgrav 	qds = false;
1847b5038d7SDag-Erling Smørgrav 	qbuf = 0;
1857b5038d7SDag-Erling Smørgrav 	qusevc = false;
1867b5038d7SDag-Erling Smørgrav 	qrandom = true;
1877b5038d7SDag-Erling Smørgrav 	key_verified = NULL;
1887b5038d7SDag-Erling Smørgrav 
1897b5038d7SDag-Erling Smørgrav 	ldns_init_random(NULL, 0);
1907b5038d7SDag-Erling Smørgrav 
1917b5038d7SDag-Erling Smørgrav 	if (argc == 0) {
1927b5038d7SDag-Erling Smørgrav 		usage(stdout, progname);
1937b5038d7SDag-Erling Smørgrav 		result = EXIT_FAILURE;
1947b5038d7SDag-Erling Smørgrav 		goto exit;
1957b5038d7SDag-Erling Smørgrav 	}
1967b5038d7SDag-Erling Smørgrav 
1977b5038d7SDag-Erling Smørgrav 	/* string from orig drill: "i:w:I46Sk:TNp:b:DsvhVcuaq:f:xr" */
1987b5038d7SDag-Erling Smørgrav 	/* global first, query opt next, option with parm's last
1997b5038d7SDag-Erling Smørgrav 	 * and sorted */ /*  "46DITSVQf:i:w:q:achuvxzy:so:p:b:k:" */
2007b5038d7SDag-Erling Smørgrav 
201*17d15b25SDag-Erling Smørgrav 	while ((c = getopt(argc, argv, "46ab:c:d:Df:hi:I:k:o:p:q:Qr:sStTuvV:w:xy:z")) != -1) {
2027b5038d7SDag-Erling Smørgrav 		switch(c) {
2037b5038d7SDag-Erling Smørgrav 			/* global options */
2047b5038d7SDag-Erling Smørgrav 			case '4':
2057b5038d7SDag-Erling Smørgrav 				qfamily = LDNS_RESOLV_INET;
2067b5038d7SDag-Erling Smørgrav 				break;
2077b5038d7SDag-Erling Smørgrav 			case '6':
2087b5038d7SDag-Erling Smørgrav 				qfamily = LDNS_RESOLV_INET6;
2097b5038d7SDag-Erling Smørgrav 				break;
2107b5038d7SDag-Erling Smørgrav 			case 'D':
2117b5038d7SDag-Erling Smørgrav 				qdnssec = true;
2127b5038d7SDag-Erling Smørgrav 				break;
2137b5038d7SDag-Erling Smørgrav 			case 'I':
214*17d15b25SDag-Erling Smørgrav 				src = optarg;
2157b5038d7SDag-Erling Smørgrav 				break;
2167b5038d7SDag-Erling Smørgrav 			case 'T':
2177b5038d7SDag-Erling Smørgrav 				if (PURPOSE == DRILL_CHASE) {
2187b5038d7SDag-Erling Smørgrav 					fprintf(stderr, "-T and -S cannot be used at the same time.\n");
2197b5038d7SDag-Erling Smørgrav 					exit(EXIT_FAILURE);
2207b5038d7SDag-Erling Smørgrav 				}
2217b5038d7SDag-Erling Smørgrav 				PURPOSE = DRILL_TRACE;
2227b5038d7SDag-Erling Smørgrav 				break;
2237b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
2247b5038d7SDag-Erling Smørgrav 			case 'S':
2257b5038d7SDag-Erling Smørgrav 				if (PURPOSE == DRILL_TRACE) {
2267b5038d7SDag-Erling Smørgrav 					fprintf(stderr, "-T and -S cannot be used at the same time.\n");
2277b5038d7SDag-Erling Smørgrav 					exit(EXIT_FAILURE);
2287b5038d7SDag-Erling Smørgrav 				}
2297b5038d7SDag-Erling Smørgrav 				PURPOSE = DRILL_CHASE;
2307b5038d7SDag-Erling Smørgrav 				break;
2317b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
2327b5038d7SDag-Erling Smørgrav 			case 'V':
2337b5038d7SDag-Erling Smørgrav 				if (strtok(optarg, "0123456789") != NULL) {
2347b5038d7SDag-Erling Smørgrav 					fprintf(stderr, "-V expects an number as an argument.\n");
2357b5038d7SDag-Erling Smørgrav 					exit(EXIT_FAILURE);
2367b5038d7SDag-Erling Smørgrav 				}
2377b5038d7SDag-Erling Smørgrav 				verbosity = atoi(optarg);
2387b5038d7SDag-Erling Smørgrav 				break;
2397b5038d7SDag-Erling Smørgrav 			case 'Q':
2407b5038d7SDag-Erling Smørgrav 				verbosity = -1;
2417b5038d7SDag-Erling Smørgrav 				break;
2427b5038d7SDag-Erling Smørgrav 			case 'f':
2437b5038d7SDag-Erling Smørgrav 				query_file = optarg;
2447b5038d7SDag-Erling Smørgrav 				break;
2457b5038d7SDag-Erling Smørgrav 			case 'i':
2467b5038d7SDag-Erling Smørgrav 				answer_file = optarg;
2477b5038d7SDag-Erling Smørgrav 				PURPOSE = DRILL_AFROMFILE;
2487b5038d7SDag-Erling Smørgrav 				break;
2497b5038d7SDag-Erling Smørgrav 			case 'w':
2507b5038d7SDag-Erling Smørgrav 				answer_file = optarg;
2517b5038d7SDag-Erling Smørgrav 				break;
2527b5038d7SDag-Erling Smørgrav 			case 'q':
2537b5038d7SDag-Erling Smørgrav 				query_file = optarg;
2547b5038d7SDag-Erling Smørgrav 				PURPOSE = DRILL_QTOFILE;
2557b5038d7SDag-Erling Smørgrav 				break;
2567b5038d7SDag-Erling Smørgrav 			case 'r':
2577b5038d7SDag-Erling Smørgrav 				if (global_dns_root) {
2587b5038d7SDag-Erling Smørgrav 					fprintf(stderr, "There was already a series of root servers set\n");
2597b5038d7SDag-Erling Smørgrav 					exit(EXIT_FAILURE);
2607b5038d7SDag-Erling Smørgrav 				}
2617b5038d7SDag-Erling Smørgrav 				global_dns_root = read_root_hints(optarg);
2627b5038d7SDag-Erling Smørgrav 				if (!global_dns_root) {
2637b5038d7SDag-Erling Smørgrav 					fprintf(stderr, "Unable to read root hints file %s, aborting\n", optarg);
2647b5038d7SDag-Erling Smørgrav 					exit(EXIT_FAILURE);
2657b5038d7SDag-Erling Smørgrav 				}
2667b5038d7SDag-Erling Smørgrav 				break;
2677b5038d7SDag-Erling Smørgrav 			/* query options */
2687b5038d7SDag-Erling Smørgrav 			case 'a':
2697b5038d7SDag-Erling Smørgrav 				qfallback = true;
2707b5038d7SDag-Erling Smørgrav 				break;
2717b5038d7SDag-Erling Smørgrav 			case 'b':
2727b5038d7SDag-Erling Smørgrav 				qbuf = (uint16_t)atoi(optarg);
2737b5038d7SDag-Erling Smørgrav 				if (qbuf == 0) {
2747b5038d7SDag-Erling Smørgrav 					error("%s", "<bufsize> could not be converted");
2757b5038d7SDag-Erling Smørgrav 				}
2767b5038d7SDag-Erling Smørgrav 				break;
2777b5038d7SDag-Erling Smørgrav 			case 'c':
2787b5038d7SDag-Erling Smørgrav 				resolv_conf_file = optarg;
2797b5038d7SDag-Erling Smørgrav 				break;
2807b5038d7SDag-Erling Smørgrav 			case 't':
2817b5038d7SDag-Erling Smørgrav 				qusevc = true;
2827b5038d7SDag-Erling Smørgrav 				break;
2837b5038d7SDag-Erling Smørgrav 			case 'k':
2842787e39aSDag-Erling Smørgrav 				status = read_key_file(optarg,
2852787e39aSDag-Erling Smørgrav 						key_list, false);
2867b5038d7SDag-Erling Smørgrav 				if (status != LDNS_STATUS_OK) {
2877b5038d7SDag-Erling Smørgrav 					error("Could not parse the key file %s: %s", optarg, ldns_get_errorstr_by_id(status));
2887b5038d7SDag-Erling Smørgrav 				}
2897b5038d7SDag-Erling Smørgrav 				qdnssec = true; /* enable that too */
2907b5038d7SDag-Erling Smørgrav 				break;
2917b5038d7SDag-Erling Smørgrav 			case 'o':
2927b5038d7SDag-Erling Smørgrav 				/* only looks at the first hit: capital=ON, lowercase=OFF*/
2937b5038d7SDag-Erling Smørgrav 				if (strstr(optarg, "QR")) {
2947b5038d7SDag-Erling Smørgrav 					DRILL_ON(qflags, LDNS_QR);
2957b5038d7SDag-Erling Smørgrav 				}
2967b5038d7SDag-Erling Smørgrav 				if (strstr(optarg, "qr")) {
2977b5038d7SDag-Erling Smørgrav 					DRILL_OFF(qflags, LDNS_QR);
2987b5038d7SDag-Erling Smørgrav 				}
2997b5038d7SDag-Erling Smørgrav 				if (strstr(optarg, "AA")) {
3007b5038d7SDag-Erling Smørgrav 					DRILL_ON(qflags, LDNS_AA);
3017b5038d7SDag-Erling Smørgrav 				}
3027b5038d7SDag-Erling Smørgrav 				if (strstr(optarg, "aa")) {
3037b5038d7SDag-Erling Smørgrav 					DRILL_OFF(qflags, LDNS_AA);
3047b5038d7SDag-Erling Smørgrav 				}
3057b5038d7SDag-Erling Smørgrav 				if (strstr(optarg, "TC")) {
3067b5038d7SDag-Erling Smørgrav 					DRILL_ON(qflags, LDNS_TC);
3077b5038d7SDag-Erling Smørgrav 				}
3087b5038d7SDag-Erling Smørgrav 				if (strstr(optarg, "tc")) {
3097b5038d7SDag-Erling Smørgrav 					DRILL_OFF(qflags, LDNS_TC);
3107b5038d7SDag-Erling Smørgrav 				}
3117b5038d7SDag-Erling Smørgrav 				if (strstr(optarg, "RD")) {
3127b5038d7SDag-Erling Smørgrav 					DRILL_ON(qflags, LDNS_RD);
3137b5038d7SDag-Erling Smørgrav 				}
3147b5038d7SDag-Erling Smørgrav 				if (strstr(optarg, "rd")) {
3157b5038d7SDag-Erling Smørgrav 					DRILL_OFF(qflags, LDNS_RD);
3167b5038d7SDag-Erling Smørgrav 				}
3177b5038d7SDag-Erling Smørgrav 				if (strstr(optarg, "CD")) {
3187b5038d7SDag-Erling Smørgrav 					DRILL_ON(qflags, LDNS_CD);
3197b5038d7SDag-Erling Smørgrav 				}
3207b5038d7SDag-Erling Smørgrav 				if (strstr(optarg, "cd")) {
3217b5038d7SDag-Erling Smørgrav 					DRILL_OFF(qflags, LDNS_CD);
3227b5038d7SDag-Erling Smørgrav 				}
3237b5038d7SDag-Erling Smørgrav 				if (strstr(optarg, "RA")) {
3247b5038d7SDag-Erling Smørgrav 					DRILL_ON(qflags, LDNS_RA);
3257b5038d7SDag-Erling Smørgrav 				}
3267b5038d7SDag-Erling Smørgrav 				if (strstr(optarg, "ra")) {
3277b5038d7SDag-Erling Smørgrav 					DRILL_OFF(qflags, LDNS_RA);
3287b5038d7SDag-Erling Smørgrav 				}
3297b5038d7SDag-Erling Smørgrav 				if (strstr(optarg, "AD")) {
3307b5038d7SDag-Erling Smørgrav 					DRILL_ON(qflags, LDNS_AD);
3317b5038d7SDag-Erling Smørgrav 				}
3327b5038d7SDag-Erling Smørgrav 				if (strstr(optarg, "ad")) {
3337b5038d7SDag-Erling Smørgrav 					DRILL_OFF(qflags, LDNS_AD);
3347b5038d7SDag-Erling Smørgrav 				}
3357b5038d7SDag-Erling Smørgrav 				break;
3367b5038d7SDag-Erling Smørgrav 			case 'p':
3377b5038d7SDag-Erling Smørgrav 				qport = (uint16_t)atoi(optarg);
3387b5038d7SDag-Erling Smørgrav 				if (qport == 0) {
3397b5038d7SDag-Erling Smørgrav 					error("%s", "<port> could not be converted");
3407b5038d7SDag-Erling Smørgrav 				}
3417b5038d7SDag-Erling Smørgrav 				break;
3427b5038d7SDag-Erling Smørgrav 			case 's':
3437b5038d7SDag-Erling Smørgrav 				qds = true;
3447b5038d7SDag-Erling Smørgrav 				break;
3457b5038d7SDag-Erling Smørgrav 			case 'u':
3467b5038d7SDag-Erling Smørgrav 				qusevc = false;
3477b5038d7SDag-Erling Smørgrav 				break;
3487b5038d7SDag-Erling Smørgrav 			case 'v':
3497b5038d7SDag-Erling Smørgrav 				version(stdout, progname);
3507b5038d7SDag-Erling Smørgrav 				result = EXIT_SUCCESS;
3517b5038d7SDag-Erling Smørgrav 				goto exit;
3527b5038d7SDag-Erling Smørgrav 			case 'x':
3537b5038d7SDag-Erling Smørgrav 				PURPOSE = DRILL_REVERSE;
3547b5038d7SDag-Erling Smørgrav 				break;
3557b5038d7SDag-Erling Smørgrav 			case 'y':
3567b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
3577b5038d7SDag-Erling Smørgrav 				if (strchr(optarg, ':')) {
3587b5038d7SDag-Erling Smørgrav 					tsig_separator = (size_t) (strchr(optarg, ':') - optarg);
3597b5038d7SDag-Erling Smørgrav 					if (strchr(optarg + tsig_separator + 1, ':')) {
3607b5038d7SDag-Erling Smørgrav 						tsig_separator2 = (size_t) (strchr(optarg + tsig_separator + 1, ':') - optarg);
3617b5038d7SDag-Erling Smørgrav 						tsig_algorithm = xmalloc(strlen(optarg) - tsig_separator2);
3627b5038d7SDag-Erling Smørgrav 						strncpy(tsig_algorithm, optarg + tsig_separator2 + 1, strlen(optarg) - tsig_separator2);
3637b5038d7SDag-Erling Smørgrav 						tsig_algorithm[strlen(optarg) - tsig_separator2 - 1] = '\0';
3647b5038d7SDag-Erling Smørgrav 					} else {
3657b5038d7SDag-Erling Smørgrav 						tsig_separator2 = strlen(optarg);
3667b5038d7SDag-Erling Smørgrav 						tsig_algorithm = xmalloc(26);
3677b5038d7SDag-Erling Smørgrav 						strncpy(tsig_algorithm, "hmac-md5.sig-alg.reg.int.", 25);
3687b5038d7SDag-Erling Smørgrav 						tsig_algorithm[25] = '\0';
3697b5038d7SDag-Erling Smørgrav 					}
3707b5038d7SDag-Erling Smørgrav 					tsig_name = xmalloc(tsig_separator + 1);
3717b5038d7SDag-Erling Smørgrav 					tsig_data = xmalloc(tsig_separator2 - tsig_separator);
3727b5038d7SDag-Erling Smørgrav 					strncpy(tsig_name, optarg, tsig_separator);
3737b5038d7SDag-Erling Smørgrav 					strncpy(tsig_data, optarg + tsig_separator + 1, tsig_separator2 - tsig_separator - 1);
3747b5038d7SDag-Erling Smørgrav 					/* strncpy does not append \0 if source is longer than n */
3757b5038d7SDag-Erling Smørgrav 					tsig_name[tsig_separator] = '\0';
3767b5038d7SDag-Erling Smørgrav 					tsig_data[ tsig_separator2 - tsig_separator - 1] = '\0';
3777b5038d7SDag-Erling Smørgrav 				}
3787b5038d7SDag-Erling Smørgrav #else
3797b5038d7SDag-Erling Smørgrav 				fprintf(stderr, "TSIG requested, but SSL is not supported\n");
3807b5038d7SDag-Erling Smørgrav 				result = EXIT_FAILURE;
3817b5038d7SDag-Erling Smørgrav 				goto exit;
3827b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
3837b5038d7SDag-Erling Smørgrav 				break;
3847b5038d7SDag-Erling Smørgrav 			case 'z':
3857b5038d7SDag-Erling Smørgrav 				qrandom = false;
3867b5038d7SDag-Erling Smørgrav 				break;
3877b5038d7SDag-Erling Smørgrav 			case 'd':
3887b5038d7SDag-Erling Smørgrav 				trace_start_name = ldns_dname_new_frm_str(optarg);
3897b5038d7SDag-Erling Smørgrav 				if (!trace_start_name) {
3907b5038d7SDag-Erling Smørgrav 					fprintf(stderr, "Unable to parse argument for -%c\n", c);
3917b5038d7SDag-Erling Smørgrav 					result = EXIT_FAILURE;
3927b5038d7SDag-Erling Smørgrav 					goto exit;
3937b5038d7SDag-Erling Smørgrav 				}
3947b5038d7SDag-Erling Smørgrav 				break;
3957b5038d7SDag-Erling Smørgrav 			case 'h':
3967b5038d7SDag-Erling Smørgrav 				version(stdout, progname);
3977b5038d7SDag-Erling Smørgrav 				usage(stdout, progname);
3987b5038d7SDag-Erling Smørgrav 				result = EXIT_SUCCESS;
3997b5038d7SDag-Erling Smørgrav 				goto exit;
4007b5038d7SDag-Erling Smørgrav 				break;
4017b5038d7SDag-Erling Smørgrav 			default:
4027b5038d7SDag-Erling Smørgrav 				fprintf(stderr, "Unknown argument: -%c, use -h to see usage\n", c);
4037b5038d7SDag-Erling Smørgrav 				result = EXIT_FAILURE;
4047b5038d7SDag-Erling Smørgrav 				goto exit;
4057b5038d7SDag-Erling Smørgrav 		}
4067b5038d7SDag-Erling Smørgrav 	}
4077b5038d7SDag-Erling Smørgrav 	argc -= optind;
4087b5038d7SDag-Erling Smørgrav 	argv += optind;
4097b5038d7SDag-Erling Smørgrav 
4102787e39aSDag-Erling Smørgrav 	if ((PURPOSE == DRILL_CHASE || (PURPOSE == DRILL_TRACE && qdnssec)) &&
4112787e39aSDag-Erling Smørgrav 			ldns_rr_list_rr_count(key_list) == 0) {
4122787e39aSDag-Erling Smørgrav 
4132787e39aSDag-Erling Smørgrav 		(void) read_key_file(LDNS_TRUST_ANCHOR_FILE, key_list, true);
4142787e39aSDag-Erling Smørgrav 	}
4152787e39aSDag-Erling Smørgrav 	if (ldns_rr_list_rr_count(key_list) > 0) {
4162787e39aSDag-Erling Smørgrav 		printf(";; Number of trusted keys: %d\n",
4172787e39aSDag-Erling Smørgrav 				(int) ldns_rr_list_rr_count(key_list));
4182787e39aSDag-Erling Smørgrav 	}
4197b5038d7SDag-Erling Smørgrav 	/* do a secure trace when requested */
4207b5038d7SDag-Erling Smørgrav 	if (PURPOSE == DRILL_TRACE && qdnssec) {
4217b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
4227b5038d7SDag-Erling Smørgrav 		if (ldns_rr_list_rr_count(key_list) == 0) {
4237b5038d7SDag-Erling Smørgrav 			warning("%s", "No trusted keys were given. Will not be able to verify authenticity!");
4247b5038d7SDag-Erling Smørgrav 		}
4257b5038d7SDag-Erling Smørgrav 		PURPOSE = DRILL_SECTRACE;
4267b5038d7SDag-Erling Smørgrav #else
4277b5038d7SDag-Erling Smørgrav 		fprintf(stderr, "ldns has not been compiled with OpenSSL support. Secure trace not available\n");
4287b5038d7SDag-Erling Smørgrav 		exit(1);
4297b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
4307b5038d7SDag-Erling Smørgrav 	}
4317b5038d7SDag-Erling Smørgrav 
4327b5038d7SDag-Erling Smørgrav 	/* parse the arguments, with multiple arguments, the last argument
4337b5038d7SDag-Erling Smørgrav 	 * found is used */
4347b5038d7SDag-Erling Smørgrav 	for(i = 0; i < argc; i++) {
4357b5038d7SDag-Erling Smørgrav 
4367b5038d7SDag-Erling Smørgrav 		/* if ^@ then it's a server */
4377b5038d7SDag-Erling Smørgrav 		if (argv[i][0] == '@') {
4387b5038d7SDag-Erling Smørgrav 			if (strlen(argv[i]) == 1) {
4397b5038d7SDag-Erling Smørgrav 				warning("%s", "No nameserver given");
4407b5038d7SDag-Erling Smørgrav 				exit(EXIT_FAILURE);
4417b5038d7SDag-Erling Smørgrav 			}
4427b5038d7SDag-Erling Smørgrav 			serv = argv[i] + 1;
4437b5038d7SDag-Erling Smørgrav 			continue;
4447b5038d7SDag-Erling Smørgrav 		}
4457b5038d7SDag-Erling Smørgrav 		/* if has a dot, it's a name */
4467b5038d7SDag-Erling Smørgrav 		if (strchr(argv[i], '.')) {
4477b5038d7SDag-Erling Smørgrav 			name = argv[i];
4487b5038d7SDag-Erling Smørgrav 			continue;
4497b5038d7SDag-Erling Smørgrav 		}
4507b5038d7SDag-Erling Smørgrav 		/* if it matches a type, it's a type */
4517b5038d7SDag-Erling Smørgrav 		if (int_type == -1) {
4527b5038d7SDag-Erling Smørgrav 			type = ldns_get_rr_type_by_name(argv[i]);
4537b5038d7SDag-Erling Smørgrav 			if (type != 0) {
4547b5038d7SDag-Erling Smørgrav 				int_type = 0;
4557b5038d7SDag-Erling Smørgrav 				continue;
4567b5038d7SDag-Erling Smørgrav 			}
4577b5038d7SDag-Erling Smørgrav 		}
4587b5038d7SDag-Erling Smørgrav 		/* if it matches a class, it's a class */
4597b5038d7SDag-Erling Smørgrav 		if (int_clas == -1) {
4607b5038d7SDag-Erling Smørgrav 			clas = ldns_get_rr_class_by_name(argv[i]);
4617b5038d7SDag-Erling Smørgrav 			if (clas != 0) {
4627b5038d7SDag-Erling Smørgrav 				int_clas = 0;
4637b5038d7SDag-Erling Smørgrav 				continue;
4647b5038d7SDag-Erling Smørgrav 			}
4657b5038d7SDag-Erling Smørgrav 		}
4667b5038d7SDag-Erling Smørgrav 		/* it all fails assume it's a name */
4677b5038d7SDag-Erling Smørgrav 		name = argv[i];
4687b5038d7SDag-Erling Smørgrav 	}
4697b5038d7SDag-Erling Smørgrav 	/* act like dig and use for . NS */
4707b5038d7SDag-Erling Smørgrav 	if (!name) {
4717b5038d7SDag-Erling Smørgrav 		name = ".";
4727b5038d7SDag-Erling Smørgrav 		int_type = 0;
4737b5038d7SDag-Erling Smørgrav 		type = LDNS_RR_TYPE_NS;
4747b5038d7SDag-Erling Smørgrav 	}
4757b5038d7SDag-Erling Smørgrav 
4767b5038d7SDag-Erling Smørgrav 	/* defaults if not given */
4777b5038d7SDag-Erling Smørgrav 	if (int_clas == -1) {
4787b5038d7SDag-Erling Smørgrav 		clas = LDNS_RR_CLASS_IN;
4797b5038d7SDag-Erling Smørgrav 	}
4807b5038d7SDag-Erling Smørgrav 	if (int_type == -1) {
4817b5038d7SDag-Erling Smørgrav 		if (PURPOSE != DRILL_REVERSE) {
4827b5038d7SDag-Erling Smørgrav 			type = LDNS_RR_TYPE_A;
4837b5038d7SDag-Erling Smørgrav 		} else {
4847b5038d7SDag-Erling Smørgrav 			type = LDNS_RR_TYPE_PTR;
4857b5038d7SDag-Erling Smørgrav 		}
4867b5038d7SDag-Erling Smørgrav 	}
4877b5038d7SDag-Erling Smørgrav 
488*17d15b25SDag-Erling Smørgrav 	if (src) {
489*17d15b25SDag-Erling Smørgrav 		src_rdf = ldns_rdf_new_addr_frm_str(src);
490*17d15b25SDag-Erling Smørgrav 		if(!src_rdf) {
491*17d15b25SDag-Erling Smørgrav 			fprintf(stderr, "-I must be (or resolve) to a valid IP[v6] address.\n");
492*17d15b25SDag-Erling Smørgrav 			exit(EXIT_FAILURE);
493*17d15b25SDag-Erling Smørgrav 		}
494*17d15b25SDag-Erling Smørgrav 	}
495*17d15b25SDag-Erling Smørgrav 
4967b5038d7SDag-Erling Smørgrav 	/* set the nameserver to use */
4977b5038d7SDag-Erling Smørgrav 	if (!serv) {
4987b5038d7SDag-Erling Smørgrav 		/* no server given make a resolver from /etc/resolv.conf */
4997b5038d7SDag-Erling Smørgrav 		status = ldns_resolver_new_frm_file(&res, resolv_conf_file);
5007b5038d7SDag-Erling Smørgrav 		if (status != LDNS_STATUS_OK) {
5017b5038d7SDag-Erling Smørgrav 			warning("Could not create a resolver structure: %s (%s)\n"
5027b5038d7SDag-Erling Smørgrav 					"Try drill @localhost if you have a resolver running on your machine.",
5037b5038d7SDag-Erling Smørgrav 				    ldns_get_errorstr_by_id(status), resolv_conf_file);
5047b5038d7SDag-Erling Smørgrav 			result = EXIT_FAILURE;
5057b5038d7SDag-Erling Smørgrav 			goto exit;
5067b5038d7SDag-Erling Smørgrav 		}
5077b5038d7SDag-Erling Smørgrav 	} else {
5087b5038d7SDag-Erling Smørgrav 		res = ldns_resolver_new();
5097b5038d7SDag-Erling Smørgrav 		if (!res || strlen(serv) <= 0) {
5107b5038d7SDag-Erling Smørgrav 			warning("Could not create a resolver structure");
5117b5038d7SDag-Erling Smørgrav 			result = EXIT_FAILURE;
5127b5038d7SDag-Erling Smørgrav 			goto exit;
5137b5038d7SDag-Erling Smørgrav 		}
5147b5038d7SDag-Erling Smørgrav 		/* add the nameserver */
5157b5038d7SDag-Erling Smørgrav 		serv_rdf = ldns_rdf_new_addr_frm_str(serv);
5167b5038d7SDag-Erling Smørgrav 		if (!serv_rdf) {
5177b5038d7SDag-Erling Smørgrav 			/* try to resolv the name if possible */
5187b5038d7SDag-Erling Smørgrav 			status = ldns_resolver_new_frm_file(&cmdline_res, resolv_conf_file);
5197b5038d7SDag-Erling Smørgrav 
5207b5038d7SDag-Erling Smørgrav 			if (status != LDNS_STATUS_OK) {
5217b5038d7SDag-Erling Smørgrav 				error("%s", "@server ip could not be converted");
5227b5038d7SDag-Erling Smørgrav 			}
5237b5038d7SDag-Erling Smørgrav 			ldns_resolver_set_dnssec(cmdline_res, qdnssec);
5247b5038d7SDag-Erling Smørgrav 			ldns_resolver_set_ip6(cmdline_res, qfamily);
5257b5038d7SDag-Erling Smørgrav 			ldns_resolver_set_fallback(cmdline_res, qfallback);
5267b5038d7SDag-Erling Smørgrav 			ldns_resolver_set_usevc(cmdline_res, qusevc);
527*17d15b25SDag-Erling Smørgrav 			ldns_resolver_set_source(cmdline_res, src_rdf);
5287b5038d7SDag-Erling Smørgrav 
5297b5038d7SDag-Erling Smørgrav 			cmdline_dname = ldns_dname_new_frm_str(serv);
5307b5038d7SDag-Erling Smørgrav 
5317b5038d7SDag-Erling Smørgrav 			cmdline_rr_list = ldns_get_rr_list_addr_by_name(
5327b5038d7SDag-Erling Smørgrav 						cmdline_res,
5337b5038d7SDag-Erling Smørgrav 						cmdline_dname,
5347b5038d7SDag-Erling Smørgrav 						LDNS_RR_CLASS_IN,
5357b5038d7SDag-Erling Smørgrav 						qflags);
5367b5038d7SDag-Erling Smørgrav 			ldns_rdf_deep_free(cmdline_dname);
5377b5038d7SDag-Erling Smørgrav 			if (!cmdline_rr_list) {
5387b5038d7SDag-Erling Smørgrav 				/* This error msg is not always accurate */
5397b5038d7SDag-Erling Smørgrav 				error("%s `%s\'", "could not find any address for the name:", serv);
5407b5038d7SDag-Erling Smørgrav 			} else {
5417b5038d7SDag-Erling Smørgrav 				if (ldns_resolver_push_nameserver_rr_list(
5427b5038d7SDag-Erling Smørgrav 						res,
5437b5038d7SDag-Erling Smørgrav 						cmdline_rr_list
5447b5038d7SDag-Erling Smørgrav 					) != LDNS_STATUS_OK) {
5457b5038d7SDag-Erling Smørgrav 					error("%s", "pushing nameserver");
5467b5038d7SDag-Erling Smørgrav 				}
5477b5038d7SDag-Erling Smørgrav 			}
5487b5038d7SDag-Erling Smørgrav 		} else {
5497b5038d7SDag-Erling Smørgrav 			if (ldns_resolver_push_nameserver(res, serv_rdf) != LDNS_STATUS_OK) {
5507b5038d7SDag-Erling Smørgrav 				error("%s", "pushing nameserver");
5517b5038d7SDag-Erling Smørgrav 			} else {
5527b5038d7SDag-Erling Smørgrav 				ldns_rdf_deep_free(serv_rdf);
5537b5038d7SDag-Erling Smørgrav 			}
5547b5038d7SDag-Erling Smørgrav 		}
5557b5038d7SDag-Erling Smørgrav 	}
5567b5038d7SDag-Erling Smørgrav 	/* set the resolver options */
5577b5038d7SDag-Erling Smørgrav 	ldns_resolver_set_port(res, qport);
558*17d15b25SDag-Erling Smørgrav 	ldns_resolver_set_source(res, src_rdf);
5597b5038d7SDag-Erling Smørgrav 	if (verbosity >= 5) {
5607b5038d7SDag-Erling Smørgrav 		ldns_resolver_set_debug(res, true);
5617b5038d7SDag-Erling Smørgrav 	} else {
5627b5038d7SDag-Erling Smørgrav 		ldns_resolver_set_debug(res, false);
5637b5038d7SDag-Erling Smørgrav 	}
5647b5038d7SDag-Erling Smørgrav 	ldns_resolver_set_dnssec(res, qdnssec);
5657b5038d7SDag-Erling Smørgrav /*	ldns_resolver_set_dnssec_cd(res, qdnssec);*/
5667b5038d7SDag-Erling Smørgrav 	ldns_resolver_set_ip6(res, qfamily);
5677b5038d7SDag-Erling Smørgrav 	ldns_resolver_set_fallback(res, qfallback);
5687b5038d7SDag-Erling Smørgrav 	ldns_resolver_set_usevc(res, qusevc);
5697b5038d7SDag-Erling Smørgrav 	ldns_resolver_set_random(res, qrandom);
5707b5038d7SDag-Erling Smørgrav 	if (qbuf != 0) {
5717b5038d7SDag-Erling Smørgrav 		ldns_resolver_set_edns_udp_size(res, qbuf);
5727b5038d7SDag-Erling Smørgrav 	}
5737b5038d7SDag-Erling Smørgrav 
5747b5038d7SDag-Erling Smørgrav 	if (!name &&
5757b5038d7SDag-Erling Smørgrav 	    PURPOSE != DRILL_AFROMFILE &&
5767b5038d7SDag-Erling Smørgrav 	    !query_file
5777b5038d7SDag-Erling Smørgrav 	   ) {
5787b5038d7SDag-Erling Smørgrav 		usage(stdout, progname);
5797b5038d7SDag-Erling Smørgrav 		result = EXIT_FAILURE;
5807b5038d7SDag-Erling Smørgrav 		goto exit;
5817b5038d7SDag-Erling Smørgrav 	}
5827b5038d7SDag-Erling Smørgrav 
5837b5038d7SDag-Erling Smørgrav 	if (tsig_name && tsig_data) {
5847b5038d7SDag-Erling Smørgrav 		ldns_resolver_set_tsig_keyname(res, tsig_name);
5857b5038d7SDag-Erling Smørgrav 		ldns_resolver_set_tsig_keydata(res, tsig_data);
5867b5038d7SDag-Erling Smørgrav 		ldns_resolver_set_tsig_algorithm(res, tsig_algorithm);
5877b5038d7SDag-Erling Smørgrav 	}
5887b5038d7SDag-Erling Smørgrav 
5897b5038d7SDag-Erling Smørgrav 	/* main switching part of drill */
5907b5038d7SDag-Erling Smørgrav 	switch(PURPOSE) {
5917b5038d7SDag-Erling Smørgrav 		case DRILL_TRACE:
5927b5038d7SDag-Erling Smørgrav 			/* do a trace from the root down */
5937b5038d7SDag-Erling Smørgrav 			if (!global_dns_root) {
5947b5038d7SDag-Erling Smørgrav 				init_root();
5957b5038d7SDag-Erling Smørgrav 			}
5967b5038d7SDag-Erling Smørgrav 			qname = ldns_dname_new_frm_str(name);
5977b5038d7SDag-Erling Smørgrav 			if (!qname) {
5987b5038d7SDag-Erling Smørgrav 				error("%s", "parsing query name");
5997b5038d7SDag-Erling Smørgrav 			}
6007b5038d7SDag-Erling Smørgrav 			/* don't care about return packet */
6017b5038d7SDag-Erling Smørgrav 			(void)do_trace(res, qname, type, clas);
6027b5038d7SDag-Erling Smørgrav 			clear_root();
6037b5038d7SDag-Erling Smørgrav 			break;
6047b5038d7SDag-Erling Smørgrav 		case DRILL_SECTRACE:
6057b5038d7SDag-Erling Smørgrav 			/* do a secure trace from the root down */
6067b5038d7SDag-Erling Smørgrav 			if (!global_dns_root) {
6077b5038d7SDag-Erling Smørgrav 				init_root();
6087b5038d7SDag-Erling Smørgrav 			}
6097b5038d7SDag-Erling Smørgrav 			qname = ldns_dname_new_frm_str(name);
6107b5038d7SDag-Erling Smørgrav 			if (!qname) {
6117b5038d7SDag-Erling Smørgrav 				error("%s", "making qname");
6127b5038d7SDag-Erling Smørgrav 			}
6137b5038d7SDag-Erling Smørgrav 			/* don't care about return packet */
6147b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
6157b5038d7SDag-Erling Smørgrav 			result = do_secure_trace(res, qname, type, clas, key_list, trace_start_name);
6167b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
6177b5038d7SDag-Erling Smørgrav 			clear_root();
6187b5038d7SDag-Erling Smørgrav 			break;
6197b5038d7SDag-Erling Smørgrav 		case DRILL_CHASE:
6207b5038d7SDag-Erling Smørgrav 			qname = ldns_dname_new_frm_str(name);
6217b5038d7SDag-Erling Smørgrav 			if (!qname) {
6227b5038d7SDag-Erling Smørgrav 				error("%s", "making qname");
6237b5038d7SDag-Erling Smørgrav 			}
6247b5038d7SDag-Erling Smørgrav 
6257b5038d7SDag-Erling Smørgrav 			ldns_resolver_set_dnssec(res, true);
6267b5038d7SDag-Erling Smørgrav 			ldns_resolver_set_dnssec_cd(res, true);
6277b5038d7SDag-Erling Smørgrav 			/* set dnssec implies udp_size of 4096 */
6287b5038d7SDag-Erling Smørgrav 			ldns_resolver_set_edns_udp_size(res, 4096);
629*17d15b25SDag-Erling Smørgrav 			pkt = NULL;
630*17d15b25SDag-Erling Smørgrav 			status = ldns_resolver_query_status(
631*17d15b25SDag-Erling Smørgrav 					&pkt, res, qname, type, clas, qflags);
632*17d15b25SDag-Erling Smørgrav 			if (status != LDNS_STATUS_OK) {
633*17d15b25SDag-Erling Smørgrav 				error("error sending query: %s",
634*17d15b25SDag-Erling Smørgrav 					ldns_get_errorstr_by_id(status));
635*17d15b25SDag-Erling Smørgrav 			}
6367b5038d7SDag-Erling Smørgrav 			if (!pkt) {
637*17d15b25SDag-Erling Smørgrav 				if (status == LDNS_STATUS_OK) {
6387b5038d7SDag-Erling Smørgrav 					error("%s", "error pkt sending");
639*17d15b25SDag-Erling Smørgrav 				}
6407b5038d7SDag-Erling Smørgrav 				result = EXIT_FAILURE;
6417b5038d7SDag-Erling Smørgrav 			} else {
6427b5038d7SDag-Erling Smørgrav 				if (verbosity >= 3) {
6437b5038d7SDag-Erling Smørgrav 					ldns_pkt_print(stdout, pkt);
6447b5038d7SDag-Erling Smørgrav 				}
6457b5038d7SDag-Erling Smørgrav 
6467b5038d7SDag-Erling Smørgrav 				if (!ldns_pkt_answer(pkt)) {
6477b5038d7SDag-Erling Smørgrav 					mesg("No answer in packet");
6487b5038d7SDag-Erling Smørgrav 				} else {
6497b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
6507b5038d7SDag-Erling Smørgrav 					ldns_resolver_set_dnssec_anchors(res, ldns_rr_list_clone(key_list));
6517b5038d7SDag-Erling Smørgrav 					result = do_chase(res, qname, type,
6527b5038d7SDag-Erling Smørgrav 					                  clas, key_list,
6537b5038d7SDag-Erling Smørgrav 					                  pkt, qflags, NULL,
6547b5038d7SDag-Erling Smørgrav 								   verbosity);
6557b5038d7SDag-Erling Smørgrav 					if (result == LDNS_STATUS_OK) {
6567b5038d7SDag-Erling Smørgrav 						if (verbosity != -1) {
6577b5038d7SDag-Erling Smørgrav 							mesg("Chase successful");
6587b5038d7SDag-Erling Smørgrav 						}
6597b5038d7SDag-Erling Smørgrav 						result = 0;
6607b5038d7SDag-Erling Smørgrav 					} else {
6617b5038d7SDag-Erling Smørgrav 						if (verbosity != -1) {
6627b5038d7SDag-Erling Smørgrav 							mesg("Chase failed.");
6637b5038d7SDag-Erling Smørgrav 						}
6647b5038d7SDag-Erling Smørgrav 					}
6657b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
6667b5038d7SDag-Erling Smørgrav 				}
6677b5038d7SDag-Erling Smørgrav 				ldns_pkt_free(pkt);
6687b5038d7SDag-Erling Smørgrav 			}
6697b5038d7SDag-Erling Smørgrav 			break;
6707b5038d7SDag-Erling Smørgrav 		case DRILL_AFROMFILE:
6717b5038d7SDag-Erling Smørgrav 			pkt = read_hex_pkt(answer_file);
6727b5038d7SDag-Erling Smørgrav 			if (pkt) {
6737b5038d7SDag-Erling Smørgrav 				if (verbosity != -1) {
6747b5038d7SDag-Erling Smørgrav 					ldns_pkt_print(stdout, pkt);
6757b5038d7SDag-Erling Smørgrav 				}
6767b5038d7SDag-Erling Smørgrav 				ldns_pkt_free(pkt);
6777b5038d7SDag-Erling Smørgrav 			}
6787b5038d7SDag-Erling Smørgrav 
6797b5038d7SDag-Erling Smørgrav 			break;
6807b5038d7SDag-Erling Smørgrav 		case DRILL_QTOFILE:
6817b5038d7SDag-Erling Smørgrav 			qname = ldns_dname_new_frm_str(name);
6827b5038d7SDag-Erling Smørgrav 			if (!qname) {
6837b5038d7SDag-Erling Smørgrav 				error("%s", "making qname");
6847b5038d7SDag-Erling Smørgrav 			}
6857b5038d7SDag-Erling Smørgrav 
6867b5038d7SDag-Erling Smørgrav 			status = ldns_resolver_prepare_query_pkt(&qpkt, res, qname, type, clas, qflags);
6877b5038d7SDag-Erling Smørgrav 			if(status != LDNS_STATUS_OK) {
6887b5038d7SDag-Erling Smørgrav 				error("%s", "making query: %s",
6897b5038d7SDag-Erling Smørgrav 					ldns_get_errorstr_by_id(status));
6907b5038d7SDag-Erling Smørgrav 			}
6917b5038d7SDag-Erling Smørgrav 			dump_hex(qpkt, query_file);
6927b5038d7SDag-Erling Smørgrav 			ldns_pkt_free(qpkt);
6937b5038d7SDag-Erling Smørgrav 			break;
6947b5038d7SDag-Erling Smørgrav 		case DRILL_NSEC:
6957b5038d7SDag-Erling Smørgrav 			break;
6967b5038d7SDag-Erling Smørgrav 		case DRILL_REVERSE:
6977b5038d7SDag-Erling Smørgrav 			/* ipv4 or ipv6 addr? */
6987b5038d7SDag-Erling Smørgrav 			if (strchr(name, ':')) {
6997b5038d7SDag-Erling Smørgrav 				if (strchr(name, '.')) {
7007b5038d7SDag-Erling Smørgrav 					error("Syntax error: both '.' and ':' seen in address\n");
7017b5038d7SDag-Erling Smørgrav 				}
7027b5038d7SDag-Erling Smørgrav 				name2 = malloc(IP6_ARPA_MAX_LEN + 20);
7037b5038d7SDag-Erling Smørgrav 				c = 0;
7047b5038d7SDag-Erling Smørgrav 				for (i=0; i<(int)strlen(name); i++) {
7057b5038d7SDag-Erling Smørgrav 					if (i >= IP6_ARPA_MAX_LEN) {
7067b5038d7SDag-Erling Smørgrav 						error("%s", "reverse argument to long");
7077b5038d7SDag-Erling Smørgrav 					}
7087b5038d7SDag-Erling Smørgrav 					if (name[i] == ':') {
7097b5038d7SDag-Erling Smørgrav 						if (i < (int) strlen(name) && name[i + 1] == ':') {
7107b5038d7SDag-Erling Smørgrav 							error("%s", ":: not supported (yet)");
7117b5038d7SDag-Erling Smørgrav 						} else {
7127b5038d7SDag-Erling Smørgrav 							if (i + 2 == (int) strlen(name) || name[i + 2] == ':') {
7137b5038d7SDag-Erling Smørgrav 								name2[c++] = '0';
7147b5038d7SDag-Erling Smørgrav 								name2[c++] = '.';
7157b5038d7SDag-Erling Smørgrav 								name2[c++] = '0';
7167b5038d7SDag-Erling Smørgrav 								name2[c++] = '.';
7177b5038d7SDag-Erling Smørgrav 								name2[c++] = '0';
7187b5038d7SDag-Erling Smørgrav 								name2[c++] = '.';
7197b5038d7SDag-Erling Smørgrav 							} else if (i + 3 == (int) strlen(name) || name[i + 3] == ':') {
7207b5038d7SDag-Erling Smørgrav 								name2[c++] = '0';
7217b5038d7SDag-Erling Smørgrav 								name2[c++] = '.';
7227b5038d7SDag-Erling Smørgrav 								name2[c++] = '0';
7237b5038d7SDag-Erling Smørgrav 								name2[c++] = '.';
7247b5038d7SDag-Erling Smørgrav 							} else if (i + 4 == (int) strlen(name) || name[i + 4] == ':') {
7257b5038d7SDag-Erling Smørgrav 								name2[c++] = '0';
7267b5038d7SDag-Erling Smørgrav 								name2[c++] = '.';
7277b5038d7SDag-Erling Smørgrav 							}
7287b5038d7SDag-Erling Smørgrav 						}
7297b5038d7SDag-Erling Smørgrav 					} else {
7307b5038d7SDag-Erling Smørgrav 						name2[c++] = name[i];
7317b5038d7SDag-Erling Smørgrav 						name2[c++] = '.';
7327b5038d7SDag-Erling Smørgrav 					}
7337b5038d7SDag-Erling Smørgrav 				}
7347b5038d7SDag-Erling Smørgrav 				name2[c++] = '\0';
7357b5038d7SDag-Erling Smørgrav 
7367b5038d7SDag-Erling Smørgrav 				qname = ldns_dname_new_frm_str(name2);
7377b5038d7SDag-Erling Smørgrav 				qname_tmp = ldns_dname_reverse(qname);
7387b5038d7SDag-Erling Smørgrav 				ldns_rdf_deep_free(qname);
7397b5038d7SDag-Erling Smørgrav 				qname = qname_tmp;
7407b5038d7SDag-Erling Smørgrav 				qname_tmp = ldns_dname_new_frm_str("ip6.arpa.");
7417b5038d7SDag-Erling Smørgrav 				status = ldns_dname_cat(qname, qname_tmp);
7427b5038d7SDag-Erling Smørgrav 				if (status != LDNS_STATUS_OK) {
7437b5038d7SDag-Erling Smørgrav 					error("%s", "could not create reverse address for ip6: %s\n", ldns_get_errorstr_by_id(status));
7447b5038d7SDag-Erling Smørgrav 				}
7457b5038d7SDag-Erling Smørgrav 				ldns_rdf_deep_free(qname_tmp);
7467b5038d7SDag-Erling Smørgrav 
7477b5038d7SDag-Erling Smørgrav 				free(name2);
7487b5038d7SDag-Erling Smørgrav 			} else {
7497b5038d7SDag-Erling Smørgrav 				qname = ldns_dname_new_frm_str(name);
7507b5038d7SDag-Erling Smørgrav 				qname_tmp = ldns_dname_reverse(qname);
7517b5038d7SDag-Erling Smørgrav 				ldns_rdf_deep_free(qname);
7527b5038d7SDag-Erling Smørgrav 				qname = qname_tmp;
7537b5038d7SDag-Erling Smørgrav 				qname_tmp = ldns_dname_new_frm_str("in-addr.arpa.");
7547b5038d7SDag-Erling Smørgrav 				status = ldns_dname_cat(qname, qname_tmp);
7557b5038d7SDag-Erling Smørgrav 				if (status != LDNS_STATUS_OK) {
7567b5038d7SDag-Erling Smørgrav 					error("%s", "could not create reverse address for ip4: %s\n", ldns_get_errorstr_by_id(status));
7577b5038d7SDag-Erling Smørgrav 				}
7587b5038d7SDag-Erling Smørgrav 				ldns_rdf_deep_free(qname_tmp);
7597b5038d7SDag-Erling Smørgrav 			}
7607b5038d7SDag-Erling Smørgrav 			if (!qname) {
7617b5038d7SDag-Erling Smørgrav 				error("%s", "-x implies an ip address");
7627b5038d7SDag-Erling Smørgrav 			}
7637b5038d7SDag-Erling Smørgrav 
7647b5038d7SDag-Erling Smørgrav 			/* create a packet and set the RD flag on it */
765*17d15b25SDag-Erling Smørgrav 			pkt = NULL;
766*17d15b25SDag-Erling Smørgrav 			status = ldns_resolver_query_status(
767*17d15b25SDag-Erling Smørgrav 					&pkt, res, qname, type, clas, qflags);
768*17d15b25SDag-Erling Smørgrav 			if (status != LDNS_STATUS_OK) {
769*17d15b25SDag-Erling Smørgrav 				error("error sending query: %s",
770*17d15b25SDag-Erling Smørgrav 					ldns_get_errorstr_by_id(status));
771*17d15b25SDag-Erling Smørgrav 			}
7727b5038d7SDag-Erling Smørgrav 			if (!pkt)  {
773*17d15b25SDag-Erling Smørgrav 				if (status == LDNS_STATUS_OK) {
7747b5038d7SDag-Erling Smørgrav 					error("%s", "pkt sending");
775*17d15b25SDag-Erling Smørgrav 				}
7767b5038d7SDag-Erling Smørgrav 				result = EXIT_FAILURE;
7777b5038d7SDag-Erling Smørgrav 			} else {
7787b5038d7SDag-Erling Smørgrav 				if (verbosity != -1) {
7797b5038d7SDag-Erling Smørgrav 					ldns_pkt_print(stdout, pkt);
7807b5038d7SDag-Erling Smørgrav 				}
7817b5038d7SDag-Erling Smørgrav 				ldns_pkt_free(pkt);
7827b5038d7SDag-Erling Smørgrav 			}
7837b5038d7SDag-Erling Smørgrav 			break;
7847b5038d7SDag-Erling Smørgrav 		case DRILL_QUERY:
7857b5038d7SDag-Erling Smørgrav 		default:
7867b5038d7SDag-Erling Smørgrav 			if (query_file) {
7877b5038d7SDag-Erling Smørgrav 				/* this old way, the query packet needed
7887b5038d7SDag-Erling Smørgrav 				   to be parseable, but we want to be able
7897b5038d7SDag-Erling Smørgrav 				   to send mangled packets, so we need
7907b5038d7SDag-Erling Smørgrav 				   to do it directly */
7917b5038d7SDag-Erling Smørgrav 				#if 0
7927b5038d7SDag-Erling Smørgrav 				qpkt = read_hex_pkt(query_file);
7937b5038d7SDag-Erling Smørgrav 				if (qpkt) {
7947b5038d7SDag-Erling Smørgrav 					status = ldns_resolver_send_pkt(&pkt, res, qpkt);
7957b5038d7SDag-Erling Smørgrav 					if (status != LDNS_STATUS_OK) {
7967b5038d7SDag-Erling Smørgrav 						printf("Error: %s\n", ldns_get_errorstr_by_id(status));
7977b5038d7SDag-Erling Smørgrav 						exit(1);
7987b5038d7SDag-Erling Smørgrav 					}
7997b5038d7SDag-Erling Smørgrav 				} else {
8007b5038d7SDag-Erling Smørgrav 					/* qpkt was bogus, reset pkt */
8017b5038d7SDag-Erling Smørgrav 					pkt = NULL;
8027b5038d7SDag-Erling Smørgrav 				}
8037b5038d7SDag-Erling Smørgrav 				#endif
8047b5038d7SDag-Erling Smørgrav 				query_buffer = read_hex_buffer(query_file);
8057b5038d7SDag-Erling Smørgrav 				if (query_buffer) {
8067b5038d7SDag-Erling Smørgrav 					status = ldns_send_buffer(&pkt, res, query_buffer, NULL);
8077b5038d7SDag-Erling Smørgrav 					ldns_buffer_free(query_buffer);
8087b5038d7SDag-Erling Smørgrav 					if (status != LDNS_STATUS_OK) {
8097b5038d7SDag-Erling Smørgrav 						printf("Error: %s\n", ldns_get_errorstr_by_id(status));
8107b5038d7SDag-Erling Smørgrav 						exit(1);
8117b5038d7SDag-Erling Smørgrav 					}
8127b5038d7SDag-Erling Smørgrav 				} else {
8137b5038d7SDag-Erling Smørgrav 					printf("NO BUFFER\n");
8147b5038d7SDag-Erling Smørgrav 					pkt = NULL;
8157b5038d7SDag-Erling Smørgrav 				}
8167b5038d7SDag-Erling Smørgrav 			} else {
8177b5038d7SDag-Erling Smørgrav 				qname = ldns_dname_new_frm_str(name);
8187b5038d7SDag-Erling Smørgrav 				if (!qname) {
8197b5038d7SDag-Erling Smørgrav 					error("%s", "error in making qname");
8207b5038d7SDag-Erling Smørgrav 				}
8217b5038d7SDag-Erling Smørgrav 
8227b5038d7SDag-Erling Smørgrav 				if (type == LDNS_RR_TYPE_AXFR) {
8237b5038d7SDag-Erling Smørgrav 					status = ldns_axfr_start(res, qname, clas);
8247b5038d7SDag-Erling Smørgrav 					if(status != LDNS_STATUS_OK) {
8257b5038d7SDag-Erling Smørgrav 						error("Error starting axfr: %s",
8267b5038d7SDag-Erling Smørgrav 							ldns_get_errorstr_by_id(status));
8277b5038d7SDag-Erling Smørgrav 					}
8287b5038d7SDag-Erling Smørgrav 					axfr_rr = ldns_axfr_next(res);
8297b5038d7SDag-Erling Smørgrav 					if(!axfr_rr) {
8307b5038d7SDag-Erling Smørgrav 						fprintf(stderr, "AXFR failed.\n");
8317b5038d7SDag-Erling Smørgrav 						ldns_pkt_print(stdout,
8327b5038d7SDag-Erling Smørgrav 							ldns_axfr_last_pkt(res));
8337b5038d7SDag-Erling Smørgrav 						goto exit;
8347b5038d7SDag-Erling Smørgrav 					}
8357b5038d7SDag-Erling Smørgrav 					while (axfr_rr) {
8367b5038d7SDag-Erling Smørgrav 						if (verbosity != -1) {
8377b5038d7SDag-Erling Smørgrav 							ldns_rr_print(stdout, axfr_rr);
8387b5038d7SDag-Erling Smørgrav 						}
8397b5038d7SDag-Erling Smørgrav 						ldns_rr_free(axfr_rr);
8407b5038d7SDag-Erling Smørgrav 						axfr_rr = ldns_axfr_next(res);
8417b5038d7SDag-Erling Smørgrav 					}
8427b5038d7SDag-Erling Smørgrav 
8437b5038d7SDag-Erling Smørgrav 					goto exit;
8447b5038d7SDag-Erling Smørgrav 				} else {
8457b5038d7SDag-Erling Smørgrav 					/* create a packet and set the RD flag on it */
846*17d15b25SDag-Erling Smørgrav 					pkt = NULL;
847*17d15b25SDag-Erling Smørgrav 					status = ldns_resolver_query_status(
848*17d15b25SDag-Erling Smørgrav 							&pkt, res, qname,
849*17d15b25SDag-Erling Smørgrav 							type, clas, qflags);
850*17d15b25SDag-Erling Smørgrav 					if (status != LDNS_STATUS_OK) {
851*17d15b25SDag-Erling Smørgrav 						error("error sending query: %s"
852*17d15b25SDag-Erling Smørgrav 						     , ldns_get_errorstr_by_id(
853*17d15b25SDag-Erling Smørgrav 							     status));
854*17d15b25SDag-Erling Smørgrav 					}
8557b5038d7SDag-Erling Smørgrav 				}
8567b5038d7SDag-Erling Smørgrav 			}
8577b5038d7SDag-Erling Smørgrav 
8587b5038d7SDag-Erling Smørgrav 			if (!pkt)  {
8597b5038d7SDag-Erling Smørgrav 				mesg("No packet received");
8607b5038d7SDag-Erling Smørgrav 				result = EXIT_FAILURE;
8617b5038d7SDag-Erling Smørgrav 			} else {
8627b5038d7SDag-Erling Smørgrav 				if (verbosity != -1) {
8637b5038d7SDag-Erling Smørgrav 					ldns_pkt_print(stdout, pkt);
8647b5038d7SDag-Erling Smørgrav 					if (ldns_pkt_tc(pkt)) {
8657b5038d7SDag-Erling Smørgrav 						fprintf(stdout,
8667b5038d7SDag-Erling Smørgrav 							"\n;; WARNING: The answer packet was truncated; you might want to\n");
8677b5038d7SDag-Erling Smørgrav 						fprintf(stdout,
8687b5038d7SDag-Erling Smørgrav 							";; query again with TCP (-t argument), or EDNS0 (-b for buffer size)\n");
8697b5038d7SDag-Erling Smørgrav 					}
8707b5038d7SDag-Erling Smørgrav 				}
8717b5038d7SDag-Erling Smørgrav 				if (qds) {
8727b5038d7SDag-Erling Smørgrav 					if (verbosity != -1) {
8737b5038d7SDag-Erling Smørgrav 						print_ds_of_keys(pkt);
8747b5038d7SDag-Erling Smørgrav 						printf("\n");
8757b5038d7SDag-Erling Smørgrav 					}
8767b5038d7SDag-Erling Smørgrav 				}
8777b5038d7SDag-Erling Smørgrav 
8787b5038d7SDag-Erling Smørgrav 				if (ldns_rr_list_rr_count(key_list) > 0) {
8797b5038d7SDag-Erling Smørgrav 					/* -k's were given on the cmd line */
8807b5038d7SDag-Erling Smørgrav 					ldns_rr_list *rrset_verified;
8817b5038d7SDag-Erling Smørgrav 					uint16_t key_count;
8827b5038d7SDag-Erling Smørgrav 
8837b5038d7SDag-Erling Smørgrav 					rrset_verified = ldns_pkt_rr_list_by_name_and_type(
8847b5038d7SDag-Erling Smørgrav 							pkt, qname, type,
8857b5038d7SDag-Erling Smørgrav 							LDNS_SECTION_ANY_NOQUESTION);
8867b5038d7SDag-Erling Smørgrav 
8877b5038d7SDag-Erling Smørgrav 					if (type == LDNS_RR_TYPE_ANY) {
8887b5038d7SDag-Erling Smørgrav 						/* don't verify this */
8897b5038d7SDag-Erling Smørgrav 						break;
8907b5038d7SDag-Erling Smørgrav 					}
8917b5038d7SDag-Erling Smørgrav 
8927b5038d7SDag-Erling Smørgrav 					if (verbosity != -1) {
8937b5038d7SDag-Erling Smørgrav 						printf("; ");
8947b5038d7SDag-Erling Smørgrav 						ldns_rr_list_print(stdout, rrset_verified);
8957b5038d7SDag-Erling Smørgrav 					}
8967b5038d7SDag-Erling Smørgrav 
8977b5038d7SDag-Erling Smørgrav 					/* verify */
8987b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
8997b5038d7SDag-Erling Smørgrav 					key_verified = ldns_rr_list_new();
9007b5038d7SDag-Erling Smørgrav 					result = ldns_pkt_verify(pkt, type, qname, key_list, NULL, key_verified);
9017b5038d7SDag-Erling Smørgrav 
9027b5038d7SDag-Erling Smørgrav 					if (result == LDNS_STATUS_ERR) {
9037b5038d7SDag-Erling Smørgrav 						/* is the existence denied then? */
9047b5038d7SDag-Erling Smørgrav 						result = ldns_verify_denial(pkt, qname, type, NULL, NULL);
9057b5038d7SDag-Erling Smørgrav 						if (result == LDNS_STATUS_OK) {
9067b5038d7SDag-Erling Smørgrav 							if (verbosity != -1) {
9077b5038d7SDag-Erling Smørgrav 								printf("Existence denied for ");
9087b5038d7SDag-Erling Smørgrav 								ldns_rdf_print(stdout, qname);
9097b5038d7SDag-Erling Smørgrav 								type_str = ldns_rr_type2str(type);
9107b5038d7SDag-Erling Smørgrav 								printf("\t%s\n", type_str);
9117b5038d7SDag-Erling Smørgrav 								LDNS_FREE(type_str);
9127b5038d7SDag-Erling Smørgrav 							}
9137b5038d7SDag-Erling Smørgrav 						} else {
9147b5038d7SDag-Erling Smørgrav 							if (verbosity != -1) {
9157b5038d7SDag-Erling Smørgrav 								printf("Bad data; RR for name and "
9167b5038d7SDag-Erling Smørgrav 								       "type not found or failed to "
9177b5038d7SDag-Erling Smørgrav 								       "verify, and denial of "
9187b5038d7SDag-Erling Smørgrav 								       "existence failed.\n");
9197b5038d7SDag-Erling Smørgrav 							}
9207b5038d7SDag-Erling Smørgrav 						}
9217b5038d7SDag-Erling Smørgrav 					} else if (result == LDNS_STATUS_OK) {
9227b5038d7SDag-Erling Smørgrav 						for(key_count = 0; key_count < ldns_rr_list_rr_count(key_verified);
9237b5038d7SDag-Erling Smørgrav 								key_count++) {
9247b5038d7SDag-Erling Smørgrav 							if (verbosity != -1) {
9257b5038d7SDag-Erling Smørgrav 								printf("; VALIDATED by id = %u, owner = ",
9267b5038d7SDag-Erling Smørgrav 										(unsigned int)ldns_calc_keytag(
9277b5038d7SDag-Erling Smørgrav 												      ldns_rr_list_rr(key_verified, key_count)));
9287b5038d7SDag-Erling Smørgrav 								ldns_rdf_print(stdout, ldns_rr_owner(
9297b5038d7SDag-Erling Smørgrav 											ldns_rr_list_rr(key_list, key_count)));
9307b5038d7SDag-Erling Smørgrav 								printf("\n");
9317b5038d7SDag-Erling Smørgrav 							}
9327b5038d7SDag-Erling Smørgrav 						}
9337b5038d7SDag-Erling Smørgrav 					} else {
9347b5038d7SDag-Erling Smørgrav 						for(key_count = 0; key_count < ldns_rr_list_rr_count(key_list);
9357b5038d7SDag-Erling Smørgrav 								key_count++) {
9367b5038d7SDag-Erling Smørgrav 							if (verbosity != -1) {
9377b5038d7SDag-Erling Smørgrav 								printf("; %s for id = %u, owner = ",
9387b5038d7SDag-Erling Smørgrav 								       ldns_get_errorstr_by_id(result),
9397b5038d7SDag-Erling Smørgrav 								       (unsigned int)ldns_calc_keytag(
9407b5038d7SDag-Erling Smørgrav 												      ldns_rr_list_rr(key_list, key_count)));
9417b5038d7SDag-Erling Smørgrav 								ldns_rdf_print(stdout, ldns_rr_owner(
9427b5038d7SDag-Erling Smørgrav 
9437b5038d7SDag-Erling Smørgrav 								ldns_rr_list_rr(key_list,
9447b5038d7SDag-Erling Smørgrav 								key_count)));
9457b5038d7SDag-Erling Smørgrav 								printf("\n");
9467b5038d7SDag-Erling Smørgrav 							}
9477b5038d7SDag-Erling Smørgrav 						}
9487b5038d7SDag-Erling Smørgrav 					}
9497b5038d7SDag-Erling Smørgrav 					ldns_rr_list_free(key_verified);
9507b5038d7SDag-Erling Smørgrav #else
9517b5038d7SDag-Erling Smørgrav 					(void) key_count;
9527b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
9537b5038d7SDag-Erling Smørgrav 				}
9547b5038d7SDag-Erling Smørgrav 				if (answer_file) {
9557b5038d7SDag-Erling Smørgrav 					dump_hex(pkt, answer_file);
9567b5038d7SDag-Erling Smørgrav 				}
9577b5038d7SDag-Erling Smørgrav 				ldns_pkt_free(pkt);
9587b5038d7SDag-Erling Smørgrav 			}
9597b5038d7SDag-Erling Smørgrav 
9607b5038d7SDag-Erling Smørgrav 			break;
9617b5038d7SDag-Erling Smørgrav 	}
9627b5038d7SDag-Erling Smørgrav 
9637b5038d7SDag-Erling Smørgrav 	exit:
9647b5038d7SDag-Erling Smørgrav 	ldns_rdf_deep_free(qname);
965*17d15b25SDag-Erling Smørgrav 	ldns_rdf_deep_free(src_rdf);
9667b5038d7SDag-Erling Smørgrav 	ldns_resolver_deep_free(res);
9677b5038d7SDag-Erling Smørgrav 	ldns_resolver_deep_free(cmdline_res);
9687b5038d7SDag-Erling Smørgrav 	ldns_rr_list_deep_free(key_list);
9697b5038d7SDag-Erling Smørgrav 	ldns_rr_list_deep_free(cmdline_rr_list);
9707b5038d7SDag-Erling Smørgrav 	ldns_rdf_deep_free(trace_start_name);
9717b5038d7SDag-Erling Smørgrav 	xfree(progname);
9727b5038d7SDag-Erling Smørgrav 	xfree(tsig_name);
9737b5038d7SDag-Erling Smørgrav 	xfree(tsig_data);
9747b5038d7SDag-Erling Smørgrav 	xfree(tsig_algorithm);
9757b5038d7SDag-Erling Smørgrav 
9767b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
9777b5038d7SDag-Erling Smørgrav 	ERR_remove_state(0);
9787b5038d7SDag-Erling Smørgrav 	CRYPTO_cleanup_all_ex_data();
9797b5038d7SDag-Erling Smørgrav 	ERR_free_strings();
9807b5038d7SDag-Erling Smørgrav 	EVP_cleanup();
9817b5038d7SDag-Erling Smørgrav #endif
9827b5038d7SDag-Erling Smørgrav #ifdef USE_WINSOCK
9837b5038d7SDag-Erling Smørgrav 	WSACleanup();
9847b5038d7SDag-Erling Smørgrav #endif
9857b5038d7SDag-Erling Smørgrav 
9867b5038d7SDag-Erling Smørgrav 	return result;
9877b5038d7SDag-Erling Smørgrav }
988