2 * Standalone program to test functionality of reassemble.h API
4 * These aren't particularly complete - they just test a few corners of
5 * functionality which I was interested in. In particular, they only test the
6 * fragment_add_seq_* (ie, FD_BLOCKSEQUENCE) family of routines. However,
7 * hopefully they will inspire people to write additional tests, and provide a
8 * useful basis on which to do so.
11 * 1. reassemble_test can be run under valgrind to detect any memory leaks in the
12 * Wireshark reassembly code.
13 * Specifically: code has been added to free dynamically allocated memory
14 * after each test (or at program completion) so that valgrind will report
15 * only actual memory leaks.
16 * The following command can be used to run reassemble_test under valgrind:
18 * G_DEBUG=gc-friendly \
19 * G_SLICE=always-malloc \
20 * valgrind --leak-check=full --show-reachable=yes ./reassemble_test
22 * 2. Debug functions have been added which will print information
23 * about the fd-chains associated with the fragment_table and the
25 * #define debug to enable the code.
27 * Copyright (c) 2007 MX Telecom Ltd. <richardv@mxtelecom.com>
29 * Wireshark - Network traffic analyzer
30 * By Gerald Combs <gerald@wireshark.org>
33 * SPDX-License-Identifier: GPL-2.0-or-later
45 #include <epan/packet.h>
46 #include <epan/packet_info.h>
47 #include <epan/proto.h>
48 #include <epan/tvbuff.h>
49 #include <epan/reassemble.h>
51 static int failure = 0;
56 printf("Assertion failed at line %i: %s\n", __LINE__, #b); \
60 #define ASSERT_EQ(exp,act) \
63 printf("Assertion failed at line %i: %s==%s (%u==%u)\n", __LINE__, #exp, #act, (guint)exp, (guint)act); \
67 #define ASSERT_EQ_POINTER(exp,act) \
70 printf("Assertion failed at line %i: %s==%s (%p==%p)\n", __LINE__, #exp, #act, (void *)exp, (void *)act); \
74 #define ASSERT_NE_POINTER(exp,act) \
77 printf("Assertion failed at line %i: %s!=%s (%p!=%p)\n", __LINE__, #exp, #act, (void *)exp, (void *)act); \
85 static packet_info pinfo;
87 /* fragment_table maps from datagram ids to fragment_head
88 reassembled_table maps from <packet number,datagram id> to
90 static reassembly_table test_reassembly_table;
93 /*************************************************
94 * Util fcns to display
95 * fragment_table & reassembled_table fd-chains
96 ************************************************/
98 static struct _fd_flags {
102 {FD_DEFRAGMENTED ,"DF"},
103 {FD_DATALEN_SET ,"DS"},
104 {FD_SUBSET_TVB, ,"ST"},
105 {FD_BLOCKSEQUENCE ,"BS"},
106 {FD_PARTIAL_REASSEMBLY ,"PR"},
108 {FD_OVERLAPCONFLICT ,"OC"},
109 {FD_MULTIPLETAILS ,"MT"},
110 {FD_TOOLONGFRAGMENT ,"TL"},
112 #define N_FD_FLAGS (signed)(sizeof(fd_flags)/sizeof(struct _fd_flags))
115 print_fd(fragment_head *fd, gboolean is_head) {
118 g_assert(fd != NULL);
119 printf(" %08x %08x %3d %3d %3d", fd, fd->next, fd->frame, fd->offset, fd->len);
121 printf(" %3d %3d", fd->datalen, fd->reassembled_in);
125 printf(" 0x%08x", fd->data);
126 for (i=0; i<N_FD_FLAGS; i++) {
127 printf(" %s", (fd->flags & fd_flags[i].flag) ? fd_flags[i].flag_name : " ");
133 print_fd_chain(fragment_head *fd_head) {
136 g_assert(fd_head != NULL);
137 print_fd(fd_head, TRUE);
138 for (fdp=fd_head->next; fdp != NULL; fdp=fdp->next) {
139 print_fd(fdp, FALSE);
144 print_fragment_table_chain(gpointer k, gpointer v, gpointer ud) {
145 fragment_key *key = (fragment_key*)k;
146 fragment_head *fd_head = (fragment_head *)v;
147 printf(" --> FT: %3d 0x%08x 0x%08x\n", key->id, *(guint32 *)(key->src.data), *(guint32 *)(key->dst.data));
148 print_fd_chain(fd_head);
152 print_fragment_table(void) {
153 printf("\n Fragment Table -------\n");
154 g_hash_table_foreach(fragment_table, print_fragment_table_chain, NULL);
158 print_reassembled_table_chain(gpointer k, gpointer v, gpointer ud) {
159 reassembled_key *key = (reassembled_key*)k;
160 fragment_head *fd_head = (fragment_head *)v;
161 printf(" --> RT: %5d %5d\n", key->id, key->frame);
162 print_fd_chain(fd_head);
166 print_reassembled_table(void) {
167 printf("\n Reassembled Table ----\n");
168 g_hash_table_foreach(test_reassembly_table.reassembled_table, print_reassembled_table_chain, NULL);
173 print_fragment_table();
174 print_reassembled_table();
178 /**********************************************************************************
182 *********************************************************************************/
184 /* Simple test case for fragment_add_seq.
185 * Adds three fragments (out of order, with one for a different datagram in between),
186 * and checks that they are reassembled correctly.
188 /* visit id frame frag len more tvb_offset
196 test_simple_fragment_add_seq(void)
198 fragment_head *fd_head, *fdh0;
200 printf("Starting test test_simple_fragment_add_seq\n");
203 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
206 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
207 ASSERT_EQ_POINTER(NULL,fd_head);
209 /* adding the same fragment again should do nothing, even with different
211 pinfo.fd->flags.visited = 1;
212 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
214 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
215 ASSERT_EQ_POINTER(NULL,fd_head);
217 /* start another pdu (just to confuse things) */
218 pinfo.fd->flags.visited = 0;
220 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 15, &pinfo, 13, NULL,
222 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
223 ASSERT_EQ_POINTER(NULL,fd_head);
225 /* now we add the terminal fragment of the first datagram */
227 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
230 /* we haven't got all the fragments yet ... */
231 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
232 ASSERT_EQ_POINTER(NULL,fd_head);
234 /* finally, add the missing fragment */
236 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 15, &pinfo, 12, NULL,
239 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
240 ASSERT_NE_POINTER(NULL,fd_head);
242 /* check the contents of the structure */
243 ASSERT_EQ(4,fd_head->frame); /* max frame number of fragment in assembly */
244 ASSERT_EQ(0,fd_head->offset); /* unused */
245 ASSERT_EQ(170,fd_head->len); /* the length of data we have */
246 ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
247 ASSERT_EQ(4,fd_head->reassembled_in);
248 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
249 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
250 ASSERT_NE_POINTER(NULL,fd_head->next);
252 ASSERT_EQ(1,fd_head->next->frame);
253 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
254 ASSERT_EQ(50,fd_head->next->len); /* segment length */
255 ASSERT_EQ(0,fd_head->next->flags);
256 ASSERT_EQ_POINTER(NULL,fd_head->next->tvb_data);
257 ASSERT_NE_POINTER(NULL,fd_head->next->next);
259 ASSERT_EQ(4,fd_head->next->next->frame);
260 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
261 ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
262 ASSERT_EQ(0,fd_head->next->next->flags);
263 ASSERT_EQ_POINTER(NULL,fd_head->next->next->tvb_data);
264 ASSERT_NE_POINTER(NULL,fd_head->next->next->next);
266 ASSERT_EQ(3,fd_head->next->next->next->frame);
267 ASSERT_EQ(2,fd_head->next->next->next->offset); /* seqno */
268 ASSERT_EQ(60,fd_head->next->next->next->len); /* segment length */
269 ASSERT_EQ(0,fd_head->next->next->next->flags);
270 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->tvb_data);
271 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->next);
273 /* test the actual reassembly */
274 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
275 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+15,60));
276 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,60));
279 print_fragment_table();
282 /* what happens if we revisit the packets now? */
284 pinfo.fd->flags.visited = 1;
286 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
289 * this api relies on the caller to check fd_head -> reassembled_in
291 * Redoing all the tests seems like overkill - just check the pointer
293 ASSERT_EQ_POINTER(fdh0,fd_head);
296 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
298 ASSERT_EQ_POINTER(fdh0,fd_head);
301 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 15, &pinfo, 12, NULL,
303 ASSERT_EQ_POINTER(fdh0,fd_head);
306 print_fragment_table();
310 /* XXX ought to have some tests for overlapping fragments */
312 /* This tests the functionality of fragment_set_partial_reassembly for
313 * FD_BLOCKSEQUENCE reassembly.
315 * We add a sequence of fragments thus:
316 * seqno frame offset len (initial) more_frags
317 * ----- ----- ------ --- --------------------
320 * 1 3 0 40 true (a duplicate fragment)
325 test_fragment_add_seq_partial_reassembly(void)
327 fragment_head *fd_head;
330 printf("Starting test test_fragment_add_seq_partial_reassembly\n");
332 /* generally it's probably fair to assume that we will be called with
336 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
339 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
340 ASSERT_NE_POINTER(NULL,fd_head);
342 /* check the contents of the structure */
343 ASSERT_EQ(1,fd_head->frame); /* max frame in reassembly */
344 ASSERT_EQ(0,fd_head->offset); /* unused */
345 ASSERT_EQ(50,fd_head->len); /* the length of data we have */
346 ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
347 ASSERT_EQ(1,fd_head->reassembled_in);
348 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
349 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
350 ASSERT_NE_POINTER(NULL,fd_head->next);
352 ASSERT_EQ(1,fd_head->next->frame);
353 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
354 ASSERT_EQ(50,fd_head->next->len); /* segment length */
355 ASSERT_EQ(0,fd_head->next->flags);
356 ASSERT_EQ_POINTER(NULL,fd_head->next->tvb_data);
357 ASSERT_EQ_POINTER(NULL,fd_head->next->next);
359 /* test the actual reassembly */
360 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
362 /* now we announce that the reassembly wasn't complete after all. */
363 fragment_set_partial_reassembly(&test_reassembly_table, &pinfo, 12, NULL);
365 /* and add another segment. To mix things up slightly (and so that we can
366 * check on the state of things), we're going to set the more_frags flag
370 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
373 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
374 ASSERT_EQ_POINTER(NULL,fd_head);
376 fd_head=fragment_get(&test_reassembly_table, &pinfo, 12, NULL);
377 ASSERT_NE_POINTER(NULL,fd_head);
379 /* check the contents of the structure */
380 ASSERT_EQ(2,fd_head->frame); /* max frame in reassembly */
381 ASSERT_EQ(0,fd_head->offset); /* unused */
382 /* ASSERT_EQ(50,fd_head->len); the length of data we have */
383 ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
384 ASSERT_EQ(0,fd_head->reassembled_in);
385 ASSERT_EQ(FD_BLOCKSEQUENCE,fd_head->flags);
386 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
387 ASSERT_NE_POINTER(NULL,fd_head->next);
390 ASSERT_EQ(1,fd->frame);
391 ASSERT_EQ(0,fd->offset); /* seqno */
392 ASSERT_EQ(50,fd->len); /* segment length */
393 ASSERT_EQ(FD_SUBSET_TVB,fd->flags);
394 ASSERT_EQ_POINTER(tvb_get_ptr(fd_head->tvb_data,0,0),tvb_get_ptr(fd->tvb_data,0,0));
395 ASSERT_NE_POINTER(NULL,fd->next);
398 ASSERT_EQ(2,fd->frame);
399 ASSERT_EQ(1,fd->offset); /* seqno */
400 ASSERT_EQ(40,fd->len); /* segment length */
401 ASSERT_EQ(0,fd->flags);
402 ASSERT_NE_POINTER(NULL,fd->tvb_data);
403 ASSERT_EQ_POINTER(NULL,fd->next);
405 /* Another copy of the second segment.
408 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
411 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
412 ASSERT_EQ_POINTER(NULL,fd_head);
413 fd_head=fragment_get(&test_reassembly_table, &pinfo, 12, NULL);
414 ASSERT_NE_POINTER(NULL,fd_head);
415 ASSERT_EQ(3,fd_head->frame); /* max frame we have */
416 ASSERT_EQ(0,fd_head->offset); /* unused */
417 /* ASSERT_EQ(50,fd_head->len); the length of data we have */
418 ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
419 ASSERT_EQ(0,fd_head->reassembled_in);
420 ASSERT_EQ(FD_BLOCKSEQUENCE,fd_head->flags);
421 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
422 ASSERT_NE_POINTER(NULL,fd_head->next);
425 ASSERT_EQ(1,fd->frame);
426 ASSERT_EQ(0,fd->offset); /* seqno */
427 ASSERT_EQ(50,fd->len); /* segment length */
428 ASSERT_EQ(FD_SUBSET_TVB,fd->flags);
429 ASSERT_EQ_POINTER(tvb_get_ptr(fd_head->tvb_data,0,0),tvb_get_ptr(fd->tvb_data,0,0));
430 ASSERT_NE_POINTER(NULL,fd->next);
433 ASSERT_EQ(2,fd->frame);
434 ASSERT_EQ(1,fd->offset); /* seqno */
435 ASSERT_EQ(40,fd->len); /* segment length */
436 ASSERT_EQ(0,fd->flags);
437 ASSERT_NE_POINTER(NULL,fd->tvb_data);
438 ASSERT_NE_POINTER(NULL,fd->next);
441 ASSERT_EQ(3,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_POINTER(NULL,fd->tvb_data);
446 ASSERT_EQ_POINTER(NULL,fd->next);
450 /* have another go at wrapping things up */
452 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 20, &pinfo, 12, NULL,
455 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
456 ASSERT_NE_POINTER(NULL,fd_head);
458 /* check the contents of the structure */
459 ASSERT_EQ(4,fd_head->frame); /* max frame we have */
460 ASSERT_EQ(0,fd_head->offset); /* unused */
461 ASSERT_EQ(190,fd_head->len); /* the length of data we have */
462 ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
463 ASSERT_EQ(4,fd_head->reassembled_in);
464 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
465 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
466 ASSERT_NE_POINTER(NULL,fd_head->next);
469 ASSERT_EQ(1,fd->frame);
470 ASSERT_EQ(0,fd->offset); /* seqno */
471 ASSERT_EQ(50,fd->len); /* segment length */
472 ASSERT_EQ(0,fd->flags);
473 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
474 ASSERT_NE_POINTER(NULL,fd->next);
477 ASSERT_EQ(2,fd->frame);
478 ASSERT_EQ(1,fd->offset); /* seqno */
479 ASSERT_EQ(40,fd->len); /* segment length */
480 ASSERT_EQ(0,fd->flags);
481 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
482 ASSERT_NE_POINTER(NULL,fd->next);
485 ASSERT_EQ(3,fd->frame);
486 ASSERT_EQ(1,fd->offset); /* seqno */
487 ASSERT_EQ(40,fd->len); /* segment length */
488 ASSERT_EQ(FD_OVERLAP,fd->flags);
489 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
490 ASSERT_NE_POINTER(NULL,fd->next);
493 ASSERT_EQ(4,fd->frame);
494 ASSERT_EQ(2,fd->offset); /* seqno */
495 ASSERT_EQ(100,fd->len); /* segment length */
496 ASSERT_EQ(0,fd->flags);
497 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
498 ASSERT_EQ_POINTER(NULL,fd->next);
500 /* test the actual reassembly */
501 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
502 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data,40));
503 ASSERT(!tvb_memeql(fd_head->tvb_data,90,data+20,100));
506 /* do it again (this time it is more complicated, with an overlap in the
509 fragment_set_partial_reassembly(&test_reassembly_table, &pinfo, 12, NULL);
512 fragment_add_seq(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
515 fd_head=fragment_get(&test_reassembly_table, &pinfo, 12, NULL);
516 ASSERT_NE_POINTER(NULL,fd_head);
517 ASSERT_EQ(5,fd_head->frame); /* max frame we have */
518 ASSERT_EQ(0,fd_head->offset); /* unused */
519 ASSERT_EQ(230,fd_head->len); /* the length of data we have */
520 ASSERT_EQ(3,fd_head->datalen); /* seqno of the last fragment we have */
521 ASSERT_EQ(5,fd_head->reassembled_in);
522 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
523 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
524 ASSERT_NE_POINTER(NULL,fd_head->next);
527 ASSERT_EQ(1,fd->frame);
528 ASSERT_EQ(0,fd->offset); /* seqno */
529 ASSERT_EQ(50,fd->len); /* segment length */
530 ASSERT_EQ(0,fd->flags);
531 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
532 ASSERT_NE_POINTER(NULL,fd->next);
535 ASSERT_EQ(2,fd->frame);
536 ASSERT_EQ(1,fd->offset); /* seqno */
537 ASSERT_EQ(40,fd->len); /* segment length */
538 ASSERT_EQ(0,fd->flags);
539 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
540 ASSERT_NE_POINTER(NULL,fd->next);
543 ASSERT_EQ(3,fd->frame);
544 ASSERT_EQ(1,fd->offset); /* seqno */
545 ASSERT_EQ(40,fd->len); /* segment length */
546 ASSERT_EQ(FD_OVERLAP,fd->flags);
547 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
548 ASSERT_NE_POINTER(NULL,fd->next);
551 ASSERT_EQ(4,fd->frame);
552 ASSERT_EQ(2,fd->offset); /* seqno */
553 ASSERT_EQ(100,fd->len); /* segment length */
554 ASSERT_EQ(0,fd->flags);
555 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
556 ASSERT_NE_POINTER(NULL,fd->next);
559 ASSERT_EQ(5,fd->frame);
560 ASSERT_EQ(3,fd->offset); /* seqno */
561 ASSERT_EQ(40,fd->len); /* segment length */
562 ASSERT_EQ(0,fd->flags);
563 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
564 ASSERT_EQ_POINTER(NULL,fd->next);
566 /* test the actual reassembly */
567 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
568 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data,40));
569 ASSERT(!tvb_memeql(fd_head->tvb_data,90,data+20,100));
570 ASSERT(!tvb_memeql(fd_head->tvb_data,190,data,40));
573 /* Test case for fragment_add_seq with duplicated (e.g., retransmitted) data.
574 * Adds three fragments--adding the 1st one twice--
575 * and checks that they are reassembled correctly.
577 /* visit id frame frag len more tvb_offset
584 test_fragment_add_seq_duplicate_first(void)
586 fragment_head *fd_head;
588 printf("Starting test test_fragment_add_seq_duplicate_first\n");
591 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
594 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
595 ASSERT_EQ_POINTER(NULL,fd_head);
597 /* Add the 2nd segment */
599 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
602 /* we haven't got all the fragments yet ... */
603 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
604 ASSERT_EQ_POINTER(NULL,fd_head);
606 /* Add the last fragment */
608 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
611 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
612 ASSERT_NE_POINTER(NULL,fd_head);
614 /* Add the first fragment again */
616 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
619 /* Reassembly should have still succeeded */
620 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
621 ASSERT_NE_POINTER(NULL,fd_head);
623 /* check the contents of the structure */
624 ASSERT_EQ(4,fd_head->frame); /* max frame we have */
625 ASSERT_EQ(0,fd_head->offset); /* unused */
626 ASSERT_EQ(150,fd_head->len); /* the length of data we have */
627 ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
628 ASSERT_EQ(3,fd_head->reassembled_in);
629 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
630 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
631 ASSERT_NE_POINTER(NULL,fd_head->next);
633 ASSERT_EQ(1,fd_head->next->frame);
634 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
635 ASSERT_EQ(50,fd_head->next->len); /* segment length */
636 ASSERT_EQ(0,fd_head->next->flags);
637 ASSERT_EQ_POINTER(NULL,fd_head->next->tvb_data);
638 ASSERT_NE_POINTER(NULL,fd_head->next->next);
640 ASSERT_EQ(4,fd_head->next->next->frame);
641 ASSERT_EQ(0,fd_head->next->next->offset); /* seqno */
642 ASSERT_EQ(50,fd_head->next->next->len); /* segment length */
643 ASSERT_EQ(FD_OVERLAP,fd_head->next->next->flags);
644 ASSERT_EQ_POINTER(NULL,fd_head->next->next->tvb_data);
645 ASSERT_NE_POINTER(NULL,fd_head->next->next->next);
647 ASSERT_EQ(2,fd_head->next->next->next->frame);
648 ASSERT_EQ(1,fd_head->next->next->next->offset); /* seqno */
649 ASSERT_EQ(60,fd_head->next->next->next->len); /* segment length */
650 ASSERT_EQ(0,fd_head->next->next->next->flags);
651 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->tvb_data);
652 ASSERT_NE_POINTER(NULL,fd_head->next->next->next->next);
654 ASSERT_EQ(3,fd_head->next->next->next->next->frame);
655 ASSERT_EQ(2,fd_head->next->next->next->next->offset); /* seqno */
656 ASSERT_EQ(40,fd_head->next->next->next->next->len); /* segment length */
657 ASSERT_EQ(0,fd_head->next->next->next->next->flags);
658 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->next->tvb_data);
659 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->next->next);
661 /* test the actual reassembly */
662 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
663 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
664 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
667 print_fragment_table();
672 /* Test case for fragment_add_seq with duplicated (e.g., retransmitted) data.
673 * Adds three fragments--adding the 2nd one twice--
674 * and checks that they are reassembled correctly.
676 /* visit id frame frag len more tvb_offset
683 test_fragment_add_seq_duplicate_middle(void)
685 fragment_head *fd_head;
687 printf("Starting test test_fragment_add_seq_duplicate_middle\n");
690 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
693 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
694 ASSERT_EQ_POINTER(NULL,fd_head);
696 /* Add the 2nd segment */
698 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
701 /* we haven't got all the fragments yet ... */
702 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
703 ASSERT_EQ_POINTER(NULL,fd_head);
705 /* Now, add the 2nd segment again (but in a different frame) */
707 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
710 /* This duplicate fragment should have been ignored */
711 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
712 ASSERT_EQ_POINTER(NULL,fd_head);
714 /* finally, add the last fragment */
716 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
719 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
720 ASSERT_NE_POINTER(NULL,fd_head);
722 /* check the contents of the structure */
723 ASSERT_EQ(4,fd_head->frame); /* max frame we have */
724 ASSERT_EQ(0,fd_head->offset); /* unused */
725 ASSERT_EQ(150,fd_head->len); /* the length of data we have */
726 ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
727 ASSERT_EQ(4,fd_head->reassembled_in);
728 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
729 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
730 ASSERT_NE_POINTER(NULL,fd_head->next);
732 ASSERT_EQ(1,fd_head->next->frame);
733 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
734 ASSERT_EQ(50,fd_head->next->len); /* segment length */
735 ASSERT_EQ(0,fd_head->next->flags);
736 ASSERT_EQ_POINTER(NULL,fd_head->next->tvb_data);
737 ASSERT_NE_POINTER(NULL,fd_head->next->next);
739 ASSERT_EQ(2,fd_head->next->next->frame);
740 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
741 ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
742 ASSERT_EQ(0,fd_head->next->next->flags);
743 ASSERT_EQ_POINTER(NULL,fd_head->next->next->tvb_data);
744 ASSERT_NE_POINTER(NULL,fd_head->next->next->next);
746 ASSERT_EQ(3,fd_head->next->next->next->frame);
747 ASSERT_EQ(1,fd_head->next->next->next->offset); /* seqno */
748 ASSERT_EQ(60,fd_head->next->next->next->len); /* segment length */
749 ASSERT_EQ(FD_OVERLAP,fd_head->next->next->next->flags);
750 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->tvb_data);
751 ASSERT_NE_POINTER(NULL,fd_head->next->next->next->next);
753 ASSERT_EQ(4,fd_head->next->next->next->next->frame);
754 ASSERT_EQ(2,fd_head->next->next->next->next->offset); /* seqno */
755 ASSERT_EQ(40,fd_head->next->next->next->next->len); /* segment length */
756 ASSERT_EQ(0,fd_head->next->next->next->next->flags);
757 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->next->tvb_data);
758 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->next->next);
760 /* test the actual reassembly */
761 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
762 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
763 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
766 print_fragment_table();
770 /* Test case for fragment_add_seq with duplicated (e.g., retransmitted) data.
771 * Adds three fragments--adding the 3rd one twice--
772 * and checks that they are reassembled correctly.
774 /* visit id frame frag len more tvb_offset
781 test_fragment_add_seq_duplicate_last(void)
783 fragment_head *fd_head;
785 printf("Starting test test_fragment_add_seq_duplicate_last\n");
788 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
791 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
792 ASSERT_EQ_POINTER(NULL,fd_head);
794 /* Add the 2nd segment */
796 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
799 /* we haven't got all the fragments yet ... */
800 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
801 ASSERT_EQ_POINTER(NULL,fd_head);
803 /* Add the last fragment */
805 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
808 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
809 ASSERT_NE_POINTER(NULL,fd_head);
811 /* Add the last fragment again */
813 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
816 /* Reassembly should have still succeeded */
817 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
818 ASSERT_NE_POINTER(NULL,fd_head);
820 /* check the contents of the structure */
821 ASSERT_EQ(4,fd_head->frame); /* max frame we have */
822 ASSERT_EQ(0,fd_head->offset); /* unused */
823 ASSERT_EQ(150,fd_head->len); /* the length of data we have */
824 ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
825 ASSERT_EQ(3,fd_head->reassembled_in);
826 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
827 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
828 ASSERT_NE_POINTER(NULL,fd_head->next);
830 ASSERT_EQ(1,fd_head->next->frame);
831 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
832 ASSERT_EQ(50,fd_head->next->len); /* segment length */
833 ASSERT_EQ(0,fd_head->next->flags);
834 ASSERT_EQ_POINTER(NULL,fd_head->next->tvb_data);
835 ASSERT_NE_POINTER(NULL,fd_head->next->next);
837 ASSERT_EQ(2,fd_head->next->next->frame);
838 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
839 ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
840 ASSERT_EQ(0,fd_head->next->next->flags);
841 ASSERT_EQ_POINTER(NULL,fd_head->next->next->tvb_data);
842 ASSERT_NE_POINTER(NULL,fd_head->next->next->next);
844 ASSERT_EQ(3,fd_head->next->next->next->frame);
845 ASSERT_EQ(2,fd_head->next->next->next->offset); /* seqno */
846 ASSERT_EQ(40,fd_head->next->next->next->len); /* segment length */
847 ASSERT_EQ(0,fd_head->next->next->next->flags);
848 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->tvb_data);
849 ASSERT_NE_POINTER(NULL,fd_head->next->next->next->next);
851 ASSERT_EQ(4,fd_head->next->next->next->next->frame);
852 ASSERT_EQ(2,fd_head->next->next->next->next->offset); /* seqno */
853 ASSERT_EQ(40,fd_head->next->next->next->next->len); /* segment length */
854 ASSERT_EQ(FD_OVERLAP,fd_head->next->next->next->next->flags);
855 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->next->tvb_data);
856 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->next->next);
858 /* test the actual reassembly */
859 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
860 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
861 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
864 print_fragment_table();
868 /* Test case for fragment_add_seq with duplicated (e.g., retransmitted) data
869 * where the retransmission "conflicts" with the original transmission
870 * (contents are different).
871 * Adds three fragments--adding the 2nd one twice--
872 * and checks that they are reassembled correctly.
874 /* visit id frame frag len more tvb_offset
881 test_fragment_add_seq_duplicate_conflict(void)
883 fragment_head *fd_head;
885 printf("Starting test test_fragment_add_seq_duplicate_conflict\n");
888 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
891 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
892 ASSERT_EQ_POINTER(NULL,fd_head);
894 /* Add the 2nd segment */
896 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
899 /* we haven't got all the fragments yet ... */
900 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
901 ASSERT_EQ_POINTER(NULL,fd_head);
903 /* Now, add the 2nd segment again (but in a different frame and with
907 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 15, &pinfo, 12, NULL,
910 /* This duplicate fragment should have been ignored */
911 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
912 ASSERT_EQ_POINTER(NULL,fd_head);
914 /* finally, add the last fragment */
916 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
919 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
920 ASSERT_NE_POINTER(NULL,fd_head);
922 /* check the contents of the structure */
923 ASSERT_EQ(4,fd_head->frame); /* max frame we have */
924 ASSERT_EQ(0,fd_head->offset); /* unused */
925 ASSERT_EQ(150,fd_head->len); /* the length of data we have */
926 ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
927 ASSERT_EQ(4,fd_head->reassembled_in);
928 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP|FD_OVERLAPCONFLICT,fd_head->flags);
929 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
930 ASSERT_NE_POINTER(NULL,fd_head->next);
932 ASSERT_EQ(1,fd_head->next->frame);
933 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
934 ASSERT_EQ(50,fd_head->next->len); /* segment length */
935 ASSERT_EQ(0,fd_head->next->flags);
936 ASSERT_EQ_POINTER(NULL,fd_head->next->tvb_data);
937 ASSERT_NE_POINTER(NULL,fd_head->next->next);
939 ASSERT_EQ(2,fd_head->next->next->frame);
940 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
941 ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
942 ASSERT_EQ(0,fd_head->next->next->flags);
943 ASSERT_EQ_POINTER(NULL,fd_head->next->next->tvb_data);
944 ASSERT_NE_POINTER(NULL,fd_head->next->next->next);
946 ASSERT_EQ(3,fd_head->next->next->next->frame);
947 ASSERT_EQ(1,fd_head->next->next->next->offset); /* seqno */
948 ASSERT_EQ(60,fd_head->next->next->next->len); /* segment length */
949 ASSERT_EQ(FD_OVERLAP|FD_OVERLAPCONFLICT,fd_head->next->next->next->flags);
950 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->tvb_data);
951 ASSERT_NE_POINTER(NULL,fd_head->next->next->next->next);
953 ASSERT_EQ(4,fd_head->next->next->next->next->frame);
954 ASSERT_EQ(2,fd_head->next->next->next->next->offset); /* seqno */
955 ASSERT_EQ(40,fd_head->next->next->next->next->len); /* segment length */
956 ASSERT_EQ(0,fd_head->next->next->next->next->flags);
957 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->next->tvb_data);
958 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->next->next);
960 /* test the actual reassembly */
961 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
962 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
963 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
966 print_fragment_table();
970 /**********************************************************************************
972 * fragment_add_seq_check
974 *********************************************************************************/
977 /* This routine is used for both fragment_add_seq_802_11 and
978 * fragment_add_seq_check.
980 * Adds a couple of out-of-order fragments and checks their reassembly.
983 /* visit id frame frag len more tvb_offset
992 test_fragment_add_seq_check_work(fragment_head *(*fn)(reassembly_table *,
993 tvbuff_t *, const int, const packet_info *,
994 const guint32, const void *, const guint32,
995 const guint32, const gboolean))
997 fragment_head *fd_head;
1000 fd_head=fn(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1003 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1004 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1005 ASSERT_EQ_POINTER(NULL,fd_head);
1007 /* start another pdu (just to confuse things) */
1009 fd_head=fn(&test_reassembly_table, tvb, 15, &pinfo, 13, NULL,
1011 ASSERT_EQ(2,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_POINTER(NULL,fd_head);
1015 /* add the terminal fragment of the first datagram */
1017 fd_head=fn(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1020 /* we haven't got all the fragments yet ... */
1021 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
1022 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1023 ASSERT_EQ_POINTER(NULL,fd_head);
1025 /* finally, add the missing fragment */
1027 fd_head=fn(&test_reassembly_table, tvb, 15, &pinfo, 12, NULL,
1030 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1031 ASSERT_EQ(3,g_hash_table_size(test_reassembly_table.reassembled_table));
1032 ASSERT_NE_POINTER(NULL,fd_head);
1034 /* check the contents of the structure */
1035 ASSERT_EQ(4,fd_head->frame); /* max frame we have */
1036 ASSERT_EQ(0,fd_head->offset); /* unused */
1037 ASSERT_EQ(170,fd_head->len); /* the length of data we have */
1038 ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
1039 ASSERT_EQ(4,fd_head->reassembled_in);
1040 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
1041 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
1042 ASSERT_NE_POINTER(NULL,fd_head->next);
1044 ASSERT_EQ(1,fd_head->next->frame);
1045 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
1046 ASSERT_EQ(50,fd_head->next->len); /* segment length */
1047 ASSERT_EQ(0,fd_head->next->flags);
1048 ASSERT_EQ_POINTER(NULL,fd_head->next->tvb_data);
1049 ASSERT_NE_POINTER(NULL,fd_head->next->next);
1051 ASSERT_EQ(4,fd_head->next->next->frame);
1052 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
1053 ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
1054 ASSERT_EQ(0,fd_head->next->next->flags);
1055 ASSERT_EQ_POINTER(NULL,fd_head->next->next->tvb_data);
1056 ASSERT_NE_POINTER(NULL,fd_head->next->next->next);
1058 ASSERT_EQ(3,fd_head->next->next->next->frame);
1059 ASSERT_EQ(2,fd_head->next->next->next->offset); /* seqno */
1060 ASSERT_EQ(60,fd_head->next->next->next->len); /* segment length */
1061 ASSERT_EQ(0,fd_head->next->next->next->flags);
1062 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->tvb_data);
1063 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->next);
1065 /* test the actual reassembly */
1066 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
1067 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+15,60));
1068 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,60));
1075 /* Simple test case for fragment_add_seq_check
1078 test_fragment_add_seq_check(void)
1080 printf("Starting test test_fragment_add_seq_check\n");
1082 test_fragment_add_seq_check_work(fragment_add_seq_check);
1086 /* This tests the case that the 802.11 hack does something different for: when
1087 * the terminal segment in a fragmented datagram arrives first.
1090 test_fragment_add_seq_check_1(void)
1092 fragment_head *fd_head;
1094 printf("Starting test test_fragment_add_seq_check_1\n");
1097 fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1100 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1101 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1102 ASSERT_EQ_POINTER(NULL,fd_head);
1104 /* Now add the missing segment */
1106 fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1109 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1110 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.reassembled_table));
1111 ASSERT_NE_POINTER(NULL,fd_head);
1113 /* check the contents of the structure */
1114 ASSERT_EQ(2,fd_head->frame); /* max frame of fragment in structure */
1115 ASSERT_EQ(0,fd_head->offset); /* unused */
1116 ASSERT_EQ(110,fd_head->len); /* the length of data we have */
1117 ASSERT_EQ(1,fd_head->datalen); /* seqno of the last fragment we have */
1118 ASSERT_EQ(2,fd_head->reassembled_in);
1119 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
1120 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
1121 ASSERT_NE_POINTER(NULL,fd_head->next);
1123 ASSERT_EQ(2,fd_head->next->frame);
1124 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
1125 ASSERT_EQ(60,fd_head->next->len); /* segment length */
1126 ASSERT_EQ(0,fd_head->next->flags);
1127 ASSERT_EQ_POINTER(NULL,fd_head->next->tvb_data);
1128 ASSERT_NE_POINTER(NULL,fd_head->next->next);
1130 ASSERT_EQ(1,fd_head->next->next->frame);
1131 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
1132 ASSERT_EQ(50,fd_head->next->next->len); /* segment length */
1133 ASSERT_EQ(0,fd_head->next->next->flags);
1134 ASSERT_EQ_POINTER(NULL,fd_head->next->next->tvb_data);
1135 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next);
1137 /* test the actual reassembly */
1138 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+5,60));
1139 ASSERT(!tvb_memeql(fd_head->tvb_data,60,data+10,50));
1142 /**********************************************************************************
1144 * fragment_add_seq_802_11
1146 *********************************************************************************/
1148 /* Tests the 802.11 hack.
1151 test_fragment_add_seq_802_11_0(void)
1153 fragment_head *fd_head;
1155 printf("Starting test test_fragment_add_seq_802_11_0\n");
1157 /* the 802.11 hack is that some non-fragmented datagrams have non-zero
1158 * fragment_number; test for this. */
1161 fd_head=fragment_add_seq_802_11(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1164 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1165 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.reassembled_table));
1166 ASSERT_NE_POINTER(NULL,fd_head);
1168 /* check the contents of the structure */
1169 ASSERT_EQ(0,fd_head->frame); /* unused */
1170 ASSERT_EQ(0,fd_head->offset); /* unused */
1171 ASSERT_EQ(0,fd_head->len); /* unused */
1172 ASSERT_EQ(0,fd_head->datalen); /* unused */
1173 ASSERT_EQ(1,fd_head->reassembled_in);
1174 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE,fd_head->flags);
1175 ASSERT_EQ_POINTER(NULL,fd_head->tvb_data);
1176 ASSERT_EQ_POINTER(NULL,fd_head->next);
1179 /* Reuse the fragment_add_seq_check testcases */
1180 static void test_fragment_add_seq_802_11_1(void)
1182 printf("Starting test test_fragment_add_seq_802_11_1\n");
1183 test_fragment_add_seq_check_work(fragment_add_seq_802_11);
1186 /**********************************************************************************
1188 * fragment_add_seq_check_multiple
1190 *********************************************************************************/
1192 /* Test 2 partial frags from 2 diff datagrams in the same frame */
1194 datagram #1: frame 1 + first part of frame 2
1195 datagram #1: last part of frame 2 + frame 3
1197 Is this a valid scenario ?
1199 The result of calling fragment_add_seq_check(&test_reassembly_table, ) for these
1200 fragments is a reassembled_table with:
1201 id, frame 1 => first_datagram; ["reassembled in" frame 2]
1202 id, frame 2 => second_datagram; ["reassembled in" frame 3]
1203 id, frame 3 => second_datagram;
1205 Note that the id, frame 2 => first datagram was overwritten
1206 by the entry for the second datagram.
1207 Is this OK ? IE: When dissected/displayed
1208 will the reassembled datagram 1 appear with frame 2 ??
1211 /* visit id frame frag len more tvb_offset
1219 Is this a valid scenario ?
1220 Is this OK ? IE: When dissected/displayed:
1221 Will the reassembled datagram 1 appear with frame 2 ??
1225 test_fragment_add_seq_check_multiple(void) {
1226 fragment_head *fd_head;
1229 fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1232 /* add the terminal fragment of the first datagram */
1234 fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1239 /* Now: start a second datagram with the first fragment in frame #2 */
1241 fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 25, &pinfo, 12, NULL,
1244 /* add the terminal fragment of the second datagram */
1246 fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
1253 /**********************************************************************************
1255 * fragment_add_seq_next
1257 *********************************************************************************/
1259 /* Simple test case for fragment_add_seq_next.
1260 * Adds a couple of fragments (with one for a different datagram in between),
1261 * and checks that they are reassembled correctly.
1264 test_simple_fragment_add_seq_next(void)
1266 fragment_head *fd_head;
1268 printf("Starting test test_simple_fragment_add_seq_next\n");
1271 fd_head= fragment_add_seq_next(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1274 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1275 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1276 ASSERT_EQ_POINTER(NULL,fd_head);
1278 /* adding the same fragment again should do nothing, even with different
1280 pinfo.fd->flags.visited = 1;
1281 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1283 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1284 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1285 ASSERT_EQ_POINTER(NULL,fd_head);
1287 /* start another pdu (just to confuse things) */
1288 pinfo.fd->flags.visited = 0;
1290 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 15, &pinfo, 13, NULL,
1292 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
1293 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1294 ASSERT_EQ_POINTER(NULL,fd_head);
1297 /* now we add the terminal fragment of the first datagram */
1299 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1302 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1303 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.reassembled_table));
1304 ASSERT_NE_POINTER(NULL,fd_head);
1306 /* check the contents of the structure */
1307 ASSERT_EQ(3,fd_head->frame); /* max frame we have */
1308 ASSERT_EQ(0,fd_head->offset); /* unused */
1309 ASSERT_EQ(110,fd_head->len); /* the length of data we have */
1310 ASSERT_EQ(1,fd_head->datalen); /* seqno of the last fragment we have */
1311 ASSERT_EQ(3,fd_head->reassembled_in);
1312 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
1313 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
1314 ASSERT_NE_POINTER(NULL,fd_head->next);
1316 ASSERT_EQ(1,fd_head->next->frame);
1317 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
1318 ASSERT_EQ(50,fd_head->next->len); /* segment length */
1319 ASSERT_EQ(0,fd_head->next->flags);
1320 ASSERT_EQ_POINTER(NULL,fd_head->next->tvb_data);
1321 ASSERT_NE_POINTER(NULL,fd_head->next->next);
1323 ASSERT_EQ(3,fd_head->next->next->frame);
1324 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
1325 ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
1326 ASSERT_EQ(0,fd_head->next->next->flags);
1327 ASSERT_EQ_POINTER(NULL,fd_head->next->next->tvb_data);
1328 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next);
1330 /* test the actual reassembly */
1331 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
1332 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
1337 /* XXX remove this? fragment_add_seq does not have the special case for
1338 * fragments having truncated tvbs anymore! */
1339 /* This tests the case where some data is missing from one of the fragments.
1340 * It should prevent reassembly.
1343 test_missing_data_fragment_add_seq_next(void)
1345 fragment_head *fd_head;
1347 printf("Starting test test_missing_data_fragment_add_seq_next\n");
1349 /* attempt to add a fragment which is longer than the data available */
1351 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1354 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1355 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1356 ASSERT_NE_POINTER(NULL,fd_head);
1358 /* check the contents of the structure. Reassembly failed so everything
1359 * should be null (meaning, just use the original tvb) */
1360 ASSERT_EQ(0,fd_head->frame); /* unused */
1361 ASSERT_EQ(0,fd_head->offset); /* unused */
1362 ASSERT_EQ(0,fd_head->len); /* the length of data we have */
1363 ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
1364 ASSERT_EQ(0,fd_head->reassembled_in);
1365 ASSERT_EQ(FD_BLOCKSEQUENCE,fd_head->flags & 0x1ff);
1366 ASSERT_EQ_POINTER(NULL,fd_head->tvb_data);
1367 ASSERT_EQ_POINTER(NULL,fd_head->next);
1369 /* add another fragment (with all data present) */
1371 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1374 /* XXX: it's not clear that this is the right result; however it's what the
1377 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1378 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1379 ASSERT_EQ_POINTER(NULL,fd_head);
1382 /* check what happens when we revisit the packets */
1383 pinfo.fd->flags.visited = TRUE;
1386 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1389 /* We just look in the reassembled_table for this packet. It never got put
1390 * there, so this always returns null.
1392 * That's crazy, because it means that the subdissector will see the data
1393 * exactly once - on the first pass through the capture (well, assuming it
1394 * doesn't bother to check fd_head->reassembled_in); however, that's
1395 * what the code does...
1397 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1398 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1399 ASSERT_EQ_POINTER(NULL,fd_head);
1402 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
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_POINTER(NULL,fd_head);
1411 * we're going to do something similar now, but this time it is the second
1412 * fragment which has something missing.
1415 test_missing_data_fragment_add_seq_next_2(void)
1417 fragment_head *fd_head;
1419 printf("Starting test test_missing_data_fragment_add_seq_next_2\n");
1422 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 10, &pinfo, 24, NULL,
1425 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1426 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1427 ASSERT_EQ_POINTER(NULL,fd_head);
1430 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 24, NULL,
1433 /* XXX: again, i'm really dubious about this. Surely this should return all
1434 * the data we had, for a best-effort attempt at dissecting it?
1435 * And it ought to go into the reassembled table?
1437 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1438 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1439 ASSERT_EQ_POINTER(NULL,fd_head);
1441 /* check what happens when we revisit the packets */
1442 pinfo.fd->flags.visited = TRUE;
1445 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 10, &pinfo, 24, NULL,
1448 /* As before, this returns NULL because the fragment isn't in the
1449 * reassembled_table. At least this is a bit more consistent than before.
1451 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1452 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1453 ASSERT_EQ_POINTER(NULL,fd_head);
1456 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 24, NULL,
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_POINTER(NULL,fd_head);
1465 * This time, our datagram only has one segment, but it has data missing.
1468 test_missing_data_fragment_add_seq_next_3(void)
1470 fragment_head *fd_head;
1472 printf("Starting test test_missing_data_fragment_add_seq_next_3\n");
1475 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 30, NULL,
1478 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1479 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.reassembled_table));
1480 ASSERT_NE_POINTER(NULL,fd_head);
1482 /* check the contents of the structure. */
1483 ASSERT_EQ(0,fd_head->frame); /* max frame we have */
1484 ASSERT_EQ(0,fd_head->offset); /* unused */
1485 ASSERT_EQ(0,fd_head->len); /* the length of data we have */
1486 ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
1487 ASSERT_EQ(20,fd_head->reassembled_in);
1488 ASSERT_EQ(FD_BLOCKSEQUENCE|FD_DEFRAGMENTED,fd_head->flags);
1489 ASSERT_EQ_POINTER(NULL,fd_head->tvb_data);
1490 ASSERT_EQ_POINTER(NULL,fd_head->next);
1492 /* revisiting the packet ought to produce the same result. */
1493 pinfo.fd->flags.visited = TRUE;
1496 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 30, NULL,
1499 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1500 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.reassembled_table));
1501 ASSERT_NE_POINTER(NULL,fd_head);
1502 ASSERT_EQ(0,fd_head->frame); /* unused */
1503 ASSERT_EQ(0,fd_head->offset); /* unused */
1504 ASSERT_EQ(0,fd_head->len); /* the length of data we have */
1505 ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
1506 ASSERT_EQ(20,fd_head->reassembled_in);
1507 ASSERT_EQ(FD_BLOCKSEQUENCE|FD_DEFRAGMENTED,fd_head->flags);
1508 ASSERT_EQ_POINTER(NULL,fd_head->tvb_data);
1509 ASSERT_EQ_POINTER(NULL,fd_head->next);
1514 /**********************************************************************************
1518 *********************************************************************************/
1521 main(int argc _U_, char **argv _U_)
1524 static const guint8 src[] = {1,2,3,4}, dst[] = {5,6,7,8};
1526 static void (*tests[])(void) = {
1527 test_simple_fragment_add_seq, /* frag table only */
1528 test_fragment_add_seq_partial_reassembly,
1529 test_fragment_add_seq_duplicate_first,
1530 test_fragment_add_seq_duplicate_middle,
1531 test_fragment_add_seq_duplicate_last,
1532 test_fragment_add_seq_duplicate_conflict,
1533 test_fragment_add_seq_check, /* frag + reassemble */
1534 test_fragment_add_seq_check_1,
1535 test_fragment_add_seq_802_11_0,
1536 test_fragment_add_seq_802_11_1,
1537 test_simple_fragment_add_seq_next,
1539 test_missing_data_fragment_add_seq_next,
1540 test_missing_data_fragment_add_seq_next_2,
1541 test_missing_data_fragment_add_seq_next_3,
1544 test_fragment_add_seq_check_multiple
1548 /* a tvbuff for testing with */
1549 data = (char *)g_malloc(DATA_LEN);
1550 /* make sure it's full of stuff */
1551 for(i=0; i<DATA_LEN; i++) {
1554 tvb = tvb_new_real_data(data, DATA_LEN, DATA_LEN*2);
1556 /* other test stuff */
1558 fd.flags.visited = 0;
1559 set_address(&pinfo.src,AT_IPv4,4,src);
1560 set_address(&pinfo.dst,AT_IPv4,4,dst);
1562 /*************************************************************************/
1563 for(i=0; i < sizeof(tests)/sizeof(tests[0]); i++ ) {
1564 /* re-init the fragment tables */
1565 reassembly_table_init(&test_reassembly_table,
1566 &addresses_reassembly_table_functions);
1567 ASSERT(test_reassembly_table.fragment_table != NULL);
1568 ASSERT(test_reassembly_table.reassembled_table != NULL);
1570 pinfo.fd->flags.visited = FALSE;
1574 /* Free memory used by the tables */
1575 reassembly_table_destroy(&test_reassembly_table);
1583 printf(failure?"FAILURE\n":"SUCCESS\n");
1588 * Editor modelines - http://www.wireshark.org/tools/modelines.html
1593 * indent-tabs-mode: nil
1596 * vi: set shiftwidth=4 tabstop=8 expandtab:
1597 * :indentSize=4:tabSize=8:noTabs=true: