diff options
author | Kevin Bracey <kevin.bracey@arm.com> | 2015-09-04 12:45:29 +0300 |
---|---|---|
committer | Pascal Quantin <pascal.quantin@gmail.com> | 2015-09-04 11:04:07 +0000 |
commit | 7c4f622d6883208d88fbc4a0f32b80b62662d3b4 (patch) | |
tree | ea11c8511f5bb4f4983676dc111d610c4fbbb31e /epan | |
parent | ad46641eaeb9c60d33b5864a6cb8bed1d5202e2e (diff) |
Insert correct padding in RFC 6282 IPHC headers
IPv6 Extension Headers compressed using IPHC should have a single Pad1
or PadN inserted at the end if necessary - the previous code just left
any padding zero-initialised (equivalent to multiple Pad1s).
This guarantees correctly-compressed packets are accurately
decompressed, including the specific option padding pattern. (The type of
padding could matter, eg for IPSec authentication - padding options are
authenticated.)
Print a warning note if a non-option header needs padding - this is
invalid.
Bug: 10523
Change-Id: I66c98370862800a8fccbe02ed6a851961e2f7d1d
Reviewed-on: https://code.wireshark.org/review/10230
Petri-Dish: Pascal Quantin <pascal.quantin@gmail.com>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Pascal Quantin <pascal.quantin@gmail.com>
Diffstat (limited to 'epan')
-rw-r--r-- | epan/dissectors/packet-6lowpan.c | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/epan/dissectors/packet-6lowpan.c b/epan/dissectors/packet-6lowpan.c index bff2a4d55a..9decf53662 100644 --- a/epan/dissectors/packet-6lowpan.c +++ b/epan/dissectors/packet-6lowpan.c @@ -184,6 +184,10 @@ void proto_reg_handoff_6lowpan(void); /* 6LoWPAN First Fragment Header */ #define LOWPAN_FRAG_DGRAM_SIZE_BITS 11 +/* Uncompressed IPv6 Option types */ +#define IP6OPT_PAD1 0x00 +#define IP6OPT_PADN 0x01 + /* Compressed port number offset. */ #define LOWPAN_PORT_8BIT_OFFSET 0xf000 #define LOWPAN_PORT_12BIT_OFFSET (LOWPAN_PORT_8BIT_OFFSET | 0xb0) @@ -289,6 +293,7 @@ static gint ett_6lopwan_traffic_class = -1; static expert_field ei_6lowpan_hc1_more_bits = EI_INIT; static expert_field ei_6lowpan_illegal_dest_addr_mode = EI_INIT; static expert_field ei_6lowpan_bad_ipv6_header_length = EI_INIT; +static expert_field ei_6lowpan_bad_ext_header_length = EI_INIT; /* Subdissector handles. */ static dissector_handle_t handle_6lowpan; @@ -1873,6 +1878,7 @@ dissect_6lowpan_iphc_nhc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gi guint8 ext_hlen; guint8 ext_len; guint8 ext_proto; + proto_item *ti_ext_len = NULL; /* Parse the IPv6 extension header protocol. */ ext_proto = lowpan_parse_nhc_proto(tvb, offset); @@ -1912,9 +1918,7 @@ dissect_6lowpan_iphc_nhc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gi /* Get and display the extension header length. */ ext_hlen = (guint8)sizeof(struct ip6_ext); ext_len = tvb_get_guint8(tvb, offset); - if (tree) { - proto_tree_add_uint(nhc_tree, hf_6lowpan_nhc_ext_length, tvb, offset, 1, ext_len); - } + ti_ext_len = proto_tree_add_uint(nhc_tree, hf_6lowpan_nhc_ext_length, tvb, offset, 1, ext_len); offset += 1; /* Compute the length of the extension header padded to an 8-byte alignment. */ @@ -1960,6 +1964,22 @@ dissect_6lowpan_iphc_nhc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gi tvb_memcpy(tvb, LOWPAN_NHDR_DATA(nhdr) + ext_hlen, offset, ext_len); offset += ext_len; + /* Add padding option */ + if (length > ext_hlen + ext_len) { + guint8 padding = length - (ext_hlen + ext_len); + guint8 *pad_ptr = LOWPAN_NHDR_DATA(nhdr) + ext_hlen + ext_len; + if (ext_proto != IP_PROTO_HOPOPTS && ext_proto != IP_PROTO_DSTOPTS) { + expert_add_info(pinfo, ti_ext_len, &ei_6lowpan_bad_ext_header_length); + } + if (padding == 1) { + pad_ptr[0] = IP6OPT_PAD1; + } else { + pad_ptr[0] = IP6OPT_PADN; + pad_ptr[1] = padding - 2; + /* No need to write pad data, as buffer is zero-initialised */ + } + } + if (ext_flags & LOWPAN_NHC_EXT_NHDR) { /* * There are more LOWPAN_NHC structures to parse. Call ourself again @@ -2796,6 +2816,7 @@ proto_register_6lowpan(void) { &ei_6lowpan_hc1_more_bits, { "6lowpan.hc1_more_bits", PI_MALFORMED, PI_ERROR, "HC1 more bits expected for illegal next header type.", EXPFILL }}, { &ei_6lowpan_illegal_dest_addr_mode, { "6lowpan.illegal_dest_addr_mode", PI_MALFORMED, PI_ERROR, "Illegal destination address mode", EXPFILL }}, { &ei_6lowpan_bad_ipv6_header_length, { "6lowpan.bad_ipv6_header_length", PI_MALFORMED, PI_ERROR, "Length is less than IPv6 header length", EXPFILL }}, + { &ei_6lowpan_bad_ext_header_length, { "6lowpan.bad_ext_header_length", PI_MALFORMED, PI_ERROR, "Extension header not 8-octet aligned", EXPFILL }}, }; int i; |