1 /* Standalone program to test functionality of reassemble.h API
3 * These aren't particularly complete - they just test a few corners of
4 * functionality which I was interested in. In particular, they only test the
5 * fragment_add_seq_* (ie, FD_BLOCKSEQUENCE) family of routines. However,
6 * hopefully they will inspire people to write additional tests, and provide a
7 * useful basis on which to do so.
10 * 1. reassemble_test can be run under valgrind to detect any memory leaks in the
11 * Wireshark reassembly code.
12 * Specifically: code has been added to free dynamically allocated memory
13 * after each test (or at program completion) so that valgrind will report
14 * only actual memory leaks.
15 * The following command can be used to run reassemble_test under valgrind:
17 * G_DEBUG=gc-friendly \
18 * G_SLICE=always-malloc \
19 * WIRESHARK_DEBUG_EP_NO_CHUNKS=1 \
20 * WIRESHARK_DEBUG_SE_NO_CHUNKS=1 \
21 * WIRESHARK_DEBUG_SE_USE_CANARY=1 \
22 * WIRESHARK_EP_VERIFY_POINTERS=1 \
23 * WIRESHARK_SE_VERIFY_POINTERS=1 \
24 * valgrind --leak-check=full --show-reachable=yes ./reassemble_test
26 * 2. Debug functions have been added which will print information
27 * about the fd-chains associated with the fragment_table and the
29 * #define debug to enable the code.
33 * Copyright (c) 2007 MX Telecom Ltd. <richardv@mxtelecom.com>
35 * Wireshark - Network traffic analyzer
36 * By Gerald Combs <gerald@wireshark.org>
39 * This program is free software; you can redistribute it and/or
40 * modify it under the terms of the GNU General Public License
41 * as published by the Free Software Foundation; either version 2
42 * of the License, or (at your option) any later version.
44 * This program is distributed in the hope that it will be useful,
45 * but WITHOUT ANY WARRANTY; without even the implied warranty of
46 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
47 * GNU General Public License for more details.
49 * You should have received a copy of the GNU General Public License
50 * along with this program; if not, write to the Free Software
51 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
65 #include <epan/emem.h>
66 #include <epan/packet.h>
67 #include <epan/packet_info.h>
68 #include <epan/proto.h>
69 #include <epan/tvbuff.h>
70 #include <epan/reassemble.h>
72 #include <epan/dissectors/packet-dcerpc.h>
74 #define ASSERT(b) do_test((b),"Assertion failed at line %i: %s\n", __LINE__, #b)
75 #define ASSERT_EQ(exp,act) do_test((exp)==(act),"Assertion failed at line %i: %s==%s (%i==%i)\n", __LINE__, #exp, #act, exp, act)
76 #define ASSERT_NE(exp,act) do_test((exp)!=(act),"Assertion failed at line %i: %s!=%s (%i!=%i)\n", __LINE__, #exp, #act, exp, act)
78 static int failure = 0;
81 do_test(gboolean condition, const char *format, ...)
89 vfprintf(stderr, format, ap);
93 /* many of the tests assume this routine doesn't return on failure; if we
94 * do, it may provide more information, but may cause a segfault. Uncomment
95 * this line if you wish.
103 static tvbuff_t *tvb;
104 static packet_info pinfo;
106 /* fragment_table maps from datagram ids to head of fragment_data list
107 reassembled_table maps from <packet number,datagram id> to head of
108 fragment_data list */
109 static GHashTable *fragment_table = NULL;
110 static GHashTable *reassembled_table = NULL;
113 /*************************************************
114 * Util fcns to display
115 * fragment_table & reassembled_table fd-chains
116 ************************************************/
118 /* Must match the typedef in reassemble.c */
119 typedef struct _fragment_key {
125 /* Must match the typedef in reassemble.c */
126 typedef struct _reassembled_key {
131 static struct _fd_flags {
135 {FD_DEFRAGMENTED ,"DF"},
136 {FD_DATALEN_SET ,"DS"},
137 {FD_NOT_MALLOCED ,"NM"},
138 {FD_BLOCKSEQUENCE ,"BS"},
139 {FD_DATA_NOT_PRESENT ,"NP"},
140 {FD_PARTIAL_REASSEMBLY ,"PR"},
142 {FD_OVERLAPCONFLICT ,"OC"},
143 {FD_MULTIPLETAILS ,"MT"},
144 {FD_TOOLONGFRAGMENT ,"TL"},
146 #define N_FD_FLAGS (signed)(sizeof(fd_flags)/sizeof(struct _fd_flags))
149 print_fd(fragment_data *fd, gboolean is_head) {
152 g_assert(fd != NULL);
153 printf(" %08x %08x %3d %3d %3d", fd, fd->next, fd->frame, fd->offset, fd->len);
155 printf(" %3d %3d", fd->datalen, fd->reassembled_in);
159 printf(" 0x%08x", fd->data);
160 for (i=0; i<N_FD_FLAGS; i++) {
161 printf(" %s", (fd->flags & fd_flags[i].flag) ? fd_flags[i].flag_name : " ");
167 print_fd_chain(fragment_data *fd_head) {
170 g_assert(fd_head != NULL);
171 print_fd(fd_head, TRUE);
172 for (fdp=fd_head->next; fdp != NULL; fdp=fdp->next) {
173 print_fd(fdp, FALSE);
178 print_fragment_table_chain(gpointer k, gpointer v, gpointer ud) {
179 fragment_key *key = (fragment_key*)k;
180 fragment_data *fd_head = (fragment_data *)v;
181 printf(" --> FT: %3d 0x%08x 0x%08x\n", key->id, *(guint32 *)(key->src.data), *(guint32 *)(key->dst.data));
182 print_fd_chain(fd_head);
186 print_fragment_table(void) {
187 printf("\n Fragment Table -------\n");
188 g_hash_table_foreach(fragment_table, print_fragment_table_chain, NULL);
192 print_reassembled_table_chain(gpointer k, gpointer v, gpointer ud) {
193 reassembled_key *key = (reassembled_key*)k;
194 fragment_data *fd_head = (fragment_data *)v;
195 printf(" --> RT: %5d %5d\n", key->id, key->frame);
196 print_fd_chain(fd_head);
200 print_reassembled_table(void) {
201 printf("\n Reassembled Table ----\n");
202 g_hash_table_foreach(reassembled_table, print_reassembled_table_chain, NULL);
207 print_fragment_table();
208 print_reassembled_table();
212 /**********************************************************************************
216 *********************************************************************************/
218 /* Simple test case for fragment_add_seq.
219 * Adds three fragments (out of order, with one for a different datagram in between),
220 * and checks that they are reassembled correctly.
222 /* visit id frame frag len more tvb_offset
230 test_simple_fragment_add_seq(void)
232 fragment_data *fd_head, *fdh0;
234 printf("Starting test test_simple_fragment_add_seq\n");
237 fd_head=fragment_add_seq(tvb, 10, &pinfo, 12, fragment_table,
240 ASSERT_EQ(1,g_hash_table_size(fragment_table));
241 ASSERT_EQ(NULL,fd_head);
243 /* adding the same fragment again should do nothing, even with different
245 pinfo.fd->flags.visited = 1;
246 fd_head=fragment_add_seq(tvb, 5, &pinfo, 12, fragment_table,
248 ASSERT_EQ(1,g_hash_table_size(fragment_table));
249 ASSERT_EQ(NULL,fd_head);
251 /* start another pdu (just to confuse things) */
252 pinfo.fd->flags.visited = 0;
254 fd_head=fragment_add_seq(tvb, 15, &pinfo, 13, fragment_table,
256 ASSERT_EQ(2,g_hash_table_size(fragment_table));
257 ASSERT_EQ(NULL,fd_head);
259 /* now we add the terminal fragment of the first datagram */
261 fd_head=fragment_add_seq(tvb, 5, &pinfo, 12, fragment_table,
264 /* we haven't got all the fragments yet ... */
265 ASSERT_EQ(2,g_hash_table_size(fragment_table));
266 ASSERT_EQ(NULL,fd_head);
268 /* finally, add the missing fragment */
270 fd_head=fragment_add_seq(tvb, 15, &pinfo, 12, fragment_table,
273 ASSERT_EQ(2,g_hash_table_size(fragment_table));
274 ASSERT_NE(NULL,fd_head);
276 /* check the contents of the structure */
277 ASSERT_EQ(0,fd_head->frame); /* unused */
278 ASSERT_EQ(0,fd_head->offset); /* unused */
279 ASSERT_EQ(170,fd_head->len); /* the length of data we have */
280 ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
281 ASSERT_EQ(4,fd_head->reassembled_in);
282 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
283 ASSERT_NE(NULL,fd_head->data);
284 ASSERT_NE(NULL,fd_head->next);
286 ASSERT_EQ(1,fd_head->next->frame);
287 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
288 ASSERT_EQ(50,fd_head->next->len); /* segment length */
289 ASSERT_EQ(0,fd_head->next->flags);
290 ASSERT_EQ(NULL,fd_head->next->data);
291 ASSERT_NE(NULL,fd_head->next->next);
293 ASSERT_EQ(4,fd_head->next->next->frame);
294 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
295 ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
296 ASSERT_EQ(0,fd_head->next->next->flags);
297 ASSERT_EQ(NULL,fd_head->next->next->data);
298 ASSERT_NE(NULL,fd_head->next->next->next);
300 ASSERT_EQ(3,fd_head->next->next->next->frame);
301 ASSERT_EQ(2,fd_head->next->next->next->offset); /* seqno */
302 ASSERT_EQ(60,fd_head->next->next->next->len); /* segment length */
303 ASSERT_EQ(0,fd_head->next->next->next->flags);
304 ASSERT_EQ(NULL,fd_head->next->next->next->data);
305 ASSERT_EQ(NULL,fd_head->next->next->next->next);
307 /* test the actual reassembly */
308 ASSERT(!memcmp(fd_head->data,data+10,50));
309 ASSERT(!memcmp(fd_head->data+50,data+15,60));
310 ASSERT(!memcmp(fd_head->data+110,data+5,60));
313 print_fragment_table();
316 /* what happens if we revisit the packets now? */
318 pinfo.fd->flags.visited = 1;
320 fd_head=fragment_add_seq(tvb, 10, &pinfo, 12, fragment_table,
323 * this api relies on the caller to check fd_head -> reassembled_in
325 * Redoing all the tests seems like overkill - just check the pointer
327 ASSERT_EQ(fdh0,fd_head);
330 fd_head=fragment_add_seq(tvb, 5, &pinfo, 12, fragment_table,
332 ASSERT_EQ(fdh0,fd_head);
335 fd_head=fragment_add_seq(tvb, 15, &pinfo, 12, fragment_table,
337 ASSERT_EQ(fdh0,fd_head);
340 print_fragment_table();
344 /* XXX ought to have some tests for overlapping fragments */
346 /* This tests the functionality of fragment_set_partial_reassembly for
347 * FD_BLOCKSEQUENCE reassembly.
349 * We add a sequence of fragments thus:
350 * seqno frame offset len (initial) more_frags
351 * ----- ----- ------ --- --------------------
354 * 1 3 0 40 true (a duplicate fragment)
359 test_fragment_add_seq_partial_reassembly(void)
361 fragment_data *fd_head, *fd;
363 printf("Starting test test_fragment_add_seq_partial_reassembly\n");
365 /* generally it's probably fair to assume that we will be called with
369 fd_head=fragment_add_seq(tvb, 10, &pinfo, 12, fragment_table,
372 ASSERT_EQ(1,g_hash_table_size(fragment_table));
373 ASSERT_NE(NULL,fd_head);
375 /* check the contents of the structure */
376 ASSERT_EQ(0,fd_head->frame); /* unused */
377 ASSERT_EQ(0,fd_head->offset); /* unused */
378 ASSERT_EQ(50,fd_head->len); /* the length of data we have */
379 ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
380 ASSERT_EQ(1,fd_head->reassembled_in);
381 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
382 ASSERT_NE(NULL,fd_head->data);
383 ASSERT_NE(NULL,fd_head->next);
385 ASSERT_EQ(1,fd_head->next->frame);
386 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
387 ASSERT_EQ(50,fd_head->next->len); /* segment length */
388 ASSERT_EQ(0,fd_head->next->flags);
389 ASSERT_EQ(NULL,fd_head->next->data);
390 ASSERT_EQ(NULL,fd_head->next->next);
392 /* test the actual reassembly */
393 ASSERT(!memcmp(fd_head->data,data+10,50));
395 /* now we announce that the reassembly wasn't complete after all. */
396 fragment_set_partial_reassembly(&pinfo,12,fragment_table);
398 /* and add another segment. To mix things up slightly (and so that we can
399 * check on the state of things), we're going to set the more_frags flag
403 fd_head=fragment_add_seq(tvb, 0, &pinfo, 12, fragment_table,
406 ASSERT_EQ(1,g_hash_table_size(fragment_table));
407 ASSERT_EQ(NULL,fd_head);
409 fd_head=fragment_get(&pinfo,12,fragment_table);
410 ASSERT_NE(NULL,fd_head);
412 /* check the contents of the structure */
413 ASSERT_EQ(0,fd_head->frame); /* unused */
414 ASSERT_EQ(0,fd_head->offset); /* unused */
415 /* ASSERT_EQ(50,fd_head->len); the length of data we have */
416 ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
417 ASSERT_EQ(0,fd_head->reassembled_in);
418 ASSERT_EQ(FD_BLOCKSEQUENCE,fd_head->flags);
419 ASSERT_NE(NULL,fd_head->data);
420 ASSERT_NE(NULL,fd_head->next);
423 ASSERT_EQ(1,fd->frame);
424 ASSERT_EQ(0,fd->offset); /* seqno */
425 ASSERT_EQ(50,fd->len); /* segment length */
426 ASSERT_EQ(FD_NOT_MALLOCED,fd->flags);
427 ASSERT_EQ(fd_head->data,fd->data);
428 ASSERT_NE(NULL,fd->next);
431 ASSERT_EQ(2,fd->frame);
432 ASSERT_EQ(1,fd->offset); /* seqno */
433 ASSERT_EQ(40,fd->len); /* segment length */
434 ASSERT_EQ(0,fd->flags);
435 ASSERT_NE(NULL,fd->data);
436 ASSERT_EQ(NULL,fd->next);
438 /* Another copy of the second segment.
441 fd_head=fragment_add_seq(tvb, 0, &pinfo, 12, fragment_table,
444 ASSERT_EQ(1,g_hash_table_size(fragment_table));
445 ASSERT_EQ(NULL,fd_head);
446 fd_head=fragment_get(&pinfo,12,fragment_table);
447 ASSERT_NE(NULL,fd_head);
448 ASSERT_EQ(0,fd_head->frame); /* unused */
449 ASSERT_EQ(0,fd_head->offset); /* unused */
450 /* ASSERT_EQ(50,fd_head->len); the length of data we have */
451 ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
452 ASSERT_EQ(0,fd_head->reassembled_in);
453 ASSERT_EQ(FD_BLOCKSEQUENCE,fd_head->flags);
454 ASSERT_NE(NULL,fd_head->data);
455 ASSERT_NE(NULL,fd_head->next);
458 ASSERT_EQ(1,fd->frame);
459 ASSERT_EQ(0,fd->offset); /* seqno */
460 ASSERT_EQ(50,fd->len); /* segment length */
461 ASSERT_EQ(FD_NOT_MALLOCED,fd->flags);
462 ASSERT_EQ(fd_head->data,fd->data);
463 ASSERT_NE(NULL,fd->next);
466 ASSERT_EQ(2,fd->frame);
467 ASSERT_EQ(1,fd->offset); /* seqno */
468 ASSERT_EQ(40,fd->len); /* segment length */
469 ASSERT_EQ(0,fd->flags);
470 ASSERT_NE(NULL,fd->data);
471 ASSERT_NE(NULL,fd->next);
474 ASSERT_EQ(3,fd->frame);
475 ASSERT_EQ(1,fd->offset); /* seqno */
476 ASSERT_EQ(40,fd->len); /* segment length */
477 ASSERT_EQ(0,fd->flags);
478 ASSERT_NE(NULL,fd->data);
479 ASSERT_EQ(NULL,fd->next);
483 /* have another go at wrapping things up */
485 fd_head=fragment_add_seq(tvb, 20, &pinfo, 12, fragment_table,
488 ASSERT_EQ(1,g_hash_table_size(fragment_table));
489 ASSERT_NE(NULL,fd_head);
491 /* check the contents of the structure */
492 ASSERT_EQ(0,fd_head->frame); /* unused */
493 ASSERT_EQ(0,fd_head->offset); /* unused */
494 ASSERT_EQ(190,fd_head->len); /* the length of data we have */
495 ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
496 ASSERT_EQ(4,fd_head->reassembled_in);
497 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
498 ASSERT_NE(NULL,fd_head->data);
499 ASSERT_NE(NULL,fd_head->next);
502 ASSERT_EQ(1,fd->frame);
503 ASSERT_EQ(0,fd->offset); /* seqno */
504 ASSERT_EQ(50,fd->len); /* segment length */
505 ASSERT_EQ(0,fd->flags);
506 ASSERT_EQ(NULL,fd->data);
507 ASSERT_NE(NULL,fd->next);
510 ASSERT_EQ(2,fd->frame);
511 ASSERT_EQ(1,fd->offset); /* seqno */
512 ASSERT_EQ(40,fd->len); /* segment length */
513 ASSERT_EQ(0,fd->flags);
514 ASSERT_EQ(NULL,fd->data);
515 ASSERT_NE(NULL,fd->next);
518 ASSERT_EQ(3,fd->frame);
519 ASSERT_EQ(1,fd->offset); /* seqno */
520 ASSERT_EQ(40,fd->len); /* segment length */
521 ASSERT_EQ(FD_OVERLAP,fd->flags);
522 ASSERT_EQ(NULL,fd->data);
523 ASSERT_NE(NULL,fd->next);
526 ASSERT_EQ(4,fd->frame);
527 ASSERT_EQ(2,fd->offset); /* seqno */
528 ASSERT_EQ(100,fd->len); /* segment length */
529 ASSERT_EQ(0,fd->flags);
530 ASSERT_EQ(NULL,fd->data);
531 ASSERT_EQ(NULL,fd->next);
533 /* test the actual reassembly */
534 ASSERT(!memcmp(fd_head->data,data+10,50));
535 ASSERT(!memcmp(fd_head->data+50,data,40));
536 ASSERT(!memcmp(fd_head->data+90,data+20,100));
539 /* do it again (this time it is more complicated, with an overlap in the
542 fragment_set_partial_reassembly(&pinfo,12,fragment_table);
545 fd_head=fragment_add_seq(tvb, 0, &pinfo, 12, fragment_table,
548 fd_head=fragment_get(&pinfo,12,fragment_table);
549 ASSERT_NE(NULL,fd_head);
550 ASSERT_EQ(0,fd_head->frame); /* unused */
551 ASSERT_EQ(0,fd_head->offset); /* unused */
552 ASSERT_EQ(230,fd_head->len); /* the length of data we have */
553 ASSERT_EQ(3,fd_head->datalen); /* seqno of the last fragment we have */
554 ASSERT_EQ(5,fd_head->reassembled_in);
555 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
556 ASSERT_NE(NULL,fd_head->data);
557 ASSERT_NE(NULL,fd_head->next);
560 ASSERT_EQ(1,fd->frame);
561 ASSERT_EQ(0,fd->offset); /* seqno */
562 ASSERT_EQ(50,fd->len); /* segment length */
563 ASSERT_EQ(0,fd->flags);
564 ASSERT_EQ(NULL,fd->data);
565 ASSERT_NE(NULL,fd->next);
568 ASSERT_EQ(2,fd->frame);
569 ASSERT_EQ(1,fd->offset); /* seqno */
570 ASSERT_EQ(40,fd->len); /* segment length */
571 ASSERT_EQ(0,fd->flags);
572 ASSERT_EQ(NULL,fd->data);
573 ASSERT_NE(NULL,fd->next);
576 ASSERT_EQ(3,fd->frame);
577 ASSERT_EQ(1,fd->offset); /* seqno */
578 ASSERT_EQ(40,fd->len); /* segment length */
579 ASSERT_EQ(FD_OVERLAP,fd->flags);
580 ASSERT_EQ(NULL,fd->data);
581 ASSERT_NE(NULL,fd->next);
584 ASSERT_EQ(4,fd->frame);
585 ASSERT_EQ(2,fd->offset); /* seqno */
586 ASSERT_EQ(100,fd->len); /* segment length */
587 ASSERT_EQ(0,fd->flags);
588 ASSERT_EQ(NULL,fd->data);
589 ASSERT_NE(NULL,fd->next);
592 ASSERT_EQ(5,fd->frame);
593 ASSERT_EQ(3,fd->offset); /* seqno */
594 ASSERT_EQ(40,fd->len); /* segment length */
595 ASSERT_EQ(0,fd->flags);
596 ASSERT_EQ(NULL,fd->data);
597 ASSERT_EQ(NULL,fd->next);
599 /* test the actual reassembly */
600 ASSERT(!memcmp(fd_head->data,data+10,50));
601 ASSERT(!memcmp(fd_head->data+50,data,40));
602 ASSERT(!memcmp(fd_head->data+90,data+20,100));
603 ASSERT(!memcmp(fd_head->data+190,data,40));
606 /**********************************************************************************
608 * fragment_add_dcerpc_dg
610 *********************************************************************************/
612 /* This can afford to be reasonably minimal, as it's just the same logic with a
613 * different hash key to fragment_add_seq
616 test_fragment_add_dcerpc_dg(void)
618 e_uuid_t act_id = {1,2,3,{4,5,6,7,8,9,10,11}};
620 fragment_data *fd_head, *fdh0;
621 GHashTable *fragment_table = NULL;
623 printf("Starting test test_fragment_add_dcerpc_dg\n");
625 /* we need our own fragment table */
626 dcerpc_fragment_table_init(&fragment_table);
627 fd_head=fragment_add_dcerpc_dg(tvb, 10, &pinfo, 12, &act_id, fragment_table,
630 ASSERT_EQ(1,g_hash_table_size(fragment_table));
631 ASSERT_EQ(NULL,fd_head);
633 /* start another pdu (just to confuse things) */
635 fd_head=fragment_add_dcerpc_dg(tvb, 15, &pinfo, 13, &act_id, fragment_table,
637 ASSERT_EQ(2,g_hash_table_size(fragment_table));
638 ASSERT_EQ(NULL,fd_head);
640 /* another pdu, with the same fragment_id, but a different act_id, to the
644 fd_head=fragment_add_dcerpc_dg(tvb, 15, &pinfo, 12, &act_id, fragment_table,
646 ASSERT_EQ(3,g_hash_table_size(fragment_table));
647 ASSERT_EQ(NULL,fd_head);
650 /* now we add the terminal fragment of the first datagram */
652 fd_head=fragment_add_dcerpc_dg(tvb, 5, &pinfo, 12, &act_id, fragment_table,
655 ASSERT_EQ(3,g_hash_table_size(fragment_table));
656 ASSERT_NE(NULL,fd_head);
658 /* check the contents of the structure */
659 ASSERT_EQ(0,fd_head->frame); /* unused */
660 ASSERT_EQ(0,fd_head->offset); /* unused */
661 ASSERT_EQ(110,fd_head->len); /* the length of data we have */
662 ASSERT_EQ(1,fd_head->datalen); /* seqno of the last fragment we have */
663 ASSERT_EQ(4,fd_head->reassembled_in);
664 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
665 ASSERT_NE(NULL,fd_head->data);
666 ASSERT_NE(NULL,fd_head->next);
668 /* test the actual reassembly */
669 ASSERT(!memcmp(fd_head->data,data+10,50));
670 ASSERT(!memcmp(fd_head->data+50,data+5,60));
672 /* what happens if we revisit the packets now? */
674 pinfo.fd->flags.visited = 1;
676 fd_head=fragment_add_dcerpc_dg(tvb, 10, &pinfo, 12, &act_id, fragment_table,
679 * this api relies on the caller to check fd_head -> reassembled_in
681 * Redoing all the tests seems like overkill - just check the pointer
683 ASSERT_EQ(fdh0,fd_head);
686 /**********************************************************************************
688 * fragment_add_seq_check
690 *********************************************************************************/
693 /* This routine is used for both fragment_add_seq_802_11 and
694 * fragment_add_seq_check.
696 * Adds a couple of out-of-order fragments and checks their reassembly.
699 /* visit id frame frag len more tvb_offset
708 test_fragment_add_seq_check_work(fragment_data *(*fn)(tvbuff_t *, const int,
709 const packet_info *, const guint32, GHashTable *,
710 GHashTable *, const guint32, const guint32, const gboolean))
712 fragment_data *fd_head;
715 fd_head=fn(tvb, 10, &pinfo, 12, fragment_table,
716 reassembled_table, 0, 50, TRUE);
718 ASSERT_EQ(1,g_hash_table_size(fragment_table));
719 ASSERT_EQ(0,g_hash_table_size(reassembled_table));
720 ASSERT_EQ(NULL,fd_head);
722 /* start another pdu (just to confuse things) */
724 fd_head=fn(tvb, 15, &pinfo, 13, fragment_table,
725 reassembled_table, 0, 60, TRUE);
726 ASSERT_EQ(2,g_hash_table_size(fragment_table));
727 ASSERT_EQ(0,g_hash_table_size(reassembled_table));
728 ASSERT_EQ(NULL,fd_head);
730 /* add the terminal fragment of the first datagram */
732 fd_head=fn(tvb, 5, &pinfo, 12, fragment_table,
733 reassembled_table, 2, 60, FALSE);
735 /* we haven't got all the fragments yet ... */
736 ASSERT_EQ(2,g_hash_table_size(fragment_table));
737 ASSERT_EQ(0,g_hash_table_size(reassembled_table));
738 ASSERT_EQ(NULL,fd_head);
740 /* finally, add the missing fragment */
742 fd_head=fn(tvb, 15, &pinfo, 12, fragment_table,
743 reassembled_table, 1, 60, TRUE);
745 ASSERT_EQ(1,g_hash_table_size(fragment_table));
746 ASSERT_EQ(3,g_hash_table_size(reassembled_table));
747 ASSERT_NE(NULL,fd_head);
749 /* check the contents of the structure */
750 ASSERT_EQ(0,fd_head->frame); /* unused */
751 ASSERT_EQ(0,fd_head->offset); /* unused */
752 ASSERT_EQ(170,fd_head->len); /* the length of data we have */
753 ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
754 ASSERT_EQ(4,fd_head->reassembled_in);
755 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
756 ASSERT_NE(NULL,fd_head->data);
757 ASSERT_NE(NULL,fd_head->next);
759 ASSERT_EQ(1,fd_head->next->frame);
760 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
761 ASSERT_EQ(50,fd_head->next->len); /* segment length */
762 ASSERT_EQ(0,fd_head->next->flags);
763 ASSERT_EQ(NULL,fd_head->next->data);
764 ASSERT_NE(NULL,fd_head->next->next);
766 ASSERT_EQ(4,fd_head->next->next->frame);
767 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
768 ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
769 ASSERT_EQ(0,fd_head->next->next->flags);
770 ASSERT_EQ(NULL,fd_head->next->next->data);
771 ASSERT_NE(NULL,fd_head->next->next->next);
773 ASSERT_EQ(3,fd_head->next->next->next->frame);
774 ASSERT_EQ(2,fd_head->next->next->next->offset); /* seqno */
775 ASSERT_EQ(60,fd_head->next->next->next->len); /* segment length */
776 ASSERT_EQ(0,fd_head->next->next->next->flags);
777 ASSERT_EQ(NULL,fd_head->next->next->next->data);
778 ASSERT_EQ(NULL,fd_head->next->next->next->next);
780 /* test the actual reassembly */
781 ASSERT(!memcmp(fd_head->data,data+10,50));
782 ASSERT(!memcmp(fd_head->data+50,data+15,60));
783 ASSERT(!memcmp(fd_head->data+110,data+5,60));
790 /* Simple test case for fragment_add_seq_check
793 test_fragment_add_seq_check(void)
795 printf("Starting test test_fragment_add_seq_check\n");
797 test_fragment_add_seq_check_work(fragment_add_seq_check);
801 /* This tests the case that the 802.11 hack does something different for: when
802 * the terminal segment in a fragmented datagram arrives first.
805 test_fragment_add_seq_check_1(void)
807 fragment_data *fd_head;
809 printf("Starting test test_fragment_add_seq_check_1\n");
812 fd_head=fragment_add_seq_check(tvb, 10, &pinfo, 12, fragment_table,
813 reassembled_table, 1, 50, FALSE);
815 ASSERT_EQ(1,g_hash_table_size(fragment_table));
816 ASSERT_EQ(0,g_hash_table_size(reassembled_table));
817 ASSERT_EQ(NULL,fd_head);
819 /* Now add the missing segment */
821 fd_head=fragment_add_seq_check(tvb, 5, &pinfo, 12, fragment_table,
822 reassembled_table, 0, 60, TRUE);
824 ASSERT_EQ(0,g_hash_table_size(fragment_table));
825 ASSERT_EQ(2,g_hash_table_size(reassembled_table));
826 ASSERT_NE(NULL,fd_head);
828 /* check the contents of the structure */
829 ASSERT_EQ(0,fd_head->frame); /* unused */
830 ASSERT_EQ(0,fd_head->offset); /* unused */
831 ASSERT_EQ(110,fd_head->len); /* the length of data we have */
832 ASSERT_EQ(1,fd_head->datalen); /* seqno of the last fragment we have */
833 ASSERT_EQ(2,fd_head->reassembled_in);
834 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
835 ASSERT_NE(NULL,fd_head->data);
836 ASSERT_NE(NULL,fd_head->next);
838 ASSERT_EQ(2,fd_head->next->frame);
839 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
840 ASSERT_EQ(60,fd_head->next->len); /* segment length */
841 ASSERT_EQ(0,fd_head->next->flags);
842 ASSERT_EQ(NULL,fd_head->next->data);
843 ASSERT_NE(NULL,fd_head->next->next);
845 ASSERT_EQ(1,fd_head->next->next->frame);
846 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
847 ASSERT_EQ(50,fd_head->next->next->len); /* segment length */
848 ASSERT_EQ(0,fd_head->next->next->flags);
849 ASSERT_EQ(NULL,fd_head->next->next->data);
850 ASSERT_EQ(NULL,fd_head->next->next->next);
852 /* test the actual reassembly */
853 ASSERT(!memcmp(fd_head->data,data+5,60));
854 ASSERT(!memcmp(fd_head->data+60,data+10,50));
857 /**********************************************************************************
859 * fragment_add_seq_802_11
861 *********************************************************************************/
863 /* Tests the 802.11 hack.
866 test_fragment_add_seq_802_11_0(void)
868 fragment_data *fd_head;
870 printf("Starting test test_fragment_add_seq_802_11_0\n");
872 /* the 802.11 hack is that some non-fragmented datagrams have non-zero
873 * fragment_number; test for this. */
876 fd_head=fragment_add_seq_802_11(tvb, 10, &pinfo, 12, fragment_table,
877 reassembled_table, 10, 50, FALSE);
879 ASSERT_EQ(0,g_hash_table_size(fragment_table));
880 ASSERT_EQ(1,g_hash_table_size(reassembled_table));
881 ASSERT_NE(NULL,fd_head);
883 /* check the contents of the structure */
884 ASSERT_EQ(0,fd_head->frame); /* unused */
885 ASSERT_EQ(0,fd_head->offset); /* unused */
886 ASSERT_EQ(0,fd_head->len); /* unused */
887 ASSERT_EQ(0,fd_head->datalen); /* unused */
888 ASSERT_EQ(1,fd_head->reassembled_in);
889 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE,fd_head->flags);
890 ASSERT_EQ(NULL,fd_head->data);
891 ASSERT_EQ(NULL,fd_head->next);
894 /* Reuse the fragment_add_seq_check testcases */
895 static void test_fragment_add_seq_802_11_1(void)
897 printf("Starting test test_fragment_add_seq_802_11_1\n");
898 test_fragment_add_seq_check_work(fragment_add_seq_802_11);
901 /**********************************************************************************
903 * fragment_add_seq_check_multiple
905 *********************************************************************************/
907 /* Test 2 partial frags from 2 diff datagrams in the same frame */
909 datagram #1: frame 1 + first part of frame 2
910 datagram #1: last part of frame 2 + frame 3
912 Is this a valid scenario ?
914 The result of calling fragment_add_seq_check() for these
915 fragments is a reassembled_table with:
916 id, frame 1 => first_datagram; ["reassembled in" frame 2]
917 id, frame 2 => second_datagram; ["reassembled in" frame 3]
918 id, frame 3 => second_datagram;
920 Note that the id, frame 2 => first datagram was overwritten
921 by the entry for the second datagram.
922 Is this OK ? IE: When dissected/displayed
923 will the reassembled datagram 1 appear with frame 2 ??
926 /* visit id frame frag len more tvb_offset
934 Is this a valid scenario ?
935 Is this OK ? IE: When dissected/displayed:
936 Will the reassembled datagram 1 appear with frame 2 ??
940 test_fragment_add_seq_check_multiple(void) {
941 fragment_data *fd_head;
944 fd_head=fragment_add_seq_check(tvb, 10, &pinfo, 12, fragment_table,
945 reassembled_table, 0, 50, TRUE);
947 /* add the terminal fragment of the first datagram */
949 fd_head=fragment_add_seq_check(tvb, 5, &pinfo, 12, fragment_table,
950 reassembled_table, 1, 20, FALSE);
954 /* Now: start a second datagram with the first fragment in frame #2 */
956 fd_head=fragment_add_seq_check(tvb, 25, &pinfo, 12, fragment_table,
957 reassembled_table, 0, 25, TRUE);
959 /* add the terminal fragment of the second datagram */
961 fd_head=fragment_add_seq_check(tvb, 0, &pinfo, 12, fragment_table,
962 reassembled_table, 1, 60, FALSE);
968 /**********************************************************************************
970 * fragment_add_seq_next
972 *********************************************************************************/
974 /* Simple test case for fragment_add_seq_next.
975 * Adds a couple of fragments (with one for a different datagram in between),
976 * and checks that they are reassembled correctly.
979 test_simple_fragment_add_seq_next(void)
981 fragment_data *fd_head;
983 printf("Starting test test_simple_fragment_add_seq_next\n");
986 fd_head= fragment_add_seq_next(tvb, 10, &pinfo, 12, fragment_table,
987 reassembled_table, 50, TRUE);
989 ASSERT_EQ(1,g_hash_table_size(fragment_table));
990 ASSERT_EQ(0,g_hash_table_size(reassembled_table));
991 ASSERT_EQ(NULL,fd_head);
993 /* adding the same fragment again should do nothing, even with different
995 pinfo.fd->flags.visited = 1;
996 fd_head=fragment_add_seq_next(tvb, 5, &pinfo, 12, fragment_table,
997 reassembled_table, 60, TRUE);
998 ASSERT_EQ(1,g_hash_table_size(fragment_table));
999 ASSERT_EQ(0,g_hash_table_size(reassembled_table));
1000 ASSERT_EQ(NULL,fd_head);
1002 /* start another pdu (just to confuse things) */
1003 pinfo.fd->flags.visited = 0;
1005 fd_head=fragment_add_seq_next(tvb, 15, &pinfo, 13, fragment_table,
1006 reassembled_table, 60, TRUE);
1007 ASSERT_EQ(2,g_hash_table_size(fragment_table));
1008 ASSERT_EQ(0,g_hash_table_size(reassembled_table));
1009 ASSERT_EQ(NULL,fd_head);
1012 /* now we add the terminal fragment of the first datagram */
1014 fd_head=fragment_add_seq_next(tvb, 5, &pinfo, 12, fragment_table,
1015 reassembled_table, 60, FALSE);
1017 ASSERT_EQ(1,g_hash_table_size(fragment_table));
1018 ASSERT_EQ(2,g_hash_table_size(reassembled_table));
1019 ASSERT_NE(NULL,fd_head);
1021 /* check the contents of the structure */
1022 ASSERT_EQ(0,fd_head->frame); /* unused */
1023 ASSERT_EQ(0,fd_head->offset); /* unused */
1024 ASSERT_EQ(110,fd_head->len); /* the length of data we have */
1025 ASSERT_EQ(1,fd_head->datalen); /* seqno of the last fragment we have */
1026 ASSERT_EQ(3,fd_head->reassembled_in);
1027 ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
1028 ASSERT_NE(NULL,fd_head->data);
1029 ASSERT_NE(NULL,fd_head->next);
1031 ASSERT_EQ(1,fd_head->next->frame);
1032 ASSERT_EQ(0,fd_head->next->offset); /* seqno */
1033 ASSERT_EQ(50,fd_head->next->len); /* segment length */
1034 ASSERT_EQ(0,fd_head->next->flags);
1035 ASSERT_EQ(NULL,fd_head->next->data);
1036 ASSERT_NE(NULL,fd_head->next->next);
1038 ASSERT_EQ(3,fd_head->next->next->frame);
1039 ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
1040 ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
1041 ASSERT_EQ(0,fd_head->next->next->flags);
1042 ASSERT_EQ(NULL,fd_head->next->next->data);
1043 ASSERT_EQ(NULL,fd_head->next->next->next);
1045 /* test the actual reassembly */
1046 ASSERT(!memcmp(fd_head->data,data+10,50));
1047 ASSERT(!memcmp(fd_head->data+50,data+5,60));
1051 /* This tests the case where some data is missing from one of the fragments.
1052 * It should prevent reassembly.
1055 test_missing_data_fragment_add_seq_next(void)
1057 fragment_data *fd_head;
1059 printf("Starting test test_missing_data_fragment_add_seq_next\n");
1061 /* attempt to add a fragment which is longer than the data available */
1063 fd_head=fragment_add_seq_next(tvb, 10, &pinfo, 12, fragment_table,
1064 reassembled_table, DATA_LEN-9, TRUE);
1066 ASSERT_EQ(1,g_hash_table_size(fragment_table));
1067 ASSERT_EQ(0,g_hash_table_size(reassembled_table));
1068 ASSERT_NE(NULL,fd_head);
1070 /* check the contents of the structure. Reassembly failed so everything
1071 * should be null (meaning, just use the original tvb) */
1072 ASSERT_EQ(0,fd_head->frame); /* unused */
1073 ASSERT_EQ(0,fd_head->offset); /* unused */
1074 ASSERT_EQ(0,fd_head->len); /* the length of data we have */
1075 ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
1076 ASSERT_EQ(0,fd_head->reassembled_in);
1077 ASSERT_EQ(FD_BLOCKSEQUENCE,fd_head->flags & 0x1ff);
1078 ASSERT_EQ(NULL,fd_head->data);
1079 ASSERT_EQ(NULL,fd_head->next);
1081 /* add another fragment (with all data present) */
1083 fd_head=fragment_add_seq_next(tvb, 5, &pinfo, 12, fragment_table,
1084 reassembled_table, 60, FALSE);
1086 /* XXX: it's not clear that this is the right result; however it's what the
1089 ASSERT_EQ(1,g_hash_table_size(fragment_table));
1090 ASSERT_EQ(0,g_hash_table_size(reassembled_table));
1091 ASSERT_EQ(NULL,fd_head);
1094 /* check what happens when we revisit the packets */
1095 pinfo.fd->flags.visited = TRUE;
1098 fd_head=fragment_add_seq_next(tvb, 10, &pinfo, 12, fragment_table,
1099 reassembled_table, DATA_LEN-9, TRUE);
1101 /* We just look in the reassembled_table for this packet. It never got put
1102 * there, so this always returns null.
1104 * That's crazy, because it means that the subdissector will see the data
1105 * exactly once - on the first pass through the capture (well, assuming it
1106 * doesn't bother to check fd_head->reassembled_in); however, that's
1107 * what the code does...
1109 ASSERT_EQ(1,g_hash_table_size(fragment_table));
1110 ASSERT_EQ(0,g_hash_table_size(reassembled_table));
1111 ASSERT_EQ(NULL,fd_head);
1114 fd_head=fragment_add_seq_next(tvb, 5, &pinfo, 12, fragment_table,
1115 reassembled_table, 60, FALSE);
1116 ASSERT_EQ(1,g_hash_table_size(fragment_table));
1117 ASSERT_EQ(0,g_hash_table_size(reassembled_table));
1118 ASSERT_EQ(NULL,fd_head);
1123 * we're going to do something similar now, but this time it is the second
1124 * fragment which has something missing.
1127 test_missing_data_fragment_add_seq_next_2(void)
1129 fragment_data *fd_head;
1131 printf("Starting test test_missing_data_fragment_add_seq_next_2\n");
1134 fd_head=fragment_add_seq_next(tvb, 10, &pinfo, 24, fragment_table,
1135 reassembled_table, 50, TRUE);
1137 ASSERT_EQ(1,g_hash_table_size(fragment_table));
1138 ASSERT_EQ(0,g_hash_table_size(reassembled_table));
1139 ASSERT_EQ(NULL,fd_head);
1142 fd_head=fragment_add_seq_next(tvb, 5, &pinfo, 24, fragment_table,
1143 reassembled_table, DATA_LEN-4, FALSE);
1145 /* XXX: again, i'm really dubious about this. Surely this should return all
1146 * the data we had, for a best-effort attempt at dissecting it?
1147 * And it ought to go into the reassembled table?
1149 ASSERT_EQ(0,g_hash_table_size(fragment_table));
1150 ASSERT_EQ(0,g_hash_table_size(reassembled_table));
1151 ASSERT_EQ(NULL,fd_head);
1153 /* check what happens when we revisit the packets */
1154 pinfo.fd->flags.visited = TRUE;
1157 fd_head=fragment_add_seq_next(tvb, 10, &pinfo, 24, fragment_table,
1158 reassembled_table, 50, TRUE);
1160 /* As before, this returns NULL because the fragment isn't in the
1161 * reassembled_table. At least this is a bit more consistent than before.
1163 ASSERT_EQ(0,g_hash_table_size(fragment_table));
1164 ASSERT_EQ(0,g_hash_table_size(reassembled_table));
1165 ASSERT_EQ(NULL,fd_head);
1168 fd_head=fragment_add_seq_next(tvb, 5, &pinfo, 24, fragment_table,
1169 reassembled_table, DATA_LEN-4, FALSE);
1170 ASSERT_EQ(0,g_hash_table_size(fragment_table));
1171 ASSERT_EQ(0,g_hash_table_size(reassembled_table));
1172 ASSERT_EQ(NULL,fd_head);
1177 * This time, our datagram only has one segment, but it has data missing.
1180 test_missing_data_fragment_add_seq_next_3(void)
1182 fragment_data *fd_head;
1184 printf("Starting test test_missing_data_fragment_add_seq_next_3\n");
1187 fd_head=fragment_add_seq_next(tvb, 5, &pinfo, 30, fragment_table,
1188 reassembled_table, DATA_LEN-4, FALSE);
1190 ASSERT_EQ(0,g_hash_table_size(fragment_table));
1191 ASSERT_EQ(1,g_hash_table_size(reassembled_table));
1192 ASSERT_NE(NULL,fd_head);
1194 /* check the contents of the structure. */
1195 ASSERT_EQ(0,fd_head->frame); /* unused */
1196 ASSERT_EQ(0,fd_head->offset); /* unused */
1197 ASSERT_EQ(0,fd_head->len); /* the length of data we have */
1198 ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
1199 ASSERT_EQ(20,fd_head->reassembled_in);
1200 ASSERT_EQ(FD_BLOCKSEQUENCE|FD_DEFRAGMENTED,fd_head->flags);
1201 ASSERT_EQ(NULL,fd_head->data);
1202 ASSERT_EQ(NULL,fd_head->next);
1204 /* revisiting the packet ought to produce the same result. */
1205 pinfo.fd->flags.visited = TRUE;
1208 fd_head=fragment_add_seq_next(tvb, 5, &pinfo, 30, fragment_table,
1209 reassembled_table, DATA_LEN-4, FALSE);
1211 ASSERT_EQ(0,g_hash_table_size(fragment_table));
1212 ASSERT_EQ(1,g_hash_table_size(reassembled_table));
1213 ASSERT_NE(NULL,fd_head);
1214 ASSERT_EQ(0,fd_head->frame); /* unused */
1215 ASSERT_EQ(0,fd_head->offset); /* unused */
1216 ASSERT_EQ(0,fd_head->len); /* the length of data we have */
1217 ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
1218 ASSERT_EQ(20,fd_head->reassembled_in);
1219 ASSERT_EQ(FD_BLOCKSEQUENCE|FD_DEFRAGMENTED,fd_head->flags);
1220 ASSERT_EQ(NULL,fd_head->data);
1221 ASSERT_EQ(NULL,fd_head->next);
1225 /**********************************************************************************
1229 *********************************************************************************/
1232 main(int argc _U_, char **argv _U_)
1235 char src[] = {1,2,3,4}, dst[] = {5,6,7,8};
1237 void (*tests[])(void) = {
1238 test_simple_fragment_add_seq, /* frag table only */
1239 test_fragment_add_seq_partial_reassembly,
1240 test_fragment_add_dcerpc_dg,
1241 test_fragment_add_seq_check, /* frag + reassemble */
1242 test_fragment_add_seq_check_1,
1243 test_fragment_add_seq_802_11_0,
1244 test_fragment_add_seq_802_11_1,
1245 test_simple_fragment_add_seq_next,
1246 test_missing_data_fragment_add_seq_next,
1247 test_missing_data_fragment_add_seq_next_2,
1248 test_missing_data_fragment_add_seq_next_3,
1250 test_fragment_add_seq_check_multiple
1254 /* initialise stuff */
1259 /* a tvbuff for testing with */
1260 data = g_malloc(DATA_LEN);
1261 /* make sure it's full of stuff */
1262 for(i=0; i<DATA_LEN; i++) {
1265 tvb = tvb_new_real_data(data, DATA_LEN, DATA_LEN*2);
1267 /* other test stuff */
1269 fd.flags.visited = 0;
1270 SET_ADDRESS(&pinfo.src,AT_IPv4,4,src);
1271 SET_ADDRESS(&pinfo.dst,AT_IPv4,4,dst);
1273 /*************************************************************************/
1274 for(i=0; i < sizeof(tests)/sizeof(tests[0]); i++ ) {
1275 /* re-init the fragment tables */
1276 fragment_table_init(&fragment_table);
1277 ASSERT(fragment_table != NULL);
1279 reassembled_table_init(&reassembled_table);
1280 ASSERT(reassembled_table != NULL);
1282 pinfo.fd->flags.visited = FALSE;
1286 /* Free memory used by the tables */
1287 fragment_table_init(&fragment_table);
1288 g_hash_table_destroy(fragment_table);
1289 fragment_table = NULL;
1291 reassembled_table_init(&reassembled_table);
1292 g_hash_table_destroy(reassembled_table);
1293 reassembled_table = NULL;
1301 printf(failure?"FAILURE\n":"SUCCESS\n");
1307 void add_new_data_source(packet_info *pinfo _U_, tvbuff_t *tvb _U_,
1308 const char *name _U_)
1312 proto_tree_add_uint(proto_tree *tree _U_, int hfindex _U_, tvbuff_t *tvb _U_,
1313 gint start _U_, gint length _U_, guint32 value _U_)
1316 void proto_item_prepend_text(proto_item *ti _U_, const char *format _U_, ...)
1319 void proto_item_append_text(proto_item *ti _U_, const char *format _U_, ...)
1322 proto_item *proto_tree_add_uint_format(proto_tree *tree _U_, int hfindex _U_,
1323 tvbuff_t *tvb _U_, gint start _U_,
1324 gint length _U_, guint32 value _U_,
1325 const char *format _U_, ...)
1328 proto_tree* proto_item_add_subtree(proto_item *ti _U_, const gint idx _U_)
1331 proto_item *proto_tree_add_boolean(proto_tree *tree _U_, int hfindex _U_,
1332 tvbuff_t *tvb _U_, gint start _U_,
1333 gint length _U_, guint32 value _U_)
1336 proto_item *proto_tree_add_item(proto_tree *tree _U_, const int hfindex _U_,
1337 tvbuff_t *tvb _U_, const gint start _U_,
1339 const guint encoding _U_)
1342 gint check_col(column_info *cinfo _U_, const gint col _U_)
1345 void col_add_fstr(column_info *cinfo _U_, const gint col _U_, const gchar *format _U_,
1349 const char* proto_registrar_get_name(const int n _U_)
1352 void proto_item_set_text(proto_item *ti _U_, const char *format _U_, ...)