Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 242f5a70 authored by Florian Schilhabel's avatar Florian Schilhabel Committed by Greg Kroah-Hartman
Browse files

staging: rtl8192su: added ioctl[SIOCSIWPMKSA] implementation



errors like:
ioctl[SIOCSIWPMKSA]: Invalid argument
should now be gone.

Signed-off-by: default avatarFlorian Schilhabel <florian.c.schilhabel@googlemail.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 53faa56b
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -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];
+43 −0
Original line number Diff line number Diff line
@@ -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);
+65 −1
Original line number Diff line number Diff line
@@ -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---*/

};