aboutsummaryrefslogtreecommitdiffstats
path: root/net/ieee80211
diff options
context:
space:
mode:
Diffstat (limited to 'net/ieee80211')
-rw-r--r--net/ieee80211/ieee80211_tx.c25
-rw-r--r--net/ieee80211/softmac/Kconfig1
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_auth.c12
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_io.c39
4 files changed, 49 insertions, 28 deletions
diff --git a/net/ieee80211/ieee80211_tx.c b/net/ieee80211/ieee80211_tx.c
index 233d527c6953..6a5de1b84459 100644
--- a/net/ieee80211/ieee80211_tx.c
+++ b/net/ieee80211/ieee80211_tx.c
@@ -555,7 +555,8 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
555/* Incoming 802.11 strucure is converted to a TXB 555/* Incoming 802.11 strucure is converted to a TXB
556 * a block of 802.11 fragment packets (stored as skbs) */ 556 * a block of 802.11 fragment packets (stored as skbs) */
557int ieee80211_tx_frame(struct ieee80211_device *ieee, 557int ieee80211_tx_frame(struct ieee80211_device *ieee,
558 struct ieee80211_hdr *frame, int len) 558 struct ieee80211_hdr *frame, int hdr_len, int total_len,
559 int encrypt_mpdu)
559{ 560{
560 struct ieee80211_txb *txb = NULL; 561 struct ieee80211_txb *txb = NULL;
561 unsigned long flags; 562 unsigned long flags;
@@ -565,6 +566,9 @@ int ieee80211_tx_frame(struct ieee80211_device *ieee,
565 566
566 spin_lock_irqsave(&ieee->lock, flags); 567 spin_lock_irqsave(&ieee->lock, flags);
567 568
569 if (encrypt_mpdu && !ieee->sec.encrypt)
570 encrypt_mpdu = 0;
571
568 /* If there is no driver handler to take the TXB, dont' bother 572 /* If there is no driver handler to take the TXB, dont' bother
569 * creating it... */ 573 * creating it... */
570 if (!ieee->hard_start_xmit) { 574 if (!ieee->hard_start_xmit) {
@@ -572,32 +576,41 @@ int ieee80211_tx_frame(struct ieee80211_device *ieee,
572 goto success; 576 goto success;
573 } 577 }
574 578
575 if (unlikely(len < 24)) { 579 if (unlikely(total_len < 24)) {
576 printk(KERN_WARNING "%s: skb too small (%d).\n", 580 printk(KERN_WARNING "%s: skb too small (%d).\n",
577 ieee->dev->name, len); 581 ieee->dev->name, total_len);
578 goto success; 582 goto success;
579 } 583 }
580 584
585 if (encrypt_mpdu)
586 frame->frame_ctl |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
587
581 /* When we allocate the TXB we allocate enough space for the reserve 588 /* When we allocate the TXB we allocate enough space for the reserve
582 * and full fragment bytes (bytes_per_frag doesn't include prefix, 589 * and full fragment bytes (bytes_per_frag doesn't include prefix,
583 * postfix, header, FCS, etc.) */ 590 * postfix, header, FCS, etc.) */
584 txb = ieee80211_alloc_txb(1, len, ieee->tx_headroom, GFP_ATOMIC); 591 txb = ieee80211_alloc_txb(1, total_len, ieee->tx_headroom, GFP_ATOMIC);
585 if (unlikely(!txb)) { 592 if (unlikely(!txb)) {
586 printk(KERN_WARNING "%s: Could not allocate TXB\n", 593 printk(KERN_WARNING "%s: Could not allocate TXB\n",
587 ieee->dev->name); 594 ieee->dev->name);
588 goto failed; 595 goto failed;
589 } 596 }
590 txb->encrypted = 0; 597 txb->encrypted = 0;
591 txb->payload_size = len; 598 txb->payload_size = total_len;
592 599
593 skb_frag = txb->fragments[0]; 600 skb_frag = txb->fragments[0];
594 601
595 memcpy(skb_put(skb_frag, len), frame, len); 602 memcpy(skb_put(skb_frag, total_len), frame, total_len);
596 603
597 if (ieee->config & 604 if (ieee->config &
598 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS)) 605 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
599 skb_put(skb_frag, 4); 606 skb_put(skb_frag, 4);
600 607
608 /* To avoid overcomplicating things, we do the corner-case frame
609 * encryption in software. The only real situation where encryption is
610 * needed here is during software-based shared key authentication. */
611 if (encrypt_mpdu)
612 ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
613
601 success: 614 success:
602 spin_unlock_irqrestore(&ieee->lock, flags); 615 spin_unlock_irqrestore(&ieee->lock, flags);
603 616
diff --git a/net/ieee80211/softmac/Kconfig b/net/ieee80211/softmac/Kconfig
index f2a27cc6ecb1..2811651cb134 100644
--- a/net/ieee80211/softmac/Kconfig
+++ b/net/ieee80211/softmac/Kconfig
@@ -2,6 +2,7 @@ config IEEE80211_SOFTMAC
2 tristate "Software MAC add-on to the IEEE 802.11 networking stack" 2 tristate "Software MAC add-on to the IEEE 802.11 networking stack"
3 depends on IEEE80211 && EXPERIMENTAL 3 depends on IEEE80211 && EXPERIMENTAL
4 select WIRELESS_EXT 4 select WIRELESS_EXT
5 select IEEE80211_CRYPT_WEP
5 ---help--- 6 ---help---
6 This option enables the hardware independent software MAC addon 7 This option enables the hardware independent software MAC addon
7 for the IEEE 802.11 networking stack. 8 for the IEEE 802.11 networking stack.
diff --git a/net/ieee80211/softmac/ieee80211softmac_auth.c b/net/ieee80211/softmac/ieee80211softmac_auth.c
index 084b6211f293..90b8484e509b 100644
--- a/net/ieee80211/softmac/ieee80211softmac_auth.c
+++ b/net/ieee80211/softmac/ieee80211softmac_auth.c
@@ -107,6 +107,7 @@ ieee80211softmac_auth_queue(void *data)
107 printkl(KERN_WARNING PFX "Authentication timed out with "MAC_FMT"\n", MAC_ARG(net->bssid)); 107 printkl(KERN_WARNING PFX "Authentication timed out with "MAC_FMT"\n", MAC_ARG(net->bssid));
108 /* Remove this item from the queue */ 108 /* Remove this item from the queue */
109 spin_lock_irqsave(&mac->lock, flags); 109 spin_lock_irqsave(&mac->lock, flags);
110 net->authenticating = 0;
110 ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_AUTH_TIMEOUT, net); 111 ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_AUTH_TIMEOUT, net);
111 cancel_delayed_work(&auth->work); /* just to make sure... */ 112 cancel_delayed_work(&auth->work); /* just to make sure... */
112 list_del(&auth->list); 113 list_del(&auth->list);
@@ -212,13 +213,13 @@ ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth)
212 aq->state = IEEE80211SOFTMAC_AUTH_SHARED_RESPONSE; 213 aq->state = IEEE80211SOFTMAC_AUTH_SHARED_RESPONSE;
213 spin_unlock_irqrestore(&mac->lock, flags); 214 spin_unlock_irqrestore(&mac->lock, flags);
214 215
215 /* Switch to correct channel for this network */ 216 /* Send our response */
216 mac->set_channel(mac->dev, net->channel);
217
218 /* Send our response (How to encrypt?) */
219 ieee80211softmac_send_mgt_frame(mac, aq->net, IEEE80211_STYPE_AUTH, aq->state); 217 ieee80211softmac_send_mgt_frame(mac, aq->net, IEEE80211_STYPE_AUTH, aq->state);
220 break; 218 return 0;
221 case IEEE80211SOFTMAC_AUTH_SHARED_PASS: 219 case IEEE80211SOFTMAC_AUTH_SHARED_PASS:
220 kfree(net->challenge);
221 net->challenge = NULL;
222 net->challenge_len = 0;
222 /* Check the status code of the response */ 223 /* Check the status code of the response */
223 switch(auth->status) { 224 switch(auth->status) {
224 case WLAN_STATUS_SUCCESS: 225 case WLAN_STATUS_SUCCESS:
@@ -229,6 +230,7 @@ ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth)
229 spin_unlock_irqrestore(&mac->lock, flags); 230 spin_unlock_irqrestore(&mac->lock, flags);
230 printkl(KERN_NOTICE PFX "Shared Key Authentication completed with "MAC_FMT"\n", 231 printkl(KERN_NOTICE PFX "Shared Key Authentication completed with "MAC_FMT"\n",
231 MAC_ARG(net->bssid)); 232 MAC_ARG(net->bssid));
233 ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_AUTHENTICATED, net);
232 break; 234 break;
233 default: 235 default:
234 printkl(KERN_NOTICE PFX "Shared Key Authentication with "MAC_FMT" failed, error code: %i\n", 236 printkl(KERN_NOTICE PFX "Shared Key Authentication with "MAC_FMT" failed, error code: %i\n",
diff --git a/net/ieee80211/softmac/ieee80211softmac_io.c b/net/ieee80211/softmac/ieee80211softmac_io.c
index 7b9e78d39598..44f51175a2fc 100644
--- a/net/ieee80211/softmac/ieee80211softmac_io.c
+++ b/net/ieee80211/softmac/ieee80211softmac_io.c
@@ -268,26 +268,27 @@ ieee80211softmac_reassoc_req(struct ieee80211_reassoc_request **pkt,
268static u32 268static u32
269ieee80211softmac_auth(struct ieee80211_auth **pkt, 269ieee80211softmac_auth(struct ieee80211_auth **pkt,
270 struct ieee80211softmac_device *mac, struct ieee80211softmac_network *net, 270 struct ieee80211softmac_device *mac, struct ieee80211softmac_network *net,
271 u16 transaction, u16 status) 271 u16 transaction, u16 status, int *encrypt_mpdu)
272{ 272{
273 u8 *data; 273 u8 *data;
274 int auth_mode = mac->ieee->sec.auth_mode;
275 int is_shared_response = (auth_mode == WLAN_AUTH_SHARED_KEY
276 && transaction == IEEE80211SOFTMAC_AUTH_SHARED_RESPONSE);
277
274 /* Allocate Packet */ 278 /* Allocate Packet */
275 (*pkt) = (struct ieee80211_auth *)ieee80211softmac_alloc_mgt( 279 (*pkt) = (struct ieee80211_auth *)ieee80211softmac_alloc_mgt(
276 2 + /* Auth Algorithm */ 280 2 + /* Auth Algorithm */
277 2 + /* Auth Transaction Seq */ 281 2 + /* Auth Transaction Seq */
278 2 + /* Status Code */ 282 2 + /* Status Code */
279 /* Challenge Text IE */ 283 /* Challenge Text IE */
280 mac->ieee->open_wep ? 0 : 284 is_shared_response ? 0 : 1 + 1 + net->challenge_len
281 1 + 1 + WLAN_AUTH_CHALLENGE_LEN 285 );
282 );
283 if (unlikely((*pkt) == NULL)) 286 if (unlikely((*pkt) == NULL))
284 return 0; 287 return 0;
285 ieee80211softmac_hdr_3addr(mac, &((*pkt)->header), IEEE80211_STYPE_AUTH, net->bssid, net->bssid); 288 ieee80211softmac_hdr_3addr(mac, &((*pkt)->header), IEEE80211_STYPE_AUTH, net->bssid, net->bssid);
286 289
287 /* Algorithm */ 290 /* Algorithm */
288 (*pkt)->algorithm = mac->ieee->open_wep ? 291 (*pkt)->algorithm = cpu_to_le16(auth_mode);
289 cpu_to_le16(WLAN_AUTH_OPEN) :
290 cpu_to_le16(WLAN_AUTH_SHARED_KEY);
291 /* Transaction */ 292 /* Transaction */
292 (*pkt)->transaction = cpu_to_le16(transaction); 293 (*pkt)->transaction = cpu_to_le16(transaction);
293 /* Status */ 294 /* Status */
@@ -295,18 +296,20 @@ ieee80211softmac_auth(struct ieee80211_auth **pkt,
295 296
296 data = (u8 *)(*pkt)->info_element; 297 data = (u8 *)(*pkt)->info_element;
297 /* Challenge Text */ 298 /* Challenge Text */
298 if(!mac->ieee->open_wep){ 299 if (is_shared_response) {
299 *data = MFIE_TYPE_CHALLENGE; 300 *data = MFIE_TYPE_CHALLENGE;
300 data++; 301 data++;
301 302
302 /* Copy the challenge in */ 303 /* Copy the challenge in */
303 // *data = challenge length 304 *data = net->challenge_len;
304 // data += sizeof(u16); 305 data++;
305 // memcpy(data, challenge, challenge length); 306 memcpy(data, net->challenge, net->challenge_len);
306 // data += challenge length; 307 data += net->challenge_len;
307 308
308 /* Add the full size to the packet length */ 309 /* Make sure this frame gets encrypted with the shared key */
309 } 310 *encrypt_mpdu = 1;
311 } else
312 *encrypt_mpdu = 0;
310 313
311 /* Return the packet size */ 314 /* Return the packet size */
312 return (data - (u8 *)(*pkt)); 315 return (data - (u8 *)(*pkt));
@@ -396,6 +399,7 @@ ieee80211softmac_send_mgt_frame(struct ieee80211softmac_device *mac,
396{ 399{
397 void *pkt = NULL; 400 void *pkt = NULL;
398 u32 pkt_size = 0; 401 u32 pkt_size = 0;
402 int encrypt_mpdu = 0;
399 403
400 switch(type) { 404 switch(type) {
401 case IEEE80211_STYPE_ASSOC_REQ: 405 case IEEE80211_STYPE_ASSOC_REQ:
@@ -405,7 +409,7 @@ ieee80211softmac_send_mgt_frame(struct ieee80211softmac_device *mac,
405 pkt_size = ieee80211softmac_reassoc_req((struct ieee80211_reassoc_request **)(&pkt), mac, (struct ieee80211softmac_network *)ptrarg); 409 pkt_size = ieee80211softmac_reassoc_req((struct ieee80211_reassoc_request **)(&pkt), mac, (struct ieee80211softmac_network *)ptrarg);
406 break; 410 break;
407 case IEEE80211_STYPE_AUTH: 411 case IEEE80211_STYPE_AUTH:
408 pkt_size = ieee80211softmac_auth((struct ieee80211_auth **)(&pkt), mac, (struct ieee80211softmac_network *)ptrarg, (u16)(arg & 0xFFFF), (u16) (arg >> 16)); 412 pkt_size = ieee80211softmac_auth((struct ieee80211_auth **)(&pkt), mac, (struct ieee80211softmac_network *)ptrarg, (u16)(arg & 0xFFFF), (u16) (arg >> 16), &encrypt_mpdu);
409 break; 413 break;
410 case IEEE80211_STYPE_DISASSOC: 414 case IEEE80211_STYPE_DISASSOC:
411 case IEEE80211_STYPE_DEAUTH: 415 case IEEE80211_STYPE_DEAUTH:
@@ -434,7 +438,8 @@ ieee80211softmac_send_mgt_frame(struct ieee80211softmac_device *mac,
434 * or get rid of it alltogether? 438 * or get rid of it alltogether?
435 * Does this work for you now? 439 * Does this work for you now?
436 */ 440 */
437 ieee80211_tx_frame(mac->ieee, (struct ieee80211_hdr *)pkt, pkt_size); 441 ieee80211_tx_frame(mac->ieee, (struct ieee80211_hdr *)pkt,
442 IEEE80211_3ADDR_LEN, pkt_size, encrypt_mpdu);
438 443
439 kfree(pkt); 444 kfree(pkt);
440 return 0; 445 return 0;