aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r--net/mac80211/mlme.c52
1 files changed, 46 insertions, 6 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index f0d4249..43da622 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -131,6 +131,12 @@ u64 ieee80211_sta_get_rates(struct ieee80211_local *local,
/* frame sending functions */
+static void add_extra_ies(struct sk_buff *skb, u8 *ies, size_t ies_len)
+{
+ if (ies)
+ memcpy(skb_put(skb, ies_len), ies, ies_len);
+}
+
/* also used by scanning code */
void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
u8 *ssid, size_t ssid_len)
@@ -142,7 +148,8 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
u8 *pos, *supp_rates, *esupp_rates = NULL;
int i;
- skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt) + 200);
+ skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt) + 200 +
+ sdata->u.sta.ie_probereq_len);
if (!skb) {
printk(KERN_DEBUG "%s: failed to allocate buffer for probe "
"request\n", sdata->dev->name);
@@ -189,6 +196,9 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
*pos = rate->bitrate / 5;
}
+ add_extra_ies(skb, sdata->u.sta.ie_probereq,
+ sdata->u.sta.ie_probereq_len);
+
ieee80211_tx_skb(sdata, skb, 0);
}
@@ -202,7 +212,8 @@ static void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
struct ieee80211_mgmt *mgmt;
skb = dev_alloc_skb(local->hw.extra_tx_headroom +
- sizeof(*mgmt) + 6 + extra_len);
+ sizeof(*mgmt) + 6 + extra_len +
+ sdata->u.sta.ie_auth_len);
if (!skb) {
printk(KERN_DEBUG "%s: failed to allocate buffer for auth "
"frame\n", sdata->dev->name);
@@ -225,6 +236,7 @@ static void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
mgmt->u.auth.status_code = cpu_to_le16(0);
if (extra)
memcpy(skb_put(skb, extra_len), extra, extra_len);
+ add_extra_ies(skb, sdata->u.sta.ie_auth, sdata->u.sta.ie_auth_len);
ieee80211_tx_skb(sdata, skb, encrypt);
}
@@ -235,17 +247,26 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
struct ieee80211_local *local = sdata->local;
struct sk_buff *skb;
struct ieee80211_mgmt *mgmt;
- u8 *pos, *ies, *ht_ie;
+ u8 *pos, *ies, *ht_ie, *e_ies;
int i, len, count, rates_len, supp_rates_len;
u16 capab;
struct ieee80211_bss *bss;
int wmm = 0;
struct ieee80211_supported_band *sband;
u64 rates = 0;
+ size_t e_ies_len;
+
+ if (ifsta->flags & IEEE80211_STA_PREV_BSSID_SET) {
+ e_ies = sdata->u.sta.ie_reassocreq;
+ e_ies_len = sdata->u.sta.ie_reassocreq_len;
+ } else {
+ e_ies = sdata->u.sta.ie_assocreq;
+ e_ies_len = sdata->u.sta.ie_assocreq_len;
+ }
skb = dev_alloc_skb(local->hw.extra_tx_headroom +
sizeof(*mgmt) + 200 + ifsta->extra_ie_len +
- ifsta->ssid_len);
+ ifsta->ssid_len + e_ies_len);
if (!skb) {
printk(KERN_DEBUG "%s: failed to allocate buffer for assoc "
"frame\n", sdata->dev->name);
@@ -436,6 +457,8 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs));
}
+ add_extra_ies(skb, e_ies, e_ies_len);
+
kfree(ifsta->assocreq_ies);
ifsta->assocreq_ies_len = (skb->data + skb->len) - ies;
ifsta->assocreq_ies = kmalloc(ifsta->assocreq_ies_len, GFP_KERNEL);
@@ -453,8 +476,19 @@ static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
struct ieee80211_if_sta *ifsta = &sdata->u.sta;
struct sk_buff *skb;
struct ieee80211_mgmt *mgmt;
+ u8 *ies;
+ size_t ies_len;
- skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt));
+ if (stype == IEEE80211_STYPE_DEAUTH) {
+ ies = sdata->u.sta.ie_deauth;
+ ies_len = sdata->u.sta.ie_deauth_len;
+ } else {
+ ies = sdata->u.sta.ie_disassoc;
+ ies_len = sdata->u.sta.ie_disassoc_len;
+ }
+
+ skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt) +
+ ies_len);
if (!skb) {
printk(KERN_DEBUG "%s: failed to allocate buffer for "
"deauth/disassoc frame\n", sdata->dev->name);
@@ -472,6 +506,8 @@ static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
/* u.deauth.reason_code == u.disassoc.reason_code */
mgmt->u.deauth.reason_code = cpu_to_le16(reason);
+ add_extra_ies(skb, ies, ies_len);
+
ieee80211_tx_skb(sdata, skb, ifsta->flags & IEEE80211_STA_MFP_ENABLED);
}
@@ -1473,7 +1509,8 @@ static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
struct ieee80211_supported_band *sband;
union iwreq_data wrqu;
- skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400);
+ skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400 +
+ sdata->u.sta.ie_proberesp_len);
if (!skb) {
printk(KERN_DEBUG "%s: failed to allocate buffer for probe "
"response\n", sdata->dev->name);
@@ -1556,6 +1593,9 @@ static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
memcpy(pos, &bss->supp_rates[8], rates);
}
+ add_extra_ies(skb, sdata->u.sta.ie_proberesp,
+ sdata->u.sta.ie_proberesp_len);
+
ifsta->probe_resp = skb;
ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON);