1/*	$NetBSD: t_names.c,v 1.5 2012/12/04 23:38:39 spz Exp $	*/
2
3/*
4 * Copyright (C) 2004-2009, 2011, 2012  Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (C) 1998-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: t_names.c,v 1.52 2011/03/12 04:59:46 tbox Exp  */
21
22#include <config.h>
23
24#include <ctype.h>
25#include <stdlib.h>
26
27#include <isc/buffer.h>
28#include <isc/mem.h>
29#include <isc/string.h>
30
31#include <dns/compress.h>
32#include <dns/name.h>
33#include <dns/result.h>
34
35#include <tests/t_api.h>
36
37#define	MAXTOKS		16
38#define	BUFLEN		256
39#define	BIGBUFLEN	4096
40
41static char	*Tokens[MAXTOKS + 1];
42
43
44#ifdef	NEED_PBUF
45
46/*%
47 * get a hex formatted dns message from a data
48 * file into an isc_buffer_t
49 * caller supplies data storage and the isc_buffer
50 * we read the file, convert, setup the buffer
51 * and return the data length
52 */
53
54static char *
55ctoh(unsigned char c) {
56	int		val;
57	static char	buf[3];
58
59	val = (c >> 4) & 0x0f;
60	if ((0 <= val) && (val <= 9))
61		buf[0] = '0' + val;
62	else if ((10 <= val) && (val <= 16))
63		buf[0] = 'a' + val - 10;
64	val = c & 0x0f;
65	if ((0 <= val) && (val <= 9))
66		buf[1] = '0' + val;
67	else if ((10 <= val) && (val <= 16))
68		buf[1] = 'a' + val - 10;
69	buf[2] = '\0';
70	return (buf);
71}
72
73static void
74pbuf(isc_buffer_t *pbuf) {
75	size_t		len;
76	unsigned char	*p;
77
78	len = 0;
79	p = pbuf->base;
80	while (len < pbuf->length) {
81		printf("%s", ctoh(*p));
82		++p;
83		++len;
84		if ((len % 40) == 0)
85			printf("\n");
86	}
87}
88
89#endif	/* NEED_PBUF */
90
91/*%
92 * Compare data at buf with data in hex representation at exp_data,
93 * of length exp_data_len, for equality.
94 * Return 0 if equal, else non-zero.
95 */
96
97static int
98chkdata(unsigned char *buf, size_t buflen, char *exp_data,
99	size_t exp_data_len)
100{
101	int		result;
102	unsigned char	*p;
103	unsigned char	*v;
104	char		*q;
105	unsigned char	*data;
106	size_t		cnt;
107
108	if (buflen == exp_data_len) {
109		data = (unsigned char *)malloc(exp_data_len *
110					       sizeof(unsigned char));
111		if (data == NULL) {
112			t_info("malloc failed unexpectedly\n");
113			return (-1);
114		}
115
116		/*
117		 * First convert exp_data from hex format.
118		 */
119		p = data;
120		q = exp_data;
121		cnt = 0;
122		while (cnt < exp_data_len) {
123
124			if (('0' <= *q) && (*q <= '9'))
125				*p = *q - '0';
126			else if (('a' <= *q) && (*q <= 'f'))
127				*p = *q - 'a' + 10;
128			else if (('A' <= *q) && (*q <= 'F'))
129				*p = *q - 'A' + 10;
130			else {
131				t_info("malformed comparison data\n");
132				free(data);
133				return (-1);
134			}
135			++q;
136
137			*p <<= 4;
138
139			if (('0' <= *q) && (*q <= '9'))
140				*p |= ((*q - '0') & 0x0f);
141			else if (('a' <= *q) && (*q <= 'f'))
142				*p |= ((*q - 'a' + 10) & 0x0f);
143			else if (('A' <= *q) && (*q <= 'F'))
144				*p |= ((*q - 'A' + 10) & 0x0f);
145			else {
146				t_info("malformed comparison data\n");
147				free(data);
148				return (-1);
149			}
150			++p;
151			++q;
152			++cnt;
153		}
154
155		/*
156		 * Now compare data.
157		 */
158		p = buf;
159		v = data;
160		for (cnt = 0; cnt < exp_data_len; ++cnt) {
161			if (*p != *v)
162				break;
163			++p;
164			++v;
165		}
166		if (cnt == exp_data_len)
167			result = 0;
168		else {
169			t_info("bad data at position %lu, "
170			       "got 0x%.2x, expected 0x%.2x\n",
171			       (unsigned long)cnt, *p, *q);
172			result = cnt + 1;
173		}
174		(void)free(data);
175	} else {
176		t_info("data length error, expected %lu, got %lu\n",
177			(unsigned long)exp_data_len, (unsigned long)buflen);
178		result = exp_data_len - buflen;
179	}
180	return (result);
181}
182
183/*%
184 * Get a hex formatted dns message from a data file into an isc_buffer_t.
185 * Caller supplies data storage and the isc_buffer.  We read the file, convert,
186 * setup the buffer and return the data length.
187 */
188static int
189getmsg(char *datafile_name, unsigned char *buf, int buflen, isc_buffer_t *pbuf)
190{
191	int			c;
192	int			len;
193	int			cnt;
194	unsigned char		*p;
195	FILE			*fp;
196
197	fp = fopen(datafile_name, "r");
198	if (fp == NULL) {
199		t_info("No such file %s\n", datafile_name);
200		return (0);
201	}
202
203	p = buf;
204	cnt = 0;
205	len = 0;
206	while ((c = getc(fp)) != EOF) {
207		unsigned int		val;
208		if (	(c == ' ') || (c == '\t') ||
209			(c == '\r') || (c == '\n'))
210				continue;
211		if (c == '#') {
212			while ((c = getc(fp)) != '\n')
213				;
214			continue;
215		}
216		if (('0' <= c) && (c <= '9'))
217			val = c - '0';
218		else if (('a' <= c) && (c <= 'f'))
219			val = c - 'a' + 10;
220		else if (('A' <= c) && (c <= 'F'))
221			val = c - 'A'+ 10;
222		else {
223			(void)fclose(fp);
224			t_info("Bad format in datafile\n");
225			return (0);
226		}
227		if ((len % 2) == 0) {
228			*p = (val << 4);
229		} else {
230			*p += val;
231			++p;
232			++cnt;
233			if (cnt >= buflen) {
234				/*
235				 * Buffer too small.
236				 */
237				(void)fclose(fp);
238				t_info("Buffer overflow error\n");
239				return (0);
240			}
241		}
242		++len;
243	}
244	(void)fclose(fp);
245
246	if (len % 2) {
247		t_info("Bad format in %s\n", datafile_name);
248		return (0);
249	}
250
251	*p = '\0';
252	isc_buffer_init(pbuf, buf, cnt);
253	isc_buffer_add(pbuf, cnt);
254	return (cnt);
255}
256
257static int
258bustline(char *line, char **toks) {
259	int	cnt;
260	char	*p;
261
262	cnt = 0;
263	if (line && *line) {
264		while ((p = strtok(line, "\t")) && (cnt < MAXTOKS)) {
265			*toks++ = p;
266			line = NULL;
267			++cnt;
268		}
269	}
270	return (cnt);
271}
272
273
274#ifdef	NEED_HNAME_TO_TNAME
275
276/*%
277 * convert a name from hex representation to text form
278 * format of hex notation is:
279 * %xXXXXXXXX
280 */
281
282static int
283hname_to_tname(char *src, char *target, size_t len) {
284	int		i;
285	int		c;
286	unsigned int	val;
287	size_t		srclen;
288	char		*p;
289	char		*q;
290
291	p = src;
292	srclen = strlen(p);
293	if ((srclen >= 2) && ((*p != '%') || (*(p+1) != 'x'))) {
294		/*
295		 * No conversion needed.
296		 */
297		if (srclen >= len)
298			return (1);
299		memcpy(target, src, srclen + 1);
300		return (0);
301	}
302
303	i = 0;
304	p += 2;
305	q = target;
306	while (*p) {
307		c = *p;
308		if (('0' < c) && (c <= '9'))
309			val = c - '0';
310		else if (('a' <= c) && (c <= 'z'))
311			val = c + 10 - 'a';
312		else if (('A' <= c) && (c <= 'Z'))
313			val = c + 10 - 'A';
314		else {
315			return (1);
316		}
317		if (i % 2) {
318			*q |= val;
319			++q;
320		} else
321			*q = (val << 4);
322		++i;
323		++p;
324	}
325	if (i % 2) {
326		return (1);
327	} else {
328		*q = '\0';
329		return (0);
330	}
331}
332
333#endif	/* NEED_HNAME_TO_TNAME */
334
335/*%
336 * initialize a dns_name_t from a text name, hiding all
337 * buffer and other object initialization from the caller
338 *
339 */
340
341static isc_result_t
342dname_from_tname(char *name, dns_name_t *dns_name) {
343	int		len;
344	isc_buffer_t	txtbuf;
345	isc_buffer_t	*binbuf;
346	unsigned char	*junk;
347	isc_result_t	result;
348
349	len = strlen(name);
350	isc_buffer_init(&txtbuf, name, len);
351	isc_buffer_add(&txtbuf, len);
352	junk = (unsigned char *)malloc(sizeof(unsigned char) * BUFLEN);
353	binbuf = (isc_buffer_t *)malloc(sizeof(isc_buffer_t));
354	if ((junk != NULL) && (binbuf != NULL)) {
355		isc_buffer_init(binbuf, junk, BUFLEN);
356		dns_name_init(dns_name, NULL);
357		dns_name_setbuffer(dns_name, binbuf);
358		result = dns_name_fromtext(dns_name,  &txtbuf, NULL, 0, NULL);
359	} else {
360		result = ISC_R_NOSPACE;
361		if (junk != NULL)
362			(void)free(junk);
363		if (binbuf != NULL)
364			(void)free(binbuf);
365	}
366	return (result);
367}
368
369static const char *a3 =	"dns_name_init initializes 'name' to the empty name";
370
371static void
372t_dns_name_init(void) {
373	int		rval;
374	int		result;
375	dns_name_t	name;
376	unsigned char	offsets[1];
377
378	rval = 0;
379	t_assert("dns_name_init", 1, T_REQUIRED, "%s", a3);
380
381	dns_name_init(&name, offsets);
382	/* magic is hidden in name.c ...
383	if (name.magic != NAME_MAGIC) {
384		t_info("name.magic is not set to NAME_MAGIC\n");
385		++rval;
386	}
387	*/
388	if (name.ndata != NULL) {
389		t_info("name.ndata is not NULL\n");
390		++rval;
391	}
392	if (name.length != 0) {
393		t_info("name.length is not 0\n");
394		++rval;
395	}
396	if (name.labels != 0) {
397		t_info("name.labels is not 0\n");
398		++rval;
399	}
400	if (name.attributes != 0) {
401		t_info("name.attributes is not 0\n");
402		++rval;
403	}
404	if (name.offsets != offsets) {
405		t_info("name.offsets is incorrect\n");
406		++rval;
407	}
408	if (name.buffer != NULL) {
409		t_info("name.buffer is not NULL\n");
410		++rval;
411	}
412
413	if (rval == 0)
414		result = T_PASS;
415	else
416		result = T_FAIL;
417	t_result(result);
418}
419
420static const char *a4 =	"dns_name_invalidate invalidates 'name'";
421
422static void
423t_dns_name_invalidate(void) {
424	int		rval;
425	int		result;
426	dns_name_t	name;
427	unsigned char	offsets[1];
428
429	t_assert("dns_name_invalidate", 1, T_REQUIRED, "%s", a4);
430
431	rval = 0;
432	dns_name_init(&name, offsets);
433	dns_name_invalidate(&name);
434
435	/* magic is hidden in name.c ...
436	if (name.magic != 0) {
437		t_info("name.magic is not set to NAME_MAGIC\n");
438		++rval;
439	}
440	*/
441	if (name.ndata != NULL) {
442		t_info("name.ndata is not NULL\n");
443		++rval;
444	}
445	if (name.length != 0) {
446		t_info("name.length is not 0\n");
447		++rval;
448	}
449	if (name.labels != 0) {
450		t_info("name.labels is not 0\n");
451		++rval;
452	}
453	if (name.attributes != 0) {
454		t_info("name.attributes is not 0\n");
455		++rval;
456	}
457	if (name.offsets != NULL) {
458		t_info("name.offsets is not NULL\n");
459		++rval;
460	}
461	if (name.buffer != NULL) {
462		t_info("name.buffer is not NULL\n");
463		++rval;
464	}
465
466	if (rval == 0)
467		result = T_PASS;
468	else
469		result = T_FAIL;
470	t_result(result);
471}
472
473static const char *a5 =	"dns_name_setbuffer dedicates a buffer for use "
474			"with 'name'";
475
476static void
477t_dns_name_setbuffer(void) {
478	int		result;
479	unsigned char	junk[BUFLEN];
480	dns_name_t	name;
481	isc_buffer_t	buffer;
482
483	t_assert("dns_name_setbuffer", 1, T_REQUIRED, "%s", a5);
484
485	isc_buffer_init(&buffer, junk, BUFLEN);
486	dns_name_init(&name, NULL);
487	dns_name_setbuffer(&name, &buffer);
488	if (name.buffer == &buffer)
489		result = T_PASS;
490	else
491		result = T_FAIL;
492
493	t_result(result);
494}
495
496static const char *a6 =	"dns_name_hasbuffer returns ISC_TRUE if 'name' has a "
497			"dedicated buffer, otherwise it returns ISC_FALSE";
498
499static void
500t_dns_name_hasbuffer(void) {
501	int		result;
502	int		rval;
503	unsigned char	junk[BUFLEN];
504	dns_name_t	name;
505	isc_buffer_t	buffer;
506
507	t_assert("dns_name_hasbuffer", 1, T_REQUIRED, "%s", a6);
508
509	rval = 0;
510	isc_buffer_init(&buffer, junk, BUFLEN);
511	dns_name_init(&name, NULL);
512	if (dns_name_hasbuffer(&name) != ISC_FALSE)
513		++rval;
514	dns_name_setbuffer(&name, &buffer);
515	if (dns_name_hasbuffer(&name) != ISC_TRUE)
516		++rval;
517	if (rval == 0)
518		result = T_PASS;
519	else
520		result = T_FAIL;
521
522	t_result(result);
523}
524
525static const char *a7 =	"dns_name_isabsolute returns ISC_TRUE if 'name' ends "
526			"in the root label";
527
528static int
529test_dns_name_isabsolute(char *test_name, isc_boolean_t expected) {
530	dns_name_t	name;
531	isc_buffer_t	buf;
532	isc_buffer_t	binbuf;
533	unsigned char	junk[BUFLEN];
534	int		len;
535	int		rval;
536	isc_boolean_t	isabs_p;
537	isc_result_t	result;
538
539	rval = T_UNRESOLVED;
540
541	t_info("testing name %s\n", test_name);
542	len = strlen(test_name);
543	isc_buffer_init(&buf, test_name, len);
544	isc_buffer_add(&buf, len);
545	isc_buffer_init(&binbuf, &junk[0], BUFLEN);
546	dns_name_init(&name, NULL);
547	dns_name_setbuffer(&name, &binbuf);
548	result = dns_name_fromtext(&name,  &buf, NULL, 0, NULL);
549	if (result == ISC_R_SUCCESS) {
550		isabs_p = dns_name_isabsolute(&name);
551		if (isabs_p == expected)
552			rval = T_PASS;
553		else
554			rval = T_FAIL;
555	} else {
556		t_info("dns_name_fromtext %s failed, result = %s\n",
557				test_name, dns_result_totext(result));
558	}
559	return (rval);
560}
561
562static void
563t_dns_name_isabsolute(void) {
564	int	line;
565	int	cnt;
566	int	result;
567	char	*p;
568	FILE	*fp;
569
570	t_assert("dns_name_isabsolute", 1, T_REQUIRED, "%s", a7);
571
572	result = T_UNRESOLVED;
573	fp = fopen("dns_name_isabsolute_data", "r");
574	if (fp != NULL) {
575		line = 0;
576		while ((p = t_fgetbs(fp)) != NULL) {
577
578			++line;
579
580			/*
581			 * Skip comment lines.
582			 */
583			if ((isspace((unsigned char)*p)) || (*p == '#')) {
584				(void)free(p);
585				continue;
586			}
587
588			cnt = bustline(p, Tokens);
589			if (cnt == 2) {
590				/*
591				 * label, bitpos, expected value.
592				 */
593				result = test_dns_name_isabsolute(Tokens[0],
594								atoi(Tokens[1])
595								  == 0 ?
596								  ISC_FALSE :
597								  ISC_TRUE);
598			} else {
599				t_info("bad datafile format at line %d\n",
600				       line);
601			}
602
603			(void)free(p);
604			t_result(result);
605		}
606		(void)fclose(fp);
607	} else {
608		t_info("Missing datafile dns_name_isabsolute_data\n");
609		t_result(result);
610	}
611}
612
613static const char *a8 =	"dns_name_hash(name, case_sensitive) returns "
614		"a hash of 'name' which is case_sensitive if case_sensitive "
615		"is true";
616
617/*%
618 * a9 merged with a8.
619 */
620
621static int
622test_dns_name_hash(char *test_name1, char *test_name2,
623		isc_boolean_t csh_match, isc_boolean_t cish_match) {
624	int		rval;
625	int		failures;
626	isc_boolean_t	match;
627	unsigned int	hash1;
628	unsigned int	hash2;
629	dns_name_t	dns_name1;
630	dns_name_t	dns_name2;
631	isc_result_t	result;
632
633	rval = T_UNRESOLVED;
634	failures = 0;
635
636	t_info("testing names %s and %s\n", test_name1, test_name2);
637
638	result = dname_from_tname(test_name1, &dns_name1);
639	if (result == ISC_R_SUCCESS) {
640		result = dname_from_tname(test_name2, &dns_name2);
641		if (result == ISC_R_SUCCESS) {
642			hash1 = dns_name_hash(&dns_name1, ISC_TRUE);
643			hash2 = dns_name_hash(&dns_name2, ISC_TRUE);
644			match = ISC_FALSE;
645			if (hash1 == hash2)
646				match = ISC_TRUE;
647			if (match != csh_match) {
648				++failures;
649				t_info("hash mismatch when ISC_TRUE\n");
650			}
651			hash1 = dns_name_hash(&dns_name1, ISC_FALSE);
652			hash2 = dns_name_hash(&dns_name2, ISC_FALSE);
653			match = ISC_FALSE;
654			if (hash1 == hash2)
655				match = ISC_TRUE;
656			if (match != cish_match) {
657				++failures;
658				t_info("hash mismatch when ISC_FALSE\n");
659			}
660			if (failures == 0)
661				rval = T_PASS;
662			else
663				rval = T_FAIL;
664		} else {
665			t_info("dns_fromtext %s failed, result = %s\n",
666				test_name2, dns_result_totext(result));
667		}
668	} else {
669		t_info("dns_fromtext %s failed, result = %s\n",
670				test_name1, dns_result_totext(result));
671	}
672	return (rval);
673}
674
675static void
676t_dns_name_hash(void) {
677	int	line;
678	int	cnt;
679	int	result;
680	char	*p;
681	FILE	*fp;
682
683	t_assert("dns_name_hash", 1, T_REQUIRED, "%s", a8);
684
685	result = T_UNRESOLVED;
686	fp = fopen("dns_name_hash_data", "r");
687	if (fp != NULL) {
688		line = 0;
689		while ((p = t_fgetbs(fp)) != NULL) {
690
691			++line;
692
693			/*
694			 * Skip comment lines.
695			 */
696			if ((isspace((unsigned char)*p)) || (*p == '#')) {
697				(void)free(p);
698				continue;
699			}
700
701			cnt = bustline(p, Tokens);
702			if (cnt == 4) {
703				/*
704				 * name1, name2, exp match value if
705				 * case_sensitive true,
706				 * exp match value of case_sensitive false
707				 */
708				result = test_dns_name_hash(
709						Tokens[0],
710						Tokens[1],
711						atoi(Tokens[2]) == 0 ?
712							ISC_FALSE : ISC_TRUE,
713						atoi(Tokens[3]) == 0 ?
714							ISC_FALSE : ISC_TRUE);
715			} else {
716				t_info("bad datafile format at line %d\n",
717						line);
718			}
719
720			(void)free(p);
721			t_result(result);
722		}
723		(void)fclose(fp);
724	} else {
725		t_info("Missing datafile dns_name_hash_data\n");
726		t_result(result);
727	}
728}
729
730static const char *a10 =
731		"dns_name_fullcompare(name1, name2, orderp, nlabelsp) "
732		"returns the DNSSEC ordering relationship between name1 and "
733		"name2, sets orderp to -1 if name1 < name2, to 0 if "
734		"name1 == name2, or to 1 if name1 > name2, sets nlabelsp "
735		"to the number of labels name1 and name2 have in common, "
736		"and sets nbitsp to the number of bits name1 and name2 "
737		"have in common";
738
739/*%
740 * a11 thru a22 merged into a10.
741 */
742static const char *
743dns_namereln_to_text(dns_namereln_t reln) {
744	const char *p;
745
746	if (reln == dns_namereln_contains)
747		p = "contains";
748	else if (reln == dns_namereln_subdomain)
749		p = "subdomain";
750	else if (reln == dns_namereln_equal)
751		p = "equal";
752	else if (reln == dns_namereln_none)
753		p = "none";
754	else if (reln == dns_namereln_commonancestor)
755		p = "commonancestor";
756	else
757		p = "unknown";
758
759	return (p);
760}
761
762static int
763test_dns_name_fullcompare(char *name1, char *name2,
764			  dns_namereln_t exp_dns_reln,
765			  int exp_order, int exp_nlabels)
766{
767	int		result;
768	int		nfails;
769	int		order;
770	unsigned int	nlabels;
771	dns_name_t	dns_name1;
772	dns_name_t	dns_name2;
773	isc_result_t	dns_result;
774	dns_namereln_t	dns_reln;
775
776	nfails = 0;
777	result = T_UNRESOLVED;
778
779
780	t_info("testing names %s and %s for relation %s\n", name1, name2,
781	       dns_namereln_to_text(exp_dns_reln));
782
783	dns_result = dname_from_tname(name1, &dns_name1);
784	if (dns_result == ISC_R_SUCCESS) {
785		dns_result = dname_from_tname(name2, &dns_name2);
786		if (dns_result == ISC_R_SUCCESS) {
787			dns_reln = dns_name_fullcompare(&dns_name1, &dns_name2,
788					&order, &nlabels);
789
790			if (dns_reln != exp_dns_reln) {
791				++nfails;
792				t_info("expected relationship of %s, got %s\n",
793					dns_namereln_to_text(exp_dns_reln),
794					dns_namereln_to_text(dns_reln));
795			}
796			/*
797			 * Normalize order.
798			 */
799			if (order < 0)
800				order = -1;
801			else if (order > 0)
802				order = 1;
803			if (order != exp_order) {
804				++nfails;
805				t_info("expected ordering %d, got %d\n",
806						exp_order, order);
807			}
808			if ((exp_nlabels >= 0) &&
809			    (nlabels != (unsigned int)exp_nlabels)) {
810				++nfails;
811				t_info("expecting %d labels, got %d\n",
812				       exp_nlabels, nlabels);
813			}
814			if (nfails == 0)
815				result = T_PASS;
816			else
817				result = T_FAIL;
818		} else {
819			t_info("dname_from_tname failed, result == %s\n",
820			       dns_result_totext(result));
821		}
822	} else {
823		t_info("dname_from_tname failed, result == %s\n",
824		       dns_result_totext(result));
825	}
826
827	return (result);
828}
829
830static void
831t_dns_name_fullcompare(void) {
832	int		line;
833	int		cnt;
834	int		result;
835	char		*p;
836	FILE		*fp;
837	dns_namereln_t	reln;
838
839	t_assert("dns_name_fullcompare", 1, T_REQUIRED, "%s", a10);
840
841	result = T_UNRESOLVED;
842	fp = fopen("dns_name_fullcompare_data", "r");
843	if (fp != NULL) {
844		line = 0;
845		while ((p = t_fgetbs(fp)) != NULL) {
846
847			++line;
848
849			/*
850			 * Skip comment lines.
851			 */
852			if ((isspace((unsigned char)*p)) || (*p == '#')) {
853				(void)free(p);
854				continue;
855			}
856
857			cnt = bustline(p, Tokens);
858			if (cnt == 6) {
859				/*
860				 * name1, name2, exp_reln, exp_order,
861				 * exp_nlabels
862				 */
863				if (!strcmp(Tokens[2], "none"))
864					reln = dns_namereln_none;
865				else if (!strcmp(Tokens[2], "contains"))
866					reln = dns_namereln_contains;
867				else if (!strcmp(Tokens[2], "subdomain"))
868					reln = dns_namereln_subdomain;
869				else if (!strcmp(Tokens[2], "equal"))
870					reln = dns_namereln_equal;
871				else if (!strcmp(Tokens[2], "commonancestor"))
872					reln = dns_namereln_commonancestor;
873				else {
874					t_info("bad format at line %d\n",
875					       line);
876					continue;
877				}
878				result = test_dns_name_fullcompare(
879						Tokens[0],
880						Tokens[1],
881						reln,
882						atoi(Tokens[3]),
883						atoi(Tokens[4]));
884			} else {
885				t_info("bad format at line %d\n", line);
886			}
887
888			(void)free(p);
889			t_result(result);
890		}
891		(void)fclose(fp);
892	} else {
893		t_info("Missing datafile dns_name_fullcompare_data\n");
894		t_result(result);
895	}
896}
897
898static const char *a23 =
899		"dns_name_compare(name1, name2) returns information about "
900		"the relative ordering under the DNSSEC ordering relationship "
901		"of name1 and name2";
902
903/*%
904 * a24 thru a29 merged into a23.
905 */
906
907static int
908test_dns_name_compare(char *name1, char *name2, int exp_order) {
909	int		result;
910	int		order;
911	isc_result_t	dns_result;
912	dns_name_t	dns_name1;
913	dns_name_t	dns_name2;
914
915	result = T_UNRESOLVED;
916
917	t_info("testing %s %s %s\n", name1,
918	       exp_order == 0 ? "==": (exp_order == -1 ? "<" : ">"),
919	       name2);
920
921	dns_result = dname_from_tname(name1, &dns_name1);
922	if (dns_result == ISC_R_SUCCESS) {
923		dns_result = dname_from_tname(name2, &dns_name2);
924		if (dns_result == ISC_R_SUCCESS) {
925			order = dns_name_compare(&dns_name1, &dns_name2);
926			/*
927			 * Normalize order.
928			 */
929			if (order < 0)
930				order = -1;
931			else if (order > 0)
932				order = 1;
933			if (order != exp_order) {
934				t_info("expected order of %d, got %d\n",
935				       exp_order, order);
936				result = T_FAIL;
937			} else
938				result = T_PASS;
939		} else {
940			t_info("dname_from_tname failed, result == %s\n",
941					dns_result_totext(result));
942		}
943	} else {
944		t_info("dname_from_tname failed, result == %s\n",
945				dns_result_totext(result));
946	}
947
948	return (result);
949}
950
951static void
952t_dns_name_compare(void) {
953	int		line;
954	int		cnt;
955	int		result;
956	char		*p;
957	FILE		*fp;
958
959	t_assert("dns_name_compare", 1, T_REQUIRED, "%s", a23);
960
961	result = T_UNRESOLVED;
962	fp = fopen("dns_name_compare_data", "r");
963	if (fp != NULL) {
964		line = 0;
965		while ((p = t_fgetbs(fp)) != NULL) {
966
967			++line;
968
969			/*
970			 * Skip comment lines.
971			 */
972			if ((isspace((unsigned char)*p)) || (*p == '#')) {
973				(void)free(p);
974				continue;
975			}
976
977			cnt = bustline(p, Tokens);
978			if (cnt == 3) {
979				/*
980				 * name1, name2, order.
981				 */
982				result = test_dns_name_compare(
983						Tokens[0],
984						Tokens[1],
985						atoi(Tokens[2]));
986			} else {
987				t_info("bad datafile format at line %d\n",
988				       line);
989			}
990
991			(void)free(p);
992			t_result(result);
993		}
994		(void)fclose(fp);
995	} else {
996		t_info("Missing datafile dns_name_compare_data\n");
997		t_result(result);
998	}
999}
1000
1001static const char *a30 =
1002		"dns_name_rdatacompare(name1, name2) returns information "
1003		"about the relative ordering of name1 and name2 as if they "
1004		"are part of rdata in DNSSEC canonical form";
1005
1006/*%
1007 * a31, a32 merged into a30.
1008 */
1009
1010static int
1011test_dns_name_rdatacompare(char *name1, char *name2, int exp_order) {
1012	int		result;
1013	int		order;
1014	isc_result_t	dns_result;
1015	dns_name_t	dns_name1;
1016	dns_name_t	dns_name2;
1017
1018	result = T_UNRESOLVED;
1019
1020	t_info("testing %s %s %s\n", name1,
1021	       exp_order == 0 ? "==": (exp_order == -1 ? "<" : ">"), name2);
1022
1023	dns_result = dname_from_tname(name1, &dns_name1);
1024	if (dns_result == ISC_R_SUCCESS) {
1025		dns_result = dname_from_tname(name2, &dns_name2);
1026		if (dns_result == ISC_R_SUCCESS) {
1027			order = dns_name_rdatacompare(&dns_name1, &dns_name2);
1028			/*
1029			 * Normalize order.
1030			 */
1031			if (order < 0)
1032				order = -1;
1033			else if (order > 0)
1034				order = 1;
1035			if (order != exp_order) {
1036				t_info("expected order of %d, got %d\n",
1037				       exp_order, order);
1038				result = T_FAIL;
1039			} else
1040				result = T_PASS;
1041		} else {
1042			t_info("dname_from_tname failed, result == %s\n",
1043			       dns_result_totext(result));
1044		}
1045	} else {
1046		t_info("dname_from_tname failed, result == %s\n",
1047		       dns_result_totext(result));
1048	}
1049
1050	return (result);
1051}
1052
1053static void
1054t_dns_name_rdatacompare(void) {
1055	int		line;
1056	int		cnt;
1057	int		result;
1058	char		*p;
1059	FILE		*fp;
1060
1061	t_assert("dns_name_rdatacompare", 1, T_REQUIRED, "%s", a30);
1062
1063	result = T_UNRESOLVED;
1064	fp = fopen("dns_name_rdatacompare_data", "r");
1065	if (fp != NULL) {
1066		line = 0;
1067		while ((p = t_fgetbs(fp)) != NULL) {
1068
1069			++line;
1070
1071			/*
1072			 * Skip comment lines.
1073			 */
1074			if ((isspace((unsigned char)*p)) || (*p == '#')) {
1075				(void)free(p);
1076				continue;
1077			}
1078
1079			cnt = bustline(p, Tokens);
1080			if (cnt == 3) {
1081				/*
1082				 * name1, name2, order.
1083				 */
1084				result = test_dns_name_rdatacompare(
1085						Tokens[0],
1086						Tokens[1],
1087						atoi(Tokens[2]));
1088			} else {
1089				t_info("bad datafile format at line %d\n",
1090				       line);
1091			}
1092
1093			(void)free(p);
1094			t_result(result);
1095		}
1096		(void)fclose(fp);
1097	} else {
1098		t_info("Missing datafile dns_name_rdatacompare_data\n");
1099		t_result(result);
1100	}
1101}
1102
1103
1104static const char *a33 =
1105		"when name1 is a subdomain of name2, "
1106		"dns_name_issubdomain(name1, name2) returns true, "
1107		"otherwise it returns false.";
1108
1109/*%
1110 * a34 merged into a33.
1111 */
1112
1113static int
1114test_dns_name_issubdomain(char *name1, char *name2, isc_boolean_t exp_rval) {
1115	int		result;
1116	isc_boolean_t	rval;
1117	isc_result_t	dns_result;
1118	dns_name_t	dns_name1;
1119	dns_name_t	dns_name2;
1120
1121	result = T_UNRESOLVED;
1122
1123	t_info("testing %s %s a subdomain of %s\n", name1,
1124	       exp_rval == 0 ? "is not" : "is", name2);
1125
1126	dns_result = dname_from_tname(name1, &dns_name1);
1127	if (dns_result == ISC_R_SUCCESS) {
1128		dns_result = dname_from_tname(name2, &dns_name2);
1129		if (dns_result == ISC_R_SUCCESS) {
1130			rval = dns_name_issubdomain(&dns_name1, &dns_name2);
1131
1132			if (rval != exp_rval) {
1133				t_info("expected return value of %s, got %s\n",
1134				       exp_rval == ISC_TRUE ? "true" : "false",
1135				       rval == ISC_TRUE ? "true" : "false");
1136				result = T_FAIL;
1137			} else
1138				result = T_PASS;
1139		} else {
1140			t_info("dname_from_tname failed, result == %s\n",
1141			       dns_result_totext(result));
1142		}
1143	} else {
1144		t_info("dname_from_tname failed, result == %s\n",
1145		       dns_result_totext(result));
1146	}
1147
1148	return (result);
1149}
1150
1151static void
1152t_dns_name_issubdomain(void) {
1153	int		line;
1154	int		cnt;
1155	int		result;
1156	char		*p;
1157	FILE		*fp;
1158
1159	t_assert("dns_name_issubdomain", 1, T_REQUIRED, "%s", a33);
1160
1161	result = T_UNRESOLVED;
1162	fp = fopen("dns_name_issubdomain_data", "r");
1163	if (fp != NULL) {
1164		line = 0;
1165		while ((p = t_fgetbs(fp)) != NULL) {
1166
1167			++line;
1168
1169			/*
1170			 * Skip comment lines.
1171			 */
1172			if ((isspace((unsigned char)*p)) || (*p == '#')) {
1173				(void)free(p);
1174				continue;
1175			}
1176
1177			cnt = bustline(p, Tokens);
1178			if (cnt == 3) {
1179				/*
1180				 * name1, name2, issubdomain_p.
1181				 */
1182				result = test_dns_name_issubdomain(
1183						Tokens[0],
1184						Tokens[1],
1185						atoi(Tokens[2]) == 0 ?
1186						ISC_FALSE : ISC_TRUE);
1187			} else {
1188				t_info("bad datafile format at line %d\n",
1189				       line);
1190			}
1191
1192			(void)free(p);
1193			t_result(result);
1194		}
1195		(void)fclose(fp);
1196	} else {
1197		t_info("Missing datafile dns_name_issubdomain_data\n");
1198		t_result(result);
1199	}
1200}
1201
1202static const char *a35 =
1203		"dns_name_countlabels(name) returns the number "
1204		"of labels in name";
1205
1206static int
1207test_dns_name_countlabels(char *test_name, unsigned int exp_nlabels) {
1208	int		result;
1209	unsigned int	nlabels;
1210	isc_result_t	dns_result;
1211	dns_name_t	dns_name;
1212
1213	result = T_UNRESOLVED;
1214
1215	t_info("testing %s\n", test_name);
1216
1217	dns_result = dname_from_tname(test_name, &dns_name);
1218	if (dns_result == ISC_R_SUCCESS) {
1219		nlabels = dns_name_countlabels(&dns_name);
1220
1221		if (nlabels != exp_nlabels) {
1222			t_info("expected %d, got %d\n", exp_nlabels, nlabels);
1223			result = T_FAIL;
1224		} else
1225			result = T_PASS;
1226	} else {
1227		t_info("dname_from_tname failed, result == %s\n",
1228		       dns_result_totext(dns_result));
1229	}
1230
1231	return (result);
1232}
1233
1234static void
1235t_dns_name_countlabels(void) {
1236	int		line;
1237	int		cnt;
1238	int		result;
1239	char		*p;
1240	FILE		*fp;
1241
1242	t_assert("dns_name_countlabels", 1, T_REQUIRED, "%s", a35);
1243
1244	result = T_UNRESOLVED;
1245	fp = fopen("dns_name_countlabels_data", "r");
1246	if (fp != NULL) {
1247		line = 0;
1248		while ((p = t_fgetbs(fp)) != NULL) {
1249
1250			++line;
1251
1252			/*
1253			 * Skip comment lines.
1254			 */
1255			if ((isspace((unsigned char)*p)) || (*p == '#')) {
1256				(void)free(p);
1257				continue;
1258			}
1259
1260			cnt = bustline(p, Tokens);
1261			if (cnt == 2) {
1262				/*
1263				 * name, nlabels.
1264				 */
1265				result = test_dns_name_countlabels(Tokens[0],
1266							      atoi(Tokens[1]));
1267			} else {
1268				t_info("bad format at line %d\n", line);
1269			}
1270
1271			(void)free(p);
1272			t_result(result);
1273		}
1274		(void)fclose(fp);
1275	} else {
1276		t_info("Missing datafile dns_name_countlabels_data\n");
1277		t_result(result);
1278	}
1279}
1280
1281static const char *a36 =
1282		"when n is less than the number of labels in name, "
1283		"dns_name_getlabel(name, n, labelp) initializes labelp "
1284		"to point to the nth label in name";
1285
1286/*%
1287 * The strategy here is two take two dns names with a shared label in
1288 * different positions, get the two labels and compare them for equality.
1289 * If they don't match, dns_name_getlabel failed.
1290 */
1291
1292static int
1293test_dns_name_getlabel(char *test_name1, int label1_pos, char *test_name2,
1294		       int label2_pos)
1295{
1296	int		result;
1297	int		nfails;
1298	unsigned int	cnt;
1299	unsigned char	*p;
1300	unsigned char	*q;
1301	dns_name_t	dns_name1;
1302	dns_name_t	dns_name2;
1303	dns_label_t	dns_label1;
1304	dns_label_t	dns_label2;
1305	isc_result_t	dns_result;
1306
1307	nfails = 0;
1308	result = T_UNRESOLVED;
1309
1310	t_info("testing with %s and %s\n", test_name1, test_name2);
1311
1312	dns_result = dname_from_tname(test_name1, &dns_name1);
1313	if (dns_result == ISC_R_SUCCESS) {
1314		dns_result = dname_from_tname(test_name2, &dns_name2);
1315		if (dns_result == ISC_R_SUCCESS) {
1316			dns_name_getlabel(&dns_name1, label1_pos, &dns_label1);
1317			dns_name_getlabel(&dns_name2, label2_pos, &dns_label2);
1318			if (dns_label1.length != dns_label2.length) {
1319				t_info("label lengths differ\n");
1320				++nfails;
1321			}
1322			p = dns_label1.base;
1323			q = dns_label2.base;
1324			for (cnt = 0; cnt < dns_label1.length; ++cnt) {
1325				if (*p++ != *q++) {
1326					t_info("labels differ at position %d",
1327					       cnt);
1328					++nfails;
1329				}
1330			}
1331			if (nfails == 0)
1332				result = T_PASS;
1333			else
1334				result = T_FAIL;
1335		} else {
1336			t_info("dname_from_tname failed, result == %s",
1337			       dns_result_totext(result));
1338		}
1339	} else {
1340		t_info("dname_from_tname failed, result == %s",
1341		       dns_result_totext(result));
1342	}
1343	return (result);
1344}
1345
1346static void
1347t_dns_name_getlabel(void) {
1348	int		line;
1349	int		cnt;
1350	int		result;
1351	char		*p;
1352	FILE		*fp;
1353
1354	t_assert("dns_name_getlabel", 1, T_REQUIRED, "%s", a36);
1355
1356	result = T_UNRESOLVED;
1357	fp = fopen("dns_name_getlabel_data", "r");
1358	if (fp != NULL) {
1359		line = 0;
1360		while ((p = t_fgetbs(fp)) != NULL) {
1361
1362			++line;
1363
1364			/*
1365			 * Skip comment lines.
1366			 */
1367			if ((isspace((unsigned char)*p)) || (*p == '#')) {
1368				(void)free(p);
1369				continue;
1370			}
1371
1372			cnt = bustline(p, Tokens);
1373			if (cnt == 4) {
1374				/*
1375				 * name1, name2, nlabels.
1376				 */
1377				result = test_dns_name_getlabel(Tokens[0],
1378							      atoi(Tokens[1]),
1379								   Tokens[2],
1380							      atoi(Tokens[3]));
1381			} else {
1382				t_info("bad format at line %d\n", line);
1383			}
1384
1385			(void)free(p);
1386			t_result(result);
1387		}
1388		(void)fclose(fp);
1389	} else {
1390		t_info("Missing datafile dns_name_getlabel_data\n");
1391		t_result(result);
1392	}
1393}
1394
1395static const char *a37 =
1396		"when source contains at least first + n labels, "
1397		"dns_name_getlabelsequence(source, first, n, target) "
1398		"initializes target to point to the n label sequence of "
1399		"labels in source starting with first";
1400
1401/*%
1402 * We adopt a similiar strategy to that used by the dns_name_getlabel test.
1403 */
1404
1405static int
1406test_dns_name_getlabelsequence(char *test_name1, int label1_start,
1407			       char *test_name2, int label2_start, int range)
1408{
1409	int		result;
1410	int		nfails;
1411	unsigned int	cnt;
1412	unsigned char	*p;
1413	unsigned char	*q;
1414	dns_name_t	dns_name1;
1415	dns_name_t	dns_name2;
1416	dns_name_t	dns_targetname1;
1417	dns_name_t	dns_targetname2;
1418	isc_result_t	dns_result;
1419	isc_buffer_t	buffer1;
1420	isc_buffer_t	buffer2;
1421	unsigned char	junk1[BUFLEN];
1422	unsigned char	junk2[BUFLEN];
1423
1424	nfails = 0;
1425	result = T_UNRESOLVED;
1426	dns_result = dname_from_tname(test_name1, &dns_name1);
1427	if (dns_result == ISC_R_SUCCESS) {
1428		dns_result = dname_from_tname(test_name2, &dns_name2);
1429		if (dns_result == ISC_R_SUCCESS) {
1430			t_info("testing %s %s\n", test_name1, test_name2);
1431			dns_name_init(&dns_targetname1, NULL);
1432			dns_name_init(&dns_targetname2, NULL);
1433			dns_name_getlabelsequence(&dns_name1, label1_start,
1434						  range, &dns_targetname1);
1435			dns_name_getlabelsequence(&dns_name2, label2_start,
1436						  range, &dns_targetname2);
1437
1438			/*
1439			 * Now convert both targets to text for comparison.
1440			 */
1441			isc_buffer_init(&buffer1, junk1, BUFLEN);
1442			isc_buffer_init(&buffer2, junk2, BUFLEN);
1443			dns_name_totext(&dns_targetname1, ISC_TRUE, &buffer1);
1444			dns_name_totext(&dns_targetname2, ISC_TRUE, &buffer2);
1445			if (buffer1.used == buffer2.used) {
1446				p = buffer1.base;
1447				q = buffer2.base;
1448				for (cnt = 0; cnt < buffer1.used; ++cnt) {
1449					if (*p != *q) {
1450						++nfails;
1451						t_info("names differ at %d\n",
1452						       cnt);
1453						break;
1454					}
1455					++p; ++q;
1456				}
1457			} else {
1458				++nfails;
1459				t_info("lengths differ\n");
1460			}
1461			if (nfails == 0)
1462				result = T_PASS;
1463			else
1464				result = T_FAIL;
1465		} else {
1466			t_info("dname_from_tname failed, result == %s",
1467			       dns_result_totext(dns_result));
1468		}
1469	} else {
1470		t_info("dname_from_tname failed, result == %s",
1471		       dns_result_totext(dns_result));
1472	}
1473	return (result);
1474}
1475
1476static void
1477t_dns_name_getlabelsequence(void) {
1478	int		line;
1479	int		cnt;
1480	int		result;
1481	char		*p;
1482	FILE		*fp;
1483
1484	t_assert("dns_name_getlabelsequence", 1, T_REQUIRED, "%s", a37);
1485
1486	result = T_UNRESOLVED;
1487	fp = fopen("dns_name_getlabelsequence_data", "r");
1488	if (fp != NULL) {
1489		line = 0;
1490		while ((p = t_fgetbs(fp)) != NULL) {
1491
1492			++line;
1493
1494			/*
1495			 * Skip comment lines.
1496			 */
1497			if ((isspace((unsigned char)*p)) || (*p == '#')) {
1498				(void)free(p);
1499				continue;
1500			}
1501
1502			cnt = bustline(p, Tokens);
1503			if (cnt == 5) {
1504				/*
1505				 * name1, name2, nlabels.
1506				 */
1507				result = test_dns_name_getlabelsequence(
1508								   Tokens[0],
1509							      atoi(Tokens[1]),
1510								   Tokens[2],
1511							      atoi(Tokens[3]),
1512							      atoi(Tokens[4]));
1513			} else {
1514				t_info("bad format at line %d\n", line);
1515			}
1516
1517			(void)free(p);
1518			t_result(result);
1519		}
1520		(void)fclose(fp);
1521	} else {
1522		t_info("Missing datafile dns_name_getlabelsequence_data\n");
1523		t_result(result);
1524	}
1525}
1526
1527static const char *a38 =
1528		"dns_name_fromregion(name, region) converts a DNS name "
1529		"from a region representation to a name representation";
1530
1531static int
1532test_dns_name_fromregion(char *test_name) {
1533	int		result;
1534	int		order;
1535	unsigned int	nlabels;
1536	isc_result_t	dns_result;
1537	dns_name_t	dns_name1;
1538	dns_name_t	dns_name2;
1539	dns_namereln_t	dns_namereln;
1540	isc_region_t	region;
1541
1542	result = T_UNRESOLVED;
1543
1544	t_info("testing %s\n", test_name);
1545
1546	dns_result = dname_from_tname(test_name, &dns_name1);
1547	if (dns_result == ISC_R_SUCCESS) {
1548
1549		dns_name_toregion(&dns_name1, &region);
1550
1551		dns_name_init(&dns_name2, NULL);
1552		dns_name_fromregion(&dns_name2, &region);
1553		dns_namereln = dns_name_fullcompare(&dns_name1, &dns_name2,
1554						    &order, &nlabels);
1555		if (dns_namereln == dns_namereln_equal)
1556			result = T_PASS;
1557		else
1558			result = T_FAIL;
1559	} else {
1560		t_info("dname_from_tname failed, result == %s\n",
1561		       dns_result_totext(result));
1562	}
1563	return (result);
1564}
1565
1566static void
1567t_dns_name_fromregion(void) {
1568	int		line;
1569	int		cnt;
1570	int		result;
1571	char		*p;
1572	FILE		*fp;
1573
1574	t_assert("dns_name_fromregion", 1, T_REQUIRED, "%s", a38);
1575
1576	result = T_UNRESOLVED;
1577	fp = fopen("dns_name_fromregion_data", "r");
1578	if (fp != NULL) {
1579		line = 0;
1580		while ((p = t_fgetbs(fp)) != NULL) {
1581
1582			++line;
1583
1584			/*
1585			 * Skip comment lines.
1586			 */
1587			if ((isspace((unsigned char)*p)) || (*p == '#')) {
1588				(void)free(p);
1589				continue;
1590			}
1591
1592			cnt = bustline(p, Tokens);
1593			if (cnt == 1) {
1594				/*
1595				 * test_name.
1596				 */
1597				result = test_dns_name_fromregion(Tokens[0]);
1598			} else {
1599				t_info("bad format at line %d\n", line);
1600			}
1601
1602			(void)free(p);
1603			t_result(result);
1604		}
1605		(void)fclose(fp);
1606	} else {
1607		t_info("Missing datafile dns_name_fromregion_data\n");
1608		t_result(result);
1609	}
1610}
1611
1612static const char *a39 =
1613		"dns_name_toregion(name, region) converts a DNS name "
1614		"from a region representation to a name representation";
1615
1616static void
1617t_dns_name_toregion(void) {
1618	int		line;
1619	int		cnt;
1620	int		result;
1621	char		*p;
1622	FILE		*fp;
1623
1624	t_assert("dns_name_toregion", 1, T_REQUIRED, "%s", a39);
1625
1626	result = T_UNRESOLVED;
1627	fp = fopen("dns_name_toregion_data", "r");
1628	if (fp != NULL) {
1629		line = 0;
1630		while ((p = t_fgetbs(fp)) != NULL) {
1631
1632			++line;
1633
1634			/*
1635			 * Skip comment lines.
1636			 */
1637			if ((isspace((unsigned char)*p)) || (*p == '#')) {
1638				(void)free(p);
1639				continue;
1640			}
1641
1642			cnt = bustline(p, Tokens);
1643			if (cnt == 1) {
1644				/*
1645				 * test_name.
1646				 */
1647				result = test_dns_name_fromregion(Tokens[0]);
1648			} else {
1649				t_info("bad format at line %d\n", line);
1650			}
1651
1652			(void)free(p);
1653			t_result(result);
1654		}
1655		(void)fclose(fp);
1656	} else {
1657		t_info("Missing datafile dns_name_toregion_data\n");
1658		t_result(result);
1659	}
1660}
1661
1662static const char *a40 =
1663		"dns_name_fromtext(name, source, origin, downcase, target) "
1664		"converts the textual representation of a DNS name at source "
1665		"into uncompressed wire form at target, appending origin to "
1666		"the converted name if origin is non-NULL and converting "
1667		"upper case to lower case during conversion "
1668		"if downcase is true.";
1669
1670static int
1671test_dns_name_fromtext(char *test_name1, char *test_name2, char *test_origin,
1672		       unsigned int downcase)
1673{
1674	int		result;
1675	int		order;
1676	unsigned int	nlabels;
1677	unsigned char	junk1[BUFLEN];
1678	unsigned char	junk2[BUFLEN];
1679	unsigned char	junk3[BUFLEN];
1680	isc_buffer_t	binbuf1;
1681	isc_buffer_t	binbuf2;
1682	isc_buffer_t	binbuf3;
1683	isc_buffer_t	txtbuf1;
1684	isc_buffer_t	txtbuf2;
1685	isc_buffer_t	txtbuf3;
1686	dns_name_t	dns_name1;
1687	dns_name_t	dns_name2;
1688	dns_name_t	dns_name3;
1689	isc_result_t	dns_result;
1690	dns_namereln_t	dns_namereln;
1691
1692	t_info("testing %s %s %s\n", test_name1, test_name2, test_origin);
1693
1694	isc_buffer_init(&binbuf1, junk1, BUFLEN);
1695	isc_buffer_init(&binbuf2, junk2, BUFLEN);
1696	isc_buffer_init(&binbuf3, junk3, BUFLEN);
1697
1698	isc_buffer_init(&txtbuf1, test_name1, strlen(test_name1));
1699	isc_buffer_add(&txtbuf1, strlen(test_name1));
1700
1701	isc_buffer_init(&txtbuf2, test_name2, strlen(test_name2));
1702	isc_buffer_add(&txtbuf2, strlen(test_name2));
1703
1704	isc_buffer_init(&txtbuf3, test_origin, strlen(test_origin));
1705	isc_buffer_add(&txtbuf3, strlen(test_origin));
1706	dns_name_init(&dns_name1, NULL);
1707	dns_name_init(&dns_name2, NULL);
1708	dns_name_init(&dns_name3, NULL);
1709	dns_name_setbuffer(&dns_name1, &binbuf1);
1710	dns_name_setbuffer(&dns_name2, &binbuf2);
1711	dns_name_setbuffer(&dns_name3, &binbuf3);
1712
1713	dns_result = dns_name_fromtext(&dns_name3,  &txtbuf3, NULL, 0,
1714				       &binbuf3);
1715	if (dns_result != ISC_R_SUCCESS) {
1716		t_info("dns_name_fromtext(dns_name3) failed, result == %s\n",
1717			dns_result_totext(dns_result));
1718		return (T_FAIL);
1719	}
1720
1721	dns_result = dns_name_fromtext(&dns_name1, &txtbuf1, &dns_name3,
1722				       downcase, &binbuf1);
1723	if (dns_result != ISC_R_SUCCESS) {
1724		t_info("dns_name_fromtext(dns_name1) failed, result == %s\n",
1725		       dns_result_totext(dns_result));
1726		return (T_FAIL);
1727	}
1728
1729	dns_result = dns_name_fromtext(&dns_name2,  &txtbuf2, NULL, 0,
1730				       &binbuf2);
1731	if (dns_result != ISC_R_SUCCESS) {
1732		t_info("dns_name_fromtext(dns_name2) failed, result == %s\n",
1733		       dns_result_totext(dns_result));
1734		return (T_FAIL);
1735	}
1736
1737	dns_namereln = dns_name_fullcompare(&dns_name1, &dns_name2, &order,
1738					    &nlabels);
1739
1740	if (dns_namereln == dns_namereln_equal)
1741		result = T_PASS;
1742	else {
1743		t_info("dns_name_fullcompare returned %s\n",
1744		       dns_namereln_to_text(dns_namereln));
1745		result = T_FAIL;
1746	}
1747
1748	return (result);
1749}
1750
1751static void
1752t_dns_name_fromtext(void) {
1753	int		line;
1754	int		cnt;
1755	int		result;
1756	char		*p;
1757	FILE		*fp;
1758
1759	t_assert("dns_name_fromtext", 1, T_REQUIRED, "%s", a40);
1760
1761	result = T_UNRESOLVED;
1762	fp = fopen("dns_name_fromtext_data", "r");
1763	if (fp != NULL) {
1764		line = 0;
1765		while ((p = t_fgetbs(fp)) != NULL) {
1766
1767			++line;
1768
1769			/*
1770			 * Skip comment lines.
1771			 */
1772			if ((isspace((unsigned char)*p)) || (*p == '#')) {
1773				(void)free(p);
1774				continue;
1775			}
1776
1777			cnt = bustline(p, Tokens);
1778			if (cnt == 4) {
1779				/*
1780				 * test_name1, test_name2, test_origin,
1781				 * downcase.
1782				 */
1783				result = test_dns_name_fromtext(Tokens[0],
1784								Tokens[1],
1785								Tokens[2],
1786							   atoi(Tokens[3])
1787								== 0 ?
1788								0 :
1789							     DNS_NAME_DOWNCASE);
1790			} else {
1791				t_info("bad format at line %d\n", line);
1792			}
1793
1794			(void)free(p);
1795			t_result(result);
1796		}
1797		(void)fclose(fp);
1798	} else {
1799		t_info("Missing datafile dns_name_fromtext\n");
1800		t_result(result);
1801	}
1802}
1803
1804static const char *a41 =
1805		"dns_name_totext(name, omit_final_dot, target) converts "
1806		"the DNS name 'name' in wire format to textual format "
1807		"at target, and adds a final '.' to the name if "
1808		"omit_final_dot is false";
1809
1810static int
1811test_dns_name_totext(char *test_name, isc_boolean_t omit_final) {
1812	int		result;
1813	int		len;
1814	int		order;
1815	unsigned int	nlabels;
1816	unsigned char	junk1[BUFLEN];
1817	unsigned char	junk2[BUFLEN];
1818	unsigned char	junk3[BUFLEN];
1819	isc_buffer_t	buf1;
1820	isc_buffer_t	buf2;
1821	isc_buffer_t	buf3;
1822	dns_name_t	dns_name1;
1823	dns_name_t	dns_name2;
1824	isc_result_t	dns_result;
1825	dns_namereln_t	dns_namereln;
1826
1827	t_info("testing %s\n", test_name);
1828
1829	len = strlen(test_name);
1830	isc_buffer_init(&buf1, test_name, len);
1831	isc_buffer_add(&buf1, len);
1832
1833	dns_name_init(&dns_name1, NULL);
1834	isc_buffer_init(&buf2, junk2, BUFLEN);
1835
1836	/*
1837	 * Out of the data file to dns_name1.
1838	 */
1839	dns_result = dns_name_fromtext(&dns_name1, &buf1, NULL, 0, &buf2);
1840	if (dns_result != ISC_R_SUCCESS) {
1841		t_info("dns_name_fromtext failed, result == %s\n",
1842		       dns_result_totext(dns_result));
1843		return (T_UNRESOLVED);
1844	}
1845
1846	/*
1847	 * From dns_name1 into a text buffer.
1848	 */
1849	isc_buffer_invalidate(&buf1);
1850	isc_buffer_init(&buf1, junk1, BUFLEN);
1851	dns_result = dns_name_totext(&dns_name1, omit_final, &buf1);
1852	if (dns_result != ISC_R_SUCCESS) {
1853		t_info("dns_name_totext failed, result == %s\n",
1854		       dns_result_totext(dns_result));
1855		return (T_FAIL);
1856	}
1857
1858	/*
1859	 * From the text buffer into dns_name2.
1860	 */
1861	dns_name_init(&dns_name2, NULL);
1862	isc_buffer_init(&buf3, junk3, BUFLEN);
1863	dns_result = dns_name_fromtext(&dns_name2, &buf1, NULL, 0, &buf3);
1864	if (dns_result != ISC_R_SUCCESS) {
1865		t_info("dns_name_fromtext failed, result == %s\n",
1866		       dns_result_totext(dns_result));
1867		return (T_UNRESOLVED);
1868	}
1869
1870	dns_namereln = dns_name_fullcompare(&dns_name1, &dns_name2,
1871					    &order, &nlabels);
1872	if (dns_namereln == dns_namereln_equal)
1873		result = T_PASS;
1874	else {
1875		t_info("dns_name_fullcompare returned %s\n",
1876		       dns_namereln_to_text(dns_namereln));
1877		result = T_FAIL;
1878	}
1879
1880	return (result);
1881}
1882
1883static void
1884t_dns_name_totext(void) {
1885	int		line;
1886	int		cnt;
1887	int		result;
1888	char		*p;
1889	FILE		*fp;
1890
1891	t_assert("dns_name_totext", 1, T_REQUIRED, "%s", a41);
1892
1893	result = T_UNRESOLVED;
1894	fp = fopen("dns_name_totext_data", "r");
1895	if (fp != NULL) {
1896		line = 0;
1897		while ((p = t_fgetbs(fp)) != NULL) {
1898
1899			++line;
1900
1901			/*
1902			 * Skip comment lines.
1903			 */
1904			if ((isspace((unsigned char)*p)) || (*p == '#')) {
1905				(void)free(p);
1906				continue;
1907			}
1908
1909			cnt = bustline(p, Tokens);
1910			if (cnt == 2) {
1911				/*
1912				 * test_name, omit_final.
1913				 */
1914				result = test_dns_name_totext(Tokens[0],
1915							 atoi(Tokens[1]) == 0 ?
1916							      ISC_FALSE :
1917							      ISC_TRUE);
1918			} else {
1919				t_info("bad format at line %d\n", line);
1920			}
1921
1922			(void)free(p);
1923			t_result(result);
1924		}
1925		(void)fclose(fp);
1926	} else {
1927		t_info("Missing datafile dns_name_totext\n");
1928		t_result(result);
1929	}
1930}
1931
1932static const char *a42 =
1933		"dns_name_fromwire(name, source, dctx, downcase, target) "
1934		"converts the possibly compressed DNS name 'name' in wire "
1935		"format to canonicalized form at target, performing upper to "
1936		"lower case conversion if downcase is true, and returns "
1937		"ISC_R_SUCCESS";
1938
1939#if 0
1940	/*
1941	 * XXXRTH these tests appear to be broken, so I have
1942	 * disabled them.
1943	 */
1944static const char *a43 =
1945		"when a label length is invalid, dns_name_fromwire() "
1946		"returns DNS_R_FORMERR";
1947
1948static const char *a44 =
1949		"when a label type is invalid, dns_name_fromwire() "
1950		"returns DNS_R_BADLABELTYPE";
1951#endif
1952
1953static const char *a45 =
1954		"when a name length is invalid, dns_name_fromwire() "
1955		"returns DNS_R_FORMERR";
1956
1957static const char *a46 =
1958		"when a compression type is invalid, dns_name_fromwire() "
1959		"returns DNS_R_DISALLOWED";
1960
1961static const char *a47 =
1962		"when a bad compression pointer is encountered, "
1963		"dns_name_fromwire() returns DNS_R_BADPOINTER";
1964
1965static const char *a48 =
1966		"when input ends unexpected, dns_name_fromwire() "
1967		"returns ISC_R_UNEXPECTEDEND";
1968
1969static const char *a49 =
1970		"when there is not enough space in target, "
1971		"dns_name_fromwire(name, source, dcts, downcase, target) "
1972		"returns ISC_R_NOSPACE";
1973
1974static int
1975test_dns_name_fromwire(char *datafile_name, int testname_offset, int downcase,
1976		       unsigned int dc_method, char *exp_name,
1977		       isc_result_t exp_result, size_t buflen)
1978{
1979	int			result;
1980	int			order;
1981	unsigned int		nlabels;
1982	int			len;
1983	unsigned char		buf1[BIGBUFLEN];
1984	char			buf2[BUFLEN];
1985	isc_buffer_t		iscbuf1;
1986	isc_buffer_t		iscbuf2;
1987	dns_name_t		dns_name1;
1988	dns_name_t		dns_name2;
1989	isc_result_t		dns_result;
1990	dns_namereln_t		dns_namereln;
1991	dns_decompress_t	dctx;
1992
1993	t_info("testing using %s\n", datafile_name);
1994	len = getmsg(datafile_name, buf1, BIGBUFLEN, &iscbuf1);
1995
1996	isc_buffer_setactive(&iscbuf1, len);
1997	iscbuf1.current = testname_offset;
1998
1999	isc_buffer_init(&iscbuf2, buf2, buflen);
2000	dns_name_init(&dns_name1, NULL);
2001	dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_STRICT);
2002	dns_decompress_setmethods(&dctx, dc_method);
2003	dns_result = dns_name_fromwire(&dns_name1, &iscbuf1,
2004				       &dctx, downcase ? ISC_TRUE : ISC_FALSE,
2005				       &iscbuf2);
2006
2007	if ((dns_result == exp_result) && (exp_result == ISC_R_SUCCESS)) {
2008
2009		dns_result = dname_from_tname(exp_name, &dns_name2);
2010		if (dns_result == ISC_R_SUCCESS) {
2011			dns_namereln = dns_name_fullcompare(&dns_name1,
2012							    &dns_name2,
2013							    &order, &nlabels);
2014			if (dns_namereln != dns_namereln_equal) {
2015				t_info("dns_name_fullcompare  returned %s\n",
2016				       dns_namereln_to_text(dns_namereln));
2017				result = T_FAIL;
2018			} else {
2019				result = T_PASS;
2020			}
2021		} else {
2022			t_info("dns_name_fromtext %s failed, result = %s\n",
2023			       exp_name, dns_result_totext(dns_result));
2024			result = T_UNRESOLVED;
2025		}
2026	} else if (dns_result == exp_result) {
2027		result = T_PASS;
2028	} else {
2029		t_info("dns_name_fromwire returned %s\n",
2030		       dns_result_totext(dns_result));
2031		result = T_FAIL;
2032	}
2033
2034	return (result);
2035}
2036
2037static void
2038t_dns_name_fromwire_x(const char *testfile, size_t buflen) {
2039	int		line;
2040	int		cnt;
2041	int		result;
2042	unsigned int	dc_method;
2043	isc_result_t	exp_result;
2044	char		*p;
2045	char		*tok;
2046	FILE		*fp;
2047
2048	result = T_UNRESOLVED;
2049	fp = fopen(testfile, "r");
2050	if (fp != NULL) {
2051		line = 0;
2052		while ((p = t_fgetbs(fp)) != NULL) {
2053
2054			++line;
2055
2056			/*
2057			 * Skip comment lines.
2058			 */
2059			if ((isspace((unsigned char)*p)) || (*p == '#')) {
2060				(void)free(p);
2061				continue;
2062			}
2063
2064			cnt = bustline(p, Tokens);
2065			if (cnt == 6) {
2066				/*
2067				 *	datafile_name, testname_offset,
2068				 *	downcase, dc_method,
2069				 *	exp_name, exp_result.
2070				 */
2071
2072				tok = Tokens[5];
2073				exp_result = ISC_R_SUCCESS;
2074				if (! strcmp(tok, "ISC_R_SUCCESS"))
2075					exp_result = ISC_R_SUCCESS;
2076				else if (! strcmp(tok, "ISC_R_NOSPACE"))
2077					exp_result = ISC_R_NOSPACE;
2078				else if (! strcmp(tok, "DNS_R_BADLABELTYPE"))
2079					exp_result = DNS_R_BADLABELTYPE;
2080				else if (! strcmp(tok, "DNS_R_FORMERR"))
2081					exp_result = DNS_R_FORMERR;
2082				else if (! strcmp(tok, "DNS_R_BADPOINTER"))
2083					exp_result = DNS_R_BADPOINTER;
2084				else if (! strcmp(tok, "ISC_R_UNEXPECTEDEND"))
2085					exp_result = ISC_R_UNEXPECTEDEND;
2086				else if (! strcmp(tok, "DNS_R_TOOMANYHOPS"))
2087					exp_result = DNS_R_TOOMANYHOPS;
2088				else if (! strcmp(tok, "DNS_R_DISALLOWED"))
2089					exp_result = DNS_R_DISALLOWED;
2090				else if (! strcmp(tok, "DNS_R_NAMETOOLONG"))
2091					exp_result = DNS_R_NAMETOOLONG;
2092
2093				tok = Tokens[3];
2094				dc_method = DNS_COMPRESS_NONE;
2095				if (! strcmp(tok, "DNS_COMPRESS_GLOBAL14"))
2096					dc_method = DNS_COMPRESS_GLOBAL14;
2097				else if (! strcmp(tok, "DNS_COMPRESS_ALL"))
2098					dc_method = DNS_COMPRESS_ALL;
2099
2100				result = test_dns_name_fromwire(Tokens[0],
2101							   atoi(Tokens[1]),
2102							   atoi(Tokens[2]),
2103								dc_method,
2104								Tokens[4],
2105								exp_result,
2106								buflen);
2107			} else {
2108				t_info("bad format at line %d\n", line);
2109			}
2110
2111			(void)free(p);
2112			t_result(result);
2113		}
2114		(void)fclose(fp);
2115	} else {
2116		t_info("Missing datafile %s\n", testfile);
2117		t_result(result);
2118	}
2119}
2120
2121static void
2122t_dns_name_fromwire(void) {
2123	t_assert("dns_name_fromwire", 1, T_REQUIRED, "%s", a42);
2124	t_dns_name_fromwire_x("dns_name_fromwire_1_data", BUFLEN);
2125
2126#if 0
2127	/*
2128	 * XXXRTH these tests appear to be broken, so I have
2129	 * disabled them.
2130	 */
2131	t_assert("dns_name_fromwire", 2, T_REQUIRED, "%s", a43);
2132	t_dns_name_fromwire_x("dns_name_fromwire_2_data", BUFLEN);
2133
2134	t_assert("dns_name_fromwire", 3, T_REQUIRED, "%s", a44);
2135	t_dns_name_fromwire_x("dns_name_fromwire_3_data", BUFLEN);
2136#endif
2137
2138	t_assert("dns_name_fromwire", 4, T_REQUIRED, "%s", a45);
2139	t_dns_name_fromwire_x("dns_name_fromwire_4_data", BUFLEN);
2140
2141	t_assert("dns_name_fromwire", 5, T_REQUIRED, "%s", a46);
2142	t_dns_name_fromwire_x("dns_name_fromwire_5_data", BUFLEN);
2143
2144	t_assert("dns_name_fromwire", 6, T_REQUIRED, "%s", a47);
2145	t_dns_name_fromwire_x("dns_name_fromwire_6_data", BUFLEN);
2146
2147	t_assert("dns_name_fromwire", 7, T_REQUIRED, "%s", a48);
2148	t_dns_name_fromwire_x("dns_name_fromwire_7_data", BUFLEN);
2149
2150	t_assert("dns_name_fromwire", 9, T_REQUIRED, "%s", a49);
2151	t_dns_name_fromwire_x("dns_name_fromwire_8_data", 2);
2152}
2153
2154
2155static const char *a51 =
2156		"dns_name_towire(name, cctx, target) converts the DNS name "
2157		"'name' into wire format, compresses it as specified "
2158		"by the compression context cctx, stores the result in "
2159		"target and returns DNS_SUCCESS";
2160
2161static const char *a52 =
2162		"when not enough space exists in target, "
2163		"dns_name_towire(name, cctx, target) returns ISC_R_NOSPACE";
2164
2165static int
2166test_dns_name_towire(char *testname, unsigned int dc_method, char *exp_data,
2167		     int exp_data_len, isc_result_t exp_result, size_t buflen)
2168{
2169	int			result;
2170	int			val;
2171	int			len;
2172	unsigned char		buf2[BUFLEN];
2173	unsigned char		buf3[BUFLEN];
2174	isc_buffer_t		iscbuf1;
2175	isc_buffer_t		iscbuf2;
2176	isc_buffer_t		iscbuf3;
2177	dns_name_t		dns_name;
2178	isc_result_t		dns_result;
2179	isc_result_t		isc_result;
2180	dns_compress_t		cctx;
2181	isc_mem_t		*mctx;
2182
2183	t_info("testing using %s\n", testname);
2184
2185	result = T_UNRESOLVED;
2186	mctx = NULL;
2187
2188	isc_result = isc_mem_create(0, 0, &mctx);
2189	if (isc_result != ISC_R_SUCCESS) {
2190		t_info("isc_mem_create failed\n");
2191		return (result);
2192	}
2193	dns_compress_init(&cctx, -1, mctx);
2194	dns_compress_setmethods(&cctx, dc_method);
2195	dns_name_init(&dns_name, NULL);
2196	len = strlen(testname);
2197	isc_buffer_init(&iscbuf1, testname, len);
2198	isc_buffer_add(&iscbuf1, len);
2199	isc_buffer_init(&iscbuf2, buf2, BUFLEN);
2200	dns_result = dns_name_fromtext(&dns_name, &iscbuf1, NULL, 0, &iscbuf2);
2201	if (dns_result == ISC_R_SUCCESS) {
2202		isc_buffer_init(&iscbuf3, buf3, buflen);
2203		dns_result = dns_name_towire(&dns_name, &cctx, &iscbuf3);
2204		if (dns_result == exp_result) {
2205			if (exp_result == ISC_R_SUCCESS) {
2206				/*
2207				 * Compare results with expected data.
2208				 */
2209				val = chkdata(buf3, iscbuf3.used, exp_data,
2210					      exp_data_len);
2211				if (val == 0)
2212					result = T_PASS;
2213				else
2214					result = T_FAIL;
2215			} else
2216				result = T_PASS;
2217		} else {
2218			t_info("dns_name_towire unexpectedly returned %s\n",
2219			       dns_result_totext(dns_result));
2220			result = T_FAIL;
2221		}
2222	} else {
2223		t_info("dns_name_fromtext %s failed, result = %s\n",
2224				testname, dns_result_totext(dns_result));
2225	}
2226	return (result);
2227}
2228
2229static void
2230t_dns_name_towire_x(const char *testfile, size_t buflen) {
2231	int		line;
2232	int		cnt;
2233	int		result;
2234	unsigned int	dc_method;
2235	isc_result_t	exp_result;
2236	char		*p;
2237	FILE		*fp;
2238
2239	result = T_UNRESOLVED;
2240	fp = fopen(testfile, "r");
2241	if (fp != NULL) {
2242		line = 0;
2243		while ((p = t_fgetbs(fp)) != NULL) {
2244
2245			++line;
2246
2247			/*
2248			 * Skip comment lines.
2249			 */
2250			if ((isspace((unsigned char)*p)) || (*p == '#')) {
2251				(void)free(p);
2252				continue;
2253			}
2254
2255			cnt = bustline(p, Tokens);
2256			if (cnt == 5) {
2257				/*
2258				 *	testname, dc_method,
2259				 *	exp_data, exp_data_len,
2260				 *	exp_result.
2261				 */
2262
2263				dc_method = t_dc_method_fromtext(Tokens[3]);
2264				exp_result = t_dns_result_fromtext(Tokens[4]);
2265
2266				result = test_dns_name_towire(Tokens[0],
2267							      dc_method,
2268							      Tokens[2],
2269							      atoi(Tokens[3]),
2270							      exp_result,
2271							      buflen);
2272			} else {
2273				t_info("bad format at line %d\n", line);
2274			}
2275
2276			(void)free(p);
2277			t_result(result);
2278		}
2279		(void)fclose(fp);
2280	} else {
2281		t_info("Missing datafile %s\n", testfile);
2282		t_result(result);
2283	}
2284}
2285
2286static void
2287t_dns_name_towire_1(void) {
2288	t_assert("dns_name_towire", 1, T_REQUIRED, "%s", a51);
2289	t_dns_name_towire_x("dns_name_towire_1_data", BUFLEN);
2290}
2291
2292static void
2293t_dns_name_towire_2(void) {
2294	t_assert("dns_name_towire", 2, T_REQUIRED, "%s", a52);
2295	t_dns_name_towire_x("dns_name_towire_2_data", 2);
2296}
2297
2298static void
2299t_dns_name_towire(void) {
2300	t_dns_name_towire_1();
2301	t_dns_name_towire_2();
2302}
2303
2304#if 0 /* This is silly.  A test should either exist, or not, but not
2305       * one that just returns "UNTESTED."
2306       */
2307static const char *a53 =
2308		"dns_name_concatenate(prefix, suffix, name, target) "
2309		"concatenates prefix and suffix, stores the result "
2310		"in target, canonicalizes any bitstring labels "
2311		"and returns ISC_R_SUCCESS";
2312
2313static void
2314t_dns_name_concatenate(void) {
2315	t_assert("dns_name_concatenate", 1, T_REQUIRED, "%s", a53);
2316	t_result(T_UNTESTED);
2317}
2318#endif
2319
2320testspec_t T_testlist[] = {
2321	{	t_dns_name_init,		"dns_name_init"		},
2322	{	t_dns_name_invalidate,		"dns_name_invalidate"	},
2323	{	t_dns_name_setbuffer,		"dns_name_setbuffer"	},
2324	{	t_dns_name_hasbuffer,		"dns_name_hasbuffer"	},
2325	{	t_dns_name_isabsolute,		"dns_name_isabsolute"	},
2326	{	t_dns_name_hash,		"dns_name_hash"		},
2327	{	t_dns_name_fullcompare,		"dns_name_fullcompare"	},
2328	{	t_dns_name_compare,		"dns_name_compare"	},
2329	{	t_dns_name_rdatacompare,	"dns_name_rdatacompare"	},
2330	{	t_dns_name_issubdomain,		"dns_name_issubdomain"	},
2331	{	t_dns_name_countlabels,		"dns_name_countlabels"	},
2332	{	t_dns_name_getlabel,		"dns_name_getlabel"	},
2333	{	t_dns_name_getlabelsequence,	"dns_name_getlabelsequence" },
2334	{	t_dns_name_fromregion,		"dns_name_fromregion"	},
2335	{	t_dns_name_toregion,		"dns_name_toregion"	},
2336	{	t_dns_name_fromwire,		"dns_name_fromwire"	},
2337	{	t_dns_name_towire,		"dns_name_towire"	},
2338	{	t_dns_name_fromtext,		"dns_name_fromtext"	},
2339	{	t_dns_name_totext,		"dns_name_totext"	},
2340#if 0
2341	{	t_dns_name_concatenate,		"dns_name_concatenate"	},
2342#endif
2343	{	NULL,				NULL			}
2344
2345};
2346
2347