From d55d8781b88da7e4dfe94ee4fbb495ffa1df0f1e Mon Sep 17 00:00:00 2001 From: Chris Maynard Date: Tue, 8 Nov 2011 17:25:22 +0000 Subject: Improve ICMP conversation tracking, especially when capturing on multiple interfaces and one of them is a GRE tunnel. Resolves bug 5770, which was reopened. svn path=/trunk/; revision=39757 --- epan/dissectors/packet-gre.c | 1 + epan/dissectors/packet-icmp.c | 4 ++++ epan/dissectors/packet-icmpv6.c | 4 ++++ epan/packet_info.h | 3 +++ 4 files changed, 12 insertions(+) diff --git a/epan/dissectors/packet-gre.c b/epan/dissectors/packet-gre.c index e278c7562d..944796f01b 100644 --- a/epan/dissectors/packet-gre.c +++ b/epan/dissectors/packet-gre.c @@ -495,6 +495,7 @@ dissect_gre(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) return; /* no payload */ } next_tvb = tvb_new_subset_remaining(tvb, offset); + pinfo->flags.in_gre_pkt = TRUE; if (!dissector_try_uint(gre_dissector_table, type, next_tvb, pinfo, tree)) call_dissector(data_handle,next_tvb, pinfo, gre_tree); } diff --git a/epan/dissectors/packet-icmp.c b/epan/dissectors/packet-icmp.c index 77b3eb3ddd..eb0522bb3c 100644 --- a/epan/dissectors/packet-icmp.c +++ b/epan/dissectors/packet-icmp.c @@ -1065,6 +1065,8 @@ dissect_icmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) if ( icmp_type == ICMP_ECHOREPLY ) { if ( !pinfo->in_error_pkt ) { conv_key[0] = (guint32)tvb_get_ntohs(tvb, 2); + if (pinfo->flags.in_gre_pkt) + conv_key[0] |= 0x00010000; /* set a bit for "in GRE" */ conv_key[1] = (guint32)((tvb_get_ntohs(tvb, 4) << 16) | tvb_get_ntohs(tvb, 6)); trans = transaction_end(pinfo, icmp_tree, conv_key); @@ -1076,6 +1078,8 @@ dissect_icmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) tmp[0] = ~tvb_get_ntohs(tvb, 2); tmp[1] = ~0x0800; /* The difference between echo request & reply */ conv_key[0] = ip_checksum((guint8 *)&tmp, sizeof(tmp)); + if (pinfo->flags.in_gre_pkt) + conv_key[0] |= 0x00010000; /* set a bit for "in GRE" */ conv_key[1] = (guint32)((tvb_get_ntohs(tvb, 4) << 16) | tvb_get_ntohs(tvb, 6)); trans = transaction_start(pinfo, icmp_tree, conv_key); diff --git a/epan/dissectors/packet-icmpv6.c b/epan/dissectors/packet-icmpv6.c index 8d04affca7..9937601ae1 100644 --- a/epan/dissectors/packet-icmpv6.c +++ b/epan/dissectors/packet-icmpv6.c @@ -3232,6 +3232,8 @@ dissect_icmpv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) if (icmp6_type == ICMP6_ECHO_REQUEST) { conv_key[0] = (guint32)cksum; + if (pinfo->flags.in_gre_pkt) + conv_key[0] |= 0x00010000; /* set a bit for "in GRE" */ trans = transaction_start(pinfo, icmp6_tree, conv_key); } else { /* ICMP6_ECHO_REPLY */ guint16 tmp[2]; @@ -3241,6 +3243,8 @@ dissect_icmpv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) cksum_vec[0].len = sizeof(tmp); cksum_vec[0].ptr = (guint8 *)tmp; conv_key[0] = in_cksum(cksum_vec, 1); + if (pinfo->flags.in_gre_pkt) + conv_key[0] |= 0x00010000; /* set a bit for "in GRE" */ trans = transaction_end(pinfo, icmp6_tree, conv_key); } } diff --git a/epan/packet_info.h b/epan/packet_info.h index 94ee3c1b42..c0a7c3f4b0 100644 --- a/epan/packet_info.h +++ b/epan/packet_info.h @@ -66,6 +66,9 @@ typedef struct _packet_info { const char *noreassembly_reason; /* reason why reassembly wasn't done, if any */ gboolean fragmented; /* TRUE if the protocol is only a fragment */ gboolean in_error_pkt; /* TRUE if we're inside an {ICMP,CLNP,...} error packet */ + struct { + guint32 in_gre_pkt:1; /* TRUE if we're encapsulated inside a GRE packet */ + } flags; port_type ptype; /* type of the following two port numbers */ guint32 srcport; /* source port */ guint32 destport; /* destination port */ -- cgit v1.2.3