1/*
2 * testcode/unitmsgparse.c - unit test for msg parse routines.
3 *
4 * Copyright (c) 2007, NLnet Labs. All rights reserved.
5 *
6 * This software is open source.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 *
15 * Redistributions in binary form must reproduce the above copyright notice,
16 * this list of conditions and the following disclaimer in the documentation
17 * and/or other materials provided with the distribution.
18 *
19 * Neither the name of the NLNET LABS nor the names of its contributors may
20 * be used to endorse or promote products derived from this software without
21 * specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 *
35 */
36/**
37 * \file
38 * Calls msg parse unit tests. Exits with code 1 on a failure.
39 */
40
41#include "config.h"
42#include <sys/time.h>
43#include "util/log.h"
44#include "testcode/unitmain.h"
45#include "util/data/msgparse.h"
46#include "util/data/msgreply.h"
47#include "util/data/msgencode.h"
48#include "util/data/dname.h"
49#include "util/alloc.h"
50#include "util/regional.h"
51#include "util/net_help.h"
52#include "testcode/readhex.h"
53#include "testcode/testpkts.h"
54#include "sldns/sbuffer.h"
55#include "sldns/str2wire.h"
56#include "sldns/wire2str.h"
57
58/** verbose message parse unit test */
59static int vbmp = 0;
60/** do not accept formerr */
61static int check_formerr_gone = 0;
62/** if matching within a section should disregard the order of RRs. */
63static int matches_nolocation = 0;
64/** see if RRSIGs are properly matched to RRsets. */
65static int check_rrsigs = 0;
66/** do not check buffer sameness */
67static int check_nosameness = 0;
68
69/** see if buffers contain the same packet */
70static int
71test_buffers(sldns_buffer* pkt, sldns_buffer* out)
72{
73	/* check binary same */
74	if(sldns_buffer_limit(pkt) == sldns_buffer_limit(out) &&
75		memcmp(sldns_buffer_begin(pkt), sldns_buffer_begin(out),
76			sldns_buffer_limit(pkt)) == 0) {
77		if(vbmp) printf("binary the same (length=%u)\n",
78				(unsigned)sldns_buffer_limit(pkt));
79		return 1;
80	}
81
82	if(vbmp) {
83		size_t sz = 16;
84		size_t count;
85		size_t lim = sldns_buffer_limit(out);
86		if(sldns_buffer_limit(pkt) < lim)
87			lim = sldns_buffer_limit(pkt);
88		for(count=0; count<lim; count+=sz) {
89			size_t rem = sz;
90			if(lim-count < sz) rem = lim-count;
91			if(memcmp(sldns_buffer_at(pkt, count),
92				sldns_buffer_at(out, count), rem) == 0) {
93				log_info("same %d %d", (int)count, (int)rem);
94				log_hex("same: ", sldns_buffer_at(pkt, count),
95					rem);
96			} else {
97				log_info("diff %d %d", (int)count, (int)rem);
98				log_hex("difp: ", sldns_buffer_at(pkt, count),
99					rem);
100				log_hex("difo: ", sldns_buffer_at(out, count),
101					rem);
102			}
103		}
104	}
105
106	/* check if it 'means the same' */
107	if(vbmp) {
108		char* s1, *s2;
109		log_buf(0, "orig in hex", pkt);
110		log_buf(0, "unbound out in hex", out);
111		printf("\npacket from unbound (%d):\n",
112			(int)sldns_buffer_limit(out));
113		s1 = sldns_wire2str_pkt(sldns_buffer_begin(out),
114			sldns_buffer_limit(out));
115		printf("%s\n", s1?s1:"null");
116		free(s1);
117
118		printf("\npacket original (%d):\n",
119			(int)sldns_buffer_limit(pkt));
120		s2 = sldns_wire2str_pkt(sldns_buffer_begin(pkt),
121			sldns_buffer_limit(pkt));
122		printf("%s\n", s2?s2:"null");
123		free(s2);
124		printf("\n");
125	}
126	/* if it had two EDNS sections, skip comparison */
127	if(1) {
128		char* s = sldns_wire2str_pkt(sldns_buffer_begin(pkt),
129			sldns_buffer_limit(pkt));
130		char* e1 = strstr(s, "; EDNS:");
131		if(e1 && strstr(e1+4, "; EDNS:")) {
132			free(s);
133			return 0;
134		}
135		free(s);
136	}
137	/* compare packets */
138	unit_assert(match_all(sldns_buffer_begin(pkt), sldns_buffer_limit(pkt),
139		sldns_buffer_begin(out), sldns_buffer_limit(out), 1,
140		matches_nolocation, 0));
141	return 0;
142}
143
144/** check if unbound formerr equals ldns formerr */
145static void
146checkformerr(sldns_buffer* pkt)
147{
148	int status = 0;
149	char* s = sldns_wire2str_pkt(sldns_buffer_begin(pkt),
150		sldns_buffer_limit(pkt));
151	if(!s) fatal_exit("out of memory");
152	if(strstr(s, "Error")) status = 1;
153	if(strstr(s, "error")) status = 1;
154	if(status == 0) {
155		printf("Formerr, but ldns gives packet:\n");
156		printf("%s\n", s);
157		free(s);
158		exit(1);
159	}
160	free(s);
161	unit_assert(status != 0);
162}
163
164/** performance test message encoding */
165static void
166perf_encode(struct query_info* qi, struct reply_info* rep, uint16_t id,
167	uint16_t flags, sldns_buffer* out, time_t timenow,
168	struct edns_data* edns)
169{
170	static int num = 0;
171	int ret;
172	size_t max = 10000;
173	size_t i;
174	struct timeval start, end;
175	double dt;
176	struct regional* r2 = regional_create();
177	if(gettimeofday(&start, NULL) < 0)
178		fatal_exit("gettimeofday: %s", strerror(errno));
179	/* encode a couple times */
180	for(i=0; i<max; i++) {
181		ret = reply_info_encode(qi, rep, id, flags, out, timenow,
182			r2, 65535, (int)(edns->bits & EDNS_DO), 0);
183		unit_assert(ret != 0); /* udp packets should fit */
184		attach_edns_record(out, edns);
185		regional_free_all(r2);
186	}
187	if(gettimeofday(&end, NULL) < 0)
188		fatal_exit("gettimeofday: %s", strerror(errno));
189	/* time in millisec */
190	dt = (double)(end.tv_sec - start.tv_sec)*1000. +
191		((double)end.tv_usec - (double)start.tv_usec)/1000.;
192	printf("[%d] did %u in %g msec for %f encode/sec size %d\n", num++,
193		(unsigned)max, dt, (double)max / (dt/1000.),
194		(int)sldns_buffer_limit(out));
195	regional_destroy(r2);
196}
197
198/** perf test a packet */
199static void
200perftestpkt(sldns_buffer* pkt, struct alloc_cache* alloc, sldns_buffer* out,
201	const char* hex)
202{
203	struct query_info qi;
204	struct reply_info* rep = 0;
205	int ret;
206	uint16_t id;
207	uint16_t flags;
208	time_t timenow = 0;
209	struct regional* region = regional_create();
210	struct edns_data edns;
211
212	hex_to_buf(pkt, hex);
213	memmove(&id, sldns_buffer_begin(pkt), sizeof(id));
214	if(sldns_buffer_limit(pkt) < 2)
215		flags = 0;
216	else	memmove(&flags, sldns_buffer_at(pkt, 2), sizeof(flags));
217	flags = ntohs(flags);
218	ret = reply_info_parse(pkt, alloc, &qi, &rep, region, &edns);
219	if(ret != 0) {
220		char rbuf[16];
221		sldns_wire2str_rcode_buf(ret, rbuf, sizeof(rbuf));
222		if(vbmp) printf("parse code %d: %s\n", ret, rbuf);
223		if(ret == LDNS_RCODE_FORMERR)
224			checkformerr(pkt);
225		unit_assert(ret != LDNS_RCODE_SERVFAIL);
226	} else {
227		perf_encode(&qi, rep, id, flags, out, timenow, &edns);
228	}
229
230	query_info_clear(&qi);
231	reply_info_parsedelete(rep, alloc);
232	regional_destroy(region);
233}
234
235/** print packed rrset */
236static void
237print_rrset(struct ub_packed_rrset_key* rrset)
238{
239	struct packed_rrset_data* d = (struct packed_rrset_data*)rrset->
240	                entry.data;
241	char buf[65535];
242	size_t i;
243	for(i=0; i<d->count+d->rrsig_count; i++) {
244		if(!packed_rr_to_string(rrset, i, 0, buf, sizeof(buf)))
245			printf("failedtoconvert %d\n", (int)i);
246		else
247			printf("%s\n", buf);
248	}
249}
250
251/** debug print a packet that failed */
252static void
253print_packet_rrsets(struct query_info* qinfo, struct reply_info* rep)
254{
255	size_t i;
256	log_query_info(0, "failed query", qinfo);
257	printf(";; ANSWER SECTION (%d rrsets)\n", (int)rep->an_numrrsets);
258	for(i=0; i<rep->an_numrrsets; i++) {
259		printf("; rrset %d\n", (int)i);
260		print_rrset(rep->rrsets[i]);
261	}
262	printf(";; AUTHORITY SECTION (%d rrsets)\n", (int)rep->ns_numrrsets);
263	for(i=rep->an_numrrsets; i<rep->an_numrrsets+rep->ns_numrrsets; i++) {
264		printf("; rrset %d\n", (int)i);
265		print_rrset(rep->rrsets[i]);
266	}
267	printf(";; ADDITIONAL SECTION (%d rrsets)\n", (int)rep->ar_numrrsets);
268	for(i=rep->an_numrrsets+rep->ns_numrrsets; i<rep->rrset_count; i++) {
269		printf("; rrset %d\n", (int)i);
270		print_rrset(rep->rrsets[i]);
271	}
272	printf(";; packet end\n");
273}
274
275/** check that there is no data element that matches the RRSIG */
276static int
277no_data_for_rrsig(struct reply_info* rep, struct ub_packed_rrset_key* rrsig)
278{
279	size_t i;
280	for(i=0; i<rep->rrset_count; i++) {
281		if(ntohs(rep->rrsets[i]->rk.type) == LDNS_RR_TYPE_RRSIG)
282			continue;
283		if(query_dname_compare(rep->rrsets[i]->rk.dname,
284			rrsig->rk.dname) == 0)
285			/* only name is compared right now */
286			return 0;
287	}
288	return 1;
289}
290
291/** check RRSIGs in packet */
292static void
293check_the_rrsigs(struct query_info* qinfo, struct reply_info* rep)
294{
295	/* every RRSIG must be matched to an RRset */
296	size_t i;
297	for(i=0; i<rep->rrset_count; i++) {
298		struct ub_packed_rrset_key* s = rep->rrsets[i];
299		if(ntohs(s->rk.type) == LDNS_RR_TYPE_RRSIG) {
300			/* see if really a problem, i.e. is there a data
301			 * element. */
302			if(no_data_for_rrsig(rep, rep->rrsets[i]))
303				continue;
304			log_dns_msg("rrsig failed for packet", qinfo, rep);
305			print_packet_rrsets(qinfo, rep);
306			printf("failed rrset is nr %d\n", (int)i);
307			unit_assert(0);
308		}
309	}
310}
311
312/** test a packet */
313static void
314testpkt(sldns_buffer* pkt, struct alloc_cache* alloc, sldns_buffer* out,
315	const char* hex)
316{
317	struct query_info qi;
318	struct reply_info* rep = 0;
319	int ret;
320	uint16_t id;
321	uint16_t flags;
322	uint32_t timenow = 0;
323	struct regional* region = regional_create();
324	struct edns_data edns;
325
326	hex_to_buf(pkt, hex);
327	memmove(&id, sldns_buffer_begin(pkt), sizeof(id));
328	if(sldns_buffer_limit(pkt) < 2)
329		flags = 0;
330	else	memmove(&flags, sldns_buffer_at(pkt, 2), sizeof(flags));
331	flags = ntohs(flags);
332	ret = reply_info_parse(pkt, alloc, &qi, &rep, region, &edns);
333	if(ret != 0) {
334		char rbuf[16];
335		sldns_wire2str_rcode_buf(ret, rbuf, sizeof(rbuf));
336		if(vbmp) printf("parse code %d: %s\n", ret, rbuf);
337		if(ret == LDNS_RCODE_FORMERR) {
338			unit_assert(!check_formerr_gone);
339			checkformerr(pkt);
340		}
341		unit_assert(ret != LDNS_RCODE_SERVFAIL);
342	} else if(!check_formerr_gone) {
343		const size_t lim = 512;
344		ret = reply_info_encode(&qi, rep, id, flags, out, timenow,
345			region, 65535, (int)(edns.bits & EDNS_DO), 0);
346		unit_assert(ret != 0); /* udp packets should fit */
347		attach_edns_record(out, &edns);
348		if(vbmp) printf("inlen %u outlen %u\n",
349			(unsigned)sldns_buffer_limit(pkt),
350			(unsigned)sldns_buffer_limit(out));
351		if(!check_nosameness)
352			test_buffers(pkt, out);
353		if(check_rrsigs)
354			check_the_rrsigs(&qi, rep);
355
356		if(sldns_buffer_limit(out) > lim) {
357			ret = reply_info_encode(&qi, rep, id, flags, out,
358				timenow, region,
359				lim - calc_edns_field_size(&edns),
360				(int)(edns.bits & EDNS_DO), 0);
361			unit_assert(ret != 0); /* should fit, but with TC */
362			attach_edns_record(out, &edns);
363			if( LDNS_QDCOUNT(sldns_buffer_begin(out)) !=
364				LDNS_QDCOUNT(sldns_buffer_begin(pkt)) ||
365				LDNS_ANCOUNT(sldns_buffer_begin(out)) !=
366				LDNS_ANCOUNT(sldns_buffer_begin(pkt)) ||
367				LDNS_NSCOUNT(sldns_buffer_begin(out)) !=
368				LDNS_NSCOUNT(sldns_buffer_begin(pkt)))
369				unit_assert(
370				LDNS_TC_WIRE(sldns_buffer_begin(out)));
371				/* must set TC bit if shortened */
372			unit_assert(sldns_buffer_limit(out) <= lim);
373		}
374	}
375
376	query_info_clear(&qi);
377	reply_info_parsedelete(rep, alloc);
378	regional_destroy(region);
379}
380
381/** simple test of parsing */
382static void
383simpletest(sldns_buffer* pkt, struct alloc_cache* alloc, sldns_buffer* out)
384{
385	/* a root query  drill -q - */
386	testpkt(pkt, alloc, out,
387		" c5 40 01 00 00 01 00 00 00 00 00 00 00 00 02 00 01 ");
388
389	/* very small packet */
390	testpkt(pkt, alloc, out,
391"; 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19\n"
392";-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --\n"
393"74 0c 85 83 00 01 00 00 00 01 00 00 03 62 6c 61 09 6e 6c 6e    ;          1-  20\n"
394"65 74 6c 61 62 73 02 6e 6c 00 00 0f 00 01 09 6e 6c 6e 65 74    ;         21-  40\n"
395"6c 61 62 73 02 6e 6c 00 00 06 00 01 00 00 46 50 00 40 04 6f    ;         41-  60\n"
396"70 65 6e 09 6e 6c 6e 65 74 6c 61 62 73 02 6e 6c 00 0a 68 6f    ;         61-  80\n"
397"73 74 6d 61 73 74 65 72 09 6e 6c 6e 65 74 6c 61 62 73 02 6e    ;         81- 100\n"
398"6c 00 77 a1 02 58 00 00 70 80 00 00 1c 20 00 09 3a 80 00 00    ;        101- 120\n"
399"46 50\n");
400
401	/* a root reply  drill -w - */
402	testpkt(pkt, alloc, out,
403	" ; 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19\n"
404	" ;-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --\n"
405	" 97 3f 81 80 00 01 00 0d 00 00 00 02 00 00 02 00 01 00 00 02    ;          1-  20\n"
406	" 00 01 00 06 6d 38 00 14 01 49 0c 52 4f 4f 54 2d 53 45 52 56    ;         21-  40\n"
407	" 45 52 53 03 4e 45 54 00 00 00 02 00 01 00 06 6d 38 00 14 01    ;         41-  60\n"
408	" 4a 0c 52 4f 4f 54 2d 53 45 52 56 45 52 53 03 4e 45 54 00 00    ;         61-  80\n"
409	" 00 02 00 01 00 06 6d 38 00 14 01 4b 0c 52 4f 4f 54 2d 53 45    ;         81- 100\n"
410	" 52 56 45 52 53 03 4e 45 54 00 00 00 02 00 01 00 06 6d 38 00    ;        101- 120\n"
411	" 14 01 4c 0c 52 4f 4f 54 2d 53 45 52 56 45 52 53 03 4e 45 54    ;        121- 140\n"
412	" 00 00 00 02 00 01 00 06 6d 38 00 14 01 4d 0c 52 4f 4f 54 2d    ;        141- 160\n"
413	" 53 45 52 56 45 52 53 03 4e 45 54 00 00 00 02 00 01 00 06 6d    ;        161- 180\n"
414	" 38 00 14 01 41 0c 52 4f 4f 54 2d 53 45 52 56 45 52 53 03 4e    ;        181- 200\n"
415	" 45 54 00 00 00 02 00 01 00 06 6d 38 00 14 01 42 0c 52 4f 4f    ;        201- 220\n"
416	" 54 2d 53 45 52 56 45 52 53 03 4e 45 54 00 00 00 02 00 01 00    ;        221- 240\n"
417	" 06 6d 38 00 14 01 43 0c 52 4f 4f 54 2d 53 45 52 56 45 52 53    ;        241- 260\n"
418	" 03 4e 45 54 00 00 00 02 00 01 00 06 6d 38 00 14 01 44 0c 52    ;        261- 280\n"
419	" 4f 4f 54 2d 53 45 52 56 45 52 53 03 4e 45 54 00 00 00 02 00    ;        281- 300\n"
420	" 01 00 06 6d 38 00 14 01 45 0c 52 4f 4f 54 2d 53 45 52 56 45    ;        301- 320\n"
421	" 52 53 03 4e 45 54 00 00 00 02 00 01 00 06 6d 38 00 14 01 46    ;        321- 340\n"
422	" 0c 52 4f 4f 54 2d 53 45 52 56 45 52 53 03 4e 45 54 00 00 00    ;        341- 360\n"
423	" 02 00 01 00 06 6d 38 00 14 01 47 0c 52 4f 4f 54 2d 53 45 52    ;        361- 380\n"
424	" 56 45 52 53 03 4e 45 54 00 00 00 02 00 01 00 06 6d 38 00 14    ;        381- 400\n"
425	" 01 48 0c 52 4f 4f 54 2d 53 45 52 56 45 52 53 03 4e 45 54 00    ;        401- 420\n"
426	" 01 41 0c 52 4f 4f 54 2d 53 45 52 56 45 52 53 03 4e 45 54 00    ;        421- 440\n"
427	" 00 01 00 01 00 02 64 b9 00 04 c6 29 00 04 01 4a 0c 52 4f 4f    ;        441- 460\n"
428	" 54 2d 53 45 52 56 45 52 53 03 4e 45 54 00 00 01 00 01 00 02    ;        461- 480\n"
429	" 64 b9 00 04 c0 3a 80 1e  ");
430
431	/* root delegation from unbound trace with new AAAA glue */
432	perftestpkt(pkt, alloc, out,
433	"55BC84000001000D00000014000002000100000200010007E900001401610C726F6F742D73657276657273036E65740000000200010007E90000040162C01E00000200010007E90000040163C01E00000200010007E90000040164C01E00000200010007E90000040165C01E00000200010007E90000040166C01E00000200010007E90000040167C01E00000200010007E90000040168C01E00000200010007E90000040169C01E00000200010007E9000004016AC01E00000200010007E9000004016BC01E00000200010007E9000004016CC01E00000200010007E9000004016DC01EC01C000100010007E9000004C6290004C03B000100010007E9000004C0E44FC9C04A000100010007E9000004C021040CC059000100010007E900000480080A5AC068000100010007E9000004C0CBE60AC077000100010007E9000004C00505F1C086000100010007E9000004C0702404C095000100010007E9000004803F0235C0A4000100010007E9000004C0249411C0B3000100010007E9000004C03A801EC0C2000100010007E9000004C1000E81C0D1000100010007E9000004C707532AC0E0000100010007E9000004CA0C1B21C01C001C00010007E900001020010503BA3E00000000000000020030C077001C00010007E900001020010500002F0000000000000000000FC095001C00010007E90000102001050000010000"
434	"00000000803F0235C0B3001C00010007E9000010200105030C2700000000000000020030C0C2001C00010007E9000010200107FD000000000000000000000001C0E0001C00010007E900001020010DC30000000000000000000000350000291000000000000000"
435	);
436}
437
438/** simple test of parsing, pcat file */
439static void
440testfromfile(sldns_buffer* pkt, struct alloc_cache* alloc, sldns_buffer* out,
441	const char* fname)
442{
443	FILE* in = fopen(fname, "r");
444	char buf[102400];
445	int no=0;
446	if(!in) {
447		perror("fname");
448		return;
449	}
450	while(fgets(buf, (int)sizeof(buf), in)) {
451		if(buf[0] == ';') /* comment */
452			continue;
453		if(strlen(buf) < 10) /* skip pcat line numbers. */
454			continue;
455		if(vbmp) {
456			printf("test no %d: %s", no, buf);
457			fflush(stdout);
458		}
459		testpkt(pkt, alloc, out, buf);
460		no++;
461	}
462	fclose(in);
463}
464
465/** simple test of parsing, drill file */
466static void
467testfromdrillfile(sldns_buffer* pkt, struct alloc_cache* alloc,
468	sldns_buffer* out, const char* fname)
469{
470	/*  ;-- is used to indicate a new message */
471	FILE* in = fopen(fname, "r");
472	char buf[102400];
473	char* np = buf;
474	buf[0]=0;
475	if(!in) {
476		perror("fname");
477		return;
478	}
479	while(fgets(np, (int)sizeof(buf) - (np-buf), in)) {
480		if(strncmp(np, ";--", 3) == 0) {
481			/* new entry */
482			/* test previous */
483			if(np != buf)
484				testpkt(pkt, alloc, out, buf);
485			/* set for new entry */
486			np = buf;
487			buf[0]=0;
488			continue;
489		}
490		if(np[0] == ';') /* comment */
491			continue;
492		np = &np[strlen(np)];
493	}
494	testpkt(pkt, alloc, out, buf);
495	fclose(in);
496}
497
498#define xstr(s) str(s)
499#define str(s) #s
500
501#define SRCDIRSTR xstr(SRCDIR)
502
503void msgparse_test(void)
504{
505	time_t origttl = MAX_NEG_TTL;
506	sldns_buffer* pkt = sldns_buffer_new(65553);
507	sldns_buffer* out = sldns_buffer_new(65553);
508	struct alloc_cache super_a, alloc;
509	MAX_NEG_TTL = 86400;
510	/* init */
511	alloc_init(&super_a, NULL, 0);
512	alloc_init(&alloc, &super_a, 2);
513
514	unit_show_feature("message parse");
515	simpletest(pkt, &alloc, out);
516	/* plain hex dumps, like pcat */
517	testfromfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.1");
518	testfromfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.2");
519	testfromfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.3");
520	/* like from drill -w - */
521	testfromdrillfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.4");
522	testfromdrillfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.5");
523
524	matches_nolocation = 1; /* RR order not important for the next test */
525	testfromdrillfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.6");
526	check_rrsigs = 1;
527	testfromdrillfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.7");
528	check_rrsigs = 0;
529	matches_nolocation = 0;
530
531	check_formerr_gone = 1;
532	testfromdrillfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.8");
533	check_formerr_gone = 0;
534
535	check_rrsigs = 1;
536	check_nosameness = 1;
537	testfromdrillfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.9");
538	check_nosameness = 0;
539	check_rrsigs = 0;
540
541	/* cleanup */
542	alloc_clear(&alloc);
543	alloc_clear(&super_a);
544	sldns_buffer_free(pkt);
545	sldns_buffer_free(out);
546	MAX_NEG_TTL = origttl;
547}
548