Ethereal-dev: [Ethereal-dev] OSPFv3 checksum calculation

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: Taisuke Sasaki <sasaki@xxxxxxxxxxxxxxxxxxxxxx>
Date: Wed, 28 Nov 2001 11:26:35 +0900
Though Ethereal-0.8.20 supports an OSPFv3 dissector,
it seems that OSPFv3 header checksum calculation is something wrong.

rfc2470 says that a "pseudo-header" of IPv6 header fields
is used in OSPFv3 checksum calculation,
but I cannot find the corresponding source code in latest
CVS repository(packet-ospf.c).

below is a temporary patch in OSPFv3 header checksum calculation.
(I have compiled, but never tested).


Index: packet-ospf.c
===================================================================
RCS file: /cvsroot/ethereal/packet-ospf.c,v
retrieving revision 1.49
diff -u -r1.49 packet-ospf.c
--- packet-ospf.c       2001/11/26 04:52:50     1.49
+++ packet-ospf.c       2001/11/28 02:21:46
@@ -228,6 +228,15 @@

 static void dissect_ospf_v3_address_prefix(tvbuff_t *, int, int, proto_tree *);

+struct pseudo_header
+{
+    struct in6_addr src;
+    struct in6_addr dst;
+    guint32 upper_len;
+    char zero[3];
+    guint8 nh;
+};
+
 static void
 dissect_ospf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 {
@@ -248,6 +257,7 @@
     guint8 instance_ID;
     guint8 reserved;
     guint32 areaid;
+    struct pseudo_header pseudo_header;


     if (check_col(pinfo->fd, COL_PROTOCOL))
@@ -309,6 +319,9 @@
            /* The packet isn't part of a fragmented datagram and isn't
               truncated, so we can checksum it. */

+           /* OSPFv2 - checksum calculation */
+           if ( version == OSPF_VERSION_2 ) {
+
            /* Header, not including the authentication data (the OSPF
               checksum excludes the 64-bit authentication field (which is an OS
PFv2-only field)). */
            cksum_vec[0].ptr = tvb_get_ptr(tvb, 0, 16);
@@ -324,6 +337,27 @@
                /* There's nothing but a header. */
                cksum_vec_len = 1;
            }
+
+           }
+           /* OSPFv3 - checksum calculation */
+           else if ( version == OSPF_VERSION_3 ) {
+               memset(&pseudo_header, 0, sizeof(pseudo_header));
+               memcpy(&pseudo_header.src, pinfo->net_src.data, sizeof(struct in
6_addr));
+               memcpy(&pseudo_header.dst, pinfo->net_dst.data, sizeof(struct in
6_addr));
+               pseudo_header.upper_len = htonl(ospflen);
+               pseudo_header.nh = pinfo->ipproto;
+
+               cksum_vec[0].ptr = (guint8 *)&pseudo_header;
+               cksum_vec[0].len = sizeof(pseudo_header);
+               cksum_vec[1].ptr = tvb_get_ptr(tvb, 0, reported_length);
+               cksum_vec[1].len = reported_length;
+               cksum_vec_len = 2;
+           }
+           else {
+               /* XXX */
+               cksum_vec_len = 0;
+           }
+
            computed_cksum = in_cksum(cksum_vec, cksum_vec_len);
            if (computed_cksum == 0) {
                proto_tree_add_text(ospf_header_tree, tvb, 12, 2,