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 */
23 #include <sys/types.h>
24 #include <sys/socket.h>
26 #include <netinet/in.h>
28 #include <arpa/inet.h>
36 #include <isc/base64.h>
37 #include <isc/buffer.h>
40 #include <isc/sockaddr.h>
43 #include <dns/client.h>
44 #include <dns/fixedname.h>
45 #include <dns/keyvalues.h>
47 #include <dns/masterdump.h>
48 #include <dns/message.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>
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
;
67 fprintf(stderr
, "sample-request [-t RRtype] server_address hostname\n");
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
;
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
);
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
)
102 result
= dns_message_gettemprdataset(message
, &qrdataset
);
103 if (result
!= ISC_R_SUCCESS
)
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
);
117 dns_message_puttempname(message
, &qname
);
118 if (qrdataset
!= NULL
)
119 dns_message_puttemprdataset(message
, &qrdataset
);
121 dns_message_destroy(&message
);
126 print_section(dns_message_t
*message
, int section
, isc_buffer_t
*buf
) {
130 result
= dns_message_sectiontotext(message
, section
,
131 &dns_master_style_full
, 0, buf
);
132 if (result
!= ISC_R_SUCCESS
)
135 isc_buffer_usedregion(buf
, &r
);
136 printf("%.*s", (int)r
.length
, (char *)r
.base
);
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
;
149 dns_client_t
*client
= NULL
;
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) {
160 tr
.length
= strlen(optarg
);
161 result
= dns_rdatatype_fromtext(&type
, &tr
);
162 if (result
!= ISC_R_SUCCESS
) {
164 "invalid RRtype: %s\n", optarg
);
179 result
= dns_lib_init();
180 if (result
!= ISC_R_SUCCESS
) {
181 fprintf(stderr
, "dns_lib_init failed: %d\n", result
);
185 result
= dns_client_create(&client
, 0);
186 if (result
!= ISC_R_SUCCESS
) {
187 fprintf(stderr
, "dns_client_create failed: %d\n", result
);
191 /* Prepare message structures */
196 result
= isc_mem_create(0, 0, &mctx
);
197 if (result
!= ISC_R_SUCCESS
) {
198 fprintf(stderr
, "failed to create a memory context\n");
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
,
206 if (result
!= ISC_R_SUCCESS
) {
207 fprintf(stderr
, "failed to create messages\n");
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
));
223 INSIST(res
->ai_addrlen
<= sizeof(sa
.type
));
224 memcpy(&sa
.type
, res
->ai_addr
, res
->ai_addrlen
);
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");
236 /* Send request and wait for a response */
237 result
= dns_client_request(client
, qmessage
, rmessage
, &sa
, 0, 0,
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 */
246 result
= isc_buffer_allocate(mctx
, &outputbuf
, 65535);
247 if (result
!= ISC_R_SUCCESS
) {
248 fprintf(stderr
, "failed to allocate a result buffer\n");
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
);
258 dns_message_destroy(&qmessage
);
259 dns_message_destroy(&rmessage
);
260 isc_mem_destroy(&mctx
);
261 dns_client_destroy(&client
);