diff options
author | Kevin Bracey <kevin.bracey@arm.com> | 2016-01-07 12:35:23 +0200 |
---|---|---|
committer | João Valverde <j@v6e.pt> | 2016-01-12 13:44:41 +0000 |
commit | d6ca6cbe7421a3eb75494c3aa955ff5d7c07a52a (patch) | |
tree | a68d81af728ae179320f64a26a4d626bb99f9822 | |
parent | 8cabf5be59bbc6074ffb4fe22e7c9933ae78db90 (diff) |
6LoWPAN: correct IPHC traffic class decompression
Traffic class values from IPHC headers were shown correctly in the IPHC
dissection, but not correctly inserted into the expanded IPv6 packet.
Problem was only visible on little-endian systems - the previous
code did work if big-endian.
Error was not present in HC1 decompression, but both IPHC and HC1
IPv6 construction code clarified by avoiding writing overlapping union
members.
Bug: 11971
Change-Id: I3515f18c892f1fc28ef7f8a0830a79d134e81f48
Reviewed-on: https://code.wireshark.org/review/13109
Petri-Dish: João Valverde <j@v6e.pt>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: João Valverde <j@v6e.pt>
-rw-r--r-- | epan/dissectors/packet-6lowpan.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/epan/dissectors/packet-6lowpan.c b/epan/dissectors/packet-6lowpan.c index ea9d8fb989..32dd5359a7 100644 --- a/epan/dissectors/packet-6lowpan.c +++ b/epan/dissectors/packet-6lowpan.c @@ -1275,8 +1275,11 @@ dissect_6lowpan_hc1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint dg } bit_offset += LOWPAN_IPV6_FLOW_LABEL_BITS; } - ipv6.ip6_flow = g_ntohl(ipv6.ip6_flow | (ipv6_class << LOWPAN_IPV6_FLOW_LABEL_BITS)); - ipv6.ip6_vfc = ((0x6 << 4) | (ipv6_class >> 4)); + + /* Rebuild the IPv6 flow label, traffic class and version fields. */ + ipv6.ip6_flow |= ((guint32)ipv6_class << LOWPAN_IPV6_FLOW_LABEL_BITS); + ipv6.ip6_flow |= ((guint32)0x6 << (LOWPAN_IPV6_TRAFFIC_CLASS_BITS + LOWPAN_IPV6_FLOW_LABEL_BITS)); + ipv6.ip6_flow = g_ntohl(ipv6.ip6_flow); /* Parse the IPv6 next header field. */ if (next_header == LOWPAN_HC1_NEXT_UDP) { @@ -1583,9 +1586,10 @@ dissect_6lowpan_iphc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint d } else ipv6.ip6_flow = 0; - /* Rebuild the IPv6 flow label and traffic class fields. */ - ipv6.ip6_flow = g_ntohl(ipv6.ip6_flow) | (ipv6_class << LOWPAN_IPV6_FLOW_LABEL_BITS); - ipv6.ip6_vfc = (0x6 << 4) | (ipv6_class >> 4); + /* Rebuild the IPv6 flow label, traffic class and version fields. */ + ipv6.ip6_flow |= ((guint32)ipv6_class << LOWPAN_IPV6_FLOW_LABEL_BITS); + ipv6.ip6_flow |= ((guint32)0x6 << (LOWPAN_IPV6_TRAFFIC_CLASS_BITS + LOWPAN_IPV6_FLOW_LABEL_BITS)); + ipv6.ip6_flow = g_ntohl(ipv6.ip6_flow); /* Convert back to byte offsets. */ offset >>= 3; |