1/*
2 * Copyright (C) 2004-2007  Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1999-2001  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: compress_test.c,v 1.34 2007/06/18 23:47:26 tbox Exp $ */
19
20/*! \file */
21
22#include <config.h>
23
24#include <stdlib.h>
25#include <string.h>
26
27#include <isc/buffer.h>
28#include <isc/commandline.h>
29#include <isc/mem.h>
30#include <isc/util.h>
31
32#include <dns/compress.h>
33#include <dns/name.h>
34
35unsigned char plain1[] = "\003yyy\003foo";
36unsigned char plain2[] = "\003bar\003yyy\003foo";
37unsigned char plain3[] = "\003xxx\003bar\003foo";
38unsigned char plain[] = "\003yyy\003foo\0\003bar\003yyy\003foo\0\003"
39			"bar\003yyy\003foo\0\003xxx\003bar\003foo";
40
41/*
42 * Result concatenate (plain1, plain2, plain2, plain3).
43 */
44int raw = 0;
45int verbose = 0;
46
47void
48test(unsigned int, dns_name_t *, dns_name_t *, dns_name_t *,
49     unsigned char *, unsigned int);
50
51int
52main(int argc, char *argv[]) {
53	dns_name_t name1;
54	dns_name_t name2;
55	dns_name_t name3;
56	isc_region_t region;
57	int c;
58
59	while ((c = isc_commandline_parse(argc, argv, "rv")) != -1) {
60		switch (c) {
61		case 'r':
62			raw++;
63			break;
64		case 'v':
65			verbose++;
66			break;
67		}
68	}
69
70	dns_name_init(&name1, NULL);
71	region.base = plain1;
72	region.length = sizeof(plain1);
73	dns_name_fromregion(&name1, &region);
74
75	dns_name_init(&name2, NULL);
76	region.base = plain2;
77	region.length = sizeof(plain2);
78	dns_name_fromregion(&name2, &region);
79
80	dns_name_init(&name3, NULL);
81	region.base = plain3;
82	region.length = sizeof(plain3);
83	dns_name_fromregion(&name3, &region);
84
85	test(DNS_COMPRESS_NONE, &name1, &name2, &name3, plain, sizeof(plain));
86	test(DNS_COMPRESS_GLOBAL14, &name1, &name2, &name3, plain,
87	     sizeof(plain));
88	test(DNS_COMPRESS_ALL, &name1, &name2, &name3, plain, sizeof(plain));
89
90	return (0);
91}
92
93void
94test(unsigned int allowed, dns_name_t *name1, dns_name_t *name2,
95     dns_name_t *name3, unsigned char *result, unsigned int length)
96{
97	isc_mem_t *mctx = NULL;
98	dns_compress_t cctx;
99	dns_decompress_t dctx;
100	isc_buffer_t source;
101	isc_buffer_t target;
102	dns_name_t name;
103	unsigned char buf1[1024];
104	unsigned char buf2[1024];
105
106	if (verbose) {
107		const char *s;
108		switch (allowed) {
109		case DNS_COMPRESS_NONE: s = "DNS_COMPRESS_NONE"; break;
110		case DNS_COMPRESS_GLOBAL14: s = "DNS_COMPRESS_GLOBAL14"; break;
111		/* case DNS_COMPRESS_ALL: s = "DNS_COMPRESS_ALL"; break; */
112		default: s = "UNKNOWN"; break;
113		}
114		fprintf(stdout, "Allowed = %s\n", s);
115	}
116	RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
117	isc_buffer_init(&source, buf1, sizeof(buf1));
118	RUNTIME_CHECK(dns_compress_init(&cctx, -1, mctx) == ISC_R_SUCCESS);
119
120	RUNTIME_CHECK(dns_name_towire(name1, &cctx, &source) == ISC_R_SUCCESS);
121
122	/*
123	RUNTIME_CHECK(dns_compress_localinit(&cctx, name1, &source) ==
124		      ISC_R_SUCCESS);
125	*/
126	dns_compress_setmethods(&cctx, allowed);
127	RUNTIME_CHECK(dns_name_towire(name2, &cctx, &source) == ISC_R_SUCCESS);
128	RUNTIME_CHECK(dns_name_towire(name2, &cctx, &source) == ISC_R_SUCCESS);
129	RUNTIME_CHECK(dns_name_towire(name3, &cctx, &source) == ISC_R_SUCCESS);
130
131	/*
132	dns_compress_localinvalidate(&cctx);
133	*/
134	dns_compress_rollback(&cctx, 0);	/* testing only */
135	dns_compress_invalidate(&cctx);
136
137	if (raw) {
138		unsigned int i;
139		for (i = 0; i < source.used; /* */ ) {
140			fprintf(stdout, "%02x",
141				((unsigned char *)source.base)[i]);
142			if ((++i % 20) == 0)
143				fputs("\n", stdout);
144			else
145				if (i == source.used)
146					fputs("\n", stdout);
147				else
148					fputs(" ", stdout);
149		}
150	}
151
152	isc_buffer_setactive(&source, source.used);
153	isc_buffer_init(&target, buf2, sizeof(buf2));
154	dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_STRICT);
155
156	dns_name_init(&name, NULL);
157	RUNTIME_CHECK(dns_name_fromwire(&name, &source, &dctx, ISC_FALSE,
158					&target) == ISC_R_SUCCESS);
159	dns_decompress_setmethods(&dctx, allowed);
160	/*
161	dns_decompress_localinit(&dctx, &name, &source);
162	*/
163	RUNTIME_CHECK(dns_name_fromwire(&name, &source, &dctx, ISC_FALSE,
164					&target) == ISC_R_SUCCESS);
165	RUNTIME_CHECK(dns_name_fromwire(&name, &source, &dctx, ISC_FALSE,
166					&target) == ISC_R_SUCCESS);
167	RUNTIME_CHECK(dns_name_fromwire(&name, &source, &dctx, ISC_FALSE,
168					&target) == ISC_R_SUCCESS);
169	/*
170	dns_decompress_localinvalidate(&dctx);
171	*/
172	dns_decompress_invalidate(&dctx);
173
174	if (raw) {
175		unsigned int i;
176		for (i = 0; i < target.used; /* */ ) {
177			fprintf(stdout, "%02x",
178				((unsigned char *)target.base)[i]);
179			if ((++i % 20) == 0)
180				fputs("\n", stdout);
181			else
182				if (i == target.used)
183					fputs("\n", stdout);
184				else
185					fputs(" ", stdout);
186		}
187		fputs("\n", stdout);
188		fflush(stdout);
189	}
190
191	RUNTIME_CHECK(target.used == length);
192	RUNTIME_CHECK(memcmp(target.base, result, target.used) == 0);
193	isc_mem_destroy(&mctx);
194}
195