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