[wpa-supplicant] Wireless-extension v19

Jean Tourrilhes jt at hpl.hp.com
Mon Sep 19 16:23:19 EDT 2005


On Mon, Sep 19, 2005 at 11:52:39AM -0700, jt wrote:
> On Sun, Sep 18, 2005 at 08:43:34PM -0700, Jouni Malinen wrote:
> > On Fri, Sep 09, 2005 at 09:10:33PM +0200, Benoit Boissinot wrote:
> > 
> > > Thanks for the comments, here is a revised version (tested with WPA2/RSN
> > > and 2.6.13-mm2).
> > 
> > This does not work with WE-18 and I would assume the same is true for
> > the previous patch since the problem is in the changes in wireless.h. It
> > looks like IW_EV_POINT_LEN changed and if wpa_supplicant is built with
> > wireless.h from v19, older versions do not work. This is quite
> > unfortunate.
> 
> 	Attached is a revised patch.

	Much better if I attach the patch, isn't it ?

	Jean
-------------- next part --------------
diff -u -p driver_wext.orig.c driver_wext.c
--- driver_wext.orig.c	2005-09-19 11:24:07.000000000 -0700
+++ driver_wext.c	2005-09-19 11:43:43.000000000 -0700
@@ -42,8 +42,20 @@ struct wpa_driver_wext_data {
 	size_t assoc_resp_ies_len;
 	struct wpa_driver_capa capa;
 	int has_capability;
+	int we_version_compiled;
 };
 
+/* Note : useless because we always compile with our own chosen version
+ * of wireless.h */
+#if WIRELESS_EXT > 18
+#define IW_EV_POINT_LEN_NEW	IW_EV_POINT_LEN
+#else
+#define 
+#define IW_EV_POINT_OFF (((char *) &(((struct iw_point *) NULL)->length)) - \
+			  (char *) NULL)
+#define IW_EV_POINT_LEN_NEW	(IW_EV_POINT_LEN - IW_EV_POINT_OFF)
+#endif
+
 
 static int wpa_driver_wext_flush_pmkid(void *priv);
 static int wpa_driver_wext_get_range(void *priv);
@@ -385,6 +397,27 @@ static void wpa_driver_wext_event_wirele
 			   iwe->cmd, iwe->len);
 		if (iwe->len <= IW_EV_LCP_LEN)
 			return;
+		/* Fixup Wireless Extension backward compatibility mess */
+		switch (iwe->cmd) {
+		case SIOCGIWAP:
+		case SIOCGIWSCAN:
+			break;
+		default:
+		case IWEVMICHAELMICFAILURE:
+		case IWEVCUSTOM:
+		case IWEVASSOCREQIE:
+		case IWEVASSOCRESPIE:
+		case IWEVPMKIDCAND:
+			if(drv->we_version_compiled > 18) {
+				memmove((char *)iwe + IW_EV_LCP_LEN + IW_EV_POINT_OFF,
+					(char *)iwe + IW_EV_LCP_LEN,
+					sizeof(struct iw_point) - IW_EV_POINT_OFF);
+				custom = pos + IW_EV_POINT_LEN_NEW;
+			} else {
+				custom = pos + IW_EV_POINT_LEN_NEW + IW_EV_POINT_OFF;
+			}
+		}
+		/* Now process the event for real */
 		switch (iwe->cmd) {
 		case SIOCGIWAP:
 			wpa_printf(MSG_DEBUG, "Wireless event: new AP: "
@@ -410,11 +443,9 @@ static void wpa_driver_wext_event_wirele
 			break;
 		case IWEVMICHAELMICFAILURE:
 			wpa_driver_wext_event_wireless_michaelmicfailure(
-				drv, ctx, pos + IW_EV_POINT_LEN,
-				iwe->u.data.length);
+				drv, ctx, custom, iwe->u.data.length);
 			break;
 		case IWEVCUSTOM:
-			custom = pos + IW_EV_POINT_LEN;
 			if (custom + iwe->u.data.length > end)
 				return;
 			buf = malloc(iwe->u.data.length + 1);
@@ -432,18 +463,15 @@ static void wpa_driver_wext_event_wirele
 			break;
 		case IWEVASSOCREQIE:
 			wpa_driver_wext_event_wireless_assocreqie(
-				drv, ctx, pos + IW_EV_POINT_LEN,
-				iwe->u.data.length);
+				drv, ctx, custom, iwe->u.data.length);
 			break;
 		case IWEVASSOCRESPIE:
 			wpa_driver_wext_event_wireless_assocrespie(
-				drv, ctx, pos + IW_EV_POINT_LEN,
-				iwe->u.data.length);
+				drv, ctx, custom, iwe->u.data.length);
 			break;
 		case IWEVPMKIDCAND:
 			wpa_driver_wext_event_wireless_pmkidcand(
-				drv, ctx, pos + IW_EV_POINT_LEN,
-				iwe->u.data.length);
+				drv, ctx, custom, iwe->u.data.length);
 			break;
 		}
 
@@ -851,9 +879,32 @@ int wpa_driver_wext_get_scan_results(voi
 		int ssid_len;
 		/* Event data may be unaligned, so make a local, aligned copy
 		 * before processing. */
-		memcpy(&iwe_buf, pos, sizeof(struct iw_event));
+		memcpy(iwe_buf, pos, sizeof(struct iw_event));
 		if (iwe->len <= IW_EV_LCP_LEN)
 			break;
+		/* Fixup Wireless Extension backward compatibility mess */
+		switch (iwe->cmd) {
+		default:
+		case SIOCGIWAP:
+		case SIOCGIWMODE:
+		case SIOCGIWFREQ:
+		case IWEVQUAL:
+		case SIOCGIWRATE:
+			break;
+		case SIOCGIWESSID:
+		case SIOCGIWENCODE:
+		case IWEVGENIE:
+		case IWEVCUSTOM:
+			if(drv->we_version_compiled > 18) {
+				memmove((char *)iwe + IW_EV_LCP_LEN + IW_EV_POINT_OFF,
+					(char *)iwe + IW_EV_LCP_LEN,
+					sizeof(struct iw_point) - IW_EV_POINT_OFF);
+				custom = pos + IW_EV_POINT_LEN_NEW;
+			} else {
+				custom = pos + IW_EV_POINT_LEN_NEW + IW_EV_POINT_OFF;
+			}
+		}
+		/* Now process the scan result for real */
 		switch (iwe->cmd) {
 		case SIOCGIWAP:
 			if (!first)
@@ -875,7 +926,6 @@ int wpa_driver_wext_get_scan_results(voi
 			break;
 		case SIOCGIWESSID:
 			ssid_len = iwe->u.essid.length;
-			custom = pos + IW_EV_POINT_LEN;
 			if (custom + ssid_len > end)
 				break;
 			if (iwe->u.essid.flags &&
@@ -938,7 +988,7 @@ int wpa_driver_wext_get_scan_results(voi
 		case IWEVGENIE:
 			if (ap_num >= max_size)
 				break;
-			gpos = genie = pos + IW_EV_POINT_LEN;
+			gpos = genie = custom;
 			gend = genie + iwe->u.data.length;
 			if (gend > end) {
 				wpa_printf(MSG_INFO, "IWEVGENIE overflow");
@@ -971,7 +1021,6 @@ int wpa_driver_wext_get_scan_results(voi
 			}
 			break;
 		case IWEVCUSTOM:
-			custom = pos + IW_EV_POINT_LEN;
 			clen = iwe->u.data.length;
 			if (custom + clen > end)
 				break;
@@ -1039,15 +1088,16 @@ int wpa_driver_wext_get_scan_results(voi
 static int wpa_driver_wext_get_range(void *priv)
 {
 	struct wpa_driver_wext_data *drv = priv;
-	struct iw_range range;
+	char	buffer[sizeof(iwrange) * 2];	/* Large enough */
+	struct iw_range *range = buffer;
 	struct iwreq iwr;
 	int minlen;
 
 	memset(&iwr, 0, sizeof(iwr));
 	strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
-	iwr.u.data.pointer = (caddr_t) &range;
-	iwr.u.data.length = sizeof(range);
-	memset(&range, 0, sizeof(range));
+	iwr.u.data.pointer = (caddr_t) buffer;
+	iwr.u.data.length = sizeof(buffer);
+	memset(&range, 0, sizeof(buffer));
 
 	minlen = ((char *) &range.enc_capa) - (char *) &range +
 		sizeof(range.enc_capa);
@@ -1056,25 +1106,27 @@ static int wpa_driver_wext_get_range(voi
 		perror("ioctl[SIOCGIWRANGE]");
 		return -1;
 	} else if (iwr.u.data.length >= minlen &&
-		   range.we_version_compiled >= 18) {
+		   range->we_version_compiled >= 18) {
 		wpa_printf(MSG_DEBUG, "SIOCGIWRANGE: WE(compiled)=%d "
 			   "WE(source)=%d enc_capa=0x%x",
-			   range.we_version_compiled, range.we_version_source,
-			   range.enc_capa);
+			   range->we_version_compiled,
+			   range->we_version_source,
+			   range->enc_capa);
 		drv->has_capability = 1;
-		if (range.enc_capa & IW_ENC_CAPA_WPA) {
+		drv->we_version_compiled = range->we_version_compiled;
+		if (range->enc_capa & IW_ENC_CAPA_WPA) {
 			drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA |
 				WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK;
 		}
-		if (range.enc_capa & IW_ENC_CAPA_WPA2) {
+		if (range->enc_capa & IW_ENC_CAPA_WPA2) {
 			drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
 				WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK;
 		}
 		drv->capa.enc |= WPA_DRIVER_CAPA_ENC_WEP40 |
 			WPA_DRIVER_CAPA_ENC_WEP104;
-		if (range.enc_capa & IW_ENC_CAPA_CIPHER_TKIP)
+		if (range->enc_capa & IW_ENC_CAPA_CIPHER_TKIP)
 			drv->capa.enc |= WPA_DRIVER_CAPA_ENC_TKIP;
-		if (range.enc_capa & IW_ENC_CAPA_CIPHER_CCMP)
+		if (range->enc_capa & IW_ENC_CAPA_CIPHER_CCMP)
 			drv->capa.enc |= WPA_DRIVER_CAPA_ENC_CCMP;
 		wpa_printf(MSG_DEBUG, "  capabilities: key_mgmt 0x%x enc 0x%x",
 			   drv->capa.key_mgmt, drv->capa.enc);


More information about the HostAP mailing list