Browse Source

[PATCH] libertas: clean up 802.11 IE post-scan handling

Remove struct IE_WPA and just use direct checking of the IE
bytes like ipw.  Remove WLAN_802_11_VARIABLE_IEs because
it's unused.

Kill ieeetypes_elementid enum and just use MFIE_* from
ieee80211.h.  Also use struct ieee80211_info_element for
scan buffer processing to simplify pointer usage.

Signed-off-by: Dan Williams <dcbw@redhat.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Dan Williams 18 years ago
parent
commit
ab6179711a

+ 0 - 13
drivers/net/wireless/libertas/hostcmd.h

@@ -91,25 +91,12 @@ struct enc_key {
 	u8 key[32];
 };
 
-struct IE_WPA {
-	u8 elementid;
-	u8 len;
-	u8 oui[4];
-	__le16 version;
-};
-
 /* wlan_offset_value */
 struct wlan_offset_value {
 	u32 offset;
 	u32 value;
 };
 
-struct WLAN_802_11_VARIABLE_IEs {
-	u8 elementid;
-	u8 length;
-	u8 data[1];
-};
-
 /* Define general data structure */
 /* cmd_DS_GEN */
 struct cmd_ds_gen {

+ 84 - 115
drivers/net/wireless/libertas/scan.c

@@ -74,8 +74,8 @@ static inline int match_bss_no_security(struct wlan_802_11_security * secinfo,
 	if (   !secinfo->wep_enabled
 	    && !secinfo->WPAenabled
 	    && !secinfo->WPA2enabled
-	    && match_bss->wpa_ie[0] != WPA_IE
-	    && match_bss->rsn_ie[0] != WPA2_IE
+	    && match_bss->wpa_ie[0] != MFIE_TYPE_GENERIC
+	    && match_bss->rsn_ie[0] != MFIE_TYPE_RSN
 	    && !(match_bss->capability & WLAN_CAPABILITY_PRIVACY)) {
 		return 1;
 	}
@@ -99,7 +99,7 @@ static inline int match_bss_wpa(struct wlan_802_11_security * secinfo,
 {
 	if (  !secinfo->wep_enabled
 	   && secinfo->WPAenabled
-	   && (match_bss->wpa_ie[0] == WPA_IE)
+	   && (match_bss->wpa_ie[0] == MFIE_TYPE_GENERIC)
 	   /* privacy bit may NOT be set in some APs like LinkSys WRT54G
 	      && (match_bss->capability & WLAN_CAPABILITY_PRIVACY)) {
 	    */
@@ -114,7 +114,7 @@ static inline int match_bss_wpa2(struct wlan_802_11_security * secinfo,
 {
 	if (  !secinfo->wep_enabled
 	   && secinfo->WPA2enabled
-	   && (match_bss->rsn_ie[0] == WPA2_IE)
+	   && (match_bss->rsn_ie[0] == MFIE_TYPE_RSN)
 	   /* privacy bit may NOT be set in some APs like LinkSys WRT54G
 	      && (match_bss->capability & WLAN_CAPABILITY_PRIVACY)) {
 	    */
@@ -130,8 +130,8 @@ static inline int match_bss_dynamic_wep(struct wlan_802_11_security * secinfo,
 	if (  !secinfo->wep_enabled
 	   && !secinfo->WPAenabled
 	   && !secinfo->WPA2enabled
-	   && (match_bss->wpa_ie[0] != WPA_IE)
-	   && (match_bss->rsn_ie[0] != WPA2_IE)
+	   && (match_bss->wpa_ie[0] != MFIE_TYPE_GENERIC)
+	   && (match_bss->rsn_ie[0] != MFIE_TYPE_RSN)
 	   && (match_bss->capability & WLAN_CAPABILITY_PRIVACY)) {
 		return 1;
 	}
@@ -900,24 +900,18 @@ void wlan_ret_802_11_scan_get_tlv_ptrs(struct mrvlietypes_data * ptlv,
 static int libertas_process_bss(struct bss_descriptor * bss,
 				u8 ** pbeaconinfo, int *bytesleft)
 {
-	enum ieeetypes_elementid elemID;
 	struct ieeetypes_fhparamset *pFH;
 	struct ieeetypes_dsparamset *pDS;
 	struct ieeetypes_cfparamset *pCF;
 	struct ieeetypes_ibssparamset *pibss;
-	u8 *pcurrentptr;
+	u8 *pos, *end;
 	u8 *pRate;
-	u8 elemlen;
 	u8 bytestocopy;
 	u8 ratesize;
 	u16 beaconsize;
 	u8 founddatarateie;
-	int bytesleftforcurrentbeacon;
 	int ret;
 
-	struct IE_WPA *pIe;
-	const u8 oui01[4] = { 0x00, 0x50, 0xf2, 0x01 };
-
 	struct ieeetypes_countryinfoset *pcountryinfo;
 
 	lbs_deb_enter(LBS_DEB_ASSOC);
@@ -934,29 +928,24 @@ static int libertas_process_bss(struct bss_descriptor * bss,
 	}
 
 	if (beaconsize == 0 || beaconsize > *bytesleft) {
-
 		*pbeaconinfo += *bytesleft;
 		*bytesleft = 0;
-
 		return -1;
 	}
 
 	/* Initialize the current working beacon pointer for this BSS iteration */
-	pcurrentptr = *pbeaconinfo;
+	pos = *pbeaconinfo;
+	end = pos + beaconsize;
 
 	/* Advance the return beacon pointer past the current beacon */
 	*pbeaconinfo += beaconsize;
 	*bytesleft -= beaconsize;
 
-	bytesleftforcurrentbeacon = beaconsize;
-
-	memcpy(bss->bssid, pcurrentptr, ETH_ALEN);
+	memcpy(bss->bssid, pos, ETH_ALEN);
 	lbs_deb_scan("process_bss: AP BSSID " MAC_FMT "\n", MAC_ARG(bss->bssid));
+	pos += ETH_ALEN;
 
-	pcurrentptr += ETH_ALEN;
-	bytesleftforcurrentbeacon -= ETH_ALEN;
-
-	if (bytesleftforcurrentbeacon < 12) {
+	if ((end - pos) < 12) {
 		lbs_deb_scan("process_bss: Not enough bytes left\n");
 		return -1;
 	}
@@ -967,26 +956,22 @@ static int libertas_process_bss(struct bss_descriptor * bss,
 	 */
 
 	/* RSSI is 1 byte long */
-	bss->rssi = *pcurrentptr;
-	lbs_deb_scan("process_bss: RSSI=%02X\n", *pcurrentptr);
-	pcurrentptr += 1;
-	bytesleftforcurrentbeacon -= 1;
+	bss->rssi = *pos;
+	lbs_deb_scan("process_bss: RSSI=%02X\n", *pos);
+	pos++;
 
 	/* time stamp is 8 bytes long */
-	bss->timestamp = le64_to_cpup((void *)pcurrentptr);
-	pcurrentptr += 8;
-	bytesleftforcurrentbeacon -= 8;
+	bss->timestamp = le64_to_cpup((void *) pos);
+	pos += 8;
 
 	/* beacon interval is 2 bytes long */
-	bss->beaconperiod = le16_to_cpup((void *)pcurrentptr);
-	pcurrentptr += 2;
-	bytesleftforcurrentbeacon -= 2;
+	bss->beaconperiod = le16_to_cpup((void *) pos);
+	pos += 2;
 
 	/* capability information is 2 bytes long */
-	bss->capability = le16_to_cpup((void *)pcurrentptr);
+	bss->capability = le16_to_cpup((void *) pos);
 	lbs_deb_scan("process_bss: capabilities = 0x%4X\n", bss->capability);
-	pcurrentptr += 2;
-	bytesleftforcurrentbeacon -= 2;
+	pos += 2;
 
 	if (bss->capability & WLAN_CAPABILITY_PRIVACY)
 		lbs_deb_scan("process_bss: AP WEP enabled\n");
@@ -996,47 +981,39 @@ static int libertas_process_bss(struct bss_descriptor * bss,
 		bss->mode = IW_MODE_INFRA;
 
 	/* rest of the current buffer are IE's */
-	lbs_deb_scan("process_bss: IE length for this AP = %d\n",
-	       bytesleftforcurrentbeacon);
-
-	lbs_dbg_hex("process_bss: IE info", (u8 *) pcurrentptr,
-		bytesleftforcurrentbeacon);
+	lbs_deb_scan("process_bss: IE length for this AP = %zd\n", end - pos);
+	lbs_dbg_hex("process_bss: IE info", pos, end - pos);
 
 	/* process variable IE */
-	while (bytesleftforcurrentbeacon >= 2) {
-		elemID = (enum ieeetypes_elementid) (*((u8 *) pcurrentptr));
-		elemlen = *((u8 *) pcurrentptr + 1);
+	while (pos <= end - 2) {
+		struct ieee80211_info_element * elem =
+			(struct ieee80211_info_element *) pos;
 
-		if (bytesleftforcurrentbeacon < elemlen) {
+		if (pos + elem->len > end) {
 			lbs_deb_scan("process_bss: error in processing IE, "
 			       "bytes left < IE length\n");
-			bytesleftforcurrentbeacon = 0;
-			continue;
+			break;
 		}
 
-		switch (elemID) {
-		case SSID:
-			bss->ssid_len = elemlen;
-			memcpy(bss->ssid, (pcurrentptr + 2), elemlen);
+		switch (elem->id) {
+		case MFIE_TYPE_SSID:
+			bss->ssid_len = elem->len;
+			memcpy(bss->ssid, elem->data, elem->len);
 			lbs_deb_scan("ssid '%s', ssid length %u\n",
 			             escape_essid(bss->ssid, bss->ssid_len),
 			             bss->ssid_len);
 			break;
 
-		case SUPPORTED_RATES:
-			memcpy(bss->datarates, (pcurrentptr + 2), elemlen);
-			memmove(bss->libertas_supported_rates, (pcurrentptr + 2),
-				elemlen);
-			ratesize = elemlen;
+		case MFIE_TYPE_RATES:
+			memcpy(bss->datarates, elem->data, elem->len);
+			memmove(bss->libertas_supported_rates, elem->data,
+				elem->len);
+			ratesize = elem->len;
 			founddatarateie = 1;
 			break;
 
-		case EXTRA_IE:
-			lbs_deb_scan("process_bss: EXTRA_IE Found!\n");
-			break;
-
-		case FH_PARAM_SET:
-			pFH = (struct ieeetypes_fhparamset *) pcurrentptr;
+		case MFIE_TYPE_FH_SET:
+			pFH = (struct ieeetypes_fhparamset *) pos;
 			memmove(&bss->phyparamset.fhparamset, pFH,
 				sizeof(struct ieeetypes_fhparamset));
 #if 0 /* I think we can store these LE */
@@ -1045,21 +1022,21 @@ static int libertas_process_bss(struct bss_descriptor * bss,
 #endif
 			break;
 
-		case DS_PARAM_SET:
-			pDS = (struct ieeetypes_dsparamset *) pcurrentptr;
+		case MFIE_TYPE_DS_SET:
+			pDS = (struct ieeetypes_dsparamset *) pos;
 			bss->channel = pDS->currentchan;
 			memcpy(&bss->phyparamset.dsparamset, pDS,
 			       sizeof(struct ieeetypes_dsparamset));
 			break;
 
-		case CF_PARAM_SET:
-			pCF = (struct ieeetypes_cfparamset *) pcurrentptr;
+		case MFIE_TYPE_CF_SET:
+			pCF = (struct ieeetypes_cfparamset *) pos;
 			memcpy(&bss->ssparamset.cfparamset, pCF,
 			       sizeof(struct ieeetypes_cfparamset));
 			break;
 
-		case IBSS_PARAM_SET:
-			pibss = (struct ieeetypes_ibssparamset *) pcurrentptr;
+		case MFIE_TYPE_IBSS_SET:
+			pibss = (struct ieeetypes_ibssparamset *) pos;
 			bss->atimwindow = le32_to_cpu(pibss->atimwindow);
 			memmove(&bss->ssparamset.ibssparamset, pibss,
 				sizeof(struct ieeetypes_ibssparamset));
@@ -1069,9 +1046,8 @@ static int libertas_process_bss(struct bss_descriptor * bss,
 #endif
 			break;
 
-			/* Handle Country Info IE */
-		case COUNTRY_INFO:
-			pcountryinfo = (struct ieeetypes_countryinfoset *) pcurrentptr;
+		case MFIE_TYPE_COUNTRY:
+			pcountryinfo = (struct ieeetypes_countryinfoset *) pos;
 			if (pcountryinfo->len < sizeof(pcountryinfo->countrycode)
 			    || pcountryinfo->len > 254) {
 				lbs_deb_scan("process_bss: 11D- Err "
@@ -1089,62 +1065,55 @@ static int libertas_process_bss(struct bss_descriptor * bss,
 				(u32) (pcountryinfo->len + 2));
 			break;
 
-		case EXTENDED_SUPPORTED_RATES:
-			/*
-			 * only process extended supported rate
-			 * if data rate is already found.
-			 * data rate IE should come before
+		case MFIE_TYPE_RATES_EX:
+			/* only process extended supported rate if data rate is
+			 * already found. Data rate IE should come before
 			 * extended supported rate IE
 			 */
-			if (founddatarateie) {
-				if ((elemlen + ratesize) > WLAN_SUPPORTED_RATES) {
-					bytestocopy =
-					    (WLAN_SUPPORTED_RATES - ratesize);
-				} else {
-					bytestocopy = elemlen;
-				}
+			if (!founddatarateie)
+				break;
 
-				pRate = (u8 *) bss->datarates;
-				pRate += ratesize;
-				memmove(pRate, (pcurrentptr + 2), bytestocopy);
-				pRate = (u8 *) bss->libertas_supported_rates;
-				pRate += ratesize;
-				memmove(pRate, (pcurrentptr + 2), bytestocopy);
+			if ((elem->len + ratesize) > WLAN_SUPPORTED_RATES) {
+				bytestocopy =
+				    (WLAN_SUPPORTED_RATES - ratesize);
+			} else {
+				bytestocopy = elem->len;
 			}
-			break;
-
-		case VENDOR_SPECIFIC_221:
-#define IE_ID_LEN_FIELDS_BYTES 2
-			pIe = (struct IE_WPA *)pcurrentptr;
 
-			if (memcmp(pIe->oui, oui01, sizeof(oui01)))
-				break;
-
-			bss->wpa_ie_len = min(elemlen + IE_ID_LEN_FIELDS_BYTES,
-				MAX_WPA_IE_LEN);
-			memcpy(bss->wpa_ie, pcurrentptr, bss->wpa_ie_len);
-			lbs_dbg_hex("process_bss: WPA IE", bss->wpa_ie, elemlen);
+			pRate = (u8 *) bss->datarates;
+			pRate += ratesize;
+			memmove(pRate, elem->data, bytestocopy);
+			pRate = (u8 *) bss->libertas_supported_rates;
+			pRate += ratesize;
+			memmove(pRate, elem->data, bytestocopy);
 			break;
-		case WPA2_IE:
-			pIe = (struct IE_WPA *)pcurrentptr;
-			bss->rsn_ie_len = min(elemlen + IE_ID_LEN_FIELDS_BYTES,
-				MAX_WPA_IE_LEN);
-			memcpy(bss->rsn_ie, pcurrentptr, bss->rsn_ie_len);
-			lbs_dbg_hex("process_bss: RSN_IE", bss->rsn_ie, elemlen);
+
+		case MFIE_TYPE_GENERIC:
+			if (elem->len >= 4 &&
+			    elem->data[0] == 0x00 &&
+			    elem->data[1] == 0x50 &&
+			    elem->data[2] == 0xf2 &&
+			    elem->data[3] == 0x01) {
+				bss->wpa_ie_len = min(elem->len + 2,
+				                      MAX_WPA_IE_LEN);
+				memcpy(bss->wpa_ie, elem, bss->wpa_ie_len);
+				lbs_dbg_hex("process_bss: WPA IE", bss->wpa_ie,
+				            elem->len);
+			}
 			break;
-		case TIM:
+
+		case MFIE_TYPE_RSN:
+			bss->rsn_ie_len = min(elem->len + 2, MAX_WPA_IE_LEN);
+			memcpy(bss->rsn_ie, elem, bss->rsn_ie_len);
+			lbs_dbg_hex("process_bss: RSN_IE", bss->rsn_ie, elem->len);
 			break;
 
-		case CHALLENGE_TEXT:
+		default:
 			break;
 		}
 
-		pcurrentptr += elemlen + 2;
-
-		/* need to account for IE ID and IE len */
-		bytesleftforcurrentbeacon -= (elemlen + 2);
-
-	}			/* while (bytesleftforcurrentbeacon > 2) */
+		pos += elem->len + 2;
+	}
 
 	/* Timestamp */
 	bss->last_scanned = jiffies;

+ 0 - 23
drivers/net/wireless/libertas/types.h

@@ -7,29 +7,6 @@
 #include <linux/if_ether.h>
 #include <asm/byteorder.h>
 
-/** IEEE type definitions  */
-enum ieeetypes_elementid {
-	SSID = 0,
-	SUPPORTED_RATES,
-	FH_PARAM_SET,
-	DS_PARAM_SET,
-	CF_PARAM_SET,
-	TIM,
-	IBSS_PARAM_SET,
-	COUNTRY_INFO = 7,
-
-	CHALLENGE_TEXT = 16,
-
-	EXTENDED_SUPPORTED_RATES = 50,
-
-	VENDOR_SPECIFIC_221 = 221,
-
-	WPA_IE = 221,
-	WPA2_IE = 48,
-
-	EXTRA_IE = 133,
-} __attribute__ ((packed));
-
 #define CAPINFO_MASK	(~(0x00da))
 
 struct ieeetypes_cfparamset {