hi, i have a protocol that is layered on top of UDP that splits up its own data stream. If a packet is bigger than some given size, it will be split into chunks. A flag byte that signals the presence of a multi-packet sequence and also the last packet, followed by an ID of the sequence and a packet sequence number. i do step by step like 1 but, the fragment_add_seq_check function always return 0. what is the problem? can any one help me? anything should be added to this example for reassemble correctly? my code is here:
#include "epan/packet.h"
#include "epan/reassemble.h"
#define FOO_PORT 1234
static int proto_foo = -1;
static int hf_foo_fragmentation = -1;
static int hf_foo_morefrag = -1;
static int hf_foo_sequenceno = -1;
static int hf_foo_sequenceid = -1;
static reassembly_table msg_reassembly_table;
static gint ett_foo = -1;
static int hf_msg_fragments = -1;
static int hf_msg_fragment = -1;
static int hf_msg_fragment_overlap = -1;
static int hf_msg_fragment_overlap_conflicts = -1;
static int hf_msg_fragment_multiple_tails = -1;
static int hf_msg_fragment_too_long_fragment = -1;
static int hf_msg_fragment_error = -1;
static int hf_msg_fragment_count = -1;
static int hf_msg_reassembled_in = -1;
static int hf_msg_reassembled_length = -1;
static int hf_msg_reassembled_data=-1;
static gint ett_msg_fragment = -1;
static gint ett_msg_fragments = -1;
static const fragment_items msg_frag_items = {
/* Fragment subtrees */
&ett_msg_fragment,
&ett_msg_fragments,
/* Fragment fields */
&hf_msg_fragments,
&hf_msg_fragment,
&hf_msg_fragment_overlap,
&hf_msg_fragment_overlap_conflicts,
&hf_msg_fragment_multiple_tails,
&hf_msg_fragment_too_long_fragment,
&hf_msg_fragment_error,
&hf_msg_fragment_count,
&hf_msg_reassembled_in,
/* Reassembled length field */
&hf_msg_reassembled_length,
&hf_msg_reassembled_data,
"Message fragments"
};
static int
dissect_foo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
{
gint offset = 0;
col_set_str(pinfo->cinfo, COL_PROTOCOL, "FOO");
col_clear(pinfo->cinfo,COL_INFO);
proto_item *ti = proto_tree_add_item(tree, proto_foo, tvb, 0, -1, ENC_NA);
proto_tree *foo_tree = proto_item_add_subtree(ti, ett_foo);
guint8 fragmentation=tvb_get_guint8(tvb,offset);
proto_tree_add_item(foo_tree, hf_foo_fragmentation, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
guint8 morefrag=tvb_get_guint8(tvb,offset);
proto_tree_add_item(foo_tree, hf_foo_morefrag, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
guint8 sequenceno=tvb_get_guint8(tvb,offset);
proto_tree_add_item(foo_tree, hf_foo_sequenceno, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
guint8 sequenceid=tvb_get_guint8(tvb,offset);
proto_tree_add_item(foo_tree, hf_foo_sequenceid, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
gboolean save_fragmented = pinfo->fragmented;
tvbuff_t *next_tvb;
if (fragmentation)
{ tvbuff_t* new_tvb = NULL;
fragment_head *frag_msg = NULL;
pinfo->fragmented = TRUE;
frag_msg = fragment_add_seq_check(&msg_reassembly_table,
tvb, offset, pinfo,
sequenceid, NULL,
sequenceno,
tvb_captured_length_remaining(tvb, offset),
morefrag);
new_tvb = process_reassembled_data(tvb, offset, pinfo,
"Reassembled Message", frag_msg, &msg_frag_items,
NULL, foo_tree);
if (frag_msg) { /* Reassembled */
col_append_str(pinfo->cinfo, COL_INFO,
" (Message Reassembled)");
} else { /* Not last packet of reassembled Short Message */
col_append_fstr(pinfo->cinfo, COL_INFO,
" (Message fragment %u)", foo_tree);
}
if (new_tvb) { /* take it all */
next_tvb = new_tvb;
} else { /* make a new subset */
next_tvb = tvb_new_subset_remaining(tvb, offset);
}
}
else { /* Not fragmented */
next_tvb = tvb_new_subset_remaining(tvb, offset);
}
pinfo->fragmented = save_fragmented;
return tvb_captured_length(tvb);
}
void
proto_register_foo(void)
{
static hf_register_info hf[] = {
{ &hf_foo_fragmentation,
{ "FOO PDU Fragmentation", "foo.fragmentation",
FT_UINT8, BASE_HEX,
NULL, 0x0,
NULL, HFILL }
},
{ &hf_foo_morefrag,
{ "FOO PDU MoreFrag", "foo.more.frag",
FT_UINT8, BASE_HEX,
NULL, 0x0,
NULL, HFILL }
},
{ &hf_foo_sequenceno,
{ "FOO PDU Sequence Number", "foo.seqn",
FT_UINT8, BASE_DEC,
NULL, 0x0,
NULL, HFILL }
},
{ &hf_foo_sequenceid,
{ "FOO PDU Sequence ID", "foo.seqn.id",
FT_UINT8, BASE_DEC,
NULL, 0x0,
NULL, HFILL }
},
{&hf_msg_fragments,
{"Message fragments", "msg.fragments",
FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL } },
{&hf_msg_fragment,
{"Message fragment", "msg.fragment",
FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
{&hf_msg_fragment_overlap,
{"Message fragment overlap", "msg.fragment.overlap",
FT_BOOLEAN, 0, NULL, 0x00, NULL, HFILL } },
{&hf_msg_fragment_overlap_conflicts,
{"Message fragment overlapping with conflicting data",
"msg.fragment.overlap.conflicts",
FT_BOOLEAN, 0, NULL, 0x00, NULL, HFILL } },
{&hf_msg_fragment_multiple_tails,
{"Message has multiple tail fragments",
"msg.fragment.multiple_tails",
FT_BOOLEAN, 0, NULL, 0x00, NULL, HFILL } },
{&hf_msg_fragment_too_long_fragment,
{"Message fragment too long", "msg.fragment.too_long_fragment",
FT_BOOLEAN, 0, NULL, 0x00, NULL, HFILL } },
{&hf_msg_fragment_error,
{"Message defragmentation error", "msg.fragment.error",
FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
{&hf_msg_fragment_count,
{"Message fragment count", "msg.fragment.count",
FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } },
{&hf_msg_reassembled_in,
{"Reassembled in", "msg.reassembled.in",
FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
{&hf_msg_reassembled_length,
{"Reassembled length", "msg.reassembled.length",
FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } },
{ &hf_msg_reassembled_data,
{ "Reassembled FOO Data", "foo.reassembled.data", FT_BYTES, BASE_NONE, NULL, 0x0,
"The reassembled payload", HFILL }},
};
/* Setup protocol subtree array */
static gint *ett[] = {
&ett_foo,
&ett_msg_fragment,
&ett_msg_fragments
};
proto_foo = proto_register_protocol (
"FOO Protocol", /* name */
"FOO", /* short name */
"foo" /* abbrev */
);
proto_register_field_array(proto_foo, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
reassembly_table_register(&msg_reassembly_table,
&addresses_ports_reassembly_table_functions);
}
void
proto_reg_handoff_foo(void)
{
static dissector_handle_t foo_handle;
foo_handle = create_dissector_handle(dissect_foo, proto_foo);
dissector_add_uint("udp.port", FOO_PORT, foo_handle);
}</code></pre></div><div id="question-tags" class="tags-container tags"><span class="post-tag tag-link-fragment_add" rel="tag" title="see questions tagged 'fragment_add'">fragment_add</span> <span class="post-tag tag-link-reassembly" rel="tag" title="see questions tagged 'reassembly'">reassembly</span></div><div id="question-controls" class="post-controls"><div class="community-wiki">This question is marked "community wiki".</div></div><div class="post-update-info-container"><div class="post-update-info post-update-info-user"><p>asked <strong>07 Jun '17, 00:01</strong></p><img src="https://secure.gravatar.com/avatar/0b6bdfea45d7093830a2a0638a758239?s=32&d=identicon&r=g" class="gravatar" width="32" height="32" alt="hhw's gravatar image" /><p><span>hhw</span><br />
10●4●7●11
accept rate: 100%
It would be useful to know how
fragment_add_seq_check()
is being called. In particular it would be useful to know what the values of the following parameters are for each call up to the final fragment (i.e., when reassembly should complete):id
frag_number
more_frags
IIRC you really want to see something like:
What is the value of morefrag when there are more fragments?
morefrag when there are more fragments is 1. if i have 3 packet the values are :