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