From 242f5a709c2fb8ee47f708d6066e350ebdbc0b23 Mon Sep 17 00:00:00 2001 From: Florian Schilhabel Date: Thu, 15 Jul 2010 19:04:58 +0200 Subject: staging: rtl8192su: added ioctl[SIOCSIWPMKSA] implementation errors like: ioctl[SIOCSIWPMKSA]: Invalid argument should now be gone. Signed-off-by: Florian Schilhabel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192su/ieee80211/ieee80211.h | 14 +++++ .../rtl8192su/ieee80211/ieee80211_softmac.c | 43 ++++++++++++++ drivers/staging/rtl8192su/r8192U_wx.c | 66 +++++++++++++++++++++- 3 files changed, 122 insertions(+), 1 deletion(-) (limited to 'drivers/staging/rtl8192su') diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211.h b/drivers/staging/rtl8192su/ieee80211/ieee80211.h index 1c14adbfb98b..1d6789db4e4d 100644 --- a/drivers/staging/rtl8192su/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192su/ieee80211/ieee80211.h @@ -1132,6 +1132,19 @@ enum { COUNTRY_CODE_MAX }; +#define NUM_PMKID_CACHE 16 + +typedef struct _RT_PMKID_LIST +{ + u8 bUsed; + u8 Bssid[6]; + u8 PMKID[16]; + u8 SsidBuf[33]; + u8* ssid_octet; + u16 ssid_length; +} RT_PMKID_LIST, *PRT_PMKID_LIST; + + #include "ieee80211_r8192s.h" struct ieee80211_device { @@ -1255,6 +1268,7 @@ struct ieee80211_device { int bcrx_sta_key; /* use individual keys to override default keys even * with RX of broad/multicast frames */ + RT_PMKID_LIST PMKIDList[NUM_PMKID_CACHE]; /* Fragmentation structures */ // each streaming contain a entry struct ieee80211_frag_entry frag_cache[17][IEEE80211_FRAG_CACHE_LEN]; diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c index 2e2f6a0c8f2d..02850479dd62 100644 --- a/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c @@ -1042,6 +1042,33 @@ void ieee80211_resp_to_probe(struct ieee80211_device *ieee, u8 *dest) } +inline int SecIsInPMKIDList(struct ieee80211_device *ieee, u8 *bssid) +{ + int i = 0; + + do + { + if ((ieee->PMKIDList[i].bUsed) && (memcmp(ieee->PMKIDList[i].Bssid, bssid, ETH_ALEN) == 0)) + { + break; + } + else + { + i++; + } + } while (i < NUM_PMKID_CACHE); + + if (i == NUM_PMKID_CACHE) + { + i = -1; + } + else + { + } + + return (i); + +} inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beacon,struct ieee80211_device *ieee) { struct sk_buff *skb; @@ -1058,6 +1085,7 @@ inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beaco unsigned int cxvernum_ie_len=0; struct ieee80211_crypt_data* crypt; int encrypt; + int PMKCacheIdx; unsigned int rate_len = ieee80211_MFIE_rate_len(ieee); unsigned int wmm_info_len = beacon->qos_data.supported?9:0; @@ -1099,6 +1127,14 @@ inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beaco { cxvernum_ie_len = 5+2; } + + PMKCacheIdx = SecIsInPMKIDList(ieee, ieee->current_network.bssid); + if (PMKCacheIdx >= 0) + { + wpa_ie_len += 18; + printk("[PMK cache]: WPA2 IE length: %x\n", wpa_ie_len); + } + len = sizeof(struct ieee80211_assoc_request_frame)+ 2 + beacon->ssid_len//essid tagged val + rate_len//rates tagged val @@ -1226,6 +1262,13 @@ inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beaco tag = skb_put(skb, wpa_ie_len); if (wpa_ie_len){ memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len); + if (PMKCacheIdx >= 0) + { + tag = skb_put(skb, 18); + *tag = 1; + *(tag + 1) = 0; + memcpy((tag + 2), &ieee->PMKIDList[PMKCacheIdx].PMKID, 16); + } } tag = skb_put(skb,wmm_info_len); diff --git a/drivers/staging/rtl8192su/r8192U_wx.c b/drivers/staging/rtl8192su/r8192U_wx.c index 917578078b3a..2005b811ebab 100644 --- a/drivers/staging/rtl8192su/r8192U_wx.c +++ b/drivers/staging/rtl8192su/r8192U_wx.c @@ -1013,6 +1013,70 @@ static int r8192_wx_set_mlme(struct net_device *dev, return ret; } +static int r8192_wx_set_pmkid(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int i; + struct r8192_priv *priv = ieee80211_priv(dev); + struct ieee80211_device* ieee = priv->ieee80211; + struct iw_pmksa* pPMK = (struct iw_pmksa*)extra; + int intReturn = false; + + switch (pPMK->cmd) + { + case IW_PMKSA_ADD: + for (i = 0; i < NUM_PMKID_CACHE; i++) + { + if (memcmp(ieee->PMKIDList[i].Bssid, pPMK->bssid.sa_data, ETH_ALEN) == 0) + { + memcpy(ieee->PMKIDList[i].PMKID, pPMK->pmkid, IW_PMKID_LEN); + memcpy(ieee->PMKIDList[i].Bssid, pPMK->bssid.sa_data, ETH_ALEN); + ieee->PMKIDList[i].bUsed = true; + intReturn = true; + goto __EXIT__; + } + } + + for (i = 0; i < NUM_PMKID_CACHE; i++) + { + if (ieee->PMKIDList[i].bUsed == false) + { + memcpy(ieee->PMKIDList[i].PMKID, pPMK->pmkid, IW_PMKID_LEN); + memcpy(ieee->PMKIDList[i].Bssid, pPMK->bssid.sa_data, ETH_ALEN); + ieee->PMKIDList[i].bUsed = true; + intReturn = true; + goto __EXIT__; + } + } + break; + + case IW_PMKSA_REMOVE: + for (i = 0; i < NUM_PMKID_CACHE; i++) + { + if (memcmp(ieee->PMKIDList[i].Bssid, pPMK->bssid.sa_data, ETH_ALEN) == true) + { + memset(&ieee->PMKIDList[i], 0x00, sizeof(RT_PMKID_LIST)); + intReturn = true; + break; + } + } + break; + + case IW_PMKSA_FLUSH: + memset(&ieee->PMKIDList[0], 0x00, (sizeof(RT_PMKID_LIST) * NUM_PMKID_CACHE)); + intReturn = true; + break; + + default: + break; + } + +__EXIT__: + return (intReturn); + +} + static int r8192_wx_set_gen_ie(struct net_device *dev, struct iw_request_info *info, union iwreq_data *data, char *extra) @@ -1095,7 +1159,7 @@ static iw_handler r8192_wx_handlers[] = NULL,//r8192_wx_get_auth,//NULL, /* SIOCSIWAUTH */ r8192_wx_set_enc_ext, /* SIOCSIWENCODEEXT */ NULL,//r8192_wx_get_enc_ext,//NULL, /* SIOCSIWENCODEEXT */ - NULL, /* SIOCSIWPMKSA */ + r8192_wx_set_pmkid, /* SIOCSIWPMKSA */ NULL, /*---hole---*/ }; -- cgit v1.2.3-59-g8ed1b