QT+epan: Set FI_BITS_OFFSET and FI_BITS_SIZE flags on [u]ints and bitmasks

Set the FI_BITS_OFFSET and FI_BITS_SIZE flags appropriately on [u]int[64]
(and thus chars and booleans) where the bitmask is passed in on the
header_field_info. Also set the flags on bitmask items by ORing the bitmasks
from the constituent fields. These flags are only used right now in the
packet diagram.

This makes the packet diagram display those types of fields correctly without
having to use proto_item_set_bits_offset_len(), so long as the bitmask is
correct and the field width of the type matches the octet length. (If it
doesn't match, that's a dissector bug.)

split bit items are a more complicated case and still not handled correctly.
This commit is contained in:
John Thacker 2020-11-17 19:43:12 -05:00 committed by AndersBroman
parent c09b33cf1d
commit 7654bb260d
6 changed files with 55 additions and 19 deletions

View File

@ -2019,10 +2019,8 @@ dissect_ip_v4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void*
tf = proto_tree_add_bitmask_with_flags(ip_tree, tvb, offset + 6, hf_ip_flags,
ett_ip_flags, ip_flags, ENC_BIG_ENDIAN, BMT_NO_FALSE | BMT_NO_TFS | BMT_NO_INT);
}
proto_item_set_bits_offset_len(tf, 0, 3);
tf = proto_tree_add_uint(ip_tree, hf_ip_frag_offset, tvb, offset + 6, 2, (iph->ip_off & IP_OFFSET)*8);
proto_item_set_bits_offset_len(tf, 3, 13);
iph->ip_ttl = tvb_get_guint8(tvb, offset + 8);
if (tree) {
@ -2606,7 +2604,7 @@ proto_register_ip(void)
{ &hf_ip_frag_offset,
{ "Fragment Offset", "ip.frag_offset", FT_UINT16, BASE_DEC,
NULL, 0x0, "Fragment offset (13 bits)", HFILL }},
NULL, IP_OFFSET, "Fragment offset (13 bits)", HFILL }},
{ &hf_ip_ttl,
{ "Time to Live", "ip.ttl", FT_UINT8, BASE_DEC,

View File

@ -2377,7 +2377,6 @@ dissect_ipv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_
/* !!! warning: (4-bit) version, (6-bit) DSCP, (2-bit) ECN and (20-bit) Flow */
ti = proto_tree_add_item(ipv6_tree, hf_ipv6_tclass, tvb,
offset + IP6H_CTL_VFC, 4, ENC_BIG_ENDIAN);
proto_item_set_bits_offset_len(ti, 4, 8);
ip6_tcls = tvb_get_bits8(tvb, (offset + IP6H_CTL_VFC) * 8 + 4, 8);
proto_item_append_text(ti, " (DSCP: %s, ECN: %s)",
val_to_str_ext_const(IPDSFIELD_DSCP(ip6_tcls), &dscp_short_vals_ext, "Unknown"),
@ -2395,7 +2394,6 @@ dissect_ipv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_
ti = proto_tree_add_item_ret_uint(ipv6_tree, hf_ipv6_flow, tvb,
offset + IP6H_CTL_FLOW + 1, 3, ENC_BIG_ENDIAN, &ip6_flow);
proto_item_set_bits_offset_len(ti, 4, 20);
ip6_plen = tvb_get_guint16(tvb, offset + IP6H_CTL_PLEN, ENC_BIG_ENDIAN);
@ -2612,7 +2610,7 @@ proto_register_ipv6(void)
},
{ &hf_ipv6_flow,
{ "Flow Label", "ipv6.flow",
FT_UINT32, BASE_HEX, NULL, 0x000FFFFF,
FT_UINT24, BASE_HEX, NULL, 0x0FFFFF,
NULL, HFILL }
},
{ &hf_ipv6_plen,

View File

@ -6510,7 +6510,6 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
"%u bytes (%u)", tcph->th_hlen, tcph->th_hlen>>2);
tf = proto_tree_add_uint_format(tcp_tree, hf_tcp_flags, tvb, offset + 12, 2,
tcph->th_flags, "Flags: 0x%03x (%s)", tcph->th_flags, flags_str);
proto_item_set_bits_offset_len(tf, 4, 12);
field_tree = proto_item_add_subtree(tf, ett_tcp_flags);
proto_tree_add_boolean(field_tree, hf_tcp_flags_res, tvb, offset + 12, 1, tcph->th_flags);
proto_tree_add_boolean(field_tree, hf_tcp_flags_ns, tvb, offset + 12, 1, tcph->th_flags);

View File

@ -196,6 +196,8 @@ struct ptvcursor {
static const char *hf_try_val_to_str(guint32 value, const header_field_info *hfinfo);
static const char *hf_try_val64_to_str(guint64 value, const header_field_info *hfinfo);
static int hfinfo_bitoffset(const header_field_info *hfinfo);
static int hfinfo_mask_bitwidth(const header_field_info *hfinfo);
static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
static void label_mark_truncated(char *label_str, gsize name_pos);
@ -5459,6 +5461,9 @@ proto_tree_set_uint(field_info *fi, guint32 value)
/* Shift bits */
integer >>= hfinfo_bitshift(hfinfo);
FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)));
FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)));
}
fvalue_set_uinteger(&fi->value, integer);
@ -5548,6 +5553,9 @@ proto_tree_set_uint64(field_info *fi, guint64 value)
/* Shift bits */
integer >>= hfinfo_bitshift(hfinfo);
FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)));
FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)));
}
fvalue_set_uinteger64(&fi->value, integer);
@ -5640,6 +5648,9 @@ proto_tree_set_int(field_info *fi, gint32 value)
no_of_bits = ws_count_ones(hfinfo->bitmask);
integer = ws_sign_ext32(integer, no_of_bits);
FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)));
FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)));
}
fvalue_set_sinteger(&fi->value, integer);
@ -5712,6 +5723,9 @@ proto_tree_set_int64(field_info *fi, gint64 value)
no_of_bits = ws_count_ones(hfinfo->bitmask);
integer = ws_sign_ext64(integer, no_of_bits);
FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)));
FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)));
}
fvalue_set_sinteger64(&fi->value, integer);
@ -9833,6 +9847,19 @@ hfinfo_bitshift(const header_field_info *hfinfo)
return ws_ctz(hfinfo->bitmask);
}
static int
hfinfo_bitoffset(const header_field_info *hfinfo)
{
if (!hfinfo->bitmask) {
return 0;
}
/* ilog2 = first set bit, counting 0 as the last bit; we want 0
* as the first bit */
return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
}
static int
hfinfo_mask_bitwidth(const header_field_info *hfinfo)
{
@ -11540,9 +11567,11 @@ proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
proto_tree* tree, guint64 value)
{
guint64 available_bits = G_MAXUINT64;
guint64 bitmask = 0;
guint64 tmpval;
header_field_info *hf;
guint32 integer32;
gint bit_offset;
gint no_of_bits;
if (len < 0 || len > 8)
@ -11564,6 +11593,8 @@ proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
PROTO_REGISTRAR_GET_NTH(**fields,hf);
DISSECTOR_ASSERT_HINT(hf->bitmask != 0, hf->abbrev);
bitmask |= hf->bitmask;
/* Skip fields that aren't fully present */
present_bits = available_bits & hf->bitmask;
if (present_bits != hf->bitmask) {
@ -11836,6 +11867,16 @@ proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
fields++;
}
/* XXX: We don't pass the hfi into this function. Perhaps we should,
* but then again most dissectors don't set the bitmask field for
* the higher level bitmask hfi, so calculate the bitmask from the
* fields present. */
if (item) {
bit_offset = len*8 - 1 - ws_ilog2(bitmask);
no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
}
return first;
}

File diff suppressed because one or more lines are too long

View File

@ -369,10 +369,10 @@
]
},
"ip.frag_offset_raw": [
"0000",
"0",
20,
2,
0,
8191,
5
],
"ip.ttl_raw": [
@ -1243,10 +1243,10 @@
]
},
"ip.frag_offset_raw": [
"0000",
"0",
20,
2,
0,
8191,
5
],
"ip.ttl_raw": [
@ -2135,10 +2135,10 @@
]
},
"ip.frag_offset_raw": [
"0000",
"0",
20,
2,
0,
8191,
5
],
"ip.ttl_raw": [
@ -3039,10 +3039,10 @@
]
},
"ip.frag_offset_raw": [
"0000",
"0",
20,
2,
0,
8191,
5
],
"ip.ttl_raw": [