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 f0d42498c257..43da6227b37c 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -131,6 +131,12 @@ u64 ieee80211_sta_get_rates(struct ieee80211_local *local,
131 131
132/* frame sending functions */ 132/* frame sending functions */
133 133
134static void add_extra_ies(struct sk_buff *skb, u8 *ies, size_t ies_len)
135{
136 if (ies)
137 memcpy(skb_put(skb, ies_len), ies, ies_len);
138}
139
134/* also used by scanning code */ 140/* also used by scanning code */
135void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, 141void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
136 u8 *ssid, size_t ssid_len) 142 u8 *ssid, size_t ssid_len)
@@ -142,7 +148,8 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
142 u8 *pos, *supp_rates, *esupp_rates = NULL; 148 u8 *pos, *supp_rates, *esupp_rates = NULL;
143 int i; 149 int i;
144 150
145 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt) + 200); 151 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt) + 200 +
152 sdata->u.sta.ie_probereq_len);
146 if (!skb) { 153 if (!skb) {
147 printk(KERN_DEBUG "%s: failed to allocate buffer for probe " 154 printk(KERN_DEBUG "%s: failed to allocate buffer for probe "
148 "request\n", sdata->dev->name); 155 "request\n", sdata->dev->name);
@@ -189,6 +196,9 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
189 *pos = rate->bitrate / 5; 196 *pos = rate->bitrate / 5;
190 } 197 }
191 198
199 add_extra_ies(skb, sdata->u.sta.ie_probereq,
200 sdata->u.sta.ie_probereq_len);
201
192 ieee80211_tx_skb(sdata, skb, 0); 202 ieee80211_tx_skb(sdata, skb, 0);
193} 203}
194 204
@@ -202,7 +212,8 @@ static void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
202 struct ieee80211_mgmt *mgmt; 212 struct ieee80211_mgmt *mgmt;
203 213
204 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 214 skb = dev_alloc_skb(local->hw.extra_tx_headroom +
205 sizeof(*mgmt) + 6 + extra_len); 215 sizeof(*mgmt) + 6 + extra_len +
216 sdata->u.sta.ie_auth_len);
206 if (!skb) { 217 if (!skb) {
207 printk(KERN_DEBUG "%s: failed to allocate buffer for auth " 218 printk(KERN_DEBUG "%s: failed to allocate buffer for auth "
208 "frame\n", sdata->dev->name); 219 "frame\n", sdata->dev->name);
@@ -225,6 +236,7 @@ static void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
225 mgmt->u.auth.status_code = cpu_to_le16(0); 236 mgmt->u.auth.status_code = cpu_to_le16(0);
226 if (extra) 237 if (extra)
227 memcpy(skb_put(skb, extra_len), extra, extra_len); 238 memcpy(skb_put(skb, extra_len), extra, extra_len);
239 add_extra_ies(skb, sdata->u.sta.ie_auth, sdata->u.sta.ie_auth_len);
228 240
229 ieee80211_tx_skb(sdata, skb, encrypt); 241 ieee80211_tx_skb(sdata, skb, encrypt);
230} 242}
@@ -235,17 +247,26 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
235 struct ieee80211_local *local = sdata->local; 247 struct ieee80211_local *local = sdata->local;
236 struct sk_buff *skb; 248 struct sk_buff *skb;
237 struct ieee80211_mgmt *mgmt; 249 struct ieee80211_mgmt *mgmt;
238 u8 *pos, *ies, *ht_ie; 250 u8 *pos, *ies, *ht_ie, *e_ies;
239 int i, len, count, rates_len, supp_rates_len; 251 int i, len, count, rates_len, supp_rates_len;
240 u16 capab; 252 u16 capab;
241 struct ieee80211_bss *bss; 253 struct ieee80211_bss *bss;
242 int wmm = 0; 254 int wmm = 0;
243 struct ieee80211_supported_band *sband; 255 struct ieee80211_supported_band *sband;
244 u64 rates = 0; 256 u64 rates = 0;
257 size_t e_ies_len;
258
259 if (ifsta->flags & IEEE80211_STA_PREV_BSSID_SET) {
260 e_ies = sdata->u.sta.ie_reassocreq;
261 e_ies_len = sdata->u.sta.ie_reassocreq_len;
262 } else {
263 e_ies = sdata->u.sta.ie_assocreq;
264 e_ies_len = sdata->u.sta.ie_assocreq_len;
265 }
245 266
246 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 267 skb = dev_alloc_skb(local->hw.extra_tx_headroom +
247 sizeof(*mgmt) + 200 + ifsta->extra_ie_len + 268 sizeof(*mgmt) + 200 + ifsta->extra_ie_len +
248 ifsta->ssid_len); 269 ifsta->ssid_len + e_ies_len);
249 if (!skb) { 270 if (!skb) {
250 printk(KERN_DEBUG "%s: failed to allocate buffer for assoc " 271 printk(KERN_DEBUG "%s: failed to allocate buffer for assoc "
251 "frame\n", sdata->dev->name); 272 "frame\n", sdata->dev->name);
@@ -436,6 +457,8 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
436 memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs)); 457 memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs));
437 } 458 }
438 459
460 add_extra_ies(skb, e_ies, e_ies_len);
461
439 kfree(ifsta->assocreq_ies); 462 kfree(ifsta->assocreq_ies);
440 ifsta->assocreq_ies_len = (skb->data + skb->len) - ies; 463 ifsta->assocreq_ies_len = (skb->data + skb->len) - ies;
441 ifsta->assocreq_ies = kmalloc(ifsta->assocreq_ies_len, GFP_KERNEL); 464 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,
453 struct ieee80211_if_sta *ifsta = &sdata->u.sta; 476 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
454 struct sk_buff *skb; 477 struct sk_buff *skb;
455 struct ieee80211_mgmt *mgmt; 478 struct ieee80211_mgmt *mgmt;
479 u8 *ies;
480 size_t ies_len;
456 481
457 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt)); 482 if (stype == IEEE80211_STYPE_DEAUTH) {
483 ies = sdata->u.sta.ie_deauth;
484 ies_len = sdata->u.sta.ie_deauth_len;
485 } else {
486 ies = sdata->u.sta.ie_disassoc;
487 ies_len = sdata->u.sta.ie_disassoc_len;
488 }
489
490 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt) +
491 ies_len);
458 if (!skb) { 492 if (!skb) {
459 printk(KERN_DEBUG "%s: failed to allocate buffer for " 493 printk(KERN_DEBUG "%s: failed to allocate buffer for "
460 "deauth/disassoc frame\n", sdata->dev->name); 494 "deauth/disassoc frame\n", sdata->dev->name);
@@ -472,6 +506,8 @@ static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
472 /* u.deauth.reason_code == u.disassoc.reason_code */ 506 /* u.deauth.reason_code == u.disassoc.reason_code */
473 mgmt->u.deauth.reason_code = cpu_to_le16(reason); 507 mgmt->u.deauth.reason_code = cpu_to_le16(reason);
474 508
509 add_extra_ies(skb, ies, ies_len);
510
475 ieee80211_tx_skb(sdata, skb, ifsta->flags & IEEE80211_STA_MFP_ENABLED); 511 ieee80211_tx_skb(sdata, skb, ifsta->flags & IEEE80211_STA_MFP_ENABLED);
476} 512}
477 513
@@ -1473,7 +1509,8 @@ static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
1473 struct ieee80211_supported_band *sband; 1509 struct ieee80211_supported_band *sband;
1474 union iwreq_data wrqu; 1510 union iwreq_data wrqu;
1475 1511
1476 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); 1512 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400 +
1513 sdata->u.sta.ie_proberesp_len);
1477 if (!skb) { 1514 if (!skb) {
1478 printk(KERN_DEBUG "%s: failed to allocate buffer for probe " 1515 printk(KERN_DEBUG "%s: failed to allocate buffer for probe "
1479 "response\n", sdata->dev->name); 1516 "response\n", sdata->dev->name);
@@ -1556,6 +1593,9 @@ static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
1556 memcpy(pos, &bss->supp_rates[8], rates); 1593 memcpy(pos, &bss->supp_rates[8], rates);
1557 } 1594 }
1558 1595
1596 add_extra_ies(skb, sdata->u.sta.ie_proberesp,
1597 sdata->u.sta.ie_proberesp_len);
1598
1559 ifsta->probe_resp = skb; 1599 ifsta->probe_resp = skb;
1560 1600
1561 ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON); 1601 ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON);