aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Maynard <Christopher.Maynard@GTECH.COM>2011-11-08 17:25:22 +0000
committerChris Maynard <Christopher.Maynard@GTECH.COM>2011-11-08 17:25:22 +0000
commitd55d8781b88da7e4dfe94ee4fbb495ffa1df0f1e (patch)
treedafa28c79b9a6815988bf26ebe7e5a1ce88e0487
parentea3cc6ae43ba30754f53a745dccfbed17bf8f1aa (diff)
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
-rw-r--r--epan/dissectors/packet-gre.c1
-rw-r--r--epan/dissectors/packet-icmp.c4
-rw-r--r--epan/dissectors/packet-icmpv6.c4
-rw-r--r--epan/packet_info.h3
4 files changed, 12 insertions, 0 deletions
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 */