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 * WIRESHARK_DEBUG_EP_NO_CHUNKS=1 \
20 * WIRESHARK_DEBUG_SE_NO_CHUNKS=1 \
21 * WIRESHARK_DEBUG_SE_USE_CANARY=1 \
22 * WIRESHARK_EP_VERIFY_POINTERS=1 \
23 * WIRESHARK_SE_VERIFY_POINTERS=1 \
24 * valgrind --leak-check=full --show-reachable=yes ./reassemble_test
26 * 2. Debug functions have been added which will print information
27 * about the fd-chains associated with the fragment_table and the
29 * #define debug to enable the code.
33 * Copyright (c) 2007 MX Telecom Ltd. <richardv@mxtelecom.com>
35 * Wireshark - Network traffic analyzer
36 * By Gerald Combs <gerald@wireshark.org>
39 * This program is free software; you can redistribute it and/or
40 * modify it under the terms of the GNU General Public License
41 * as published by the Free Software Foundation; either version 2
42 * of the License, or (at your option) any later version.
44 * This program is distributed in the hope that it will be useful,
45 * but WITHOUT ANY WARRANTY; without even the implied warranty of
46 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
47 * GNU General Public License for more details.
49 * You should have received a copy of the GNU General Public License
50 * along with this program; if not, write to the Free Software
51 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
63 #include <epan/emem.h>
64 #include <epan/packet.h>
65 #include <epan/packet_info.h>
66 #include <epan/proto.h>
67 #include <epan/tvbuff.h>
68 #include <epan/reassemble.h>
70 #define ASSERT(b) do_test((b),"Assertion failed at line %i: %s\n", __LINE__, #b)
71 #define ASSERT_EQ(exp,act) do_test((exp)==(act),"Assertion failed at line %i: %s==%s (%i==%i)\n", __LINE__, #exp, #act, exp, act)
72 #define ASSERT_NE(exp,act) do_test((exp)!=(act),"Assertion failed at line %i: %s!=%s (%i!=%i)\n", __LINE__, #exp, #act, exp, act)
74 static int failure
= 0;
77 do_test(gboolean condition
, const char *format
, ...)
85 vfprintf(stderr
, format
, ap
);
89 /* many of the tests assume this routine doesn't return on failure; if we
90 * do, it may provide more information, but may cause a segfault. Uncomment
91 * this line if you wish.
100 static packet_info pinfo
;
102 /* fragment_table maps from datagram ids to fragment_head
103 reassembled_table maps from <packet number,datagram id> to
105 static reassembly_table test_reassembly_table
;
108 /*************************************************
109 * Util fcns to display
110 * fragment_table & reassembled_table fd-chains
111 ************************************************/
113 static struct _fd_flags
{
117 {FD_DEFRAGMENTED
,"DF"},
118 {FD_DATALEN_SET
,"DS"},
119 {FD_SUBSET_TVB
, ,"ST"},
120 {FD_BLOCKSEQUENCE
,"BS"},
121 {FD_DATA_NOT_PRESENT
,"NP"},
122 {FD_PARTIAL_REASSEMBLY
,"PR"},
124 {FD_OVERLAPCONFLICT
,"OC"},
125 {FD_MULTIPLETAILS
,"MT"},
126 {FD_TOOLONGFRAGMENT
,"TL"},
128 #define N_FD_FLAGS (signed)(sizeof(fd_flags)/sizeof(struct _fd_flags))
131 print_fd(fragment_head
*fd
, gboolean is_head
) {
134 g_assert(fd
!= NULL
);
135 printf(" %08x %08x %3d %3d %3d", fd
, fd
->next
, fd
->frame
, fd
->offset
, fd
->len
);
137 printf(" %3d %3d", fd
->datalen
, fd
->reassembled_in
);
141 printf(" 0x%08x", fd
->data
);
142 for (i
=0; i
<N_FD_FLAGS
; i
++) {
143 printf(" %s", (fd
->flags
& fd_flags
[i
].flag
) ? fd_flags
[i
].flag_name
: " ");
149 print_fd_chain(fragment_head
*fd_head
) {
152 g_assert(fd_head
!= NULL
);
153 print_fd(fd_head
, TRUE
);
154 for (fdp
=fd_head
->next
; fdp
!= NULL
; fdp
=fdp
->next
) {
155 print_fd(fdp
, FALSE
);
160 print_fragment_table_chain(gpointer k
, gpointer v
, gpointer ud
) {
161 fragment_key
*key
= (fragment_key
*)k
;
162 fragment_head
*fd_head
= (fragment_head
*)v
;
163 printf(" --> FT: %3d 0x%08x 0x%08x\n", key
->id
, *(guint32
*)(key
->src
.data
), *(guint32
*)(key
->dst
.data
));
164 print_fd_chain(fd_head
);
168 print_fragment_table(void) {
169 printf("\n Fragment Table -------\n");
170 g_hash_table_foreach(fragment_table
, print_fragment_table_chain
, NULL
);
174 print_reassembled_table_chain(gpointer k
, gpointer v
, gpointer ud
) {
175 reassembled_key
*key
= (reassembled_key
*)k
;
176 fragment_head
*fd_head
= (fragment_head
*)v
;
177 printf(" --> RT: %5d %5d\n", key
->id
, key
->frame
);
178 print_fd_chain(fd_head
);
182 print_reassembled_table(void) {
183 printf("\n Reassembled Table ----\n");
184 g_hash_table_foreach(test_reassembly_table
.reassembled_table
, print_reassembled_table_chain
, NULL
);
189 print_fragment_table();
190 print_reassembled_table();
194 /**********************************************************************************
198 *********************************************************************************/
200 /* Simple test case for fragment_add_seq.
201 * Adds three fragments (out of order, with one for a different datagram in between),
202 * and checks that they are reassembled correctly.
204 /* visit id frame frag len more tvb_offset
212 test_simple_fragment_add_seq(void)
214 fragment_head
*fd_head
, *fdh0
;
216 printf("Starting test test_simple_fragment_add_seq\n");
219 fd_head
=fragment_add_seq(&test_reassembly_table
, tvb
, 10, &pinfo
, 12, NULL
,
222 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table
.fragment_table
));
223 ASSERT_EQ(NULL
,fd_head
);
225 /* adding the same fragment again should do nothing, even with different
227 pinfo
.fd
->flags
.visited
= 1;
228 fd_head
=fragment_add_seq(&test_reassembly_table
, tvb
, 5, &pinfo
, 12, NULL
,
230 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table
.fragment_table
));
231 ASSERT_EQ(NULL
,fd_head
);
233 /* start another pdu (just to confuse things) */
234 pinfo
.fd
->flags
.visited
= 0;
236 fd_head
=fragment_add_seq(&test_reassembly_table
, tvb
, 15, &pinfo
, 13, NULL
,
238 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table
.fragment_table
));
239 ASSERT_EQ(NULL
,fd_head
);
241 /* now we add the terminal fragment of the first datagram */
243 fd_head
=fragment_add_seq(&test_reassembly_table
, tvb
, 5, &pinfo
, 12, NULL
,
246 /* we haven't got all the fragments yet ... */
247 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table
.fragment_table
));
248 ASSERT_EQ(NULL
,fd_head
);
250 /* finally, add the missing fragment */
252 fd_head
=fragment_add_seq(&test_reassembly_table
, tvb
, 15, &pinfo
, 12, NULL
,
255 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table
.fragment_table
));
256 ASSERT_NE(NULL
,fd_head
);
258 /* check the contents of the structure */
259 ASSERT_EQ(0,fd_head
->frame
); /* unused */
260 ASSERT_EQ(0,fd_head
->offset
); /* unused */
261 ASSERT_EQ(170,fd_head
->len
); /* the length of data we have */
262 ASSERT_EQ(2,fd_head
->datalen
); /* seqno of the last fragment we have */
263 ASSERT_EQ(4,fd_head
->reassembled_in
);
264 ASSERT_EQ(FD_DEFRAGMENTED
|FD_BLOCKSEQUENCE
|FD_DATALEN_SET
,fd_head
->flags
);
265 ASSERT_NE(NULL
,fd_head
->tvb_data
);
266 ASSERT_NE(NULL
,fd_head
->next
);
268 ASSERT_EQ(1,fd_head
->next
->frame
);
269 ASSERT_EQ(0,fd_head
->next
->offset
); /* seqno */
270 ASSERT_EQ(50,fd_head
->next
->len
); /* segment length */
271 ASSERT_EQ(0,fd_head
->next
->flags
);
272 ASSERT_EQ(NULL
,fd_head
->next
->tvb_data
);
273 ASSERT_NE(NULL
,fd_head
->next
->next
);
275 ASSERT_EQ(4,fd_head
->next
->next
->frame
);
276 ASSERT_EQ(1,fd_head
->next
->next
->offset
); /* seqno */
277 ASSERT_EQ(60,fd_head
->next
->next
->len
); /* segment length */
278 ASSERT_EQ(0,fd_head
->next
->next
->flags
);
279 ASSERT_EQ(NULL
,fd_head
->next
->next
->tvb_data
);
280 ASSERT_NE(NULL
,fd_head
->next
->next
->next
);
282 ASSERT_EQ(3,fd_head
->next
->next
->next
->frame
);
283 ASSERT_EQ(2,fd_head
->next
->next
->next
->offset
); /* seqno */
284 ASSERT_EQ(60,fd_head
->next
->next
->next
->len
); /* segment length */
285 ASSERT_EQ(0,fd_head
->next
->next
->next
->flags
);
286 ASSERT_EQ(NULL
,fd_head
->next
->next
->next
->tvb_data
);
287 ASSERT_EQ(NULL
,fd_head
->next
->next
->next
->next
);
289 /* test the actual reassembly */
290 ASSERT(!tvb_memeql(fd_head
->tvb_data
,0,data
+10,50));
291 ASSERT(!tvb_memeql(fd_head
->tvb_data
,50,data
+15,60));
292 ASSERT(!tvb_memeql(fd_head
->tvb_data
,110,data
+5,60));
295 print_fragment_table();
298 /* what happens if we revisit the packets now? */
300 pinfo
.fd
->flags
.visited
= 1;
302 fd_head
=fragment_add_seq(&test_reassembly_table
, tvb
, 10, &pinfo
, 12, NULL
,
305 * this api relies on the caller to check fd_head -> reassembled_in
307 * Redoing all the tests seems like overkill - just check the pointer
309 ASSERT_EQ(fdh0
,fd_head
);
312 fd_head
=fragment_add_seq(&test_reassembly_table
, tvb
, 5, &pinfo
, 12, NULL
,
314 ASSERT_EQ(fdh0
,fd_head
);
317 fd_head
=fragment_add_seq(&test_reassembly_table
, tvb
, 15, &pinfo
, 12, NULL
,
319 ASSERT_EQ(fdh0
,fd_head
);
322 print_fragment_table();
326 /* XXX ought to have some tests for overlapping fragments */
328 /* This tests the functionality of fragment_set_partial_reassembly for
329 * FD_BLOCKSEQUENCE reassembly.
331 * We add a sequence of fragments thus:
332 * seqno frame offset len (initial) more_frags
333 * ----- ----- ------ --- --------------------
336 * 1 3 0 40 true (a duplicate fragment)
341 test_fragment_add_seq_partial_reassembly(void)
343 fragment_head
*fd_head
;
346 printf("Starting test test_fragment_add_seq_partial_reassembly\n");
348 /* generally it's probably fair to assume that we will be called with
352 fd_head
=fragment_add_seq(&test_reassembly_table
, tvb
, 10, &pinfo
, 12, NULL
,
355 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table
.fragment_table
));
356 ASSERT_NE(NULL
,fd_head
);
358 /* check the contents of the structure */
359 ASSERT_EQ(0,fd_head
->frame
); /* unused */
360 ASSERT_EQ(0,fd_head
->offset
); /* unused */
361 ASSERT_EQ(50,fd_head
->len
); /* the length of data we have */
362 ASSERT_EQ(0,fd_head
->datalen
); /* seqno of the last fragment we have */
363 ASSERT_EQ(1,fd_head
->reassembled_in
);
364 ASSERT_EQ(FD_DEFRAGMENTED
|FD_BLOCKSEQUENCE
|FD_DATALEN_SET
,fd_head
->flags
);
365 ASSERT_NE(NULL
,fd_head
->tvb_data
);
366 ASSERT_NE(NULL
,fd_head
->next
);
368 ASSERT_EQ(1,fd_head
->next
->frame
);
369 ASSERT_EQ(0,fd_head
->next
->offset
); /* seqno */
370 ASSERT_EQ(50,fd_head
->next
->len
); /* segment length */
371 ASSERT_EQ(0,fd_head
->next
->flags
);
372 ASSERT_EQ(NULL
,fd_head
->next
->tvb_data
);
373 ASSERT_EQ(NULL
,fd_head
->next
->next
);
375 /* test the actual reassembly */
376 ASSERT(!tvb_memeql(fd_head
->tvb_data
,0,data
+10,50));
378 /* now we announce that the reassembly wasn't complete after all. */
379 fragment_set_partial_reassembly(&test_reassembly_table
, &pinfo
, 12, NULL
);
381 /* and add another segment. To mix things up slightly (and so that we can
382 * check on the state of things), we're going to set the more_frags flag
386 fd_head
=fragment_add_seq(&test_reassembly_table
, tvb
, 0, &pinfo
, 12, NULL
,
389 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table
.fragment_table
));
390 ASSERT_EQ(NULL
,fd_head
);
392 fd_head
=fragment_get(&test_reassembly_table
, &pinfo
, 12, NULL
);
393 ASSERT_NE(NULL
,fd_head
);
395 /* check the contents of the structure */
396 ASSERT_EQ(0,fd_head
->frame
); /* unused */
397 ASSERT_EQ(0,fd_head
->offset
); /* unused */
398 /* ASSERT_EQ(50,fd_head->len); the length of data we have */
399 ASSERT_EQ(0,fd_head
->datalen
); /* seqno of the last fragment we have */
400 ASSERT_EQ(0,fd_head
->reassembled_in
);
401 ASSERT_EQ(FD_BLOCKSEQUENCE
,fd_head
->flags
);
402 ASSERT_NE(NULL
,fd_head
->tvb_data
);
403 ASSERT_NE(NULL
,fd_head
->next
);
406 ASSERT_EQ(1,fd
->frame
);
407 ASSERT_EQ(0,fd
->offset
); /* seqno */
408 ASSERT_EQ(50,fd
->len
); /* segment length */
409 ASSERT_EQ(FD_SUBSET_TVB
,fd
->flags
);
410 ASSERT_EQ(tvb_get_ptr(fd_head
->tvb_data
,0,0),tvb_get_ptr(fd
->tvb_data
,0,0));
411 ASSERT_NE(NULL
,fd
->next
);
414 ASSERT_EQ(2,fd
->frame
);
415 ASSERT_EQ(1,fd
->offset
); /* seqno */
416 ASSERT_EQ(40,fd
->len
); /* segment length */
417 ASSERT_EQ(0,fd
->flags
);
418 ASSERT_NE(NULL
,fd
->tvb_data
);
419 ASSERT_EQ(NULL
,fd
->next
);
421 /* Another copy of the second segment.
424 fd_head
=fragment_add_seq(&test_reassembly_table
, tvb
, 0, &pinfo
, 12, NULL
,
427 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table
.fragment_table
));
428 ASSERT_EQ(NULL
,fd_head
);
429 fd_head
=fragment_get(&test_reassembly_table
, &pinfo
, 12, NULL
);
430 ASSERT_NE(NULL
,fd_head
);
431 ASSERT_EQ(0,fd_head
->frame
); /* unused */
432 ASSERT_EQ(0,fd_head
->offset
); /* unused */
433 /* ASSERT_EQ(50,fd_head->len); the length of data we have */
434 ASSERT_EQ(0,fd_head
->datalen
); /* seqno of the last fragment we have */
435 ASSERT_EQ(0,fd_head
->reassembled_in
);
436 ASSERT_EQ(FD_BLOCKSEQUENCE
,fd_head
->flags
);
437 ASSERT_NE(NULL
,fd_head
->tvb_data
);
438 ASSERT_NE(NULL
,fd_head
->next
);
441 ASSERT_EQ(1,fd
->frame
);
442 ASSERT_EQ(0,fd
->offset
); /* seqno */
443 ASSERT_EQ(50,fd
->len
); /* segment length */
444 ASSERT_EQ(FD_SUBSET_TVB
,fd
->flags
);
445 ASSERT_EQ(tvb_get_ptr(fd_head
->tvb_data
,0,0),tvb_get_ptr(fd
->tvb_data
,0,0));
446 ASSERT_NE(NULL
,fd
->next
);
449 ASSERT_EQ(2,fd
->frame
);
450 ASSERT_EQ(1,fd
->offset
); /* seqno */
451 ASSERT_EQ(40,fd
->len
); /* segment length */
452 ASSERT_EQ(0,fd
->flags
);
453 ASSERT_NE(NULL
,fd
->tvb_data
);
454 ASSERT_NE(NULL
,fd
->next
);
457 ASSERT_EQ(3,fd
->frame
);
458 ASSERT_EQ(1,fd
->offset
); /* seqno */
459 ASSERT_EQ(40,fd
->len
); /* segment length */
460 ASSERT_EQ(0,fd
->flags
);
461 ASSERT_NE(NULL
,fd
->tvb_data
);
462 ASSERT_EQ(NULL
,fd
->next
);
466 /* have another go at wrapping things up */
468 fd_head
=fragment_add_seq(&test_reassembly_table
, tvb
, 20, &pinfo
, 12, NULL
,
471 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table
.fragment_table
));
472 ASSERT_NE(NULL
,fd_head
);
474 /* check the contents of the structure */
475 ASSERT_EQ(0,fd_head
->frame
); /* unused */
476 ASSERT_EQ(0,fd_head
->offset
); /* unused */
477 ASSERT_EQ(190,fd_head
->len
); /* the length of data we have */
478 ASSERT_EQ(2,fd_head
->datalen
); /* seqno of the last fragment we have */
479 ASSERT_EQ(4,fd_head
->reassembled_in
);
480 ASSERT_EQ(FD_DEFRAGMENTED
|FD_BLOCKSEQUENCE
|FD_DATALEN_SET
|FD_OVERLAP
,fd_head
->flags
);
481 ASSERT_NE(NULL
,fd_head
->tvb_data
);
482 ASSERT_NE(NULL
,fd_head
->next
);
485 ASSERT_EQ(1,fd
->frame
);
486 ASSERT_EQ(0,fd
->offset
); /* seqno */
487 ASSERT_EQ(50,fd
->len
); /* segment length */
488 ASSERT_EQ(0,fd
->flags
);
489 ASSERT_EQ(NULL
,fd
->tvb_data
);
490 ASSERT_NE(NULL
,fd
->next
);
493 ASSERT_EQ(2,fd
->frame
);
494 ASSERT_EQ(1,fd
->offset
); /* seqno */
495 ASSERT_EQ(40,fd
->len
); /* segment length */
496 ASSERT_EQ(0,fd
->flags
);
497 ASSERT_EQ(NULL
,fd
->tvb_data
);
498 ASSERT_NE(NULL
,fd
->next
);
501 ASSERT_EQ(3,fd
->frame
);
502 ASSERT_EQ(1,fd
->offset
); /* seqno */
503 ASSERT_EQ(40,fd
->len
); /* segment length */
504 ASSERT_EQ(FD_OVERLAP
,fd
->flags
);
505 ASSERT_EQ(NULL
,fd
->tvb_data
);
506 ASSERT_NE(NULL
,fd
->next
);
509 ASSERT_EQ(4,fd
->frame
);
510 ASSERT_EQ(2,fd
->offset
); /* seqno */
511 ASSERT_EQ(100,fd
->len
); /* segment length */
512 ASSERT_EQ(0,fd
->flags
);
513 ASSERT_EQ(NULL
,fd
->tvb_data
);
514 ASSERT_EQ(NULL
,fd
->next
);
516 /* test the actual reassembly */
517 ASSERT(!tvb_memeql(fd_head
->tvb_data
,0,data
+10,50));
518 ASSERT(!tvb_memeql(fd_head
->tvb_data
,50,data
,40));
519 ASSERT(!tvb_memeql(fd_head
->tvb_data
,90,data
+20,100));
522 /* do it again (this time it is more complicated, with an overlap in the
525 fragment_set_partial_reassembly(&test_reassembly_table
, &pinfo
, 12, NULL
);
528 fd_head
=fragment_add_seq(&test_reassembly_table
, tvb
, 0, &pinfo
, 12, NULL
,
531 fd_head
=fragment_get(&test_reassembly_table
, &pinfo
, 12, NULL
);
532 ASSERT_NE(NULL
,fd_head
);
533 ASSERT_EQ(0,fd_head
->frame
); /* unused */
534 ASSERT_EQ(0,fd_head
->offset
); /* unused */
535 ASSERT_EQ(230,fd_head
->len
); /* the length of data we have */
536 ASSERT_EQ(3,fd_head
->datalen
); /* seqno of the last fragment we have */
537 ASSERT_EQ(5,fd_head
->reassembled_in
);
538 ASSERT_EQ(FD_DEFRAGMENTED
|FD_BLOCKSEQUENCE
|FD_DATALEN_SET
|FD_OVERLAP
,fd_head
->flags
);
539 ASSERT_NE(NULL
,fd_head
->tvb_data
);
540 ASSERT_NE(NULL
,fd_head
->next
);
543 ASSERT_EQ(1,fd
->frame
);
544 ASSERT_EQ(0,fd
->offset
); /* seqno */
545 ASSERT_EQ(50,fd
->len
); /* segment length */
546 ASSERT_EQ(0,fd
->flags
);
547 ASSERT_EQ(NULL
,fd
->tvb_data
);
548 ASSERT_NE(NULL
,fd
->next
);
551 ASSERT_EQ(2,fd
->frame
);
552 ASSERT_EQ(1,fd
->offset
); /* seqno */
553 ASSERT_EQ(40,fd
->len
); /* segment length */
554 ASSERT_EQ(0,fd
->flags
);
555 ASSERT_EQ(NULL
,fd
->tvb_data
);
556 ASSERT_NE(NULL
,fd
->next
);
559 ASSERT_EQ(3,fd
->frame
);
560 ASSERT_EQ(1,fd
->offset
); /* seqno */
561 ASSERT_EQ(40,fd
->len
); /* segment length */
562 ASSERT_EQ(FD_OVERLAP
,fd
->flags
);
563 ASSERT_EQ(NULL
,fd
->tvb_data
);
564 ASSERT_NE(NULL
,fd
->next
);
567 ASSERT_EQ(4,fd
->frame
);
568 ASSERT_EQ(2,fd
->offset
); /* seqno */
569 ASSERT_EQ(100,fd
->len
); /* segment length */
570 ASSERT_EQ(0,fd
->flags
);
571 ASSERT_EQ(NULL
,fd
->tvb_data
);
572 ASSERT_NE(NULL
,fd
->next
);
575 ASSERT_EQ(5,fd
->frame
);
576 ASSERT_EQ(3,fd
->offset
); /* seqno */
577 ASSERT_EQ(40,fd
->len
); /* segment length */
578 ASSERT_EQ(0,fd
->flags
);
579 ASSERT_EQ(NULL
,fd
->tvb_data
);
580 ASSERT_EQ(NULL
,fd
->next
);
582 /* test the actual reassembly */
583 ASSERT(!tvb_memeql(fd_head
->tvb_data
,0,data
+10,50));
584 ASSERT(!tvb_memeql(fd_head
->tvb_data
,50,data
,40));
585 ASSERT(!tvb_memeql(fd_head
->tvb_data
,90,data
+20,100));
586 ASSERT(!tvb_memeql(fd_head
->tvb_data
,190,data
,40));
589 /* Test case for fragment_add_seq with duplicated (e.g., retransmitted) data.
590 * Adds three fragments--adding the 1st one twice--
591 * and checks that they are reassembled correctly.
593 /* visit id frame frag len more tvb_offset
600 test_fragment_add_seq_duplicate_first(void)
602 fragment_head
*fd_head
;
604 printf("Starting test test_fragment_add_seq_duplicate_first\n");
607 fd_head
=fragment_add_seq(&test_reassembly_table
, tvb
, 10, &pinfo
, 12, NULL
,
610 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table
.fragment_table
));
611 ASSERT_EQ(NULL
,fd_head
);
613 /* Add the 2nd segment */
615 fd_head
=fragment_add_seq(&test_reassembly_table
, tvb
, 5, &pinfo
, 12, NULL
,
618 /* we haven't got all the fragments yet ... */
619 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table
.fragment_table
));
620 ASSERT_EQ(NULL
,fd_head
);
622 /* Add the last fragment */
624 fd_head
=fragment_add_seq(&test_reassembly_table
, tvb
, 5, &pinfo
, 12, NULL
,
627 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table
.fragment_table
));
628 ASSERT_NE(NULL
,fd_head
);
630 /* Add the first fragment again */
632 fd_head
=fragment_add_seq(&test_reassembly_table
, tvb
, 10, &pinfo
, 12, NULL
,
635 /* Reassembly should have still succeeded */
636 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table
.fragment_table
));
637 ASSERT_NE(NULL
,fd_head
);
639 /* check the contents of the structure */
640 ASSERT_EQ(0,fd_head
->frame
); /* unused */
641 ASSERT_EQ(0,fd_head
->offset
); /* unused */
642 ASSERT_EQ(150,fd_head
->len
); /* the length of data we have */
643 ASSERT_EQ(2,fd_head
->datalen
); /* seqno of the last fragment we have */
644 ASSERT_EQ(3,fd_head
->reassembled_in
);
645 ASSERT_EQ(FD_DEFRAGMENTED
|FD_BLOCKSEQUENCE
|FD_DATALEN_SET
|FD_OVERLAP
,fd_head
->flags
);
646 ASSERT_NE(NULL
,fd_head
->tvb_data
);
647 ASSERT_NE(NULL
,fd_head
->next
);
649 ASSERT_EQ(1,fd_head
->next
->frame
);
650 ASSERT_EQ(0,fd_head
->next
->offset
); /* seqno */
651 ASSERT_EQ(50,fd_head
->next
->len
); /* segment length */
652 ASSERT_EQ(0,fd_head
->next
->flags
);
653 ASSERT_EQ(NULL
,fd_head
->next
->tvb_data
);
654 ASSERT_NE(NULL
,fd_head
->next
->next
);
656 ASSERT_EQ(4,fd_head
->next
->next
->frame
);
657 ASSERT_EQ(0,fd_head
->next
->next
->offset
); /* seqno */
658 ASSERT_EQ(50,fd_head
->next
->next
->len
); /* segment length */
659 ASSERT_EQ(FD_OVERLAP
,fd_head
->next
->next
->flags
);
660 ASSERT_EQ(NULL
,fd_head
->next
->next
->tvb_data
);
661 ASSERT_NE(NULL
,fd_head
->next
->next
->next
);
663 ASSERT_EQ(2,fd_head
->next
->next
->next
->frame
);
664 ASSERT_EQ(1,fd_head
->next
->next
->next
->offset
); /* seqno */
665 ASSERT_EQ(60,fd_head
->next
->next
->next
->len
); /* segment length */
666 ASSERT_EQ(0,fd_head
->next
->next
->next
->flags
);
667 ASSERT_EQ(NULL
,fd_head
->next
->next
->next
->tvb_data
);
668 ASSERT_NE(NULL
,fd_head
->next
->next
->next
->next
);
670 ASSERT_EQ(3,fd_head
->next
->next
->next
->next
->frame
);
671 ASSERT_EQ(2,fd_head
->next
->next
->next
->next
->offset
); /* seqno */
672 ASSERT_EQ(40,fd_head
->next
->next
->next
->next
->len
); /* segment length */
673 ASSERT_EQ(0,fd_head
->next
->next
->next
->next
->flags
);
674 ASSERT_EQ(NULL
,fd_head
->next
->next
->next
->next
->tvb_data
);
675 ASSERT_EQ(NULL
,fd_head
->next
->next
->next
->next
->next
);
677 /* test the actual reassembly */
678 ASSERT(!tvb_memeql(fd_head
->tvb_data
,0,data
+10,50));
679 ASSERT(!tvb_memeql(fd_head
->tvb_data
,50,data
+5,60));
680 ASSERT(!tvb_memeql(fd_head
->tvb_data
,110,data
+5,40));
683 print_fragment_table();
688 /* Test case for fragment_add_seq with duplicated (e.g., retransmitted) data.
689 * Adds three fragments--adding the 2nd one twice--
690 * and checks that they are reassembled correctly.
692 /* visit id frame frag len more tvb_offset
699 test_fragment_add_seq_duplicate_middle(void)
701 fragment_head
*fd_head
;
703 printf("Starting test test_fragment_add_seq_duplicate_middle\n");
706 fd_head
=fragment_add_seq(&test_reassembly_table
, tvb
, 10, &pinfo
, 12, NULL
,
709 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table
.fragment_table
));
710 ASSERT_EQ(NULL
,fd_head
);
712 /* Add the 2nd segment */
714 fd_head
=fragment_add_seq(&test_reassembly_table
, tvb
, 5, &pinfo
, 12, NULL
,
717 /* we haven't got all the fragments yet ... */
718 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table
.fragment_table
));
719 ASSERT_EQ(NULL
,fd_head
);
721 /* Now, add the 2nd segment again (but in a different frame) */
723 fd_head
=fragment_add_seq(&test_reassembly_table
, tvb
, 5, &pinfo
, 12, NULL
,
726 /* This duplicate fragment should have been ignored */
727 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table
.fragment_table
));
728 ASSERT_EQ(NULL
,fd_head
);
730 /* finally, add the last fragment */
732 fd_head
=fragment_add_seq(&test_reassembly_table
, tvb
, 5, &pinfo
, 12, NULL
,
735 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table
.fragment_table
));
736 ASSERT_NE(NULL
,fd_head
);
738 /* check the contents of the structure */
739 ASSERT_EQ(0,fd_head
->frame
); /* unused */
740 ASSERT_EQ(0,fd_head
->offset
); /* unused */
741 ASSERT_EQ(150,fd_head
->len
); /* the length of data we have */
742 ASSERT_EQ(2,fd_head
->datalen
); /* seqno of the last fragment we have */
743 ASSERT_EQ(4,fd_head
->reassembled_in
);
744 ASSERT_EQ(FD_DEFRAGMENTED
|FD_BLOCKSEQUENCE
|FD_DATALEN_SET
|FD_OVERLAP
,fd_head
->flags
);
745 ASSERT_NE(NULL
,fd_head
->tvb_data
);
746 ASSERT_NE(NULL
,fd_head
->next
);
748 ASSERT_EQ(1,fd_head
->next
->frame
);
749 ASSERT_EQ(0,fd_head
->next
->offset
); /* seqno */
750 ASSERT_EQ(50,fd_head
->next
->len
); /* segment length */
751 ASSERT_EQ(0,fd_head
->next
->flags
);
752 ASSERT_EQ(NULL
,fd_head
->next
->tvb_data
);
753 ASSERT_NE(NULL
,fd_head
->next
->next
);
755 ASSERT_EQ(2,fd_head
->next
->next
->frame
);
756 ASSERT_EQ(1,fd_head
->next
->next
->offset
); /* seqno */
757 ASSERT_EQ(60,fd_head
->next
->next
->len
); /* segment length */
758 ASSERT_EQ(0,fd_head
->next
->next
->flags
);
759 ASSERT_EQ(NULL
,fd_head
->next
->next
->tvb_data
);
760 ASSERT_NE(NULL
,fd_head
->next
->next
->next
);
762 ASSERT_EQ(3,fd_head
->next
->next
->next
->frame
);
763 ASSERT_EQ(1,fd_head
->next
->next
->next
->offset
); /* seqno */
764 ASSERT_EQ(60,fd_head
->next
->next
->next
->len
); /* segment length */
765 ASSERT_EQ(FD_OVERLAP
,fd_head
->next
->next
->next
->flags
);
766 ASSERT_EQ(NULL
,fd_head
->next
->next
->next
->tvb_data
);
767 ASSERT_NE(NULL
,fd_head
->next
->next
->next
->next
);
769 ASSERT_EQ(4,fd_head
->next
->next
->next
->next
->frame
);
770 ASSERT_EQ(2,fd_head
->next
->next
->next
->next
->offset
); /* seqno */
771 ASSERT_EQ(40,fd_head
->next
->next
->next
->next
->len
); /* segment length */
772 ASSERT_EQ(0,fd_head
->next
->next
->next
->next
->flags
);
773 ASSERT_EQ(NULL
,fd_head
->next
->next
->next
->next
->tvb_data
);
774 ASSERT_EQ(NULL
,fd_head
->next
->next
->next
->next
->next
);
776 /* test the actual reassembly */
777 ASSERT(!tvb_memeql(fd_head
->tvb_data
,0,data
+10,50));
778 ASSERT(!tvb_memeql(fd_head
->tvb_data
,50,data
+5,60));
779 ASSERT(!tvb_memeql(fd_head
->tvb_data
,110,data
+5,40));
782 print_fragment_table();
786 /* Test case for fragment_add_seq with duplicated (e.g., retransmitted) data.
787 * Adds three fragments--adding the 3rd one twice--
788 * and checks that they are reassembled correctly.
790 /* visit id frame frag len more tvb_offset
797 test_fragment_add_seq_duplicate_last(void)
799 fragment_head
*fd_head
;
801 printf("Starting test test_fragment_add_seq_duplicate_last\n");
804 fd_head
=fragment_add_seq(&test_reassembly_table
, tvb
, 10, &pinfo
, 12, NULL
,
807 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table
.fragment_table
));
808 ASSERT_EQ(NULL
,fd_head
);
810 /* Add the 2nd segment */
812 fd_head
=fragment_add_seq(&test_reassembly_table
, tvb
, 5, &pinfo
, 12, NULL
,
815 /* we haven't got all the fragments yet ... */
816 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table
.fragment_table
));
817 ASSERT_EQ(NULL
,fd_head
);
819 /* Add the last fragment */
821 fd_head
=fragment_add_seq(&test_reassembly_table
, tvb
, 5, &pinfo
, 12, NULL
,
824 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table
.fragment_table
));
825 ASSERT_NE(NULL
,fd_head
);
827 /* Add the last fragment again */
829 fd_head
=fragment_add_seq(&test_reassembly_table
, tvb
, 5, &pinfo
, 12, NULL
,
832 /* Reassembly should have still succeeded */
833 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table
.fragment_table
));
834 ASSERT_NE(NULL
,fd_head
);
836 /* check the contents of the structure */
837 ASSERT_EQ(0,fd_head
->frame
); /* unused */
838 ASSERT_EQ(0,fd_head
->offset
); /* unused */
839 ASSERT_EQ(150,fd_head
->len
); /* the length of data we have */
840 ASSERT_EQ(2,fd_head
->datalen
); /* seqno of the last fragment we have */
841 ASSERT_EQ(3,fd_head
->reassembled_in
);
842 ASSERT_EQ(FD_DEFRAGMENTED
|FD_BLOCKSEQUENCE
|FD_DATALEN_SET
|FD_OVERLAP
,fd_head
->flags
);
843 ASSERT_NE(NULL
,fd_head
->tvb_data
);
844 ASSERT_NE(NULL
,fd_head
->next
);
846 ASSERT_EQ(1,fd_head
->next
->frame
);
847 ASSERT_EQ(0,fd_head
->next
->offset
); /* seqno */
848 ASSERT_EQ(50,fd_head
->next
->len
); /* segment length */
849 ASSERT_EQ(0,fd_head
->next
->flags
);
850 ASSERT_EQ(NULL
,fd_head
->next
->tvb_data
);
851 ASSERT_NE(NULL
,fd_head
->next
->next
);
853 ASSERT_EQ(2,fd_head
->next
->next
->frame
);
854 ASSERT_EQ(1,fd_head
->next
->next
->offset
); /* seqno */
855 ASSERT_EQ(60,fd_head
->next
->next
->len
); /* segment length */
856 ASSERT_EQ(0,fd_head
->next
->next
->flags
);
857 ASSERT_EQ(NULL
,fd_head
->next
->next
->tvb_data
);
858 ASSERT_NE(NULL
,fd_head
->next
->next
->next
);
860 ASSERT_EQ(3,fd_head
->next
->next
->next
->frame
);
861 ASSERT_EQ(2,fd_head
->next
->next
->next
->offset
); /* seqno */
862 ASSERT_EQ(40,fd_head
->next
->next
->next
->len
); /* segment length */
863 ASSERT_EQ(0,fd_head
->next
->next
->next
->flags
);
864 ASSERT_EQ(NULL
,fd_head
->next
->next
->next
->tvb_data
);
865 ASSERT_NE(NULL
,fd_head
->next
->next
->next
->next
);
867 ASSERT_EQ(4,fd_head
->next
->next
->next
->next
->frame
);
868 ASSERT_EQ(2,fd_head
->next
->next
->next
->next
->offset
); /* seqno */
869 ASSERT_EQ(40,fd_head
->next
->next
->next
->next
->len
); /* segment length */
870 ASSERT_EQ(FD_OVERLAP
,fd_head
->next
->next
->next
->next
->flags
);
871 ASSERT_EQ(NULL
,fd_head
->next
->next
->next
->next
->tvb_data
);
872 ASSERT_EQ(NULL
,fd_head
->next
->next
->next
->next
->next
);
874 /* test the actual reassembly */
875 ASSERT(!tvb_memeql(fd_head
->tvb_data
,0,data
+10,50));
876 ASSERT(!tvb_memeql(fd_head
->tvb_data
,50,data
+5,60));
877 ASSERT(!tvb_memeql(fd_head
->tvb_data
,110,data
+5,40));
880 print_fragment_table();
884 /* Test case for fragment_add_seq with duplicated (e.g., retransmitted) data
885 * where the retransmission "conflicts" with the original transmission
886 * (contents are different).
887 * Adds three fragments--adding the 2nd one twice--
888 * and checks that they are reassembled correctly.
890 /* visit id frame frag len more tvb_offset
897 test_fragment_add_seq_duplicate_conflict(void)
899 fragment_head
*fd_head
;
901 printf("Starting test test_fragment_add_seq_duplicate_conflict\n");
904 fd_head
=fragment_add_seq(&test_reassembly_table
, tvb
, 10, &pinfo
, 12, NULL
,
907 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table
.fragment_table
));
908 ASSERT_EQ(NULL
,fd_head
);
910 /* Add the 2nd segment */
912 fd_head
=fragment_add_seq(&test_reassembly_table
, tvb
, 5, &pinfo
, 12, NULL
,
915 /* we haven't got all the fragments yet ... */
916 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table
.fragment_table
));
917 ASSERT_EQ(NULL
,fd_head
);
919 /* Now, add the 2nd segment again (but in a different frame and with
923 fd_head
=fragment_add_seq(&test_reassembly_table
, tvb
, 15, &pinfo
, 12, NULL
,
926 /* This duplicate fragment should have been ignored */
927 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table
.fragment_table
));
928 ASSERT_EQ(NULL
,fd_head
);
930 /* finally, add the last fragment */
932 fd_head
=fragment_add_seq(&test_reassembly_table
, tvb
, 5, &pinfo
, 12, NULL
,
935 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table
.fragment_table
));
936 ASSERT_NE(NULL
,fd_head
);
938 /* check the contents of the structure */
939 ASSERT_EQ(0,fd_head
->frame
); /* unused */
940 ASSERT_EQ(0,fd_head
->offset
); /* unused */
941 ASSERT_EQ(150,fd_head
->len
); /* the length of data we have */
942 ASSERT_EQ(2,fd_head
->datalen
); /* seqno of the last fragment we have */
943 ASSERT_EQ(4,fd_head
->reassembled_in
);
944 ASSERT_EQ(FD_DEFRAGMENTED
|FD_BLOCKSEQUENCE
|FD_DATALEN_SET
|FD_OVERLAP
|FD_OVERLAPCONFLICT
,fd_head
->flags
);
945 ASSERT_NE(NULL
,fd_head
->tvb_data
);
946 ASSERT_NE(NULL
,fd_head
->next
);
948 ASSERT_EQ(1,fd_head
->next
->frame
);
949 ASSERT_EQ(0,fd_head
->next
->offset
); /* seqno */
950 ASSERT_EQ(50,fd_head
->next
->len
); /* segment length */
951 ASSERT_EQ(0,fd_head
->next
->flags
);
952 ASSERT_EQ(NULL
,fd_head
->next
->tvb_data
);
953 ASSERT_NE(NULL
,fd_head
->next
->next
);
955 ASSERT_EQ(2,fd_head
->next
->next
->frame
);
956 ASSERT_EQ(1,fd_head
->next
->next
->offset
); /* seqno */
957 ASSERT_EQ(60,fd_head
->next
->next
->len
); /* segment length */
958 ASSERT_EQ(0,fd_head
->next
->next
->flags
);
959 ASSERT_EQ(NULL
,fd_head
->next
->next
->tvb_data
);
960 ASSERT_NE(NULL
,fd_head
->next
->next
->next
);
962 ASSERT_EQ(3,fd_head
->next
->next
->next
->frame
);
963 ASSERT_EQ(1,fd_head
->next
->next
->next
->offset
); /* seqno */
964 ASSERT_EQ(60,fd_head
->next
->next
->next
->len
); /* segment length */
965 ASSERT_EQ(FD_OVERLAP
|FD_OVERLAPCONFLICT
,fd_head
->next
->next
->next
->flags
);
966 ASSERT_EQ(NULL
,fd_head
->next
->next
->next
->tvb_data
);
967 ASSERT_NE(NULL
,fd_head
->next
->next
->next
->next
);
969 ASSERT_EQ(4,fd_head
->next
->next
->next
->next
->frame
);
970 ASSERT_EQ(2,fd_head
->next
->next
->next
->next
->offset
); /* seqno */
971 ASSERT_EQ(40,fd_head
->next
->next
->next
->next
->len
); /* segment length */
972 ASSERT_EQ(0,fd_head
->next
->next
->next
->next
->flags
);
973 ASSERT_EQ(NULL
,fd_head
->next
->next
->next
->next
->tvb_data
);
974 ASSERT_EQ(NULL
,fd_head
->next
->next
->next
->next
->next
);
976 /* test the actual reassembly */
977 ASSERT(!tvb_memeql(fd_head
->tvb_data
,0,data
+10,50));
978 ASSERT(!tvb_memeql(fd_head
->tvb_data
,50,data
+5,60));
979 ASSERT(!tvb_memeql(fd_head
->tvb_data
,110,data
+5,40));
982 print_fragment_table();
986 /**********************************************************************************
988 * fragment_add_seq_check
990 *********************************************************************************/
993 /* This routine is used for both fragment_add_seq_802_11 and
994 * fragment_add_seq_check.
996 * Adds a couple of out-of-order fragments and checks their reassembly.
999 /* visit id frame frag len more tvb_offset
1008 test_fragment_add_seq_check_work(fragment_head
*(*fn
)(reassembly_table
*,
1009 tvbuff_t
*, const int, const packet_info
*,
1010 const guint32
, const void *, const guint32
,
1011 const guint32
, const gboolean
))
1013 fragment_head
*fd_head
;
1015 pinfo
.fd
-> num
= 1;
1016 fd_head
=fn(&test_reassembly_table
, tvb
, 10, &pinfo
, 12, NULL
,
1019 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table
.fragment_table
));
1020 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table
.reassembled_table
));
1021 ASSERT_EQ(NULL
,fd_head
);
1023 /* start another pdu (just to confuse things) */
1025 fd_head
=fn(&test_reassembly_table
, tvb
, 15, &pinfo
, 13, NULL
,
1027 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table
.fragment_table
));
1028 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table
.reassembled_table
));
1029 ASSERT_EQ(NULL
,fd_head
);
1031 /* add the terminal fragment of the first datagram */
1033 fd_head
=fn(&test_reassembly_table
, tvb
, 5, &pinfo
, 12, NULL
,
1036 /* we haven't got all the fragments yet ... */
1037 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table
.fragment_table
));
1038 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table
.reassembled_table
));
1039 ASSERT_EQ(NULL
,fd_head
);
1041 /* finally, add the missing fragment */
1043 fd_head
=fn(&test_reassembly_table
, tvb
, 15, &pinfo
, 12, NULL
,
1046 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table
.fragment_table
));
1047 ASSERT_EQ(3,g_hash_table_size(test_reassembly_table
.reassembled_table
));
1048 ASSERT_NE(NULL
,fd_head
);
1050 /* check the contents of the structure */
1051 ASSERT_EQ(0,fd_head
->frame
); /* unused */
1052 ASSERT_EQ(0,fd_head
->offset
); /* unused */
1053 ASSERT_EQ(170,fd_head
->len
); /* the length of data we have */
1054 ASSERT_EQ(2,fd_head
->datalen
); /* seqno of the last fragment we have */
1055 ASSERT_EQ(4,fd_head
->reassembled_in
);
1056 ASSERT_EQ(FD_DEFRAGMENTED
|FD_BLOCKSEQUENCE
|FD_DATALEN_SET
,fd_head
->flags
);
1057 ASSERT_NE(NULL
,fd_head
->tvb_data
);
1058 ASSERT_NE(NULL
,fd_head
->next
);
1060 ASSERT_EQ(1,fd_head
->next
->frame
);
1061 ASSERT_EQ(0,fd_head
->next
->offset
); /* seqno */
1062 ASSERT_EQ(50,fd_head
->next
->len
); /* segment length */
1063 ASSERT_EQ(0,fd_head
->next
->flags
);
1064 ASSERT_EQ(NULL
,fd_head
->next
->tvb_data
);
1065 ASSERT_NE(NULL
,fd_head
->next
->next
);
1067 ASSERT_EQ(4,fd_head
->next
->next
->frame
);
1068 ASSERT_EQ(1,fd_head
->next
->next
->offset
); /* seqno */
1069 ASSERT_EQ(60,fd_head
->next
->next
->len
); /* segment length */
1070 ASSERT_EQ(0,fd_head
->next
->next
->flags
);
1071 ASSERT_EQ(NULL
,fd_head
->next
->next
->tvb_data
);
1072 ASSERT_NE(NULL
,fd_head
->next
->next
->next
);
1074 ASSERT_EQ(3,fd_head
->next
->next
->next
->frame
);
1075 ASSERT_EQ(2,fd_head
->next
->next
->next
->offset
); /* seqno */
1076 ASSERT_EQ(60,fd_head
->next
->next
->next
->len
); /* segment length */
1077 ASSERT_EQ(0,fd_head
->next
->next
->next
->flags
);
1078 ASSERT_EQ(NULL
,fd_head
->next
->next
->next
->tvb_data
);
1079 ASSERT_EQ(NULL
,fd_head
->next
->next
->next
->next
);
1081 /* test the actual reassembly */
1082 ASSERT(!tvb_memeql(fd_head
->tvb_data
,0,data
+10,50));
1083 ASSERT(!tvb_memeql(fd_head
->tvb_data
,50,data
+15,60));
1084 ASSERT(!tvb_memeql(fd_head
->tvb_data
,110,data
+5,60));
1091 /* Simple test case for fragment_add_seq_check
1094 test_fragment_add_seq_check(void)
1096 printf("Starting test test_fragment_add_seq_check\n");
1098 test_fragment_add_seq_check_work(fragment_add_seq_check
);
1102 /* This tests the case that the 802.11 hack does something different for: when
1103 * the terminal segment in a fragmented datagram arrives first.
1106 test_fragment_add_seq_check_1(void)
1108 fragment_head
*fd_head
;
1110 printf("Starting test test_fragment_add_seq_check_1\n");
1113 fd_head
=fragment_add_seq_check(&test_reassembly_table
, tvb
, 10, &pinfo
, 12, NULL
,
1116 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table
.fragment_table
));
1117 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table
.reassembled_table
));
1118 ASSERT_EQ(NULL
,fd_head
);
1120 /* Now add the missing segment */
1122 fd_head
=fragment_add_seq_check(&test_reassembly_table
, tvb
, 5, &pinfo
, 12, NULL
,
1125 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table
.fragment_table
));
1126 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table
.reassembled_table
));
1127 ASSERT_NE(NULL
,fd_head
);
1129 /* check the contents of the structure */
1130 ASSERT_EQ(0,fd_head
->frame
); /* unused */
1131 ASSERT_EQ(0,fd_head
->offset
); /* unused */
1132 ASSERT_EQ(110,fd_head
->len
); /* the length of data we have */
1133 ASSERT_EQ(1,fd_head
->datalen
); /* seqno of the last fragment we have */
1134 ASSERT_EQ(2,fd_head
->reassembled_in
);
1135 ASSERT_EQ(FD_DEFRAGMENTED
|FD_BLOCKSEQUENCE
|FD_DATALEN_SET
,fd_head
->flags
);
1136 ASSERT_NE(NULL
,fd_head
->tvb_data
);
1137 ASSERT_NE(NULL
,fd_head
->next
);
1139 ASSERT_EQ(2,fd_head
->next
->frame
);
1140 ASSERT_EQ(0,fd_head
->next
->offset
); /* seqno */
1141 ASSERT_EQ(60,fd_head
->next
->len
); /* segment length */
1142 ASSERT_EQ(0,fd_head
->next
->flags
);
1143 ASSERT_EQ(NULL
,fd_head
->next
->tvb_data
);
1144 ASSERT_NE(NULL
,fd_head
->next
->next
);
1146 ASSERT_EQ(1,fd_head
->next
->next
->frame
);
1147 ASSERT_EQ(1,fd_head
->next
->next
->offset
); /* seqno */
1148 ASSERT_EQ(50,fd_head
->next
->next
->len
); /* segment length */
1149 ASSERT_EQ(0,fd_head
->next
->next
->flags
);
1150 ASSERT_EQ(NULL
,fd_head
->next
->next
->tvb_data
);
1151 ASSERT_EQ(NULL
,fd_head
->next
->next
->next
);
1153 /* test the actual reassembly */
1154 ASSERT(!tvb_memeql(fd_head
->tvb_data
,0,data
+5,60));
1155 ASSERT(!tvb_memeql(fd_head
->tvb_data
,60,data
+10,50));
1158 /**********************************************************************************
1160 * fragment_add_seq_802_11
1162 *********************************************************************************/
1164 /* Tests the 802.11 hack.
1167 test_fragment_add_seq_802_11_0(void)
1169 fragment_head
*fd_head
;
1171 printf("Starting test test_fragment_add_seq_802_11_0\n");
1173 /* the 802.11 hack is that some non-fragmented datagrams have non-zero
1174 * fragment_number; test for this. */
1177 fd_head
=fragment_add_seq_802_11(&test_reassembly_table
, tvb
, 10, &pinfo
, 12, NULL
,
1180 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table
.fragment_table
));
1181 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table
.reassembled_table
));
1182 ASSERT_NE(NULL
,fd_head
);
1184 /* check the contents of the structure */
1185 ASSERT_EQ(0,fd_head
->frame
); /* unused */
1186 ASSERT_EQ(0,fd_head
->offset
); /* unused */
1187 ASSERT_EQ(0,fd_head
->len
); /* unused */
1188 ASSERT_EQ(0,fd_head
->datalen
); /* unused */
1189 ASSERT_EQ(1,fd_head
->reassembled_in
);
1190 ASSERT_EQ(FD_DEFRAGMENTED
|FD_BLOCKSEQUENCE
,fd_head
->flags
);
1191 ASSERT_EQ(NULL
,fd_head
->tvb_data
);
1192 ASSERT_EQ(NULL
,fd_head
->next
);
1195 /* Reuse the fragment_add_seq_check testcases */
1196 static void test_fragment_add_seq_802_11_1(void)
1198 printf("Starting test test_fragment_add_seq_802_11_1\n");
1199 test_fragment_add_seq_check_work(fragment_add_seq_802_11
);
1202 /**********************************************************************************
1204 * fragment_add_seq_check_multiple
1206 *********************************************************************************/
1208 /* Test 2 partial frags from 2 diff datagrams in the same frame */
1210 datagram #1: frame 1 + first part of frame 2
1211 datagram #1: last part of frame 2 + frame 3
1213 Is this a valid scenario ?
1215 The result of calling fragment_add_seq_check(&test_reassembly_table, ) for these
1216 fragments is a reassembled_table with:
1217 id, frame 1 => first_datagram; ["reassembled in" frame 2]
1218 id, frame 2 => second_datagram; ["reassembled in" frame 3]
1219 id, frame 3 => second_datagram;
1221 Note that the id, frame 2 => first datagram was overwritten
1222 by the entry for the second datagram.
1223 Is this OK ? IE: When dissected/displayed
1224 will the reassembled datagram 1 appear with frame 2 ??
1227 /* visit id frame frag len more tvb_offset
1235 Is this a valid scenario ?
1236 Is this OK ? IE: When dissected/displayed:
1237 Will the reassembled datagram 1 appear with frame 2 ??
1241 test_fragment_add_seq_check_multiple(void) {
1242 fragment_head
*fd_head
;
1244 pinfo
.fd
-> num
= 1;
1245 fd_head
=fragment_add_seq_check(&test_reassembly_table
, tvb
, 10, &pinfo
, 12, NULL
,
1248 /* add the terminal fragment of the first datagram */
1250 fd_head
=fragment_add_seq_check(&test_reassembly_table
, tvb
, 5, &pinfo
, 12, NULL
,
1255 /* Now: start a second datagram with the first fragment in frame #2 */
1257 fd_head
=fragment_add_seq_check(&test_reassembly_table
, tvb
, 25, &pinfo
, 12, NULL
,
1260 /* add the terminal fragment of the second datagram */
1262 fd_head
=fragment_add_seq_check(&test_reassembly_table
, tvb
, 0, &pinfo
, 12, NULL
,
1269 /**********************************************************************************
1271 * fragment_add_seq_next
1273 *********************************************************************************/
1275 /* Simple test case for fragment_add_seq_next.
1276 * Adds a couple of fragments (with one for a different datagram in between),
1277 * and checks that they are reassembled correctly.
1280 test_simple_fragment_add_seq_next(void)
1282 fragment_head
*fd_head
;
1284 printf("Starting test test_simple_fragment_add_seq_next\n");
1287 fd_head
= fragment_add_seq_next(&test_reassembly_table
, tvb
, 10, &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 /* adding the same fragment again should do nothing, even with different
1296 pinfo
.fd
->flags
.visited
= 1;
1297 fd_head
=fragment_add_seq_next(&test_reassembly_table
, tvb
, 5, &pinfo
, 12, NULL
,
1299 ASSERT_EQ(1,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
);
1303 /* start another pdu (just to confuse things) */
1304 pinfo
.fd
->flags
.visited
= 0;
1306 fd_head
=fragment_add_seq_next(&test_reassembly_table
, tvb
, 15, &pinfo
, 13, NULL
,
1308 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table
.fragment_table
));
1309 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table
.reassembled_table
));
1310 ASSERT_EQ(NULL
,fd_head
);
1313 /* now we add the terminal fragment of the first datagram */
1315 fd_head
=fragment_add_seq_next(&test_reassembly_table
, tvb
, 5, &pinfo
, 12, NULL
,
1318 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table
.fragment_table
));
1319 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table
.reassembled_table
));
1320 ASSERT_NE(NULL
,fd_head
);
1322 /* check the contents of the structure */
1323 ASSERT_EQ(0,fd_head
->frame
); /* unused */
1324 ASSERT_EQ(0,fd_head
->offset
); /* unused */
1325 ASSERT_EQ(110,fd_head
->len
); /* the length of data we have */
1326 ASSERT_EQ(1,fd_head
->datalen
); /* seqno of the last fragment we have */
1327 ASSERT_EQ(3,fd_head
->reassembled_in
);
1328 ASSERT_EQ(FD_DEFRAGMENTED
|FD_BLOCKSEQUENCE
|FD_DATALEN_SET
,fd_head
->flags
);
1329 ASSERT_NE(NULL
,fd_head
->tvb_data
);
1330 ASSERT_NE(NULL
,fd_head
->next
);
1332 ASSERT_EQ(1,fd_head
->next
->frame
);
1333 ASSERT_EQ(0,fd_head
->next
->offset
); /* seqno */
1334 ASSERT_EQ(50,fd_head
->next
->len
); /* segment length */
1335 ASSERT_EQ(0,fd_head
->next
->flags
);
1336 ASSERT_EQ(NULL
,fd_head
->next
->tvb_data
);
1337 ASSERT_NE(NULL
,fd_head
->next
->next
);
1339 ASSERT_EQ(3,fd_head
->next
->next
->frame
);
1340 ASSERT_EQ(1,fd_head
->next
->next
->offset
); /* seqno */
1341 ASSERT_EQ(60,fd_head
->next
->next
->len
); /* segment length */
1342 ASSERT_EQ(0,fd_head
->next
->next
->flags
);
1343 ASSERT_EQ(NULL
,fd_head
->next
->next
->tvb_data
);
1344 ASSERT_EQ(NULL
,fd_head
->next
->next
->next
);
1346 /* test the actual reassembly */
1347 ASSERT(!tvb_memeql(fd_head
->tvb_data
,0,data
+10,50));
1348 ASSERT(!tvb_memeql(fd_head
->tvb_data
,50,data
+5,60));
1352 /* This tests the case where some data is missing from one of the fragments.
1353 * It should prevent reassembly.
1356 test_missing_data_fragment_add_seq_next(void)
1358 fragment_head
*fd_head
;
1360 printf("Starting test test_missing_data_fragment_add_seq_next\n");
1362 /* attempt to add a fragment which is longer than the data available */
1364 fd_head
=fragment_add_seq_next(&test_reassembly_table
, tvb
, 10, &pinfo
, 12, NULL
,
1367 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table
.fragment_table
));
1368 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table
.reassembled_table
));
1369 ASSERT_NE(NULL
,fd_head
);
1371 /* check the contents of the structure. Reassembly failed so everything
1372 * should be null (meaning, just use the original tvb) */
1373 ASSERT_EQ(0,fd_head
->frame
); /* unused */
1374 ASSERT_EQ(0,fd_head
->offset
); /* unused */
1375 ASSERT_EQ(0,fd_head
->len
); /* the length of data we have */
1376 ASSERT_EQ(0,fd_head
->datalen
); /* seqno of the last fragment we have */
1377 ASSERT_EQ(0,fd_head
->reassembled_in
);
1378 ASSERT_EQ(FD_BLOCKSEQUENCE
,fd_head
->flags
& 0x1ff);
1379 ASSERT_EQ(NULL
,fd_head
->tvb_data
);
1380 ASSERT_EQ(NULL
,fd_head
->next
);
1382 /* add another fragment (with all data present) */
1384 fd_head
=fragment_add_seq_next(&test_reassembly_table
, tvb
, 5, &pinfo
, 12, NULL
,
1387 /* XXX: it's not clear that this is the right result; however it's what the
1390 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table
.fragment_table
));
1391 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table
.reassembled_table
));
1392 ASSERT_EQ(NULL
,fd_head
);
1395 /* check what happens when we revisit the packets */
1396 pinfo
.fd
->flags
.visited
= TRUE
;
1399 fd_head
=fragment_add_seq_next(&test_reassembly_table
, tvb
, 10, &pinfo
, 12, NULL
,
1402 /* We just look in the reassembled_table for this packet. It never got put
1403 * there, so this always returns null.
1405 * That's crazy, because it means that the subdissector will see the data
1406 * exactly once - on the first pass through the capture (well, assuming it
1407 * doesn't bother to check fd_head->reassembled_in); however, that's
1408 * what the code does...
1410 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table
.fragment_table
));
1411 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table
.reassembled_table
));
1412 ASSERT_EQ(NULL
,fd_head
);
1415 fd_head
=fragment_add_seq_next(&test_reassembly_table
, tvb
, 5, &pinfo
, 12, NULL
,
1417 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table
.fragment_table
));
1418 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table
.reassembled_table
));
1419 ASSERT_EQ(NULL
,fd_head
);
1424 * we're going to do something similar now, but this time it is the second
1425 * fragment which has something missing.
1428 test_missing_data_fragment_add_seq_next_2(void)
1430 fragment_head
*fd_head
;
1432 printf("Starting test test_missing_data_fragment_add_seq_next_2\n");
1435 fd_head
=fragment_add_seq_next(&test_reassembly_table
, tvb
, 10, &pinfo
, 24, NULL
,
1438 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table
.fragment_table
));
1439 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table
.reassembled_table
));
1440 ASSERT_EQ(NULL
,fd_head
);
1443 fd_head
=fragment_add_seq_next(&test_reassembly_table
, tvb
, 5, &pinfo
, 24, NULL
,
1446 /* XXX: again, i'm really dubious about this. Surely this should return all
1447 * the data we had, for a best-effort attempt at dissecting it?
1448 * And it ought to go into the reassembled table?
1450 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table
.fragment_table
));
1451 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table
.reassembled_table
));
1452 ASSERT_EQ(NULL
,fd_head
);
1454 /* check what happens when we revisit the packets */
1455 pinfo
.fd
->flags
.visited
= TRUE
;
1458 fd_head
=fragment_add_seq_next(&test_reassembly_table
, tvb
, 10, &pinfo
, 24, NULL
,
1461 /* As before, this returns NULL because the fragment isn't in the
1462 * reassembled_table. At least this is a bit more consistent than before.
1464 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table
.fragment_table
));
1465 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table
.reassembled_table
));
1466 ASSERT_EQ(NULL
,fd_head
);
1469 fd_head
=fragment_add_seq_next(&test_reassembly_table
, tvb
, 5, &pinfo
, 24, NULL
,
1471 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table
.fragment_table
));
1472 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table
.reassembled_table
));
1473 ASSERT_EQ(NULL
,fd_head
);
1478 * This time, our datagram only has one segment, but it has data missing.
1481 test_missing_data_fragment_add_seq_next_3(void)
1483 fragment_head
*fd_head
;
1485 printf("Starting test test_missing_data_fragment_add_seq_next_3\n");
1488 fd_head
=fragment_add_seq_next(&test_reassembly_table
, tvb
, 5, &pinfo
, 30, NULL
,
1491 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table
.fragment_table
));
1492 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table
.reassembled_table
));
1493 ASSERT_NE(NULL
,fd_head
);
1495 /* check the contents of the structure. */
1496 ASSERT_EQ(0,fd_head
->frame
); /* unused */
1497 ASSERT_EQ(0,fd_head
->offset
); /* unused */
1498 ASSERT_EQ(0,fd_head
->len
); /* the length of data we have */
1499 ASSERT_EQ(0,fd_head
->datalen
); /* seqno of the last fragment we have */
1500 ASSERT_EQ(20,fd_head
->reassembled_in
);
1501 ASSERT_EQ(FD_BLOCKSEQUENCE
|FD_DEFRAGMENTED
,fd_head
->flags
);
1502 ASSERT_EQ(NULL
,fd_head
->tvb_data
);
1503 ASSERT_EQ(NULL
,fd_head
->next
);
1505 /* revisiting the packet ought to produce the same result. */
1506 pinfo
.fd
->flags
.visited
= TRUE
;
1509 fd_head
=fragment_add_seq_next(&test_reassembly_table
, tvb
, 5, &pinfo
, 30, NULL
,
1512 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table
.fragment_table
));
1513 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table
.reassembled_table
));
1514 ASSERT_NE(NULL
,fd_head
);
1515 ASSERT_EQ(0,fd_head
->frame
); /* unused */
1516 ASSERT_EQ(0,fd_head
->offset
); /* unused */
1517 ASSERT_EQ(0,fd_head
->len
); /* the length of data we have */
1518 ASSERT_EQ(0,fd_head
->datalen
); /* seqno of the last fragment we have */
1519 ASSERT_EQ(20,fd_head
->reassembled_in
);
1520 ASSERT_EQ(FD_BLOCKSEQUENCE
|FD_DEFRAGMENTED
,fd_head
->flags
);
1521 ASSERT_EQ(NULL
,fd_head
->tvb_data
);
1522 ASSERT_EQ(NULL
,fd_head
->next
);
1526 /**********************************************************************************
1530 *********************************************************************************/
1533 main(int argc _U_
, char **argv _U_
)
1536 static const guint8 src
[] = {1,2,3,4}, dst
[] = {5,6,7,8};
1538 static void (*tests
[])(void) = {
1539 test_simple_fragment_add_seq
, /* frag table only */
1540 test_fragment_add_seq_partial_reassembly
,
1541 test_fragment_add_seq_duplicate_first
,
1542 test_fragment_add_seq_duplicate_middle
,
1543 test_fragment_add_seq_duplicate_last
,
1544 test_fragment_add_seq_duplicate_conflict
,
1545 test_fragment_add_seq_check
, /* frag + reassemble */
1546 test_fragment_add_seq_check_1
,
1547 test_fragment_add_seq_802_11_0
,
1548 test_fragment_add_seq_802_11_1
,
1549 test_simple_fragment_add_seq_next
,
1550 test_missing_data_fragment_add_seq_next
,
1551 test_missing_data_fragment_add_seq_next_2
,
1552 test_missing_data_fragment_add_seq_next_3
,
1554 test_fragment_add_seq_check_multiple
1558 /* initialise stuff */
1561 /* a tvbuff for testing with */
1562 data
= (char *)g_malloc(DATA_LEN
);
1563 /* make sure it's full of stuff */
1564 for(i
=0; i
<DATA_LEN
; i
++) {
1567 tvb
= tvb_new_real_data(data
, DATA_LEN
, DATA_LEN
*2);
1569 /* other test stuff */
1571 fd
.flags
.visited
= 0;
1572 SET_ADDRESS(&pinfo
.src
,AT_IPv4
,4,src
);
1573 SET_ADDRESS(&pinfo
.dst
,AT_IPv4
,4,dst
);
1575 /*************************************************************************/
1576 for(i
=0; i
< sizeof(tests
)/sizeof(tests
[0]); i
++ ) {
1577 /* re-init the fragment tables */
1578 reassembly_table_init(&test_reassembly_table
,
1579 &addresses_reassembly_table_functions
);
1580 ASSERT(test_reassembly_table
.fragment_table
!= NULL
);
1581 ASSERT(test_reassembly_table
.reassembled_table
!= NULL
);
1583 pinfo
.fd
->flags
.visited
= FALSE
;
1587 /* Free memory used by the tables */
1588 reassembly_table_destroy(&test_reassembly_table
);
1596 printf(failure
?"FAILURE\n":"SUCCESS\n");