xref: /freebsd/contrib/ldns/drill/drill.c (revision 7b5038d71c5c74ab863c1ff3fec33de94bf35a57)
1*7b5038d7SDag-Erling Smørgrav /*
2*7b5038d7SDag-Erling Smørgrav  * drill.c
3*7b5038d7SDag-Erling Smørgrav  * the main file of drill
4*7b5038d7SDag-Erling Smørgrav  * (c) 2005-2008 NLnet Labs
5*7b5038d7SDag-Erling Smørgrav  *
6*7b5038d7SDag-Erling Smørgrav  * See the file LICENSE for the license
7*7b5038d7SDag-Erling Smørgrav  *
8*7b5038d7SDag-Erling Smørgrav  */
9*7b5038d7SDag-Erling Smørgrav 
10*7b5038d7SDag-Erling Smørgrav #include "drill.h"
11*7b5038d7SDag-Erling Smørgrav #include <ldns/ldns.h>
12*7b5038d7SDag-Erling Smørgrav 
13*7b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
14*7b5038d7SDag-Erling Smørgrav #include <openssl/err.h>
15*7b5038d7SDag-Erling Smørgrav #endif
16*7b5038d7SDag-Erling Smørgrav 
17*7b5038d7SDag-Erling Smørgrav #define IP6_ARPA_MAX_LEN 65
18*7b5038d7SDag-Erling Smørgrav 
19*7b5038d7SDag-Erling Smørgrav /* query debug, 2 hex dumps */
20*7b5038d7SDag-Erling Smørgrav int		verbosity;
21*7b5038d7SDag-Erling Smørgrav 
22*7b5038d7SDag-Erling Smørgrav static void
23*7b5038d7SDag-Erling Smørgrav usage(FILE *stream, const char *progname)
24*7b5038d7SDag-Erling Smørgrav {
25*7b5038d7SDag-Erling Smørgrav 	fprintf(stream, "  Usage: %s name [@server] [type] [class]\n", progname);
26*7b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t<name>  can be a domain name or an IP address (-x lookups)\n");
27*7b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t<type>  defaults to A\n");
28*7b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t<class> defaults to IN\n");
29*7b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\n\targuments may be placed in random order\n");
30*7b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\n  Options:\n");
31*7b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-D\t\tenable DNSSEC (DO bit)\n");
32*7b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
33*7b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-T\t\ttrace from the root down to <name>\n");
34*7b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-S\t\tchase signature(s) from <name> to a know key [*]\n");
35*7b5038d7SDag-Erling Smørgrav #endif /*HAVE_SSL*/
36*7b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-V <number>\tverbosity (0-5)\n");
37*7b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-Q\t\tquiet mode (overrules -V)\n");
38*7b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\n");
39*7b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-f file\t\tread packet from file and send it\n");
40*7b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-i file\t\tread packet from file and print it\n");
41*7b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-w file\t\twrite answer packet to file\n");
42*7b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-q file\t\twrite query packet to file\n");
43*7b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-h\t\tshow this help\n");
44*7b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-v\t\tshow version\n");
45*7b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\n  Query options:\n");
46*7b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-4\t\tstay on ip4\n");
47*7b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-6\t\tstay on ip6\n");
48*7b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-a\t\tfallback to EDNS0 and TCP if the answer is truncated\n");
49*7b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-b <bufsize>\tuse <bufsize> as the buffer size (defaults to 512 b)\n");
50*7b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-c <file>\t\tuse file for rescursive nameserver configuration (/etc/resolv.conf)\n");
51*7b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-k <file>\tspecify a file that contains a trusted DNSSEC key (DNSKEY|DS) [**]\n");
52*7b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t\t\tused to verify any signatures in the current answer\n");
53*7b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-o <mnemonic>\tset flags to: [QR|qr][AA|aa][TC|tc][RD|rd][CD|cd][RA|ra][AD|ad]\n");
54*7b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t\t\tlowercase: unset bit, uppercase: set bit\n");
55*7b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-p <port>\tuse <port> as remote port number\n");
56*7b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-s\t\tshow the DS RR for each key in a packet\n");
57*7b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-u\t\tsend the query with udp (the default)\n");
58*7b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-x\t\tdo a reverse lookup\n");
59*7b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\twhen doing a secure trace:\n");
60*7b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-r <file>\t\tuse file as root servers hint file\n");
61*7b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-t\t\tsend the query with tcp (connected)\n");
62*7b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-d <domain>\t\tuse domain as the start point for the trace\n");
63*7b5038d7SDag-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");
64*7b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\t-z\t\tdon't randomize the nameservers before use\n");
65*7b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\n  [*] = enables/implies DNSSEC\n");
66*7b5038d7SDag-Erling Smørgrav 	fprintf(stream, "  [**] = can be given more than once\n");
67*7b5038d7SDag-Erling Smørgrav 	fprintf(stream, "\n  ldns-team@nlnetlabs.nl | http://www.nlnetlabs.nl/ldns/\n");
68*7b5038d7SDag-Erling Smørgrav }
69*7b5038d7SDag-Erling Smørgrav 
70*7b5038d7SDag-Erling Smørgrav /**
71*7b5038d7SDag-Erling Smørgrav  * Prints the drill version to stderr
72*7b5038d7SDag-Erling Smørgrav  */
73*7b5038d7SDag-Erling Smørgrav static void
74*7b5038d7SDag-Erling Smørgrav version(FILE *stream, const char *progname)
75*7b5038d7SDag-Erling Smørgrav {
76*7b5038d7SDag-Erling Smørgrav         fprintf(stream, "%s version %s (ldns version %s)\n", progname, DRILL_VERSION, ldns_version());
77*7b5038d7SDag-Erling Smørgrav         fprintf(stream, "Written by NLnet Labs.\n");
78*7b5038d7SDag-Erling Smørgrav         fprintf(stream, "\nCopyright (c) 2004-2008 NLnet Labs.\n");
79*7b5038d7SDag-Erling Smørgrav         fprintf(stream, "Licensed under the revised BSD license.\n");
80*7b5038d7SDag-Erling Smørgrav         fprintf(stream, "There is NO warranty; not even for MERCHANTABILITY or FITNESS\n");
81*7b5038d7SDag-Erling Smørgrav         fprintf(stream, "FOR A PARTICULAR PURPOSE.\n");
82*7b5038d7SDag-Erling Smørgrav }
83*7b5038d7SDag-Erling Smørgrav 
84*7b5038d7SDag-Erling Smørgrav 
85*7b5038d7SDag-Erling Smørgrav /**
86*7b5038d7SDag-Erling Smørgrav  * Main function of drill
87*7b5038d7SDag-Erling Smørgrav  * parse the arguments and prepare a query
88*7b5038d7SDag-Erling Smørgrav  */
89*7b5038d7SDag-Erling Smørgrav int
90*7b5038d7SDag-Erling Smørgrav main(int argc, char *argv[])
91*7b5038d7SDag-Erling Smørgrav {
92*7b5038d7SDag-Erling Smørgrav         ldns_resolver	*res = NULL;
93*7b5038d7SDag-Erling Smørgrav         ldns_resolver   *cmdline_res = NULL; /* only used to resolv @name names */
94*7b5038d7SDag-Erling Smørgrav 	ldns_rr_list	*cmdline_rr_list = NULL;
95*7b5038d7SDag-Erling Smørgrav 	ldns_rdf	*cmdline_dname = NULL;
96*7b5038d7SDag-Erling Smørgrav         ldns_rdf 	*qname, *qname_tmp;
97*7b5038d7SDag-Erling Smørgrav         ldns_pkt	*pkt;
98*7b5038d7SDag-Erling Smørgrav         ldns_pkt	*qpkt;
99*7b5038d7SDag-Erling Smørgrav         char 		*serv;
100*7b5038d7SDag-Erling Smørgrav         const char 	*name;
101*7b5038d7SDag-Erling Smørgrav         char 		*name2;
102*7b5038d7SDag-Erling Smørgrav 	char		*progname;
103*7b5038d7SDag-Erling Smørgrav 	char 		*query_file = NULL;
104*7b5038d7SDag-Erling Smørgrav 	char		*answer_file = NULL;
105*7b5038d7SDag-Erling Smørgrav 	ldns_buffer	*query_buffer = NULL;
106*7b5038d7SDag-Erling Smørgrav 	ldns_rdf 	*serv_rdf;
107*7b5038d7SDag-Erling Smørgrav         ldns_rr_type 	type;
108*7b5038d7SDag-Erling Smørgrav         ldns_rr_class	clas;
109*7b5038d7SDag-Erling Smørgrav #if 0
110*7b5038d7SDag-Erling Smørgrav 	ldns_pkt_opcode opcode = LDNS_PACKET_QUERY;
111*7b5038d7SDag-Erling Smørgrav #endif
112*7b5038d7SDag-Erling Smørgrav 	int 		i, c;
113*7b5038d7SDag-Erling Smørgrav 	int 		int_type;
114*7b5038d7SDag-Erling Smørgrav 	int		int_clas;
115*7b5038d7SDag-Erling Smørgrav 	int		PURPOSE;
116*7b5038d7SDag-Erling Smørgrav 	char		*tsig_name = NULL;
117*7b5038d7SDag-Erling Smørgrav 	char		*tsig_data = NULL;
118*7b5038d7SDag-Erling Smørgrav 	char 		*tsig_algorithm = NULL;
119*7b5038d7SDag-Erling Smørgrav 	size_t		tsig_separator;
120*7b5038d7SDag-Erling Smørgrav 	size_t		tsig_separator2;
121*7b5038d7SDag-Erling Smørgrav 	ldns_rr		*axfr_rr;
122*7b5038d7SDag-Erling Smørgrav 	ldns_status	status;
123*7b5038d7SDag-Erling Smørgrav 	char *type_str;
124*7b5038d7SDag-Erling Smørgrav 
125*7b5038d7SDag-Erling Smørgrav 	/* list of keys used in dnssec operations */
126*7b5038d7SDag-Erling Smørgrav 	ldns_rr_list	*key_list = ldns_rr_list_new();
127*7b5038d7SDag-Erling Smørgrav 	/* what key verify the current answer */
128*7b5038d7SDag-Erling Smørgrav 	ldns_rr_list 	*key_verified;
129*7b5038d7SDag-Erling Smørgrav 
130*7b5038d7SDag-Erling Smørgrav 	/* resolver options */
131*7b5038d7SDag-Erling Smørgrav 	uint16_t	qflags;
132*7b5038d7SDag-Erling Smørgrav 	uint16_t 	qbuf;
133*7b5038d7SDag-Erling Smørgrav 	uint16_t	qport;
134*7b5038d7SDag-Erling Smørgrav 	uint8_t		qfamily;
135*7b5038d7SDag-Erling Smørgrav 	bool		qdnssec;
136*7b5038d7SDag-Erling Smørgrav 	bool		qfallback;
137*7b5038d7SDag-Erling Smørgrav 	bool		qds;
138*7b5038d7SDag-Erling Smørgrav 	bool		qusevc;
139*7b5038d7SDag-Erling Smørgrav 	bool 		qrandom;
140*7b5038d7SDag-Erling Smørgrav 
141*7b5038d7SDag-Erling Smørgrav 	char		*resolv_conf_file = NULL;
142*7b5038d7SDag-Erling Smørgrav 
143*7b5038d7SDag-Erling Smørgrav 	ldns_rdf *trace_start_name = NULL;
144*7b5038d7SDag-Erling Smørgrav 
145*7b5038d7SDag-Erling Smørgrav 	int		result = 0;
146*7b5038d7SDag-Erling Smørgrav 
147*7b5038d7SDag-Erling Smørgrav #ifdef USE_WINSOCK
148*7b5038d7SDag-Erling Smørgrav 	int r;
149*7b5038d7SDag-Erling Smørgrav 	WSADATA wsa_data;
150*7b5038d7SDag-Erling Smørgrav #endif
151*7b5038d7SDag-Erling Smørgrav 
152*7b5038d7SDag-Erling Smørgrav 	int_type = -1; serv = NULL; type = 0;
153*7b5038d7SDag-Erling Smørgrav 	int_clas = -1; name = NULL; clas = 0;
154*7b5038d7SDag-Erling Smørgrav 	qname = NULL;
155*7b5038d7SDag-Erling Smørgrav 	progname = strdup(argv[0]);
156*7b5038d7SDag-Erling Smørgrav 
157*7b5038d7SDag-Erling Smørgrav #ifdef USE_WINSOCK
158*7b5038d7SDag-Erling Smørgrav 	r = WSAStartup(MAKEWORD(2,2), &wsa_data);
159*7b5038d7SDag-Erling Smørgrav 	if(r != 0) {
160*7b5038d7SDag-Erling Smørgrav 		printf("Failed WSAStartup: %d\n", r);
161*7b5038d7SDag-Erling Smørgrav 		result = EXIT_FAILURE;
162*7b5038d7SDag-Erling Smørgrav 		goto exit;
163*7b5038d7SDag-Erling Smørgrav 	}
164*7b5038d7SDag-Erling Smørgrav #endif /* USE_WINSOCK */
165*7b5038d7SDag-Erling Smørgrav 
166*7b5038d7SDag-Erling Smørgrav 
167*7b5038d7SDag-Erling Smørgrav 	PURPOSE = DRILL_QUERY;
168*7b5038d7SDag-Erling Smørgrav 	qflags = LDNS_RD;
169*7b5038d7SDag-Erling Smørgrav 	qport = LDNS_PORT;
170*7b5038d7SDag-Erling Smørgrav 	verbosity = 2;
171*7b5038d7SDag-Erling Smørgrav 	qdnssec = false;
172*7b5038d7SDag-Erling Smørgrav 	qfamily = LDNS_RESOLV_INETANY;
173*7b5038d7SDag-Erling Smørgrav 	qfallback = false;
174*7b5038d7SDag-Erling Smørgrav 	qds = false;
175*7b5038d7SDag-Erling Smørgrav 	qbuf = 0;
176*7b5038d7SDag-Erling Smørgrav 	qusevc = false;
177*7b5038d7SDag-Erling Smørgrav 	qrandom = true;
178*7b5038d7SDag-Erling Smørgrav 	key_verified = NULL;
179*7b5038d7SDag-Erling Smørgrav 
180*7b5038d7SDag-Erling Smørgrav 	ldns_init_random(NULL, 0);
181*7b5038d7SDag-Erling Smørgrav 
182*7b5038d7SDag-Erling Smørgrav 	if (argc == 0) {
183*7b5038d7SDag-Erling Smørgrav 		usage(stdout, progname);
184*7b5038d7SDag-Erling Smørgrav 		result = EXIT_FAILURE;
185*7b5038d7SDag-Erling Smørgrav 		goto exit;
186*7b5038d7SDag-Erling Smørgrav 	}
187*7b5038d7SDag-Erling Smørgrav 
188*7b5038d7SDag-Erling Smørgrav 	/* string from orig drill: "i:w:I46Sk:TNp:b:DsvhVcuaq:f:xr" */
189*7b5038d7SDag-Erling Smørgrav 	/* global first, query opt next, option with parm's last
190*7b5038d7SDag-Erling Smørgrav 	 * and sorted */ /*  "46DITSVQf:i:w:q:achuvxzy:so:p:b:k:" */
191*7b5038d7SDag-Erling Smørgrav 
192*7b5038d7SDag-Erling Smørgrav 	while ((c = getopt(argc, argv, "46ab:c:d:Df:hi:Ik:o:p:q:Qr:sStTuvV:w:xy:z")) != -1) {
193*7b5038d7SDag-Erling Smørgrav 		switch(c) {
194*7b5038d7SDag-Erling Smørgrav 			/* global options */
195*7b5038d7SDag-Erling Smørgrav 			case '4':
196*7b5038d7SDag-Erling Smørgrav 				qfamily = LDNS_RESOLV_INET;
197*7b5038d7SDag-Erling Smørgrav 				break;
198*7b5038d7SDag-Erling Smørgrav 			case '6':
199*7b5038d7SDag-Erling Smørgrav 				qfamily = LDNS_RESOLV_INET6;
200*7b5038d7SDag-Erling Smørgrav 				break;
201*7b5038d7SDag-Erling Smørgrav 			case 'D':
202*7b5038d7SDag-Erling Smørgrav 				qdnssec = true;
203*7b5038d7SDag-Erling Smørgrav 				break;
204*7b5038d7SDag-Erling Smørgrav 			case 'I':
205*7b5038d7SDag-Erling Smørgrav 				/* reserved for backward compatibility */
206*7b5038d7SDag-Erling Smørgrav 				break;
207*7b5038d7SDag-Erling Smørgrav 			case 'T':
208*7b5038d7SDag-Erling Smørgrav 				if (PURPOSE == DRILL_CHASE) {
209*7b5038d7SDag-Erling Smørgrav 					fprintf(stderr, "-T and -S cannot be used at the same time.\n");
210*7b5038d7SDag-Erling Smørgrav 					exit(EXIT_FAILURE);
211*7b5038d7SDag-Erling Smørgrav 				}
212*7b5038d7SDag-Erling Smørgrav 				PURPOSE = DRILL_TRACE;
213*7b5038d7SDag-Erling Smørgrav 				break;
214*7b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
215*7b5038d7SDag-Erling Smørgrav 			case 'S':
216*7b5038d7SDag-Erling Smørgrav 				if (PURPOSE == DRILL_TRACE) {
217*7b5038d7SDag-Erling Smørgrav 					fprintf(stderr, "-T and -S cannot be used at the same time.\n");
218*7b5038d7SDag-Erling Smørgrav 					exit(EXIT_FAILURE);
219*7b5038d7SDag-Erling Smørgrav 				}
220*7b5038d7SDag-Erling Smørgrav 				PURPOSE = DRILL_CHASE;
221*7b5038d7SDag-Erling Smørgrav 				break;
222*7b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
223*7b5038d7SDag-Erling Smørgrav 			case 'V':
224*7b5038d7SDag-Erling Smørgrav 				if (strtok(optarg, "0123456789") != NULL) {
225*7b5038d7SDag-Erling Smørgrav 					fprintf(stderr, "-V expects an number as an argument.\n");
226*7b5038d7SDag-Erling Smørgrav 					exit(EXIT_FAILURE);
227*7b5038d7SDag-Erling Smørgrav 				}
228*7b5038d7SDag-Erling Smørgrav 				verbosity = atoi(optarg);
229*7b5038d7SDag-Erling Smørgrav 				break;
230*7b5038d7SDag-Erling Smørgrav 			case 'Q':
231*7b5038d7SDag-Erling Smørgrav 				verbosity = -1;
232*7b5038d7SDag-Erling Smørgrav 				break;
233*7b5038d7SDag-Erling Smørgrav 			case 'f':
234*7b5038d7SDag-Erling Smørgrav 				query_file = optarg;
235*7b5038d7SDag-Erling Smørgrav 				break;
236*7b5038d7SDag-Erling Smørgrav 			case 'i':
237*7b5038d7SDag-Erling Smørgrav 				answer_file = optarg;
238*7b5038d7SDag-Erling Smørgrav 				PURPOSE = DRILL_AFROMFILE;
239*7b5038d7SDag-Erling Smørgrav 				break;
240*7b5038d7SDag-Erling Smørgrav 			case 'w':
241*7b5038d7SDag-Erling Smørgrav 				answer_file = optarg;
242*7b5038d7SDag-Erling Smørgrav 				break;
243*7b5038d7SDag-Erling Smørgrav 			case 'q':
244*7b5038d7SDag-Erling Smørgrav 				query_file = optarg;
245*7b5038d7SDag-Erling Smørgrav 				PURPOSE = DRILL_QTOFILE;
246*7b5038d7SDag-Erling Smørgrav 				break;
247*7b5038d7SDag-Erling Smørgrav 			case 'r':
248*7b5038d7SDag-Erling Smørgrav 				if (global_dns_root) {
249*7b5038d7SDag-Erling Smørgrav 					fprintf(stderr, "There was already a series of root servers set\n");
250*7b5038d7SDag-Erling Smørgrav 					exit(EXIT_FAILURE);
251*7b5038d7SDag-Erling Smørgrav 				}
252*7b5038d7SDag-Erling Smørgrav 				global_dns_root = read_root_hints(optarg);
253*7b5038d7SDag-Erling Smørgrav 				if (!global_dns_root) {
254*7b5038d7SDag-Erling Smørgrav 					fprintf(stderr, "Unable to read root hints file %s, aborting\n", optarg);
255*7b5038d7SDag-Erling Smørgrav 					exit(EXIT_FAILURE);
256*7b5038d7SDag-Erling Smørgrav 				}
257*7b5038d7SDag-Erling Smørgrav 				break;
258*7b5038d7SDag-Erling Smørgrav 			/* query options */
259*7b5038d7SDag-Erling Smørgrav 			case 'a':
260*7b5038d7SDag-Erling Smørgrav 				qfallback = true;
261*7b5038d7SDag-Erling Smørgrav 				break;
262*7b5038d7SDag-Erling Smørgrav 			case 'b':
263*7b5038d7SDag-Erling Smørgrav 				qbuf = (uint16_t)atoi(optarg);
264*7b5038d7SDag-Erling Smørgrav 				if (qbuf == 0) {
265*7b5038d7SDag-Erling Smørgrav 					error("%s", "<bufsize> could not be converted");
266*7b5038d7SDag-Erling Smørgrav 				}
267*7b5038d7SDag-Erling Smørgrav 				break;
268*7b5038d7SDag-Erling Smørgrav 			case 'c':
269*7b5038d7SDag-Erling Smørgrav 				resolv_conf_file = optarg;
270*7b5038d7SDag-Erling Smørgrav 				break;
271*7b5038d7SDag-Erling Smørgrav 			case 't':
272*7b5038d7SDag-Erling Smørgrav 				qusevc = true;
273*7b5038d7SDag-Erling Smørgrav 				break;
274*7b5038d7SDag-Erling Smørgrav 			case 'k':
275*7b5038d7SDag-Erling Smørgrav 				status = read_key_file(optarg, key_list);
276*7b5038d7SDag-Erling Smørgrav 				if (status != LDNS_STATUS_OK) {
277*7b5038d7SDag-Erling Smørgrav 					error("Could not parse the key file %s: %s", optarg, ldns_get_errorstr_by_id(status));
278*7b5038d7SDag-Erling Smørgrav 				}
279*7b5038d7SDag-Erling Smørgrav 				qdnssec = true; /* enable that too */
280*7b5038d7SDag-Erling Smørgrav 				break;
281*7b5038d7SDag-Erling Smørgrav 			case 'o':
282*7b5038d7SDag-Erling Smørgrav 				/* only looks at the first hit: capital=ON, lowercase=OFF*/
283*7b5038d7SDag-Erling Smørgrav 				if (strstr(optarg, "QR")) {
284*7b5038d7SDag-Erling Smørgrav 					DRILL_ON(qflags, LDNS_QR);
285*7b5038d7SDag-Erling Smørgrav 				}
286*7b5038d7SDag-Erling Smørgrav 				if (strstr(optarg, "qr")) {
287*7b5038d7SDag-Erling Smørgrav 					DRILL_OFF(qflags, LDNS_QR);
288*7b5038d7SDag-Erling Smørgrav 				}
289*7b5038d7SDag-Erling Smørgrav 				if (strstr(optarg, "AA")) {
290*7b5038d7SDag-Erling Smørgrav 					DRILL_ON(qflags, LDNS_AA);
291*7b5038d7SDag-Erling Smørgrav 				}
292*7b5038d7SDag-Erling Smørgrav 				if (strstr(optarg, "aa")) {
293*7b5038d7SDag-Erling Smørgrav 					DRILL_OFF(qflags, LDNS_AA);
294*7b5038d7SDag-Erling Smørgrav 				}
295*7b5038d7SDag-Erling Smørgrav 				if (strstr(optarg, "TC")) {
296*7b5038d7SDag-Erling Smørgrav 					DRILL_ON(qflags, LDNS_TC);
297*7b5038d7SDag-Erling Smørgrav 				}
298*7b5038d7SDag-Erling Smørgrav 				if (strstr(optarg, "tc")) {
299*7b5038d7SDag-Erling Smørgrav 					DRILL_OFF(qflags, LDNS_TC);
300*7b5038d7SDag-Erling Smørgrav 				}
301*7b5038d7SDag-Erling Smørgrav 				if (strstr(optarg, "RD")) {
302*7b5038d7SDag-Erling Smørgrav 					DRILL_ON(qflags, LDNS_RD);
303*7b5038d7SDag-Erling Smørgrav 				}
304*7b5038d7SDag-Erling Smørgrav 				if (strstr(optarg, "rd")) {
305*7b5038d7SDag-Erling Smørgrav 					DRILL_OFF(qflags, LDNS_RD);
306*7b5038d7SDag-Erling Smørgrav 				}
307*7b5038d7SDag-Erling Smørgrav 				if (strstr(optarg, "CD")) {
308*7b5038d7SDag-Erling Smørgrav 					DRILL_ON(qflags, LDNS_CD);
309*7b5038d7SDag-Erling Smørgrav 				}
310*7b5038d7SDag-Erling Smørgrav 				if (strstr(optarg, "cd")) {
311*7b5038d7SDag-Erling Smørgrav 					DRILL_OFF(qflags, LDNS_CD);
312*7b5038d7SDag-Erling Smørgrav 				}
313*7b5038d7SDag-Erling Smørgrav 				if (strstr(optarg, "RA")) {
314*7b5038d7SDag-Erling Smørgrav 					DRILL_ON(qflags, LDNS_RA);
315*7b5038d7SDag-Erling Smørgrav 				}
316*7b5038d7SDag-Erling Smørgrav 				if (strstr(optarg, "ra")) {
317*7b5038d7SDag-Erling Smørgrav 					DRILL_OFF(qflags, LDNS_RA);
318*7b5038d7SDag-Erling Smørgrav 				}
319*7b5038d7SDag-Erling Smørgrav 				if (strstr(optarg, "AD")) {
320*7b5038d7SDag-Erling Smørgrav 					DRILL_ON(qflags, LDNS_AD);
321*7b5038d7SDag-Erling Smørgrav 				}
322*7b5038d7SDag-Erling Smørgrav 				if (strstr(optarg, "ad")) {
323*7b5038d7SDag-Erling Smørgrav 					DRILL_OFF(qflags, LDNS_AD);
324*7b5038d7SDag-Erling Smørgrav 				}
325*7b5038d7SDag-Erling Smørgrav 				break;
326*7b5038d7SDag-Erling Smørgrav 			case 'p':
327*7b5038d7SDag-Erling Smørgrav 				qport = (uint16_t)atoi(optarg);
328*7b5038d7SDag-Erling Smørgrav 				if (qport == 0) {
329*7b5038d7SDag-Erling Smørgrav 					error("%s", "<port> could not be converted");
330*7b5038d7SDag-Erling Smørgrav 				}
331*7b5038d7SDag-Erling Smørgrav 				break;
332*7b5038d7SDag-Erling Smørgrav 			case 's':
333*7b5038d7SDag-Erling Smørgrav 				qds = true;
334*7b5038d7SDag-Erling Smørgrav 				break;
335*7b5038d7SDag-Erling Smørgrav 			case 'u':
336*7b5038d7SDag-Erling Smørgrav 				qusevc = false;
337*7b5038d7SDag-Erling Smørgrav 				break;
338*7b5038d7SDag-Erling Smørgrav 			case 'v':
339*7b5038d7SDag-Erling Smørgrav 				version(stdout, progname);
340*7b5038d7SDag-Erling Smørgrav 				result = EXIT_SUCCESS;
341*7b5038d7SDag-Erling Smørgrav 				goto exit;
342*7b5038d7SDag-Erling Smørgrav 			case 'x':
343*7b5038d7SDag-Erling Smørgrav 				PURPOSE = DRILL_REVERSE;
344*7b5038d7SDag-Erling Smørgrav 				break;
345*7b5038d7SDag-Erling Smørgrav 			case 'y':
346*7b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
347*7b5038d7SDag-Erling Smørgrav 				if (strchr(optarg, ':')) {
348*7b5038d7SDag-Erling Smørgrav 					tsig_separator = (size_t) (strchr(optarg, ':') - optarg);
349*7b5038d7SDag-Erling Smørgrav 					if (strchr(optarg + tsig_separator + 1, ':')) {
350*7b5038d7SDag-Erling Smørgrav 						tsig_separator2 = (size_t) (strchr(optarg + tsig_separator + 1, ':') - optarg);
351*7b5038d7SDag-Erling Smørgrav 						tsig_algorithm = xmalloc(strlen(optarg) - tsig_separator2);
352*7b5038d7SDag-Erling Smørgrav 						strncpy(tsig_algorithm, optarg + tsig_separator2 + 1, strlen(optarg) - tsig_separator2);
353*7b5038d7SDag-Erling Smørgrav 						tsig_algorithm[strlen(optarg) - tsig_separator2 - 1] = '\0';
354*7b5038d7SDag-Erling Smørgrav 					} else {
355*7b5038d7SDag-Erling Smørgrav 						tsig_separator2 = strlen(optarg);
356*7b5038d7SDag-Erling Smørgrav 						tsig_algorithm = xmalloc(26);
357*7b5038d7SDag-Erling Smørgrav 						strncpy(tsig_algorithm, "hmac-md5.sig-alg.reg.int.", 25);
358*7b5038d7SDag-Erling Smørgrav 						tsig_algorithm[25] = '\0';
359*7b5038d7SDag-Erling Smørgrav 					}
360*7b5038d7SDag-Erling Smørgrav 					tsig_name = xmalloc(tsig_separator + 1);
361*7b5038d7SDag-Erling Smørgrav 					tsig_data = xmalloc(tsig_separator2 - tsig_separator);
362*7b5038d7SDag-Erling Smørgrav 					strncpy(tsig_name, optarg, tsig_separator);
363*7b5038d7SDag-Erling Smørgrav 					strncpy(tsig_data, optarg + tsig_separator + 1, tsig_separator2 - tsig_separator - 1);
364*7b5038d7SDag-Erling Smørgrav 					/* strncpy does not append \0 if source is longer than n */
365*7b5038d7SDag-Erling Smørgrav 					tsig_name[tsig_separator] = '\0';
366*7b5038d7SDag-Erling Smørgrav 					tsig_data[ tsig_separator2 - tsig_separator - 1] = '\0';
367*7b5038d7SDag-Erling Smørgrav 				}
368*7b5038d7SDag-Erling Smørgrav #else
369*7b5038d7SDag-Erling Smørgrav 				fprintf(stderr, "TSIG requested, but SSL is not supported\n");
370*7b5038d7SDag-Erling Smørgrav 				result = EXIT_FAILURE;
371*7b5038d7SDag-Erling Smørgrav 				goto exit;
372*7b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
373*7b5038d7SDag-Erling Smørgrav 				break;
374*7b5038d7SDag-Erling Smørgrav 			case 'z':
375*7b5038d7SDag-Erling Smørgrav 				qrandom = false;
376*7b5038d7SDag-Erling Smørgrav 				break;
377*7b5038d7SDag-Erling Smørgrav 			case 'd':
378*7b5038d7SDag-Erling Smørgrav 				trace_start_name = ldns_dname_new_frm_str(optarg);
379*7b5038d7SDag-Erling Smørgrav 				if (!trace_start_name) {
380*7b5038d7SDag-Erling Smørgrav 					fprintf(stderr, "Unable to parse argument for -%c\n", c);
381*7b5038d7SDag-Erling Smørgrav 					result = EXIT_FAILURE;
382*7b5038d7SDag-Erling Smørgrav 					goto exit;
383*7b5038d7SDag-Erling Smørgrav 				}
384*7b5038d7SDag-Erling Smørgrav 				break;
385*7b5038d7SDag-Erling Smørgrav 			case 'h':
386*7b5038d7SDag-Erling Smørgrav 				version(stdout, progname);
387*7b5038d7SDag-Erling Smørgrav 				usage(stdout, progname);
388*7b5038d7SDag-Erling Smørgrav 				result = EXIT_SUCCESS;
389*7b5038d7SDag-Erling Smørgrav 				goto exit;
390*7b5038d7SDag-Erling Smørgrav 				break;
391*7b5038d7SDag-Erling Smørgrav 			default:
392*7b5038d7SDag-Erling Smørgrav 				fprintf(stderr, "Unknown argument: -%c, use -h to see usage\n", c);
393*7b5038d7SDag-Erling Smørgrav 				result = EXIT_FAILURE;
394*7b5038d7SDag-Erling Smørgrav 				goto exit;
395*7b5038d7SDag-Erling Smørgrav 		}
396*7b5038d7SDag-Erling Smørgrav 	}
397*7b5038d7SDag-Erling Smørgrav 	argc -= optind;
398*7b5038d7SDag-Erling Smørgrav 	argv += optind;
399*7b5038d7SDag-Erling Smørgrav 
400*7b5038d7SDag-Erling Smørgrav 	/* do a secure trace when requested */
401*7b5038d7SDag-Erling Smørgrav 	if (PURPOSE == DRILL_TRACE && qdnssec) {
402*7b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
403*7b5038d7SDag-Erling Smørgrav 		if (ldns_rr_list_rr_count(key_list) == 0) {
404*7b5038d7SDag-Erling Smørgrav 			warning("%s", "No trusted keys were given. Will not be able to verify authenticity!");
405*7b5038d7SDag-Erling Smørgrav 		}
406*7b5038d7SDag-Erling Smørgrav 		PURPOSE = DRILL_SECTRACE;
407*7b5038d7SDag-Erling Smørgrav #else
408*7b5038d7SDag-Erling Smørgrav 		fprintf(stderr, "ldns has not been compiled with OpenSSL support. Secure trace not available\n");
409*7b5038d7SDag-Erling Smørgrav 		exit(1);
410*7b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
411*7b5038d7SDag-Erling Smørgrav 	}
412*7b5038d7SDag-Erling Smørgrav 
413*7b5038d7SDag-Erling Smørgrav 	/* parse the arguments, with multiple arguments, the last argument
414*7b5038d7SDag-Erling Smørgrav 	 * found is used */
415*7b5038d7SDag-Erling Smørgrav 	for(i = 0; i < argc; i++) {
416*7b5038d7SDag-Erling Smørgrav 
417*7b5038d7SDag-Erling Smørgrav 		/* if ^@ then it's a server */
418*7b5038d7SDag-Erling Smørgrav 		if (argv[i][0] == '@') {
419*7b5038d7SDag-Erling Smørgrav 			if (strlen(argv[i]) == 1) {
420*7b5038d7SDag-Erling Smørgrav 				warning("%s", "No nameserver given");
421*7b5038d7SDag-Erling Smørgrav 				exit(EXIT_FAILURE);
422*7b5038d7SDag-Erling Smørgrav 			}
423*7b5038d7SDag-Erling Smørgrav 			serv = argv[i] + 1;
424*7b5038d7SDag-Erling Smørgrav 			continue;
425*7b5038d7SDag-Erling Smørgrav 		}
426*7b5038d7SDag-Erling Smørgrav 		/* if has a dot, it's a name */
427*7b5038d7SDag-Erling Smørgrav 		if (strchr(argv[i], '.')) {
428*7b5038d7SDag-Erling Smørgrav 			name = argv[i];
429*7b5038d7SDag-Erling Smørgrav 			continue;
430*7b5038d7SDag-Erling Smørgrav 		}
431*7b5038d7SDag-Erling Smørgrav 		/* if it matches a type, it's a type */
432*7b5038d7SDag-Erling Smørgrav 		if (int_type == -1) {
433*7b5038d7SDag-Erling Smørgrav 			type = ldns_get_rr_type_by_name(argv[i]);
434*7b5038d7SDag-Erling Smørgrav 			if (type != 0) {
435*7b5038d7SDag-Erling Smørgrav 				int_type = 0;
436*7b5038d7SDag-Erling Smørgrav 				continue;
437*7b5038d7SDag-Erling Smørgrav 			}
438*7b5038d7SDag-Erling Smørgrav 		}
439*7b5038d7SDag-Erling Smørgrav 		/* if it matches a class, it's a class */
440*7b5038d7SDag-Erling Smørgrav 		if (int_clas == -1) {
441*7b5038d7SDag-Erling Smørgrav 			clas = ldns_get_rr_class_by_name(argv[i]);
442*7b5038d7SDag-Erling Smørgrav 			if (clas != 0) {
443*7b5038d7SDag-Erling Smørgrav 				int_clas = 0;
444*7b5038d7SDag-Erling Smørgrav 				continue;
445*7b5038d7SDag-Erling Smørgrav 			}
446*7b5038d7SDag-Erling Smørgrav 		}
447*7b5038d7SDag-Erling Smørgrav 		/* it all fails assume it's a name */
448*7b5038d7SDag-Erling Smørgrav 		name = argv[i];
449*7b5038d7SDag-Erling Smørgrav 	}
450*7b5038d7SDag-Erling Smørgrav 	/* act like dig and use for . NS */
451*7b5038d7SDag-Erling Smørgrav 	if (!name) {
452*7b5038d7SDag-Erling Smørgrav 		name = ".";
453*7b5038d7SDag-Erling Smørgrav 		int_type = 0;
454*7b5038d7SDag-Erling Smørgrav 		type = LDNS_RR_TYPE_NS;
455*7b5038d7SDag-Erling Smørgrav 	}
456*7b5038d7SDag-Erling Smørgrav 
457*7b5038d7SDag-Erling Smørgrav 	/* defaults if not given */
458*7b5038d7SDag-Erling Smørgrav 	if (int_clas == -1) {
459*7b5038d7SDag-Erling Smørgrav 		clas = LDNS_RR_CLASS_IN;
460*7b5038d7SDag-Erling Smørgrav 	}
461*7b5038d7SDag-Erling Smørgrav 	if (int_type == -1) {
462*7b5038d7SDag-Erling Smørgrav 		if (PURPOSE != DRILL_REVERSE) {
463*7b5038d7SDag-Erling Smørgrav 			type = LDNS_RR_TYPE_A;
464*7b5038d7SDag-Erling Smørgrav 		} else {
465*7b5038d7SDag-Erling Smørgrav 			type = LDNS_RR_TYPE_PTR;
466*7b5038d7SDag-Erling Smørgrav 		}
467*7b5038d7SDag-Erling Smørgrav 	}
468*7b5038d7SDag-Erling Smørgrav 
469*7b5038d7SDag-Erling Smørgrav 	/* set the nameserver to use */
470*7b5038d7SDag-Erling Smørgrav 	if (!serv) {
471*7b5038d7SDag-Erling Smørgrav 		/* no server given make a resolver from /etc/resolv.conf */
472*7b5038d7SDag-Erling Smørgrav 		status = ldns_resolver_new_frm_file(&res, resolv_conf_file);
473*7b5038d7SDag-Erling Smørgrav 		if (status != LDNS_STATUS_OK) {
474*7b5038d7SDag-Erling Smørgrav 			warning("Could not create a resolver structure: %s (%s)\n"
475*7b5038d7SDag-Erling Smørgrav 					"Try drill @localhost if you have a resolver running on your machine.",
476*7b5038d7SDag-Erling Smørgrav 				    ldns_get_errorstr_by_id(status), resolv_conf_file);
477*7b5038d7SDag-Erling Smørgrav 			result = EXIT_FAILURE;
478*7b5038d7SDag-Erling Smørgrav 			goto exit;
479*7b5038d7SDag-Erling Smørgrav 		}
480*7b5038d7SDag-Erling Smørgrav 	} else {
481*7b5038d7SDag-Erling Smørgrav 		res = ldns_resolver_new();
482*7b5038d7SDag-Erling Smørgrav 		if (!res || strlen(serv) <= 0) {
483*7b5038d7SDag-Erling Smørgrav 			warning("Could not create a resolver structure");
484*7b5038d7SDag-Erling Smørgrav 			result = EXIT_FAILURE;
485*7b5038d7SDag-Erling Smørgrav 			goto exit;
486*7b5038d7SDag-Erling Smørgrav 		}
487*7b5038d7SDag-Erling Smørgrav 		/* add the nameserver */
488*7b5038d7SDag-Erling Smørgrav 		serv_rdf = ldns_rdf_new_addr_frm_str(serv);
489*7b5038d7SDag-Erling Smørgrav 		if (!serv_rdf) {
490*7b5038d7SDag-Erling Smørgrav 			/* try to resolv the name if possible */
491*7b5038d7SDag-Erling Smørgrav 			status = ldns_resolver_new_frm_file(&cmdline_res, resolv_conf_file);
492*7b5038d7SDag-Erling Smørgrav 
493*7b5038d7SDag-Erling Smørgrav 			if (status != LDNS_STATUS_OK) {
494*7b5038d7SDag-Erling Smørgrav 				error("%s", "@server ip could not be converted");
495*7b5038d7SDag-Erling Smørgrav 			}
496*7b5038d7SDag-Erling Smørgrav 			ldns_resolver_set_dnssec(cmdline_res, qdnssec);
497*7b5038d7SDag-Erling Smørgrav 			ldns_resolver_set_ip6(cmdline_res, qfamily);
498*7b5038d7SDag-Erling Smørgrav 			ldns_resolver_set_fallback(cmdline_res, qfallback);
499*7b5038d7SDag-Erling Smørgrav 			ldns_resolver_set_usevc(cmdline_res, qusevc);
500*7b5038d7SDag-Erling Smørgrav 
501*7b5038d7SDag-Erling Smørgrav 			cmdline_dname = ldns_dname_new_frm_str(serv);
502*7b5038d7SDag-Erling Smørgrav 
503*7b5038d7SDag-Erling Smørgrav 			cmdline_rr_list = ldns_get_rr_list_addr_by_name(
504*7b5038d7SDag-Erling Smørgrav 						cmdline_res,
505*7b5038d7SDag-Erling Smørgrav 						cmdline_dname,
506*7b5038d7SDag-Erling Smørgrav 						LDNS_RR_CLASS_IN,
507*7b5038d7SDag-Erling Smørgrav 						qflags);
508*7b5038d7SDag-Erling Smørgrav 			ldns_rdf_deep_free(cmdline_dname);
509*7b5038d7SDag-Erling Smørgrav 			if (!cmdline_rr_list) {
510*7b5038d7SDag-Erling Smørgrav 				/* This error msg is not always accurate */
511*7b5038d7SDag-Erling Smørgrav 				error("%s `%s\'", "could not find any address for the name:", serv);
512*7b5038d7SDag-Erling Smørgrav 			} else {
513*7b5038d7SDag-Erling Smørgrav 				if (ldns_resolver_push_nameserver_rr_list(
514*7b5038d7SDag-Erling Smørgrav 						res,
515*7b5038d7SDag-Erling Smørgrav 						cmdline_rr_list
516*7b5038d7SDag-Erling Smørgrav 					) != LDNS_STATUS_OK) {
517*7b5038d7SDag-Erling Smørgrav 					error("%s", "pushing nameserver");
518*7b5038d7SDag-Erling Smørgrav 				}
519*7b5038d7SDag-Erling Smørgrav 			}
520*7b5038d7SDag-Erling Smørgrav 		} else {
521*7b5038d7SDag-Erling Smørgrav 			if (ldns_resolver_push_nameserver(res, serv_rdf) != LDNS_STATUS_OK) {
522*7b5038d7SDag-Erling Smørgrav 				error("%s", "pushing nameserver");
523*7b5038d7SDag-Erling Smørgrav 			} else {
524*7b5038d7SDag-Erling Smørgrav 				ldns_rdf_deep_free(serv_rdf);
525*7b5038d7SDag-Erling Smørgrav 			}
526*7b5038d7SDag-Erling Smørgrav 		}
527*7b5038d7SDag-Erling Smørgrav 	}
528*7b5038d7SDag-Erling Smørgrav 	/* set the resolver options */
529*7b5038d7SDag-Erling Smørgrav 	ldns_resolver_set_port(res, qport);
530*7b5038d7SDag-Erling Smørgrav 	if (verbosity >= 5) {
531*7b5038d7SDag-Erling Smørgrav 		ldns_resolver_set_debug(res, true);
532*7b5038d7SDag-Erling Smørgrav 	} else {
533*7b5038d7SDag-Erling Smørgrav 		ldns_resolver_set_debug(res, false);
534*7b5038d7SDag-Erling Smørgrav 	}
535*7b5038d7SDag-Erling Smørgrav 	ldns_resolver_set_dnssec(res, qdnssec);
536*7b5038d7SDag-Erling Smørgrav /*	ldns_resolver_set_dnssec_cd(res, qdnssec);*/
537*7b5038d7SDag-Erling Smørgrav 	ldns_resolver_set_ip6(res, qfamily);
538*7b5038d7SDag-Erling Smørgrav 	ldns_resolver_set_fallback(res, qfallback);
539*7b5038d7SDag-Erling Smørgrav 	ldns_resolver_set_usevc(res, qusevc);
540*7b5038d7SDag-Erling Smørgrav 	ldns_resolver_set_random(res, qrandom);
541*7b5038d7SDag-Erling Smørgrav 	if (qbuf != 0) {
542*7b5038d7SDag-Erling Smørgrav 		ldns_resolver_set_edns_udp_size(res, qbuf);
543*7b5038d7SDag-Erling Smørgrav 	}
544*7b5038d7SDag-Erling Smørgrav 
545*7b5038d7SDag-Erling Smørgrav 	if (!name &&
546*7b5038d7SDag-Erling Smørgrav 	    PURPOSE != DRILL_AFROMFILE &&
547*7b5038d7SDag-Erling Smørgrav 	    !query_file
548*7b5038d7SDag-Erling Smørgrav 	   ) {
549*7b5038d7SDag-Erling Smørgrav 		usage(stdout, progname);
550*7b5038d7SDag-Erling Smørgrav 		result = EXIT_FAILURE;
551*7b5038d7SDag-Erling Smørgrav 		goto exit;
552*7b5038d7SDag-Erling Smørgrav 	}
553*7b5038d7SDag-Erling Smørgrav 
554*7b5038d7SDag-Erling Smørgrav 	if (tsig_name && tsig_data) {
555*7b5038d7SDag-Erling Smørgrav 		ldns_resolver_set_tsig_keyname(res, tsig_name);
556*7b5038d7SDag-Erling Smørgrav 		ldns_resolver_set_tsig_keydata(res, tsig_data);
557*7b5038d7SDag-Erling Smørgrav 		ldns_resolver_set_tsig_algorithm(res, tsig_algorithm);
558*7b5038d7SDag-Erling Smørgrav 	}
559*7b5038d7SDag-Erling Smørgrav 
560*7b5038d7SDag-Erling Smørgrav 	/* main switching part of drill */
561*7b5038d7SDag-Erling Smørgrav 	switch(PURPOSE) {
562*7b5038d7SDag-Erling Smørgrav 		case DRILL_TRACE:
563*7b5038d7SDag-Erling Smørgrav 			/* do a trace from the root down */
564*7b5038d7SDag-Erling Smørgrav 			if (!global_dns_root) {
565*7b5038d7SDag-Erling Smørgrav 				init_root();
566*7b5038d7SDag-Erling Smørgrav 			}
567*7b5038d7SDag-Erling Smørgrav 			qname = ldns_dname_new_frm_str(name);
568*7b5038d7SDag-Erling Smørgrav 			if (!qname) {
569*7b5038d7SDag-Erling Smørgrav 				error("%s", "parsing query name");
570*7b5038d7SDag-Erling Smørgrav 			}
571*7b5038d7SDag-Erling Smørgrav 			/* don't care about return packet */
572*7b5038d7SDag-Erling Smørgrav 			(void)do_trace(res, qname, type, clas);
573*7b5038d7SDag-Erling Smørgrav 			clear_root();
574*7b5038d7SDag-Erling Smørgrav 			break;
575*7b5038d7SDag-Erling Smørgrav 		case DRILL_SECTRACE:
576*7b5038d7SDag-Erling Smørgrav 			/* do a secure trace from the root down */
577*7b5038d7SDag-Erling Smørgrav 			if (!global_dns_root) {
578*7b5038d7SDag-Erling Smørgrav 				init_root();
579*7b5038d7SDag-Erling Smørgrav 			}
580*7b5038d7SDag-Erling Smørgrav 			qname = ldns_dname_new_frm_str(name);
581*7b5038d7SDag-Erling Smørgrav 			if (!qname) {
582*7b5038d7SDag-Erling Smørgrav 				error("%s", "making qname");
583*7b5038d7SDag-Erling Smørgrav 			}
584*7b5038d7SDag-Erling Smørgrav 			/* don't care about return packet */
585*7b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
586*7b5038d7SDag-Erling Smørgrav 			result = do_secure_trace(res, qname, type, clas, key_list, trace_start_name);
587*7b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
588*7b5038d7SDag-Erling Smørgrav 			clear_root();
589*7b5038d7SDag-Erling Smørgrav 			break;
590*7b5038d7SDag-Erling Smørgrav 		case DRILL_CHASE:
591*7b5038d7SDag-Erling Smørgrav 			qname = ldns_dname_new_frm_str(name);
592*7b5038d7SDag-Erling Smørgrav 			if (!qname) {
593*7b5038d7SDag-Erling Smørgrav 				error("%s", "making qname");
594*7b5038d7SDag-Erling Smørgrav 			}
595*7b5038d7SDag-Erling Smørgrav 
596*7b5038d7SDag-Erling Smørgrav 			ldns_resolver_set_dnssec(res, true);
597*7b5038d7SDag-Erling Smørgrav 			ldns_resolver_set_dnssec_cd(res, true);
598*7b5038d7SDag-Erling Smørgrav 			/* set dnssec implies udp_size of 4096 */
599*7b5038d7SDag-Erling Smørgrav 			ldns_resolver_set_edns_udp_size(res, 4096);
600*7b5038d7SDag-Erling Smørgrav 			pkt = ldns_resolver_query(res, qname, type, clas, qflags);
601*7b5038d7SDag-Erling Smørgrav 
602*7b5038d7SDag-Erling Smørgrav 			if (!pkt) {
603*7b5038d7SDag-Erling Smørgrav 				error("%s", "error pkt sending");
604*7b5038d7SDag-Erling Smørgrav 				result = EXIT_FAILURE;
605*7b5038d7SDag-Erling Smørgrav 			} else {
606*7b5038d7SDag-Erling Smørgrav 				if (verbosity >= 3) {
607*7b5038d7SDag-Erling Smørgrav 					ldns_pkt_print(stdout, pkt);
608*7b5038d7SDag-Erling Smørgrav 				}
609*7b5038d7SDag-Erling Smørgrav 
610*7b5038d7SDag-Erling Smørgrav 				if (!ldns_pkt_answer(pkt)) {
611*7b5038d7SDag-Erling Smørgrav 					mesg("No answer in packet");
612*7b5038d7SDag-Erling Smørgrav 				} else {
613*7b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
614*7b5038d7SDag-Erling Smørgrav 					ldns_resolver_set_dnssec_anchors(res, ldns_rr_list_clone(key_list));
615*7b5038d7SDag-Erling Smørgrav 					result = do_chase(res, qname, type,
616*7b5038d7SDag-Erling Smørgrav 					                  clas, key_list,
617*7b5038d7SDag-Erling Smørgrav 					                  pkt, qflags, NULL,
618*7b5038d7SDag-Erling Smørgrav 								   verbosity);
619*7b5038d7SDag-Erling Smørgrav 					if (result == LDNS_STATUS_OK) {
620*7b5038d7SDag-Erling Smørgrav 						if (verbosity != -1) {
621*7b5038d7SDag-Erling Smørgrav 							mesg("Chase successful");
622*7b5038d7SDag-Erling Smørgrav 						}
623*7b5038d7SDag-Erling Smørgrav 						result = 0;
624*7b5038d7SDag-Erling Smørgrav 					} else {
625*7b5038d7SDag-Erling Smørgrav 						if (verbosity != -1) {
626*7b5038d7SDag-Erling Smørgrav 							mesg("Chase failed.");
627*7b5038d7SDag-Erling Smørgrav 						}
628*7b5038d7SDag-Erling Smørgrav 					}
629*7b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
630*7b5038d7SDag-Erling Smørgrav 				}
631*7b5038d7SDag-Erling Smørgrav 				ldns_pkt_free(pkt);
632*7b5038d7SDag-Erling Smørgrav 			}
633*7b5038d7SDag-Erling Smørgrav 			break;
634*7b5038d7SDag-Erling Smørgrav 		case DRILL_AFROMFILE:
635*7b5038d7SDag-Erling Smørgrav 			pkt = read_hex_pkt(answer_file);
636*7b5038d7SDag-Erling Smørgrav 			if (pkt) {
637*7b5038d7SDag-Erling Smørgrav 				if (verbosity != -1) {
638*7b5038d7SDag-Erling Smørgrav 					ldns_pkt_print(stdout, pkt);
639*7b5038d7SDag-Erling Smørgrav 				}
640*7b5038d7SDag-Erling Smørgrav 				ldns_pkt_free(pkt);
641*7b5038d7SDag-Erling Smørgrav 			}
642*7b5038d7SDag-Erling Smørgrav 
643*7b5038d7SDag-Erling Smørgrav 			break;
644*7b5038d7SDag-Erling Smørgrav 		case DRILL_QTOFILE:
645*7b5038d7SDag-Erling Smørgrav 			qname = ldns_dname_new_frm_str(name);
646*7b5038d7SDag-Erling Smørgrav 			if (!qname) {
647*7b5038d7SDag-Erling Smørgrav 				error("%s", "making qname");
648*7b5038d7SDag-Erling Smørgrav 			}
649*7b5038d7SDag-Erling Smørgrav 
650*7b5038d7SDag-Erling Smørgrav 			status = ldns_resolver_prepare_query_pkt(&qpkt, res, qname, type, clas, qflags);
651*7b5038d7SDag-Erling Smørgrav 			if(status != LDNS_STATUS_OK) {
652*7b5038d7SDag-Erling Smørgrav 				error("%s", "making query: %s",
653*7b5038d7SDag-Erling Smørgrav 					ldns_get_errorstr_by_id(status));
654*7b5038d7SDag-Erling Smørgrav 			}
655*7b5038d7SDag-Erling Smørgrav 			dump_hex(qpkt, query_file);
656*7b5038d7SDag-Erling Smørgrav 			ldns_pkt_free(qpkt);
657*7b5038d7SDag-Erling Smørgrav 			break;
658*7b5038d7SDag-Erling Smørgrav 		case DRILL_NSEC:
659*7b5038d7SDag-Erling Smørgrav 			break;
660*7b5038d7SDag-Erling Smørgrav 		case DRILL_REVERSE:
661*7b5038d7SDag-Erling Smørgrav 			/* ipv4 or ipv6 addr? */
662*7b5038d7SDag-Erling Smørgrav 			if (strchr(name, ':')) {
663*7b5038d7SDag-Erling Smørgrav 				if (strchr(name, '.')) {
664*7b5038d7SDag-Erling Smørgrav 					error("Syntax error: both '.' and ':' seen in address\n");
665*7b5038d7SDag-Erling Smørgrav 				}
666*7b5038d7SDag-Erling Smørgrav 				name2 = malloc(IP6_ARPA_MAX_LEN + 20);
667*7b5038d7SDag-Erling Smørgrav 				c = 0;
668*7b5038d7SDag-Erling Smørgrav 				for (i=0; i<(int)strlen(name); i++) {
669*7b5038d7SDag-Erling Smørgrav 					if (i >= IP6_ARPA_MAX_LEN) {
670*7b5038d7SDag-Erling Smørgrav 						error("%s", "reverse argument to long");
671*7b5038d7SDag-Erling Smørgrav 					}
672*7b5038d7SDag-Erling Smørgrav 					if (name[i] == ':') {
673*7b5038d7SDag-Erling Smørgrav 						if (i < (int) strlen(name) && name[i + 1] == ':') {
674*7b5038d7SDag-Erling Smørgrav 							error("%s", ":: not supported (yet)");
675*7b5038d7SDag-Erling Smørgrav 						} else {
676*7b5038d7SDag-Erling Smørgrav 							if (i + 2 == (int) strlen(name) || name[i + 2] == ':') {
677*7b5038d7SDag-Erling Smørgrav 								name2[c++] = '0';
678*7b5038d7SDag-Erling Smørgrav 								name2[c++] = '.';
679*7b5038d7SDag-Erling Smørgrav 								name2[c++] = '0';
680*7b5038d7SDag-Erling Smørgrav 								name2[c++] = '.';
681*7b5038d7SDag-Erling Smørgrav 								name2[c++] = '0';
682*7b5038d7SDag-Erling Smørgrav 								name2[c++] = '.';
683*7b5038d7SDag-Erling Smørgrav 							} else if (i + 3 == (int) strlen(name) || name[i + 3] == ':') {
684*7b5038d7SDag-Erling Smørgrav 								name2[c++] = '0';
685*7b5038d7SDag-Erling Smørgrav 								name2[c++] = '.';
686*7b5038d7SDag-Erling Smørgrav 								name2[c++] = '0';
687*7b5038d7SDag-Erling Smørgrav 								name2[c++] = '.';
688*7b5038d7SDag-Erling Smørgrav 							} else if (i + 4 == (int) strlen(name) || name[i + 4] == ':') {
689*7b5038d7SDag-Erling Smørgrav 								name2[c++] = '0';
690*7b5038d7SDag-Erling Smørgrav 								name2[c++] = '.';
691*7b5038d7SDag-Erling Smørgrav 							}
692*7b5038d7SDag-Erling Smørgrav 						}
693*7b5038d7SDag-Erling Smørgrav 					} else {
694*7b5038d7SDag-Erling Smørgrav 						name2[c++] = name[i];
695*7b5038d7SDag-Erling Smørgrav 						name2[c++] = '.';
696*7b5038d7SDag-Erling Smørgrav 					}
697*7b5038d7SDag-Erling Smørgrav 				}
698*7b5038d7SDag-Erling Smørgrav 				name2[c++] = '\0';
699*7b5038d7SDag-Erling Smørgrav 
700*7b5038d7SDag-Erling Smørgrav 				qname = ldns_dname_new_frm_str(name2);
701*7b5038d7SDag-Erling Smørgrav 				qname_tmp = ldns_dname_reverse(qname);
702*7b5038d7SDag-Erling Smørgrav 				ldns_rdf_deep_free(qname);
703*7b5038d7SDag-Erling Smørgrav 				qname = qname_tmp;
704*7b5038d7SDag-Erling Smørgrav 				qname_tmp = ldns_dname_new_frm_str("ip6.arpa.");
705*7b5038d7SDag-Erling Smørgrav 				status = ldns_dname_cat(qname, qname_tmp);
706*7b5038d7SDag-Erling Smørgrav 				if (status != LDNS_STATUS_OK) {
707*7b5038d7SDag-Erling Smørgrav 					error("%s", "could not create reverse address for ip6: %s\n", ldns_get_errorstr_by_id(status));
708*7b5038d7SDag-Erling Smørgrav 				}
709*7b5038d7SDag-Erling Smørgrav 				ldns_rdf_deep_free(qname_tmp);
710*7b5038d7SDag-Erling Smørgrav 
711*7b5038d7SDag-Erling Smørgrav 				free(name2);
712*7b5038d7SDag-Erling Smørgrav 			} else {
713*7b5038d7SDag-Erling Smørgrav 				qname = ldns_dname_new_frm_str(name);
714*7b5038d7SDag-Erling Smørgrav 				qname_tmp = ldns_dname_reverse(qname);
715*7b5038d7SDag-Erling Smørgrav 				ldns_rdf_deep_free(qname);
716*7b5038d7SDag-Erling Smørgrav 				qname = qname_tmp;
717*7b5038d7SDag-Erling Smørgrav 				qname_tmp = ldns_dname_new_frm_str("in-addr.arpa.");
718*7b5038d7SDag-Erling Smørgrav 				status = ldns_dname_cat(qname, qname_tmp);
719*7b5038d7SDag-Erling Smørgrav 				if (status != LDNS_STATUS_OK) {
720*7b5038d7SDag-Erling Smørgrav 					error("%s", "could not create reverse address for ip4: %s\n", ldns_get_errorstr_by_id(status));
721*7b5038d7SDag-Erling Smørgrav 				}
722*7b5038d7SDag-Erling Smørgrav 				ldns_rdf_deep_free(qname_tmp);
723*7b5038d7SDag-Erling Smørgrav 			}
724*7b5038d7SDag-Erling Smørgrav 			if (!qname) {
725*7b5038d7SDag-Erling Smørgrav 				error("%s", "-x implies an ip address");
726*7b5038d7SDag-Erling Smørgrav 			}
727*7b5038d7SDag-Erling Smørgrav 
728*7b5038d7SDag-Erling Smørgrav 			/* create a packet and set the RD flag on it */
729*7b5038d7SDag-Erling Smørgrav 			pkt = ldns_resolver_query(res, qname, type, clas, qflags);
730*7b5038d7SDag-Erling Smørgrav 			if (!pkt)  {
731*7b5038d7SDag-Erling Smørgrav 				error("%s", "pkt sending");
732*7b5038d7SDag-Erling Smørgrav 				result = EXIT_FAILURE;
733*7b5038d7SDag-Erling Smørgrav 			} else {
734*7b5038d7SDag-Erling Smørgrav 				if (verbosity != -1) {
735*7b5038d7SDag-Erling Smørgrav 					ldns_pkt_print(stdout, pkt);
736*7b5038d7SDag-Erling Smørgrav 				}
737*7b5038d7SDag-Erling Smørgrav 				ldns_pkt_free(pkt);
738*7b5038d7SDag-Erling Smørgrav 			}
739*7b5038d7SDag-Erling Smørgrav 			break;
740*7b5038d7SDag-Erling Smørgrav 		case DRILL_QUERY:
741*7b5038d7SDag-Erling Smørgrav 		default:
742*7b5038d7SDag-Erling Smørgrav 			if (query_file) {
743*7b5038d7SDag-Erling Smørgrav 				/* this old way, the query packet needed
744*7b5038d7SDag-Erling Smørgrav 				   to be parseable, but we want to be able
745*7b5038d7SDag-Erling Smørgrav 				   to send mangled packets, so we need
746*7b5038d7SDag-Erling Smørgrav 				   to do it directly */
747*7b5038d7SDag-Erling Smørgrav 				#if 0
748*7b5038d7SDag-Erling Smørgrav 				qpkt = read_hex_pkt(query_file);
749*7b5038d7SDag-Erling Smørgrav 				if (qpkt) {
750*7b5038d7SDag-Erling Smørgrav 					status = ldns_resolver_send_pkt(&pkt, res, qpkt);
751*7b5038d7SDag-Erling Smørgrav 					if (status != LDNS_STATUS_OK) {
752*7b5038d7SDag-Erling Smørgrav 						printf("Error: %s\n", ldns_get_errorstr_by_id(status));
753*7b5038d7SDag-Erling Smørgrav 						exit(1);
754*7b5038d7SDag-Erling Smørgrav 					}
755*7b5038d7SDag-Erling Smørgrav 				} else {
756*7b5038d7SDag-Erling Smørgrav 					/* qpkt was bogus, reset pkt */
757*7b5038d7SDag-Erling Smørgrav 					pkt = NULL;
758*7b5038d7SDag-Erling Smørgrav 				}
759*7b5038d7SDag-Erling Smørgrav 				#endif
760*7b5038d7SDag-Erling Smørgrav 				query_buffer = read_hex_buffer(query_file);
761*7b5038d7SDag-Erling Smørgrav 				if (query_buffer) {
762*7b5038d7SDag-Erling Smørgrav 					status = ldns_send_buffer(&pkt, res, query_buffer, NULL);
763*7b5038d7SDag-Erling Smørgrav 					ldns_buffer_free(query_buffer);
764*7b5038d7SDag-Erling Smørgrav 					if (status != LDNS_STATUS_OK) {
765*7b5038d7SDag-Erling Smørgrav 						printf("Error: %s\n", ldns_get_errorstr_by_id(status));
766*7b5038d7SDag-Erling Smørgrav 						exit(1);
767*7b5038d7SDag-Erling Smørgrav 					}
768*7b5038d7SDag-Erling Smørgrav 				} else {
769*7b5038d7SDag-Erling Smørgrav 					printf("NO BUFFER\n");
770*7b5038d7SDag-Erling Smørgrav 					pkt = NULL;
771*7b5038d7SDag-Erling Smørgrav 				}
772*7b5038d7SDag-Erling Smørgrav 			} else {
773*7b5038d7SDag-Erling Smørgrav 				qname = ldns_dname_new_frm_str(name);
774*7b5038d7SDag-Erling Smørgrav 				if (!qname) {
775*7b5038d7SDag-Erling Smørgrav 					error("%s", "error in making qname");
776*7b5038d7SDag-Erling Smørgrav 				}
777*7b5038d7SDag-Erling Smørgrav 
778*7b5038d7SDag-Erling Smørgrav 				if (type == LDNS_RR_TYPE_AXFR) {
779*7b5038d7SDag-Erling Smørgrav 					status = ldns_axfr_start(res, qname, clas);
780*7b5038d7SDag-Erling Smørgrav 					if(status != LDNS_STATUS_OK) {
781*7b5038d7SDag-Erling Smørgrav 						error("Error starting axfr: %s",
782*7b5038d7SDag-Erling Smørgrav 							ldns_get_errorstr_by_id(status));
783*7b5038d7SDag-Erling Smørgrav 					}
784*7b5038d7SDag-Erling Smørgrav 					axfr_rr = ldns_axfr_next(res);
785*7b5038d7SDag-Erling Smørgrav 					if(!axfr_rr) {
786*7b5038d7SDag-Erling Smørgrav 						fprintf(stderr, "AXFR failed.\n");
787*7b5038d7SDag-Erling Smørgrav 						ldns_pkt_print(stdout,
788*7b5038d7SDag-Erling Smørgrav 							ldns_axfr_last_pkt(res));
789*7b5038d7SDag-Erling Smørgrav 						goto exit;
790*7b5038d7SDag-Erling Smørgrav 					}
791*7b5038d7SDag-Erling Smørgrav 					while (axfr_rr) {
792*7b5038d7SDag-Erling Smørgrav 						if (verbosity != -1) {
793*7b5038d7SDag-Erling Smørgrav 							ldns_rr_print(stdout, axfr_rr);
794*7b5038d7SDag-Erling Smørgrav 						}
795*7b5038d7SDag-Erling Smørgrav 						ldns_rr_free(axfr_rr);
796*7b5038d7SDag-Erling Smørgrav 						axfr_rr = ldns_axfr_next(res);
797*7b5038d7SDag-Erling Smørgrav 					}
798*7b5038d7SDag-Erling Smørgrav 
799*7b5038d7SDag-Erling Smørgrav 					goto exit;
800*7b5038d7SDag-Erling Smørgrav 				} else {
801*7b5038d7SDag-Erling Smørgrav 					/* create a packet and set the RD flag on it */
802*7b5038d7SDag-Erling Smørgrav 					pkt = ldns_resolver_query(res, qname, type, clas, qflags);
803*7b5038d7SDag-Erling Smørgrav 				}
804*7b5038d7SDag-Erling Smørgrav 			}
805*7b5038d7SDag-Erling Smørgrav 
806*7b5038d7SDag-Erling Smørgrav 			if (!pkt)  {
807*7b5038d7SDag-Erling Smørgrav 				mesg("No packet received");
808*7b5038d7SDag-Erling Smørgrav 				result = EXIT_FAILURE;
809*7b5038d7SDag-Erling Smørgrav 			} else {
810*7b5038d7SDag-Erling Smørgrav 				if (verbosity != -1) {
811*7b5038d7SDag-Erling Smørgrav 					ldns_pkt_print(stdout, pkt);
812*7b5038d7SDag-Erling Smørgrav 					if (ldns_pkt_tc(pkt)) {
813*7b5038d7SDag-Erling Smørgrav 						fprintf(stdout,
814*7b5038d7SDag-Erling Smørgrav 							"\n;; WARNING: The answer packet was truncated; you might want to\n");
815*7b5038d7SDag-Erling Smørgrav 						fprintf(stdout,
816*7b5038d7SDag-Erling Smørgrav 							";; query again with TCP (-t argument), or EDNS0 (-b for buffer size)\n");
817*7b5038d7SDag-Erling Smørgrav 					}
818*7b5038d7SDag-Erling Smørgrav 				}
819*7b5038d7SDag-Erling Smørgrav 				if (qds) {
820*7b5038d7SDag-Erling Smørgrav 					if (verbosity != -1) {
821*7b5038d7SDag-Erling Smørgrav 						print_ds_of_keys(pkt);
822*7b5038d7SDag-Erling Smørgrav 						printf("\n");
823*7b5038d7SDag-Erling Smørgrav 					}
824*7b5038d7SDag-Erling Smørgrav 				}
825*7b5038d7SDag-Erling Smørgrav 
826*7b5038d7SDag-Erling Smørgrav 				if (ldns_rr_list_rr_count(key_list) > 0) {
827*7b5038d7SDag-Erling Smørgrav 					/* -k's were given on the cmd line */
828*7b5038d7SDag-Erling Smørgrav 					ldns_rr_list *rrset_verified;
829*7b5038d7SDag-Erling Smørgrav 					uint16_t key_count;
830*7b5038d7SDag-Erling Smørgrav 
831*7b5038d7SDag-Erling Smørgrav 					rrset_verified = ldns_pkt_rr_list_by_name_and_type(
832*7b5038d7SDag-Erling Smørgrav 							pkt, qname, type,
833*7b5038d7SDag-Erling Smørgrav 							LDNS_SECTION_ANY_NOQUESTION);
834*7b5038d7SDag-Erling Smørgrav 
835*7b5038d7SDag-Erling Smørgrav 					if (type == LDNS_RR_TYPE_ANY) {
836*7b5038d7SDag-Erling Smørgrav 						/* don't verify this */
837*7b5038d7SDag-Erling Smørgrav 						break;
838*7b5038d7SDag-Erling Smørgrav 					}
839*7b5038d7SDag-Erling Smørgrav 
840*7b5038d7SDag-Erling Smørgrav 					if (verbosity != -1) {
841*7b5038d7SDag-Erling Smørgrav 						printf("; ");
842*7b5038d7SDag-Erling Smørgrav 						ldns_rr_list_print(stdout, rrset_verified);
843*7b5038d7SDag-Erling Smørgrav 					}
844*7b5038d7SDag-Erling Smørgrav 
845*7b5038d7SDag-Erling Smørgrav 					/* verify */
846*7b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
847*7b5038d7SDag-Erling Smørgrav 					key_verified = ldns_rr_list_new();
848*7b5038d7SDag-Erling Smørgrav 					result = ldns_pkt_verify(pkt, type, qname, key_list, NULL, key_verified);
849*7b5038d7SDag-Erling Smørgrav 
850*7b5038d7SDag-Erling Smørgrav 					if (result == LDNS_STATUS_ERR) {
851*7b5038d7SDag-Erling Smørgrav 						/* is the existence denied then? */
852*7b5038d7SDag-Erling Smørgrav 						result = ldns_verify_denial(pkt, qname, type, NULL, NULL);
853*7b5038d7SDag-Erling Smørgrav 						if (result == LDNS_STATUS_OK) {
854*7b5038d7SDag-Erling Smørgrav 							if (verbosity != -1) {
855*7b5038d7SDag-Erling Smørgrav 								printf("Existence denied for ");
856*7b5038d7SDag-Erling Smørgrav 								ldns_rdf_print(stdout, qname);
857*7b5038d7SDag-Erling Smørgrav 								type_str = ldns_rr_type2str(type);
858*7b5038d7SDag-Erling Smørgrav 								printf("\t%s\n", type_str);
859*7b5038d7SDag-Erling Smørgrav 								LDNS_FREE(type_str);
860*7b5038d7SDag-Erling Smørgrav 							}
861*7b5038d7SDag-Erling Smørgrav 						} else {
862*7b5038d7SDag-Erling Smørgrav 							if (verbosity != -1) {
863*7b5038d7SDag-Erling Smørgrav 								printf("Bad data; RR for name and "
864*7b5038d7SDag-Erling Smørgrav 								       "type not found or failed to "
865*7b5038d7SDag-Erling Smørgrav 								       "verify, and denial of "
866*7b5038d7SDag-Erling Smørgrav 								       "existence failed.\n");
867*7b5038d7SDag-Erling Smørgrav 							}
868*7b5038d7SDag-Erling Smørgrav 						}
869*7b5038d7SDag-Erling Smørgrav 					} else if (result == LDNS_STATUS_OK) {
870*7b5038d7SDag-Erling Smørgrav 						for(key_count = 0; key_count < ldns_rr_list_rr_count(key_verified);
871*7b5038d7SDag-Erling Smørgrav 								key_count++) {
872*7b5038d7SDag-Erling Smørgrav 							if (verbosity != -1) {
873*7b5038d7SDag-Erling Smørgrav 								printf("; VALIDATED by id = %u, owner = ",
874*7b5038d7SDag-Erling Smørgrav 										(unsigned int)ldns_calc_keytag(
875*7b5038d7SDag-Erling Smørgrav 												      ldns_rr_list_rr(key_verified, key_count)));
876*7b5038d7SDag-Erling Smørgrav 								ldns_rdf_print(stdout, ldns_rr_owner(
877*7b5038d7SDag-Erling Smørgrav 											ldns_rr_list_rr(key_list, key_count)));
878*7b5038d7SDag-Erling Smørgrav 								printf("\n");
879*7b5038d7SDag-Erling Smørgrav 							}
880*7b5038d7SDag-Erling Smørgrav 						}
881*7b5038d7SDag-Erling Smørgrav 					} else {
882*7b5038d7SDag-Erling Smørgrav 						for(key_count = 0; key_count < ldns_rr_list_rr_count(key_list);
883*7b5038d7SDag-Erling Smørgrav 								key_count++) {
884*7b5038d7SDag-Erling Smørgrav 							if (verbosity != -1) {
885*7b5038d7SDag-Erling Smørgrav 								printf("; %s for id = %u, owner = ",
886*7b5038d7SDag-Erling Smørgrav 								       ldns_get_errorstr_by_id(result),
887*7b5038d7SDag-Erling Smørgrav 								       (unsigned int)ldns_calc_keytag(
888*7b5038d7SDag-Erling Smørgrav 												      ldns_rr_list_rr(key_list, key_count)));
889*7b5038d7SDag-Erling Smørgrav 								ldns_rdf_print(stdout, ldns_rr_owner(
890*7b5038d7SDag-Erling Smørgrav 
891*7b5038d7SDag-Erling Smørgrav 								ldns_rr_list_rr(key_list,
892*7b5038d7SDag-Erling Smørgrav 								key_count)));
893*7b5038d7SDag-Erling Smørgrav 								printf("\n");
894*7b5038d7SDag-Erling Smørgrav 							}
895*7b5038d7SDag-Erling Smørgrav 						}
896*7b5038d7SDag-Erling Smørgrav 					}
897*7b5038d7SDag-Erling Smørgrav 					ldns_rr_list_free(key_verified);
898*7b5038d7SDag-Erling Smørgrav #else
899*7b5038d7SDag-Erling Smørgrav 					(void) key_count;
900*7b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
901*7b5038d7SDag-Erling Smørgrav 				}
902*7b5038d7SDag-Erling Smørgrav 				if (answer_file) {
903*7b5038d7SDag-Erling Smørgrav 					dump_hex(pkt, answer_file);
904*7b5038d7SDag-Erling Smørgrav 				}
905*7b5038d7SDag-Erling Smørgrav 				ldns_pkt_free(pkt);
906*7b5038d7SDag-Erling Smørgrav 			}
907*7b5038d7SDag-Erling Smørgrav 
908*7b5038d7SDag-Erling Smørgrav 			break;
909*7b5038d7SDag-Erling Smørgrav 	}
910*7b5038d7SDag-Erling Smørgrav 
911*7b5038d7SDag-Erling Smørgrav 	exit:
912*7b5038d7SDag-Erling Smørgrav 	ldns_rdf_deep_free(qname);
913*7b5038d7SDag-Erling Smørgrav 	ldns_resolver_deep_free(res);
914*7b5038d7SDag-Erling Smørgrav 	ldns_resolver_deep_free(cmdline_res);
915*7b5038d7SDag-Erling Smørgrav 	ldns_rr_list_deep_free(key_list);
916*7b5038d7SDag-Erling Smørgrav 	ldns_rr_list_deep_free(cmdline_rr_list);
917*7b5038d7SDag-Erling Smørgrav 	ldns_rdf_deep_free(trace_start_name);
918*7b5038d7SDag-Erling Smørgrav 	xfree(progname);
919*7b5038d7SDag-Erling Smørgrav 	xfree(tsig_name);
920*7b5038d7SDag-Erling Smørgrav 	xfree(tsig_data);
921*7b5038d7SDag-Erling Smørgrav 	xfree(tsig_algorithm);
922*7b5038d7SDag-Erling Smørgrav 
923*7b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
924*7b5038d7SDag-Erling Smørgrav 	ERR_remove_state(0);
925*7b5038d7SDag-Erling Smørgrav 	CRYPTO_cleanup_all_ex_data();
926*7b5038d7SDag-Erling Smørgrav 	ERR_free_strings();
927*7b5038d7SDag-Erling Smørgrav 	EVP_cleanup();
928*7b5038d7SDag-Erling Smørgrav #endif
929*7b5038d7SDag-Erling Smørgrav #ifdef USE_WINSOCK
930*7b5038d7SDag-Erling Smørgrav 	WSACleanup();
931*7b5038d7SDag-Erling Smørgrav #endif
932*7b5038d7SDag-Erling Smørgrav 
933*7b5038d7SDag-Erling Smørgrav 	return result;
934*7b5038d7SDag-Erling Smørgrav }
935