Ethereal-dev: [Ethereal-dev] IEEE 802.11 (wlan) dissector update

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

From: Johan Jorgensen <johan.jorgensen@xxxxxxxx>
Date: Wed, 30 May 2001 13:33:30 +0200
Hi everybody,

The attached patch corrects the following errors:

1. Lockups in calls to add_tagged_field(..) when dissecting corrupt
frames. (Thanks to Marco Molteni for pointing it out)

2. Beacon interval is now shown in real-time

3. Current AP address was mistakenly interpreted as a string - caused
ethereal to crash.

4. Corrections to fixed fields. All fixed fields suffered from
BIT_SWAPomania (introduced by me by mistake). This caused some fields to
be displayed incorrectly.

Various other small fixes which have to do with byte-ordering (sequence
and fragment numbers etc are now displayed correctly)

People who are using my prismdump utility to capture 802.11 frames
should download a new version as I fixed a few bugs in there too.

Regards,
Johan Jorgensen
Index: packet-ieee80211.c
===================================================================
RCS file: /cvsroot/ethereal/packet-ieee80211.c,v
retrieving revision 1.17
diff -u -r1.17 packet-ieee80211.c
--- packet-ieee80211.c	2001/04/20 20:34:28	1.17
+++ packet-ieee80211.c	2001/05/30 09:43:29
@@ -24,6 +24,15 @@
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Credits:
+ * 
+ * The following people helped me by pointing out bugs etc. Thank you!
+ *
+ * Marco Molteni
+ * Lena-Marie Nilsson     
+ * Magnus Hultman-Persson
+ *
  */
 
 #ifdef HAVE_CONFIG_H
@@ -231,15 +240,15 @@
 /* ************************************************************************* */
 /*                      Fixed fields found in mgt frames                     */
 /* ************************************************************************* */
-static int ff_auth_alg = -1;	/* Authentication algorithm field          */
-static int ff_auth_seq = -1;	/* Authentication transaction sequence     */
-static int ff_current_ap = -1;	/* Current AP MAC address                  */
-static int ff_listen_ival = -1;	/* Listen interval fixed field             */
-static int ff_timestamp = -1;	/* 64 bit timestamp                        */
-static int ff_beacon_interval = -1;	/* 16 bit Beacon interval                  */
-static int ff_assoc_id = -1;	/* 16 bit AID field                        */
-static int ff_reason = -1;	/* 16 bit reason code                      */
-static int ff_status_code = -1;	/* Status code                             */
+static int ff_auth_alg = -1;	/* Authentication algorithm field            */
+static int ff_auth_seq = -1;	/* Authentication transaction sequence       */
+static int ff_current_ap = -1;	/* Current AP MAC address                    */
+static int ff_listen_ival = -1;	/* Listen interval fixed field               */
+static int ff_timestamp = -1;	/* 64 bit timestamp                          */
+static int ff_beacon_interval = -1;	/* 16 bit Beacon interval            */
+static int ff_assoc_id = -1;	/* 16 bit AID field                          */
+static int ff_reason = -1;	/* 16 bit reason code                        */
+static int ff_status_code = -1;	/* Status code                               */
 
 /* ************************************************************************* */
 /*            Flags found in the capability field (fixed field)              */
@@ -381,6 +390,7 @@
   guint16 *temp16;
   proto_item *cap_item;
   static proto_tree *cap_tree;
+  double temp_double;
 
   switch (lfcode)
     {
@@ -388,14 +398,14 @@
       dataptr = tvb_get_ptr (tvb, offset, 8);
       memset (out_buff, 0, SHORT_STR);
       snprintf (out_buff, SHORT_STR, "0x%02X%02X%02X%02X%02X%02X%02X%02X",
-		BIT_SWAP (dataptr[7]),
-		BIT_SWAP (dataptr[6]),
-		BIT_SWAP (dataptr[5]),
-		BIT_SWAP (dataptr[4]),
-		BIT_SWAP (dataptr[3]),
-		BIT_SWAP (dataptr[2]),
-		BIT_SWAP (dataptr[1]),
-		BIT_SWAP (dataptr[0]));
+		dataptr[7],
+		dataptr[6],
+		dataptr[5],
+		dataptr[4],
+		dataptr[3],
+		dataptr[2],
+		dataptr[1],
+		dataptr[0]);
 
       proto_tree_add_string (tree, ff_timestamp, tvb, offset, 8, out_buff);
       break;
