[PATCH] libertas: clean up 802.11 IE post-scan handling
authorDan Williams <dcbw@redhat.com>
Thu, 2 Aug 2007 14:48:02 +0000 (10:48 -0400)
committerDavid S. Miller <davem@sunset.davemloft.net>
Wed, 10 Oct 2007 23:49:39 +0000 (16:49 -0700)
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>
drivers/net/wireless/libertas/hostcmd.h
drivers/net/wireless/libertas/scan.c
drivers/net/wireless/libertas/types.h

index 01a97d0fa98ab635f77f142d12aa97ffc2ac4ea0..05ea54df71bd14440268eed06b1722304ec1eae0 100644 (file)
@@ -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 {
index 8753f9344f3e85d4218403f06e384d213a764cea..2d6bc7811b2716b0f4ed88da2dde2c27a7309b47 100644 (file)
@@ -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;
index f4be1293cd164cf31ffcff2bd38f695787119201..2df352db1557b6ec89e4d3691a623e284809acc4 100644 (file)
@@ -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 {