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.
31 * Copyright (c) 2007 MX Telecom Ltd. <richardv@mxtelecom.com>
33 * Wireshark - Network traffic analyzer
34 * By Gerald Combs <gerald@wireshark.org>
37 * This program is free software; you can redistribute it and/or
38 * modify it under the terms of the GNU General Public License
39 * as published by the Free Software Foundation; either version 2
40 * of the License, or (at your option) any later version.
42 * This program is distributed in the hope that it will be useful,
43 * but WITHOUT ANY WARRANTY; without even the implied warranty of
44 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
45 * GNU General Public License for more details.
47 * You should have received a copy of the GNU General Public License
48 * along with this program; if not, write to the Free Software
49 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
61 #include <epan/emem.h>
62 #include <epan/packet.h>
63 #include <epan/packet_info.h>
64 #include <epan/proto.h>
65 #include <epan/tvbuff.h>
66 #include <epan/reassemble.h>
68 #define ASSERT(b) do_test((b),"Assertion failed at line %i: %s\n", __LINE__, #b)
69 #define ASSERT_EQ(exp,act) do_test((exp)==(act),"Assertion failed at line %i: %s==%s (%i==%i)\n", __LINE__, #exp, #act, exp, act)
70 #define ASSERT_NE(exp,act) do_test((exp)!=(act),"Assertion failed at line %i: %s!=%s (%i!=%i)\n", __LINE__, #exp, #act, exp, act)
72 static int failure = 0;
75 do_test(gboolean condition, const char *format, ...)
83 vfprintf(stderr, format, ap);
87 /* many of the tests assume this routine doesn't return on failure; if we
88 * do, it may provide more information, but may cause a segfault. Uncomment
89 * this line if you wish.
98 static packet_info pinfo;
100 /* fragment_table maps from datagram ids to fragment_head
101 reassembled_table maps from <packet number,datagram id> to
103 static reassembly_table test_reassembly_table;
106 /*************************************************
107 * Util fcns to display
108 * fragment_table & reassembled_table fd-chains
109 ************************************************/
111 static struct _fd_flags {
115 {FD_DEFRAGMENTED ,"DF"},
116 {FD_DATALEN_SET ,"DS"},
117 {FD_SUBSET_TVB, ,"ST"},
118 {FD_BLOCKSEQUENCE ,"BS"},
119 {FD_DATA_NOT_PRESENT ,"NP"},
120 {FD_PARTIAL_REASSEMBLY ,"PR"},
122 {FD_OVERLAPCONFLICT ,"OC"},
123 {FD_MULTIPLETAILS ,"MT"},
124 {FD_TOOLONGFRAGMENT ,"TL"},
126 #define N_FD_FLAGS (signed)(sizeof(fd_flags)/sizeof(struct _fd_flags))
129 print_fd(fragment_head *fd, gboolean is_head) {
132 g_assert(fd != NULL);
133 printf(" %08x %08x %3d %3d %3d", fd, fd->next, fd->frame, fd->offset, fd->len);
135 printf(" %3d %3d", fd->datalen, fd->reassembled_in);
139 printf(" 0x%08x", fd->data);
140 for (i=0; i<N_FD_FLAGS; i++) {
141 printf(" %s", (fd->flags & fd_flags[i].flag) ? fd_flags[i].flag_name : " ");
147 print_fd_chain(fragment_head *fd_head) {
150 g_assert(fd_head != NULL);
151 print_fd(fd_head, TRUE);
152 for (fdp=fd_head->next; fdp != NULL; fdp=fdp->next) {
153 print_fd(fdp, FALSE);
158 print_fragment_table_chain(gpointer k, gpointer v, gpointer ud) {
159 fragment_key *key = (fragment_key*)k;
160 fragment_head *fd_head = (fragment_head *)v;
161 printf(" --> FT: %3d 0x%08x 0x%08x\n", key->id, *(guint32 *)(key->src.data), *(guint32 *)(key->dst.data));
162 print_fd_chain(fd_head);
166 print_fragment_table(void) {
167 printf("\n Fragment Table -------\n");
168 g_hash_table_foreach(fragment_table, print_fragment_table_chain, NULL);
172 print_reassembled_table_chain(gpointer k, gpointer v, gpointer ud) {
173 reassembled_key *key = (reassembled_key*)k;
174 fragment_head *fd_head = (fragment_head *)v;
175 printf(" --> RT: %5d %5d\n", key->id, key->frame);
176 print_fd_chain(fd_head);
180 print_reassembled_table(void) {
181 printf("\n Reassembled Table ----\n");
182 g_hash_table_foreach(test_reassembly_table.reassembled_table, print_reassembled_table_chain, NULL);
187 print_fragment_table();
188 print_reassembled_table();
192 /**********************************************************************************
196 *********************************************************************************/
198 /* Simple test case for fragment_add_seq.
199 * Adds three fragments (out of order, with one for a different datagram in between),
200 * and checks that they are reassembled correctly.
202 /* visit id frame frag len more tvb_offset
210 test_simple_fragment_add_seq(void)
212 fragment_head *fd_head, *fdh0;
214 printf("Starting test test_simple_fragment_add_seq\n");
217 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
220 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
221 ASSERT_EQ(NULL,fd_head);
223 /* adding the same fragment again should do nothing, even with different
225 pinfo.fd->flags.visited = 1;
226 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
228 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
229 ASSERT_EQ(NULL,fd_head);
231 /* start another pdu (just to confuse things) */
232 pinfo.fd->flags.visited = 0;
234 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 15, &pinfo, 13, NULL,
236 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
237 ASSERT_EQ(NULL,fd_head);
239 /* now we add the terminal fragment of the first datagram */
241 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
244 /* we haven't got all the fragments yet ... */
245 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
246 ASSERT_EQ(NULL,fd_head);
248 /* finally, add the missing fragment */
250 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 15, &pinfo, 12, NULL,
253 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
254 ASSERT_NE(NULL,fd_head);
256 /* check the contents of the structure */
257 ASSERT_EQ(0,fd_head->frame); /* unused */
258 ASSERT_EQ(0,fd_head->offset); /* unused */
259 ASSERT_EQ(170,fd_head->len); /* the length of data we have */
260 ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
261 ASSERT_EQ(4,fd_head->reassembled_in);
262 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
263 ASSERT_NE(NULL,fd_head->tvb_data);
264 ASSERT_NE(NULL,fd_head->next);
266 ASSERT_EQ(1,fd_head->next->frame);
267 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
268 ASSERT_EQ(50,fd_head->next->len); /* segment length */
269 ASSERT_EQ(0,fd_head->next->flags);
270 ASSERT_EQ(NULL,fd_head->next->tvb_data);
271 ASSERT_NE(NULL,fd_head->next->next);
273 ASSERT_EQ(4,fd_head->next->next->frame);
274 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
275 ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
276 ASSERT_EQ(0,fd_head->next->next->flags);
277 ASSERT_EQ(NULL,fd_head->next->next->tvb_data);
278 ASSERT_NE(NULL,fd_head->next->next->next);
280 ASSERT_EQ(3,fd_head->next->next->next->frame);
281 ASSERT_EQ(2,fd_head->next->next->next->offset); /* seqno */
282 ASSERT_EQ(60,fd_head->next->next->next->len); /* segment length */
283 ASSERT_EQ(0,fd_head->next->next->next->flags);
284 ASSERT_EQ(NULL,fd_head->next->next->next->tvb_data);
285 ASSERT_EQ(NULL,fd_head->next->next->next->next);
287 /* test the actual reassembly */
288 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
289 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+15,60));
290 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,60));
293 print_fragment_table();
296 /* what happens if we revisit the packets now? */
298 pinfo.fd->flags.visited = 1;
300 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
303 * this api relies on the caller to check fd_head -> reassembled_in
305 * Redoing all the tests seems like overkill - just check the pointer
307 ASSERT_EQ(fdh0,fd_head);
310 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
312 ASSERT_EQ(fdh0,fd_head);
315 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 15, &pinfo, 12, NULL,
317 ASSERT_EQ(fdh0,fd_head);
320 print_fragment_table();
324 /* XXX ought to have some tests for overlapping fragments */
326 /* This tests the functionality of fragment_set_partial_reassembly for
327 * FD_BLOCKSEQUENCE reassembly.
329 * We add a sequence of fragments thus:
330 * seqno frame offset len (initial) more_frags
331 * ----- ----- ------ --- --------------------
334 * 1 3 0 40 true (a duplicate fragment)
339 test_fragment_add_seq_partial_reassembly(void)
341 fragment_head *fd_head;
344 printf("Starting test test_fragment_add_seq_partial_reassembly\n");
346 /* generally it's probably fair to assume that we will be called with
350 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
353 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
354 ASSERT_NE(NULL,fd_head);
356 /* check the contents of the structure */
357 ASSERT_EQ(0,fd_head->frame); /* unused */
358 ASSERT_EQ(0,fd_head->offset); /* unused */
359 ASSERT_EQ(50,fd_head->len); /* the length of data we have */
360 ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
361 ASSERT_EQ(1,fd_head->reassembled_in);
362 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
363 ASSERT_NE(NULL,fd_head->tvb_data);
364 ASSERT_NE(NULL,fd_head->next);
366 ASSERT_EQ(1,fd_head->next->frame);
367 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
368 ASSERT_EQ(50,fd_head->next->len); /* segment length */
369 ASSERT_EQ(0,fd_head->next->flags);
370 ASSERT_EQ(NULL,fd_head->next->tvb_data);
371 ASSERT_EQ(NULL,fd_head->next->next);
373 /* test the actual reassembly */
374 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
376 /* now we announce that the reassembly wasn't complete after all. */
377 fragment_set_partial_reassembly(&test_reassembly_table, &pinfo, 12, NULL);
379 /* and add another segment. To mix things up slightly (and so that we can
380 * check on the state of things), we're going to set the more_frags flag
384 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
387 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
388 ASSERT_EQ(NULL,fd_head);
390 fd_head=fragment_get(&test_reassembly_table, &pinfo, 12, NULL);
391 ASSERT_NE(NULL,fd_head);
393 /* check the contents of the structure */
394 ASSERT_EQ(0,fd_head->frame); /* unused */
395 ASSERT_EQ(0,fd_head->offset); /* unused */
396 /* ASSERT_EQ(50,fd_head->len); the length of data we have */
397 ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
398 ASSERT_EQ(0,fd_head->reassembled_in);
399 ASSERT_EQ(FD_BLOCKSEQUENCE,fd_head->flags);
400 ASSERT_NE(NULL,fd_head->tvb_data);
401 ASSERT_NE(NULL,fd_head->next);
404 ASSERT_EQ(1,fd->frame);
405 ASSERT_EQ(0,fd->offset); /* seqno */
406 ASSERT_EQ(50,fd->len); /* segment length */
407 ASSERT_EQ(FD_SUBSET_TVB,fd->flags);
408 ASSERT_EQ(tvb_get_ptr(fd_head->tvb_data,0,0),tvb_get_ptr(fd->tvb_data,0,0));
409 ASSERT_NE(NULL,fd->next);
412 ASSERT_EQ(2,fd->frame);
413 ASSERT_EQ(1,fd->offset); /* seqno */
414 ASSERT_EQ(40,fd->len); /* segment length */
415 ASSERT_EQ(0,fd->flags);
416 ASSERT_NE(NULL,fd->tvb_data);
417 ASSERT_EQ(NULL,fd->next);
419 /* Another copy of the second segment.
422 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
425 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
426 ASSERT_EQ(NULL,fd_head);
427 fd_head=fragment_get(&test_reassembly_table, &pinfo, 12, NULL);
428 ASSERT_NE(NULL,fd_head);
429 ASSERT_EQ(0,fd_head->frame); /* unused */
430 ASSERT_EQ(0,fd_head->offset); /* unused */
431 /* ASSERT_EQ(50,fd_head->len); the length of data we have */
432 ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
433 ASSERT_EQ(0,fd_head->reassembled_in);
434 ASSERT_EQ(FD_BLOCKSEQUENCE,fd_head->flags);
435 ASSERT_NE(NULL,fd_head->tvb_data);
436 ASSERT_NE(NULL,fd_head->next);
439 ASSERT_EQ(1,fd->frame);
440 ASSERT_EQ(0,fd->offset); /* seqno */
441 ASSERT_EQ(50,fd->len); /* segment length */
442 ASSERT_EQ(FD_SUBSET_TVB,fd->flags);
443 ASSERT_EQ(tvb_get_ptr(fd_head->tvb_data,0,0),tvb_get_ptr(fd->tvb_data,0,0));
444 ASSERT_NE(NULL,fd->next);
447 ASSERT_EQ(2,fd->frame);
448 ASSERT_EQ(1,fd->offset); /* seqno */
449 ASSERT_EQ(40,fd->len); /* segment length */
450 ASSERT_EQ(0,fd->flags);
451 ASSERT_NE(NULL,fd->tvb_data);
452 ASSERT_NE(NULL,fd->next);
455 ASSERT_EQ(3,fd->frame);
456 ASSERT_EQ(1,fd->offset); /* seqno */
457 ASSERT_EQ(40,fd->len); /* segment length */
458 ASSERT_EQ(0,fd->flags);
459 ASSERT_NE(NULL,fd->tvb_data);
460 ASSERT_EQ(NULL,fd->next);
464 /* have another go at wrapping things up */
466 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 20, &pinfo, 12, NULL,
469 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
470 ASSERT_NE(NULL,fd_head);
472 /* check the contents of the structure */
473 ASSERT_EQ(0,fd_head->frame); /* unused */
474 ASSERT_EQ(0,fd_head->offset); /* unused */
475 ASSERT_EQ(190,fd_head->len); /* the length of data we have */
476 ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
477 ASSERT_EQ(4,fd_head->reassembled_in);
478 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
479 ASSERT_NE(NULL,fd_head->tvb_data);
480 ASSERT_NE(NULL,fd_head->next);
483 ASSERT_EQ(1,fd->frame);
484 ASSERT_EQ(0,fd->offset); /* seqno */
485 ASSERT_EQ(50,fd->len); /* segment length */
486 ASSERT_EQ(0,fd->flags);
487 ASSERT_EQ(NULL,fd->tvb_data);
488 ASSERT_NE(NULL,fd->next);
491 ASSERT_EQ(2,fd->frame);
492 ASSERT_EQ(1,fd->offset); /* seqno */
493 ASSERT_EQ(40,fd->len); /* segment length */
494 ASSERT_EQ(0,fd->flags);
495 ASSERT_EQ(NULL,fd->tvb_data);
496 ASSERT_NE(NULL,fd->next);
499 ASSERT_EQ(3,fd->frame);
500 ASSERT_EQ(1,fd->offset); /* seqno */
501 ASSERT_EQ(40,fd->len); /* segment length */
502 ASSERT_EQ(FD_OVERLAP,fd->flags);
503 ASSERT_EQ(NULL,fd->tvb_data);
504 ASSERT_NE(NULL,fd->next);
507 ASSERT_EQ(4,fd->frame);
508 ASSERT_EQ(2,fd->offset); /* seqno */
509 ASSERT_EQ(100,fd->len); /* segment length */
510 ASSERT_EQ(0,fd->flags);
511 ASSERT_EQ(NULL,fd->tvb_data);
512 ASSERT_EQ(NULL,fd->next);
514 /* test the actual reassembly */
515 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
516 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data,40));
517 ASSERT(!tvb_memeql(fd_head->tvb_data,90,data+20,100));
520 /* do it again (this time it is more complicated, with an overlap in the
523 fragment_set_partial_reassembly(&test_reassembly_table, &pinfo, 12, NULL);
526 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
529 fd_head=fragment_get(&test_reassembly_table, &pinfo, 12, NULL);
530 ASSERT_NE(NULL,fd_head);
531 ASSERT_EQ(0,fd_head->frame); /* unused */
532 ASSERT_EQ(0,fd_head->offset); /* unused */
533 ASSERT_EQ(230,fd_head->len); /* the length of data we have */
534 ASSERT_EQ(3,fd_head->datalen); /* seqno of the last fragment we have */
535 ASSERT_EQ(5,fd_head->reassembled_in);
536 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
537 ASSERT_NE(NULL,fd_head->tvb_data);
538 ASSERT_NE(NULL,fd_head->next);
541 ASSERT_EQ(1,fd->frame);
542 ASSERT_EQ(0,fd->offset); /* seqno */
543 ASSERT_EQ(50,fd->len); /* segment length */
544 ASSERT_EQ(0,fd->flags);
545 ASSERT_EQ(NULL,fd->tvb_data);
546 ASSERT_NE(NULL,fd->next);
549 ASSERT_EQ(2,fd->frame);
550 ASSERT_EQ(1,fd->offset); /* seqno */
551 ASSERT_EQ(40,fd->len); /* segment length */
552 ASSERT_EQ(0,fd->flags);
553 ASSERT_EQ(NULL,fd->tvb_data);
554 ASSERT_NE(NULL,fd->next);
557 ASSERT_EQ(3,fd->frame);
558 ASSERT_EQ(1,fd->offset); /* seqno */
559 ASSERT_EQ(40,fd->len); /* segment length */
560 ASSERT_EQ(FD_OVERLAP,fd->flags);
561 ASSERT_EQ(NULL,fd->tvb_data);
562 ASSERT_NE(NULL,fd->next);
565 ASSERT_EQ(4,fd->frame);
566 ASSERT_EQ(2,fd->offset); /* seqno */
567 ASSERT_EQ(100,fd->len); /* segment length */
568 ASSERT_EQ(0,fd->flags);
569 ASSERT_EQ(NULL,fd->tvb_data);
570 ASSERT_NE(NULL,fd->next);
573 ASSERT_EQ(5,fd->frame);
574 ASSERT_EQ(3,fd->offset); /* seqno */
575 ASSERT_EQ(40,fd->len); /* segment length */
576 ASSERT_EQ(0,fd->flags);
577 ASSERT_EQ(NULL,fd->tvb_data);
578 ASSERT_EQ(NULL,fd->next);
580 /* test the actual reassembly */
581 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
582 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data,40));
583 ASSERT(!tvb_memeql(fd_head->tvb_data,90,data+20,100));
584 ASSERT(!tvb_memeql(fd_head->tvb_data,190,data,40));
587 /* Test case for fragment_add_seq with duplicated (e.g., retransmitted) data.
588 * Adds three fragments--adding the 1st one twice--
589 * and checks that they are reassembled correctly.
591 /* visit id frame frag len more tvb_offset
598 test_fragment_add_seq_duplicate_first(void)
600 fragment_head *fd_head;
602 printf("Starting test test_fragment_add_seq_duplicate_first\n");
605 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
608 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
609 ASSERT_EQ(NULL,fd_head);
611 /* Add the 2nd segment */
613 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
616 /* we haven't got all the fragments yet ... */
617 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
618 ASSERT_EQ(NULL,fd_head);
620 /* Add the last fragment */
622 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
625 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
626 ASSERT_NE(NULL,fd_head);
628 /* Add the first fragment again */
630 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
633 /* Reassembly should have still succeeded */
634 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
635 ASSERT_NE(NULL,fd_head);
637 /* check the contents of the structure */
638 ASSERT_EQ(0,fd_head->frame); /* unused */
639 ASSERT_EQ(0,fd_head->offset); /* unused */
640 ASSERT_EQ(150,fd_head->len); /* the length of data we have */
641 ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
642 ASSERT_EQ(3,fd_head->reassembled_in);
643 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
644 ASSERT_NE(NULL,fd_head->tvb_data);
645 ASSERT_NE(NULL,fd_head->next);
647 ASSERT_EQ(1,fd_head->next->frame);
648 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
649 ASSERT_EQ(50,fd_head->next->len); /* segment length */
650 ASSERT_EQ(0,fd_head->next->flags);
651 ASSERT_EQ(NULL,fd_head->next->tvb_data);
652 ASSERT_NE(NULL,fd_head->next->next);
654 ASSERT_EQ(4,fd_head->next->next->frame);
655 ASSERT_EQ(0,fd_head->next->next->offset); /* seqno */
656 ASSERT_EQ(50,fd_head->next->next->len); /* segment length */
657 ASSERT_EQ(FD_OVERLAP,fd_head->next->next->flags);
658 ASSERT_EQ(NULL,fd_head->next->next->tvb_data);
659 ASSERT_NE(NULL,fd_head->next->next->next);
661 ASSERT_EQ(2,fd_head->next->next->next->frame);
662 ASSERT_EQ(1,fd_head->next->next->next->offset); /* seqno */
663 ASSERT_EQ(60,fd_head->next->next->next->len); /* segment length */
664 ASSERT_EQ(0,fd_head->next->next->next->flags);
665 ASSERT_EQ(NULL,fd_head->next->next->next->tvb_data);
666 ASSERT_NE(NULL,fd_head->next->next->next->next);
668 ASSERT_EQ(3,fd_head->next->next->next->next->frame);
669 ASSERT_EQ(2,fd_head->next->next->next->next->offset); /* seqno */
670 ASSERT_EQ(40,fd_head->next->next->next->next->len); /* segment length */
671 ASSERT_EQ(0,fd_head->next->next->next->next->flags);
672 ASSERT_EQ(NULL,fd_head->next->next->next->next->tvb_data);
673 ASSERT_EQ(NULL,fd_head->next->next->next->next->next);
675 /* test the actual reassembly */
676 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
677 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
678 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
681 print_fragment_table();
686 /* Test case for fragment_add_seq with duplicated (e.g., retransmitted) data.
687 * Adds three fragments--adding the 2nd one twice--
688 * and checks that they are reassembled correctly.
690 /* visit id frame frag len more tvb_offset
697 test_fragment_add_seq_duplicate_middle(void)
699 fragment_head *fd_head;
701 printf("Starting test test_fragment_add_seq_duplicate_middle\n");
704 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
707 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
708 ASSERT_EQ(NULL,fd_head);
710 /* Add the 2nd segment */
712 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
715 /* we haven't got all the fragments yet ... */
716 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
717 ASSERT_EQ(NULL,fd_head);
719 /* Now, add the 2nd segment again (but in a different frame) */
721 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
724 /* This duplicate fragment should have been ignored */
725 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
726 ASSERT_EQ(NULL,fd_head);
728 /* finally, add the last fragment */
730 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
733 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
734 ASSERT_NE(NULL,fd_head);
736 /* check the contents of the structure */
737 ASSERT_EQ(0,fd_head->frame); /* unused */
738 ASSERT_EQ(0,fd_head->offset); /* unused */
739 ASSERT_EQ(150,fd_head->len); /* the length of data we have */
740 ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
741 ASSERT_EQ(4,fd_head->reassembled_in);
742 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
743 ASSERT_NE(NULL,fd_head->tvb_data);
744 ASSERT_NE(NULL,fd_head->next);
746 ASSERT_EQ(1,fd_head->next->frame);
747 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
748 ASSERT_EQ(50,fd_head->next->len); /* segment length */
749 ASSERT_EQ(0,fd_head->next->flags);
750 ASSERT_EQ(NULL,fd_head->next->tvb_data);
751 ASSERT_NE(NULL,fd_head->next->next);
753 ASSERT_EQ(2,fd_head->next->next->frame);
754 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
755 ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
756 ASSERT_EQ(0,fd_head->next->next->flags);
757 ASSERT_EQ(NULL,fd_head->next->next->tvb_data);
758 ASSERT_NE(NULL,fd_head->next->next->next);
760 ASSERT_EQ(3,fd_head->next->next->next->frame);
761 ASSERT_EQ(1,fd_head->next->next->next->offset); /* seqno */
762 ASSERT_EQ(60,fd_head->next->next->next->len); /* segment length */
763 ASSERT_EQ(FD_OVERLAP,fd_head->next->next->next->flags);
764 ASSERT_EQ(NULL,fd_head->next->next->next->tvb_data);
765 ASSERT_NE(NULL,fd_head->next->next->next->next);
767 ASSERT_EQ(4,fd_head->next->next->next->next->frame);
768 ASSERT_EQ(2,fd_head->next->next->next->next->offset); /* seqno */
769 ASSERT_EQ(40,fd_head->next->next->next->next->len); /* segment length */
770 ASSERT_EQ(0,fd_head->next->next->next->next->flags);
771 ASSERT_EQ(NULL,fd_head->next->next->next->next->tvb_data);
772 ASSERT_EQ(NULL,fd_head->next->next->next->next->next);
774 /* test the actual reassembly */
775 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
776 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
777 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
780 print_fragment_table();
784 /* Test case for fragment_add_seq with duplicated (e.g., retransmitted) data.
785 * Adds three fragments--adding the 3rd one twice--
786 * and checks that they are reassembled correctly.
788 /* visit id frame frag len more tvb_offset
795 test_fragment_add_seq_duplicate_last(void)
797 fragment_head *fd_head;
799 printf("Starting test test_fragment_add_seq_duplicate_last\n");
802 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
805 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
806 ASSERT_EQ(NULL,fd_head);
808 /* Add the 2nd segment */
810 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
813 /* we haven't got all the fragments yet ... */
814 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
815 ASSERT_EQ(NULL,fd_head);
817 /* Add the last fragment */
819 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
822 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
823 ASSERT_NE(NULL,fd_head);
825 /* Add the last fragment again */
827 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
830 /* Reassembly should have still succeeded */
831 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
832 ASSERT_NE(NULL,fd_head);
834 /* check the contents of the structure */
835 ASSERT_EQ(0,fd_head->frame); /* unused */
836 ASSERT_EQ(0,fd_head->offset); /* unused */
837 ASSERT_EQ(150,fd_head->len); /* the length of data we have */
838 ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
839 ASSERT_EQ(3,fd_head->reassembled_in);
840 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
841 ASSERT_NE(NULL,fd_head->tvb_data);
842 ASSERT_NE(NULL,fd_head->next);
844 ASSERT_EQ(1,fd_head->next->frame);
845 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
846 ASSERT_EQ(50,fd_head->next->len); /* segment length */
847 ASSERT_EQ(0,fd_head->next->flags);
848 ASSERT_EQ(NULL,fd_head->next->tvb_data);
849 ASSERT_NE(NULL,fd_head->next->next);
851 ASSERT_EQ(2,fd_head->next->next->frame);
852 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
853 ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
854 ASSERT_EQ(0,fd_head->next->next->flags);
855 ASSERT_EQ(NULL,fd_head->next->next->tvb_data);
856 ASSERT_NE(NULL,fd_head->next->next->next);
858 ASSERT_EQ(3,fd_head->next->next->next->frame);
859 ASSERT_EQ(2,fd_head->next->next->next->offset); /* seqno */
860 ASSERT_EQ(40,fd_head->next->next->next->len); /* segment length */
861 ASSERT_EQ(0,fd_head->next->next->next->flags);
862 ASSERT_EQ(NULL,fd_head->next->next->next->tvb_data);
863 ASSERT_NE(NULL,fd_head->next->next->next->next);
865 ASSERT_EQ(4,fd_head->next->next->next->next->frame);
866 ASSERT_EQ(2,fd_head->next->next->next->next->offset); /* seqno */
867 ASSERT_EQ(40,fd_head->next->next->next->next->len); /* segment length */
868 ASSERT_EQ(FD_OVERLAP,fd_head->next->next->next->next->flags);
869 ASSERT_EQ(NULL,fd_head->next->next->next->next->tvb_data);
870 ASSERT_EQ(NULL,fd_head->next->next->next->next->next);
872 /* test the actual reassembly */
873 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
874 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
875 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
878 print_fragment_table();
882 /* Test case for fragment_add_seq with duplicated (e.g., retransmitted) data
883 * where the retransmission "conflicts" with the original transmission
884 * (contents are different).
885 * Adds three fragments--adding the 2nd one twice--
886 * and checks that they are reassembled correctly.
888 /* visit id frame frag len more tvb_offset
895 test_fragment_add_seq_duplicate_conflict(void)
897 fragment_head *fd_head;
899 printf("Starting test test_fragment_add_seq_duplicate_conflict\n");
902 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
905 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
906 ASSERT_EQ(NULL,fd_head);
908 /* Add the 2nd segment */
910 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
913 /* we haven't got all the fragments yet ... */
914 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
915 ASSERT_EQ(NULL,fd_head);
917 /* Now, add the 2nd segment again (but in a different frame and with
921 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 15, &pinfo, 12, NULL,
924 /* This duplicate fragment should have been ignored */
925 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
926 ASSERT_EQ(NULL,fd_head);
928 /* finally, add the last fragment */
930 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
933 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
934 ASSERT_NE(NULL,fd_head);
936 /* check the contents of the structure */
937 ASSERT_EQ(0,fd_head->frame); /* unused */
938 ASSERT_EQ(0,fd_head->offset); /* unused */
939 ASSERT_EQ(150,fd_head->len); /* the length of data we have */
940 ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
941 ASSERT_EQ(4,fd_head->reassembled_in);
942 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP|FD_OVERLAPCONFLICT,fd_head->flags);
943 ASSERT_NE(NULL,fd_head->tvb_data);
944 ASSERT_NE(NULL,fd_head->next);
946 ASSERT_EQ(1,fd_head->next->frame);
947 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
948 ASSERT_EQ(50,fd_head->next->len); /* segment length */
949 ASSERT_EQ(0,fd_head->next->flags);
950 ASSERT_EQ(NULL,fd_head->next->tvb_data);
951 ASSERT_NE(NULL,fd_head->next->next);
953 ASSERT_EQ(2,fd_head->next->next->frame);
954 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
955 ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
956 ASSERT_EQ(0,fd_head->next->next->flags);
957 ASSERT_EQ(NULL,fd_head->next->next->tvb_data);
958 ASSERT_NE(NULL,fd_head->next->next->next);
960 ASSERT_EQ(3,fd_head->next->next->next->frame);
961 ASSERT_EQ(1,fd_head->next->next->next->offset); /* seqno */
962 ASSERT_EQ(60,fd_head->next->next->next->len); /* segment length */
963 ASSERT_EQ(FD_OVERLAP|FD_OVERLAPCONFLICT,fd_head->next->next->next->flags);
964 ASSERT_EQ(NULL,fd_head->next->next->next->tvb_data);
965 ASSERT_NE(NULL,fd_head->next->next->next->next);
967 ASSERT_EQ(4,fd_head->next->next->next->next->frame);
968 ASSERT_EQ(2,fd_head->next->next->next->next->offset); /* seqno */
969 ASSERT_EQ(40,fd_head->next->next->next->next->len); /* segment length */
970 ASSERT_EQ(0,fd_head->next->next->next->next->flags);
971 ASSERT_EQ(NULL,fd_head->next->next->next->next->tvb_data);
972 ASSERT_EQ(NULL,fd_head->next->next->next->next->next);
974 /* test the actual reassembly */
975 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
976 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
977 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
980 print_fragment_table();
984 /**********************************************************************************
986 * fragment_add_seq_check
988 *********************************************************************************/
991 /* This routine is used for both fragment_add_seq_802_11 and
992 * fragment_add_seq_check.
994 * Adds a couple of out-of-order fragments and checks their reassembly.
997 /* visit id frame frag len more tvb_offset
1006 test_fragment_add_seq_check_work(fragment_head *(*fn)(reassembly_table *,
1007 tvbuff_t *, const int, const packet_info *,
1008 const guint32, const void *, const guint32,
1009 const guint32, const gboolean))
1011 fragment_head *fd_head;
1013 pinfo.fd -> num = 1;
1014 fd_head=fn(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1017 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1018 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1019 ASSERT_EQ(NULL,fd_head);
1021 /* start another pdu (just to confuse things) */
1023 fd_head=fn(&test_reassembly_table, tvb, 15, &pinfo, 13, NULL,
1025 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
1026 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1027 ASSERT_EQ(NULL,fd_head);
1029 /* add the terminal fragment of the first datagram */
1031 fd_head=fn(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1034 /* we haven't got all the fragments yet ... */
1035 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
1036 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1037 ASSERT_EQ(NULL,fd_head);
1039 /* finally, add the missing fragment */
1041 fd_head=fn(&test_reassembly_table, tvb, 15, &pinfo, 12, NULL,
1044 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1045 ASSERT_EQ(3,g_hash_table_size(test_reassembly_table.reassembled_table));
1046 ASSERT_NE(NULL,fd_head);
1048 /* check the contents of the structure */
1049 ASSERT_EQ(0,fd_head->frame); /* unused */
1050 ASSERT_EQ(0,fd_head->offset); /* unused */
1051 ASSERT_EQ(170,fd_head->len); /* the length of data we have */
1052 ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
1053 ASSERT_EQ(4,fd_head->reassembled_in);
1054 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
1055 ASSERT_NE(NULL,fd_head->tvb_data);
1056 ASSERT_NE(NULL,fd_head->next);
1058 ASSERT_EQ(1,fd_head->next->frame);
1059 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
1060 ASSERT_EQ(50,fd_head->next->len); /* segment length */
1061 ASSERT_EQ(0,fd_head->next->flags);
1062 ASSERT_EQ(NULL,fd_head->next->tvb_data);
1063 ASSERT_NE(NULL,fd_head->next->next);
1065 ASSERT_EQ(4,fd_head->next->next->frame);
1066 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
1067 ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
1068 ASSERT_EQ(0,fd_head->next->next->flags);
1069 ASSERT_EQ(NULL,fd_head->next->next->tvb_data);
1070 ASSERT_NE(NULL,fd_head->next->next->next);
1072 ASSERT_EQ(3,fd_head->next->next->next->frame);
1073 ASSERT_EQ(2,fd_head->next->next->next->offset); /* seqno */
1074 ASSERT_EQ(60,fd_head->next->next->next->len); /* segment length */
1075 ASSERT_EQ(0,fd_head->next->next->next->flags);
1076 ASSERT_EQ(NULL,fd_head->next->next->next->tvb_data);
1077 ASSERT_EQ(NULL,fd_head->next->next->next->next);
1079 /* test the actual reassembly */
1080 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
1081 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+15,60));
1082 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,60));
1089 /* Simple test case for fragment_add_seq_check
1092 test_fragment_add_seq_check(void)
1094 printf("Starting test test_fragment_add_seq_check\n");
1096 test_fragment_add_seq_check_work(fragment_add_seq_check);
1100 /* This tests the case that the 802.11 hack does something different for: when
1101 * the terminal segment in a fragmented datagram arrives first.
1104 test_fragment_add_seq_check_1(void)
1106 fragment_head *fd_head;
1108 printf("Starting test test_fragment_add_seq_check_1\n");
1111 fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1114 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1115 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1116 ASSERT_EQ(NULL,fd_head);
1118 /* Now add the missing segment */
1120 fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1123 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1124 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.reassembled_table));
1125 ASSERT_NE(NULL,fd_head);
1127 /* check the contents of the structure */
1128 ASSERT_EQ(0,fd_head->frame); /* unused */
1129 ASSERT_EQ(0,fd_head->offset); /* unused */
1130 ASSERT_EQ(110,fd_head->len); /* the length of data we have */
1131 ASSERT_EQ(1,fd_head->datalen); /* seqno of the last fragment we have */
1132 ASSERT_EQ(2,fd_head->reassembled_in);
1133 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
1134 ASSERT_NE(NULL,fd_head->tvb_data);
1135 ASSERT_NE(NULL,fd_head->next);
1137 ASSERT_EQ(2,fd_head->next->frame);
1138 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
1139 ASSERT_EQ(60,fd_head->next->len); /* segment length */
1140 ASSERT_EQ(0,fd_head->next->flags);
1141 ASSERT_EQ(NULL,fd_head->next->tvb_data);
1142 ASSERT_NE(NULL,fd_head->next->next);
1144 ASSERT_EQ(1,fd_head->next->next->frame);
1145 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
1146 ASSERT_EQ(50,fd_head->next->next->len); /* segment length */
1147 ASSERT_EQ(0,fd_head->next->next->flags);
1148 ASSERT_EQ(NULL,fd_head->next->next->tvb_data);
1149 ASSERT_EQ(NULL,fd_head->next->next->next);
1151 /* test the actual reassembly */
1152 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+5,60));
1153 ASSERT(!tvb_memeql(fd_head->tvb_data,60,data+10,50));
1156 /**********************************************************************************
1158 * fragment_add_seq_802_11
1160 *********************************************************************************/
1162 /* Tests the 802.11 hack.
1165 test_fragment_add_seq_802_11_0(void)
1167 fragment_head *fd_head;
1169 printf("Starting test test_fragment_add_seq_802_11_0\n");
1171 /* the 802.11 hack is that some non-fragmented datagrams have non-zero
1172 * fragment_number; test for this. */
1175 fd_head=fragment_add_seq_802_11(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1178 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1179 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.reassembled_table));
1180 ASSERT_NE(NULL,fd_head);
1182 /* check the contents of the structure */
1183 ASSERT_EQ(0,fd_head->frame); /* unused */
1184 ASSERT_EQ(0,fd_head->offset); /* unused */
1185 ASSERT_EQ(0,fd_head->len); /* unused */
1186 ASSERT_EQ(0,fd_head->datalen); /* unused */
1187 ASSERT_EQ(1,fd_head->reassembled_in);
1188 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE,fd_head->flags);
1189 ASSERT_EQ(NULL,fd_head->tvb_data);
1190 ASSERT_EQ(NULL,fd_head->next);
1193 /* Reuse the fragment_add_seq_check testcases */
1194 static void test_fragment_add_seq_802_11_1(void)
1196 printf("Starting test test_fragment_add_seq_802_11_1\n");
1197 test_fragment_add_seq_check_work(fragment_add_seq_802_11);
1200 /**********************************************************************************
1202 * fragment_add_seq_check_multiple
1204 *********************************************************************************/
1206 /* Test 2 partial frags from 2 diff datagrams in the same frame */
1208 datagram #1: frame 1 + first part of frame 2
1209 datagram #1: last part of frame 2 + frame 3
1211 Is this a valid scenario ?
1213 The result of calling fragment_add_seq_check(&test_reassembly_table, ) for these
1214 fragments is a reassembled_table with:
1215 id, frame 1 => first_datagram; ["reassembled in" frame 2]
1216 id, frame 2 => second_datagram; ["reassembled in" frame 3]
1217 id, frame 3 => second_datagram;
1219 Note that the id, frame 2 => first datagram was overwritten
1220 by the entry for the second datagram.
1221 Is this OK ? IE: When dissected/displayed
1222 will the reassembled datagram 1 appear with frame 2 ??
1225 /* visit id frame frag len more tvb_offset
1233 Is this a valid scenario ?
1234 Is this OK ? IE: When dissected/displayed:
1235 Will the reassembled datagram 1 appear with frame 2 ??
1239 test_fragment_add_seq_check_multiple(void) {
1240 fragment_head *fd_head;
1242 pinfo.fd -> num = 1;
1243 fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1246 /* add the terminal fragment of the first datagram */
1248 fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1253 /* Now: start a second datagram with the first fragment in frame #2 */
1255 fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 25, &pinfo, 12, NULL,
1258 /* add the terminal fragment of the second datagram */
1260 fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
1267 /**********************************************************************************
1269 * fragment_add_seq_next
1271 *********************************************************************************/
1273 /* Simple test case for fragment_add_seq_next.
1274 * Adds a couple of fragments (with one for a different datagram in between),
1275 * and checks that they are reassembled correctly.
1278 test_simple_fragment_add_seq_next(void)
1280 fragment_head *fd_head;
1282 printf("Starting test test_simple_fragment_add_seq_next\n");
1285 fd_head= fragment_add_seq_next(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1288 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1289 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1290 ASSERT_EQ(NULL,fd_head);
1292 /* adding the same fragment again should do nothing, even with different
1294 pinfo.fd->flags.visited = 1;
1295 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1297 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1298 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1299 ASSERT_EQ(NULL,fd_head);
1301 /* start another pdu (just to confuse things) */
1302 pinfo.fd->flags.visited = 0;
1304 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 15, &pinfo, 13, NULL,
1306 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
1307 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1308 ASSERT_EQ(NULL,fd_head);
1311 /* now we add the terminal fragment of the first datagram */
1313 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1316 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1317 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.reassembled_table));
1318 ASSERT_NE(NULL,fd_head);
1320 /* check the contents of the structure */
1321 ASSERT_EQ(0,fd_head->frame); /* unused */
1322 ASSERT_EQ(0,fd_head->offset); /* unused */
1323 ASSERT_EQ(110,fd_head->len); /* the length of data we have */
1324 ASSERT_EQ(1,fd_head->datalen); /* seqno of the last fragment we have */
1325 ASSERT_EQ(3,fd_head->reassembled_in);
1326 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
1327 ASSERT_NE(NULL,fd_head->tvb_data);
1328 ASSERT_NE(NULL,fd_head->next);
1330 ASSERT_EQ(1,fd_head->next->frame);
1331 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
1332 ASSERT_EQ(50,fd_head->next->len); /* segment length */
1333 ASSERT_EQ(0,fd_head->next->flags);
1334 ASSERT_EQ(NULL,fd_head->next->tvb_data);
1335 ASSERT_NE(NULL,fd_head->next->next);
1337 ASSERT_EQ(3,fd_head->next->next->frame);
1338 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
1339 ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
1340 ASSERT_EQ(0,fd_head->next->next->flags);
1341 ASSERT_EQ(NULL,fd_head->next->next->tvb_data);
1342 ASSERT_EQ(NULL,fd_head->next->next->next);
1344 /* test the actual reassembly */
1345 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
1346 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
1350 /* This tests the case where some data is missing from one of the fragments.
1351 * It should prevent reassembly.
1354 test_missing_data_fragment_add_seq_next(void)
1356 fragment_head *fd_head;
1358 printf("Starting test test_missing_data_fragment_add_seq_next\n");
1360 /* attempt to add a fragment which is longer than the data available */
1362 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1365 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1366 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1367 ASSERT_NE(NULL,fd_head);
1369 /* check the contents of the structure. Reassembly failed so everything
1370 * should be null (meaning, just use the original tvb) */
1371 ASSERT_EQ(0,fd_head->frame); /* unused */
1372 ASSERT_EQ(0,fd_head->offset); /* unused */
1373 ASSERT_EQ(0,fd_head->len); /* the length of data we have */
1374 ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
1375 ASSERT_EQ(0,fd_head->reassembled_in);
1376 ASSERT_EQ(FD_BLOCKSEQUENCE,fd_head->flags & 0x1ff);
1377 ASSERT_EQ(NULL,fd_head->tvb_data);
1378 ASSERT_EQ(NULL,fd_head->next);
1380 /* add another fragment (with all data present) */
1382 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1385 /* XXX: it's not clear that this is the right result; however it's what the
1388 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1389 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1390 ASSERT_EQ(NULL,fd_head);
1393 /* check what happens when we revisit the packets */
1394 pinfo.fd->flags.visited = TRUE;
1397 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1400 /* We just look in the reassembled_table for this packet. It never got put
1401 * there, so this always returns null.
1403 * That's crazy, because it means that the subdissector will see the data
1404 * exactly once - on the first pass through the capture (well, assuming it
1405 * doesn't bother to check fd_head->reassembled_in); however, that's
1406 * what the code does...
1408 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1409 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1410 ASSERT_EQ(NULL,fd_head);
1413 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1415 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1416 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1417 ASSERT_EQ(NULL,fd_head);
1422 * we're going to do something similar now, but this time it is the second
1423 * fragment which has something missing.
1426 test_missing_data_fragment_add_seq_next_2(void)
1428 fragment_head *fd_head;
1430 printf("Starting test test_missing_data_fragment_add_seq_next_2\n");
1433 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 10, &pinfo, 24, NULL,
1436 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1437 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1438 ASSERT_EQ(NULL,fd_head);
1441 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 24, NULL,
1444 /* XXX: again, i'm really dubious about this. Surely this should return all
1445 * the data we had, for a best-effort attempt at dissecting it?
1446 * And it ought to go into the reassembled table?
1448 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1449 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1450 ASSERT_EQ(NULL,fd_head);
1452 /* check what happens when we revisit the packets */
1453 pinfo.fd->flags.visited = TRUE;
1456 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 10, &pinfo, 24, NULL,
1459 /* As before, this returns NULL because the fragment isn't in the
1460 * reassembled_table. At least this is a bit more consistent than before.
1462 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1463 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1464 ASSERT_EQ(NULL,fd_head);
1467 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 24, NULL,
1469 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1470 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1471 ASSERT_EQ(NULL,fd_head);
1476 * This time, our datagram only has one segment, but it has data missing.
1479 test_missing_data_fragment_add_seq_next_3(void)
1481 fragment_head *fd_head;
1483 printf("Starting test test_missing_data_fragment_add_seq_next_3\n");
1486 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 30, NULL,
1489 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1490 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.reassembled_table));
1491 ASSERT_NE(NULL,fd_head);
1493 /* check the contents of the structure. */
1494 ASSERT_EQ(0,fd_head->frame); /* unused */
1495 ASSERT_EQ(0,fd_head->offset); /* unused */
1496 ASSERT_EQ(0,fd_head->len); /* the length of data we have */
1497 ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
1498 ASSERT_EQ(20,fd_head->reassembled_in);
1499 ASSERT_EQ(FD_BLOCKSEQUENCE|FD_DEFRAGMENTED,fd_head->flags);
1500 ASSERT_EQ(NULL,fd_head->tvb_data);
1501 ASSERT_EQ(NULL,fd_head->next);
1503 /* revisiting the packet ought to produce the same result. */
1504 pinfo.fd->flags.visited = TRUE;
1507 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 30, NULL,
1510 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1511 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.reassembled_table));
1512 ASSERT_NE(NULL,fd_head);
1513 ASSERT_EQ(0,fd_head->frame); /* unused */
1514 ASSERT_EQ(0,fd_head->offset); /* unused */
1515 ASSERT_EQ(0,fd_head->len); /* the length of data we have */
1516 ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
1517 ASSERT_EQ(20,fd_head->reassembled_in);
1518 ASSERT_EQ(FD_BLOCKSEQUENCE|FD_DEFRAGMENTED,fd_head->flags);
1519 ASSERT_EQ(NULL,fd_head->tvb_data);
1520 ASSERT_EQ(NULL,fd_head->next);
1524 /**********************************************************************************
1528 *********************************************************************************/
1531 main(int argc _U_, char **argv _U_)
1534 static const guint8 src[] = {1,2,3,4}, dst[] = {5,6,7,8};
1536 static void (*tests[])(void) = {
1537 test_simple_fragment_add_seq, /* frag table only */
1538 test_fragment_add_seq_partial_reassembly,
1539 test_fragment_add_seq_duplicate_first,
1540 test_fragment_add_seq_duplicate_middle,
1541 test_fragment_add_seq_duplicate_last,
1542 test_fragment_add_seq_duplicate_conflict,
1543 test_fragment_add_seq_check, /* frag + reassemble */
1544 test_fragment_add_seq_check_1,
1545 test_fragment_add_seq_802_11_0,
1546 test_fragment_add_seq_802_11_1,
1547 test_simple_fragment_add_seq_next,
1548 test_missing_data_fragment_add_seq_next,
1549 test_missing_data_fragment_add_seq_next_2,
1550 test_missing_data_fragment_add_seq_next_3,
1552 test_fragment_add_seq_check_multiple
1556 /* initialise stuff */
1559 /* a tvbuff for testing with */
1560 data = (char *)g_malloc(DATA_LEN);
1561 /* make sure it's full of stuff */
1562 for(i=0; i<DATA_LEN; i++) {
1565 tvb = tvb_new_real_data(data, DATA_LEN, DATA_LEN*2);
1567 /* other test stuff */
1569 fd.flags.visited = 0;
1570 SET_ADDRESS(&pinfo.src,AT_IPv4,4,src);
1571 SET_ADDRESS(&pinfo.dst,AT_IPv4,4,dst);
1573 /*************************************************************************/
1574 for(i=0; i < sizeof(tests)/sizeof(tests[0]); i++ ) {
1575 /* re-init the fragment tables */
1576 reassembly_table_init(&test_reassembly_table,
1577 &addresses_reassembly_table_functions);
1578 ASSERT(test_reassembly_table.fragment_table != NULL);
1579 ASSERT(test_reassembly_table.reassembled_table != NULL);
1581 pinfo.fd->flags.visited = FALSE;
1585 /* Free memory used by the tables */
1586 reassembly_table_destroy(&test_reassembly_table);
1594 printf(failure?"FAILURE\n":"SUCCESS\n");