1/*	$NetBSD: name_test.c,v 1.2.6.1 2012/06/05 21:15:19 bouyer Exp $	*/
2
3/*
4 * Copyright (C) 2004, 2005, 2007, 2009  Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (C) 1998-2001, 2003  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: name_test.c,v 1.43 2009/09/02 23:48:01 tbox Exp  */
21
22#include <config.h>
23
24#include <stdlib.h>
25
26#include <isc/commandline.h>
27#include <isc/string.h>
28#include <isc/util.h>
29
30#include <dns/fixedname.h>
31#include <dns/result.h>
32
33static void
34print_wirename(isc_region_t *name) {
35	unsigned char *ccurr, *cend;
36
37	if (name->length == 0) {
38		printf("<empty wire name>\n");
39		return;
40	}
41	ccurr = name->base;
42	cend = ccurr + name->length;
43	while (ccurr != cend)
44		printf("%02x ", *ccurr++);
45	printf("\n");
46}
47
48static void
49print_name(dns_name_t *name) {
50	isc_result_t result;
51	isc_buffer_t source;
52	isc_region_t r;
53	char s[1000];
54
55	isc_buffer_init(&source, s, sizeof(s));
56	if (dns_name_countlabels(name) > 0)
57		result = dns_name_totext(name, ISC_FALSE, &source);
58	else
59		result = ISC_R_SUCCESS;
60	if (result == ISC_R_SUCCESS) {
61		isc_buffer_usedregion(&source, &r);
62		if (r.length > 0)
63			printf("%.*s\n", (int)r.length, r.base);
64		else
65			printf("<empty text name>\n");
66	} else
67		printf("error: %s\n", dns_result_totext(result));
68}
69
70int
71main(int argc, char *argv[]) {
72	char s[1000];
73	isc_result_t result;
74	dns_fixedname_t wname, wname2, oname, compname, downname;
75	isc_buffer_t source;
76	isc_region_t r;
77	dns_name_t *name, *origin, *comp, *down;
78	unsigned int downcase = 0;
79	size_t len;
80	isc_boolean_t quiet = ISC_FALSE;
81	isc_boolean_t concatenate = ISC_FALSE;
82	isc_boolean_t got_name = ISC_FALSE;
83	isc_boolean_t check_absolute = ISC_FALSE;
84	isc_boolean_t check_wildcard = ISC_FALSE;
85	isc_boolean_t test_downcase = ISC_FALSE;
86	isc_boolean_t inplace = ISC_FALSE;
87	isc_boolean_t want_split = ISC_FALSE;
88	unsigned int labels, split_label = 0;
89	dns_fixedname_t fprefix, fsuffix;
90	dns_name_t *prefix, *suffix;
91	int ch;
92
93	while ((ch = isc_commandline_parse(argc, argv, "acdiqs:w")) != -1) {
94		switch (ch) {
95		case 'a':
96			check_absolute = ISC_TRUE;
97			break;
98		case 'c':
99			concatenate = ISC_TRUE;
100			break;
101		case 'd':
102			test_downcase = ISC_TRUE;
103			break;
104		case 'i':
105			inplace = ISC_TRUE;
106			break;
107		case 'q':
108			quiet = ISC_TRUE;
109			break;
110		case 's':
111			want_split = ISC_TRUE;
112			split_label = atoi(isc_commandline_argument);
113			break;
114		case 'w':
115			check_wildcard = ISC_TRUE;
116			break;
117		}
118	}
119
120	argc -= isc_commandline_index;
121	argv += isc_commandline_index;
122
123	if (argc > 0) {
124		if (strcasecmp("none", argv[0]) == 0)
125			origin = NULL;
126		else {
127			len = strlen(argv[0]);
128			isc_buffer_init(&source, argv[0], len);
129			isc_buffer_add(&source, len);
130			dns_fixedname_init(&oname);
131			origin = &oname.name;
132			result = dns_name_fromtext(origin, &source,
133						   dns_rootname, 0, NULL);
134			if (result != 0) {
135				fprintf(stderr,
136					"dns_name_fromtext() failed: %d\n",
137					result);
138				exit(1);
139			}
140		}
141	} else if (concatenate)
142		origin = NULL;
143	else
144		origin = dns_rootname;
145
146	if (argc >= 1) {
147		if (strcasecmp("none", argv[1]) == 0)
148			comp = NULL;
149		else {
150			len = strlen(argv[1]);
151			isc_buffer_init(&source, argv[1], len);
152			isc_buffer_add(&source, len);
153			dns_fixedname_init(&compname);
154			comp = &compname.name;
155			result = dns_name_fromtext(comp, &source, origin,
156						   0, NULL);
157			if (result != 0) {
158				fprintf(stderr,
159					"dns_name_fromtext() failed: %d\n",
160					result);
161				exit(1);
162			}
163		}
164	} else
165		comp = NULL;
166
167	dns_fixedname_init(&wname);
168	name = dns_fixedname_name(&wname);
169	dns_fixedname_init(&wname2);
170	while (fgets(s, sizeof(s), stdin) != NULL) {
171		len = strlen(s);
172		if (len > 0U && s[len - 1] == '\n') {
173			s[len - 1] = '\0';
174			len--;
175		}
176		isc_buffer_init(&source, s, len);
177		isc_buffer_add(&source, len);
178
179		if (len > 0U)
180			result = dns_name_fromtext(name, &source, origin,
181						   downcase, NULL);
182		else {
183			if (name == dns_fixedname_name(&wname))
184				dns_fixedname_init(&wname);
185			else
186				dns_fixedname_init(&wname2);
187			result = ISC_R_SUCCESS;
188		}
189
190		if (result != ISC_R_SUCCESS) {
191			printf("%s\n", dns_result_totext(result));
192			if (name == dns_fixedname_name(&wname))
193				dns_fixedname_init(&wname);
194			else
195				dns_fixedname_init(&wname2);
196			continue;
197		}
198
199		if (check_absolute && dns_name_countlabels(name) > 0) {
200			if (dns_name_isabsolute(name))
201				printf("absolute\n");
202			else
203				printf("relative\n");
204		}
205		if (check_wildcard && dns_name_countlabels(name) > 0) {
206			if (dns_name_iswildcard(name))
207				printf("wildcard\n");
208			else
209				printf("not wildcard\n");
210		}
211		dns_name_toregion(name, &r);
212		if (!quiet) {
213			print_wirename(&r);
214			printf("%u labels, %u bytes.\n",
215			       dns_name_countlabels(name), r.length);
216		}
217
218		if (concatenate) {
219			if (got_name) {
220				printf("Concatenating.\n");
221				result = dns_name_concatenate(&wname.name,
222							      &wname2.name,
223							      &wname2.name,
224							      NULL);
225				name = &wname2.name;
226				if (result == ISC_R_SUCCESS) {
227					if (check_absolute &&
228					    dns_name_countlabels(name) > 0) {
229						if (dns_name_isabsolute(name))
230							printf("absolute\n");
231						else
232							printf("relative\n");
233					}
234					if (check_wildcard &&
235					    dns_name_countlabels(name) > 0) {
236						if (dns_name_iswildcard(name))
237							printf("wildcard\n");
238						else
239							printf("not "
240							       "wildcard\n");
241					}
242					dns_name_toregion(name, &r);
243					if (!quiet) {
244						print_wirename(&r);
245						printf("%u labels, "
246						       "%u bytes.\n",
247						   dns_name_countlabels(name),
248						       r.length);
249					}
250				} else
251					printf("%s\n",
252					       dns_result_totext(result));
253				got_name = ISC_FALSE;
254			} else
255				got_name = ISC_TRUE;
256		}
257		isc_buffer_init(&source, s, sizeof(s));
258		if (dns_name_countlabels(name) > 0)
259			result = dns_name_totext(name, ISC_FALSE, &source);
260		else
261			result = ISC_R_SUCCESS;
262		if (result == ISC_R_SUCCESS) {
263			isc_buffer_usedregion(&source, &r);
264			if (r.length > 0)
265				printf("%.*s\n", (int)r.length, r.base);
266			else
267				printf("<empty text name>\n");
268			if (!quiet) {
269				printf("%u bytes.\n", source.used);
270			}
271		} else
272			printf("%s\n", dns_result_totext(result));
273
274		if (test_downcase) {
275			if (inplace) {
276				down = name;
277			} else {
278				dns_fixedname_init(&downname);
279				down = dns_fixedname_name(&downname);
280			}
281			result = dns_name_downcase(name, down, NULL);
282			INSIST(result == ISC_R_SUCCESS);
283			if (!quiet) {
284				dns_name_toregion(down, &r);
285				print_wirename(&r);
286				printf("%u labels, %u bytes.\n",
287				       dns_name_countlabels(down),
288				       r.length);
289			}
290			isc_buffer_init(&source, s, sizeof(s));
291			print_name(down);
292		}
293
294		if (comp != NULL && dns_name_countlabels(name) > 0) {
295			int order;
296			unsigned int nlabels;
297			dns_namereln_t namereln;
298
299			namereln = dns_name_fullcompare(name, comp, &order,
300							&nlabels);
301			if (!quiet) {
302				if (order < 0)
303					printf("<");
304				else if (order > 0)
305					printf(">");
306				else
307					printf("=");
308				switch (namereln) {
309				case dns_namereln_contains:
310					printf(", contains");
311					break;
312				case dns_namereln_subdomain:
313					printf(", subdomain");
314					break;
315				case dns_namereln_commonancestor:
316					printf(", common ancestor");
317					break;
318				default:
319					break;
320				}
321				if (namereln != dns_namereln_none &&
322				    namereln != dns_namereln_equal)
323					printf(", nlabels = %u", nlabels);
324				printf("\n");
325			}
326			printf("dns_name_equal() returns %s\n",
327			       dns_name_equal(name, comp) ? "TRUE" : "FALSE");
328		}
329
330		labels = dns_name_countlabels(name);
331		if (want_split && split_label < labels) {
332			dns_fixedname_init(&fprefix);
333			prefix = dns_fixedname_name(&fprefix);
334			dns_fixedname_init(&fsuffix);
335			suffix = dns_fixedname_name(&fsuffix);
336			printf("splitting at label %u: ", split_label);
337			dns_name_split(name, split_label, prefix, suffix);
338			printf("\n    prefix = ");
339			print_name(prefix);
340			printf("    suffix = ");
341			print_name(suffix);
342		}
343
344		if (concatenate) {
345			if (got_name)
346				name = &wname2.name;
347			else
348				name = &wname.name;
349		}
350	}
351
352	return (0);
353}
354