xref: /dflybsd-src/contrib/ldns/drill/drill.c (revision 7733acb50455a11cc2ee36edd926ff0fa3361e9a)
1825eb42bSJan Lentfer /*
2825eb42bSJan Lentfer  * drill.c
3825eb42bSJan Lentfer  * the main file of drill
4825eb42bSJan Lentfer  * (c) 2005-2008 NLnet Labs
5825eb42bSJan Lentfer  *
6825eb42bSJan Lentfer  * See the file LICENSE for the license
7825eb42bSJan Lentfer  *
8825eb42bSJan Lentfer  */
9825eb42bSJan Lentfer 
10825eb42bSJan Lentfer #include "drill.h"
11825eb42bSJan Lentfer #include <ldns/ldns.h>
12825eb42bSJan Lentfer 
13825eb42bSJan Lentfer #ifdef HAVE_SSL
14825eb42bSJan Lentfer #include <openssl/err.h>
15825eb42bSJan Lentfer #endif
16825eb42bSJan Lentfer 
17825eb42bSJan Lentfer /* query debug, 2 hex dumps */
18825eb42bSJan Lentfer int		verbosity;
19825eb42bSJan Lentfer 
205340022aSzrj static int
is_ixfr_with_serial(const char * name,uint32_t * serial)215340022aSzrj is_ixfr_with_serial(const char* name, uint32_t *serial)
225340022aSzrj {
235340022aSzrj 	char* end;
245340022aSzrj 	if (strlen(name) > 5 &&
255340022aSzrj 		strncasecmp(name, "IXFR", 4) == 0 &&
265340022aSzrj 		name[4] == '=') {
275340022aSzrj 		*serial = (uint32_t) strtol((name+5), &end, 10);
285340022aSzrj 		return 1;
295340022aSzrj 	}
305340022aSzrj 	return 0;
315340022aSzrj }
325340022aSzrj 
33825eb42bSJan Lentfer static void
usage(FILE * stream,const char * progname)34825eb42bSJan Lentfer usage(FILE *stream, const char *progname)
35825eb42bSJan Lentfer {
36825eb42bSJan Lentfer 	fprintf(stream, "  Usage: %s name [@server] [type] [class]\n", progname);
37825eb42bSJan Lentfer 	fprintf(stream, "\t<name>  can be a domain name or an IP address (-x lookups)\n");
38825eb42bSJan Lentfer 	fprintf(stream, "\t<type>  defaults to A\n");
39825eb42bSJan Lentfer 	fprintf(stream, "\t<class> defaults to IN\n");
40825eb42bSJan Lentfer 	fprintf(stream, "\n\targuments may be placed in random order\n");
41825eb42bSJan Lentfer 	fprintf(stream, "\n  Options:\n");
42825eb42bSJan Lentfer 	fprintf(stream, "\t-D\t\tenable DNSSEC (DO bit)\n");
43825eb42bSJan Lentfer #ifdef HAVE_SSL
44825eb42bSJan Lentfer 	fprintf(stream, "\t-T\t\ttrace from the root down to <name>\n");
455340022aSzrj 	fprintf(stream, "\t-S\t\tchase signature(s) from <name> to a known key [*]\n");
46825eb42bSJan Lentfer #endif /*HAVE_SSL*/
475340022aSzrj 	fprintf(stream, "\t-I <address>\tsource address to query from\n");
48825eb42bSJan Lentfer 	fprintf(stream, "\t-V <number>\tverbosity (0-5)\n");
49825eb42bSJan Lentfer 	fprintf(stream, "\t-Q\t\tquiet mode (overrules -V)\n");
50825eb42bSJan Lentfer 	fprintf(stream, "\n");
51825eb42bSJan Lentfer 	fprintf(stream, "\t-f file\t\tread packet from file and send it\n");
52825eb42bSJan Lentfer 	fprintf(stream, "\t-i file\t\tread packet from file and print it\n");
53825eb42bSJan Lentfer 	fprintf(stream, "\t-w file\t\twrite answer packet to file\n");
54825eb42bSJan Lentfer 	fprintf(stream, "\t-q file\t\twrite query packet to file\n");
55825eb42bSJan Lentfer 	fprintf(stream, "\t-h\t\tshow this help\n");
56825eb42bSJan Lentfer 	fprintf(stream, "\t-v\t\tshow version\n");
57825eb42bSJan Lentfer 	fprintf(stream, "\n  Query options:\n");
58825eb42bSJan Lentfer 	fprintf(stream, "\t-4\t\tstay on ip4\n");
59825eb42bSJan Lentfer 	fprintf(stream, "\t-6\t\tstay on ip6\n");
60825eb42bSJan Lentfer 	fprintf(stream, "\t-a\t\tfallback to EDNS0 and TCP if the answer is truncated\n");
61825eb42bSJan Lentfer 	fprintf(stream, "\t-b <bufsize>\tuse <bufsize> as the buffer size (defaults to 512 b)\n");
62*ee791febSAntonio Huete Jimenez 	fprintf(stream, "\t-c <file>\tuse file for recursive nameserver configuration"
63d1b2b5caSJohn Marino 			"\n\t\t\t(/etc/resolv.conf)\n");
64d1b2b5caSJohn Marino 	fprintf(stream, "\t-k <file>\tspecify a file that contains a trusted DNSSEC key [**]\n");
65d1b2b5caSJohn Marino 	fprintf(stream, "\t\t\tUsed to verify any signatures in the current answer.\n");
66d1b2b5caSJohn Marino 	fprintf(stream, "\t\t\tWhen DNSSEC enabled tracing (-TD) or signature\n"
67d1b2b5caSJohn Marino 			"\t\t\tchasing (-S) and no key files are given, keys are read\n"
68d1b2b5caSJohn Marino 			"\t\t\tfrom: %s\n",
69d1b2b5caSJohn Marino 			LDNS_TRUST_ANCHOR_FILE);
70d1b2b5caSJohn Marino 	fprintf(stream, "\t-o <mnemonic>\tset flags to:"
71d1b2b5caSJohn Marino 			"\n\t\t\t[QR|qr][AA|aa][TC|tc][RD|rd][CD|cd][RA|ra][AD|ad]\n");
72825eb42bSJan Lentfer 	fprintf(stream, "\t\t\tlowercase: unset bit, uppercase: set bit\n");
73825eb42bSJan Lentfer 	fprintf(stream, "\t-p <port>\tuse <port> as remote port number\n");
74825eb42bSJan Lentfer 	fprintf(stream, "\t-s\t\tshow the DS RR for each key in a packet\n");
75825eb42bSJan Lentfer 	fprintf(stream, "\t-u\t\tsend the query with udp (the default)\n");
76825eb42bSJan Lentfer 	fprintf(stream, "\t-x\t\tdo a reverse lookup\n");
77825eb42bSJan Lentfer 	fprintf(stream, "\twhen doing a secure trace:\n");
78d1b2b5caSJohn Marino 	fprintf(stream, "\t-r <file>\tuse file as root servers hint file\n");
79825eb42bSJan Lentfer 	fprintf(stream, "\t-t\t\tsend the query with tcp (connected)\n");
80d1b2b5caSJohn Marino 	fprintf(stream, "\t-d <domain>\tuse domain as the start point for the trace\n");
81825eb42bSJan Lentfer     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");
82825eb42bSJan Lentfer 	fprintf(stream, "\t-z\t\tdon't randomize the nameservers before use\n");
83825eb42bSJan Lentfer 	fprintf(stream, "\n  [*] = enables/implies DNSSEC\n");
84825eb42bSJan Lentfer 	fprintf(stream, "  [**] = can be given more than once\n");
85825eb42bSJan Lentfer 	fprintf(stream, "\n  ldns-team@nlnetlabs.nl | http://www.nlnetlabs.nl/ldns/\n");
86825eb42bSJan Lentfer }
87825eb42bSJan Lentfer 
88825eb42bSJan Lentfer /**
89825eb42bSJan Lentfer  * Prints the drill version to stderr
90825eb42bSJan Lentfer  */
91825eb42bSJan Lentfer static void
version(FILE * stream,const char * progname)92825eb42bSJan Lentfer version(FILE *stream, const char *progname)
93825eb42bSJan Lentfer {
94825eb42bSJan Lentfer         fprintf(stream, "%s version %s (ldns version %s)\n", progname, DRILL_VERSION, ldns_version());
95825eb42bSJan Lentfer         fprintf(stream, "Written by NLnet Labs.\n");
96825eb42bSJan Lentfer         fprintf(stream, "\nCopyright (c) 2004-2008 NLnet Labs.\n");
97825eb42bSJan Lentfer         fprintf(stream, "Licensed under the revised BSD license.\n");
98825eb42bSJan Lentfer         fprintf(stream, "There is NO warranty; not even for MERCHANTABILITY or FITNESS\n");
99825eb42bSJan Lentfer         fprintf(stream, "FOR A PARTICULAR PURPOSE.\n");
100825eb42bSJan Lentfer }
101825eb42bSJan Lentfer 
102825eb42bSJan Lentfer 
103825eb42bSJan Lentfer /**
104825eb42bSJan Lentfer  * Main function of drill
105825eb42bSJan Lentfer  * parse the arguments and prepare a query
106825eb42bSJan Lentfer  */
107825eb42bSJan Lentfer int
main(int argc,char * argv[])108825eb42bSJan Lentfer main(int argc, char *argv[])
109825eb42bSJan Lentfer {
110825eb42bSJan Lentfer         ldns_resolver	*res = NULL;
111825eb42bSJan Lentfer         ldns_resolver   *cmdline_res = NULL; /* only used to resolv @name names */
112825eb42bSJan Lentfer 	ldns_rr_list	*cmdline_rr_list = NULL;
113825eb42bSJan Lentfer 	ldns_rdf	*cmdline_dname = NULL;
114819dec71SDaniel Fojt         ldns_rdf 	*qname;
115825eb42bSJan Lentfer         ldns_pkt	*pkt;
116825eb42bSJan Lentfer         ldns_pkt	*qpkt;
117825eb42bSJan Lentfer         char 		*serv;
1185340022aSzrj         char 		*src = NULL;
119d1b2b5caSJohn Marino         const char 	*name;
120825eb42bSJan Lentfer 	char		*progname;
121825eb42bSJan Lentfer 	char 		*query_file = NULL;
122825eb42bSJan Lentfer 	char		*answer_file = NULL;
123825eb42bSJan Lentfer 	ldns_buffer	*query_buffer = NULL;
124825eb42bSJan Lentfer 	ldns_rdf 	*serv_rdf;
1255340022aSzrj 	ldns_rdf 	*src_rdf = NULL;
126825eb42bSJan Lentfer 	ldns_rr_type 	type;
127825eb42bSJan Lentfer 	ldns_rr_class	clas;
128825eb42bSJan Lentfer #if 0
129825eb42bSJan Lentfer 	ldns_pkt_opcode opcode = LDNS_PACKET_QUERY;
130825eb42bSJan Lentfer #endif
131825eb42bSJan Lentfer 	int 		i, c;
132825eb42bSJan Lentfer 	int 		int_type;
133825eb42bSJan Lentfer 	int		int_clas;
134825eb42bSJan Lentfer 	int		PURPOSE;
135825eb42bSJan Lentfer 	char		*tsig_name = NULL;
136825eb42bSJan Lentfer 	char		*tsig_data = NULL;
137825eb42bSJan Lentfer 	char 		*tsig_algorithm = NULL;
138825eb42bSJan Lentfer 	size_t		tsig_separator;
139825eb42bSJan Lentfer 	size_t		tsig_separator2;
140825eb42bSJan Lentfer 	ldns_rr		*axfr_rr;
141825eb42bSJan Lentfer 	ldns_status	status;
142825eb42bSJan Lentfer 	char *type_str;
1435340022aSzrj 	uint32_t	serial = 0;
144825eb42bSJan Lentfer 	/* list of keys used in dnssec operations */
145825eb42bSJan Lentfer 	ldns_rr_list	*key_list = ldns_rr_list_new();
146825eb42bSJan Lentfer 	/* what key verify the current answer */
147825eb42bSJan Lentfer 	ldns_rr_list 	*key_verified;
148825eb42bSJan Lentfer 
149825eb42bSJan Lentfer 	/* resolver options */
150825eb42bSJan Lentfer 	uint16_t	qflags;
151825eb42bSJan Lentfer 	uint16_t 	qbuf;
152825eb42bSJan Lentfer 	uint16_t	qport;
153825eb42bSJan Lentfer 	uint8_t		qfamily;
154825eb42bSJan Lentfer 	bool		qdnssec;
155825eb42bSJan Lentfer 	bool		qfallback;
156825eb42bSJan Lentfer 	bool		qds;
157825eb42bSJan Lentfer 	bool		qusevc;
158825eb42bSJan Lentfer 	bool 		qrandom;
159819dec71SDaniel Fojt 	bool            drill_reverse = false;
160825eb42bSJan Lentfer 
161825eb42bSJan Lentfer 	char		*resolv_conf_file = NULL;
162825eb42bSJan Lentfer 
163825eb42bSJan Lentfer 	ldns_rdf *trace_start_name = NULL;
164825eb42bSJan Lentfer 
165825eb42bSJan Lentfer 	int		result = 0;
166825eb42bSJan Lentfer 
1675340022aSzrj 	uint8_t         s6addr[16];
1685340022aSzrj 	char            ip6_arpa_str[74];
169819dec71SDaniel Fojt 	uint8_t         s4addr[4];
170819dec71SDaniel Fojt 	char            in_addr_arpa_str[40];
1715340022aSzrj 
172825eb42bSJan Lentfer #ifdef USE_WINSOCK
173825eb42bSJan Lentfer 	int r;
174825eb42bSJan Lentfer 	WSADATA wsa_data;
175825eb42bSJan Lentfer #endif
176*ee791febSAntonio Huete Jimenez 	ldns_output_format_storage fmt_storage;
177*ee791febSAntonio Huete Jimenez 	ldns_output_format* fmt = ldns_output_format_init(&fmt_storage);
178825eb42bSJan Lentfer 
179825eb42bSJan Lentfer 	int_type = -1; serv = NULL; type = 0;
180825eb42bSJan Lentfer 	int_clas = -1; name = NULL; clas = 0;
1815340022aSzrj 	qname = NULL; src = NULL;
182825eb42bSJan Lentfer 	progname = strdup(argv[0]);
183825eb42bSJan Lentfer 
184825eb42bSJan Lentfer #ifdef USE_WINSOCK
185825eb42bSJan Lentfer 	r = WSAStartup(MAKEWORD(2,2), &wsa_data);
186825eb42bSJan Lentfer 	if(r != 0) {
187825eb42bSJan Lentfer 		printf("Failed WSAStartup: %d\n", r);
188825eb42bSJan Lentfer 		result = EXIT_FAILURE;
189825eb42bSJan Lentfer 		goto exit;
190825eb42bSJan Lentfer 	}
191825eb42bSJan Lentfer #endif /* USE_WINSOCK */
192825eb42bSJan Lentfer 
193825eb42bSJan Lentfer 
194825eb42bSJan Lentfer 	PURPOSE = DRILL_QUERY;
195825eb42bSJan Lentfer 	qflags = LDNS_RD;
196825eb42bSJan Lentfer 	qport = LDNS_PORT;
197825eb42bSJan Lentfer 	verbosity = 2;
198825eb42bSJan Lentfer 	qdnssec = false;
199825eb42bSJan Lentfer 	qfamily = LDNS_RESOLV_INETANY;
200825eb42bSJan Lentfer 	qfallback = false;
201825eb42bSJan Lentfer 	qds = false;
202825eb42bSJan Lentfer 	qbuf = 0;
203825eb42bSJan Lentfer 	qusevc = false;
204825eb42bSJan Lentfer 	qrandom = true;
205825eb42bSJan Lentfer 	key_verified = NULL;
206*ee791febSAntonio Huete Jimenez 	ldns_edns_option_list* edns_list = NULL;
207825eb42bSJan Lentfer 
208825eb42bSJan Lentfer 	ldns_init_random(NULL, 0);
209825eb42bSJan Lentfer 
210825eb42bSJan Lentfer 	/* string from orig drill: "i:w:I46Sk:TNp:b:DsvhVcuaq:f:xr" */
211825eb42bSJan Lentfer 	/* global first, query opt next, option with parm's last
212825eb42bSJan Lentfer 	 * and sorted */ /*  "46DITSVQf:i:w:q:achuvxzy:so:p:b:k:" */
213825eb42bSJan Lentfer 
2145340022aSzrj 	while ((c = getopt(argc, argv, "46ab:c:d:Df:hi:I:k:o:p:q:Qr:sStTuvV:w:xy:z")) != -1) {
215825eb42bSJan Lentfer 		switch(c) {
216825eb42bSJan Lentfer 			/* global options */
217825eb42bSJan Lentfer 			case '4':
218825eb42bSJan Lentfer 				qfamily = LDNS_RESOLV_INET;
219825eb42bSJan Lentfer 				break;
220825eb42bSJan Lentfer 			case '6':
221825eb42bSJan Lentfer 				qfamily = LDNS_RESOLV_INET6;
222825eb42bSJan Lentfer 				break;
223825eb42bSJan Lentfer 			case 'D':
224825eb42bSJan Lentfer 				qdnssec = true;
225825eb42bSJan Lentfer 				break;
226825eb42bSJan Lentfer 			case 'I':
2275340022aSzrj 				src = optarg;
228825eb42bSJan Lentfer 				break;
229825eb42bSJan Lentfer 			case 'T':
230825eb42bSJan Lentfer 				if (PURPOSE == DRILL_CHASE) {
231825eb42bSJan Lentfer 					fprintf(stderr, "-T and -S cannot be used at the same time.\n");
232825eb42bSJan Lentfer 					exit(EXIT_FAILURE);
233825eb42bSJan Lentfer 				}
234825eb42bSJan Lentfer 				PURPOSE = DRILL_TRACE;
235825eb42bSJan Lentfer 				break;
236825eb42bSJan Lentfer #ifdef HAVE_SSL
237825eb42bSJan Lentfer 			case 'S':
238825eb42bSJan Lentfer 				if (PURPOSE == DRILL_TRACE) {
239825eb42bSJan Lentfer 					fprintf(stderr, "-T and -S cannot be used at the same time.\n");
240825eb42bSJan Lentfer 					exit(EXIT_FAILURE);
241825eb42bSJan Lentfer 				}
242825eb42bSJan Lentfer 				PURPOSE = DRILL_CHASE;
243825eb42bSJan Lentfer 				break;
244825eb42bSJan Lentfer #endif /* HAVE_SSL */
245825eb42bSJan Lentfer 			case 'V':
246d1b2b5caSJohn Marino 				if (strtok(optarg, "0123456789") != NULL) {
247d1b2b5caSJohn Marino 					fprintf(stderr, "-V expects an number as an argument.\n");
248d1b2b5caSJohn Marino 					exit(EXIT_FAILURE);
249d1b2b5caSJohn Marino 				}
250825eb42bSJan Lentfer 				verbosity = atoi(optarg);
251825eb42bSJan Lentfer 				break;
252825eb42bSJan Lentfer 			case 'Q':
253*ee791febSAntonio Huete Jimenez 				fmt->flags |= LDNS_FMT_SHORT;
254825eb42bSJan Lentfer 				verbosity = -1;
255825eb42bSJan Lentfer 				break;
256825eb42bSJan Lentfer 			case 'f':
257825eb42bSJan Lentfer 				query_file = optarg;
258825eb42bSJan Lentfer 				break;
259825eb42bSJan Lentfer 			case 'i':
260825eb42bSJan Lentfer 				answer_file = optarg;
261825eb42bSJan Lentfer 				PURPOSE = DRILL_AFROMFILE;
262825eb42bSJan Lentfer 				break;
263825eb42bSJan Lentfer 			case 'w':
264825eb42bSJan Lentfer 				answer_file = optarg;
265825eb42bSJan Lentfer 				break;
266825eb42bSJan Lentfer 			case 'q':
267825eb42bSJan Lentfer 				query_file = optarg;
268825eb42bSJan Lentfer 				PURPOSE = DRILL_QTOFILE;
269825eb42bSJan Lentfer 				break;
270825eb42bSJan Lentfer 			case 'r':
271825eb42bSJan Lentfer 				if (global_dns_root) {
272825eb42bSJan Lentfer 					fprintf(stderr, "There was already a series of root servers set\n");
273825eb42bSJan Lentfer 					exit(EXIT_FAILURE);
274825eb42bSJan Lentfer 				}
275825eb42bSJan Lentfer 				global_dns_root = read_root_hints(optarg);
276825eb42bSJan Lentfer 				if (!global_dns_root) {
277825eb42bSJan Lentfer 					fprintf(stderr, "Unable to read root hints file %s, aborting\n", optarg);
278825eb42bSJan Lentfer 					exit(EXIT_FAILURE);
279825eb42bSJan Lentfer 				}
280825eb42bSJan Lentfer 				break;
281825eb42bSJan Lentfer 			/* query options */
282825eb42bSJan Lentfer 			case 'a':
283825eb42bSJan Lentfer 				qfallback = true;
284825eb42bSJan Lentfer 				break;
285825eb42bSJan Lentfer 			case 'b':
286825eb42bSJan Lentfer 				qbuf = (uint16_t)atoi(optarg);
287825eb42bSJan Lentfer 				if (qbuf == 0) {
288825eb42bSJan Lentfer 					error("%s", "<bufsize> could not be converted");
289825eb42bSJan Lentfer 				}
290825eb42bSJan Lentfer 				break;
291825eb42bSJan Lentfer 			case 'c':
292825eb42bSJan Lentfer 				resolv_conf_file = optarg;
293825eb42bSJan Lentfer 				break;
294825eb42bSJan Lentfer 			case 't':
295825eb42bSJan Lentfer 				qusevc = true;
296825eb42bSJan Lentfer 				break;
297825eb42bSJan Lentfer 			case 'k':
298d1b2b5caSJohn Marino 				status = read_key_file(optarg,
299d1b2b5caSJohn Marino 						key_list, false);
300825eb42bSJan Lentfer 				if (status != LDNS_STATUS_OK) {
301825eb42bSJan Lentfer 					error("Could not parse the key file %s: %s", optarg, ldns_get_errorstr_by_id(status));
302825eb42bSJan Lentfer 				}
303825eb42bSJan Lentfer 				qdnssec = true; /* enable that too */
304825eb42bSJan Lentfer 				break;
305825eb42bSJan Lentfer 			case 'o':
306825eb42bSJan Lentfer 				/* only looks at the first hit: capital=ON, lowercase=OFF*/
307825eb42bSJan Lentfer 				if (strstr(optarg, "QR")) {
308825eb42bSJan Lentfer 					DRILL_ON(qflags, LDNS_QR);
309825eb42bSJan Lentfer 				}
310825eb42bSJan Lentfer 				if (strstr(optarg, "qr")) {
311825eb42bSJan Lentfer 					DRILL_OFF(qflags, LDNS_QR);
312825eb42bSJan Lentfer 				}
313825eb42bSJan Lentfer 				if (strstr(optarg, "AA")) {
314825eb42bSJan Lentfer 					DRILL_ON(qflags, LDNS_AA);
315825eb42bSJan Lentfer 				}
316825eb42bSJan Lentfer 				if (strstr(optarg, "aa")) {
317825eb42bSJan Lentfer 					DRILL_OFF(qflags, LDNS_AA);
318825eb42bSJan Lentfer 				}
319825eb42bSJan Lentfer 				if (strstr(optarg, "TC")) {
320825eb42bSJan Lentfer 					DRILL_ON(qflags, LDNS_TC);
321825eb42bSJan Lentfer 				}
322825eb42bSJan Lentfer 				if (strstr(optarg, "tc")) {
323825eb42bSJan Lentfer 					DRILL_OFF(qflags, LDNS_TC);
324825eb42bSJan Lentfer 				}
325825eb42bSJan Lentfer 				if (strstr(optarg, "RD")) {
326825eb42bSJan Lentfer 					DRILL_ON(qflags, LDNS_RD);
327825eb42bSJan Lentfer 				}
328825eb42bSJan Lentfer 				if (strstr(optarg, "rd")) {
329825eb42bSJan Lentfer 					DRILL_OFF(qflags, LDNS_RD);
330825eb42bSJan Lentfer 				}
331825eb42bSJan Lentfer 				if (strstr(optarg, "CD")) {
332825eb42bSJan Lentfer 					DRILL_ON(qflags, LDNS_CD);
333825eb42bSJan Lentfer 				}
334825eb42bSJan Lentfer 				if (strstr(optarg, "cd")) {
335825eb42bSJan Lentfer 					DRILL_OFF(qflags, LDNS_CD);
336825eb42bSJan Lentfer 				}
337825eb42bSJan Lentfer 				if (strstr(optarg, "RA")) {
338825eb42bSJan Lentfer 					DRILL_ON(qflags, LDNS_RA);
339825eb42bSJan Lentfer 				}
340825eb42bSJan Lentfer 				if (strstr(optarg, "ra")) {
341825eb42bSJan Lentfer 					DRILL_OFF(qflags, LDNS_RA);
342825eb42bSJan Lentfer 				}
343825eb42bSJan Lentfer 				if (strstr(optarg, "AD")) {
344825eb42bSJan Lentfer 					DRILL_ON(qflags, LDNS_AD);
345825eb42bSJan Lentfer 				}
346825eb42bSJan Lentfer 				if (strstr(optarg, "ad")) {
347825eb42bSJan Lentfer 					DRILL_OFF(qflags, LDNS_AD);
348825eb42bSJan Lentfer 				}
349825eb42bSJan Lentfer 				break;
350825eb42bSJan Lentfer 			case 'p':
351825eb42bSJan Lentfer 				qport = (uint16_t)atoi(optarg);
352825eb42bSJan Lentfer 				if (qport == 0) {
353825eb42bSJan Lentfer 					error("%s", "<port> could not be converted");
354825eb42bSJan Lentfer 				}
355825eb42bSJan Lentfer 				break;
356825eb42bSJan Lentfer 			case 's':
357825eb42bSJan Lentfer 				qds = true;
358825eb42bSJan Lentfer 				break;
359825eb42bSJan Lentfer 			case 'u':
360825eb42bSJan Lentfer 				qusevc = false;
361825eb42bSJan Lentfer 				break;
362825eb42bSJan Lentfer 			case 'v':
363825eb42bSJan Lentfer 				version(stdout, progname);
364825eb42bSJan Lentfer 				result = EXIT_SUCCESS;
365825eb42bSJan Lentfer 				goto exit;
366825eb42bSJan Lentfer 			case 'x':
367819dec71SDaniel Fojt 				drill_reverse = true;
368825eb42bSJan Lentfer 				break;
369825eb42bSJan Lentfer 			case 'y':
370825eb42bSJan Lentfer #ifdef HAVE_SSL
371825eb42bSJan Lentfer 				if (strchr(optarg, ':')) {
372825eb42bSJan Lentfer 					tsig_separator = (size_t) (strchr(optarg, ':') - optarg);
373819dec71SDaniel Fojt 					if (tsig_algorithm) {
374819dec71SDaniel Fojt 						free(tsig_algorithm);
375819dec71SDaniel Fojt 						tsig_algorithm = NULL;
376819dec71SDaniel Fojt 					}
377825eb42bSJan Lentfer 					if (strchr(optarg + tsig_separator + 1, ':')) {
378825eb42bSJan Lentfer 						tsig_separator2 = (size_t) (strchr(optarg + tsig_separator + 1, ':') - optarg);
379825eb42bSJan Lentfer 						tsig_algorithm = xmalloc(strlen(optarg) - tsig_separator2);
380825eb42bSJan Lentfer 						strncpy(tsig_algorithm, optarg + tsig_separator2 + 1, strlen(optarg) - tsig_separator2);
381825eb42bSJan Lentfer 						tsig_algorithm[strlen(optarg) - tsig_separator2 - 1] = '\0';
382825eb42bSJan Lentfer 					} else {
383825eb42bSJan Lentfer 						tsig_separator2 = strlen(optarg);
3845340022aSzrj 						tsig_algorithm = strdup("hmac-md5.sig-alg.reg.int");
385825eb42bSJan Lentfer 					}
386825eb42bSJan Lentfer 					tsig_name = xmalloc(tsig_separator + 1);
387825eb42bSJan Lentfer 					tsig_data = xmalloc(tsig_separator2 - tsig_separator);
388825eb42bSJan Lentfer 					strncpy(tsig_name, optarg, tsig_separator);
389825eb42bSJan Lentfer 					strncpy(tsig_data, optarg + tsig_separator + 1, tsig_separator2 - tsig_separator - 1);
390825eb42bSJan Lentfer 					/* strncpy does not append \0 if source is longer than n */
391825eb42bSJan Lentfer 					tsig_name[tsig_separator] = '\0';
392825eb42bSJan Lentfer 					tsig_data[ tsig_separator2 - tsig_separator - 1] = '\0';
393825eb42bSJan Lentfer 				}
394825eb42bSJan Lentfer #else
395825eb42bSJan Lentfer 				fprintf(stderr, "TSIG requested, but SSL is not supported\n");
396825eb42bSJan Lentfer 				result = EXIT_FAILURE;
397825eb42bSJan Lentfer 				goto exit;
398825eb42bSJan Lentfer #endif /* HAVE_SSL */
399825eb42bSJan Lentfer 				break;
400825eb42bSJan Lentfer 			case 'z':
401825eb42bSJan Lentfer 				qrandom = false;
402825eb42bSJan Lentfer 				break;
403825eb42bSJan Lentfer 			case 'd':
404825eb42bSJan Lentfer 				trace_start_name = ldns_dname_new_frm_str(optarg);
405825eb42bSJan Lentfer 				if (!trace_start_name) {
406825eb42bSJan Lentfer 					fprintf(stderr, "Unable to parse argument for -%c\n", c);
407825eb42bSJan Lentfer 					result = EXIT_FAILURE;
408825eb42bSJan Lentfer 					goto exit;
409825eb42bSJan Lentfer 				}
410825eb42bSJan Lentfer 				break;
411825eb42bSJan Lentfer 			case 'h':
412825eb42bSJan Lentfer 				version(stdout, progname);
413825eb42bSJan Lentfer 				usage(stdout, progname);
414825eb42bSJan Lentfer 				result = EXIT_SUCCESS;
415825eb42bSJan Lentfer 				goto exit;
416825eb42bSJan Lentfer 				break;
417825eb42bSJan Lentfer 			default:
418825eb42bSJan Lentfer 				fprintf(stderr, "Unknown argument: -%c, use -h to see usage\n", c);
419825eb42bSJan Lentfer 				result = EXIT_FAILURE;
420825eb42bSJan Lentfer 				goto exit;
421825eb42bSJan Lentfer 		}
422825eb42bSJan Lentfer 	}
423825eb42bSJan Lentfer 	argc -= optind;
424825eb42bSJan Lentfer 	argv += optind;
425825eb42bSJan Lentfer 
426d1b2b5caSJohn Marino 	if ((PURPOSE == DRILL_CHASE || (PURPOSE == DRILL_TRACE && qdnssec)) &&
427d1b2b5caSJohn Marino 			ldns_rr_list_rr_count(key_list) == 0) {
428d1b2b5caSJohn Marino 
429d1b2b5caSJohn Marino 		(void) read_key_file(LDNS_TRUST_ANCHOR_FILE, key_list, true);
430d1b2b5caSJohn Marino 	}
431d1b2b5caSJohn Marino 	if (ldns_rr_list_rr_count(key_list) > 0) {
432d1b2b5caSJohn Marino 		printf(";; Number of trusted keys: %d\n",
433d1b2b5caSJohn Marino 				(int) ldns_rr_list_rr_count(key_list));
434d1b2b5caSJohn Marino 	}
435825eb42bSJan Lentfer 	/* do a secure trace when requested */
436825eb42bSJan Lentfer 	if (PURPOSE == DRILL_TRACE && qdnssec) {
437825eb42bSJan Lentfer #ifdef HAVE_SSL
438825eb42bSJan Lentfer 		if (ldns_rr_list_rr_count(key_list) == 0) {
439825eb42bSJan Lentfer 			warning("%s", "No trusted keys were given. Will not be able to verify authenticity!");
440825eb42bSJan Lentfer 		}
441825eb42bSJan Lentfer 		PURPOSE = DRILL_SECTRACE;
442825eb42bSJan Lentfer #else
443825eb42bSJan Lentfer 		fprintf(stderr, "ldns has not been compiled with OpenSSL support. Secure trace not available\n");
444825eb42bSJan Lentfer 		exit(1);
445825eb42bSJan Lentfer #endif /* HAVE_SSL */
446825eb42bSJan Lentfer 	}
447825eb42bSJan Lentfer 
448825eb42bSJan Lentfer 	/* parse the arguments, with multiple arguments, the last argument
449825eb42bSJan Lentfer 	 * found is used */
450825eb42bSJan Lentfer 	for(i = 0; i < argc; i++) {
451825eb42bSJan Lentfer 
452825eb42bSJan Lentfer 		/* if ^@ then it's a server */
453825eb42bSJan Lentfer 		if (argv[i][0] == '@') {
454825eb42bSJan Lentfer 			if (strlen(argv[i]) == 1) {
455825eb42bSJan Lentfer 				warning("%s", "No nameserver given");
456825eb42bSJan Lentfer 				exit(EXIT_FAILURE);
457825eb42bSJan Lentfer 			}
458825eb42bSJan Lentfer 			serv = argv[i] + 1;
459825eb42bSJan Lentfer 			continue;
460825eb42bSJan Lentfer 		}
461*ee791febSAntonio Huete Jimenez 		/* if ^+ then it's an EDNS option */
462*ee791febSAntonio Huete Jimenez 		if (argv[i][0] == '+') {
463*ee791febSAntonio Huete Jimenez 			if (!strcmp(argv[i]+1, "nsid")) {
464*ee791febSAntonio Huete Jimenez 				ldns_edns_option *edns;
465*ee791febSAntonio Huete Jimenez 				edns_list = ldns_edns_option_list_new();
466*ee791febSAntonio Huete Jimenez 
467*ee791febSAntonio Huete Jimenez 				/* create NSID EDNS*/
468*ee791febSAntonio Huete Jimenez 				edns = ldns_edns_new_from_data(LDNS_EDNS_NSID, 0, NULL);
469*ee791febSAntonio Huete Jimenez 
470*ee791febSAntonio Huete Jimenez 				if (edns_list == NULL || edns == NULL) {
471*ee791febSAntonio Huete Jimenez 					error("EDNS option could not be allocated");
472*ee791febSAntonio Huete Jimenez 					break;
473*ee791febSAntonio Huete Jimenez 				}
474*ee791febSAntonio Huete Jimenez 
475*ee791febSAntonio Huete Jimenez 				if (!(ldns_edns_option_list_push(edns_list, edns))) {
476*ee791febSAntonio Huete Jimenez 					error("EDNS option NSID could not be attached");
477*ee791febSAntonio Huete Jimenez 					break;
478*ee791febSAntonio Huete Jimenez 				}
479*ee791febSAntonio Huete Jimenez 				continue;
480*ee791febSAntonio Huete Jimenez 			}
481*ee791febSAntonio Huete Jimenez 			else {
482*ee791febSAntonio Huete Jimenez 				error("Unsupported argument after '+'");
483*ee791febSAntonio Huete Jimenez 				break;
484*ee791febSAntonio Huete Jimenez 			}
485*ee791febSAntonio Huete Jimenez 		}
486825eb42bSJan Lentfer 		/* if has a dot, it's a name */
487825eb42bSJan Lentfer 		if (strchr(argv[i], '.')) {
488825eb42bSJan Lentfer 			name = argv[i];
489825eb42bSJan Lentfer 			continue;
490825eb42bSJan Lentfer 		}
491825eb42bSJan Lentfer 		/* if it matches a type, it's a type */
492825eb42bSJan Lentfer 		if (int_type == -1) {
493825eb42bSJan Lentfer 			type = ldns_get_rr_type_by_name(argv[i]);
494825eb42bSJan Lentfer 			if (type != 0) {
495825eb42bSJan Lentfer 				int_type = 0;
496825eb42bSJan Lentfer 				continue;
4975340022aSzrj 			} else if (is_ixfr_with_serial(argv[i], &serial)) {
4985340022aSzrj 				type = LDNS_RR_TYPE_IXFR;
4995340022aSzrj 				int_type = 0;
5005340022aSzrj 				continue;
501825eb42bSJan Lentfer 			}
502825eb42bSJan Lentfer 		}
503825eb42bSJan Lentfer 		/* if it matches a class, it's a class */
504825eb42bSJan Lentfer 		if (int_clas == -1) {
505825eb42bSJan Lentfer 			clas = ldns_get_rr_class_by_name(argv[i]);
506825eb42bSJan Lentfer 			if (clas != 0) {
507825eb42bSJan Lentfer 				int_clas = 0;
508825eb42bSJan Lentfer 				continue;
509825eb42bSJan Lentfer 			}
510825eb42bSJan Lentfer 		}
511825eb42bSJan Lentfer 		/* it all fails assume it's a name */
512825eb42bSJan Lentfer 		name = argv[i];
513825eb42bSJan Lentfer 	}
514825eb42bSJan Lentfer 	/* act like dig and use for . NS */
515825eb42bSJan Lentfer 	if (!name) {
516825eb42bSJan Lentfer 		name = ".";
517825eb42bSJan Lentfer 		int_type = 0;
518825eb42bSJan Lentfer 		type = LDNS_RR_TYPE_NS;
519825eb42bSJan Lentfer 	}
520825eb42bSJan Lentfer 
521825eb42bSJan Lentfer 	/* defaults if not given */
522825eb42bSJan Lentfer 	if (int_clas == -1) {
523825eb42bSJan Lentfer 		clas = LDNS_RR_CLASS_IN;
524825eb42bSJan Lentfer 	}
525825eb42bSJan Lentfer 	if (int_type == -1) {
526819dec71SDaniel Fojt 		if (!drill_reverse) {
527825eb42bSJan Lentfer 			type = LDNS_RR_TYPE_A;
528825eb42bSJan Lentfer 		} else {
529825eb42bSJan Lentfer 			type = LDNS_RR_TYPE_PTR;
530825eb42bSJan Lentfer 		}
531825eb42bSJan Lentfer 	}
532819dec71SDaniel Fojt 	if (!drill_reverse)
533819dec71SDaniel Fojt 		; /* pass */
534819dec71SDaniel Fojt 	else if (strchr(name, ':')) { /* ipv4 or ipv6 addr? */
535819dec71SDaniel Fojt 		if (!inet_pton(AF_INET6, name, &s6addr)) {
536819dec71SDaniel Fojt 			error("Syntax error: cannot parse IPv6 address\n");
537819dec71SDaniel Fojt 		}
538819dec71SDaniel Fojt 		(void) snprintf(ip6_arpa_str, sizeof(ip6_arpa_str),
539819dec71SDaniel Fojt 		    "%x.%x.%x.%x.%x.%x.%x.%x."
540819dec71SDaniel Fojt 		    "%x.%x.%x.%x.%x.%x.%x.%x."
541819dec71SDaniel Fojt 		    "%x.%x.%x.%x.%x.%x.%x.%x."
542819dec71SDaniel Fojt 		    "%x.%x.%x.%x.%x.%x.%x.%x.ip6.arpa.",
543819dec71SDaniel Fojt 		    (unsigned int)(s6addr[15] & 0x0F),
544819dec71SDaniel Fojt 		    (unsigned int)(s6addr[15] >> 4),
545819dec71SDaniel Fojt 		    (unsigned int)(s6addr[14] & 0x0F),
546819dec71SDaniel Fojt 		    (unsigned int)(s6addr[14] >> 4),
547819dec71SDaniel Fojt 		    (unsigned int)(s6addr[13] & 0x0F),
548819dec71SDaniel Fojt 		    (unsigned int)(s6addr[13] >> 4),
549819dec71SDaniel Fojt 		    (unsigned int)(s6addr[12] & 0x0F),
550819dec71SDaniel Fojt 		    (unsigned int)(s6addr[12] >> 4),
551819dec71SDaniel Fojt 		    (unsigned int)(s6addr[11] & 0x0F),
552819dec71SDaniel Fojt 		    (unsigned int)(s6addr[11] >> 4),
553819dec71SDaniel Fojt 		    (unsigned int)(s6addr[10] & 0x0F),
554819dec71SDaniel Fojt 		    (unsigned int)(s6addr[10] >> 4),
555819dec71SDaniel Fojt 		    (unsigned int)(s6addr[9] & 0x0F),
556819dec71SDaniel Fojt 		    (unsigned int)(s6addr[9] >> 4),
557819dec71SDaniel Fojt 		    (unsigned int)(s6addr[8] & 0x0F),
558819dec71SDaniel Fojt 		    (unsigned int)(s6addr[8] >> 4),
559819dec71SDaniel Fojt 		    (unsigned int)(s6addr[7] & 0x0F),
560819dec71SDaniel Fojt 		    (unsigned int)(s6addr[7] >> 4),
561819dec71SDaniel Fojt 		    (unsigned int)(s6addr[6] & 0x0F),
562819dec71SDaniel Fojt 		    (unsigned int)(s6addr[6] >> 4),
563819dec71SDaniel Fojt 		    (unsigned int)(s6addr[5] & 0x0F),
564819dec71SDaniel Fojt 		    (unsigned int)(s6addr[5] >> 4),
565819dec71SDaniel Fojt 		    (unsigned int)(s6addr[4] & 0x0F),
566819dec71SDaniel Fojt 		    (unsigned int)(s6addr[4] >> 4),
567819dec71SDaniel Fojt 		    (unsigned int)(s6addr[3] & 0x0F),
568819dec71SDaniel Fojt 		    (unsigned int)(s6addr[3] >> 4),
569819dec71SDaniel Fojt 		    (unsigned int)(s6addr[2] & 0x0F),
570819dec71SDaniel Fojt 		    (unsigned int)(s6addr[2] >> 4),
571819dec71SDaniel Fojt 		    (unsigned int)(s6addr[1] & 0x0F),
572819dec71SDaniel Fojt 		    (unsigned int)(s6addr[1] >> 4),
573819dec71SDaniel Fojt 		    (unsigned int)(s6addr[0] & 0x0F),
574819dec71SDaniel Fojt 		    (unsigned int)(s6addr[0] >> 4));
575819dec71SDaniel Fojt 		name = ip6_arpa_str;
576819dec71SDaniel Fojt 
577819dec71SDaniel Fojt 	} else if (!inet_pton(AF_INET, name, &s4addr)) {
578819dec71SDaniel Fojt 		error("Syntax error: cannot parse IPv4 address\n");
579819dec71SDaniel Fojt 
580819dec71SDaniel Fojt 	} else {
581819dec71SDaniel Fojt 		(void) snprintf(in_addr_arpa_str, sizeof(in_addr_arpa_str),
582819dec71SDaniel Fojt 		    "%d.%d.%d.%d.in-addr.arpa.", (int)s4addr[3],
583819dec71SDaniel Fojt 		    (int)s4addr[2], (int)s4addr[1], (int)s4addr[0]);
584819dec71SDaniel Fojt 		name = in_addr_arpa_str;
585819dec71SDaniel Fojt 	}
586825eb42bSJan Lentfer 
5875340022aSzrj 	if (src) {
5885340022aSzrj 		src_rdf = ldns_rdf_new_addr_frm_str(src);
5895340022aSzrj 		if(!src_rdf) {
5905340022aSzrj 			fprintf(stderr, "-I must be a valid IP[v6] address.\n");
5915340022aSzrj 			exit(EXIT_FAILURE);
5925340022aSzrj 		}
5935340022aSzrj 		if (ldns_rdf_size(src_rdf) == 4) {
5945340022aSzrj 			qfamily = LDNS_RESOLV_INET;
5955340022aSzrj 
5965340022aSzrj 		} else if (ldns_rdf_size(src_rdf) == 16) {
5975340022aSzrj 			qfamily = LDNS_RESOLV_INET6;
5985340022aSzrj 		}
5995340022aSzrj 	}
6005340022aSzrj 
601825eb42bSJan Lentfer 	/* set the nameserver to use */
602825eb42bSJan Lentfer 	if (!serv) {
6035340022aSzrj 		/* no server given -- make a resolver from /etc/resolv.conf */
604825eb42bSJan Lentfer 		status = ldns_resolver_new_frm_file(&res, resolv_conf_file);
605825eb42bSJan Lentfer 		if (status != LDNS_STATUS_OK) {
606825eb42bSJan Lentfer 			warning("Could not create a resolver structure: %s (%s)\n"
607825eb42bSJan Lentfer 					"Try drill @localhost if you have a resolver running on your machine.",
608825eb42bSJan Lentfer 				    ldns_get_errorstr_by_id(status), resolv_conf_file);
609825eb42bSJan Lentfer 			result = EXIT_FAILURE;
610825eb42bSJan Lentfer 			goto exit;
611825eb42bSJan Lentfer 		}
612825eb42bSJan Lentfer 	} else {
613825eb42bSJan Lentfer 		res = ldns_resolver_new();
614825eb42bSJan Lentfer 		if (!res || strlen(serv) <= 0) {
615825eb42bSJan Lentfer 			warning("Could not create a resolver structure");
616825eb42bSJan Lentfer 			result = EXIT_FAILURE;
617825eb42bSJan Lentfer 			goto exit;
618825eb42bSJan Lentfer 		}
619825eb42bSJan Lentfer 		/* add the nameserver */
620825eb42bSJan Lentfer 		serv_rdf = ldns_rdf_new_addr_frm_str(serv);
621825eb42bSJan Lentfer 		if (!serv_rdf) {
622825eb42bSJan Lentfer 			/* try to resolv the name if possible */
623825eb42bSJan Lentfer 			status = ldns_resolver_new_frm_file(&cmdline_res, resolv_conf_file);
624825eb42bSJan Lentfer 
625825eb42bSJan Lentfer 			if (status != LDNS_STATUS_OK) {
626825eb42bSJan Lentfer 				error("%s", "@server ip could not be converted");
627825eb42bSJan Lentfer 			}
628825eb42bSJan Lentfer 			ldns_resolver_set_dnssec(cmdline_res, qdnssec);
629825eb42bSJan Lentfer 			ldns_resolver_set_ip6(cmdline_res, qfamily);
630825eb42bSJan Lentfer 			ldns_resolver_set_fallback(cmdline_res, qfallback);
631825eb42bSJan Lentfer 			ldns_resolver_set_usevc(cmdline_res, qusevc);
6325340022aSzrj 			ldns_resolver_set_source(cmdline_res, src_rdf);
633825eb42bSJan Lentfer 
634825eb42bSJan Lentfer 			cmdline_dname = ldns_dname_new_frm_str(serv);
635825eb42bSJan Lentfer 
636825eb42bSJan Lentfer 			cmdline_rr_list = ldns_get_rr_list_addr_by_name(
637825eb42bSJan Lentfer 						cmdline_res,
638825eb42bSJan Lentfer 						cmdline_dname,
639825eb42bSJan Lentfer 						LDNS_RR_CLASS_IN,
640825eb42bSJan Lentfer 						qflags);
641825eb42bSJan Lentfer 			ldns_rdf_deep_free(cmdline_dname);
642825eb42bSJan Lentfer 			if (!cmdline_rr_list) {
643825eb42bSJan Lentfer 				/* This error msg is not always accurate */
644825eb42bSJan Lentfer 				error("%s `%s\'", "could not find any address for the name:", serv);
645825eb42bSJan Lentfer 			} else {
646825eb42bSJan Lentfer 				if (ldns_resolver_push_nameserver_rr_list(
647825eb42bSJan Lentfer 						res,
648825eb42bSJan Lentfer 						cmdline_rr_list
649825eb42bSJan Lentfer 					) != LDNS_STATUS_OK) {
650825eb42bSJan Lentfer 					error("%s", "pushing nameserver");
651825eb42bSJan Lentfer 				}
652825eb42bSJan Lentfer 			}
653825eb42bSJan Lentfer 		} else {
654825eb42bSJan Lentfer 			if (ldns_resolver_push_nameserver(res, serv_rdf) != LDNS_STATUS_OK) {
655825eb42bSJan Lentfer 				error("%s", "pushing nameserver");
656825eb42bSJan Lentfer 			} else {
657825eb42bSJan Lentfer 				ldns_rdf_deep_free(serv_rdf);
658825eb42bSJan Lentfer 			}
659825eb42bSJan Lentfer 		}
660825eb42bSJan Lentfer 	}
661825eb42bSJan Lentfer 	/* set the resolver options */
6625340022aSzrj 	ldns_resolver_set_ixfr_serial(res, serial);
663825eb42bSJan Lentfer 	ldns_resolver_set_port(res, qport);
6645340022aSzrj 	ldns_resolver_set_source(res, src_rdf);
665825eb42bSJan Lentfer 	if (verbosity >= 5) {
666825eb42bSJan Lentfer 		ldns_resolver_set_debug(res, true);
667825eb42bSJan Lentfer 	} else {
668825eb42bSJan Lentfer 		ldns_resolver_set_debug(res, false);
669825eb42bSJan Lentfer 	}
670825eb42bSJan Lentfer 	ldns_resolver_set_dnssec(res, qdnssec);
671825eb42bSJan Lentfer /*	ldns_resolver_set_dnssec_cd(res, qdnssec);*/
672825eb42bSJan Lentfer 	ldns_resolver_set_ip6(res, qfamily);
673825eb42bSJan Lentfer 	ldns_resolver_set_fallback(res, qfallback);
674825eb42bSJan Lentfer 	ldns_resolver_set_usevc(res, qusevc);
675825eb42bSJan Lentfer 	ldns_resolver_set_random(res, qrandom);
676825eb42bSJan Lentfer 	if (qbuf != 0) {
677825eb42bSJan Lentfer 		ldns_resolver_set_edns_udp_size(res, qbuf);
678825eb42bSJan Lentfer 	}
679825eb42bSJan Lentfer 
680825eb42bSJan Lentfer 	if (!name &&
681825eb42bSJan Lentfer 	    PURPOSE != DRILL_AFROMFILE &&
682825eb42bSJan Lentfer 	    !query_file
683825eb42bSJan Lentfer 	   ) {
684825eb42bSJan Lentfer 		usage(stdout, progname);
685825eb42bSJan Lentfer 		result = EXIT_FAILURE;
686825eb42bSJan Lentfer 		goto exit;
687825eb42bSJan Lentfer 	}
688825eb42bSJan Lentfer 
689825eb42bSJan Lentfer 	if (tsig_name && tsig_data) {
6905340022aSzrj 		/* With dig TSIG keys are also specified with -y,
6915340022aSzrj 		 * but format with drill is: -y <name:key[:algo]>
6925340022aSzrj 		 *             and with dig: -y [hmac:]name:key
6935340022aSzrj 		 *
6945340022aSzrj 		 * When we detect an unknown tsig algorithm in algo,
6955340022aSzrj 		 * but a known algorithm in name, we cane assume dig
6965340022aSzrj 		 * order was used.
6975340022aSzrj 		 *
6985340022aSzrj 		 * Following if statement is to anticipate and correct dig order
6995340022aSzrj 		 */
7005340022aSzrj 		if (   strcasecmp(tsig_algorithm, "hmac-md5.sig-alg.reg.int")
7015340022aSzrj 		    && strcasecmp(tsig_algorithm, "hmac-md5")
7025340022aSzrj 		    && strcasecmp(tsig_algorithm, "hmac-sha1")
7035340022aSzrj 		    && strcasecmp(tsig_algorithm, "hmac-sha256")
7045340022aSzrj 		    && (
7055340022aSzrj 		       strcasecmp(tsig_name, "hmac-md5.sig-alg.reg.int")  == 0
7065340022aSzrj 		    || strcasecmp(tsig_name, "hmac-md5")                  == 0
7075340022aSzrj 		    || strcasecmp(tsig_name, "hmac-sha1")                 == 0
7085340022aSzrj 		    || strcasecmp(tsig_name, "hmac-sha256")               == 0
7095340022aSzrj 		       )) {
7105340022aSzrj 
7115340022aSzrj 			/* Roll options */
7125340022aSzrj 			char *tmp_tsig_algorithm = tsig_name;
7135340022aSzrj 			tsig_name      = tsig_data;
7145340022aSzrj 			tsig_data      = tsig_algorithm;
7155340022aSzrj 			tsig_algorithm = tmp_tsig_algorithm;
7165340022aSzrj 		}
7175340022aSzrj 
7185340022aSzrj 		if (strcasecmp(tsig_algorithm, "hmac-md5") == 0) {
7195340022aSzrj 			free(tsig_algorithm);
7205340022aSzrj 			tsig_algorithm = strdup("hmac-md5.sig-alg.reg.int");
7215340022aSzrj 		}
7225340022aSzrj 
723825eb42bSJan Lentfer 		ldns_resolver_set_tsig_keyname(res, tsig_name);
724825eb42bSJan Lentfer 		ldns_resolver_set_tsig_keydata(res, tsig_data);
725825eb42bSJan Lentfer 		ldns_resolver_set_tsig_algorithm(res, tsig_algorithm);
726825eb42bSJan Lentfer 	}
727825eb42bSJan Lentfer 
728825eb42bSJan Lentfer 	/* main switching part of drill */
729825eb42bSJan Lentfer 	switch(PURPOSE) {
730825eb42bSJan Lentfer 		case DRILL_TRACE:
731825eb42bSJan Lentfer 			/* do a trace from the root down */
732825eb42bSJan Lentfer 			if (!global_dns_root) {
733825eb42bSJan Lentfer 				init_root();
734825eb42bSJan Lentfer 			}
735825eb42bSJan Lentfer 			qname = ldns_dname_new_frm_str(name);
736825eb42bSJan Lentfer 			if (!qname) {
737825eb42bSJan Lentfer 				error("%s", "parsing query name");
738825eb42bSJan Lentfer 			}
739825eb42bSJan Lentfer 			/* don't care about return packet */
7405340022aSzrj 			do_trace(res, qname, type, clas);
741825eb42bSJan Lentfer 			clear_root();
742825eb42bSJan Lentfer 			break;
743825eb42bSJan Lentfer 		case DRILL_SECTRACE:
744825eb42bSJan Lentfer 			/* do a secure trace from the root down */
745825eb42bSJan Lentfer 			if (!global_dns_root) {
746825eb42bSJan Lentfer 				init_root();
747825eb42bSJan Lentfer 			}
748825eb42bSJan Lentfer 			qname = ldns_dname_new_frm_str(name);
749825eb42bSJan Lentfer 			if (!qname) {
750825eb42bSJan Lentfer 				error("%s", "making qname");
751825eb42bSJan Lentfer 			}
752825eb42bSJan Lentfer 			/* don't care about return packet */
753825eb42bSJan Lentfer #ifdef HAVE_SSL
754825eb42bSJan Lentfer 			result = do_secure_trace(res, qname, type, clas, key_list, trace_start_name);
755825eb42bSJan Lentfer #endif /* HAVE_SSL */
756825eb42bSJan Lentfer 			clear_root();
757825eb42bSJan Lentfer 			break;
758825eb42bSJan Lentfer 		case DRILL_CHASE:
759825eb42bSJan Lentfer 			qname = ldns_dname_new_frm_str(name);
760825eb42bSJan Lentfer 			if (!qname) {
761825eb42bSJan Lentfer 				error("%s", "making qname");
762825eb42bSJan Lentfer 			}
763825eb42bSJan Lentfer 
764825eb42bSJan Lentfer 			ldns_resolver_set_dnssec(res, true);
765825eb42bSJan Lentfer 			ldns_resolver_set_dnssec_cd(res, true);
766825eb42bSJan Lentfer 			/* set dnssec implies udp_size of 4096 */
767825eb42bSJan Lentfer 			ldns_resolver_set_edns_udp_size(res, 4096);
7685340022aSzrj 			pkt = NULL;
7695340022aSzrj 			status = ldns_resolver_query_status(
7705340022aSzrj 					&pkt, res, qname, type, clas, qflags);
7715340022aSzrj 			if (status != LDNS_STATUS_OK) {
7725340022aSzrj 				error("error sending query: %s",
7735340022aSzrj 					ldns_get_errorstr_by_id(status));
7745340022aSzrj 			}
775825eb42bSJan Lentfer 			if (!pkt) {
7765340022aSzrj 				if (status == LDNS_STATUS_OK) {
777825eb42bSJan Lentfer 					error("%s", "error pkt sending");
7785340022aSzrj 				}
779825eb42bSJan Lentfer 				result = EXIT_FAILURE;
780825eb42bSJan Lentfer 			} else {
781825eb42bSJan Lentfer 				if (verbosity >= 3) {
782825eb42bSJan Lentfer 					ldns_pkt_print(stdout, pkt);
783825eb42bSJan Lentfer 				}
784825eb42bSJan Lentfer 
785825eb42bSJan Lentfer 				if (!ldns_pkt_answer(pkt)) {
786825eb42bSJan Lentfer 					mesg("No answer in packet");
787825eb42bSJan Lentfer 				} else {
788825eb42bSJan Lentfer #ifdef HAVE_SSL
789825eb42bSJan Lentfer 					ldns_resolver_set_dnssec_anchors(res, ldns_rr_list_clone(key_list));
790825eb42bSJan Lentfer 					result = do_chase(res, qname, type,
791825eb42bSJan Lentfer 					                  clas, key_list,
7925340022aSzrj 					                  pkt, qflags, NULL);
793825eb42bSJan Lentfer 					if (result == LDNS_STATUS_OK) {
794825eb42bSJan Lentfer 						if (verbosity != -1) {
795825eb42bSJan Lentfer 							mesg("Chase successful");
796825eb42bSJan Lentfer 						}
797825eb42bSJan Lentfer 						result = 0;
798825eb42bSJan Lentfer 					} else {
799825eb42bSJan Lentfer 						if (verbosity != -1) {
800825eb42bSJan Lentfer 							mesg("Chase failed.");
801825eb42bSJan Lentfer 						}
802825eb42bSJan Lentfer 					}
803825eb42bSJan Lentfer #endif /* HAVE_SSL */
804825eb42bSJan Lentfer 				}
805825eb42bSJan Lentfer 				ldns_pkt_free(pkt);
806825eb42bSJan Lentfer 			}
807825eb42bSJan Lentfer 			break;
808825eb42bSJan Lentfer 		case DRILL_AFROMFILE:
809825eb42bSJan Lentfer 			pkt = read_hex_pkt(answer_file);
810825eb42bSJan Lentfer 			if (pkt) {
811825eb42bSJan Lentfer 				if (verbosity != -1) {
812825eb42bSJan Lentfer 					ldns_pkt_print(stdout, pkt);
813825eb42bSJan Lentfer 				}
814825eb42bSJan Lentfer 				ldns_pkt_free(pkt);
815825eb42bSJan Lentfer 			}
816825eb42bSJan Lentfer 
817825eb42bSJan Lentfer 			break;
818825eb42bSJan Lentfer 		case DRILL_QTOFILE:
819825eb42bSJan Lentfer 			qname = ldns_dname_new_frm_str(name);
820825eb42bSJan Lentfer 			if (!qname) {
821825eb42bSJan Lentfer 				error("%s", "making qname");
822825eb42bSJan Lentfer 			}
823825eb42bSJan Lentfer 			status = ldns_resolver_prepare_query_pkt(&qpkt, res, qname, type, clas, qflags);
824825eb42bSJan Lentfer 			if(status != LDNS_STATUS_OK) {
825825eb42bSJan Lentfer 				error("%s", "making query: %s",
826825eb42bSJan Lentfer 					ldns_get_errorstr_by_id(status));
827825eb42bSJan Lentfer 			}
828825eb42bSJan Lentfer 			dump_hex(qpkt, query_file);
829825eb42bSJan Lentfer 			ldns_pkt_free(qpkt);
830825eb42bSJan Lentfer 			break;
831825eb42bSJan Lentfer 		case DRILL_NSEC:
832825eb42bSJan Lentfer 			break;
833825eb42bSJan Lentfer 		case DRILL_QUERY:
834825eb42bSJan Lentfer 		default:
835825eb42bSJan Lentfer 			if (query_file) {
836825eb42bSJan Lentfer 				/* this old way, the query packet needed
837825eb42bSJan Lentfer 				   to be parseable, but we want to be able
838825eb42bSJan Lentfer 				   to send mangled packets, so we need
839825eb42bSJan Lentfer 				   to do it directly */
840825eb42bSJan Lentfer 				#if 0
841825eb42bSJan Lentfer 				qpkt = read_hex_pkt(query_file);
842825eb42bSJan Lentfer 				if (qpkt) {
843825eb42bSJan Lentfer 					status = ldns_resolver_send_pkt(&pkt, res, qpkt);
844825eb42bSJan Lentfer 					if (status != LDNS_STATUS_OK) {
845825eb42bSJan Lentfer 						printf("Error: %s\n", ldns_get_errorstr_by_id(status));
846825eb42bSJan Lentfer 						exit(1);
847825eb42bSJan Lentfer 					}
848825eb42bSJan Lentfer 				} else {
849825eb42bSJan Lentfer 					/* qpkt was bogus, reset pkt */
850825eb42bSJan Lentfer 					pkt = NULL;
851825eb42bSJan Lentfer 				}
852825eb42bSJan Lentfer 				#endif
853825eb42bSJan Lentfer 				query_buffer = read_hex_buffer(query_file);
854825eb42bSJan Lentfer 				if (query_buffer) {
855825eb42bSJan Lentfer 					status = ldns_send_buffer(&pkt, res, query_buffer, NULL);
856825eb42bSJan Lentfer 					ldns_buffer_free(query_buffer);
857825eb42bSJan Lentfer 					if (status != LDNS_STATUS_OK) {
858825eb42bSJan Lentfer 						printf("Error: %s\n", ldns_get_errorstr_by_id(status));
859825eb42bSJan Lentfer 						exit(1);
860825eb42bSJan Lentfer 					}
861825eb42bSJan Lentfer 				} else {
862825eb42bSJan Lentfer 					printf("NO BUFFER\n");
863825eb42bSJan Lentfer 					pkt = NULL;
864825eb42bSJan Lentfer 				}
865825eb42bSJan Lentfer 			} else {
866825eb42bSJan Lentfer 				qname = ldns_dname_new_frm_str(name);
867825eb42bSJan Lentfer 				if (!qname) {
868825eb42bSJan Lentfer 					error("%s", "error in making qname");
869825eb42bSJan Lentfer 				}
870825eb42bSJan Lentfer 
871825eb42bSJan Lentfer 				if (type == LDNS_RR_TYPE_AXFR) {
872825eb42bSJan Lentfer 					status = ldns_axfr_start(res, qname, clas);
873825eb42bSJan Lentfer 					if(status != LDNS_STATUS_OK) {
874825eb42bSJan Lentfer 						error("Error starting axfr: %s",
875825eb42bSJan Lentfer 							ldns_get_errorstr_by_id(status));
876825eb42bSJan Lentfer 					}
877825eb42bSJan Lentfer 					axfr_rr = ldns_axfr_next(res);
878825eb42bSJan Lentfer 					if(!axfr_rr) {
879825eb42bSJan Lentfer 						fprintf(stderr, "AXFR failed.\n");
880825eb42bSJan Lentfer 						ldns_pkt_print(stdout,
881825eb42bSJan Lentfer 							ldns_axfr_last_pkt(res));
882825eb42bSJan Lentfer 						goto exit;
883825eb42bSJan Lentfer 					}
884825eb42bSJan Lentfer 					while (axfr_rr) {
885825eb42bSJan Lentfer 						if (verbosity != -1) {
886825eb42bSJan Lentfer 							ldns_rr_print(stdout, axfr_rr);
887825eb42bSJan Lentfer 						}
888825eb42bSJan Lentfer 						ldns_rr_free(axfr_rr);
889825eb42bSJan Lentfer 						axfr_rr = ldns_axfr_next(res);
890825eb42bSJan Lentfer 					}
891825eb42bSJan Lentfer 
892825eb42bSJan Lentfer 					goto exit;
893825eb42bSJan Lentfer 				} else {
894825eb42bSJan Lentfer 					/* create a packet and set the RD flag on it */
8955340022aSzrj 					pkt = NULL;
896*ee791febSAntonio Huete Jimenez 
897*ee791febSAntonio Huete Jimenez 					status = ldns_resolver_prepare_query_pkt(&qpkt,
898*ee791febSAntonio Huete Jimenez 						res, qname, type, clas, qflags);
899*ee791febSAntonio Huete Jimenez 					if(status != LDNS_STATUS_OK) {
900*ee791febSAntonio Huete Jimenez 						error("%s", "making query: %s",
901*ee791febSAntonio Huete Jimenez 							ldns_get_errorstr_by_id(status));
902*ee791febSAntonio Huete Jimenez 					}
903*ee791febSAntonio Huete Jimenez 
904*ee791febSAntonio Huete Jimenez 					if (edns_list) {
905*ee791febSAntonio Huete Jimenez 						/* attach the structed EDNS options */
906*ee791febSAntonio Huete Jimenez 						ldns_pkt_set_edns_option_list(qpkt, edns_list);
907*ee791febSAntonio Huete Jimenez 					}
908*ee791febSAntonio Huete Jimenez 
909*ee791febSAntonio Huete Jimenez 					status = ldns_resolver_send_pkt(&pkt, res, qpkt);
910*ee791febSAntonio Huete Jimenez 					ldns_pkt_free(qpkt);
911*ee791febSAntonio Huete Jimenez 
9125340022aSzrj 					if (status != LDNS_STATUS_OK) {
9135340022aSzrj 						error("error sending query: %s"
9145340022aSzrj 						     , ldns_get_errorstr_by_id(
9155340022aSzrj 							     status));
9165340022aSzrj 					}
917825eb42bSJan Lentfer 				}
918825eb42bSJan Lentfer 			}
919825eb42bSJan Lentfer 
920*ee791febSAntonio Huete Jimenez 			/* now handling the response message/packet */
921825eb42bSJan Lentfer 			if (!pkt) {
922825eb42bSJan Lentfer 				mesg("No packet received");
923825eb42bSJan Lentfer 				result = EXIT_FAILURE;
924825eb42bSJan Lentfer 			} else {
925*ee791febSAntonio Huete Jimenez 				ldns_pkt_print_fmt(stdout, fmt, pkt);
926825eb42bSJan Lentfer 				if (verbosity != -1) {
927825eb42bSJan Lentfer 					if (ldns_pkt_tc(pkt)) {
928825eb42bSJan Lentfer 						fprintf(stdout,
929825eb42bSJan Lentfer 							"\n;; WARNING: The answer packet was truncated; you might want to\n");
930825eb42bSJan Lentfer 						fprintf(stdout,
931825eb42bSJan Lentfer 							";; query again with TCP (-t argument), or EDNS0 (-b for buffer size)\n");
932825eb42bSJan Lentfer 					}
933825eb42bSJan Lentfer 				}
934825eb42bSJan Lentfer 				if (qds) {
935825eb42bSJan Lentfer 					if (verbosity != -1) {
936825eb42bSJan Lentfer 						print_ds_of_keys(pkt);
937825eb42bSJan Lentfer 						printf("\n");
938825eb42bSJan Lentfer 					}
939825eb42bSJan Lentfer 				}
940825eb42bSJan Lentfer 
941825eb42bSJan Lentfer 				if (ldns_rr_list_rr_count(key_list) > 0) {
942825eb42bSJan Lentfer 					/* -k's were given on the cmd line */
943825eb42bSJan Lentfer 					ldns_rr_list *rrset_verified;
944825eb42bSJan Lentfer 					uint16_t key_count;
945825eb42bSJan Lentfer 
946825eb42bSJan Lentfer 					rrset_verified = ldns_pkt_rr_list_by_name_and_type(
947825eb42bSJan Lentfer 							pkt, qname, type,
948825eb42bSJan Lentfer 							LDNS_SECTION_ANY_NOQUESTION);
949825eb42bSJan Lentfer 
950825eb42bSJan Lentfer 					if (type == LDNS_RR_TYPE_ANY) {
951825eb42bSJan Lentfer 						/* don't verify this */
952825eb42bSJan Lentfer 						break;
953825eb42bSJan Lentfer 					}
954825eb42bSJan Lentfer 
955825eb42bSJan Lentfer 					if (verbosity != -1) {
956825eb42bSJan Lentfer 						printf("; ");
957825eb42bSJan Lentfer 						ldns_rr_list_print(stdout, rrset_verified);
958825eb42bSJan Lentfer 					}
959825eb42bSJan Lentfer 
960825eb42bSJan Lentfer 					/* verify */
961825eb42bSJan Lentfer #ifdef HAVE_SSL
962825eb42bSJan Lentfer 					key_verified = ldns_rr_list_new();
963825eb42bSJan Lentfer 					result = ldns_pkt_verify(pkt, type, qname, key_list, NULL, key_verified);
964825eb42bSJan Lentfer 
965825eb42bSJan Lentfer 					if (result == LDNS_STATUS_ERR) {
966825eb42bSJan Lentfer 						/* is the existence denied then? */
967825eb42bSJan Lentfer 						result = ldns_verify_denial(pkt, qname, type, NULL, NULL);
968825eb42bSJan Lentfer 						if (result == LDNS_STATUS_OK) {
969825eb42bSJan Lentfer 							if (verbosity != -1) {
970825eb42bSJan Lentfer 								printf("Existence denied for ");
971825eb42bSJan Lentfer 								ldns_rdf_print(stdout, qname);
972825eb42bSJan Lentfer 								type_str = ldns_rr_type2str(type);
973825eb42bSJan Lentfer 								printf("\t%s\n", type_str);
974825eb42bSJan Lentfer 								LDNS_FREE(type_str);
975825eb42bSJan Lentfer 							}
976825eb42bSJan Lentfer 						} else {
977825eb42bSJan Lentfer 							if (verbosity != -1) {
978825eb42bSJan Lentfer 								printf("Bad data; RR for name and "
979825eb42bSJan Lentfer 								       "type not found or failed to "
980825eb42bSJan Lentfer 								       "verify, and denial of "
981825eb42bSJan Lentfer 								       "existence failed.\n");
982825eb42bSJan Lentfer 							}
983825eb42bSJan Lentfer 						}
984825eb42bSJan Lentfer 					} else if (result == LDNS_STATUS_OK) {
985825eb42bSJan Lentfer 						for(key_count = 0; key_count < ldns_rr_list_rr_count(key_verified);
986825eb42bSJan Lentfer 								key_count++) {
987825eb42bSJan Lentfer 							if (verbosity != -1) {
988fd185f4dSJan Lentfer 								printf("; VALIDATED by id = %u, owner = ",
989fd185f4dSJan Lentfer 										(unsigned int)ldns_calc_keytag(
990825eb42bSJan Lentfer 												      ldns_rr_list_rr(key_verified, key_count)));
991825eb42bSJan Lentfer 								ldns_rdf_print(stdout, ldns_rr_owner(
992825eb42bSJan Lentfer 											ldns_rr_list_rr(key_list, key_count)));
993825eb42bSJan Lentfer 								printf("\n");
994825eb42bSJan Lentfer 							}
995825eb42bSJan Lentfer 						}
996825eb42bSJan Lentfer 					} else {
997825eb42bSJan Lentfer 						for(key_count = 0; key_count < ldns_rr_list_rr_count(key_list);
998825eb42bSJan Lentfer 								key_count++) {
999825eb42bSJan Lentfer 							if (verbosity != -1) {
1000fd185f4dSJan Lentfer 								printf("; %s for id = %u, owner = ",
1001825eb42bSJan Lentfer 								       ldns_get_errorstr_by_id(result),
1002fd185f4dSJan Lentfer 								       (unsigned int)ldns_calc_keytag(
1003825eb42bSJan Lentfer 												      ldns_rr_list_rr(key_list, key_count)));
1004825eb42bSJan Lentfer 								ldns_rdf_print(stdout, ldns_rr_owner(
1005825eb42bSJan Lentfer 
1006825eb42bSJan Lentfer 								ldns_rr_list_rr(key_list,
1007825eb42bSJan Lentfer 								key_count)));
1008825eb42bSJan Lentfer 								printf("\n");
1009825eb42bSJan Lentfer 							}
1010825eb42bSJan Lentfer 						}
1011825eb42bSJan Lentfer 					}
1012825eb42bSJan Lentfer 					ldns_rr_list_free(key_verified);
1013825eb42bSJan Lentfer #else
1014825eb42bSJan Lentfer 					(void) key_count;
1015825eb42bSJan Lentfer #endif /* HAVE_SSL */
1016825eb42bSJan Lentfer 				}
1017825eb42bSJan Lentfer 				if (answer_file) {
1018825eb42bSJan Lentfer 					dump_hex(pkt, answer_file);
1019825eb42bSJan Lentfer 				}
1020825eb42bSJan Lentfer 				ldns_pkt_free(pkt);
1021825eb42bSJan Lentfer 			}
1022825eb42bSJan Lentfer 
1023825eb42bSJan Lentfer 			break;
1024825eb42bSJan Lentfer 	}
1025825eb42bSJan Lentfer 
1026825eb42bSJan Lentfer 	exit:
1027825eb42bSJan Lentfer 	ldns_rdf_deep_free(qname);
10285340022aSzrj 	ldns_rdf_deep_free(src_rdf);
1029825eb42bSJan Lentfer 	ldns_resolver_deep_free(res);
1030825eb42bSJan Lentfer 	ldns_resolver_deep_free(cmdline_res);
1031825eb42bSJan Lentfer 	ldns_rr_list_deep_free(key_list);
1032825eb42bSJan Lentfer 	ldns_rr_list_deep_free(cmdline_rr_list);
1033825eb42bSJan Lentfer 	ldns_rdf_deep_free(trace_start_name);
1034825eb42bSJan Lentfer 	xfree(progname);
1035825eb42bSJan Lentfer 	xfree(tsig_name);
1036825eb42bSJan Lentfer 	xfree(tsig_data);
1037825eb42bSJan Lentfer 	xfree(tsig_algorithm);
1038825eb42bSJan Lentfer 
1039825eb42bSJan Lentfer #ifdef HAVE_SSL
1040*ee791febSAntonio Huete Jimenez #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(HAVE_LIBRESSL)
1041*ee791febSAntonio Huete Jimenez #ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
1042825eb42bSJan Lentfer 	CRYPTO_cleanup_all_ex_data ();
1043*ee791febSAntonio Huete Jimenez #endif
1044*ee791febSAntonio Huete Jimenez #ifdef HAVE_ERR_FREE_STRINGS
1045825eb42bSJan Lentfer 	ERR_free_strings ();
1046*ee791febSAntonio Huete Jimenez #endif
1047*ee791febSAntonio Huete Jimenez #ifdef HAVE_EVP_CLEANUP
1048825eb42bSJan Lentfer 	EVP_cleanup ();
1049825eb42bSJan Lentfer #endif
1050*ee791febSAntonio Huete Jimenez #endif
1051*ee791febSAntonio Huete Jimenez #endif
1052825eb42bSJan Lentfer #ifdef USE_WINSOCK
1053825eb42bSJan Lentfer 	WSACleanup();
1054825eb42bSJan Lentfer #endif
1055825eb42bSJan Lentfer 
1056825eb42bSJan Lentfer 	return result;
1057825eb42bSJan Lentfer }
1058