diff options
-rw-r--r-- | include/net/ieee80211.h | 3 | ||||
-rw-r--r-- | net/ieee80211/ieee80211_tx.c | 25 | ||||
-rw-r--r-- | net/ieee80211/softmac/Kconfig | 1 | ||||
-rw-r--r-- | net/ieee80211/softmac/ieee80211softmac_auth.c | 12 | ||||
-rw-r--r-- | net/ieee80211/softmac/ieee80211softmac_io.c | 39 |
5 files changed, 51 insertions, 29 deletions
diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h index 293e920ca59d..d5147770ad47 100644 --- a/include/net/ieee80211.h +++ b/include/net/ieee80211.h | |||
@@ -1247,7 +1247,8 @@ extern int ieee80211_set_encryption(struct ieee80211_device *ieee); | |||
1247 | extern int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev); | 1247 | extern int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev); |
1248 | extern void ieee80211_txb_free(struct ieee80211_txb *); | 1248 | extern void ieee80211_txb_free(struct ieee80211_txb *); |
1249 | extern int ieee80211_tx_frame(struct ieee80211_device *ieee, | 1249 | extern int ieee80211_tx_frame(struct ieee80211_device *ieee, |
1250 | struct ieee80211_hdr *frame, int len); | 1250 | struct ieee80211_hdr *frame, int hdr_len, |
1251 | int total_len, int encrypt_mpdu); | ||
1251 | 1252 | ||
1252 | /* ieee80211_rx.c */ | 1253 | /* ieee80211_rx.c */ |
1253 | extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, | 1254 | extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, |
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) */ |
557 | int ieee80211_tx_frame(struct ieee80211_device *ieee, | 557 | int 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, | |||
268 | static u32 | 268 | static u32 |
269 | ieee80211softmac_auth(struct ieee80211_auth **pkt, | 269 | ieee80211softmac_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; |