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