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