diff --git a/AUTHORS b/AUTHORS index ad222f0897..0d5337bb69 100644 --- a/AUTHORS +++ b/AUTHORS @@ -849,6 +849,10 @@ Pavel Novotny { Additional items for RADIUS tunnels } +Shinsuke Suzuki { + Fix to IPv6 PIM checksum calculation +} + Alain Magloire was kind enough to give his permission to use his version of snprintf.c. diff --git a/doc/ethereal.pod.template b/doc/ethereal.pod.template index e47ff0b75b..cc4431f69f 100644 --- a/doc/ethereal.pod.template +++ b/doc/ethereal.pod.template @@ -1208,6 +1208,7 @@ B. Daniel Thompson Chris Jepeway Pavel Novotny + Shinsuke Suzuki Alain Magloire was kind enough to give his permission to use his version of snprintf.c. diff --git a/packet-pim.c b/packet-pim.c index ae454bee8d..2df8f45d3e 100644 --- a/packet-pim.c +++ b/packet-pim.c @@ -2,7 +2,7 @@ * Routines for PIM disassembly * (c) Copyright Jun-ichiro itojun Hagino * - * $Id: packet-pim.c,v 1.32 2001/07/21 10:27:13 guy Exp $ + * $Id: packet-pim.c,v 1.33 2001/10/30 10:10:59 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -606,13 +606,19 @@ static const value_string type2vals[] = { { 0, NULL }, }; +/* + * For PIM v2, see RFC 2362, and draft-ietf-pim-sm-v2-new-03 (when PIM + * is run over IPv6, the rules for computing the PIM checksum from the + * draft in question, not from RFC 2362, should be used). + */ static void dissect_pim(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { int offset = 0; guint8 pim_typever; guint length, pim_length; guint16 pim_cksum, computed_cksum; - vec_t cksum_vec[1]; + vec_t cksum_vec[4]; + guint32 phdr[2]; char *typestr; proto_tree *pim_tree = NULL; proto_item *ti; @@ -688,9 +694,33 @@ dissect_pim(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { * The packet isn't part of a fragmented datagram and isn't * truncated, so we can checksum it. */ - cksum_vec[0].ptr = tvb_get_ptr(tvb, 0, pim_length); - cksum_vec[0].len = pim_length; - computed_cksum = in_cksum(&cksum_vec[0], 1); + + switch (pinfo->src.type) { + case AT_IPv4: + cksum_vec[0].ptr = tvb_get_ptr(tvb, 0, pim_length); + cksum_vec[0].len = pim_length; + computed_cksum = in_cksum(&cksum_vec[0], 1); + break; + case AT_IPv6: + /* Set up the fields of the pseudo-header. */ + cksum_vec[0].ptr = pinfo->src.data; + cksum_vec[0].len = pinfo->src.len; + cksum_vec[1].ptr = pinfo->dst.data; + cksum_vec[1].len = pinfo->dst.len; + cksum_vec[2].ptr = (const guint8 *)&phdr; + phdr[0] = htonl(pim_length); + phdr[1] = htonl(IP_PROTO_PIM); + cksum_vec[2].len = 8; + cksum_vec[3].ptr = tvb_get_ptr(tvb, 0, pim_length); + cksum_vec[3].len = pim_length; + computed_cksum = in_cksum(&cksum_vec[0], 4); + break; + default: + /* PIM is available for IPv4 and IPv6 right now */ + g_assert_not_reached(); + break; + } + if (computed_cksum == 0) { proto_tree_add_uint_format(pim_tree, hf_pim_cksum, tvb, offset + 2, 2, pim_cksum,