more decompress
[wireshark-sm.git] / epan / reassemble_test.c
blobd0cecbf3ec3f0ae6aed6a4d49baaa272cf51d196
1 /* reassemble_test.c
2 * Standalone program to test functionality of reassemble.h API
4 * These aren't particularly complete - they just test a few corners of
5 * functionality which I was interested in. In particular, they only test the
6 * fragment_add_seq_* (ie, FD_BLOCKSEQUENCE) family of routines. However,
7 * hopefully they will inspire people to write additional tests, and provide a
8 * useful basis on which to do so.
10 * 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:
16 * env \
17 * G_DEBUG=gc-friendly \
18 * G_SLICE=always-malloc \
19 * valgrind --leak-check=full --show-reachable=yes ./reassemble_test
21 * Copyright (c) 2007 MX Telecom Ltd. <richardv@mxtelecom.com>
23 * Wireshark - Network traffic analyzer
24 * By Gerald Combs <gerald@wireshark.org>
25 * Copyright 1998
27 * SPDX-License-Identifier: GPL-2.0-or-later
30 #include <stdarg.h>
31 #include <stdlib.h>
32 #include <stdio.h>
33 #include <string.h>
35 #include <glib.h>
37 #include "config.h"
39 #include <epan/packet.h>
40 #include <epan/packet_info.h>
41 #include <epan/proto.h>
42 #include <epan/tvbuff.h>
43 #include <epan/reassemble.h>
45 #include "exceptions.h"
47 static int failure;
48 static const bool debug; /* Set to true to dump tables. */
50 #define ASSERT(b) \
51 if (!(b)) { \
52 failure = 1; \
53 printf("Assertion failed at line %i: %s\n", __LINE__, #b); \
54 exit(1); \
57 #define ASSERT_EQ(exp,act) \
58 if ((exp)!=(act)) { \
59 failure = 1; \
60 printf("Assertion failed at line %i: %s==%s (%u==%u)\n", __LINE__, #exp, #act, (unsigned)exp, (unsigned)act); \
61 exit(1); \
64 #define ASSERT_EQ_POINTER(exp,act) \
65 if ((exp)!=(act)) { \
66 failure = 1; \
67 printf("Assertion failed at line %i: %s==%s (%p==%p)\n", __LINE__, #exp, #act, (const void *)exp, (const void *)act); \
68 exit(1); \
71 #define ASSERT_NE_POINTER(exp,act) \
72 if ((exp)==(act)) { \
73 failure = 1; \
74 printf("Assertion failed at line %i: %s!=%s (%p!=%p)\n", __LINE__, #exp, #act, (const void *)exp, (const void *)act); \
75 exit(1); \
78 #define DATA_LEN 256
80 static uint8_t *data;
81 static tvbuff_t *tvb;
82 static packet_info pinfo;
84 /* fragment_table maps from datagram ids to fragment_head
85 reassembled_table maps from <packet number,datagram id> to
86 fragment_head */
87 static reassembly_table test_reassembly_table;
89 /*************************************************
90 * Util fcns to display
91 * fragment_table & reassembled_table fd-chains
92 ************************************************/
94 static struct _fd_flags {
95 uint32_t flag;
96 char *flag_name;
97 } fd_flags[] = {
98 {FD_DEFRAGMENTED ,"DF"},
99 {FD_DATALEN_SET ,"DS"},
100 {FD_SUBSET_TVB ,"ST"},
101 {FD_BLOCKSEQUENCE ,"BS"},
102 {FD_PARTIAL_REASSEMBLY ,"PR"},
103 {FD_OVERLAP ,"OL"},
104 {FD_OVERLAPCONFLICT ,"OC"},
105 {FD_MULTIPLETAILS ,"MT"},
106 {FD_TOOLONGFRAGMENT ,"TL"},
108 #define N_FD_FLAGS array_length(fd_flags)
110 static void
111 print_fd_head(fragment_head *fd) {
112 unsigned int i;
114 g_assert_true(fd != NULL);
115 printf(" %16p %16p %3u %3u", (void *)fd, (void *)(fd->next), fd->frame, fd->len);
117 printf(" %3u %3u", fd->datalen, fd->reassembled_in);
119 if (fd->tvb_data != NULL) {
120 printf(" %16p", tvb_get_ptr(fd->tvb_data, 0, 1)); /* Address of first byte only... */
121 } else {
122 printf(" %16s", "<null tvb_data>");
124 for (i = 0; i < N_FD_FLAGS; i++) {
125 printf(" %s", (fd->flags & fd_flags[i].flag) ? fd_flags[i].flag_name : " ");
127 printf("\n");
130 static void
131 print_fd_item(fragment_item *fd) {
132 unsigned int i;
134 g_assert_true(fd != NULL);
135 printf(" %16p %16p %3u %3u %3u", (void *)fd, (void *)(fd->next), fd->frame, fd->offset, fd->len);
136 printf( " ");
137 if (fd->tvb_data != NULL) {
138 printf(" %16p", tvb_get_ptr(fd->tvb_data, 0, 1)); /* Address of first byte only... */
139 } else {
140 printf(" %16s", "<null tvb_data>");
142 for (i = 0; i < N_FD_FLAGS; i++) {
143 printf(" %s", (fd->flags & fd_flags[i].flag) ? fd_flags[i].flag_name : " ");
145 printf("\n");
148 static void
149 print_fd_chain(fragment_head *fd_head) {
150 fragment_item *fdp;
152 g_assert_true(fd_head != NULL);
153 print_fd_head(fd_head);
154 for (fdp=fd_head->next; fdp != NULL; fdp=fdp->next) {
155 print_fd_item(fdp);
159 static void
160 print_fragment_table_chain(void *k _U_, void *v, void *ud _U_) {
161 #ifdef DUMP_KEYS
162 fragment_key *key = (fragment_key*)k;
163 #endif
164 fragment_head *fd_head = (fragment_head *)v;
165 #ifdef DUMP_KEYS
166 printf(" --> FT: %3d 0x%08x 0x%08x\n", key->id, *(uint32_t *)(key->src.data), *(uint32_t *)(key->dst.data));
167 #endif
168 print_fd_chain(fd_head);
171 static void
172 print_fragment_table(void) {
173 printf("\n Fragment Table -------\n");
174 g_hash_table_foreach(test_reassembly_table.fragment_table, print_fragment_table_chain, NULL);
177 static void
178 print_reassembled_table_chain(void *k _U_, void *v, void *ud _U_) {
179 #ifdef DUMP_KEYS
180 reassembled_key *key = (reassembled_key*)k;
181 #endif
182 fragment_head *fd_head = (fragment_head *)v;
183 #ifdef DUMP_KEYS
184 printf(" --> RT: %5d %5d\n", key->id, key->frame);
185 #endif
186 print_fd_chain(fd_head);
189 static void
190 print_reassembled_table(void) {
191 printf("\n Reassembled Table ----\n");
192 g_hash_table_foreach(test_reassembly_table.reassembled_table, print_reassembled_table_chain, NULL);
195 static void
196 print_tables(void) {
197 print_fragment_table();
198 print_reassembled_table();
201 /**********************************************************************************
203 * fragment_add_seq
205 *********************************************************************************/
207 /* Simple test case for fragment_add_seq.
208 * Adds three fragments (out of order, with one for a different datagram in between),
209 * and checks that they are reassembled correctly.
211 /* visit id frame frag len more tvb_offset
212 0 12 1 0 50 T 10
213 1 12 1 0 60 T 5
214 0 13 2 0 60 T 15
215 0 12 3 2 60 F 5
216 0 12 4 1 60 T 15
218 static void
219 test_simple_fragment_add_seq(void)
221 fragment_head *fd_head, *fdh0;
223 printf("Starting test test_simple_fragment_add_seq\n");
225 pinfo.num = 1;
226 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
227 0, 50, true, 0);
229 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
230 ASSERT_EQ_POINTER(NULL,fd_head);
232 /* adding the same fragment again should do nothing, even with different
233 * offset etc */
234 pinfo.fd->visited = 1;
235 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
236 0, 60, true, 0);
237 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
238 ASSERT_EQ_POINTER(NULL,fd_head);
240 /* start another pdu (just to confuse things) */
241 pinfo.fd->visited = 0;
242 pinfo.num = 2;
243 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 15, &pinfo, 13, NULL,
244 0, 60, true, 0);
245 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
246 ASSERT_EQ_POINTER(NULL,fd_head);
248 /* now we add the terminal fragment of the first datagram */
249 pinfo.num = 3;
250 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
251 2, 60, false, 0);
253 /* we haven't got all the fragments yet ... */
254 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
255 ASSERT_EQ_POINTER(NULL,fd_head);
257 /* finally, add the missing fragment */
258 pinfo.num = 4;
259 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 15, &pinfo, 12, NULL,
260 1, 60, true, 0);
262 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
263 ASSERT_NE_POINTER(NULL,fd_head);
265 /* check the contents of the structure */
266 ASSERT_EQ(4,fd_head->frame); /* max frame number of fragment in assembly */
267 ASSERT_EQ(170,fd_head->len); /* the length of data we have */
268 ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
269 ASSERT_EQ(4,fd_head->reassembled_in);
270 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
271 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
272 ASSERT_NE_POINTER(NULL,fd_head->next);
274 ASSERT_EQ(1,fd_head->next->frame);
275 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
276 ASSERT_EQ(50,fd_head->next->len); /* segment length */
277 ASSERT_EQ(0,fd_head->next->flags);
278 ASSERT_EQ_POINTER(NULL,fd_head->next->tvb_data);
279 ASSERT_NE_POINTER(NULL,fd_head->next->next);
281 ASSERT_EQ(4,fd_head->next->next->frame);
282 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
283 ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
284 ASSERT_EQ(0,fd_head->next->next->flags);
285 ASSERT_EQ_POINTER(NULL,fd_head->next->next->tvb_data);
286 ASSERT_NE_POINTER(NULL,fd_head->next->next->next);
288 ASSERT_EQ(3,fd_head->next->next->next->frame);
289 ASSERT_EQ(2,fd_head->next->next->next->offset); /* seqno */
290 ASSERT_EQ(60,fd_head->next->next->next->len); /* segment length */
291 ASSERT_EQ(0,fd_head->next->next->next->flags);
292 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->tvb_data);
293 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->next);
295 /* test the actual reassembly */
296 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
297 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+15,60));
298 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,60));
300 if (debug) {
301 print_fragment_table();
304 /* what happens if we revisit the packets now? */
305 fdh0 = fd_head;
306 pinfo.fd->visited = 1;
307 pinfo.num = 1;
308 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
309 0, 50, true, 0);
311 * this api relies on the caller to check fd_head -> reassembled_in
313 * Redoing all the tests seems like overkill - just check the pointer
315 ASSERT_EQ_POINTER(fdh0,fd_head);
317 pinfo.num = 3;
318 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
319 2, 60, false, 0);
320 ASSERT_EQ_POINTER(fdh0,fd_head);
322 pinfo.num = 4;
323 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 15, &pinfo, 12, NULL,
324 1, 60, true, 0);
325 ASSERT_EQ_POINTER(fdh0,fd_head);
327 if (debug) {
328 print_fragment_table();
332 /* XXX ought to have some tests for overlapping fragments */
334 /* This tests the functionality of fragment_set_partial_reassembly for
335 * FD_BLOCKSEQUENCE reassembly.
337 * We add a sequence of fragments thus:
338 * seqno frame offset len (initial) more_frags
339 * ----- ----- ------ --- --------------------
340 * 0 1 10 50 false
341 * 1 2 0 40 true
342 * 1 3 0 40 true (a duplicate fragment)
343 * 2 4 20 100 false
344 * 3 5 0 40 false
346 static void
347 test_fragment_add_seq_partial_reassembly(void)
349 fragment_head *fd_head;
350 fragment_item *fd;
352 printf("Starting test test_fragment_add_seq_partial_reassembly\n");
354 /* generally it's probably fair to assume that we will be called with
355 * more_frags=false.
357 pinfo.num = 1;
358 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
359 0, 50, false, 0);
361 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
362 ASSERT_NE_POINTER(NULL,fd_head);
364 /* check the contents of the structure */
365 ASSERT_EQ(1,fd_head->frame); /* max frame in reassembly */
366 ASSERT_EQ(50,fd_head->len); /* the length of data we have */
367 ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
368 ASSERT_EQ(1,fd_head->reassembled_in);
369 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
370 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
371 ASSERT_NE_POINTER(NULL,fd_head->next);
373 ASSERT_EQ(1,fd_head->next->frame);
374 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
375 ASSERT_EQ(50,fd_head->next->len); /* segment length */
376 ASSERT_EQ(0,fd_head->next->flags);
377 ASSERT_EQ_POINTER(NULL,fd_head->next->tvb_data);
378 ASSERT_EQ_POINTER(NULL,fd_head->next->next);
380 /* test the actual reassembly */
381 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
383 /* now we announce that the reassembly wasn't complete after all. */
384 fragment_set_partial_reassembly(&test_reassembly_table, &pinfo, 12, NULL);
386 /* and add another segment. To mix things up slightly (and so that we can
387 * check on the state of things), we're going to set the more_frags flag
388 * here
390 pinfo.num = 2;
391 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
392 1, 40, true, 0);
394 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
395 ASSERT_EQ_POINTER(NULL,fd_head);
397 fd_head=fragment_get(&test_reassembly_table, &pinfo, 12, NULL);
398 ASSERT_NE_POINTER(NULL,fd_head);
400 /* check the contents of the structure */
401 ASSERT_EQ(2,fd_head->frame); /* max frame in reassembly */
402 /* ASSERT_EQ(50,fd_head->len); the length of data we have */
403 ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
404 ASSERT_EQ(0,fd_head->reassembled_in);
405 ASSERT_EQ(FD_BLOCKSEQUENCE,fd_head->flags);
406 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
407 ASSERT_NE_POINTER(NULL,fd_head->next);
409 fd=fd_head->next;
410 ASSERT_EQ(1,fd->frame);
411 ASSERT_EQ(0,fd->offset); /* seqno */
412 ASSERT_EQ(50,fd->len); /* segment length */
413 ASSERT_EQ(FD_SUBSET_TVB,fd->flags);
414 ASSERT_EQ_POINTER(tvb_get_ptr(fd_head->tvb_data,0,0),tvb_get_ptr(fd->tvb_data,0,0));
415 ASSERT_NE_POINTER(NULL,fd->next);
417 fd=fd->next;
418 ASSERT_EQ(2,fd->frame);
419 ASSERT_EQ(1,fd->offset); /* seqno */
420 ASSERT_EQ(40,fd->len); /* segment length */
421 ASSERT_EQ(0,fd->flags);
422 ASSERT_NE_POINTER(NULL,fd->tvb_data);
423 ASSERT_EQ_POINTER(NULL,fd->next);
425 /* Another copy of the second segment.
427 pinfo.num = 3;
428 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
429 1, 40, true, 0);
431 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
432 ASSERT_EQ_POINTER(NULL,fd_head);
433 fd_head=fragment_get(&test_reassembly_table, &pinfo, 12, NULL);
434 ASSERT_NE_POINTER(NULL,fd_head);
435 ASSERT_EQ(3,fd_head->frame); /* max frame we have */
436 /* ASSERT_EQ(50,fd_head->len); the length of data we have */
437 ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
438 ASSERT_EQ(0,fd_head->reassembled_in);
439 ASSERT_EQ(FD_BLOCKSEQUENCE,fd_head->flags);
440 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
441 ASSERT_NE_POINTER(NULL,fd_head->next);
443 fd=fd_head->next;
444 ASSERT_EQ(1,fd->frame);
445 ASSERT_EQ(0,fd->offset); /* seqno */
446 ASSERT_EQ(50,fd->len); /* segment length */
447 ASSERT_EQ(FD_SUBSET_TVB,fd->flags);
448 ASSERT_EQ_POINTER(tvb_get_ptr(fd_head->tvb_data,0,0),tvb_get_ptr(fd->tvb_data,0,0));
449 ASSERT_NE_POINTER(NULL,fd->next);
451 fd=fd->next;
452 ASSERT_EQ(2,fd->frame);
453 ASSERT_EQ(1,fd->offset); /* seqno */
454 ASSERT_EQ(40,fd->len); /* segment length */
455 ASSERT_EQ(0,fd->flags);
456 ASSERT_NE_POINTER(NULL,fd->tvb_data);
457 ASSERT_NE_POINTER(NULL,fd->next);
459 fd=fd->next;
460 ASSERT_EQ(3,fd->frame);
461 ASSERT_EQ(1,fd->offset); /* seqno */
462 ASSERT_EQ(40,fd->len); /* segment length */
463 ASSERT_EQ(0,fd->flags);
464 ASSERT_NE_POINTER(NULL,fd->tvb_data);
465 ASSERT_EQ_POINTER(NULL,fd->next);
469 /* have another go at wrapping things up */
470 pinfo.num = 4;
471 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 20, &pinfo, 12, NULL,
472 2, 100, false, 0);
474 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
475 ASSERT_NE_POINTER(NULL,fd_head);
477 /* check the contents of the structure */
478 ASSERT_EQ(4,fd_head->frame); /* max frame we have */
479 ASSERT_EQ(190,fd_head->len); /* the length of data we have */
480 ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
481 ASSERT_EQ(4,fd_head->reassembled_in);
482 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
483 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
484 ASSERT_NE_POINTER(NULL,fd_head->next);
486 fd=fd_head->next;
487 ASSERT_EQ(1,fd->frame);
488 ASSERT_EQ(0,fd->offset); /* seqno */
489 ASSERT_EQ(50,fd->len); /* segment length */
490 ASSERT_EQ(0,fd->flags);
491 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
492 ASSERT_NE_POINTER(NULL,fd->next);
494 fd=fd->next;
495 ASSERT_EQ(2,fd->frame);
496 ASSERT_EQ(1,fd->offset); /* seqno */
497 ASSERT_EQ(40,fd->len); /* segment length */
498 ASSERT_EQ(0,fd->flags);
499 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
500 ASSERT_NE_POINTER(NULL,fd->next);
502 fd=fd->next;
503 ASSERT_EQ(3,fd->frame);
504 ASSERT_EQ(1,fd->offset); /* seqno */
505 ASSERT_EQ(40,fd->len); /* segment length */
506 ASSERT_EQ(FD_OVERLAP,fd->flags);
507 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
508 ASSERT_NE_POINTER(NULL,fd->next);
510 fd=fd->next;
511 ASSERT_EQ(4,fd->frame);
512 ASSERT_EQ(2,fd->offset); /* seqno */
513 ASSERT_EQ(100,fd->len); /* segment length */
514 ASSERT_EQ(0,fd->flags);
515 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
516 ASSERT_EQ_POINTER(NULL,fd->next);
518 /* test the actual reassembly */
519 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
520 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data,40));
521 ASSERT(!tvb_memeql(fd_head->tvb_data,90,data+20,100));
524 /* do it again (this time it is more complicated, with an overlap in the
525 * reassembly) */
527 fragment_set_partial_reassembly(&test_reassembly_table, &pinfo, 12, NULL);
529 pinfo.num = 5;
530 fragment_add_seq(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
531 3, 40, false, 0);
533 fd_head=fragment_get(&test_reassembly_table, &pinfo, 12, NULL);
534 ASSERT_NE_POINTER(NULL,fd_head);
535 ASSERT_EQ(5,fd_head->frame); /* max frame we have */
536 ASSERT_EQ(230,fd_head->len); /* the length of data we have */
537 ASSERT_EQ(3,fd_head->datalen); /* seqno of the last fragment we have */
538 ASSERT_EQ(5,fd_head->reassembled_in);
539 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
540 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
541 ASSERT_NE_POINTER(NULL,fd_head->next);
543 fd=fd_head->next;
544 ASSERT_EQ(1,fd->frame);
545 ASSERT_EQ(0,fd->offset); /* seqno */
546 ASSERT_EQ(50,fd->len); /* segment length */
547 ASSERT_EQ(0,fd->flags);
548 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
549 ASSERT_NE_POINTER(NULL,fd->next);
551 fd=fd->next;
552 ASSERT_EQ(2,fd->frame);
553 ASSERT_EQ(1,fd->offset); /* seqno */
554 ASSERT_EQ(40,fd->len); /* segment length */
555 ASSERT_EQ(0,fd->flags);
556 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
557 ASSERT_NE_POINTER(NULL,fd->next);
559 fd=fd->next;
560 ASSERT_EQ(3,fd->frame);
561 ASSERT_EQ(1,fd->offset); /* seqno */
562 ASSERT_EQ(40,fd->len); /* segment length */
563 ASSERT_EQ(FD_OVERLAP,fd->flags);
564 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
565 ASSERT_NE_POINTER(NULL,fd->next);
567 fd=fd->next;
568 ASSERT_EQ(4,fd->frame);
569 ASSERT_EQ(2,fd->offset); /* seqno */
570 ASSERT_EQ(100,fd->len); /* segment length */
571 ASSERT_EQ(0,fd->flags);
572 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
573 ASSERT_NE_POINTER(NULL,fd->next);
575 fd=fd->next;
576 ASSERT_EQ(5,fd->frame);
577 ASSERT_EQ(3,fd->offset); /* seqno */
578 ASSERT_EQ(40,fd->len); /* segment length */
579 ASSERT_EQ(0,fd->flags);
580 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
581 ASSERT_EQ_POINTER(NULL,fd->next);
583 /* test the actual reassembly */
584 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
585 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data,40));
586 ASSERT(!tvb_memeql(fd_head->tvb_data,90,data+20,100));
587 ASSERT(!tvb_memeql(fd_head->tvb_data,190,data,40));
590 /* Test case for fragment_add_seq with duplicated (e.g., retransmitted) data.
591 * Adds three fragments--adding the 1st one twice--
592 * and checks that they are reassembled correctly.
594 /* visit id frame frag len more tvb_offset
595 0 12 1 0 50 T 10
596 0 12 2 1 60 T 5
597 0 12 3 2 40 F 5
598 0 12 4 0 50 T 10
600 static void
601 test_fragment_add_seq_duplicate_first(void)
603 fragment_head *fd_head;
605 printf("Starting test test_fragment_add_seq_duplicate_first\n");
607 pinfo.num = 1;
608 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
609 0, 50, true, 0);
611 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
612 ASSERT_EQ_POINTER(NULL,fd_head);
614 /* Add the 2nd segment */
615 pinfo.num = 2;
616 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
617 1, 60, true, 0);
619 /* we haven't got all the fragments yet ... */
620 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
621 ASSERT_EQ_POINTER(NULL,fd_head);
623 /* Add the last fragment */
624 pinfo.num = 3;
625 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
626 2, 40, false, 0);
628 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
629 ASSERT_NE_POINTER(NULL,fd_head);
631 /* Add the first fragment again */
632 pinfo.num = 4;
633 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
634 0, 50, true, 0);
636 /* Reassembly should have still succeeded */
637 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
638 ASSERT_NE_POINTER(NULL,fd_head);
640 /* check the contents of the structure */
641 ASSERT_EQ(4,fd_head->frame); /* max frame we have */
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_POINTER(NULL,fd_head->tvb_data);
647 ASSERT_NE_POINTER(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_POINTER(NULL,fd_head->next->tvb_data);
654 ASSERT_NE_POINTER(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_POINTER(NULL,fd_head->next->next->tvb_data);
661 ASSERT_NE_POINTER(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_POINTER(NULL,fd_head->next->next->next->tvb_data);
668 ASSERT_NE_POINTER(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_POINTER(NULL,fd_head->next->next->next->next->tvb_data);
675 ASSERT_EQ_POINTER(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));
682 if (debug) {
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
693 0 12 1 0 50 T 10
694 0 12 2 1 60 T 5
695 0 12 3 1 60 T 5
696 0 12 4 3 40 F 5
698 static void
699 test_fragment_add_seq_duplicate_middle(void)
701 fragment_head *fd_head;
703 printf("Starting test test_fragment_add_seq_duplicate_middle\n");
705 pinfo.num = 1;
706 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
707 0, 50, true, 0);
709 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
710 ASSERT_EQ_POINTER(NULL,fd_head);
712 /* Add the 2nd segment */
713 pinfo.num = 2;
714 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
715 1, 60, true, 0);
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_POINTER(NULL,fd_head);
721 /* Now, add the 2nd segment again (but in a different frame) */
722 pinfo.num = 3;
723 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
724 1, 60, true, 0);
726 /* This duplicate fragment should have been ignored */
727 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
728 ASSERT_EQ_POINTER(NULL,fd_head);
730 /* finally, add the last fragment */
731 pinfo.num = 4;
732 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
733 2, 40, false, 0);
735 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
736 ASSERT_NE_POINTER(NULL,fd_head);
738 /* check the contents of the structure */
739 ASSERT_EQ(4,fd_head->frame); /* max frame we have */
740 ASSERT_EQ(150,fd_head->len); /* the length of data we have */
741 ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
742 ASSERT_EQ(4,fd_head->reassembled_in);
743 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
744 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
745 ASSERT_NE_POINTER(NULL,fd_head->next);
747 ASSERT_EQ(1,fd_head->next->frame);
748 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
749 ASSERT_EQ(50,fd_head->next->len); /* segment length */
750 ASSERT_EQ(0,fd_head->next->flags);
751 ASSERT_EQ_POINTER(NULL,fd_head->next->tvb_data);
752 ASSERT_NE_POINTER(NULL,fd_head->next->next);
754 ASSERT_EQ(2,fd_head->next->next->frame);
755 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
756 ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
757 ASSERT_EQ(0,fd_head->next->next->flags);
758 ASSERT_EQ_POINTER(NULL,fd_head->next->next->tvb_data);
759 ASSERT_NE_POINTER(NULL,fd_head->next->next->next);
761 ASSERT_EQ(3,fd_head->next->next->next->frame);
762 ASSERT_EQ(1,fd_head->next->next->next->offset); /* seqno */
763 ASSERT_EQ(60,fd_head->next->next->next->len); /* segment length */
764 ASSERT_EQ(FD_OVERLAP,fd_head->next->next->next->flags);
765 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->tvb_data);
766 ASSERT_NE_POINTER(NULL,fd_head->next->next->next->next);
768 ASSERT_EQ(4,fd_head->next->next->next->next->frame);
769 ASSERT_EQ(2,fd_head->next->next->next->next->offset); /* seqno */
770 ASSERT_EQ(40,fd_head->next->next->next->next->len); /* segment length */
771 ASSERT_EQ(0,fd_head->next->next->next->next->flags);
772 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->next->tvb_data);
773 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->next->next);
775 /* test the actual reassembly */
776 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
777 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
778 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
780 if (debug) {
781 print_fragment_table();
785 /* Test case for fragment_add_seq with duplicated (e.g., retransmitted) data.
786 * Adds three fragments--adding the 3rd one twice--
787 * and checks that they are reassembled correctly.
789 /* visit id frame frag len more tvb_offset
790 0 12 1 0 50 T 10
791 0 12 2 1 60 T 5
792 0 12 3 2 40 F 5
793 0 12 4 2 40 F 5
795 static void
796 test_fragment_add_seq_duplicate_last(void)
798 fragment_head *fd_head;
800 printf("Starting test test_fragment_add_seq_duplicate_last\n");
802 pinfo.num = 1;
803 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
804 0, 50, true, 0);
806 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
807 ASSERT_EQ_POINTER(NULL,fd_head);
809 /* Add the 2nd segment */
810 pinfo.num = 2;
811 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
812 1, 60, true, 0);
814 /* we haven't got all the fragments yet ... */
815 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
816 ASSERT_EQ_POINTER(NULL,fd_head);
818 /* Add the last fragment */
819 pinfo.num = 3;
820 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
821 2, 40, false, 0);
823 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
824 ASSERT_NE_POINTER(NULL,fd_head);
826 /* Add the last fragment again */
827 pinfo.num = 4;
828 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
829 2, 40, false, 0);
831 /* Reassembly should have still succeeded */
832 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
833 ASSERT_NE_POINTER(NULL,fd_head);
835 /* check the contents of the structure */
836 ASSERT_EQ(4,fd_head->frame); /* max frame we have */
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_POINTER(NULL,fd_head->tvb_data);
842 ASSERT_NE_POINTER(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_POINTER(NULL,fd_head->next->tvb_data);
849 ASSERT_NE_POINTER(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_POINTER(NULL,fd_head->next->next->tvb_data);
856 ASSERT_NE_POINTER(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_POINTER(NULL,fd_head->next->next->next->tvb_data);
863 ASSERT_NE_POINTER(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_POINTER(NULL,fd_head->next->next->next->next->tvb_data);
870 ASSERT_EQ_POINTER(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));
877 if (debug) {
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
889 0 12 1 0 50 T 10
890 0 12 2 1 60 T 5
891 0 12 3 1 60 T 15
892 0 12 4 2 40 F 5
894 static void
895 test_fragment_add_seq_duplicate_conflict(void)
897 fragment_head *fd_head;
899 printf("Starting test test_fragment_add_seq_duplicate_conflict\n");
901 pinfo.num = 1;
902 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
903 0, 50, true, 0);
905 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
906 ASSERT_EQ_POINTER(NULL,fd_head);
908 /* Add the 2nd segment */
909 pinfo.num = 2;
910 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
911 1, 60, true, 0);
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_POINTER(NULL,fd_head);
917 /* Now, add the 2nd segment again (but in a different frame and with
918 * different data)
920 pinfo.num = 3;
921 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 15, &pinfo, 12, NULL,
922 1, 60, true, 0);
924 /* This duplicate fragment should have been ignored */
925 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
926 ASSERT_EQ_POINTER(NULL,fd_head);
928 /* finally, add the last fragment */
929 pinfo.num = 4;
930 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
931 2, 40, false, 0);
933 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
934 ASSERT_NE_POINTER(NULL,fd_head);
936 /* check the contents of the structure */
937 ASSERT_EQ(4,fd_head->frame); /* max frame we have */
938 ASSERT_EQ(150,fd_head->len); /* the length of data we have */
939 ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
940 ASSERT_EQ(4,fd_head->reassembled_in);
941 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP|FD_OVERLAPCONFLICT,fd_head->flags);
942 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
943 ASSERT_NE_POINTER(NULL,fd_head->next);
945 ASSERT_EQ(1,fd_head->next->frame);
946 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
947 ASSERT_EQ(50,fd_head->next->len); /* segment length */
948 ASSERT_EQ(0,fd_head->next->flags);
949 ASSERT_EQ_POINTER(NULL,fd_head->next->tvb_data);
950 ASSERT_NE_POINTER(NULL,fd_head->next->next);
952 ASSERT_EQ(2,fd_head->next->next->frame);
953 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
954 ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
955 ASSERT_EQ(0,fd_head->next->next->flags);
956 ASSERT_EQ_POINTER(NULL,fd_head->next->next->tvb_data);
957 ASSERT_NE_POINTER(NULL,fd_head->next->next->next);
959 ASSERT_EQ(3,fd_head->next->next->next->frame);
960 ASSERT_EQ(1,fd_head->next->next->next->offset); /* seqno */
961 ASSERT_EQ(60,fd_head->next->next->next->len); /* segment length */
962 ASSERT_EQ(FD_OVERLAP|FD_OVERLAPCONFLICT,fd_head->next->next->next->flags);
963 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->tvb_data);
964 ASSERT_NE_POINTER(NULL,fd_head->next->next->next->next);
966 ASSERT_EQ(4,fd_head->next->next->next->next->frame);
967 ASSERT_EQ(2,fd_head->next->next->next->next->offset); /* seqno */
968 ASSERT_EQ(40,fd_head->next->next->next->next->len); /* segment length */
969 ASSERT_EQ(0,fd_head->next->next->next->next->flags);
970 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->next->tvb_data);
971 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->next->next);
973 /* test the actual reassembly */
974 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
975 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
976 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
978 if (debug) {
979 print_fragment_table();
983 /**********************************************************************************
985 * fragment_add_seq_check
987 *********************************************************************************/
990 /* This routine is used for both fragment_add_seq_802_11 and
991 * fragment_add_seq_check.
993 * Adds a couple of out-of-order fragments and checks their reassembly.
996 /* visit id frame frag len more tvb_offset
997 0 12 1 0 50 T 10
998 0 13 2 0 60 T 15
999 0 12 3 2 60 F 5
1000 0 12 4 1 60 F 15
1004 static void
1005 test_fragment_add_seq_check_work(fragment_head *(*fn)(reassembly_table *,
1006 tvbuff_t *, const int, const packet_info *,
1007 const uint32_t, const void *, const uint32_t,
1008 const uint32_t, const bool))
1010 fragment_head *fd_head;
1012 pinfo.num = 1;
1013 fd_head=fn(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1014 0, 50, true);
1016 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1017 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1018 ASSERT_EQ_POINTER(NULL,fd_head);
1020 /* start another pdu (just to confuse things) */
1021 pinfo.num = 2;
1022 fd_head=fn(&test_reassembly_table, tvb, 15, &pinfo, 13, NULL,
1023 0, 60, true);
1024 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
1025 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1026 ASSERT_EQ_POINTER(NULL,fd_head);
1028 /* add the terminal fragment of the first datagram */
1029 pinfo.num = 3;
1030 fd_head=fn(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1031 2, 60, false);
1033 /* we haven't got all the fragments yet ... */
1034 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
1035 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1036 ASSERT_EQ_POINTER(NULL,fd_head);
1038 /* finally, add the missing fragment */
1039 pinfo.num = 4;
1040 fd_head=fn(&test_reassembly_table, tvb, 15, &pinfo, 12, NULL,
1041 1, 60, true);
1043 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1044 ASSERT_EQ(3,g_hash_table_size(test_reassembly_table.reassembled_table));
1045 ASSERT_NE_POINTER(NULL,fd_head);
1047 /* check the contents of the structure */
1048 ASSERT_EQ(4,fd_head->frame); /* max frame we have */
1049 ASSERT_EQ(170,fd_head->len); /* the length of data we have */
1050 ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
1051 ASSERT_EQ(4,fd_head->reassembled_in);
1052 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
1053 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
1054 ASSERT_NE_POINTER(NULL,fd_head->next);
1056 ASSERT_EQ(1,fd_head->next->frame);
1057 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
1058 ASSERT_EQ(50,fd_head->next->len); /* segment length */
1059 ASSERT_EQ(0,fd_head->next->flags);
1060 ASSERT_EQ_POINTER(NULL,fd_head->next->tvb_data);
1061 ASSERT_NE_POINTER(NULL,fd_head->next->next);
1063 ASSERT_EQ(4,fd_head->next->next->frame);
1064 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
1065 ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
1066 ASSERT_EQ(0,fd_head->next->next->flags);
1067 ASSERT_EQ_POINTER(NULL,fd_head->next->next->tvb_data);
1068 ASSERT_NE_POINTER(NULL,fd_head->next->next->next);
1070 ASSERT_EQ(3,fd_head->next->next->next->frame);
1071 ASSERT_EQ(2,fd_head->next->next->next->offset); /* seqno */
1072 ASSERT_EQ(60,fd_head->next->next->next->len); /* segment length */
1073 ASSERT_EQ(0,fd_head->next->next->next->flags);
1074 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->tvb_data);
1075 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->next);
1077 /* test the actual reassembly */
1078 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
1079 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+15,60));
1080 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,60));
1082 if (debug) {
1083 print_tables();
1087 /* Simple test case for fragment_add_seq_check
1089 static void
1090 test_fragment_add_seq_check(void)
1092 printf("Starting test test_fragment_add_seq_check\n");
1094 test_fragment_add_seq_check_work(fragment_add_seq_check);
1098 /* This tests the case that the 802.11 hack does something different for: when
1099 * the terminal segment in a fragmented datagram arrives first.
1101 static void
1102 test_fragment_add_seq_check_1(void)
1104 fragment_head *fd_head;
1106 printf("Starting test test_fragment_add_seq_check_1\n");
1108 pinfo.num = 1;
1109 fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1110 1, 50, false);
1112 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1113 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1114 ASSERT_EQ_POINTER(NULL,fd_head);
1116 /* Now add the missing segment */
1117 pinfo.num = 2;
1118 fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1119 0, 60, true);
1121 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1122 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.reassembled_table));
1123 ASSERT_NE_POINTER(NULL,fd_head);
1125 /* check the contents of the structure */
1126 ASSERT_EQ(2,fd_head->frame); /* max frame of fragment in structure */
1127 ASSERT_EQ(110,fd_head->len); /* the length of data we have */
1128 ASSERT_EQ(1,fd_head->datalen); /* seqno of the last fragment we have */
1129 ASSERT_EQ(2,fd_head->reassembled_in);
1130 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
1131 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
1132 ASSERT_NE_POINTER(NULL,fd_head->next);
1134 ASSERT_EQ(2,fd_head->next->frame);
1135 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
1136 ASSERT_EQ(60,fd_head->next->len); /* segment length */
1137 ASSERT_EQ(0,fd_head->next->flags);
1138 ASSERT_EQ_POINTER(NULL,fd_head->next->tvb_data);
1139 ASSERT_NE_POINTER(NULL,fd_head->next->next);
1141 ASSERT_EQ(1,fd_head->next->next->frame);
1142 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
1143 ASSERT_EQ(50,fd_head->next->next->len); /* segment length */
1144 ASSERT_EQ(0,fd_head->next->next->flags);
1145 ASSERT_EQ_POINTER(NULL,fd_head->next->next->tvb_data);
1146 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next);
1148 /* test the actual reassembly */
1149 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+5,60));
1150 ASSERT(!tvb_memeql(fd_head->tvb_data,60,data+10,50));
1153 /**********************************************************************************
1155 * fragment_add_seq_802_11
1157 *********************************************************************************/
1159 /* Tests the 802.11 hack.
1161 static void
1162 test_fragment_add_seq_802_11_0(void)
1164 fragment_head *fd_head;
1166 printf("Starting test test_fragment_add_seq_802_11_0\n");
1168 /* the 802.11 hack is that some non-fragmented datagrams have non-zero
1169 * fragment_number; test for this. */
1171 pinfo.num = 1;
1172 fd_head=fragment_add_seq_802_11(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1173 10, 50, false);
1175 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1176 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.reassembled_table));
1177 ASSERT_NE_POINTER(NULL,fd_head);
1179 /* check the contents of the structure */
1180 ASSERT_EQ(0,fd_head->frame); /* unused */
1181 ASSERT_EQ(0,fd_head->len); /* unused */
1182 ASSERT_EQ(0,fd_head->datalen); /* unused */
1183 ASSERT_EQ(1,fd_head->reassembled_in);
1184 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE,fd_head->flags);
1185 ASSERT_EQ_POINTER(NULL,fd_head->tvb_data);
1186 ASSERT_EQ_POINTER(NULL,fd_head->next);
1189 /* Reuse the fragment_add_seq_check testcases */
1190 static void test_fragment_add_seq_802_11_1(void)
1192 printf("Starting test test_fragment_add_seq_802_11_1\n");
1193 test_fragment_add_seq_check_work(fragment_add_seq_802_11);
1196 /**********************************************************************************
1198 * fragment_add_seq_check_multiple
1200 *********************************************************************************/
1202 /* Test 2 partial frags from 2 diff datagrams in the same frame */
1204 datagram #1: frame 1 + first part of frame 2
1205 datagram #1: last part of frame 2 + frame 3
1207 Is this a valid scenario ?
1209 The result of calling fragment_add_seq_check(&test_reassembly_table, ) for these
1210 fragments is a reassembled_table with:
1211 id, frame 1 => first_datagram; ["reassembled in" frame 2]
1212 id, frame 2 => second_datagram; ["reassembled in" frame 3]
1213 id, frame 3 => second_datagram;
1215 Note that the id, frame 2 => first datagram was overwritten
1216 by the entry for the second datagram.
1217 Is this OK ? IE: When dissected/displayed
1218 will the reassembled datagram 1 appear with frame 2 ??
1221 /* visit id frame frag len more tvb_offset
1222 0 12 1 0 50 T 10
1223 0 12 2 1 20 F 5
1224 0 12 2 0 25 T 25
1225 0 12 3 1 60 F 0
1229 Is this a valid scenario ?
1230 Is this OK ? IE: When dissected/displayed:
1231 Will the reassembled datagram 1 appear with frame 2 ??
1233 #if 0
1234 static void
1235 test_fragment_add_seq_check_multiple(void) {
1236 fragment_head *fd_head;
1238 pinfo.num = 1;
1239 fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1240 0, 50, true);
1242 /* add the terminal fragment of the first datagram */
1243 pinfo.num = 2;
1244 fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1245 1, 20, false);
1247 print_tables();
1249 /* Now: start a second datagram with the first fragment in frame #2 */
1250 pinfo.num = 2;
1251 fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 25, &pinfo, 12, NULL,
1252 0, 25, true);
1254 /* add the terminal fragment of the second datagram */
1255 pinfo.num = 3;
1256 fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
1257 1, 60, false);
1259 print_tables();
1261 #endif
1263 /**********************************************************************************
1265 * fragment_add_seq_next
1267 *********************************************************************************/
1269 /* Simple test case for fragment_add_seq_next.
1270 * Adds a couple of fragments (with one for a different datagram in between),
1271 * and checks that they are reassembled correctly.
1273 static void
1274 test_simple_fragment_add_seq_next(void)
1276 fragment_head *fd_head;
1278 printf("Starting test test_simple_fragment_add_seq_next\n");
1280 pinfo.num = 1;
1281 fd_head= fragment_add_seq_next(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1282 50, true);
1284 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1285 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1286 ASSERT_EQ_POINTER(NULL,fd_head);
1288 /* adding the same fragment again should do nothing, even with different
1289 * offset etc */
1290 pinfo.fd->visited = 1;
1291 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1292 60, true);
1293 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1294 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1295 ASSERT_EQ_POINTER(NULL,fd_head);
1297 /* start another pdu (just to confuse things) */
1298 pinfo.fd->visited = 0;
1299 pinfo.num = 2;
1300 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 15, &pinfo, 13, NULL,
1301 60, true);
1302 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
1303 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1304 ASSERT_EQ_POINTER(NULL,fd_head);
1307 /* now we add the terminal fragment of the first datagram */
1308 pinfo.num = 3;
1309 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1310 60, false);
1312 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1313 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.reassembled_table));
1314 ASSERT_NE_POINTER(NULL,fd_head);
1316 /* check the contents of the structure */
1317 ASSERT_EQ(3,fd_head->frame); /* max frame we have */
1318 ASSERT_EQ(110,fd_head->len); /* the length of data we have */
1319 ASSERT_EQ(1,fd_head->datalen); /* seqno of the last fragment we have */
1320 ASSERT_EQ(3,fd_head->reassembled_in);
1321 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
1322 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
1323 ASSERT_NE_POINTER(NULL,fd_head->next);
1325 ASSERT_EQ(1,fd_head->next->frame);
1326 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
1327 ASSERT_EQ(50,fd_head->next->len); /* segment length */
1328 ASSERT_EQ(0,fd_head->next->flags);
1329 ASSERT_EQ_POINTER(NULL,fd_head->next->tvb_data);
1330 ASSERT_NE_POINTER(NULL,fd_head->next->next);
1332 ASSERT_EQ(3,fd_head->next->next->frame);
1333 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
1334 ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
1335 ASSERT_EQ(0,fd_head->next->next->flags);
1336 ASSERT_EQ_POINTER(NULL,fd_head->next->next->tvb_data);
1337 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next);
1339 /* test the actual reassembly */
1340 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
1341 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
1345 #if 0
1346 /* XXX remove this? fragment_add_seq does not have the special case for
1347 * fragments having truncated tvbs anymore! */
1348 /* This tests the case where some data is missing from one of the fragments.
1349 * It should prevent reassembly.
1351 static void
1352 test_missing_data_fragment_add_seq_next(void)
1354 fragment_head *fd_head;
1356 printf("Starting test test_missing_data_fragment_add_seq_next\n");
1358 /* attempt to add a fragment which is longer than the data available */
1359 pinfo.num = 1;
1360 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1361 DATA_LEN-9, true);
1363 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1364 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1365 ASSERT_NE_POINTER(NULL,fd_head);
1367 /* check the contents of the structure. Reassembly failed so everything
1368 * should be null (meaning, just use the original tvb) */
1369 ASSERT_EQ(0,fd_head->frame); /* unused */
1370 ASSERT_EQ(0,fd_head->len); /* the length of data we have */
1371 ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
1372 ASSERT_EQ(0,fd_head->reassembled_in);
1373 ASSERT_EQ(FD_BLOCKSEQUENCE,fd_head->flags & 0x1ff);
1374 ASSERT_EQ_POINTER(NULL,fd_head->tvb_data);
1375 ASSERT_EQ_POINTER(NULL,fd_head->next);
1377 /* add another fragment (with all data present) */
1378 pinfo.num = 4;
1379 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1380 60, false);
1382 /* XXX: it's not clear that this is the right result; however it's what the
1383 * code does...
1385 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1386 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1387 ASSERT_EQ_POINTER(NULL,fd_head);
1390 /* check what happens when we revisit the packets */
1391 pinfo.fd->visited = true;
1392 pinfo.num = 1;
1394 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1395 DATA_LEN-9, true);
1397 /* We just look in the reassembled_table for this packet. It never got put
1398 * there, so this always returns null.
1400 * That's crazy, because it means that the subdissector will see the data
1401 * exactly once - on the first pass through the capture (well, assuming it
1402 * doesn't bother to check fd_head->reassembled_in); however, that's
1403 * what the code does...
1405 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1406 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1407 ASSERT_EQ_POINTER(NULL,fd_head);
1409 pinfo.num = 4;
1410 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1411 60, false);
1412 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1413 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1414 ASSERT_EQ_POINTER(NULL,fd_head);
1419 * we're going to do something similar now, but this time it is the second
1420 * fragment which has something missing.
1422 static void
1423 test_missing_data_fragment_add_seq_next_2(void)
1425 fragment_head *fd_head;
1427 printf("Starting test test_missing_data_fragment_add_seq_next_2\n");
1429 pinfo.num = 11;
1430 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 10, &pinfo, 24, NULL,
1431 50, true);
1433 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1434 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1435 ASSERT_EQ_POINTER(NULL,fd_head);
1437 pinfo.num = 12;
1438 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 24, NULL,
1439 DATA_LEN-4, false);
1441 /* XXX: again, i'm really dubious about this. Surely this should return all
1442 * the data we had, for a best-effort attempt at dissecting it?
1443 * And it ought to go into the reassembled table?
1445 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1446 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1447 ASSERT_EQ_POINTER(NULL,fd_head);
1449 /* check what happens when we revisit the packets */
1450 pinfo.fd->visited = true;
1451 pinfo.num = 11;
1453 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 10, &pinfo, 24, NULL,
1454 50, true);
1456 /* As before, this returns NULL because the fragment isn't in the
1457 * reassembled_table. At least this is a bit more consistent than before.
1459 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1460 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1461 ASSERT_EQ_POINTER(NULL,fd_head);
1463 pinfo.num = 12;
1464 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 24, NULL,
1465 DATA_LEN-4, false);
1466 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1467 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1468 ASSERT_EQ_POINTER(NULL,fd_head);
1473 * This time, our datagram only has one segment, but it has data missing.
1475 static void
1476 test_missing_data_fragment_add_seq_next_3(void)
1478 fragment_head *fd_head;
1480 printf("Starting test test_missing_data_fragment_add_seq_next_3\n");
1482 pinfo.num = 20;
1483 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 30, NULL,
1484 DATA_LEN-4, false);
1486 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1487 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.reassembled_table));
1488 ASSERT_NE_POINTER(NULL,fd_head);
1490 /* check the contents of the structure. */
1491 ASSERT_EQ(0,fd_head->frame); /* max frame we have */
1492 ASSERT_EQ(0,fd_head->len); /* the length of data we have */
1493 ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
1494 ASSERT_EQ(20,fd_head->reassembled_in);
1495 ASSERT_EQ(FD_BLOCKSEQUENCE|FD_DEFRAGMENTED,fd_head->flags);
1496 ASSERT_EQ_POINTER(NULL,fd_head->tvb_data);
1497 ASSERT_EQ_POINTER(NULL,fd_head->next);
1499 /* revisiting the packet ought to produce the same result. */
1500 pinfo.fd->visited = true;
1502 pinfo.num = 20;
1503 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 30, NULL,
1504 DATA_LEN-4, false);
1506 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1507 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.reassembled_table));
1508 ASSERT_NE_POINTER(NULL,fd_head);
1509 ASSERT_EQ(0,fd_head->frame); /* unused */
1510 ASSERT_EQ(0,fd_head->len); /* the length of data we have */
1511 ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
1512 ASSERT_EQ(20,fd_head->reassembled_in);
1513 ASSERT_EQ(FD_BLOCKSEQUENCE|FD_DEFRAGMENTED,fd_head->flags);
1514 ASSERT_EQ_POINTER(NULL,fd_head->tvb_data);
1515 ASSERT_EQ_POINTER(NULL,fd_head->next);
1517 #endif
1519 /**********************************************************************************
1521 * fragment_add
1523 *********************************************************************************/
1525 /* Simple test case for fragment_add.
1526 * Adds three fragments (out of order, with one for a different datagram in between),
1527 * and checks that they are reassembled correctly.
1529 /* visit id frame frag_offset len more tvb_offset
1530 0 12 1 0 50 T 10
1531 1 12 1 0 60 T 5
1532 0 13 2 0 60 T 15
1533 0 12 3 110 60 F 5
1534 0 12 4 50 60 T 15
1536 static void
1537 test_simple_fragment_add(void)
1539 fragment_head *fd_head, *fdh0;
1540 fragment_item *fd;
1542 printf("Starting test test_simple_fragment_add\n");
1544 pinfo.num = 1;
1545 fd_head=fragment_add(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1546 0, 50, true);
1548 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1549 ASSERT_EQ_POINTER(NULL,fd_head);
1551 /* adding the same fragment again should do nothing, even with different
1552 * offset etc */
1553 pinfo.fd->visited = 1;
1554 fd_head=fragment_add(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1555 0, 60, true);
1556 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1557 ASSERT_EQ_POINTER(NULL,fd_head);
1559 /* start another pdu (just to confuse things) */
1560 pinfo.fd->visited = 0;
1561 pinfo.num = 2;
1562 fd_head=fragment_add(&test_reassembly_table, tvb, 15, &pinfo, 13, NULL,
1563 0, 60, true);
1564 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
1565 ASSERT_EQ_POINTER(NULL,fd_head);
1567 /* now we add the terminal fragment of the first datagram */
1568 pinfo.num = 3;
1569 fd_head=fragment_add(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1570 110, 60, false);
1572 /* we haven't got all the fragments yet ... */
1573 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
1574 ASSERT_EQ_POINTER(NULL,fd_head);
1576 /* finally, add the missing fragment */
1577 pinfo.num = 4;
1578 fd_head=fragment_add(&test_reassembly_table, tvb, 15, &pinfo, 12, NULL,
1579 50, 60, true);
1581 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
1582 ASSERT_NE_POINTER(NULL,fd_head);
1584 /* check the contents of the structure */
1585 ASSERT_EQ(4,fd_head->frame); /* max frame number of fragment in assembly */
1586 ASSERT_EQ(0,fd_head->len); /* unused in fragment_add */
1587 ASSERT_EQ(170,fd_head->datalen); /* total datalen of assembly */
1588 ASSERT_EQ(4,fd_head->reassembled_in);
1589 ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET,fd_head->flags);
1590 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
1591 ASSERT_NE_POINTER(NULL,fd_head->next);
1593 fd = fd_head->next;
1594 ASSERT_EQ(1,fd->frame);
1595 ASSERT_EQ(0,fd->offset); /* offset */
1596 ASSERT_EQ(50,fd->len); /* segment length */
1597 ASSERT_EQ(0,fd->flags);
1598 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
1599 ASSERT_NE_POINTER(NULL,fd->next);
1601 fd = fd->next;
1602 ASSERT_EQ(4,fd->frame);
1603 ASSERT_EQ(50,fd->offset); /* offset */
1604 ASSERT_EQ(60,fd->len); /* segment length */
1605 ASSERT_EQ(0,fd->flags);
1606 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
1607 ASSERT_NE_POINTER(NULL,fd->next);
1609 fd = fd->next;
1610 ASSERT_EQ(3,fd->frame);
1611 ASSERT_EQ(110,fd->offset); /* offset */
1612 ASSERT_EQ(60,fd->len); /* segment length */
1613 ASSERT_EQ(0,fd->flags);
1614 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
1615 ASSERT_EQ_POINTER(NULL,fd->next);
1617 /* test the actual reassembly */
1618 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
1619 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+15,60));
1620 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,60));
1622 if (debug) {
1623 print_fragment_table();
1626 /* what happens if we revisit the packets now? */
1627 fdh0 = fd_head;
1628 pinfo.fd->visited = 1;
1629 pinfo.num = 1;
1630 fd_head=fragment_add(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1631 0, 50, true);
1633 * this api relies on the caller to check fd_head -> reassembled_in
1635 * Redoing all the tests seems like overkill - just check the pointer
1637 ASSERT_EQ_POINTER(fdh0,fd_head);
1639 pinfo.num = 3;
1640 fd_head=fragment_add(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1641 110, 60, false);
1642 ASSERT_EQ_POINTER(fdh0,fd_head);
1644 pinfo.num = 4;
1645 fd_head=fragment_add(&test_reassembly_table, tvb, 15, &pinfo, 12, NULL,
1646 50, 60, true);
1647 ASSERT_EQ_POINTER(fdh0,fd_head);
1649 if (debug) {
1650 print_fragment_table();
1654 /* This tests the functionality of fragment_set_partial_reassembly for
1655 * fragment_add based reassembly.
1657 * We add a sequence of fragments thus:
1658 * seq_off frame tvb_off len (initial) more_frags
1659 * ------- ----- ------- --- --------------------
1660 * 0 1 10 50 false
1661 * 50 2 0 40 true
1662 * 50 3 0 40 true (a duplicate fragment)
1663 * 90 4 20 100 false
1664 * 190 5 0 40 false
1666 static void
1667 test_fragment_add_partial_reassembly(void)
1669 fragment_head *fd_head;
1670 fragment_item *fd;
1672 printf("Starting test test_fragment_add_partial_reassembly\n");
1674 /* generally it's probably fair to assume that we will be called with
1675 * more_frags=false.
1677 pinfo.num = 1;
1678 fd_head=fragment_add(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1679 0, 50, false);
1681 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1682 ASSERT_NE_POINTER(NULL,fd_head);
1684 /* check the contents of the structure */
1685 ASSERT_EQ(1,fd_head->frame); /* max frame in reassembly */
1686 ASSERT_EQ(0,fd_head->len); /* unused */
1687 ASSERT_EQ(50,fd_head->datalen); /* the length of data we have */
1688 ASSERT_EQ(1,fd_head->reassembled_in);
1689 ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET,fd_head->flags);
1690 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
1691 ASSERT_NE_POINTER(NULL,fd_head->next);
1693 ASSERT_EQ(1,fd_head->next->frame);
1694 ASSERT_EQ(0,fd_head->next->offset); /* offset */
1695 ASSERT_EQ(50,fd_head->next->len); /* segment length */
1696 ASSERT_EQ(0,fd_head->next->flags);
1697 ASSERT_EQ_POINTER(NULL,fd_head->next->tvb_data);
1698 ASSERT_EQ_POINTER(NULL,fd_head->next->next);
1700 /* test the actual reassembly */
1701 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
1703 /* now we announce that the reassembly wasn't complete after all. */
1704 fragment_set_partial_reassembly(&test_reassembly_table, &pinfo, 12, NULL);
1706 /* and add another segment. To mix things up slightly (and so that we can
1707 * check on the state of things), we're going to set the more_frags flag
1708 * here
1710 pinfo.num = 2;
1711 fd_head=fragment_add(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
1712 50, 40, true);
1714 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1715 ASSERT_EQ_POINTER(NULL,fd_head);
1717 fd_head=fragment_get(&test_reassembly_table, &pinfo, 12, NULL);
1718 ASSERT_NE_POINTER(NULL,fd_head);
1720 /* check the contents of the structure */
1721 ASSERT_EQ(2,fd_head->frame); /* max frame in reassembly */
1722 ASSERT_EQ(0,fd_head->len); /* unused */
1723 /* ASSERT_EQ(0,fd_head->datalen);
1724 * reassembly not finished; datalen not well defined.
1725 * Current implemenation has it as 0, could change to 90 without issues */
1726 ASSERT_EQ(0,fd_head->reassembled_in);
1727 ASSERT_EQ(0,fd_head->flags);
1728 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
1729 ASSERT_NE_POINTER(NULL,fd_head->next);
1731 fd=fd_head->next;
1732 ASSERT_EQ(1,fd->frame);
1733 ASSERT_EQ(0,fd->offset); /* offset */
1734 ASSERT_EQ(50,fd->len); /* segment length */
1735 ASSERT_EQ(FD_SUBSET_TVB,fd->flags);
1736 ASSERT_EQ_POINTER(tvb_get_ptr(fd_head->tvb_data,0,0),tvb_get_ptr(fd->tvb_data,0,0));
1737 ASSERT_NE_POINTER(NULL,fd->next);
1739 fd=fd->next;
1740 ASSERT_EQ(2,fd->frame);
1741 ASSERT_EQ(50,fd->offset); /* offset */
1742 ASSERT_EQ(40,fd->len); /* segment length */
1743 ASSERT_EQ(0,fd->flags);
1744 ASSERT_NE_POINTER(NULL,fd->tvb_data);
1745 ASSERT_EQ_POINTER(NULL,fd->next);
1747 /* Another copy of the second segment.
1749 pinfo.num = 3;
1750 fd_head=fragment_add(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
1751 50, 40, true);
1753 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1754 ASSERT_EQ_POINTER(NULL,fd_head);
1755 fd_head=fragment_get(&test_reassembly_table, &pinfo, 12, NULL);
1756 ASSERT_NE_POINTER(NULL,fd_head);
1757 ASSERT_EQ(3,fd_head->frame); /* max frame we have */
1758 ASSERT_EQ(0,fd_head->len); /* unused */
1759 /* ASSERT_EQ(0,fd_head->datalen);
1760 * reassembly not finished; datalen not well defined.
1761 * Current implemenation has it as 0, could change to 90 without issues */
1762 ASSERT_EQ(0,fd_head->reassembled_in);
1763 ASSERT_EQ(0,fd_head->flags);
1764 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
1765 ASSERT_NE_POINTER(NULL,fd_head->next);
1767 fd=fd_head->next;
1768 ASSERT_EQ(1,fd->frame);
1769 ASSERT_EQ(0,fd->offset);
1770 ASSERT_EQ(50,fd->len); /* segment length */
1771 ASSERT_EQ(FD_SUBSET_TVB,fd->flags);
1772 ASSERT_EQ_POINTER(tvb_get_ptr(fd_head->tvb_data,0,0),tvb_get_ptr(fd->tvb_data,0,0));
1773 ASSERT_NE_POINTER(NULL,fd->next);
1775 fd=fd->next;
1776 ASSERT_EQ(2,fd->frame);
1777 ASSERT_EQ(50,fd->offset);
1778 ASSERT_EQ(40,fd->len); /* segment length */
1779 ASSERT_EQ(0,fd->flags);
1780 ASSERT_NE_POINTER(NULL,fd->tvb_data);
1781 ASSERT_NE_POINTER(NULL,fd->next);
1783 fd=fd->next;
1784 ASSERT_EQ(3,fd->frame);
1785 ASSERT_EQ(50,fd->offset);
1786 ASSERT_EQ(40,fd->len); /* segment length */
1787 ASSERT_EQ(0,fd->flags);
1788 ASSERT_NE_POINTER(NULL,fd->tvb_data);
1789 ASSERT_EQ_POINTER(NULL,fd->next);
1793 /* have another go at wrapping things up */
1794 pinfo.num = 4;
1795 fd_head=fragment_add(&test_reassembly_table, tvb, 20, &pinfo, 12, NULL,
1796 90, 100, false);
1798 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1799 ASSERT_NE_POINTER(NULL,fd_head);
1801 /* check the contents of the structure */
1802 ASSERT_EQ(4,fd_head->frame); /* max frame we have */
1803 ASSERT_EQ(0,fd_head->len); /* unused */
1804 ASSERT_EQ(190,fd_head->datalen); /* the length of data we have */
1805 ASSERT_EQ(4,fd_head->reassembled_in);
1806 ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
1807 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
1808 ASSERT_NE_POINTER(NULL,fd_head->next);
1810 fd=fd_head->next;
1811 ASSERT_EQ(1,fd->frame);
1812 ASSERT_EQ(0,fd->offset);
1813 ASSERT_EQ(50,fd->len); /* segment length */
1814 ASSERT_EQ(0,fd->flags);
1815 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
1816 ASSERT_NE_POINTER(NULL,fd->next);
1818 fd=fd->next;
1819 ASSERT_EQ(2,fd->frame);
1820 ASSERT_EQ(50,fd->offset);
1821 ASSERT_EQ(40,fd->len); /* segment length */
1822 ASSERT_EQ(0,fd->flags);
1823 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
1824 ASSERT_NE_POINTER(NULL,fd->next);
1826 fd=fd->next;
1827 ASSERT_EQ(3,fd->frame);
1828 ASSERT_EQ(50,fd->offset);
1829 ASSERT_EQ(40,fd->len); /* segment length */
1830 ASSERT_EQ(FD_OVERLAP,fd->flags);
1831 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
1832 ASSERT_NE_POINTER(NULL,fd->next);
1834 fd=fd->next;
1835 ASSERT_EQ(4,fd->frame);
1836 ASSERT_EQ(90,fd->offset);
1837 ASSERT_EQ(100,fd->len); /* segment length */
1838 ASSERT_EQ(0,fd->flags);
1839 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
1840 ASSERT_EQ_POINTER(NULL,fd->next);
1842 /* test the actual reassembly */
1843 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
1844 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data,40));
1845 ASSERT(!tvb_memeql(fd_head->tvb_data,90,data+20,100));
1848 /* do it again (this time it is more complicated, with an overlap in the
1849 * reassembly) */
1851 fragment_set_partial_reassembly(&test_reassembly_table, &pinfo, 12, NULL);
1853 pinfo.num = 5;
1854 fragment_add(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
1855 190, 40, false);
1857 fd_head=fragment_get(&test_reassembly_table, &pinfo, 12, NULL);
1858 ASSERT_NE_POINTER(NULL,fd_head);
1859 ASSERT_EQ(5,fd_head->frame); /* max frame we have */
1860 ASSERT_EQ(0,fd_head->len); /* unused */
1861 ASSERT_EQ(230,fd_head->datalen); /* the length of data we have */
1862 ASSERT_EQ(5,fd_head->reassembled_in);
1863 ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
1864 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
1865 ASSERT_NE_POINTER(NULL,fd_head->next);
1867 fd=fd_head->next;
1868 ASSERT_EQ(1,fd->frame);
1869 ASSERT_EQ(0,fd->offset);
1870 ASSERT_EQ(50,fd->len); /* segment length */
1871 ASSERT_EQ(0,fd->flags);
1872 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
1873 ASSERT_NE_POINTER(NULL,fd->next);
1875 fd=fd->next;
1876 ASSERT_EQ(2,fd->frame);
1877 ASSERT_EQ(50,fd->offset);
1878 ASSERT_EQ(40,fd->len); /* segment length */
1879 ASSERT_EQ(0,fd->flags);
1880 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
1881 ASSERT_NE_POINTER(NULL,fd->next);
1883 fd=fd->next;
1884 ASSERT_EQ(3,fd->frame);
1885 ASSERT_EQ(50,fd->offset);
1886 ASSERT_EQ(40,fd->len); /* segment length */
1887 ASSERT_EQ(FD_OVERLAP,fd->flags);
1888 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
1889 ASSERT_NE_POINTER(NULL,fd->next);
1891 fd=fd->next;
1892 ASSERT_EQ(4,fd->frame);
1893 ASSERT_EQ(90,fd->offset);
1894 ASSERT_EQ(100,fd->len); /* segment length */
1895 ASSERT_EQ(0,fd->flags);
1896 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
1897 ASSERT_NE_POINTER(NULL,fd->next);
1899 fd=fd->next;
1900 ASSERT_EQ(5,fd->frame);
1901 ASSERT_EQ(190,fd->offset);
1902 ASSERT_EQ(40,fd->len); /* segment length */
1903 ASSERT_EQ(0,fd->flags);
1904 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
1905 ASSERT_EQ_POINTER(NULL,fd->next);
1907 /* test the actual reassembly */
1908 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
1909 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data,40));
1910 ASSERT(!tvb_memeql(fd_head->tvb_data,90,data+20,100));
1911 ASSERT(!tvb_memeql(fd_head->tvb_data,190,data,40));
1914 /* XXX: Is the proper behavior here really throwing an exception instead
1915 * of setting FD_OVERLAP?
1917 /* Test case for fragment_add with duplicated (e.g., retransmitted) data.
1918 * Adds three fragments--adding the 1st one twice at the end--
1919 * and checks that they are reassembled correctly.
1921 /* visit id frame frag_off len more tvb_offset
1922 0 12 1 0 50 T 10
1923 0 12 2 50 60 T 5
1924 0 12 3 110 40 F 5
1925 0 12 4 0 50 T 10
1927 static void
1928 test_fragment_add_duplicate_first(void)
1930 fragment_head *fd_head;
1931 fragment_item *fd;
1933 printf("Starting test test_fragment_add_duplicate_first\n");
1935 pinfo.num = 1;
1936 fd_head=fragment_add(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1937 0, 50, true);
1939 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1940 ASSERT_EQ_POINTER(NULL,fd_head);
1942 /* Add the 2nd segment */
1943 pinfo.num = 2;
1944 fd_head=fragment_add(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1945 50, 60, true);
1947 /* we haven't got all the fragments yet ... */
1948 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1949 ASSERT_EQ_POINTER(NULL,fd_head);
1951 /* Add the last fragment */
1952 pinfo.num = 3;
1953 fd_head=fragment_add(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1954 110, 40, false);
1956 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1957 ASSERT_NE_POINTER(NULL,fd_head);
1959 /* Add the first fragment again */
1960 pinfo.num = 4;
1961 fd_head=fragment_add(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1962 0, 50, true);
1964 /* Reassembly should have still succeeded */
1965 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1966 ASSERT_NE_POINTER(NULL,fd_head);
1968 /* check the contents of the structure */
1969 ASSERT_EQ(4,fd_head->frame); /* add the duplicate frame */
1970 ASSERT_EQ(0,fd_head->len); /* unused */
1971 ASSERT_EQ(150,fd_head->datalen);
1972 ASSERT_EQ(3,fd_head->reassembled_in);
1973 ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
1974 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
1975 ASSERT_NE_POINTER(NULL,fd_head->next);
1977 fd = fd_head->next;
1979 ASSERT_EQ(1,fd->frame);
1980 ASSERT_EQ(0,fd->offset);
1981 ASSERT_EQ(50,fd->len); /* segment length */
1982 ASSERT_EQ(0,fd->flags);
1983 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
1984 ASSERT_NE_POINTER(NULL,fd->next);
1986 fd = fd->next;
1987 ASSERT_EQ(4,fd->frame);
1988 ASSERT_EQ(0,fd->offset);
1989 ASSERT_EQ(50,fd->len);
1990 ASSERT_EQ(FD_OVERLAP,fd->flags);
1991 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
1992 ASSERT_NE_POINTER(NULL,fd->next);
1994 fd = fd->next;
1995 ASSERT_EQ(2,fd->frame);
1996 ASSERT_EQ(50,fd->offset);
1997 ASSERT_EQ(60,fd->len); /* segment length */
1998 ASSERT_EQ(0,fd->flags);
1999 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2000 ASSERT_NE_POINTER(NULL,fd->next);
2002 fd = fd->next;
2003 ASSERT_EQ(3,fd->frame);
2004 ASSERT_EQ(110,fd->offset);
2005 ASSERT_EQ(40,fd->len); /* segment length */
2006 ASSERT_EQ(0,fd->flags);
2007 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2008 ASSERT_EQ_POINTER(NULL,fd->next);
2010 /* test the actual reassembly */
2011 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
2012 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
2013 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
2015 if (debug) {
2016 print_fragment_table();
2021 /* Test case for fragment_add with duplicated (e.g., retransmitted) data.
2022 * Adds three fragments--adding the 2nd one twice--
2023 * and checks that they are reassembled correctly.
2025 /* visit id frame frag_off len more tvb_offset
2026 0 12 1 0 50 T 10
2027 0 12 2 50 60 T 5
2028 0 12 3 50 60 T 5
2029 0 12 4 110 40 F 5
2031 static void
2032 test_fragment_add_duplicate_middle(void)
2034 fragment_head *fd_head;
2035 fragment_item *fd;
2037 printf("Starting test test_fragment_add_duplicate_middle\n");
2039 pinfo.num = 1;
2040 fd_head=fragment_add(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
2041 0, 50, true);
2043 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2044 ASSERT_EQ_POINTER(NULL,fd_head);
2046 /* Add the 2nd segment */
2047 pinfo.num = 2;
2048 fd_head=fragment_add(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
2049 50, 60, true);
2051 /* we haven't got all the fragments yet ... */
2052 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2053 ASSERT_EQ_POINTER(NULL,fd_head);
2055 /* Now, add the 2nd segment again (but in a different frame) */
2056 pinfo.num = 3;
2057 fd_head=fragment_add(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
2058 50, 60, true);
2060 /* This duplicate fragment should have been ignored */
2061 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2062 ASSERT_EQ_POINTER(NULL,fd_head);
2064 /* finally, add the last fragment */
2065 pinfo.num = 4;
2066 fd_head=fragment_add(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
2067 110, 40, false);
2069 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2070 ASSERT_NE_POINTER(NULL,fd_head);
2072 /* check the contents of the structure */
2073 ASSERT_EQ(4,fd_head->frame); /* max frame we have */
2074 ASSERT_EQ(0,fd_head->len); /* unused */
2075 ASSERT_EQ(150,fd_head->datalen);
2076 ASSERT_EQ(4,fd_head->reassembled_in);
2077 ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
2078 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
2079 ASSERT_NE_POINTER(NULL,fd_head->next);
2081 fd = fd_head->next;
2082 ASSERT_EQ(1,fd->frame);
2083 ASSERT_EQ(0,fd->offset);
2084 ASSERT_EQ(50,fd->len); /* segment length */
2085 ASSERT_EQ(0,fd->flags);
2086 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2087 ASSERT_NE_POINTER(NULL,fd->next);
2089 fd = fd->next;
2090 ASSERT_EQ(2,fd->frame);
2091 ASSERT_EQ(50,fd->offset);
2092 ASSERT_EQ(60,fd->len); /* segment length */
2093 ASSERT_EQ(0,fd->flags);
2094 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2095 ASSERT_NE_POINTER(NULL,fd->next);
2097 fd = fd->next;
2098 ASSERT_EQ(3,fd->frame);
2099 ASSERT_EQ(50,fd->offset);
2100 ASSERT_EQ(60,fd->len); /* segment length */
2101 ASSERT_EQ(FD_OVERLAP,fd->flags);
2102 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2103 ASSERT_NE_POINTER(NULL,fd->next);
2105 fd = fd->next;
2106 ASSERT_EQ(4,fd->frame);
2107 ASSERT_EQ(110,fd->offset);
2108 ASSERT_EQ(40,fd->len); /* segment length */
2109 ASSERT_EQ(0,fd->flags);
2110 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2111 ASSERT_EQ_POINTER(NULL,fd->next);
2113 /* test the actual reassembly */
2114 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
2115 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
2116 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
2118 if (debug) {
2119 print_fragment_table();
2123 /* XXX: Is the proper behavior here really throwing an exception instead
2124 * of setting FD_OVERLAP?
2126 /* Test case for fragment_add with duplicated (e.g., retransmitted) data.
2127 * Adds three fragments--adding the 3rd one twice--
2128 * and checks that they are reassembled correctly.
2130 /* visit id frame frag len more tvb_offset
2131 0 12 1 0 50 T 10
2132 0 12 2 1 60 T 5
2133 0 12 3 2 40 F 5
2134 0 12 4 2 40 F 5
2136 static void
2137 test_fragment_add_duplicate_last(void)
2139 fragment_head *fd_head;
2140 fragment_item *fd;
2142 printf("Starting test test_fragment_add_duplicate_last\n");
2144 pinfo.num = 1;
2145 fd_head=fragment_add(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
2146 0, 50, true);
2148 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2149 ASSERT_EQ_POINTER(NULL,fd_head);
2151 /* Add the 2nd segment */
2152 pinfo.num = 2;
2153 fd_head=fragment_add(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
2154 50, 60, true);
2156 /* we haven't got all the fragments yet ... */
2157 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2158 ASSERT_EQ_POINTER(NULL,fd_head);
2160 /* Add the last fragment */
2161 pinfo.num = 3;
2162 fd_head=fragment_add(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
2163 110, 40, false);
2165 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2166 ASSERT_NE_POINTER(NULL,fd_head);
2168 /* Add the last fragment again */
2169 pinfo.num = 4;
2170 fd_head=fragment_add(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
2171 110, 40, false);
2173 /* Reassembly should have still succeeded */
2174 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2175 ASSERT_NE_POINTER(NULL,fd_head);
2177 /* check the contents of the structure */
2178 ASSERT_EQ(4,fd_head->frame); /* max frame we have */
2179 ASSERT_EQ(0,fd_head->len); /* unused */
2180 ASSERT_EQ(150,fd_head->datalen);
2181 ASSERT_EQ(3,fd_head->reassembled_in);
2182 ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
2183 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
2184 ASSERT_NE_POINTER(NULL,fd_head->next);
2186 fd = fd_head->next;
2187 ASSERT_EQ(1,fd->frame);
2188 ASSERT_EQ(0,fd->offset);
2189 ASSERT_EQ(50,fd->len); /* segment length */
2190 ASSERT_EQ(0,fd->flags);
2191 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2192 ASSERT_NE_POINTER(NULL,fd->next);
2194 fd = fd->next;
2195 ASSERT_EQ(2,fd->frame);
2196 ASSERT_EQ(50,fd->offset);
2197 ASSERT_EQ(60,fd->len); /* segment length */
2198 ASSERT_EQ(0,fd->flags);
2199 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2200 ASSERT_NE_POINTER(NULL,fd->next);
2202 fd = fd->next;
2203 ASSERT_EQ(3,fd->frame);
2204 ASSERT_EQ(110,fd->offset);
2205 ASSERT_EQ(40,fd->len); /* segment length */
2206 ASSERT_EQ(0,fd->flags);
2207 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2209 ASSERT_NE_POINTER(NULL,fd->next);
2211 fd = fd->next;
2212 ASSERT_EQ(4,fd->frame);
2213 ASSERT_EQ(110,fd->offset);
2214 ASSERT_EQ(40,fd->len);
2215 ASSERT_EQ(FD_OVERLAP,fd->flags);
2216 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2217 ASSERT_EQ_POINTER(NULL,fd->next);
2219 /* test the actual reassembly */
2220 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
2221 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
2222 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
2224 if (debug) {
2225 print_fragment_table();
2229 /* Test case for fragment_add with duplicated (e.g., retransmitted) data
2230 * where the retransmission "conflicts" with the original transmission
2231 * (contents are different).
2232 * Adds three fragments--adding the 2nd one twice--
2233 * and checks that they are reassembled correctly.
2235 /* visit id frame frag_off len more tvb_offset
2236 0 12 1 0 50 T 10
2237 0 12 2 50 60 T 5
2238 0 12 3 50 60 T 15
2239 0 12 4 110 40 F 5
2241 static void
2242 test_fragment_add_duplicate_conflict(void)
2244 fragment_head *fd_head;
2245 fragment_item *fd;
2247 printf("Starting test test_fragment_add_duplicate_conflict\n");
2249 pinfo.num = 1;
2250 fd_head=fragment_add(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
2251 0, 50, true);
2253 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2254 ASSERT_EQ_POINTER(NULL,fd_head);
2256 /* Add the 2nd segment */
2257 pinfo.num = 2;
2258 fd_head=fragment_add(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
2259 50, 60, true);
2261 /* we haven't got all the fragments yet ... */
2262 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2263 ASSERT_EQ_POINTER(NULL,fd_head);
2265 /* Now, add the 2nd segment again (but in a different frame and with
2266 * different data)
2268 pinfo.num = 3;
2269 fd_head=fragment_add(&test_reassembly_table, tvb, 15, &pinfo, 12, NULL,
2270 50, 60, true);
2272 /* This duplicate fragment should have been ignored */
2273 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2274 ASSERT_EQ_POINTER(NULL,fd_head);
2276 /* finally, add the last fragment */
2277 pinfo.num = 4;
2278 fd_head=fragment_add(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
2279 110, 40, false);
2281 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2282 ASSERT_NE_POINTER(NULL,fd_head);
2284 /* check the contents of the structure */
2285 ASSERT_EQ(4,fd_head->frame); /* max frame we have */
2286 ASSERT_EQ(0,fd_head->len); /* unused */
2287 ASSERT_EQ(150,fd_head->datalen);
2288 ASSERT_EQ(4,fd_head->reassembled_in);
2289 ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET|FD_OVERLAP|FD_OVERLAPCONFLICT,fd_head->flags);
2290 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
2291 ASSERT_NE_POINTER(NULL,fd_head->next);
2293 fd = fd_head->next;
2294 ASSERT_EQ(1,fd->frame);
2295 ASSERT_EQ(0,fd->offset);
2296 ASSERT_EQ(50,fd->len); /* segment length */
2297 ASSERT_EQ(0,fd->flags);
2298 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2299 ASSERT_NE_POINTER(NULL,fd->next);
2301 fd = fd->next;
2302 ASSERT_EQ(2,fd->frame);
2303 ASSERT_EQ(50,fd->offset);
2304 ASSERT_EQ(60,fd->len); /* segment length */
2305 ASSERT_EQ(0,fd->flags);
2306 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2307 ASSERT_NE_POINTER(NULL,fd->next);
2309 fd = fd->next;
2310 ASSERT_EQ(3,fd->frame);
2311 ASSERT_EQ(50,fd->offset);
2312 ASSERT_EQ(60,fd->len); /* segment length */
2313 ASSERT_EQ(FD_OVERLAP|FD_OVERLAPCONFLICT,fd->flags);
2314 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2315 ASSERT_NE_POINTER(NULL,fd->next);
2317 fd = fd->next;
2318 ASSERT_EQ(4,fd->frame);
2319 ASSERT_EQ(110,fd->offset);
2320 ASSERT_EQ(40,fd->len); /* segment length */
2321 ASSERT_EQ(0,fd->flags);
2322 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2323 ASSERT_EQ_POINTER(NULL,fd->next);
2325 /* test the actual reassembly */
2326 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
2327 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
2328 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
2330 if (debug) {
2331 print_fragment_table();
2335 /**********************************************************************************
2337 * fragment_add_check
2339 *********************************************************************************/
2341 /* Simple test case for fragment_add_check.
2342 * Adds three fragments (out of order, with one for a different datagram in between),
2343 * and checks that they are reassembled correctly.
2345 /* visit id frame frag_offset len more tvb_offset
2346 0 12 1 0 50 T 10
2347 1 12 1 0 60 T 5
2348 0 13 2 0 60 T 15
2349 0 12 3 110 60 F 5
2350 0 12 4 50 60 T 15
2352 static void
2353 test_simple_fragment_add_check(void)
2355 fragment_head *fd_head, *fdh0;
2356 fragment_item *fd;
2358 printf("Starting test test_simple_fragment_add_check\n");
2360 pinfo.num = 1;
2361 fd_head=fragment_add_check(&test_reassembly_table, tvb, 10, &pinfo, 12,
2362 NULL, 0, 50, true);
2364 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2365 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
2366 ASSERT_EQ_POINTER(NULL,fd_head);
2368 /* adding the same fragment again should do nothing, even with different
2369 * offset etc */
2370 pinfo.fd->visited = 1;
2371 fd_head=fragment_add_check(&test_reassembly_table, tvb, 5, &pinfo, 12,
2372 NULL, 0, 60, true);
2373 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2374 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
2375 ASSERT_EQ_POINTER(NULL,fd_head);
2377 /* start another pdu (just to confuse things) */
2378 pinfo.fd->visited = 0;
2379 pinfo.num = 2;
2380 fd_head=fragment_add_check(&test_reassembly_table, tvb, 15, &pinfo, 13,
2381 NULL, 0, 60, true);
2382 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
2383 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
2384 ASSERT_EQ_POINTER(NULL,fd_head);
2386 /* now we add the terminal fragment of the first datagram */
2387 pinfo.num = 3;
2388 fd_head=fragment_add_check(&test_reassembly_table, tvb, 5, &pinfo, 12,
2389 NULL, 110, 60, false);
2391 /* we haven't got all the fragments yet ... */
2392 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
2393 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
2394 ASSERT_EQ_POINTER(NULL,fd_head);
2396 /* finally, add the missing fragment */
2397 pinfo.num = 4;
2398 fd_head=fragment_add_check(&test_reassembly_table, tvb, 15, &pinfo, 12,
2399 NULL, 50, 60, true);
2401 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2402 ASSERT_EQ(3,g_hash_table_size(test_reassembly_table.reassembled_table));
2403 ASSERT_NE_POINTER(NULL,fd_head);
2405 /* check the contents of the structure */
2406 ASSERT_EQ(4,fd_head->frame); /* max frame number of fragment in assembly */
2407 ASSERT_EQ(0,fd_head->len); /* unused in fragment_add */
2408 ASSERT_EQ(170,fd_head->datalen); /* total datalen of assembly */
2409 ASSERT_EQ(4,fd_head->reassembled_in);
2410 ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET,fd_head->flags);
2411 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
2412 ASSERT_NE_POINTER(NULL,fd_head->next);
2414 fd = fd_head->next;
2415 ASSERT_EQ(1,fd->frame);
2416 ASSERT_EQ(0,fd->offset);
2417 ASSERT_EQ(50,fd->len); /* segment length */
2418 ASSERT_EQ(0,fd->flags);
2419 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2420 ASSERT_NE_POINTER(NULL,fd->next);
2422 fd = fd->next;
2423 ASSERT_EQ(4,fd->frame);
2424 ASSERT_EQ(50,fd->offset);
2425 ASSERT_EQ(60,fd->len); /* segment length */
2426 ASSERT_EQ(0,fd->flags);
2427 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2428 ASSERT_NE_POINTER(NULL,fd->next);
2430 fd = fd->next;
2431 ASSERT_EQ(3,fd->frame);
2432 ASSERT_EQ(110,fd->offset);
2433 ASSERT_EQ(60,fd->len); /* segment length */
2434 ASSERT_EQ(0,fd->flags);
2435 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2436 ASSERT_EQ_POINTER(NULL,fd->next);
2438 /* test the actual reassembly */
2439 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
2440 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+15,60));
2441 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,60));
2443 if (debug) {
2444 print_fragment_table();
2447 /* what happens if we revisit the packets now? */
2448 fdh0 = fd_head;
2449 pinfo.fd->visited = 1;
2450 pinfo.num = 1;
2451 fd_head=fragment_add_check(&test_reassembly_table, tvb, 10, &pinfo, 12,
2452 NULL, 0, 50, true);
2454 * this api relies on the caller to check fd_head -> reassembled_in
2456 * Redoing all the tests seems like overkill - just check the pointer
2458 ASSERT_EQ_POINTER(fdh0,fd_head);
2460 pinfo.num = 3;
2461 fd_head=fragment_add_check(&test_reassembly_table, tvb, 5, &pinfo, 12,
2462 NULL, 110, 60, false);
2463 ASSERT_EQ_POINTER(fdh0,fd_head);
2465 pinfo.num = 4;
2466 fd_head=fragment_add_check(&test_reassembly_table, tvb, 15, &pinfo, 12,
2467 NULL, 50, 60, true);
2468 ASSERT_EQ_POINTER(fdh0,fd_head);
2470 if (debug) {
2471 print_fragment_table();
2475 #if 0
2476 /* XXX: fragment_set_partial_reassembly() does not work for fragment_add_check
2477 * because it doesn't remove the previously completed reassembly from
2478 * reassembled_table (and lookup_fd_head() only looks in the fragment
2479 * table, not the reassembled_table) */
2480 /* This tests the functionality of fragment_set_partial_reassembly for
2481 * fragment_add_check based reassembly.
2483 * We add a sequence of fragments thus:
2484 * seq_off frame tvb_off len (initial) more_frags
2485 * ------- ----- ------- --- --------------------
2486 * 0 1 10 50 false
2487 * 50 2 0 40 true
2488 * 50 3 0 40 true (a duplicate fragment)
2489 * 90 4 20 100 false
2490 * 190 5 0 40 false
2492 static void
2493 test_fragment_add_check_partial_reassembly(void)
2495 fragment_head *fd_head;
2496 fragment_item *fd;
2498 printf("Starting test test_fragment_add_check_partial_reassembly\n");
2500 /* generally it's probably fair to assume that we will be called with
2501 * more_frags=false.
2503 pinfo.num = 1;
2504 fd_head=fragment_add_check(&test_reassembly_table, tvb, 10, &pinfo, 12,
2505 NULL, 0, 50, false);
2507 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
2508 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.reassembled_table));
2509 ASSERT_NE_POINTER(NULL,fd_head);
2511 /* check the contents of the structure */
2512 ASSERT_EQ(1,fd_head->frame); /* max frame in reassembly */
2513 ASSERT_EQ(0,fd_head->len); /* unused */
2514 ASSERT_EQ(50,fd_head->datalen); /* the length of data we have */
2515 ASSERT_EQ(1,fd_head->reassembled_in);
2516 ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET,fd_head->flags);
2517 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
2518 ASSERT_NE_POINTER(NULL,fd_head->next);
2520 ASSERT_EQ(1,fd_head->next->frame);
2521 ASSERT_EQ(0,fd_head->next->offset); /* offset */
2522 ASSERT_EQ(50,fd_head->next->len); /* segment length */
2523 ASSERT_EQ(0,fd_head->next->flags);
2524 ASSERT_EQ_POINTER(NULL,fd_head->next->tvb_data);
2525 ASSERT_EQ_POINTER(NULL,fd_head->next->next);
2527 /* test the actual reassembly */
2528 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
2530 /* now we announce that the reassembly wasn't complete after all. */
2531 fragment_set_partial_reassembly(&test_reassembly_table, &pinfo, 12, NULL);
2533 /* and add another segment. To mix things up slightly (and so that we can
2534 * check on the state of things), we're going to set the more_frags flag
2535 * here
2537 pinfo.num = 2;
2538 fd_head=fragment_add_check(&test_reassembly_table, tvb, 0, &pinfo, 12,
2539 NULL, 50, 40, true);
2541 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2542 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.reassembled_table));
2543 ASSERT_EQ_POINTER(NULL,fd_head);
2545 fd_head=fragment_get(&test_reassembly_table, &pinfo, 12, NULL);
2546 ASSERT_NE_POINTER(NULL,fd_head);
2548 /* check the contents of the structure */
2549 ASSERT_EQ(2,fd_head->frame); /* max frame in reassembly */
2550 ASSERT_EQ(0,fd_head->len); /* unused */
2551 /* ASSERT_EQ(0,fd_head->datalen);
2552 * reassembly not finished; datalen not well defined.
2553 * Current implemenation has it as 0, could change to 90 without issues */
2554 ASSERT_EQ(0,fd_head->reassembled_in);
2555 ASSERT_EQ(0,fd_head->flags);
2556 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
2557 ASSERT_NE_POINTER(NULL,fd_head->next);
2559 fd=fd_head->next;
2560 ASSERT_EQ(1,fd->frame);
2561 ASSERT_EQ(0,fd->offset); /* offset */
2562 ASSERT_EQ(50,fd->len); /* segment length */
2563 ASSERT_EQ(FD_SUBSET_TVB,fd->flags);
2564 ASSERT_EQ_POINTER(tvb_get_ptr(fd_head->tvb_data,0,0),tvb_get_ptr(fd->tvb_data,0,0));
2565 ASSERT_NE_POINTER(NULL,fd->next);
2567 fd=fd->next;
2568 ASSERT_EQ(2,fd->frame);
2569 ASSERT_EQ(50,fd->offset); /* offset */
2570 ASSERT_EQ(40,fd->len); /* segment length */
2571 ASSERT_EQ(0,fd->flags);
2572 ASSERT_NE_POINTER(NULL,fd->tvb_data);
2573 ASSERT_EQ_POINTER(NULL,fd->next);
2575 /* Another copy of the second segment.
2577 pinfo.num = 3;
2578 fd_head=fragment_add_check(&test_reassembly_table, tvb, 0, &pinfo, 12,
2579 NULL, 50, 40, true);
2581 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2582 ASSERT_EQ_POINTER(NULL,fd_head);
2583 fd_head=fragment_get(&test_reassembly_table, &pinfo, 12, NULL);
2584 ASSERT_NE_POINTER(NULL,fd_head);
2585 ASSERT_EQ(3,fd_head->frame); /* max frame we have */
2586 ASSERT_EQ(0,fd_head->len); /* unused */
2587 /* ASSERT_EQ(0,fd_head->datalen);
2588 * reassembly not finished; datalen not well defined.
2589 * Current implemenation has it as 0, could change to 90 without issues */
2590 ASSERT_EQ(0,fd_head->reassembled_in);
2591 ASSERT_EQ(0,fd_head->flags);
2592 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
2593 ASSERT_NE_POINTER(NULL,fd_head->next);
2595 fd=fd_head->next;
2596 ASSERT_EQ(1,fd->frame);
2597 ASSERT_EQ(0,fd->offset);
2598 ASSERT_EQ(50,fd->len); /* segment length */
2599 ASSERT_EQ(FD_SUBSET_TVB,fd->flags);
2600 ASSERT_EQ_POINTER(tvb_get_ptr(fd_head->tvb_data,0,0),tvb_get_ptr(fd->tvb_data,0,0));
2601 ASSERT_NE_POINTER(NULL,fd->next);
2603 fd=fd->next;
2604 ASSERT_EQ(2,fd->frame);
2605 ASSERT_EQ(50,fd->offset);
2606 ASSERT_EQ(40,fd->len); /* segment length */
2607 ASSERT_EQ(0,fd->flags);
2608 ASSERT_NE_POINTER(NULL,fd->tvb_data);
2609 ASSERT_NE_POINTER(NULL,fd->next);
2611 fd=fd->next;
2612 ASSERT_EQ(3,fd->frame);
2613 ASSERT_EQ(50,fd->offset);
2614 ASSERT_EQ(40,fd->len); /* segment length */
2615 ASSERT_EQ(0,fd->flags);
2616 ASSERT_NE_POINTER(NULL,fd->tvb_data);
2617 ASSERT_EQ_POINTER(NULL,fd->next);
2621 /* have another go at wrapping things up */
2622 pinfo.num = 4;
2623 fd_head=fragment_add_check(&test_reassembly_table, tvb, 20, &pinfo, 12,
2624 NULL, 90, 100, false);
2626 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2627 ASSERT_NE_POINTER(NULL,fd_head);
2629 /* check the contents of the structure */
2630 ASSERT_EQ(4,fd_head->frame); /* max frame we have */
2631 ASSERT_EQ(0,fd_head->len); /* unused */
2632 ASSERT_EQ(190,fd_head->datalen); /* the length of data we have */
2633 ASSERT_EQ(4,fd_head->reassembled_in);
2634 ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
2635 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
2636 ASSERT_NE_POINTER(NULL,fd_head->next);
2638 fd=fd_head->next;
2639 ASSERT_EQ(1,fd->frame);
2640 ASSERT_EQ(0,fd->offset);
2641 ASSERT_EQ(50,fd->len); /* segment length */
2642 ASSERT_EQ(0,fd->flags);
2643 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2644 ASSERT_NE_POINTER(NULL,fd->next);
2646 fd=fd->next;
2647 ASSERT_EQ(2,fd->frame);
2648 ASSERT_EQ(50,fd->offset);
2649 ASSERT_EQ(40,fd->len); /* segment length */
2650 ASSERT_EQ(0,fd->flags);
2651 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2652 ASSERT_NE_POINTER(NULL,fd->next);
2654 fd=fd->next;
2655 ASSERT_EQ(3,fd->frame);
2656 ASSERT_EQ(50,fd->offset);
2657 ASSERT_EQ(40,fd->len); /* segment length */
2658 ASSERT_EQ(FD_OVERLAP,fd->flags);
2659 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2660 ASSERT_NE_POINTER(NULL,fd->next);
2662 fd=fd->next;
2663 ASSERT_EQ(4,fd->frame);
2664 ASSERT_EQ(90,fd->offset);
2665 ASSERT_EQ(100,fd->len); /* segment length */
2666 ASSERT_EQ(0,fd->flags);
2667 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2668 ASSERT_EQ_POINTER(NULL,fd->next);
2670 /* test the actual reassembly */
2671 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
2672 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data,40));
2673 ASSERT(!tvb_memeql(fd_head->tvb_data,90,data+20,100));
2676 /* do it again (this time it is more complicated, with an overlap in the
2677 * reassembly) */
2679 fragment_set_partial_reassembly(&test_reassembly_table, &pinfo, 12, NULL);
2681 pinfo.num = 5;
2682 fragment_add_check(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
2683 190, 40, false);
2685 fd_head=fragment_get(&test_reassembly_table, &pinfo, 12, NULL);
2686 ASSERT_NE_POINTER(NULL,fd_head);
2687 ASSERT_EQ(5,fd_head->frame); /* max frame we have */
2688 ASSERT_EQ(0,fd_head->len); /* unused */
2689 ASSERT_EQ(230,fd_head->datalen); /* the length of data we have */
2690 ASSERT_EQ(5,fd_head->reassembled_in);
2691 ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
2692 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
2693 ASSERT_NE_POINTER(NULL,fd_head->next);
2695 fd=fd_head->next;
2696 ASSERT_EQ(1,fd->frame);
2697 ASSERT_EQ(0,fd->offset);
2698 ASSERT_EQ(50,fd->len); /* segment length */
2699 ASSERT_EQ(0,fd->flags);
2700 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2701 ASSERT_NE_POINTER(NULL,fd->next);
2703 fd=fd->next;
2704 ASSERT_EQ(2,fd->frame);
2705 ASSERT_EQ(50,fd->offset);
2706 ASSERT_EQ(40,fd->len); /* segment length */
2707 ASSERT_EQ(0,fd->flags);
2708 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2709 ASSERT_NE_POINTER(NULL,fd->next);
2711 fd=fd->next;
2712 ASSERT_EQ(3,fd->frame);
2713 ASSERT_EQ(50,fd->offset);
2714 ASSERT_EQ(40,fd->len); /* segment length */
2715 ASSERT_EQ(FD_OVERLAP,fd->flags);
2716 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2717 ASSERT_NE_POINTER(NULL,fd->next);
2719 fd=fd->next;
2720 ASSERT_EQ(4,fd->frame);
2721 ASSERT_EQ(90,fd->offset);
2722 ASSERT_EQ(100,fd->len); /* segment length */
2723 ASSERT_EQ(0,fd->flags);
2724 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2725 ASSERT_NE_POINTER(NULL,fd->next);
2727 fd=fd->next;
2728 ASSERT_EQ(5,fd->frame);
2729 ASSERT_EQ(190,fd->offset);
2730 ASSERT_EQ(40,fd->len); /* segment length */
2731 ASSERT_EQ(0,fd->flags);
2732 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2733 ASSERT_EQ_POINTER(NULL,fd->next);
2735 /* test the actual reassembly */
2736 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
2737 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data,40));
2738 ASSERT(!tvb_memeql(fd_head->tvb_data,90,data+20,100));
2739 ASSERT(!tvb_memeql(fd_head->tvb_data,190,data,40));
2741 #endif
2743 #if 0
2744 /* XXX: fragment_add_check moves completed reassemblies to the
2745 * reassembled_table, so adding a duplicated fragment after the end doesn't
2746 * get marked as duplicate, but starts a new reassembly. This is the correct
2747 * thing for very long captures where the identification field gets reused,
2748 * somewhat wrong when it is retransmitted data (it won't get marked as such
2749 * but doesn't interfere with defragmentation too much), and very wrong when
2750 * there is both retransmitted data and later on the identification field
2751 * gets reused (the dangling data will get added to the wrong reassembly.)
2753 * Not sure what behavior to check. Possibly both behaviors should be supported,
2754 * perhaps being affected by how close pinfo.num is to the reassembly, though
2755 * that gets complicated.
2757 /* Test case for fragment_add_check with duplicated (e.g., retransmitted) data.
2758 * Adds three fragments--adding the 1st one twice at the end--
2759 * and checks that they are reassembled correctly.
2761 /* visit id frame frag_off len more tvb_offset
2762 0 12 1 0 50 T 10
2763 0 12 2 50 60 T 5
2764 0 12 3 110 40 F 5
2765 0 12 4 0 50 T 10
2767 static void
2768 test_fragment_add_check_duplicate_first(void)
2770 fragment_head *fd_head;
2771 fragment_item *fd;
2772 volatile bool ex_thrown;
2774 printf("Starting test test_fragment_add_check_duplicate_first\n");
2776 pinfo.num = 1;
2777 fd_head=fragment_add_check(&test_reassembly_table, tvb, 10, &pinfo, 12,
2778 NULL, 0, 50, true);
2780 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2781 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
2782 ASSERT_EQ_POINTER(NULL,fd_head);
2784 /* Add the 2nd segment */
2785 pinfo.num = 2;
2786 fd_head=fragment_add_check(&test_reassembly_table, tvb, 5, &pinfo, 12,
2787 NULL, 50, 60, true);
2789 /* we haven't got all the fragments yet ... */
2790 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2791 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
2792 ASSERT_EQ_POINTER(NULL,fd_head);
2794 /* Add the last fragment */
2795 pinfo.num = 3;
2796 fd_head=fragment_add_check(&test_reassembly_table, tvb, 5, &pinfo, 12,
2797 NULL, 110, 40, false);
2799 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
2800 ASSERT_EQ(3,g_hash_table_size(test_reassembly_table.reassembled_table));
2801 ASSERT_NE_POINTER(NULL,fd_head);
2803 /* Add the first fragment again */
2804 pinfo.num = 4;
2805 fd_head=fragment_add_check(&test_reassembly_table, tvb, 10, &pinfo, 12,
2806 NULL, 0, 50, true);
2808 /* Reassembly should have still succeeded */
2809 /* XXX: Current behavior is to start a new reassembly - which is
2810 * the proper behavior in a long capture that reuses the id, but the
2811 * wrong thing when it's actually a retransmission. Should the distinction
2812 * be made by analyzing pinfo.num to see if it is nearby? Or is that the
2813 * dissector's job? */
2814 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2815 ASSERT_EQ(3,g_hash_table_size(test_reassembly_table.reassembled_table));
2816 ASSERT_NE_POINTER(NULL,fd_head);
2818 /* check the contents of the structure */
2819 /*ASSERT_EQ(4,fd_head->frame); max frame we have */
2820 ASSERT_EQ(3,fd_head->frame); /* never add the duplicate frame */
2821 ASSERT_EQ(0,fd_head->len); /* unused */
2822 ASSERT_EQ(150,fd_head->datalen);
2823 ASSERT_EQ(3,fd_head->reassembled_in);
2824 /* ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags); */
2825 /* FD_OVERLAP doesn't get set because we hit the exception early */
2826 ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET,fd_head->flags);
2827 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
2828 ASSERT_NE_POINTER(NULL,fd_head->next);
2830 fd = fd_head->next;
2832 ASSERT_EQ(1,fd->frame);
2833 ASSERT_EQ(0,fd->offset);
2834 ASSERT_EQ(50,fd->len); /* segment length */
2835 ASSERT_EQ(0,fd->flags);
2836 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2837 ASSERT_NE_POINTER(NULL,fd->next);
2840 fd = fd_head->next;
2841 ASSERT_EQ(4,fd->frame);
2842 ASSERT_EQ(0,fd->offset);
2843 ASSERT_EQ(50,fd->len);
2844 ASSERT_EQ(FD_OVERLAP,fd->flags);
2845 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2846 ASSERT_NE_POINTER(NULL,fd->next); */
2848 fd = fd->next;
2849 ASSERT_EQ(2,fd->frame);
2850 ASSERT_EQ(50,fd->offset);
2851 ASSERT_EQ(60,fd->len); /* segment length */
2852 ASSERT_EQ(0,fd->flags);
2853 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2854 ASSERT_NE_POINTER(NULL,fd->next);
2856 fd = fd->next;
2857 ASSERT_EQ(3,fd->frame);
2858 ASSERT_EQ(110,fd->offset);
2859 ASSERT_EQ(40,fd->len); /* segment length */
2860 ASSERT_EQ(0,fd->flags);
2861 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2862 ASSERT_EQ_POINTER(NULL,fd->next);
2864 /* test the actual reassembly */
2865 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
2866 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
2867 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
2869 if (debug) {
2870 print_fragment_table();
2873 #endif
2875 /* Test case for fragment_add_check with duplicated (e.g., retransmitted) data.
2876 * Adds three fragments--adding the 2nd one twice--
2877 * and checks that they are reassembled correctly.
2879 /* visit id frame frag_off len more tvb_offset
2880 0 12 1 0 50 T 10
2881 0 12 2 50 60 T 5
2882 0 12 3 50 60 T 5
2883 0 12 4 110 40 F 5
2885 static void
2886 test_fragment_add_check_duplicate_middle(void)
2888 fragment_head *fd_head;
2889 fragment_item *fd;
2891 printf("Starting test test_fragment_add_check_duplicate_middle\n");
2893 pinfo.num = 1;
2894 fd_head=fragment_add_check(&test_reassembly_table, tvb, 10, &pinfo, 12,
2895 NULL, 0, 50, true);
2897 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2898 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
2899 ASSERT_EQ_POINTER(NULL,fd_head);
2901 /* Add the 2nd segment */
2902 pinfo.num = 2;
2903 fd_head=fragment_add_check(&test_reassembly_table, tvb, 5, &pinfo, 12,
2904 NULL, 50, 60, true);
2906 /* we haven't got all the fragments yet ... */
2907 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2908 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
2909 ASSERT_EQ_POINTER(NULL,fd_head);
2911 /* Now, add the 2nd segment again (but in a different frame) */
2912 pinfo.num = 3;
2913 fd_head=fragment_add_check(&test_reassembly_table, tvb, 5, &pinfo, 12,
2914 NULL, 50, 60, true);
2916 /* This duplicate fragment should have been ignored */
2917 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2918 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
2919 ASSERT_EQ_POINTER(NULL,fd_head);
2921 /* finally, add the last fragment */
2922 pinfo.num = 4;
2923 fd_head=fragment_add_check(&test_reassembly_table, tvb, 5, &pinfo, 12,
2924 NULL, 110, 40, false);
2926 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
2927 ASSERT_EQ(4,g_hash_table_size(test_reassembly_table.reassembled_table));
2928 ASSERT_NE_POINTER(NULL,fd_head);
2930 /* check the contents of the structure */
2931 ASSERT_EQ(4,fd_head->frame); /* max frame we have */
2932 ASSERT_EQ(0,fd_head->len); /* unused */
2933 ASSERT_EQ(150,fd_head->datalen);
2934 ASSERT_EQ(4,fd_head->reassembled_in);
2935 ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
2936 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
2937 ASSERT_NE_POINTER(NULL,fd_head->next);
2939 fd = fd_head->next;
2940 ASSERT_EQ(1,fd->frame);
2941 ASSERT_EQ(0,fd->offset);
2942 ASSERT_EQ(50,fd->len); /* segment length */
2943 ASSERT_EQ(0,fd->flags);
2944 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2945 ASSERT_NE_POINTER(NULL,fd->next);
2947 fd = fd->next;
2948 ASSERT_EQ(2,fd->frame);
2949 ASSERT_EQ(50,fd->offset);
2950 ASSERT_EQ(60,fd->len); /* segment length */
2951 ASSERT_EQ(0,fd->flags);
2952 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2953 ASSERT_NE_POINTER(NULL,fd->next);
2955 fd = fd->next;
2956 ASSERT_EQ(3,fd->frame);
2957 ASSERT_EQ(50,fd->offset);
2958 ASSERT_EQ(60,fd->len); /* segment length */
2959 ASSERT_EQ(FD_OVERLAP,fd->flags);
2960 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2961 ASSERT_NE_POINTER(NULL,fd->next);
2963 fd = fd->next;
2964 ASSERT_EQ(4,fd->frame);
2965 ASSERT_EQ(110,fd->offset);
2966 ASSERT_EQ(40,fd->len); /* segment length */
2967 ASSERT_EQ(0,fd->flags);
2968 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2969 ASSERT_EQ_POINTER(NULL,fd->next);
2971 /* test the actual reassembly */
2972 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
2973 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
2974 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
2976 if (debug) {
2977 print_fragment_table();
2981 #if 0
2982 /* XXX: same issue as test_fragment_add_check_duplicate_first, above.
2984 /* Test case for fragment_add_check with duplicated (e.g., retransmitted) data.
2985 * Adds three fragments--adding the 3rd one twice--
2986 * and checks that they are reassembled correctly.
2988 /* visit id frame frag len more tvb_offset
2989 0 12 1 0 50 T 10
2990 0 12 2 1 60 T 5
2991 0 12 3 2 40 F 5
2992 0 12 4 2 40 F 5
2994 static void
2995 test_fragment_add_check_duplicate_last(void)
2997 fragment_head *fd_head;
2998 fragment_item *fd;
3000 printf("Starting test test_fragment_add_check_duplicate_last\n");
3002 pinfo.num = 1;
3003 fd_head=fragment_add_check(&test_reassembly_table, tvb, 10, &pinfo, 12,
3004 NULL, 0, 50, true);
3006 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
3007 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
3008 ASSERT_EQ_POINTER(NULL,fd_head);
3010 /* Add the 2nd segment */
3011 pinfo.num = 2;
3012 fd_head=fragment_add_check(&test_reassembly_table, tvb, 5, &pinfo, 12,
3013 NULL, 50, 60, true);
3015 /* we haven't got all the fragments yet ... */
3016 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
3017 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
3018 ASSERT_EQ_POINTER(NULL,fd_head);
3020 /* Add the last fragment */
3021 pinfo.num = 3;
3022 fd_head=fragment_add_check(&test_reassembly_table, tvb, 5, &pinfo, 12,
3023 NULL, 110, 40, false);
3025 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
3026 ASSERT_EQ(3,g_hash_table_size(test_reassembly_table.reassembled_table));
3027 ASSERT_NE_POINTER(NULL,fd_head);
3029 /* Add the last fragment again */
3030 pinfo.num = 4;
3031 fd_head=fragment_add_check(&test_reassembly_table, tvb, 5, &pinfo, 12,
3032 NULL, 110, 40, false);
3034 /* Reassembly should have still succeeded */
3035 /* XXX: Current behavior is to start a new reassembly */
3036 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
3037 ASSERT_EQ(3,g_hash_table_size(test_reassembly_table.reassembled_table));
3038 ASSERT_NE_POINTER(NULL,fd_head);
3040 /* check the contents of the structure */
3041 /* ASSERT_EQ(4,fd_head->frame); never add the last frame again */
3042 ASSERT_EQ(3,fd_head->frame); /* max frame we have */
3043 ASSERT_EQ(0,fd_head->len); /* unused */
3044 ASSERT_EQ(150,fd_head->datalen);
3045 ASSERT_EQ(3,fd_head->reassembled_in);
3046 /* ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
3047 * FD_OVERLAP doesn't get set since we don't add a fragment after the
3048 * end but start a new assembly instead. */
3049 ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET,fd_head->flags);
3050 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
3051 ASSERT_NE_POINTER(NULL,fd_head->next);
3053 fd = fd_head->next;
3054 ASSERT_EQ(1,fd->frame);
3055 ASSERT_EQ(0,fd->offset);
3056 ASSERT_EQ(50,fd->len); /* segment length */
3057 ASSERT_EQ(0,fd->flags);
3058 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
3059 ASSERT_NE_POINTER(NULL,fd->next);
3061 fd = fd->next;
3062 ASSERT_EQ(2,fd->frame);
3063 ASSERT_EQ(50,fd->offset);
3064 ASSERT_EQ(60,fd->len); /* segment length */
3065 ASSERT_EQ(0,fd->flags);
3066 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
3067 ASSERT_NE_POINTER(NULL,fd->next);
3069 fd = fd->next;
3070 ASSERT_EQ(3,fd->frame);
3071 ASSERT_EQ(110,fd->offset);
3072 ASSERT_EQ(40,fd->len); /* segment length */
3073 ASSERT_EQ(0,fd->flags);
3074 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
3076 /* Duplicate packet never gets added
3077 ASSERT_NE_POINTER(NULL,fd->next);
3079 fd = fd->next;
3080 ASSERT_EQ(4,fd->frame);
3081 ASSERT_EQ(110,fd->offset);
3082 ASSERT_EQ(40,fd->len);
3083 ASSERT_EQ(FD_OVERLAP,fd->flags);
3084 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
3085 ASSERT_EQ_POINTER(NULL,fd->next); */
3087 /* test the actual reassembly */
3088 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
3089 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
3090 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
3092 if (debug) {
3093 print_fragment_table();
3096 #endif
3098 /* Test case for fragment_add_check with duplicated (e.g., retransmitted) data
3099 * where the retransmission "conflicts" with the original transmission
3100 * (contents are different).
3101 * Adds three fragments--adding the 2nd one twice--
3102 * and checks that they are reassembled correctly.
3104 /* visit id frame frag_off len more tvb_offset
3105 0 12 1 0 50 T 10
3106 0 12 2 50 60 T 5
3107 0 12 3 50 60 T 15
3108 0 12 4 110 40 F 5
3110 static void
3111 test_fragment_add_check_duplicate_conflict(void)
3113 fragment_head *fd_head;
3114 fragment_item *fd;
3116 printf("Starting test test_fragment_add_check_duplicate_conflict\n");
3118 pinfo.num = 1;
3119 fd_head=fragment_add_check(&test_reassembly_table, tvb, 10, &pinfo, 12,
3120 NULL, 0, 50, true);
3122 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
3123 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
3124 ASSERT_EQ_POINTER(NULL,fd_head);
3126 /* Add the 2nd segment */
3127 pinfo.num = 2;
3128 fd_head=fragment_add_check(&test_reassembly_table, tvb, 5, &pinfo, 12,
3129 NULL, 50, 60, true);
3131 /* we haven't got all the fragments yet ... */
3132 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
3133 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
3134 ASSERT_EQ_POINTER(NULL,fd_head);
3136 /* Now, add the 2nd segment again (but in a different frame and with
3137 * different data)
3139 pinfo.num = 3;
3140 fd_head=fragment_add_check(&test_reassembly_table, tvb, 15, &pinfo, 12,
3141 NULL, 50, 60, true);
3143 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
3144 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
3145 ASSERT_EQ_POINTER(NULL,fd_head);
3147 /* finally, add the last fragment */
3148 pinfo.num = 4;
3149 fd_head=fragment_add_check(&test_reassembly_table, tvb, 5, &pinfo, 12,
3150 NULL, 110, 40, false);
3152 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
3153 ASSERT_EQ(4,g_hash_table_size(test_reassembly_table.reassembled_table));
3154 ASSERT_NE_POINTER(NULL,fd_head);
3156 /* check the contents of the structure */
3157 ASSERT_EQ(4,fd_head->frame); /* max frame we have */
3158 ASSERT_EQ(0,fd_head->len); /* unused */
3159 ASSERT_EQ(150,fd_head->datalen);
3160 ASSERT_EQ(4,fd_head->reassembled_in);
3161 ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET|FD_OVERLAP|FD_OVERLAPCONFLICT,fd_head->flags);
3162 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
3163 ASSERT_NE_POINTER(NULL,fd_head->next);
3165 fd = fd_head->next;
3166 ASSERT_EQ(1,fd->frame);
3167 ASSERT_EQ(0,fd->offset);
3168 ASSERT_EQ(50,fd->len); /* segment length */
3169 ASSERT_EQ(0,fd->flags);
3170 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
3171 ASSERT_NE_POINTER(NULL,fd->next);
3173 fd = fd->next;
3174 ASSERT_EQ(2,fd->frame);
3175 ASSERT_EQ(50,fd->offset);
3176 ASSERT_EQ(60,fd->len); /* segment length */
3177 ASSERT_EQ(0,fd->flags);
3178 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
3179 ASSERT_NE_POINTER(NULL,fd->next);
3181 fd = fd->next;
3182 ASSERT_EQ(3,fd->frame);
3183 ASSERT_EQ(50,fd->offset);
3184 ASSERT_EQ(60,fd->len); /* segment length */
3185 ASSERT_EQ(FD_OVERLAP|FD_OVERLAPCONFLICT,fd->flags);
3186 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
3187 ASSERT_NE_POINTER(NULL,fd->next);
3189 fd = fd->next;
3190 ASSERT_EQ(4,fd->frame);
3191 ASSERT_EQ(110,fd->offset);
3192 ASSERT_EQ(40,fd->len); /* segment length */
3193 ASSERT_EQ(0,fd->flags);
3194 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
3195 ASSERT_EQ_POINTER(NULL,fd->next);
3197 /* test the actual reassembly */
3198 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
3199 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
3200 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
3202 if (debug) {
3203 print_fragment_table();
3206 /**********************************************************************************
3208 * main
3210 *********************************************************************************/
3213 main(int argc _U_, char **argv _U_)
3215 frame_data fd;
3216 static const uint8_t src[] = {1,2,3,4}, dst[] = {5,6,7,8};
3217 unsigned int i;
3218 static void (*tests[])(void) = {
3219 test_simple_fragment_add_seq, /* frag table only */
3220 test_fragment_add_seq_partial_reassembly,
3221 test_fragment_add_seq_duplicate_first,
3222 test_fragment_add_seq_duplicate_middle,
3223 test_fragment_add_seq_duplicate_last,
3224 test_fragment_add_seq_duplicate_conflict,
3225 test_fragment_add_seq_check, /* frag + reassemble */
3226 test_fragment_add_seq_check_1,
3227 test_fragment_add_seq_802_11_0,
3228 test_fragment_add_seq_802_11_1,
3229 test_simple_fragment_add_seq_next,
3230 #if 0
3231 test_missing_data_fragment_add_seq_next,
3232 test_missing_data_fragment_add_seq_next_2,
3233 test_missing_data_fragment_add_seq_next_3,
3234 #endif
3235 #if 0
3236 test_fragment_add_seq_check_multiple
3237 #endif
3238 test_simple_fragment_add, /* frag table only */
3239 test_fragment_add_partial_reassembly,
3240 test_fragment_add_duplicate_first,
3241 test_fragment_add_duplicate_middle,
3242 test_fragment_add_duplicate_last,
3243 test_fragment_add_duplicate_conflict,
3244 test_simple_fragment_add_check, /* frag table only */
3245 #if 0
3246 test_fragment_add_check_partial_reassembly,
3247 test_fragment_add_check_duplicate_first,
3248 #endif
3249 test_fragment_add_check_duplicate_middle,
3250 #if 0
3251 test_fragment_add_check_duplicate_last,
3252 #endif
3253 test_fragment_add_check_duplicate_conflict,
3256 /* a tvbuff for testing with */
3257 data = (uint8_t *)g_malloc(DATA_LEN);
3258 /* make sure it's full of stuff */
3259 for(i=0; i<DATA_LEN; i++) {
3260 data[i]=i & 0xFF;
3262 tvb = tvb_new_real_data(data, DATA_LEN, DATA_LEN*2);
3264 /* other test stuff */
3265 pinfo.fd = &fd;
3266 fd.visited = 0;
3267 set_address(&pinfo.src,AT_IPv4,4,src);
3268 set_address(&pinfo.dst,AT_IPv4,4,dst);
3270 /*************************************************************************/
3271 for(i=0; i < array_length(tests); i++ ) {
3272 /* re-init the fragment tables */
3273 reassembly_table_init(&test_reassembly_table,
3274 &addresses_reassembly_table_functions);
3275 ASSERT(test_reassembly_table.fragment_table != NULL);
3276 ASSERT(test_reassembly_table.reassembled_table != NULL);
3278 pinfo.fd->visited = false;
3280 tests[i]();
3282 /* Free memory used by the tables */
3283 reassembly_table_destroy(&test_reassembly_table);
3286 tvb_free(tvb);
3287 tvb = NULL;
3288 g_free(data);
3289 data = NULL;
3291 printf(failure?"FAILURE\n":"SUCCESS\n");
3292 return failure;
3296 * Editor modelines - https://www.wireshark.org/tools/modelines.html
3298 * Local variables:
3299 * c-basic-offset: 4
3300 * tab-width: 8
3301 * indent-tabs-mode: nil
3302 * End:
3304 * vi: set shiftwidth=4 tabstop=8 expandtab:
3305 * :indentSize=4:tabSize=8:noTabs=true: