Ethereal-dev: [Ethereal-dev] yet another 802.11 patch.

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, 31 Jan 2001 14:04:57 +0100
Hello everybody,
We have found a few more bugs in the 802.11 dissector. The following
should now be fixed:

Correct number of addresses shown in dataframes.
Duration ID changed to "Association ID" in power-save polls
Added sequence and fragment numbers.
Corrected representation of frame-control flags.
Added dissection of data frames with piggybacked CF-Ack, Poll but no
data.
Cleaned up code a bit (mostly empty lines)...

The new fileformat has moved on and is going to be my hobby project (to
be done in my sparetime). I will be back with more information about
that and perhaps a design proposal soon...

Best regards,
Johan Jorgensen
Index: packet-ieee80211.c
===================================================================
RCS file: /cvsroot/ethereal/packet-ieee80211.c,v
retrieving revision 1.12
diff -u -r1.12 packet-ieee80211.c
--- packet-ieee80211.c	2001/01/23 05:54:09	1.12
+++ packet-ieee80211.c	2001/01/31 12:55:39
@@ -72,8 +72,8 @@
 #define COOK_PROT_VERSION(x)  ((x & 0x3))
 #define COOK_FRAME_TYPE(x)    ((x & 0xC) >> 2)
 #define COOK_FRAME_SUBTYPE(x) ((x & 0xF0) >> 4)
-#define COOK_ADDR_SELECTOR(x) (((x & 0x200) >> 8) + ((x & 0x100) >> 8))
-
+#define COOK_ADDR_SELECTOR(x) (((x & 0x2)) && ((x & 0x1)))
+#define COOK_ASSOC_ID(x)      ((x & 0x3FFF))
 #define COOK_FRAGMENT_NUMBER(x) (x & 0x000F)
 #define COOK_SEQUENCE_NUMBER(x) ((x & 0xFFF0) >> 4)
 #define COOK_FLAGS(x)           ((x & 0xFF00) >> 8)
@@ -81,14 +81,14 @@
 #define COL_SHOW_INFO(fd,info) if (check_col(fd,COL_INFO)) \
 col_add_str(fd,COL_INFO,info);
 
-#define IS_TO_DS(x)            ((x & 0x100) >> 8)
-#define IS_FROM_DS(x)          ((x & 0x200) >> 9)
-#define HAVE_FRAGMENTS(x)      ((x & 0x400) >> 10)
-#define IS_RETRY(x)            ((x & 0x800) >> 11)
-#define POWER_MGT_STATUS(x)    ((x & 0x1000))
-#define HAS_MORE_DATA(x)       ((x & 0x2000))
-#define IS_WEP(x)              ((x & 0x4000))
-#define IS_STRICTLY_ORDERED(x) ((x & 0x8000))
+#define IS_TO_DS(x)            ((x & 0x1))
+#define IS_FROM_DS(x)          ((x & 0x2))
+#define HAVE_FRAGMENTS(x)      ((x & 0x4))
+#define IS_RETRY(x)            ((x & 0x8))
+#define POWER_MGT_STATUS(x)    ((x & 0x10))
+#define HAS_MORE_DATA(x)       ((x & 0x20))
+#define IS_WEP(x)              ((x & 0x40))
+#define IS_STRICTLY_ORDERED(x) ((x & 0x80))
 
 #define MGT_RESERVED_RANGE(x) (((x>=0x06)&&(x<=0x07))||((x>=0x0D)&&(x<=0x0F)))
 #define CTRL_RESERVED_RANGE(x) ((x>=0x10)&&(x<=0x19))
@@ -129,10 +129,11 @@
 #define DATA                 0x20	/* Data - Data                             */
 #define DATA_CF_ACK          0x21	/* Data - Data + CF acknowledge            */
 #define DATA_CF_POLL         0x22	/* Data - Data + CF poll                   */
-#define DATA_CF_ACK_POLL     0x23	/* Data - Data + CF acknowledge & CF poll  */
+#define DATA_CF_ACK_POLL     0x23	/* Data - Data + CF acknowledge + CF poll  */
 #define DATA_NULL_FUNCTION   0x24	/* Data - Null function (no data)          */
 #define DATA_CF_ACK_NOD      0x25	/* Data - CF ack (no data)                 */
-#define DATA_CF_ACK_POLL_NOD 0x26	/* Data - CF ack + CF poll (no data)       */
+#define DATA_CF_POLL_NOD     0x26       /* Data - Data + CF poll (No data)         */
+#define DATA_CF_ACK_POLL_NOD 0x27	/* Data - CF ack + CF poll (no data)       */
 
 #define DATA_ADDR_T1         0x00
 #define DATA_ADDR_T2         0x01
