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
This commit is contained in:
Chris Maynard 2011-11-08 17:25:22 +00:00
parent ea3cc6ae43
commit d55d8781b8
4 changed files with 12 additions and 0 deletions

View File

@ -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);
}

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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 */