]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - testcode/unitmsgparse.c
Vendor import of Unbound 1.8.0.
[FreeBSD/FreeBSD.git] / testcode / unitmsgparse.c
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 */
59 static int vbmp = 0;
60 /** do not accept formerr */
61 static int check_formerr_gone = 0;
62 /** if matching within a section should disregard the order of RRs. */
63 static int matches_nolocation = 0;
64 /** see if RRSIGs are properly matched to RRsets. */
65 static int check_rrsigs = 0;
66 /** do not check buffer sameness */
67 static int check_nosameness = 0;
68
69 /** see if buffers contain the same packet */
70 static int
71 test_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));
141         return 0;
142 }
143
144 /** check if unbound formerr equals ldns formerr */
145 static void
146 checkformerr(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 */
165 static void
166 perf_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) );
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 */
199 static void
200 perftestpkt(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 */
236 static void
237 print_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 */
252 static void
253 print_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 */
276 static int
277 no_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 */
292 static void
293 check_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 */
313 static void
314 testpkt(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) );
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));
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 */
382 static void
383 simpletest(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 */
439 static void
440 testfromfile(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 */
466 static void
467 testfromdrillfile(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
503 void 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 }