Ethereal-dev: [Ethereal-dev] Ethereal patch for PMKID parsing (IEEE 802.11i)

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

From: Jouni Malinen <jkmaline@xxxxxxxxx>
Date: Thu, 1 Jul 2004 21:54:59 -0700
The attached patch adds parsing of PMKID for IEEE 802.11i (both in RSN
IE and in Key Data field of msg 1 of 4-Way Handshake).

-- 
Jouni Malinen                                            PGP id EFC895FA
Index: packet-ieee80211.c
===================================================================
RCS file: /cvsroot/ethereal/packet-ieee80211.c,v
retrieving revision 1.110
diff -u -p -r1.110 packet-ieee80211.c
--- packet-ieee80211.c	26 Jun 2004 09:48:11 -0000	1.110
+++ packet-ieee80211.c	2 Jul 2004 04:49:49 -0000
@@ -242,6 +242,8 @@ static char *wep_keystr[] = {NULL, NULL,
 #define WPA_OUI	"\x00\x50\xF2"
 #define RSN_OUI "\x00\x0F\xAC"
 
+#define PMKID_LEN 16
+
 /* ************************************************************************* */
 /*                         Frame types, and their names                      */
 /* ************************************************************************* */
@@ -730,7 +732,7 @@ dissect_vendor_specific_ie(proto_tree * 
 		guint32 tag_len, const guint8 *tag_val)
 {
       guint32 tag_val_off = 0;
-      char out_buff[SHORT_STR];
+      char out_buff[SHORT_STR], *pos;
       int i;
 	
       if (tag_val_off + 6 <= tag_len && !memcmp(tag_val, WPA_OUI"\x01", 4)) {
@@ -794,8 +796,23 @@ dissect_vendor_specific_ie(proto_tree * 
         if (tag_val_off < tag_len)
           proto_tree_add_string(tree, tag_interpretation, tvb,
                                  offset, tag_len - tag_val_off, "Not interpreted");
-      }
-      else
+      } else if (tag_val_off + 4 <= tag_len &&
+		 !memcmp(tag_val, RSN_OUI"\x04", 4)) {
+	/* IEEE 802.11i / Key Data Encapsulation / Data Type=4 - PMKID.
+	 * This is only used within EAPOL-Key frame Key Data. */
+	pos = out_buff;
+	pos += snprintf(pos, out_buff + SHORT_STR - pos, "RSN PMKID: ");
+	if (tag_len - 4 != PMKID_LEN) {
+	  pos += snprintf(pos, out_buff + SHORT_STR - pos,
+			  "(invalid PMKID len=%d, expected 16) ", tag_len - 4);
+	}
+	for (i = 0; i < tag_len - 4; i++) {
+	  pos += snprintf(pos, out_buff + SHORT_STR - pos, "%02X",
+			  tag_val[tag_val_off + 4 + i]);
+	}
+	proto_tree_add_string(tree, tag_interpretation, tvb, offset,
+			      tag_len, out_buff);
+      } else
         proto_tree_add_string(tree, tag_interpretation, 
         		tvb, offset, tag_len, "Not interpreted");
 }
@@ -807,7 +824,7 @@ dissect_rsn_ie(proto_tree * tree, tvbuff
   guint32 tag_val_off = 0;
   guint16 rsn_capab;
   char out_buff[SHORT_STR];
-  int i, count;
+  int i, j, count;
   proto_item *cap_item;
   proto_tree *cap_tree;
 
@@ -907,7 +924,22 @@ dissect_rsn_ie(proto_tree * tree, tvbuff
   offset += 2;
   tag_val_off += 2;
 
-  /* TODO: PMKID List (16 * n octets) */
+  /* PMKID List (16 * n octets) */
+  for (i = 0; i < count; i++) {
+    char *pos;
+    if (tag_val_off + PMKID_LEN > tag_len)
+      goto done;
+    pos = out_buff;
+    pos += snprintf(pos, out_buff + SHORT_STR - pos, "PMKID %u: ", i);
+    for (j = 0; j < PMKID_LEN; j++) {
+      pos += snprintf(pos, out_buff + SHORT_STR - pos, "%02X",
+		      tag_val[tag_val_off + j]);
+    }
+    proto_tree_add_string(tree, tag_interpretation, tvb, offset,
+			  PMKID_LEN, out_buff);
+    offset += PMKID_LEN;
+    tag_val_off += PMKID_LEN;
+  }
 
  done:
   if (tag_val_off < tag_len)