This is a static archive of our old Q&A Site. Please post any new questions and answers at

Does Wireshark uses a pseudo-header for VRRPv3 IPv4 checksum calculation?


According to draft-ietf-vrrp-ipv6-spec-08 (VRRPv3) IPv4 is defined in RFC3768 (VRRPv2).

"This protocol is intended for use with IPv6 routers only. VRRP for IPv4 is defined in VRRP-V4." , sentence from draft-ietf-vrrp-ipv6-spec-08, section 1.1 - Scope

It appears that Wireshark uses the pseudo-header in the checksum calculation for IPv4 and for IPv6. For me the pseudo-header should be used for IPv6 as defined in the draft but should not be used in IPv4 since it doesn't appear in the checksum calculation defined in the section 5.3.8. of RFC3768.

Could you confirm that the Wireshark's checksum calculation for VRRPv3 uses a pseudo-header even for IPv4? It is intentional or a bug?

asked 26 Oct '12, 03:44

ToinoBiclas's gravatar image

accept rate: 0%

edited 26 Oct '12, 03:45

One Answer:


RFC5798 defines VRRPv3 for IPv4 and IPv6. There are header field related to the IP protocol version and those that are independent of the IP protocol version.

The checksum is independent of the IP protocol version. See

5.2.8. Checksum
   The checksum field is used to detect data corruption in the VRRP

The checksum is the 16-bit one's complement of the one's complement sum of the entire VRRP message starting with the version field and a "pseudo-header" as defined in Section 8.1 of [RFC2460]. The next header field in the "pseudo-header" should be set to 112 (decimal) for VRRP. For computing the checksum, the checksum field is set to zero. See RFC1071 for more detail [RFC1071].

So the checksum calculation of Wireshark is correct, as it only adds the pseudo header for VRRPv3, regardless of the IP protocol (however, see below!).


cksum = tvb_get_ntohs(tvb, offset); vrrp_len = (gint)tvb_reported_length(tvb); if (!pinfo->fragmented && (gint)tvb_length(tvb) >= vrrp_len) { / The packet isn’t part of a fragmented datagram and isn’t truncated, so we can checksum it. / switch(hi_nibble(ver_type)) { case 3: / Set up the fields of the pseudo-header. / cksum_vec[0].ptr = pinfo->; cksum_vec[0].len = pinfo->src.len; cksum_vec1.ptr = pinfo->; cksum_vec1.len = pinfo->dst.len; cksum_vec2.ptr = (const guint8 *)&phdr; phdr[0] = g_htonl(vrrp_len); phdr1 = g_htonl(IP_PROTO_VRRP); cksum_vec2.len = 8; cksum_vec3.ptr = tvb_get_ptr(tvb, 0, vrrp_len); cksum_vec3.len = vrrp_len; computed_cksum = in_cksum(cksum_vec, 4); break; case 2: default: cksum_vec[0].ptr = tvb_get_ptr(tvb, 0, vrrp_len); cksum_vec[0].len = vrrp_len; computed_cksum = in_cksum(&cksum_vec[0], 1); break; }

However, RFC5798 is a bit unclear, as it refers to the IPv6 pseudo header in RFC2460 without explanation how to apply that to IPv4 for the checksum calculation.

There have been discussions about this, apparently without a clear result !?!

So, this is again one of those RFC interpretation versus interoperability issues and I guess different implementations calculate the checksum differently.

There is also a bug report for this:

BTW: If you want clarification, you can contact the author of the RFC. You'll find his e-mail address at the end of the RFC. However, he did not comment on the discussion about the checksum.


answered 06 Nov '12, 02:54

Kurt%20Knochner's gravatar image

Kurt Knochner ♦
accept rate: 15%

edited 06 Nov '12, 03:12

Added a preference to the VRRP dissector in;a=commit;h=a653014e69a4f0e0b59393ddc03871006057b36a whether to use V2 or V3 metod for V3 packets.

(09 Apr '14, 07:06) Anders ♦