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