@@ -403,19 +413,17 @@
 
     case FIELD_BEACON_INTERVAL:
       dataptr = tvb_get_ptr (tvb, offset, 2);
-      out_buff[0] = BIT_SWAP (dataptr[1]);
-      out_buff[1] = BIT_SWAP (dataptr[0]);
-      temp16 = (guint16 *) out_buff;
-      proto_tree_add_uint (tree, ff_beacon_interval, tvb, offset, 2,
-			   pntohs (temp16));
+      temp_double = ((double) *((guint16 *) dataptr));
+      temp_double = temp_double * 1024 / 1000000;
+      proto_tree_add_double_format (tree, ff_beacon_interval, tvb, offset, 2,
+				    temp_double,"Beacon Interval: %f [Seconds]",
+				    temp_double);
       break;
 
 
     case FIELD_CAP_INFO:
       dataptr = tvb_get_ptr (tvb, offset, 2);
-      out_buff[0] = BIT_SWAP (dataptr[1]);
-      out_buff[0] = BIT_SWAP (dataptr[0]);
-      temp16 = (guint16 *) out_buff;
+      temp16 = (guint16 *) dataptr;
 
       cap_item = proto_tree_add_uint_format (tree, ff_capture, 
 					     tvb, offset, 2,
@@ -441,9 +449,7 @@
 
     case FIELD_AUTH_ALG:
       dataptr = tvb_get_ptr (tvb, offset, 2);
-      out_buff[0] = BIT_SWAP (dataptr[1]);
-      out_buff[1] = BIT_SWAP (dataptr[0]);
-      temp16 = (guint16 *) out_buff;
+      temp16 =(guint16 *) dataptr;
       proto_tree_add_uint (tree, ff_auth_alg, tvb, offset, 2,
 			   pntohs (temp16));
       break;
@@ -451,9 +457,7 @@
 
     case FIELD_AUTH_TRANS_SEQ:
       dataptr = tvb_get_ptr (tvb, offset, 2);
-      out_buff[0] = BIT_SWAP (dataptr[1]);
-      out_buff[1] = BIT_SWAP (dataptr[0]);
-      temp16 = (guint16 *) out_buff;
+      temp16 = (guint16 *)dataptr;
       proto_tree_add_uint (tree, ff_auth_seq, tvb, offset, 2,
 			   pntohs (temp16));
       break;
@@ -461,23 +465,13 @@
 
     case FIELD_CURRENT_AP_ADDR:
       dataptr = tvb_get_ptr (tvb, offset, 6);
-      memset (out_buff, 0, SHORT_STR);
-      out_buff[0] = BIT_SWAP (dataptr[5]);
-      out_buff[1] = BIT_SWAP (dataptr[4]);
-      out_buff[2] = BIT_SWAP (dataptr[3]);
-      out_buff[3] = BIT_SWAP (dataptr[2]);
-      out_buff[4] = BIT_SWAP (dataptr[1]);
-      out_buff[5] = BIT_SWAP (dataptr[0]);
-
-      proto_tree_add_string (tree, ff_current_ap, tvb, offset, 6, out_buff);
+      proto_tree_add_ether (tree, ff_current_ap, tvb, offset, 6, dataptr);
       break;
 
 
     case FIELD_LISTEN_IVAL:
       dataptr = tvb_get_ptr (tvb, offset, 2);
-      out_buff[0] = BIT_SWAP (dataptr[1]);
-      out_buff[1] = BIT_SWAP (dataptr[0]);
-      temp16 = (guint16 *) out_buff;
+      temp16 = (guint16 *) dataptr;
       proto_tree_add_uint (tree, ff_listen_ival, tvb, offset, 2,
 			   pntohs (temp16));
       break;
@@ -485,26 +479,20 @@
 
     case FIELD_REASON_CODE:
       dataptr = tvb_get_ptr (tvb, offset, 2);
-      out_buff[0] = BIT_SWAP (dataptr[1]);
-      out_buff[1] = BIT_SWAP (dataptr[0]);
-      temp16 = (guint16 *) out_buff;
+      temp16 = (guint16 *) dataptr;
       proto_tree_add_uint (tree, ff_reason, tvb, offset, 2, pntohs (temp16));
       break;
 
 
     case FIELD_ASSOC_ID:
       dataptr = tvb_get_ptr (tvb, offset, 2);
-      out_buff[0] = BIT_SWAP (dataptr[1]);
-      out_buff[1] = BIT_SWAP (dataptr[0]);
-      temp16 = (guint16 *) out_buff;
+      temp16 = (guint16 *) dataptr;
       proto_tree_add_uint (tree, ff_assoc_id, tvb, offset, 2, pntohs (temp16));
       break;
 
     case FIELD_STATUS_CODE:
       dataptr = tvb_get_ptr (tvb, offset, 2);
-      out_buff[0] = BIT_SWAP (dataptr[1]);
-      out_buff[1] = BIT_SWAP (dataptr[0]);
-      temp16 = (guint16 *) out_buff;
+      temp16 = (guint16 *) dataptr;
       proto_tree_add_uint (tree, ff_status_code, tvb, offset, 2,
 			   pntohs (temp16));
       break;
@@ -731,6 +719,7 @@
   tvbuff_t *next_tvb;
   guint32 next_idx;
   guint32 addr_type;
+  guint32 next_len;
 
   cap_len = pinfo->captured_len;
   fcf = tvb_get_letohs (tvb, 0);
@@ -827,11 +816,11 @@
 				tvb_get_ptr (tvb, 16, 6));
 
 	  proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
