Ethereal-dev: [Ethereal-dev] 802.11 compute FCS patch

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

From: Chris Waters <chris@xxxxxxxxxxxx>
Date: Tue, 30 Jul 2002 21:47:16 -0700
Hi,

Here is a patch for the 802.11 dissector that computes the FCS over the
received data and compares it against the received FCS. It leverages the WEP
CRC table.

Regards,

Chris.


RCS file: /cvsroot/ethereal/packet-ieee80211.c,v
retrieving revision 1.71
diff -u -r1.71 packet-ieee80211.c
--- packet-ieee80211.c 2002/07/17 00:42:40 1.71
+++ packet-ieee80211.c 2002/07/31 04:40:37
@@ -87,6 +87,9 @@
 static int wep_decrypt(guint8 *buf, guint32 len, int key_override);
 static tvbuff_t *try_decrypt_wep(tvbuff_t *tvb, guint32 offset, guint32
len);
 #define SSWAP(a,b) {guint8 tmp = s[a]; s[a] = s[b]; s[b] = tmp;}
+
+/* FCS utility function. */
+static unsigned long crc32(const unsigned char* buf, unsigned int len);

 /* #define USE_ENV */
 /* When this is set, an unlimited number of WEP keys can be set in the
@@ -1517,10 +1520,19 @@
     * We have the entire packet, and it includes a 4-byte FCS.
     * Slice it off, and put it into the tree.
     */
-   len -= 4;
-   reported_len -= 4;
-   if (tree)
-     proto_tree_add_item (hdr_tree, hf_fcs, tvb, hdr_len + len, 4, FALSE);
+  len -= 4;
+   reported_len -= 4;
+  if (tree) {
+   unsigned long fcs = crc32(tvb_get_ptr(tvb, 0, hdr_len + len), hdr_len +
len);
+   unsigned long sent_fcs = tvb_get_ntohl(tvb, hdr_len + len);
+   if ( fcs == sent_fcs )
+    proto_tree_add_uint_format(hdr_tree, hf_fcs, tvb, hdr_len + len, 4,
+      sent_fcs, "Frame check sequence: 0x%08x (correct)", sent_fcs);
+   else
+    proto_tree_add_uint_format(hdr_tree, hf_fcs, tvb, hdr_len + len, 4,
+      sent_fcs, "Frame check sequence: 0x%08x (incorrect, should be
0x%08x)", sent_fcs, fcs);
+  }
+
  }
     }

@@ -2622,4 +2634,23 @@
   }

   return;
+}
+
+
+static unsigned long
+crc32(const unsigned char* buf, unsigned int len)
+{
+  unsigned int i;
+  unsigned long crc32 = 0xFFFFFFFF, c_crc;
+
+  for (i = 0; i < len; i++)
+  crc32 = wep_crc32_table[(crc32 ^ buf[i]) & 0xff] ^ (crc32 >> 8);
+
+ /* Byte reverse. */
+  c_crc = ((unsigned char)(crc32>>0)<<24) |
+  ((unsigned char)(crc32>>8)<<16) |
+  ((unsigned char)(crc32>>16)<<8) |
+  ((unsigned char)(crc32>>24)<<0);
+
+  return ( ~c_crc );
 }