1/* 2 * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC") 3 * Copyright (C) 1999-2002 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: zone_test.c,v 1.35 2009/09/02 23:48:01 tbox Exp $ */ 19 20#include <config.h> 21 22#include <sys/param.h> 23#include <sys/types.h> 24#include <sys/time.h> 25 26#include <unistd.h> 27#include <stdlib.h> 28 29#include <isc/app.h> 30#include <isc/commandline.h> 31#include <isc/mem.h> 32#include <isc/socket.h> 33#include <isc/string.h> 34#include <isc/task.h> 35#include <isc/timer.h> 36#include <isc/util.h> 37 38#include <dns/db.h> 39#include <dns/fixedname.h> 40#include <dns/rdataclass.h> 41#include <dns/rdataset.h> 42#include <dns/result.h> 43#include <dns/zone.h> 44 45#ifdef ISC_PLATFORM_NEEDSYSSELECTH 46#include <sys/select.h> 47#endif 48 49static int debug = 0; 50static int quiet = 0; 51static int stats = 0; 52static isc_mem_t *mctx = NULL; 53dns_zone_t *zone = NULL; 54isc_taskmgr_t *taskmgr = NULL; 55isc_timermgr_t *timermgr = NULL; 56isc_socketmgr_t *socketmgr = NULL; 57dns_zonemgr_t *zonemgr = NULL; 58dns_zonetype_t zonetype = dns_zone_master; 59isc_sockaddr_t addr; 60 61#define ERRRET(result, function) \ 62 do { \ 63 if (result != ISC_R_SUCCESS) { \ 64 fprintf(stderr, "%s() returned %s\n", \ 65 function, dns_result_totext(result)); \ 66 return; \ 67 } \ 68 } while (0) 69 70#define ERRCONT(result, function) \ 71 if (result != ISC_R_SUCCESS) { \ 72 fprintf(stderr, "%s() returned %s\n", \ 73 function, dns_result_totext(result)); \ 74 continue; \ 75 } else \ 76 (void)NULL 77 78static void 79usage() { 80 fprintf(stderr, 81 "usage: zone_test [-dqsSM] [-c class] [-f file] zone\n"); 82 exit(1); 83} 84 85static void 86setup(const char *zonename, const char *filename, const char *classname) { 87 isc_result_t result; 88 dns_rdataclass_t rdclass; 89 isc_consttextregion_t region; 90 isc_buffer_t buffer; 91 dns_fixedname_t fixorigin; 92 dns_name_t *origin; 93 const char *rbt = "rbt"; 94 95 if (debug) 96 fprintf(stderr, "loading \"%s\" from \"%s\" class \"%s\"\n", 97 zonename, filename, classname); 98 result = dns_zone_create(&zone, mctx); 99 ERRRET(result, "dns_zone_new"); 100 101 dns_zone_settype(zone, zonetype); 102 103 isc_buffer_init(&buffer, zonename, strlen(zonename)); 104 isc_buffer_add(&buffer, strlen(zonename)); 105 dns_fixedname_init(&fixorigin); 106 result = dns_name_fromtext(dns_fixedname_name(&fixorigin), 107 &buffer, dns_rootname, 0, NULL); 108 ERRRET(result, "dns_name_fromtext"); 109 origin = dns_fixedname_name(&fixorigin); 110 111 result = dns_zone_setorigin(zone, origin); 112 ERRRET(result, "dns_zone_setorigin"); 113 114 result = dns_zone_setdbtype(zone, 1, &rbt); 115 ERRRET(result, "dns_zone_setdatabase"); 116 117 result = dns_zone_setfile(zone, filename); 118 ERRRET(result, "dns_zone_setfile"); 119 120 region.base = classname; 121 region.length = strlen(classname); 122 result = dns_rdataclass_fromtext(&rdclass, 123 (isc_textregion_t *)(void*)®ion); 124 ERRRET(result, "dns_rdataclass_fromtext"); 125 126 dns_zone_setclass(zone, rdclass); 127 128 if (zonetype == dns_zone_slave) 129 dns_zone_setmasters(zone, &addr, 1); 130 131 result = dns_zone_load(zone); 132 ERRRET(result, "dns_zone_load"); 133 134 result = dns_zonemgr_managezone(zonemgr, zone); 135 ERRRET(result, "dns_zonemgr_managezone"); 136} 137 138static void 139print_rdataset(dns_name_t *name, dns_rdataset_t *rdataset) { 140 isc_buffer_t text; 141 char t[1000]; 142 isc_result_t result; 143 isc_region_t r; 144 145 isc_buffer_init(&text, t, sizeof(t)); 146 result = dns_rdataset_totext(rdataset, name, ISC_FALSE, ISC_FALSE, 147 &text); 148 isc_buffer_usedregion(&text, &r); 149 if (result == ISC_R_SUCCESS) 150 printf("%.*s", (int)r.length, (char *)r.base); 151 else 152 printf("%s\n", dns_result_totext(result)); 153} 154 155static void 156query(void) { 157 char buf[1024]; 158 dns_fixedname_t name; 159 dns_fixedname_t found; 160 dns_db_t *db; 161 char *s; 162 isc_buffer_t buffer; 163 isc_result_t result; 164 dns_rdataset_t rdataset; 165 dns_rdataset_t sigset; 166 fd_set rfdset; 167 168 db = NULL; 169 result = dns_zone_getdb(zone, &db); 170 if (result != ISC_R_SUCCESS) { 171 fprintf(stderr, "%s() returned %s\n", "dns_zone_getdb", 172 dns_result_totext(result)); 173 return; 174 } 175 176 dns_fixedname_init(&found); 177 dns_rdataset_init(&rdataset); 178 dns_rdataset_init(&sigset); 179 180 do { 181 182 fprintf(stdout, "zone_test "); 183 fflush(stdout); 184 FD_ZERO(&rfdset); 185 FD_SET(0, &rfdset); 186 select(1, &rfdset, NULL, NULL, NULL); 187 if (fgets(buf, sizeof(buf), stdin) == NULL) { 188 fprintf(stdout, "\n"); 189 break; 190 } 191 buf[sizeof(buf) - 1] = '\0'; 192 193 s = strchr(buf, '\n'); 194 if (s != NULL) 195 *s = '\0'; 196 s = strchr(buf, '\r'); 197 if (s != NULL) 198 *s = '\0'; 199 if (strcmp(buf, "dump") == 0) { 200 dns_zone_dumptostream(zone, stdout); 201 continue; 202 } 203 if (strlen(buf) == 0U) 204 continue; 205 dns_fixedname_init(&name); 206 isc_buffer_init(&buffer, buf, strlen(buf)); 207 isc_buffer_add(&buffer, strlen(buf)); 208 result = dns_name_fromtext(dns_fixedname_name(&name), 209 &buffer, dns_rootname, 0, NULL); 210 ERRCONT(result, "dns_name_fromtext"); 211 212 result = dns_db_find(db, dns_fixedname_name(&name), 213 NULL /*vesion*/, 214 dns_rdatatype_a, 215 0 /*options*/, 216 0 /*time*/, 217 NULL /*nodep*/, 218 dns_fixedname_name(&found), 219 &rdataset, &sigset); 220 fprintf(stderr, "%s() returned %s\n", "dns_db_find", 221 dns_result_totext(result)); 222 switch (result) { 223 case DNS_R_DELEGATION: 224 print_rdataset(dns_fixedname_name(&found), &rdataset); 225 break; 226 case ISC_R_SUCCESS: 227 print_rdataset(dns_fixedname_name(&name), &rdataset); 228 break; 229 default: 230 break; 231 } 232 233 if (dns_rdataset_isassociated(&rdataset)) 234 dns_rdataset_disassociate(&rdataset); 235 if (dns_rdataset_isassociated(&sigset)) 236 dns_rdataset_disassociate(&sigset); 237 } while (1); 238 dns_rdataset_invalidate(&rdataset); 239 dns_db_detach(&db); 240} 241 242int 243main(int argc, char **argv) { 244 int c; 245 char *filename = NULL; 246 const char *classname = "IN"; 247 248 while ((c = isc_commandline_parse(argc, argv, "cdf:m:qsMS")) != EOF) { 249 switch (c) { 250 case 'c': 251 classname = isc_commandline_argument; 252 break; 253 case 'd': 254 debug++; 255 break; 256 case 'f': 257 if (filename != NULL) 258 usage(); 259 filename = isc_commandline_argument; 260 break; 261 case 'm': 262 memset(&addr, 0, sizeof(addr)); 263 addr.type.sin.sin_family = AF_INET; 264 inet_pton(AF_INET, isc_commandline_argument, 265 &addr.type.sin.sin_addr); 266 addr.type.sin.sin_port = htons(53); 267 break; 268 case 'q': 269 quiet++; 270 break; 271 case 's': 272 stats++; 273 break; 274 case 'S': 275 zonetype = dns_zone_slave; 276 break; 277 case 'M': 278 zonetype = dns_zone_master; 279 break; 280 default: 281 usage(); 282 } 283 } 284 285 if (argv[isc_commandline_index] == NULL) 286 usage(); 287 288 RUNTIME_CHECK(isc_app_start() == ISC_R_SUCCESS); 289 RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); 290 RUNTIME_CHECK(isc_taskmgr_create(mctx, 2, 0, &taskmgr) == 291 ISC_R_SUCCESS); 292 RUNTIME_CHECK(isc_timermgr_create(mctx, &timermgr) == ISC_R_SUCCESS); 293 RUNTIME_CHECK(isc_socketmgr_create(mctx, &socketmgr) == ISC_R_SUCCESS); 294 RUNTIME_CHECK(dns_zonemgr_create(mctx, taskmgr, timermgr, socketmgr, 295 &zonemgr) == ISC_R_SUCCESS); 296 if (filename == NULL) 297 filename = argv[isc_commandline_index]; 298 setup(argv[isc_commandline_index], filename, classname); 299 query(); 300 if (zone != NULL) 301 dns_zone_detach(&zone); 302 dns_zonemgr_shutdown(zonemgr); 303 dns_zonemgr_detach(&zonemgr); 304 isc_socketmgr_destroy(&socketmgr); 305 isc_taskmgr_destroy(&taskmgr); 306 isc_timermgr_destroy(&timermgr); 307 if (!quiet && stats) 308 isc_mem_stats(mctx, stdout); 309 isc_mem_destroy(&mctx); 310 311 return (0); 312} 313