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