1/* 2 * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC") 3 * Copyright (C) 2000, 2001 Internet Software Consortium. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15 * PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18/* $Id: sig0_test.c,v 1.19 2009/09/02 23:48:01 tbox Exp $ */ 19 20#include <config.h> 21 22#include <stddef.h> 23#include <stdlib.h> 24#include <string.h> 25 26#include <isc/app.h> 27#include <isc/boolean.h> 28#include <isc/assertions.h> 29#include <isc/commandline.h> 30#include <isc/entropy.h> 31#include <isc/error.h> 32#include <isc/log.h> 33#include <isc/mem.h> 34#include <isc/mutex.h> 35#include <isc/net.h> 36#include <isc/task.h> 37#include <isc/timer.h> 38#include <isc/socket.h> 39#include <isc/util.h> 40 41#include <dns/dnssec.h> 42#include <dns/events.h> 43#include <dns/fixedname.h> 44#include <dns/keyvalues.h> 45#include <dns/masterdump.h> 46#include <dns/message.h> 47#include <dns/name.h> 48#include <dns/rdataset.h> 49#include <dns/resolver.h> 50#include <dns/result.h> 51#include <dns/types.h> 52 53#include <dst/result.h> 54#include <dst/dst.h> 55 56#define CHECK(str, x) { \ 57 if ((x) != ISC_R_SUCCESS) { \ 58 printf("%s: %s\n", (str), isc_result_totext(x)); \ 59 exit(-1); \ 60 } \ 61} 62 63isc_mutex_t lock; 64dst_key_t *key; 65isc_mem_t *mctx; 66unsigned char qdata[1024], rdata[1024]; 67isc_buffer_t qbuffer, rbuffer; 68isc_taskmgr_t *taskmgr; 69isc_entropy_t *ent = NULL; 70isc_task_t *task1; 71isc_log_t *lctx = NULL; 72isc_logconfig_t *logconfig = NULL; 73isc_socket_t *s; 74isc_sockaddr_t address; 75char output[10 * 1024]; 76isc_buffer_t outbuf; 77static const dns_master_style_t *style = &dns_master_style_debug; 78 79static void 80senddone(isc_task_t *task, isc_event_t *event) { 81 isc_socketevent_t *sevent = (isc_socketevent_t *)event; 82 83 REQUIRE(sevent != NULL); 84 REQUIRE(sevent->ev_type == ISC_SOCKEVENT_SENDDONE); 85 REQUIRE(task == task1); 86 87 printf("senddone\n"); 88 89 isc_event_free(&event); 90} 91 92static void 93recvdone(isc_task_t *task, isc_event_t *event) { 94 isc_socketevent_t *sevent = (isc_socketevent_t *)event; 95 isc_buffer_t source; 96 isc_result_t result; 97 dns_message_t *response; 98 99 REQUIRE(sevent != NULL); 100 REQUIRE(sevent->ev_type == ISC_SOCKEVENT_RECVDONE); 101 REQUIRE(task == task1); 102 103 printf("recvdone\n"); 104 if (sevent->result != ISC_R_SUCCESS) { 105 printf("failed\n"); 106 exit(-1); 107 } 108 109 isc_buffer_init(&source, sevent->region.base, sevent->region.length); 110 isc_buffer_add(&source, sevent->n); 111 112 response = NULL; 113 result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &response); 114 CHECK("dns_message_create", result); 115 result = dns_message_parse(response, &source, 0); 116 CHECK("dns_message_parse", result); 117 118 isc_buffer_init(&outbuf, output, sizeof(output)); 119 result = dns_message_totext(response, style, 0, &outbuf); 120 CHECK("dns_message_totext", result); 121 printf("%.*s\n", (int)isc_buffer_usedlength(&outbuf), 122 (char *)isc_buffer_base(&outbuf)); 123 124 dns_message_destroy(&response); 125 isc_event_free(&event); 126 127 isc_app_shutdown(); 128} 129 130static void 131buildquery(void) { 132 isc_result_t result; 133 dns_rdataset_t *question = NULL; 134 dns_name_t *qname = NULL; 135 isc_region_t r, inr; 136 dns_message_t *query; 137 char nametext[] = "host.example"; 138 isc_buffer_t namesrc, namedst; 139 unsigned char namedata[256]; 140 isc_sockaddr_t sa; 141 dns_compress_t cctx; 142 143 query = NULL; 144 result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &query); 145 CHECK("dns_message_create", result); 146 result = dns_message_setsig0key(query, key); 147 CHECK("dns_message_setsig0key", result); 148 149 result = dns_message_gettemprdataset(query, &question); 150 CHECK("dns_message_gettemprdataset", result); 151 dns_rdataset_init(question); 152 dns_rdataset_makequestion(question, dns_rdataclass_in, 153 dns_rdatatype_a); 154 result = dns_message_gettempname(query, &qname); 155 CHECK("dns_message_gettempname", result); 156 isc_buffer_init(&namesrc, nametext, strlen(nametext)); 157 isc_buffer_add(&namesrc, strlen(nametext)); 158 isc_buffer_init(&namedst, namedata, sizeof(namedata)); 159 dns_name_init(qname, NULL); 160 result = dns_name_fromtext(qname, &namesrc, dns_rootname, 0, &namedst); 161 CHECK("dns_name_fromtext", result); 162 ISC_LIST_APPEND(qname->list, question, link); 163 dns_message_addname(query, qname, DNS_SECTION_QUESTION); 164 165 isc_buffer_init(&qbuffer, qdata, sizeof(qdata)); 166 167 result = dns_compress_init(&cctx, -1, mctx); 168 CHECK("dns_compress_init", result); 169 result = dns_message_renderbegin(query, &cctx, &qbuffer); 170 CHECK("dns_message_renderbegin", result); 171 result = dns_message_rendersection(query, DNS_SECTION_QUESTION, 0); 172 CHECK("dns_message_rendersection(question)", result); 173 result = dns_message_rendersection(query, DNS_SECTION_ANSWER, 0); 174 CHECK("dns_message_rendersection(answer)", result); 175 result = dns_message_rendersection(query, DNS_SECTION_AUTHORITY, 0); 176 CHECK("dns_message_rendersection(auth)", result); 177 result = dns_message_rendersection(query, DNS_SECTION_ADDITIONAL, 0); 178 CHECK("dns_message_rendersection(add)", result); 179 result = dns_message_renderend(query); 180 CHECK("dns_message_renderend", result); 181 dns_compress_invalidate(&cctx); 182 183 isc_buffer_init(&outbuf, output, sizeof(output)); 184 result = dns_message_totext(query, style, 0, &outbuf); 185 CHECK("dns_message_totext", result); 186 printf("%.*s\n", (int)isc_buffer_usedlength(&outbuf), 187 (char *)isc_buffer_base(&outbuf)); 188 189 isc_buffer_usedregion(&qbuffer, &r); 190 isc_sockaddr_any(&sa); 191 result = isc_socket_bind(s, &sa, 0); 192 CHECK("isc_socket_bind", result); 193 result = isc_socket_sendto(s, &r, task1, senddone, NULL, &address, 194 NULL); 195 CHECK("isc_socket_sendto", result); 196 197 inr.base = rdata; 198 inr.length = sizeof(rdata); 199 result = isc_socket_recv(s, &inr, 1, task1, recvdone, NULL); 200 CHECK("isc_socket_recv", result); 201 dns_message_destroy(&query); 202} 203 204int 205main(int argc, char *argv[]) { 206 isc_boolean_t verbose = ISC_FALSE; 207 isc_socketmgr_t *socketmgr; 208 isc_timermgr_t *timermgr; 209 struct in_addr inaddr; 210 dns_fixedname_t fname; 211 dns_name_t *name; 212 isc_buffer_t b; 213 int ch; 214 isc_result_t result; 215 in_port_t port = 53; 216 217 RUNTIME_CHECK(isc_app_start() == ISC_R_SUCCESS); 218 219 RUNTIME_CHECK(isc_mutex_init(&lock) == ISC_R_SUCCESS); 220 221 mctx = NULL; 222 RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); 223 224 while ((ch = isc_commandline_parse(argc, argv, "vp:")) != -1) { 225 switch (ch) { 226 case 'v': 227 verbose = ISC_TRUE; 228 break; 229 case 'p': 230 port = (unsigned int)atoi(isc_commandline_argument); 231 break; 232 } 233 } 234 235 RUNTIME_CHECK(isc_entropy_create(mctx, &ent) == ISC_R_SUCCESS); 236 RUNTIME_CHECK(dst_lib_init(mctx, ent, 0) == ISC_R_SUCCESS); 237 238 dns_result_register(); 239 dst_result_register(); 240 241 taskmgr = NULL; 242 RUNTIME_CHECK(isc_taskmgr_create(mctx, 2, 0, &taskmgr) == 243 ISC_R_SUCCESS); 244 task1 = NULL; 245 RUNTIME_CHECK(isc_task_create(taskmgr, 0, &task1) == ISC_R_SUCCESS); 246 247 timermgr = NULL; 248 RUNTIME_CHECK(isc_timermgr_create(mctx, &timermgr) == ISC_R_SUCCESS); 249 socketmgr = NULL; 250 RUNTIME_CHECK(isc_socketmgr_create(mctx, &socketmgr) == ISC_R_SUCCESS); 251 252 RUNTIME_CHECK(isc_log_create(mctx, &lctx, &logconfig) == ISC_R_SUCCESS); 253 254 s = NULL; 255 RUNTIME_CHECK(isc_socket_create(socketmgr, PF_INET, 256 isc_sockettype_udp, &s) == 257 ISC_R_SUCCESS); 258 259 inaddr.s_addr = htonl(INADDR_LOOPBACK); 260 isc_sockaddr_fromin(&address, &inaddr, port); 261 262 dns_fixedname_init(&fname); 263 name = dns_fixedname_name(&fname); 264 isc_buffer_init(&b, "child.example.", strlen("child.example.")); 265 isc_buffer_add(&b, strlen("child.example.")); 266 result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL); 267 CHECK("dns_name_fromtext", result); 268 269 key = NULL; 270 result = dst_key_fromfile(name, 4017, DNS_KEYALG_DSA, 271 DST_TYPE_PUBLIC | DST_TYPE_PRIVATE, 272 NULL, mctx, &key); 273 CHECK("dst_key_fromfile", result); 274 275 buildquery(); 276 277 (void)isc_app_run(); 278 279 isc_task_shutdown(task1); 280 isc_task_detach(&task1); 281 isc_taskmgr_destroy(&taskmgr); 282 283 isc_socket_detach(&s); 284 isc_socketmgr_destroy(&socketmgr); 285 isc_timermgr_destroy(&timermgr); 286 287 dst_key_free(&key); 288 289 dst_lib_destroy(); 290 291 isc_entropy_detach(&ent); 292 293 isc_log_destroy(&lctx); 294 295 if (verbose) 296 isc_mem_stats(mctx, stdout); 297 isc_mem_destroy(&mctx); 298 299 DESTROYLOCK(&lock); 300 301 isc_app_finish(); 302 303 return (0); 304} 305