xref: /minix3/external/bsd/bind/dist/lib/samples/sample-request.c (revision 00b67f09dd46474d133c95011a48590a8e8f94c7)
1*00b67f09SDavid van Moolenbroek /*	$NetBSD: sample-request.c,v 1.1.1.5 2015/07/08 15:38:07 christos Exp $	*/
2*00b67f09SDavid van Moolenbroek 
3*00b67f09SDavid van Moolenbroek /*
4*00b67f09SDavid van Moolenbroek  * Copyright (C) 2009, 2012-2015  Internet Systems Consortium, Inc. ("ISC")
5*00b67f09SDavid van Moolenbroek  *
6*00b67f09SDavid van Moolenbroek  * Permission to use, copy, modify, and/or distribute this software for any
7*00b67f09SDavid van Moolenbroek  * purpose with or without fee is hereby granted, provided that the above
8*00b67f09SDavid van Moolenbroek  * copyright notice and this permission notice appear in all copies.
9*00b67f09SDavid van Moolenbroek  *
10*00b67f09SDavid van Moolenbroek  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
11*00b67f09SDavid van Moolenbroek  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
12*00b67f09SDavid van Moolenbroek  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
13*00b67f09SDavid van Moolenbroek  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
14*00b67f09SDavid van Moolenbroek  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15*00b67f09SDavid van Moolenbroek  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16*00b67f09SDavid van Moolenbroek  * PERFORMANCE OF THIS SOFTWARE.
17*00b67f09SDavid van Moolenbroek  */
18*00b67f09SDavid van Moolenbroek 
19*00b67f09SDavid van Moolenbroek /* Id: sample-request.c,v 1.5 2009/09/29 15:06:07 fdupont Exp  */
20*00b67f09SDavid van Moolenbroek 
21*00b67f09SDavid van Moolenbroek #include <config.h>
22*00b67f09SDavid van Moolenbroek 
23*00b67f09SDavid van Moolenbroek #ifndef WIN32
24*00b67f09SDavid van Moolenbroek #include <sys/types.h>
25*00b67f09SDavid van Moolenbroek #include <sys/socket.h>
26*00b67f09SDavid van Moolenbroek 
27*00b67f09SDavid van Moolenbroek #include <netinet/in.h>
28*00b67f09SDavid van Moolenbroek 
29*00b67f09SDavid van Moolenbroek #include <arpa/inet.h>
30*00b67f09SDavid van Moolenbroek 
31*00b67f09SDavid van Moolenbroek #include <netdb.h>
32*00b67f09SDavid van Moolenbroek #include <unistd.h>
33*00b67f09SDavid van Moolenbroek #endif
34*00b67f09SDavid van Moolenbroek 
35*00b67f09SDavid van Moolenbroek #include <stdio.h>
36*00b67f09SDavid van Moolenbroek #include <stdlib.h>
37*00b67f09SDavid van Moolenbroek #include <string.h>
38*00b67f09SDavid van Moolenbroek 
39*00b67f09SDavid van Moolenbroek #include <isc/base64.h>
40*00b67f09SDavid van Moolenbroek #include <isc/buffer.h>
41*00b67f09SDavid van Moolenbroek #include <isc/commandline.h>
42*00b67f09SDavid van Moolenbroek #include <isc/lib.h>
43*00b67f09SDavid van Moolenbroek #include <isc/mem.h>
44*00b67f09SDavid van Moolenbroek #include <isc/sockaddr.h>
45*00b67f09SDavid van Moolenbroek #include <isc/util.h>
46*00b67f09SDavid van Moolenbroek 
47*00b67f09SDavid van Moolenbroek #include <dns/client.h>
48*00b67f09SDavid van Moolenbroek #include <dns/fixedname.h>
49*00b67f09SDavid van Moolenbroek #include <dns/keyvalues.h>
50*00b67f09SDavid van Moolenbroek #include <dns/lib.h>
51*00b67f09SDavid van Moolenbroek #include <dns/masterdump.h>
52*00b67f09SDavid van Moolenbroek #include <dns/message.h>
53*00b67f09SDavid van Moolenbroek #include <dns/name.h>
54*00b67f09SDavid van Moolenbroek #include <dns/rdata.h>
55*00b67f09SDavid van Moolenbroek #include <dns/rdataset.h>
56*00b67f09SDavid van Moolenbroek #include <dns/rdatastruct.h>
57*00b67f09SDavid van Moolenbroek #include <dns/rdatatype.h>
58*00b67f09SDavid van Moolenbroek #include <dns/result.h>
59*00b67f09SDavid van Moolenbroek #include <dns/secalg.h>
60*00b67f09SDavid van Moolenbroek 
61*00b67f09SDavid van Moolenbroek #include <dst/dst.h>
62*00b67f09SDavid van Moolenbroek 
63*00b67f09SDavid van Moolenbroek static isc_mem_t *mctx;
64*00b67f09SDavid van Moolenbroek static dns_fixedname_t fixedqname;
65*00b67f09SDavid van Moolenbroek 
66*00b67f09SDavid van Moolenbroek ISC_PLATFORM_NORETURN_PRE static void
67*00b67f09SDavid van Moolenbroek usage(void) ISC_PLATFORM_NORETURN_POST;
68*00b67f09SDavid van Moolenbroek 
69*00b67f09SDavid van Moolenbroek static void
usage(void)70*00b67f09SDavid van Moolenbroek usage(void) {
71*00b67f09SDavid van Moolenbroek 	fprintf(stderr, "sample-request [-t RRtype] server_address hostname\n");
72*00b67f09SDavid van Moolenbroek 
73*00b67f09SDavid van Moolenbroek 	exit(1);
74*00b67f09SDavid van Moolenbroek }
75*00b67f09SDavid van Moolenbroek 
76*00b67f09SDavid van Moolenbroek static isc_result_t
make_querymessage(dns_message_t * message,const char * namestr,dns_rdatatype_t rdtype)77*00b67f09SDavid van Moolenbroek make_querymessage(dns_message_t *message, const char *namestr,
78*00b67f09SDavid van Moolenbroek 		  dns_rdatatype_t rdtype)
79*00b67f09SDavid van Moolenbroek {
80*00b67f09SDavid van Moolenbroek 	dns_name_t *qname = NULL, *qname0;
81*00b67f09SDavid van Moolenbroek 	dns_rdataset_t *qrdataset = NULL;
82*00b67f09SDavid van Moolenbroek 	isc_result_t result;
83*00b67f09SDavid van Moolenbroek 	isc_buffer_t b;
84*00b67f09SDavid van Moolenbroek 	unsigned int namelen;
85*00b67f09SDavid van Moolenbroek 
86*00b67f09SDavid van Moolenbroek 	REQUIRE(message != NULL);
87*00b67f09SDavid van Moolenbroek 	REQUIRE(namestr != NULL);
88*00b67f09SDavid van Moolenbroek 
89*00b67f09SDavid van Moolenbroek 	/* Construct qname */
90*00b67f09SDavid van Moolenbroek 	namelen = strlen(namestr);
91*00b67f09SDavid van Moolenbroek 	isc_buffer_constinit(&b, namestr, namelen);
92*00b67f09SDavid van Moolenbroek 	isc_buffer_add(&b, namelen);
93*00b67f09SDavid van Moolenbroek 	dns_fixedname_init(&fixedqname);
94*00b67f09SDavid van Moolenbroek 	qname0 = dns_fixedname_name(&fixedqname);
95*00b67f09SDavid van Moolenbroek 	result = dns_name_fromtext(qname0, &b, dns_rootname, 0, NULL);
96*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS) {
97*00b67f09SDavid van Moolenbroek 		fprintf(stderr, "failed to convert qname: %d\n", result);
98*00b67f09SDavid van Moolenbroek 		return (result);
99*00b67f09SDavid van Moolenbroek 	}
100*00b67f09SDavid van Moolenbroek 
101*00b67f09SDavid van Moolenbroek 	/* Construct query message */
102*00b67f09SDavid van Moolenbroek 	message->opcode = dns_opcode_query;
103*00b67f09SDavid van Moolenbroek 	message->rdclass = dns_rdataclass_in;
104*00b67f09SDavid van Moolenbroek 
105*00b67f09SDavid van Moolenbroek 	result = dns_message_gettempname(message, &qname);
106*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS)
107*00b67f09SDavid van Moolenbroek 		goto cleanup;
108*00b67f09SDavid van Moolenbroek 
109*00b67f09SDavid van Moolenbroek 	result = dns_message_gettemprdataset(message, &qrdataset);
110*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS)
111*00b67f09SDavid van Moolenbroek 		goto cleanup;
112*00b67f09SDavid van Moolenbroek 
113*00b67f09SDavid van Moolenbroek 	dns_name_init(qname, NULL);
114*00b67f09SDavid van Moolenbroek 	dns_name_clone(qname0, qname);
115*00b67f09SDavid van Moolenbroek 	dns_rdataset_makequestion(qrdataset, message->rdclass, rdtype);
116*00b67f09SDavid van Moolenbroek 	ISC_LIST_APPEND(qname->list, qrdataset, link);
117*00b67f09SDavid van Moolenbroek 	dns_message_addname(message, qname, DNS_SECTION_QUESTION);
118*00b67f09SDavid van Moolenbroek 
119*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
120*00b67f09SDavid van Moolenbroek 
121*00b67f09SDavid van Moolenbroek  cleanup:
122*00b67f09SDavid van Moolenbroek 	if (qname != NULL)
123*00b67f09SDavid van Moolenbroek 		dns_message_puttempname(message, &qname);
124*00b67f09SDavid van Moolenbroek 	if (qrdataset != NULL)
125*00b67f09SDavid van Moolenbroek 		dns_message_puttemprdataset(message, &qrdataset);
126*00b67f09SDavid van Moolenbroek 	dns_message_destroy(&message);
127*00b67f09SDavid van Moolenbroek 	return (result);
128*00b67f09SDavid van Moolenbroek }
129*00b67f09SDavid van Moolenbroek 
130*00b67f09SDavid van Moolenbroek static void
print_section(dns_message_t * message,int section,isc_buffer_t * buf)131*00b67f09SDavid van Moolenbroek print_section(dns_message_t *message, int section, isc_buffer_t *buf) {
132*00b67f09SDavid van Moolenbroek 	isc_result_t result;
133*00b67f09SDavid van Moolenbroek 	isc_region_t r;
134*00b67f09SDavid van Moolenbroek 
135*00b67f09SDavid van Moolenbroek 	result = dns_message_sectiontotext(message, section,
136*00b67f09SDavid van Moolenbroek 					   &dns_master_style_full, 0, buf);
137*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS)
138*00b67f09SDavid van Moolenbroek 		goto fail;
139*00b67f09SDavid van Moolenbroek 
140*00b67f09SDavid van Moolenbroek 	isc_buffer_usedregion(buf, &r);
141*00b67f09SDavid van Moolenbroek 	printf("%.*s", (int)r.length, (char *)r.base);
142*00b67f09SDavid van Moolenbroek 
143*00b67f09SDavid van Moolenbroek 	return;
144*00b67f09SDavid van Moolenbroek 
145*00b67f09SDavid van Moolenbroek  fail:
146*00b67f09SDavid van Moolenbroek 	fprintf(stderr, "failed to convert a section\n");
147*00b67f09SDavid van Moolenbroek }
148*00b67f09SDavid van Moolenbroek 
149*00b67f09SDavid van Moolenbroek int
main(int argc,char * argv[])150*00b67f09SDavid van Moolenbroek main(int argc, char *argv[]) {
151*00b67f09SDavid van Moolenbroek 	int ch, i, gai_error;
152*00b67f09SDavid van Moolenbroek 	struct addrinfo hints, *res;
153*00b67f09SDavid van Moolenbroek 	isc_textregion_t tr;
154*00b67f09SDavid van Moolenbroek 	dns_client_t *client = NULL;
155*00b67f09SDavid van Moolenbroek 	isc_result_t result;
156*00b67f09SDavid van Moolenbroek 	isc_sockaddr_t sa;
157*00b67f09SDavid van Moolenbroek 	dns_message_t *qmessage, *rmessage;
158*00b67f09SDavid van Moolenbroek 	dns_rdatatype_t type = dns_rdatatype_a;
159*00b67f09SDavid van Moolenbroek 	isc_buffer_t *outputbuf;
160*00b67f09SDavid van Moolenbroek 
161*00b67f09SDavid van Moolenbroek 	while ((ch = isc_commandline_parse(argc, argv, "t:")) != -1) {
162*00b67f09SDavid van Moolenbroek 		switch (ch) {
163*00b67f09SDavid van Moolenbroek 		case 't':
164*00b67f09SDavid van Moolenbroek 			tr.base = isc_commandline_argument;
165*00b67f09SDavid van Moolenbroek 			tr.length = strlen(isc_commandline_argument);
166*00b67f09SDavid van Moolenbroek 			result = dns_rdatatype_fromtext(&type, &tr);
167*00b67f09SDavid van Moolenbroek 			if (result != ISC_R_SUCCESS) {
168*00b67f09SDavid van Moolenbroek 				fprintf(stderr,
169*00b67f09SDavid van Moolenbroek 					"invalid RRtype: %s\n",
170*00b67f09SDavid van Moolenbroek 					isc_commandline_argument);
171*00b67f09SDavid van Moolenbroek 				exit(1);
172*00b67f09SDavid van Moolenbroek 			}
173*00b67f09SDavid van Moolenbroek 			break;
174*00b67f09SDavid van Moolenbroek 		default:
175*00b67f09SDavid van Moolenbroek 			usage();
176*00b67f09SDavid van Moolenbroek 		}
177*00b67f09SDavid van Moolenbroek 	}
178*00b67f09SDavid van Moolenbroek 
179*00b67f09SDavid van Moolenbroek 	argc -= isc_commandline_index;
180*00b67f09SDavid van Moolenbroek 	argv += isc_commandline_index;
181*00b67f09SDavid van Moolenbroek 	if (argc < 2)
182*00b67f09SDavid van Moolenbroek 		usage();
183*00b67f09SDavid van Moolenbroek 
184*00b67f09SDavid van Moolenbroek 	isc_lib_register();
185*00b67f09SDavid van Moolenbroek 	result = dns_lib_init();
186*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS) {
187*00b67f09SDavid van Moolenbroek 		fprintf(stderr, "dns_lib_init failed: %d\n", result);
188*00b67f09SDavid van Moolenbroek 		exit(1);
189*00b67f09SDavid van Moolenbroek 	}
190*00b67f09SDavid van Moolenbroek 
191*00b67f09SDavid van Moolenbroek 	result = dns_client_create(&client, 0);
192*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS) {
193*00b67f09SDavid van Moolenbroek 		fprintf(stderr, "dns_client_create failed: %d\n", result);
194*00b67f09SDavid van Moolenbroek 		exit(1);
195*00b67f09SDavid van Moolenbroek 	}
196*00b67f09SDavid van Moolenbroek 
197*00b67f09SDavid van Moolenbroek 	/* Prepare message structures */
198*00b67f09SDavid van Moolenbroek 	mctx = NULL;
199*00b67f09SDavid van Moolenbroek 	qmessage = NULL;
200*00b67f09SDavid van Moolenbroek 	rmessage = NULL;
201*00b67f09SDavid van Moolenbroek 
202*00b67f09SDavid van Moolenbroek 	result = isc_mem_create(0, 0, &mctx);
203*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS) {
204*00b67f09SDavid van Moolenbroek 		fprintf(stderr, "failed to create a memory context\n");
205*00b67f09SDavid van Moolenbroek 		exit(1);
206*00b67f09SDavid van Moolenbroek 	}
207*00b67f09SDavid van Moolenbroek 	result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &qmessage);
208*00b67f09SDavid van Moolenbroek 	if (result == ISC_R_SUCCESS) {
209*00b67f09SDavid van Moolenbroek 		result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE,
210*00b67f09SDavid van Moolenbroek 					    &rmessage);
211*00b67f09SDavid van Moolenbroek 	}
212*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS) {
213*00b67f09SDavid van Moolenbroek 		fprintf(stderr, "failed to create messages\n");
214*00b67f09SDavid van Moolenbroek 		exit(1);
215*00b67f09SDavid van Moolenbroek 	}
216*00b67f09SDavid van Moolenbroek 
217*00b67f09SDavid van Moolenbroek 	/* Initialize the nameserver address */
218*00b67f09SDavid van Moolenbroek 	memset(&hints, 0, sizeof(hints));
219*00b67f09SDavid van Moolenbroek 	hints.ai_family = AF_UNSPEC;
220*00b67f09SDavid van Moolenbroek 	hints.ai_socktype = SOCK_DGRAM;
221*00b67f09SDavid van Moolenbroek 	hints.ai_protocol = IPPROTO_UDP;
222*00b67f09SDavid van Moolenbroek #ifdef AI_NUMERICHOST
223*00b67f09SDavid van Moolenbroek 	hints.ai_flags = AI_NUMERICHOST;
224*00b67f09SDavid van Moolenbroek #endif
225*00b67f09SDavid van Moolenbroek 	gai_error = getaddrinfo(argv[0], "53", &hints, &res);
226*00b67f09SDavid van Moolenbroek 	if (gai_error != 0) {
227*00b67f09SDavid van Moolenbroek 		fprintf(stderr, "getaddrinfo failed: %s\n",
228*00b67f09SDavid van Moolenbroek 			gai_strerror(gai_error));
229*00b67f09SDavid van Moolenbroek 		exit(1);
230*00b67f09SDavid van Moolenbroek 	}
231*00b67f09SDavid van Moolenbroek 	INSIST(res->ai_addrlen <= sizeof(sa.type));
232*00b67f09SDavid van Moolenbroek 	memmove(&sa.type, res->ai_addr, res->ai_addrlen);
233*00b67f09SDavid van Moolenbroek 	freeaddrinfo(res);
234*00b67f09SDavid van Moolenbroek 	sa.length = (unsigned int)res->ai_addrlen;
235*00b67f09SDavid van Moolenbroek 	ISC_LINK_INIT(&sa, link);
236*00b67f09SDavid van Moolenbroek 
237*00b67f09SDavid van Moolenbroek 	/* Construct qname */
238*00b67f09SDavid van Moolenbroek 	result = make_querymessage(qmessage, argv[1], type);
239*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS) {
240*00b67f09SDavid van Moolenbroek 		fprintf(stderr, "failed to create a query\n");
241*00b67f09SDavid van Moolenbroek 		exit(1);
242*00b67f09SDavid van Moolenbroek 	}
243*00b67f09SDavid van Moolenbroek 
244*00b67f09SDavid van Moolenbroek 	/* Send request and wait for a response */
245*00b67f09SDavid van Moolenbroek 	result = dns_client_request(client, qmessage, rmessage, &sa, 0, 0,
246*00b67f09SDavid van Moolenbroek 				    NULL, 60, 0, 3);
247*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS) {
248*00b67f09SDavid van Moolenbroek 		fprintf(stderr, "failed to get a response: %s\n",
249*00b67f09SDavid van Moolenbroek 			dns_result_totext(result));
250*00b67f09SDavid van Moolenbroek 	}
251*00b67f09SDavid van Moolenbroek 
252*00b67f09SDavid van Moolenbroek 	/* Dump the response */
253*00b67f09SDavid van Moolenbroek 	outputbuf = NULL;
254*00b67f09SDavid van Moolenbroek 	result = isc_buffer_allocate(mctx, &outputbuf, 65535);
255*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS) {
256*00b67f09SDavid van Moolenbroek 		fprintf(stderr, "failed to allocate a result buffer\n");
257*00b67f09SDavid van Moolenbroek 		exit(1);
258*00b67f09SDavid van Moolenbroek 	}
259*00b67f09SDavid van Moolenbroek 	for (i = 0; i < DNS_SECTION_MAX; i++) {
260*00b67f09SDavid van Moolenbroek 		print_section(rmessage, i, outputbuf);
261*00b67f09SDavid van Moolenbroek 		isc_buffer_clear(outputbuf);
262*00b67f09SDavid van Moolenbroek 	}
263*00b67f09SDavid van Moolenbroek 	isc_buffer_free(&outputbuf);
264*00b67f09SDavid van Moolenbroek 
265*00b67f09SDavid van Moolenbroek 	/* Cleanup */
266*00b67f09SDavid van Moolenbroek 	dns_message_destroy(&qmessage);
267*00b67f09SDavid van Moolenbroek 	dns_message_destroy(&rmessage);
268*00b67f09SDavid van Moolenbroek 	isc_mem_destroy(&mctx);
269*00b67f09SDavid van Moolenbroek 	dns_client_destroy(&client);
270*00b67f09SDavid van Moolenbroek 	dns_lib_shutdown();
271*00b67f09SDavid van Moolenbroek 
272*00b67f09SDavid van Moolenbroek 	return (0);
273*00b67f09SDavid van Moolenbroek }
274