Remove all $Id$ from top of file
[metze/wireshark/wip.git] / epan / reassemble_test.c
1 /* Standalone program to test functionality of reassemble.h API
2  *
3  * These aren't particularly complete - they just test a few corners of
4  * functionality which I was interested in. In particular, they only test the
5  * fragment_add_seq_* (ie, FD_BLOCKSEQUENCE) family of routines. However,
6  * hopefully they will inspire people to write additional tests, and provide a
7  * useful basis on which to do so.
8  *
9  * December 2010:
10  * 1. reassemble_test can be run under valgrind to detect any memory leaks in the
11  *    Wireshark reassembly code.
12  *    Specifically: code has been added to free dynamically allocated memory
13  *     after each test (or at program completion) so that valgrind will report
14  *     only actual memory leaks.
15  *    The following command can be used to run reassemble_test under valgrind:
16  *      env                               \
17  *        G_DEBUG=gc-friendly             \
18  *        G_SLICE=always-malloc           \
19  *        WIRESHARK_DEBUG_EP_NO_CHUNKS=1  \
20  *        WIRESHARK_DEBUG_SE_NO_CHUNKS=1  \
21  *        WIRESHARK_DEBUG_SE_USE_CANARY=1 \
22  *        WIRESHARK_EP_VERIFY_POINTERS=1  \
23  *        WIRESHARK_SE_VERIFY_POINTERS=1  \
24  *      valgrind --leak-check=full --show-reachable=yes ./reassemble_test
25  *
26  *  2. Debug functions have been added which will print information
27  *     about the fd-chains associated with the fragment_table and the
28  *     reassembled table.
29  *     #define debug  to enable the code.
30  *
31  * Copyright (c) 2007 MX Telecom Ltd. <richardv@mxtelecom.com>
32  *
33  * Wireshark - Network traffic analyzer
34  * By Gerald Combs <gerald@wireshark.org>
35  * Copyright 1998
36  *
37  * This program is free software; you can redistribute it and/or
38  * modify it under the terms of the GNU General Public License
39  * as published by the Free Software Foundation; either version 2
40  * of the License, or (at your option) any later version.
41  *
42  * This program is distributed in the hope that it will be useful,
43  * but WITHOUT ANY WARRANTY; without even the implied warranty of
44  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
45  * GNU General Public License for more details.
46  *
47  * You should have received a copy of the GNU General Public License
48  * along with this program; if not, write to the Free Software
49  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
50  */
51
52 #include <stdarg.h>
53 #include <stdlib.h>
54 #include <stdio.h>
55 #include <string.h>
56
57 #include <glib.h>
58
59 #include "config.h"
60
61 #include <epan/emem.h>
62 #include <epan/packet.h>
63 #include <epan/packet_info.h>
64 #include <epan/proto.h>
65 #include <epan/tvbuff.h>
66 #include <epan/reassemble.h>
67
68 #define ASSERT(b) do_test((b),"Assertion failed at line %i: %s\n", __LINE__, #b)
69 #define ASSERT_EQ(exp,act) do_test((exp)==(act),"Assertion failed at line %i: %s==%s (%i==%i)\n", __LINE__, #exp, #act, exp, act)
70 #define ASSERT_NE(exp,act) do_test((exp)!=(act),"Assertion failed at line %i: %s!=%s (%i!=%i)\n", __LINE__, #exp, #act, exp, act)
71
72 static int failure = 0;
73
74 static void
75 do_test(gboolean condition, const char *format, ...)
76 {
77     va_list ap;
78
79     if (condition)
80         return;
81
82     va_start(ap, format);
83     vfprintf(stderr, format, ap);
84     va_end(ap);
85     failure = 1;
86
87     /* many of the tests assume this routine doesn't return on failure; if we
88      * do, it may provide more information, but may cause a segfault. Uncomment
89      * this line if you wish.
90      */
91     exit(1);
92 }
93
94 #define DATA_LEN 256
95
96 static char *data;
97 static tvbuff_t *tvb;
98 static packet_info pinfo;
99
100 /* fragment_table maps from datagram ids to fragment_head
101    reassembled_table maps from <packet number,datagram id> to
102    fragment_head */
103 static reassembly_table test_reassembly_table;
104
105 #ifdef debug
106 /*************************************************
107  * Util fcns to display
108  *   fragment_table & reassembled_table fd-chains
109  ************************************************/
110
111 static struct _fd_flags {
112     guint32 flag;
113     gchar  *flag_name;
114 } fd_flags[] = {
115     {FD_DEFRAGMENTED         ,"DF"},
116     {FD_DATALEN_SET          ,"DS"},
117     {FD_SUBSET_TVB,          ,"ST"},
118     {FD_BLOCKSEQUENCE        ,"BS"},
119     {FD_DATA_NOT_PRESENT     ,"NP"},
120     {FD_PARTIAL_REASSEMBLY   ,"PR"},
121     {FD_OVERLAP              ,"OL"},
122     {FD_OVERLAPCONFLICT      ,"OC"},
123     {FD_MULTIPLETAILS        ,"MT"},
124     {FD_TOOLONGFRAGMENT      ,"TL"},
125 };
126 #define N_FD_FLAGS (signed)(sizeof(fd_flags)/sizeof(struct _fd_flags))
127
128 static void
129 print_fd(fragment_head *fd, gboolean is_head) {
130     int i;
131
132     g_assert(fd != NULL);
133     printf("        %08x %08x %3d %3d %3d", fd, fd->next, fd->frame, fd->offset, fd->len);
134     if (is_head) {
135         printf(" %3d %3d", fd->datalen, fd->reassembled_in);
136     } else {
137         printf( "        ");
138     }
139     printf(" 0x%08x", fd->data);
140     for (i=0; i<N_FD_FLAGS; i++) {
141         printf(" %s", (fd->flags & fd_flags[i].flag) ? fd_flags[i].flag_name : "  ");
142     }
143     printf("\n");
144 }
145
146 static void
147 print_fd_chain(fragment_head *fd_head) {
148     fragment_item *fdp;
149
150     g_assert(fd_head != NULL);
151     print_fd(fd_head, TRUE);
152     for (fdp=fd_head->next; fdp != NULL; fdp=fdp->next) {
153         print_fd(fdp, FALSE);
154     }
155 }
156
157 static void
158 print_fragment_table_chain(gpointer k, gpointer v, gpointer ud) {
159     fragment_key  *key     = (fragment_key*)k;
160     fragment_head *fd_head = (fragment_head *)v;
161     printf("  --> FT: %3d 0x%08x 0x%08x\n", key->id, *(guint32 *)(key->src.data), *(guint32 *)(key->dst.data));
162     print_fd_chain(fd_head);
163 }
164
165 static void
166 print_fragment_table(void) {
167     printf("\n Fragment Table -------\n");
168     g_hash_table_foreach(fragment_table, print_fragment_table_chain, NULL);
169 }
170
171 static void
172 print_reassembled_table_chain(gpointer k, gpointer v, gpointer ud) {
173     reassembled_key  *key  = (reassembled_key*)k;
174     fragment_head *fd_head = (fragment_head *)v;
175     printf("  --> RT: %5d %5d\n", key->id, key->frame);
176     print_fd_chain(fd_head);
177 }
178
179 static void
180 print_reassembled_table(void) {
181     printf("\n Reassembled Table ----\n");
182     g_hash_table_foreach(test_reassembly_table.reassembled_table, print_reassembled_table_chain, NULL);
183 }
184
185 static void
186 print_tables(void) {
187     print_fragment_table();
188     print_reassembled_table();
189 }
190 #endif
191
192 /**********************************************************************************
193  *
194  * fragment_add_seq
195  *
196  *********************************************************************************/
197
198 /* Simple test case for fragment_add_seq.
199  * Adds three fragments (out of order, with one for a different datagram in between),
200  * and checks that they are reassembled correctly.
201  */
202 /*   visit  id  frame  frag  len  more  tvb_offset
203        0    12     1     0    50   T      10
204        1    12     1     0    60   T       5
205        0    13     2     0    60   T      15
206        0    12     3     2    60   F       5
207        0    12     4     1    60   F      15
208 */
209 static void
210 test_simple_fragment_add_seq(void)
211 {
212     fragment_head *fd_head, *fdh0;
213
214     printf("Starting test test_simple_fragment_add_seq\n");
215
216     pinfo.fd->num = 1;
217     fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
218                              0, 50, TRUE, 0);
219
220     ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
221     ASSERT_EQ(NULL,fd_head);
222
223     /* adding the same fragment again should do nothing, even with different
224      * offset etc */
225     pinfo.fd->flags.visited = 1;
226     fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
227                              0, 60, TRUE, 0);
228     ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
229     ASSERT_EQ(NULL,fd_head);
230
231     /* start another pdu (just to confuse things) */
232     pinfo.fd->flags.visited = 0;
233     pinfo.fd->num = 2;
234     fd_head=fragment_add_seq(&test_reassembly_table, tvb, 15, &pinfo, 13, NULL,
235                              0, 60, TRUE, 0);
236     ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
237     ASSERT_EQ(NULL,fd_head);
238
239     /* now we add the terminal fragment of the first datagram */
240     pinfo.fd->num = 3;
241     fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
242                              2, 60, FALSE, 0);
243
244     /* we haven't got all the fragments yet ... */
245     ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
246     ASSERT_EQ(NULL,fd_head);
247
248     /* finally, add the missing fragment */
249     pinfo.fd->num = 4;
250     fd_head=fragment_add_seq(&test_reassembly_table, tvb, 15, &pinfo, 12, NULL,
251                              1, 60, TRUE, 0);
252
253     ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
254     ASSERT_NE(NULL,fd_head);
255
256     /* check the contents of the structure */
257     ASSERT_EQ(0,fd_head->frame);  /* unused */
258     ASSERT_EQ(0,fd_head->offset); /* unused */
259     ASSERT_EQ(170,fd_head->len); /* the length of data we have */
260     ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
261     ASSERT_EQ(4,fd_head->reassembled_in);
262     ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
263     ASSERT_NE(NULL,fd_head->tvb_data);
264     ASSERT_NE(NULL,fd_head->next);
265
266     ASSERT_EQ(1,fd_head->next->frame);
267     ASSERT_EQ(0,fd_head->next->offset);  /* seqno */
268     ASSERT_EQ(50,fd_head->next->len);    /* segment length */
269     ASSERT_EQ(0,fd_head->next->flags);
270     ASSERT_EQ(NULL,fd_head->next->tvb_data);
271     ASSERT_NE(NULL,fd_head->next->next);
272
273     ASSERT_EQ(4,fd_head->next->next->frame);
274     ASSERT_EQ(1,fd_head->next->next->offset);  /* seqno */
275     ASSERT_EQ(60,fd_head->next->next->len);    /* segment length */
276     ASSERT_EQ(0,fd_head->next->next->flags);
277     ASSERT_EQ(NULL,fd_head->next->next->tvb_data);
278     ASSERT_NE(NULL,fd_head->next->next->next);
279
280     ASSERT_EQ(3,fd_head->next->next->next->frame);
281     ASSERT_EQ(2,fd_head->next->next->next->offset);  /* seqno */
282     ASSERT_EQ(60,fd_head->next->next->next->len);    /* segment length */
283     ASSERT_EQ(0,fd_head->next->next->next->flags);
284     ASSERT_EQ(NULL,fd_head->next->next->next->tvb_data);
285     ASSERT_EQ(NULL,fd_head->next->next->next->next);
286
287     /* test the actual reassembly */
288     ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
289     ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+15,60));
290     ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,60));
291
292 #if 0
293     print_fragment_table();
294 #endif
295
296     /* what happens if we revisit the packets now? */
297     fdh0 = fd_head;
298     pinfo.fd->flags.visited = 1;
299     pinfo.fd->num = 1;
300     fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
301                              0, 50, TRUE, 0);
302     /*
303      * this api relies on the caller to check fd_head -> reassembled_in
304      *
305      * Redoing all the tests seems like overkill - just check the pointer
306      */
307     ASSERT_EQ(fdh0,fd_head);
308
309     pinfo.fd->num = 3;
310     fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
311                              2, 60, FALSE, 0);
312     ASSERT_EQ(fdh0,fd_head);
313
314     pinfo.fd->num = 4;
315     fd_head=fragment_add_seq(&test_reassembly_table, tvb, 15, &pinfo, 12, NULL,
316                              1, 60, TRUE, 0);
317     ASSERT_EQ(fdh0,fd_head);
318
319 #if 0
320     print_fragment_table();
321 #endif
322 }
323
324 /* XXX ought to have some tests for overlapping fragments */
325
326 /* This tests the functionality of fragment_set_partial_reassembly for
327  * FD_BLOCKSEQUENCE reassembly.
328  *
329  * We add a sequence of fragments thus:
330  *    seqno   frame  offset   len   (initial) more_frags
331  *    -----   -----  ------   ---   --------------------
332  *      0       1       10       50   false
333  *      1       2        0       40   true
334  *      1       3        0       40   true (a duplicate fragment)
335  *      2       4       20      100   false
336  *      3       5        0       40   false
337  */
338 static void
339 test_fragment_add_seq_partial_reassembly(void)
340 {
341     fragment_head *fd_head;
342     fragment_item *fd;
343
344     printf("Starting test test_fragment_add_seq_partial_reassembly\n");
345
346     /* generally it's probably fair to assume that we will be called with
347      * more_frags=FALSE.
348      */
349     pinfo.fd->num = 1;
350     fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
351                              0, 50, FALSE, 0);
352
353     ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
354     ASSERT_NE(NULL,fd_head);
355
356     /* check the contents of the structure */
357     ASSERT_EQ(0,fd_head->frame);  /* unused */
358     ASSERT_EQ(0,fd_head->offset); /* unused */
359     ASSERT_EQ(50,fd_head->len); /* the length of data we have */
360     ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
361     ASSERT_EQ(1,fd_head->reassembled_in);
362     ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
363     ASSERT_NE(NULL,fd_head->tvb_data);
364     ASSERT_NE(NULL,fd_head->next);
365
366     ASSERT_EQ(1,fd_head->next->frame);
367     ASSERT_EQ(0,fd_head->next->offset);  /* seqno */
368     ASSERT_EQ(50,fd_head->next->len);    /* segment length */
369     ASSERT_EQ(0,fd_head->next->flags);
370     ASSERT_EQ(NULL,fd_head->next->tvb_data);
371     ASSERT_EQ(NULL,fd_head->next->next);
372
373     /* test the actual reassembly */
374     ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
375
376     /* now we announce that the reassembly wasn't complete after all. */
377     fragment_set_partial_reassembly(&test_reassembly_table, &pinfo, 12, NULL);
378
379     /* and add another segment. To mix things up slightly (and so that we can
380      * check on the state of things), we're going to set the more_frags flag
381      * here
382      */
383     pinfo.fd->num = 2;
384     fd_head=fragment_add_seq(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
385                              1, 40, TRUE, 0);
386
387     ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
388     ASSERT_EQ(NULL,fd_head);
389
390     fd_head=fragment_get(&test_reassembly_table, &pinfo, 12, NULL);
391     ASSERT_NE(NULL,fd_head);
392
393     /* check the contents of the structure */
394     ASSERT_EQ(0,fd_head->frame);   /* unused */
395     ASSERT_EQ(0,fd_head->offset);  /* unused */
396     /* ASSERT_EQ(50,fd_head->len);     the length of data we have */
397     ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
398     ASSERT_EQ(0,fd_head->reassembled_in);
399     ASSERT_EQ(FD_BLOCKSEQUENCE,fd_head->flags);
400     ASSERT_NE(NULL,fd_head->tvb_data);
401     ASSERT_NE(NULL,fd_head->next);
402
403     fd=fd_head->next;
404     ASSERT_EQ(1,fd->frame);
405     ASSERT_EQ(0,fd->offset);  /* seqno */
406     ASSERT_EQ(50,fd->len);    /* segment length */
407     ASSERT_EQ(FD_SUBSET_TVB,fd->flags);
408     ASSERT_EQ(tvb_get_ptr(fd_head->tvb_data,0,0),tvb_get_ptr(fd->tvb_data,0,0));
409     ASSERT_NE(NULL,fd->next);
410
411     fd=fd->next;
412     ASSERT_EQ(2,fd->frame);
413     ASSERT_EQ(1,fd->offset);  /* seqno */
414     ASSERT_EQ(40,fd->len);    /* segment length */
415     ASSERT_EQ(0,fd->flags);
416     ASSERT_NE(NULL,fd->tvb_data);
417     ASSERT_EQ(NULL,fd->next);
418
419     /* Another copy of the second segment.
420      */
421     pinfo.fd->num = 3;
422     fd_head=fragment_add_seq(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
423                              1, 40, TRUE, 0);
424
425     ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
426     ASSERT_EQ(NULL,fd_head);
427     fd_head=fragment_get(&test_reassembly_table, &pinfo, 12, NULL);
428     ASSERT_NE(NULL,fd_head);
429     ASSERT_EQ(0,fd_head->frame);   /* unused */
430     ASSERT_EQ(0,fd_head->offset);  /* unused */
431     /* ASSERT_EQ(50,fd_head->len);     the length of data we have */
432     ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
433     ASSERT_EQ(0,fd_head->reassembled_in);
434     ASSERT_EQ(FD_BLOCKSEQUENCE,fd_head->flags);
435     ASSERT_NE(NULL,fd_head->tvb_data);
436     ASSERT_NE(NULL,fd_head->next);
437
438     fd=fd_head->next;
439     ASSERT_EQ(1,fd->frame);
440     ASSERT_EQ(0,fd->offset);  /* seqno */
441     ASSERT_EQ(50,fd->len);    /* segment length */
442     ASSERT_EQ(FD_SUBSET_TVB,fd->flags);
443     ASSERT_EQ(tvb_get_ptr(fd_head->tvb_data,0,0),tvb_get_ptr(fd->tvb_data,0,0));
444     ASSERT_NE(NULL,fd->next);
445
446     fd=fd->next;
447     ASSERT_EQ(2,fd->frame);
448     ASSERT_EQ(1,fd->offset);  /* seqno */
449     ASSERT_EQ(40,fd->len);    /* segment length */
450     ASSERT_EQ(0,fd->flags);
451     ASSERT_NE(NULL,fd->tvb_data);
452     ASSERT_NE(NULL,fd->next);
453
454     fd=fd->next;
455     ASSERT_EQ(3,fd->frame);
456     ASSERT_EQ(1,fd->offset);  /* seqno */
457     ASSERT_EQ(40,fd->len);    /* segment length */
458     ASSERT_EQ(0,fd->flags);
459     ASSERT_NE(NULL,fd->tvb_data);
460     ASSERT_EQ(NULL,fd->next);
461
462
463
464     /* have another go at wrapping things up */
465     pinfo.fd->num = 4;
466     fd_head=fragment_add_seq(&test_reassembly_table, tvb, 20, &pinfo, 12, NULL,
467                              2, 100, FALSE, 0);
468
469     ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
470     ASSERT_NE(NULL,fd_head);
471
472     /* check the contents of the structure */
473     ASSERT_EQ(0,fd_head->frame);  /* unused */
474     ASSERT_EQ(0,fd_head->offset); /* unused */
475     ASSERT_EQ(190,fd_head->len); /* the length of data we have */
476     ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
477     ASSERT_EQ(4,fd_head->reassembled_in);
478     ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
479     ASSERT_NE(NULL,fd_head->tvb_data);
480     ASSERT_NE(NULL,fd_head->next);
481
482     fd=fd_head->next;
483     ASSERT_EQ(1,fd->frame);
484     ASSERT_EQ(0,fd->offset);  /* seqno */
485     ASSERT_EQ(50,fd->len);    /* segment length */
486     ASSERT_EQ(0,fd->flags);
487     ASSERT_EQ(NULL,fd->tvb_data);
488     ASSERT_NE(NULL,fd->next);
489
490     fd=fd->next;
491     ASSERT_EQ(2,fd->frame);
492     ASSERT_EQ(1,fd->offset);  /* seqno */
493     ASSERT_EQ(40,fd->len);    /* segment length */
494     ASSERT_EQ(0,fd->flags);
495     ASSERT_EQ(NULL,fd->tvb_data);
496     ASSERT_NE(NULL,fd->next);
497
498     fd=fd->next;
499     ASSERT_EQ(3,fd->frame);
500     ASSERT_EQ(1,fd->offset);  /* seqno */
501     ASSERT_EQ(40,fd->len);    /* segment length */
502     ASSERT_EQ(FD_OVERLAP,fd->flags);
503     ASSERT_EQ(NULL,fd->tvb_data);
504     ASSERT_NE(NULL,fd->next);
505
506     fd=fd->next;
507     ASSERT_EQ(4,fd->frame);
508     ASSERT_EQ(2,fd->offset);  /* seqno */
509     ASSERT_EQ(100,fd->len);    /* segment length */
510     ASSERT_EQ(0,fd->flags);
511     ASSERT_EQ(NULL,fd->tvb_data);
512     ASSERT_EQ(NULL,fd->next);
513
514     /* test the actual reassembly */
515     ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
516     ASSERT(!tvb_memeql(fd_head->tvb_data,50,data,40));
517     ASSERT(!tvb_memeql(fd_head->tvb_data,90,data+20,100));
518
519
520     /* do it again (this time it is more complicated, with an overlap in the
521      * reassembly) */
522
523     fragment_set_partial_reassembly(&test_reassembly_table, &pinfo, 12, NULL);
524
525     pinfo.fd->num = 5;
526     fd_head=fragment_add_seq(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
527                              3, 40, FALSE, 0);
528
529     fd_head=fragment_get(&test_reassembly_table, &pinfo, 12, NULL);
530     ASSERT_NE(NULL,fd_head);
531     ASSERT_EQ(0,fd_head->frame);   /* unused */
532     ASSERT_EQ(0,fd_head->offset);  /* unused */
533     ASSERT_EQ(230,fd_head->len);   /* the length of data we have */
534     ASSERT_EQ(3,fd_head->datalen); /* seqno of the last fragment we have */
535     ASSERT_EQ(5,fd_head->reassembled_in);
536     ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
537     ASSERT_NE(NULL,fd_head->tvb_data);
538     ASSERT_NE(NULL,fd_head->next);
539
540     fd=fd_head->next;
541     ASSERT_EQ(1,fd->frame);
542     ASSERT_EQ(0,fd->offset);  /* seqno */
543     ASSERT_EQ(50,fd->len);    /* segment length */
544     ASSERT_EQ(0,fd->flags);
545     ASSERT_EQ(NULL,fd->tvb_data);
546     ASSERT_NE(NULL,fd->next);
547
548     fd=fd->next;
549     ASSERT_EQ(2,fd->frame);
550     ASSERT_EQ(1,fd->offset);  /* seqno */
551     ASSERT_EQ(40,fd->len);    /* segment length */
552     ASSERT_EQ(0,fd->flags);
553     ASSERT_EQ(NULL,fd->tvb_data);
554     ASSERT_NE(NULL,fd->next);
555
556     fd=fd->next;
557     ASSERT_EQ(3,fd->frame);
558     ASSERT_EQ(1,fd->offset);  /* seqno */
559     ASSERT_EQ(40,fd->len);    /* segment length */
560     ASSERT_EQ(FD_OVERLAP,fd->flags);
561     ASSERT_EQ(NULL,fd->tvb_data);
562     ASSERT_NE(NULL,fd->next);
563
564     fd=fd->next;
565     ASSERT_EQ(4,fd->frame);
566     ASSERT_EQ(2,fd->offset);  /* seqno */
567     ASSERT_EQ(100,fd->len);   /* segment length */
568     ASSERT_EQ(0,fd->flags);
569     ASSERT_EQ(NULL,fd->tvb_data);
570     ASSERT_NE(NULL,fd->next);
571
572     fd=fd->next;
573     ASSERT_EQ(5,fd->frame);
574     ASSERT_EQ(3,fd->offset);  /* seqno */
575     ASSERT_EQ(40,fd->len);    /* segment length */
576     ASSERT_EQ(0,fd->flags);
577     ASSERT_EQ(NULL,fd->tvb_data);
578     ASSERT_EQ(NULL,fd->next);
579
580     /* test the actual reassembly */
581     ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
582     ASSERT(!tvb_memeql(fd_head->tvb_data,50,data,40));
583     ASSERT(!tvb_memeql(fd_head->tvb_data,90,data+20,100));
584     ASSERT(!tvb_memeql(fd_head->tvb_data,190,data,40));
585 }
586
587 /* Test case for fragment_add_seq with duplicated (e.g., retransmitted) data.
588  * Adds three fragments--adding the 1st one twice--
589  * and checks that they are reassembled correctly.
590  */
591 /*   visit  id  frame  frag  len  more  tvb_offset
592        0    12     1     0    50   T      10
593        0    12     2     1    60   T      5
594        0    12     3     2    40   F      5
595        0    12     4     0    50   T      10
596 */
597 static void
598 test_fragment_add_seq_duplicate_first(void)
599 {
600     fragment_head *fd_head;
601
602     printf("Starting test test_fragment_add_seq_duplicate_first\n");
603
604     pinfo.fd->num = 1;
605     fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
606                              0, 50, TRUE, 0);
607
608     ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
609     ASSERT_EQ(NULL,fd_head);
610
611     /* Add the 2nd segment */
612     pinfo.fd->num = 2;
613     fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
614                              1, 60, TRUE, 0);
615
616     /* we haven't got all the fragments yet ... */
617     ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
618     ASSERT_EQ(NULL,fd_head);
619
620     /* Add the last fragment */
621     pinfo.fd->num = 3;
622     fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
623                              2, 40, FALSE, 0);
624
625     ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
626     ASSERT_NE(NULL,fd_head);
627
628     /* Add the first fragment again */
629     pinfo.fd->num = 4;
630     fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
631                              0, 50, TRUE, 0);
632
633     /* Reassembly should have still succeeded */
634     ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
635     ASSERT_NE(NULL,fd_head);
636
637     /* check the contents of the structure */
638     ASSERT_EQ(0,fd_head->frame);  /* unused */
639     ASSERT_EQ(0,fd_head->offset); /* unused */
640     ASSERT_EQ(150,fd_head->len); /* the length of data we have */
641     ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
642     ASSERT_EQ(3,fd_head->reassembled_in);
643     ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
644     ASSERT_NE(NULL,fd_head->tvb_data);
645     ASSERT_NE(NULL,fd_head->next);
646
647     ASSERT_EQ(1,fd_head->next->frame);
648     ASSERT_EQ(0,fd_head->next->offset);  /* seqno */
649     ASSERT_EQ(50,fd_head->next->len);    /* segment length */
650     ASSERT_EQ(0,fd_head->next->flags);
651     ASSERT_EQ(NULL,fd_head->next->tvb_data);
652     ASSERT_NE(NULL,fd_head->next->next);
653
654     ASSERT_EQ(4,fd_head->next->next->frame);
655     ASSERT_EQ(0,fd_head->next->next->offset);  /* seqno */
656     ASSERT_EQ(50,fd_head->next->next->len);    /* segment length */
657     ASSERT_EQ(FD_OVERLAP,fd_head->next->next->flags);
658     ASSERT_EQ(NULL,fd_head->next->next->tvb_data);
659     ASSERT_NE(NULL,fd_head->next->next->next);
660
661     ASSERT_EQ(2,fd_head->next->next->next->frame);
662     ASSERT_EQ(1,fd_head->next->next->next->offset);  /* seqno */
663     ASSERT_EQ(60,fd_head->next->next->next->len);    /* segment length */
664     ASSERT_EQ(0,fd_head->next->next->next->flags);
665     ASSERT_EQ(NULL,fd_head->next->next->next->tvb_data);
666     ASSERT_NE(NULL,fd_head->next->next->next->next);
667
668     ASSERT_EQ(3,fd_head->next->next->next->next->frame);
669     ASSERT_EQ(2,fd_head->next->next->next->next->offset);  /* seqno */
670     ASSERT_EQ(40,fd_head->next->next->next->next->len);    /* segment length */
671     ASSERT_EQ(0,fd_head->next->next->next->next->flags);
672     ASSERT_EQ(NULL,fd_head->next->next->next->next->tvb_data);
673     ASSERT_EQ(NULL,fd_head->next->next->next->next->next);
674
675     /* test the actual reassembly */
676     ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
677     ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
678     ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
679
680 #if 0
681     print_fragment_table();
682 #endif
683 }
684
685
686 /* Test case for fragment_add_seq with duplicated (e.g., retransmitted) data.
687  * Adds three fragments--adding the 2nd one twice--
688  * and checks that they are reassembled correctly.
689  */
690 /*   visit  id  frame  frag  len  more  tvb_offset
691        0    12     1     0    50   T      10
692        0    12     2     1    60   T      5
693        0    12     3     1    60   T      5
694        0    12     4     3    40   F      5
695 */
696 static void
697 test_fragment_add_seq_duplicate_middle(void)
698 {
699     fragment_head *fd_head;
700
701     printf("Starting test test_fragment_add_seq_duplicate_middle\n");
702
703     pinfo.fd->num = 1;
704     fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
705                              0, 50, TRUE, 0);
706
707     ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
708     ASSERT_EQ(NULL,fd_head);
709
710     /* Add the 2nd segment */
711     pinfo.fd->num = 2;
712     fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
713                              1, 60, TRUE, 0);
714
715     /* we haven't got all the fragments yet ... */
716     ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
717     ASSERT_EQ(NULL,fd_head);
718
719     /* Now, add the 2nd segment again (but in a different frame) */
720     pinfo.fd->num = 3;
721     fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
722                              1, 60, TRUE, 0);
723
724     /* This duplicate fragment should have been ignored */
725     ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
726     ASSERT_EQ(NULL,fd_head);
727
728     /* finally, add the last fragment */
729     pinfo.fd->num = 4;
730     fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
731                              2, 40, FALSE, 0);
732
733     ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
734     ASSERT_NE(NULL,fd_head);
735
736     /* check the contents of the structure */
737     ASSERT_EQ(0,fd_head->frame);  /* unused */
738     ASSERT_EQ(0,fd_head->offset); /* unused */
739     ASSERT_EQ(150,fd_head->len); /* the length of data we have */
740     ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
741     ASSERT_EQ(4,fd_head->reassembled_in);
742     ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
743     ASSERT_NE(NULL,fd_head->tvb_data);
744     ASSERT_NE(NULL,fd_head->next);
745
746     ASSERT_EQ(1,fd_head->next->frame);
747     ASSERT_EQ(0,fd_head->next->offset);  /* seqno */
748     ASSERT_EQ(50,fd_head->next->len);    /* segment length */
749     ASSERT_EQ(0,fd_head->next->flags);
750     ASSERT_EQ(NULL,fd_head->next->tvb_data);
751     ASSERT_NE(NULL,fd_head->next->next);
752
753     ASSERT_EQ(2,fd_head->next->next->frame);
754     ASSERT_EQ(1,fd_head->next->next->offset);  /* seqno */
755     ASSERT_EQ(60,fd_head->next->next->len);    /* segment length */
756     ASSERT_EQ(0,fd_head->next->next->flags);
757     ASSERT_EQ(NULL,fd_head->next->next->tvb_data);
758     ASSERT_NE(NULL,fd_head->next->next->next);
759
760     ASSERT_EQ(3,fd_head->next->next->next->frame);
761     ASSERT_EQ(1,fd_head->next->next->next->offset);  /* seqno */
762     ASSERT_EQ(60,fd_head->next->next->next->len);    /* segment length */
763     ASSERT_EQ(FD_OVERLAP,fd_head->next->next->next->flags);
764     ASSERT_EQ(NULL,fd_head->next->next->next->tvb_data);
765     ASSERT_NE(NULL,fd_head->next->next->next->next);
766
767     ASSERT_EQ(4,fd_head->next->next->next->next->frame);
768     ASSERT_EQ(2,fd_head->next->next->next->next->offset);  /* seqno */
769     ASSERT_EQ(40,fd_head->next->next->next->next->len);    /* segment length */
770     ASSERT_EQ(0,fd_head->next->next->next->next->flags);
771     ASSERT_EQ(NULL,fd_head->next->next->next->next->tvb_data);
772     ASSERT_EQ(NULL,fd_head->next->next->next->next->next);
773
774     /* test the actual reassembly */
775     ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
776     ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
777     ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
778
779 #if 0
780     print_fragment_table();
781 #endif
782 }
783
784 /* Test case for fragment_add_seq with duplicated (e.g., retransmitted) data.
785  * Adds three fragments--adding the 3rd one twice--
786  * and checks that they are reassembled correctly.
787  */
788 /*   visit  id  frame  frag  len  more  tvb_offset
789        0    12     1     0    50   T      10
790        0    12     2     1    60   T      5
791        0    12     3     2    40   F      5
792        0    12     4     2    40   F      5
793 */
794 static void
795 test_fragment_add_seq_duplicate_last(void)
796 {
797     fragment_head *fd_head;
798
799     printf("Starting test test_fragment_add_seq_duplicate_last\n");
800
801     pinfo.fd->num = 1;
802     fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
803                              0, 50, TRUE, 0);
804
805     ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
806     ASSERT_EQ(NULL,fd_head);
807
808     /* Add the 2nd segment */
809     pinfo.fd->num = 2;
810     fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
811                              1, 60, TRUE, 0);
812
813     /* we haven't got all the fragments yet ... */
814     ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
815     ASSERT_EQ(NULL,fd_head);
816
817     /* Add the last fragment */
818     pinfo.fd->num = 3;
819     fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
820                              2, 40, FALSE, 0);
821
822     ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
823     ASSERT_NE(NULL,fd_head);
824
825     /* Add the last fragment again */
826     pinfo.fd->num = 4;
827     fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
828                              2, 40, FALSE, 0);
829
830     /* Reassembly should have still succeeded */
831     ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
832     ASSERT_NE(NULL,fd_head);
833
834     /* check the contents of the structure */
835     ASSERT_EQ(0,fd_head->frame);  /* unused */
836     ASSERT_EQ(0,fd_head->offset); /* unused */
837     ASSERT_EQ(150,fd_head->len); /* the length of data we have */
838     ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
839     ASSERT_EQ(3,fd_head->reassembled_in);
840     ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
841     ASSERT_NE(NULL,fd_head->tvb_data);
842     ASSERT_NE(NULL,fd_head->next);
843
844     ASSERT_EQ(1,fd_head->next->frame);
845     ASSERT_EQ(0,fd_head->next->offset);  /* seqno */
846     ASSERT_EQ(50,fd_head->next->len);    /* segment length */
847     ASSERT_EQ(0,fd_head->next->flags);
848     ASSERT_EQ(NULL,fd_head->next->tvb_data);
849     ASSERT_NE(NULL,fd_head->next->next);
850
851     ASSERT_EQ(2,fd_head->next->next->frame);
852     ASSERT_EQ(1,fd_head->next->next->offset);  /* seqno */
853     ASSERT_EQ(60,fd_head->next->next->len);    /* segment length */
854     ASSERT_EQ(0,fd_head->next->next->flags);
855     ASSERT_EQ(NULL,fd_head->next->next->tvb_data);
856     ASSERT_NE(NULL,fd_head->next->next->next);
857
858     ASSERT_EQ(3,fd_head->next->next->next->frame);
859     ASSERT_EQ(2,fd_head->next->next->next->offset);  /* seqno */
860     ASSERT_EQ(40,fd_head->next->next->next->len);    /* segment length */
861     ASSERT_EQ(0,fd_head->next->next->next->flags);
862     ASSERT_EQ(NULL,fd_head->next->next->next->tvb_data);
863     ASSERT_NE(NULL,fd_head->next->next->next->next);
864
865     ASSERT_EQ(4,fd_head->next->next->next->next->frame);
866     ASSERT_EQ(2,fd_head->next->next->next->next->offset);  /* seqno */
867     ASSERT_EQ(40,fd_head->next->next->next->next->len);    /* segment length */
868     ASSERT_EQ(FD_OVERLAP,fd_head->next->next->next->next->flags);
869     ASSERT_EQ(NULL,fd_head->next->next->next->next->tvb_data);
870     ASSERT_EQ(NULL,fd_head->next->next->next->next->next);
871
872     /* test the actual reassembly */
873     ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
874     ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
875     ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
876
877 #if 0
878     print_fragment_table();
879 #endif
880 }
881
882 /* Test case for fragment_add_seq with duplicated (e.g., retransmitted) data
883  * where the retransmission "conflicts" with the original transmission
884  * (contents are different).
885  * Adds three fragments--adding the 2nd one twice--
886  * and checks that they are reassembled correctly.
887  */
888 /*   visit  id  frame  frag  len  more  tvb_offset
889        0    12     1     0    50   T      10
890        0    12     2     1    60   T      5
891        0    12     3     1    60   T      15
892        0    12     4     2    40   F      5
893 */
894 static void
895 test_fragment_add_seq_duplicate_conflict(void)
896 {
897     fragment_head *fd_head;
898
899     printf("Starting test test_fragment_add_seq_duplicate_conflict\n");
900
901     pinfo.fd->num = 1;
902     fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
903                              0, 50, TRUE, 0);
904
905     ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
906     ASSERT_EQ(NULL,fd_head);
907
908     /* Add the 2nd segment */
909     pinfo.fd->num = 2;
910     fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
911                              1, 60, TRUE, 0);
912
913     /* we haven't got all the fragments yet ... */
914     ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
915     ASSERT_EQ(NULL,fd_head);
916
917     /* Now, add the 2nd segment again (but in a different frame and with
918      * different data)
919      */
920     pinfo.fd->num = 3;
921     fd_head=fragment_add_seq(&test_reassembly_table, tvb, 15, &pinfo, 12, NULL,
922                              1, 60, TRUE, 0);
923
924     /* This duplicate fragment should have been ignored */
925     ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
926     ASSERT_EQ(NULL,fd_head);
927
928     /* finally, add the last fragment */
929     pinfo.fd->num = 4;
930     fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
931                              2, 40, FALSE, 0);
932
933     ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
934     ASSERT_NE(NULL,fd_head);
935
936     /* check the contents of the structure */
937     ASSERT_EQ(0,fd_head->frame);  /* unused */
938     ASSERT_EQ(0,fd_head->offset); /* unused */
939     ASSERT_EQ(150,fd_head->len); /* the length of data we have */
940     ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
941     ASSERT_EQ(4,fd_head->reassembled_in);
942     ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP|FD_OVERLAPCONFLICT,fd_head->flags);
943     ASSERT_NE(NULL,fd_head->tvb_data);
944     ASSERT_NE(NULL,fd_head->next);
945
946     ASSERT_EQ(1,fd_head->next->frame);
947     ASSERT_EQ(0,fd_head->next->offset);  /* seqno */
948     ASSERT_EQ(50,fd_head->next->len);    /* segment length */
949     ASSERT_EQ(0,fd_head->next->flags);
950     ASSERT_EQ(NULL,fd_head->next->tvb_data);
951     ASSERT_NE(NULL,fd_head->next->next);
952
953     ASSERT_EQ(2,fd_head->next->next->frame);
954     ASSERT_EQ(1,fd_head->next->next->offset);  /* seqno */
955     ASSERT_EQ(60,fd_head->next->next->len);    /* segment length */
956     ASSERT_EQ(0,fd_head->next->next->flags);
957     ASSERT_EQ(NULL,fd_head->next->next->tvb_data);
958     ASSERT_NE(NULL,fd_head->next->next->next);
959
960     ASSERT_EQ(3,fd_head->next->next->next->frame);
961     ASSERT_EQ(1,fd_head->next->next->next->offset);  /* seqno */
962     ASSERT_EQ(60,fd_head->next->next->next->len);    /* segment length */
963     ASSERT_EQ(FD_OVERLAP|FD_OVERLAPCONFLICT,fd_head->next->next->next->flags);
964     ASSERT_EQ(NULL,fd_head->next->next->next->tvb_data);
965     ASSERT_NE(NULL,fd_head->next->next->next->next);
966
967     ASSERT_EQ(4,fd_head->next->next->next->next->frame);
968     ASSERT_EQ(2,fd_head->next->next->next->next->offset);  /* seqno */
969     ASSERT_EQ(40,fd_head->next->next->next->next->len);    /* segment length */
970     ASSERT_EQ(0,fd_head->next->next->next->next->flags);
971     ASSERT_EQ(NULL,fd_head->next->next->next->next->tvb_data);
972     ASSERT_EQ(NULL,fd_head->next->next->next->next->next);
973
974     /* test the actual reassembly */
975     ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
976     ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
977     ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
978
979 #if 0
980     print_fragment_table();
981 #endif
982 }
983
984 /**********************************************************************************
985  *
986  * fragment_add_seq_check
987  *
988  *********************************************************************************/
989
990
991 /* This routine is used for both fragment_add_seq_802_11 and
992  * fragment_add_seq_check.
993  *
994  * Adds a couple of out-of-order fragments and checks their reassembly.
995  */
996
997 /*   visit  id  frame  frag  len  more  tvb_offset
998        0    12     1     0    50   T      10
999        0    13     2     0    60   T      15
1000        0    12     3     2    60   F       5
1001        0    12     4     1    60   F      15
1002 */
1003
1004
1005 static void
1006 test_fragment_add_seq_check_work(fragment_head *(*fn)(reassembly_table *,
1007                                  tvbuff_t *, const int, const packet_info *,
1008                                  const guint32, const void *, const guint32,
1009                                  const guint32, const gboolean))
1010 {
1011     fragment_head *fd_head;
1012
1013     pinfo.fd -> num = 1;
1014     fd_head=fn(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1015                0, 50, TRUE);
1016
1017     ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1018     ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1019     ASSERT_EQ(NULL,fd_head);
1020
1021     /* start another pdu (just to confuse things) */
1022     pinfo.fd->num = 2;
1023     fd_head=fn(&test_reassembly_table, tvb, 15, &pinfo, 13, NULL,
1024                0, 60, TRUE);
1025     ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
1026     ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1027     ASSERT_EQ(NULL,fd_head);
1028
1029     /* add the terminal fragment of the first datagram */
1030     pinfo.fd->num = 3;
1031     fd_head=fn(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1032                2, 60, FALSE);
1033
1034     /* we haven't got all the fragments yet ... */
1035     ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
1036     ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1037     ASSERT_EQ(NULL,fd_head);
1038
1039     /* finally, add the missing fragment */
1040     pinfo.fd->num = 4;
1041     fd_head=fn(&test_reassembly_table, tvb, 15, &pinfo, 12, NULL,
1042                1, 60, TRUE);
1043
1044     ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1045     ASSERT_EQ(3,g_hash_table_size(test_reassembly_table.reassembled_table));
1046     ASSERT_NE(NULL,fd_head);
1047
1048     /* check the contents of the structure */
1049     ASSERT_EQ(0,fd_head->frame);  /* unused */
1050     ASSERT_EQ(0,fd_head->offset); /* unused */
1051     ASSERT_EQ(170,fd_head->len); /* the length of data we have */
1052     ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
1053     ASSERT_EQ(4,fd_head->reassembled_in);
1054     ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
1055     ASSERT_NE(NULL,fd_head->tvb_data);
1056     ASSERT_NE(NULL,fd_head->next);
1057
1058     ASSERT_EQ(1,fd_head->next->frame);
1059     ASSERT_EQ(0,fd_head->next->offset);  /* seqno */
1060     ASSERT_EQ(50,fd_head->next->len);    /* segment length */
1061     ASSERT_EQ(0,fd_head->next->flags);
1062     ASSERT_EQ(NULL,fd_head->next->tvb_data);
1063     ASSERT_NE(NULL,fd_head->next->next);
1064
1065     ASSERT_EQ(4,fd_head->next->next->frame);
1066     ASSERT_EQ(1,fd_head->next->next->offset);  /* seqno */
1067     ASSERT_EQ(60,fd_head->next->next->len);    /* segment length */
1068     ASSERT_EQ(0,fd_head->next->next->flags);
1069     ASSERT_EQ(NULL,fd_head->next->next->tvb_data);
1070     ASSERT_NE(NULL,fd_head->next->next->next);
1071
1072     ASSERT_EQ(3,fd_head->next->next->next->frame);
1073     ASSERT_EQ(2,fd_head->next->next->next->offset);  /* seqno */
1074     ASSERT_EQ(60,fd_head->next->next->next->len);    /* segment length */
1075     ASSERT_EQ(0,fd_head->next->next->next->flags);
1076     ASSERT_EQ(NULL,fd_head->next->next->next->tvb_data);
1077     ASSERT_EQ(NULL,fd_head->next->next->next->next);
1078
1079     /* test the actual reassembly */
1080     ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
1081     ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+15,60));
1082     ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,60));
1083
1084 #if 0
1085     print_tables();
1086 #endif
1087 }
1088
1089 /* Simple test case for fragment_add_seq_check
1090  */
1091 static void
1092 test_fragment_add_seq_check(void)
1093 {
1094     printf("Starting test test_fragment_add_seq_check\n");
1095
1096     test_fragment_add_seq_check_work(fragment_add_seq_check);
1097 }
1098
1099
1100 /* This tests the case that the 802.11 hack does something different for: when
1101  * the terminal segment in a fragmented datagram arrives first.
1102  */
1103 static void
1104 test_fragment_add_seq_check_1(void)
1105 {
1106     fragment_head *fd_head;
1107
1108     printf("Starting test test_fragment_add_seq_check_1\n");
1109
1110     pinfo.fd->num = 1;
1111     fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1112                                    1, 50, FALSE);
1113
1114     ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1115     ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1116     ASSERT_EQ(NULL,fd_head);
1117
1118     /* Now add the missing segment */
1119     pinfo.fd->num = 2;
1120     fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1121                                    0, 60, TRUE);
1122
1123     ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1124     ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.reassembled_table));
1125     ASSERT_NE(NULL,fd_head);
1126
1127     /* check the contents of the structure */
1128     ASSERT_EQ(0,fd_head->frame);  /* unused */
1129     ASSERT_EQ(0,fd_head->offset); /* unused */
1130     ASSERT_EQ(110,fd_head->len); /* the length of data we have */
1131     ASSERT_EQ(1,fd_head->datalen); /* seqno of the last fragment we have */
1132     ASSERT_EQ(2,fd_head->reassembled_in);
1133     ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
1134     ASSERT_NE(NULL,fd_head->tvb_data);
1135     ASSERT_NE(NULL,fd_head->next);
1136
1137     ASSERT_EQ(2,fd_head->next->frame);
1138     ASSERT_EQ(0,fd_head->next->offset);  /* seqno */
1139     ASSERT_EQ(60,fd_head->next->len);    /* segment length */
1140     ASSERT_EQ(0,fd_head->next->flags);
1141     ASSERT_EQ(NULL,fd_head->next->tvb_data);
1142     ASSERT_NE(NULL,fd_head->next->next);
1143
1144     ASSERT_EQ(1,fd_head->next->next->frame);
1145     ASSERT_EQ(1,fd_head->next->next->offset);  /* seqno */
1146     ASSERT_EQ(50,fd_head->next->next->len);    /* segment length */
1147     ASSERT_EQ(0,fd_head->next->next->flags);
1148     ASSERT_EQ(NULL,fd_head->next->next->tvb_data);
1149     ASSERT_EQ(NULL,fd_head->next->next->next);
1150
1151     /* test the actual reassembly */
1152     ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+5,60));
1153     ASSERT(!tvb_memeql(fd_head->tvb_data,60,data+10,50));
1154 }
1155
1156 /**********************************************************************************
1157  *
1158  * fragment_add_seq_802_11
1159  *
1160  *********************************************************************************/
1161
1162 /* Tests the 802.11 hack.
1163  */
1164 static void
1165 test_fragment_add_seq_802_11_0(void)
1166 {
1167     fragment_head *fd_head;
1168
1169     printf("Starting test test_fragment_add_seq_802_11_0\n");
1170
1171     /* the 802.11 hack is that some non-fragmented datagrams have non-zero
1172      * fragment_number; test for this. */
1173
1174     pinfo.fd->num = 1;
1175     fd_head=fragment_add_seq_802_11(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1176                                     10, 50, FALSE);
1177
1178     ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1179     ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.reassembled_table));
1180     ASSERT_NE(NULL,fd_head);
1181
1182     /* check the contents of the structure */
1183     ASSERT_EQ(0,fd_head->frame);  /* unused */
1184     ASSERT_EQ(0,fd_head->offset); /* unused */
1185     ASSERT_EQ(0,fd_head->len);    /* unused */
1186     ASSERT_EQ(0,fd_head->datalen); /* unused */
1187     ASSERT_EQ(1,fd_head->reassembled_in);
1188     ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE,fd_head->flags);
1189     ASSERT_EQ(NULL,fd_head->tvb_data);
1190     ASSERT_EQ(NULL,fd_head->next);
1191 }
1192
1193 /* Reuse the fragment_add_seq_check testcases */
1194 static void test_fragment_add_seq_802_11_1(void)
1195 {
1196     printf("Starting test test_fragment_add_seq_802_11_1\n");
1197     test_fragment_add_seq_check_work(fragment_add_seq_802_11);
1198 }
1199
1200 /**********************************************************************************
1201  *
1202  * fragment_add_seq_check_multiple
1203  *
1204  *********************************************************************************/
1205
1206 /* Test 2 partial frags from 2 diff datagrams in the same frame */
1207 /*
1208    datagram #1: frame 1 + first part of frame 2
1209    datagram #1: last part of frame 2 + frame 3
1210
1211    Is this a valid scenario ?
1212
1213    The result of calling fragment_add_seq_check(&test_reassembly_table, ) for these
1214    fragments is a reassembled_table with:
1215     id, frame 1 => first_datagram;  ["reassembled in" frame 2]
1216     id, frame 2 => second_datagram; ["reassembled in" frame 3]
1217     id, frame 3 => second_datagram;
1218
1219     Note that the id, frame 2 => first datagram was overwritten
1220      by the entry for the second datagram.
1221    Is this OK ? IE: When dissected/displayed
1222       will the reassembled datagram 1 appear with frame 2 ??
1223 */
1224
1225 /*   visit  id  frame  frag  len  more  tvb_offset
1226        0    12     1     0    50   T      10
1227        0    12     2     1    20   F       5
1228        0    12     2     0    25   T      25
1229        0    12     3     1    60   F       0
1230 */
1231
1232 /*
1233    Is this a valid scenario ?
1234    Is this OK ? IE: When dissected/displayed:
1235       Will the reassembled datagram 1 appear with frame 2 ??
1236 */
1237 #if 0
1238 static void
1239 test_fragment_add_seq_check_multiple(void) {
1240     fragment_head *fd_head;
1241
1242     pinfo.fd -> num = 1;
1243     fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1244                                    0, 50, TRUE);
1245
1246     /* add the terminal fragment of the first datagram */
1247     pinfo.fd->num = 2;
1248     fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1249                                    1, 20, FALSE);
1250
1251     print_tables();
1252
1253     /* Now: start a second datagram with the first fragment in frame #2 */
1254     pinfo.fd->num = 2;
1255     fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 25, &pinfo, 12, NULL,
1256                0, 25, TRUE);
1257
1258     /* add the terminal fragment of the second datagram */
1259     pinfo.fd->num = 3;
1260     fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
1261                                    1, 60, FALSE);
1262
1263     print_tables();
1264 }
1265 #endif
1266
1267 /**********************************************************************************
1268  *
1269  * fragment_add_seq_next
1270  *
1271  *********************************************************************************/
1272
1273 /* Simple test case for fragment_add_seq_next.
1274  * Adds a couple of fragments (with one for a different datagram in between),
1275  * and checks that they are reassembled correctly.
1276  */
1277 static void
1278 test_simple_fragment_add_seq_next(void)
1279 {
1280     fragment_head *fd_head;
1281
1282     printf("Starting test test_simple_fragment_add_seq_next\n");
1283
1284     pinfo.fd->num = 1;
1285     fd_head= fragment_add_seq_next(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1286                                   50, TRUE);
1287
1288     ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1289     ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1290     ASSERT_EQ(NULL,fd_head);
1291
1292     /* adding the same fragment again should do nothing, even with different
1293      * offset etc */
1294     pinfo.fd->flags.visited = 1;
1295     fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1296                                   60, TRUE);
1297     ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1298     ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1299     ASSERT_EQ(NULL,fd_head);
1300
1301     /* start another pdu (just to confuse things) */
1302     pinfo.fd->flags.visited = 0;
1303     pinfo.fd->num = 2;
1304     fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 15, &pinfo, 13, NULL,
1305                                   60, TRUE);
1306     ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
1307     ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1308     ASSERT_EQ(NULL,fd_head);
1309
1310
1311     /* now we add the terminal fragment of the first datagram */
1312     pinfo.fd->num = 3;
1313     fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1314                                   60, FALSE);
1315
1316     ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1317     ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.reassembled_table));
1318     ASSERT_NE(NULL,fd_head);
1319
1320     /* check the contents of the structure */
1321     ASSERT_EQ(0,fd_head->frame);  /* unused */
1322     ASSERT_EQ(0,fd_head->offset); /* unused */
1323     ASSERT_EQ(110,fd_head->len); /* the length of data we have */
1324     ASSERT_EQ(1,fd_head->datalen); /* seqno of the last fragment we have */
1325     ASSERT_EQ(3,fd_head->reassembled_in);
1326     ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
1327     ASSERT_NE(NULL,fd_head->tvb_data);
1328     ASSERT_NE(NULL,fd_head->next);
1329
1330     ASSERT_EQ(1,fd_head->next->frame);
1331     ASSERT_EQ(0,fd_head->next->offset);  /* seqno */
1332     ASSERT_EQ(50,fd_head->next->len);    /* segment length */
1333     ASSERT_EQ(0,fd_head->next->flags);
1334     ASSERT_EQ(NULL,fd_head->next->tvb_data);
1335     ASSERT_NE(NULL,fd_head->next->next);
1336
1337     ASSERT_EQ(3,fd_head->next->next->frame);
1338     ASSERT_EQ(1,fd_head->next->next->offset);  /* seqno */
1339     ASSERT_EQ(60,fd_head->next->next->len);    /* segment length */
1340     ASSERT_EQ(0,fd_head->next->next->flags);
1341     ASSERT_EQ(NULL,fd_head->next->next->tvb_data);
1342     ASSERT_EQ(NULL,fd_head->next->next->next);
1343
1344     /* test the actual reassembly */
1345     ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
1346     ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
1347 }
1348
1349
1350 /* This tests the case where some data is missing from one of the fragments.
1351  * It should prevent reassembly.
1352  */
1353 static void
1354 test_missing_data_fragment_add_seq_next(void)
1355 {
1356     fragment_head *fd_head;
1357
1358     printf("Starting test test_missing_data_fragment_add_seq_next\n");
1359
1360     /* attempt to add a fragment which is longer than the data available */
1361     pinfo.fd->num = 1;
1362     fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1363                                   DATA_LEN-9, TRUE);
1364
1365     ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1366     ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1367     ASSERT_NE(NULL,fd_head);
1368
1369     /* check the contents of the structure. Reassembly failed so everything
1370      * should be null (meaning, just use the original tvb)  */
1371     ASSERT_EQ(0,fd_head->frame);  /* unused */
1372     ASSERT_EQ(0,fd_head->offset); /* unused */
1373     ASSERT_EQ(0,fd_head->len); /* the length of data we have */
1374     ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
1375     ASSERT_EQ(0,fd_head->reassembled_in);
1376     ASSERT_EQ(FD_BLOCKSEQUENCE,fd_head->flags & 0x1ff);
1377     ASSERT_EQ(NULL,fd_head->tvb_data);
1378     ASSERT_EQ(NULL,fd_head->next);
1379
1380     /* add another fragment (with all data present) */
1381     pinfo.fd->num = 4;
1382     fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1383                                   60, FALSE);
1384
1385     /* XXX: it's not clear that this is the right result; however it's what the
1386      * code does...
1387      */
1388     ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1389     ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1390     ASSERT_EQ(NULL,fd_head);
1391
1392
1393     /* check what happens when we revisit the packets */
1394     pinfo.fd->flags.visited = TRUE;
1395     pinfo.fd->num = 1;
1396
1397     fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1398                                   DATA_LEN-9, TRUE);
1399
1400     /* We just look in the reassembled_table for this packet. It never got put
1401      * there, so this always returns null.
1402      *
1403      * That's crazy, because it means that the subdissector will see the data
1404      * exactly once - on the first pass through the capture (well, assuming it
1405      * doesn't bother to check fd_head->reassembled_in); however, that's
1406      * what the code does...
1407      */
1408     ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1409     ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1410     ASSERT_EQ(NULL,fd_head);
1411
1412     pinfo.fd->num = 4;
1413     fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1414                                   60, FALSE);
1415     ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1416     ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1417     ASSERT_EQ(NULL,fd_head);
1418 }
1419
1420
1421 /*
1422  * we're going to do something similar now, but this time it is the second
1423  * fragment which has something missing.
1424  */
1425 static void
1426 test_missing_data_fragment_add_seq_next_2(void)
1427 {
1428     fragment_head *fd_head;
1429
1430     printf("Starting test test_missing_data_fragment_add_seq_next_2\n");
1431
1432     pinfo.fd->num = 11;
1433     fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 10, &pinfo, 24, NULL,
1434                                   50, TRUE);
1435
1436     ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1437     ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1438     ASSERT_EQ(NULL,fd_head);
1439
1440     pinfo.fd->num = 12;
1441     fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 24, NULL,
1442                                   DATA_LEN-4, FALSE);
1443
1444     /* XXX: again, i'm really dubious about this. Surely this should return all
1445      * the data we had, for a best-effort attempt at dissecting it?
1446      * And it ought to go into the reassembled table?
1447      */
1448     ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1449     ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1450     ASSERT_EQ(NULL,fd_head);
1451
1452     /* check what happens when we revisit the packets */
1453     pinfo.fd->flags.visited = TRUE;
1454     pinfo.fd->num = 11;
1455
1456     fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 10, &pinfo, 24, NULL,
1457                                   50, TRUE);
1458
1459     /* As before, this returns NULL because the fragment isn't in the
1460      * reassembled_table. At least this is a bit more consistent than before.
1461      */
1462     ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1463     ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1464     ASSERT_EQ(NULL,fd_head);
1465
1466     pinfo.fd->num = 12;
1467     fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 24, NULL,
1468                                   DATA_LEN-4, FALSE);
1469     ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1470     ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1471     ASSERT_EQ(NULL,fd_head);
1472
1473 }
1474
1475 /*
1476  * This time, our datagram only has one segment, but it has data missing.
1477  */
1478 static void
1479 test_missing_data_fragment_add_seq_next_3(void)
1480 {
1481     fragment_head *fd_head;
1482
1483     printf("Starting test test_missing_data_fragment_add_seq_next_3\n");
1484
1485     pinfo.fd->num = 20;
1486     fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 30, NULL,
1487                                   DATA_LEN-4, FALSE);
1488
1489     ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1490     ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.reassembled_table));
1491     ASSERT_NE(NULL,fd_head);
1492
1493     /* check the contents of the structure. */
1494     ASSERT_EQ(0,fd_head->frame);  /* unused */
1495     ASSERT_EQ(0,fd_head->offset); /* unused */
1496     ASSERT_EQ(0,fd_head->len); /* the length of data we have */
1497     ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
1498     ASSERT_EQ(20,fd_head->reassembled_in);
1499     ASSERT_EQ(FD_BLOCKSEQUENCE|FD_DEFRAGMENTED,fd_head->flags);
1500     ASSERT_EQ(NULL,fd_head->tvb_data);
1501     ASSERT_EQ(NULL,fd_head->next);
1502
1503     /* revisiting the packet ought to produce the same result. */
1504     pinfo.fd->flags.visited = TRUE;
1505
1506     pinfo.fd->num = 20;
1507     fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 30, NULL,
1508                                   DATA_LEN-4, FALSE);
1509
1510     ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1511     ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.reassembled_table));
1512     ASSERT_NE(NULL,fd_head);
1513     ASSERT_EQ(0,fd_head->frame);  /* unused */
1514     ASSERT_EQ(0,fd_head->offset); /* unused */
1515     ASSERT_EQ(0,fd_head->len); /* the length of data we have */
1516     ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
1517     ASSERT_EQ(20,fd_head->reassembled_in);
1518     ASSERT_EQ(FD_BLOCKSEQUENCE|FD_DEFRAGMENTED,fd_head->flags);
1519     ASSERT_EQ(NULL,fd_head->tvb_data);
1520     ASSERT_EQ(NULL,fd_head->next);
1521 }
1522
1523
1524 /**********************************************************************************
1525  *
1526  * main
1527  *
1528  *********************************************************************************/
1529
1530 int
1531 main(int argc _U_, char **argv _U_)
1532 {
1533     frame_data fd;
1534     static const guint8 src[] = {1,2,3,4}, dst[] = {5,6,7,8};
1535     unsigned int i;
1536     static void (*tests[])(void) = {
1537         test_simple_fragment_add_seq,              /* frag table only   */
1538         test_fragment_add_seq_partial_reassembly,
1539         test_fragment_add_seq_duplicate_first,
1540         test_fragment_add_seq_duplicate_middle,
1541         test_fragment_add_seq_duplicate_last,
1542         test_fragment_add_seq_duplicate_conflict,
1543         test_fragment_add_seq_check,               /* frag + reassemble */
1544         test_fragment_add_seq_check_1,
1545         test_fragment_add_seq_802_11_0,
1546         test_fragment_add_seq_802_11_1,
1547         test_simple_fragment_add_seq_next,
1548         test_missing_data_fragment_add_seq_next,
1549         test_missing_data_fragment_add_seq_next_2,
1550         test_missing_data_fragment_add_seq_next_3,
1551 #if 0
1552         test_fragment_add_seq_check_multiple
1553 #endif
1554     };
1555
1556     /* initialise stuff */
1557     emem_init();
1558
1559     /* a tvbuff for testing with */
1560     data = (char *)g_malloc(DATA_LEN);
1561     /* make sure it's full of stuff */
1562     for(i=0; i<DATA_LEN; i++) {
1563         data[i]=i & 0xFF;
1564     }
1565     tvb = tvb_new_real_data(data, DATA_LEN, DATA_LEN*2);
1566
1567     /* other test stuff */
1568     pinfo.fd = &fd;
1569     fd.flags.visited = 0;
1570     SET_ADDRESS(&pinfo.src,AT_IPv4,4,src);
1571     SET_ADDRESS(&pinfo.dst,AT_IPv4,4,dst);
1572
1573     /*************************************************************************/
1574     for(i=0; i < sizeof(tests)/sizeof(tests[0]); i++ ) {
1575         /* re-init the fragment tables */
1576         reassembly_table_init(&test_reassembly_table,
1577                               &addresses_reassembly_table_functions);
1578         ASSERT(test_reassembly_table.fragment_table != NULL);
1579         ASSERT(test_reassembly_table.reassembled_table != NULL);
1580
1581         pinfo.fd->flags.visited = FALSE;
1582
1583         tests[i]();
1584
1585         /* Free memory used by the tables */
1586         reassembly_table_destroy(&test_reassembly_table);
1587     }
1588
1589     tvb_free(tvb);
1590     tvb = NULL;
1591     g_free(data);
1592     data = NULL;
1593
1594     printf(failure?"FAILURE\n":"SUCCESS\n");
1595     return failure;
1596 }