-			       COOK_FRAGMENT_NUMBER (tvb_get_ntohs
+			       COOK_FRAGMENT_NUMBER (tvb_get_letohs
 						     (tvb, 22)));
 
 	  proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
-			       COOK_SEQUENCE_NUMBER (tvb_get_ntohs
+			       COOK_SEQUENCE_NUMBER (tvb_get_letohs
 						     (tvb, 22)));
 	  cap_len = cap_len - MGT_FRAME_LEN - 4;
 	}
@@ -984,8 +973,11 @@
 						   next_idx);
 
 
-	  while (pinfo->captured_len > (next_idx + 4))
-	    next_idx += add_tagged_field (tagged_tree, tvb, next_idx);
+	  while (pinfo->captured_len > (next_idx + 4)) {
+	    if ((next_len=add_tagged_field (tagged_tree, tvb, next_idx))==0)
+	      break;
+	    next_idx +=next_len;
+	  }
 	}
       break;
 
@@ -1008,13 +1000,16 @@
 	  tagged_tree = get_tagged_parameter_tree (tree, tvb, next_idx,
 						   pinfo->captured_len - 4 -
 						   next_idx);
-
-	  while (pinfo->captured_len > (next_idx + 4))
-	    next_idx += add_tagged_field (tagged_tree, tvb, next_idx);
 
+	  while (pinfo->captured_len > (next_idx + 4)) {
+	    if ((next_len=add_tagged_field (tagged_tree, tvb, next_idx))==0)
+	      break;
+	  next_idx +=next_len;
+	  }
 	}
       break;
 
+
     case MGT_REASSOC_REQ:
       COL_SHOW_INFO (pinfo->fd, "Reassociation Request");
       if (tree)
@@ -1031,8 +1026,11 @@
 						   pinfo->captured_len - 4 -
 						   next_idx);
 
-	  while ((pinfo->captured_len) > (next_idx + 4))
-	    next_idx += add_tagged_field (tagged_tree, tvb, next_idx);
+	  while ((pinfo->captured_len) > (next_idx + 4)) {
+	    if ((next_len=add_tagged_field (tagged_tree, tvb, next_idx))==0)
+	      break;
+	    next_idx +=next_len;
+	  }
 	}
       break;
 
