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_PARTIAL_REASSEMBLY ,"PR"},
115 {FD_OVERLAPCONFLICT ,"OC"},
116 {FD_MULTIPLETAILS ,"MT"},
117 {FD_TOOLONGFRAGMENT ,"TL"},
119 #define N_FD_FLAGS (signed)(sizeof(fd_flags)/sizeof(struct _fd_flags))
122 print_fd(fragment_head *fd, gboolean is_head) {
125 g_assert(fd != NULL);
126 printf(" %08x %08x %3d %3d %3d", fd, fd->next, fd->frame, fd->offset, fd->len);
128 printf(" %3d %3d", fd->datalen, fd->reassembled_in);
132 printf(" 0x%08x", fd->data);
133 for (i=0; i<N_FD_FLAGS; i++) {
134 printf(" %s", (fd->flags & fd_flags[i].flag) ? fd_flags[i].flag_name : " ");
140 print_fd_chain(fragment_head *fd_head) {
143 g_assert(fd_head != NULL);
144 print_fd(fd_head, TRUE);
145 for (fdp=fd_head->next; fdp != NULL; fdp=fdp->next) {
146 print_fd(fdp, FALSE);
151 print_fragment_table_chain(gpointer k, gpointer v, gpointer ud) {
152 fragment_key *key = (fragment_key*)k;
153 fragment_head *fd_head = (fragment_head *)v;
154 printf(" --> FT: %3d 0x%08x 0x%08x\n", key->id, *(guint32 *)(key->src.data), *(guint32 *)(key->dst.data));
155 print_fd_chain(fd_head);
159 print_fragment_table(void) {
160 printf("\n Fragment Table -------\n");
161 g_hash_table_foreach(fragment_table, print_fragment_table_chain, NULL);
165 print_reassembled_table_chain(gpointer k, gpointer v, gpointer ud) {
166 reassembled_key *key = (reassembled_key*)k;
167 fragment_head *fd_head = (fragment_head *)v;
168 printf(" --> RT: %5d %5d\n", key->id, key->frame);
169 print_fd_chain(fd_head);
173 print_reassembled_table(void) {
174 printf("\n Reassembled Table ----\n");
175 g_hash_table_foreach(test_reassembly_table.reassembled_table, print_reassembled_table_chain, NULL);
180 print_fragment_table();
181 print_reassembled_table();
185 /**********************************************************************************
189 *********************************************************************************/
191 /* Simple test case for fragment_add_seq.
192 * Adds three fragments (out of order, with one for a different datagram in between),
193 * and checks that they are reassembled correctly.
195 /* visit id frame frag len more tvb_offset
203 test_simple_fragment_add_seq(void)
205 fragment_head *fd_head, *fdh0;
207 printf("Starting test test_simple_fragment_add_seq\n");
210 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
213 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
214 ASSERT_EQ(NULL,fd_head);
216 /* adding the same fragment again should do nothing, even with different
218 pinfo.fd->flags.visited = 1;
219 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
221 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
222 ASSERT_EQ(NULL,fd_head);
224 /* start another pdu (just to confuse things) */
225 pinfo.fd->flags.visited = 0;
227 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 15, &pinfo, 13, NULL,
229 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
230 ASSERT_EQ(NULL,fd_head);
232 /* now we add the terminal fragment of the first datagram */
234 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
237 /* we haven't got all the fragments yet ... */
238 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
239 ASSERT_EQ(NULL,fd_head);
241 /* finally, add the missing fragment */
243 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 15, &pinfo, 12, NULL,
246 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
247 ASSERT_NE(NULL,fd_head);
249 /* check the contents of the structure */
250 ASSERT_EQ(0,fd_head->frame); /* unused */
251 ASSERT_EQ(0,fd_head->offset); /* unused */
252 ASSERT_EQ(170,fd_head->len); /* the length of data we have */
253 ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
254 ASSERT_EQ(4,fd_head->reassembled_in);
255 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
256 ASSERT_NE(NULL,fd_head->tvb_data);
257 ASSERT_NE(NULL,fd_head->next);
259 ASSERT_EQ(1,fd_head->next->frame);
260 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
261 ASSERT_EQ(50,fd_head->next->len); /* segment length */
262 ASSERT_EQ(0,fd_head->next->flags);
263 ASSERT_EQ(NULL,fd_head->next->tvb_data);
264 ASSERT_NE(NULL,fd_head->next->next);
266 ASSERT_EQ(4,fd_head->next->next->frame);
267 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
268 ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
269 ASSERT_EQ(0,fd_head->next->next->flags);
270 ASSERT_EQ(NULL,fd_head->next->next->tvb_data);
271 ASSERT_NE(NULL,fd_head->next->next->next);
273 ASSERT_EQ(3,fd_head->next->next->next->frame);
274 ASSERT_EQ(2,fd_head->next->next->next->offset); /* seqno */
275 ASSERT_EQ(60,fd_head->next->next->next->len); /* segment length */
276 ASSERT_EQ(0,fd_head->next->next->next->flags);
277 ASSERT_EQ(NULL,fd_head->next->next->next->tvb_data);
278 ASSERT_EQ(NULL,fd_head->next->next->next->next);
280 /* test the actual reassembly */
281 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
282 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+15,60));
283 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,60));
286 print_fragment_table();
289 /* what happens if we revisit the packets now? */
291 pinfo.fd->flags.visited = 1;
293 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
296 * this api relies on the caller to check fd_head -> reassembled_in
298 * Redoing all the tests seems like overkill - just check the pointer
300 ASSERT_EQ(fdh0,fd_head);
303 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
305 ASSERT_EQ(fdh0,fd_head);
308 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 15, &pinfo, 12, NULL,
310 ASSERT_EQ(fdh0,fd_head);
313 print_fragment_table();
317 /* XXX ought to have some tests for overlapping fragments */
319 /* This tests the functionality of fragment_set_partial_reassembly for
320 * FD_BLOCKSEQUENCE reassembly.
322 * We add a sequence of fragments thus:
323 * seqno frame offset len (initial) more_frags
324 * ----- ----- ------ --- --------------------
327 * 1 3 0 40 true (a duplicate fragment)
332 test_fragment_add_seq_partial_reassembly(void)
334 fragment_head *fd_head;
337 printf("Starting test test_fragment_add_seq_partial_reassembly\n");
339 /* generally it's probably fair to assume that we will be called with
343 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
346 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
347 ASSERT_NE(NULL,fd_head);
349 /* check the contents of the structure */
350 ASSERT_EQ(0,fd_head->frame); /* unused */
351 ASSERT_EQ(0,fd_head->offset); /* unused */
352 ASSERT_EQ(50,fd_head->len); /* the length of data we have */
353 ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
354 ASSERT_EQ(1,fd_head->reassembled_in);
355 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
356 ASSERT_NE(NULL,fd_head->tvb_data);
357 ASSERT_NE(NULL,fd_head->next);
359 ASSERT_EQ(1,fd_head->next->frame);
360 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
361 ASSERT_EQ(50,fd_head->next->len); /* segment length */
362 ASSERT_EQ(0,fd_head->next->flags);
363 ASSERT_EQ(NULL,fd_head->next->tvb_data);
364 ASSERT_EQ(NULL,fd_head->next->next);
366 /* test the actual reassembly */
367 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
369 /* now we announce that the reassembly wasn't complete after all. */
370 fragment_set_partial_reassembly(&test_reassembly_table, &pinfo, 12, NULL);
372 /* and add another segment. To mix things up slightly (and so that we can
373 * check on the state of things), we're going to set the more_frags flag
377 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
380 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
381 ASSERT_EQ(NULL,fd_head);
383 fd_head=fragment_get(&test_reassembly_table, &pinfo, 12, NULL);
384 ASSERT_NE(NULL,fd_head);
386 /* check the contents of the structure */
387 ASSERT_EQ(0,fd_head->frame); /* unused */
388 ASSERT_EQ(0,fd_head->offset); /* unused */
389 /* ASSERT_EQ(50,fd_head->len); the length of data we have */
390 ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
391 ASSERT_EQ(0,fd_head->reassembled_in);
392 ASSERT_EQ(FD_BLOCKSEQUENCE,fd_head->flags);
393 ASSERT_NE(NULL,fd_head->tvb_data);
394 ASSERT_NE(NULL,fd_head->next);
397 ASSERT_EQ(1,fd->frame);
398 ASSERT_EQ(0,fd->offset); /* seqno */
399 ASSERT_EQ(50,fd->len); /* segment length */
400 ASSERT_EQ(FD_SUBSET_TVB,fd->flags);
401 ASSERT_EQ(tvb_get_ptr(fd_head->tvb_data,0,0),tvb_get_ptr(fd->tvb_data,0,0));
402 ASSERT_NE(NULL,fd->next);
405 ASSERT_EQ(2,fd->frame);
406 ASSERT_EQ(1,fd->offset); /* seqno */
407 ASSERT_EQ(40,fd->len); /* segment length */
408 ASSERT_EQ(0,fd->flags);
409 ASSERT_NE(NULL,fd->tvb_data);
410 ASSERT_EQ(NULL,fd->next);
412 /* Another copy of the second segment.
415 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
418 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
419 ASSERT_EQ(NULL,fd_head);
420 fd_head=fragment_get(&test_reassembly_table, &pinfo, 12, NULL);
421 ASSERT_NE(NULL,fd_head);
422 ASSERT_EQ(0,fd_head->frame); /* unused */
423 ASSERT_EQ(0,fd_head->offset); /* unused */
424 /* ASSERT_EQ(50,fd_head->len); the length of data we have */
425 ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
426 ASSERT_EQ(0,fd_head->reassembled_in);
427 ASSERT_EQ(FD_BLOCKSEQUENCE,fd_head->flags);
428 ASSERT_NE(NULL,fd_head->tvb_data);
429 ASSERT_NE(NULL,fd_head->next);
432 ASSERT_EQ(1,fd->frame);
433 ASSERT_EQ(0,fd->offset); /* seqno */
434 ASSERT_EQ(50,fd->len); /* segment length */
435 ASSERT_EQ(FD_SUBSET_TVB,fd->flags);
436 ASSERT_EQ(tvb_get_ptr(fd_head->tvb_data,0,0),tvb_get_ptr(fd->tvb_data,0,0));
437 ASSERT_NE(NULL,fd->next);
440 ASSERT_EQ(2,fd->frame);
441 ASSERT_EQ(1,fd->offset); /* seqno */
442 ASSERT_EQ(40,fd->len); /* segment length */
443 ASSERT_EQ(0,fd->flags);
444 ASSERT_NE(NULL,fd->tvb_data);
445 ASSERT_NE(NULL,fd->next);
448 ASSERT_EQ(3,fd->frame);
449 ASSERT_EQ(1,fd->offset); /* seqno */
450 ASSERT_EQ(40,fd->len); /* segment length */
451 ASSERT_EQ(0,fd->flags);
452 ASSERT_NE(NULL,fd->tvb_data);
453 ASSERT_EQ(NULL,fd->next);
457 /* have another go at wrapping things up */
459 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 20, &pinfo, 12, NULL,
462 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
463 ASSERT_NE(NULL,fd_head);
465 /* check the contents of the structure */
466 ASSERT_EQ(0,fd_head->frame); /* unused */
467 ASSERT_EQ(0,fd_head->offset); /* unused */
468 ASSERT_EQ(190,fd_head->len); /* the length of data we have */
469 ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
470 ASSERT_EQ(4,fd_head->reassembled_in);
471 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
472 ASSERT_NE(NULL,fd_head->tvb_data);
473 ASSERT_NE(NULL,fd_head->next);
476 ASSERT_EQ(1,fd->frame);
477 ASSERT_EQ(0,fd->offset); /* seqno */
478 ASSERT_EQ(50,fd->len); /* segment length */
479 ASSERT_EQ(0,fd->flags);
480 ASSERT_EQ(NULL,fd->tvb_data);
481 ASSERT_NE(NULL,fd->next);
484 ASSERT_EQ(2,fd->frame);
485 ASSERT_EQ(1,fd->offset); /* seqno */
486 ASSERT_EQ(40,fd->len); /* segment length */
487 ASSERT_EQ(0,fd->flags);
488 ASSERT_EQ(NULL,fd->tvb_data);
489 ASSERT_NE(NULL,fd->next);
492 ASSERT_EQ(3,fd->frame);
493 ASSERT_EQ(1,fd->offset); /* seqno */
494 ASSERT_EQ(40,fd->len); /* segment length */
495 ASSERT_EQ(FD_OVERLAP,fd->flags);
496 ASSERT_EQ(NULL,fd->tvb_data);
497 ASSERT_NE(NULL,fd->next);
500 ASSERT_EQ(4,fd->frame);
501 ASSERT_EQ(2,fd->offset); /* seqno */
502 ASSERT_EQ(100,fd->len); /* segment length */
503 ASSERT_EQ(0,fd->flags);
504 ASSERT_EQ(NULL,fd->tvb_data);
505 ASSERT_EQ(NULL,fd->next);
507 /* test the actual reassembly */
508 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
509 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data,40));
510 ASSERT(!tvb_memeql(fd_head->tvb_data,90,data+20,100));
513 /* do it again (this time it is more complicated, with an overlap in the
516 fragment_set_partial_reassembly(&test_reassembly_table, &pinfo, 12, NULL);
519 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
522 fd_head=fragment_get(&test_reassembly_table, &pinfo, 12, NULL);
523 ASSERT_NE(NULL,fd_head);
524 ASSERT_EQ(0,fd_head->frame); /* unused */
525 ASSERT_EQ(0,fd_head->offset); /* unused */
526 ASSERT_EQ(230,fd_head->len); /* the length of data we have */
527 ASSERT_EQ(3,fd_head->datalen); /* seqno of the last fragment we have */
528 ASSERT_EQ(5,fd_head->reassembled_in);
529 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
530 ASSERT_NE(NULL,fd_head->tvb_data);
531 ASSERT_NE(NULL,fd_head->next);
534 ASSERT_EQ(1,fd->frame);
535 ASSERT_EQ(0,fd->offset); /* seqno */
536 ASSERT_EQ(50,fd->len); /* segment length */
537 ASSERT_EQ(0,fd->flags);
538 ASSERT_EQ(NULL,fd->tvb_data);
539 ASSERT_NE(NULL,fd->next);
542 ASSERT_EQ(2,fd->frame);
543 ASSERT_EQ(1,fd->offset); /* seqno */
544 ASSERT_EQ(40,fd->len); /* segment length */
545 ASSERT_EQ(0,fd->flags);
546 ASSERT_EQ(NULL,fd->tvb_data);
547 ASSERT_NE(NULL,fd->next);
550 ASSERT_EQ(3,fd->frame);
551 ASSERT_EQ(1,fd->offset); /* seqno */
552 ASSERT_EQ(40,fd->len); /* segment length */
553 ASSERT_EQ(FD_OVERLAP,fd->flags);
554 ASSERT_EQ(NULL,fd->tvb_data);
555 ASSERT_NE(NULL,fd->next);
558 ASSERT_EQ(4,fd->frame);
559 ASSERT_EQ(2,fd->offset); /* seqno */
560 ASSERT_EQ(100,fd->len); /* segment length */
561 ASSERT_EQ(0,fd->flags);
562 ASSERT_EQ(NULL,fd->tvb_data);
563 ASSERT_NE(NULL,fd->next);
566 ASSERT_EQ(5,fd->frame);
567 ASSERT_EQ(3,fd->offset); /* seqno */
568 ASSERT_EQ(40,fd->len); /* segment length */
569 ASSERT_EQ(0,fd->flags);
570 ASSERT_EQ(NULL,fd->tvb_data);
571 ASSERT_EQ(NULL,fd->next);
573 /* test the actual reassembly */
574 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
575 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data,40));
576 ASSERT(!tvb_memeql(fd_head->tvb_data,90,data+20,100));
577 ASSERT(!tvb_memeql(fd_head->tvb_data,190,data,40));
580 /* Test case for fragment_add_seq with duplicated (e.g., retransmitted) data.
581 * Adds three fragments--adding the 1st one twice--
582 * and checks that they are reassembled correctly.
584 /* visit id frame frag len more tvb_offset
591 test_fragment_add_seq_duplicate_first(void)
593 fragment_head *fd_head;
595 printf("Starting test test_fragment_add_seq_duplicate_first\n");
598 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
601 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
602 ASSERT_EQ(NULL,fd_head);
604 /* Add the 2nd segment */
606 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
609 /* we haven't got all the fragments yet ... */
610 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
611 ASSERT_EQ(NULL,fd_head);
613 /* Add the last fragment */
615 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
618 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
619 ASSERT_NE(NULL,fd_head);
621 /* Add the first fragment again */
623 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
626 /* Reassembly should have still succeeded */
627 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
628 ASSERT_NE(NULL,fd_head);
630 /* check the contents of the structure */
631 ASSERT_EQ(0,fd_head->frame); /* unused */
632 ASSERT_EQ(0,fd_head->offset); /* unused */
633 ASSERT_EQ(150,fd_head->len); /* the length of data we have */
634 ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
635 ASSERT_EQ(3,fd_head->reassembled_in);
636 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
637 ASSERT_NE(NULL,fd_head->tvb_data);
638 ASSERT_NE(NULL,fd_head->next);
640 ASSERT_EQ(1,fd_head->next->frame);
641 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
642 ASSERT_EQ(50,fd_head->next->len); /* segment length */
643 ASSERT_EQ(0,fd_head->next->flags);
644 ASSERT_EQ(NULL,fd_head->next->tvb_data);
645 ASSERT_NE(NULL,fd_head->next->next);
647 ASSERT_EQ(4,fd_head->next->next->frame);
648 ASSERT_EQ(0,fd_head->next->next->offset); /* seqno */
649 ASSERT_EQ(50,fd_head->next->next->len); /* segment length */
650 ASSERT_EQ(FD_OVERLAP,fd_head->next->next->flags);
651 ASSERT_EQ(NULL,fd_head->next->next->tvb_data);
652 ASSERT_NE(NULL,fd_head->next->next->next);
654 ASSERT_EQ(2,fd_head->next->next->next->frame);
655 ASSERT_EQ(1,fd_head->next->next->next->offset); /* seqno */
656 ASSERT_EQ(60,fd_head->next->next->next->len); /* segment length */
657 ASSERT_EQ(0,fd_head->next->next->next->flags);
658 ASSERT_EQ(NULL,fd_head->next->next->next->tvb_data);
659 ASSERT_NE(NULL,fd_head->next->next->next->next);
661 ASSERT_EQ(3,fd_head->next->next->next->next->frame);
662 ASSERT_EQ(2,fd_head->next->next->next->next->offset); /* seqno */
663 ASSERT_EQ(40,fd_head->next->next->next->next->len); /* segment length */
664 ASSERT_EQ(0,fd_head->next->next->next->next->flags);
665 ASSERT_EQ(NULL,fd_head->next->next->next->next->tvb_data);
666 ASSERT_EQ(NULL,fd_head->next->next->next->next->next);
668 /* test the actual reassembly */
669 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
670 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
671 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
674 print_fragment_table();
679 /* Test case for fragment_add_seq with duplicated (e.g., retransmitted) data.
680 * Adds three fragments--adding the 2nd one twice--
681 * and checks that they are reassembled correctly.
683 /* visit id frame frag len more tvb_offset
690 test_fragment_add_seq_duplicate_middle(void)
692 fragment_head *fd_head;
694 printf("Starting test test_fragment_add_seq_duplicate_middle\n");
697 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
700 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
701 ASSERT_EQ(NULL,fd_head);
703 /* Add the 2nd segment */
705 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
708 /* we haven't got all the fragments yet ... */
709 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
710 ASSERT_EQ(NULL,fd_head);
712 /* Now, add the 2nd segment again (but in a different frame) */
714 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
717 /* This duplicate fragment should have been ignored */
718 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
719 ASSERT_EQ(NULL,fd_head);
721 /* finally, add the last fragment */
723 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
726 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
727 ASSERT_NE(NULL,fd_head);
729 /* check the contents of the structure */
730 ASSERT_EQ(0,fd_head->frame); /* unused */
731 ASSERT_EQ(0,fd_head->offset); /* unused */
732 ASSERT_EQ(150,fd_head->len); /* the length of data we have */
733 ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
734 ASSERT_EQ(4,fd_head->reassembled_in);
735 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
736 ASSERT_NE(NULL,fd_head->tvb_data);
737 ASSERT_NE(NULL,fd_head->next);
739 ASSERT_EQ(1,fd_head->next->frame);
740 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
741 ASSERT_EQ(50,fd_head->next->len); /* segment length */
742 ASSERT_EQ(0,fd_head->next->flags);
743 ASSERT_EQ(NULL,fd_head->next->tvb_data);
744 ASSERT_NE(NULL,fd_head->next->next);
746 ASSERT_EQ(2,fd_head->next->next->frame);
747 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
748 ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
749 ASSERT_EQ(0,fd_head->next->next->flags);
750 ASSERT_EQ(NULL,fd_head->next->next->tvb_data);
751 ASSERT_NE(NULL,fd_head->next->next->next);
753 ASSERT_EQ(3,fd_head->next->next->next->frame);
754 ASSERT_EQ(1,fd_head->next->next->next->offset); /* seqno */
755 ASSERT_EQ(60,fd_head->next->next->next->len); /* segment length */
756 ASSERT_EQ(FD_OVERLAP,fd_head->next->next->next->flags);
757 ASSERT_EQ(NULL,fd_head->next->next->next->tvb_data);
758 ASSERT_NE(NULL,fd_head->next->next->next->next);
760 ASSERT_EQ(4,fd_head->next->next->next->next->frame);
761 ASSERT_EQ(2,fd_head->next->next->next->next->offset); /* seqno */
762 ASSERT_EQ(40,fd_head->next->next->next->next->len); /* segment length */
763 ASSERT_EQ(0,fd_head->next->next->next->next->flags);
764 ASSERT_EQ(NULL,fd_head->next->next->next->next->tvb_data);
765 ASSERT_EQ(NULL,fd_head->next->next->next->next->next);
767 /* test the actual reassembly */
768 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
769 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
770 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
773 print_fragment_table();
777 /* Test case for fragment_add_seq with duplicated (e.g., retransmitted) data.
778 * Adds three fragments--adding the 3rd one twice--
779 * and checks that they are reassembled correctly.
781 /* visit id frame frag len more tvb_offset
788 test_fragment_add_seq_duplicate_last(void)
790 fragment_head *fd_head;
792 printf("Starting test test_fragment_add_seq_duplicate_last\n");
795 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
798 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
799 ASSERT_EQ(NULL,fd_head);
801 /* Add the 2nd segment */
803 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
806 /* we haven't got all the fragments yet ... */
807 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
808 ASSERT_EQ(NULL,fd_head);
810 /* Add the last fragment */
812 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
815 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
816 ASSERT_NE(NULL,fd_head);
818 /* Add the last fragment again */
820 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
823 /* Reassembly should have still succeeded */
824 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
825 ASSERT_NE(NULL,fd_head);
827 /* check the contents of the structure */
828 ASSERT_EQ(0,fd_head->frame); /* unused */
829 ASSERT_EQ(0,fd_head->offset); /* unused */
830 ASSERT_EQ(150,fd_head->len); /* the length of data we have */
831 ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
832 ASSERT_EQ(3,fd_head->reassembled_in);
833 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
834 ASSERT_NE(NULL,fd_head->tvb_data);
835 ASSERT_NE(NULL,fd_head->next);
837 ASSERT_EQ(1,fd_head->next->frame);
838 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
839 ASSERT_EQ(50,fd_head->next->len); /* segment length */
840 ASSERT_EQ(0,fd_head->next->flags);
841 ASSERT_EQ(NULL,fd_head->next->tvb_data);
842 ASSERT_NE(NULL,fd_head->next->next);
844 ASSERT_EQ(2,fd_head->next->next->frame);
845 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
846 ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
847 ASSERT_EQ(0,fd_head->next->next->flags);
848 ASSERT_EQ(NULL,fd_head->next->next->tvb_data);
849 ASSERT_NE(NULL,fd_head->next->next->next);
851 ASSERT_EQ(3,fd_head->next->next->next->frame);
852 ASSERT_EQ(2,fd_head->next->next->next->offset); /* seqno */
853 ASSERT_EQ(40,fd_head->next->next->next->len); /* segment length */
854 ASSERT_EQ(0,fd_head->next->next->next->flags);
855 ASSERT_EQ(NULL,fd_head->next->next->next->tvb_data);
856 ASSERT_NE(NULL,fd_head->next->next->next->next);
858 ASSERT_EQ(4,fd_head->next->next->next->next->frame);
859 ASSERT_EQ(2,fd_head->next->next->next->next->offset); /* seqno */
860 ASSERT_EQ(40,fd_head->next->next->next->next->len); /* segment length */
861 ASSERT_EQ(FD_OVERLAP,fd_head->next->next->next->next->flags);
862 ASSERT_EQ(NULL,fd_head->next->next->next->next->tvb_data);
863 ASSERT_EQ(NULL,fd_head->next->next->next->next->next);
865 /* test the actual reassembly */
866 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
867 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
868 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
871 print_fragment_table();
875 /* Test case for fragment_add_seq with duplicated (e.g., retransmitted) data
876 * where the retransmission "conflicts" with the original transmission
877 * (contents are different).
878 * Adds three fragments--adding the 2nd one twice--
879 * and checks that they are reassembled correctly.
881 /* visit id frame frag len more tvb_offset
888 test_fragment_add_seq_duplicate_conflict(void)
890 fragment_head *fd_head;
892 printf("Starting test test_fragment_add_seq_duplicate_conflict\n");
895 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
898 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
899 ASSERT_EQ(NULL,fd_head);
901 /* Add the 2nd segment */
903 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
906 /* we haven't got all the fragments yet ... */
907 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
908 ASSERT_EQ(NULL,fd_head);
910 /* Now, add the 2nd segment again (but in a different frame and with
914 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 15, &pinfo, 12, NULL,
917 /* This duplicate fragment should have been ignored */
918 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
919 ASSERT_EQ(NULL,fd_head);
921 /* finally, add the last fragment */
923 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
926 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
927 ASSERT_NE(NULL,fd_head);
929 /* check the contents of the structure */
930 ASSERT_EQ(0,fd_head->frame); /* unused */
931 ASSERT_EQ(0,fd_head->offset); /* unused */
932 ASSERT_EQ(150,fd_head->len); /* the length of data we have */
933 ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
934 ASSERT_EQ(4,fd_head->reassembled_in);
935 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP|FD_OVERLAPCONFLICT,fd_head->flags);
936 ASSERT_NE(NULL,fd_head->tvb_data);
937 ASSERT_NE(NULL,fd_head->next);
939 ASSERT_EQ(1,fd_head->next->frame);
940 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
941 ASSERT_EQ(50,fd_head->next->len); /* segment length */
942 ASSERT_EQ(0,fd_head->next->flags);
943 ASSERT_EQ(NULL,fd_head->next->tvb_data);
944 ASSERT_NE(NULL,fd_head->next->next);
946 ASSERT_EQ(2,fd_head->next->next->frame);
947 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
948 ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
949 ASSERT_EQ(0,fd_head->next->next->flags);
950 ASSERT_EQ(NULL,fd_head->next->next->tvb_data);
951 ASSERT_NE(NULL,fd_head->next->next->next);
953 ASSERT_EQ(3,fd_head->next->next->next->frame);
954 ASSERT_EQ(1,fd_head->next->next->next->offset); /* seqno */
955 ASSERT_EQ(60,fd_head->next->next->next->len); /* segment length */
956 ASSERT_EQ(FD_OVERLAP|FD_OVERLAPCONFLICT,fd_head->next->next->next->flags);
957 ASSERT_EQ(NULL,fd_head->next->next->next->tvb_data);
958 ASSERT_NE(NULL,fd_head->next->next->next->next);
960 ASSERT_EQ(4,fd_head->next->next->next->next->frame);
961 ASSERT_EQ(2,fd_head->next->next->next->next->offset); /* seqno */
962 ASSERT_EQ(40,fd_head->next->next->next->next->len); /* segment length */
963 ASSERT_EQ(0,fd_head->next->next->next->next->flags);
964 ASSERT_EQ(NULL,fd_head->next->next->next->next->tvb_data);
965 ASSERT_EQ(NULL,fd_head->next->next->next->next->next);
967 /* test the actual reassembly */
968 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
969 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
970 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
973 print_fragment_table();
977 /**********************************************************************************
979 * fragment_add_seq_check
981 *********************************************************************************/
984 /* This routine is used for both fragment_add_seq_802_11 and
985 * fragment_add_seq_check.
987 * Adds a couple of out-of-order fragments and checks their reassembly.
990 /* visit id frame frag len more tvb_offset
999 test_fragment_add_seq_check_work(fragment_head *(*fn)(reassembly_table *,
1000 tvbuff_t *, const int, const packet_info *,
1001 const guint32, const void *, const guint32,
1002 const guint32, const gboolean))
1004 fragment_head *fd_head;
1007 fd_head=fn(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1010 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1011 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1012 ASSERT_EQ(NULL,fd_head);
1014 /* start another pdu (just to confuse things) */
1016 fd_head=fn(&test_reassembly_table, tvb, 15, &pinfo, 13, NULL,
1018 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
1019 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1020 ASSERT_EQ(NULL,fd_head);
1022 /* add the terminal fragment of the first datagram */
1024 fd_head=fn(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1027 /* we haven't got all the fragments yet ... */
1028 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
1029 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1030 ASSERT_EQ(NULL,fd_head);
1032 /* finally, add the missing fragment */
1034 fd_head=fn(&test_reassembly_table, tvb, 15, &pinfo, 12, NULL,
1037 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1038 ASSERT_EQ(3,g_hash_table_size(test_reassembly_table.reassembled_table));
1039 ASSERT_NE(NULL,fd_head);
1041 /* check the contents of the structure */
1042 ASSERT_EQ(0,fd_head->frame); /* unused */
1043 ASSERT_EQ(0,fd_head->offset); /* unused */
1044 ASSERT_EQ(170,fd_head->len); /* the length of data we have */
1045 ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
1046 ASSERT_EQ(4,fd_head->reassembled_in);
1047 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
1048 ASSERT_NE(NULL,fd_head->tvb_data);
1049 ASSERT_NE(NULL,fd_head->next);
1051 ASSERT_EQ(1,fd_head->next->frame);
1052 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
1053 ASSERT_EQ(50,fd_head->next->len); /* segment length */
1054 ASSERT_EQ(0,fd_head->next->flags);
1055 ASSERT_EQ(NULL,fd_head->next->tvb_data);
1056 ASSERT_NE(NULL,fd_head->next->next);
1058 ASSERT_EQ(4,fd_head->next->next->frame);
1059 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
1060 ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
1061 ASSERT_EQ(0,fd_head->next->next->flags);
1062 ASSERT_EQ(NULL,fd_head->next->next->tvb_data);
1063 ASSERT_NE(NULL,fd_head->next->next->next);
1065 ASSERT_EQ(3,fd_head->next->next->next->frame);
1066 ASSERT_EQ(2,fd_head->next->next->next->offset); /* seqno */
1067 ASSERT_EQ(60,fd_head->next->next->next->len); /* segment length */
1068 ASSERT_EQ(0,fd_head->next->next->next->flags);
1069 ASSERT_EQ(NULL,fd_head->next->next->next->tvb_data);
1070 ASSERT_EQ(NULL,fd_head->next->next->next->next);
1072 /* test the actual reassembly */
1073 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
1074 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+15,60));
1075 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,60));
1082 /* Simple test case for fragment_add_seq_check
1085 test_fragment_add_seq_check(void)
1087 printf("Starting test test_fragment_add_seq_check\n");
1089 test_fragment_add_seq_check_work(fragment_add_seq_check);
1093 /* This tests the case that the 802.11 hack does something different for: when
1094 * the terminal segment in a fragmented datagram arrives first.
1097 test_fragment_add_seq_check_1(void)
1099 fragment_head *fd_head;
1101 printf("Starting test test_fragment_add_seq_check_1\n");
1104 fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1107 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1108 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1109 ASSERT_EQ(NULL,fd_head);
1111 /* Now add the missing segment */
1113 fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1116 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1117 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.reassembled_table));
1118 ASSERT_NE(NULL,fd_head);
1120 /* check the contents of the structure */
1121 ASSERT_EQ(0,fd_head->frame); /* unused */
1122 ASSERT_EQ(0,fd_head->offset); /* unused */
1123 ASSERT_EQ(110,fd_head->len); /* the length of data we have */
1124 ASSERT_EQ(1,fd_head->datalen); /* seqno of the last fragment we have */
1125 ASSERT_EQ(2,fd_head->reassembled_in);
1126 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
1127 ASSERT_NE(NULL,fd_head->tvb_data);
1128 ASSERT_NE(NULL,fd_head->next);
1130 ASSERT_EQ(2,fd_head->next->frame);
1131 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
1132 ASSERT_EQ(60,fd_head->next->len); /* segment length */
1133 ASSERT_EQ(0,fd_head->next->flags);
1134 ASSERT_EQ(NULL,fd_head->next->tvb_data);
1135 ASSERT_NE(NULL,fd_head->next->next);
1137 ASSERT_EQ(1,fd_head->next->next->frame);
1138 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
1139 ASSERT_EQ(50,fd_head->next->next->len); /* segment length */
1140 ASSERT_EQ(0,fd_head->next->next->flags);
1141 ASSERT_EQ(NULL,fd_head->next->next->tvb_data);
1142 ASSERT_EQ(NULL,fd_head->next->next->next);
1144 /* test the actual reassembly */
1145 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+5,60));
1146 ASSERT(!tvb_memeql(fd_head->tvb_data,60,data+10,50));
1149 /**********************************************************************************
1151 * fragment_add_seq_802_11
1153 *********************************************************************************/
1155 /* Tests the 802.11 hack.
1158 test_fragment_add_seq_802_11_0(void)
1160 fragment_head *fd_head;
1162 printf("Starting test test_fragment_add_seq_802_11_0\n");
1164 /* the 802.11 hack is that some non-fragmented datagrams have non-zero
1165 * fragment_number; test for this. */
1168 fd_head=fragment_add_seq_802_11(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1171 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1172 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.reassembled_table));
1173 ASSERT_NE(NULL,fd_head);
1175 /* check the contents of the structure */
1176 ASSERT_EQ(0,fd_head->frame); /* unused */
1177 ASSERT_EQ(0,fd_head->offset); /* unused */
1178 ASSERT_EQ(0,fd_head->len); /* unused */
1179 ASSERT_EQ(0,fd_head->datalen); /* unused */
1180 ASSERT_EQ(1,fd_head->reassembled_in);
1181 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE,fd_head->flags);
1182 ASSERT_EQ(NULL,fd_head->tvb_data);
1183 ASSERT_EQ(NULL,fd_head->next);
1186 /* Reuse the fragment_add_seq_check testcases */
1187 static void test_fragment_add_seq_802_11_1(void)
1189 printf("Starting test test_fragment_add_seq_802_11_1\n");
1190 test_fragment_add_seq_check_work(fragment_add_seq_802_11);
1193 /**********************************************************************************
1195 * fragment_add_seq_check_multiple
1197 *********************************************************************************/
1199 /* Test 2 partial frags from 2 diff datagrams in the same frame */
1201 datagram #1: frame 1 + first part of frame 2
1202 datagram #1: last part of frame 2 + frame 3
1204 Is this a valid scenario ?
1206 The result of calling fragment_add_seq_check(&test_reassembly_table, ) for these
1207 fragments is a reassembled_table with:
1208 id, frame 1 => first_datagram; ["reassembled in" frame 2]
1209 id, frame 2 => second_datagram; ["reassembled in" frame 3]
1210 id, frame 3 => second_datagram;
1212 Note that the id, frame 2 => first datagram was overwritten
1213 by the entry for the second datagram.
1214 Is this OK ? IE: When dissected/displayed
1215 will the reassembled datagram 1 appear with frame 2 ??
1218 /* visit id frame frag len more tvb_offset
1226 Is this a valid scenario ?
1227 Is this OK ? IE: When dissected/displayed:
1228 Will the reassembled datagram 1 appear with frame 2 ??
1232 test_fragment_add_seq_check_multiple(void) {
1233 fragment_head *fd_head;
1236 fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1239 /* add the terminal fragment of the first datagram */
1241 fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1246 /* Now: start a second datagram with the first fragment in frame #2 */
1248 fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 25, &pinfo, 12, NULL,
1251 /* add the terminal fragment of the second datagram */
1253 fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
1260 /**********************************************************************************
1262 * fragment_add_seq_next
1264 *********************************************************************************/
1266 /* Simple test case for fragment_add_seq_next.
1267 * Adds a couple of fragments (with one for a different datagram in between),
1268 * and checks that they are reassembled correctly.
1271 test_simple_fragment_add_seq_next(void)
1273 fragment_head *fd_head;
1275 printf("Starting test test_simple_fragment_add_seq_next\n");
1278 fd_head= fragment_add_seq_next(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1281 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1282 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1283 ASSERT_EQ(NULL,fd_head);
1285 /* adding the same fragment again should do nothing, even with different
1287 pinfo.fd->flags.visited = 1;
1288 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1290 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1291 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1292 ASSERT_EQ(NULL,fd_head);
1294 /* start another pdu (just to confuse things) */
1295 pinfo.fd->flags.visited = 0;
1297 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 15, &pinfo, 13, NULL,
1299 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
1300 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1301 ASSERT_EQ(NULL,fd_head);
1304 /* now we add the terminal fragment of the first datagram */
1306 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1309 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1310 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.reassembled_table));
1311 ASSERT_NE(NULL,fd_head);
1313 /* check the contents of the structure */
1314 ASSERT_EQ(0,fd_head->frame); /* unused */
1315 ASSERT_EQ(0,fd_head->offset); /* unused */
1316 ASSERT_EQ(110,fd_head->len); /* the length of data we have */
1317 ASSERT_EQ(1,fd_head->datalen); /* seqno of the last fragment we have */
1318 ASSERT_EQ(3,fd_head->reassembled_in);
1319 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
1320 ASSERT_NE(NULL,fd_head->tvb_data);
1321 ASSERT_NE(NULL,fd_head->next);
1323 ASSERT_EQ(1,fd_head->next->frame);
1324 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
1325 ASSERT_EQ(50,fd_head->next->len); /* segment length */
1326 ASSERT_EQ(0,fd_head->next->flags);
1327 ASSERT_EQ(NULL,fd_head->next->tvb_data);
1328 ASSERT_NE(NULL,fd_head->next->next);
1330 ASSERT_EQ(3,fd_head->next->next->frame);
1331 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
1332 ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
1333 ASSERT_EQ(0,fd_head->next->next->flags);
1334 ASSERT_EQ(NULL,fd_head->next->next->tvb_data);
1335 ASSERT_EQ(NULL,fd_head->next->next->next);
1337 /* test the actual reassembly */
1338 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
1339 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
1344 /* XXX remove this? fragment_add_seq does not have the special case for
1345 * fragments having truncated tvbs anymore! */
1346 /* This tests the case where some data is missing from one of the fragments.
1347 * It should prevent reassembly.
1350 test_missing_data_fragment_add_seq_next(void)
1352 fragment_head *fd_head;
1354 printf("Starting test test_missing_data_fragment_add_seq_next\n");
1356 /* attempt to add a fragment which is longer than the data available */
1358 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1361 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1362 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1363 ASSERT_NE(NULL,fd_head);
1365 /* check the contents of the structure. Reassembly failed so everything
1366 * should be null (meaning, just use the original tvb) */
1367 ASSERT_EQ(0,fd_head->frame); /* unused */
1368 ASSERT_EQ(0,fd_head->offset); /* unused */
1369 ASSERT_EQ(0,fd_head->len); /* the length of data we have */
1370 ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
1371 ASSERT_EQ(0,fd_head->reassembled_in);
1372 ASSERT_EQ(FD_BLOCKSEQUENCE,fd_head->flags & 0x1ff);
1373 ASSERT_EQ(NULL,fd_head->tvb_data);
1374 ASSERT_EQ(NULL,fd_head->next);
1376 /* add another fragment (with all data present) */
1378 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1381 /* XXX: it's not clear that this is the right result; however it's what the
1384 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1385 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1386 ASSERT_EQ(NULL,fd_head);
1389 /* check what happens when we revisit the packets */
1390 pinfo.fd->flags.visited = TRUE;
1393 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1396 /* We just look in the reassembled_table for this packet. It never got put
1397 * there, so this always returns null.
1399 * That's crazy, because it means that the subdissector will see the data
1400 * exactly once - on the first pass through the capture (well, assuming it
1401 * doesn't bother to check fd_head->reassembled_in); however, that's
1402 * what the code does...
1404 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1405 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1406 ASSERT_EQ(NULL,fd_head);
1409 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1411 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1412 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1413 ASSERT_EQ(NULL,fd_head);
1418 * we're going to do something similar now, but this time it is the second
1419 * fragment which has something missing.
1422 test_missing_data_fragment_add_seq_next_2(void)
1424 fragment_head *fd_head;
1426 printf("Starting test test_missing_data_fragment_add_seq_next_2\n");
1429 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 10, &pinfo, 24, NULL,
1432 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1433 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1434 ASSERT_EQ(NULL,fd_head);
1437 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 24, NULL,
1440 /* XXX: again, i'm really dubious about this. Surely this should return all
1441 * the data we had, for a best-effort attempt at dissecting it?
1442 * And it ought to go into the reassembled table?
1444 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1445 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1446 ASSERT_EQ(NULL,fd_head);
1448 /* check what happens when we revisit the packets */
1449 pinfo.fd->flags.visited = TRUE;
1452 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 10, &pinfo, 24, NULL,
1455 /* As before, this returns NULL because the fragment isn't in the
1456 * reassembled_table. At least this is a bit more consistent than before.
1458 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1459 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1460 ASSERT_EQ(NULL,fd_head);
1463 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 24, NULL,
1465 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1466 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1467 ASSERT_EQ(NULL,fd_head);
1472 * This time, our datagram only has one segment, but it has data missing.
1475 test_missing_data_fragment_add_seq_next_3(void)
1477 fragment_head *fd_head;
1479 printf("Starting test test_missing_data_fragment_add_seq_next_3\n");
1482 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 30, NULL,
1485 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1486 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.reassembled_table));
1487 ASSERT_NE(NULL,fd_head);
1489 /* check the contents of the structure. */
1490 ASSERT_EQ(0,fd_head->frame); /* unused */
1491 ASSERT_EQ(0,fd_head->offset); /* unused */
1492 ASSERT_EQ(0,fd_head->len); /* the length of data we have */
1493 ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
1494 ASSERT_EQ(20,fd_head->reassembled_in);
1495 ASSERT_EQ(FD_BLOCKSEQUENCE|FD_DEFRAGMENTED,fd_head->flags);
1496 ASSERT_EQ(NULL,fd_head->tvb_data);
1497 ASSERT_EQ(NULL,fd_head->next);
1499 /* revisiting the packet ought to produce the same result. */
1500 pinfo.fd->flags.visited = TRUE;
1503 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 30, NULL,
1506 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1507 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.reassembled_table));
1508 ASSERT_NE(NULL,fd_head);
1509 ASSERT_EQ(0,fd_head->frame); /* unused */
1510 ASSERT_EQ(0,fd_head->offset); /* unused */
1511 ASSERT_EQ(0,fd_head->len); /* the length of data we have */
1512 ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
1513 ASSERT_EQ(20,fd_head->reassembled_in);
1514 ASSERT_EQ(FD_BLOCKSEQUENCE|FD_DEFRAGMENTED,fd_head->flags);
1515 ASSERT_EQ(NULL,fd_head->tvb_data);
1516 ASSERT_EQ(NULL,fd_head->next);
1521 /**********************************************************************************
1525 *********************************************************************************/
1528 main(int argc _U_, char **argv _U_)
1531 static const guint8 src[] = {1,2,3,4}, dst[] = {5,6,7,8};
1533 static void (*tests[])(void) = {
1534 test_simple_fragment_add_seq, /* frag table only */
1535 test_fragment_add_seq_partial_reassembly,
1536 test_fragment_add_seq_duplicate_first,
1537 test_fragment_add_seq_duplicate_middle,
1538 test_fragment_add_seq_duplicate_last,
1539 test_fragment_add_seq_duplicate_conflict,
1540 test_fragment_add_seq_check, /* frag + reassemble */
1541 test_fragment_add_seq_check_1,
1542 test_fragment_add_seq_802_11_0,
1543 test_fragment_add_seq_802_11_1,
1544 test_simple_fragment_add_seq_next,
1546 test_missing_data_fragment_add_seq_next,
1547 test_missing_data_fragment_add_seq_next_2,
1548 test_missing_data_fragment_add_seq_next_3,
1551 test_fragment_add_seq_check_multiple
1555 /* a tvbuff for testing with */
1556 data = (char *)g_malloc(DATA_LEN);
1557 /* make sure it's full of stuff */
1558 for(i=0; i<DATA_LEN; i++) {
1561 tvb = tvb_new_real_data(data, DATA_LEN, DATA_LEN*2);
1563 /* other test stuff */
1565 fd.flags.visited = 0;
1566 set_address(&pinfo.src,AT_IPv4,4,src);
1567 set_address(&pinfo.dst,AT_IPv4,4,dst);
1569 /*************************************************************************/
1570 for(i=0; i < sizeof(tests)/sizeof(tests[0]); i++ ) {
1571 /* re-init the fragment tables */
1572 reassembly_table_init(&test_reassembly_table,
1573 &addresses_reassembly_table_functions);
1574 ASSERT(test_reassembly_table.fragment_table != NULL);
1575 ASSERT(test_reassembly_table.reassembled_table != NULL);
1577 pinfo.fd->flags.visited = FALSE;
1581 /* Free memory used by the tables */
1582 reassembly_table_destroy(&test_reassembly_table);
1590 printf(failure?"FAILURE\n":"SUCCESS\n");
1595 * Editor modelines - http://www.wireshark.org/tools/modelines.html
1600 * indent-tabs-mode: nil
1603 * vi: set shiftwidth=4 tabstop=8 expandtab:
1604 * :indentSize=4:tabSize=8:noTabs=true: