xref: /minix/external/bsd/bind/dist/bin/tests/zone_test.c (revision bb9622b5)
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*)&region);
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