@@ -1051,14 +1049,16 @@
 	  tagged_tree = get_tagged_parameter_tree (tree, tvb, next_idx,
 						   pinfo->captured_len - 4 -
 						   next_idx);
-
-	  while (pinfo->captured_len > (next_idx + 4))
-	    next_idx += add_tagged_field (tagged_tree, tvb, next_idx);
 
-
+	  while (pinfo->captured_len > (next_idx + 4)) {
+	    if ((next_len=add_tagged_field (tagged_tree, tvb, next_idx))==0)
+	      break;
+	    next_idx +=next_len;
+	  }
 	}
       break;
 
+
     case MGT_PROBE_REQ:
       COL_SHOW_INFO (pinfo->fd, "Probe Request");
       if (tree)
@@ -1068,13 +1068,15 @@
 						   pinfo->captured_len - 4 -
 						   next_idx);
 
-	  while (pinfo->captured_len > (next_idx + 4))
-	    next_idx += add_tagged_field (tagged_tree, tvb, next_idx);
+	  while (pinfo->captured_len > (next_idx + 4)) {
+	    if ((next_len=add_tagged_field (tagged_tree, tvb, next_idx))==0)
+	      break;
+	    next_idx +=next_len;
+	  }
 	}
       break;
 
 
-
     case MGT_PROBE_RESP:
       COL_SHOW_INFO (pinfo->fd, "Probe Response");
       if (tree)
@@ -1091,8 +1093,11 @@
 						   pinfo->captured_len - 4 -
 						   next_idx);
 
-	  while ((pinfo->captured_len) > (next_idx + 4))
-	    next_idx += add_tagged_field (tagged_tree, tvb, next_idx);
+	  while ((pinfo->captured_len) > (next_idx + 4)) {
+	    if ((next_len=add_tagged_field (tagged_tree, tvb, next_idx))==0)
+	      break;
+	    next_idx +=next_len;
+	  }
 	}
       break;
 
@@ -1116,9 +1121,11 @@
 						   pinfo->captured_len - 4 -
 						   next_idx);
 
-	  while (pinfo->captured_len > (next_idx + 4))
-	    next_idx += add_tagged_field (tagged_tree, tvb, next_idx);
-
+	  while (pinfo->captured_len > (next_idx + 4)) {
+	    if ((next_len=add_tagged_field (tagged_tree, tvb, next_idx))==0)
+	      break;
+	    next_idx +=next_len;
+	  }
 	}
       break;
 
@@ -1135,8 +1142,7 @@
       COL_SHOW_INFO (pinfo->fd, "Dissassociate");
       if (tree)
 	{
-	  fixed_tree =
-	    get_fixed_parameter_tree (tree, tvb, MGT_FRAME_LEN, cap_len);
+	  fixed_tree = get_fixed_parameter_tree (tree, tvb, MGT_FRAME_LEN, cap_len);
 	  add_fixed_field (fixed_tree, tvb, MGT_FRAME_LEN, FIELD_REASON_CODE);
 	}
       break;
@@ -1162,8 +1168,11 @@
 						       pinfo->captured_len -
 						       next_idx - 4);
 
-	      while ((pinfo->captured_len) > (next_idx - 4))
-		next_idx += add_tagged_field (tagged_tree, tvb, next_idx);
+	      while ((pinfo->captured_len) > (next_idx - 4)) {
+		if ((next_len=add_tagged_field (tagged_tree, tvb, next_idx))==0)
+		  break;
+		next_idx +=next_len;
+	      }
 	    }
 	}
       break;
@@ -1648,7 +1657,7 @@
       FT_UINT16, BASE_DEC, VALS (&auth_alg), 0, ""}},
 
     {&ff_beacon_interval,
-     {"Beacon Interval", "wlan.fixed.beacon", FT_UINT16, BASE_DEC, NULL, 0,
+     {"Beacon Interval", "wlan.fixed.beacon", FT_DOUBLE, BASE_DEC, NULL, 0,
       ""}},
 
     {&hf_fixed_parameters,