1 /* reassemble_test.c
2 * Standalone program to test functionality of reassemble.h API
3 *
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.
9 *
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
20 *
21 * Copyright (c) 2007 MX Telecom Ltd. <richardv@mxtelecom.com>
22 *
23 * Wireshark - Network traffic analyzer
24 * By Gerald Combs <gerald@wireshark.org>
25 * Copyright 1998
26 *
27 * SPDX-License-Identifier: GPL-2.0-or-later
28 */
29
from_string(const char * str)30 #include <stdarg.h>
31 #include <stdlib.h>
32 #include <stdio.h>
33 #include <string.h>
34
35 #include <glib.h>
36
37 #include "config.h"
38
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>
44
45 #include "exceptions.h"
46
47 static int failure = 0;
48 static const gboolean debug = FALSE; /* Set to TRUE to dump tables. */
49
50 #define ASSERT(b) \
51 if (!(b)) { \
52 failure = 1; \
53 printf("Assertion failed at line %i: %s\n", __LINE__, #b); \
54 exit(1); \
operator <<(std::basic_ostream<Elem,Traits> & os,const address & addr)55 }
56
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, (guint)exp, (guint)act); \
61 exit(1); \
62 }
63
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); \
69 }
70
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); \
76 }
77
78 #define DATA_LEN 256
79
80 static guint8 *data;
81 static tvbuff_t *tvb;
82 static packet_info pinfo;
83
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;
88
89 /*************************************************
90 * Util fcns to display
91 * fragment_table & reassembled_table fd-chains
92 ************************************************/
93
94 static struct _fd_flags {
95 guint32 flag;
96 gchar *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"},
107 };
108 #define N_FD_FLAGS (signed)(sizeof(fd_flags)/sizeof(struct _fd_flags))
109
110 static void
111 print_fd(fragment_head *fd, gboolean is_head) {
112 int i;
113
114 g_assert_true(fd != NULL);
115 printf(" %16p %16p %3u %3u %3u", (void *)fd, (void *)(fd->next), fd->frame, fd->offset, fd->len);
116 if (is_head) {
117 printf(" %3u %3u", fd->datalen, fd->reassembled_in);
118 } else {
119 printf( " ");
120 }
121 if (fd->tvb_data != NULL) {
122 printf(" %16p", tvb_get_ptr(fd->tvb_data, 0, 1)); /* Address of first byte only... */
123 } else {
124 printf(" %16s", "<null tvb_data>");
125 }
126 for (i=0; i < N_FD_FLAGS; i++) {
127 printf(" %s", (fd->flags & fd_flags[i].flag) ? fd_flags[i].flag_name : " ");
128 }
129 printf("\n");
130 }
131
132 static void
133 print_fd_chain(fragment_head *fd_head) {
134 fragment_item *fdp;
135
136 g_assert_true(fd_head != NULL);
137 print_fd(fd_head, TRUE);
138 for (fdp=fd_head->next; fdp != NULL; fdp=fdp->next) {
139 print_fd(fdp, FALSE);
140 }
141 }
142
143 static void
144 print_fragment_table_chain(gpointer k _U_, gpointer v, gpointer ud _U_) {
145 #ifdef DUMP_KEYS
146 fragment_key *key = (fragment_key*)k;
147 #endif
148 fragment_head *fd_head = (fragment_head *)v;
149 #ifdef DUMP_KEYS
150 printf(" --> FT: %3d 0x%08x 0x%08x\n", key->id, *(guint32 *)(key->src.data), *(guint32 *)(key->dst.data));
151 #endif
152 print_fd_chain(fd_head);
153 }
154
155 static void
156 print_fragment_table(void) {
157 printf("\n Fragment Table -------\n");
158 g_hash_table_foreach(test_reassembly_table.fragment_table, print_fragment_table_chain, NULL);
159 }
160
161 static void
162 print_reassembled_table_chain(gpointer k _U_, gpointer v, gpointer ud _U_) {
163 #ifdef DUMP_KEYS
164 reassembled_key *key = (reassembled_key*)k;
165 #endif
166 fragment_head *fd_head = (fragment_head *)v;
167 #ifdef DUMP_KEYS
168 printf(" --> RT: %5d %5d\n", key->id, key->frame);
169 #endif
170 print_fd_chain(fd_head);
171 }
172
173 static void
174 print_reassembled_table(void) {
175 printf("\n Reassembled Table ----\n");
176 g_hash_table_foreach(test_reassembly_table.reassembled_table, print_reassembled_table_chain, NULL);
177 }
178
179 static void
180 print_tables(void) {
181 print_fragment_table();
182 print_reassembled_table();
183 }
184
185 /**********************************************************************************
186 *
187 * fragment_add_seq
188 *
189 *********************************************************************************/
190
191 /* Simple test case for fragment_add_seq.
192 * Adds three fragments (out of order, with one for a different datagram in between),
193 * and checks that they are reassembled correctly.
194 */
195 /* visit id frame frag len more tvb_offset
196 0 12 1 0 50 T 10
197 1 12 1 0 60 T 5
198 0 13 2 0 60 T 15
199 0 12 3 2 60 F 5
200 0 12 4 1 60 T 15
201 */
202 static void
203 test_simple_fragment_add_seq(void)
204 {
205 fragment_head *fd_head, *fdh0;
206
207 printf("Starting test test_simple_fragment_add_seq\n");
208
209 pinfo.num = 1;
210 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
211 0, 50, TRUE, 0);
212
213 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
214 ASSERT_EQ_POINTER(NULL,fd_head);
215
216 /* adding the same fragment again should do nothing, even with different
217 * offset etc */
218 pinfo.fd->visited = 1;
219 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
220 0, 60, TRUE, 0);
221 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
222 ASSERT_EQ_POINTER(NULL,fd_head);
223
224 /* start another pdu (just to confuse things) */
225 pinfo.fd->visited = 0;
226 pinfo.num = 2;
227 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 15, &pinfo, 13, NULL,
228 0, 60, TRUE, 0);
229 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
230 ASSERT_EQ_POINTER(NULL,fd_head);
231
232 /* now we add the terminal fragment of the first datagram */
233 pinfo.num = 3;
234 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
235 2, 60, FALSE, 0);
236
237 /* we haven't got all the fragments yet ... */
238 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
239 ASSERT_EQ_POINTER(NULL,fd_head);
240
241 /* finally, add the missing fragment */
242 pinfo.num = 4;
243 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 15, &pinfo, 12, NULL,
244 1, 60, TRUE, 0);
245
246 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
247 ASSERT_NE_POINTER(NULL,fd_head);
248
249 /* check the contents of the structure */
250 ASSERT_EQ(4,fd_head->frame); /* max frame number of fragment in assembly */
251 ASSERT_EQ(0,fd_head->offset); /* unused */
252 ASSERT_EQ(170,fd_head->len); /* the length of data we have */
253 ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
254 ASSERT_EQ(4,fd_head->reassembled_in);
255 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
256 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
257 ASSERT_NE_POINTER(NULL,fd_head->next);
258
259 ASSERT_EQ(1,fd_head->next->frame);
260 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
261 ASSERT_EQ(50,fd_head->next->len); /* segment length */
262 ASSERT_EQ(0,fd_head->next->flags);
263 ASSERT_EQ_POINTER(NULL,fd_head->next->tvb_data);
264 ASSERT_NE_POINTER(NULL,fd_head->next->next);
265
266 ASSERT_EQ(4,fd_head->next->next->frame);
267 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
268 ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
269 ASSERT_EQ(0,fd_head->next->next->flags);
270 ASSERT_EQ_POINTER(NULL,fd_head->next->next->tvb_data);
271 ASSERT_NE_POINTER(NULL,fd_head->next->next->next);
272
273 ASSERT_EQ(3,fd_head->next->next->next->frame);
274 ASSERT_EQ(2,fd_head->next->next->next->offset); /* seqno */
275 ASSERT_EQ(60,fd_head->next->next->next->len); /* segment length */
276 ASSERT_EQ(0,fd_head->next->next->next->flags);
277 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->tvb_data);
278 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->next);
279
280 /* test the actual reassembly */
281 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
282 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+15,60));
283 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,60));
284
285 if (debug) {
286 print_fragment_table();
287 }
288
289 /* what happens if we revisit the packets now? */
290 fdh0 = fd_head;
291 pinfo.fd->visited = 1;
292 pinfo.num = 1;
293 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
294 0, 50, TRUE, 0);
295 /*
296 * this api relies on the caller to check fd_head -> reassembled_in
297 *
298 * Redoing all the tests seems like overkill - just check the pointer
299 */
300 ASSERT_EQ_POINTER(fdh0,fd_head);
301
302 pinfo.num = 3;
303 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
304 2, 60, FALSE, 0);
305 ASSERT_EQ_POINTER(fdh0,fd_head);
306
307 pinfo.num = 4;
308 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 15, &pinfo, 12, NULL,
309 1, 60, TRUE, 0);
310 ASSERT_EQ_POINTER(fdh0,fd_head);
311
312 if (debug) {
313 print_fragment_table();
314 }
315 }
316
317 /* XXX ought to have some tests for overlapping fragments */
318
319 /* This tests the functionality of fragment_set_partial_reassembly for
320 * FD_BLOCKSEQUENCE reassembly.
321 *
322 * We add a sequence of fragments thus:
323 * seqno frame offset len (initial) more_frags
324 * ----- ----- ------ --- --------------------
325 * 0 1 10 50 false
326 * 1 2 0 40 true
327 * 1 3 0 40 true (a duplicate fragment)
328 * 2 4 20 100 false
329 * 3 5 0 40 false
330 */
331 static void
332 test_fragment_add_seq_partial_reassembly(void)
333 {
334 fragment_head *fd_head;
335 fragment_item *fd;
336
337 printf("Starting test test_fragment_add_seq_partial_reassembly\n");
338
339 /* generally it's probably fair to assume that we will be called with
340 * more_frags=FALSE.
341 */
342 pinfo.num = 1;
343 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
344 0, 50, FALSE, 0);
345
346 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
347 ASSERT_NE_POINTER(NULL,fd_head);
348
349 /* check the contents of the structure */
350 ASSERT_EQ(1,fd_head->frame); /* max frame in reassembly */
351 ASSERT_EQ(0,fd_head->offset); /* unused */
352 ASSERT_EQ(50,fd_head->len); /* the length of data we have */
353 ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
354 ASSERT_EQ(1,fd_head->reassembled_in);
355 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
356 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
357 ASSERT_NE_POINTER(NULL,fd_head->next);
358
359 ASSERT_EQ(1,fd_head->next->frame);
360 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
361 ASSERT_EQ(50,fd_head->next->len); /* segment length */
362 ASSERT_EQ(0,fd_head->next->flags);
363 ASSERT_EQ_POINTER(NULL,fd_head->next->tvb_data);
364 ASSERT_EQ_POINTER(NULL,fd_head->next->next);
365
366 /* test the actual reassembly */
367 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
368
369 /* now we announce that the reassembly wasn't complete after all. */
370 fragment_set_partial_reassembly(&test_reassembly_table, &pinfo, 12, NULL);
371
372 /* and add another segment. To mix things up slightly (and so that we can
373 * check on the state of things), we're going to set the more_frags flag
374 * here
375 */
376 pinfo.num = 2;
377 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
378 1, 40, TRUE, 0);
379
380 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
381 ASSERT_EQ_POINTER(NULL,fd_head);
382
383 fd_head=fragment_get(&test_reassembly_table, &pinfo, 12, NULL);
384 ASSERT_NE_POINTER(NULL,fd_head);
385
386 /* check the contents of the structure */
387 ASSERT_EQ(2,fd_head->frame); /* max frame in reassembly */
388 ASSERT_EQ(0,fd_head->offset); /* unused */
389 /* ASSERT_EQ(50,fd_head->len); the length of data we have */
390 ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
391 ASSERT_EQ(0,fd_head->reassembled_in);
392 ASSERT_EQ(FD_BLOCKSEQUENCE,fd_head->flags);
393 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
394 ASSERT_NE_POINTER(NULL,fd_head->next);
395
396 fd=fd_head->next;
397 ASSERT_EQ(1,fd->frame);
398 ASSERT_EQ(0,fd->offset); /* seqno */
399 ASSERT_EQ(50,fd->len); /* segment length */
400 ASSERT_EQ(FD_SUBSET_TVB,fd->flags);
401 ASSERT_EQ_POINTER(tvb_get_ptr(fd_head->tvb_data,0,0),tvb_get_ptr(fd->tvb_data,0,0));
402 ASSERT_NE_POINTER(NULL,fd->next);
403
404 fd=fd->next;
405 ASSERT_EQ(2,fd->frame);
406 ASSERT_EQ(1,fd->offset); /* seqno */
407 ASSERT_EQ(40,fd->len); /* segment length */
408 ASSERT_EQ(0,fd->flags);
409 ASSERT_NE_POINTER(NULL,fd->tvb_data);
410 ASSERT_EQ_POINTER(NULL,fd->next);
411
412 /* Another copy of the second segment.
413 */
414 pinfo.num = 3;
415 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
416 1, 40, TRUE, 0);
417
418 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
419 ASSERT_EQ_POINTER(NULL,fd_head);
420 fd_head=fragment_get(&test_reassembly_table, &pinfo, 12, NULL);
421 ASSERT_NE_POINTER(NULL,fd_head);
422 ASSERT_EQ(3,fd_head->frame); /* max frame we have */
423 ASSERT_EQ(0,fd_head->offset); /* unused */
424 /* ASSERT_EQ(50,fd_head->len); the length of data we have */
425 ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
426 ASSERT_EQ(0,fd_head->reassembled_in);
427 ASSERT_EQ(FD_BLOCKSEQUENCE,fd_head->flags);
428 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
429 ASSERT_NE_POINTER(NULL,fd_head->next);
430
431 fd=fd_head->next;
432 ASSERT_EQ(1,fd->frame);
433 ASSERT_EQ(0,fd->offset); /* seqno */
434 ASSERT_EQ(50,fd->len); /* segment length */
435 ASSERT_EQ(FD_SUBSET_TVB,fd->flags);
436 ASSERT_EQ_POINTER(tvb_get_ptr(fd_head->tvb_data,0,0),tvb_get_ptr(fd->tvb_data,0,0));
437 ASSERT_NE_POINTER(NULL,fd->next);
438
439 fd=fd->next;
440 ASSERT_EQ(2,fd->frame);
441 ASSERT_EQ(1,fd->offset); /* seqno */
442 ASSERT_EQ(40,fd->len); /* segment length */
443 ASSERT_EQ(0,fd->flags);
444 ASSERT_NE_POINTER(NULL,fd->tvb_data);
445 ASSERT_NE_POINTER(NULL,fd->next);
446
447 fd=fd->next;
448 ASSERT_EQ(3,fd->frame);
449 ASSERT_EQ(1,fd->offset); /* seqno */
450 ASSERT_EQ(40,fd->len); /* segment length */
451 ASSERT_EQ(0,fd->flags);
452 ASSERT_NE_POINTER(NULL,fd->tvb_data);
453 ASSERT_EQ_POINTER(NULL,fd->next);
454
455
456
457 /* have another go at wrapping things up */
458 pinfo.num = 4;
459 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 20, &pinfo, 12, NULL,
460 2, 100, FALSE, 0);
461
462 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
463 ASSERT_NE_POINTER(NULL,fd_head);
464
465 /* check the contents of the structure */
466 ASSERT_EQ(4,fd_head->frame); /* max frame we have */
467 ASSERT_EQ(0,fd_head->offset); /* unused */
468 ASSERT_EQ(190,fd_head->len); /* the length of data we have */
469 ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
470 ASSERT_EQ(4,fd_head->reassembled_in);
471 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
472 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
473 ASSERT_NE_POINTER(NULL,fd_head->next);
474
475 fd=fd_head->next;
476 ASSERT_EQ(1,fd->frame);
477 ASSERT_EQ(0,fd->offset); /* seqno */
478 ASSERT_EQ(50,fd->len); /* segment length */
479 ASSERT_EQ(0,fd->flags);
480 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
481 ASSERT_NE_POINTER(NULL,fd->next);
482
483 fd=fd->next;
484 ASSERT_EQ(2,fd->frame);
485 ASSERT_EQ(1,fd->offset); /* seqno */
486 ASSERT_EQ(40,fd->len); /* segment length */
487 ASSERT_EQ(0,fd->flags);
488 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
489 ASSERT_NE_POINTER(NULL,fd->next);
490
491 fd=fd->next;
492 ASSERT_EQ(3,fd->frame);
493 ASSERT_EQ(1,fd->offset); /* seqno */
494 ASSERT_EQ(40,fd->len); /* segment length */
495 ASSERT_EQ(FD_OVERLAP,fd->flags);
496 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
497 ASSERT_NE_POINTER(NULL,fd->next);
498
499 fd=fd->next;
500 ASSERT_EQ(4,fd->frame);
501 ASSERT_EQ(2,fd->offset); /* seqno */
502 ASSERT_EQ(100,fd->len); /* segment length */
503 ASSERT_EQ(0,fd->flags);
504 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
505 ASSERT_EQ_POINTER(NULL,fd->next);
506
507 /* test the actual reassembly */
508 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
509 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data,40));
510 ASSERT(!tvb_memeql(fd_head->tvb_data,90,data+20,100));
511
512
513 /* do it again (this time it is more complicated, with an overlap in the
514 * reassembly) */
515
516 fragment_set_partial_reassembly(&test_reassembly_table, &pinfo, 12, NULL);
517
518 pinfo.num = 5;
519 fragment_add_seq(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
520 3, 40, FALSE, 0);
521
522 fd_head=fragment_get(&test_reassembly_table, &pinfo, 12, NULL);
523 ASSERT_NE_POINTER(NULL,fd_head);
524 ASSERT_EQ(5,fd_head->frame); /* max frame we have */
525 ASSERT_EQ(0,fd_head->offset); /* unused */
526 ASSERT_EQ(230,fd_head->len); /* the length of data we have */
527 ASSERT_EQ(3,fd_head->datalen); /* seqno of the last fragment we have */
528 ASSERT_EQ(5,fd_head->reassembled_in);
529 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
530 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
531 ASSERT_NE_POINTER(NULL,fd_head->next);
532
533 fd=fd_head->next;
534 ASSERT_EQ(1,fd->frame);
535 ASSERT_EQ(0,fd->offset); /* seqno */
536 ASSERT_EQ(50,fd->len); /* segment length */
537 ASSERT_EQ(0,fd->flags);
538 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
539 ASSERT_NE_POINTER(NULL,fd->next);
540
541 fd=fd->next;
542 ASSERT_EQ(2,fd->frame);
543 ASSERT_EQ(1,fd->offset); /* seqno */
544 ASSERT_EQ(40,fd->len); /* segment length */
545 ASSERT_EQ(0,fd->flags);
546 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
547 ASSERT_NE_POINTER(NULL,fd->next);
548
549 fd=fd->next;
550 ASSERT_EQ(3,fd->frame);
551 ASSERT_EQ(1,fd->offset); /* seqno */
552 ASSERT_EQ(40,fd->len); /* segment length */
553 ASSERT_EQ(FD_OVERLAP,fd->flags);
554 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
555 ASSERT_NE_POINTER(NULL,fd->next);
556
557 fd=fd->next;
558 ASSERT_EQ(4,fd->frame);
559 ASSERT_EQ(2,fd->offset); /* seqno */
560 ASSERT_EQ(100,fd->len); /* segment length */
561 ASSERT_EQ(0,fd->flags);
562 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
563 ASSERT_NE_POINTER(NULL,fd->next);
564
565 fd=fd->next;
566 ASSERT_EQ(5,fd->frame);
567 ASSERT_EQ(3,fd->offset); /* seqno */
568 ASSERT_EQ(40,fd->len); /* segment length */
569 ASSERT_EQ(0,fd->flags);
570 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
571 ASSERT_EQ_POINTER(NULL,fd->next);
572
573 /* test the actual reassembly */
574 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
575 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data,40));
576 ASSERT(!tvb_memeql(fd_head->tvb_data,90,data+20,100));
577 ASSERT(!tvb_memeql(fd_head->tvb_data,190,data,40));
578 }
579
580 /* Test case for fragment_add_seq with duplicated (e.g., retransmitted) data.
581 * Adds three fragments--adding the 1st one twice--
582 * and checks that they are reassembled correctly.
583 */
584 /* visit id frame frag len more tvb_offset
585 0 12 1 0 50 T 10
586 0 12 2 1 60 T 5
587 0 12 3 2 40 F 5
588 0 12 4 0 50 T 10
589 */
590 static void
591 test_fragment_add_seq_duplicate_first(void)
592 {
593 fragment_head *fd_head;
594
595 printf("Starting test test_fragment_add_seq_duplicate_first\n");
596
597 pinfo.num = 1;
598 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
599 0, 50, TRUE, 0);
600
601 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
602 ASSERT_EQ_POINTER(NULL,fd_head);
603
604 /* Add the 2nd segment */
605 pinfo.num = 2;
606 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
607 1, 60, TRUE, 0);
608
609 /* we haven't got all the fragments yet ... */
610 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
611 ASSERT_EQ_POINTER(NULL,fd_head);
612
613 /* Add the last fragment */
614 pinfo.num = 3;
615 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
616 2, 40, FALSE, 0);
617
618 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
619 ASSERT_NE_POINTER(NULL,fd_head);
620
621 /* Add the first fragment again */
622 pinfo.num = 4;
623 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
624 0, 50, TRUE, 0);
625
626 /* Reassembly should have still succeeded */
627 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
628 ASSERT_NE_POINTER(NULL,fd_head);
629
630 /* check the contents of the structure */
631 ASSERT_EQ(4,fd_head->frame); /* max frame we have */
632 ASSERT_EQ(0,fd_head->offset); /* unused */
633 ASSERT_EQ(150,fd_head->len); /* the length of data we have */
634 ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
635 ASSERT_EQ(3,fd_head->reassembled_in);
636 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
637 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
638 ASSERT_NE_POINTER(NULL,fd_head->next);
639
640 ASSERT_EQ(1,fd_head->next->frame);
641 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
642 ASSERT_EQ(50,fd_head->next->len); /* segment length */
643 ASSERT_EQ(0,fd_head->next->flags);
644 ASSERT_EQ_POINTER(NULL,fd_head->next->tvb_data);
645 ASSERT_NE_POINTER(NULL,fd_head->next->next);
646
647 ASSERT_EQ(4,fd_head->next->next->frame);
648 ASSERT_EQ(0,fd_head->next->next->offset); /* seqno */
649 ASSERT_EQ(50,fd_head->next->next->len); /* segment length */
650 ASSERT_EQ(FD_OVERLAP,fd_head->next->next->flags);
651 ASSERT_EQ_POINTER(NULL,fd_head->next->next->tvb_data);
652 ASSERT_NE_POINTER(NULL,fd_head->next->next->next);
653
654 ASSERT_EQ(2,fd_head->next->next->next->frame);
655 ASSERT_EQ(1,fd_head->next->next->next->offset); /* seqno */
656 ASSERT_EQ(60,fd_head->next->next->next->len); /* segment length */
657 ASSERT_EQ(0,fd_head->next->next->next->flags);
658 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->tvb_data);
659 ASSERT_NE_POINTER(NULL,fd_head->next->next->next->next);
660
661 ASSERT_EQ(3,fd_head->next->next->next->next->frame);
662 ASSERT_EQ(2,fd_head->next->next->next->next->offset); /* seqno */
663 ASSERT_EQ(40,fd_head->next->next->next->next->len); /* segment length */
664 ASSERT_EQ(0,fd_head->next->next->next->next->flags);
665 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->next->tvb_data);
666 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->next->next);
667
668 /* test the actual reassembly */
669 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
670 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
671 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
672
673 if (debug) {
674 print_fragment_table();
675 }
676 }
677
678
679 /* Test case for fragment_add_seq with duplicated (e.g., retransmitted) data.
680 * Adds three fragments--adding the 2nd one twice--
681 * and checks that they are reassembled correctly.
682 */
683 /* visit id frame frag len more tvb_offset
684 0 12 1 0 50 T 10
685 0 12 2 1 60 T 5
686 0 12 3 1 60 T 5
687 0 12 4 3 40 F 5
688 */
689 static void
690 test_fragment_add_seq_duplicate_middle(void)
691 {
692 fragment_head *fd_head;
693
694 printf("Starting test test_fragment_add_seq_duplicate_middle\n");
695
696 pinfo.num = 1;
697 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
698 0, 50, TRUE, 0);
699
700 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
701 ASSERT_EQ_POINTER(NULL,fd_head);
702
703 /* Add the 2nd segment */
704 pinfo.num = 2;
705 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
706 1, 60, TRUE, 0);
707
708 /* we haven't got all the fragments yet ... */
709 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
710 ASSERT_EQ_POINTER(NULL,fd_head);
711
712 /* Now, add the 2nd segment again (but in a different frame) */
713 pinfo.num = 3;
714 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
715 1, 60, TRUE, 0);
716
717 /* This duplicate fragment should have been ignored */
718 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
719 ASSERT_EQ_POINTER(NULL,fd_head);
720
721 /* finally, add the last fragment */
722 pinfo.num = 4;
723 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
724 2, 40, FALSE, 0);
725
726 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
727 ASSERT_NE_POINTER(NULL,fd_head);
728
729 /* check the contents of the structure */
730 ASSERT_EQ(4,fd_head->frame); /* max frame we have */
731 ASSERT_EQ(0,fd_head->offset); /* unused */
732 ASSERT_EQ(150,fd_head->len); /* the length of data we have */
733 ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
734 ASSERT_EQ(4,fd_head->reassembled_in);
735 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
736 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
737 ASSERT_NE_POINTER(NULL,fd_head->next);
738
739 ASSERT_EQ(1,fd_head->next->frame);
740 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
741 ASSERT_EQ(50,fd_head->next->len); /* segment length */
742 ASSERT_EQ(0,fd_head->next->flags);
743 ASSERT_EQ_POINTER(NULL,fd_head->next->tvb_data);
744 ASSERT_NE_POINTER(NULL,fd_head->next->next);
745
746 ASSERT_EQ(2,fd_head->next->next->frame);
747 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
748 ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
749 ASSERT_EQ(0,fd_head->next->next->flags);
750 ASSERT_EQ_POINTER(NULL,fd_head->next->next->tvb_data);
751 ASSERT_NE_POINTER(NULL,fd_head->next->next->next);
752
753 ASSERT_EQ(3,fd_head->next->next->next->frame);
754 ASSERT_EQ(1,fd_head->next->next->next->offset); /* seqno */
755 ASSERT_EQ(60,fd_head->next->next->next->len); /* segment length */
756 ASSERT_EQ(FD_OVERLAP,fd_head->next->next->next->flags);
757 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->tvb_data);
758 ASSERT_NE_POINTER(NULL,fd_head->next->next->next->next);
759
760 ASSERT_EQ(4,fd_head->next->next->next->next->frame);
761 ASSERT_EQ(2,fd_head->next->next->next->next->offset); /* seqno */
762 ASSERT_EQ(40,fd_head->next->next->next->next->len); /* segment length */
763 ASSERT_EQ(0,fd_head->next->next->next->next->flags);
764 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->next->tvb_data);
765 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->next->next);
766
767 /* test the actual reassembly */
768 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
769 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
770 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
771
772 if (debug) {
773 print_fragment_table();
774 }
775 }
776
777 /* Test case for fragment_add_seq with duplicated (e.g., retransmitted) data.
778 * Adds three fragments--adding the 3rd one twice--
779 * and checks that they are reassembled correctly.
780 */
781 /* visit id frame frag len more tvb_offset
782 0 12 1 0 50 T 10
783 0 12 2 1 60 T 5
784 0 12 3 2 40 F 5
785 0 12 4 2 40 F 5
786 */
787 static void
788 test_fragment_add_seq_duplicate_last(void)
789 {
790 fragment_head *fd_head;
791
792 printf("Starting test test_fragment_add_seq_duplicate_last\n");
793
794 pinfo.num = 1;
795 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
796 0, 50, TRUE, 0);
797
798 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
799 ASSERT_EQ_POINTER(NULL,fd_head);
800
801 /* Add the 2nd segment */
802 pinfo.num = 2;
803 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
804 1, 60, TRUE, 0);
805
806 /* we haven't got all the fragments yet ... */
807 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
808 ASSERT_EQ_POINTER(NULL,fd_head);
809
810 /* Add the last fragment */
811 pinfo.num = 3;
812 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
813 2, 40, FALSE, 0);
814
815 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
816 ASSERT_NE_POINTER(NULL,fd_head);
817
818 /* Add the last fragment again */
819 pinfo.num = 4;
820 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
821 2, 40, FALSE, 0);
822
823 /* Reassembly should have still succeeded */
824 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
825 ASSERT_NE_POINTER(NULL,fd_head);
826
827 /* check the contents of the structure */
828 ASSERT_EQ(4,fd_head->frame); /* max frame we have */
829 ASSERT_EQ(0,fd_head->offset); /* unused */
830 ASSERT_EQ(150,fd_head->len); /* the length of data we have */
831 ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
832 ASSERT_EQ(3,fd_head->reassembled_in);
833 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
834 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
835 ASSERT_NE_POINTER(NULL,fd_head->next);
836
837 ASSERT_EQ(1,fd_head->next->frame);
838 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
839 ASSERT_EQ(50,fd_head->next->len); /* segment length */
840 ASSERT_EQ(0,fd_head->next->flags);
841 ASSERT_EQ_POINTER(NULL,fd_head->next->tvb_data);
842 ASSERT_NE_POINTER(NULL,fd_head->next->next);
843
844 ASSERT_EQ(2,fd_head->next->next->frame);
845 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
846 ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
847 ASSERT_EQ(0,fd_head->next->next->flags);
848 ASSERT_EQ_POINTER(NULL,fd_head->next->next->tvb_data);
849 ASSERT_NE_POINTER(NULL,fd_head->next->next->next);
850
851 ASSERT_EQ(3,fd_head->next->next->next->frame);
852 ASSERT_EQ(2,fd_head->next->next->next->offset); /* seqno */
853 ASSERT_EQ(40,fd_head->next->next->next->len); /* segment length */
854 ASSERT_EQ(0,fd_head->next->next->next->flags);
855 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->tvb_data);
856 ASSERT_NE_POINTER(NULL,fd_head->next->next->next->next);
857
858 ASSERT_EQ(4,fd_head->next->next->next->next->frame);
859 ASSERT_EQ(2,fd_head->next->next->next->next->offset); /* seqno */
860 ASSERT_EQ(40,fd_head->next->next->next->next->len); /* segment length */
861 ASSERT_EQ(FD_OVERLAP,fd_head->next->next->next->next->flags);
862 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->next->tvb_data);
863 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->next->next);
864
865 /* test the actual reassembly */
866 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
867 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
868 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
869
870 if (debug) {
871 print_fragment_table();
872 }
873 }
874
875 /* Test case for fragment_add_seq with duplicated (e.g., retransmitted) data
876 * where the retransmission "conflicts" with the original transmission
877 * (contents are different).
878 * Adds three fragments--adding the 2nd one twice--
879 * and checks that they are reassembled correctly.
880 */
881 /* visit id frame frag len more tvb_offset
882 0 12 1 0 50 T 10
883 0 12 2 1 60 T 5
884 0 12 3 1 60 T 15
885 0 12 4 2 40 F 5
886 */
887 static void
888 test_fragment_add_seq_duplicate_conflict(void)
889 {
890 fragment_head *fd_head;
891
892 printf("Starting test test_fragment_add_seq_duplicate_conflict\n");
893
894 pinfo.num = 1;
895 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
896 0, 50, TRUE, 0);
897
898 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
899 ASSERT_EQ_POINTER(NULL,fd_head);
900
901 /* Add the 2nd segment */
902 pinfo.num = 2;
903 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
904 1, 60, TRUE, 0);
905
906 /* we haven't got all the fragments yet ... */
907 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
908 ASSERT_EQ_POINTER(NULL,fd_head);
909
910 /* Now, add the 2nd segment again (but in a different frame and with
911 * different data)
912 */
913 pinfo.num = 3;
914 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 15, &pinfo, 12, NULL,
915 1, 60, TRUE, 0);
916
917 /* This duplicate fragment should have been ignored */
918 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
919 ASSERT_EQ_POINTER(NULL,fd_head);
920
921 /* finally, add the last fragment */
922 pinfo.num = 4;
923 fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
924 2, 40, FALSE, 0);
925
926 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
927 ASSERT_NE_POINTER(NULL,fd_head);
928
929 /* check the contents of the structure */
930 ASSERT_EQ(4,fd_head->frame); /* max frame we have */
931 ASSERT_EQ(0,fd_head->offset); /* unused */
932 ASSERT_EQ(150,fd_head->len); /* the length of data we have */
933 ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
934 ASSERT_EQ(4,fd_head->reassembled_in);
935 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP|FD_OVERLAPCONFLICT,fd_head->flags);
936 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
937 ASSERT_NE_POINTER(NULL,fd_head->next);
938
939 ASSERT_EQ(1,fd_head->next->frame);
940 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
941 ASSERT_EQ(50,fd_head->next->len); /* segment length */
942 ASSERT_EQ(0,fd_head->next->flags);
943 ASSERT_EQ_POINTER(NULL,fd_head->next->tvb_data);
944 ASSERT_NE_POINTER(NULL,fd_head->next->next);
945
946 ASSERT_EQ(2,fd_head->next->next->frame);
947 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
948 ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
949 ASSERT_EQ(0,fd_head->next->next->flags);
950 ASSERT_EQ_POINTER(NULL,fd_head->next->next->tvb_data);
951 ASSERT_NE_POINTER(NULL,fd_head->next->next->next);
952
953 ASSERT_EQ(3,fd_head->next->next->next->frame);
954 ASSERT_EQ(1,fd_head->next->next->next->offset); /* seqno */
955 ASSERT_EQ(60,fd_head->next->next->next->len); /* segment length */
956 ASSERT_EQ(FD_OVERLAP|FD_OVERLAPCONFLICT,fd_head->next->next->next->flags);
957 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->tvb_data);
958 ASSERT_NE_POINTER(NULL,fd_head->next->next->next->next);
959
960 ASSERT_EQ(4,fd_head->next->next->next->next->frame);
961 ASSERT_EQ(2,fd_head->next->next->next->next->offset); /* seqno */
962 ASSERT_EQ(40,fd_head->next->next->next->next->len); /* segment length */
963 ASSERT_EQ(0,fd_head->next->next->next->next->flags);
964 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->next->tvb_data);
965 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->next->next);
966
967 /* test the actual reassembly */
968 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
969 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
970 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
971
972 if (debug) {
973 print_fragment_table();
974 }
975 }
976
977 /**********************************************************************************
978 *
979 * fragment_add_seq_check
980 *
981 *********************************************************************************/
982
983
984 /* This routine is used for both fragment_add_seq_802_11 and
985 * fragment_add_seq_check.
986 *
987 * Adds a couple of out-of-order fragments and checks their reassembly.
988 */
989
990 /* visit id frame frag len more tvb_offset
991 0 12 1 0 50 T 10
992 0 13 2 0 60 T 15
993 0 12 3 2 60 F 5
994 0 12 4 1 60 F 15
995 */
996
997
998 static void
999 test_fragment_add_seq_check_work(fragment_head *(*fn)(reassembly_table *,
1000 tvbuff_t *, const int, const packet_info *,
1001 const guint32, const void *, const guint32,
1002 const guint32, const gboolean))
1003 {
1004 fragment_head *fd_head;
1005
1006 pinfo.num = 1;
1007 fd_head=fn(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1008 0, 50, TRUE);
1009
1010 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1011 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1012 ASSERT_EQ_POINTER(NULL,fd_head);
1013
1014 /* start another pdu (just to confuse things) */
1015 pinfo.num = 2;
1016 fd_head=fn(&test_reassembly_table, tvb, 15, &pinfo, 13, NULL,
1017 0, 60, TRUE);
1018 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
1019 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1020 ASSERT_EQ_POINTER(NULL,fd_head);
1021
1022 /* add the terminal fragment of the first datagram */
1023 pinfo.num = 3;
1024 fd_head=fn(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1025 2, 60, FALSE);
1026
1027 /* we haven't got all the fragments yet ... */
1028 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
1029 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1030 ASSERT_EQ_POINTER(NULL,fd_head);
1031
1032 /* finally, add the missing fragment */
1033 pinfo.num = 4;
1034 fd_head=fn(&test_reassembly_table, tvb, 15, &pinfo, 12, NULL,
1035 1, 60, TRUE);
1036
1037 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1038 ASSERT_EQ(3,g_hash_table_size(test_reassembly_table.reassembled_table));
1039 ASSERT_NE_POINTER(NULL,fd_head);
1040
1041 /* check the contents of the structure */
1042 ASSERT_EQ(4,fd_head->frame); /* max frame we have */
1043 ASSERT_EQ(0,fd_head->offset); /* unused */
1044 ASSERT_EQ(170,fd_head->len); /* the length of data we have */
1045 ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
1046 ASSERT_EQ(4,fd_head->reassembled_in);
1047 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
1048 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
1049 ASSERT_NE_POINTER(NULL,fd_head->next);
1050
1051 ASSERT_EQ(1,fd_head->next->frame);
1052 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
1053 ASSERT_EQ(50,fd_head->next->len); /* segment length */
1054 ASSERT_EQ(0,fd_head->next->flags);
1055 ASSERT_EQ_POINTER(NULL,fd_head->next->tvb_data);
1056 ASSERT_NE_POINTER(NULL,fd_head->next->next);
1057
1058 ASSERT_EQ(4,fd_head->next->next->frame);
1059 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
1060 ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
1061 ASSERT_EQ(0,fd_head->next->next->flags);
1062 ASSERT_EQ_POINTER(NULL,fd_head->next->next->tvb_data);
1063 ASSERT_NE_POINTER(NULL,fd_head->next->next->next);
1064
1065 ASSERT_EQ(3,fd_head->next->next->next->frame);
1066 ASSERT_EQ(2,fd_head->next->next->next->offset); /* seqno */
1067 ASSERT_EQ(60,fd_head->next->next->next->len); /* segment length */
1068 ASSERT_EQ(0,fd_head->next->next->next->flags);
1069 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->tvb_data);
1070 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->next);
1071
1072 /* test the actual reassembly */
1073 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
1074 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+15,60));
1075 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,60));
1076
1077 if (debug) {
1078 print_tables();
1079 }
1080 }
1081
1082 /* Simple test case for fragment_add_seq_check
1083 */
1084 static void
1085 test_fragment_add_seq_check(void)
1086 {
1087 printf("Starting test test_fragment_add_seq_check\n");
1088
1089 test_fragment_add_seq_check_work(fragment_add_seq_check);
1090 }
1091
1092
1093 /* This tests the case that the 802.11 hack does something different for: when
1094 * the terminal segment in a fragmented datagram arrives first.
1095 */
1096 static void
1097 test_fragment_add_seq_check_1(void)
1098 {
1099 fragment_head *fd_head;
1100
1101 printf("Starting test test_fragment_add_seq_check_1\n");
1102
1103 pinfo.num = 1;
1104 fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1105 1, 50, FALSE);
1106
1107 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1108 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1109 ASSERT_EQ_POINTER(NULL,fd_head);
1110
1111 /* Now add the missing segment */
1112 pinfo.num = 2;
1113 fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1114 0, 60, TRUE);
1115
1116 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1117 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.reassembled_table));
1118 ASSERT_NE_POINTER(NULL,fd_head);
1119
1120 /* check the contents of the structure */
1121 ASSERT_EQ(2,fd_head->frame); /* max frame of fragment in structure */
1122 ASSERT_EQ(0,fd_head->offset); /* unused */
1123 ASSERT_EQ(110,fd_head->len); /* the length of data we have */
1124 ASSERT_EQ(1,fd_head->datalen); /* seqno of the last fragment we have */
1125 ASSERT_EQ(2,fd_head->reassembled_in);
1126 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
1127 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
1128 ASSERT_NE_POINTER(NULL,fd_head->next);
1129
1130 ASSERT_EQ(2,fd_head->next->frame);
1131 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
1132 ASSERT_EQ(60,fd_head->next->len); /* segment length */
1133 ASSERT_EQ(0,fd_head->next->flags);
1134 ASSERT_EQ_POINTER(NULL,fd_head->next->tvb_data);
1135 ASSERT_NE_POINTER(NULL,fd_head->next->next);
1136
1137 ASSERT_EQ(1,fd_head->next->next->frame);
1138 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
1139 ASSERT_EQ(50,fd_head->next->next->len); /* segment length */
1140 ASSERT_EQ(0,fd_head->next->next->flags);
1141 ASSERT_EQ_POINTER(NULL,fd_head->next->next->tvb_data);
1142 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next);
1143
1144 /* test the actual reassembly */
1145 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+5,60));
1146 ASSERT(!tvb_memeql(fd_head->tvb_data,60,data+10,50));
1147 }
1148
1149 /**********************************************************************************
1150 *
1151 * fragment_add_seq_802_11
1152 *
1153 *********************************************************************************/
1154
1155 /* Tests the 802.11 hack.
1156 */
1157 static void
1158 test_fragment_add_seq_802_11_0(void)
1159 {
1160 fragment_head *fd_head;
1161
1162 printf("Starting test test_fragment_add_seq_802_11_0\n");
1163
1164 /* the 802.11 hack is that some non-fragmented datagrams have non-zero
1165 * fragment_number; test for this. */
1166
1167 pinfo.num = 1;
1168 fd_head=fragment_add_seq_802_11(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1169 10, 50, FALSE);
1170
1171 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1172 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.reassembled_table));
1173 ASSERT_NE_POINTER(NULL,fd_head);
1174
1175 /* check the contents of the structure */
1176 ASSERT_EQ(0,fd_head->frame); /* unused */
1177 ASSERT_EQ(0,fd_head->offset); /* unused */
1178 ASSERT_EQ(0,fd_head->len); /* unused */
1179 ASSERT_EQ(0,fd_head->datalen); /* unused */
1180 ASSERT_EQ(1,fd_head->reassembled_in);
1181 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE,fd_head->flags);
1182 ASSERT_EQ_POINTER(NULL,fd_head->tvb_data);
1183 ASSERT_EQ_POINTER(NULL,fd_head->next);
1184 }
1185
1186 /* Reuse the fragment_add_seq_check testcases */
1187 static void test_fragment_add_seq_802_11_1(void)
1188 {
1189 printf("Starting test test_fragment_add_seq_802_11_1\n");
1190 test_fragment_add_seq_check_work(fragment_add_seq_802_11);
1191 }
1192
1193 /**********************************************************************************
1194 *
1195 * fragment_add_seq_check_multiple
1196 *
1197 *********************************************************************************/
1198
1199 /* Test 2 partial frags from 2 diff datagrams in the same frame */
1200 /*
1201 datagram #1: frame 1 + first part of frame 2
1202 datagram #1: last part of frame 2 + frame 3
1203
1204 Is this a valid scenario ?
1205
1206 The result of calling fragment_add_seq_check(&test_reassembly_table, ) for these
1207 fragments is a reassembled_table with:
1208 id, frame 1 => first_datagram; ["reassembled in" frame 2]
1209 id, frame 2 => second_datagram; ["reassembled in" frame 3]
1210 id, frame 3 => second_datagram;
1211
1212 Note that the id, frame 2 => first datagram was overwritten
1213 by the entry for the second datagram.
1214 Is this OK ? IE: When dissected/displayed
1215 will the reassembled datagram 1 appear with frame 2 ??
1216 */
1217
1218 /* visit id frame frag len more tvb_offset
1219 0 12 1 0 50 T 10
1220 0 12 2 1 20 F 5
1221 0 12 2 0 25 T 25
1222 0 12 3 1 60 F 0
1223 */
1224
1225 /*
1226 Is this a valid scenario ?
1227 Is this OK ? IE: When dissected/displayed:
1228 Will the reassembled datagram 1 appear with frame 2 ??
1229 */
1230 #if 0
1231 static void
1232 test_fragment_add_seq_check_multiple(void) {
1233 fragment_head *fd_head;
1234
1235 pinfo.num = 1;
1236 fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1237 0, 50, TRUE);
1238
1239 /* add the terminal fragment of the first datagram */
1240 pinfo.num = 2;
1241 fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1242 1, 20, FALSE);
1243
1244 print_tables();
1245
1246 /* Now: start a second datagram with the first fragment in frame #2 */
1247 pinfo.num = 2;
1248 fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 25, &pinfo, 12, NULL,
1249 0, 25, TRUE);
1250
1251 /* add the terminal fragment of the second datagram */
1252 pinfo.num = 3;
1253 fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
1254 1, 60, FALSE);
1255
1256 print_tables();
1257 }
1258 #endif
1259
1260 /**********************************************************************************
1261 *
1262 * fragment_add_seq_next
1263 *
1264 *********************************************************************************/
1265
1266 /* Simple test case for fragment_add_seq_next.
1267 * Adds a couple of fragments (with one for a different datagram in between),
1268 * and checks that they are reassembled correctly.
1269 */
1270 static void
1271 test_simple_fragment_add_seq_next(void)
1272 {
1273 fragment_head *fd_head;
1274
1275 printf("Starting test test_simple_fragment_add_seq_next\n");
1276
1277 pinfo.num = 1;
1278 fd_head= fragment_add_seq_next(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1279 50, TRUE);
1280
1281 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1282 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1283 ASSERT_EQ_POINTER(NULL,fd_head);
1284
1285 /* adding the same fragment again should do nothing, even with different
1286 * offset etc */
1287 pinfo.fd->visited = 1;
1288 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1289 60, TRUE);
1290 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1291 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1292 ASSERT_EQ_POINTER(NULL,fd_head);
1293
1294 /* start another pdu (just to confuse things) */
1295 pinfo.fd->visited = 0;
1296 pinfo.num = 2;
1297 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 15, &pinfo, 13, NULL,
1298 60, TRUE);
1299 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
1300 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1301 ASSERT_EQ_POINTER(NULL,fd_head);
1302
1303
1304 /* now we add the terminal fragment of the first datagram */
1305 pinfo.num = 3;
1306 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1307 60, FALSE);
1308
1309 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1310 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.reassembled_table));
1311 ASSERT_NE_POINTER(NULL,fd_head);
1312
1313 /* check the contents of the structure */
1314 ASSERT_EQ(3,fd_head->frame); /* max frame we have */
1315 ASSERT_EQ(0,fd_head->offset); /* unused */
1316 ASSERT_EQ(110,fd_head->len); /* the length of data we have */
1317 ASSERT_EQ(1,fd_head->datalen); /* seqno of the last fragment we have */
1318 ASSERT_EQ(3,fd_head->reassembled_in);
1319 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
1320 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
1321 ASSERT_NE_POINTER(NULL,fd_head->next);
1322
1323 ASSERT_EQ(1,fd_head->next->frame);
1324 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
1325 ASSERT_EQ(50,fd_head->next->len); /* segment length */
1326 ASSERT_EQ(0,fd_head->next->flags);
1327 ASSERT_EQ_POINTER(NULL,fd_head->next->tvb_data);
1328 ASSERT_NE_POINTER(NULL,fd_head->next->next);
1329
1330 ASSERT_EQ(3,fd_head->next->next->frame);
1331 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
1332 ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
1333 ASSERT_EQ(0,fd_head->next->next->flags);
1334 ASSERT_EQ_POINTER(NULL,fd_head->next->next->tvb_data);
1335 ASSERT_EQ_POINTER(NULL,fd_head->next->next->next);
1336
1337 /* test the actual reassembly */
1338 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
1339 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
1340 }
1341
1342
1343 #if 0
1344 /* XXX remove this? fragment_add_seq does not have the special case for
1345 * fragments having truncated tvbs anymore! */
1346 /* This tests the case where some data is missing from one of the fragments.
1347 * It should prevent reassembly.
1348 */
1349 static void
1350 test_missing_data_fragment_add_seq_next(void)
1351 {
1352 fragment_head *fd_head;
1353
1354 printf("Starting test test_missing_data_fragment_add_seq_next\n");
1355
1356 /* attempt to add a fragment which is longer than the data available */
1357 pinfo.num = 1;
1358 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1359 DATA_LEN-9, TRUE);
1360
1361 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1362 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1363 ASSERT_NE_POINTER(NULL,fd_head);
1364
1365 /* check the contents of the structure. Reassembly failed so everything
1366 * should be null (meaning, just use the original tvb) */
1367 ASSERT_EQ(0,fd_head->frame); /* unused */
1368 ASSERT_EQ(0,fd_head->offset); /* unused */
1369 ASSERT_EQ(0,fd_head->len); /* the length of data we have */
1370 ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
1371 ASSERT_EQ(0,fd_head->reassembled_in);
1372 ASSERT_EQ(FD_BLOCKSEQUENCE,fd_head->flags & 0x1ff);
1373 ASSERT_EQ_POINTER(NULL,fd_head->tvb_data);
1374 ASSERT_EQ_POINTER(NULL,fd_head->next);
1375
1376 /* add another fragment (with all data present) */
1377 pinfo.num = 4;
1378 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1379 60, FALSE);
1380
1381 /* XXX: it's not clear that this is the right result; however it's what the
1382 * code does...
1383 */
1384 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1385 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1386 ASSERT_EQ_POINTER(NULL,fd_head);
1387
1388
1389 /* check what happens when we revisit the packets */
1390 pinfo.fd->visited = TRUE;
1391 pinfo.num = 1;
1392
1393 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1394 DATA_LEN-9, TRUE);
1395
1396 /* We just look in the reassembled_table for this packet. It never got put
1397 * there, so this always returns null.
1398 *
1399 * That's crazy, because it means that the subdissector will see the data
1400 * exactly once - on the first pass through the capture (well, assuming it
1401 * doesn't bother to check fd_head->reassembled_in); however, that's
1402 * what the code does...
1403 */
1404 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1405 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1406 ASSERT_EQ_POINTER(NULL,fd_head);
1407
1408 pinfo.num = 4;
1409 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1410 60, FALSE);
1411 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1412 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1413 ASSERT_EQ_POINTER(NULL,fd_head);
1414 }
1415
1416
1417 /*
1418 * we're going to do something similar now, but this time it is the second
1419 * fragment which has something missing.
1420 */
1421 static void
1422 test_missing_data_fragment_add_seq_next_2(void)
1423 {
1424 fragment_head *fd_head;
1425
1426 printf("Starting test test_missing_data_fragment_add_seq_next_2\n");
1427
1428 pinfo.num = 11;
1429 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 10, &pinfo, 24, NULL,
1430 50, TRUE);
1431
1432 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1433 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1434 ASSERT_EQ_POINTER(NULL,fd_head);
1435
1436 pinfo.num = 12;
1437 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 24, NULL,
1438 DATA_LEN-4, FALSE);
1439
1440 /* XXX: again, i'm really dubious about this. Surely this should return all
1441 * the data we had, for a best-effort attempt at dissecting it?
1442 * And it ought to go into the reassembled table?
1443 */
1444 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1445 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1446 ASSERT_EQ_POINTER(NULL,fd_head);
1447
1448 /* check what happens when we revisit the packets */
1449 pinfo.fd->visited = TRUE;
1450 pinfo.num = 11;
1451
1452 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 10, &pinfo, 24, NULL,
1453 50, TRUE);
1454
1455 /* As before, this returns NULL because the fragment isn't in the
1456 * reassembled_table. At least this is a bit more consistent than before.
1457 */
1458 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1459 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1460 ASSERT_EQ_POINTER(NULL,fd_head);
1461
1462 pinfo.num = 12;
1463 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 24, NULL,
1464 DATA_LEN-4, FALSE);
1465 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1466 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
1467 ASSERT_EQ_POINTER(NULL,fd_head);
1468
1469 }
1470
1471 /*
1472 * This time, our datagram only has one segment, but it has data missing.
1473 */
1474 static void
1475 test_missing_data_fragment_add_seq_next_3(void)
1476 {
1477 fragment_head *fd_head;
1478
1479 printf("Starting test test_missing_data_fragment_add_seq_next_3\n");
1480
1481 pinfo.num = 20;
1482 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 30, NULL,
1483 DATA_LEN-4, FALSE);
1484
1485 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
1486 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.reassembled_table));
1487 ASSERT_NE_POINTER(NULL,fd_head);
1488
1489 /* check the contents of the structure. */
1490 ASSERT_EQ(0,fd_head->frame); /* max frame we have */
1491 ASSERT_EQ(0,fd_head->offset); /* unused */
1492 ASSERT_EQ(0,fd_head->len); /* the length of data we have */
1493 ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
1494 ASSERT_EQ(20,fd_head->reassembled_in);
1495 ASSERT_EQ(FD_BLOCKSEQUENCE|FD_DEFRAGMENTED,fd_head->flags);
1496 ASSERT_EQ_POINTER(NULL,fd_head->tvb_data);
1497 ASSERT_EQ_POINTER(NULL,fd_head->next);
1498
1499 /* revisiting the packet ought to produce the same result. */
1500 pinfo.fd->visited = TRUE;
1501
1502 pinfo.num = 20;
1503 fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 30, NULL,
1504 DATA_LEN-4, FALSE);
1505
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->offset); /* unused */
1511 ASSERT_EQ(0,fd_head->len); /* the length of data we have */
1512 ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
1513 ASSERT_EQ(20,fd_head->reassembled_in);
1514 ASSERT_EQ(FD_BLOCKSEQUENCE|FD_DEFRAGMENTED,fd_head->flags);
1515 ASSERT_EQ_POINTER(NULL,fd_head->tvb_data);
1516 ASSERT_EQ_POINTER(NULL,fd_head->next);
1517 }
1518 #endif
1519
1520 /**********************************************************************************
1521 *
1522 * fragment_add
1523 *
1524 *********************************************************************************/
1525
1526 /* Simple test case for fragment_add.
1527 * Adds three fragments (out of order, with one for a different datagram in between),
1528 * and checks that they are reassembled correctly.
1529 */
1530 /* visit id frame frag_offset len more tvb_offset
1531 0 12 1 0 50 T 10
1532 1 12 1 0 60 T 5
1533 0 13 2 0 60 T 15
1534 0 12 3 110 60 F 5
1535 0 12 4 50 60 T 15
1536 */
1537 static void
1538 test_simple_fragment_add(void)
1539 {
1540 fragment_head *fd_head, *fdh0;
1541 fragment_item *fd;
1542
1543 printf("Starting test test_simple_fragment_add\n");
1544
1545 pinfo.num = 1;
1546 fd_head=fragment_add(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1547 0, 50, TRUE);
1548
1549 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1550 ASSERT_EQ_POINTER(NULL,fd_head);
1551
1552 /* adding the same fragment again should do nothing, even with different
1553 * offset etc */
1554 pinfo.fd->visited = 1;
1555 fd_head=fragment_add(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1556 0, 60, TRUE);
1557 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1558 ASSERT_EQ_POINTER(NULL,fd_head);
1559
1560 /* start another pdu (just to confuse things) */
1561 pinfo.fd->visited = 0;
1562 pinfo.num = 2;
1563 fd_head=fragment_add(&test_reassembly_table, tvb, 15, &pinfo, 13, NULL,
1564 0, 60, TRUE);
1565 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
1566 ASSERT_EQ_POINTER(NULL,fd_head);
1567
1568 /* now we add the terminal fragment of the first datagram */
1569 pinfo.num = 3;
1570 fd_head=fragment_add(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1571 110, 60, FALSE);
1572
1573 /* we haven't got all the fragments yet ... */
1574 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
1575 ASSERT_EQ_POINTER(NULL,fd_head);
1576
1577 /* finally, add the missing fragment */
1578 pinfo.num = 4;
1579 fd_head=fragment_add(&test_reassembly_table, tvb, 15, &pinfo, 12, NULL,
1580 50, 60, TRUE);
1581
1582 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
1583 ASSERT_NE_POINTER(NULL,fd_head);
1584
1585 /* check the contents of the structure */
1586 ASSERT_EQ(4,fd_head->frame); /* max frame number of fragment in assembly */
1587 ASSERT_EQ(0,fd_head->offset); /* unused */
1588 ASSERT_EQ(0,fd_head->len); /* unused in fragment_add */
1589 ASSERT_EQ(170,fd_head->datalen); /* total datalen of assembly */
1590 ASSERT_EQ(4,fd_head->reassembled_in);
1591 ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET,fd_head->flags);
1592 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
1593 ASSERT_NE_POINTER(NULL,fd_head->next);
1594
1595 fd = fd_head->next;
1596 ASSERT_EQ(1,fd->frame);
1597 ASSERT_EQ(0,fd->offset); /* offset */
1598 ASSERT_EQ(50,fd->len); /* segment length */
1599 ASSERT_EQ(0,fd->flags);
1600 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
1601 ASSERT_NE_POINTER(NULL,fd->next);
1602
1603 fd = fd->next;
1604 ASSERT_EQ(4,fd->frame);
1605 ASSERT_EQ(50,fd->offset); /* offset */
1606 ASSERT_EQ(60,fd->len); /* segment length */
1607 ASSERT_EQ(0,fd->flags);
1608 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
1609 ASSERT_NE_POINTER(NULL,fd->next);
1610
1611 fd = fd->next;
1612 ASSERT_EQ(3,fd->frame);
1613 ASSERT_EQ(110,fd->offset); /* offset */
1614 ASSERT_EQ(60,fd->len); /* segment length */
1615 ASSERT_EQ(0,fd->flags);
1616 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
1617 ASSERT_EQ_POINTER(NULL,fd->next);
1618
1619 /* test the actual reassembly */
1620 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
1621 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+15,60));
1622 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,60));
1623
1624 if (debug) {
1625 print_fragment_table();
1626 }
1627
1628 /* what happens if we revisit the packets now? */
1629 fdh0 = fd_head;
1630 pinfo.fd->visited = 1;
1631 pinfo.num = 1;
1632 fd_head=fragment_add(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1633 0, 50, TRUE);
1634 /*
1635 * this api relies on the caller to check fd_head -> reassembled_in
1636 *
1637 * Redoing all the tests seems like overkill - just check the pointer
1638 */
1639 ASSERT_EQ_POINTER(fdh0,fd_head);
1640
1641 pinfo.num = 3;
1642 fd_head=fragment_add(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1643 110, 60, FALSE);
1644 ASSERT_EQ_POINTER(fdh0,fd_head);
1645
1646 pinfo.num = 4;
1647 fd_head=fragment_add(&test_reassembly_table, tvb, 15, &pinfo, 12, NULL,
1648 50, 60, TRUE);
1649 ASSERT_EQ_POINTER(fdh0,fd_head);
1650
1651 if (debug) {
1652 print_fragment_table();
1653 }
1654 }
1655
1656 /* This tests the functionality of fragment_set_partial_reassembly for
1657 * fragment_add based reassembly.
1658 *
1659 * We add a sequence of fragments thus:
1660 * seq_off frame tvb_off len (initial) more_frags
1661 * ------- ----- ------- --- --------------------
1662 * 0 1 10 50 false
1663 * 50 2 0 40 true
1664 * 50 3 0 40 true (a duplicate fragment)
1665 * 90 4 20 100 false
1666 * 190 5 0 40 false
1667 */
1668 static void
1669 test_fragment_add_partial_reassembly(void)
1670 {
1671 fragment_head *fd_head;
1672 fragment_item *fd;
1673
1674 printf("Starting test test_fragment_add_partial_reassembly\n");
1675
1676 /* generally it's probably fair to assume that we will be called with
1677 * more_frags=FALSE.
1678 */
1679 pinfo.num = 1;
1680 fd_head=fragment_add(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1681 0, 50, FALSE);
1682
1683 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1684 ASSERT_NE_POINTER(NULL,fd_head);
1685
1686 /* check the contents of the structure */
1687 ASSERT_EQ(1,fd_head->frame); /* max frame in reassembly */
1688 ASSERT_EQ(0,fd_head->offset); /* unused */
1689 ASSERT_EQ(0,fd_head->len); /* unused */
1690 ASSERT_EQ(50,fd_head->datalen); /* the length of data we we have */
1691 ASSERT_EQ(1,fd_head->reassembled_in);
1692 ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET,fd_head->flags);
1693 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
1694 ASSERT_NE_POINTER(NULL,fd_head->next);
1695
1696 ASSERT_EQ(1,fd_head->next->frame);
1697 ASSERT_EQ(0,fd_head->next->offset); /* offset */
1698 ASSERT_EQ(50,fd_head->next->len); /* segment length */
1699 ASSERT_EQ(0,fd_head->next->flags);
1700 ASSERT_EQ_POINTER(NULL,fd_head->next->tvb_data);
1701 ASSERT_EQ_POINTER(NULL,fd_head->next->next);
1702
1703 /* test the actual reassembly */
1704 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
1705
1706 /* now we announce that the reassembly wasn't complete after all. */
1707 fragment_set_partial_reassembly(&test_reassembly_table, &pinfo, 12, NULL);
1708
1709 /* and add another segment. To mix things up slightly (and so that we can
1710 * check on the state of things), we're going to set the more_frags flag
1711 * here
1712 */
1713 pinfo.num = 2;
1714 fd_head=fragment_add(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
1715 50, 40, TRUE);
1716
1717 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1718 ASSERT_EQ_POINTER(NULL,fd_head);
1719
1720 fd_head=fragment_get(&test_reassembly_table, &pinfo, 12, NULL);
1721 ASSERT_NE_POINTER(NULL,fd_head);
1722
1723 /* check the contents of the structure */
1724 ASSERT_EQ(2,fd_head->frame); /* max frame in reassembly */
1725 ASSERT_EQ(0,fd_head->offset); /* unused */
1726 ASSERT_EQ(0,fd_head->len); /* unused */
1727 /* ASSERT_EQ(0,fd_head->datalen);
1728 * reassembly not finished; datalen not well defined.
1729 * Current implemenation has it as 0, could change to 90 without issues */
1730 ASSERT_EQ(0,fd_head->reassembled_in);
1731 ASSERT_EQ(0,fd_head->flags);
1732 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
1733 ASSERT_NE_POINTER(NULL,fd_head->next);
1734
1735 fd=fd_head->next;
1736 ASSERT_EQ(1,fd->frame);
1737 ASSERT_EQ(0,fd->offset); /* offset */
1738 ASSERT_EQ(50,fd->len); /* segment length */
1739 ASSERT_EQ(FD_SUBSET_TVB,fd->flags);
1740 ASSERT_EQ_POINTER(tvb_get_ptr(fd_head->tvb_data,0,0),tvb_get_ptr(fd->tvb_data,0,0));
1741 ASSERT_NE_POINTER(NULL,fd->next);
1742
1743 fd=fd->next;
1744 ASSERT_EQ(2,fd->frame);
1745 ASSERT_EQ(50,fd->offset); /* offset */
1746 ASSERT_EQ(40,fd->len); /* segment length */
1747 ASSERT_EQ(0,fd->flags);
1748 ASSERT_NE_POINTER(NULL,fd->tvb_data);
1749 ASSERT_EQ_POINTER(NULL,fd->next);
1750
1751 /* Another copy of the second segment.
1752 */
1753 pinfo.num = 3;
1754 fd_head=fragment_add(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
1755 50, 40, TRUE);
1756
1757 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1758 ASSERT_EQ_POINTER(NULL,fd_head);
1759 fd_head=fragment_get(&test_reassembly_table, &pinfo, 12, NULL);
1760 ASSERT_NE_POINTER(NULL,fd_head);
1761 ASSERT_EQ(3,fd_head->frame); /* max frame we have */
1762 ASSERT_EQ(0,fd_head->offset); /* unused */
1763 ASSERT_EQ(0,fd_head->len); /* unused */
1764 /* ASSERT_EQ(0,fd_head->datalen);
1765 * reassembly not finished; datalen not well defined.
1766 * Current implemenation has it as 0, could change to 90 without issues */
1767 ASSERT_EQ(0,fd_head->reassembled_in);
1768 ASSERT_EQ(0,fd_head->flags);
1769 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
1770 ASSERT_NE_POINTER(NULL,fd_head->next);
1771
1772 fd=fd_head->next;
1773 ASSERT_EQ(1,fd->frame);
1774 ASSERT_EQ(0,fd->offset);
1775 ASSERT_EQ(50,fd->len); /* segment length */
1776 ASSERT_EQ(FD_SUBSET_TVB,fd->flags);
1777 ASSERT_EQ_POINTER(tvb_get_ptr(fd_head->tvb_data,0,0),tvb_get_ptr(fd->tvb_data,0,0));
1778 ASSERT_NE_POINTER(NULL,fd->next);
1779
1780 fd=fd->next;
1781 ASSERT_EQ(2,fd->frame);
1782 ASSERT_EQ(50,fd->offset);
1783 ASSERT_EQ(40,fd->len); /* segment length */
1784 ASSERT_EQ(0,fd->flags);
1785 ASSERT_NE_POINTER(NULL,fd->tvb_data);
1786 ASSERT_NE_POINTER(NULL,fd->next);
1787
1788 fd=fd->next;
1789 ASSERT_EQ(3,fd->frame);
1790 ASSERT_EQ(50,fd->offset);
1791 ASSERT_EQ(40,fd->len); /* segment length */
1792 ASSERT_EQ(0,fd->flags);
1793 ASSERT_NE_POINTER(NULL,fd->tvb_data);
1794 ASSERT_EQ_POINTER(NULL,fd->next);
1795
1796
1797
1798 /* have another go at wrapping things up */
1799 pinfo.num = 4;
1800 fd_head=fragment_add(&test_reassembly_table, tvb, 20, &pinfo, 12, NULL,
1801 90, 100, FALSE);
1802
1803 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1804 ASSERT_NE_POINTER(NULL,fd_head);
1805
1806 /* check the contents of the structure */
1807 ASSERT_EQ(4,fd_head->frame); /* max frame we have */
1808 ASSERT_EQ(0,fd_head->offset); /* unused */
1809 ASSERT_EQ(0,fd_head->len); /* unused */
1810 ASSERT_EQ(190,fd_head->datalen); /* the length of data we have */
1811 ASSERT_EQ(4,fd_head->reassembled_in);
1812 ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
1813 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
1814 ASSERT_NE_POINTER(NULL,fd_head->next);
1815
1816 fd=fd_head->next;
1817 ASSERT_EQ(1,fd->frame);
1818 ASSERT_EQ(0,fd->offset);
1819 ASSERT_EQ(50,fd->len); /* segment length */
1820 ASSERT_EQ(0,fd->flags);
1821 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
1822 ASSERT_NE_POINTER(NULL,fd->next);
1823
1824 fd=fd->next;
1825 ASSERT_EQ(2,fd->frame);
1826 ASSERT_EQ(50,fd->offset);
1827 ASSERT_EQ(40,fd->len); /* segment length */
1828 ASSERT_EQ(0,fd->flags);
1829 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
1830 ASSERT_NE_POINTER(NULL,fd->next);
1831
1832 fd=fd->next;
1833 ASSERT_EQ(3,fd->frame);
1834 ASSERT_EQ(50,fd->offset);
1835 ASSERT_EQ(40,fd->len); /* segment length */
1836 ASSERT_EQ(FD_OVERLAP,fd->flags);
1837 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
1838 ASSERT_NE_POINTER(NULL,fd->next);
1839
1840 fd=fd->next;
1841 ASSERT_EQ(4,fd->frame);
1842 ASSERT_EQ(90,fd->offset);
1843 ASSERT_EQ(100,fd->len); /* segment length */
1844 ASSERT_EQ(0,fd->flags);
1845 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
1846 ASSERT_EQ_POINTER(NULL,fd->next);
1847
1848 /* test the actual reassembly */
1849 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
1850 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data,40));
1851 ASSERT(!tvb_memeql(fd_head->tvb_data,90,data+20,100));
1852
1853
1854 /* do it again (this time it is more complicated, with an overlap in the
1855 * reassembly) */
1856
1857 fragment_set_partial_reassembly(&test_reassembly_table, &pinfo, 12, NULL);
1858
1859 pinfo.num = 5;
1860 fragment_add(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
1861 190, 40, FALSE);
1862
1863 fd_head=fragment_get(&test_reassembly_table, &pinfo, 12, NULL);
1864 ASSERT_NE_POINTER(NULL,fd_head);
1865 ASSERT_EQ(5,fd_head->frame); /* max frame we have */
1866 ASSERT_EQ(0,fd_head->offset); /* unused */
1867 ASSERT_EQ(0,fd_head->len); /* unused */
1868 ASSERT_EQ(230,fd_head->datalen); /* the length of data we have */
1869 ASSERT_EQ(5,fd_head->reassembled_in);
1870 ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
1871 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
1872 ASSERT_NE_POINTER(NULL,fd_head->next);
1873
1874 fd=fd_head->next;
1875 ASSERT_EQ(1,fd->frame);
1876 ASSERT_EQ(0,fd->offset);
1877 ASSERT_EQ(50,fd->len); /* segment length */
1878 ASSERT_EQ(0,fd->flags);
1879 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
1880 ASSERT_NE_POINTER(NULL,fd->next);
1881
1882 fd=fd->next;
1883 ASSERT_EQ(2,fd->frame);
1884 ASSERT_EQ(50,fd->offset);
1885 ASSERT_EQ(40,fd->len); /* segment length */
1886 ASSERT_EQ(0,fd->flags);
1887 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
1888 ASSERT_NE_POINTER(NULL,fd->next);
1889
1890 fd=fd->next;
1891 ASSERT_EQ(3,fd->frame);
1892 ASSERT_EQ(50,fd->offset);
1893 ASSERT_EQ(40,fd->len); /* segment length */
1894 ASSERT_EQ(FD_OVERLAP,fd->flags);
1895 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
1896 ASSERT_NE_POINTER(NULL,fd->next);
1897
1898 fd=fd->next;
1899 ASSERT_EQ(4,fd->frame);
1900 ASSERT_EQ(90,fd->offset);
1901 ASSERT_EQ(100,fd->len); /* segment length */
1902 ASSERT_EQ(0,fd->flags);
1903 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
1904 ASSERT_NE_POINTER(NULL,fd->next);
1905
1906 fd=fd->next;
1907 ASSERT_EQ(5,fd->frame);
1908 ASSERT_EQ(190,fd->offset);
1909 ASSERT_EQ(40,fd->len); /* segment length */
1910 ASSERT_EQ(0,fd->flags);
1911 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
1912 ASSERT_EQ_POINTER(NULL,fd->next);
1913
1914 /* test the actual reassembly */
1915 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
1916 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data,40));
1917 ASSERT(!tvb_memeql(fd_head->tvb_data,90,data+20,100));
1918 ASSERT(!tvb_memeql(fd_head->tvb_data,190,data,40));
1919 }
1920
1921 /* XXX: Is the proper behavior here really throwing an exception instead
1922 * of setting FD_OVERLAP?
1923 */
1924 /* Test case for fragment_add with duplicated (e.g., retransmitted) data.
1925 * Adds three fragments--adding the 1st one twice at the end--
1926 * and checks that they are reassembled correctly.
1927 */
1928 /* visit id frame frag_off len more tvb_offset
1929 0 12 1 0 50 T 10
1930 0 12 2 50 60 T 5
1931 0 12 3 110 40 F 5
1932 0 12 4 0 50 T 10
1933 */
1934 static void
1935 test_fragment_add_duplicate_first(void)
1936 {
1937 fragment_head *fd_head;
1938 fragment_item *fd;
1939 volatile gboolean ex_thrown;
1940
1941 printf("Starting test test_fragment_add_duplicate_first\n");
1942
1943 pinfo.num = 1;
1944 fd_head=fragment_add(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1945 0, 50, TRUE);
1946
1947 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1948 ASSERT_EQ_POINTER(NULL,fd_head);
1949
1950 /* Add the 2nd segment */
1951 pinfo.num = 2;
1952 fd_head=fragment_add(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1953 50, 60, TRUE);
1954
1955 /* we haven't got all the fragments yet ... */
1956 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1957 ASSERT_EQ_POINTER(NULL,fd_head);
1958
1959 /* Add the last fragment */
1960 pinfo.num = 3;
1961 fd_head=fragment_add(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
1962 110, 40, FALSE);
1963
1964 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1965 ASSERT_NE_POINTER(NULL,fd_head);
1966
1967 /* Add the first fragment again */
1968 pinfo.num = 4;
1969 /* XXX: The current reassemble.c code for fragment_add() throws an
1970 * exception and doesn't try to add a duplicate if and only if the
1971 * assembly is already completed. This means that it doesn't get
1972 * put in the linked list. This is counter to how the _seq functions
1973 * work, as well as to how this code works if a duplicate comes in the
1974 * middle instead of at the end. Test matches current code, but the
1975 * current code should perhaps be changed. */
1976 ex_thrown = FALSE;
1977 TRY {
1978 fd_head=fragment_add(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
1979 0, 50, TRUE);
1980 }
1981 CATCH(ReassemblyError) {
1982 ex_thrown = TRUE;
1983 }
1984 ENDTRY;
1985
1986 ASSERT_EQ(TRUE, ex_thrown);
1987
1988 /* Reassembly should have still succeeded */
1989 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
1990 ASSERT_NE_POINTER(NULL,fd_head);
1991
1992 /* check the contents of the structure */
1993 /*ASSERT_EQ(4,fd_head->frame); max frame we have */
1994 ASSERT_EQ(3,fd_head->frame); /* never add the duplicate frame */
1995 ASSERT_EQ(0,fd_head->offset); /* unused */
1996 ASSERT_EQ(0,fd_head->len); /* unused */
1997 ASSERT_EQ(150,fd_head->datalen);
1998 ASSERT_EQ(3,fd_head->reassembled_in);
1999 /* ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags); */
2000 /* FD_OVERLAP doesn't get set because we hit the exception early */
2001 ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET,fd_head->flags);
2002 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
2003 ASSERT_NE_POINTER(NULL,fd_head->next);
2004
2005 fd = fd_head->next;
2006
2007 ASSERT_EQ(1,fd->frame);
2008 ASSERT_EQ(0,fd->offset);
2009 ASSERT_EQ(50,fd->len); /* segment length */
2010 ASSERT_EQ(0,fd->flags);
2011 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2012 ASSERT_NE_POINTER(NULL,fd->next);
2013
2014 /*
2015 fd = fd_head->next;
2016 ASSERT_EQ(4,fd->frame);
2017 ASSERT_EQ(0,fd->offset);
2018 ASSERT_EQ(50,fd->len);
2019 ASSERT_EQ(FD_OVERLAP,fd->flags);
2020 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2021 ASSERT_NE_POINTER(NULL,fd->next); */
2022
2023 fd = fd->next;
2024 ASSERT_EQ(2,fd->frame);
2025 ASSERT_EQ(50,fd->offset);
2026 ASSERT_EQ(60,fd->len); /* segment length */
2027 ASSERT_EQ(0,fd->flags);
2028 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2029 ASSERT_NE_POINTER(NULL,fd->next);
2030
2031 fd = fd->next;
2032 ASSERT_EQ(3,fd->frame);
2033 ASSERT_EQ(110,fd->offset);
2034 ASSERT_EQ(40,fd->len); /* segment length */
2035 ASSERT_EQ(0,fd->flags);
2036 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2037 ASSERT_EQ_POINTER(NULL,fd->next);
2038
2039 /* test the actual reassembly */
2040 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
2041 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
2042 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
2043
2044 if (debug) {
2045 print_fragment_table();
2046 }
2047 }
2048
2049
2050 /* Test case for fragment_add with duplicated (e.g., retransmitted) data.
2051 * Adds three fragments--adding the 2nd one twice--
2052 * and checks that they are reassembled correctly.
2053 */
2054 /* visit id frame frag_off len more tvb_offset
2055 0 12 1 0 50 T 10
2056 0 12 2 50 60 T 5
2057 0 12 3 50 60 T 5
2058 0 12 4 110 40 F 5
2059 */
2060 static void
2061 test_fragment_add_duplicate_middle(void)
2062 {
2063 fragment_head *fd_head;
2064 fragment_item *fd;
2065
2066 printf("Starting test test_fragment_add_duplicate_middle\n");
2067
2068 pinfo.num = 1;
2069 fd_head=fragment_add(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
2070 0, 50, TRUE);
2071
2072 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2073 ASSERT_EQ_POINTER(NULL,fd_head);
2074
2075 /* Add the 2nd segment */
2076 pinfo.num = 2;
2077 fd_head=fragment_add(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
2078 50, 60, TRUE);
2079
2080 /* we haven't got all the fragments yet ... */
2081 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2082 ASSERT_EQ_POINTER(NULL,fd_head);
2083
2084 /* Now, add the 2nd segment again (but in a different frame) */
2085 pinfo.num = 3;
2086 fd_head=fragment_add(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
2087 50, 60, TRUE);
2088
2089 /* This duplicate fragment should have been ignored */
2090 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2091 ASSERT_EQ_POINTER(NULL,fd_head);
2092
2093 /* finally, add the last fragment */
2094 pinfo.num = 4;
2095 fd_head=fragment_add(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
2096 110, 40, FALSE);
2097
2098 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2099 ASSERT_NE_POINTER(NULL,fd_head);
2100
2101 /* check the contents of the structure */
2102 ASSERT_EQ(4,fd_head->frame); /* max frame we have */
2103 ASSERT_EQ(0,fd_head->offset); /* unused */
2104 ASSERT_EQ(0,fd_head->len); /* unused */
2105 ASSERT_EQ(150,fd_head->datalen);
2106 ASSERT_EQ(4,fd_head->reassembled_in);
2107 ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
2108 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
2109 ASSERT_NE_POINTER(NULL,fd_head->next);
2110
2111 fd = fd_head->next;
2112 ASSERT_EQ(1,fd->frame);
2113 ASSERT_EQ(0,fd->offset);
2114 ASSERT_EQ(50,fd->len); /* segment length */
2115 ASSERT_EQ(0,fd->flags);
2116 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2117 ASSERT_NE_POINTER(NULL,fd->next);
2118
2119 fd = fd->next;
2120 ASSERT_EQ(2,fd->frame);
2121 ASSERT_EQ(50,fd->offset);
2122 ASSERT_EQ(60,fd->len); /* segment length */
2123 ASSERT_EQ(0,fd->flags);
2124 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2125 ASSERT_NE_POINTER(NULL,fd->next);
2126
2127 fd = fd->next;
2128 ASSERT_EQ(3,fd->frame);
2129 ASSERT_EQ(50,fd->offset);
2130 ASSERT_EQ(60,fd->len); /* segment length */
2131 ASSERT_EQ(FD_OVERLAP,fd->flags);
2132 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2133 ASSERT_NE_POINTER(NULL,fd->next);
2134
2135 fd = fd->next;
2136 ASSERT_EQ(4,fd->frame);
2137 ASSERT_EQ(110,fd->offset);
2138 ASSERT_EQ(40,fd->len); /* segment length */
2139 ASSERT_EQ(0,fd->flags);
2140 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2141 ASSERT_EQ_POINTER(NULL,fd->next);
2142
2143 /* test the actual reassembly */
2144 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
2145 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
2146 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
2147
2148 if (debug) {
2149 print_fragment_table();
2150 }
2151 }
2152
2153 /* XXX: Is the proper behavior here really throwing an exception instead
2154 * of setting FD_OVERLAP?
2155 */
2156 /* Test case for fragment_add with duplicated (e.g., retransmitted) data.
2157 * Adds three fragments--adding the 3rd one twice--
2158 * and checks that they are reassembled correctly.
2159 */
2160 /* visit id frame frag len more tvb_offset
2161 0 12 1 0 50 T 10
2162 0 12 2 1 60 T 5
2163 0 12 3 2 40 F 5
2164 0 12 4 2 40 F 5
2165 */
2166 static void
2167 test_fragment_add_duplicate_last(void)
2168 {
2169 fragment_head *fd_head;
2170 fragment_item *fd;
2171 volatile gboolean ex_thrown;
2172
2173 printf("Starting test test_fragment_add_duplicate_last\n");
2174
2175 pinfo.num = 1;
2176 fd_head=fragment_add(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
2177 0, 50, TRUE);
2178
2179 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2180 ASSERT_EQ_POINTER(NULL,fd_head);
2181
2182 /* Add the 2nd segment */
2183 pinfo.num = 2;
2184 fd_head=fragment_add(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
2185 50, 60, TRUE);
2186
2187 /* we haven't got all the fragments yet ... */
2188 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2189 ASSERT_EQ_POINTER(NULL,fd_head);
2190
2191 /* Add the last fragment */
2192 pinfo.num = 3;
2193 fd_head=fragment_add(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
2194 110, 40, FALSE);
2195
2196 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2197 ASSERT_NE_POINTER(NULL,fd_head);
2198
2199 /* Add the last fragment again */
2200 pinfo.num = 4;
2201 /* XXX: The current reassemble.c code for fragment_add() throws an
2202 * exception and doesn't try to add a duplicate if and only if the
2203 * assembly is already completed. This means that it doesn't get
2204 * put in the linked list. This is counter to how the _seq functions
2205 * work, as well as to how this code works if a duplicate comes in the
2206 * middle instead of at the end. Test matches current code, but the
2207 * current code should perhaps be changed. */
2208 ex_thrown = FALSE;
2209 TRY {
2210 fd_head=fragment_add(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
2211 110, 40, FALSE);
2212 }
2213 CATCH(ReassemblyError) {
2214 ex_thrown = TRUE;
2215 }
2216 ENDTRY;
2217
2218 ASSERT_EQ(TRUE, ex_thrown);
2219
2220 /* Reassembly should have still succeeded */
2221 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2222 ASSERT_NE_POINTER(NULL,fd_head);
2223
2224 /* check the contents of the structure */
2225 /* ASSERT_EQ(4,fd_head->frame); never add the last frame again */
2226 ASSERT_EQ(3,fd_head->frame); /* max frame we have */
2227 ASSERT_EQ(0,fd_head->offset); /* unused */
2228 ASSERT_EQ(0,fd_head->len); /* unused */
2229 ASSERT_EQ(150,fd_head->datalen);
2230 ASSERT_EQ(3,fd_head->reassembled_in);
2231 /* ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
2232 * FD_OVERLAP doesn't get set since we don't add a fragment after the
2233 * end but throw an exception instead. */
2234 ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET,fd_head->flags);
2235 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
2236 ASSERT_NE_POINTER(NULL,fd_head->next);
2237
2238 fd = fd_head->next;
2239 ASSERT_EQ(1,fd->frame);
2240 ASSERT_EQ(0,fd->offset);
2241 ASSERT_EQ(50,fd->len); /* segment length */
2242 ASSERT_EQ(0,fd->flags);
2243 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2244 ASSERT_NE_POINTER(NULL,fd->next);
2245
2246 fd = fd->next;
2247 ASSERT_EQ(2,fd->frame);
2248 ASSERT_EQ(50,fd->offset);
2249 ASSERT_EQ(60,fd->len); /* segment length */
2250 ASSERT_EQ(0,fd->flags);
2251 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2252 ASSERT_NE_POINTER(NULL,fd->next);
2253
2254 fd = fd->next;
2255 ASSERT_EQ(3,fd->frame);
2256 ASSERT_EQ(110,fd->offset);
2257 ASSERT_EQ(40,fd->len); /* segment length */
2258 ASSERT_EQ(0,fd->flags);
2259 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2260
2261 /* Duplicate packet never gets added
2262 ASSERT_NE_POINTER(NULL,fd->next);
2263
2264 fd = fd->next;
2265 ASSERT_EQ(4,fd->frame);
2266 ASSERT_EQ(110,fd->offset);
2267 ASSERT_EQ(40,fd->len);
2268 ASSERT_EQ(FD_OVERLAP,fd->flags);
2269 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2270 ASSERT_EQ_POINTER(NULL,fd->next); */
2271
2272 /* test the actual reassembly */
2273 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
2274 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
2275 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
2276
2277 if (debug) {
2278 print_fragment_table();
2279 }
2280 }
2281
2282 /* Test case for fragment_add with duplicated (e.g., retransmitted) data
2283 * where the retransmission "conflicts" with the original transmission
2284 * (contents are different).
2285 * Adds three fragments--adding the 2nd one twice--
2286 * and checks that they are reassembled correctly.
2287 */
2288 /* visit id frame frag_off len more tvb_offset
2289 0 12 1 0 50 T 10
2290 0 12 2 50 60 T 5
2291 0 12 3 50 60 T 15
2292 0 12 4 110 40 F 5
2293 */
2294 static void
2295 test_fragment_add_duplicate_conflict(void)
2296 {
2297 fragment_head *fd_head;
2298 fragment_item *fd;
2299
2300 printf("Starting test test_fragment_add_duplicate_conflict\n");
2301
2302 pinfo.num = 1;
2303 fd_head=fragment_add(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
2304 0, 50, TRUE);
2305
2306 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2307 ASSERT_EQ_POINTER(NULL,fd_head);
2308
2309 /* Add the 2nd segment */
2310 pinfo.num = 2;
2311 fd_head=fragment_add(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
2312 50, 60, TRUE);
2313
2314 /* we haven't got all the fragments yet ... */
2315 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2316 ASSERT_EQ_POINTER(NULL,fd_head);
2317
2318 /* Now, add the 2nd segment again (but in a different frame and with
2319 * different data)
2320 */
2321 pinfo.num = 3;
2322 fd_head=fragment_add(&test_reassembly_table, tvb, 15, &pinfo, 12, NULL,
2323 50, 60, TRUE);
2324
2325 /* This duplicate fragment should have been ignored */
2326 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2327 ASSERT_EQ_POINTER(NULL,fd_head);
2328
2329 /* finally, add the last fragment */
2330 pinfo.num = 4;
2331 fd_head=fragment_add(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
2332 110, 40, FALSE);
2333
2334 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2335 ASSERT_NE_POINTER(NULL,fd_head);
2336
2337 /* check the contents of the structure */
2338 ASSERT_EQ(4,fd_head->frame); /* max frame we have */
2339 ASSERT_EQ(0,fd_head->offset); /* unused */
2340 ASSERT_EQ(0,fd_head->len); /* unused */
2341 ASSERT_EQ(150,fd_head->datalen);
2342 ASSERT_EQ(4,fd_head->reassembled_in);
2343 ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET|FD_OVERLAP|FD_OVERLAPCONFLICT,fd_head->flags);
2344 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
2345 ASSERT_NE_POINTER(NULL,fd_head->next);
2346
2347 fd = fd_head->next;
2348 ASSERT_EQ(1,fd->frame);
2349 ASSERT_EQ(0,fd->offset);
2350 ASSERT_EQ(50,fd->len); /* segment length */
2351 ASSERT_EQ(0,fd->flags);
2352 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2353 ASSERT_NE_POINTER(NULL,fd->next);
2354
2355 fd = fd->next;
2356 ASSERT_EQ(2,fd->frame);
2357 ASSERT_EQ(50,fd->offset);
2358 ASSERT_EQ(60,fd->len); /* segment length */
2359 ASSERT_EQ(0,fd->flags);
2360 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2361 ASSERT_NE_POINTER(NULL,fd->next);
2362
2363 fd = fd->next;
2364 ASSERT_EQ(3,fd->frame);
2365 ASSERT_EQ(50,fd->offset);
2366 ASSERT_EQ(60,fd->len); /* segment length */
2367 ASSERT_EQ(FD_OVERLAP|FD_OVERLAPCONFLICT,fd->flags);
2368 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2369 ASSERT_NE_POINTER(NULL,fd->next);
2370
2371 fd = fd->next;
2372 ASSERT_EQ(4,fd->frame);
2373 ASSERT_EQ(110,fd->offset);
2374 ASSERT_EQ(40,fd->len); /* segment length */
2375 ASSERT_EQ(0,fd->flags);
2376 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2377 ASSERT_EQ_POINTER(NULL,fd->next);
2378
2379 /* test the actual reassembly */
2380 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
2381 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
2382 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
2383
2384 if (debug) {
2385 print_fragment_table();
2386 }
2387 }
2388
2389 /**********************************************************************************
2390 *
2391 * fragment_add_check
2392 *
2393 *********************************************************************************/
2394
2395 /* Simple test case for fragment_add_check.
2396 * Adds three fragments (out of order, with one for a different datagram in between),
2397 * and checks that they are reassembled correctly.
2398 */
2399 /* visit id frame frag_offset len more tvb_offset
2400 0 12 1 0 50 T 10
2401 1 12 1 0 60 T 5
2402 0 13 2 0 60 T 15
2403 0 12 3 110 60 F 5
2404 0 12 4 50 60 T 15
2405 */
2406 static void
2407 test_simple_fragment_add_check(void)
2408 {
2409 fragment_head *fd_head, *fdh0;
2410 fragment_item *fd;
2411
2412 printf("Starting test test_simple_fragment_add_check\n");
2413
2414 pinfo.num = 1;
2415 fd_head=fragment_add_check(&test_reassembly_table, tvb, 10, &pinfo, 12,
2416 NULL, 0, 50, TRUE);
2417
2418 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2419 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
2420 ASSERT_EQ_POINTER(NULL,fd_head);
2421
2422 /* adding the same fragment again should do nothing, even with different
2423 * offset etc */
2424 pinfo.fd->visited = 1;
2425 fd_head=fragment_add_check(&test_reassembly_table, tvb, 5, &pinfo, 12,
2426 NULL, 0, 60, TRUE);
2427 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2428 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
2429 ASSERT_EQ_POINTER(NULL,fd_head);
2430
2431 /* start another pdu (just to confuse things) */
2432 pinfo.fd->visited = 0;
2433 pinfo.num = 2;
2434 fd_head=fragment_add_check(&test_reassembly_table, tvb, 15, &pinfo, 13,
2435 NULL, 0, 60, TRUE);
2436 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
2437 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
2438 ASSERT_EQ_POINTER(NULL,fd_head);
2439
2440 /* now we add the terminal fragment of the first datagram */
2441 pinfo.num = 3;
2442 fd_head=fragment_add_check(&test_reassembly_table, tvb, 5, &pinfo, 12,
2443 NULL, 110, 60, FALSE);
2444
2445 /* we haven't got all the fragments yet ... */
2446 ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
2447 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
2448 ASSERT_EQ_POINTER(NULL,fd_head);
2449
2450 /* finally, add the missing fragment */
2451 pinfo.num = 4;
2452 fd_head=fragment_add_check(&test_reassembly_table, tvb, 15, &pinfo, 12,
2453 NULL, 50, 60, TRUE);
2454
2455 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2456 ASSERT_EQ(3,g_hash_table_size(test_reassembly_table.reassembled_table));
2457 ASSERT_NE_POINTER(NULL,fd_head);
2458
2459 /* check the contents of the structure */
2460 ASSERT_EQ(4,fd_head->frame); /* max frame number of fragment in assembly */
2461 ASSERT_EQ(0,fd_head->offset); /* unused */
2462 ASSERT_EQ(0,fd_head->len); /* unused in fragment_add */
2463 ASSERT_EQ(170,fd_head->datalen); /* total datalen of assembly */
2464 ASSERT_EQ(4,fd_head->reassembled_in);
2465 ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET,fd_head->flags);
2466 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
2467 ASSERT_NE_POINTER(NULL,fd_head->next);
2468
2469 fd = fd_head->next;
2470 ASSERT_EQ(1,fd->frame);
2471 ASSERT_EQ(0,fd->offset);
2472 ASSERT_EQ(50,fd->len); /* segment length */
2473 ASSERT_EQ(0,fd->flags);
2474 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2475 ASSERT_NE_POINTER(NULL,fd->next);
2476
2477 fd = fd->next;
2478 ASSERT_EQ(4,fd->frame);
2479 ASSERT_EQ(50,fd->offset);
2480 ASSERT_EQ(60,fd->len); /* segment length */
2481 ASSERT_EQ(0,fd->flags);
2482 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2483 ASSERT_NE_POINTER(NULL,fd->next);
2484
2485 fd = fd->next;
2486 ASSERT_EQ(3,fd->frame);
2487 ASSERT_EQ(110,fd->offset);
2488 ASSERT_EQ(60,fd->len); /* segment length */
2489 ASSERT_EQ(0,fd->flags);
2490 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2491 ASSERT_EQ_POINTER(NULL,fd->next);
2492
2493 /* test the actual reassembly */
2494 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
2495 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+15,60));
2496 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,60));
2497
2498 if (debug) {
2499 print_fragment_table();
2500 }
2501
2502 /* what happens if we revisit the packets now? */
2503 fdh0 = fd_head;
2504 pinfo.fd->visited = 1;
2505 pinfo.num = 1;
2506 fd_head=fragment_add_check(&test_reassembly_table, tvb, 10, &pinfo, 12,
2507 NULL, 0, 50, TRUE);
2508 /*
2509 * this api relies on the caller to check fd_head -> reassembled_in
2510 *
2511 * Redoing all the tests seems like overkill - just check the pointer
2512 */
2513 ASSERT_EQ_POINTER(fdh0,fd_head);
2514
2515 pinfo.num = 3;
2516 fd_head=fragment_add_check(&test_reassembly_table, tvb, 5, &pinfo, 12,
2517 NULL, 110, 60, FALSE);
2518 ASSERT_EQ_POINTER(fdh0,fd_head);
2519
2520 pinfo.num = 4;
2521 fd_head=fragment_add_check(&test_reassembly_table, tvb, 15, &pinfo, 12,
2522 NULL, 50, 60, TRUE);
2523 ASSERT_EQ_POINTER(fdh0,fd_head);
2524
2525 if (debug) {
2526 print_fragment_table();
2527 }
2528 }
2529
2530 #if 0
2531 /* XXX: fragment_set_partial_reassembly() does not work for fragment_add_check
2532 * because it doesn't remove the previously completed reassembly from
2533 * reassembled_table (and lookup_fd_head() only looks in the fragment
2534 * table, not the reassembled_table) */
2535 /* This tests the functionality of fragment_set_partial_reassembly for
2536 * fragment_add_check based reassembly.
2537 *
2538 * We add a sequence of fragments thus:
2539 * seq_off frame tvb_off len (initial) more_frags
2540 * ------- ----- ------- --- --------------------
2541 * 0 1 10 50 false
2542 * 50 2 0 40 true
2543 * 50 3 0 40 true (a duplicate fragment)
2544 * 90 4 20 100 false
2545 * 190 5 0 40 false
2546 */
2547 static void
2548 test_fragment_add_check_partial_reassembly(void)
2549 {
2550 fragment_head *fd_head;
2551 fragment_item *fd;
2552
2553 printf("Starting test test_fragment_add_check_partial_reassembly\n");
2554
2555 /* generally it's probably fair to assume that we will be called with
2556 * more_frags=FALSE.
2557 */
2558 pinfo.num = 1;
2559 fd_head=fragment_add_check(&test_reassembly_table, tvb, 10, &pinfo, 12,
2560 NULL, 0, 50, FALSE);
2561
2562 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
2563 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.reassembled_table));
2564 ASSERT_NE_POINTER(NULL,fd_head);
2565
2566 /* check the contents of the structure */
2567 ASSERT_EQ(1,fd_head->frame); /* max frame in reassembly */
2568 ASSERT_EQ(0,fd_head->offset); /* unused */
2569 ASSERT_EQ(0,fd_head->len); /* unused */
2570 ASSERT_EQ(50,fd_head->datalen); /* the length of data we we have */
2571 ASSERT_EQ(1,fd_head->reassembled_in);
2572 ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET,fd_head->flags);
2573 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
2574 ASSERT_NE_POINTER(NULL,fd_head->next);
2575
2576 ASSERT_EQ(1,fd_head->next->frame);
2577 ASSERT_EQ(0,fd_head->next->offset); /* offset */
2578 ASSERT_EQ(50,fd_head->next->len); /* segment length */
2579 ASSERT_EQ(0,fd_head->next->flags);
2580 ASSERT_EQ_POINTER(NULL,fd_head->next->tvb_data);
2581 ASSERT_EQ_POINTER(NULL,fd_head->next->next);
2582
2583 /* test the actual reassembly */
2584 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
2585
2586 /* now we announce that the reassembly wasn't complete after all. */
2587 fragment_set_partial_reassembly(&test_reassembly_table, &pinfo, 12, NULL);
2588
2589 /* and add another segment. To mix things up slightly (and so that we can
2590 * check on the state of things), we're going to set the more_frags flag
2591 * here
2592 */
2593 pinfo.num = 2;
2594 fd_head=fragment_add_check(&test_reassembly_table, tvb, 0, &pinfo, 12,
2595 NULL, 50, 40, TRUE);
2596
2597 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2598 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.reassembled_table));
2599 ASSERT_EQ_POINTER(NULL,fd_head);
2600
2601 fd_head=fragment_get(&test_reassembly_table, &pinfo, 12, NULL);
2602 ASSERT_NE_POINTER(NULL,fd_head);
2603
2604 /* check the contents of the structure */
2605 ASSERT_EQ(2,fd_head->frame); /* max frame in reassembly */
2606 ASSERT_EQ(0,fd_head->offset); /* unused */
2607 ASSERT_EQ(0,fd_head->len); /* unused */
2608 /* ASSERT_EQ(0,fd_head->datalen);
2609 * reassembly not finished; datalen not well defined.
2610 * Current implemenation has it as 0, could change to 90 without issues */
2611 ASSERT_EQ(0,fd_head->reassembled_in);
2612 ASSERT_EQ(0,fd_head->flags);
2613 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
2614 ASSERT_NE_POINTER(NULL,fd_head->next);
2615
2616 fd=fd_head->next;
2617 ASSERT_EQ(1,fd->frame);
2618 ASSERT_EQ(0,fd->offset); /* offset */
2619 ASSERT_EQ(50,fd->len); /* segment length */
2620 ASSERT_EQ(FD_SUBSET_TVB,fd->flags);
2621 ASSERT_EQ_POINTER(tvb_get_ptr(fd_head->tvb_data,0,0),tvb_get_ptr(fd->tvb_data,0,0));
2622 ASSERT_NE_POINTER(NULL,fd->next);
2623
2624 fd=fd->next;
2625 ASSERT_EQ(2,fd->frame);
2626 ASSERT_EQ(50,fd->offset); /* offset */
2627 ASSERT_EQ(40,fd->len); /* segment length */
2628 ASSERT_EQ(0,fd->flags);
2629 ASSERT_NE_POINTER(NULL,fd->tvb_data);
2630 ASSERT_EQ_POINTER(NULL,fd->next);
2631
2632 /* Another copy of the second segment.
2633 */
2634 pinfo.num = 3;
2635 fd_head=fragment_add_check(&test_reassembly_table, tvb, 0, &pinfo, 12,
2636 NULL, 50, 40, TRUE);
2637
2638 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2639 ASSERT_EQ_POINTER(NULL,fd_head);
2640 fd_head=fragment_get(&test_reassembly_table, &pinfo, 12, NULL);
2641 ASSERT_NE_POINTER(NULL,fd_head);
2642 ASSERT_EQ(3,fd_head->frame); /* max frame we have */
2643 ASSERT_EQ(0,fd_head->offset); /* unused */
2644 ASSERT_EQ(0,fd_head->len); /* unused */
2645 /* ASSERT_EQ(0,fd_head->datalen);
2646 * reassembly not finished; datalen not well defined.
2647 * Current implemenation has it as 0, could change to 90 without issues */
2648 ASSERT_EQ(0,fd_head->reassembled_in);
2649 ASSERT_EQ(0,fd_head->flags);
2650 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
2651 ASSERT_NE_POINTER(NULL,fd_head->next);
2652
2653 fd=fd_head->next;
2654 ASSERT_EQ(1,fd->frame);
2655 ASSERT_EQ(0,fd->offset);
2656 ASSERT_EQ(50,fd->len); /* segment length */
2657 ASSERT_EQ(FD_SUBSET_TVB,fd->flags);
2658 ASSERT_EQ_POINTER(tvb_get_ptr(fd_head->tvb_data,0,0),tvb_get_ptr(fd->tvb_data,0,0));
2659 ASSERT_NE_POINTER(NULL,fd->next);
2660
2661 fd=fd->next;
2662 ASSERT_EQ(2,fd->frame);
2663 ASSERT_EQ(50,fd->offset);
2664 ASSERT_EQ(40,fd->len); /* segment length */
2665 ASSERT_EQ(0,fd->flags);
2666 ASSERT_NE_POINTER(NULL,fd->tvb_data);
2667 ASSERT_NE_POINTER(NULL,fd->next);
2668
2669 fd=fd->next;
2670 ASSERT_EQ(3,fd->frame);
2671 ASSERT_EQ(50,fd->offset);
2672 ASSERT_EQ(40,fd->len); /* segment length */
2673 ASSERT_EQ(0,fd->flags);
2674 ASSERT_NE_POINTER(NULL,fd->tvb_data);
2675 ASSERT_EQ_POINTER(NULL,fd->next);
2676
2677
2678
2679 /* have another go at wrapping things up */
2680 pinfo.num = 4;
2681 fd_head=fragment_add_check(&test_reassembly_table, tvb, 20, &pinfo, 12,
2682 NULL, 90, 100, FALSE);
2683
2684 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2685 ASSERT_NE_POINTER(NULL,fd_head);
2686
2687 /* check the contents of the structure */
2688 ASSERT_EQ(4,fd_head->frame); /* max frame we have */
2689 ASSERT_EQ(0,fd_head->offset); /* unused */
2690 ASSERT_EQ(0,fd_head->len); /* unused */
2691 ASSERT_EQ(190,fd_head->datalen); /* the length of data we have */
2692 ASSERT_EQ(4,fd_head->reassembled_in);
2693 ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
2694 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
2695 ASSERT_NE_POINTER(NULL,fd_head->next);
2696
2697 fd=fd_head->next;
2698 ASSERT_EQ(1,fd->frame);
2699 ASSERT_EQ(0,fd->offset);
2700 ASSERT_EQ(50,fd->len); /* segment length */
2701 ASSERT_EQ(0,fd->flags);
2702 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2703 ASSERT_NE_POINTER(NULL,fd->next);
2704
2705 fd=fd->next;
2706 ASSERT_EQ(2,fd->frame);
2707 ASSERT_EQ(50,fd->offset);
2708 ASSERT_EQ(40,fd->len); /* segment length */
2709 ASSERT_EQ(0,fd->flags);
2710 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2711 ASSERT_NE_POINTER(NULL,fd->next);
2712
2713 fd=fd->next;
2714 ASSERT_EQ(3,fd->frame);
2715 ASSERT_EQ(50,fd->offset);
2716 ASSERT_EQ(40,fd->len); /* segment length */
2717 ASSERT_EQ(FD_OVERLAP,fd->flags);
2718 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2719 ASSERT_NE_POINTER(NULL,fd->next);
2720
2721 fd=fd->next;
2722 ASSERT_EQ(4,fd->frame);
2723 ASSERT_EQ(90,fd->offset);
2724 ASSERT_EQ(100,fd->len); /* segment length */
2725 ASSERT_EQ(0,fd->flags);
2726 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2727 ASSERT_EQ_POINTER(NULL,fd->next);
2728
2729 /* test the actual reassembly */
2730 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
2731 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data,40));
2732 ASSERT(!tvb_memeql(fd_head->tvb_data,90,data+20,100));
2733
2734
2735 /* do it again (this time it is more complicated, with an overlap in the
2736 * reassembly) */
2737
2738 fragment_set_partial_reassembly(&test_reassembly_table, &pinfo, 12, NULL);
2739
2740 pinfo.num = 5;
2741 fragment_add_check(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
2742 190, 40, FALSE);
2743
2744 fd_head=fragment_get(&test_reassembly_table, &pinfo, 12, NULL);
2745 ASSERT_NE_POINTER(NULL,fd_head);
2746 ASSERT_EQ(5,fd_head->frame); /* max frame we have */
2747 ASSERT_EQ(0,fd_head->offset); /* unused */
2748 ASSERT_EQ(0,fd_head->len); /* unused */
2749 ASSERT_EQ(230,fd_head->datalen); /* the length of data we have */
2750 ASSERT_EQ(5,fd_head->reassembled_in);
2751 ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
2752 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
2753 ASSERT_NE_POINTER(NULL,fd_head->next);
2754
2755 fd=fd_head->next;
2756 ASSERT_EQ(1,fd->frame);
2757 ASSERT_EQ(0,fd->offset);
2758 ASSERT_EQ(50,fd->len); /* segment length */
2759 ASSERT_EQ(0,fd->flags);
2760 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2761 ASSERT_NE_POINTER(NULL,fd->next);
2762
2763 fd=fd->next;
2764 ASSERT_EQ(2,fd->frame);
2765 ASSERT_EQ(50,fd->offset);
2766 ASSERT_EQ(40,fd->len); /* segment length */
2767 ASSERT_EQ(0,fd->flags);
2768 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2769 ASSERT_NE_POINTER(NULL,fd->next);
2770
2771 fd=fd->next;
2772 ASSERT_EQ(3,fd->frame);
2773 ASSERT_EQ(50,fd->offset);
2774 ASSERT_EQ(40,fd->len); /* segment length */
2775 ASSERT_EQ(FD_OVERLAP,fd->flags);
2776 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2777 ASSERT_NE_POINTER(NULL,fd->next);
2778
2779 fd=fd->next;
2780 ASSERT_EQ(4,fd->frame);
2781 ASSERT_EQ(90,fd->offset);
2782 ASSERT_EQ(100,fd->len); /* segment length */
2783 ASSERT_EQ(0,fd->flags);
2784 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2785 ASSERT_NE_POINTER(NULL,fd->next);
2786
2787 fd=fd->next;
2788 ASSERT_EQ(5,fd->frame);
2789 ASSERT_EQ(190,fd->offset);
2790 ASSERT_EQ(40,fd->len); /* segment length */
2791 ASSERT_EQ(0,fd->flags);
2792 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2793 ASSERT_EQ_POINTER(NULL,fd->next);
2794
2795 /* test the actual reassembly */
2796 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
2797 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data,40));
2798 ASSERT(!tvb_memeql(fd_head->tvb_data,90,data+20,100));
2799 ASSERT(!tvb_memeql(fd_head->tvb_data,190,data,40));
2800 }
2801 #endif
2802
2803 #if 0
2804 /* XXX: fragment_add_check moves completed reassemblies to the
2805 * reassembled_table, so adding a duplicated fragment after the end doesn't
2806 * get marked as duplicate, but starts a new reassembly. This is the correct
2807 * thing for very long captures where the identification field gets reused,
2808 * somewhat wrong when it is retransmitted data (it won't get marked as such
2809 * but doesn't interfere with defragmentation too much), and very wrong when
2810 * there is both retransmitted data and later on the identification field
2811 * gets reused (the dangling data will get added to the wrong reassembly.)
2812 *
2813 * Not sure what behavior to check. Possibly both behaviors should be supported,
2814 * perhaps being affected by how close pinfo.num is to the reassembly, though
2815 * that gets complicated.
2816 */
2817 /* Test case for fragment_add_check with duplicated (e.g., retransmitted) data.
2818 * Adds three fragments--adding the 1st one twice at the end--
2819 * and checks that they are reassembled correctly.
2820 */
2821 /* visit id frame frag_off len more tvb_offset
2822 0 12 1 0 50 T 10
2823 0 12 2 50 60 T 5
2824 0 12 3 110 40 F 5
2825 0 12 4 0 50 T 10
2826 */
2827 static void
2828 test_fragment_add_check_duplicate_first(void)
2829 {
2830 fragment_head *fd_head;
2831 fragment_item *fd;
2832 volatile gboolean ex_thrown;
2833
2834 printf("Starting test test_fragment_add_check_duplicate_first\n");
2835
2836 pinfo.num = 1;
2837 fd_head=fragment_add_check(&test_reassembly_table, tvb, 10, &pinfo, 12,
2838 NULL, 0, 50, TRUE);
2839
2840 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2841 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
2842 ASSERT_EQ_POINTER(NULL,fd_head);
2843
2844 /* Add the 2nd segment */
2845 pinfo.num = 2;
2846 fd_head=fragment_add_check(&test_reassembly_table, tvb, 5, &pinfo, 12,
2847 NULL, 50, 60, TRUE);
2848
2849 /* we haven't got all the fragments yet ... */
2850 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2851 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
2852 ASSERT_EQ_POINTER(NULL,fd_head);
2853
2854 /* Add the last fragment */
2855 pinfo.num = 3;
2856 fd_head=fragment_add_check(&test_reassembly_table, tvb, 5, &pinfo, 12,
2857 NULL, 110, 40, FALSE);
2858
2859 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
2860 ASSERT_EQ(3,g_hash_table_size(test_reassembly_table.reassembled_table));
2861 ASSERT_NE_POINTER(NULL,fd_head);
2862
2863 /* Add the first fragment again */
2864 pinfo.num = 4;
2865 fd_head=fragment_add_check(&test_reassembly_table, tvb, 10, &pinfo, 12,
2866 NULL, 0, 50, TRUE);
2867
2868 /* Reassembly should have still succeeded */
2869 /* XXX: Current behavior is to start a new reassembly - which is
2870 * the proper behavior in a long capture that reuses the id, but the
2871 * wrong thing when it's actually a retransmission. Should the distinction
2872 * be made by analyzing pinfo.num to see if it is nearby? Or is that the
2873 * dissector's job? */
2874 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2875 ASSERT_EQ(3,g_hash_table_size(test_reassembly_table.reassembled_table));
2876 ASSERT_NE_POINTER(NULL,fd_head);
2877
2878 /* check the contents of the structure */
2879 /*ASSERT_EQ(4,fd_head->frame); max frame we have */
2880 ASSERT_EQ(3,fd_head->frame); /* never add the duplicate frame */
2881 ASSERT_EQ(0,fd_head->offset); /* unused */
2882 ASSERT_EQ(0,fd_head->len); /* unused */
2883 ASSERT_EQ(150,fd_head->datalen);
2884 ASSERT_EQ(3,fd_head->reassembled_in);
2885 /* ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags); */
2886 /* FD_OVERLAP doesn't get set because we hit the exception early */
2887 ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET,fd_head->flags);
2888 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
2889 ASSERT_NE_POINTER(NULL,fd_head->next);
2890
2891 fd = fd_head->next;
2892
2893 ASSERT_EQ(1,fd->frame);
2894 ASSERT_EQ(0,fd->offset);
2895 ASSERT_EQ(50,fd->len); /* segment length */
2896 ASSERT_EQ(0,fd->flags);
2897 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2898 ASSERT_NE_POINTER(NULL,fd->next);
2899
2900 /*
2901 fd = fd_head->next;
2902 ASSERT_EQ(4,fd->frame);
2903 ASSERT_EQ(0,fd->offset);
2904 ASSERT_EQ(50,fd->len);
2905 ASSERT_EQ(FD_OVERLAP,fd->flags);
2906 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2907 ASSERT_NE_POINTER(NULL,fd->next); */
2908
2909 fd = fd->next;
2910 ASSERT_EQ(2,fd->frame);
2911 ASSERT_EQ(50,fd->offset);
2912 ASSERT_EQ(60,fd->len); /* segment length */
2913 ASSERT_EQ(0,fd->flags);
2914 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2915 ASSERT_NE_POINTER(NULL,fd->next);
2916
2917 fd = fd->next;
2918 ASSERT_EQ(3,fd->frame);
2919 ASSERT_EQ(110,fd->offset);
2920 ASSERT_EQ(40,fd->len); /* segment length */
2921 ASSERT_EQ(0,fd->flags);
2922 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
2923 ASSERT_EQ_POINTER(NULL,fd->next);
2924
2925 /* test the actual reassembly */
2926 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
2927 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
2928 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
2929
2930 if (debug) {
2931 print_fragment_table();
2932 }
2933 }
2934 #endif
2935
2936 /* Test case for fragment_add_check with duplicated (e.g., retransmitted) data.
2937 * Adds three fragments--adding the 2nd one twice--
2938 * and checks that they are reassembled correctly.
2939 */
2940 /* visit id frame frag_off len more tvb_offset
2941 0 12 1 0 50 T 10
2942 0 12 2 50 60 T 5
2943 0 12 3 50 60 T 5
2944 0 12 4 110 40 F 5
2945 */
2946 static void
2947 test_fragment_add_check_duplicate_middle(void)
2948 {
2949 fragment_head *fd_head;
2950 fragment_item *fd;
2951
2952 printf("Starting test test_fragment_add_check_duplicate_middle\n");
2953
2954 pinfo.num = 1;
2955 fd_head=fragment_add_check(&test_reassembly_table, tvb, 10, &pinfo, 12,
2956 NULL, 0, 50, TRUE);
2957
2958 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2959 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
2960 ASSERT_EQ_POINTER(NULL,fd_head);
2961
2962 /* Add the 2nd segment */
2963 pinfo.num = 2;
2964 fd_head=fragment_add_check(&test_reassembly_table, tvb, 5, &pinfo, 12,
2965 NULL, 50, 60, TRUE);
2966
2967 /* we haven't got all the fragments yet ... */
2968 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2969 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
2970 ASSERT_EQ_POINTER(NULL,fd_head);
2971
2972 /* Now, add the 2nd segment again (but in a different frame) */
2973 pinfo.num = 3;
2974 fd_head=fragment_add_check(&test_reassembly_table, tvb, 5, &pinfo, 12,
2975 NULL, 50, 60, TRUE);
2976
2977 /* This duplicate fragment should have been ignored */
2978 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
2979 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
2980 ASSERT_EQ_POINTER(NULL,fd_head);
2981
2982 /* finally, add the last fragment */
2983 pinfo.num = 4;
2984 fd_head=fragment_add_check(&test_reassembly_table, tvb, 5, &pinfo, 12,
2985 NULL, 110, 40, FALSE);
2986
2987 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
2988 ASSERT_EQ(4,g_hash_table_size(test_reassembly_table.reassembled_table));
2989 ASSERT_NE_POINTER(NULL,fd_head);
2990
2991 /* check the contents of the structure */
2992 ASSERT_EQ(4,fd_head->frame); /* max frame we have */
2993 ASSERT_EQ(0,fd_head->offset); /* unused */
2994 ASSERT_EQ(0,fd_head->len); /* unused */
2995 ASSERT_EQ(150,fd_head->datalen);
2996 ASSERT_EQ(4,fd_head->reassembled_in);
2997 ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
2998 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
2999 ASSERT_NE_POINTER(NULL,fd_head->next);
3000
3001 fd = fd_head->next;
3002 ASSERT_EQ(1,fd->frame);
3003 ASSERT_EQ(0,fd->offset);
3004 ASSERT_EQ(50,fd->len); /* segment length */
3005 ASSERT_EQ(0,fd->flags);
3006 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
3007 ASSERT_NE_POINTER(NULL,fd->next);
3008
3009 fd = fd->next;
3010 ASSERT_EQ(2,fd->frame);
3011 ASSERT_EQ(50,fd->offset);
3012 ASSERT_EQ(60,fd->len); /* segment length */
3013 ASSERT_EQ(0,fd->flags);
3014 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
3015 ASSERT_NE_POINTER(NULL,fd->next);
3016
3017 fd = fd->next;
3018 ASSERT_EQ(3,fd->frame);
3019 ASSERT_EQ(50,fd->offset);
3020 ASSERT_EQ(60,fd->len); /* segment length */
3021 ASSERT_EQ(FD_OVERLAP,fd->flags);
3022 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
3023 ASSERT_NE_POINTER(NULL,fd->next);
3024
3025 fd = fd->next;
3026 ASSERT_EQ(4,fd->frame);
3027 ASSERT_EQ(110,fd->offset);
3028 ASSERT_EQ(40,fd->len); /* segment length */
3029 ASSERT_EQ(0,fd->flags);
3030 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
3031 ASSERT_EQ_POINTER(NULL,fd->next);
3032
3033 /* test the actual reassembly */
3034 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
3035 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
3036 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
3037
3038 if (debug) {
3039 print_fragment_table();
3040 }
3041 }
3042
3043 #if 0
3044 /* XXX: same issue as test_fragment_add_check_duplicate_first, above.
3045 */
3046 /* Test case for fragment_add_check with duplicated (e.g., retransmitted) data.
3047 * Adds three fragments--adding the 3rd one twice--
3048 * and checks that they are reassembled correctly.
3049 */
3050 /* visit id frame frag len more tvb_offset
3051 0 12 1 0 50 T 10
3052 0 12 2 1 60 T 5
3053 0 12 3 2 40 F 5
3054 0 12 4 2 40 F 5
3055 */
3056 static void
3057 test_fragment_add_check_duplicate_last(void)
3058 {
3059 fragment_head *fd_head;
3060 fragment_item *fd;
3061
3062 printf("Starting test test_fragment_add_check_duplicate_last\n");
3063
3064 pinfo.num = 1;
3065 fd_head=fragment_add_check(&test_reassembly_table, tvb, 10, &pinfo, 12,
3066 NULL, 0, 50, TRUE);
3067
3068 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
3069 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
3070 ASSERT_EQ_POINTER(NULL,fd_head);
3071
3072 /* Add the 2nd segment */
3073 pinfo.num = 2;
3074 fd_head=fragment_add_check(&test_reassembly_table, tvb, 5, &pinfo, 12,
3075 NULL, 50, 60, TRUE);
3076
3077 /* we haven't got all the fragments yet ... */
3078 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
3079 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
3080 ASSERT_EQ_POINTER(NULL,fd_head);
3081
3082 /* Add the last fragment */
3083 pinfo.num = 3;
3084 fd_head=fragment_add_check(&test_reassembly_table, tvb, 5, &pinfo, 12,
3085 NULL, 110, 40, FALSE);
3086
3087 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
3088 ASSERT_EQ(3,g_hash_table_size(test_reassembly_table.reassembled_table));
3089 ASSERT_NE_POINTER(NULL,fd_head);
3090
3091 /* Add the last fragment again */
3092 pinfo.num = 4;
3093 fd_head=fragment_add_check(&test_reassembly_table, tvb, 5, &pinfo, 12,
3094 NULL, 110, 40, FALSE);
3095
3096 /* Reassembly should have still succeeded */
3097 /* XXX: Current behavior is to start a new reassembly */
3098 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
3099 ASSERT_EQ(3,g_hash_table_size(test_reassembly_table.reassembled_table));
3100 ASSERT_NE_POINTER(NULL,fd_head);
3101
3102 /* check the contents of the structure */
3103 /* ASSERT_EQ(4,fd_head->frame); never add the last frame again */
3104 ASSERT_EQ(3,fd_head->frame); /* max frame we have */
3105 ASSERT_EQ(0,fd_head->offset); /* unused */
3106 ASSERT_EQ(0,fd_head->len); /* unused */
3107 ASSERT_EQ(150,fd_head->datalen);
3108 ASSERT_EQ(3,fd_head->reassembled_in);
3109 /* ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
3110 * FD_OVERLAP doesn't get set since we don't add a fragment after the
3111 * end but start a new assembly instead. */
3112 ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET,fd_head->flags);
3113 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
3114 ASSERT_NE_POINTER(NULL,fd_head->next);
3115
3116 fd = fd_head->next;
3117 ASSERT_EQ(1,fd->frame);
3118 ASSERT_EQ(0,fd->offset);
3119 ASSERT_EQ(50,fd->len); /* segment length */
3120 ASSERT_EQ(0,fd->flags);
3121 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
3122 ASSERT_NE_POINTER(NULL,fd->next);
3123
3124 fd = fd->next;
3125 ASSERT_EQ(2,fd->frame);
3126 ASSERT_EQ(50,fd->offset);
3127 ASSERT_EQ(60,fd->len); /* segment length */
3128 ASSERT_EQ(0,fd->flags);
3129 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
3130 ASSERT_NE_POINTER(NULL,fd->next);
3131
3132 fd = fd->next;
3133 ASSERT_EQ(3,fd->frame);
3134 ASSERT_EQ(110,fd->offset);
3135 ASSERT_EQ(40,fd->len); /* segment length */
3136 ASSERT_EQ(0,fd->flags);
3137 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
3138
3139 /* Duplicate packet never gets added
3140 ASSERT_NE_POINTER(NULL,fd->next);
3141
3142 fd = fd->next;
3143 ASSERT_EQ(4,fd->frame);
3144 ASSERT_EQ(110,fd->offset);
3145 ASSERT_EQ(40,fd->len);
3146 ASSERT_EQ(FD_OVERLAP,fd->flags);
3147 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
3148 ASSERT_EQ_POINTER(NULL,fd->next); */
3149
3150 /* test the actual reassembly */
3151 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
3152 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
3153 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
3154
3155 if (debug) {
3156 print_fragment_table();
3157 }
3158 }
3159 #endif
3160
3161 /* Test case for fragment_add_check with duplicated (e.g., retransmitted) data
3162 * where the retransmission "conflicts" with the original transmission
3163 * (contents are different).
3164 * Adds three fragments--adding the 2nd one twice--
3165 * and checks that they are reassembled correctly.
3166 */
3167 /* visit id frame frag_off len more tvb_offset
3168 0 12 1 0 50 T 10
3169 0 12 2 50 60 T 5
3170 0 12 3 50 60 T 15
3171 0 12 4 110 40 F 5
3172 */
3173 static void
3174 test_fragment_add_check_duplicate_conflict(void)
3175 {
3176 fragment_head *fd_head;
3177 fragment_item *fd;
3178
3179 printf("Starting test test_fragment_add_check_duplicate_conflict\n");
3180
3181 pinfo.num = 1;
3182 fd_head=fragment_add_check(&test_reassembly_table, tvb, 10, &pinfo, 12,
3183 NULL, 0, 50, TRUE);
3184
3185 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
3186 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
3187 ASSERT_EQ_POINTER(NULL,fd_head);
3188
3189 /* Add the 2nd segment */
3190 pinfo.num = 2;
3191 fd_head=fragment_add_check(&test_reassembly_table, tvb, 5, &pinfo, 12,
3192 NULL, 50, 60, TRUE);
3193
3194 /* we haven't got all the fragments yet ... */
3195 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
3196 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
3197 ASSERT_EQ_POINTER(NULL,fd_head);
3198
3199 /* Now, add the 2nd segment again (but in a different frame and with
3200 * different data)
3201 */
3202 pinfo.num = 3;
3203 fd_head=fragment_add_check(&test_reassembly_table, tvb, 15, &pinfo, 12,
3204 NULL, 50, 60, TRUE);
3205
3206 ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
3207 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
3208 ASSERT_EQ_POINTER(NULL,fd_head);
3209
3210 /* finally, add the last fragment */
3211 pinfo.num = 4;
3212 fd_head=fragment_add_check(&test_reassembly_table, tvb, 5, &pinfo, 12,
3213 NULL, 110, 40, FALSE);
3214
3215 ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
3216 ASSERT_EQ(4,g_hash_table_size(test_reassembly_table.reassembled_table));
3217 ASSERT_NE_POINTER(NULL,fd_head);
3218
3219 /* check the contents of the structure */
3220 ASSERT_EQ(4,fd_head->frame); /* max frame we have */
3221 ASSERT_EQ(0,fd_head->offset); /* unused */
3222 ASSERT_EQ(0,fd_head->len); /* unused */
3223 ASSERT_EQ(150,fd_head->datalen);
3224 ASSERT_EQ(4,fd_head->reassembled_in);
3225 ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET|FD_OVERLAP|FD_OVERLAPCONFLICT,fd_head->flags);
3226 ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
3227 ASSERT_NE_POINTER(NULL,fd_head->next);
3228
3229 fd = fd_head->next;
3230 ASSERT_EQ(1,fd->frame);
3231 ASSERT_EQ(0,fd->offset);
3232 ASSERT_EQ(50,fd->len); /* segment length */
3233 ASSERT_EQ(0,fd->flags);
3234 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
3235 ASSERT_NE_POINTER(NULL,fd->next);
3236
3237 fd = fd->next;
3238 ASSERT_EQ(2,fd->frame);
3239 ASSERT_EQ(50,fd->offset);
3240 ASSERT_EQ(60,fd->len); /* segment length */
3241 ASSERT_EQ(0,fd->flags);
3242 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
3243 ASSERT_NE_POINTER(NULL,fd->next);
3244
3245 fd = fd->next;
3246 ASSERT_EQ(3,fd->frame);
3247 ASSERT_EQ(50,fd->offset);
3248 ASSERT_EQ(60,fd->len); /* segment length */
3249 ASSERT_EQ(FD_OVERLAP|FD_OVERLAPCONFLICT,fd->flags);
3250 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
3251 ASSERT_NE_POINTER(NULL,fd->next);
3252
3253 fd = fd->next;
3254 ASSERT_EQ(4,fd->frame);
3255 ASSERT_EQ(110,fd->offset);
3256 ASSERT_EQ(40,fd->len); /* segment length */
3257 ASSERT_EQ(0,fd->flags);
3258 ASSERT_EQ_POINTER(NULL,fd->tvb_data);
3259 ASSERT_EQ_POINTER(NULL,fd->next);
3260
3261 /* test the actual reassembly */
3262 ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
3263 ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
3264 ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
3265
3266 if (debug) {
3267 print_fragment_table();
3268 }
3269 }
3270 /**********************************************************************************
3271 *
3272 * main
3273 *
3274 *********************************************************************************/
3275
3276 int
3277 main(int argc _U_, char **argv _U_)
3278 {
3279 frame_data fd;
3280 static const guint8 src[] = {1,2,3,4}, dst[] = {5,6,7,8};
3281 unsigned int i;
3282 static void (*tests[])(void) = {
3283 test_simple_fragment_add_seq, /* frag table only */
3284 test_fragment_add_seq_partial_reassembly,
3285 test_fragment_add_seq_duplicate_first,
3286 test_fragment_add_seq_duplicate_middle,
3287 test_fragment_add_seq_duplicate_last,
3288 test_fragment_add_seq_duplicate_conflict,
3289 test_fragment_add_seq_check, /* frag + reassemble */
3290 test_fragment_add_seq_check_1,
3291 test_fragment_add_seq_802_11_0,
3292 test_fragment_add_seq_802_11_1,
3293 test_simple_fragment_add_seq_next,
3294 #if 0
3295 test_missing_data_fragment_add_seq_next,
3296 test_missing_data_fragment_add_seq_next_2,
3297 test_missing_data_fragment_add_seq_next_3,
3298 #endif
3299 #if 0
3300 test_fragment_add_seq_check_multiple
3301 #endif
3302 test_simple_fragment_add, /* frag table only */
3303 test_fragment_add_partial_reassembly,
3304 test_fragment_add_duplicate_first,
3305 test_fragment_add_duplicate_middle,
3306 test_fragment_add_duplicate_last,
3307 test_fragment_add_duplicate_conflict,
3308 test_simple_fragment_add_check, /* frag table only */
3309 #if 0
3310 test_fragment_add_check_partial_reassembly,
3311 test_fragment_add_check_duplicate_first,
3312 #endif
3313 test_fragment_add_check_duplicate_middle,
3314 #if 0
3315 test_fragment_add_check_duplicate_last,
3316 #endif
3317 test_fragment_add_check_duplicate_conflict,
3318 };
3319
3320 /* a tvbuff for testing with */
3321 data = (guint8 *)g_malloc(DATA_LEN);
3322 /* make sure it's full of stuff */
3323 for(i=0; i<DATA_LEN; i++) {
3324 data[i]=i & 0xFF;
3325 }
3326 tvb = tvb_new_real_data(data, DATA_LEN, DATA_LEN*2);
3327
3328 /* other test stuff */
3329 pinfo.fd = &fd;
3330 fd.visited = 0;
3331 set_address(&pinfo.src,AT_IPv4,4,src);
3332 set_address(&pinfo.dst,AT_IPv4,4,dst);
3333
3334 /*************************************************************************/
3335 for(i=0; i < sizeof(tests)/sizeof(tests[0]); i++ ) {
3336 /* re-init the fragment tables */
3337 reassembly_table_init(&test_reassembly_table,
3338 &addresses_reassembly_table_functions);
3339 ASSERT(test_reassembly_table.fragment_table != NULL);
3340 ASSERT(test_reassembly_table.reassembled_table != NULL);
3341
3342 pinfo.fd->visited = FALSE;
3343
3344 tests[i]();
3345
3346 /* Free memory used by the tables */
3347 reassembly_table_destroy(&test_reassembly_table);
3348 }
3349
3350 tvb_free(tvb);
3351 tvb = NULL;
3352 g_free(data);
3353 data = NULL;
3354
3355 printf(failure?"FAILURE\n":"SUCCESS\n");
3356 return failure;
3357 }
3358
3359 /*
3360 * Editor modelines - https://www.wireshark.org/tools/modelines.html
3361 *
3362 * Local variables:
3363 * c-basic-offset: 4
3364 * tab-width: 8
3365 * indent-tabs-mode: nil
3366 * End:
3367 *
3368 * vi: set shiftwidth=4 tabstop=8 expandtab:
3369 * :indentSize=4:tabSize=8:noTabs=true:
3370 */
3371