@@ -201,7 +202,7 @@
 /*                   Header values for Duration/ID field                     */
 /* ************************************************************************* */
 static int hf_did_duration = -1;
-
+static int hf_assoc_id = -1;
 
 
 /* ************************************************************************* */
@@ -244,7 +245,7 @@
 /*            Flags found in the capability field (fixed field)              */
 /* ************************************************************************* */
 static int ff_capture = -1;
-static int ff_cf_sta_poll = -1;	/* CF pollable status for a STA            */
+static int ff_cf_sta_poll = -1; /* CF pollable status for a STA            */
 static int ff_cf_ap_poll = -1;	/* CF pollable status for an AP            */
 static int ff_cf_ess = -1;
 static int ff_cf_ibss = -1;
@@ -275,7 +276,7 @@
 static dissector_handle_t llc_handle;
 
 /* ************************************************************************* */
-/*                                                                           */
+/*            Return the length of the current header (in bytes)             */
 /* ************************************************************************* */
 int
 find_header_length (const u_char * pd, int offset)
@@ -283,8 +284,8 @@
   guint16 frame_control;
 
   frame_control = pntohs (pd);
-  return ((IS_FROM_DS (frame_control))
-	  && (IS_TO_DS (frame_control))) ? 30 : 24;
+  return ((IS_FROM_DS(frame_control))
+	  && (IS_TO_DS(frame_control))) ? 30 : 24;
 }
 
 
@@ -754,11 +755,10 @@
 					   "IEEE 802.11 Header");
       hdr_tree = proto_item_add_subtree (ti, ett_80211);
 
-      fc_item =
-	proto_tree_add_uint_format (hdr_tree, hf_fc_field, tvb, 0, 2,
-				    tvb_get_letohs (tvb, 0),
-				    "Frame Control: 0x%04X",
-				    tvb_get_letohs (tvb, 0));
+      fc_item = proto_tree_add_uint_format (hdr_tree, hf_fc_field, tvb, 0, 2,
+					    tvb_get_letohs (tvb, 0),
+					    "Frame Control: 0x%04X",
+					    tvb_get_letohs (tvb, 0));
 
       fc_tree = proto_item_add_subtree (fc_item, ett_fc_tree);
 
@@ -784,12 +784,6 @@
       proto_tree_add_uint (flag_tree, hf_fc_data_ds, tvb, 1, 1,
 			   COOK_DS_STATUS (flags));
 
-      /*      proto_tree_add_boolean(flag_tree,hf_fc_to_ds,tvb,1,1,
-         flags);
-
-         proto_tree_add_boolean(flag_tree,hf_fc_from_ds,tvb,1,1,
-         flags); */
-
       proto_tree_add_boolean (flag_tree, hf_fc_more_frag, tvb, 1, 1,
 			      flags);
 
@@ -804,12 +798,16 @@
 
       proto_tree_add_boolean (flag_tree, hf_fc_order, tvb, 1, 1, flags);
 
-      proto_tree_add_uint (hdr_tree, hf_did_duration, tvb, 2, 2,
-			   tvb_get_ntohs (tvb, 2));
-
+      if ((COMPOSE_FRAME_TYPE(fcf))==CTRL_PS_POLL) 
+	proto_tree_add_uint(hdr_tree, hf_assoc_id,tvb,2,2,
+			    COOK_ASSOC_ID(tvb_get_ntohs(tvb,2)));
+     
+      else
+	  proto_tree_add_uint (hdr_tree, hf_did_duration, tvb, 2, 2,
+			       tvb_get_ntohs (tvb, 2));
     }
 
-  /* Perform Tasks which are common to a certain frame type */
+  /* Perform tasks which are common to a certain frame type */
   switch (COOK_FRAME_TYPE (fcf))
     {
 
@@ -857,6 +855,7 @@
 
     case DATA_FRAME:
       addr_type = COOK_ADDR_SELECTOR (fcf);
+      hdr_len = find_header_length (tvb_get_ptr (tvb, 0, cap_len), 0);
 
       /* In order to show src/dst address we must always do the following */
       switch (addr_type)
@@ -911,9 +910,15 @@
 				    tvb_get_ptr (tvb, 10, 6));
 	      proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 16, 6,
 				    tvb_get_ptr (tvb, 16, 6));
