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