PageRenderTime 77ms CodeModel.GetById 34ms app.highlight 38ms RepoModel.GetById 1ms app.codeStats 0ms

/contrib/bind9/lib/export/samples/sample-request.c

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