+	      proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
+				   COOK_FRAGMENT_NUMBER (tvb_get_ntohs
+							 (tvb, 22)));
+	      proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
+				   COOK_SEQUENCE_NUMBER (tvb_get_ntohs
+							 (tvb, 22)));
 	      break;
-
-
+	      
+	      
 	    case DATA_ADDR_T2:
 	      proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 4, 6,
 				    tvb_get_ptr (tvb, 4, 6));
@@ -921,9 +926,15 @@
 				    tvb_get_ptr (tvb, 10, 6));
 	      proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 16, 6,
 				    tvb_get_ptr (tvb, 16, 6));
+	      proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
+				   COOK_FRAGMENT_NUMBER (tvb_get_ntohs
+							 (tvb, 22)));
+	      proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
+				   COOK_SEQUENCE_NUMBER (tvb_get_ntohs
+							 (tvb, 22)));
 	      break;
+   
 
-
 	    case DATA_ADDR_T3:
 	      proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 4, 6,
 				    tvb_get_ptr (tvb, 4, 6));
@@ -931,8 +942,14 @@
 				    tvb_get_ptr (tvb, 10, 6));
 	      proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 16, 6,
 				    tvb_get_ptr (tvb, 16, 6));
+	      proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
+				   COOK_FRAGMENT_NUMBER (tvb_get_ntohs
+							 (tvb, 22)));
+	      proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
+				   COOK_SEQUENCE_NUMBER (tvb_get_ntohs
+							 (tvb, 22)));
 	      break;
-
+	      
 
 	    case DATA_ADDR_T4:
 	      proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6,
@@ -941,10 +958,15 @@
 				    tvb_get_ptr (tvb, 10, 6));
 	      proto_tree_add_ether (hdr_tree, hf_addr_da, tvb, 16, 6,
 				    tvb_get_ptr (tvb, 16, 6));
+	      proto_tree_add_uint (hdr_tree, hf_frag_number, tvb, 22, 2,
+				   COOK_FRAGMENT_NUMBER (tvb_get_ntohs
+							 (tvb, 22)));
+	      proto_tree_add_uint (hdr_tree, hf_seq_number, tvb, 22, 2,
+				   COOK_SEQUENCE_NUMBER (tvb_get_ntohs
+							 (tvb, 22)));
 	      proto_tree_add_ether (hdr_tree, hf_addr_sa, tvb, 24, 6,
 				    tvb_get_ptr (tvb, 24, 6));
 	      break;
-
 	    }
 
 	}
@@ -1279,15 +1301,10 @@
 
       if (tree)
 	{
-	  proto_tree_add_uint (hdr_tree, hf_did_duration, tvb, 2, 2,
-			       tvb_get_ntohs (tvb, 2));
-
 	  proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6,
 				tvb_get_ptr (tvb, 4, 6));
-
 	  proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 10, 6,
 				tvb_get_ptr (tvb, 10, 6));
-
 	}
       break;
 
@@ -1309,15 +1326,11 @@
 
       if (tree)
 	{
-	  proto_tree_add_uint (hdr_tree, hf_did_duration, tvb, 2, 2,
-			       tvb_get_ntohs (tvb, 2));
-
 	  proto_tree_add_ether (hdr_tree, hf_addr_ra, tvb, 4, 6,
 				tvb_get_ptr (tvb, 4, 6));
 
 	  proto_tree_add_ether (hdr_tree, hf_addr_bssid, tvb, 10, 6,
 				tvb_get_ptr (tvb, 10, 6));
-
 	}
       break;
 
@@ -1383,13 +1396,16 @@
       break;
 
 
+    case DATA_CF_POLL_NOD:
+      COL_SHOW_INFO (pinfo->fd, "Data + CF-Poll (No data)");
+      break;
+
 
     case DATA_CF_ACK_POLL_NOD:
       COL_SHOW_INFO (pinfo->fd, "Data + CF-Acknowledgement/Poll (No data)");
       break;
 
 
-
     default:
       COL_SHOW_INFO (pinfo->fd, "Unrecognized (Reserved frame)");
       break;
@@ -1591,6 +1607,10 @@
     {&hf_fc_order,
      {"Order flag", "wlan.fc.order", FT_BOOLEAN, 8, TFS (&order_flags), 0x80,
       "Strictly ordered flag"}},
+
+    {&hf_assoc_id,
+     {"Association ID","wlan.aid",FT_UINT16, BASE_DEC,NULL,0,
+      "Association-ID field" }},
 
     {&hf_did_duration,
      {"Duration", "wlan.duration", FT_UINT16, BASE_DEC, NULL, 0,