aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-ber.c
diff options
context:
space:
mode:
Diffstat (limited to 'epan/dissectors/packet-ber.c')
-rw-r--r--epan/dissectors/packet-ber.c29
1 files changed, 19 insertions, 10 deletions
diff --git a/epan/dissectors/packet-ber.c b/epan/dissectors/packet-ber.c
index b03fee175e..8cd173ba56 100644
--- a/epan/dissectors/packet-ber.c
+++ b/epan/dissectors/packet-ber.c
@@ -4035,6 +4035,7 @@ dissect_ber_constrained_bitstring(gboolean implicit_tag, asn1_ctx_t *actx, proto
item = proto_tree_add_item(parent_tree, hf_id, tvb, offset, len, ENC_NA);
actx->created_item = item;
if (named_bits) {
+ guint8 *bitstring = (guint8 *)tvb_memdup(wmem_packet_scope(), tvb, offset, len);
const int named_bits_bytelen = (num_named_bits + 7) / 8;
if (show_internal_ber_fields) {
guint zero_bits_omitted = 0;
@@ -4047,13 +4048,6 @@ dissect_ber_constrained_bitstring(gboolean implicit_tag, asn1_ctx_t *actx, proto
tree = proto_item_add_subtree(item, ett_id);
}
for (int i = 0; i < named_bits_bytelen; i++) {
- // If less data is available than the number of named bits, then
- // the trailing (right) bits are assumed to be 0.
- guint64 value = 0;
- if (i < len) {
- value = tvb_get_guint8(tvb, offset + i);
- }
-
// Process 8 bits at a time instead of 64, each field masks a
// single byte.
const int bit_offset = 8 * i;
@@ -4065,6 +4059,18 @@ dissect_ber_constrained_bitstring(gboolean implicit_tag, asn1_ctx_t *actx, proto
section_named_bits = (const int** )flags;
}
+ // If less data is available than the number of named bits, then
+ // the trailing (right) bits are assumed to be 0.
+ guint64 value = 0;
+ if (i < len) {
+ value = bitstring[i];
+ if (num_named_bits - bit_offset > 7) {
+ bitstring[i] = 0;
+ } else {
+ bitstring[i] &= 0xff >> (num_named_bits - bit_offset);
+ }
+ }
+
// TODO should non-zero pad bits be masked from the value?
// When trailing zeroes are not present in the data, mark the
// last byte for the lack of a better alternative.
@@ -4072,9 +4078,12 @@ dissect_ber_constrained_bitstring(gboolean implicit_tag, asn1_ctx_t *actx, proto
}
// If more data is available than the number of named bits, then
// either the spec was updated or the packet is malformed.
- if (named_bits_bytelen < len) {
- expert_add_info_format(actx->pinfo, item, &ei_ber_bits_unknown, "Unknown bit(s): 0x%s",
- tvb_bytes_to_str(wmem_packet_scope(), tvb, offset + named_bits_bytelen, len - named_bits_bytelen));
+ for (int i = 0; i < len; i++) {
+ if (bitstring[i]) {
+ expert_add_info_format(actx->pinfo, item, &ei_ber_bits_unknown, "Unknown bit(s): 0x%s",
+ bytes_to_str(wmem_packet_scope(), bitstring, len));
+ break;
+ }
}
}
}