1 /* Standalone program to test functionality of reassemble.h API
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.
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:
17 * G_DEBUG=gc-friendly \
18 * G_SLICE=always-malloc \
19 * valgrind --leak-check=full --show-reachable=yes ./reassemble_test
21 * 2. Debug functions have been added which will print information
22 * about the fd-chains associated with the fragment_table and the
24 * #define debug to enable the code.
26 * Copyright (c) 2007 MX Telecom Ltd. <richardv@mxtelecom.com>
28 * Wireshark - Network traffic analyzer
29 * By Gerald Combs <gerald@wireshark.org>
32 * This program is free software; you can redistribute it and/or
33 * modify it under the terms of the GNU General Public License
34 * as published by the Free Software Foundation; either version 2
35 * of the License, or (at your option) any later version.
37 * This program is distributed in the hope that it will be useful,
38 * but WITHOUT ANY WARRANTY; without even the implied warranty of
39 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
40 * GNU General Public License for more details.
42 * You should have received a copy of the GNU General Public License
43 * along with this program; if not, write to the Free Software
44 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
56 #include <epan/packet.h>
57 #include <epan/packet_info.h>
58 #include <epan/proto.h>
59 #include <epan/tvbuff.h>
60 #include <epan/reassemble.h>
62 #define ASSERT(b) do_test((b),"Assertion failed at line %i: %s\n", __LINE__, #b)
63 #define ASSERT_EQ(exp,act) do_test((exp)==(act),"Assertion failed at line %i: %s==%s (%i==%i)\n", __LINE__, #exp, #act, exp, act)
64 #define ASSERT_NE(exp,act) do_test((exp)!=(act),"Assertion failed at line %i: %s!=%s (%i!=%i)\n", __LINE__, #exp, #act, exp, act)
66 static int failure = 0;
69 do_test(gboolean condition, const char *format, ...)
77 vfprintf(stderr, format, ap);
81 /* many of the tests assume this routine doesn't return on failure; if we
82 * do, it may provide more information, but may cause a segfault. Uncomment
83 * this line if you wish.
92 static packet_info pinfo;
94 /* fragment_table maps from datagram ids to fragment_head
95 reassembled_table maps from <packet number,datagram id> to
97 static reassembly_table test_reassembly_table;
100 /*************************************************
101 * Util fcns to display
102 * fragment_table & reassembled_table fd-chains
103 ************************************************/
105 static struct _fd_flags {
109 {FD_DEFRAGMENTED ,"DF"},
110 {FD_DATALEN_SET ,"DS"},
111 {FD_SUBSET_TVB, ,"ST"},
112 {FD_BLOCKSEQUENCE ,"BS"},
113 {FD_DATA_NOT_PRESENT ,"NP"},
114 {FD_PARTIAL_REASSEMBLY ,"PR"},
116 {FD_OVERLAPCONFLICT ,"OC"},
117 {FD_MULTIPLETAILS ,"MT"},
118 {FD_TOOLONGFRAGMENT ,"TL"},
120 #define N_FD_FLAGS (signed)(sizeof(fd_flags)/sizeof(struct _fd_flags))
123 print_fd(fragment_head *fd, gboolean is_head) {
126 g_assert(fd != NULL);
127 printf(" %08x %08x %3d %3d %3d", fd, fd->next, fd->frame, fd->offset, fd->len);
129 printf(" %3d %3d", fd->datalen, fd->reassembled_in);
133 printf(" 0x%08x", fd->data);
134 for (i=0; i<N_FD_FLAGS; i++) {
135 printf(" %s", (fd->flags & fd_flags[i].flag) ? fd_flags[i].flag_name : " ");
141 print_fd_chain(fragment_head *fd_head) {
144 g_assert(fd_head != NULL);
145 print_fd(fd_head, TRUE);
146 for (fdp=fd_head->next; fdp != NULL; fdp=fdp->next) {
147 print_fd(fdp, FALSE);
152 print_fragment_table_chain(gpointer k, gpointer v, gpointer ud) {
153 fragment_key *key = (fragment_key*)k;
154 fragment_head *fd_head = (fragment_head *)v;
155 printf(" --> FT: %3d 0x%08x 0x%08x\n", key->id, *(guint32 *)(key->src.data), *(guint32 *)(key->dst.data));
156 print_fd_chain(fd_head);
160 print_fragment_table(void) {
161 printf("\n Fragment Table -------\n");
162 g_hash_table_foreach(fragment_table, print_fragment_table_chain, NULL);
166 print_reassembled_table_chain(gpointer k, gpointer v, gpointer ud) {
167 reassembled_key *key = (reassembled_key*)k;
168 fragment_head *fd_head = (fragment_head *)v;
169 printf(" --> RT: %5d %5d\n", key->id, key->frame);
170 print_fd_chain(fd_head);
174 print_reassembled_table(void) {
175 printf("\n Reassembled Table ----\n");
176 g_hash_table_foreach(test_reassembly_table.reassembled_table, print_reassembled_table_chain, NULL);
181 print_fragment_table();
182 print_reassembled_table();
186 /**********************************************************************************
190 *********************************************************************************/
192 /* Simple test case for fragment_add_seq.
193 * Adds three fragments (out of order, with one for a different datagram in between),
194 * and checks that they are reassembled correctly.
196 /* visit id frame frag len more tvb_offset
204 test_simple_fragment_add_seq(void)
206 fragment_head *fd_head, *fdh0;
208 printf("Starting test test_simple_fragment_add_seq\n");
211 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
214 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
215 ASSERT_EQ(NULL,fd_head);
217 /* adding the same fragment again should do nothing, even with different
219 pinfo.fd->flags.visited = 1;
220 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
222 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
223 ASSERT_EQ(NULL,fd_head);
225 /* start another pdu (just to confuse things) */
226 pinfo.fd->flags.visited = 0;
228 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 15, &pinfo, 13, NULL,
230 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
231 ASSERT_EQ(NULL,fd_head);
233 /* now we add the terminal fragment of the first datagram */
235 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
238 /* we haven't got all the fragments yet ... */
239 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
240 ASSERT_EQ(NULL,fd_head);
242 /* finally, add the missing fragment */
244 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 15, &pinfo, 12, NULL,
247 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
248 ASSERT_NE(NULL,fd_head);
250 /* check the contents of the structure */
251 ASSERT_EQ(0,fd_head->frame); /* unused */
252 ASSERT_EQ(0,fd_head->offset); /* unused */
253 ASSERT_EQ(170,fd_head->len); /* the length of data we have */
254 ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
255 ASSERT_EQ(4,fd_head->reassembled_in);
256 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
257 ASSERT_NE(NULL,fd_head->tvb_data);
258 ASSERT_NE(NULL,fd_head->next);
260 ASSERT_EQ(1,fd_head->next->frame);
261 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
262 ASSERT_EQ(50,fd_head->next->len); /* segment length */
263 ASSERT_EQ(0,fd_head->next->flags);
264 ASSERT_EQ(NULL,fd_head->next->tvb_data);
265 ASSERT_NE(NULL,fd_head->next->next);
267 ASSERT_EQ(4,fd_head->next->next->frame);
268 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
269 ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
270 ASSERT_EQ(0,fd_head->next->next->flags);
271 ASSERT_EQ(NULL,fd_head->next->next->tvb_data);
272 ASSERT_NE(NULL,fd_head->next->next->next);
274 ASSERT_EQ(3,fd_head->next->next->next->frame);
275 ASSERT_EQ(2,fd_head->next->next->next->offset); /* seqno */
276 ASSERT_EQ(60,fd_head->next->next->next->len); /* segment length */
277 ASSERT_EQ(0,fd_head->next->next->next->flags);
278 ASSERT_EQ(NULL,fd_head->next->next->next->tvb_data);
279 ASSERT_EQ(NULL,fd_head->next->next->next->next);
281 /* test the actual reassembly */
282 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
283 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+15,60));
284 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,60));
287 print_fragment_table();
290 /* what happens if we revisit the packets now? */
292 pinfo.fd->flags.visited = 1;
294 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
297 * this api relies on the caller to check fd_head -> reassembled_in
299 * Redoing all the tests seems like overkill - just check the pointer
301 ASSERT_EQ(fdh0,fd_head);
304 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
306 ASSERT_EQ(fdh0,fd_head);
309 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 15, &pinfo, 12, NULL,
311 ASSERT_EQ(fdh0,fd_head);
314 print_fragment_table();
318 /* XXX ought to have some tests for overlapping fragments */
320 /* This tests the functionality of fragment_set_partial_reassembly for
321 * FD_BLOCKSEQUENCE reassembly.
323 * We add a sequence of fragments thus:
324 * seqno frame offset len (initial) more_frags
325 * ----- ----- ------ --- --------------------
328 * 1 3 0 40 true (a duplicate fragment)
333 test_fragment_add_seq_partial_reassembly(void)
335 fragment_head *fd_head;
338 printf("Starting test test_fragment_add_seq_partial_reassembly\n");
340 /* generally it's probably fair to assume that we will be called with
344 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
347 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
348 ASSERT_NE(NULL,fd_head);
350 /* check the contents of the structure */
351 ASSERT_EQ(0,fd_head->frame); /* unused */
352 ASSERT_EQ(0,fd_head->offset); /* unused */
353 ASSERT_EQ(50,fd_head->len); /* the length of data we have */
354 ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
355 ASSERT_EQ(1,fd_head->reassembled_in);
356 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
357 ASSERT_NE(NULL,fd_head->tvb_data);
358 ASSERT_NE(NULL,fd_head->next);
360 ASSERT_EQ(1,fd_head->next->frame);
361 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
362 ASSERT_EQ(50,fd_head->next->len); /* segment length */
363 ASSERT_EQ(0,fd_head->next->flags);
364 ASSERT_EQ(NULL,fd_head->next->tvb_data);
365 ASSERT_EQ(NULL,fd_head->next->next);
367 /* test the actual reassembly */
368 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
370 /* now we announce that the reassembly wasn't complete after all. */
371 fragment_set_partial_reassembly(&test_reassembly_table, &pinfo, 12, NULL);
373 /* and add another segment. To mix things up slightly (and so that we can
374 * check on the state of things), we're going to set the more_frags flag
378 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
381 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
382 ASSERT_EQ(NULL,fd_head);
384 fd_head=fragment_get(&test_reassembly_table, &pinfo, 12, NULL);
385 ASSERT_NE(NULL,fd_head);
387 /* check the contents of the structure */
388 ASSERT_EQ(0,fd_head->frame); /* unused */
389 ASSERT_EQ(0,fd_head->offset); /* unused */
390 /* ASSERT_EQ(50,fd_head->len); the length of data we have */
391 ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
392 ASSERT_EQ(0,fd_head->reassembled_in);
393 ASSERT_EQ(FD_BLOCKSEQUENCE,fd_head->flags);
394 ASSERT_NE(NULL,fd_head->tvb_data);
395 ASSERT_NE(NULL,fd_head->next);
398 ASSERT_EQ(1,fd->frame);
399 ASSERT_EQ(0,fd->offset); /* seqno */
400 ASSERT_EQ(50,fd->len); /* segment length */
401 ASSERT_EQ(FD_SUBSET_TVB,fd->flags);
402 ASSERT_EQ(tvb_get_ptr(fd_head->tvb_data,0,0),tvb_get_ptr(fd->tvb_data,0,0));
403 ASSERT_NE(NULL,fd->next);
406 ASSERT_EQ(2,fd->frame);
407 ASSERT_EQ(1,fd->offset); /* seqno */
408 ASSERT_EQ(40,fd->len); /* segment length */
409 ASSERT_EQ(0,fd->flags);
410 ASSERT_NE(NULL,fd->tvb_data);
411 ASSERT_EQ(NULL,fd->next);
413 /* Another copy of the second segment.
416 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
419 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
420 ASSERT_EQ(NULL,fd_head);
421 fd_head=fragment_get(&test_reassembly_table, &pinfo, 12, NULL);
422 ASSERT_NE(NULL,fd_head);
423 ASSERT_EQ(0,fd_head->frame); /* unused */
424 ASSERT_EQ(0,fd_head->offset); /* unused */
425 /* ASSERT_EQ(50,fd_head->len); the length of data we have */
426 ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
427 ASSERT_EQ(0,fd_head->reassembled_in);
428 ASSERT_EQ(FD_BLOCKSEQUENCE,fd_head->flags);
429 ASSERT_NE(NULL,fd_head->tvb_data);
430 ASSERT_NE(NULL,fd_head->next);
433 ASSERT_EQ(1,fd->frame);
434 ASSERT_EQ(0,fd->offset); /* seqno */
435 ASSERT_EQ(50,fd->len); /* segment length */
436 ASSERT_EQ(FD_SUBSET_TVB,fd->flags);
437 ASSERT_EQ(tvb_get_ptr(fd_head->tvb_data,0,0),tvb_get_ptr(fd->tvb_data,0,0));
438 ASSERT_NE(NULL,fd->next);
441 ASSERT_EQ(2,fd->frame);
442 ASSERT_EQ(1,fd->offset); /* seqno */
443 ASSERT_EQ(40,fd->len); /* segment length */
444 ASSERT_EQ(0,fd->flags);
445 ASSERT_NE(NULL,fd->tvb_data);
446 ASSERT_NE(NULL,fd->next);
449 ASSERT_EQ(3,fd->frame);
450 ASSERT_EQ(1,fd->offset); /* seqno */
451 ASSERT_EQ(40,fd->len); /* segment length */
452 ASSERT_EQ(0,fd->flags);
453 ASSERT_NE(NULL,fd->tvb_data);
454 ASSERT_EQ(NULL,fd->next);
458 /* have another go at wrapping things up */
460 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 20, &pinfo, 12, NULL,
463 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
464 ASSERT_NE(NULL,fd_head);
466 /* check the contents of the structure */
467 ASSERT_EQ(0,fd_head->frame); /* unused */
468 ASSERT_EQ(0,fd_head->offset); /* unused */
469 ASSERT_EQ(190,fd_head->len); /* the length of data we have */
470 ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
471 ASSERT_EQ(4,fd_head->reassembled_in);
472 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
473 ASSERT_NE(NULL,fd_head->tvb_data);
474 ASSERT_NE(NULL,fd_head->next);
477 ASSERT_EQ(1,fd->frame);
478 ASSERT_EQ(0,fd->offset); /* seqno */
479 ASSERT_EQ(50,fd->len); /* segment length */
480 ASSERT_EQ(0,fd->flags);
481 ASSERT_EQ(NULL,fd->tvb_data);
482 ASSERT_NE(NULL,fd->next);
485 ASSERT_EQ(2,fd->frame);
486 ASSERT_EQ(1,fd->offset); /* seqno */
487 ASSERT_EQ(40,fd->len); /* segment length */
488 ASSERT_EQ(0,fd->flags);
489 ASSERT_EQ(NULL,fd->tvb_data);
490 ASSERT_NE(NULL,fd->next);
493 ASSERT_EQ(3,fd->frame);
494 ASSERT_EQ(1,fd->offset); /* seqno */
495 ASSERT_EQ(40,fd->len); /* segment length */
496 ASSERT_EQ(FD_OVERLAP,fd->flags);
497 ASSERT_EQ(NULL,fd->tvb_data);
498 ASSERT_NE(NULL,fd->next);
501 ASSERT_EQ(4,fd->frame);
502 ASSERT_EQ(2,fd->offset); /* seqno */
503 ASSERT_EQ(100,fd->len); /* segment length */
504 ASSERT_EQ(0,fd->flags);
505 ASSERT_EQ(NULL,fd->tvb_data);
506 ASSERT_EQ(NULL,fd->next);
508 /* test the actual reassembly */
509 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
510 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data,40));
511 ASSERT(!tvb_memeql(fd_head->tvb_data,90,data+20,100));
514 /* do it again (this time it is more complicated, with an overlap in the
517 fragment_set_partial_reassembly(&test_reassembly_table, &pinfo, 12, NULL);
520 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
523 fd_head=fragment_get(&test_reassembly_table, &pinfo, 12, NULL);
524 ASSERT_NE(NULL,fd_head);
525 ASSERT_EQ(0,fd_head->frame); /* unused */
526 ASSERT_EQ(0,fd_head->offset); /* unused */
527 ASSERT_EQ(230,fd_head->len); /* the length of data we have */
528 ASSERT_EQ(3,fd_head->datalen); /* seqno of the last fragment we have */
529 ASSERT_EQ(5,fd_head->reassembled_in);
530 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
531 ASSERT_NE(NULL,fd_head->tvb_data);
532 ASSERT_NE(NULL,fd_head->next);
535 ASSERT_EQ(1,fd->frame);
536 ASSERT_EQ(0,fd->offset); /* seqno */
537 ASSERT_EQ(50,fd->len); /* segment length */
538 ASSERT_EQ(0,fd->flags);
539 ASSERT_EQ(NULL,fd->tvb_data);
540 ASSERT_NE(NULL,fd->next);
543 ASSERT_EQ(2,fd->frame);
544 ASSERT_EQ(1,fd->offset); /* seqno */
545 ASSERT_EQ(40,fd->len); /* segment length */
546 ASSERT_EQ(0,fd->flags);
547 ASSERT_EQ(NULL,fd->tvb_data);
548 ASSERT_NE(NULL,fd->next);
551 ASSERT_EQ(3,fd->frame);
552 ASSERT_EQ(1,fd->offset); /* seqno */
553 ASSERT_EQ(40,fd->len); /* segment length */
554 ASSERT_EQ(FD_OVERLAP,fd->flags);
555 ASSERT_EQ(NULL,fd->tvb_data);
556 ASSERT_NE(NULL,fd->next);
559 ASSERT_EQ(4,fd->frame);
560 ASSERT_EQ(2,fd->offset); /* seqno */
561 ASSERT_EQ(100,fd->len); /* segment length */
562 ASSERT_EQ(0,fd->flags);
563 ASSERT_EQ(NULL,fd->tvb_data);
564 ASSERT_NE(NULL,fd->next);
567 ASSERT_EQ(5,fd->frame);
568 ASSERT_EQ(3,fd->offset); /* seqno */
569 ASSERT_EQ(40,fd->len); /* segment length */
570 ASSERT_EQ(0,fd->flags);
571 ASSERT_EQ(NULL,fd->tvb_data);
572 ASSERT_EQ(NULL,fd->next);
574 /* test the actual reassembly */
575 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
576 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data,40));
577 ASSERT(!tvb_memeql(fd_head->tvb_data,90,data+20,100));
578 ASSERT(!tvb_memeql(fd_head->tvb_data,190,data,40));
581 /* Test case for fragment_add_seq with duplicated (e.g., retransmitted) data.
582 * Adds three fragments--adding the 1st one twice--
583 * and checks that they are reassembled correctly.
585 /* visit id frame frag len more tvb_offset
592 test_fragment_add_seq_duplicate_first(void)
594 fragment_head *fd_head;
596 printf("Starting test test_fragment_add_seq_duplicate_first\n");
599 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
602 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
603 ASSERT_EQ(NULL,fd_head);
605 /* Add the 2nd segment */
607 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
610 /* we haven't got all the fragments yet ... */
611 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
612 ASSERT_EQ(NULL,fd_head);
614 /* Add the last fragment */
616 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
619 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
620 ASSERT_NE(NULL,fd_head);
622 /* Add the first fragment again */
624 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
627 /* Reassembly should have still succeeded */
628 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
629 ASSERT_NE(NULL,fd_head);
631 /* check the contents of the structure */
632 ASSERT_EQ(0,fd_head->frame); /* unused */
633 ASSERT_EQ(0,fd_head->offset); /* unused */
634 ASSERT_EQ(150,fd_head->len); /* the length of data we have */
635 ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
636 ASSERT_EQ(3,fd_head->reassembled_in);
637 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
638 ASSERT_NE(NULL,fd_head->tvb_data);
639 ASSERT_NE(NULL,fd_head->next);
641 ASSERT_EQ(1,fd_head->next->frame);
642 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
643 ASSERT_EQ(50,fd_head->next->len); /* segment length */
644 ASSERT_EQ(0,fd_head->next->flags);
645 ASSERT_EQ(NULL,fd_head->next->tvb_data);
646 ASSERT_NE(NULL,fd_head->next->next);
648 ASSERT_EQ(4,fd_head->next->next->frame);
649 ASSERT_EQ(0,fd_head->next->next->offset); /* seqno */
650 ASSERT_EQ(50,fd_head->next->next->len); /* segment length */
651 ASSERT_EQ(FD_OVERLAP,fd_head->next->next->flags);
652 ASSERT_EQ(NULL,fd_head->next->next->tvb_data);
653 ASSERT_NE(NULL,fd_head->next->next->next);
655 ASSERT_EQ(2,fd_head->next->next->next->frame);
656 ASSERT_EQ(1,fd_head->next->next->next->offset); /* seqno */
657 ASSERT_EQ(60,fd_head->next->next->next->len); /* segment length */
658 ASSERT_EQ(0,fd_head->next->next->next->flags);
659 ASSERT_EQ(NULL,fd_head->next->next->next->tvb_data);
660 ASSERT_NE(NULL,fd_head->next->next->next->next);
662 ASSERT_EQ(3,fd_head->next->next->next->next->frame);
663 ASSERT_EQ(2,fd_head->next->next->next->next->offset); /* seqno */
664 ASSERT_EQ(40,fd_head->next->next->next->next->len); /* segment length */
665 ASSERT_EQ(0,fd_head->next->next->next->next->flags);
666 ASSERT_EQ(NULL,fd_head->next->next->next->next->tvb_data);
667 ASSERT_EQ(NULL,fd_head->next->next->next->next->next);
669 /* test the actual reassembly */
670 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
671 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
672 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
675 print_fragment_table();
680 /* Test case for fragment_add_seq with duplicated (e.g., retransmitted) data.
681 * Adds three fragments--adding the 2nd one twice--
682 * and checks that they are reassembled correctly.
684 /* visit id frame frag len more tvb_offset
691 test_fragment_add_seq_duplicate_middle(void)
693 fragment_head *fd_head;
695 printf("Starting test test_fragment_add_seq_duplicate_middle\n");
698 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
701 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
702 ASSERT_EQ(NULL,fd_head);
704 /* Add the 2nd segment */
706 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
709 /* we haven't got all the fragments yet ... */
710 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
711 ASSERT_EQ(NULL,fd_head);
713 /* Now, add the 2nd segment again (but in a different frame) */
715 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
718 /* This duplicate fragment should have been ignored */
719 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
720 ASSERT_EQ(NULL,fd_head);
722 /* finally, add the last fragment */
724 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
727 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
728 ASSERT_NE(NULL,fd_head);
730 /* check the contents of the structure */
731 ASSERT_EQ(0,fd_head->frame); /* unused */
732 ASSERT_EQ(0,fd_head->offset); /* unused */
733 ASSERT_EQ(150,fd_head->len); /* the length of data we have */
734 ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
735 ASSERT_EQ(4,fd_head->reassembled_in);
736 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
737 ASSERT_NE(NULL,fd_head->tvb_data);
738 ASSERT_NE(NULL,fd_head->next);
740 ASSERT_EQ(1,fd_head->next->frame);
741 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
742 ASSERT_EQ(50,fd_head->next->len); /* segment length */
743 ASSERT_EQ(0,fd_head->next->flags);
744 ASSERT_EQ(NULL,fd_head->next->tvb_data);
745 ASSERT_NE(NULL,fd_head->next->next);
747 ASSERT_EQ(2,fd_head->next->next->frame);
748 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
749 ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
750 ASSERT_EQ(0,fd_head->next->next->flags);
751 ASSERT_EQ(NULL,fd_head->next->next->tvb_data);
752 ASSERT_NE(NULL,fd_head->next->next->next);
754 ASSERT_EQ(3,fd_head->next->next->next->frame);
755 ASSERT_EQ(1,fd_head->next->next->next->offset); /* seqno */
756 ASSERT_EQ(60,fd_head->next->next->next->len); /* segment length */
757 ASSERT_EQ(FD_OVERLAP,fd_head->next->next->next->flags);
758 ASSERT_EQ(NULL,fd_head->next->next->next->tvb_data);
759 ASSERT_NE(NULL,fd_head->next->next->next->next);
761 ASSERT_EQ(4,fd_head->next->next->next->next->frame);
762 ASSERT_EQ(2,fd_head->next->next->next->next->offset); /* seqno */
763 ASSERT_EQ(40,fd_head->next->next->next->next->len); /* segment length */
764 ASSERT_EQ(0,fd_head->next->next->next->next->flags);
765 ASSERT_EQ(NULL,fd_head->next->next->next->next->tvb_data);
766 ASSERT_EQ(NULL,fd_head->next->next->next->next->next);
768 /* test the actual reassembly */
769 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
770 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
771 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
774 print_fragment_table();
778 /* Test case for fragment_add_seq with duplicated (e.g., retransmitted) data.
779 * Adds three fragments--adding the 3rd one twice--
780 * and checks that they are reassembled correctly.
782 /* visit id frame frag len more tvb_offset
789 test_fragment_add_seq_duplicate_last(void)
791 fragment_head *fd_head;
793 printf("Starting test test_fragment_add_seq_duplicate_last\n");
796 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
799 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
800 ASSERT_EQ(NULL,fd_head);
802 /* Add the 2nd segment */
804 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
807 /* we haven't got all the fragments yet ... */
808 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
809 ASSERT_EQ(NULL,fd_head);
811 /* Add the last fragment */
813 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
816 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
817 ASSERT_NE(NULL,fd_head);
819 /* Add the last fragment again */
821 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
824 /* Reassembly should have still succeeded */
825 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
826 ASSERT_NE(NULL,fd_head);
828 /* check the contents of the structure */
829 ASSERT_EQ(0,fd_head->frame); /* unused */
830 ASSERT_EQ(0,fd_head->offset); /* unused */
831 ASSERT_EQ(150,fd_head->len); /* the length of data we have */
832 ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
833 ASSERT_EQ(3,fd_head->reassembled_in);
834 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
835 ASSERT_NE(NULL,fd_head->tvb_data);
836 ASSERT_NE(NULL,fd_head->next);
838 ASSERT_EQ(1,fd_head->next->frame);
839 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
840 ASSERT_EQ(50,fd_head->next->len); /* segment length */
841 ASSERT_EQ(0,fd_head->next->flags);
842 ASSERT_EQ(NULL,fd_head->next->tvb_data);
843 ASSERT_NE(NULL,fd_head->next->next);
845 ASSERT_EQ(2,fd_head->next->next->frame);
846 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
847 ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
848 ASSERT_EQ(0,fd_head->next->next->flags);
849 ASSERT_EQ(NULL,fd_head->next->next->tvb_data);
850 ASSERT_NE(NULL,fd_head->next->next->next);
852 ASSERT_EQ(3,fd_head->next->next->next->frame);
853 ASSERT_EQ(2,fd_head->next->next->next->offset); /* seqno */
854 ASSERT_EQ(40,fd_head->next->next->next->len); /* segment length */
855 ASSERT_EQ(0,fd_head->next->next->next->flags);
856 ASSERT_EQ(NULL,fd_head->next->next->next->tvb_data);
857 ASSERT_NE(NULL,fd_head->next->next->next->next);
859 ASSERT_EQ(4,fd_head->next->next->next->next->frame);
860 ASSERT_EQ(2,fd_head->next->next->next->next->offset); /* seqno */
861 ASSERT_EQ(40,fd_head->next->next->next->next->len); /* segment length */
862 ASSERT_EQ(FD_OVERLAP,fd_head->next->next->next->next->flags);
863 ASSERT_EQ(NULL,fd_head->next->next->next->next->tvb_data);
864 ASSERT_EQ(NULL,fd_head->next->next->next->next->next);
866 /* test the actual reassembly */
867 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
868 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
869 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
872 print_fragment_table();
876 /* Test case for fragment_add_seq with duplicated (e.g., retransmitted) data
877 * where the retransmission "conflicts" with the original transmission
878 * (contents are different).
879 * Adds three fragments--adding the 2nd one twice--
880 * and checks that they are reassembled correctly.
882 /* visit id frame frag len more tvb_offset
889 test_fragment_add_seq_duplicate_conflict(void)
891 fragment_head *fd_head;
893 printf("Starting test test_fragment_add_seq_duplicate_conflict\n");
896 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
899 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
900 ASSERT_EQ(NULL,fd_head);
902 /* Add the 2nd segment */
904 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
907 /* we haven't got all the fragments yet ... */
908 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
909 ASSERT_EQ(NULL,fd_head);
911 /* Now, add the 2nd segment again (but in a different frame and with
915 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 15, &pinfo, 12, NULL,
918 /* This duplicate fragment should have been ignored */
919 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
920 ASSERT_EQ(NULL,fd_head);
922 /* finally, add the last fragment */
924 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
927 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
928 ASSERT_NE(NULL,fd_head);
930 /* check the contents of the structure */
931 ASSERT_EQ(0,fd_head->frame); /* unused */
932 ASSERT_EQ(0,fd_head->offset); /* unused */
933 ASSERT_EQ(150,fd_head->len); /* the length of data we have */
934 ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
935 ASSERT_EQ(4,fd_head->reassembled_in);
936 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP|FD_OVERLAPCONFLICT,fd_head->flags);
937 ASSERT_NE(NULL,fd_head->tvb_data);
938 ASSERT_NE(NULL,fd_head->next);
940 ASSERT_EQ(1,fd_head->next->frame);
941 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
942 ASSERT_EQ(50,fd_head->next->len); /* segment length */
943 ASSERT_EQ(0,fd_head->next->flags);
944 ASSERT_EQ(NULL,fd_head->next->tvb_data);
945 ASSERT_NE(NULL,fd_head->next->next);
947 ASSERT_EQ(2,fd_head->next->next->frame);
948 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
949 ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
950 ASSERT_EQ(0,fd_head->next->next->flags);
951 ASSERT_EQ(NULL,fd_head->next->next->tvb_data);
952 ASSERT_NE(NULL,fd_head->next->next->next);
954 ASSERT_EQ(3,fd_head->next->next->next->frame);
955 ASSERT_EQ(1,fd_head->next->next->next->offset); /* seqno */
956 ASSERT_EQ(60,fd_head->next->next->next->len); /* segment length */
957 ASSERT_EQ(FD_OVERLAP|FD_OVERLAPCONFLICT,fd_head->next->next->next->flags);
958 ASSERT_EQ(NULL,fd_head->next->next->next->tvb_data);
959 ASSERT_NE(NULL,fd_head->next->next->next->next);
961 ASSERT_EQ(4,fd_head->next->next->next->next->frame);
962 ASSERT_EQ(2,fd_head->next->next->next->next->offset); /* seqno */
963 ASSERT_EQ(40,fd_head->next->next->next->next->len); /* segment length */
964 ASSERT_EQ(0,fd_head->next->next->next->next->flags);
965 ASSERT_EQ(NULL,fd_head->next->next->next->next->tvb_data);
966 ASSERT_EQ(NULL,fd_head->next->next->next->next->next);
968 /* test the actual reassembly */
969 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
970 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
971 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
974 print_fragment_table();
978 /**********************************************************************************
980 * fragment_add_seq_check
982 *********************************************************************************/
985 /* This routine is used for both fragment_add_seq_802_11 and
986 * fragment_add_seq_check.
988 * Adds a couple of out-of-order fragments and checks their reassembly.
991 /* visit id frame frag len more tvb_offset
1000 test_fragment_add_seq_check_work(fragment_head *(*fn)(reassembly_table *,
1001 tvbuff_t *, const int, const packet_info *,
1002 const guint32, const void *, const guint32,
1003 const guint32, const gboolean))
1005 fragment_head *fd_head;
1008 fd_head=fn(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1011 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1012 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1013 ASSERT_EQ(NULL,fd_head);
1015 /* start another pdu (just to confuse things) */
1017 fd_head=fn(&test_reassembly_table, tvb, 15, &pinfo, 13, NULL,
1019 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
1020 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1021 ASSERT_EQ(NULL,fd_head);
1023 /* add the terminal fragment of the first datagram */
1025 fd_head=fn(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1028 /* we haven't got all the fragments yet ... */
1029 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
1030 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1031 ASSERT_EQ(NULL,fd_head);
1033 /* finally, add the missing fragment */
1035 fd_head=fn(&test_reassembly_table, tvb, 15, &pinfo, 12, NULL,
1038 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1039 ASSERT_EQ(3,g_hash_table_size(test_reassembly_table.reassembled_table));
1040 ASSERT_NE(NULL,fd_head);
1042 /* check the contents of the structure */
1043 ASSERT_EQ(0,fd_head->frame); /* unused */
1044 ASSERT_EQ(0,fd_head->offset); /* unused */
1045 ASSERT_EQ(170,fd_head->len); /* the length of data we have */
1046 ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
1047 ASSERT_EQ(4,fd_head->reassembled_in);
1048 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
1049 ASSERT_NE(NULL,fd_head->tvb_data);
1050 ASSERT_NE(NULL,fd_head->next);
1052 ASSERT_EQ(1,fd_head->next->frame);
1053 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
1054 ASSERT_EQ(50,fd_head->next->len); /* segment length */
1055 ASSERT_EQ(0,fd_head->next->flags);
1056 ASSERT_EQ(NULL,fd_head->next->tvb_data);
1057 ASSERT_NE(NULL,fd_head->next->next);
1059 ASSERT_EQ(4,fd_head->next->next->frame);
1060 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
1061 ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
1062 ASSERT_EQ(0,fd_head->next->next->flags);
1063 ASSERT_EQ(NULL,fd_head->next->next->tvb_data);
1064 ASSERT_NE(NULL,fd_head->next->next->next);
1066 ASSERT_EQ(3,fd_head->next->next->next->frame);
1067 ASSERT_EQ(2,fd_head->next->next->next->offset); /* seqno */
1068 ASSERT_EQ(60,fd_head->next->next->next->len); /* segment length */
1069 ASSERT_EQ(0,fd_head->next->next->next->flags);
1070 ASSERT_EQ(NULL,fd_head->next->next->next->tvb_data);
1071 ASSERT_EQ(NULL,fd_head->next->next->next->next);
1073 /* test the actual reassembly */
1074 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
1075 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+15,60));
1076 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,60));
1083 /* Simple test case for fragment_add_seq_check
1086 test_fragment_add_seq_check(void)
1088 printf("Starting test test_fragment_add_seq_check\n");
1090 test_fragment_add_seq_check_work(fragment_add_seq_check);
1094 /* This tests the case that the 802.11 hack does something different for: when
1095 * the terminal segment in a fragmented datagram arrives first.
1098 test_fragment_add_seq_check_1(void)
1100 fragment_head *fd_head;
1102 printf("Starting test test_fragment_add_seq_check_1\n");
1105 fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1108 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1109 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1110 ASSERT_EQ(NULL,fd_head);
1112 /* Now add the missing segment */
1114 fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1117 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1118 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.reassembled_table));
1119 ASSERT_NE(NULL,fd_head);
1121 /* check the contents of the structure */
1122 ASSERT_EQ(0,fd_head->frame); /* unused */
1123 ASSERT_EQ(0,fd_head->offset); /* unused */
1124 ASSERT_EQ(110,fd_head->len); /* the length of data we have */
1125 ASSERT_EQ(1,fd_head->datalen); /* seqno of the last fragment we have */
1126 ASSERT_EQ(2,fd_head->reassembled_in);
1127 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
1128 ASSERT_NE(NULL,fd_head->tvb_data);
1129 ASSERT_NE(NULL,fd_head->next);
1131 ASSERT_EQ(2,fd_head->next->frame);
1132 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
1133 ASSERT_EQ(60,fd_head->next->len); /* segment length */
1134 ASSERT_EQ(0,fd_head->next->flags);
1135 ASSERT_EQ(NULL,fd_head->next->tvb_data);
1136 ASSERT_NE(NULL,fd_head->next->next);
1138 ASSERT_EQ(1,fd_head->next->next->frame);
1139 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
1140 ASSERT_EQ(50,fd_head->next->next->len); /* segment length */
1141 ASSERT_EQ(0,fd_head->next->next->flags);
1142 ASSERT_EQ(NULL,fd_head->next->next->tvb_data);
1143 ASSERT_EQ(NULL,fd_head->next->next->next);
1145 /* test the actual reassembly */
1146 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+5,60));
1147 ASSERT(!tvb_memeql(fd_head->tvb_data,60,data+10,50));
1150 /**********************************************************************************
1152 * fragment_add_seq_802_11
1154 *********************************************************************************/
1156 /* Tests the 802.11 hack.
1159 test_fragment_add_seq_802_11_0(void)
1161 fragment_head *fd_head;
1163 printf("Starting test test_fragment_add_seq_802_11_0\n");
1165 /* the 802.11 hack is that some non-fragmented datagrams have non-zero
1166 * fragment_number; test for this. */
1169 fd_head=fragment_add_seq_802_11(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1172 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1173 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.reassembled_table));
1174 ASSERT_NE(NULL,fd_head);
1176 /* check the contents of the structure */
1177 ASSERT_EQ(0,fd_head->frame); /* unused */
1178 ASSERT_EQ(0,fd_head->offset); /* unused */
1179 ASSERT_EQ(0,fd_head->len); /* unused */
1180 ASSERT_EQ(0,fd_head->datalen); /* unused */
1181 ASSERT_EQ(1,fd_head->reassembled_in);
1182 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE,fd_head->flags);
1183 ASSERT_EQ(NULL,fd_head->tvb_data);
1184 ASSERT_EQ(NULL,fd_head->next);
1187 /* Reuse the fragment_add_seq_check testcases */
1188 static void test_fragment_add_seq_802_11_1(void)
1190 printf("Starting test test_fragment_add_seq_802_11_1\n");
1191 test_fragment_add_seq_check_work(fragment_add_seq_802_11);
1194 /**********************************************************************************
1196 * fragment_add_seq_check_multiple
1198 *********************************************************************************/
1200 /* Test 2 partial frags from 2 diff datagrams in the same frame */
1202 datagram #1: frame 1 + first part of frame 2
1203 datagram #1: last part of frame 2 + frame 3
1205 Is this a valid scenario ?
1207 The result of calling fragment_add_seq_check(&test_reassembly_table, ) for these
1208 fragments is a reassembled_table with:
1209 id, frame 1 => first_datagram; ["reassembled in" frame 2]
1210 id, frame 2 => second_datagram; ["reassembled in" frame 3]
1211 id, frame 3 => second_datagram;
1213 Note that the id, frame 2 => first datagram was overwritten
1214 by the entry for the second datagram.
1215 Is this OK ? IE: When dissected/displayed
1216 will the reassembled datagram 1 appear with frame 2 ??
1219 /* visit id frame frag len more tvb_offset
1227 Is this a valid scenario ?
1228 Is this OK ? IE: When dissected/displayed:
1229 Will the reassembled datagram 1 appear with frame 2 ??
1233 test_fragment_add_seq_check_multiple(void) {
1234 fragment_head *fd_head;
1237 fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1240 /* add the terminal fragment of the first datagram */
1242 fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1247 /* Now: start a second datagram with the first fragment in frame #2 */
1249 fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 25, &pinfo, 12, NULL,
1252 /* add the terminal fragment of the second datagram */
1254 fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
1261 /**********************************************************************************
1263 * fragment_add_seq_next
1265 *********************************************************************************/
1267 /* Simple test case for fragment_add_seq_next.
1268 * Adds a couple of fragments (with one for a different datagram in between),
1269 * and checks that they are reassembled correctly.
1272 test_simple_fragment_add_seq_next(void)
1274 fragment_head *fd_head;
1276 printf("Starting test test_simple_fragment_add_seq_next\n");
1279 fd_head= fragment_add_seq_next(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1282 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1283 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1284 ASSERT_EQ(NULL,fd_head);
1286 /* adding the same fragment again should do nothing, even with different
1288 pinfo.fd->flags.visited = 1;
1289 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1291 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1292 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1293 ASSERT_EQ(NULL,fd_head);
1295 /* start another pdu (just to confuse things) */
1296 pinfo.fd->flags.visited = 0;
1298 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 15, &pinfo, 13, NULL,
1300 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
1301 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1302 ASSERT_EQ(NULL,fd_head);
1305 /* now we add the terminal fragment of the first datagram */
1307 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1310 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1311 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.reassembled_table));
1312 ASSERT_NE(NULL,fd_head);
1314 /* check the contents of the structure */
1315 ASSERT_EQ(0,fd_head->frame); /* unused */
1316 ASSERT_EQ(0,fd_head->offset); /* unused */
1317 ASSERT_EQ(110,fd_head->len); /* the length of data we have */
1318 ASSERT_EQ(1,fd_head->datalen); /* seqno of the last fragment we have */
1319 ASSERT_EQ(3,fd_head->reassembled_in);
1320 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
1321 ASSERT_NE(NULL,fd_head->tvb_data);
1322 ASSERT_NE(NULL,fd_head->next);
1324 ASSERT_EQ(1,fd_head->next->frame);
1325 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
1326 ASSERT_EQ(50,fd_head->next->len); /* segment length */
1327 ASSERT_EQ(0,fd_head->next->flags);
1328 ASSERT_EQ(NULL,fd_head->next->tvb_data);
1329 ASSERT_NE(NULL,fd_head->next->next);
1331 ASSERT_EQ(3,fd_head->next->next->frame);
1332 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
1333 ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
1334 ASSERT_EQ(0,fd_head->next->next->flags);
1335 ASSERT_EQ(NULL,fd_head->next->next->tvb_data);
1336 ASSERT_EQ(NULL,fd_head->next->next->next);
1338 /* test the actual reassembly */
1339 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
1340 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
1344 /* This tests the case where some data is missing from one of the fragments.
1345 * It should prevent reassembly.
1348 test_missing_data_fragment_add_seq_next(void)
1350 fragment_head *fd_head;
1352 printf("Starting test test_missing_data_fragment_add_seq_next\n");
1354 /* attempt to add a fragment which is longer than the data available */
1356 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1359 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1360 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1361 ASSERT_NE(NULL,fd_head);
1363 /* check the contents of the structure. Reassembly failed so everything
1364 * should be null (meaning, just use the original tvb) */
1365 ASSERT_EQ(0,fd_head->frame); /* unused */
1366 ASSERT_EQ(0,fd_head->offset); /* unused */
1367 ASSERT_EQ(0,fd_head->len); /* the length of data we have */
1368 ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
1369 ASSERT_EQ(0,fd_head->reassembled_in);
1370 ASSERT_EQ(FD_BLOCKSEQUENCE,fd_head->flags & 0x1ff);
1371 ASSERT_EQ(NULL,fd_head->tvb_data);
1372 ASSERT_EQ(NULL,fd_head->next);
1374 /* add another fragment (with all data present) */
1376 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1379 /* XXX: it's not clear that this is the right result; however it's what the
1382 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1383 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1384 ASSERT_EQ(NULL,fd_head);
1387 /* check what happens when we revisit the packets */
1388 pinfo.fd->flags.visited = TRUE;
1391 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1394 /* We just look in the reassembled_table for this packet. It never got put
1395 * there, so this always returns null.
1397 * That's crazy, because it means that the subdissector will see the data
1398 * exactly once - on the first pass through the capture (well, assuming it
1399 * doesn't bother to check fd_head->reassembled_in); however, that's
1400 * what the code does...
1402 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1403 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1404 ASSERT_EQ(NULL,fd_head);
1407 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1409 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1410 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1411 ASSERT_EQ(NULL,fd_head);
1416 * we're going to do something similar now, but this time it is the second
1417 * fragment which has something missing.
1420 test_missing_data_fragment_add_seq_next_2(void)
1422 fragment_head *fd_head;
1424 printf("Starting test test_missing_data_fragment_add_seq_next_2\n");
1427 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 10, &pinfo, 24, NULL,
1430 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1431 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1432 ASSERT_EQ(NULL,fd_head);
1435 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 24, NULL,
1438 /* XXX: again, i'm really dubious about this. Surely this should return all
1439 * the data we had, for a best-effort attempt at dissecting it?
1440 * And it ought to go into the reassembled table?
1442 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1443 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1444 ASSERT_EQ(NULL,fd_head);
1446 /* check what happens when we revisit the packets */
1447 pinfo.fd->flags.visited = TRUE;
1450 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 10, &pinfo, 24, NULL,
1453 /* As before, this returns NULL because the fragment isn't in the
1454 * reassembled_table. At least this is a bit more consistent than before.
1456 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1457 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1458 ASSERT_EQ(NULL,fd_head);
1461 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 24, NULL,
1463 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1464 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1465 ASSERT_EQ(NULL,fd_head);
1470 * This time, our datagram only has one segment, but it has data missing.
1473 test_missing_data_fragment_add_seq_next_3(void)
1475 fragment_head *fd_head;
1477 printf("Starting test test_missing_data_fragment_add_seq_next_3\n");
1480 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 30, NULL,
1483 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1484 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.reassembled_table));
1485 ASSERT_NE(NULL,fd_head);
1487 /* check the contents of the structure. */
1488 ASSERT_EQ(0,fd_head->frame); /* unused */
1489 ASSERT_EQ(0,fd_head->offset); /* unused */
1490 ASSERT_EQ(0,fd_head->len); /* the length of data we have */
1491 ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
1492 ASSERT_EQ(20,fd_head->reassembled_in);
1493 ASSERT_EQ(FD_BLOCKSEQUENCE|FD_DEFRAGMENTED,fd_head->flags);
1494 ASSERT_EQ(NULL,fd_head->tvb_data);
1495 ASSERT_EQ(NULL,fd_head->next);
1497 /* revisiting the packet ought to produce the same result. */
1498 pinfo.fd->flags.visited = TRUE;
1501 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 30, NULL,
1504 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1505 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.reassembled_table));
1506 ASSERT_NE(NULL,fd_head);
1507 ASSERT_EQ(0,fd_head->frame); /* unused */
1508 ASSERT_EQ(0,fd_head->offset); /* unused */
1509 ASSERT_EQ(0,fd_head->len); /* the length of data we have */
1510 ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
1511 ASSERT_EQ(20,fd_head->reassembled_in);
1512 ASSERT_EQ(FD_BLOCKSEQUENCE|FD_DEFRAGMENTED,fd_head->flags);
1513 ASSERT_EQ(NULL,fd_head->tvb_data);
1514 ASSERT_EQ(NULL,fd_head->next);
1518 /**********************************************************************************
1522 *********************************************************************************/
1525 main(int argc _U_, char **argv _U_)
1528 static const guint8 src[] = {1,2,3,4}, dst[] = {5,6,7,8};
1530 static void (*tests[])(void) = {
1531 test_simple_fragment_add_seq, /* frag table only */
1532 test_fragment_add_seq_partial_reassembly,
1533 test_fragment_add_seq_duplicate_first,
1534 test_fragment_add_seq_duplicate_middle,
1535 test_fragment_add_seq_duplicate_last,
1536 test_fragment_add_seq_duplicate_conflict,
1537 test_fragment_add_seq_check, /* frag + reassemble */
1538 test_fragment_add_seq_check_1,
1539 test_fragment_add_seq_802_11_0,
1540 test_fragment_add_seq_802_11_1,
1541 test_simple_fragment_add_seq_next,
1542 test_missing_data_fragment_add_seq_next,
1543 test_missing_data_fragment_add_seq_next_2,
1544 test_missing_data_fragment_add_seq_next_3,
1546 test_fragment_add_seq_check_multiple
1550 /* a tvbuff for testing with */
1551 data = (char *)g_malloc(DATA_LEN);
1552 /* make sure it's full of stuff */
1553 for(i=0; i<DATA_LEN; i++) {
1556 tvb = tvb_new_real_data(data, DATA_LEN, DATA_LEN*2);
1558 /* other test stuff */
1560 fd.flags.visited = 0;
1561 set_address(&pinfo.src,AT_IPv4,4,src);
1562 set_address(&pinfo.dst,AT_IPv4,4,dst);
1564 /*************************************************************************/
1565 for(i=0; i < sizeof(tests)/sizeof(tests[0]); i++ ) {
1566 /* re-init the fragment tables */
1567 reassembly_table_init(&test_reassembly_table,
1568 &addresses_reassembly_table_functions);
1569 ASSERT(test_reassembly_table.fragment_table != NULL);
1570 ASSERT(test_reassembly_table.reassembled_table != NULL);
1572 pinfo.fd->flags.visited = FALSE;
1576 /* Free memory used by the tables */
1577 reassembly_table_destroy(&test_reassembly_table);
1585 printf(failure?"FAILURE\n":"SUCCESS\n");
1590 * Editor modelines - http://www.wireshark.org/tools/modelines.html
1595 * indent-tabs-mode: nil
1598 * vi: set shiftwidth=4 tabstop=8 expandtab:
1599 * :indentSize=4:tabSize=8:noTabs=true: