2016-07-15 00:28:41 +00:00
|
|
|
/* reassemble_test.c
|
|
|
|
* Standalone program to test functionality of reassemble.h API
|
2007-02-21 06:19:03 +00:00
|
|
|
*
|
|
|
|
* These aren't particularly complete - they just test a few corners of
|
|
|
|
* functionality which I was interested in. In particular, they only test the
|
|
|
|
* fragment_add_seq_* (ie, FD_BLOCKSEQUENCE) family of routines. However,
|
|
|
|
* hopefully they will inspire people to write additional tests, and provide a
|
|
|
|
* useful basis on which to do so.
|
|
|
|
*
|
2021-02-19 11:51:19 +00:00
|
|
|
* reassemble_test can be run under valgrind to detect any memory leaks in the
|
|
|
|
* Wireshark reassembly code.
|
2010-12-10 15:35:59 +00:00
|
|
|
* Specifically: code has been added to free dynamically allocated memory
|
|
|
|
* after each test (or at program completion) so that valgrind will report
|
|
|
|
* only actual memory leaks.
|
|
|
|
* The following command can be used to run reassemble_test under valgrind:
|
|
|
|
* env \
|
|
|
|
* G_DEBUG=gc-friendly \
|
|
|
|
* G_SLICE=always-malloc \
|
|
|
|
* valgrind --leak-check=full --show-reachable=yes ./reassemble_test
|
|
|
|
*
|
2007-02-21 06:19:03 +00:00
|
|
|
* Copyright (c) 2007 MX Telecom Ltd. <richardv@mxtelecom.com>
|
|
|
|
*
|
|
|
|
* Wireshark - Network traffic analyzer
|
|
|
|
* By Gerald Combs <gerald@wireshark.org>
|
|
|
|
* Copyright 1998
|
|
|
|
*
|
2018-02-08 16:59:17 +00:00
|
|
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
2007-02-21 06:19:03 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include <glib.h>
|
|
|
|
|
2012-09-20 01:48:30 +00:00
|
|
|
#include "config.h"
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
#include <epan/packet.h>
|
|
|
|
#include <epan/packet_info.h>
|
|
|
|
#include <epan/proto.h>
|
|
|
|
#include <epan/tvbuff.h>
|
|
|
|
#include <epan/reassemble.h>
|
|
|
|
|
2020-09-24 14:11:00 +00:00
|
|
|
#include "exceptions.h"
|
|
|
|
|
2010-02-24 08:46:29 +00:00
|
|
|
static int failure = 0;
|
2021-02-19 11:51:19 +00:00
|
|
|
static const gboolean debug = FALSE; /* Set to TRUE to dump tables. */
|
2007-02-21 06:19:03 +00:00
|
|
|
|
2016-07-15 00:28:41 +00:00
|
|
|
#define ASSERT(b) \
|
|
|
|
if (!(b)) { \
|
|
|
|
failure = 1; \
|
|
|
|
printf("Assertion failed at line %i: %s\n", __LINE__, #b); \
|
|
|
|
exit(1); \
|
|
|
|
}
|
2009-09-06 18:25:23 +00:00
|
|
|
|
2016-07-15 00:28:41 +00:00
|
|
|
#define ASSERT_EQ(exp,act) \
|
|
|
|
if ((exp)!=(act)) { \
|
|
|
|
failure = 1; \
|
2016-07-16 02:33:40 +00:00
|
|
|
printf("Assertion failed at line %i: %s==%s (%u==%u)\n", __LINE__, #exp, #act, (guint)exp, (guint)act); \
|
2016-07-15 00:28:41 +00:00
|
|
|
exit(1); \
|
|
|
|
}
|
2010-02-24 08:39:51 +00:00
|
|
|
|
2016-07-15 11:54:10 +00:00
|
|
|
#define ASSERT_EQ_POINTER(exp,act) \
|
|
|
|
if ((exp)!=(act)) { \
|
2016-07-15 00:28:41 +00:00
|
|
|
failure = 1; \
|
reassemble_test: Fix some compiler warnings.
Fix
../epan/reassemble_test.c:394:23: warning: cast from 'const unsigned char *' to 'void *' drops const qualifier [-Wcast-qual]
ASSERT_EQ_POINTER(tvb_get_ptr(fd_head->tvb_data,0,0),tvb_get_ptr(fd->tvb_data,0,0));
^
../epan/reassemble_test.c:394:58: warning: cast from 'const unsigned char *' to 'void *' drops const qualifier [-Wcast-qual]
ASSERT_EQ_POINTER(tvb_get_ptr(fd_head->tvb_data,0,0),tvb_get_ptr(fd->tvb_data,0,0));
^
../epan/reassemble_test.c:429:23: warning: cast from 'const unsigned char *' to 'void *' drops const qualifier [-Wcast-qual]
ASSERT_EQ_POINTER(tvb_get_ptr(fd_head->tvb_data,0,0),tvb_get_ptr(fd->tvb_data,0,0));
^
../epan/reassemble_test.c:429:58: warning: cast from 'const unsigned char *' to 'void *' drops const qualifier [-Wcast-qual]
ASSERT_EQ_POINTER(tvb_get_ptr(fd_head->tvb_data,0,0),tvb_get_ptr(fd->tvb_data,0,0));
Change-Id: I17c4a28b1d2893b1c2acae14dec498baadfd0646
Reviewed-on: https://code.wireshark.org/review/32477
Reviewed-by: Gerald Combs <gerald@wireshark.org>
Petri-Dish: Gerald Combs <gerald@wireshark.org>
Tested-by: Petri Dish Buildbot
Reviewed-by: Anders Broman <a.broman58@gmail.com>
2019-03-19 00:19:20 +00:00
|
|
|
printf("Assertion failed at line %i: %s==%s (%p==%p)\n", __LINE__, #exp, #act, (const void *)exp, (const void *)act); \
|
2016-07-15 00:28:41 +00:00
|
|
|
exit(1); \
|
|
|
|
}
|
2007-02-21 06:19:03 +00:00
|
|
|
|
2016-07-15 11:54:10 +00:00
|
|
|
#define ASSERT_NE_POINTER(exp,act) \
|
|
|
|
if ((exp)==(act)) { \
|
|
|
|
failure = 1; \
|
reassemble_test: Fix some compiler warnings.
Fix
../epan/reassemble_test.c:394:23: warning: cast from 'const unsigned char *' to 'void *' drops const qualifier [-Wcast-qual]
ASSERT_EQ_POINTER(tvb_get_ptr(fd_head->tvb_data,0,0),tvb_get_ptr(fd->tvb_data,0,0));
^
../epan/reassemble_test.c:394:58: warning: cast from 'const unsigned char *' to 'void *' drops const qualifier [-Wcast-qual]
ASSERT_EQ_POINTER(tvb_get_ptr(fd_head->tvb_data,0,0),tvb_get_ptr(fd->tvb_data,0,0));
^
../epan/reassemble_test.c:429:23: warning: cast from 'const unsigned char *' to 'void *' drops const qualifier [-Wcast-qual]
ASSERT_EQ_POINTER(tvb_get_ptr(fd_head->tvb_data,0,0),tvb_get_ptr(fd->tvb_data,0,0));
^
../epan/reassemble_test.c:429:58: warning: cast from 'const unsigned char *' to 'void *' drops const qualifier [-Wcast-qual]
ASSERT_EQ_POINTER(tvb_get_ptr(fd_head->tvb_data,0,0),tvb_get_ptr(fd->tvb_data,0,0));
Change-Id: I17c4a28b1d2893b1c2acae14dec498baadfd0646
Reviewed-on: https://code.wireshark.org/review/32477
Reviewed-by: Gerald Combs <gerald@wireshark.org>
Petri-Dish: Gerald Combs <gerald@wireshark.org>
Tested-by: Petri Dish Buildbot
Reviewed-by: Anders Broman <a.broman58@gmail.com>
2019-03-19 00:19:20 +00:00
|
|
|
printf("Assertion failed at line %i: %s!=%s (%p!=%p)\n", __LINE__, #exp, #act, (const void *)exp, (const void *)act); \
|
2016-07-15 11:54:10 +00:00
|
|
|
exit(1); \
|
|
|
|
}
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
#define DATA_LEN 256
|
|
|
|
|
2020-07-01 08:19:22 +00:00
|
|
|
static guint8 *data;
|
2010-02-24 08:46:29 +00:00
|
|
|
static tvbuff_t *tvb;
|
|
|
|
static packet_info pinfo;
|
2007-02-21 06:19:03 +00:00
|
|
|
|
2014-02-25 20:42:35 +00:00
|
|
|
/* fragment_table maps from datagram ids to fragment_head
|
|
|
|
reassembled_table maps from <packet number,datagram id> to
|
2013-07-17 21:12:24 +00:00
|
|
|
fragment_head */
|
2013-03-23 02:41:43 +00:00
|
|
|
static reassembly_table test_reassembly_table;
|
2010-12-10 15:35:59 +00:00
|
|
|
|
|
|
|
/*************************************************
|
|
|
|
* Util fcns to display
|
|
|
|
* fragment_table & reassembled_table fd-chains
|
|
|
|
************************************************/
|
|
|
|
|
|
|
|
static struct _fd_flags {
|
|
|
|
guint32 flag;
|
|
|
|
gchar *flag_name;
|
|
|
|
} fd_flags[] = {
|
|
|
|
{FD_DEFRAGMENTED ,"DF"},
|
|
|
|
{FD_DATALEN_SET ,"DS"},
|
2021-02-19 11:51:19 +00:00
|
|
|
{FD_SUBSET_TVB ,"ST"},
|
2010-12-10 15:35:59 +00:00
|
|
|
{FD_BLOCKSEQUENCE ,"BS"},
|
|
|
|
{FD_PARTIAL_REASSEMBLY ,"PR"},
|
|
|
|
{FD_OVERLAP ,"OL"},
|
|
|
|
{FD_OVERLAPCONFLICT ,"OC"},
|
|
|
|
{FD_MULTIPLETAILS ,"MT"},
|
|
|
|
{FD_TOOLONGFRAGMENT ,"TL"},
|
|
|
|
};
|
|
|
|
#define N_FD_FLAGS (signed)(sizeof(fd_flags)/sizeof(struct _fd_flags))
|
|
|
|
|
|
|
|
static void
|
2013-07-17 21:12:24 +00:00
|
|
|
print_fd(fragment_head *fd, gboolean is_head) {
|
2010-12-10 15:35:59 +00:00
|
|
|
int i;
|
|
|
|
|
|
|
|
g_assert(fd != NULL);
|
2021-02-19 11:51:19 +00:00
|
|
|
printf(" %16p %16p %3u %3u %3u", fd, fd->next, fd->frame, fd->offset, fd->len);
|
2010-12-10 15:35:59 +00:00
|
|
|
if (is_head) {
|
Fix some cppcheck issues:
- Some redundant assignments or tests.
- Some declarations were changed to match definitions in terms of
including _U_ for the same parameters
- Some parenthesis added/changed to made precedence more obvious
epan/color_filters.c:533: style: Variable 'name' is reassigned a value before the old one has been used.
epan/color_filters.c:534: style: Variable 'filter_exp' is reassigned a value before the old one has been used.
asn1/tcap/packet-tcap-template.c:2199: warning: Function 'dissect_tcap_ITU_ComponentPDU' argument order different: declaration '_U_, tvb, offset, _U_, tree, _U_' definition '_U_, tvb, offset, actx, tree, _U_'
epan/dissectors/packet-aim.c:2546: warning: Function 'dissect_aim_tlv_value_icq' argument order different: declaration 'ti, subtype, tvb, _U_' definition 'ti, _U_, tvb, pinfo'
epan/dissectors/packet-arp.c:1133: style: Clarify calculation precedence for '&' and '?'.
epan/dissectors/packet-arp.c:1143: style: Clarify calculation precedence for '&' and '?'.
epan/dissectors/packet-arp.c:1158: style: Clarify calculation precedence for '&' and '?'.
epan/dissectors/packet-arp.c:1168: style: Clarify calculation precedence for '&' and '?'.
epan/dissectors/packet-gtpv2.c:5997: warning: Function 'dissect_gtpv2_mbms_service_area' argument order different: declaration 'tvb, _U_, tree, _U_, _U_, _U_, _U_, _U_' definition 'tvb, _U_, tree, item, _U_, _U_, _U_, _U_'
epan/dissectors/packet-gtpv2.c:6291: warning: Function 'dissect_gtpv2_mbms_time_to_data_xfer' argument order different: declaration 'tvb, _U_, tree, _U_, _U_, _U_, _U_, _U_' definition 'tvb, _U_, tree, item, _U_, _U_, _U_, _U_'
epan/dissectors/packet-gtpv2.c:6369: warning: Function 'dissect_gtpv2_epc_timer' argument order different: declaration 'tvb, _U_, tree, _U_, _U_, _U_, _U_, _U_' definition 'tvb, _U_, tree, item, _U_, message_type, _U_, _U_'
epan/dissectors/packet-knxip.c:2939: style: Condition 'mac_error' is always false (just added comment)
epan/dissectors/packet-mac-lte.c:4386: style: Clarify calculation precedence for '&' and '?'.
epan/dissectors/packet-nas_5gs.c:1828: style: Variable 'nas5gs_data->payload_container_type' is reassigned a value before the old one has been used. (noted confusing recursion)
epan/dissectors/packet-rpcrdma.c:587: warning: Identical condition 'offset>max_offset', second condition is always false
epan/dissectors/packet-rsl.c:2098: style: Assignment of function parameter has no effect outside the function.
Change-Id: Ib5c9a04cfb6e6233972bc041434601c8ef09c969
Reviewed-on: https://code.wireshark.org/review/37343
Petri-Dish: Martin Mathieson <martin.r.mathieson@googlemail.com>
Tested-by: Petri Dish Buildbot
Reviewed-by: Martin Mathieson <martin.r.mathieson@googlemail.com>
2020-05-31 10:02:09 +00:00
|
|
|
printf(" %3u %3u", fd->datalen, fd->reassembled_in);
|
2010-12-10 15:35:59 +00:00
|
|
|
} else {
|
|
|
|
printf( " ");
|
|
|
|
}
|
2021-02-19 11:51:19 +00:00
|
|
|
if (fd->tvb_data != NULL) {
|
|
|
|
printf(" %16p", tvb_get_ptr(fd->tvb_data, 0, 1)); /* Address of first byte only... */
|
|
|
|
} else {
|
|
|
|
printf(" %16s", "<null tvb_data>");
|
|
|
|
}
|
|
|
|
for (i=0; i < N_FD_FLAGS; i++) {
|
2010-12-10 15:35:59 +00:00
|
|
|
printf(" %s", (fd->flags & fd_flags[i].flag) ? fd_flags[i].flag_name : " ");
|
|
|
|
}
|
|
|
|
printf("\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2013-07-17 21:12:24 +00:00
|
|
|
print_fd_chain(fragment_head *fd_head) {
|
|
|
|
fragment_item *fdp;
|
2010-12-10 15:35:59 +00:00
|
|
|
|
|
|
|
g_assert(fd_head != NULL);
|
|
|
|
print_fd(fd_head, TRUE);
|
|
|
|
for (fdp=fd_head->next; fdp != NULL; fdp=fdp->next) {
|
|
|
|
print_fd(fdp, FALSE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2021-02-19 11:51:19 +00:00
|
|
|
print_fragment_table_chain(gpointer k _U_, gpointer v, gpointer ud _U_) {
|
|
|
|
#ifdef DUMP_KEYS
|
2010-12-10 15:35:59 +00:00
|
|
|
fragment_key *key = (fragment_key*)k;
|
2021-02-19 11:51:19 +00:00
|
|
|
#endif
|
2013-07-17 21:12:24 +00:00
|
|
|
fragment_head *fd_head = (fragment_head *)v;
|
2021-02-19 11:51:19 +00:00
|
|
|
#ifdef DUMP_KEYS
|
2010-12-10 15:35:59 +00:00
|
|
|
printf(" --> FT: %3d 0x%08x 0x%08x\n", key->id, *(guint32 *)(key->src.data), *(guint32 *)(key->dst.data));
|
2021-02-19 11:51:19 +00:00
|
|
|
#endif
|
2010-12-10 15:35:59 +00:00
|
|
|
print_fd_chain(fd_head);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
print_fragment_table(void) {
|
|
|
|
printf("\n Fragment Table -------\n");
|
2021-02-19 11:51:19 +00:00
|
|
|
g_hash_table_foreach(test_reassembly_table.fragment_table, print_fragment_table_chain, NULL);
|
2010-12-10 15:35:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2021-02-19 11:51:19 +00:00
|
|
|
print_reassembled_table_chain(gpointer k _U_, gpointer v, gpointer ud _U_) {
|
|
|
|
#ifdef DUMP_KEYS
|
2010-12-10 15:35:59 +00:00
|
|
|
reassembled_key *key = (reassembled_key*)k;
|
2021-02-19 11:51:19 +00:00
|
|
|
#endif
|
2013-07-17 21:12:24 +00:00
|
|
|
fragment_head *fd_head = (fragment_head *)v;
|
2021-02-19 11:51:19 +00:00
|
|
|
#ifdef DUMP_KEYS
|
2010-12-10 15:35:59 +00:00
|
|
|
printf(" --> RT: %5d %5d\n", key->id, key->frame);
|
2021-02-19 11:51:19 +00:00
|
|
|
#endif
|
2010-12-10 15:35:59 +00:00
|
|
|
print_fd_chain(fd_head);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
print_reassembled_table(void) {
|
|
|
|
printf("\n Reassembled Table ----\n");
|
2013-03-23 02:41:43 +00:00
|
|
|
g_hash_table_foreach(test_reassembly_table.reassembled_table, print_reassembled_table_chain, NULL);
|
2010-12-10 15:35:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
print_tables(void) {
|
|
|
|
print_fragment_table();
|
|
|
|
print_reassembled_table();
|
|
|
|
}
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
/**********************************************************************************
|
|
|
|
*
|
|
|
|
* fragment_add_seq
|
|
|
|
*
|
|
|
|
*********************************************************************************/
|
|
|
|
|
|
|
|
/* Simple test case for fragment_add_seq.
|
|
|
|
* Adds three fragments (out of order, with one for a different datagram in between),
|
|
|
|
* and checks that they are reassembled correctly.
|
|
|
|
*/
|
2010-12-10 15:35:59 +00:00
|
|
|
/* visit id frame frag len more tvb_offset
|
|
|
|
0 12 1 0 50 T 10
|
|
|
|
1 12 1 0 60 T 5
|
|
|
|
0 13 2 0 60 T 15
|
|
|
|
0 12 3 2 60 F 5
|
2020-09-24 14:11:00 +00:00
|
|
|
0 12 4 1 60 T 15
|
2010-12-10 15:35:59 +00:00
|
|
|
*/
|
2009-10-20 15:07:22 +00:00
|
|
|
static void
|
|
|
|
test_simple_fragment_add_seq(void)
|
2007-02-21 06:19:03 +00:00
|
|
|
{
|
2013-07-17 21:12:24 +00:00
|
|
|
fragment_head *fd_head, *fdh0;
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
printf("Starting test test_simple_fragment_add_seq\n");
|
|
|
|
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 1;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
|
|
|
|
0, 50, TRUE, 0);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
2013-03-23 02:41:43 +00:00
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
/* adding the same fragment again should do nothing, even with different
|
|
|
|
* offset etc */
|
2018-12-27 02:26:24 +00:00
|
|
|
pinfo.fd->visited = 1;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
|
|
|
|
0, 60, TRUE, 0);
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
/* start another pdu (just to confuse things) */
|
2018-12-27 02:26:24 +00:00
|
|
|
pinfo.fd->visited = 0;
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 2;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq(&test_reassembly_table, tvb, 15, &pinfo, 13, NULL,
|
|
|
|
0, 60, TRUE, 0);
|
|
|
|
ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
/* now we add the terminal fragment of the first datagram */
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 3;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
|
|
|
|
2, 60, FALSE, 0);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
/* we haven't got all the fragments yet ... */
|
2013-03-23 02:41:43 +00:00
|
|
|
ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
/* finally, add the missing fragment */
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 4;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq(&test_reassembly_table, tvb, 15, &pinfo, 12, NULL,
|
|
|
|
1, 60, TRUE, 0);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
2013-03-23 02:41:43 +00:00
|
|
|
ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_NE_POINTER(NULL,fd_head);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
/* check the contents of the structure */
|
Fragmentation reassembly as in PPP MP (RFC 1990/2686)
Add support for defragmentation of fragments that use the defragmentation
scheme of PPP MP (RFC 1990). Instead of getting "sequence_number,
fragment_number, last" as in other protocols, PPP MP provides a single
sequence number that is effectively "seqnum + fragnum", though it provides
flags for both the first and last fragment of a reassembly.
See Appendix A of RFC 4623 (PWE3 Fragmentation and Reassembly) for a list
of protocols that use this style, including PPP MP (RFC 1990), PWE3 MPLS
(RFC 4385), L2TPv2 (RFC 2661), L2TPv3 (RFC 3931), ATM, and Frame Relay.
Also add support for the Multi-class Extension to Multilink PPP (RFC 2686),
which uses some of the previously reserved bits as classes that distinguish
otherwise identical sequence numbers.
Bug: 12548
Change-Id: Ic2ce3c50e61ab2eb50e4d92fd353ca4d2a48fe18
Reviewed-on: https://code.wireshark.org/review/16327
Reviewed-by: Michael Mann <mmann78@netscape.net>
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
2016-07-07 22:24:43 +00:00
|
|
|
ASSERT_EQ(4,fd_head->frame); /* max frame number of fragment in assembly */
|
2007-02-21 06:19:03 +00:00
|
|
|
ASSERT_EQ(0,fd_head->offset); /* unused */
|
|
|
|
ASSERT_EQ(170,fd_head->len); /* the length of data we have */
|
|
|
|
ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
|
|
|
|
ASSERT_EQ(4,fd_head->reassembled_in);
|
|
|
|
ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
ASSERT_EQ(1,fd_head->next->frame);
|
|
|
|
ASSERT_EQ(0,fd_head->next->offset); /* seqno */
|
|
|
|
ASSERT_EQ(50,fd_head->next->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd_head->next->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next->next);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
ASSERT_EQ(4,fd_head->next->next->frame);
|
|
|
|
ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
|
|
|
|
ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd_head->next->next->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next->next->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next->next->next);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
ASSERT_EQ(3,fd_head->next->next->next->frame);
|
|
|
|
ASSERT_EQ(2,fd_head->next->next->next->offset); /* seqno */
|
|
|
|
ASSERT_EQ(60,fd_head->next->next->next->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd_head->next->next->next->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->tvb_data);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->next);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
/* test the actual reassembly */
|
2013-07-14 14:42:05 +00:00
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+15,60));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,60));
|
2007-02-21 06:19:03 +00:00
|
|
|
|
2021-02-19 11:51:19 +00:00
|
|
|
if (debug) {
|
|
|
|
print_fragment_table();
|
|
|
|
}
|
2010-12-10 15:35:59 +00:00
|
|
|
|
2007-02-21 06:19:03 +00:00
|
|
|
/* what happens if we revisit the packets now? */
|
|
|
|
fdh0 = fd_head;
|
2018-12-27 02:26:24 +00:00
|
|
|
pinfo.fd->visited = 1;
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 1;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
|
|
|
|
0, 50, TRUE, 0);
|
2007-02-21 06:19:03 +00:00
|
|
|
/*
|
|
|
|
* this api relies on the caller to check fd_head -> reassembled_in
|
|
|
|
*
|
|
|
|
* Redoing all the tests seems like overkill - just check the pointer
|
|
|
|
*/
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(fdh0,fd_head);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 3;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
|
|
|
|
2, 60, FALSE, 0);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(fdh0,fd_head);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 4;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq(&test_reassembly_table, tvb, 15, &pinfo, 12, NULL,
|
|
|
|
1, 60, TRUE, 0);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(fdh0,fd_head);
|
2010-12-10 15:35:59 +00:00
|
|
|
|
2021-02-19 11:51:19 +00:00
|
|
|
if (debug) {
|
|
|
|
print_fragment_table();
|
|
|
|
}
|
2007-02-21 06:19:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* XXX ought to have some tests for overlapping fragments */
|
|
|
|
|
|
|
|
/* This tests the functionality of fragment_set_partial_reassembly for
|
|
|
|
* FD_BLOCKSEQUENCE reassembly.
|
|
|
|
*
|
|
|
|
* We add a sequence of fragments thus:
|
|
|
|
* seqno frame offset len (initial) more_frags
|
|
|
|
* ----- ----- ------ --- --------------------
|
|
|
|
* 0 1 10 50 false
|
|
|
|
* 1 2 0 40 true
|
|
|
|
* 1 3 0 40 true (a duplicate fragment)
|
|
|
|
* 2 4 20 100 false
|
|
|
|
* 3 5 0 40 false
|
|
|
|
*/
|
2009-10-20 15:07:22 +00:00
|
|
|
static void
|
|
|
|
test_fragment_add_seq_partial_reassembly(void)
|
2007-02-21 06:19:03 +00:00
|
|
|
{
|
2013-07-17 21:12:24 +00:00
|
|
|
fragment_head *fd_head;
|
|
|
|
fragment_item *fd;
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
printf("Starting test test_fragment_add_seq_partial_reassembly\n");
|
|
|
|
|
|
|
|
/* generally it's probably fair to assume that we will be called with
|
|
|
|
* more_frags=FALSE.
|
|
|
|
*/
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 1;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
|
|
|
|
0, 50, FALSE, 0);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
2013-03-23 02:41:43 +00:00
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_NE_POINTER(NULL,fd_head);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
/* check the contents of the structure */
|
Fragmentation reassembly as in PPP MP (RFC 1990/2686)
Add support for defragmentation of fragments that use the defragmentation
scheme of PPP MP (RFC 1990). Instead of getting "sequence_number,
fragment_number, last" as in other protocols, PPP MP provides a single
sequence number that is effectively "seqnum + fragnum", though it provides
flags for both the first and last fragment of a reassembly.
See Appendix A of RFC 4623 (PWE3 Fragmentation and Reassembly) for a list
of protocols that use this style, including PPP MP (RFC 1990), PWE3 MPLS
(RFC 4385), L2TPv2 (RFC 2661), L2TPv3 (RFC 3931), ATM, and Frame Relay.
Also add support for the Multi-class Extension to Multilink PPP (RFC 2686),
which uses some of the previously reserved bits as classes that distinguish
otherwise identical sequence numbers.
Bug: 12548
Change-Id: Ic2ce3c50e61ab2eb50e4d92fd353ca4d2a48fe18
Reviewed-on: https://code.wireshark.org/review/16327
Reviewed-by: Michael Mann <mmann78@netscape.net>
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
2016-07-07 22:24:43 +00:00
|
|
|
ASSERT_EQ(1,fd_head->frame); /* max frame in reassembly */
|
2007-02-21 06:19:03 +00:00
|
|
|
ASSERT_EQ(0,fd_head->offset); /* unused */
|
|
|
|
ASSERT_EQ(50,fd_head->len); /* the length of data we have */
|
|
|
|
ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
|
|
|
|
ASSERT_EQ(1,fd_head->reassembled_in);
|
|
|
|
ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
ASSERT_EQ(1,fd_head->next->frame);
|
|
|
|
ASSERT_EQ(0,fd_head->next->offset); /* seqno */
|
|
|
|
ASSERT_EQ(50,fd_head->next->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd_head->next->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next->tvb_data);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next->next);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
/* test the actual reassembly */
|
2013-07-14 14:42:05 +00:00
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
/* now we announce that the reassembly wasn't complete after all. */
|
2013-03-23 02:41:43 +00:00
|
|
|
fragment_set_partial_reassembly(&test_reassembly_table, &pinfo, 12, NULL);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
/* and add another segment. To mix things up slightly (and so that we can
|
|
|
|
* check on the state of things), we're going to set the more_frags flag
|
|
|
|
* here
|
|
|
|
*/
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 2;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
|
|
|
|
1, 40, TRUE, 0);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
2013-03-23 02:41:43 +00:00
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_get(&test_reassembly_table, &pinfo, 12, NULL);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_NE_POINTER(NULL,fd_head);
|
2009-09-06 18:25:23 +00:00
|
|
|
|
2007-02-21 06:19:03 +00:00
|
|
|
/* check the contents of the structure */
|
Fragmentation reassembly as in PPP MP (RFC 1990/2686)
Add support for defragmentation of fragments that use the defragmentation
scheme of PPP MP (RFC 1990). Instead of getting "sequence_number,
fragment_number, last" as in other protocols, PPP MP provides a single
sequence number that is effectively "seqnum + fragnum", though it provides
flags for both the first and last fragment of a reassembly.
See Appendix A of RFC 4623 (PWE3 Fragmentation and Reassembly) for a list
of protocols that use this style, including PPP MP (RFC 1990), PWE3 MPLS
(RFC 4385), L2TPv2 (RFC 2661), L2TPv3 (RFC 3931), ATM, and Frame Relay.
Also add support for the Multi-class Extension to Multilink PPP (RFC 2686),
which uses some of the previously reserved bits as classes that distinguish
otherwise identical sequence numbers.
Bug: 12548
Change-Id: Ic2ce3c50e61ab2eb50e4d92fd353ca4d2a48fe18
Reviewed-on: https://code.wireshark.org/review/16327
Reviewed-by: Michael Mann <mmann78@netscape.net>
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
2016-07-07 22:24:43 +00:00
|
|
|
ASSERT_EQ(2,fd_head->frame); /* max frame in reassembly */
|
2007-02-21 06:19:03 +00:00
|
|
|
ASSERT_EQ(0,fd_head->offset); /* unused */
|
|
|
|
/* ASSERT_EQ(50,fd_head->len); the length of data we have */
|
|
|
|
ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
|
|
|
|
ASSERT_EQ(0,fd_head->reassembled_in);
|
|
|
|
ASSERT_EQ(FD_BLOCKSEQUENCE,fd_head->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
fd=fd_head->next;
|
|
|
|
ASSERT_EQ(1,fd->frame);
|
|
|
|
ASSERT_EQ(0,fd->offset); /* seqno */
|
|
|
|
ASSERT_EQ(50,fd->len); /* segment length */
|
2013-07-14 14:42:05 +00:00
|
|
|
ASSERT_EQ(FD_SUBSET_TVB,fd->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(tvb_get_ptr(fd_head->tvb_data,0,0),tvb_get_ptr(fd->tvb_data,0,0));
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
fd=fd->next;
|
|
|
|
ASSERT_EQ(2,fd->frame);
|
|
|
|
ASSERT_EQ(1,fd->offset); /* seqno */
|
|
|
|
ASSERT_EQ(40,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_NE_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->next);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
/* Another copy of the second segment.
|
|
|
|
*/
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 3;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
|
|
|
|
1, 40, TRUE, 0);
|
2009-09-06 18:25:23 +00:00
|
|
|
|
2013-03-23 02:41:43 +00:00
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_get(&test_reassembly_table, &pinfo, 12, NULL);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_NE_POINTER(NULL,fd_head);
|
Fragmentation reassembly as in PPP MP (RFC 1990/2686)
Add support for defragmentation of fragments that use the defragmentation
scheme of PPP MP (RFC 1990). Instead of getting "sequence_number,
fragment_number, last" as in other protocols, PPP MP provides a single
sequence number that is effectively "seqnum + fragnum", though it provides
flags for both the first and last fragment of a reassembly.
See Appendix A of RFC 4623 (PWE3 Fragmentation and Reassembly) for a list
of protocols that use this style, including PPP MP (RFC 1990), PWE3 MPLS
(RFC 4385), L2TPv2 (RFC 2661), L2TPv3 (RFC 3931), ATM, and Frame Relay.
Also add support for the Multi-class Extension to Multilink PPP (RFC 2686),
which uses some of the previously reserved bits as classes that distinguish
otherwise identical sequence numbers.
Bug: 12548
Change-Id: Ic2ce3c50e61ab2eb50e4d92fd353ca4d2a48fe18
Reviewed-on: https://code.wireshark.org/review/16327
Reviewed-by: Michael Mann <mmann78@netscape.net>
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
2016-07-07 22:24:43 +00:00
|
|
|
ASSERT_EQ(3,fd_head->frame); /* max frame we have */
|
2007-02-21 06:19:03 +00:00
|
|
|
ASSERT_EQ(0,fd_head->offset); /* unused */
|
|
|
|
/* ASSERT_EQ(50,fd_head->len); the length of data we have */
|
|
|
|
ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
|
|
|
|
ASSERT_EQ(0,fd_head->reassembled_in);
|
|
|
|
ASSERT_EQ(FD_BLOCKSEQUENCE,fd_head->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
fd=fd_head->next;
|
|
|
|
ASSERT_EQ(1,fd->frame);
|
|
|
|
ASSERT_EQ(0,fd->offset); /* seqno */
|
|
|
|
ASSERT_EQ(50,fd->len); /* segment length */
|
2013-07-14 14:42:05 +00:00
|
|
|
ASSERT_EQ(FD_SUBSET_TVB,fd->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(tvb_get_ptr(fd_head->tvb_data,0,0),tvb_get_ptr(fd->tvb_data,0,0));
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
fd=fd->next;
|
|
|
|
ASSERT_EQ(2,fd->frame);
|
|
|
|
ASSERT_EQ(1,fd->offset); /* seqno */
|
|
|
|
ASSERT_EQ(40,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_NE_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
fd=fd->next;
|
|
|
|
ASSERT_EQ(3,fd->frame);
|
|
|
|
ASSERT_EQ(1,fd->offset); /* seqno */
|
|
|
|
ASSERT_EQ(40,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_NE_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->next);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
2009-09-06 18:25:23 +00:00
|
|
|
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
/* have another go at wrapping things up */
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 4;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq(&test_reassembly_table, tvb, 20, &pinfo, 12, NULL,
|
|
|
|
2, 100, FALSE, 0);
|
2009-09-06 18:25:23 +00:00
|
|
|
|
2013-03-23 02:41:43 +00:00
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_NE_POINTER(NULL,fd_head);
|
2009-09-06 18:25:23 +00:00
|
|
|
|
2007-02-21 06:19:03 +00:00
|
|
|
/* check the contents of the structure */
|
Fragmentation reassembly as in PPP MP (RFC 1990/2686)
Add support for defragmentation of fragments that use the defragmentation
scheme of PPP MP (RFC 1990). Instead of getting "sequence_number,
fragment_number, last" as in other protocols, PPP MP provides a single
sequence number that is effectively "seqnum + fragnum", though it provides
flags for both the first and last fragment of a reassembly.
See Appendix A of RFC 4623 (PWE3 Fragmentation and Reassembly) for a list
of protocols that use this style, including PPP MP (RFC 1990), PWE3 MPLS
(RFC 4385), L2TPv2 (RFC 2661), L2TPv3 (RFC 3931), ATM, and Frame Relay.
Also add support for the Multi-class Extension to Multilink PPP (RFC 2686),
which uses some of the previously reserved bits as classes that distinguish
otherwise identical sequence numbers.
Bug: 12548
Change-Id: Ic2ce3c50e61ab2eb50e4d92fd353ca4d2a48fe18
Reviewed-on: https://code.wireshark.org/review/16327
Reviewed-by: Michael Mann <mmann78@netscape.net>
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
2016-07-07 22:24:43 +00:00
|
|
|
ASSERT_EQ(4,fd_head->frame); /* max frame we have */
|
2007-02-21 06:19:03 +00:00
|
|
|
ASSERT_EQ(0,fd_head->offset); /* unused */
|
|
|
|
ASSERT_EQ(190,fd_head->len); /* the length of data we have */
|
|
|
|
ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
|
|
|
|
ASSERT_EQ(4,fd_head->reassembled_in);
|
|
|
|
ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
fd=fd_head->next;
|
|
|
|
ASSERT_EQ(1,fd->frame);
|
|
|
|
ASSERT_EQ(0,fd->offset); /* seqno */
|
|
|
|
ASSERT_EQ(50,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
fd=fd->next;
|
|
|
|
ASSERT_EQ(2,fd->frame);
|
|
|
|
ASSERT_EQ(1,fd->offset); /* seqno */
|
|
|
|
ASSERT_EQ(40,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
2009-09-06 18:25:23 +00:00
|
|
|
|
2007-02-21 06:19:03 +00:00
|
|
|
fd=fd->next;
|
|
|
|
ASSERT_EQ(3,fd->frame);
|
|
|
|
ASSERT_EQ(1,fd->offset); /* seqno */
|
|
|
|
ASSERT_EQ(40,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(FD_OVERLAP,fd->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
fd=fd->next;
|
|
|
|
ASSERT_EQ(4,fd->frame);
|
|
|
|
ASSERT_EQ(2,fd->offset); /* seqno */
|
|
|
|
ASSERT_EQ(100,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->next);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
/* test the actual reassembly */
|
2013-07-14 14:42:05 +00:00
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,50,data,40));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,90,data+20,100));
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
/* do it again (this time it is more complicated, with an overlap in the
|
|
|
|
* reassembly) */
|
|
|
|
|
2013-03-23 02:41:43 +00:00
|
|
|
fragment_set_partial_reassembly(&test_reassembly_table, &pinfo, 12, NULL);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 5;
|
2018-05-16 06:23:55 +00:00
|
|
|
fragment_add_seq(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
|
2013-03-23 02:41:43 +00:00
|
|
|
3, 40, FALSE, 0);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_get(&test_reassembly_table, &pinfo, 12, NULL);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_NE_POINTER(NULL,fd_head);
|
Fragmentation reassembly as in PPP MP (RFC 1990/2686)
Add support for defragmentation of fragments that use the defragmentation
scheme of PPP MP (RFC 1990). Instead of getting "sequence_number,
fragment_number, last" as in other protocols, PPP MP provides a single
sequence number that is effectively "seqnum + fragnum", though it provides
flags for both the first and last fragment of a reassembly.
See Appendix A of RFC 4623 (PWE3 Fragmentation and Reassembly) for a list
of protocols that use this style, including PPP MP (RFC 1990), PWE3 MPLS
(RFC 4385), L2TPv2 (RFC 2661), L2TPv3 (RFC 3931), ATM, and Frame Relay.
Also add support for the Multi-class Extension to Multilink PPP (RFC 2686),
which uses some of the previously reserved bits as classes that distinguish
otherwise identical sequence numbers.
Bug: 12548
Change-Id: Ic2ce3c50e61ab2eb50e4d92fd353ca4d2a48fe18
Reviewed-on: https://code.wireshark.org/review/16327
Reviewed-by: Michael Mann <mmann78@netscape.net>
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
2016-07-07 22:24:43 +00:00
|
|
|
ASSERT_EQ(5,fd_head->frame); /* max frame we have */
|
2007-02-21 06:19:03 +00:00
|
|
|
ASSERT_EQ(0,fd_head->offset); /* unused */
|
|
|
|
ASSERT_EQ(230,fd_head->len); /* the length of data we have */
|
|
|
|
ASSERT_EQ(3,fd_head->datalen); /* seqno of the last fragment we have */
|
|
|
|
ASSERT_EQ(5,fd_head->reassembled_in);
|
|
|
|
ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
fd=fd_head->next;
|
|
|
|
ASSERT_EQ(1,fd->frame);
|
|
|
|
ASSERT_EQ(0,fd->offset); /* seqno */
|
|
|
|
ASSERT_EQ(50,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
fd=fd->next;
|
|
|
|
ASSERT_EQ(2,fd->frame);
|
|
|
|
ASSERT_EQ(1,fd->offset); /* seqno */
|
|
|
|
ASSERT_EQ(40,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
fd=fd->next;
|
|
|
|
ASSERT_EQ(3,fd->frame);
|
|
|
|
ASSERT_EQ(1,fd->offset); /* seqno */
|
|
|
|
ASSERT_EQ(40,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(FD_OVERLAP,fd->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
fd=fd->next;
|
|
|
|
ASSERT_EQ(4,fd->frame);
|
|
|
|
ASSERT_EQ(2,fd->offset); /* seqno */
|
|
|
|
ASSERT_EQ(100,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
fd=fd->next;
|
|
|
|
ASSERT_EQ(5,fd->frame);
|
|
|
|
ASSERT_EQ(3,fd->offset); /* seqno */
|
|
|
|
ASSERT_EQ(40,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->next);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
/* test the actual reassembly */
|
2013-07-14 14:42:05 +00:00
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,50,data,40));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,90,data+20,100));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,190,data,40));
|
2007-02-21 06:19:03 +00:00
|
|
|
}
|
|
|
|
|
2011-03-03 23:28:32 +00:00
|
|
|
/* Test case for fragment_add_seq with duplicated (e.g., retransmitted) data.
|
|
|
|
* Adds three fragments--adding the 1st one twice--
|
|
|
|
* and checks that they are reassembled correctly.
|
|
|
|
*/
|
|
|
|
/* visit id frame frag len more tvb_offset
|
|
|
|
0 12 1 0 50 T 10
|
|
|
|
0 12 2 1 60 T 5
|
|
|
|
0 12 3 2 40 F 5
|
|
|
|
0 12 4 0 50 T 10
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
test_fragment_add_seq_duplicate_first(void)
|
|
|
|
{
|
2013-07-17 21:12:24 +00:00
|
|
|
fragment_head *fd_head;
|
2011-03-03 23:28:32 +00:00
|
|
|
|
|
|
|
printf("Starting test test_fragment_add_seq_duplicate_first\n");
|
|
|
|
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 1;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
|
|
|
|
0, 50, TRUE, 0);
|
2011-03-03 23:28:32 +00:00
|
|
|
|
2013-03-23 02:41:43 +00:00
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
2011-03-03 23:28:32 +00:00
|
|
|
|
|
|
|
/* Add the 2nd segment */
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 2;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
|
|
|
|
1, 60, TRUE, 0);
|
2011-03-03 23:28:32 +00:00
|
|
|
|
|
|
|
/* we haven't got all the fragments yet ... */
|
2013-03-23 02:41:43 +00:00
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
2011-03-03 23:28:32 +00:00
|
|
|
|
|
|
|
/* Add the last fragment */
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 3;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
|
|
|
|
2, 40, FALSE, 0);
|
2011-03-03 23:28:32 +00:00
|
|
|
|
2013-03-23 02:41:43 +00:00
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_NE_POINTER(NULL,fd_head);
|
2011-03-03 23:28:32 +00:00
|
|
|
|
|
|
|
/* Add the first fragment again */
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 4;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
|
|
|
|
0, 50, TRUE, 0);
|
2011-03-03 23:28:32 +00:00
|
|
|
|
|
|
|
/* Reassembly should have still succeeded */
|
2013-03-23 02:41:43 +00:00
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_NE_POINTER(NULL,fd_head);
|
2011-03-03 23:28:32 +00:00
|
|
|
|
|
|
|
/* check the contents of the structure */
|
Fragmentation reassembly as in PPP MP (RFC 1990/2686)
Add support for defragmentation of fragments that use the defragmentation
scheme of PPP MP (RFC 1990). Instead of getting "sequence_number,
fragment_number, last" as in other protocols, PPP MP provides a single
sequence number that is effectively "seqnum + fragnum", though it provides
flags for both the first and last fragment of a reassembly.
See Appendix A of RFC 4623 (PWE3 Fragmentation and Reassembly) for a list
of protocols that use this style, including PPP MP (RFC 1990), PWE3 MPLS
(RFC 4385), L2TPv2 (RFC 2661), L2TPv3 (RFC 3931), ATM, and Frame Relay.
Also add support for the Multi-class Extension to Multilink PPP (RFC 2686),
which uses some of the previously reserved bits as classes that distinguish
otherwise identical sequence numbers.
Bug: 12548
Change-Id: Ic2ce3c50e61ab2eb50e4d92fd353ca4d2a48fe18
Reviewed-on: https://code.wireshark.org/review/16327
Reviewed-by: Michael Mann <mmann78@netscape.net>
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
2016-07-07 22:24:43 +00:00
|
|
|
ASSERT_EQ(4,fd_head->frame); /* max frame we have */
|
2011-03-03 23:28:32 +00:00
|
|
|
ASSERT_EQ(0,fd_head->offset); /* unused */
|
|
|
|
ASSERT_EQ(150,fd_head->len); /* the length of data we have */
|
|
|
|
ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
|
|
|
|
ASSERT_EQ(3,fd_head->reassembled_in);
|
|
|
|
ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next);
|
2011-03-03 23:28:32 +00:00
|
|
|
|
|
|
|
ASSERT_EQ(1,fd_head->next->frame);
|
|
|
|
ASSERT_EQ(0,fd_head->next->offset); /* seqno */
|
|
|
|
ASSERT_EQ(50,fd_head->next->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd_head->next->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next->next);
|
2011-03-03 23:28:32 +00:00
|
|
|
|
|
|
|
ASSERT_EQ(4,fd_head->next->next->frame);
|
|
|
|
ASSERT_EQ(0,fd_head->next->next->offset); /* seqno */
|
|
|
|
ASSERT_EQ(50,fd_head->next->next->len); /* segment length */
|
|
|
|
ASSERT_EQ(FD_OVERLAP,fd_head->next->next->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next->next->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next->next->next);
|
2011-03-03 23:28:32 +00:00
|
|
|
|
|
|
|
ASSERT_EQ(2,fd_head->next->next->next->frame);
|
|
|
|
ASSERT_EQ(1,fd_head->next->next->next->offset); /* seqno */
|
|
|
|
ASSERT_EQ(60,fd_head->next->next->next->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd_head->next->next->next->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next->next->next->next);
|
2011-03-03 23:28:32 +00:00
|
|
|
|
|
|
|
ASSERT_EQ(3,fd_head->next->next->next->next->frame);
|
|
|
|
ASSERT_EQ(2,fd_head->next->next->next->next->offset); /* seqno */
|
|
|
|
ASSERT_EQ(40,fd_head->next->next->next->next->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd_head->next->next->next->next->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->next->tvb_data);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->next->next);
|
2011-03-03 23:28:32 +00:00
|
|
|
|
|
|
|
/* test the actual reassembly */
|
2013-07-14 14:42:05 +00:00
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
|
2011-03-03 23:28:32 +00:00
|
|
|
|
2021-02-19 11:51:19 +00:00
|
|
|
if (debug) {
|
|
|
|
print_fragment_table();
|
|
|
|
}
|
2011-03-03 23:28:32 +00:00
|
|
|
}
|
|
|
|
|
2011-03-03 20:22:45 +00:00
|
|
|
|
|
|
|
/* Test case for fragment_add_seq with duplicated (e.g., retransmitted) data.
|
|
|
|
* Adds three fragments--adding the 2nd one twice--
|
|
|
|
* and checks that they are reassembled correctly.
|
|
|
|
*/
|
|
|
|
/* visit id frame frag len more tvb_offset
|
|
|
|
0 12 1 0 50 T 10
|
2011-03-03 23:28:32 +00:00
|
|
|
0 12 2 1 60 T 5
|
|
|
|
0 12 3 1 60 T 5
|
|
|
|
0 12 4 3 40 F 5
|
2011-03-03 20:22:45 +00:00
|
|
|
*/
|
|
|
|
static void
|
2011-03-03 23:28:32 +00:00
|
|
|
test_fragment_add_seq_duplicate_middle(void)
|
2011-03-03 20:22:45 +00:00
|
|
|
{
|
2013-07-17 21:12:24 +00:00
|
|
|
fragment_head *fd_head;
|
2011-03-03 20:22:45 +00:00
|
|
|
|
2011-03-03 23:28:32 +00:00
|
|
|
printf("Starting test test_fragment_add_seq_duplicate_middle\n");
|
2011-03-03 20:22:45 +00:00
|
|
|
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 1;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
|
|
|
|
0, 50, TRUE, 0);
|
2011-03-03 20:22:45 +00:00
|
|
|
|
2013-03-23 02:41:43 +00:00
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
2011-03-03 20:22:45 +00:00
|
|
|
|
|
|
|
/* Add the 2nd segment */
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 2;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
|
|
|
|
1, 60, TRUE, 0);
|
2011-03-03 20:22:45 +00:00
|
|
|
|
|
|
|
/* we haven't got all the fragments yet ... */
|
2013-03-23 02:41:43 +00:00
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
2011-03-03 20:22:45 +00:00
|
|
|
|
|
|
|
/* Now, add the 2nd segment again (but in a different frame) */
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 3;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
|
|
|
|
1, 60, TRUE, 0);
|
2011-03-03 20:22:45 +00:00
|
|
|
|
|
|
|
/* This duplicate fragment should have been ignored */
|
2013-03-23 02:41:43 +00:00
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
2011-03-03 20:22:45 +00:00
|
|
|
|
|
|
|
/* finally, add the last fragment */
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 4;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
|
|
|
|
2, 40, FALSE, 0);
|
2011-03-03 20:22:45 +00:00
|
|
|
|
2013-03-23 02:41:43 +00:00
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_NE_POINTER(NULL,fd_head);
|
2011-03-03 20:22:45 +00:00
|
|
|
|
|
|
|
/* check the contents of the structure */
|
Fragmentation reassembly as in PPP MP (RFC 1990/2686)
Add support for defragmentation of fragments that use the defragmentation
scheme of PPP MP (RFC 1990). Instead of getting "sequence_number,
fragment_number, last" as in other protocols, PPP MP provides a single
sequence number that is effectively "seqnum + fragnum", though it provides
flags for both the first and last fragment of a reassembly.
See Appendix A of RFC 4623 (PWE3 Fragmentation and Reassembly) for a list
of protocols that use this style, including PPP MP (RFC 1990), PWE3 MPLS
(RFC 4385), L2TPv2 (RFC 2661), L2TPv3 (RFC 3931), ATM, and Frame Relay.
Also add support for the Multi-class Extension to Multilink PPP (RFC 2686),
which uses some of the previously reserved bits as classes that distinguish
otherwise identical sequence numbers.
Bug: 12548
Change-Id: Ic2ce3c50e61ab2eb50e4d92fd353ca4d2a48fe18
Reviewed-on: https://code.wireshark.org/review/16327
Reviewed-by: Michael Mann <mmann78@netscape.net>
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
2016-07-07 22:24:43 +00:00
|
|
|
ASSERT_EQ(4,fd_head->frame); /* max frame we have */
|
2011-03-03 20:22:45 +00:00
|
|
|
ASSERT_EQ(0,fd_head->offset); /* unused */
|
|
|
|
ASSERT_EQ(150,fd_head->len); /* the length of data we have */
|
|
|
|
ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
|
|
|
|
ASSERT_EQ(4,fd_head->reassembled_in);
|
|
|
|
ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next);
|
2011-03-03 20:22:45 +00:00
|
|
|
|
|
|
|
ASSERT_EQ(1,fd_head->next->frame);
|
|
|
|
ASSERT_EQ(0,fd_head->next->offset); /* seqno */
|
|
|
|
ASSERT_EQ(50,fd_head->next->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd_head->next->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next->next);
|
2011-03-03 20:22:45 +00:00
|
|
|
|
|
|
|
ASSERT_EQ(2,fd_head->next->next->frame);
|
|
|
|
ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
|
|
|
|
ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd_head->next->next->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next->next->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next->next->next);
|
2011-03-03 20:22:45 +00:00
|
|
|
|
|
|
|
ASSERT_EQ(3,fd_head->next->next->next->frame);
|
|
|
|
ASSERT_EQ(1,fd_head->next->next->next->offset); /* seqno */
|
|
|
|
ASSERT_EQ(60,fd_head->next->next->next->len); /* segment length */
|
|
|
|
ASSERT_EQ(FD_OVERLAP,fd_head->next->next->next->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next->next->next->next);
|
2011-03-03 20:22:45 +00:00
|
|
|
|
|
|
|
ASSERT_EQ(4,fd_head->next->next->next->next->frame);
|
|
|
|
ASSERT_EQ(2,fd_head->next->next->next->next->offset); /* seqno */
|
|
|
|
ASSERT_EQ(40,fd_head->next->next->next->next->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd_head->next->next->next->next->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->next->tvb_data);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->next->next);
|
2011-03-03 20:22:45 +00:00
|
|
|
|
|
|
|
/* test the actual reassembly */
|
2013-07-14 14:42:05 +00:00
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
|
2011-03-03 23:28:32 +00:00
|
|
|
|
2021-02-19 11:51:19 +00:00
|
|
|
if (debug) {
|
|
|
|
print_fragment_table();
|
|
|
|
}
|
2011-03-03 23:28:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Test case for fragment_add_seq with duplicated (e.g., retransmitted) data.
|
|
|
|
* Adds three fragments--adding the 3rd one twice--
|
|
|
|
* and checks that they are reassembled correctly.
|
|
|
|
*/
|
|
|
|
/* visit id frame frag len more tvb_offset
|
|
|
|
0 12 1 0 50 T 10
|
|
|
|
0 12 2 1 60 T 5
|
|
|
|
0 12 3 2 40 F 5
|
|
|
|
0 12 4 2 40 F 5
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
test_fragment_add_seq_duplicate_last(void)
|
|
|
|
{
|
2013-07-17 21:12:24 +00:00
|
|
|
fragment_head *fd_head;
|
2011-03-03 23:28:32 +00:00
|
|
|
|
|
|
|
printf("Starting test test_fragment_add_seq_duplicate_last\n");
|
|
|
|
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 1;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
|
|
|
|
0, 50, TRUE, 0);
|
2011-03-03 23:28:32 +00:00
|
|
|
|
2013-03-23 02:41:43 +00:00
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
2011-03-03 23:28:32 +00:00
|
|
|
|
|
|
|
/* Add the 2nd segment */
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 2;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
|
|
|
|
1, 60, TRUE, 0);
|
2011-03-03 23:28:32 +00:00
|
|
|
|
|
|
|
/* we haven't got all the fragments yet ... */
|
2013-03-23 02:41:43 +00:00
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
2011-03-03 23:28:32 +00:00
|
|
|
|
|
|
|
/* Add the last fragment */
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 3;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
|
|
|
|
2, 40, FALSE, 0);
|
2011-03-03 23:28:32 +00:00
|
|
|
|
2013-03-23 02:41:43 +00:00
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_NE_POINTER(NULL,fd_head);
|
2011-03-03 23:28:32 +00:00
|
|
|
|
|
|
|
/* Add the last fragment again */
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 4;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
|
|
|
|
2, 40, FALSE, 0);
|
2011-03-03 23:28:32 +00:00
|
|
|
|
|
|
|
/* Reassembly should have still succeeded */
|
2013-03-23 02:41:43 +00:00
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_NE_POINTER(NULL,fd_head);
|
2011-03-03 23:28:32 +00:00
|
|
|
|
|
|
|
/* check the contents of the structure */
|
Fragmentation reassembly as in PPP MP (RFC 1990/2686)
Add support for defragmentation of fragments that use the defragmentation
scheme of PPP MP (RFC 1990). Instead of getting "sequence_number,
fragment_number, last" as in other protocols, PPP MP provides a single
sequence number that is effectively "seqnum + fragnum", though it provides
flags for both the first and last fragment of a reassembly.
See Appendix A of RFC 4623 (PWE3 Fragmentation and Reassembly) for a list
of protocols that use this style, including PPP MP (RFC 1990), PWE3 MPLS
(RFC 4385), L2TPv2 (RFC 2661), L2TPv3 (RFC 3931), ATM, and Frame Relay.
Also add support for the Multi-class Extension to Multilink PPP (RFC 2686),
which uses some of the previously reserved bits as classes that distinguish
otherwise identical sequence numbers.
Bug: 12548
Change-Id: Ic2ce3c50e61ab2eb50e4d92fd353ca4d2a48fe18
Reviewed-on: https://code.wireshark.org/review/16327
Reviewed-by: Michael Mann <mmann78@netscape.net>
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
2016-07-07 22:24:43 +00:00
|
|
|
ASSERT_EQ(4,fd_head->frame); /* max frame we have */
|
2011-03-03 23:28:32 +00:00
|
|
|
ASSERT_EQ(0,fd_head->offset); /* unused */
|
|
|
|
ASSERT_EQ(150,fd_head->len); /* the length of data we have */
|
|
|
|
ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
|
|
|
|
ASSERT_EQ(3,fd_head->reassembled_in);
|
|
|
|
ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next);
|
2011-03-03 23:28:32 +00:00
|
|
|
|
|
|
|
ASSERT_EQ(1,fd_head->next->frame);
|
|
|
|
ASSERT_EQ(0,fd_head->next->offset); /* seqno */
|
|
|
|
ASSERT_EQ(50,fd_head->next->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd_head->next->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next->next);
|
2011-03-03 23:28:32 +00:00
|
|
|
|
|
|
|
ASSERT_EQ(2,fd_head->next->next->frame);
|
|
|
|
ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
|
|
|
|
ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd_head->next->next->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next->next->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next->next->next);
|
2011-03-03 23:28:32 +00:00
|
|
|
|
|
|
|
ASSERT_EQ(3,fd_head->next->next->next->frame);
|
|
|
|
ASSERT_EQ(2,fd_head->next->next->next->offset); /* seqno */
|
|
|
|
ASSERT_EQ(40,fd_head->next->next->next->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd_head->next->next->next->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next->next->next->next);
|
2011-03-03 23:28:32 +00:00
|
|
|
|
|
|
|
ASSERT_EQ(4,fd_head->next->next->next->next->frame);
|
|
|
|
ASSERT_EQ(2,fd_head->next->next->next->next->offset); /* seqno */
|
|
|
|
ASSERT_EQ(40,fd_head->next->next->next->next->len); /* segment length */
|
|
|
|
ASSERT_EQ(FD_OVERLAP,fd_head->next->next->next->next->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->next->tvb_data);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->next->next);
|
2011-03-03 23:28:32 +00:00
|
|
|
|
|
|
|
/* test the actual reassembly */
|
2013-07-14 14:42:05 +00:00
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
|
2011-03-03 20:22:45 +00:00
|
|
|
|
2021-02-19 11:51:19 +00:00
|
|
|
if (debug) {
|
|
|
|
print_fragment_table();
|
|
|
|
}
|
2011-03-03 20:22:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Test case for fragment_add_seq with duplicated (e.g., retransmitted) data
|
|
|
|
* where the retransmission "conflicts" with the original transmission
|
|
|
|
* (contents are different).
|
|
|
|
* Adds three fragments--adding the 2nd one twice--
|
|
|
|
* and checks that they are reassembled correctly.
|
|
|
|
*/
|
|
|
|
/* visit id frame frag len more tvb_offset
|
|
|
|
0 12 1 0 50 T 10
|
2011-03-03 23:28:32 +00:00
|
|
|
0 12 2 1 60 T 5
|
|
|
|
0 12 3 1 60 T 15
|
|
|
|
0 12 4 2 40 F 5
|
2011-03-03 20:22:45 +00:00
|
|
|
*/
|
|
|
|
static void
|
2011-03-03 23:28:32 +00:00
|
|
|
test_fragment_add_seq_duplicate_conflict(void)
|
2011-03-03 20:22:45 +00:00
|
|
|
{
|
2013-07-17 21:12:24 +00:00
|
|
|
fragment_head *fd_head;
|
2011-03-03 20:22:45 +00:00
|
|
|
|
2011-03-03 23:28:32 +00:00
|
|
|
printf("Starting test test_fragment_add_seq_duplicate_conflict\n");
|
2011-03-03 20:22:45 +00:00
|
|
|
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 1;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
|
|
|
|
0, 50, TRUE, 0);
|
2011-03-03 20:22:45 +00:00
|
|
|
|
2013-03-23 02:41:43 +00:00
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
2011-03-03 20:22:45 +00:00
|
|
|
|
|
|
|
/* Add the 2nd segment */
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 2;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
|
|
|
|
1, 60, TRUE, 0);
|
2011-03-03 20:22:45 +00:00
|
|
|
|
|
|
|
/* we haven't got all the fragments yet ... */
|
2013-03-23 02:41:43 +00:00
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
2011-03-03 20:22:45 +00:00
|
|
|
|
|
|
|
/* Now, add the 2nd segment again (but in a different frame and with
|
|
|
|
* different data)
|
|
|
|
*/
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 3;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq(&test_reassembly_table, tvb, 15, &pinfo, 12, NULL,
|
|
|
|
1, 60, TRUE, 0);
|
2011-03-03 20:22:45 +00:00
|
|
|
|
|
|
|
/* This duplicate fragment should have been ignored */
|
2013-03-23 02:41:43 +00:00
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
2011-03-03 20:22:45 +00:00
|
|
|
|
|
|
|
/* finally, add the last fragment */
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 4;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
|
|
|
|
2, 40, FALSE, 0);
|
2011-03-03 20:22:45 +00:00
|
|
|
|
2013-03-23 02:41:43 +00:00
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_NE_POINTER(NULL,fd_head);
|
2011-03-03 20:22:45 +00:00
|
|
|
|
|
|
|
/* check the contents of the structure */
|
Fragmentation reassembly as in PPP MP (RFC 1990/2686)
Add support for defragmentation of fragments that use the defragmentation
scheme of PPP MP (RFC 1990). Instead of getting "sequence_number,
fragment_number, last" as in other protocols, PPP MP provides a single
sequence number that is effectively "seqnum + fragnum", though it provides
flags for both the first and last fragment of a reassembly.
See Appendix A of RFC 4623 (PWE3 Fragmentation and Reassembly) for a list
of protocols that use this style, including PPP MP (RFC 1990), PWE3 MPLS
(RFC 4385), L2TPv2 (RFC 2661), L2TPv3 (RFC 3931), ATM, and Frame Relay.
Also add support for the Multi-class Extension to Multilink PPP (RFC 2686),
which uses some of the previously reserved bits as classes that distinguish
otherwise identical sequence numbers.
Bug: 12548
Change-Id: Ic2ce3c50e61ab2eb50e4d92fd353ca4d2a48fe18
Reviewed-on: https://code.wireshark.org/review/16327
Reviewed-by: Michael Mann <mmann78@netscape.net>
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
2016-07-07 22:24:43 +00:00
|
|
|
ASSERT_EQ(4,fd_head->frame); /* max frame we have */
|
2011-03-03 20:22:45 +00:00
|
|
|
ASSERT_EQ(0,fd_head->offset); /* unused */
|
|
|
|
ASSERT_EQ(150,fd_head->len); /* the length of data we have */
|
|
|
|
ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
|
|
|
|
ASSERT_EQ(4,fd_head->reassembled_in);
|
|
|
|
ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET|FD_OVERLAP|FD_OVERLAPCONFLICT,fd_head->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next);
|
2011-03-03 20:22:45 +00:00
|
|
|
|
|
|
|
ASSERT_EQ(1,fd_head->next->frame);
|
|
|
|
ASSERT_EQ(0,fd_head->next->offset); /* seqno */
|
|
|
|
ASSERT_EQ(50,fd_head->next->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd_head->next->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next->next);
|
2011-03-03 20:22:45 +00:00
|
|
|
|
|
|
|
ASSERT_EQ(2,fd_head->next->next->frame);
|
|
|
|
ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
|
|
|
|
ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd_head->next->next->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next->next->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next->next->next);
|
2011-03-03 20:22:45 +00:00
|
|
|
|
|
|
|
ASSERT_EQ(3,fd_head->next->next->next->frame);
|
|
|
|
ASSERT_EQ(1,fd_head->next->next->next->offset); /* seqno */
|
|
|
|
ASSERT_EQ(60,fd_head->next->next->next->len); /* segment length */
|
|
|
|
ASSERT_EQ(FD_OVERLAP|FD_OVERLAPCONFLICT,fd_head->next->next->next->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next->next->next->next);
|
2011-03-03 20:22:45 +00:00
|
|
|
|
|
|
|
ASSERT_EQ(4,fd_head->next->next->next->next->frame);
|
|
|
|
ASSERT_EQ(2,fd_head->next->next->next->next->offset); /* seqno */
|
|
|
|
ASSERT_EQ(40,fd_head->next->next->next->next->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd_head->next->next->next->next->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->next->tvb_data);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->next->next);
|
2011-03-03 20:22:45 +00:00
|
|
|
|
|
|
|
/* test the actual reassembly */
|
2013-07-14 14:42:05 +00:00
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
|
2011-03-03 20:22:45 +00:00
|
|
|
|
2021-02-19 11:51:19 +00:00
|
|
|
if (debug) {
|
|
|
|
print_fragment_table();
|
|
|
|
}
|
2011-03-03 20:22:45 +00:00
|
|
|
}
|
|
|
|
|
2007-02-21 06:19:03 +00:00
|
|
|
/**********************************************************************************
|
|
|
|
*
|
|
|
|
* fragment_add_seq_check
|
|
|
|
*
|
|
|
|
*********************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
/* This routine is used for both fragment_add_seq_802_11 and
|
|
|
|
* fragment_add_seq_check.
|
|
|
|
*
|
|
|
|
* Adds a couple of out-of-order fragments and checks their reassembly.
|
|
|
|
*/
|
2010-12-10 15:35:59 +00:00
|
|
|
|
|
|
|
/* visit id frame frag len more tvb_offset
|
|
|
|
0 12 1 0 50 T 10
|
|
|
|
0 13 2 0 60 T 15
|
|
|
|
0 12 3 2 60 F 5
|
|
|
|
0 12 4 1 60 F 15
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
2009-10-20 15:07:22 +00:00
|
|
|
static void
|
2013-07-17 21:12:24 +00:00
|
|
|
test_fragment_add_seq_check_work(fragment_head *(*fn)(reassembly_table *,
|
2014-10-10 14:41:10 +00:00
|
|
|
tvbuff_t *, const int, const packet_info *,
|
|
|
|
const guint32, const void *, const guint32,
|
|
|
|
const guint32, const gboolean))
|
2007-02-21 06:19:03 +00:00
|
|
|
{
|
2013-07-17 21:12:24 +00:00
|
|
|
fragment_head *fd_head;
|
2007-02-21 06:19:03 +00:00
|
|
|
|
2016-01-24 17:35:50 +00:00
|
|
|
pinfo.num = 1;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fn(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
|
|
|
|
0, 50, TRUE);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
2013-03-23 02:41:43 +00:00
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
/* start another pdu (just to confuse things) */
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 2;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fn(&test_reassembly_table, tvb, 15, &pinfo, 13, NULL,
|
|
|
|
0, 60, TRUE);
|
|
|
|
ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
2009-09-06 18:25:23 +00:00
|
|
|
|
2007-02-21 06:19:03 +00:00
|
|
|
/* add the terminal fragment of the first datagram */
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 3;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fn(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
|
|
|
|
2, 60, FALSE);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
/* we haven't got all the fragments yet ... */
|
2013-03-23 02:41:43 +00:00
|
|
|
ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
/* finally, add the missing fragment */
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 4;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fn(&test_reassembly_table, tvb, 15, &pinfo, 12, NULL,
|
|
|
|
1, 60, TRUE);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
2013-03-23 02:41:43 +00:00
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(3,g_hash_table_size(test_reassembly_table.reassembled_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_NE_POINTER(NULL,fd_head);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
/* check the contents of the structure */
|
Fragmentation reassembly as in PPP MP (RFC 1990/2686)
Add support for defragmentation of fragments that use the defragmentation
scheme of PPP MP (RFC 1990). Instead of getting "sequence_number,
fragment_number, last" as in other protocols, PPP MP provides a single
sequence number that is effectively "seqnum + fragnum", though it provides
flags for both the first and last fragment of a reassembly.
See Appendix A of RFC 4623 (PWE3 Fragmentation and Reassembly) for a list
of protocols that use this style, including PPP MP (RFC 1990), PWE3 MPLS
(RFC 4385), L2TPv2 (RFC 2661), L2TPv3 (RFC 3931), ATM, and Frame Relay.
Also add support for the Multi-class Extension to Multilink PPP (RFC 2686),
which uses some of the previously reserved bits as classes that distinguish
otherwise identical sequence numbers.
Bug: 12548
Change-Id: Ic2ce3c50e61ab2eb50e4d92fd353ca4d2a48fe18
Reviewed-on: https://code.wireshark.org/review/16327
Reviewed-by: Michael Mann <mmann78@netscape.net>
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
2016-07-07 22:24:43 +00:00
|
|
|
ASSERT_EQ(4,fd_head->frame); /* max frame we have */
|
2007-02-21 06:19:03 +00:00
|
|
|
ASSERT_EQ(0,fd_head->offset); /* unused */
|
|
|
|
ASSERT_EQ(170,fd_head->len); /* the length of data we have */
|
|
|
|
ASSERT_EQ(2,fd_head->datalen); /* seqno of the last fragment we have */
|
|
|
|
ASSERT_EQ(4,fd_head->reassembled_in);
|
|
|
|
ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
ASSERT_EQ(1,fd_head->next->frame);
|
|
|
|
ASSERT_EQ(0,fd_head->next->offset); /* seqno */
|
|
|
|
ASSERT_EQ(50,fd_head->next->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd_head->next->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next->next);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
ASSERT_EQ(4,fd_head->next->next->frame);
|
|
|
|
ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
|
|
|
|
ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd_head->next->next->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next->next->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next->next->next);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
ASSERT_EQ(3,fd_head->next->next->next->frame);
|
|
|
|
ASSERT_EQ(2,fd_head->next->next->next->offset); /* seqno */
|
|
|
|
ASSERT_EQ(60,fd_head->next->next->next->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd_head->next->next->next->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->tvb_data);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next->next->next->next);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
/* test the actual reassembly */
|
2013-07-14 14:42:05 +00:00
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+15,60));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,60));
|
2010-12-10 15:35:59 +00:00
|
|
|
|
2021-02-19 11:51:19 +00:00
|
|
|
if (debug) {
|
|
|
|
print_tables();
|
|
|
|
}
|
2007-02-21 06:19:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Simple test case for fragment_add_seq_check
|
|
|
|
*/
|
2009-10-20 15:07:22 +00:00
|
|
|
static void
|
|
|
|
test_fragment_add_seq_check(void)
|
2007-02-21 06:19:03 +00:00
|
|
|
{
|
|
|
|
printf("Starting test test_fragment_add_seq_check\n");
|
|
|
|
|
|
|
|
test_fragment_add_seq_check_work(fragment_add_seq_check);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* This tests the case that the 802.11 hack does something different for: when
|
|
|
|
* the terminal segment in a fragmented datagram arrives first.
|
|
|
|
*/
|
2009-10-20 15:07:22 +00:00
|
|
|
static void
|
|
|
|
test_fragment_add_seq_check_1(void)
|
2007-02-21 06:19:03 +00:00
|
|
|
{
|
2013-07-17 21:12:24 +00:00
|
|
|
fragment_head *fd_head;
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
printf("Starting test test_fragment_add_seq_check_1\n");
|
|
|
|
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 1;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
|
|
|
|
1, 50, FALSE);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
2013-03-23 02:41:43 +00:00
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
/* Now add the missing segment */
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 2;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
|
|
|
|
0, 60, TRUE);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
2013-03-23 02:41:43 +00:00
|
|
|
ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.reassembled_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_NE_POINTER(NULL,fd_head);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
/* check the contents of the structure */
|
Fragmentation reassembly as in PPP MP (RFC 1990/2686)
Add support for defragmentation of fragments that use the defragmentation
scheme of PPP MP (RFC 1990). Instead of getting "sequence_number,
fragment_number, last" as in other protocols, PPP MP provides a single
sequence number that is effectively "seqnum + fragnum", though it provides
flags for both the first and last fragment of a reassembly.
See Appendix A of RFC 4623 (PWE3 Fragmentation and Reassembly) for a list
of protocols that use this style, including PPP MP (RFC 1990), PWE3 MPLS
(RFC 4385), L2TPv2 (RFC 2661), L2TPv3 (RFC 3931), ATM, and Frame Relay.
Also add support for the Multi-class Extension to Multilink PPP (RFC 2686),
which uses some of the previously reserved bits as classes that distinguish
otherwise identical sequence numbers.
Bug: 12548
Change-Id: Ic2ce3c50e61ab2eb50e4d92fd353ca4d2a48fe18
Reviewed-on: https://code.wireshark.org/review/16327
Reviewed-by: Michael Mann <mmann78@netscape.net>
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
2016-07-07 22:24:43 +00:00
|
|
|
ASSERT_EQ(2,fd_head->frame); /* max frame of fragment in structure */
|
2007-02-21 06:19:03 +00:00
|
|
|
ASSERT_EQ(0,fd_head->offset); /* unused */
|
|
|
|
ASSERT_EQ(110,fd_head->len); /* the length of data we have */
|
|
|
|
ASSERT_EQ(1,fd_head->datalen); /* seqno of the last fragment we have */
|
|
|
|
ASSERT_EQ(2,fd_head->reassembled_in);
|
|
|
|
ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
ASSERT_EQ(2,fd_head->next->frame);
|
|
|
|
ASSERT_EQ(0,fd_head->next->offset); /* seqno */
|
|
|
|
ASSERT_EQ(60,fd_head->next->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd_head->next->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next->next);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
ASSERT_EQ(1,fd_head->next->next->frame);
|
|
|
|
ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
|
|
|
|
ASSERT_EQ(50,fd_head->next->next->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd_head->next->next->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next->next->tvb_data);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next->next->next);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
/* test the actual reassembly */
|
2013-07-14 14:42:05 +00:00
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+5,60));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,60,data+10,50));
|
2007-02-21 06:19:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**********************************************************************************
|
|
|
|
*
|
|
|
|
* fragment_add_seq_802_11
|
|
|
|
*
|
|
|
|
*********************************************************************************/
|
|
|
|
|
|
|
|
/* Tests the 802.11 hack.
|
|
|
|
*/
|
2009-10-20 15:07:22 +00:00
|
|
|
static void
|
|
|
|
test_fragment_add_seq_802_11_0(void)
|
2007-02-21 06:19:03 +00:00
|
|
|
{
|
2013-07-17 21:12:24 +00:00
|
|
|
fragment_head *fd_head;
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
printf("Starting test test_fragment_add_seq_802_11_0\n");
|
|
|
|
|
|
|
|
/* the 802.11 hack is that some non-fragmented datagrams have non-zero
|
|
|
|
* fragment_number; test for this. */
|
|
|
|
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 1;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq_802_11(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
|
|
|
|
10, 50, FALSE);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
2013-03-23 02:41:43 +00:00
|
|
|
ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.reassembled_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_NE_POINTER(NULL,fd_head);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
/* check the contents of the structure */
|
|
|
|
ASSERT_EQ(0,fd_head->frame); /* unused */
|
|
|
|
ASSERT_EQ(0,fd_head->offset); /* unused */
|
|
|
|
ASSERT_EQ(0,fd_head->len); /* unused */
|
|
|
|
ASSERT_EQ(0,fd_head->datalen); /* unused */
|
|
|
|
ASSERT_EQ(1,fd_head->reassembled_in);
|
|
|
|
ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE,fd_head->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->tvb_data);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next);
|
2007-02-21 06:19:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Reuse the fragment_add_seq_check testcases */
|
|
|
|
static void test_fragment_add_seq_802_11_1(void)
|
|
|
|
{
|
|
|
|
printf("Starting test test_fragment_add_seq_802_11_1\n");
|
|
|
|
test_fragment_add_seq_check_work(fragment_add_seq_802_11);
|
|
|
|
}
|
|
|
|
|
2010-12-10 15:35:59 +00:00
|
|
|
/**********************************************************************************
|
|
|
|
*
|
|
|
|
* fragment_add_seq_check_multiple
|
|
|
|
*
|
|
|
|
*********************************************************************************/
|
|
|
|
|
|
|
|
/* Test 2 partial frags from 2 diff datagrams in the same frame */
|
|
|
|
/*
|
|
|
|
datagram #1: frame 1 + first part of frame 2
|
|
|
|
datagram #1: last part of frame 2 + frame 3
|
|
|
|
|
|
|
|
Is this a valid scenario ?
|
|
|
|
|
2013-03-23 02:41:43 +00:00
|
|
|
The result of calling fragment_add_seq_check(&test_reassembly_table, ) for these
|
2010-12-10 15:35:59 +00:00
|
|
|
fragments is a reassembled_table with:
|
|
|
|
id, frame 1 => first_datagram; ["reassembled in" frame 2]
|
|
|
|
id, frame 2 => second_datagram; ["reassembled in" frame 3]
|
|
|
|
id, frame 3 => second_datagram;
|
|
|
|
|
|
|
|
Note that the id, frame 2 => first datagram was overwritten
|
|
|
|
by the entry for the second datagram.
|
|
|
|
Is this OK ? IE: When dissected/displayed
|
|
|
|
will the reassembled datagram 1 appear with frame 2 ??
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* visit id frame frag len more tvb_offset
|
|
|
|
0 12 1 0 50 T 10
|
|
|
|
0 12 2 1 20 F 5
|
|
|
|
0 12 2 0 25 T 25
|
|
|
|
0 12 3 1 60 F 0
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
Is this a valid scenario ?
|
|
|
|
Is this OK ? IE: When dissected/displayed:
|
|
|
|
Will the reassembled datagram 1 appear with frame 2 ??
|
|
|
|
*/
|
|
|
|
#if 0
|
|
|
|
static void
|
|
|
|
test_fragment_add_seq_check_multiple(void) {
|
2013-07-17 21:12:24 +00:00
|
|
|
fragment_head *fd_head;
|
2010-12-10 15:35:59 +00:00
|
|
|
|
2016-01-24 17:35:50 +00:00
|
|
|
pinfo.num = 1;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
|
|
|
|
0, 50, TRUE);
|
2010-12-10 15:35:59 +00:00
|
|
|
|
|
|
|
/* add the terminal fragment of the first datagram */
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 2;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
|
|
|
|
1, 20, FALSE);
|
2010-12-10 15:35:59 +00:00
|
|
|
|
|
|
|
print_tables();
|
|
|
|
|
|
|
|
/* Now: start a second datagram with the first fragment in frame #2 */
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 2;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 25, &pinfo, 12, NULL,
|
|
|
|
0, 25, TRUE);
|
2010-12-10 15:35:59 +00:00
|
|
|
|
|
|
|
/* add the terminal fragment of the second datagram */
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 3;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq_check(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
|
|
|
|
1, 60, FALSE);
|
2010-12-10 15:35:59 +00:00
|
|
|
|
|
|
|
print_tables();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2007-02-21 06:19:03 +00:00
|
|
|
/**********************************************************************************
|
|
|
|
*
|
|
|
|
* fragment_add_seq_next
|
|
|
|
*
|
|
|
|
*********************************************************************************/
|
|
|
|
|
|
|
|
/* Simple test case for fragment_add_seq_next.
|
|
|
|
* Adds a couple of fragments (with one for a different datagram in between),
|
|
|
|
* and checks that they are reassembled correctly.
|
|
|
|
*/
|
2009-10-20 15:07:22 +00:00
|
|
|
static void
|
|
|
|
test_simple_fragment_add_seq_next(void)
|
2007-02-21 06:19:03 +00:00
|
|
|
{
|
2013-07-17 21:12:24 +00:00
|
|
|
fragment_head *fd_head;
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
printf("Starting test test_simple_fragment_add_seq_next\n");
|
|
|
|
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 1;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head= fragment_add_seq_next(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
|
|
|
|
50, TRUE);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
2013-03-23 02:41:43 +00:00
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
/* adding the same fragment again should do nothing, even with different
|
|
|
|
* offset etc */
|
2018-12-27 02:26:24 +00:00
|
|
|
pinfo.fd->visited = 1;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
|
|
|
|
60, TRUE);
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
/* start another pdu (just to confuse things) */
|
2018-12-27 02:26:24 +00:00
|
|
|
pinfo.fd->visited = 0;
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 2;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 15, &pinfo, 13, NULL,
|
|
|
|
60, TRUE);
|
|
|
|
ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
2009-09-06 18:25:23 +00:00
|
|
|
|
|
|
|
|
2007-02-21 06:19:03 +00:00
|
|
|
/* now we add the terminal fragment of the first datagram */
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 3;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
|
|
|
|
60, FALSE);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
2013-03-23 02:41:43 +00:00
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.reassembled_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_NE_POINTER(NULL,fd_head);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
/* check the contents of the structure */
|
Fragmentation reassembly as in PPP MP (RFC 1990/2686)
Add support for defragmentation of fragments that use the defragmentation
scheme of PPP MP (RFC 1990). Instead of getting "sequence_number,
fragment_number, last" as in other protocols, PPP MP provides a single
sequence number that is effectively "seqnum + fragnum", though it provides
flags for both the first and last fragment of a reassembly.
See Appendix A of RFC 4623 (PWE3 Fragmentation and Reassembly) for a list
of protocols that use this style, including PPP MP (RFC 1990), PWE3 MPLS
(RFC 4385), L2TPv2 (RFC 2661), L2TPv3 (RFC 3931), ATM, and Frame Relay.
Also add support for the Multi-class Extension to Multilink PPP (RFC 2686),
which uses some of the previously reserved bits as classes that distinguish
otherwise identical sequence numbers.
Bug: 12548
Change-Id: Ic2ce3c50e61ab2eb50e4d92fd353ca4d2a48fe18
Reviewed-on: https://code.wireshark.org/review/16327
Reviewed-by: Michael Mann <mmann78@netscape.net>
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
2016-07-07 22:24:43 +00:00
|
|
|
ASSERT_EQ(3,fd_head->frame); /* max frame we have */
|
2007-02-21 06:19:03 +00:00
|
|
|
ASSERT_EQ(0,fd_head->offset); /* unused */
|
|
|
|
ASSERT_EQ(110,fd_head->len); /* the length of data we have */
|
|
|
|
ASSERT_EQ(1,fd_head->datalen); /* seqno of the last fragment we have */
|
|
|
|
ASSERT_EQ(3,fd_head->reassembled_in);
|
|
|
|
ASSERT_EQ(FD_DEFRAGMENTED|FD_BLOCKSEQUENCE|FD_DATALEN_SET,fd_head->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
ASSERT_EQ(1,fd_head->next->frame);
|
|
|
|
ASSERT_EQ(0,fd_head->next->offset); /* seqno */
|
|
|
|
ASSERT_EQ(50,fd_head->next->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd_head->next->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next->next);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
ASSERT_EQ(3,fd_head->next->next->frame);
|
|
|
|
ASSERT_EQ(1,fd_head->next->next->offset); /* seqno */
|
|
|
|
ASSERT_EQ(60,fd_head->next->next->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd_head->next->next->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next->next->tvb_data);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next->next->next);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
/* test the actual reassembly */
|
2013-07-14 14:42:05 +00:00
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
|
2007-02-21 06:19:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-02-23 00:56:45 +00:00
|
|
|
#if 0
|
|
|
|
/* XXX remove this? fragment_add_seq does not have the special case for
|
|
|
|
* fragments having truncated tvbs anymore! */
|
2007-02-21 06:19:03 +00:00
|
|
|
/* This tests the case where some data is missing from one of the fragments.
|
|
|
|
* It should prevent reassembly.
|
|
|
|
*/
|
2009-10-20 15:07:22 +00:00
|
|
|
static void
|
|
|
|
test_missing_data_fragment_add_seq_next(void)
|
2007-02-21 06:19:03 +00:00
|
|
|
{
|
2013-07-17 21:12:24 +00:00
|
|
|
fragment_head *fd_head;
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
printf("Starting test test_missing_data_fragment_add_seq_next\n");
|
|
|
|
|
|
|
|
/* attempt to add a fragment which is longer than the data available */
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 1;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
|
|
|
|
DATA_LEN-9, TRUE);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
2013-03-23 02:41:43 +00:00
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_NE_POINTER(NULL,fd_head);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
/* check the contents of the structure. Reassembly failed so everything
|
|
|
|
* should be null (meaning, just use the original tvb) */
|
|
|
|
ASSERT_EQ(0,fd_head->frame); /* unused */
|
|
|
|
ASSERT_EQ(0,fd_head->offset); /* unused */
|
|
|
|
ASSERT_EQ(0,fd_head->len); /* the length of data we have */
|
|
|
|
ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
|
|
|
|
ASSERT_EQ(0,fd_head->reassembled_in);
|
|
|
|
ASSERT_EQ(FD_BLOCKSEQUENCE,fd_head->flags & 0x1ff);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->tvb_data);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
/* add another fragment (with all data present) */
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 4;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
|
|
|
|
60, FALSE);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
/* XXX: it's not clear that this is the right result; however it's what the
|
|
|
|
* code does...
|
|
|
|
*/
|
2013-03-23 02:41:43 +00:00
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
/* check what happens when we revisit the packets */
|
2018-12-27 02:26:24 +00:00
|
|
|
pinfo.fd->visited = TRUE;
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 1;
|
2007-02-21 06:19:03 +00:00
|
|
|
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
|
|
|
|
DATA_LEN-9, TRUE);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
/* We just look in the reassembled_table for this packet. It never got put
|
|
|
|
* there, so this always returns null.
|
|
|
|
*
|
|
|
|
* That's crazy, because it means that the subdissector will see the data
|
|
|
|
* exactly once - on the first pass through the capture (well, assuming it
|
|
|
|
* doesn't bother to check fd_head->reassembled_in); however, that's
|
|
|
|
* what the code does...
|
|
|
|
*/
|
2013-03-23 02:41:43 +00:00
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 4;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
|
|
|
|
60, FALSE);
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
2007-02-21 06:19:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* we're going to do something similar now, but this time it is the second
|
|
|
|
* fragment which has something missing.
|
|
|
|
*/
|
2009-10-20 15:07:22 +00:00
|
|
|
static void
|
|
|
|
test_missing_data_fragment_add_seq_next_2(void)
|
2007-02-21 06:19:03 +00:00
|
|
|
{
|
2013-07-17 21:12:24 +00:00
|
|
|
fragment_head *fd_head;
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
printf("Starting test test_missing_data_fragment_add_seq_next_2\n");
|
|
|
|
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 11;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 10, &pinfo, 24, NULL,
|
|
|
|
50, TRUE);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
2013-03-23 02:41:43 +00:00
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 12;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 24, NULL,
|
|
|
|
DATA_LEN-4, FALSE);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
/* XXX: again, i'm really dubious about this. Surely this should return all
|
|
|
|
* the data we had, for a best-effort attempt at dissecting it?
|
|
|
|
* And it ought to go into the reassembled table?
|
|
|
|
*/
|
2013-03-23 02:41:43 +00:00
|
|
|
ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
/* check what happens when we revisit the packets */
|
2018-12-27 02:26:24 +00:00
|
|
|
pinfo.fd->visited = TRUE;
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 11;
|
2007-02-21 06:19:03 +00:00
|
|
|
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 10, &pinfo, 24, NULL,
|
|
|
|
50, TRUE);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
/* As before, this returns NULL because the fragment isn't in the
|
|
|
|
* reassembled_table. At least this is a bit more consistent than before.
|
|
|
|
*/
|
2013-03-23 02:41:43 +00:00
|
|
|
ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 12;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 24, NULL,
|
|
|
|
DATA_LEN-4, FALSE);
|
|
|
|
ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This time, our datagram only has one segment, but it has data missing.
|
|
|
|
*/
|
2009-10-20 15:07:22 +00:00
|
|
|
static void
|
|
|
|
test_missing_data_fragment_add_seq_next_3(void)
|
2007-02-21 06:19:03 +00:00
|
|
|
{
|
2013-07-17 21:12:24 +00:00
|
|
|
fragment_head *fd_head;
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
printf("Starting test test_missing_data_fragment_add_seq_next_3\n");
|
|
|
|
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 20;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 30, NULL,
|
|
|
|
DATA_LEN-4, FALSE);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
2013-03-23 02:41:43 +00:00
|
|
|
ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.reassembled_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_NE_POINTER(NULL,fd_head);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
/* check the contents of the structure. */
|
Fragmentation reassembly as in PPP MP (RFC 1990/2686)
Add support for defragmentation of fragments that use the defragmentation
scheme of PPP MP (RFC 1990). Instead of getting "sequence_number,
fragment_number, last" as in other protocols, PPP MP provides a single
sequence number that is effectively "seqnum + fragnum", though it provides
flags for both the first and last fragment of a reassembly.
See Appendix A of RFC 4623 (PWE3 Fragmentation and Reassembly) for a list
of protocols that use this style, including PPP MP (RFC 1990), PWE3 MPLS
(RFC 4385), L2TPv2 (RFC 2661), L2TPv3 (RFC 3931), ATM, and Frame Relay.
Also add support for the Multi-class Extension to Multilink PPP (RFC 2686),
which uses some of the previously reserved bits as classes that distinguish
otherwise identical sequence numbers.
Bug: 12548
Change-Id: Ic2ce3c50e61ab2eb50e4d92fd353ca4d2a48fe18
Reviewed-on: https://code.wireshark.org/review/16327
Reviewed-by: Michael Mann <mmann78@netscape.net>
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
2016-07-07 22:24:43 +00:00
|
|
|
ASSERT_EQ(0,fd_head->frame); /* max frame we have */
|
2007-02-21 06:19:03 +00:00
|
|
|
ASSERT_EQ(0,fd_head->offset); /* unused */
|
|
|
|
ASSERT_EQ(0,fd_head->len); /* the length of data we have */
|
|
|
|
ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
|
|
|
|
ASSERT_EQ(20,fd_head->reassembled_in);
|
|
|
|
ASSERT_EQ(FD_BLOCKSEQUENCE|FD_DEFRAGMENTED,fd_head->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->tvb_data);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
/* revisiting the packet ought to produce the same result. */
|
2018-12-27 02:26:24 +00:00
|
|
|
pinfo.fd->visited = TRUE;
|
2007-02-21 06:19:03 +00:00
|
|
|
|
2016-01-24 03:40:51 +00:00
|
|
|
pinfo.num = 20;
|
2013-03-23 02:41:43 +00:00
|
|
|
fd_head=fragment_add_seq_next(&test_reassembly_table, tvb, 5, &pinfo, 30, NULL,
|
|
|
|
DATA_LEN-4, FALSE);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
2013-03-23 02:41:43 +00:00
|
|
|
ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.reassembled_table));
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_NE_POINTER(NULL,fd_head);
|
2007-02-21 06:19:03 +00:00
|
|
|
ASSERT_EQ(0,fd_head->frame); /* unused */
|
|
|
|
ASSERT_EQ(0,fd_head->offset); /* unused */
|
|
|
|
ASSERT_EQ(0,fd_head->len); /* the length of data we have */
|
|
|
|
ASSERT_EQ(0,fd_head->datalen); /* seqno of the last fragment we have */
|
|
|
|
ASSERT_EQ(20,fd_head->reassembled_in);
|
|
|
|
ASSERT_EQ(FD_BLOCKSEQUENCE|FD_DEFRAGMENTED,fd_head->flags);
|
2016-07-15 11:54:10 +00:00
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->tvb_data);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next);
|
2007-02-21 06:19:03 +00:00
|
|
|
}
|
2016-02-23 00:56:45 +00:00
|
|
|
#endif
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
/**********************************************************************************
|
|
|
|
*
|
2020-09-24 14:11:00 +00:00
|
|
|
* fragment_add
|
2007-02-21 06:19:03 +00:00
|
|
|
*
|
|
|
|
*********************************************************************************/
|
|
|
|
|
2020-09-24 14:11:00 +00:00
|
|
|
/* Simple test case for fragment_add.
|
|
|
|
* Adds three fragments (out of order, with one for a different datagram in between),
|
|
|
|
* and checks that they are reassembled correctly.
|
|
|
|
*/
|
|
|
|
/* visit id frame frag_offset len more tvb_offset
|
|
|
|
0 12 1 0 50 T 10
|
|
|
|
1 12 1 0 60 T 5
|
|
|
|
0 13 2 0 60 T 15
|
|
|
|
0 12 3 110 60 F 5
|
|
|
|
0 12 4 50 60 T 15
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
test_simple_fragment_add(void)
|
2007-02-21 06:19:03 +00:00
|
|
|
{
|
2020-09-24 14:11:00 +00:00
|
|
|
fragment_head *fd_head, *fdh0;
|
|
|
|
fragment_item *fd;
|
|
|
|
|
|
|
|
printf("Starting test test_simple_fragment_add\n");
|
|
|
|
|
|
|
|
pinfo.num = 1;
|
|
|
|
fd_head=fragment_add(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
|
|
|
|
0, 50, TRUE);
|
|
|
|
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* adding the same fragment again should do nothing, even with different
|
|
|
|
* offset etc */
|
|
|
|
pinfo.fd->visited = 1;
|
|
|
|
fd_head=fragment_add(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
|
|
|
|
0, 60, TRUE);
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* start another pdu (just to confuse things) */
|
|
|
|
pinfo.fd->visited = 0;
|
|
|
|
pinfo.num = 2;
|
|
|
|
fd_head=fragment_add(&test_reassembly_table, tvb, 15, &pinfo, 13, NULL,
|
|
|
|
0, 60, TRUE);
|
|
|
|
ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* now we add the terminal fragment of the first datagram */
|
|
|
|
pinfo.num = 3;
|
|
|
|
fd_head=fragment_add(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
|
|
|
|
110, 60, FALSE);
|
|
|
|
|
|
|
|
/* we haven't got all the fragments yet ... */
|
|
|
|
ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* finally, add the missing fragment */
|
|
|
|
pinfo.num = 4;
|
|
|
|
fd_head=fragment_add(&test_reassembly_table, tvb, 15, &pinfo, 12, NULL,
|
|
|
|
50, 60, TRUE);
|
|
|
|
|
|
|
|
ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* check the contents of the structure */
|
|
|
|
ASSERT_EQ(4,fd_head->frame); /* max frame number of fragment in assembly */
|
|
|
|
ASSERT_EQ(0,fd_head->offset); /* unused */
|
|
|
|
ASSERT_EQ(0,fd_head->len); /* unused in fragment_add */
|
|
|
|
ASSERT_EQ(170,fd_head->datalen); /* total datalen of assembly */
|
|
|
|
ASSERT_EQ(4,fd_head->reassembled_in);
|
|
|
|
ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET,fd_head->flags);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next);
|
|
|
|
|
|
|
|
fd = fd_head->next;
|
|
|
|
ASSERT_EQ(1,fd->frame);
|
|
|
|
ASSERT_EQ(0,fd->offset); /* offset */
|
|
|
|
ASSERT_EQ(50,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd = fd->next;
|
|
|
|
ASSERT_EQ(4,fd->frame);
|
|
|
|
ASSERT_EQ(50,fd->offset); /* offset */
|
|
|
|
ASSERT_EQ(60,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd = fd->next;
|
|
|
|
ASSERT_EQ(3,fd->frame);
|
|
|
|
ASSERT_EQ(110,fd->offset); /* offset */
|
|
|
|
ASSERT_EQ(60,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
/* test the actual reassembly */
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+15,60));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,60));
|
|
|
|
|
2021-02-19 11:51:19 +00:00
|
|
|
if (debug) {
|
|
|
|
print_fragment_table();
|
|
|
|
}
|
2020-09-24 14:11:00 +00:00
|
|
|
|
|
|
|
/* what happens if we revisit the packets now? */
|
|
|
|
fdh0 = fd_head;
|
|
|
|
pinfo.fd->visited = 1;
|
|
|
|
pinfo.num = 1;
|
|
|
|
fd_head=fragment_add(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
|
|
|
|
0, 50, TRUE);
|
|
|
|
/*
|
|
|
|
* this api relies on the caller to check fd_head -> reassembled_in
|
|
|
|
*
|
|
|
|
* Redoing all the tests seems like overkill - just check the pointer
|
|
|
|
*/
|
|
|
|
ASSERT_EQ_POINTER(fdh0,fd_head);
|
|
|
|
|
|
|
|
pinfo.num = 3;
|
|
|
|
fd_head=fragment_add(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
|
|
|
|
110, 60, FALSE);
|
|
|
|
ASSERT_EQ_POINTER(fdh0,fd_head);
|
|
|
|
|
|
|
|
pinfo.num = 4;
|
|
|
|
fd_head=fragment_add(&test_reassembly_table, tvb, 15, &pinfo, 12, NULL,
|
|
|
|
50, 60, TRUE);
|
|
|
|
ASSERT_EQ_POINTER(fdh0,fd_head);
|
|
|
|
|
2021-02-19 11:51:19 +00:00
|
|
|
if (debug) {
|
|
|
|
print_fragment_table();
|
|
|
|
}
|
2020-09-24 14:11:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* This tests the functionality of fragment_set_partial_reassembly for
|
|
|
|
* fragment_add based reassembly.
|
|
|
|
*
|
|
|
|
* We add a sequence of fragments thus:
|
|
|
|
* seq_off frame tvb_off len (initial) more_frags
|
|
|
|
* ------- ----- ------- --- --------------------
|
|
|
|
* 0 1 10 50 false
|
|
|
|
* 50 2 0 40 true
|
|
|
|
* 50 3 0 40 true (a duplicate fragment)
|
|
|
|
* 90 4 20 100 false
|
|
|
|
* 190 5 0 40 false
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
test_fragment_add_partial_reassembly(void)
|
|
|
|
{
|
|
|
|
fragment_head *fd_head;
|
|
|
|
fragment_item *fd;
|
|
|
|
|
|
|
|
printf("Starting test test_fragment_add_partial_reassembly\n");
|
|
|
|
|
|
|
|
/* generally it's probably fair to assume that we will be called with
|
|
|
|
* more_frags=FALSE.
|
|
|
|
*/
|
|
|
|
pinfo.num = 1;
|
|
|
|
fd_head=fragment_add(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
|
|
|
|
0, 50, FALSE);
|
|
|
|
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* check the contents of the structure */
|
|
|
|
ASSERT_EQ(1,fd_head->frame); /* max frame in reassembly */
|
|
|
|
ASSERT_EQ(0,fd_head->offset); /* unused */
|
|
|
|
ASSERT_EQ(0,fd_head->len); /* unused */
|
|
|
|
ASSERT_EQ(50,fd_head->datalen); /* the length of data we we have */
|
|
|
|
ASSERT_EQ(1,fd_head->reassembled_in);
|
|
|
|
ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET,fd_head->flags);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next);
|
|
|
|
|
|
|
|
ASSERT_EQ(1,fd_head->next->frame);
|
|
|
|
ASSERT_EQ(0,fd_head->next->offset); /* offset */
|
|
|
|
ASSERT_EQ(50,fd_head->next->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd_head->next->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next->tvb_data);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next->next);
|
|
|
|
|
|
|
|
/* test the actual reassembly */
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
|
|
|
|
|
|
|
|
/* now we announce that the reassembly wasn't complete after all. */
|
|
|
|
fragment_set_partial_reassembly(&test_reassembly_table, &pinfo, 12, NULL);
|
|
|
|
|
|
|
|
/* and add another segment. To mix things up slightly (and so that we can
|
|
|
|
* check on the state of things), we're going to set the more_frags flag
|
|
|
|
* here
|
|
|
|
*/
|
|
|
|
pinfo.num = 2;
|
|
|
|
fd_head=fragment_add(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
|
|
|
|
50, 40, TRUE);
|
|
|
|
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
fd_head=fragment_get(&test_reassembly_table, &pinfo, 12, NULL);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* check the contents of the structure */
|
|
|
|
ASSERT_EQ(2,fd_head->frame); /* max frame in reassembly */
|
|
|
|
ASSERT_EQ(0,fd_head->offset); /* unused */
|
|
|
|
ASSERT_EQ(0,fd_head->len); /* unused */
|
|
|
|
/* ASSERT_EQ(0,fd_head->datalen);
|
|
|
|
* reassembly not finished; datalen not well defined.
|
|
|
|
* Current implemenation has it as 0, could change to 90 without issues */
|
|
|
|
ASSERT_EQ(0,fd_head->reassembled_in);
|
|
|
|
ASSERT_EQ(0,fd_head->flags);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next);
|
|
|
|
|
|
|
|
fd=fd_head->next;
|
|
|
|
ASSERT_EQ(1,fd->frame);
|
|
|
|
ASSERT_EQ(0,fd->offset); /* offset */
|
|
|
|
ASSERT_EQ(50,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(FD_SUBSET_TVB,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(tvb_get_ptr(fd_head->tvb_data,0,0),tvb_get_ptr(fd->tvb_data,0,0));
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd=fd->next;
|
|
|
|
ASSERT_EQ(2,fd->frame);
|
|
|
|
ASSERT_EQ(50,fd->offset); /* offset */
|
|
|
|
ASSERT_EQ(40,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
/* Another copy of the second segment.
|
|
|
|
*/
|
|
|
|
pinfo.num = 3;
|
|
|
|
fd_head=fragment_add(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
|
|
|
|
50, 40, TRUE);
|
|
|
|
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
|
|
|
fd_head=fragment_get(&test_reassembly_table, &pinfo, 12, NULL);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head);
|
|
|
|
ASSERT_EQ(3,fd_head->frame); /* max frame we have */
|
|
|
|
ASSERT_EQ(0,fd_head->offset); /* unused */
|
|
|
|
ASSERT_EQ(0,fd_head->len); /* unused */
|
|
|
|
/* ASSERT_EQ(0,fd_head->datalen);
|
|
|
|
* reassembly not finished; datalen not well defined.
|
|
|
|
* Current implemenation has it as 0, could change to 90 without issues */
|
|
|
|
ASSERT_EQ(0,fd_head->reassembled_in);
|
|
|
|
ASSERT_EQ(0,fd_head->flags);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next);
|
|
|
|
|
|
|
|
fd=fd_head->next;
|
|
|
|
ASSERT_EQ(1,fd->frame);
|
|
|
|
ASSERT_EQ(0,fd->offset);
|
|
|
|
ASSERT_EQ(50,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(FD_SUBSET_TVB,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(tvb_get_ptr(fd_head->tvb_data,0,0),tvb_get_ptr(fd->tvb_data,0,0));
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd=fd->next;
|
|
|
|
ASSERT_EQ(2,fd->frame);
|
|
|
|
ASSERT_EQ(50,fd->offset);
|
|
|
|
ASSERT_EQ(40,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd=fd->next;
|
|
|
|
ASSERT_EQ(3,fd->frame);
|
|
|
|
ASSERT_EQ(50,fd->offset);
|
|
|
|
ASSERT_EQ(40,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* have another go at wrapping things up */
|
|
|
|
pinfo.num = 4;
|
|
|
|
fd_head=fragment_add(&test_reassembly_table, tvb, 20, &pinfo, 12, NULL,
|
|
|
|
90, 100, FALSE);
|
|
|
|
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* check the contents of the structure */
|
|
|
|
ASSERT_EQ(4,fd_head->frame); /* max frame we have */
|
|
|
|
ASSERT_EQ(0,fd_head->offset); /* unused */
|
|
|
|
ASSERT_EQ(0,fd_head->len); /* unused */
|
|
|
|
ASSERT_EQ(190,fd_head->datalen); /* the length of data we have */
|
|
|
|
ASSERT_EQ(4,fd_head->reassembled_in);
|
|
|
|
ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next);
|
|
|
|
|
|
|
|
fd=fd_head->next;
|
|
|
|
ASSERT_EQ(1,fd->frame);
|
|
|
|
ASSERT_EQ(0,fd->offset);
|
|
|
|
ASSERT_EQ(50,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd=fd->next;
|
|
|
|
ASSERT_EQ(2,fd->frame);
|
|
|
|
ASSERT_EQ(50,fd->offset);
|
|
|
|
ASSERT_EQ(40,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd=fd->next;
|
|
|
|
ASSERT_EQ(3,fd->frame);
|
|
|
|
ASSERT_EQ(50,fd->offset);
|
|
|
|
ASSERT_EQ(40,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(FD_OVERLAP,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd=fd->next;
|
|
|
|
ASSERT_EQ(4,fd->frame);
|
|
|
|
ASSERT_EQ(90,fd->offset);
|
|
|
|
ASSERT_EQ(100,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
/* test the actual reassembly */
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,50,data,40));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,90,data+20,100));
|
|
|
|
|
|
|
|
|
|
|
|
/* do it again (this time it is more complicated, with an overlap in the
|
|
|
|
* reassembly) */
|
|
|
|
|
|
|
|
fragment_set_partial_reassembly(&test_reassembly_table, &pinfo, 12, NULL);
|
|
|
|
|
|
|
|
pinfo.num = 5;
|
|
|
|
fragment_add(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
|
|
|
|
190, 40, FALSE);
|
|
|
|
|
|
|
|
fd_head=fragment_get(&test_reassembly_table, &pinfo, 12, NULL);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head);
|
|
|
|
ASSERT_EQ(5,fd_head->frame); /* max frame we have */
|
|
|
|
ASSERT_EQ(0,fd_head->offset); /* unused */
|
|
|
|
ASSERT_EQ(0,fd_head->len); /* unused */
|
|
|
|
ASSERT_EQ(230,fd_head->datalen); /* the length of data we have */
|
|
|
|
ASSERT_EQ(5,fd_head->reassembled_in);
|
|
|
|
ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next);
|
|
|
|
|
|
|
|
fd=fd_head->next;
|
|
|
|
ASSERT_EQ(1,fd->frame);
|
|
|
|
ASSERT_EQ(0,fd->offset);
|
|
|
|
ASSERT_EQ(50,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd=fd->next;
|
|
|
|
ASSERT_EQ(2,fd->frame);
|
|
|
|
ASSERT_EQ(50,fd->offset);
|
|
|
|
ASSERT_EQ(40,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd=fd->next;
|
|
|
|
ASSERT_EQ(3,fd->frame);
|
|
|
|
ASSERT_EQ(50,fd->offset);
|
|
|
|
ASSERT_EQ(40,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(FD_OVERLAP,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd=fd->next;
|
|
|
|
ASSERT_EQ(4,fd->frame);
|
|
|
|
ASSERT_EQ(90,fd->offset);
|
|
|
|
ASSERT_EQ(100,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd=fd->next;
|
|
|
|
ASSERT_EQ(5,fd->frame);
|
|
|
|
ASSERT_EQ(190,fd->offset);
|
|
|
|
ASSERT_EQ(40,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
/* test the actual reassembly */
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,50,data,40));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,90,data+20,100));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,190,data,40));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* XXX: Is the proper behavior here really throwing an exception instead
|
|
|
|
* of setting FD_OVERLAP?
|
|
|
|
*/
|
|
|
|
/* Test case for fragment_add with duplicated (e.g., retransmitted) data.
|
|
|
|
* Adds three fragments--adding the 1st one twice at the end--
|
|
|
|
* and checks that they are reassembled correctly.
|
|
|
|
*/
|
|
|
|
/* visit id frame frag_off len more tvb_offset
|
|
|
|
0 12 1 0 50 T 10
|
|
|
|
0 12 2 50 60 T 5
|
|
|
|
0 12 3 110 40 F 5
|
|
|
|
0 12 4 0 50 T 10
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
test_fragment_add_duplicate_first(void)
|
|
|
|
{
|
|
|
|
fragment_head *fd_head;
|
|
|
|
fragment_item *fd;
|
|
|
|
volatile gboolean ex_thrown;
|
|
|
|
|
|
|
|
printf("Starting test test_fragment_add_duplicate_first\n");
|
|
|
|
|
|
|
|
pinfo.num = 1;
|
|
|
|
fd_head=fragment_add(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
|
|
|
|
0, 50, TRUE);
|
|
|
|
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* Add the 2nd segment */
|
|
|
|
pinfo.num = 2;
|
|
|
|
fd_head=fragment_add(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
|
|
|
|
50, 60, TRUE);
|
|
|
|
|
|
|
|
/* we haven't got all the fragments yet ... */
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* Add the last fragment */
|
|
|
|
pinfo.num = 3;
|
|
|
|
fd_head=fragment_add(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
|
|
|
|
110, 40, FALSE);
|
|
|
|
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* Add the first fragment again */
|
|
|
|
pinfo.num = 4;
|
|
|
|
/* XXX: The current reassemble.c code for fragment_add() throws an
|
|
|
|
* exception and doesn't try to add a duplicate if and only if the
|
|
|
|
* assembly is already completed. This means that it doesn't get
|
|
|
|
* put in the linked list. This is counter to how the _seq functions
|
|
|
|
* work, as well as to how this code works if a duplicate comes in the
|
|
|
|
* middle instead of at the end. Test matches current code, but the
|
|
|
|
* current code should perhaps be changed. */
|
|
|
|
ex_thrown = FALSE;
|
|
|
|
TRY {
|
|
|
|
fd_head=fragment_add(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
|
|
|
|
0, 50, TRUE);
|
|
|
|
}
|
|
|
|
CATCH(ReassemblyError) {
|
|
|
|
ex_thrown = TRUE;
|
|
|
|
}
|
|
|
|
ENDTRY;
|
|
|
|
|
|
|
|
ASSERT_EQ(TRUE, ex_thrown);
|
|
|
|
|
|
|
|
/* Reassembly should have still succeeded */
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* check the contents of the structure */
|
|
|
|
/*ASSERT_EQ(4,fd_head->frame); max frame we have */
|
|
|
|
ASSERT_EQ(3,fd_head->frame); /* never add the duplicate frame */
|
|
|
|
ASSERT_EQ(0,fd_head->offset); /* unused */
|
|
|
|
ASSERT_EQ(0,fd_head->len); /* unused */
|
|
|
|
ASSERT_EQ(150,fd_head->datalen);
|
|
|
|
ASSERT_EQ(3,fd_head->reassembled_in);
|
|
|
|
/* ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags); */
|
|
|
|
/* FD_OVERLAP doesn't get set because we hit the exception early */
|
|
|
|
ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET,fd_head->flags);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next);
|
|
|
|
|
|
|
|
fd = fd_head->next;
|
|
|
|
|
|
|
|
ASSERT_EQ(1,fd->frame);
|
|
|
|
ASSERT_EQ(0,fd->offset);
|
|
|
|
ASSERT_EQ(50,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
/*
|
|
|
|
fd = fd_head->next;
|
|
|
|
ASSERT_EQ(4,fd->frame);
|
|
|
|
ASSERT_EQ(0,fd->offset);
|
|
|
|
ASSERT_EQ(50,fd->len);
|
|
|
|
ASSERT_EQ(FD_OVERLAP,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next); */
|
|
|
|
|
|
|
|
fd = fd->next;
|
|
|
|
ASSERT_EQ(2,fd->frame);
|
|
|
|
ASSERT_EQ(50,fd->offset);
|
|
|
|
ASSERT_EQ(60,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd = fd->next;
|
|
|
|
ASSERT_EQ(3,fd->frame);
|
|
|
|
ASSERT_EQ(110,fd->offset);
|
|
|
|
ASSERT_EQ(40,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
/* test the actual reassembly */
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
|
|
|
|
|
2021-02-19 11:51:19 +00:00
|
|
|
if (debug) {
|
|
|
|
print_fragment_table();
|
|
|
|
}
|
2020-09-24 14:11:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Test case for fragment_add with duplicated (e.g., retransmitted) data.
|
|
|
|
* Adds three fragments--adding the 2nd one twice--
|
|
|
|
* and checks that they are reassembled correctly.
|
|
|
|
*/
|
|
|
|
/* visit id frame frag_off len more tvb_offset
|
|
|
|
0 12 1 0 50 T 10
|
|
|
|
0 12 2 50 60 T 5
|
|
|
|
0 12 3 50 60 T 5
|
|
|
|
0 12 4 110 40 F 5
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
test_fragment_add_duplicate_middle(void)
|
|
|
|
{
|
|
|
|
fragment_head *fd_head;
|
|
|
|
fragment_item *fd;
|
|
|
|
|
|
|
|
printf("Starting test test_fragment_add_duplicate_middle\n");
|
|
|
|
|
|
|
|
pinfo.num = 1;
|
|
|
|
fd_head=fragment_add(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
|
|
|
|
0, 50, TRUE);
|
|
|
|
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* Add the 2nd segment */
|
|
|
|
pinfo.num = 2;
|
|
|
|
fd_head=fragment_add(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
|
|
|
|
50, 60, TRUE);
|
|
|
|
|
|
|
|
/* we haven't got all the fragments yet ... */
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* Now, add the 2nd segment again (but in a different frame) */
|
|
|
|
pinfo.num = 3;
|
|
|
|
fd_head=fragment_add(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
|
|
|
|
50, 60, TRUE);
|
|
|
|
|
|
|
|
/* This duplicate fragment should have been ignored */
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* finally, add the last fragment */
|
|
|
|
pinfo.num = 4;
|
|
|
|
fd_head=fragment_add(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
|
|
|
|
110, 40, FALSE);
|
|
|
|
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* check the contents of the structure */
|
|
|
|
ASSERT_EQ(4,fd_head->frame); /* max frame we have */
|
|
|
|
ASSERT_EQ(0,fd_head->offset); /* unused */
|
|
|
|
ASSERT_EQ(0,fd_head->len); /* unused */
|
|
|
|
ASSERT_EQ(150,fd_head->datalen);
|
|
|
|
ASSERT_EQ(4,fd_head->reassembled_in);
|
|
|
|
ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next);
|
|
|
|
|
|
|
|
fd = fd_head->next;
|
|
|
|
ASSERT_EQ(1,fd->frame);
|
|
|
|
ASSERT_EQ(0,fd->offset);
|
|
|
|
ASSERT_EQ(50,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd = fd->next;
|
|
|
|
ASSERT_EQ(2,fd->frame);
|
|
|
|
ASSERT_EQ(50,fd->offset);
|
|
|
|
ASSERT_EQ(60,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd = fd->next;
|
|
|
|
ASSERT_EQ(3,fd->frame);
|
|
|
|
ASSERT_EQ(50,fd->offset);
|
|
|
|
ASSERT_EQ(60,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(FD_OVERLAP,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd = fd->next;
|
|
|
|
ASSERT_EQ(4,fd->frame);
|
|
|
|
ASSERT_EQ(110,fd->offset);
|
|
|
|
ASSERT_EQ(40,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
/* test the actual reassembly */
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
|
|
|
|
|
2021-02-19 11:51:19 +00:00
|
|
|
if (debug) {
|
|
|
|
print_fragment_table();
|
|
|
|
}
|
2020-09-24 14:11:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* XXX: Is the proper behavior here really throwing an exception instead
|
|
|
|
* of setting FD_OVERLAP?
|
|
|
|
*/
|
|
|
|
/* Test case for fragment_add with duplicated (e.g., retransmitted) data.
|
|
|
|
* Adds three fragments--adding the 3rd one twice--
|
|
|
|
* and checks that they are reassembled correctly.
|
|
|
|
*/
|
|
|
|
/* visit id frame frag len more tvb_offset
|
|
|
|
0 12 1 0 50 T 10
|
|
|
|
0 12 2 1 60 T 5
|
|
|
|
0 12 3 2 40 F 5
|
|
|
|
0 12 4 2 40 F 5
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
test_fragment_add_duplicate_last(void)
|
|
|
|
{
|
|
|
|
fragment_head *fd_head;
|
|
|
|
fragment_item *fd;
|
|
|
|
volatile gboolean ex_thrown;
|
|
|
|
|
|
|
|
printf("Starting test test_fragment_add_duplicate_last\n");
|
|
|
|
|
|
|
|
pinfo.num = 1;
|
|
|
|
fd_head=fragment_add(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
|
|
|
|
0, 50, TRUE);
|
|
|
|
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* Add the 2nd segment */
|
|
|
|
pinfo.num = 2;
|
|
|
|
fd_head=fragment_add(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
|
|
|
|
50, 60, TRUE);
|
|
|
|
|
|
|
|
/* we haven't got all the fragments yet ... */
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* Add the last fragment */
|
|
|
|
pinfo.num = 3;
|
|
|
|
fd_head=fragment_add(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
|
|
|
|
110, 40, FALSE);
|
|
|
|
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* Add the last fragment again */
|
|
|
|
pinfo.num = 4;
|
|
|
|
/* XXX: The current reassemble.c code for fragment_add() throws an
|
|
|
|
* exception and doesn't try to add a duplicate if and only if the
|
|
|
|
* assembly is already completed. This means that it doesn't get
|
|
|
|
* put in the linked list. This is counter to how the _seq functions
|
|
|
|
* work, as well as to how this code works if a duplicate comes in the
|
|
|
|
* middle instead of at the end. Test matches current code, but the
|
|
|
|
* current code should perhaps be changed. */
|
|
|
|
ex_thrown = FALSE;
|
|
|
|
TRY {
|
|
|
|
fd_head=fragment_add(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
|
|
|
|
110, 40, FALSE);
|
|
|
|
}
|
|
|
|
CATCH(ReassemblyError) {
|
|
|
|
ex_thrown = TRUE;
|
|
|
|
}
|
|
|
|
ENDTRY;
|
|
|
|
|
|
|
|
ASSERT_EQ(TRUE, ex_thrown);
|
|
|
|
|
|
|
|
/* Reassembly should have still succeeded */
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* check the contents of the structure */
|
|
|
|
/* ASSERT_EQ(4,fd_head->frame); never add the last frame again */
|
|
|
|
ASSERT_EQ(3,fd_head->frame); /* max frame we have */
|
|
|
|
ASSERT_EQ(0,fd_head->offset); /* unused */
|
|
|
|
ASSERT_EQ(0,fd_head->len); /* unused */
|
|
|
|
ASSERT_EQ(150,fd_head->datalen);
|
|
|
|
ASSERT_EQ(3,fd_head->reassembled_in);
|
|
|
|
/* ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
|
|
|
|
* FD_OVERLAP doesn't get set since we don't add a fragment after the
|
|
|
|
* end but throw an exception instead. */
|
|
|
|
ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET,fd_head->flags);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next);
|
|
|
|
|
|
|
|
fd = fd_head->next;
|
|
|
|
ASSERT_EQ(1,fd->frame);
|
|
|
|
ASSERT_EQ(0,fd->offset);
|
|
|
|
ASSERT_EQ(50,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd = fd->next;
|
|
|
|
ASSERT_EQ(2,fd->frame);
|
|
|
|
ASSERT_EQ(50,fd->offset);
|
|
|
|
ASSERT_EQ(60,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd = fd->next;
|
|
|
|
ASSERT_EQ(3,fd->frame);
|
|
|
|
ASSERT_EQ(110,fd->offset);
|
|
|
|
ASSERT_EQ(40,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
|
|
|
|
/* Duplicate packet never gets added
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd = fd->next;
|
|
|
|
ASSERT_EQ(4,fd->frame);
|
|
|
|
ASSERT_EQ(110,fd->offset);
|
|
|
|
ASSERT_EQ(40,fd->len);
|
|
|
|
ASSERT_EQ(FD_OVERLAP,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->next); */
|
|
|
|
|
|
|
|
/* test the actual reassembly */
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
|
|
|
|
|
2021-02-19 11:51:19 +00:00
|
|
|
if (debug) {
|
|
|
|
print_fragment_table();
|
|
|
|
}
|
2020-09-24 14:11:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Test case for fragment_add with duplicated (e.g., retransmitted) data
|
|
|
|
* where the retransmission "conflicts" with the original transmission
|
|
|
|
* (contents are different).
|
|
|
|
* Adds three fragments--adding the 2nd one twice--
|
|
|
|
* and checks that they are reassembled correctly.
|
|
|
|
*/
|
|
|
|
/* visit id frame frag_off len more tvb_offset
|
|
|
|
0 12 1 0 50 T 10
|
|
|
|
0 12 2 50 60 T 5
|
|
|
|
0 12 3 50 60 T 15
|
|
|
|
0 12 4 110 40 F 5
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
test_fragment_add_duplicate_conflict(void)
|
|
|
|
{
|
|
|
|
fragment_head *fd_head;
|
|
|
|
fragment_item *fd;
|
|
|
|
|
|
|
|
printf("Starting test test_fragment_add_duplicate_conflict\n");
|
|
|
|
|
|
|
|
pinfo.num = 1;
|
|
|
|
fd_head=fragment_add(&test_reassembly_table, tvb, 10, &pinfo, 12, NULL,
|
|
|
|
0, 50, TRUE);
|
|
|
|
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* Add the 2nd segment */
|
|
|
|
pinfo.num = 2;
|
|
|
|
fd_head=fragment_add(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
|
|
|
|
50, 60, TRUE);
|
|
|
|
|
|
|
|
/* we haven't got all the fragments yet ... */
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* Now, add the 2nd segment again (but in a different frame and with
|
|
|
|
* different data)
|
|
|
|
*/
|
|
|
|
pinfo.num = 3;
|
|
|
|
fd_head=fragment_add(&test_reassembly_table, tvb, 15, &pinfo, 12, NULL,
|
|
|
|
50, 60, TRUE);
|
|
|
|
|
|
|
|
/* This duplicate fragment should have been ignored */
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* finally, add the last fragment */
|
|
|
|
pinfo.num = 4;
|
|
|
|
fd_head=fragment_add(&test_reassembly_table, tvb, 5, &pinfo, 12, NULL,
|
|
|
|
110, 40, FALSE);
|
|
|
|
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* check the contents of the structure */
|
|
|
|
ASSERT_EQ(4,fd_head->frame); /* max frame we have */
|
|
|
|
ASSERT_EQ(0,fd_head->offset); /* unused */
|
|
|
|
ASSERT_EQ(0,fd_head->len); /* unused */
|
|
|
|
ASSERT_EQ(150,fd_head->datalen);
|
|
|
|
ASSERT_EQ(4,fd_head->reassembled_in);
|
|
|
|
ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET|FD_OVERLAP|FD_OVERLAPCONFLICT,fd_head->flags);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next);
|
|
|
|
|
|
|
|
fd = fd_head->next;
|
|
|
|
ASSERT_EQ(1,fd->frame);
|
|
|
|
ASSERT_EQ(0,fd->offset);
|
|
|
|
ASSERT_EQ(50,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd = fd->next;
|
|
|
|
ASSERT_EQ(2,fd->frame);
|
|
|
|
ASSERT_EQ(50,fd->offset);
|
|
|
|
ASSERT_EQ(60,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd = fd->next;
|
|
|
|
ASSERT_EQ(3,fd->frame);
|
|
|
|
ASSERT_EQ(50,fd->offset);
|
|
|
|
ASSERT_EQ(60,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(FD_OVERLAP|FD_OVERLAPCONFLICT,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd = fd->next;
|
|
|
|
ASSERT_EQ(4,fd->frame);
|
|
|
|
ASSERT_EQ(110,fd->offset);
|
|
|
|
ASSERT_EQ(40,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
/* test the actual reassembly */
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
|
|
|
|
|
2021-02-19 11:51:19 +00:00
|
|
|
if (debug) {
|
|
|
|
print_fragment_table();
|
|
|
|
}
|
2020-09-24 14:11:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**********************************************************************************
|
|
|
|
*
|
|
|
|
* fragment_add_check
|
|
|
|
*
|
|
|
|
*********************************************************************************/
|
|
|
|
|
|
|
|
/* Simple test case for fragment_add_check.
|
|
|
|
* Adds three fragments (out of order, with one for a different datagram in between),
|
|
|
|
* and checks that they are reassembled correctly.
|
|
|
|
*/
|
|
|
|
/* visit id frame frag_offset len more tvb_offset
|
|
|
|
0 12 1 0 50 T 10
|
|
|
|
1 12 1 0 60 T 5
|
|
|
|
0 13 2 0 60 T 15
|
|
|
|
0 12 3 110 60 F 5
|
|
|
|
0 12 4 50 60 T 15
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
test_simple_fragment_add_check(void)
|
|
|
|
{
|
|
|
|
fragment_head *fd_head, *fdh0;
|
|
|
|
fragment_item *fd;
|
|
|
|
|
|
|
|
printf("Starting test test_simple_fragment_add_check\n");
|
|
|
|
|
|
|
|
pinfo.num = 1;
|
|
|
|
fd_head=fragment_add_check(&test_reassembly_table, tvb, 10, &pinfo, 12,
|
|
|
|
NULL, 0, 50, TRUE);
|
|
|
|
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* adding the same fragment again should do nothing, even with different
|
|
|
|
* offset etc */
|
|
|
|
pinfo.fd->visited = 1;
|
|
|
|
fd_head=fragment_add_check(&test_reassembly_table, tvb, 5, &pinfo, 12,
|
|
|
|
NULL, 0, 60, TRUE);
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* start another pdu (just to confuse things) */
|
|
|
|
pinfo.fd->visited = 0;
|
|
|
|
pinfo.num = 2;
|
|
|
|
fd_head=fragment_add_check(&test_reassembly_table, tvb, 15, &pinfo, 13,
|
|
|
|
NULL, 0, 60, TRUE);
|
|
|
|
ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* now we add the terminal fragment of the first datagram */
|
|
|
|
pinfo.num = 3;
|
|
|
|
fd_head=fragment_add_check(&test_reassembly_table, tvb, 5, &pinfo, 12,
|
|
|
|
NULL, 110, 60, FALSE);
|
|
|
|
|
|
|
|
/* we haven't got all the fragments yet ... */
|
|
|
|
ASSERT_EQ(2,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* finally, add the missing fragment */
|
|
|
|
pinfo.num = 4;
|
|
|
|
fd_head=fragment_add_check(&test_reassembly_table, tvb, 15, &pinfo, 12,
|
|
|
|
NULL, 50, 60, TRUE);
|
|
|
|
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(3,g_hash_table_size(test_reassembly_table.reassembled_table));
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* check the contents of the structure */
|
|
|
|
ASSERT_EQ(4,fd_head->frame); /* max frame number of fragment in assembly */
|
|
|
|
ASSERT_EQ(0,fd_head->offset); /* unused */
|
|
|
|
ASSERT_EQ(0,fd_head->len); /* unused in fragment_add */
|
|
|
|
ASSERT_EQ(170,fd_head->datalen); /* total datalen of assembly */
|
|
|
|
ASSERT_EQ(4,fd_head->reassembled_in);
|
|
|
|
ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET,fd_head->flags);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next);
|
|
|
|
|
|
|
|
fd = fd_head->next;
|
|
|
|
ASSERT_EQ(1,fd->frame);
|
|
|
|
ASSERT_EQ(0,fd->offset);
|
|
|
|
ASSERT_EQ(50,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd = fd->next;
|
|
|
|
ASSERT_EQ(4,fd->frame);
|
|
|
|
ASSERT_EQ(50,fd->offset);
|
|
|
|
ASSERT_EQ(60,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd = fd->next;
|
|
|
|
ASSERT_EQ(3,fd->frame);
|
|
|
|
ASSERT_EQ(110,fd->offset);
|
|
|
|
ASSERT_EQ(60,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
/* test the actual reassembly */
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+15,60));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,60));
|
|
|
|
|
2021-02-19 11:51:19 +00:00
|
|
|
if (debug) {
|
|
|
|
print_fragment_table();
|
|
|
|
}
|
2020-09-24 14:11:00 +00:00
|
|
|
|
|
|
|
/* what happens if we revisit the packets now? */
|
|
|
|
fdh0 = fd_head;
|
|
|
|
pinfo.fd->visited = 1;
|
|
|
|
pinfo.num = 1;
|
|
|
|
fd_head=fragment_add_check(&test_reassembly_table, tvb, 10, &pinfo, 12,
|
|
|
|
NULL, 0, 50, TRUE);
|
|
|
|
/*
|
|
|
|
* this api relies on the caller to check fd_head -> reassembled_in
|
|
|
|
*
|
|
|
|
* Redoing all the tests seems like overkill - just check the pointer
|
|
|
|
*/
|
|
|
|
ASSERT_EQ_POINTER(fdh0,fd_head);
|
|
|
|
|
|
|
|
pinfo.num = 3;
|
|
|
|
fd_head=fragment_add_check(&test_reassembly_table, tvb, 5, &pinfo, 12,
|
|
|
|
NULL, 110, 60, FALSE);
|
|
|
|
ASSERT_EQ_POINTER(fdh0,fd_head);
|
|
|
|
|
|
|
|
pinfo.num = 4;
|
|
|
|
fd_head=fragment_add_check(&test_reassembly_table, tvb, 15, &pinfo, 12,
|
|
|
|
NULL, 50, 60, TRUE);
|
|
|
|
ASSERT_EQ_POINTER(fdh0,fd_head);
|
|
|
|
|
2021-02-19 11:51:19 +00:00
|
|
|
if (debug) {
|
|
|
|
print_fragment_table();
|
|
|
|
}
|
2020-09-24 14:11:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
/* XXX: fragment_set_partial_reassembly() does not work for fragment_add_check
|
|
|
|
* because it doesn't remove the previously completed reassembly from
|
|
|
|
* reassembled_table (and lookup_fd_head() only looks in the fragment
|
|
|
|
* table, not the reassembled_table) */
|
|
|
|
/* This tests the functionality of fragment_set_partial_reassembly for
|
|
|
|
* fragment_add_check based reassembly.
|
|
|
|
*
|
|
|
|
* We add a sequence of fragments thus:
|
|
|
|
* seq_off frame tvb_off len (initial) more_frags
|
|
|
|
* ------- ----- ------- --- --------------------
|
|
|
|
* 0 1 10 50 false
|
|
|
|
* 50 2 0 40 true
|
|
|
|
* 50 3 0 40 true (a duplicate fragment)
|
|
|
|
* 90 4 20 100 false
|
|
|
|
* 190 5 0 40 false
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
test_fragment_add_check_partial_reassembly(void)
|
|
|
|
{
|
|
|
|
fragment_head *fd_head;
|
|
|
|
fragment_item *fd;
|
|
|
|
|
|
|
|
printf("Starting test test_fragment_add_check_partial_reassembly\n");
|
|
|
|
|
|
|
|
/* generally it's probably fair to assume that we will be called with
|
|
|
|
* more_frags=FALSE.
|
|
|
|
*/
|
|
|
|
pinfo.num = 1;
|
|
|
|
fd_head=fragment_add_check(&test_reassembly_table, tvb, 10, &pinfo, 12,
|
|
|
|
NULL, 0, 50, FALSE);
|
|
|
|
|
|
|
|
ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.reassembled_table));
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* check the contents of the structure */
|
|
|
|
ASSERT_EQ(1,fd_head->frame); /* max frame in reassembly */
|
|
|
|
ASSERT_EQ(0,fd_head->offset); /* unused */
|
|
|
|
ASSERT_EQ(0,fd_head->len); /* unused */
|
|
|
|
ASSERT_EQ(50,fd_head->datalen); /* the length of data we we have */
|
|
|
|
ASSERT_EQ(1,fd_head->reassembled_in);
|
|
|
|
ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET,fd_head->flags);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next);
|
|
|
|
|
|
|
|
ASSERT_EQ(1,fd_head->next->frame);
|
|
|
|
ASSERT_EQ(0,fd_head->next->offset); /* offset */
|
|
|
|
ASSERT_EQ(50,fd_head->next->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd_head->next->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next->tvb_data);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head->next->next);
|
|
|
|
|
|
|
|
/* test the actual reassembly */
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
|
|
|
|
|
|
|
|
/* now we announce that the reassembly wasn't complete after all. */
|
|
|
|
fragment_set_partial_reassembly(&test_reassembly_table, &pinfo, 12, NULL);
|
|
|
|
|
|
|
|
/* and add another segment. To mix things up slightly (and so that we can
|
|
|
|
* check on the state of things), we're going to set the more_frags flag
|
|
|
|
* here
|
|
|
|
*/
|
|
|
|
pinfo.num = 2;
|
|
|
|
fd_head=fragment_add_check(&test_reassembly_table, tvb, 0, &pinfo, 12,
|
|
|
|
NULL, 50, 40, TRUE);
|
|
|
|
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.reassembled_table));
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
fd_head=fragment_get(&test_reassembly_table, &pinfo, 12, NULL);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* check the contents of the structure */
|
|
|
|
ASSERT_EQ(2,fd_head->frame); /* max frame in reassembly */
|
|
|
|
ASSERT_EQ(0,fd_head->offset); /* unused */
|
|
|
|
ASSERT_EQ(0,fd_head->len); /* unused */
|
|
|
|
/* ASSERT_EQ(0,fd_head->datalen);
|
|
|
|
* reassembly not finished; datalen not well defined.
|
|
|
|
* Current implemenation has it as 0, could change to 90 without issues */
|
|
|
|
ASSERT_EQ(0,fd_head->reassembled_in);
|
|
|
|
ASSERT_EQ(0,fd_head->flags);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next);
|
|
|
|
|
|
|
|
fd=fd_head->next;
|
|
|
|
ASSERT_EQ(1,fd->frame);
|
|
|
|
ASSERT_EQ(0,fd->offset); /* offset */
|
|
|
|
ASSERT_EQ(50,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(FD_SUBSET_TVB,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(tvb_get_ptr(fd_head->tvb_data,0,0),tvb_get_ptr(fd->tvb_data,0,0));
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd=fd->next;
|
|
|
|
ASSERT_EQ(2,fd->frame);
|
|
|
|
ASSERT_EQ(50,fd->offset); /* offset */
|
|
|
|
ASSERT_EQ(40,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
/* Another copy of the second segment.
|
|
|
|
*/
|
|
|
|
pinfo.num = 3;
|
|
|
|
fd_head=fragment_add_check(&test_reassembly_table, tvb, 0, &pinfo, 12,
|
|
|
|
NULL, 50, 40, TRUE);
|
|
|
|
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
|
|
|
fd_head=fragment_get(&test_reassembly_table, &pinfo, 12, NULL);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head);
|
|
|
|
ASSERT_EQ(3,fd_head->frame); /* max frame we have */
|
|
|
|
ASSERT_EQ(0,fd_head->offset); /* unused */
|
|
|
|
ASSERT_EQ(0,fd_head->len); /* unused */
|
|
|
|
/* ASSERT_EQ(0,fd_head->datalen);
|
|
|
|
* reassembly not finished; datalen not well defined.
|
|
|
|
* Current implemenation has it as 0, could change to 90 without issues */
|
|
|
|
ASSERT_EQ(0,fd_head->reassembled_in);
|
|
|
|
ASSERT_EQ(0,fd_head->flags);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next);
|
|
|
|
|
|
|
|
fd=fd_head->next;
|
|
|
|
ASSERT_EQ(1,fd->frame);
|
|
|
|
ASSERT_EQ(0,fd->offset);
|
|
|
|
ASSERT_EQ(50,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(FD_SUBSET_TVB,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(tvb_get_ptr(fd_head->tvb_data,0,0),tvb_get_ptr(fd->tvb_data,0,0));
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd=fd->next;
|
|
|
|
ASSERT_EQ(2,fd->frame);
|
|
|
|
ASSERT_EQ(50,fd->offset);
|
|
|
|
ASSERT_EQ(40,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd=fd->next;
|
|
|
|
ASSERT_EQ(3,fd->frame);
|
|
|
|
ASSERT_EQ(50,fd->offset);
|
|
|
|
ASSERT_EQ(40,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* have another go at wrapping things up */
|
|
|
|
pinfo.num = 4;
|
|
|
|
fd_head=fragment_add_check(&test_reassembly_table, tvb, 20, &pinfo, 12,
|
|
|
|
NULL, 90, 100, FALSE);
|
|
|
|
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* check the contents of the structure */
|
|
|
|
ASSERT_EQ(4,fd_head->frame); /* max frame we have */
|
|
|
|
ASSERT_EQ(0,fd_head->offset); /* unused */
|
|
|
|
ASSERT_EQ(0,fd_head->len); /* unused */
|
|
|
|
ASSERT_EQ(190,fd_head->datalen); /* the length of data we have */
|
|
|
|
ASSERT_EQ(4,fd_head->reassembled_in);
|
|
|
|
ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next);
|
|
|
|
|
|
|
|
fd=fd_head->next;
|
|
|
|
ASSERT_EQ(1,fd->frame);
|
|
|
|
ASSERT_EQ(0,fd->offset);
|
|
|
|
ASSERT_EQ(50,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd=fd->next;
|
|
|
|
ASSERT_EQ(2,fd->frame);
|
|
|
|
ASSERT_EQ(50,fd->offset);
|
|
|
|
ASSERT_EQ(40,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd=fd->next;
|
|
|
|
ASSERT_EQ(3,fd->frame);
|
|
|
|
ASSERT_EQ(50,fd->offset);
|
|
|
|
ASSERT_EQ(40,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(FD_OVERLAP,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd=fd->next;
|
|
|
|
ASSERT_EQ(4,fd->frame);
|
|
|
|
ASSERT_EQ(90,fd->offset);
|
|
|
|
ASSERT_EQ(100,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
/* test the actual reassembly */
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,50,data,40));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,90,data+20,100));
|
|
|
|
|
|
|
|
|
|
|
|
/* do it again (this time it is more complicated, with an overlap in the
|
|
|
|
* reassembly) */
|
|
|
|
|
|
|
|
fragment_set_partial_reassembly(&test_reassembly_table, &pinfo, 12, NULL);
|
|
|
|
|
|
|
|
pinfo.num = 5;
|
|
|
|
fragment_add_check(&test_reassembly_table, tvb, 0, &pinfo, 12, NULL,
|
|
|
|
190, 40, FALSE);
|
|
|
|
|
|
|
|
fd_head=fragment_get(&test_reassembly_table, &pinfo, 12, NULL);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head);
|
|
|
|
ASSERT_EQ(5,fd_head->frame); /* max frame we have */
|
|
|
|
ASSERT_EQ(0,fd_head->offset); /* unused */
|
|
|
|
ASSERT_EQ(0,fd_head->len); /* unused */
|
|
|
|
ASSERT_EQ(230,fd_head->datalen); /* the length of data we have */
|
|
|
|
ASSERT_EQ(5,fd_head->reassembled_in);
|
|
|
|
ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next);
|
|
|
|
|
|
|
|
fd=fd_head->next;
|
|
|
|
ASSERT_EQ(1,fd->frame);
|
|
|
|
ASSERT_EQ(0,fd->offset);
|
|
|
|
ASSERT_EQ(50,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd=fd->next;
|
|
|
|
ASSERT_EQ(2,fd->frame);
|
|
|
|
ASSERT_EQ(50,fd->offset);
|
|
|
|
ASSERT_EQ(40,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd=fd->next;
|
|
|
|
ASSERT_EQ(3,fd->frame);
|
|
|
|
ASSERT_EQ(50,fd->offset);
|
|
|
|
ASSERT_EQ(40,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(FD_OVERLAP,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd=fd->next;
|
|
|
|
ASSERT_EQ(4,fd->frame);
|
|
|
|
ASSERT_EQ(90,fd->offset);
|
|
|
|
ASSERT_EQ(100,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd=fd->next;
|
|
|
|
ASSERT_EQ(5,fd->frame);
|
|
|
|
ASSERT_EQ(190,fd->offset);
|
|
|
|
ASSERT_EQ(40,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
/* test the actual reassembly */
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,50,data,40));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,90,data+20,100));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,190,data,40));
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
/* XXX: fragment_add_check moves completed reassemblies to the
|
|
|
|
* reassembled_table, so adding a duplicated fragment after the end doesn't
|
|
|
|
* get marked as duplicate, but starts a new reassembly. This is the correct
|
|
|
|
* thing for very long captures where the identification field gets reused,
|
|
|
|
* somewhat wrong when it is retransmitted data (it won't get marked as such
|
|
|
|
* but doesn't interfere with defragmentation too much), and very wrong when
|
|
|
|
* there is both retransmitted data and later on the identification field
|
|
|
|
* gets reused (the dangling data will get added to the wrong reassembly.)
|
|
|
|
*
|
|
|
|
* Not sure what behavior to check. Possibly both behaviors should be supported,
|
|
|
|
* perhaps being affected by how close pinfo.num is to the reassembly, though
|
|
|
|
* that gets complicated.
|
|
|
|
*/
|
|
|
|
/* Test case for fragment_add_check with duplicated (e.g., retransmitted) data.
|
|
|
|
* Adds three fragments--adding the 1st one twice at the end--
|
|
|
|
* and checks that they are reassembled correctly.
|
|
|
|
*/
|
|
|
|
/* visit id frame frag_off len more tvb_offset
|
|
|
|
0 12 1 0 50 T 10
|
|
|
|
0 12 2 50 60 T 5
|
|
|
|
0 12 3 110 40 F 5
|
|
|
|
0 12 4 0 50 T 10
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
test_fragment_add_check_duplicate_first(void)
|
|
|
|
{
|
|
|
|
fragment_head *fd_head;
|
|
|
|
fragment_item *fd;
|
|
|
|
volatile gboolean ex_thrown;
|
|
|
|
|
|
|
|
printf("Starting test test_fragment_add_check_duplicate_first\n");
|
|
|
|
|
|
|
|
pinfo.num = 1;
|
|
|
|
fd_head=fragment_add_check(&test_reassembly_table, tvb, 10, &pinfo, 12,
|
|
|
|
NULL, 0, 50, TRUE);
|
|
|
|
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* Add the 2nd segment */
|
|
|
|
pinfo.num = 2;
|
|
|
|
fd_head=fragment_add_check(&test_reassembly_table, tvb, 5, &pinfo, 12,
|
|
|
|
NULL, 50, 60, TRUE);
|
|
|
|
|
|
|
|
/* we haven't got all the fragments yet ... */
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* Add the last fragment */
|
|
|
|
pinfo.num = 3;
|
|
|
|
fd_head=fragment_add_check(&test_reassembly_table, tvb, 5, &pinfo, 12,
|
|
|
|
NULL, 110, 40, FALSE);
|
|
|
|
|
|
|
|
ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(3,g_hash_table_size(test_reassembly_table.reassembled_table));
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* Add the first fragment again */
|
|
|
|
pinfo.num = 4;
|
|
|
|
fd_head=fragment_add_check(&test_reassembly_table, tvb, 10, &pinfo, 12,
|
|
|
|
NULL, 0, 50, TRUE);
|
|
|
|
|
|
|
|
/* Reassembly should have still succeeded */
|
|
|
|
/* XXX: Current behavior is to start a new reassembly - which is
|
|
|
|
* the proper behavior in a long capture that reuses the id, but the
|
|
|
|
* wrong thing when it's actually a retransmission. Should the distinction
|
|
|
|
* be made by analyzing pinfo.num to see if it is nearby? Or is that the
|
|
|
|
* dissector's job? */
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(3,g_hash_table_size(test_reassembly_table.reassembled_table));
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* check the contents of the structure */
|
|
|
|
/*ASSERT_EQ(4,fd_head->frame); max frame we have */
|
|
|
|
ASSERT_EQ(3,fd_head->frame); /* never add the duplicate frame */
|
|
|
|
ASSERT_EQ(0,fd_head->offset); /* unused */
|
|
|
|
ASSERT_EQ(0,fd_head->len); /* unused */
|
|
|
|
ASSERT_EQ(150,fd_head->datalen);
|
|
|
|
ASSERT_EQ(3,fd_head->reassembled_in);
|
|
|
|
/* ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags); */
|
|
|
|
/* FD_OVERLAP doesn't get set because we hit the exception early */
|
|
|
|
ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET,fd_head->flags);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next);
|
|
|
|
|
|
|
|
fd = fd_head->next;
|
|
|
|
|
|
|
|
ASSERT_EQ(1,fd->frame);
|
|
|
|
ASSERT_EQ(0,fd->offset);
|
|
|
|
ASSERT_EQ(50,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
/*
|
|
|
|
fd = fd_head->next;
|
|
|
|
ASSERT_EQ(4,fd->frame);
|
|
|
|
ASSERT_EQ(0,fd->offset);
|
|
|
|
ASSERT_EQ(50,fd->len);
|
|
|
|
ASSERT_EQ(FD_OVERLAP,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next); */
|
|
|
|
|
|
|
|
fd = fd->next;
|
|
|
|
ASSERT_EQ(2,fd->frame);
|
|
|
|
ASSERT_EQ(50,fd->offset);
|
|
|
|
ASSERT_EQ(60,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd = fd->next;
|
|
|
|
ASSERT_EQ(3,fd->frame);
|
|
|
|
ASSERT_EQ(110,fd->offset);
|
|
|
|
ASSERT_EQ(40,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
/* test the actual reassembly */
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
|
|
|
|
|
2021-02-19 11:51:19 +00:00
|
|
|
if (debug) {
|
|
|
|
print_fragment_table();
|
|
|
|
}
|
2020-09-24 14:11:00 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Test case for fragment_add_check with duplicated (e.g., retransmitted) data.
|
|
|
|
* Adds three fragments--adding the 2nd one twice--
|
|
|
|
* and checks that they are reassembled correctly.
|
|
|
|
*/
|
|
|
|
/* visit id frame frag_off len more tvb_offset
|
|
|
|
0 12 1 0 50 T 10
|
|
|
|
0 12 2 50 60 T 5
|
|
|
|
0 12 3 50 60 T 5
|
|
|
|
0 12 4 110 40 F 5
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
test_fragment_add_check_duplicate_middle(void)
|
|
|
|
{
|
|
|
|
fragment_head *fd_head;
|
|
|
|
fragment_item *fd;
|
|
|
|
|
|
|
|
printf("Starting test test_fragment_add_check_duplicate_middle\n");
|
|
|
|
|
|
|
|
pinfo.num = 1;
|
|
|
|
fd_head=fragment_add_check(&test_reassembly_table, tvb, 10, &pinfo, 12,
|
|
|
|
NULL, 0, 50, TRUE);
|
|
|
|
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* Add the 2nd segment */
|
|
|
|
pinfo.num = 2;
|
|
|
|
fd_head=fragment_add_check(&test_reassembly_table, tvb, 5, &pinfo, 12,
|
|
|
|
NULL, 50, 60, TRUE);
|
|
|
|
|
|
|
|
/* we haven't got all the fragments yet ... */
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* Now, add the 2nd segment again (but in a different frame) */
|
|
|
|
pinfo.num = 3;
|
|
|
|
fd_head=fragment_add_check(&test_reassembly_table, tvb, 5, &pinfo, 12,
|
|
|
|
NULL, 50, 60, TRUE);
|
|
|
|
|
|
|
|
/* This duplicate fragment should have been ignored */
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* finally, add the last fragment */
|
|
|
|
pinfo.num = 4;
|
|
|
|
fd_head=fragment_add_check(&test_reassembly_table, tvb, 5, &pinfo, 12,
|
|
|
|
NULL, 110, 40, FALSE);
|
|
|
|
|
|
|
|
ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(4,g_hash_table_size(test_reassembly_table.reassembled_table));
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* check the contents of the structure */
|
|
|
|
ASSERT_EQ(4,fd_head->frame); /* max frame we have */
|
|
|
|
ASSERT_EQ(0,fd_head->offset); /* unused */
|
|
|
|
ASSERT_EQ(0,fd_head->len); /* unused */
|
|
|
|
ASSERT_EQ(150,fd_head->datalen);
|
|
|
|
ASSERT_EQ(4,fd_head->reassembled_in);
|
|
|
|
ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next);
|
|
|
|
|
|
|
|
fd = fd_head->next;
|
|
|
|
ASSERT_EQ(1,fd->frame);
|
|
|
|
ASSERT_EQ(0,fd->offset);
|
|
|
|
ASSERT_EQ(50,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd = fd->next;
|
|
|
|
ASSERT_EQ(2,fd->frame);
|
|
|
|
ASSERT_EQ(50,fd->offset);
|
|
|
|
ASSERT_EQ(60,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd = fd->next;
|
|
|
|
ASSERT_EQ(3,fd->frame);
|
|
|
|
ASSERT_EQ(50,fd->offset);
|
|
|
|
ASSERT_EQ(60,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(FD_OVERLAP,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd = fd->next;
|
|
|
|
ASSERT_EQ(4,fd->frame);
|
|
|
|
ASSERT_EQ(110,fd->offset);
|
|
|
|
ASSERT_EQ(40,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
/* test the actual reassembly */
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
|
|
|
|
|
2021-02-19 11:51:19 +00:00
|
|
|
if (debug) {
|
|
|
|
print_fragment_table();
|
|
|
|
}
|
2020-09-24 14:11:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
/* XXX: same issue as test_fragment_add_check_duplicate_first, above.
|
|
|
|
*/
|
|
|
|
/* Test case for fragment_add_check with duplicated (e.g., retransmitted) data.
|
|
|
|
* Adds three fragments--adding the 3rd one twice--
|
|
|
|
* and checks that they are reassembled correctly.
|
|
|
|
*/
|
|
|
|
/* visit id frame frag len more tvb_offset
|
|
|
|
0 12 1 0 50 T 10
|
|
|
|
0 12 2 1 60 T 5
|
|
|
|
0 12 3 2 40 F 5
|
|
|
|
0 12 4 2 40 F 5
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
test_fragment_add_check_duplicate_last(void)
|
|
|
|
{
|
|
|
|
fragment_head *fd_head;
|
|
|
|
fragment_item *fd;
|
|
|
|
|
|
|
|
printf("Starting test test_fragment_add_check_duplicate_last\n");
|
|
|
|
|
|
|
|
pinfo.num = 1;
|
|
|
|
fd_head=fragment_add_check(&test_reassembly_table, tvb, 10, &pinfo, 12,
|
|
|
|
NULL, 0, 50, TRUE);
|
|
|
|
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* Add the 2nd segment */
|
|
|
|
pinfo.num = 2;
|
|
|
|
fd_head=fragment_add_check(&test_reassembly_table, tvb, 5, &pinfo, 12,
|
|
|
|
NULL, 50, 60, TRUE);
|
|
|
|
|
|
|
|
/* we haven't got all the fragments yet ... */
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* Add the last fragment */
|
|
|
|
pinfo.num = 3;
|
|
|
|
fd_head=fragment_add_check(&test_reassembly_table, tvb, 5, &pinfo, 12,
|
|
|
|
NULL, 110, 40, FALSE);
|
|
|
|
|
|
|
|
ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(3,g_hash_table_size(test_reassembly_table.reassembled_table));
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* Add the last fragment again */
|
|
|
|
pinfo.num = 4;
|
|
|
|
fd_head=fragment_add_check(&test_reassembly_table, tvb, 5, &pinfo, 12,
|
|
|
|
NULL, 110, 40, FALSE);
|
|
|
|
|
|
|
|
/* Reassembly should have still succeeded */
|
|
|
|
/* XXX: Current behavior is to start a new reassembly */
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(3,g_hash_table_size(test_reassembly_table.reassembled_table));
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* check the contents of the structure */
|
|
|
|
/* ASSERT_EQ(4,fd_head->frame); never add the last frame again */
|
|
|
|
ASSERT_EQ(3,fd_head->frame); /* max frame we have */
|
|
|
|
ASSERT_EQ(0,fd_head->offset); /* unused */
|
|
|
|
ASSERT_EQ(0,fd_head->len); /* unused */
|
|
|
|
ASSERT_EQ(150,fd_head->datalen);
|
|
|
|
ASSERT_EQ(3,fd_head->reassembled_in);
|
|
|
|
/* ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET|FD_OVERLAP,fd_head->flags);
|
|
|
|
* FD_OVERLAP doesn't get set since we don't add a fragment after the
|
|
|
|
* end but start a new assembly instead. */
|
|
|
|
ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET,fd_head->flags);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next);
|
|
|
|
|
|
|
|
fd = fd_head->next;
|
|
|
|
ASSERT_EQ(1,fd->frame);
|
|
|
|
ASSERT_EQ(0,fd->offset);
|
|
|
|
ASSERT_EQ(50,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd = fd->next;
|
|
|
|
ASSERT_EQ(2,fd->frame);
|
|
|
|
ASSERT_EQ(50,fd->offset);
|
|
|
|
ASSERT_EQ(60,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd = fd->next;
|
|
|
|
ASSERT_EQ(3,fd->frame);
|
|
|
|
ASSERT_EQ(110,fd->offset);
|
|
|
|
ASSERT_EQ(40,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
|
|
|
|
/* Duplicate packet never gets added
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd = fd->next;
|
|
|
|
ASSERT_EQ(4,fd->frame);
|
|
|
|
ASSERT_EQ(110,fd->offset);
|
|
|
|
ASSERT_EQ(40,fd->len);
|
|
|
|
ASSERT_EQ(FD_OVERLAP,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->next); */
|
|
|
|
|
|
|
|
/* test the actual reassembly */
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
|
|
|
|
|
2021-02-19 11:51:19 +00:00
|
|
|
if (debug) {
|
|
|
|
print_fragment_table();
|
|
|
|
}
|
2020-09-24 14:11:00 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Test case for fragment_add_check with duplicated (e.g., retransmitted) data
|
|
|
|
* where the retransmission "conflicts" with the original transmission
|
|
|
|
* (contents are different).
|
|
|
|
* Adds three fragments--adding the 2nd one twice--
|
|
|
|
* and checks that they are reassembled correctly.
|
|
|
|
*/
|
|
|
|
/* visit id frame frag_off len more tvb_offset
|
|
|
|
0 12 1 0 50 T 10
|
|
|
|
0 12 2 50 60 T 5
|
|
|
|
0 12 3 50 60 T 15
|
|
|
|
0 12 4 110 40 F 5
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
test_fragment_add_check_duplicate_conflict(void)
|
|
|
|
{
|
|
|
|
fragment_head *fd_head;
|
|
|
|
fragment_item *fd;
|
|
|
|
|
|
|
|
printf("Starting test test_fragment_add_check_duplicate_conflict\n");
|
|
|
|
|
|
|
|
pinfo.num = 1;
|
|
|
|
fd_head=fragment_add_check(&test_reassembly_table, tvb, 10, &pinfo, 12,
|
|
|
|
NULL, 0, 50, TRUE);
|
|
|
|
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* Add the 2nd segment */
|
|
|
|
pinfo.num = 2;
|
|
|
|
fd_head=fragment_add_check(&test_reassembly_table, tvb, 5, &pinfo, 12,
|
|
|
|
NULL, 50, 60, TRUE);
|
|
|
|
|
|
|
|
/* we haven't got all the fragments yet ... */
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* Now, add the 2nd segment again (but in a different frame and with
|
|
|
|
* different data)
|
|
|
|
*/
|
|
|
|
pinfo.num = 3;
|
|
|
|
fd_head=fragment_add_check(&test_reassembly_table, tvb, 15, &pinfo, 12,
|
|
|
|
NULL, 50, 60, TRUE);
|
|
|
|
|
|
|
|
ASSERT_EQ(1,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.reassembled_table));
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* finally, add the last fragment */
|
|
|
|
pinfo.num = 4;
|
|
|
|
fd_head=fragment_add_check(&test_reassembly_table, tvb, 5, &pinfo, 12,
|
|
|
|
NULL, 110, 40, FALSE);
|
|
|
|
|
|
|
|
ASSERT_EQ(0,g_hash_table_size(test_reassembly_table.fragment_table));
|
|
|
|
ASSERT_EQ(4,g_hash_table_size(test_reassembly_table.reassembled_table));
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head);
|
|
|
|
|
|
|
|
/* check the contents of the structure */
|
|
|
|
ASSERT_EQ(4,fd_head->frame); /* max frame we have */
|
|
|
|
ASSERT_EQ(0,fd_head->offset); /* unused */
|
|
|
|
ASSERT_EQ(0,fd_head->len); /* unused */
|
|
|
|
ASSERT_EQ(150,fd_head->datalen);
|
|
|
|
ASSERT_EQ(4,fd_head->reassembled_in);
|
|
|
|
ASSERT_EQ(FD_DEFRAGMENTED|FD_DATALEN_SET|FD_OVERLAP|FD_OVERLAPCONFLICT,fd_head->flags);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd_head->next);
|
|
|
|
|
|
|
|
fd = fd_head->next;
|
|
|
|
ASSERT_EQ(1,fd->frame);
|
|
|
|
ASSERT_EQ(0,fd->offset);
|
|
|
|
ASSERT_EQ(50,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd = fd->next;
|
|
|
|
ASSERT_EQ(2,fd->frame);
|
|
|
|
ASSERT_EQ(50,fd->offset);
|
|
|
|
ASSERT_EQ(60,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd = fd->next;
|
|
|
|
ASSERT_EQ(3,fd->frame);
|
|
|
|
ASSERT_EQ(50,fd->offset);
|
|
|
|
ASSERT_EQ(60,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(FD_OVERLAP|FD_OVERLAPCONFLICT,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_NE_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
fd = fd->next;
|
|
|
|
ASSERT_EQ(4,fd->frame);
|
|
|
|
ASSERT_EQ(110,fd->offset);
|
|
|
|
ASSERT_EQ(40,fd->len); /* segment length */
|
|
|
|
ASSERT_EQ(0,fd->flags);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->tvb_data);
|
|
|
|
ASSERT_EQ_POINTER(NULL,fd->next);
|
|
|
|
|
|
|
|
/* test the actual reassembly */
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,0,data+10,50));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,50,data+5,60));
|
|
|
|
ASSERT(!tvb_memeql(fd_head->tvb_data,110,data+5,40));
|
|
|
|
|
2021-02-19 11:51:19 +00:00
|
|
|
if (debug) {
|
|
|
|
print_fragment_table();
|
|
|
|
}
|
2020-09-24 14:11:00 +00:00
|
|
|
}
|
|
|
|
/**********************************************************************************
|
|
|
|
*
|
|
|
|
* main
|
|
|
|
*
|
|
|
|
*********************************************************************************/
|
|
|
|
|
|
|
|
int
|
|
|
|
main(int argc _U_, char **argv _U_)
|
|
|
|
{
|
|
|
|
frame_data fd;
|
|
|
|
static const guint8 src[] = {1,2,3,4}, dst[] = {5,6,7,8};
|
|
|
|
unsigned int i;
|
|
|
|
static void (*tests[])(void) = {
|
|
|
|
test_simple_fragment_add_seq, /* frag table only */
|
|
|
|
test_fragment_add_seq_partial_reassembly,
|
|
|
|
test_fragment_add_seq_duplicate_first,
|
|
|
|
test_fragment_add_seq_duplicate_middle,
|
|
|
|
test_fragment_add_seq_duplicate_last,
|
|
|
|
test_fragment_add_seq_duplicate_conflict,
|
|
|
|
test_fragment_add_seq_check, /* frag + reassemble */
|
|
|
|
test_fragment_add_seq_check_1,
|
|
|
|
test_fragment_add_seq_802_11_0,
|
|
|
|
test_fragment_add_seq_802_11_1,
|
|
|
|
test_simple_fragment_add_seq_next,
|
|
|
|
#if 0
|
|
|
|
test_missing_data_fragment_add_seq_next,
|
|
|
|
test_missing_data_fragment_add_seq_next_2,
|
|
|
|
test_missing_data_fragment_add_seq_next_3,
|
|
|
|
#endif
|
|
|
|
#if 0
|
|
|
|
test_fragment_add_seq_check_multiple
|
|
|
|
#endif
|
|
|
|
test_simple_fragment_add, /* frag table only */
|
|
|
|
test_fragment_add_partial_reassembly,
|
|
|
|
test_fragment_add_duplicate_first,
|
|
|
|
test_fragment_add_duplicate_middle,
|
|
|
|
test_fragment_add_duplicate_last,
|
|
|
|
test_fragment_add_duplicate_conflict,
|
|
|
|
test_simple_fragment_add_check, /* frag table only */
|
|
|
|
#if 0
|
|
|
|
test_fragment_add_check_partial_reassembly,
|
|
|
|
test_fragment_add_check_duplicate_first,
|
|
|
|
#endif
|
|
|
|
test_fragment_add_check_duplicate_middle,
|
|
|
|
#if 0
|
|
|
|
test_fragment_add_check_duplicate_last,
|
2010-12-10 15:35:59 +00:00
|
|
|
#endif
|
2020-09-24 14:11:00 +00:00
|
|
|
test_fragment_add_check_duplicate_conflict,
|
2007-02-21 06:19:03 +00:00
|
|
|
};
|
2009-09-06 18:25:23 +00:00
|
|
|
|
2007-02-21 06:19:03 +00:00
|
|
|
/* a tvbuff for testing with */
|
2020-07-01 08:19:22 +00:00
|
|
|
data = (guint8 *)g_malloc(DATA_LEN);
|
2007-02-21 06:19:03 +00:00
|
|
|
/* make sure it's full of stuff */
|
|
|
|
for(i=0; i<DATA_LEN; i++) {
|
|
|
|
data[i]=i & 0xFF;
|
|
|
|
}
|
|
|
|
tvb = tvb_new_real_data(data, DATA_LEN, DATA_LEN*2);
|
|
|
|
|
|
|
|
/* other test stuff */
|
|
|
|
pinfo.fd = &fd;
|
2018-12-27 02:26:24 +00:00
|
|
|
fd.visited = 0;
|
2015-10-21 19:04:16 +00:00
|
|
|
set_address(&pinfo.src,AT_IPv4,4,src);
|
|
|
|
set_address(&pinfo.dst,AT_IPv4,4,dst);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
for(i=0; i < sizeof(tests)/sizeof(tests[0]); i++ ) {
|
|
|
|
/* re-init the fragment tables */
|
2013-03-23 02:41:43 +00:00
|
|
|
reassembly_table_init(&test_reassembly_table,
|
2014-10-10 14:41:10 +00:00
|
|
|
&addresses_reassembly_table_functions);
|
2013-03-23 02:41:43 +00:00
|
|
|
ASSERT(test_reassembly_table.fragment_table != NULL);
|
|
|
|
ASSERT(test_reassembly_table.reassembled_table != NULL);
|
2007-02-21 06:19:03 +00:00
|
|
|
|
2018-12-27 02:26:24 +00:00
|
|
|
pinfo.fd->visited = FALSE;
|
2009-09-06 18:25:23 +00:00
|
|
|
|
2007-02-21 06:19:03 +00:00
|
|
|
tests[i]();
|
2010-12-10 15:35:59 +00:00
|
|
|
|
|
|
|
/* Free memory used by the tables */
|
2013-03-23 02:41:43 +00:00
|
|
|
reassembly_table_destroy(&test_reassembly_table);
|
2007-02-21 06:19:03 +00:00
|
|
|
}
|
|
|
|
|
2010-12-10 15:35:59 +00:00
|
|
|
tvb_free(tvb);
|
|
|
|
tvb = NULL;
|
|
|
|
g_free(data);
|
|
|
|
data = NULL;
|
|
|
|
|
2007-02-21 06:19:03 +00:00
|
|
|
printf(failure?"FAILURE\n":"SUCCESS\n");
|
|
|
|
return failure;
|
|
|
|
}
|
2014-10-10 14:41:10 +00:00
|
|
|
|
|
|
|
/*
|
2019-07-26 18:43:17 +00:00
|
|
|
* Editor modelines - https://www.wireshark.org/tools/modelines.html
|
2014-10-10 14:41:10 +00:00
|
|
|
*
|
|
|
|
* Local variables:
|
|
|
|
* c-basic-offset: 4
|
|
|
|
* tab-width: 8
|
|
|
|
* indent-tabs-mode: nil
|
|
|
|
* End:
|
|
|
|
*
|
|
|
|
* vi: set shiftwidth=4 tabstop=8 expandtab:
|
|
|
|
* :indentSize=4:tabSize=8:noTabs=true:
|
|
|
|
*/
|