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