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.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>
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>
60 printdata(dns_rdataset_t
*rdataset
, dns_name_t
*owner
) {
66 if (!dns_rdataset_isassociated(rdataset
)) {
67 printf("[WARN: empty]\n");
68 return (ISC_R_SUCCESS
);
71 isc_buffer_init(&target
, t
, sizeof(t
));
73 result
= dns_rdataset_totext(rdataset
, owner
, ISC_FALSE
, ISC_FALSE
,
75 if (result
!= ISC_R_SUCCESS
)
77 isc_buffer_usedregion(&target
, &r
);
78 printf("%.*s", (int)r
.length
, (char *)r
.base
);
80 return (ISC_R_SUCCESS
);
83 ISC_PLATFORM_NORETURN_PRE
static void
84 usage(void) ISC_PLATFORM_NORETURN_POST
;
88 fprintf(stderr
, "sample [-t RRtype] "
89 "[[-a algorithm] [-e] -k keyname -K keystring] "
90 "[-s domain:serveraddr_for_domain ] "
91 "server_address hostname\n");
97 set_key(dns_client_t
*client
, char *keynamestr
, char *keystr
,
98 isc_boolean_t is_sep
, isc_mem_t
**mctxp
)
101 dns_fixedname_t fkeyname
;
104 dns_rdata_dnskey_t keystruct
;
105 unsigned char keydata
[4096];
106 isc_buffer_t keydatabuf
;
107 unsigned char rrdata
[4096];
108 isc_buffer_t rrdatabuf
;
114 result
= isc_mem_create(0, 0, mctxp
);
115 if (result
!= ISC_R_SUCCESS
) {
116 fprintf(stderr
, "failed to crate mctx\n");
120 if (algname
!= NULL
) {
122 tr
.length
= strlen(algname
);
123 result
= dns_secalg_fromtext(&alg
, &tr
);
124 if (result
!= ISC_R_SUCCESS
) {
125 fprintf(stderr
, "failed to identify the algorithm\n");
129 alg
= DNS_KEYALG_RSASHA1
;
131 keystruct
.common
.rdclass
= dns_rdataclass_in
;
132 keystruct
.common
.rdtype
= dns_rdatatype_dnskey
;
133 keystruct
.flags
= DNS_KEYOWNER_ZONE
; /* fixed */
135 keystruct
.flags
|= DNS_KEYFLAG_KSK
;
136 keystruct
.protocol
= DNS_KEYPROTO_DNSSEC
; /* fixed */
137 keystruct
.algorithm
= alg
;
139 isc_buffer_init(&keydatabuf
, keydata
, sizeof(keydata
));
140 isc_buffer_init(&rrdatabuf
, rrdata
, sizeof(rrdata
));
141 result
= isc_base64_decodestring(keystr
, &keydatabuf
);
142 if (result
!= ISC_R_SUCCESS
) {
143 fprintf(stderr
, "base64 decode failed\n");
146 isc_buffer_usedregion(&keydatabuf
, &r
);
147 keystruct
.datalen
= r
.length
;
148 keystruct
.data
= r
.base
;
150 result
= dns_rdata_fromstruct(NULL
, keystruct
.common
.rdclass
,
151 keystruct
.common
.rdtype
,
152 &keystruct
, &rrdatabuf
);
153 if (result
!= ISC_R_SUCCESS
) {
154 fprintf(stderr
, "failed to construct key rdata\n");
157 namelen
= strlen(keynamestr
);
158 isc_buffer_init(&b
, keynamestr
, namelen
);
159 isc_buffer_add(&b
, namelen
);
160 dns_fixedname_init(&fkeyname
);
161 keyname
= dns_fixedname_name(&fkeyname
);
162 result
= dns_name_fromtext(keyname
, &b
, dns_rootname
, 0, NULL
);
163 if (result
!= ISC_R_SUCCESS
) {
164 fprintf(stderr
, "failed to construct key name\n");
167 result
= dns_client_addtrustedkey(client
, dns_rdataclass_in
,
168 keyname
, &rrdatabuf
);
169 if (result
!= ISC_R_SUCCESS
) {
170 fprintf(stderr
, "failed to add key for %s\n",
177 addserver(dns_client_t
*client
, const char *addrstr
, const char *namespace) {
178 struct addrinfo hints
, *res
;
181 isc_sockaddrlist_t servers
;
185 dns_fixedname_t fname
;
186 dns_name_t
*name
= NULL
;
188 memset(&hints
, 0, sizeof(hints
));
189 hints
.ai_family
= AF_UNSPEC
;
190 hints
.ai_socktype
= SOCK_DGRAM
;
191 hints
.ai_protocol
= IPPROTO_UDP
;
192 hints
.ai_flags
= AI_NUMERICHOST
;
193 gai_error
= getaddrinfo(addrstr
, "53", &hints
, &res
);
194 if (gai_error
!= 0) {
195 fprintf(stderr
, "getaddrinfo failed: %s\n",
196 gai_strerror(gai_error
));
199 INSIST(res
->ai_addrlen
<= sizeof(sa
.type
));
200 memcpy(&sa
.type
, res
->ai_addr
, res
->ai_addrlen
);
202 sa
.length
= res
->ai_addrlen
;
203 ISC_LINK_INIT(&sa
, link
);
204 ISC_LIST_INIT(servers
);
205 ISC_LIST_APPEND(servers
, &sa
, link
);
207 if (namespace != NULL
) {
208 namelen
= strlen(namespace);
209 isc_buffer_init(&b
, namespace, namelen
);
210 isc_buffer_add(&b
, namelen
);
211 dns_fixedname_init(&fname
);
212 name
= dns_fixedname_name(&fname
);
213 result
= dns_name_fromtext(name
, &b
, dns_rootname
, 0, NULL
);
214 if (result
!= ISC_R_SUCCESS
) {
215 fprintf(stderr
, "failed to convert qname: %d\n",
221 result
= dns_client_setservers(client
, dns_rdataclass_in
, name
,
223 if (result
!= ISC_R_SUCCESS
) {
224 fprintf(stderr
, "set server failed: %d\n", result
);
230 main(int argc
, char *argv
[]) {
233 char *altserver
= NULL
;
234 char *altserveraddr
= NULL
;
235 char *altservername
= NULL
;
236 dns_client_t
*client
= NULL
;
237 char *keynamestr
= NULL
;
241 dns_fixedname_t qname0
;
243 dns_name_t
*qname
, *name
;
244 dns_rdatatype_t type
= dns_rdatatype_a
;
245 dns_rdataset_t
*rdataset
;
246 dns_namelist_t namelist
;
247 isc_mem_t
*keymctx
= NULL
;
248 unsigned int clientopt
, resopt
;
249 isc_boolean_t is_sep
= ISC_FALSE
;
251 while ((ch
= getopt(argc
, argv
, "a:es:t:k:K:")) != -1) {
255 tr
.length
= strlen(optarg
);
256 result
= dns_rdatatype_fromtext(&type
, &tr
);
257 if (result
!= ISC_R_SUCCESS
) {
259 "invalid RRtype: %s\n", optarg
);
270 if (altserver
!= NULL
) {
271 fprintf(stderr
, "alternate server "
272 "already defined: %s\n",
294 if (altserver
!= NULL
) {
297 cp
= strchr(altserver
, ':');
299 fprintf(stderr
, "invalid alternate server: %s\n",
304 altservername
= altserver
;
305 altserveraddr
= cp
+ 1;
309 result
= dns_lib_init();
310 if (result
!= ISC_R_SUCCESS
) {
311 fprintf(stderr
, "dns_lib_init failed: %d\n", result
);
316 result
= dns_client_create(&client
, clientopt
);
317 if (result
!= ISC_R_SUCCESS
) {
318 fprintf(stderr
, "dns_client_create failed: %d\n", result
);
322 /* Set the nameserver */
323 addserver(client
, argv
[0], NULL
);
325 /* Set the alternate nameserver (when specified) */
326 if (altserver
!= NULL
)
327 addserver(client
, altserveraddr
, altservername
);
329 /* Install DNSSEC key (if given) */
330 if (keynamestr
!= NULL
) {
331 if (keystr
== NULL
) {
333 "key string is missing "
334 "while key name is provided\n");
337 set_key(client
, keynamestr
, keystr
, is_sep
, &keymctx
);
340 /* Construct qname */
341 namelen
= strlen(argv
[1]);
342 isc_buffer_init(&b
, argv
[1], namelen
);
343 isc_buffer_add(&b
, namelen
);
344 dns_fixedname_init(&qname0
);
345 qname
= dns_fixedname_name(&qname0
);
346 result
= dns_name_fromtext(qname
, &b
, dns_rootname
, 0, NULL
);
347 if (result
!= ISC_R_SUCCESS
)
348 fprintf(stderr
, "failed to convert qname: %d\n", result
);
350 /* Perform resolution */
352 if (keynamestr
== NULL
)
353 resopt
|= DNS_CLIENTRESOPT_NODNSSEC
;
354 ISC_LIST_INIT(namelist
);
355 result
= dns_client_resolve(client
, qname
, dns_rdataclass_in
, type
,
357 if (result
!= ISC_R_SUCCESS
) {
359 "resolution failed: %s\n", dns_result_totext(result
));
361 for (name
= ISC_LIST_HEAD(namelist
); name
!= NULL
;
362 name
= ISC_LIST_NEXT(name
, link
)) {
363 for (rdataset
= ISC_LIST_HEAD(name
->list
);
365 rdataset
= ISC_LIST_NEXT(rdataset
, link
)) {
366 if (printdata(rdataset
, name
) != ISC_R_SUCCESS
)
367 fprintf(stderr
, "print data failed\n");
371 dns_client_freeresanswer(client
, &namelist
);
374 dns_client_destroy(&client
);
375 if (keynamestr
!= NULL
)
376 isc_mem_destroy(&keymctx
);