Add 6LoWPAN Selective Fragment Recovery
Reassemble fragments with RFRAG Dispatch type and header. Change-Id: Ifa30289069fda13fadc090fa5b78c0fcbfbae39e Reviewed-on: https://code.wireshark.org/review/32594 Petri-Dish: Alexis La Goutte <alexis.lagoutte@gmail.com> Tested-by: Petri Dish Buildbot Reviewed-by: Peter Wu <peter@lekensteyn.nl> Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
parent
43b85f102c
commit
dfbf88397e
|
@ -1,4 +1,10 @@
|
|||
/* packet-6lowpan.c
|
||||
*
|
||||
* Add Selective Fragment Recovery per
|
||||
* https://tools.ietf.org/html/draft-ietf-6lo-fragment-recovery-02
|
||||
* By James Ko <jck@exegin.com>
|
||||
* Copyright 2019 Exegin Technologies Limited
|
||||
*
|
||||
* Routines for 6LoWPAN packet disassembly
|
||||
* By Owen Kirby <osk@exegin.com>
|
||||
* Copyright 2009 Owen Kirby
|
||||
|
@ -47,6 +53,12 @@ void proto_reg_handoff_6lowpan(void);
|
|||
#define LOWPAN_PATTERN_FRAG1 0x18
|
||||
#define LOWPAN_PATTERN_FRAGN 0x1c
|
||||
#define LOWPAN_PATTERN_FRAG_BITS 5
|
||||
#define LOWPAN_PATTERN_RFRAG 0x74
|
||||
#define LOWPAN_PATTERN_RFRAG_ACK 0x75
|
||||
#define LOWPAN_PATTERN_RFRAG_BITS 7
|
||||
|
||||
#define LOWPAN_RFRAG_SEQUENCE_BITS 5
|
||||
#define LOWPAN_RFRAG_FRAG_SZ_BITS 10
|
||||
|
||||
/* RFC8025 and RFC8138 */
|
||||
#define LOWPAN_PATTERN_PAGING_DISPATCH 0xf
|
||||
|
@ -334,6 +346,16 @@ static int hf_6lowpan_frag_dgram_size = -1;
|
|||
static int hf_6lowpan_frag_dgram_tag = -1;
|
||||
static int hf_6lowpan_frag_dgram_offset = -1;
|
||||
|
||||
/* Recoverable Fragmentation header fields. */
|
||||
static int hf_6lowpan_rfrag_congestion = -1;
|
||||
static int hf_6lowpan_rfrag_ack_requested = -1;
|
||||
static int hf_6lowpan_rfrag_dgram_tag = -1;
|
||||
static int hf_6lowpan_rfrag_sequence = -1;
|
||||
static int hf_6lowpan_rfrag_size = -1;
|
||||
static int hf_6lowpan_rfrag_dgram_size = -1;
|
||||
static int hf_6lowpan_rfrag_offset = -1;
|
||||
static int hf_6lowpan_rfrag_ack_bitmap = -1;
|
||||
|
||||
/* Protocol tree handles. */
|
||||
static gint ett_6lowpan = -1;
|
||||
static gint ett_6lowpan_hc1 = -1;
|
||||
|
@ -368,6 +390,8 @@ static const value_string lowpan_patterns [] = {
|
|||
{ LOWPAN_PATTERN_MESH, "Mesh" },
|
||||
{ LOWPAN_PATTERN_FRAG1, "First fragment" },
|
||||
{ LOWPAN_PATTERN_FRAGN, "Fragment" },
|
||||
{ LOWPAN_PATTERN_RFRAG, "Recoverable Fragment" },
|
||||
{ LOWPAN_PATTERN_RFRAG_ACK, "Recoverable Fragment ACK" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
static const true_false_string lowpan_compression = {
|
||||
|
@ -586,6 +610,8 @@ static tvbuff_t * dissect_6lowpan_iphc (tvbuff_t *tvb, packet_info *pin
|
|||
static struct lowpan_nhdr *
|
||||
dissect_6lowpan_iphc_nhc (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset, gint dgram_size, const guint8 *siid, const guint8 *diid);
|
||||
static tvbuff_t * dissect_6lowpan_mesh (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint8 *siid, guint8 *diid);
|
||||
static tvbuff_t * dissect_6lowpan_rfrag (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, const guint8 *siid, const guint8 *diid);
|
||||
static tvbuff_t * dissect_6lowpan_rfrag_ack (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
|
||||
static tvbuff_t * dissect_6lowpan_frag_first (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, const guint8 *siid, const guint8 *diid);
|
||||
static tvbuff_t * dissect_6lowpan_frag_middle (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
|
||||
static void dissect_6lowpan_unknown (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
|
||||
|
@ -1139,6 +1165,8 @@ dissect_6lowpan_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *
|
|||
if ((mesh & LOWPAN_MESH_HEADER_HOPS) == LOWPAN_MESH_HEADER_HOPS) offset++;
|
||||
continue;
|
||||
}
|
||||
if (tvb_get_bits8(tvb, offset*8, LOWPAN_PATTERN_RFRAG_BITS) == LOWPAN_PATTERN_RFRAG) break;
|
||||
if (tvb_get_bits8(tvb, offset*8, LOWPAN_PATTERN_RFRAG_BITS) == LOWPAN_PATTERN_RFRAG_ACK) break;
|
||||
if (tvb_get_bits8(tvb, offset*8, LOWPAN_PATTERN_FRAG_BITS) == LOWPAN_PATTERN_FRAG1) {
|
||||
/* First fragment headers must be followed by another valid header. */
|
||||
offset += 4;
|
||||
|
@ -1202,6 +1230,15 @@ dissect_6lowpan(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data
|
|||
}
|
||||
|
||||
/* After the mesh and broadcast headers, process dispatch codes recursively. */
|
||||
/* Recoverable Fragmentation headers.*/
|
||||
if (tvb_get_bits8(next, 0, LOWPAN_PATTERN_RFRAG_BITS) == LOWPAN_PATTERN_RFRAG) {
|
||||
next = dissect_6lowpan_rfrag(next, pinfo, lowpan_tree, src_iid, dst_iid);
|
||||
if (!next) return tvb_captured_length(tvb);
|
||||
}
|
||||
else if (tvb_get_bits8(next, 0, LOWPAN_PATTERN_RFRAG_BITS) == LOWPAN_PATTERN_RFRAG_ACK) {
|
||||
next = dissect_6lowpan_rfrag_ack(next, pinfo, lowpan_tree);
|
||||
if (!next) return tvb_captured_length(tvb);
|
||||
}
|
||||
/* Fragmentation headers.*/
|
||||
if (tvb_get_bits8(next, 0, LOWPAN_PATTERN_FRAG_BITS) == LOWPAN_PATTERN_FRAG1) {
|
||||
next = dissect_6lowpan_frag_first(next, pinfo, lowpan_tree, src_iid, dst_iid);
|
||||
|
@ -2760,6 +2797,203 @@ dissect_6lowpan_mesh(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint8
|
|||
return tvb_new_subset_remaining(tvb, offset);
|
||||
} /* dissect_6lowpan_mesh */
|
||||
|
||||
/*FUNCTION:------------------------------------------------------
|
||||
* NAME
|
||||
* dissect_6lowpan_frag_headers
|
||||
* DESCRIPTION
|
||||
* Dissector routine for headers in the first fragment.
|
||||
* The first fragment can contain an uncompressed IPv6, HC1 or IPHC fragment.
|
||||
* PARAMETERS
|
||||
* tvb ; fragment buffer.
|
||||
* pinfo ; packet info.
|
||||
* tree ; 6LoWPAN display tree.
|
||||
* siid ; Source Interface ID.
|
||||
* diid ; Destination Interface ID.
|
||||
* RETURNS
|
||||
* tvbuff_t * ; buffer containing the uncompressed IPv6 headers
|
||||
*---------------------------------------------------------------
|
||||
*/
|
||||
static tvbuff_t *
|
||||
dissect_6lowpan_frag_headers(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *length_item, const guint8 *siid, const guint8 *diid)
|
||||
{
|
||||
tvbuff_t *frag_tvb = NULL;
|
||||
|
||||
/* The first fragment can contain an uncompressed IPv6, HC1 or IPHC fragment. */
|
||||
if (tvb_get_bits8(tvb, 0, LOWPAN_PATTERN_IPV6_BITS) == LOWPAN_PATTERN_IPV6) {
|
||||
frag_tvb = dissect_6lowpan_ipv6(tvb, pinfo, tree);
|
||||
}
|
||||
else if (tvb_get_bits8(tvb, 0, LOWPAN_PATTERN_HC1_BITS) == LOWPAN_PATTERN_HC1) {
|
||||
/* Check if the datagram size is sane. */
|
||||
if (tvb_reported_length(tvb) < IPv6_HDR_SIZE) {
|
||||
expert_add_info_format(pinfo, length_item, &ei_6lowpan_bad_ipv6_header_length,
|
||||
"Length is less than IPv6 header length %u", IPv6_HDR_SIZE);
|
||||
}
|
||||
frag_tvb = dissect_6lowpan_hc1(tvb, pinfo, tree, tvb_reported_length(tvb), siid, diid);
|
||||
}
|
||||
else if (tvb_get_bits8(tvb, 0, LOWPAN_PATTERN_IPHC_BITS) == LOWPAN_PATTERN_IPHC) {
|
||||
/* Check if the datagram size is sane. */
|
||||
if (tvb_reported_length(tvb) < IPv6_HDR_SIZE) {
|
||||
expert_add_info_format(pinfo, length_item, &ei_6lowpan_bad_ipv6_header_length,
|
||||
"Length is less than IPv6 header length %u", IPv6_HDR_SIZE);
|
||||
}
|
||||
frag_tvb = dissect_6lowpan_iphc(tvb, pinfo, tree, tvb_reported_length(tvb), siid, diid);
|
||||
}
|
||||
/* Unknown 6LoWPAN dispatch type */
|
||||
else {
|
||||
dissect_6lowpan_unknown(tvb, pinfo, tree);
|
||||
}
|
||||
return frag_tvb;
|
||||
} /* dissect_6lowpan_frag_headers */
|
||||
|
||||
/*FUNCTION:------------------------------------------------------
|
||||
* NAME
|
||||
* dissect_6lowpan_rfrag
|
||||
* DESCRIPTION
|
||||
* Dissector routine for a 6LoWPAN Recoverable Fragment headers.
|
||||
*
|
||||
* If reassembly could be completed, this should return an
|
||||
* uncompressed IPv6 packet. If reassembly had to be delayed
|
||||
* for more packets, this will return NULL.
|
||||
* PARAMETERS
|
||||
* tvb ; packet buffer.
|
||||
* pinfo ; packet info.
|
||||
* tree ; 6LoWPAN display tree.
|
||||
* siid ; Source Interface ID.
|
||||
* diid ; Destination Interface ID.
|
||||
* RETURNS
|
||||
* tvbuff_t * ; reassembled IPv6 packet.
|
||||
*---------------------------------------------------------------
|
||||
*/
|
||||
static tvbuff_t *
|
||||
dissect_6lowpan_rfrag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, const guint8 *siid, const guint8 *diid)
|
||||
{
|
||||
gint offset = 0;
|
||||
guint32 frag_size;
|
||||
guint32 dgram_tag;
|
||||
proto_tree * frag_tree;
|
||||
proto_item * ti;
|
||||
proto_item * length_item;
|
||||
/* Reassembly parameters. */
|
||||
tvbuff_t * new_tvb;
|
||||
tvbuff_t * frag_tvb;
|
||||
fragment_head * frag_data;
|
||||
gboolean save_fragmented;
|
||||
guint16 sequence;
|
||||
guint32 frag_offset;
|
||||
|
||||
/* Create a tree for the fragmentation header. */
|
||||
frag_tree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_6lowpan_frag, &ti, "RFRAG Header");
|
||||
|
||||
/* Get and display the pattern and explicit congestion bit. */
|
||||
proto_tree_add_bits_item(frag_tree, hf_6lowpan_pattern, tvb, offset * 8, LOWPAN_PATTERN_RFRAG_BITS, ENC_BIG_ENDIAN);
|
||||
proto_tree_add_item(frag_tree, hf_6lowpan_rfrag_congestion, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||||
offset += 1;
|
||||
|
||||
/* Get and display the datagram tag. */
|
||||
proto_tree_add_item_ret_uint(frag_tree, hf_6lowpan_rfrag_dgram_tag, tvb, offset, 1, ENC_BIG_ENDIAN, &dgram_tag);
|
||||
offset += 1;
|
||||
|
||||
proto_tree_add_item(frag_tree, hf_6lowpan_rfrag_ack_requested, tvb, offset, 2, ENC_BIG_ENDIAN);
|
||||
sequence = tvb_get_bits16(tvb, (offset * 8) + 1, LOWPAN_RFRAG_SEQUENCE_BITS, ENC_BIG_ENDIAN);
|
||||
proto_tree_add_item(frag_tree, hf_6lowpan_rfrag_sequence, tvb, offset, 2, ENC_BIG_ENDIAN);
|
||||
|
||||
frag_size = tvb_get_bits16(tvb, (offset * 8) + 1 + LOWPAN_RFRAG_SEQUENCE_BITS, LOWPAN_RFRAG_FRAG_SZ_BITS, ENC_BIG_ENDIAN);
|
||||
length_item = proto_tree_add_uint(frag_tree, hf_6lowpan_rfrag_size, tvb, offset * 8, 2, frag_size);
|
||||
offset += 2;
|
||||
|
||||
if (sequence) {
|
||||
proto_tree_add_item_ret_uint(frag_tree, hf_6lowpan_rfrag_offset, tvb, offset, 2, ENC_BIG_ENDIAN, &frag_offset);
|
||||
}
|
||||
else {
|
||||
proto_tree_add_item_ret_uint(frag_tree, hf_6lowpan_rfrag_dgram_size, tvb, offset, 2, ENC_BIG_ENDIAN, &frag_offset);
|
||||
}
|
||||
offset += 2;
|
||||
|
||||
/* Adjust the fragmentation header length. */
|
||||
proto_item_set_end(ti, tvb, offset);
|
||||
|
||||
frag_tvb = tvb_new_subset_length(tvb, offset, frag_size);
|
||||
if (sequence == 0) {
|
||||
dissect_6lowpan_frag_headers(frag_tvb, pinfo, tree, length_item, siid, diid);
|
||||
}
|
||||
|
||||
/* Add this datagram to the fragment table. */
|
||||
save_fragmented = pinfo->fragmented;
|
||||
pinfo->fragmented = TRUE;
|
||||
guint32 frag_id = lowpan_reassembly_id(pinfo, dgram_tag);
|
||||
if (sequence == 0) {
|
||||
frag_data = fragment_add_check(&lowpan_reassembly_table,
|
||||
frag_tvb, 0, pinfo, frag_id, NULL,
|
||||
0, frag_size, TRUE);
|
||||
fragment_set_tot_len(&lowpan_reassembly_table, pinfo, frag_id, NULL, frag_offset);
|
||||
}
|
||||
else {
|
||||
guint32 dgram_size = fragment_get_tot_len(&lowpan_reassembly_table, pinfo, frag_id, NULL);
|
||||
frag_data = fragment_add_check(&lowpan_reassembly_table,
|
||||
frag_tvb, 0, pinfo, frag_id, NULL,
|
||||
frag_offset, frag_size, (frag_offset+frag_size) < dgram_size);
|
||||
}
|
||||
|
||||
/* Attempt reassembly. */
|
||||
new_tvb = process_reassembled_data(frag_tvb, 0, pinfo,
|
||||
"Reassembled 6LoWPAN", frag_data, &lowpan_frag_items,
|
||||
NULL, tree);
|
||||
|
||||
pinfo->fragmented = save_fragmented;
|
||||
|
||||
if (new_tvb) {
|
||||
/* Reassembly was successful; return the completed datagram. */
|
||||
return new_tvb;
|
||||
} else {
|
||||
/* Reassembly was unsuccessful; show this fragment. This may
|
||||
just mean that we don't yet have all the fragments, so
|
||||
we should not just continue dissecting. */
|
||||
call_data_dissector(frag_tvb, pinfo, proto_tree_get_root(tree));
|
||||
return NULL;
|
||||
}
|
||||
} /* dissect_6lowpan_rfrag */
|
||||
|
||||
/*FUNCTION:------------------------------------------------------
|
||||
* NAME
|
||||
* dissect_6lowpan_rfrag_ack
|
||||
* DESCRIPTION
|
||||
* Dissector routine for a 6LoWPAN ACK Dispatch type and header
|
||||
* PARAMETERS
|
||||
* tvb ; packet buffer.
|
||||
* pinfo ; packet info.
|
||||
* tree ; 6LoWPAN display tree.
|
||||
* RETURNS
|
||||
* tvbuff_t * ; reassembled IPv6 packet.
|
||||
*---------------------------------------------------------------
|
||||
*/
|
||||
static tvbuff_t *
|
||||
dissect_6lowpan_rfrag_ack(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
||||
{
|
||||
gint offset = 0;
|
||||
proto_tree * frag_tree;
|
||||
proto_item * ti;
|
||||
(void)pinfo;
|
||||
|
||||
/* Create a tree for the fragmentation header. */
|
||||
frag_tree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_6lowpan_frag, &ti, "RFRAG ACK Header");
|
||||
|
||||
/* Get and display the pattern and explicit congestion bit. */
|
||||
proto_tree_add_bits_item(frag_tree, hf_6lowpan_pattern, tvb, offset * 8, LOWPAN_PATTERN_RFRAG_BITS, ENC_BIG_ENDIAN);
|
||||
proto_tree_add_item(frag_tree, hf_6lowpan_rfrag_congestion, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||||
offset += 1;
|
||||
|
||||
/* Get and display the datagram tag. */
|
||||
proto_tree_add_item(frag_tree, hf_6lowpan_rfrag_dgram_tag, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||||
offset += 1;
|
||||
|
||||
proto_tree_add_bits_item(frag_tree, hf_6lowpan_rfrag_ack_bitmap, tvb, offset * 8, 32, ENC_BIG_ENDIAN);
|
||||
offset += 4;
|
||||
|
||||
/* TODO: Match ACK bits to original fragments? */
|
||||
|
||||
return tvb_new_subset_remaining(tvb, offset);
|
||||
} /* dissect_6lowpan_rfrag_ack */
|
||||
|
||||
/*FUNCTION:------------------------------------------------------
|
||||
* NAME
|
||||
* dissect_6lowpan_frag_first
|
||||
|
@ -2812,33 +3046,9 @@ dissect_6lowpan_frag_first(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
|||
/* Adjust the fragmentation header length. */
|
||||
proto_item_set_end(ti, tvb, offset);
|
||||
|
||||
/* The first fragment can contain an uncompressed IPv6, HC1 or IPHC fragment. */
|
||||
frag_tvb = tvb_new_subset_remaining(tvb, offset);
|
||||
if (tvb_get_bits8(frag_tvb, 0, LOWPAN_PATTERN_IPV6_BITS) == LOWPAN_PATTERN_IPV6) {
|
||||
frag_tvb = dissect_6lowpan_ipv6(frag_tvb, pinfo, tree);
|
||||
}
|
||||
else if (tvb_get_bits8(frag_tvb, 0, LOWPAN_PATTERN_HC1_BITS) == LOWPAN_PATTERN_HC1) {
|
||||
/* Check if the datagram size is sane. */
|
||||
if (dgram_size < IPv6_HDR_SIZE) {
|
||||
expert_add_info_format(pinfo, length_item, &ei_6lowpan_bad_ipv6_header_length,
|
||||
"Length is less than IPv6 header length %u", IPv6_HDR_SIZE);
|
||||
}
|
||||
frag_tvb = dissect_6lowpan_hc1(frag_tvb, pinfo, tree, dgram_size, siid, diid);
|
||||
}
|
||||
else if (tvb_get_bits8(frag_tvb, 0, LOWPAN_PATTERN_IPHC_BITS) == LOWPAN_PATTERN_IPHC) {
|
||||
/* Check if the datagram size is sane. */
|
||||
if (dgram_size < IPv6_HDR_SIZE) {
|
||||
expert_add_info_format(pinfo, length_item, &ei_6lowpan_bad_ipv6_header_length,
|
||||
"Length is less than IPv6 header length %u", IPv6_HDR_SIZE);
|
||||
}
|
||||
frag_tvb = dissect_6lowpan_iphc(frag_tvb, pinfo, tree, dgram_size, siid, diid);
|
||||
}
|
||||
/* Unknown 6LoWPAN dispatch type */
|
||||
else {
|
||||
dissect_6lowpan_unknown(frag_tvb, pinfo, tree);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
frag_tvb = tvb_new_subset_length(tvb, offset, dgram_size);
|
||||
frag_tvb = dissect_6lowpan_frag_headers(frag_tvb, pinfo, tree, length_item, siid, diid);
|
||||
/* Check call to dissect_6lowpan_xxx was successful */
|
||||
if (frag_tvb == NULL) {
|
||||
return NULL;
|
||||
|
@ -3219,6 +3429,32 @@ proto_register_6lowpan(void)
|
|||
{ "Datagram offset", "6lowpan.frag.offset",
|
||||
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
|
||||
|
||||
/* Recoverable Fragmentation header fields. */
|
||||
{ &hf_6lowpan_rfrag_congestion,
|
||||
{ "Congestion", "6lowpan.rfrag.congestion",
|
||||
FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x01, NULL, HFILL }},
|
||||
{ &hf_6lowpan_rfrag_ack_requested,
|
||||
{ "Ack requested", "6lowpan.rfrag.ack_requested",
|
||||
FT_BOOLEAN, 16, TFS(&tfs_yes_no), 0x8000, NULL, HFILL }},
|
||||
{ &hf_6lowpan_rfrag_dgram_tag,
|
||||
{ "Datagram tag", "6lowpan.rfrag.tag",
|
||||
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
|
||||
{ &hf_6lowpan_rfrag_sequence,
|
||||
{ "Fragment sequence", "6lowpan.rfrag.sequence",
|
||||
FT_UINT16, BASE_DEC, NULL, 0x7C00, NULL, HFILL }},
|
||||
{ &hf_6lowpan_rfrag_size,
|
||||
{ "Fragment size", "6lowpan.rfrag.size",
|
||||
FT_UINT16, BASE_DEC, NULL, 0x03FF, NULL, HFILL }},
|
||||
{ &hf_6lowpan_rfrag_dgram_size,
|
||||
{ "Datagram size", "6lowpan.rfrag.datagram_size",
|
||||
FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
|
||||
{ &hf_6lowpan_rfrag_offset,
|
||||
{ "Fragment offset", "6lowpan.rfrag.offset",
|
||||
FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
|
||||
{ &hf_6lowpan_rfrag_ack_bitmap,
|
||||
{ "Fragment ACK bitmask", "6lowpan.rfrag.ack_bitmask",
|
||||
FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
|
||||
|
||||
/* Reassembly fields. */
|
||||
{ &hf_6lowpan_fragments,
|
||||
{ "Message fragments", "6lowpan.fragments",
|
||||
|
|
Loading…
Reference in New Issue