aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUli Heilmeier <uh@heilmeier.eu>2017-12-17 18:40:17 +0100
committerMichael Mann <mmann78@netscape.net>2018-01-01 21:12:27 +0000
commit404d004907228c14fe66959f5d34d52d0cae3f13 (patch)
treeed82b87b6885d3370209d366e427e312d043744e
parent3d58a16038731bfe3f234756830ab300cf5c4dea (diff)
IPv6: Add segmentation offload (TSO) support
When capturing on hardware with segmentation offload enabled IPv6 payload size can be reported as zero. This commit adds a preference to dissect such frames. Heavily based on the TSO code of packet-ip.c Bug: 14155 Change-Id: Ibec3c35c739d8673fa655bde4f66198a22f567c4 Reviewed-on: https://code.wireshark.org/review/24900 Petri-Dish: João Valverde <j@v6e.pt> Tested-by: Petri Dish Buildbot Reviewed-by: Michael Mann <mmann78@netscape.net>
-rw-r--r--epan/dissectors/packet-ipv6.c34
1 files changed, 31 insertions, 3 deletions
diff --git a/epan/dissectors/packet-ipv6.c b/epan/dissectors/packet-ipv6.c
index a94e5d5375..5ef9efab43 100644
--- a/epan/dissectors/packet-ipv6.c
+++ b/epan/dissectors/packet-ipv6.c
@@ -346,6 +346,7 @@ static expert_field ei_ipv6_opt_unknown_data = EI_INIT;
static expert_field ei_ipv6_opt_deprecated = EI_INIT;
static expert_field ei_ipv6_hopopts_not_first = EI_INIT;
static expert_field ei_ipv6_plen_exceeds_framing = EI_INIT;
+static expert_field ei_ipv6_plen_zero = EI_INIT;
static expert_field ei_ipv6_bogus_ipv6_version = EI_INIT;
static expert_field ei_ipv6_invalid_header = EI_INIT;
static expert_field ei_ipv6_opt_header_mismatch = EI_INIT;
@@ -551,6 +552,9 @@ static gboolean ipv6_exthdr_under_root = FALSE;
/* Hide extension header generated field for length */
static gboolean ipv6_exthdr_hide_len_oct_field = FALSE;
+/* Assume TSO and correct zero-length IP packets */
+static gboolean ipv6_tso_supported = FALSE;
+
/*
* defragmentation of IPv6
*/
@@ -2308,13 +2312,28 @@ dissect_ipv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_
proto_tree_add_item_ret_uint(ipv6_tree, hf_ipv6_flow, tvb,
offset + IP6H_CTL_FLOW, 4, ENC_BIG_ENDIAN, &ip6_flow);
- ti_ipv6_plen = proto_tree_add_item(ipv6_tree, hf_ipv6_plen, tvb,
- offset + IP6H_CTL_PLEN, 2, ENC_BIG_ENDIAN);
ipv6_pinfo->ip6_plen = tvb_get_guint16(tvb, offset + IP6H_CTL_PLEN, ENC_BIG_ENDIAN);
+
+ ip6_nxt = tvb_get_guint8(tvb, offset + IP6H_CTL_NXT);
+
+ if (ipv6_tso_supported && ipv6_pinfo->ip6_plen == 0 && ip6_nxt != IP_PROTO_HOPOPTS && ip6_nxt != IP_PROTO_NONE) {
+ ipv6_pinfo->ip6_plen = tvb_reported_length(tvb) - IPv6_HDR_SIZE;
+ pi = proto_tree_add_uint_format_value(ipv6_tree, hf_ipv6_plen, tvb, offset + IP6H_CTL_PLEN, 2,
+ ipv6_pinfo->ip6_plen,
+ "%u bytes (reported as 0, presumed to be because of \"TCP segmentation offload\" (TSO))",
+ ipv6_pinfo->ip6_plen);
+ PROTO_ITEM_SET_GENERATED(pi);
+ } else {
+ ti_ipv6_plen = proto_tree_add_item(ipv6_tree, hf_ipv6_plen, tvb,
+ offset + IP6H_CTL_PLEN, 2, ENC_BIG_ENDIAN);
+ if (ipv6_pinfo->ip6_plen == 0 && ip6_nxt != IP_PROTO_HOPOPTS && ip6_nxt != IP_PROTO_NONE) {
+ expert_add_info(pinfo, ti_ipv6_plen, &ei_ipv6_plen_zero);
+ }
+ }
+
ipv6_pinfo->frag_plen = ipv6_pinfo->ip6_plen;
proto_tree_add_item(ipv6_tree, hf_ipv6_nxt, tvb, offset + IP6H_CTL_NXT, 1, ENC_NA);
- ip6_nxt = tvb_get_guint8(tvb, offset + IP6H_CTL_NXT);
proto_tree_add_item(ipv6_tree, hf_ipv6_hlim, tvb,
offset + IP6H_CTL_HLIM, 1, ENC_BIG_ENDIAN);
@@ -3421,6 +3440,10 @@ proto_register_ipv6(void)
{ "ipv6.plen_exceeds_framing", PI_PROTOCOL, PI_WARN,
"IPv6 payload length does not match expected framing length", EXPFILL }
},
+ { &ei_ipv6_plen_zero,
+ { "ipv6.plen_zero", PI_PROTOCOL, PI_CHAT,
+ "IPv6 payload length equals 0 (maybe because of \"TCP segmentation offload\" (TSO))", EXPFILL }
+ },
{ &ei_ipv6_bogus_ipv6_version,
{ "ipv6.bogus_ipv6_version", PI_MALFORMED, PI_ERROR,
"Bogus IP version", EXPFILL }
@@ -3593,6 +3616,11 @@ proto_register_ipv6(void)
"If enabled the Length field in octets will be hidden",
&ipv6_exthdr_hide_len_oct_field);
+ prefs_register_bool_preference(ipv6_module, "tso_support",
+ "Support packet-capture from IPv6 TSO-enabled hardware",
+ "Whether to correct for TSO-enabled (TCP segmentation offload) hardware "
+ "captures, such as spoofing the IPv6 packet length", &ipv6_tso_supported);
+
ipv6_handle = register_dissector("ipv6", dissect_ipv6, proto_ipv6);
reassembly_table_register(&ipv6_reassembly_table,
&addresses_reassembly_table_functions);