aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Garzik <jgarzik@pobox.com>2005-05-12 22:48:20 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-05-12 22:48:20 -0400
commitb453872c35cfcbdbf5a794737817f7d4e7b1b579 (patch)
tree6639da0b12e3f071b57f388c97d28e451f8f3cd3
parentfff9cfd99c0f88645c3f50d7476d6c8cef99f140 (diff)
[NET] ieee80211 subsystem
Contributors: Host AP contributors James Ketrenos <jketreno@linux.intel.com> Francois Romieu <romieu@fr.zoreil.com> Adrian Bunk <bunk@stusta.de> Matthew Galgoci <mgalgoci@parcelfarce.linux.th eplanet.co.uk>
-rw-r--r--drivers/net/wireless/atmel.c62
-rw-r--r--drivers/net/wireless/ieee802_11.h78
-rw-r--r--drivers/net/wireless/orinoco.c11
-rw-r--r--drivers/net/wireless/wl3501.h4
-rw-r--r--include/net/ieee80211.h887
-rw-r--r--include/net/ieee80211_crypt.h86
-rw-r--r--net/Kconfig2
-rw-r--r--net/Makefile1
-rw-r--r--net/ieee80211/Kconfig67
-rw-r--r--net/ieee80211/Makefile11
-rw-r--r--net/ieee80211/ieee80211_crypt.c259
-rw-r--r--net/ieee80211/ieee80211_crypt_ccmp.c470
-rw-r--r--net/ieee80211/ieee80211_crypt_tkip.c708
-rw-r--r--net/ieee80211/ieee80211_crypt_wep.c272
-rw-r--r--net/ieee80211/ieee80211_module.c268
-rw-r--r--net/ieee80211/ieee80211_rx.c1206
-rw-r--r--net/ieee80211/ieee80211_tx.c448
-rw-r--r--net/ieee80211/ieee80211_wx.c471
18 files changed, 5195 insertions, 116 deletions
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index 18a7d38d2a13..bed160a25cab 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -68,7 +68,7 @@
68#include <linux/device.h> 68#include <linux/device.h>
69#include <linux/moduleparam.h> 69#include <linux/moduleparam.h>
70#include <linux/firmware.h> 70#include <linux/firmware.h>
71#include "ieee802_11.h" 71#include <net/ieee80211.h>
72#include "atmel.h" 72#include "atmel.h"
73 73
74#define DRIVER_MAJOR 0 74#define DRIVER_MAJOR 0
@@ -618,12 +618,12 @@ static int atmel_lock_mac(struct atmel_private *priv);
618static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data); 618static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data);
619static void atmel_command_irq(struct atmel_private *priv); 619static void atmel_command_irq(struct atmel_private *priv);
620static int atmel_validate_channel(struct atmel_private *priv, int channel); 620static int atmel_validate_channel(struct atmel_private *priv, int channel);
621static void atmel_management_frame(struct atmel_private *priv, struct ieee802_11_hdr *header, 621static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_hdr *header,
622 u16 frame_len, u8 rssi); 622 u16 frame_len, u8 rssi);
623static void atmel_management_timer(u_long a); 623static void atmel_management_timer(u_long a);
624static void atmel_send_command(struct atmel_private *priv, int command, void *cmd, int cmd_size); 624static void atmel_send_command(struct atmel_private *priv, int command, void *cmd, int cmd_size);
625static int atmel_send_command_wait(struct atmel_private *priv, int command, void *cmd, int cmd_size); 625static int atmel_send_command_wait(struct atmel_private *priv, int command, void *cmd, int cmd_size);
626static void atmel_transmit_management_frame(struct atmel_private *priv, struct ieee802_11_hdr *header, 626static void atmel_transmit_management_frame(struct atmel_private *priv, struct ieee80211_hdr *header,
627 u8 *body, int body_len); 627 u8 *body, int body_len);
628 628
629static u8 atmel_get_mib8(struct atmel_private *priv, u8 type, u8 index); 629static u8 atmel_get_mib8(struct atmel_private *priv, u8 type, u8 index);
@@ -827,7 +827,7 @@ static void tx_update_descriptor(struct atmel_private *priv, int is_bcast, u16 l
827static int start_tx (struct sk_buff *skb, struct net_device *dev) 827static int start_tx (struct sk_buff *skb, struct net_device *dev)
828{ 828{
829 struct atmel_private *priv = netdev_priv(dev); 829 struct atmel_private *priv = netdev_priv(dev);
830 struct ieee802_11_hdr header; 830 struct ieee80211_hdr header;
831 unsigned long flags; 831 unsigned long flags;
832 u16 buff, frame_ctl, len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN; 832 u16 buff, frame_ctl, len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;
833 u8 SNAP_RFC1024[6] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00}; 833 u8 SNAP_RFC1024[6] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
@@ -863,17 +863,17 @@ static int start_tx (struct sk_buff *skb, struct net_device *dev)
863 return 1; 863 return 1;
864 } 864 }
865 865
866 frame_ctl = IEEE802_11_FTYPE_DATA; 866 frame_ctl = IEEE80211_FTYPE_DATA;
867 header.duration_id = 0; 867 header.duration_id = 0;
868 header.seq_ctl = 0; 868 header.seq_ctl = 0;
869 if (priv->wep_is_on) 869 if (priv->wep_is_on)
870 frame_ctl |= IEEE802_11_FCTL_WEP; 870 frame_ctl |= IEEE80211_FCTL_WEP;
871 if (priv->operating_mode == IW_MODE_ADHOC) { 871 if (priv->operating_mode == IW_MODE_ADHOC) {
872 memcpy(&header.addr1, skb->data, 6); 872 memcpy(&header.addr1, skb->data, 6);
873 memcpy(&header.addr2, dev->dev_addr, 6); 873 memcpy(&header.addr2, dev->dev_addr, 6);
874 memcpy(&header.addr3, priv->BSSID, 6); 874 memcpy(&header.addr3, priv->BSSID, 6);
875 } else { 875 } else {
876 frame_ctl |= IEEE802_11_FCTL_TODS; 876 frame_ctl |= IEEE80211_FCTL_TODS;
877 memcpy(&header.addr1, priv->CurrentBSSID, 6); 877 memcpy(&header.addr1, priv->CurrentBSSID, 6);
878 memcpy(&header.addr2, dev->dev_addr, 6); 878 memcpy(&header.addr2, dev->dev_addr, 6);
879 memcpy(&header.addr3, skb->data, 6); 879 memcpy(&header.addr3, skb->data, 6);
@@ -902,7 +902,7 @@ static int start_tx (struct sk_buff *skb, struct net_device *dev)
902} 902}
903 903
904static void atmel_transmit_management_frame(struct atmel_private *priv, 904static void atmel_transmit_management_frame(struct atmel_private *priv,
905 struct ieee802_11_hdr *header, 905 struct ieee80211_hdr *header,
906 u8 *body, int body_len) 906 u8 *body, int body_len)
907{ 907{
908 u16 buff; 908 u16 buff;
@@ -917,7 +917,7 @@ static void atmel_transmit_management_frame(struct atmel_private *priv,
917 tx_update_descriptor(priv, header->addr1[0] & 0x01, len, buff, TX_PACKET_TYPE_MGMT); 917 tx_update_descriptor(priv, header->addr1[0] & 0x01, len, buff, TX_PACKET_TYPE_MGMT);
918} 918}
919 919
920static void fast_rx_path(struct atmel_private *priv, struct ieee802_11_hdr *header, 920static void fast_rx_path(struct atmel_private *priv, struct ieee80211_hdr *header,
921 u16 msdu_size, u16 rx_packet_loc, u32 crc) 921 u16 msdu_size, u16 rx_packet_loc, u32 crc)
922{ 922{
923 /* fast path: unfragmented packet copy directly into skbuf */ 923 /* fast path: unfragmented packet copy directly into skbuf */
@@ -955,7 +955,7 @@ static void fast_rx_path(struct atmel_private *priv, struct ieee802_11_hdr *head
955 } 955 }
956 956
957 memcpy(skbp, header->addr1, 6); /* destination address */ 957 memcpy(skbp, header->addr1, 6); /* destination address */
958 if (le16_to_cpu(header->frame_ctl) & IEEE802_11_FCTL_FROMDS) 958 if (le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_FROMDS)
959 memcpy(&skbp[6], header->addr3, 6); 959 memcpy(&skbp[6], header->addr3, 6);
960 else 960 else
961 memcpy(&skbp[6], header->addr2, 6); /* source address */ 961 memcpy(&skbp[6], header->addr2, 6); /* source address */
@@ -990,14 +990,14 @@ static int probe_crc(struct atmel_private *priv, u16 packet_loc, u16 msdu_size)
990 return (crc ^ 0xffffffff) == netcrc; 990 return (crc ^ 0xffffffff) == netcrc;
991} 991}
992 992
993static void frag_rx_path(struct atmel_private *priv, struct ieee802_11_hdr *header, 993static void frag_rx_path(struct atmel_private *priv, struct ieee80211_hdr *header,
994 u16 msdu_size, u16 rx_packet_loc, u32 crc, u16 seq_no, u8 frag_no, int more_frags) 994 u16 msdu_size, u16 rx_packet_loc, u32 crc, u16 seq_no, u8 frag_no, int more_frags)
995{ 995{
996 u8 mac4[6]; 996 u8 mac4[6];
997 u8 source[6]; 997 u8 source[6];
998 struct sk_buff *skb; 998 struct sk_buff *skb;
999 999
1000 if (le16_to_cpu(header->frame_ctl) & IEEE802_11_FCTL_FROMDS) 1000 if (le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_FROMDS)
1001 memcpy(source, header->addr3, 6); 1001 memcpy(source, header->addr3, 6);
1002 else 1002 else
1003 memcpy(source, header->addr2, 6); 1003 memcpy(source, header->addr2, 6);
@@ -1082,7 +1082,7 @@ static void frag_rx_path(struct atmel_private *priv, struct ieee802_11_hdr *head
1082static void rx_done_irq(struct atmel_private *priv) 1082static void rx_done_irq(struct atmel_private *priv)
1083{ 1083{
1084 int i; 1084 int i;
1085 struct ieee802_11_hdr header; 1085 struct ieee80211_hdr header;
1086 1086
1087 for (i = 0; 1087 for (i = 0;
1088 atmel_rmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head)) == RX_DESC_FLAG_VALID && 1088 atmel_rmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head)) == RX_DESC_FLAG_VALID &&
@@ -1117,7 +1117,7 @@ static void rx_done_irq(struct atmel_private *priv)
1117 /* probe for CRC use here if needed once five packets have arrived with 1117 /* probe for CRC use here if needed once five packets have arrived with
1118 the same crc status, we assume we know what's happening and stop probing */ 1118 the same crc status, we assume we know what's happening and stop probing */
1119 if (priv->probe_crc) { 1119 if (priv->probe_crc) {
1120 if (!priv->wep_is_on || !(frame_ctl & IEEE802_11_FCTL_WEP)) { 1120 if (!priv->wep_is_on || !(frame_ctl & IEEE80211_FCTL_WEP)) {
1121 priv->do_rx_crc = probe_crc(priv, rx_packet_loc, msdu_size); 1121 priv->do_rx_crc = probe_crc(priv, rx_packet_loc, msdu_size);
1122 } else { 1122 } else {
1123 priv->do_rx_crc = probe_crc(priv, rx_packet_loc + 24, msdu_size - 24); 1123 priv->do_rx_crc = probe_crc(priv, rx_packet_loc + 24, msdu_size - 24);
@@ -1132,16 +1132,16 @@ static void rx_done_irq(struct atmel_private *priv)
1132 } 1132 }
1133 1133
1134 /* don't CRC header when WEP in use */ 1134 /* don't CRC header when WEP in use */
1135 if (priv->do_rx_crc && (!priv->wep_is_on || !(frame_ctl & IEEE802_11_FCTL_WEP))) { 1135 if (priv->do_rx_crc && (!priv->wep_is_on || !(frame_ctl & IEEE80211_FCTL_WEP))) {
1136 crc = crc32_le(0xffffffff, (unsigned char *)&header, 24); 1136 crc = crc32_le(0xffffffff, (unsigned char *)&header, 24);
1137 } 1137 }
1138 msdu_size -= 24; /* header */ 1138 msdu_size -= 24; /* header */
1139 1139
1140 if ((frame_ctl & IEEE802_11_FCTL_FTYPE) == IEEE802_11_FTYPE_DATA) { 1140 if ((frame_ctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) {
1141 1141
1142 int more_fragments = frame_ctl & IEEE802_11_FCTL_MOREFRAGS; 1142 int more_fragments = frame_ctl & IEEE80211_FCTL_MOREFRAGS;
1143 u8 packet_fragment_no = seq_control & IEEE802_11_SCTL_FRAG; 1143 u8 packet_fragment_no = seq_control & IEEE80211_SCTL_FRAG;
1144 u16 packet_sequence_no = (seq_control & IEEE802_11_SCTL_SEQ) >> 4; 1144 u16 packet_sequence_no = (seq_control & IEEE80211_SCTL_SEQ) >> 4;
1145 1145
1146 if (!more_fragments && packet_fragment_no == 0 ) { 1146 if (!more_fragments && packet_fragment_no == 0 ) {
1147 fast_rx_path(priv, &header, msdu_size, rx_packet_loc, crc); 1147 fast_rx_path(priv, &header, msdu_size, rx_packet_loc, crc);
@@ -1151,7 +1151,7 @@ static void rx_done_irq(struct atmel_private *priv)
1151 } 1151 }
1152 } 1152 }
1153 1153
1154 if ((frame_ctl & IEEE802_11_FCTL_FTYPE) == IEEE802_11_FTYPE_MGMT) { 1154 if ((frame_ctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) {
1155 /* copy rest of packet into buffer */ 1155 /* copy rest of packet into buffer */
1156 atmel_copy_to_host(priv->dev, (unsigned char *)&priv->rx_buf, rx_packet_loc + 24, msdu_size); 1156 atmel_copy_to_host(priv->dev, (unsigned char *)&priv->rx_buf, rx_packet_loc + 24, msdu_size);
1157 1157
@@ -2663,10 +2663,10 @@ static void handle_beacon_probe(struct atmel_private *priv, u16 capability, u8 c
2663 2663
2664static void send_authentication_request(struct atmel_private *priv, u8 *challenge, int challenge_len) 2664static void send_authentication_request(struct atmel_private *priv, u8 *challenge, int challenge_len)
2665{ 2665{
2666 struct ieee802_11_hdr header; 2666 struct ieee80211_hdr header;
2667 struct auth_body auth; 2667 struct auth_body auth;
2668 2668
2669 header.frame_ctl = cpu_to_le16(IEEE802_11_FTYPE_MGMT | IEEE802_11_STYPE_AUTH); 2669 header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH);
2670 header.duration_id = cpu_to_le16(0x8000); 2670 header.duration_id = cpu_to_le16(0x8000);
2671 header.seq_ctl = 0; 2671 header.seq_ctl = 0;
2672 memcpy(header.addr1, priv->CurrentBSSID, 6); 2672 memcpy(header.addr1, priv->CurrentBSSID, 6);
@@ -2677,7 +2677,7 @@ static void send_authentication_request(struct atmel_private *priv, u8 *challeng
2677 auth.alg = cpu_to_le16(C80211_MGMT_AAN_SHAREDKEY); 2677 auth.alg = cpu_to_le16(C80211_MGMT_AAN_SHAREDKEY);
2678 /* no WEP for authentication frames with TrSeqNo 1 */ 2678 /* no WEP for authentication frames with TrSeqNo 1 */
2679 if (priv->CurrentAuthentTransactionSeqNum != 1) 2679 if (priv->CurrentAuthentTransactionSeqNum != 1)
2680 header.frame_ctl |= cpu_to_le16(IEEE802_11_FCTL_WEP); 2680 header.frame_ctl |= cpu_to_le16(IEEE80211_FCTL_WEP);
2681 } else { 2681 } else {
2682 auth.alg = cpu_to_le16(C80211_MGMT_AAN_OPENSYSTEM); 2682 auth.alg = cpu_to_le16(C80211_MGMT_AAN_OPENSYSTEM);
2683 } 2683 }
@@ -2701,7 +2701,7 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc)
2701{ 2701{
2702 u8 *ssid_el_p; 2702 u8 *ssid_el_p;
2703 int bodysize; 2703 int bodysize;
2704 struct ieee802_11_hdr header; 2704 struct ieee80211_hdr header;
2705 struct ass_req_format { 2705 struct ass_req_format {
2706 u16 capability; 2706 u16 capability;
2707 u16 listen_interval; 2707 u16 listen_interval;
@@ -2714,8 +2714,8 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc)
2714 u8 rates[4]; 2714 u8 rates[4];
2715 } body; 2715 } body;
2716 2716
2717 header.frame_ctl = cpu_to_le16(IEEE802_11_FTYPE_MGMT | 2717 header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT |
2718 (is_reassoc ? IEEE802_11_STYPE_REASSOC_REQ : IEEE802_11_STYPE_ASSOC_REQ)); 2718 (is_reassoc ? IEEE80211_STYPE_REASSOC_REQ : IEEE80211_STYPE_ASSOC_REQ));
2719 header.duration_id = cpu_to_le16(0x8000); 2719 header.duration_id = cpu_to_le16(0x8000);
2720 header.seq_ctl = 0; 2720 header.seq_ctl = 0;
2721 2721
@@ -2751,9 +2751,9 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc)
2751 atmel_transmit_management_frame(priv, &header, (void *)&body, bodysize); 2751 atmel_transmit_management_frame(priv, &header, (void *)&body, bodysize);
2752} 2752}
2753 2753
2754static int is_frame_from_current_bss(struct atmel_private *priv, struct ieee802_11_hdr *header) 2754static int is_frame_from_current_bss(struct atmel_private *priv, struct ieee80211_hdr *header)
2755{ 2755{
2756 if (le16_to_cpu(header->frame_ctl) & IEEE802_11_FCTL_FROMDS) 2756 if (le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_FROMDS)
2757 return memcmp(header->addr3, priv->CurrentBSSID, 6) == 0; 2757 return memcmp(header->addr3, priv->CurrentBSSID, 6) == 0;
2758 else 2758 else
2759 return memcmp(header->addr2, priv->CurrentBSSID, 6) == 0; 2759 return memcmp(header->addr2, priv->CurrentBSSID, 6) == 0;
@@ -2801,7 +2801,7 @@ static int retrieve_bss(struct atmel_private *priv)
2801} 2801}
2802 2802
2803 2803
2804static void store_bss_info(struct atmel_private *priv, struct ieee802_11_hdr *header, 2804static void store_bss_info(struct atmel_private *priv, struct ieee80211_hdr *header,
2805 u16 capability, u16 beacon_period, u8 channel, u8 rssi, 2805 u16 capability, u16 beacon_period, u8 channel, u8 rssi,
2806 u8 ssid_len, u8 *ssid, int is_beacon) 2806 u8 ssid_len, u8 *ssid, int is_beacon)
2807{ 2807{
@@ -3085,12 +3085,12 @@ static void atmel_smooth_qual(struct atmel_private *priv)
3085} 3085}
3086 3086
3087/* deals with incoming managment frames. */ 3087/* deals with incoming managment frames. */
3088static void atmel_management_frame(struct atmel_private *priv, struct ieee802_11_hdr *header, 3088static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_hdr *header,
3089 u16 frame_len, u8 rssi) 3089 u16 frame_len, u8 rssi)
3090{ 3090{
3091 u16 subtype; 3091 u16 subtype;
3092 3092
3093 switch (subtype = le16_to_cpu(header->frame_ctl) & IEEE802_11_FCTL_STYPE) { 3093 switch (subtype = le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_STYPE) {
3094 case C80211_SUBTYPE_MGMT_BEACON : 3094 case C80211_SUBTYPE_MGMT_BEACON :
3095 case C80211_SUBTYPE_MGMT_ProbeResponse: 3095 case C80211_SUBTYPE_MGMT_ProbeResponse:
3096 3096
diff --git a/drivers/net/wireless/ieee802_11.h b/drivers/net/wireless/ieee802_11.h
deleted file mode 100644
index 53dd5248f9f1..000000000000
--- a/drivers/net/wireless/ieee802_11.h
+++ /dev/null
@@ -1,78 +0,0 @@
1#ifndef _IEEE802_11_H
2#define _IEEE802_11_H
3
4#define IEEE802_11_DATA_LEN 2304
5/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
6 6.2.1.1.2.
7
8 The figure in section 7.1.2 suggests a body size of up to 2312
9 bytes is allowed, which is a bit confusing, I suspect this
10 represents the 2304 bytes of real data, plus a possible 8 bytes of
11 WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */
12
13
14#define IEEE802_11_HLEN 30
15#define IEEE802_11_FRAME_LEN (IEEE802_11_DATA_LEN + IEEE802_11_HLEN)
16
17struct ieee802_11_hdr {
18 u16 frame_ctl;
19 u16 duration_id;
20 u8 addr1[ETH_ALEN];
21 u8 addr2[ETH_ALEN];
22 u8 addr3[ETH_ALEN];
23 u16 seq_ctl;
24 u8 addr4[ETH_ALEN];
25} __attribute__ ((packed));
26
27/* Frame control field constants */
28#define IEEE802_11_FCTL_VERS 0x0002
29#define IEEE802_11_FCTL_FTYPE 0x000c
30#define IEEE802_11_FCTL_STYPE 0x00f0
31#define IEEE802_11_FCTL_TODS 0x0100
32#define IEEE802_11_FCTL_FROMDS 0x0200
33#define IEEE802_11_FCTL_MOREFRAGS 0x0400
34#define IEEE802_11_FCTL_RETRY 0x0800
35#define IEEE802_11_FCTL_PM 0x1000
36#define IEEE802_11_FCTL_MOREDATA 0x2000
37#define IEEE802_11_FCTL_WEP 0x4000
38#define IEEE802_11_FCTL_ORDER 0x8000
39
40#define IEEE802_11_FTYPE_MGMT 0x0000
41#define IEEE802_11_FTYPE_CTL 0x0004
42#define IEEE802_11_FTYPE_DATA 0x0008
43
44/* management */
45#define IEEE802_11_STYPE_ASSOC_REQ 0x0000
46#define IEEE802_11_STYPE_ASSOC_RESP 0x0010
47#define IEEE802_11_STYPE_REASSOC_REQ 0x0020
48#define IEEE802_11_STYPE_REASSOC_RESP 0x0030
49#define IEEE802_11_STYPE_PROBE_REQ 0x0040
50#define IEEE802_11_STYPE_PROBE_RESP 0x0050
51#define IEEE802_11_STYPE_BEACON 0x0080
52#define IEEE802_11_STYPE_ATIM 0x0090
53#define IEEE802_11_STYPE_DISASSOC 0x00A0
54#define IEEE802_11_STYPE_AUTH 0x00B0
55#define IEEE802_11_STYPE_DEAUTH 0x00C0
56
57/* control */
58#define IEEE802_11_STYPE_PSPOLL 0x00A0
59#define IEEE802_11_STYPE_RTS 0x00B0
60#define IEEE802_11_STYPE_CTS 0x00C0
61#define IEEE802_11_STYPE_ACK 0x00D0
62#define IEEE802_11_STYPE_CFEND 0x00E0
63#define IEEE802_11_STYPE_CFENDACK 0x00F0
64
65/* data */
66#define IEEE802_11_STYPE_DATA 0x0000
67#define IEEE802_11_STYPE_DATA_CFACK 0x0010
68#define IEEE802_11_STYPE_DATA_CFPOLL 0x0020
69#define IEEE802_11_STYPE_DATA_CFACKPOLL 0x0030
70#define IEEE802_11_STYPE_NULLFUNC 0x0040
71#define IEEE802_11_STYPE_CFACK 0x0050
72#define IEEE802_11_STYPE_CFPOLL 0x0060
73#define IEEE802_11_STYPE_CFACKPOLL 0x0070
74
75#define IEEE802_11_SCTL_FRAG 0x000F
76#define IEEE802_11_SCTL_SEQ 0xFFF0
77
78#endif /* _IEEE802_11_H */
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index a3a32430ae9d..b47684c3217e 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -464,6 +464,8 @@
464#include <linux/etherdevice.h> 464#include <linux/etherdevice.h>
465#include <linux/wireless.h> 465#include <linux/wireless.h>
466 466
467#include <net/ieee80211.h>
468
467#include <asm/uaccess.h> 469#include <asm/uaccess.h>
468#include <asm/io.h> 470#include <asm/io.h>
469#include <asm/system.h> 471#include <asm/system.h>
@@ -471,7 +473,6 @@
471#include "hermes.h" 473#include "hermes.h"
472#include "hermes_rid.h" 474#include "hermes_rid.h"
473#include "orinoco.h" 475#include "orinoco.h"
474#include "ieee802_11.h"
475 476
476/********************************************************************/ 477/********************************************************************/
477/* Module information */ 478/* Module information */
@@ -509,7 +510,7 @@ MODULE_PARM_DESC(suppress_linkstatus, "Don't log link status changes");
509/********************************************************************/ 510/********************************************************************/
510 511
511#define ORINOCO_MIN_MTU 256 512#define ORINOCO_MIN_MTU 256
512#define ORINOCO_MAX_MTU (IEEE802_11_DATA_LEN - ENCAPS_OVERHEAD) 513#define ORINOCO_MAX_MTU (IEEE80211_DATA_LEN - ENCAPS_OVERHEAD)
513 514
514#define SYMBOL_MAX_VER_LEN (14) 515#define SYMBOL_MAX_VER_LEN (14)
515#define USER_BAP 0 516#define USER_BAP 0
@@ -760,7 +761,7 @@ static int orinoco_change_mtu(struct net_device *dev, int new_mtu)
760 if ( (new_mtu < ORINOCO_MIN_MTU) || (new_mtu > ORINOCO_MAX_MTU) ) 761 if ( (new_mtu < ORINOCO_MIN_MTU) || (new_mtu > ORINOCO_MAX_MTU) )
761 return -EINVAL; 762 return -EINVAL;
762 763
763 if ( (new_mtu + ENCAPS_OVERHEAD + IEEE802_11_HLEN) > 764 if ( (new_mtu + ENCAPS_OVERHEAD + IEEE80211_HLEN) >
764 (priv->nicbuf_size - ETH_HLEN) ) 765 (priv->nicbuf_size - ETH_HLEN) )
765 return -EINVAL; 766 return -EINVAL;
766 767
@@ -1104,7 +1105,7 @@ static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw)
1104 stats->rx_dropped++; 1105 stats->rx_dropped++;
1105 goto drop; 1106 goto drop;
1106 } 1107 }
1107 if (length > IEEE802_11_DATA_LEN) { 1108 if (length > IEEE80211_DATA_LEN) {
1108 printk(KERN_WARNING "%s: Oversized frame received (%d bytes)\n", 1109 printk(KERN_WARNING "%s: Oversized frame received (%d bytes)\n",
1109 dev->name, length); 1110 dev->name, length);
1110 stats->rx_length_errors++; 1111 stats->rx_length_errors++;
@@ -2264,7 +2265,7 @@ static int orinoco_init(struct net_device *dev)
2264 2265
2265 /* No need to lock, the hw_unavailable flag is already set in 2266 /* No need to lock, the hw_unavailable flag is already set in
2266 * alloc_orinocodev() */ 2267 * alloc_orinocodev() */
2267 priv->nicbuf_size = IEEE802_11_FRAME_LEN + ETH_HLEN; 2268 priv->nicbuf_size = IEEE80211_FRAME_LEN + ETH_HLEN;
2268 2269
2269 /* Initialize the firmware */ 2270 /* Initialize the firmware */
2270 err = hermes_init(hw); 2271 err = hermes_init(hw);
diff --git a/drivers/net/wireless/wl3501.h b/drivers/net/wireless/wl3501.h
index 8636d9306785..b5719437e981 100644
--- a/drivers/net/wireless/wl3501.h
+++ b/drivers/net/wireless/wl3501.h
@@ -2,7 +2,7 @@
2#define __WL3501_H__ 2#define __WL3501_H__
3 3
4#include <linux/spinlock.h> 4#include <linux/spinlock.h>
5#include "ieee802_11.h" 5#include <net/ieee80211.h>
6 6
7/* define for WLA 2.0 */ 7/* define for WLA 2.0 */
8#define WL3501_BLKSZ 256 8#define WL3501_BLKSZ 256
@@ -548,7 +548,7 @@ struct wl3501_80211_tx_plcp_hdr {
548 548
549struct wl3501_80211_tx_hdr { 549struct wl3501_80211_tx_hdr {
550 struct wl3501_80211_tx_plcp_hdr pclp_hdr; 550 struct wl3501_80211_tx_plcp_hdr pclp_hdr;
551 struct ieee802_11_hdr mac_hdr; 551 struct ieee80211_hdr mac_hdr;
552} __attribute__ ((packed)); 552} __attribute__ ((packed));
553 553
554/* 554/*
diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h
new file mode 100644
index 000000000000..b1bfaf1084f4
--- /dev/null
+++ b/include/net/ieee80211.h
@@ -0,0 +1,887 @@
1/*
2 * Merged with mainline ieee80211.h in Aug 2004. Original ieee802_11
3 * remains copyright by the original authors
4 *
5 * Portions of the merged code are based on Host AP (software wireless
6 * LAN access point) driver for Intersil Prism2/2.5/3.
7 *
8 * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
9 * <jkmaline@cc.hut.fi>
10 * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
11 *
12 * Adaption to a generic IEEE 802.11 stack by James Ketrenos
13 * <jketreno@linux.intel.com>
14 * Copyright (c) 2004, Intel Corporation
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License version 2 as
18 * published by the Free Software Foundation. See README and COPYING for
19 * more details.
20 */
21#ifndef IEEE80211_H
22#define IEEE80211_H
23#include <linux/if_ether.h> /* ETH_ALEN */
24#include <linux/kernel.h> /* ARRAY_SIZE */
25
26#if WIRELESS_EXT < 17
27#define IW_QUAL_QUAL_INVALID 0x10
28#define IW_QUAL_LEVEL_INVALID 0x20
29#define IW_QUAL_NOISE_INVALID 0x40
30#define IW_QUAL_QUAL_UPDATED 0x1
31#define IW_QUAL_LEVEL_UPDATED 0x2
32#define IW_QUAL_NOISE_UPDATED 0x4
33#endif
34
35#define IEEE80211_DATA_LEN 2304
36/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
37 6.2.1.1.2.
38
39 The figure in section 7.1.2 suggests a body size of up to 2312
40 bytes is allowed, which is a bit confusing, I suspect this
41 represents the 2304 bytes of real data, plus a possible 8 bytes of
42 WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */
43
44
45#define IEEE80211_HLEN 30
46#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN)
47
48struct ieee80211_hdr {
49 u16 frame_ctl;
50 u16 duration_id;
51 u8 addr1[ETH_ALEN];
52 u8 addr2[ETH_ALEN];
53 u8 addr3[ETH_ALEN];
54 u16 seq_ctl;
55 u8 addr4[ETH_ALEN];
56} __attribute__ ((packed));
57
58struct ieee80211_hdr_3addr {
59 u16 frame_ctl;
60 u16 duration_id;
61 u8 addr1[ETH_ALEN];
62 u8 addr2[ETH_ALEN];
63 u8 addr3[ETH_ALEN];
64 u16 seq_ctl;
65} __attribute__ ((packed));
66
67enum eap_type {
68 EAP_PACKET = 0,
69 EAPOL_START,
70 EAPOL_LOGOFF,
71 EAPOL_KEY,
72 EAPOL_ENCAP_ASF_ALERT
73};
74
75static const char *eap_types[] = {
76 [EAP_PACKET] = "EAP-Packet",
77 [EAPOL_START] = "EAPOL-Start",
78 [EAPOL_LOGOFF] = "EAPOL-Logoff",
79 [EAPOL_KEY] = "EAPOL-Key",
80 [EAPOL_ENCAP_ASF_ALERT] = "EAPOL-Encap-ASF-Alert"
81};
82
83static inline const char *eap_get_type(int type)
84{
85 return (type >= ARRAY_SIZE(eap_types)) ? "Unknown" : eap_types[type];
86}
87
88struct eapol {
89 u8 snap[6];
90 u16 ethertype;
91 u8 version;
92 u8 type;
93 u16 length;
94} __attribute__ ((packed));
95
96#define IEEE80211_3ADDR_LEN 24
97#define IEEE80211_4ADDR_LEN 30
98#define IEEE80211_FCS_LEN 4
99
100#define MIN_FRAG_THRESHOLD 256U
101#define MAX_FRAG_THRESHOLD 2346U
102
103/* Frame control field constants */
104#define IEEE80211_FCTL_VERS 0x0002
105#define IEEE80211_FCTL_FTYPE 0x000c
106#define IEEE80211_FCTL_STYPE 0x00f0
107#define IEEE80211_FCTL_TODS 0x0100
108#define IEEE80211_FCTL_FROMDS 0x0200
109#define IEEE80211_FCTL_MOREFRAGS 0x0400
110#define IEEE80211_FCTL_RETRY 0x0800
111#define IEEE80211_FCTL_PM 0x1000
112#define IEEE80211_FCTL_MOREDATA 0x2000
113#define IEEE80211_FCTL_WEP 0x4000
114#define IEEE80211_FCTL_ORDER 0x8000
115
116#define IEEE80211_FTYPE_MGMT 0x0000
117#define IEEE80211_FTYPE_CTL 0x0004
118#define IEEE80211_FTYPE_DATA 0x0008
119
120/* management */
121#define IEEE80211_STYPE_ASSOC_REQ 0x0000
122#define IEEE80211_STYPE_ASSOC_RESP 0x0010
123#define IEEE80211_STYPE_REASSOC_REQ 0x0020
124#define IEEE80211_STYPE_REASSOC_RESP 0x0030
125#define IEEE80211_STYPE_PROBE_REQ 0x0040
126#define IEEE80211_STYPE_PROBE_RESP 0x0050
127#define IEEE80211_STYPE_BEACON 0x0080
128#define IEEE80211_STYPE_ATIM 0x0090
129#define IEEE80211_STYPE_DISASSOC 0x00A0
130#define IEEE80211_STYPE_AUTH 0x00B0
131#define IEEE80211_STYPE_DEAUTH 0x00C0
132
133/* control */
134#define IEEE80211_STYPE_PSPOLL 0x00A0
135#define IEEE80211_STYPE_RTS 0x00B0
136#define IEEE80211_STYPE_CTS 0x00C0
137#define IEEE80211_STYPE_ACK 0x00D0
138#define IEEE80211_STYPE_CFEND 0x00E0
139#define IEEE80211_STYPE_CFENDACK 0x00F0
140
141/* data */
142#define IEEE80211_STYPE_DATA 0x0000
143#define IEEE80211_STYPE_DATA_CFACK 0x0010
144#define IEEE80211_STYPE_DATA_CFPOLL 0x0020
145#define IEEE80211_STYPE_DATA_CFACKPOLL 0x0030
146#define IEEE80211_STYPE_NULLFUNC 0x0040
147#define IEEE80211_STYPE_CFACK 0x0050
148#define IEEE80211_STYPE_CFPOLL 0x0060
149#define IEEE80211_STYPE_CFACKPOLL 0x0070
150
151#define IEEE80211_SCTL_FRAG 0x000F
152#define IEEE80211_SCTL_SEQ 0xFFF0
153
154
155/* debug macros */
156
157#ifdef CONFIG_IEEE80211_DEBUG
158extern u32 ieee80211_debug_level;
159#define IEEE80211_DEBUG(level, fmt, args...) \
160do { if (ieee80211_debug_level & (level)) \
161 printk(KERN_DEBUG "ieee80211: %c %s " fmt, \
162 in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0)
163#else
164#define IEEE80211_DEBUG(level, fmt, args...) do {} while (0)
165#endif /* CONFIG_IEEE80211_DEBUG */
166
167/*
168 * To use the debug system;
169 *
170 * If you are defining a new debug classification, simply add it to the #define
171 * list here in the form of:
172 *
173 * #define IEEE80211_DL_xxxx VALUE
174 *
175 * shifting value to the left one bit from the previous entry. xxxx should be
176 * the name of the classification (for example, WEP)
177 *
178 * You then need to either add a IEEE80211_xxxx_DEBUG() macro definition for your
179 * classification, or use IEEE80211_DEBUG(IEEE80211_DL_xxxx, ...) whenever you want
180 * to send output to that classification.
181 *
182 * To add your debug level to the list of levels seen when you perform
183 *
184 * % cat /proc/net/ipw/debug_level
185 *
186 * you simply need to add your entry to the ipw_debug_levels array.
187 *
188 * If you do not see debug_level in /proc/net/ipw then you do not have
189 * CONFIG_IEEE80211_DEBUG defined in your kernel configuration
190 *
191 */
192
193#define IEEE80211_DL_INFO (1<<0)
194#define IEEE80211_DL_WX (1<<1)
195#define IEEE80211_DL_SCAN (1<<2)
196#define IEEE80211_DL_STATE (1<<3)
197#define IEEE80211_DL_MGMT (1<<4)
198#define IEEE80211_DL_FRAG (1<<5)
199#define IEEE80211_DL_EAP (1<<6)
200#define IEEE80211_DL_DROP (1<<7)
201
202#define IEEE80211_DL_TX (1<<8)
203#define IEEE80211_DL_RX (1<<9)
204
205#define IEEE80211_ERROR(f, a...) printk(KERN_ERR "ieee80211: " f, ## a)
206#define IEEE80211_WARNING(f, a...) printk(KERN_WARNING "ieee80211: " f, ## a)
207#define IEEE80211_DEBUG_INFO(f, a...) IEEE80211_DEBUG(IEEE80211_DL_INFO, f, ## a)
208
209#define IEEE80211_DEBUG_WX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_WX, f, ## a)
210#define IEEE80211_DEBUG_SCAN(f, a...) IEEE80211_DEBUG(IEEE80211_DL_SCAN, f, ## a)
211#define IEEE80211_DEBUG_STATE(f, a...) IEEE80211_DEBUG(IEEE80211_DL_STATE, f, ## a)
212#define IEEE80211_DEBUG_MGMT(f, a...) IEEE80211_DEBUG(IEEE80211_DL_MGMT, f, ## a)
213#define IEEE80211_DEBUG_FRAG(f, a...) IEEE80211_DEBUG(IEEE80211_DL_FRAG, f, ## a)
214#define IEEE80211_DEBUG_EAP(f, a...) IEEE80211_DEBUG(IEEE80211_DL_EAP, f, ## a)
215#define IEEE80211_DEBUG_DROP(f, a...) IEEE80211_DEBUG(IEEE80211_DL_DROP, f, ## a)
216#define IEEE80211_DEBUG_TX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_TX, f, ## a)
217#define IEEE80211_DEBUG_RX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_RX, f, ## a)
218#include <linux/netdevice.h>
219#include <linux/wireless.h>
220#include <linux/if_arp.h> /* ARPHRD_ETHER */
221
222#ifndef WIRELESS_SPY
223#define WIRELESS_SPY // enable iwspy support
224#endif
225#include <net/iw_handler.h> // new driver API
226
227#ifndef ETH_P_PAE
228#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
229#endif /* ETH_P_PAE */
230
231#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */
232
233#ifndef ETH_P_80211_RAW
234#define ETH_P_80211_RAW (ETH_P_ECONET + 1)
235#endif
236
237/* IEEE 802.11 defines */
238
239#define P80211_OUI_LEN 3
240
241struct ieee80211_snap_hdr {
242
243 u8 dsap; /* always 0xAA */
244 u8 ssap; /* always 0xAA */
245 u8 ctrl; /* always 0x03 */
246 u8 oui[P80211_OUI_LEN]; /* organizational universal id */
247
248} __attribute__ ((packed));
249
250#define SNAP_SIZE sizeof(struct ieee80211_snap_hdr)
251
252#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE)
253#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE)
254
255#define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG)
256#define WLAN_GET_SEQ_SEQ(seq) ((seq) & IEEE80211_SCTL_SEQ)
257
258/* Authentication algorithms */
259#define WLAN_AUTH_OPEN 0
260#define WLAN_AUTH_SHARED_KEY 1
261
262#define WLAN_AUTH_CHALLENGE_LEN 128
263
264#define WLAN_CAPABILITY_BSS (1<<0)
265#define WLAN_CAPABILITY_IBSS (1<<1)
266#define WLAN_CAPABILITY_CF_POLLABLE (1<<2)
267#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3)
268#define WLAN_CAPABILITY_PRIVACY (1<<4)
269#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5)
270#define WLAN_CAPABILITY_PBCC (1<<6)
271#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7)
272
273/* Status codes */
274#define WLAN_STATUS_SUCCESS 0
275#define WLAN_STATUS_UNSPECIFIED_FAILURE 1
276#define WLAN_STATUS_CAPS_UNSUPPORTED 10
277#define WLAN_STATUS_REASSOC_NO_ASSOC 11
278#define WLAN_STATUS_ASSOC_DENIED_UNSPEC 12
279#define WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG 13
280#define WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION 14
281#define WLAN_STATUS_CHALLENGE_FAIL 15
282#define WLAN_STATUS_AUTH_TIMEOUT 16
283#define WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA 17
284#define WLAN_STATUS_ASSOC_DENIED_RATES 18
285/* 802.11b */
286#define WLAN_STATUS_ASSOC_DENIED_NOSHORT 19
287#define WLAN_STATUS_ASSOC_DENIED_NOPBCC 20
288#define WLAN_STATUS_ASSOC_DENIED_NOAGILITY 21
289
290/* Reason codes */
291#define WLAN_REASON_UNSPECIFIED 1
292#define WLAN_REASON_PREV_AUTH_NOT_VALID 2
293#define WLAN_REASON_DEAUTH_LEAVING 3
294#define WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY 4
295#define WLAN_REASON_DISASSOC_AP_BUSY 5
296#define WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA 6
297#define WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA 7
298#define WLAN_REASON_DISASSOC_STA_HAS_LEFT 8
299#define WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH 9
300
301
302/* Information Element IDs */
303#define WLAN_EID_SSID 0
304#define WLAN_EID_SUPP_RATES 1
305#define WLAN_EID_FH_PARAMS 2
306#define WLAN_EID_DS_PARAMS 3
307#define WLAN_EID_CF_PARAMS 4
308#define WLAN_EID_TIM 5
309#define WLAN_EID_IBSS_PARAMS 6
310#define WLAN_EID_CHALLENGE 16
311#define WLAN_EID_RSN 48
312#define WLAN_EID_GENERIC 221
313
314#define IEEE80211_MGMT_HDR_LEN 24
315#define IEEE80211_DATA_HDR3_LEN 24
316#define IEEE80211_DATA_HDR4_LEN 30
317
318
319#define IEEE80211_STATMASK_SIGNAL (1<<0)
320#define IEEE80211_STATMASK_RSSI (1<<1)
321#define IEEE80211_STATMASK_NOISE (1<<2)
322#define IEEE80211_STATMASK_RATE (1<<3)
323#define IEEE80211_STATMASK_WEMASK 0x7
324
325
326#define IEEE80211_CCK_MODULATION (1<<0)
327#define IEEE80211_OFDM_MODULATION (1<<1)
328
329#define IEEE80211_24GHZ_BAND (1<<0)
330#define IEEE80211_52GHZ_BAND (1<<1)
331
332#define IEEE80211_CCK_RATE_1MB 0x02
333#define IEEE80211_CCK_RATE_2MB 0x04
334#define IEEE80211_CCK_RATE_5MB 0x0B
335#define IEEE80211_CCK_RATE_11MB 0x16
336#define IEEE80211_OFDM_RATE_6MB 0x0C
337#define IEEE80211_OFDM_RATE_9MB 0x12
338#define IEEE80211_OFDM_RATE_12MB 0x18
339#define IEEE80211_OFDM_RATE_18MB 0x24
340#define IEEE80211_OFDM_RATE_24MB 0x30
341#define IEEE80211_OFDM_RATE_36MB 0x48
342#define IEEE80211_OFDM_RATE_48MB 0x60
343#define IEEE80211_OFDM_RATE_54MB 0x6C
344#define IEEE80211_BASIC_RATE_MASK 0x80
345
346#define IEEE80211_CCK_RATE_1MB_MASK (1<<0)
347#define IEEE80211_CCK_RATE_2MB_MASK (1<<1)
348#define IEEE80211_CCK_RATE_5MB_MASK (1<<2)
349#define IEEE80211_CCK_RATE_11MB_MASK (1<<3)
350#define IEEE80211_OFDM_RATE_6MB_MASK (1<<4)
351#define IEEE80211_OFDM_RATE_9MB_MASK (1<<5)
352#define IEEE80211_OFDM_RATE_12MB_MASK (1<<6)
353#define IEEE80211_OFDM_RATE_18MB_MASK (1<<7)
354#define IEEE80211_OFDM_RATE_24MB_MASK (1<<8)
355#define IEEE80211_OFDM_RATE_36MB_MASK (1<<9)
356#define IEEE80211_OFDM_RATE_48MB_MASK (1<<10)
357#define IEEE80211_OFDM_RATE_54MB_MASK (1<<11)
358
359#define IEEE80211_CCK_RATES_MASK 0x0000000F
360#define IEEE80211_CCK_BASIC_RATES_MASK (IEEE80211_CCK_RATE_1MB_MASK | \
361 IEEE80211_CCK_RATE_2MB_MASK)
362#define IEEE80211_CCK_DEFAULT_RATES_MASK (IEEE80211_CCK_BASIC_RATES_MASK | \
363 IEEE80211_CCK_RATE_5MB_MASK | \
364 IEEE80211_CCK_RATE_11MB_MASK)
365
366#define IEEE80211_OFDM_RATES_MASK 0x00000FF0
367#define IEEE80211_OFDM_BASIC_RATES_MASK (IEEE80211_OFDM_RATE_6MB_MASK | \
368 IEEE80211_OFDM_RATE_12MB_MASK | \
369 IEEE80211_OFDM_RATE_24MB_MASK)
370#define IEEE80211_OFDM_DEFAULT_RATES_MASK (IEEE80211_OFDM_BASIC_RATES_MASK | \
371 IEEE80211_OFDM_RATE_9MB_MASK | \
372 IEEE80211_OFDM_RATE_18MB_MASK | \
373 IEEE80211_OFDM_RATE_36MB_MASK | \
374 IEEE80211_OFDM_RATE_48MB_MASK | \
375 IEEE80211_OFDM_RATE_54MB_MASK)
376#define IEEE80211_DEFAULT_RATES_MASK (IEEE80211_OFDM_DEFAULT_RATES_MASK | \
377 IEEE80211_CCK_DEFAULT_RATES_MASK)
378
379#define IEEE80211_NUM_OFDM_RATES 8
380#define IEEE80211_NUM_CCK_RATES 4
381#define IEEE80211_OFDM_SHIFT_MASK_A 4
382
383
384
385
386/* NOTE: This data is for statistical purposes; not all hardware provides this
387 * information for frames received. Not setting these will not cause
388 * any adverse affects. */
389struct ieee80211_rx_stats {
390 u32 mac_time;
391 s8 rssi;
392 u8 signal;
393 u8 noise;
394 u16 rate; /* in 100 kbps */
395 u8 received_channel;
396 u8 control;
397 u8 mask;
398 u8 freq;
399 u16 len;
400};
401
402/* IEEE 802.11 requires that STA supports concurrent reception of at least
403 * three fragmented frames. This define can be increased to support more
404 * concurrent frames, but it should be noted that each entry can consume about
405 * 2 kB of RAM and increasing cache size will slow down frame reassembly. */
406#define IEEE80211_FRAG_CACHE_LEN 4
407
408struct ieee80211_frag_entry {
409 unsigned long first_frag_time;
410 unsigned int seq;
411 unsigned int last_frag;
412 struct sk_buff *skb;
413 u8 src_addr[ETH_ALEN];
414 u8 dst_addr[ETH_ALEN];
415};
416
417struct ieee80211_stats {
418 unsigned int tx_unicast_frames;
419 unsigned int tx_multicast_frames;
420 unsigned int tx_fragments;
421 unsigned int tx_unicast_octets;
422 unsigned int tx_multicast_octets;
423 unsigned int tx_deferred_transmissions;
424 unsigned int tx_single_retry_frames;
425 unsigned int tx_multiple_retry_frames;
426 unsigned int tx_retry_limit_exceeded;
427 unsigned int tx_discards;
428 unsigned int rx_unicast_frames;
429 unsigned int rx_multicast_frames;
430 unsigned int rx_fragments;
431 unsigned int rx_unicast_octets;
432 unsigned int rx_multicast_octets;
433 unsigned int rx_fcs_errors;
434 unsigned int rx_discards_no_buffer;
435 unsigned int tx_discards_wrong_sa;
436 unsigned int rx_discards_undecryptable;
437 unsigned int rx_message_in_msg_fragments;
438 unsigned int rx_message_in_bad_msg_fragments;
439};
440
441struct ieee80211_device;
442
443#include "ieee80211_crypt.h"
444
445#define SEC_KEY_1 (1<<0)
446#define SEC_KEY_2 (1<<1)
447#define SEC_KEY_3 (1<<2)
448#define SEC_KEY_4 (1<<3)
449#define SEC_ACTIVE_KEY (1<<4)
450#define SEC_AUTH_MODE (1<<5)
451#define SEC_UNICAST_GROUP (1<<6)
452#define SEC_LEVEL (1<<7)
453#define SEC_ENABLED (1<<8)
454
455#define SEC_LEVEL_0 0 /* None */
456#define SEC_LEVEL_1 1 /* WEP 40 and 104 bit */
457#define SEC_LEVEL_2 2 /* Level 1 + TKIP */
458#define SEC_LEVEL_2_CKIP 3 /* Level 1 + CKIP */
459#define SEC_LEVEL_3 4 /* Level 2 + CCMP */
460
461#define WEP_KEYS 4
462#define WEP_KEY_LEN 13
463
464struct ieee80211_security {
465 u16 active_key:2,
466 enabled:1,
467 auth_mode:2,
468 auth_algo:4,
469 unicast_uses_group:1;
470 u8 key_sizes[WEP_KEYS];
471 u8 keys[WEP_KEYS][WEP_KEY_LEN];
472 u8 level;
473 u16 flags;
474} __attribute__ ((packed));
475
476
477/*
478
479 802.11 data frame from AP
480
481 ,-------------------------------------------------------------------.
482Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 |
483 |------|------|---------|---------|---------|------|---------|------|
484Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | frame | fcs |
485 | | tion | (BSSID) | | | ence | data | |
486 `-------------------------------------------------------------------'
487
488Total: 28-2340 bytes
489
490*/
491
492struct ieee80211_header_data {
493 u16 frame_ctl;
494 u16 duration_id;
495 u8 addr1[6];
496 u8 addr2[6];
497 u8 addr3[6];
498 u16 seq_ctrl;
499};
500
501#define BEACON_PROBE_SSID_ID_POSITION 12
502
503/* Management Frame Information Element Types */
504#define MFIE_TYPE_SSID 0
505#define MFIE_TYPE_RATES 1
506#define MFIE_TYPE_FH_SET 2
507#define MFIE_TYPE_DS_SET 3
508#define MFIE_TYPE_CF_SET 4
509#define MFIE_TYPE_TIM 5
510#define MFIE_TYPE_IBSS_SET 6
511#define MFIE_TYPE_CHALLENGE 16
512#define MFIE_TYPE_RSN 48
513#define MFIE_TYPE_RATES_EX 50
514#define MFIE_TYPE_GENERIC 221
515
516struct ieee80211_info_element_hdr {
517 u8 id;
518 u8 len;
519} __attribute__ ((packed));
520
521struct ieee80211_info_element {
522 u8 id;
523 u8 len;
524 u8 data[0];
525} __attribute__ ((packed));
526
527/*
528 * These are the data types that can make up management packets
529 *
530 u16 auth_algorithm;
531 u16 auth_sequence;
532 u16 beacon_interval;
533 u16 capability;
534 u8 current_ap[ETH_ALEN];
535 u16 listen_interval;
536 struct {
537 u16 association_id:14, reserved:2;
538 } __attribute__ ((packed));
539 u32 time_stamp[2];
540 u16 reason;
541 u16 status;
542*/
543
544struct ieee80211_authentication {
545 struct ieee80211_header_data header;
546 u16 algorithm;
547 u16 transaction;
548 u16 status;
549 struct ieee80211_info_element info_element;
550} __attribute__ ((packed));
551
552
553struct ieee80211_probe_response {
554 struct ieee80211_header_data header;
555 u32 time_stamp[2];
556 u16 beacon_interval;
557 u16 capability;
558 struct ieee80211_info_element info_element;
559} __attribute__ ((packed));
560
561struct ieee80211_assoc_request_frame {
562 u16 capability;
563 u16 listen_interval;
564 u8 current_ap[ETH_ALEN];
565 struct ieee80211_info_element info_element;
566} __attribute__ ((packed));
567
568struct ieee80211_assoc_response_frame {
569 struct ieee80211_hdr_3addr header;
570 u16 capability;
571 u16 status;
572 u16 aid;
573 struct ieee80211_info_element info_element; /* supported rates */
574} __attribute__ ((packed));
575
576
577struct ieee80211_txb {
578 u8 nr_frags;
579 u8 encrypted;
580 u16 reserved;
581 u16 frag_size;
582 u16 payload_size;
583 struct sk_buff *fragments[0];
584};
585
586
587/* SWEEP TABLE ENTRIES NUMBER*/
588#define MAX_SWEEP_TAB_ENTRIES 42
589#define MAX_SWEEP_TAB_ENTRIES_PER_PACKET 7
590/* MAX_RATES_LENGTH needs to be 12. The spec says 8, and many APs
591 * only use 8, and then use extended rates for the remaining supported
592 * rates. Other APs, however, stick all of their supported rates on the
593 * main rates information element... */
594#define MAX_RATES_LENGTH ((u8)12)
595#define MAX_RATES_EX_LENGTH ((u8)16)
596#define MAX_NETWORK_COUNT 128
597
598#define CRC_LENGTH 4U
599
600#define MAX_WPA_IE_LEN 64
601
602#define NETWORK_EMPTY_ESSID (1<<0)
603#define NETWORK_HAS_OFDM (1<<1)
604#define NETWORK_HAS_CCK (1<<2)
605
606struct ieee80211_network {
607 /* These entries are used to identify a unique network */
608 u8 bssid[ETH_ALEN];
609 u8 channel;
610 /* Ensure null-terminated for any debug msgs */
611 u8 ssid[IW_ESSID_MAX_SIZE + 1];
612 u8 ssid_len;
613
614 /* These are network statistics */
615 struct ieee80211_rx_stats stats;
616 u16 capability;
617 u8 rates[MAX_RATES_LENGTH];
618 u8 rates_len;
619 u8 rates_ex[MAX_RATES_EX_LENGTH];
620 u8 rates_ex_len;
621 unsigned long last_scanned;
622 u8 mode;
623 u8 flags;
624 u32 last_associate;
625 u32 time_stamp[2];
626 u16 beacon_interval;
627 u16 listen_interval;
628 u16 atim_window;
629 u8 wpa_ie[MAX_WPA_IE_LEN];
630 size_t wpa_ie_len;
631 u8 rsn_ie[MAX_WPA_IE_LEN];
632 size_t rsn_ie_len;
633 struct list_head list;
634};
635
636enum ieee80211_state {
637 IEEE80211_UNINITIALIZED = 0,
638 IEEE80211_INITIALIZED,
639 IEEE80211_ASSOCIATING,
640 IEEE80211_ASSOCIATED,
641 IEEE80211_AUTHENTICATING,
642 IEEE80211_AUTHENTICATED,
643 IEEE80211_SHUTDOWN
644};
645
646#define DEFAULT_MAX_SCAN_AGE (15 * HZ)
647#define DEFAULT_FTS 2346
648#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
649#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
650
651
652extern inline int is_multicast_ether_addr(const u8 *addr)
653{
654 return ((addr[0] != 0xff) && (0x01 & addr[0]));
655}
656
657extern inline int is_broadcast_ether_addr(const u8 *addr)
658{
659 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) && \
660 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
661}
662
663#define CFG_IEEE80211_RESERVE_FCS (1<<0)
664#define CFG_IEEE80211_COMPUTE_FCS (1<<1)
665
666struct ieee80211_device {
667 struct net_device *dev;
668
669 /* Bookkeeping structures */
670 struct net_device_stats stats;
671 struct ieee80211_stats ieee_stats;
672
673 /* Probe / Beacon management */
674 struct list_head network_free_list;
675 struct list_head network_list;
676 struct ieee80211_network *networks;
677 int scans;
678 int scan_age;
679
680 int iw_mode; /* operating mode (IW_MODE_*) */
681
682 spinlock_t lock;
683
684 int tx_headroom; /* Set to size of any additional room needed at front
685 * of allocated Tx SKBs */
686 u32 config;
687
688 /* WEP and other encryption related settings at the device level */
689 int open_wep; /* Set to 1 to allow unencrypted frames */
690
691 int reset_on_keychange; /* Set to 1 if the HW needs to be reset on
692 * WEP key changes */
693
694 /* If the host performs {en,de}cryption, then set to 1 */
695 int host_encrypt;
696 int host_decrypt;
697 int ieee802_1x; /* is IEEE 802.1X used */
698
699 /* WPA data */
700 int wpa_enabled;
701 int drop_unencrypted;
702 int tkip_countermeasures;
703 int privacy_invoked;
704 size_t wpa_ie_len;
705 u8 *wpa_ie;
706
707 struct list_head crypt_deinit_list;
708 struct ieee80211_crypt_data *crypt[WEP_KEYS];
709 int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */
710 struct timer_list crypt_deinit_timer;
711
712 int bcrx_sta_key; /* use individual keys to override default keys even
713 * with RX of broad/multicast frames */
714
715 /* Fragmentation structures */
716 struct ieee80211_frag_entry frag_cache[IEEE80211_FRAG_CACHE_LEN];
717 unsigned int frag_next_idx;
718 u16 fts; /* Fragmentation Threshold */
719
720 /* Association info */
721 u8 bssid[ETH_ALEN];
722
723 enum ieee80211_state state;
724
725 int mode; /* A, B, G */
726 int modulation; /* CCK, OFDM */
727 int freq_band; /* 2.4Ghz, 5.2Ghz, Mixed */
728 int abg_ture; /* ABG flag */
729
730 /* Callback functions */
731 void (*set_security)(struct net_device *dev,
732 struct ieee80211_security *sec);
733 int (*hard_start_xmit)(struct ieee80211_txb *txb,
734 struct net_device *dev);
735 int (*reset_port)(struct net_device *dev);
736
737 /* This must be the last item so that it points to the data
738 * allocated beyond this structure by alloc_ieee80211 */
739 u8 priv[0];
740};
741
742#define IEEE_A (1<<0)
743#define IEEE_B (1<<1)
744#define IEEE_G (1<<2)
745#define IEEE_MODE_MASK (IEEE_A|IEEE_B|IEEE_G)
746
747extern inline void *ieee80211_priv(struct net_device *dev)
748{
749 return ((struct ieee80211_device *)netdev_priv(dev))->priv;
750}
751
752extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
753{
754 /* Single white space is for Linksys APs */
755 if (essid_len == 1 && essid[0] == ' ')
756 return 1;
757
758 /* Otherwise, if the entire essid is 0, we assume it is hidden */
759 while (essid_len) {
760 essid_len--;
761 if (essid[essid_len] != '\0')
762 return 0;
763 }
764
765 return 1;
766}
767
768extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode)
769{
770 /*
771 * It is possible for both access points and our device to support
772 * combinations of modes, so as long as there is one valid combination
773 * of ap/device supported modes, then return success
774 *
775 */
776 if ((mode & IEEE_A) &&
777 (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
778 (ieee->freq_band & IEEE80211_52GHZ_BAND))
779 return 1;
780
781 if ((mode & IEEE_G) &&
782 (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
783 (ieee->freq_band & IEEE80211_24GHZ_BAND))
784 return 1;
785
786 if ((mode & IEEE_B) &&
787 (ieee->modulation & IEEE80211_CCK_MODULATION) &&
788 (ieee->freq_band & IEEE80211_24GHZ_BAND))
789 return 1;
790
791 return 0;
792}
793
794extern inline int ieee80211_get_hdrlen(u16 fc)
795{
796 int hdrlen = 24;
797
798 switch (WLAN_FC_GET_TYPE(fc)) {
799 case IEEE80211_FTYPE_DATA:
800 if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
801 hdrlen = 30; /* Addr4 */
802 break;
803 case IEEE80211_FTYPE_CTL:
804 switch (WLAN_FC_GET_STYPE(fc)) {
805 case IEEE80211_STYPE_CTS:
806 case IEEE80211_STYPE_ACK:
807 hdrlen = 10;
808 break;
809 default:
810 hdrlen = 16;
811 break;
812 }
813 break;
814 }
815
816 return hdrlen;
817}
818
819
820
821/* ieee80211.c */
822extern void free_ieee80211(struct net_device *dev);
823extern struct net_device *alloc_ieee80211(int sizeof_priv);
824
825extern int ieee80211_set_encryption(struct ieee80211_device *ieee);
826
827/* ieee80211_tx.c */
828
829
830extern int ieee80211_xmit(struct sk_buff *skb,
831 struct net_device *dev);
832extern void ieee80211_txb_free(struct ieee80211_txb *);
833
834
835/* ieee80211_rx.c */
836extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
837 struct ieee80211_rx_stats *rx_stats);
838extern void ieee80211_rx_mgt(struct ieee80211_device *ieee,
839 struct ieee80211_hdr *header,
840 struct ieee80211_rx_stats *stats);
841
842/* iee80211_wx.c */
843extern int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
844 struct iw_request_info *info,
845 union iwreq_data *wrqu, char *key);
846extern int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
847 struct iw_request_info *info,
848 union iwreq_data *wrqu, char *key);
849extern int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
850 struct iw_request_info *info,
851 union iwreq_data *wrqu, char *key);
852
853
854extern inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
855{
856 ieee->scans++;
857}
858
859extern inline int ieee80211_get_scans(struct ieee80211_device *ieee)
860{
861 return ieee->scans;
862}
863
864static inline const char *escape_essid(const char *essid, u8 essid_len) {
865 static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
866 const char *s = essid;
867 char *d = escaped;
868
869 if (ieee80211_is_empty_essid(essid, essid_len)) {
870 memcpy(escaped, "<hidden>", sizeof("<hidden>"));
871 return escaped;
872 }
873
874 essid_len = min(essid_len, (u8)IW_ESSID_MAX_SIZE);
875 while (essid_len--) {
876 if (*s == '\0') {
877 *d++ = '\\';
878 *d++ = '0';
879 s++;
880 } else {
881 *d++ = *s++;
882 }
883 }
884 *d = '\0';
885 return escaped;
886}
887#endif /* IEEE80211_H */
diff --git a/include/net/ieee80211_crypt.h b/include/net/ieee80211_crypt.h
new file mode 100644
index 000000000000..b58a3bcc0dc0
--- /dev/null
+++ b/include/net/ieee80211_crypt.h
@@ -0,0 +1,86 @@
1/*
2 * Original code based on Host AP (software wireless LAN access point) driver
3 * for Intersil Prism2/2.5/3.
4 *
5 * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
6 * <jkmaline@cc.hut.fi>
7 * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
8 *
9 * Adaption to a generic IEEE 802.11 stack by James Ketrenos
10 * <jketreno@linux.intel.com>
11 *
12 * Copyright (c) 2004, Intel Corporation
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation. See README and COPYING for
17 * more details.
18 */
19
20/*
21 * This file defines the interface to the ieee80211 crypto module.
22 */
23#ifndef IEEE80211_CRYPT_H
24#define IEEE80211_CRYPT_H
25
26#include <linux/skbuff.h>
27
28struct ieee80211_crypto_ops {
29 const char *name;
30
31 /* init new crypto context (e.g., allocate private data space,
32 * select IV, etc.); returns NULL on failure or pointer to allocated
33 * private data on success */
34 void * (*init)(int keyidx);
35
36 /* deinitialize crypto context and free allocated private data */
37 void (*deinit)(void *priv);
38
39 /* encrypt/decrypt return < 0 on error or >= 0 on success. The return
40 * value from decrypt_mpdu is passed as the keyidx value for
41 * decrypt_msdu. skb must have enough head and tail room for the
42 * encryption; if not, error will be returned; these functions are
43 * called for all MPDUs (i.e., fragments).
44 */
45 int (*encrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
46 int (*decrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
47
48 /* These functions are called for full MSDUs, i.e. full frames.
49 * These can be NULL if full MSDU operations are not needed. */
50 int (*encrypt_msdu)(struct sk_buff *skb, int hdr_len, void *priv);
51 int (*decrypt_msdu)(struct sk_buff *skb, int keyidx, int hdr_len,
52 void *priv);
53
54 int (*set_key)(void *key, int len, u8 *seq, void *priv);
55 int (*get_key)(void *key, int len, u8 *seq, void *priv);
56
57 /* procfs handler for printing out key information and possible
58 * statistics */
59 char * (*print_stats)(char *p, void *priv);
60
61 /* maximum number of bytes added by encryption; encrypt buf is
62 * allocated with extra_prefix_len bytes, copy of in_buf, and
63 * extra_postfix_len; encrypt need not use all this space, but
64 * the result must start at the beginning of the buffer and correct
65 * length must be returned */
66 int extra_prefix_len, extra_postfix_len;
67
68 struct module *owner;
69};
70
71struct ieee80211_crypt_data {
72 struct list_head list; /* delayed deletion list */
73 struct ieee80211_crypto_ops *ops;
74 void *priv;
75 atomic_t refcnt;
76};
77
78int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops);
79int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops);
80struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name);
81void ieee80211_crypt_deinit_entries(struct ieee80211_device *, int);
82void ieee80211_crypt_deinit_handler(unsigned long);
83void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
84 struct ieee80211_crypt_data **crypt);
85
86#endif
diff --git a/net/Kconfig b/net/Kconfig
index 9251b28e8d5d..8a12ea8f0c05 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -640,6 +640,8 @@ source "net/irda/Kconfig"
640 640
641source "net/bluetooth/Kconfig" 641source "net/bluetooth/Kconfig"
642 642
643source "net/ieee80211/Kconfig"
644
643source "drivers/net/Kconfig" 645source "drivers/net/Kconfig"
644 646
645endmenu 647endmenu
diff --git a/net/Makefile b/net/Makefile
index 8e2bdc025ab8..83bc52d87bae 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -42,6 +42,7 @@ obj-$(CONFIG_DECNET) += decnet/
42obj-$(CONFIG_ECONET) += econet/ 42obj-$(CONFIG_ECONET) += econet/
43obj-$(CONFIG_VLAN_8021Q) += 8021q/ 43obj-$(CONFIG_VLAN_8021Q) += 8021q/
44obj-$(CONFIG_IP_SCTP) += sctp/ 44obj-$(CONFIG_IP_SCTP) += sctp/
45obj-$(CONFIG_IEEE80211) += ieee80211/
45 46
46ifeq ($(CONFIG_NET),y) 47ifeq ($(CONFIG_NET),y)
47obj-$(CONFIG_SYSCTL) += sysctl_net.o 48obj-$(CONFIG_SYSCTL) += sysctl_net.o
diff --git a/net/ieee80211/Kconfig b/net/ieee80211/Kconfig
new file mode 100644
index 000000000000..23b23f72a9a4
--- /dev/null
+++ b/net/ieee80211/Kconfig
@@ -0,0 +1,67 @@
1config IEEE80211
2 tristate "Generic IEEE 802.11 Networking Stack"
3 select NET_RADIO
4 ---help---
5 This option enables the hardware independent IEEE 802.11
6 networking stack.
7
8config IEEE80211_DEBUG
9 bool "Enable full debugging output"
10 depends on IEEE80211
11 ---help---
12 This option will enable debug tracing output for the
13 ieee80211 network stack.
14
15 This will result in the kernel module being ~70k larger. You
16 can control which debug output is sent to the kernel log by
17 setting the value in
18
19 /proc/net/ieee80211/debug_level
20
21 For example:
22
23 % echo 0x00000FFO > /proc/net/ieee80211/debug_level
24
25 For a list of values you can assign to debug_level, you
26 can look at the bit mask values in <net/ieee80211.h>
27
28 If you are not trying to debug or develop the ieee80211
29 subsystem, you most likely want to say N here.
30
31config IEEE80211_CRYPT_WEP
32 tristate "IEEE 802.11 WEP encryption (802.1x)"
33 depends on IEEE80211
34 select CRYPTO
35 select CRYPTO_ARC4
36 select CRC32
37 ---help---
38 Include software based cipher suites in support of IEEE
39 802.11's WEP. This is needed for WEP as well as 802.1x.
40
41 This can be compiled as a modules and it will be called
42 "ieee80211_crypt_wep".
43
44config IEEE80211_CRYPT_CCMP
45 tristate "IEEE 802.11i CCMP support"
46 depends on IEEE80211
47 select CRYPTO_AES
48 ---help---
49 Include software based cipher suites in support of IEEE 802.11i
50 (aka TGi, WPA, WPA2, WPA-PSK, etc.) for use with CCMP enabled
51 networks.
52
53 This can be compiled as a modules and it will be called
54 "ieee80211_crypt_ccmp".
55
56config IEEE80211_CRYPT_TKIP
57 tristate "IEEE 802.11i TKIP encryption"
58 depends on IEEE80211
59 select CRYPTO_MICHAEL_MIC
60 ---help---
61 Include software based cipher suites in support of IEEE 802.11i
62 (aka TGi, WPA, WPA2, WPA-PSK, etc.) for use with TKIP enabled
63 networks.
64
65 This can be compiled as a modules and it will be called
66 "ieee80211_crypt_tkip".
67
diff --git a/net/ieee80211/Makefile b/net/ieee80211/Makefile
new file mode 100644
index 000000000000..29be9cae1def
--- /dev/null
+++ b/net/ieee80211/Makefile
@@ -0,0 +1,11 @@
1obj-$(CONFIG_IEEE80211) += ieee80211.o
2obj-$(CONFIG_IEEE80211) += ieee80211_crypt.o
3obj-$(CONFIG_IEEE80211_CRYPT_WEP) += ieee80211_crypt_wep.o
4obj-$(CONFIG_IEEE80211_CRYPT_CCMP) += ieee80211_crypt_ccmp.o
5obj-$(CONFIG_IEEE80211_CRYPT_TKIP) += ieee80211_crypt_tkip.o
6ieee80211-objs := \
7 ieee80211_module.o \
8 ieee80211_tx.o \
9 ieee80211_rx.o \
10 ieee80211_wx.o
11
diff --git a/net/ieee80211/ieee80211_crypt.c b/net/ieee80211/ieee80211_crypt.c
new file mode 100644
index 000000000000..05a6f2f298db
--- /dev/null
+++ b/net/ieee80211/ieee80211_crypt.c
@@ -0,0 +1,259 @@
1/*
2 * Host AP crypto routines
3 *
4 * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
5 * Portions Copyright (C) 2004, Intel Corporation <jketreno@linux.intel.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation. See README and COPYING for
10 * more details.
11 *
12 */
13
14#include <linux/config.h>
15#include <linux/version.h>
16#include <linux/module.h>
17#include <linux/init.h>
18#include <linux/slab.h>
19#include <asm/string.h>
20#include <asm/errno.h>
21
22#include <net/ieee80211.h>
23
24MODULE_AUTHOR("Jouni Malinen");
25MODULE_DESCRIPTION("HostAP crypto");
26MODULE_LICENSE("GPL");
27
28struct ieee80211_crypto_alg {
29 struct list_head list;
30 struct ieee80211_crypto_ops *ops;
31};
32
33
34struct ieee80211_crypto {
35 struct list_head algs;
36 spinlock_t lock;
37};
38
39static struct ieee80211_crypto *hcrypt;
40
41void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee,
42 int force)
43{
44 struct list_head *ptr, *n;
45 struct ieee80211_crypt_data *entry;
46
47 for (ptr = ieee->crypt_deinit_list.next, n = ptr->next;
48 ptr != &ieee->crypt_deinit_list; ptr = n, n = ptr->next) {
49 entry = list_entry(ptr, struct ieee80211_crypt_data, list);
50
51 if (atomic_read(&entry->refcnt) != 0 && !force)
52 continue;
53
54 list_del(ptr);
55
56 if (entry->ops) {
57 entry->ops->deinit(entry->priv);
58 module_put(entry->ops->owner);
59 }
60 kfree(entry);
61 }
62}
63
64void ieee80211_crypt_deinit_handler(unsigned long data)
65{
66 struct ieee80211_device *ieee = (struct ieee80211_device *)data;
67 unsigned long flags;
68
69 spin_lock_irqsave(&ieee->lock, flags);
70 ieee80211_crypt_deinit_entries(ieee, 0);
71 if (!list_empty(&ieee->crypt_deinit_list)) {
72 printk(KERN_DEBUG "%s: entries remaining in delayed crypt "
73 "deletion list\n", ieee->dev->name);
74 ieee->crypt_deinit_timer.expires = jiffies + HZ;
75 add_timer(&ieee->crypt_deinit_timer);
76 }
77 spin_unlock_irqrestore(&ieee->lock, flags);
78
79}
80
81void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
82 struct ieee80211_crypt_data **crypt)
83{
84 struct ieee80211_crypt_data *tmp;
85 unsigned long flags;
86
87 if (*crypt == NULL)
88 return;
89
90 tmp = *crypt;
91 *crypt = NULL;
92
93 /* must not run ops->deinit() while there may be pending encrypt or
94 * decrypt operations. Use a list of delayed deinits to avoid needing
95 * locking. */
96
97 spin_lock_irqsave(&ieee->lock, flags);
98 list_add(&tmp->list, &ieee->crypt_deinit_list);
99 if (!timer_pending(&ieee->crypt_deinit_timer)) {
100 ieee->crypt_deinit_timer.expires = jiffies + HZ;
101 add_timer(&ieee->crypt_deinit_timer);
102 }
103 spin_unlock_irqrestore(&ieee->lock, flags);
104}
105
106int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops)
107{
108 unsigned long flags;
109 struct ieee80211_crypto_alg *alg;
110
111 if (hcrypt == NULL)
112 return -1;
113
114 alg = kmalloc(sizeof(*alg), GFP_KERNEL);
115 if (alg == NULL)
116 return -ENOMEM;
117
118 memset(alg, 0, sizeof(*alg));
119 alg->ops = ops;
120
121 spin_lock_irqsave(&hcrypt->lock, flags);
122 list_add(&alg->list, &hcrypt->algs);
123 spin_unlock_irqrestore(&hcrypt->lock, flags);
124
125 printk(KERN_DEBUG "ieee80211_crypt: registered algorithm '%s'\n",
126 ops->name);
127
128 return 0;
129}
130
131int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops)
132{
133 unsigned long flags;
134 struct list_head *ptr;
135 struct ieee80211_crypto_alg *del_alg = NULL;
136
137 if (hcrypt == NULL)
138 return -1;
139
140 spin_lock_irqsave(&hcrypt->lock, flags);
141 for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
142 struct ieee80211_crypto_alg *alg =
143 (struct ieee80211_crypto_alg *) ptr;
144 if (alg->ops == ops) {
145 list_del(&alg->list);
146 del_alg = alg;
147 break;
148 }
149 }
150 spin_unlock_irqrestore(&hcrypt->lock, flags);
151
152 if (del_alg) {
153 printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
154 "'%s'\n", ops->name);
155 kfree(del_alg);
156 }
157
158 return del_alg ? 0 : -1;
159}
160
161
162struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name)
163{
164 unsigned long flags;
165 struct list_head *ptr;
166 struct ieee80211_crypto_alg *found_alg = NULL;
167
168 if (hcrypt == NULL)
169 return NULL;
170
171 spin_lock_irqsave(&hcrypt->lock, flags);
172 for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
173 struct ieee80211_crypto_alg *alg =
174 (struct ieee80211_crypto_alg *) ptr;
175 if (strcmp(alg->ops->name, name) == 0) {
176 found_alg = alg;
177 break;
178 }
179 }
180 spin_unlock_irqrestore(&hcrypt->lock, flags);
181
182 if (found_alg)
183 return found_alg->ops;
184 else
185 return NULL;
186}
187
188
189static void * ieee80211_crypt_null_init(int keyidx) { return (void *) 1; }
190static void ieee80211_crypt_null_deinit(void *priv) {}
191
192static struct ieee80211_crypto_ops ieee80211_crypt_null = {
193 .name = "NULL",
194 .init = ieee80211_crypt_null_init,
195 .deinit = ieee80211_crypt_null_deinit,
196 .encrypt_mpdu = NULL,
197 .decrypt_mpdu = NULL,
198 .encrypt_msdu = NULL,
199 .decrypt_msdu = NULL,
200 .set_key = NULL,
201 .get_key = NULL,
202 .extra_prefix_len = 0,
203 .extra_postfix_len = 0,
204 .owner = THIS_MODULE,
205};
206
207
208static int __init ieee80211_crypto_init(void)
209{
210 int ret = -ENOMEM;
211
212 hcrypt = kmalloc(sizeof(*hcrypt), GFP_KERNEL);
213 if (!hcrypt)
214 goto out;
215
216 memset(hcrypt, 0, sizeof(*hcrypt));
217 INIT_LIST_HEAD(&hcrypt->algs);
218 spin_lock_init(&hcrypt->lock);
219
220 ret = ieee80211_register_crypto_ops(&ieee80211_crypt_null);
221 if (ret < 0) {
222 kfree(hcrypt);
223 hcrypt = NULL;
224 }
225out:
226 return ret;
227}
228
229
230static void __exit ieee80211_crypto_deinit(void)
231{
232 struct list_head *ptr, *n;
233
234 if (hcrypt == NULL)
235 return;
236
237 for (ptr = hcrypt->algs.next, n = ptr->next; ptr != &hcrypt->algs;
238 ptr = n, n = ptr->next) {
239 struct ieee80211_crypto_alg *alg =
240 (struct ieee80211_crypto_alg *) ptr;
241 list_del(ptr);
242 printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
243 "'%s' (deinit)\n", alg->ops->name);
244 kfree(alg);
245 }
246
247 kfree(hcrypt);
248}
249
250EXPORT_SYMBOL(ieee80211_crypt_deinit_entries);
251EXPORT_SYMBOL(ieee80211_crypt_deinit_handler);
252EXPORT_SYMBOL(ieee80211_crypt_delayed_deinit);
253
254EXPORT_SYMBOL(ieee80211_register_crypto_ops);
255EXPORT_SYMBOL(ieee80211_unregister_crypto_ops);
256EXPORT_SYMBOL(ieee80211_get_crypto_ops);
257
258module_init(ieee80211_crypto_init);
259module_exit(ieee80211_crypto_deinit);
diff --git a/net/ieee80211/ieee80211_crypt_ccmp.c b/net/ieee80211/ieee80211_crypt_ccmp.c
new file mode 100644
index 000000000000..f5f412ae7f28
--- /dev/null
+++ b/net/ieee80211/ieee80211_crypt_ccmp.c
@@ -0,0 +1,470 @@
1/*
2 * Host AP crypt: host-based CCMP encryption implementation for Host AP driver
3 *
4 * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation. See README and COPYING for
9 * more details.
10 */
11
12#include <linux/config.h>
13#include <linux/version.h>
14#include <linux/module.h>
15#include <linux/init.h>
16#include <linux/slab.h>
17#include <linux/random.h>
18#include <linux/skbuff.h>
19#include <linux/netdevice.h>
20#include <linux/if_ether.h>
21#include <linux/if_arp.h>
22#include <asm/string.h>
23#include <linux/wireless.h>
24
25#include <net/ieee80211.h>
26
27
28#include <linux/crypto.h>
29#include <asm/scatterlist.h>
30
31MODULE_AUTHOR("Jouni Malinen");
32MODULE_DESCRIPTION("Host AP crypt: CCMP");
33MODULE_LICENSE("GPL");
34
35#define AES_BLOCK_LEN 16
36#define CCMP_HDR_LEN 8
37#define CCMP_MIC_LEN 8
38#define CCMP_TK_LEN 16
39#define CCMP_PN_LEN 6
40
41struct ieee80211_ccmp_data {
42 u8 key[CCMP_TK_LEN];
43 int key_set;
44
45 u8 tx_pn[CCMP_PN_LEN];
46 u8 rx_pn[CCMP_PN_LEN];
47
48 u32 dot11RSNAStatsCCMPFormatErrors;
49 u32 dot11RSNAStatsCCMPReplays;
50 u32 dot11RSNAStatsCCMPDecryptErrors;
51
52 int key_idx;
53
54 struct crypto_tfm *tfm;
55
56 /* scratch buffers for virt_to_page() (crypto API) */
57 u8 tx_b0[AES_BLOCK_LEN], tx_b[AES_BLOCK_LEN],
58 tx_e[AES_BLOCK_LEN], tx_s0[AES_BLOCK_LEN];
59 u8 rx_b0[AES_BLOCK_LEN], rx_b[AES_BLOCK_LEN], rx_a[AES_BLOCK_LEN];
60};
61
62void ieee80211_ccmp_aes_encrypt(struct crypto_tfm *tfm,
63 const u8 pt[16], u8 ct[16])
64{
65 struct scatterlist src, dst;
66
67 src.page = virt_to_page(pt);
68 src.offset = offset_in_page(pt);
69 src.length = AES_BLOCK_LEN;
70
71 dst.page = virt_to_page(ct);
72 dst.offset = offset_in_page(ct);
73 dst.length = AES_BLOCK_LEN;
74
75 crypto_cipher_encrypt(tfm, &dst, &src, AES_BLOCK_LEN);
76}
77
78static void * ieee80211_ccmp_init(int key_idx)
79{
80 struct ieee80211_ccmp_data *priv;
81
82 priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
83 if (priv == NULL)
84 goto fail;
85 memset(priv, 0, sizeof(*priv));
86 priv->key_idx = key_idx;
87
88 priv->tfm = crypto_alloc_tfm("aes", 0);
89 if (priv->tfm == NULL) {
90 printk(KERN_DEBUG "ieee80211_crypt_ccmp: could not allocate "
91 "crypto API aes\n");
92 goto fail;
93 }
94
95 return priv;
96
97fail:
98 if (priv) {
99 if (priv->tfm)
100 crypto_free_tfm(priv->tfm);
101 kfree(priv);
102 }
103
104 return NULL;
105}
106
107
108static void ieee80211_ccmp_deinit(void *priv)
109{
110 struct ieee80211_ccmp_data *_priv = priv;
111 if (_priv && _priv->tfm)
112 crypto_free_tfm(_priv->tfm);
113 kfree(priv);
114}
115
116
117static inline void xor_block(u8 *b, u8 *a, size_t len)
118{
119 int i;
120 for (i = 0; i < len; i++)
121 b[i] ^= a[i];
122}
123
124
125static void ccmp_init_blocks(struct crypto_tfm *tfm,
126 struct ieee80211_hdr *hdr,
127 u8 *pn, size_t dlen, u8 *b0, u8 *auth,
128 u8 *s0)
129{
130 u8 *pos, qc = 0;
131 size_t aad_len;
132 u16 fc;
133 int a4_included, qc_included;
134 u8 aad[2 * AES_BLOCK_LEN];
135
136 fc = le16_to_cpu(hdr->frame_ctl);
137 a4_included = ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
138 (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS));
139 qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) &&
140 (WLAN_FC_GET_STYPE(fc) & 0x08));
141 aad_len = 22;
142 if (a4_included)
143 aad_len += 6;
144 if (qc_included) {
145 pos = (u8 *) &hdr->addr4;
146 if (a4_included)
147 pos += 6;
148 qc = *pos & 0x0f;
149 aad_len += 2;
150 }
151
152 /* CCM Initial Block:
153 * Flag (Include authentication header, M=3 (8-octet MIC),
154 * L=1 (2-octet Dlen))
155 * Nonce: 0x00 | A2 | PN
156 * Dlen */
157 b0[0] = 0x59;
158 b0[1] = qc;
159 memcpy(b0 + 2, hdr->addr2, ETH_ALEN);
160 memcpy(b0 + 8, pn, CCMP_PN_LEN);
161 b0[14] = (dlen >> 8) & 0xff;
162 b0[15] = dlen & 0xff;
163
164 /* AAD:
165 * FC with bits 4..6 and 11..13 masked to zero; 14 is always one
166 * A1 | A2 | A3
167 * SC with bits 4..15 (seq#) masked to zero
168 * A4 (if present)
169 * QC (if present)
170 */
171 pos = (u8 *) hdr;
172 aad[0] = 0; /* aad_len >> 8 */
173 aad[1] = aad_len & 0xff;
174 aad[2] = pos[0] & 0x8f;
175 aad[3] = pos[1] & 0xc7;
176 memcpy(aad + 4, hdr->addr1, 3 * ETH_ALEN);
177 pos = (u8 *) &hdr->seq_ctl;
178 aad[22] = pos[0] & 0x0f;
179 aad[23] = 0; /* all bits masked */
180 memset(aad + 24, 0, 8);
181 if (a4_included)
182 memcpy(aad + 24, hdr->addr4, ETH_ALEN);
183 if (qc_included) {
184 aad[a4_included ? 30 : 24] = qc;
185 /* rest of QC masked */
186 }
187
188 /* Start with the first block and AAD */
189 ieee80211_ccmp_aes_encrypt(tfm, b0, auth);
190 xor_block(auth, aad, AES_BLOCK_LEN);
191 ieee80211_ccmp_aes_encrypt(tfm, auth, auth);
192 xor_block(auth, &aad[AES_BLOCK_LEN], AES_BLOCK_LEN);
193 ieee80211_ccmp_aes_encrypt(tfm, auth, auth);
194 b0[0] &= 0x07;
195 b0[14] = b0[15] = 0;
196 ieee80211_ccmp_aes_encrypt(tfm, b0, s0);
197}
198
199
200static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
201{
202 struct ieee80211_ccmp_data *key = priv;
203 int data_len, i, blocks, last, len;
204 u8 *pos, *mic;
205 struct ieee80211_hdr *hdr;
206 u8 *b0 = key->tx_b0;
207 u8 *b = key->tx_b;
208 u8 *e = key->tx_e;
209 u8 *s0 = key->tx_s0;
210
211 if (skb_headroom(skb) < CCMP_HDR_LEN ||
212 skb_tailroom(skb) < CCMP_MIC_LEN ||
213 skb->len < hdr_len)
214 return -1;
215
216 data_len = skb->len - hdr_len;
217 pos = skb_push(skb, CCMP_HDR_LEN);
218 memmove(pos, pos + CCMP_HDR_LEN, hdr_len);
219 pos += hdr_len;
220 mic = skb_put(skb, CCMP_MIC_LEN);
221
222 i = CCMP_PN_LEN - 1;
223 while (i >= 0) {
224 key->tx_pn[i]++;
225 if (key->tx_pn[i] != 0)
226 break;
227 i--;
228 }
229
230 *pos++ = key->tx_pn[5];
231 *pos++ = key->tx_pn[4];
232 *pos++ = 0;
233 *pos++ = (key->key_idx << 6) | (1 << 5) /* Ext IV included */;
234 *pos++ = key->tx_pn[3];
235 *pos++ = key->tx_pn[2];
236 *pos++ = key->tx_pn[1];
237 *pos++ = key->tx_pn[0];
238
239 hdr = (struct ieee80211_hdr *) skb->data;
240 ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0);
241
242 blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
243 last = data_len % AES_BLOCK_LEN;
244
245 for (i = 1; i <= blocks; i++) {
246 len = (i == blocks && last) ? last : AES_BLOCK_LEN;
247 /* Authentication */
248 xor_block(b, pos, len);
249 ieee80211_ccmp_aes_encrypt(key->tfm, b, b);
250 /* Encryption, with counter */
251 b0[14] = (i >> 8) & 0xff;
252 b0[15] = i & 0xff;
253 ieee80211_ccmp_aes_encrypt(key->tfm, b0, e);
254 xor_block(pos, e, len);
255 pos += len;
256 }
257
258 for (i = 0; i < CCMP_MIC_LEN; i++)
259 mic[i] = b[i] ^ s0[i];
260
261 return 0;
262}
263
264
265static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
266{
267 struct ieee80211_ccmp_data *key = priv;
268 u8 keyidx, *pos;
269 struct ieee80211_hdr *hdr;
270 u8 *b0 = key->rx_b0;
271 u8 *b = key->rx_b;
272 u8 *a = key->rx_a;
273 u8 pn[6];
274 int i, blocks, last, len;
275 size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN - CCMP_MIC_LEN;
276 u8 *mic = skb->data + skb->len - CCMP_MIC_LEN;
277
278 if (skb->len < hdr_len + CCMP_HDR_LEN + CCMP_MIC_LEN) {
279 key->dot11RSNAStatsCCMPFormatErrors++;
280 return -1;
281 }
282
283 hdr = (struct ieee80211_hdr *) skb->data;
284 pos = skb->data + hdr_len;
285 keyidx = pos[3];
286 if (!(keyidx & (1 << 5))) {
287 if (net_ratelimit()) {
288 printk(KERN_DEBUG "CCMP: received packet without ExtIV"
289 " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2));
290 }
291 key->dot11RSNAStatsCCMPFormatErrors++;
292 return -2;
293 }
294 keyidx >>= 6;
295 if (key->key_idx != keyidx) {
296 printk(KERN_DEBUG "CCMP: RX tkey->key_idx=%d frame "
297 "keyidx=%d priv=%p\n", key->key_idx, keyidx, priv);
298 return -6;
299 }
300 if (!key->key_set) {
301 if (net_ratelimit()) {
302 printk(KERN_DEBUG "CCMP: received packet from " MAC_FMT
303 " with keyid=%d that does not have a configured"
304 " key\n", MAC_ARG(hdr->addr2), keyidx);
305 }
306 return -3;
307 }
308
309 pn[0] = pos[7];
310 pn[1] = pos[6];
311 pn[2] = pos[5];
312 pn[3] = pos[4];
313 pn[4] = pos[1];
314 pn[5] = pos[0];
315 pos += 8;
316
317 if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) {
318 if (net_ratelimit()) {
319 printk(KERN_DEBUG "CCMP: replay detected: STA=" MAC_FMT
320 " previous PN %02x%02x%02x%02x%02x%02x "
321 "received PN %02x%02x%02x%02x%02x%02x\n",
322 MAC_ARG(hdr->addr2), MAC_ARG(key->rx_pn),
323 MAC_ARG(pn));
324 }
325 key->dot11RSNAStatsCCMPReplays++;
326 return -4;
327 }
328
329 ccmp_init_blocks(key->tfm, hdr, pn, data_len, b0, a, b);
330 xor_block(mic, b, CCMP_MIC_LEN);
331
332 blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
333 last = data_len % AES_BLOCK_LEN;
334
335 for (i = 1; i <= blocks; i++) {
336 len = (i == blocks && last) ? last : AES_BLOCK_LEN;
337 /* Decrypt, with counter */
338 b0[14] = (i >> 8) & 0xff;
339 b0[15] = i & 0xff;
340 ieee80211_ccmp_aes_encrypt(key->tfm, b0, b);
341 xor_block(pos, b, len);
342 /* Authentication */
343 xor_block(a, pos, len);
344 ieee80211_ccmp_aes_encrypt(key->tfm, a, a);
345 pos += len;
346 }
347
348 if (memcmp(mic, a, CCMP_MIC_LEN) != 0) {
349 if (net_ratelimit()) {
350 printk(KERN_DEBUG "CCMP: decrypt failed: STA="
351 MAC_FMT "\n", MAC_ARG(hdr->addr2));
352 }
353 key->dot11RSNAStatsCCMPDecryptErrors++;
354 return -5;
355 }
356
357 memcpy(key->rx_pn, pn, CCMP_PN_LEN);
358
359 /* Remove hdr and MIC */
360 memmove(skb->data + CCMP_HDR_LEN, skb->data, hdr_len);
361 skb_pull(skb, CCMP_HDR_LEN);
362 skb_trim(skb, skb->len - CCMP_MIC_LEN);
363
364 return keyidx;
365}
366
367
368static int ieee80211_ccmp_set_key(void *key, int len, u8 *seq, void *priv)
369{
370 struct ieee80211_ccmp_data *data = priv;
371 int keyidx;
372 struct crypto_tfm *tfm = data->tfm;
373
374 keyidx = data->key_idx;
375 memset(data, 0, sizeof(*data));
376 data->key_idx = keyidx;
377 data->tfm = tfm;
378 if (len == CCMP_TK_LEN) {
379 memcpy(data->key, key, CCMP_TK_LEN);
380 data->key_set = 1;
381 if (seq) {
382 data->rx_pn[0] = seq[5];
383 data->rx_pn[1] = seq[4];
384 data->rx_pn[2] = seq[3];
385 data->rx_pn[3] = seq[2];
386 data->rx_pn[4] = seq[1];
387 data->rx_pn[5] = seq[0];
388 }
389 crypto_cipher_setkey(data->tfm, data->key, CCMP_TK_LEN);
390 } else if (len == 0)
391 data->key_set = 0;
392 else
393 return -1;
394
395 return 0;
396}
397
398
399static int ieee80211_ccmp_get_key(void *key, int len, u8 *seq, void *priv)
400{
401 struct ieee80211_ccmp_data *data = priv;
402
403 if (len < CCMP_TK_LEN)
404 return -1;
405
406 if (!data->key_set)
407 return 0;
408 memcpy(key, data->key, CCMP_TK_LEN);
409
410 if (seq) {
411 seq[0] = data->tx_pn[5];
412 seq[1] = data->tx_pn[4];
413 seq[2] = data->tx_pn[3];
414 seq[3] = data->tx_pn[2];
415 seq[4] = data->tx_pn[1];
416 seq[5] = data->tx_pn[0];
417 }
418
419 return CCMP_TK_LEN;
420}
421
422
423static char * ieee80211_ccmp_print_stats(char *p, void *priv)
424{
425 struct ieee80211_ccmp_data *ccmp = priv;
426 p += sprintf(p, "key[%d] alg=CCMP key_set=%d "
427 "tx_pn=%02x%02x%02x%02x%02x%02x "
428 "rx_pn=%02x%02x%02x%02x%02x%02x "
429 "format_errors=%d replays=%d decrypt_errors=%d\n",
430 ccmp->key_idx, ccmp->key_set,
431 MAC_ARG(ccmp->tx_pn), MAC_ARG(ccmp->rx_pn),
432 ccmp->dot11RSNAStatsCCMPFormatErrors,
433 ccmp->dot11RSNAStatsCCMPReplays,
434 ccmp->dot11RSNAStatsCCMPDecryptErrors);
435
436 return p;
437}
438
439
440static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = {
441 .name = "CCMP",
442 .init = ieee80211_ccmp_init,
443 .deinit = ieee80211_ccmp_deinit,
444 .encrypt_mpdu = ieee80211_ccmp_encrypt,
445 .decrypt_mpdu = ieee80211_ccmp_decrypt,
446 .encrypt_msdu = NULL,
447 .decrypt_msdu = NULL,
448 .set_key = ieee80211_ccmp_set_key,
449 .get_key = ieee80211_ccmp_get_key,
450 .print_stats = ieee80211_ccmp_print_stats,
451 .extra_prefix_len = CCMP_HDR_LEN,
452 .extra_postfix_len = CCMP_MIC_LEN,
453 .owner = THIS_MODULE,
454};
455
456
457static int __init ieee80211_crypto_ccmp_init(void)
458{
459 return ieee80211_register_crypto_ops(&ieee80211_crypt_ccmp);
460}
461
462
463static void __exit ieee80211_crypto_ccmp_exit(void)
464{
465 ieee80211_unregister_crypto_ops(&ieee80211_crypt_ccmp);
466}
467
468
469module_init(ieee80211_crypto_ccmp_init);
470module_exit(ieee80211_crypto_ccmp_exit);
diff --git a/net/ieee80211/ieee80211_crypt_tkip.c b/net/ieee80211/ieee80211_crypt_tkip.c
new file mode 100644
index 000000000000..f91d92c6df25
--- /dev/null
+++ b/net/ieee80211/ieee80211_crypt_tkip.c
@@ -0,0 +1,708 @@
1/*
2 * Host AP crypt: host-based TKIP encryption implementation for Host AP driver
3 *
4 * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation. See README and COPYING for
9 * more details.
10 */
11
12#include <linux/config.h>
13#include <linux/version.h>
14#include <linux/module.h>
15#include <linux/init.h>
16#include <linux/slab.h>
17#include <linux/random.h>
18#include <linux/skbuff.h>
19#include <linux/netdevice.h>
20#include <linux/if_ether.h>
21#include <linux/if_arp.h>
22#include <asm/string.h>
23
24#include <net/ieee80211.h>
25
26
27#include <linux/crypto.h>
28#include <asm/scatterlist.h>
29#include <linux/crc32.h>
30
31MODULE_AUTHOR("Jouni Malinen");
32MODULE_DESCRIPTION("Host AP crypt: TKIP");
33MODULE_LICENSE("GPL");
34
35struct ieee80211_tkip_data {
36#define TKIP_KEY_LEN 32
37 u8 key[TKIP_KEY_LEN];
38 int key_set;
39
40 u32 tx_iv32;
41 u16 tx_iv16;
42 u16 tx_ttak[5];
43 int tx_phase1_done;
44
45 u32 rx_iv32;
46 u16 rx_iv16;
47 u16 rx_ttak[5];
48 int rx_phase1_done;
49 u32 rx_iv32_new;
50 u16 rx_iv16_new;
51
52 u32 dot11RSNAStatsTKIPReplays;
53 u32 dot11RSNAStatsTKIPICVErrors;
54 u32 dot11RSNAStatsTKIPLocalMICFailures;
55
56 int key_idx;
57
58 struct crypto_tfm *tfm_arc4;
59 struct crypto_tfm *tfm_michael;
60
61 /* scratch buffers for virt_to_page() (crypto API) */
62 u8 rx_hdr[16], tx_hdr[16];
63};
64
65static void * ieee80211_tkip_init(int key_idx)
66{
67 struct ieee80211_tkip_data *priv;
68
69 priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
70 if (priv == NULL)
71 goto fail;
72 memset(priv, 0, sizeof(*priv));
73 priv->key_idx = key_idx;
74
75 priv->tfm_arc4 = crypto_alloc_tfm("arc4", 0);
76 if (priv->tfm_arc4 == NULL) {
77 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
78 "crypto API arc4\n");
79 goto fail;
80 }
81
82 priv->tfm_michael = crypto_alloc_tfm("michael_mic", 0);
83 if (priv->tfm_michael == NULL) {
84 printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
85 "crypto API michael_mic\n");
86 goto fail;
87 }
88
89 return priv;
90
91fail:
92 if (priv) {
93 if (priv->tfm_michael)
94 crypto_free_tfm(priv->tfm_michael);
95 if (priv->tfm_arc4)
96 crypto_free_tfm(priv->tfm_arc4);
97 kfree(priv);
98 }
99
100 return NULL;
101}
102
103
104static void ieee80211_tkip_deinit(void *priv)
105{
106 struct ieee80211_tkip_data *_priv = priv;
107 if (_priv && _priv->tfm_michael)
108 crypto_free_tfm(_priv->tfm_michael);
109 if (_priv && _priv->tfm_arc4)
110 crypto_free_tfm(_priv->tfm_arc4);
111 kfree(priv);
112}
113
114
115static inline u16 RotR1(u16 val)
116{
117 return (val >> 1) | (val << 15);
118}
119
120
121static inline u8 Lo8(u16 val)
122{
123 return val & 0xff;
124}
125
126
127static inline u8 Hi8(u16 val)
128{
129 return val >> 8;
130}
131
132
133static inline u16 Lo16(u32 val)
134{
135 return val & 0xffff;
136}
137
138
139static inline u16 Hi16(u32 val)
140{
141 return val >> 16;
142}
143
144
145static inline u16 Mk16(u8 hi, u8 lo)
146{
147 return lo | (((u16) hi) << 8);
148}
149
150
151static inline u16 Mk16_le(u16 *v)
152{
153 return le16_to_cpu(*v);
154}
155
156
157static const u16 Sbox[256] =
158{
159 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
160 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
161 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
162 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
163 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
164 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
165 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
166 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
167 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
168 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
169 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
170 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
171 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
172 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
173 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
174 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
175 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
176 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
177 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
178 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
179 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
180 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
181 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
182 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
183 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
184 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
185 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
186 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
187 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
188 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
189 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
190 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
191};
192
193
194static inline u16 _S_(u16 v)
195{
196 u16 t = Sbox[Hi8(v)];
197 return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8));
198}
199
200
201#define PHASE1_LOOP_COUNT 8
202
203static void tkip_mixing_phase1(u16 *TTAK, const u8 *TK, const u8 *TA, u32 IV32)
204{
205 int i, j;
206
207 /* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */
208 TTAK[0] = Lo16(IV32);
209 TTAK[1] = Hi16(IV32);
210 TTAK[2] = Mk16(TA[1], TA[0]);
211 TTAK[3] = Mk16(TA[3], TA[2]);
212 TTAK[4] = Mk16(TA[5], TA[4]);
213
214 for (i = 0; i < PHASE1_LOOP_COUNT; i++) {
215 j = 2 * (i & 1);
216 TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j]));
217 TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j]));
218 TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j]));
219 TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j]));
220 TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i;
221 }
222}
223
224
225static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK,
226 u16 IV16)
227{
228 /* Make temporary area overlap WEP seed so that the final copy can be
229 * avoided on little endian hosts. */
230 u16 *PPK = (u16 *) &WEPSeed[4];
231
232 /* Step 1 - make copy of TTAK and bring in TSC */
233 PPK[0] = TTAK[0];
234 PPK[1] = TTAK[1];
235 PPK[2] = TTAK[2];
236 PPK[3] = TTAK[3];
237 PPK[4] = TTAK[4];
238 PPK[5] = TTAK[4] + IV16;
239
240 /* Step 2 - 96-bit bijective mixing using S-box */
241 PPK[0] += _S_(PPK[5] ^ Mk16_le((u16 *) &TK[0]));
242 PPK[1] += _S_(PPK[0] ^ Mk16_le((u16 *) &TK[2]));
243 PPK[2] += _S_(PPK[1] ^ Mk16_le((u16 *) &TK[4]));
244 PPK[3] += _S_(PPK[2] ^ Mk16_le((u16 *) &TK[6]));
245 PPK[4] += _S_(PPK[3] ^ Mk16_le((u16 *) &TK[8]));
246 PPK[5] += _S_(PPK[4] ^ Mk16_le((u16 *) &TK[10]));
247
248 PPK[0] += RotR1(PPK[5] ^ Mk16_le((u16 *) &TK[12]));
249 PPK[1] += RotR1(PPK[0] ^ Mk16_le((u16 *) &TK[14]));
250 PPK[2] += RotR1(PPK[1]);
251 PPK[3] += RotR1(PPK[2]);
252 PPK[4] += RotR1(PPK[3]);
253 PPK[5] += RotR1(PPK[4]);
254
255 /* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value
256 * WEPSeed[0..2] is transmitted as WEP IV */
257 WEPSeed[0] = Hi8(IV16);
258 WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F;
259 WEPSeed[2] = Lo8(IV16);
260 WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((u16 *) &TK[0])) >> 1);
261
262#ifdef __BIG_ENDIAN
263 {
264 int i;
265 for (i = 0; i < 6; i++)
266 PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8);
267 }
268#endif
269}
270
271static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
272{
273 struct ieee80211_tkip_data *tkey = priv;
274 int len;
275 u8 rc4key[16], *pos, *icv;
276 struct ieee80211_hdr *hdr;
277 u32 crc;
278 struct scatterlist sg;
279
280 if (skb_headroom(skb) < 8 || skb_tailroom(skb) < 4 ||
281 skb->len < hdr_len)
282 return -1;
283
284 hdr = (struct ieee80211_hdr *) skb->data;
285 if (!tkey->tx_phase1_done) {
286 tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2,
287 tkey->tx_iv32);
288 tkey->tx_phase1_done = 1;
289 }
290 tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16);
291
292 len = skb->len - hdr_len;
293 pos = skb_push(skb, 8);
294 memmove(pos, pos + 8, hdr_len);
295 pos += hdr_len;
296 icv = skb_put(skb, 4);
297
298 *pos++ = rc4key[0];
299 *pos++ = rc4key[1];
300 *pos++ = rc4key[2];
301 *pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */;
302 *pos++ = tkey->tx_iv32 & 0xff;
303 *pos++ = (tkey->tx_iv32 >> 8) & 0xff;
304 *pos++ = (tkey->tx_iv32 >> 16) & 0xff;
305 *pos++ = (tkey->tx_iv32 >> 24) & 0xff;
306
307 crc = ~crc32_le(~0, pos, len);
308 icv[0] = crc;
309 icv[1] = crc >> 8;
310 icv[2] = crc >> 16;
311 icv[3] = crc >> 24;
312
313 crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16);
314 sg.page = virt_to_page(pos);
315 sg.offset = offset_in_page(pos);
316 sg.length = len + 4;
317 crypto_cipher_encrypt(tkey->tfm_arc4, &sg, &sg, len + 4);
318
319 tkey->tx_iv16++;
320 if (tkey->tx_iv16 == 0) {
321 tkey->tx_phase1_done = 0;
322 tkey->tx_iv32++;
323 }
324
325 return 0;
326}
327
328static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
329{
330 struct ieee80211_tkip_data *tkey = priv;
331 u8 rc4key[16];
332 u8 keyidx, *pos;
333 u32 iv32;
334 u16 iv16;
335 struct ieee80211_hdr *hdr;
336 u8 icv[4];
337 u32 crc;
338 struct scatterlist sg;
339 int plen;
340
341 if (skb->len < hdr_len + 8 + 4)
342 return -1;
343
344 hdr = (struct ieee80211_hdr *) skb->data;
345 pos = skb->data + hdr_len;
346 keyidx = pos[3];
347 if (!(keyidx & (1 << 5))) {
348 if (net_ratelimit()) {
349 printk(KERN_DEBUG "TKIP: received packet without ExtIV"
350 " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2));
351 }
352 return -2;
353 }
354 keyidx >>= 6;
355 if (tkey->key_idx != keyidx) {
356 printk(KERN_DEBUG "TKIP: RX tkey->key_idx=%d frame "
357 "keyidx=%d priv=%p\n", tkey->key_idx, keyidx, priv);
358 return -6;
359 }
360 if (!tkey->key_set) {
361 if (net_ratelimit()) {
362 printk(KERN_DEBUG "TKIP: received packet from " MAC_FMT
363 " with keyid=%d that does not have a configured"
364 " key\n", MAC_ARG(hdr->addr2), keyidx);
365 }
366 return -3;
367 }
368 iv16 = (pos[0] << 8) | pos[2];
369 iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24);
370 pos += 8;
371
372 if (iv32 < tkey->rx_iv32 ||
373 (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) {
374 if (net_ratelimit()) {
375 printk(KERN_DEBUG "TKIP: replay detected: STA=" MAC_FMT
376 " previous TSC %08x%04x received TSC "
377 "%08x%04x\n", MAC_ARG(hdr->addr2),
378 tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
379 }
380 tkey->dot11RSNAStatsTKIPReplays++;
381 return -4;
382 }
383
384 if (iv32 != tkey->rx_iv32 || !tkey->rx_phase1_done) {
385 tkip_mixing_phase1(tkey->rx_ttak, tkey->key, hdr->addr2, iv32);
386 tkey->rx_phase1_done = 1;
387 }
388 tkip_mixing_phase2(rc4key, tkey->key, tkey->rx_ttak, iv16);
389
390 plen = skb->len - hdr_len - 12;
391
392 crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16);
393 sg.page = virt_to_page(pos);
394 sg.offset = offset_in_page(pos);
395 sg.length = plen + 4;
396 crypto_cipher_decrypt(tkey->tfm_arc4, &sg, &sg, plen + 4);
397
398 crc = ~crc32_le(~0, pos, plen);
399 icv[0] = crc;
400 icv[1] = crc >> 8;
401 icv[2] = crc >> 16;
402 icv[3] = crc >> 24;
403 if (memcmp(icv, pos + plen, 4) != 0) {
404 if (iv32 != tkey->rx_iv32) {
405 /* Previously cached Phase1 result was already lost, so
406 * it needs to be recalculated for the next packet. */
407 tkey->rx_phase1_done = 0;
408 }
409 if (net_ratelimit()) {
410 printk(KERN_DEBUG "TKIP: ICV error detected: STA="
411 MAC_FMT "\n", MAC_ARG(hdr->addr2));
412 }
413 tkey->dot11RSNAStatsTKIPICVErrors++;
414 return -5;
415 }
416
417 /* Update real counters only after Michael MIC verification has
418 * completed */
419 tkey->rx_iv32_new = iv32;
420 tkey->rx_iv16_new = iv16;
421
422 /* Remove IV and ICV */
423 memmove(skb->data + 8, skb->data, hdr_len);
424 skb_pull(skb, 8);
425 skb_trim(skb, skb->len - 4);
426
427 return keyidx;
428}
429
430
431static int michael_mic(struct ieee80211_tkip_data *tkey, u8 *key, u8 *hdr,
432 u8 *data, size_t data_len, u8 *mic)
433{
434 struct scatterlist sg[2];
435
436 if (tkey->tfm_michael == NULL) {
437 printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
438 return -1;
439 }
440 sg[0].page = virt_to_page(hdr);
441 sg[0].offset = offset_in_page(hdr);
442 sg[0].length = 16;
443
444 sg[1].page = virt_to_page(data);
445 sg[1].offset = offset_in_page(data);
446 sg[1].length = data_len;
447
448 crypto_digest_init(tkey->tfm_michael);
449 crypto_digest_setkey(tkey->tfm_michael, key, 8);
450 crypto_digest_update(tkey->tfm_michael, sg, 2);
451 crypto_digest_final(tkey->tfm_michael, mic);
452
453 return 0;
454}
455
456static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr)
457{
458 struct ieee80211_hdr *hdr11;
459
460 hdr11 = (struct ieee80211_hdr *) skb->data;
461 switch (le16_to_cpu(hdr11->frame_ctl) &
462 (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
463 case IEEE80211_FCTL_TODS:
464 memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
465 memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
466 break;
467 case IEEE80211_FCTL_FROMDS:
468 memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
469 memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */
470 break;
471 case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
472 memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
473 memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN); /* SA */
474 break;
475 case 0:
476 memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
477 memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
478 break;
479 }
480
481 hdr[12] = 0; /* priority */
482 hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
483}
484
485
486static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv)
487{
488 struct ieee80211_tkip_data *tkey = priv;
489 u8 *pos;
490
491 if (skb_tailroom(skb) < 8 || skb->len < hdr_len) {
492 printk(KERN_DEBUG "Invalid packet for Michael MIC add "
493 "(tailroom=%d hdr_len=%d skb->len=%d)\n",
494 skb_tailroom(skb), hdr_len, skb->len);
495 return -1;
496 }
497
498 michael_mic_hdr(skb, tkey->tx_hdr);
499 pos = skb_put(skb, 8);
500 if (michael_mic(tkey, &tkey->key[16], tkey->tx_hdr,
501 skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
502 return -1;
503
504 return 0;
505}
506
507
508#if WIRELESS_EXT >= 18
509static void ieee80211_michael_mic_failure(struct net_device *dev,
510 struct ieee80211_hdr *hdr,
511 int keyidx)
512{
513 union iwreq_data wrqu;
514 struct iw_michaelmicfailure ev;
515
516 /* TODO: needed parameters: count, keyid, key type, TSC */
517 memset(&ev, 0, sizeof(ev));
518 ev.flags = keyidx & IW_MICFAILURE_KEY_ID;
519 if (hdr->addr1[0] & 0x01)
520 ev.flags |= IW_MICFAILURE_GROUP;
521 else
522 ev.flags |= IW_MICFAILURE_PAIRWISE;
523 ev.src_addr.sa_family = ARPHRD_ETHER;
524 memcpy(ev.src_addr.sa_data, hdr->addr2, ETH_ALEN);
525 memset(&wrqu, 0, sizeof(wrqu));
526 wrqu.data.length = sizeof(ev);
527 wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *) &ev);
528}
529#elif WIRELESS_EXT >= 15
530static void ieee80211_michael_mic_failure(struct net_device *dev,
531 struct ieee80211_hdr *hdr,
532 int keyidx)
533{
534 union iwreq_data wrqu;
535 char buf[128];
536
537 /* TODO: needed parameters: count, keyid, key type, TSC */
538 sprintf(buf, "MLME-MICHAELMICFAILURE.indication(keyid=%d %scast addr="
539 MAC_FMT ")", keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni",
540 MAC_ARG(hdr->addr2));
541 memset(&wrqu, 0, sizeof(wrqu));
542 wrqu.data.length = strlen(buf);
543 wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
544}
545#else /* WIRELESS_EXT >= 15 */
546static inline void ieee80211_michael_mic_failure(struct net_device *dev,
547 struct ieee80211_hdr *hdr,
548 int keyidx)
549{
550}
551#endif /* WIRELESS_EXT >= 15 */
552
553
554static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
555 int hdr_len, void *priv)
556{
557 struct ieee80211_tkip_data *tkey = priv;
558 u8 mic[8];
559
560 if (!tkey->key_set)
561 return -1;
562
563 michael_mic_hdr(skb, tkey->rx_hdr);
564 if (michael_mic(tkey, &tkey->key[24], tkey->rx_hdr,
565 skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
566 return -1;
567 if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
568 struct ieee80211_hdr *hdr;
569 hdr = (struct ieee80211_hdr *) skb->data;
570 printk(KERN_DEBUG "%s: Michael MIC verification failed for "
571 "MSDU from " MAC_FMT " keyidx=%d\n",
572 skb->dev ? skb->dev->name : "N/A", MAC_ARG(hdr->addr2),
573 keyidx);
574 if (skb->dev)
575 ieee80211_michael_mic_failure(skb->dev, hdr, keyidx);
576 tkey->dot11RSNAStatsTKIPLocalMICFailures++;
577 return -1;
578 }
579
580 /* Update TSC counters for RX now that the packet verification has
581 * completed. */
582 tkey->rx_iv32 = tkey->rx_iv32_new;
583 tkey->rx_iv16 = tkey->rx_iv16_new;
584
585 skb_trim(skb, skb->len - 8);
586
587 return 0;
588}
589
590
591static int ieee80211_tkip_set_key(void *key, int len, u8 *seq, void *priv)
592{
593 struct ieee80211_tkip_data *tkey = priv;
594 int keyidx;
595 struct crypto_tfm *tfm = tkey->tfm_michael;
596 struct crypto_tfm *tfm2 = tkey->tfm_arc4;
597
598 keyidx = tkey->key_idx;
599 memset(tkey, 0, sizeof(*tkey));
600 tkey->key_idx = keyidx;
601 tkey->tfm_michael = tfm;
602 tkey->tfm_arc4 = tfm2;
603 if (len == TKIP_KEY_LEN) {
604 memcpy(tkey->key, key, TKIP_KEY_LEN);
605 tkey->key_set = 1;
606 tkey->tx_iv16 = 1; /* TSC is initialized to 1 */
607 if (seq) {
608 tkey->rx_iv32 = (seq[5] << 24) | (seq[4] << 16) |
609 (seq[3] << 8) | seq[2];
610 tkey->rx_iv16 = (seq[1] << 8) | seq[0];
611 }
612 } else if (len == 0)
613 tkey->key_set = 0;
614 else
615 return -1;
616
617 return 0;
618}
619
620
621static int ieee80211_tkip_get_key(void *key, int len, u8 *seq, void *priv)
622{
623 struct ieee80211_tkip_data *tkey = priv;
624
625 if (len < TKIP_KEY_LEN)
626 return -1;
627
628 if (!tkey->key_set)
629 return 0;
630 memcpy(key, tkey->key, TKIP_KEY_LEN);
631
632 if (seq) {
633 /* Return the sequence number of the last transmitted frame. */
634 u16 iv16 = tkey->tx_iv16;
635 u32 iv32 = tkey->tx_iv32;
636 if (iv16 == 0)
637 iv32--;
638 iv16--;
639 seq[0] = tkey->tx_iv16;
640 seq[1] = tkey->tx_iv16 >> 8;
641 seq[2] = tkey->tx_iv32;
642 seq[3] = tkey->tx_iv32 >> 8;
643 seq[4] = tkey->tx_iv32 >> 16;
644 seq[5] = tkey->tx_iv32 >> 24;
645 }
646
647 return TKIP_KEY_LEN;
648}
649
650
651static char * ieee80211_tkip_print_stats(char *p, void *priv)
652{
653 struct ieee80211_tkip_data *tkip = priv;
654 p += sprintf(p, "key[%d] alg=TKIP key_set=%d "
655 "tx_pn=%02x%02x%02x%02x%02x%02x "
656 "rx_pn=%02x%02x%02x%02x%02x%02x "
657 "replays=%d icv_errors=%d local_mic_failures=%d\n",
658 tkip->key_idx, tkip->key_set,
659 (tkip->tx_iv32 >> 24) & 0xff,
660 (tkip->tx_iv32 >> 16) & 0xff,
661 (tkip->tx_iv32 >> 8) & 0xff,
662 tkip->tx_iv32 & 0xff,
663 (tkip->tx_iv16 >> 8) & 0xff,
664 tkip->tx_iv16 & 0xff,
665 (tkip->rx_iv32 >> 24) & 0xff,
666 (tkip->rx_iv32 >> 16) & 0xff,
667 (tkip->rx_iv32 >> 8) & 0xff,
668 tkip->rx_iv32 & 0xff,
669 (tkip->rx_iv16 >> 8) & 0xff,
670 tkip->rx_iv16 & 0xff,
671 tkip->dot11RSNAStatsTKIPReplays,
672 tkip->dot11RSNAStatsTKIPICVErrors,
673 tkip->dot11RSNAStatsTKIPLocalMICFailures);
674 return p;
675}
676
677
678static struct ieee80211_crypto_ops ieee80211_crypt_tkip = {
679 .name = "TKIP",
680 .init = ieee80211_tkip_init,
681 .deinit = ieee80211_tkip_deinit,
682 .encrypt_mpdu = ieee80211_tkip_encrypt,
683 .decrypt_mpdu = ieee80211_tkip_decrypt,
684 .encrypt_msdu = ieee80211_michael_mic_add,
685 .decrypt_msdu = ieee80211_michael_mic_verify,
686 .set_key = ieee80211_tkip_set_key,
687 .get_key = ieee80211_tkip_get_key,
688 .print_stats = ieee80211_tkip_print_stats,
689 .extra_prefix_len = 4 + 4, /* IV + ExtIV */
690 .extra_postfix_len = 8 + 4, /* MIC + ICV */
691 .owner = THIS_MODULE,
692};
693
694
695static int __init ieee80211_crypto_tkip_init(void)
696{
697 return ieee80211_register_crypto_ops(&ieee80211_crypt_tkip);
698}
699
700
701static void __exit ieee80211_crypto_tkip_exit(void)
702{
703 ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip);
704}
705
706
707module_init(ieee80211_crypto_tkip_init);
708module_exit(ieee80211_crypto_tkip_exit);
diff --git a/net/ieee80211/ieee80211_crypt_wep.c b/net/ieee80211/ieee80211_crypt_wep.c
new file mode 100644
index 000000000000..bec1d3470d39
--- /dev/null
+++ b/net/ieee80211/ieee80211_crypt_wep.c
@@ -0,0 +1,272 @@
1/*
2 * Host AP crypt: host-based WEP encryption implementation for Host AP driver
3 *
4 * Copyright (c) 2002-2004, Jouni Malinen <jkmaline@cc.hut.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation. See README and COPYING for
9 * more details.
10 */
11
12#include <linux/config.h>
13#include <linux/version.h>
14#include <linux/module.h>
15#include <linux/init.h>
16#include <linux/slab.h>
17#include <linux/random.h>
18#include <linux/skbuff.h>
19#include <asm/string.h>
20
21#include <net/ieee80211.h>
22
23
24#include <linux/crypto.h>
25#include <asm/scatterlist.h>
26#include <linux/crc32.h>
27
28MODULE_AUTHOR("Jouni Malinen");
29MODULE_DESCRIPTION("Host AP crypt: WEP");
30MODULE_LICENSE("GPL");
31
32
33struct prism2_wep_data {
34 u32 iv;
35#define WEP_KEY_LEN 13
36 u8 key[WEP_KEY_LEN + 1];
37 u8 key_len;
38 u8 key_idx;
39 struct crypto_tfm *tfm;
40};
41
42
43static void * prism2_wep_init(int keyidx)
44{
45 struct prism2_wep_data *priv;
46
47 priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
48 if (priv == NULL)
49 goto fail;
50 memset(priv, 0, sizeof(*priv));
51 priv->key_idx = keyidx;
52
53 priv->tfm = crypto_alloc_tfm("arc4", 0);
54 if (priv->tfm == NULL) {
55 printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
56 "crypto API arc4\n");
57 goto fail;
58 }
59
60 /* start WEP IV from a random value */
61 get_random_bytes(&priv->iv, 4);
62
63 return priv;
64
65fail:
66 if (priv) {
67 if (priv->tfm)
68 crypto_free_tfm(priv->tfm);
69 kfree(priv);
70 }
71 return NULL;
72}
73
74
75static void prism2_wep_deinit(void *priv)
76{
77 struct prism2_wep_data *_priv = priv;
78 if (_priv && _priv->tfm)
79 crypto_free_tfm(_priv->tfm);
80 kfree(priv);
81}
82
83
84/* Perform WEP encryption on given skb that has at least 4 bytes of headroom
85 * for IV and 4 bytes of tailroom for ICV. Both IV and ICV will be transmitted,
86 * so the payload length increases with 8 bytes.
87 *
88 * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data))
89 */
90static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
91{
92 struct prism2_wep_data *wep = priv;
93 u32 crc, klen, len;
94 u8 key[WEP_KEY_LEN + 3];
95 u8 *pos, *icv;
96 struct scatterlist sg;
97
98 if (skb_headroom(skb) < 4 || skb_tailroom(skb) < 4 ||
99 skb->len < hdr_len)
100 return -1;
101
102 len = skb->len - hdr_len;
103 pos = skb_push(skb, 4);
104 memmove(pos, pos + 4, hdr_len);
105 pos += hdr_len;
106
107 klen = 3 + wep->key_len;
108
109 wep->iv++;
110
111 /* Fluhrer, Mantin, and Shamir have reported weaknesses in the key
112 * scheduling algorithm of RC4. At least IVs (KeyByte + 3, 0xff, N)
113 * can be used to speedup attacks, so avoid using them. */
114 if ((wep->iv & 0xff00) == 0xff00) {
115 u8 B = (wep->iv >> 16) & 0xff;
116 if (B >= 3 && B < klen)
117 wep->iv += 0x0100;
118 }
119
120 /* Prepend 24-bit IV to RC4 key and TX frame */
121 *pos++ = key[0] = (wep->iv >> 16) & 0xff;
122 *pos++ = key[1] = (wep->iv >> 8) & 0xff;
123 *pos++ = key[2] = wep->iv & 0xff;
124 *pos++ = wep->key_idx << 6;
125
126 /* Copy rest of the WEP key (the secret part) */
127 memcpy(key + 3, wep->key, wep->key_len);
128
129 /* Append little-endian CRC32 and encrypt it to produce ICV */
130 crc = ~crc32_le(~0, pos, len);
131 icv = skb_put(skb, 4);
132 icv[0] = crc;
133 icv[1] = crc >> 8;
134 icv[2] = crc >> 16;
135 icv[3] = crc >> 24;
136
137 crypto_cipher_setkey(wep->tfm, key, klen);
138 sg.page = virt_to_page(pos);
139 sg.offset = offset_in_page(pos);
140 sg.length = len + 4;
141 crypto_cipher_encrypt(wep->tfm, &sg, &sg, len + 4);
142
143 return 0;
144}
145
146
147/* Perform WEP decryption on given buffer. Buffer includes whole WEP part of
148 * the frame: IV (4 bytes), encrypted payload (including SNAP header),
149 * ICV (4 bytes). len includes both IV and ICV.
150 *
151 * Returns 0 if frame was decrypted successfully and ICV was correct and -1 on
152 * failure. If frame is OK, IV and ICV will be removed.
153 */
154static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
155{
156 struct prism2_wep_data *wep = priv;
157 u32 crc, klen, plen;
158 u8 key[WEP_KEY_LEN + 3];
159 u8 keyidx, *pos, icv[4];
160 struct scatterlist sg;
161
162 if (skb->len < hdr_len + 8)
163 return -1;
164
165 pos = skb->data + hdr_len;
166 key[0] = *pos++;
167 key[1] = *pos++;
168 key[2] = *pos++;
169 keyidx = *pos++ >> 6;
170 if (keyidx != wep->key_idx)
171 return -1;
172
173 klen = 3 + wep->key_len;
174
175 /* Copy rest of the WEP key (the secret part) */
176 memcpy(key + 3, wep->key, wep->key_len);
177
178 /* Apply RC4 to data and compute CRC32 over decrypted data */
179 plen = skb->len - hdr_len - 8;
180
181 crypto_cipher_setkey(wep->tfm, key, klen);
182 sg.page = virt_to_page(pos);
183 sg.offset = offset_in_page(pos);
184 sg.length = plen + 4;
185 crypto_cipher_decrypt(wep->tfm, &sg, &sg, plen + 4);
186
187 crc = ~crc32_le(~0, pos, plen);
188 icv[0] = crc;
189 icv[1] = crc >> 8;
190 icv[2] = crc >> 16;
191 icv[3] = crc >> 24;
192 if (memcmp(icv, pos + plen, 4) != 0) {
193 /* ICV mismatch - drop frame */
194 return -2;
195 }
196
197 /* Remove IV and ICV */
198 memmove(skb->data + 4, skb->data, hdr_len);
199 skb_pull(skb, 4);
200 skb_trim(skb, skb->len - 4);
201
202 return 0;
203}
204
205
206static int prism2_wep_set_key(void *key, int len, u8 *seq, void *priv)
207{
208 struct prism2_wep_data *wep = priv;
209
210 if (len < 0 || len > WEP_KEY_LEN)
211 return -1;
212
213 memcpy(wep->key, key, len);
214 wep->key_len = len;
215
216 return 0;
217}
218
219
220static int prism2_wep_get_key(void *key, int len, u8 *seq, void *priv)
221{
222 struct prism2_wep_data *wep = priv;
223
224 if (len < wep->key_len)
225 return -1;
226
227 memcpy(key, wep->key, wep->key_len);
228
229 return wep->key_len;
230}
231
232
233static char * prism2_wep_print_stats(char *p, void *priv)
234{
235 struct prism2_wep_data *wep = priv;
236 p += sprintf(p, "key[%d] alg=WEP len=%d\n",
237 wep->key_idx, wep->key_len);
238 return p;
239}
240
241
242static struct ieee80211_crypto_ops ieee80211_crypt_wep = {
243 .name = "WEP",
244 .init = prism2_wep_init,
245 .deinit = prism2_wep_deinit,
246 .encrypt_mpdu = prism2_wep_encrypt,
247 .decrypt_mpdu = prism2_wep_decrypt,
248 .encrypt_msdu = NULL,
249 .decrypt_msdu = NULL,
250 .set_key = prism2_wep_set_key,
251 .get_key = prism2_wep_get_key,
252 .print_stats = prism2_wep_print_stats,
253 .extra_prefix_len = 4, /* IV */
254 .extra_postfix_len = 4, /* ICV */
255 .owner = THIS_MODULE,
256};
257
258
259static int __init ieee80211_crypto_wep_init(void)
260{
261 return ieee80211_register_crypto_ops(&ieee80211_crypt_wep);
262}
263
264
265static void __exit ieee80211_crypto_wep_exit(void)
266{
267 ieee80211_unregister_crypto_ops(&ieee80211_crypt_wep);
268}
269
270
271module_init(ieee80211_crypto_wep_init);
272module_exit(ieee80211_crypto_wep_exit);
diff --git a/net/ieee80211/ieee80211_module.c b/net/ieee80211/ieee80211_module.c
new file mode 100644
index 000000000000..e4ca0daaaeea
--- /dev/null
+++ b/net/ieee80211/ieee80211_module.c
@@ -0,0 +1,268 @@
1/*******************************************************************************
2
3 Copyright(c) 2004 Intel Corporation. All rights reserved.
4
5 Portions of this file are based on the WEP enablement code provided by the
6 Host AP project hostap-drivers v0.1.3
7 Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
8 <jkmaline@cc.hut.fi>
9 Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
10
11 This program is free software; you can redistribute it and/or modify it
12 under the terms of version 2 of the GNU General Public License as
13 published by the Free Software Foundation.
14
15 This program is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18 more details.
19
20 You should have received a copy of the GNU General Public License along with
21 this program; if not, write to the Free Software Foundation, Inc., 59
22 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
24 The full GNU General Public License is included in this distribution in the
25 file called LICENSE.
26
27 Contact Information:
28 James P. Ketrenos <ipw2100-admin@linux.intel.com>
29 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30
31*******************************************************************************/
32
33#include <linux/compiler.h>
34#include <linux/config.h>
35#include <linux/errno.h>
36#include <linux/if_arp.h>
37#include <linux/in6.h>
38#include <linux/in.h>
39#include <linux/ip.h>
40#include <linux/kernel.h>
41#include <linux/module.h>
42#include <linux/netdevice.h>
43#include <linux/pci.h>
44#include <linux/proc_fs.h>
45#include <linux/skbuff.h>
46#include <linux/slab.h>
47#include <linux/tcp.h>
48#include <linux/types.h>
49#include <linux/version.h>
50#include <linux/wireless.h>
51#include <linux/etherdevice.h>
52#include <asm/uaccess.h>
53#include <net/arp.h>
54
55#include <net/ieee80211.h>
56
57MODULE_DESCRIPTION("802.11 data/management/control stack");
58MODULE_AUTHOR("Copyright (C) 2004 Intel Corporation <jketreno@linux.intel.com>");
59MODULE_LICENSE("GPL");
60
61#define DRV_NAME "ieee80211"
62
63static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee)
64{
65 if (ieee->networks)
66 return 0;
67
68 ieee->networks = kmalloc(
69 MAX_NETWORK_COUNT * sizeof(struct ieee80211_network),
70 GFP_KERNEL);
71 if (!ieee->networks) {
72 printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
73 ieee->dev->name);
74 return -ENOMEM;
75 }
76
77 memset(ieee->networks, 0,
78 MAX_NETWORK_COUNT * sizeof(struct ieee80211_network));
79
80 return 0;
81}
82
83static inline void ieee80211_networks_free(struct ieee80211_device *ieee)
84{
85 if (!ieee->networks)
86 return;
87 kfree(ieee->networks);
88 ieee->networks = NULL;
89}
90
91static inline void ieee80211_networks_initialize(struct ieee80211_device *ieee)
92{
93 int i;
94
95 INIT_LIST_HEAD(&ieee->network_free_list);
96 INIT_LIST_HEAD(&ieee->network_list);
97 for (i = 0; i < MAX_NETWORK_COUNT; i++)
98 list_add_tail(&ieee->networks[i].list, &ieee->network_free_list);
99}
100
101
102struct net_device *alloc_ieee80211(int sizeof_priv)
103{
104 struct ieee80211_device *ieee;
105 struct net_device *dev;
106 int err;
107
108 IEEE80211_DEBUG_INFO("Initializing...\n");
109
110 dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv);
111 if (!dev) {
112 IEEE80211_ERROR("Unable to network device.\n");
113 goto failed;
114 }
115 ieee = netdev_priv(dev);
116 dev->hard_start_xmit = ieee80211_xmit;
117
118 ieee->dev = dev;
119
120 err = ieee80211_networks_allocate(ieee);
121 if (err) {
122 IEEE80211_ERROR("Unable to allocate beacon storage: %d\n",
123 err);
124 goto failed;
125 }
126 ieee80211_networks_initialize(ieee);
127
128 /* Default fragmentation threshold is maximum payload size */
129 ieee->fts = DEFAULT_FTS;
130 ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
131 ieee->open_wep = 1;
132
133 /* Default to enabling full open WEP with host based encrypt/decrypt */
134 ieee->host_encrypt = 1;
135 ieee->host_decrypt = 1;
136 ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
137
138 INIT_LIST_HEAD(&ieee->crypt_deinit_list);
139 init_timer(&ieee->crypt_deinit_timer);
140 ieee->crypt_deinit_timer.data = (unsigned long)ieee;
141 ieee->crypt_deinit_timer.function = ieee80211_crypt_deinit_handler;
142
143 spin_lock_init(&ieee->lock);
144
145 ieee->wpa_enabled = 0;
146 ieee->tkip_countermeasures = 0;
147 ieee->drop_unencrypted = 0;
148 ieee->privacy_invoked = 0;
149 ieee->ieee802_1x = 1;
150
151 return dev;
152
153 failed:
154 if (dev)
155 free_netdev(dev);
156 return NULL;
157}
158
159
160void free_ieee80211(struct net_device *dev)
161{
162 struct ieee80211_device *ieee = netdev_priv(dev);
163
164 int i;
165
166 del_timer_sync(&ieee->crypt_deinit_timer);
167 ieee80211_crypt_deinit_entries(ieee, 1);
168
169 for (i = 0; i < WEP_KEYS; i++) {
170 struct ieee80211_crypt_data *crypt = ieee->crypt[i];
171 if (crypt) {
172 if (crypt->ops) {
173 crypt->ops->deinit(crypt->priv);
174 module_put(crypt->ops->owner);
175 }
176 kfree(crypt);
177 ieee->crypt[i] = NULL;
178 }
179 }
180
181 ieee80211_networks_free(ieee);
182 free_netdev(dev);
183}
184
185#ifdef CONFIG_IEEE80211_DEBUG
186
187static int debug = 0;
188u32 ieee80211_debug_level = 0;
189struct proc_dir_entry *ieee80211_proc = NULL;
190
191static int show_debug_level(char *page, char **start, off_t offset,
192 int count, int *eof, void *data)
193{
194 return snprintf(page, count, "0x%08X\n", ieee80211_debug_level);
195}
196
197static int store_debug_level(struct file *file, const char *buffer,
198 unsigned long count, void *data)
199{
200 char buf[] = "0x00000000";
201 unsigned long len = min(sizeof(buf) - 1, (u32)count);
202 char *p = (char *)buf;
203 unsigned long val;
204
205 if (copy_from_user(buf, buffer, len))
206 return count;
207 buf[len] = 0;
208 if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
209 p++;
210 if (p[0] == 'x' || p[0] == 'X')
211 p++;
212 val = simple_strtoul(p, &p, 16);
213 } else
214 val = simple_strtoul(p, &p, 10);
215 if (p == buf)
216 printk(KERN_INFO DRV_NAME
217 ": %s is not in hex or decimal form.\n", buf);
218 else
219 ieee80211_debug_level = val;
220
221 return strnlen(buf, count);
222}
223
224static int __init ieee80211_init(void)
225{
226 struct proc_dir_entry *e;
227
228 ieee80211_debug_level = debug;
229 ieee80211_proc = create_proc_entry(DRV_NAME, S_IFDIR, proc_net);
230 if (ieee80211_proc == NULL) {
231 IEEE80211_ERROR("Unable to create " DRV_NAME
232 " proc directory\n");
233 return -EIO;
234 }
235 e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
236 ieee80211_proc);
237 if (!e) {
238 remove_proc_entry(DRV_NAME, proc_net);
239 ieee80211_proc = NULL;
240 return -EIO;
241 }
242 e->read_proc = show_debug_level;
243 e->write_proc = store_debug_level;
244 e->data = NULL;
245
246 return 0;
247}
248
249static void __exit ieee80211_exit(void)
250{
251 if (ieee80211_proc) {
252 remove_proc_entry("debug_level", ieee80211_proc);
253 remove_proc_entry(DRV_NAME, proc_net);
254 ieee80211_proc = NULL;
255 }
256}
257
258#include <linux/moduleparam.h>
259module_param(debug, int, 0444);
260MODULE_PARM_DESC(debug, "debug output mask");
261
262
263module_exit(ieee80211_exit);
264module_init(ieee80211_init);
265#endif
266
267EXPORT_SYMBOL(alloc_ieee80211);
268EXPORT_SYMBOL(free_ieee80211);
diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c
new file mode 100644
index 000000000000..2bda8a174818
--- /dev/null
+++ b/net/ieee80211/ieee80211_rx.c
@@ -0,0 +1,1206 @@
1/*
2 * Original code based Host AP (software wireless LAN access point) driver
3 * for Intersil Prism2/2.5/3 - hostap.o module, common routines
4 *
5 * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
6 * <jkmaline@cc.hut.fi>
7 * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
8 * Copyright (c) 2004, Intel Corporation
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation. See README and COPYING for
13 * more details.
14 */
15
16#include <linux/compiler.h>
17#include <linux/config.h>
18#include <linux/errno.h>
19#include <linux/if_arp.h>
20#include <linux/in6.h>
21#include <linux/in.h>
22#include <linux/ip.h>
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/netdevice.h>
26#include <linux/pci.h>
27#include <linux/proc_fs.h>
28#include <linux/skbuff.h>
29#include <linux/slab.h>
30#include <linux/tcp.h>
31#include <linux/types.h>
32#include <linux/version.h>
33#include <linux/wireless.h>
34#include <linux/etherdevice.h>
35#include <asm/uaccess.h>
36#include <linux/ctype.h>
37
38#include <net/ieee80211.h>
39
40static inline void ieee80211_monitor_rx(struct ieee80211_device *ieee,
41 struct sk_buff *skb,
42 struct ieee80211_rx_stats *rx_stats)
43{
44 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
45 u16 fc = le16_to_cpu(hdr->frame_ctl);
46
47 skb->dev = ieee->dev;
48 skb->mac.raw = skb->data;
49 skb_pull(skb, ieee80211_get_hdrlen(fc));
50 skb->pkt_type = PACKET_OTHERHOST;
51 skb->protocol = __constant_htons(ETH_P_80211_RAW);
52 memset(skb->cb, 0, sizeof(skb->cb));
53 netif_rx(skb);
54}
55
56
57/* Called only as a tasklet (software IRQ) */
58static struct ieee80211_frag_entry *
59ieee80211_frag_cache_find(struct ieee80211_device *ieee, unsigned int seq,
60 unsigned int frag, u8 *src, u8 *dst)
61{
62 struct ieee80211_frag_entry *entry;
63 int i;
64
65 for (i = 0; i < IEEE80211_FRAG_CACHE_LEN; i++) {
66 entry = &ieee->frag_cache[i];
67 if (entry->skb != NULL &&
68 time_after(jiffies, entry->first_frag_time + 2 * HZ)) {
69 IEEE80211_DEBUG_FRAG(
70 "expiring fragment cache entry "
71 "seq=%u last_frag=%u\n",
72 entry->seq, entry->last_frag);
73 dev_kfree_skb_any(entry->skb);
74 entry->skb = NULL;
75 }
76
77 if (entry->skb != NULL && entry->seq == seq &&
78 (entry->last_frag + 1 == frag || frag == -1) &&
79 memcmp(entry->src_addr, src, ETH_ALEN) == 0 &&
80 memcmp(entry->dst_addr, dst, ETH_ALEN) == 0)
81 return entry;
82 }
83
84 return NULL;
85}
86
87/* Called only as a tasklet (software IRQ) */
88static struct sk_buff *
89ieee80211_frag_cache_get(struct ieee80211_device *ieee,
90 struct ieee80211_hdr *hdr)
91{
92 struct sk_buff *skb = NULL;
93 u16 sc;
94 unsigned int frag, seq;
95 struct ieee80211_frag_entry *entry;
96
97 sc = le16_to_cpu(hdr->seq_ctl);
98 frag = WLAN_GET_SEQ_FRAG(sc);
99 seq = WLAN_GET_SEQ_SEQ(sc);
100
101 if (frag == 0) {
102 /* Reserve enough space to fit maximum frame length */
103 skb = dev_alloc_skb(ieee->dev->mtu +
104 sizeof(struct ieee80211_hdr) +
105 8 /* LLC */ +
106 2 /* alignment */ +
107 8 /* WEP */ + ETH_ALEN /* WDS */);
108 if (skb == NULL)
109 return NULL;
110
111 entry = &ieee->frag_cache[ieee->frag_next_idx];
112 ieee->frag_next_idx++;
113 if (ieee->frag_next_idx >= IEEE80211_FRAG_CACHE_LEN)
114 ieee->frag_next_idx = 0;
115
116 if (entry->skb != NULL)
117 dev_kfree_skb_any(entry->skb);
118
119 entry->first_frag_time = jiffies;
120 entry->seq = seq;
121 entry->last_frag = frag;
122 entry->skb = skb;
123 memcpy(entry->src_addr, hdr->addr2, ETH_ALEN);
124 memcpy(entry->dst_addr, hdr->addr1, ETH_ALEN);
125 } else {
126 /* received a fragment of a frame for which the head fragment
127 * should have already been received */
128 entry = ieee80211_frag_cache_find(ieee, seq, frag, hdr->addr2,
129 hdr->addr1);
130 if (entry != NULL) {
131 entry->last_frag = frag;
132 skb = entry->skb;
133 }
134 }
135
136 return skb;
137}
138
139
140/* Called only as a tasklet (software IRQ) */
141static int ieee80211_frag_cache_invalidate(struct ieee80211_device *ieee,
142 struct ieee80211_hdr *hdr)
143{
144 u16 sc;
145 unsigned int seq;
146 struct ieee80211_frag_entry *entry;
147
148 sc = le16_to_cpu(hdr->seq_ctl);
149 seq = WLAN_GET_SEQ_SEQ(sc);
150
151 entry = ieee80211_frag_cache_find(ieee, seq, -1, hdr->addr2,
152 hdr->addr1);
153
154 if (entry == NULL) {
155 IEEE80211_DEBUG_FRAG(
156 "could not invalidate fragment cache "
157 "entry (seq=%u)\n", seq);
158 return -1;
159 }
160
161 entry->skb = NULL;
162 return 0;
163}
164
165
166#ifdef NOT_YET
167/* ieee80211_rx_frame_mgtmt
168 *
169 * Responsible for handling management control frames
170 *
171 * Called by ieee80211_rx */
172static inline int
173ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb,
174 struct ieee80211_rx_stats *rx_stats, u16 type,
175 u16 stype)
176{
177 if (ieee->iw_mode == IW_MODE_MASTER) {
178 printk(KERN_DEBUG "%s: Master mode not yet suppported.\n",
179 ieee->dev->name);
180 return 0;
181/*
182 hostap_update_sta_ps(ieee, (struct hostap_ieee80211_hdr *)
183 skb->data);*/
184 }
185
186 if (ieee->hostapd && type == WLAN_FC_TYPE_MGMT) {
187 if (stype == WLAN_FC_STYPE_BEACON &&
188 ieee->iw_mode == IW_MODE_MASTER) {
189 struct sk_buff *skb2;
190 /* Process beacon frames also in kernel driver to
191 * update STA(AP) table statistics */
192 skb2 = skb_clone(skb, GFP_ATOMIC);
193 if (skb2)
194 hostap_rx(skb2->dev, skb2, rx_stats);
195 }
196
197 /* send management frames to the user space daemon for
198 * processing */
199 ieee->apdevstats.rx_packets++;
200 ieee->apdevstats.rx_bytes += skb->len;
201 prism2_rx_80211(ieee->apdev, skb, rx_stats, PRISM2_RX_MGMT);
202 return 0;
203 }
204
205 if (ieee->iw_mode == IW_MODE_MASTER) {
206 if (type != WLAN_FC_TYPE_MGMT && type != WLAN_FC_TYPE_CTRL) {
207 printk(KERN_DEBUG "%s: unknown management frame "
208 "(type=0x%02x, stype=0x%02x) dropped\n",
209 skb->dev->name, type, stype);
210 return -1;
211 }
212
213 hostap_rx(skb->dev, skb, rx_stats);
214 return 0;
215 }
216
217 printk(KERN_DEBUG "%s: hostap_rx_frame_mgmt: management frame "
218 "received in non-Host AP mode\n", skb->dev->name);
219 return -1;
220}
221#endif
222
223
224/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
225/* Ethernet-II snap header (RFC1042 for most EtherTypes) */
226static unsigned char rfc1042_header[] =
227{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
228/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
229static unsigned char bridge_tunnel_header[] =
230{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
231/* No encapsulation header if EtherType < 0x600 (=length) */
232
233/* Called by ieee80211_rx_frame_decrypt */
234static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee,
235 struct sk_buff *skb)
236{
237 struct net_device *dev = ieee->dev;
238 u16 fc, ethertype;
239 struct ieee80211_hdr *hdr;
240 u8 *pos;
241
242 if (skb->len < 24)
243 return 0;
244
245 hdr = (struct ieee80211_hdr *) skb->data;
246 fc = le16_to_cpu(hdr->frame_ctl);
247
248 /* check that the frame is unicast frame to us */
249 if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
250 IEEE80211_FCTL_TODS &&
251 memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0 &&
252 memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) {
253 /* ToDS frame with own addr BSSID and DA */
254 } else if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
255 IEEE80211_FCTL_FROMDS &&
256 memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) {
257 /* FromDS frame with own addr as DA */
258 } else
259 return 0;
260
261 if (skb->len < 24 + 8)
262 return 0;
263
264 /* check for port access entity Ethernet type */
265 pos = skb->data + 24;
266 ethertype = (pos[6] << 8) | pos[7];
267 if (ethertype == ETH_P_PAE)
268 return 1;
269
270 return 0;
271}
272
273/* Called only as a tasklet (software IRQ), by ieee80211_rx */
274static inline int
275ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb,
276 struct ieee80211_crypt_data *crypt)
277{
278 struct ieee80211_hdr *hdr;
279 int res, hdrlen;
280
281 if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
282 return 0;
283
284 hdr = (struct ieee80211_hdr *) skb->data;
285 hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
286
287#ifdef CONFIG_IEEE80211_CRYPT_TKIP
288 if (ieee->tkip_countermeasures &&
289 strcmp(crypt->ops->name, "TKIP") == 0) {
290 if (net_ratelimit()) {
291 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
292 "received packet from " MAC_FMT "\n",
293 ieee->dev->name, MAC_ARG(hdr->addr2));
294 }
295 return -1;
296 }
297#endif
298
299 atomic_inc(&crypt->refcnt);
300 res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv);
301 atomic_dec(&crypt->refcnt);
302 if (res < 0) {
303 IEEE80211_DEBUG_DROP(
304 "decryption failed (SA=" MAC_FMT
305 ") res=%d\n", MAC_ARG(hdr->addr2), res);
306 if (res == -2)
307 IEEE80211_DEBUG_DROP("Decryption failed ICV "
308 "mismatch (key %d)\n",
309 skb->data[hdrlen + 3] >> 6);
310 ieee->ieee_stats.rx_discards_undecryptable++;
311 return -1;
312 }
313
314 return res;
315}
316
317
318/* Called only as a tasklet (software IRQ), by ieee80211_rx */
319static inline int
320ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device* ieee, struct sk_buff *skb,
321 int keyidx, struct ieee80211_crypt_data *crypt)
322{
323 struct ieee80211_hdr *hdr;
324 int res, hdrlen;
325
326 if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
327 return 0;
328
329 hdr = (struct ieee80211_hdr *) skb->data;
330 hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
331
332 atomic_inc(&crypt->refcnt);
333 res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv);
334 atomic_dec(&crypt->refcnt);
335 if (res < 0) {
336 printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
337 " (SA=" MAC_FMT " keyidx=%d)\n",
338 ieee->dev->name, MAC_ARG(hdr->addr2), keyidx);
339 return -1;
340 }
341
342 return 0;
343}
344
345
346/* All received frames are sent to this function. @skb contains the frame in
347 * IEEE 802.11 format, i.e., in the format it was sent over air.
348 * This function is called only as a tasklet (software IRQ). */
349int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
350 struct ieee80211_rx_stats *rx_stats)
351{
352 struct net_device *dev = ieee->dev;
353 struct ieee80211_hdr *hdr;
354 size_t hdrlen;
355 u16 fc, type, stype, sc;
356 struct net_device_stats *stats;
357 unsigned int frag;
358 u8 *payload;
359 u16 ethertype;
360#ifdef NOT_YET
361 struct net_device *wds = NULL;
362 struct sk_buff *skb2 = NULL;
363 struct net_device *wds = NULL;
364 int frame_authorized = 0;
365 int from_assoc_ap = 0;
366 void *sta = NULL;
367#endif
368 u8 dst[ETH_ALEN];
369 u8 src[ETH_ALEN];
370 struct ieee80211_crypt_data *crypt = NULL;
371 int keyidx = 0;
372
373 hdr = (struct ieee80211_hdr *)skb->data;
374 stats = &ieee->stats;
375
376 if (skb->len < 10) {
377 printk(KERN_INFO "%s: SKB length < 10\n",
378 dev->name);
379 goto rx_dropped;
380 }
381
382 fc = le16_to_cpu(hdr->frame_ctl);
383 type = WLAN_FC_GET_TYPE(fc);
384 stype = WLAN_FC_GET_STYPE(fc);
385 sc = le16_to_cpu(hdr->seq_ctl);
386 frag = WLAN_GET_SEQ_FRAG(sc);
387 hdrlen = ieee80211_get_hdrlen(fc);
388
389#ifdef NOT_YET
390#if WIRELESS_EXT > 15
391 /* Put this code here so that we avoid duplicating it in all
392 * Rx paths. - Jean II */
393#ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */
394 /* If spy monitoring on */
395 if (iface->spy_data.spy_number > 0) {
396 struct iw_quality wstats;
397 wstats.level = rx_stats->signal;
398 wstats.noise = rx_stats->noise;
399 wstats.updated = 6; /* No qual value */
400 /* Update spy records */
401 wireless_spy_update(dev, hdr->addr2, &wstats);
402 }
403#endif /* IW_WIRELESS_SPY */
404#endif /* WIRELESS_EXT > 15 */
405 hostap_update_rx_stats(local->ap, hdr, rx_stats);
406#endif
407
408#if WIRELESS_EXT > 15
409 if (ieee->iw_mode == IW_MODE_MONITOR) {
410 ieee80211_monitor_rx(ieee, skb, rx_stats);
411 stats->rx_packets++;
412 stats->rx_bytes += skb->len;
413 return 1;
414 }
415#endif
416
417 if (ieee->host_decrypt) {
418 int idx = 0;
419 if (skb->len >= hdrlen + 3)
420 idx = skb->data[hdrlen + 3] >> 6;
421 crypt = ieee->crypt[idx];
422#ifdef NOT_YET
423 sta = NULL;
424
425 /* Use station specific key to override default keys if the
426 * receiver address is a unicast address ("individual RA"). If
427 * bcrx_sta_key parameter is set, station specific key is used
428 * even with broad/multicast targets (this is against IEEE
429 * 802.11, but makes it easier to use different keys with
430 * stations that do not support WEP key mapping). */
431
432 if (!(hdr->addr1[0] & 0x01) || local->bcrx_sta_key)
433 (void) hostap_handle_sta_crypto(local, hdr, &crypt,
434 &sta);
435#endif
436
437 /* allow NULL decrypt to indicate an station specific override
438 * for default encryption */
439 if (crypt && (crypt->ops == NULL ||
440 crypt->ops->decrypt_mpdu == NULL))
441 crypt = NULL;
442
443 if (!crypt && (fc & IEEE80211_FCTL_WEP)) {
444 /* This seems to be triggered by some (multicast?)
445 * frames from other than current BSS, so just drop the
446 * frames silently instead of filling system log with
447 * these reports. */
448 IEEE80211_DEBUG_DROP("Decryption failed (not set)"
449 " (SA=" MAC_FMT ")\n",
450 MAC_ARG(hdr->addr2));
451 ieee->ieee_stats.rx_discards_undecryptable++;
452 goto rx_dropped;
453 }
454 }
455
456#ifdef NOT_YET
457 if (type != WLAN_FC_TYPE_DATA) {
458 if (type == WLAN_FC_TYPE_MGMT && stype == WLAN_FC_STYPE_AUTH &&
459 fc & IEEE80211_FCTL_WEP && ieee->host_decrypt &&
460 (keyidx = hostap_rx_frame_decrypt(ieee, skb, crypt)) < 0)
461 {
462 printk(KERN_DEBUG "%s: failed to decrypt mgmt::auth "
463 "from " MAC_FMT "\n", dev->name,
464 MAC_ARG(hdr->addr2));
465 /* TODO: could inform hostapd about this so that it
466 * could send auth failure report */
467 goto rx_dropped;
468 }
469
470 if (ieee80211_rx_frame_mgmt(ieee, skb, rx_stats, type, stype))
471 goto rx_dropped;
472 else
473 goto rx_exit;
474 }
475#endif
476
477 /* Data frame - extract src/dst addresses */
478 if (skb->len < IEEE80211_DATA_HDR3_LEN)
479 goto rx_dropped;
480
481 switch (fc & (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
482 case IEEE80211_FCTL_FROMDS:
483 memcpy(dst, hdr->addr1, ETH_ALEN);
484 memcpy(src, hdr->addr3, ETH_ALEN);
485 break;
486 case IEEE80211_FCTL_TODS:
487 memcpy(dst, hdr->addr3, ETH_ALEN);
488 memcpy(src, hdr->addr2, ETH_ALEN);
489 break;
490 case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
491 if (skb->len < IEEE80211_DATA_HDR4_LEN)
492 goto rx_dropped;
493 memcpy(dst, hdr->addr3, ETH_ALEN);
494 memcpy(src, hdr->addr4, ETH_ALEN);
495 break;
496 case 0:
497 memcpy(dst, hdr->addr1, ETH_ALEN);
498 memcpy(src, hdr->addr2, ETH_ALEN);
499 break;
500 }
501
502#ifdef NOT_YET
503 if (hostap_rx_frame_wds(ieee, hdr, fc, &wds))
504 goto rx_dropped;
505 if (wds) {
506 skb->dev = dev = wds;
507 stats = hostap_get_stats(dev);
508 }
509
510 if (ieee->iw_mode == IW_MODE_MASTER && !wds &&
511 (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == IEEE80211_FCTL_FROMDS &&
512 ieee->stadev &&
513 memcmp(hdr->addr2, ieee->assoc_ap_addr, ETH_ALEN) == 0) {
514 /* Frame from BSSID of the AP for which we are a client */
515 skb->dev = dev = ieee->stadev;
516 stats = hostap_get_stats(dev);
517 from_assoc_ap = 1;
518 }
519#endif
520
521 dev->last_rx = jiffies;
522
523#ifdef NOT_YET
524 if ((ieee->iw_mode == IW_MODE_MASTER ||
525 ieee->iw_mode == IW_MODE_REPEAT) &&
526 !from_assoc_ap) {
527 switch (hostap_handle_sta_rx(ieee, dev, skb, rx_stats,
528 wds != NULL)) {
529 case AP_RX_CONTINUE_NOT_AUTHORIZED:
530 frame_authorized = 0;
531 break;
532 case AP_RX_CONTINUE:
533 frame_authorized = 1;
534 break;
535 case AP_RX_DROP:
536 goto rx_dropped;
537 case AP_RX_EXIT:
538 goto rx_exit;
539 }
540 }
541#endif
542
543 /* Nullfunc frames may have PS-bit set, so they must be passed to
544 * hostap_handle_sta_rx() before being dropped here. */
545 if (stype != IEEE80211_STYPE_DATA &&
546 stype != IEEE80211_STYPE_DATA_CFACK &&
547 stype != IEEE80211_STYPE_DATA_CFPOLL &&
548 stype != IEEE80211_STYPE_DATA_CFACKPOLL) {
549 if (stype != IEEE80211_STYPE_NULLFUNC)
550 IEEE80211_DEBUG_DROP(
551 "RX: dropped data frame "
552 "with no data (type=0x%02x, "
553 "subtype=0x%02x, len=%d)\n",
554 type, stype, skb->len);
555 goto rx_dropped;
556 }
557
558 /* skb: hdr + (possibly fragmented, possibly encrypted) payload */
559
560 if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
561 (keyidx = ieee80211_rx_frame_decrypt(ieee, skb, crypt)) < 0)
562 goto rx_dropped;
563
564 hdr = (struct ieee80211_hdr *) skb->data;
565
566 /* skb: hdr + (possibly fragmented) plaintext payload */
567 // PR: FIXME: hostap has additional conditions in the "if" below:
568 // ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
569 if ((frag != 0 || (fc & IEEE80211_FCTL_MOREFRAGS))) {
570 int flen;
571 struct sk_buff *frag_skb = ieee80211_frag_cache_get(ieee, hdr);
572 IEEE80211_DEBUG_FRAG("Rx Fragment received (%u)\n", frag);
573
574 if (!frag_skb) {
575 IEEE80211_DEBUG(IEEE80211_DL_RX | IEEE80211_DL_FRAG,
576 "Rx cannot get skb from fragment "
577 "cache (morefrag=%d seq=%u frag=%u)\n",
578 (fc & IEEE80211_FCTL_MOREFRAGS) != 0,
579 WLAN_GET_SEQ_SEQ(sc), frag);
580 goto rx_dropped;
581 }
582
583 flen = skb->len;
584 if (frag != 0)
585 flen -= hdrlen;
586
587 if (frag_skb->tail + flen > frag_skb->end) {
588 printk(KERN_WARNING "%s: host decrypted and "
589 "reassembled frame did not fit skb\n",
590 dev->name);
591 ieee80211_frag_cache_invalidate(ieee, hdr);
592 goto rx_dropped;
593 }
594
595 if (frag == 0) {
596 /* copy first fragment (including full headers) into
597 * beginning of the fragment cache skb */
598 memcpy(skb_put(frag_skb, flen), skb->data, flen);
599 } else {
600 /* append frame payload to the end of the fragment
601 * cache skb */
602 memcpy(skb_put(frag_skb, flen), skb->data + hdrlen,
603 flen);
604 }
605 dev_kfree_skb_any(skb);
606 skb = NULL;
607
608 if (fc & IEEE80211_FCTL_MOREFRAGS) {
609 /* more fragments expected - leave the skb in fragment
610 * cache for now; it will be delivered to upper layers
611 * after all fragments have been received */
612 goto rx_exit;
613 }
614
615 /* this was the last fragment and the frame will be
616 * delivered, so remove skb from fragment cache */
617 skb = frag_skb;
618 hdr = (struct ieee80211_hdr *) skb->data;
619 ieee80211_frag_cache_invalidate(ieee, hdr);
620 }
621
622 /* skb: hdr + (possible reassembled) full MSDU payload; possibly still
623 * encrypted/authenticated */
624 if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
625 ieee80211_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt))
626 goto rx_dropped;
627
628 hdr = (struct ieee80211_hdr *) skb->data;
629 if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep) {
630 if (/*ieee->ieee802_1x &&*/
631 ieee80211_is_eapol_frame(ieee, skb)) {
632#ifdef CONFIG_IEEE80211_DEBUG
633 /* pass unencrypted EAPOL frames even if encryption is
634 * configured */
635 struct eapol *eap = (struct eapol *)(skb->data +
636 24);
637 IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n",
638 eap_get_type(eap->type));
639#endif
640 } else {
641 IEEE80211_DEBUG_DROP(
642 "encryption configured, but RX "
643 "frame not encrypted (SA=" MAC_FMT ")\n",
644 MAC_ARG(hdr->addr2));
645 goto rx_dropped;
646 }
647 }
648
649#ifdef CONFIG_IEEE80211_DEBUG
650 if (crypt && !(fc & IEEE80211_FCTL_WEP) &&
651 ieee80211_is_eapol_frame(ieee, skb)) {
652 struct eapol *eap = (struct eapol *)(skb->data +
653 24);
654 IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n",
655 eap_get_type(eap->type));
656 }
657#endif
658
659 if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep &&
660 !ieee80211_is_eapol_frame(ieee, skb)) {
661 IEEE80211_DEBUG_DROP(
662 "dropped unencrypted RX data "
663 "frame from " MAC_FMT
664 " (drop_unencrypted=1)\n",
665 MAC_ARG(hdr->addr2));
666 goto rx_dropped;
667 }
668
669 /* skb: hdr + (possible reassembled) full plaintext payload */
670
671 payload = skb->data + hdrlen;
672 ethertype = (payload[6] << 8) | payload[7];
673
674#ifdef NOT_YET
675 /* If IEEE 802.1X is used, check whether the port is authorized to send
676 * the received frame. */
677 if (ieee->ieee802_1x && ieee->iw_mode == IW_MODE_MASTER) {
678 if (ethertype == ETH_P_PAE) {
679 printk(KERN_DEBUG "%s: RX: IEEE 802.1X frame\n",
680 dev->name);
681 if (ieee->hostapd && ieee->apdev) {
682 /* Send IEEE 802.1X frames to the user
683 * space daemon for processing */
684 prism2_rx_80211(ieee->apdev, skb, rx_stats,
685 PRISM2_RX_MGMT);
686 ieee->apdevstats.rx_packets++;
687 ieee->apdevstats.rx_bytes += skb->len;
688 goto rx_exit;
689 }
690 } else if (!frame_authorized) {
691 printk(KERN_DEBUG "%s: dropped frame from "
692 "unauthorized port (IEEE 802.1X): "
693 "ethertype=0x%04x\n",
694 dev->name, ethertype);
695 goto rx_dropped;
696 }
697 }
698#endif
699
700 /* convert hdr + possible LLC headers into Ethernet header */
701 if (skb->len - hdrlen >= 8 &&
702 ((memcmp(payload, rfc1042_header, SNAP_SIZE) == 0 &&
703 ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
704 memcmp(payload, bridge_tunnel_header, SNAP_SIZE) == 0)) {
705 /* remove RFC1042 or Bridge-Tunnel encapsulation and
706 * replace EtherType */
707 skb_pull(skb, hdrlen + SNAP_SIZE);
708 memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
709 memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
710 } else {
711 u16 len;
712 /* Leave Ethernet header part of hdr and full payload */
713 skb_pull(skb, hdrlen);
714 len = htons(skb->len);
715 memcpy(skb_push(skb, 2), &len, 2);
716 memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
717 memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
718 }
719
720#ifdef NOT_YET
721 if (wds && ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
722 IEEE80211_FCTL_TODS) &&
723 skb->len >= ETH_HLEN + ETH_ALEN) {
724 /* Non-standard frame: get addr4 from its bogus location after
725 * the payload */
726 memcpy(skb->data + ETH_ALEN,
727 skb->data + skb->len - ETH_ALEN, ETH_ALEN);
728 skb_trim(skb, skb->len - ETH_ALEN);
729 }
730#endif
731
732 stats->rx_packets++;
733 stats->rx_bytes += skb->len;
734
735#ifdef NOT_YET
736 if (ieee->iw_mode == IW_MODE_MASTER && !wds &&
737 ieee->ap->bridge_packets) {
738 if (dst[0] & 0x01) {
739 /* copy multicast frame both to the higher layers and
740 * to the wireless media */
741 ieee->ap->bridged_multicast++;
742 skb2 = skb_clone(skb, GFP_ATOMIC);
743 if (skb2 == NULL)
744 printk(KERN_DEBUG "%s: skb_clone failed for "
745 "multicast frame\n", dev->name);
746 } else if (hostap_is_sta_assoc(ieee->ap, dst)) {
747 /* send frame directly to the associated STA using
748 * wireless media and not passing to higher layers */
749 ieee->ap->bridged_unicast++;
750 skb2 = skb;
751 skb = NULL;
752 }
753 }
754
755 if (skb2 != NULL) {
756 /* send to wireless media */
757 skb2->protocol = __constant_htons(ETH_P_802_3);
758 skb2->mac.raw = skb2->nh.raw = skb2->data;
759 /* skb2->nh.raw = skb2->data + ETH_HLEN; */
760 skb2->dev = dev;
761 dev_queue_xmit(skb2);
762 }
763
764#endif
765
766 if (skb) {
767 skb->protocol = eth_type_trans(skb, dev);
768 memset(skb->cb, 0, sizeof(skb->cb));
769 skb->dev = dev;
770 skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */
771 netif_rx(skb);
772 }
773
774 rx_exit:
775#ifdef NOT_YET
776 if (sta)
777 hostap_handle_sta_release(sta);
778#endif
779 return 1;
780
781 rx_dropped:
782 stats->rx_dropped++;
783
784 /* Returning 0 indicates to caller that we have not handled the SKB--
785 * so it is still allocated and can be used again by underlying
786 * hardware as a DMA target */
787 return 0;
788}
789
790#define MGMT_FRAME_FIXED_PART_LENGTH 0x24
791
792static inline int ieee80211_is_ofdm_rate(u8 rate)
793{
794 switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
795 case IEEE80211_OFDM_RATE_6MB:
796 case IEEE80211_OFDM_RATE_9MB:
797 case IEEE80211_OFDM_RATE_12MB:
798 case IEEE80211_OFDM_RATE_18MB:
799 case IEEE80211_OFDM_RATE_24MB:
800 case IEEE80211_OFDM_RATE_36MB:
801 case IEEE80211_OFDM_RATE_48MB:
802 case IEEE80211_OFDM_RATE_54MB:
803 return 1;
804 }
805 return 0;
806}
807
808
809static inline int ieee80211_network_init(
810 struct ieee80211_device *ieee,
811 struct ieee80211_probe_response *beacon,
812 struct ieee80211_network *network,
813 struct ieee80211_rx_stats *stats)
814{
815#ifdef CONFIG_IEEE80211_DEBUG
816 char rates_str[64];
817 char *p;
818#endif
819 struct ieee80211_info_element *info_element;
820 u16 left;
821 u8 i;
822
823 /* Pull out fixed field data */
824 memcpy(network->bssid, beacon->header.addr3, ETH_ALEN);
825 network->capability = beacon->capability;
826 network->last_scanned = jiffies;
827 network->time_stamp[0] = beacon->time_stamp[0];
828 network->time_stamp[1] = beacon->time_stamp[1];
829 network->beacon_interval = beacon->beacon_interval;
830 /* Where to pull this? beacon->listen_interval;*/
831 network->listen_interval = 0x0A;
832 network->rates_len = network->rates_ex_len = 0;
833 network->last_associate = 0;
834 network->ssid_len = 0;
835 network->flags = 0;
836 network->atim_window = 0;
837
838 if (stats->freq == IEEE80211_52GHZ_BAND) {
839 /* for A band (No DS info) */
840 network->channel = stats->received_channel;
841 } else
842 network->flags |= NETWORK_HAS_CCK;
843
844 network->wpa_ie_len = 0;
845 network->rsn_ie_len = 0;
846
847 info_element = &beacon->info_element;
848 left = stats->len - ((void *)info_element - (void *)beacon);
849 while (left >= sizeof(struct ieee80211_info_element_hdr)) {
850 if (sizeof(struct ieee80211_info_element_hdr) + info_element->len > left) {
851 IEEE80211_DEBUG_SCAN("SCAN: parse failed: info_element->len + 2 > left : info_element->len+2=%d left=%d.\n",
852 info_element->len + sizeof(struct ieee80211_info_element),
853 left);
854 return 1;
855 }
856
857 switch (info_element->id) {
858 case MFIE_TYPE_SSID:
859 if (ieee80211_is_empty_essid(info_element->data,
860 info_element->len)) {
861 network->flags |= NETWORK_EMPTY_ESSID;
862 break;
863 }
864
865 network->ssid_len = min(info_element->len,
866 (u8)IW_ESSID_MAX_SIZE);
867 memcpy(network->ssid, info_element->data, network->ssid_len);
868 if (network->ssid_len < IW_ESSID_MAX_SIZE)
869 memset(network->ssid + network->ssid_len, 0,
870 IW_ESSID_MAX_SIZE - network->ssid_len);
871
872 IEEE80211_DEBUG_SCAN("MFIE_TYPE_SSID: '%s' len=%d.\n",
873 network->ssid, network->ssid_len);
874 break;
875
876 case MFIE_TYPE_RATES:
877#ifdef CONFIG_IEEE80211_DEBUG
878 p = rates_str;
879#endif
880 network->rates_len = min(info_element->len, MAX_RATES_LENGTH);
881 for (i = 0; i < network->rates_len; i++) {
882 network->rates[i] = info_element->data[i];
883#ifdef CONFIG_IEEE80211_DEBUG
884 p += snprintf(p, sizeof(rates_str) - (p - rates_str), "%02X ", network->rates[i]);
885#endif
886 if (ieee80211_is_ofdm_rate(info_element->data[i])) {
887 network->flags |= NETWORK_HAS_OFDM;
888 if (info_element->data[i] &
889 IEEE80211_BASIC_RATE_MASK)
890 network->flags &=
891 ~NETWORK_HAS_CCK;
892 }
893 }
894
895 IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES: '%s' (%d)\n",
896 rates_str, network->rates_len);
897 break;
898
899 case MFIE_TYPE_RATES_EX:
900#ifdef CONFIG_IEEE80211_DEBUG
901 p = rates_str;
902#endif
903 network->rates_ex_len = min(info_element->len, MAX_RATES_EX_LENGTH);
904 for (i = 0; i < network->rates_ex_len; i++) {
905 network->rates_ex[i] = info_element->data[i];
906#ifdef CONFIG_IEEE80211_DEBUG
907 p += snprintf(p, sizeof(rates_str) - (p - rates_str), "%02X ", network->rates[i]);
908#endif
909 if (ieee80211_is_ofdm_rate(info_element->data[i])) {
910 network->flags |= NETWORK_HAS_OFDM;
911 if (info_element->data[i] &
912 IEEE80211_BASIC_RATE_MASK)
913 network->flags &=
914 ~NETWORK_HAS_CCK;
915 }
916 }
917
918 IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES_EX: '%s' (%d)\n",
919 rates_str, network->rates_ex_len);
920 break;
921
922 case MFIE_TYPE_DS_SET:
923 IEEE80211_DEBUG_SCAN("MFIE_TYPE_DS_SET: %d\n",
924 info_element->data[0]);
925 if (stats->freq == IEEE80211_24GHZ_BAND)
926 network->channel = info_element->data[0];
927 break;
928
929 case MFIE_TYPE_FH_SET:
930 IEEE80211_DEBUG_SCAN("MFIE_TYPE_FH_SET: ignored\n");
931 break;
932
933 case MFIE_TYPE_CF_SET:
934 IEEE80211_DEBUG_SCAN("MFIE_TYPE_CF_SET: ignored\n");
935 break;
936
937 case MFIE_TYPE_TIM:
938 IEEE80211_DEBUG_SCAN("MFIE_TYPE_TIM: ignored\n");
939 break;
940
941 case MFIE_TYPE_IBSS_SET:
942 IEEE80211_DEBUG_SCAN("MFIE_TYPE_IBSS_SET: ignored\n");
943 break;
944
945 case MFIE_TYPE_CHALLENGE:
946 IEEE80211_DEBUG_SCAN("MFIE_TYPE_CHALLENGE: ignored\n");
947 break;
948
949 case MFIE_TYPE_GENERIC:
950 IEEE80211_DEBUG_SCAN("MFIE_TYPE_GENERIC: %d bytes\n",
951 info_element->len);
952 if (info_element->len >= 4 &&
953 info_element->data[0] == 0x00 &&
954 info_element->data[1] == 0x50 &&
955 info_element->data[2] == 0xf2 &&
956 info_element->data[3] == 0x01) {
957 network->wpa_ie_len = min(info_element->len + 2,
958 MAX_WPA_IE_LEN);
959 memcpy(network->wpa_ie, info_element,
960 network->wpa_ie_len);
961 }
962 break;
963
964 case MFIE_TYPE_RSN:
965 IEEE80211_DEBUG_SCAN("MFIE_TYPE_RSN: %d bytes\n",
966 info_element->len);
967 network->rsn_ie_len = min(info_element->len + 2,
968 MAX_WPA_IE_LEN);
969 memcpy(network->rsn_ie, info_element,
970 network->rsn_ie_len);
971 break;
972
973 default:
974 IEEE80211_DEBUG_SCAN("unsupported IE %d\n",
975 info_element->id);
976 break;
977 }
978
979 left -= sizeof(struct ieee80211_info_element_hdr) +
980 info_element->len;
981 info_element = (struct ieee80211_info_element *)
982 &info_element->data[info_element->len];
983 }
984
985 network->mode = 0;
986 if (stats->freq == IEEE80211_52GHZ_BAND)
987 network->mode = IEEE_A;
988 else {
989 if (network->flags & NETWORK_HAS_OFDM)
990 network->mode |= IEEE_G;
991 if (network->flags & NETWORK_HAS_CCK)
992 network->mode |= IEEE_B;
993 }
994
995 if (network->mode == 0) {
996 IEEE80211_DEBUG_SCAN("Filtered out '%s (" MAC_FMT ")' "
997 "network.\n",
998 escape_essid(network->ssid,
999 network->ssid_len),
1000 MAC_ARG(network->bssid));
1001 return 1;
1002 }
1003
1004 if (ieee80211_is_empty_essid(network->ssid, network->ssid_len))
1005 network->flags |= NETWORK_EMPTY_ESSID;
1006
1007 memcpy(&network->stats, stats, sizeof(network->stats));
1008
1009 return 0;
1010}
1011
1012static inline int is_same_network(struct ieee80211_network *src,
1013 struct ieee80211_network *dst)
1014{
1015 /* A network is only a duplicate if the channel, BSSID, and ESSID
1016 * all match. We treat all <hidden> with the same BSSID and channel
1017 * as one network */
1018 return ((src->ssid_len == dst->ssid_len) &&
1019 (src->channel == dst->channel) &&
1020 !memcmp(src->bssid, dst->bssid, ETH_ALEN) &&
1021 !memcmp(src->ssid, dst->ssid, src->ssid_len));
1022}
1023
1024static inline void update_network(struct ieee80211_network *dst,
1025 struct ieee80211_network *src)
1026{
1027 memcpy(&dst->stats, &src->stats, sizeof(struct ieee80211_rx_stats));
1028 dst->capability = src->capability;
1029 memcpy(dst->rates, src->rates, src->rates_len);
1030 dst->rates_len = src->rates_len;
1031 memcpy(dst->rates_ex, src->rates_ex, src->rates_ex_len);
1032 dst->rates_ex_len = src->rates_ex_len;
1033
1034 dst->mode = src->mode;
1035 dst->flags = src->flags;
1036 dst->time_stamp[0] = src->time_stamp[0];
1037 dst->time_stamp[1] = src->time_stamp[1];
1038
1039 dst->beacon_interval = src->beacon_interval;
1040 dst->listen_interval = src->listen_interval;
1041 dst->atim_window = src->atim_window;
1042
1043 memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len);
1044 dst->wpa_ie_len = src->wpa_ie_len;
1045 memcpy(dst->rsn_ie, src->rsn_ie, src->rsn_ie_len);
1046 dst->rsn_ie_len = src->rsn_ie_len;
1047
1048 dst->last_scanned = jiffies;
1049 /* dst->last_associate is not overwritten */
1050}
1051
1052static inline void ieee80211_process_probe_response(
1053 struct ieee80211_device *ieee,
1054 struct ieee80211_probe_response *beacon,
1055 struct ieee80211_rx_stats *stats)
1056{
1057 struct ieee80211_network network;
1058 struct ieee80211_network *target;
1059 struct ieee80211_network *oldest = NULL;
1060#ifdef CONFIG_IEEE80211_DEBUG
1061 struct ieee80211_info_element *info_element = &beacon->info_element;
1062#endif
1063 unsigned long flags;
1064
1065 IEEE80211_DEBUG_SCAN(
1066 "'%s' (" MAC_FMT "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
1067 escape_essid(info_element->data, info_element->len),
1068 MAC_ARG(beacon->header.addr3),
1069 (beacon->capability & (1<<0xf)) ? '1' : '0',
1070 (beacon->capability & (1<<0xe)) ? '1' : '0',
1071 (beacon->capability & (1<<0xd)) ? '1' : '0',
1072 (beacon->capability & (1<<0xc)) ? '1' : '0',
1073 (beacon->capability & (1<<0xb)) ? '1' : '0',
1074 (beacon->capability & (1<<0xa)) ? '1' : '0',
1075 (beacon->capability & (1<<0x9)) ? '1' : '0',
1076 (beacon->capability & (1<<0x8)) ? '1' : '0',
1077 (beacon->capability & (1<<0x7)) ? '1' : '0',
1078 (beacon->capability & (1<<0x6)) ? '1' : '0',
1079 (beacon->capability & (1<<0x5)) ? '1' : '0',
1080 (beacon->capability & (1<<0x4)) ? '1' : '0',
1081 (beacon->capability & (1<<0x3)) ? '1' : '0',
1082 (beacon->capability & (1<<0x2)) ? '1' : '0',
1083 (beacon->capability & (1<<0x1)) ? '1' : '0',
1084 (beacon->capability & (1<<0x0)) ? '1' : '0');
1085
1086 if (ieee80211_network_init(ieee, beacon, &network, stats)) {
1087 IEEE80211_DEBUG_SCAN("Dropped '%s' (" MAC_FMT ") via %s.\n",
1088 escape_essid(info_element->data,
1089 info_element->len),
1090 MAC_ARG(beacon->header.addr3),
1091 WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
1092 IEEE80211_STYPE_PROBE_RESP ?
1093 "PROBE RESPONSE" : "BEACON");
1094 return;
1095 }
1096
1097 /* The network parsed correctly -- so now we scan our known networks
1098 * to see if we can find it in our list.
1099 *
1100 * NOTE: This search is definitely not optimized. Once its doing
1101 * the "right thing" we'll optimize it for efficiency if
1102 * necessary */
1103
1104 /* Search for this entry in the list and update it if it is
1105 * already there. */
1106
1107 spin_lock_irqsave(&ieee->lock, flags);
1108
1109 list_for_each_entry(target, &ieee->network_list, list) {
1110 if (is_same_network(target, &network))
1111 break;
1112
1113 if ((oldest == NULL) ||
1114 (target->last_scanned < oldest->last_scanned))
1115 oldest = target;
1116 }
1117
1118 /* If we didn't find a match, then get a new network slot to initialize
1119 * with this beacon's information */
1120 if (&target->list == &ieee->network_list) {
1121 if (list_empty(&ieee->network_free_list)) {
1122 /* If there are no more slots, expire the oldest */
1123 list_del(&oldest->list);
1124 target = oldest;
1125 IEEE80211_DEBUG_SCAN("Expired '%s' (" MAC_FMT ") from "
1126 "network list.\n",
1127 escape_essid(target->ssid,
1128 target->ssid_len),
1129 MAC_ARG(target->bssid));
1130 } else {
1131 /* Otherwise just pull from the free list */
1132 target = list_entry(ieee->network_free_list.next,
1133 struct ieee80211_network, list);
1134 list_del(ieee->network_free_list.next);
1135 }
1136
1137
1138#ifdef CONFIG_IEEE80211_DEBUG
1139 IEEE80211_DEBUG_SCAN("Adding '%s' (" MAC_FMT ") via %s.\n",
1140 escape_essid(network.ssid,
1141 network.ssid_len),
1142 MAC_ARG(network.bssid),
1143 WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
1144 IEEE80211_STYPE_PROBE_RESP ?
1145 "PROBE RESPONSE" : "BEACON");
1146#endif
1147 memcpy(target, &network, sizeof(*target));
1148 list_add_tail(&target->list, &ieee->network_list);
1149 } else {
1150 IEEE80211_DEBUG_SCAN("Updating '%s' (" MAC_FMT ") via %s.\n",
1151 escape_essid(target->ssid,
1152 target->ssid_len),
1153 MAC_ARG(target->bssid),
1154 WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
1155 IEEE80211_STYPE_PROBE_RESP ?
1156 "PROBE RESPONSE" : "BEACON");
1157 update_network(target, &network);
1158 }
1159
1160 spin_unlock_irqrestore(&ieee->lock, flags);
1161}
1162
1163void ieee80211_rx_mgt(struct ieee80211_device *ieee,
1164 struct ieee80211_hdr *header,
1165 struct ieee80211_rx_stats *stats)
1166{
1167 switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
1168 case IEEE80211_STYPE_ASSOC_RESP:
1169 IEEE80211_DEBUG_MGMT("received ASSOCIATION RESPONSE (%d)\n",
1170 WLAN_FC_GET_STYPE(header->frame_ctl));
1171 break;
1172
1173 case IEEE80211_STYPE_REASSOC_RESP:
1174 IEEE80211_DEBUG_MGMT("received REASSOCIATION RESPONSE (%d)\n",
1175 WLAN_FC_GET_STYPE(header->frame_ctl));
1176 break;
1177
1178 case IEEE80211_STYPE_PROBE_RESP:
1179 IEEE80211_DEBUG_MGMT("received PROBE RESPONSE (%d)\n",
1180 WLAN_FC_GET_STYPE(header->frame_ctl));
1181 IEEE80211_DEBUG_SCAN("Probe response\n");
1182 ieee80211_process_probe_response(
1183 ieee, (struct ieee80211_probe_response *)header, stats);
1184 break;
1185
1186 case IEEE80211_STYPE_BEACON:
1187 IEEE80211_DEBUG_MGMT("received BEACON (%d)\n",
1188 WLAN_FC_GET_STYPE(header->frame_ctl));
1189 IEEE80211_DEBUG_SCAN("Beacon\n");
1190 ieee80211_process_probe_response(
1191 ieee, (struct ieee80211_probe_response *)header, stats);
1192 break;
1193
1194 default:
1195 IEEE80211_DEBUG_MGMT("received UNKNOWN (%d)\n",
1196 WLAN_FC_GET_STYPE(header->frame_ctl));
1197 IEEE80211_WARNING("%s: Unknown management packet: %d\n",
1198 ieee->dev->name,
1199 WLAN_FC_GET_STYPE(header->frame_ctl));
1200 break;
1201 }
1202}
1203
1204
1205EXPORT_SYMBOL(ieee80211_rx_mgt);
1206EXPORT_SYMBOL(ieee80211_rx);
diff --git a/net/ieee80211/ieee80211_tx.c b/net/ieee80211/ieee80211_tx.c
new file mode 100644
index 000000000000..d70e6b82715e
--- /dev/null
+++ b/net/ieee80211/ieee80211_tx.c
@@ -0,0 +1,448 @@
1/******************************************************************************
2
3 Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
4
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of version 2 of the GNU General Public License as
7 published by the Free Software Foundation.
8
9 This program is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 more details.
13
14 You should have received a copy of the GNU General Public License along with
15 this program; if not, write to the Free Software Foundation, Inc., 59
16 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18 The full GNU General Public License is included in this distribution in the
19 file called LICENSE.
20
21 Contact Information:
22 James P. Ketrenos <ipw2100-admin@linux.intel.com>
23 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24
25******************************************************************************/
26#include <linux/compiler.h>
27#include <linux/config.h>
28#include <linux/errno.h>
29#include <linux/if_arp.h>
30#include <linux/in6.h>
31#include <linux/in.h>
32#include <linux/ip.h>
33#include <linux/kernel.h>
34#include <linux/module.h>
35#include <linux/netdevice.h>
36#include <linux/pci.h>
37#include <linux/proc_fs.h>
38#include <linux/skbuff.h>
39#include <linux/slab.h>
40#include <linux/tcp.h>
41#include <linux/types.h>
42#include <linux/version.h>
43#include <linux/wireless.h>
44#include <linux/etherdevice.h>
45#include <asm/uaccess.h>
46
47#include <net/ieee80211.h>
48
49
50/*
51
52
53802.11 Data Frame
54
55 ,-------------------------------------------------------------------.
56Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 |
57 |------|------|---------|---------|---------|------|---------|------|
58Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | Frame | fcs |
59 | | tion | (BSSID) | | | ence | data | |
60 `--------------------------------------------------| |------'
61Total: 28 non-data bytes `----.----'
62 |
63 .- 'Frame data' expands to <---------------------------'
64 |
65 V
66 ,---------------------------------------------------.
67Bytes | 1 | 1 | 1 | 3 | 2 | 0-2304 |
68 |------|------|---------|----------|------|---------|
69Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP |
70 | DSAP | SSAP | | | | Packet |
71 | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8| | |
72 `-----------------------------------------| |
73Total: 8 non-data bytes `----.----'
74 |
75 .- 'IP Packet' expands, if WEP enabled, to <--'
76 |
77 V
78 ,-----------------------.
79Bytes | 4 | 0-2296 | 4 |
80 |-----|-----------|-----|
81Desc. | IV | Encrypted | ICV |
82 | | IP Packet | |
83 `-----------------------'
84Total: 8 non-data bytes
85
86
87802.3 Ethernet Data Frame
88
89 ,-----------------------------------------.
90Bytes | 6 | 6 | 2 | Variable | 4 |
91 |-------|-------|------|-----------|------|
92Desc. | Dest. | Source| Type | IP Packet | fcs |
93 | MAC | MAC | | | |
94 `-----------------------------------------'
95Total: 18 non-data bytes
96
97In the event that fragmentation is required, the incoming payload is split into
98N parts of size ieee->fts. The first fragment contains the SNAP header and the
99remaining packets are just data.
100
101If encryption is enabled, each fragment payload size is reduced by enough space
102to add the prefix and postfix (IV and ICV totalling 8 bytes in the case of WEP)
103So if you have 1500 bytes of payload with ieee->fts set to 500 without
104encryption it will take 3 frames. With WEP it will take 4 frames as the
105payload of each frame is reduced to 492 bytes.
106
107* SKB visualization
108*
109* ,- skb->data
110* |
111* | ETHERNET HEADER ,-<-- PAYLOAD
112* | | 14 bytes from skb->data
113* | 2 bytes for Type --> ,T. | (sizeof ethhdr)
114* | | | |
115* |,-Dest.--. ,--Src.---. | | |
116* | 6 bytes| | 6 bytes | | | |
117* v | | | | | |
118* 0 | v 1 | v | v 2
119* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
120* ^ | ^ | ^ |
121* | | | | | |
122* | | | | `T' <---- 2 bytes for Type
123* | | | |
124* | | '---SNAP--' <-------- 6 bytes for SNAP
125* | |
126* `-IV--' <-------------------- 4 bytes for IV (WEP)
127*
128* SNAP HEADER
129*
130*/
131
132static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
133static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
134
135static inline int ieee80211_put_snap(u8 *data, u16 h_proto)
136{
137 struct ieee80211_snap_hdr *snap;
138 u8 *oui;
139
140 snap = (struct ieee80211_snap_hdr *)data;
141 snap->dsap = 0xaa;
142 snap->ssap = 0xaa;
143 snap->ctrl = 0x03;
144
145 if (h_proto == 0x8137 || h_proto == 0x80f3)
146 oui = P802_1H_OUI;
147 else
148 oui = RFC1042_OUI;
149 snap->oui[0] = oui[0];
150 snap->oui[1] = oui[1];
151 snap->oui[2] = oui[2];
152
153 *(u16 *)(data + SNAP_SIZE) = htons(h_proto);
154
155 return SNAP_SIZE + sizeof(u16);
156}
157
158static inline int ieee80211_encrypt_fragment(
159 struct ieee80211_device *ieee,
160 struct sk_buff *frag,
161 int hdr_len)
162{
163 struct ieee80211_crypt_data* crypt = ieee->crypt[ieee->tx_keyidx];
164 int res;
165
166#ifdef CONFIG_IEEE80211_CRYPT_TKIP
167 struct ieee80211_hdr *header;
168
169 if (ieee->tkip_countermeasures &&
170 crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
171 header = (struct ieee80211_hdr *) frag->data;
172 if (net_ratelimit()) {
173 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
174 "TX packet to " MAC_FMT "\n",
175 ieee->dev->name, MAC_ARG(header->addr1));
176 }
177 return -1;
178 }
179#endif
180 /* To encrypt, frame format is:
181 * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */
182
183 // PR: FIXME: Copied from hostap. Check fragmentation/MSDU/MPDU encryption.
184 /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
185 * call both MSDU and MPDU encryption functions from here. */
186 atomic_inc(&crypt->refcnt);
187 res = 0;
188 if (crypt->ops->encrypt_msdu)
189 res = crypt->ops->encrypt_msdu(frag, hdr_len, crypt->priv);
190 if (res == 0 && crypt->ops->encrypt_mpdu)
191 res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv);
192
193 atomic_dec(&crypt->refcnt);
194 if (res < 0) {
195 printk(KERN_INFO "%s: Encryption failed: len=%d.\n",
196 ieee->dev->name, frag->len);
197 ieee->ieee_stats.tx_discards++;
198 return -1;
199 }
200
201 return 0;
202}
203
204
205void ieee80211_txb_free(struct ieee80211_txb *txb) {
206 int i;
207 if (unlikely(!txb))
208 return;
209 for (i = 0; i < txb->nr_frags; i++)
210 if (txb->fragments[i])
211 dev_kfree_skb_any(txb->fragments[i]);
212 kfree(txb);
213}
214
215struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
216 int gfp_mask)
217{
218 struct ieee80211_txb *txb;
219 int i;
220 txb = kmalloc(
221 sizeof(struct ieee80211_txb) + (sizeof(u8*) * nr_frags),
222 gfp_mask);
223 if (!txb)
224 return NULL;
225
226 memset(txb, sizeof(struct ieee80211_txb), 0);
227 txb->nr_frags = nr_frags;
228 txb->frag_size = txb_size;
229
230 for (i = 0; i < nr_frags; i++) {
231 txb->fragments[i] = dev_alloc_skb(txb_size);
232 if (unlikely(!txb->fragments[i])) {
233 i--;
234 break;
235 }
236 }
237 if (unlikely(i != nr_frags)) {
238 while (i >= 0)
239 dev_kfree_skb_any(txb->fragments[i--]);
240 kfree(txb);
241 return NULL;
242 }
243 return txb;
244}
245
246/* SKBs are added to the ieee->tx_queue. */
247int ieee80211_xmit(struct sk_buff *skb,
248 struct net_device *dev)
249{
250 struct ieee80211_device *ieee = netdev_priv(dev);
251 struct ieee80211_txb *txb = NULL;
252 struct ieee80211_hdr *frag_hdr;
253 int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
254 unsigned long flags;
255 struct net_device_stats *stats = &ieee->stats;
256 int ether_type, encrypt;
257 int bytes, fc, hdr_len;
258 struct sk_buff *skb_frag;
259 struct ieee80211_hdr header = { /* Ensure zero initialized */
260 .duration_id = 0,
261 .seq_ctl = 0
262 };
263 u8 dest[ETH_ALEN], src[ETH_ALEN];
264
265 struct ieee80211_crypt_data* crypt;
266
267 spin_lock_irqsave(&ieee->lock, flags);
268
269 /* If there is no driver handler to take the TXB, dont' bother
270 * creating it... */
271 if (!ieee->hard_start_xmit) {
272 printk(KERN_WARNING "%s: No xmit handler.\n",
273 ieee->dev->name);
274 goto success;
275 }
276
277 if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
278 printk(KERN_WARNING "%s: skb too small (%d).\n",
279 ieee->dev->name, skb->len);
280 goto success;
281 }
282
283 ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
284
285 crypt = ieee->crypt[ieee->tx_keyidx];
286
287 encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
288 ieee->host_encrypt && crypt && crypt->ops;
289
290 if (!encrypt && ieee->ieee802_1x &&
291 ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
292 stats->tx_dropped++;
293 goto success;
294 }
295
296#ifdef CONFIG_IEEE80211_DEBUG
297 if (crypt && !encrypt && ether_type == ETH_P_PAE) {
298 struct eapol *eap = (struct eapol *)(skb->data +
299 sizeof(struct ethhdr) - SNAP_SIZE - sizeof(u16));
300 IEEE80211_DEBUG_EAP("TX: IEEE 802.11 EAPOL frame: %s\n",
301 eap_get_type(eap->type));
302 }
303#endif
304
305 /* Save source and destination addresses */
306 memcpy(&dest, skb->data, ETH_ALEN);
307 memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN);
308
309 /* Advance the SKB to the start of the payload */
310 skb_pull(skb, sizeof(struct ethhdr));
311
312 /* Determine total amount of storage required for TXB packets */
313 bytes = skb->len + SNAP_SIZE + sizeof(u16);
314
315 if (encrypt)
316 fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA |
317 IEEE80211_FCTL_WEP;
318 else
319 fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA;
320
321 if (ieee->iw_mode == IW_MODE_INFRA) {
322 fc |= IEEE80211_FCTL_TODS;
323 /* To DS: Addr1 = BSSID, Addr2 = SA,
324 Addr3 = DA */
325 memcpy(&header.addr1, ieee->bssid, ETH_ALEN);
326 memcpy(&header.addr2, &src, ETH_ALEN);
327 memcpy(&header.addr3, &dest, ETH_ALEN);
328 } else if (ieee->iw_mode == IW_MODE_ADHOC) {
329 /* not From/To DS: Addr1 = DA, Addr2 = SA,
330 Addr3 = BSSID */
331 memcpy(&header.addr1, dest, ETH_ALEN);
332 memcpy(&header.addr2, src, ETH_ALEN);
333 memcpy(&header.addr3, ieee->bssid, ETH_ALEN);
334 }
335 header.frame_ctl = cpu_to_le16(fc);
336 hdr_len = IEEE80211_3ADDR_LEN;
337
338 /* Determine fragmentation size based on destination (multicast
339 * and broadcast are not fragmented) */
340 if (is_multicast_ether_addr(dest) ||
341 is_broadcast_ether_addr(dest))
342 frag_size = MAX_FRAG_THRESHOLD;
343 else
344 frag_size = ieee->fts;
345
346 /* Determine amount of payload per fragment. Regardless of if
347 * this stack is providing the full 802.11 header, one will
348 * eventually be affixed to this fragment -- so we must account for
349 * it when determining the amount of payload space. */
350 bytes_per_frag = frag_size - IEEE80211_3ADDR_LEN;
351 if (ieee->config &
352 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
353 bytes_per_frag -= IEEE80211_FCS_LEN;
354
355 /* Each fragment may need to have room for encryptiong pre/postfix */
356 if (encrypt)
357 bytes_per_frag -= crypt->ops->extra_prefix_len +
358 crypt->ops->extra_postfix_len;
359
360 /* Number of fragments is the total bytes_per_frag /
361 * payload_per_fragment */
362 nr_frags = bytes / bytes_per_frag;
363 bytes_last_frag = bytes % bytes_per_frag;
364 if (bytes_last_frag)
365 nr_frags++;
366 else
367 bytes_last_frag = bytes_per_frag;
368
369 /* When we allocate the TXB we allocate enough space for the reserve
370 * and full fragment bytes (bytes_per_frag doesn't include prefix,
371 * postfix, header, FCS, etc.) */
372 txb = ieee80211_alloc_txb(nr_frags, frag_size, GFP_ATOMIC);
373 if (unlikely(!txb)) {
374 printk(KERN_WARNING "%s: Could not allocate TXB\n",
375 ieee->dev->name);
376 goto failed;
377 }
378 txb->encrypted = encrypt;
379 txb->payload_size = bytes;
380
381 for (i = 0; i < nr_frags; i++) {
382 skb_frag = txb->fragments[i];
383
384 if (encrypt)
385 skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
386
387 frag_hdr = (struct ieee80211_hdr *)skb_put(skb_frag, hdr_len);
388 memcpy(frag_hdr, &header, hdr_len);
389
390 /* If this is not the last fragment, then add the MOREFRAGS
391 * bit to the frame control */
392 if (i != nr_frags - 1) {
393 frag_hdr->frame_ctl = cpu_to_le16(
394 fc | IEEE80211_FCTL_MOREFRAGS);
395 bytes = bytes_per_frag;
396 } else {
397 /* The last fragment takes the remaining length */
398 bytes = bytes_last_frag;
399 }
400
401 /* Put a SNAP header on the first fragment */
402 if (i == 0) {
403 ieee80211_put_snap(
404 skb_put(skb_frag, SNAP_SIZE + sizeof(u16)),
405 ether_type);
406 bytes -= SNAP_SIZE + sizeof(u16);
407 }
408
409 memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
410
411 /* Advance the SKB... */
412 skb_pull(skb, bytes);
413
414 /* Encryption routine will move the header forward in order
415 * to insert the IV between the header and the payload */
416 if (encrypt)
417 ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
418 if (ieee->config &
419 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
420 skb_put(skb_frag, 4);
421 }
422
423
424 success:
425 spin_unlock_irqrestore(&ieee->lock, flags);
426
427 dev_kfree_skb_any(skb);
428
429 if (txb) {
430 if ((*ieee->hard_start_xmit)(txb, dev) == 0) {
431 stats->tx_packets++;
432 stats->tx_bytes += txb->payload_size;
433 return 0;
434 }
435 ieee80211_txb_free(txb);
436 }
437
438 return 0;
439
440 failed:
441 spin_unlock_irqrestore(&ieee->lock, flags);
442 netif_stop_queue(dev);
443 stats->tx_errors++;
444 return 1;
445
446}
447
448EXPORT_SYMBOL(ieee80211_txb_free);
diff --git a/net/ieee80211/ieee80211_wx.c b/net/ieee80211/ieee80211_wx.c
new file mode 100644
index 000000000000..25a868c2e2f7
--- /dev/null
+++ b/net/ieee80211/ieee80211_wx.c
@@ -0,0 +1,471 @@
1/******************************************************************************
2
3 Copyright(c) 2004 Intel Corporation. All rights reserved.
4
5 Portions of this file are based on the WEP enablement code provided by the
6 Host AP project hostap-drivers v0.1.3
7 Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
8 <jkmaline@cc.hut.fi>
9 Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
10
11 This program is free software; you can redistribute it and/or modify it
12 under the terms of version 2 of the GNU General Public License as
13 published by the Free Software Foundation.
14
15 This program is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18 more details.
19
20 You should have received a copy of the GNU General Public License along with
21 this program; if not, write to the Free Software Foundation, Inc., 59
22 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
24 The full GNU General Public License is included in this distribution in the
25 file called LICENSE.
26
27 Contact Information:
28 James P. Ketrenos <ipw2100-admin@linux.intel.com>
29 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30
31******************************************************************************/
32#include <linux/wireless.h>
33#include <linux/version.h>
34#include <linux/kmod.h>
35#include <linux/module.h>
36
37#include <net/ieee80211.h>
38static const char *ieee80211_modes[] = {
39 "?", "a", "b", "ab", "g", "ag", "bg", "abg"
40};
41
42#define MAX_CUSTOM_LEN 64
43static inline char *ipw2100_translate_scan(struct ieee80211_device *ieee,
44 char *start, char *stop,
45 struct ieee80211_network *network)
46{
47 char custom[MAX_CUSTOM_LEN];
48 char *p;
49 struct iw_event iwe;
50 int i, j;
51 u8 max_rate, rate;
52
53 /* First entry *MUST* be the AP MAC address */
54 iwe.cmd = SIOCGIWAP;
55 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
56 memcpy(iwe.u.ap_addr.sa_data, network->bssid, ETH_ALEN);
57 start = iwe_stream_add_event(start, stop, &iwe, IW_EV_ADDR_LEN);
58
59 /* Remaining entries will be displayed in the order we provide them */
60
61 /* Add the ESSID */
62 iwe.cmd = SIOCGIWESSID;
63 iwe.u.data.flags = 1;
64 if (network->flags & NETWORK_EMPTY_ESSID) {
65 iwe.u.data.length = sizeof("<hidden>");
66 start = iwe_stream_add_point(start, stop, &iwe, "<hidden>");
67 } else {
68 iwe.u.data.length = min(network->ssid_len, (u8)32);
69 start = iwe_stream_add_point(start, stop, &iwe, network->ssid);
70 }
71
72 /* Add the protocol name */
73 iwe.cmd = SIOCGIWNAME;
74 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11%s", ieee80211_modes[network->mode]);
75 start = iwe_stream_add_event(start, stop, &iwe, IW_EV_CHAR_LEN);
76
77 /* Add mode */
78 iwe.cmd = SIOCGIWMODE;
79 if (network->capability &
80 (WLAN_CAPABILITY_BSS | WLAN_CAPABILITY_IBSS)) {
81 if (network->capability & WLAN_CAPABILITY_BSS)
82 iwe.u.mode = IW_MODE_MASTER;
83 else
84 iwe.u.mode = IW_MODE_ADHOC;
85
86 start = iwe_stream_add_event(start, stop, &iwe,
87 IW_EV_UINT_LEN);
88 }
89
90 /* Add frequency/channel */
91 iwe.cmd = SIOCGIWFREQ;
92/* iwe.u.freq.m = ieee80211_frequency(network->channel, network->mode);
93 iwe.u.freq.e = 3; */
94 iwe.u.freq.m = network->channel;
95 iwe.u.freq.e = 0;
96 iwe.u.freq.i = 0;
97 start = iwe_stream_add_event(start, stop, &iwe, IW_EV_FREQ_LEN);
98
99 /* Add encryption capability */
100 iwe.cmd = SIOCGIWENCODE;
101 if (network->capability & WLAN_CAPABILITY_PRIVACY)
102 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
103 else
104 iwe.u.data.flags = IW_ENCODE_DISABLED;
105 iwe.u.data.length = 0;
106 start = iwe_stream_add_point(start, stop, &iwe, network->ssid);
107
108 /* Add basic and extended rates */
109 max_rate = 0;
110 p = custom;
111 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
112 for (i = 0, j = 0; i < network->rates_len; ) {
113 if (j < network->rates_ex_len &&
114 ((network->rates_ex[j] & 0x7F) <
115 (network->rates[i] & 0x7F)))
116 rate = network->rates_ex[j++] & 0x7F;
117 else
118 rate = network->rates[i++] & 0x7F;
119 if (rate > max_rate)
120 max_rate = rate;
121 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
122 "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
123 }
124 for (; j < network->rates_ex_len; j++) {
125 rate = network->rates_ex[j] & 0x7F;
126 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
127 "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
128 if (rate > max_rate)
129 max_rate = rate;
130 }
131
132 iwe.cmd = SIOCGIWRATE;
133 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
134 iwe.u.bitrate.value = max_rate * 500000;
135 start = iwe_stream_add_event(start, stop, &iwe,
136 IW_EV_PARAM_LEN);
137
138 iwe.cmd = IWEVCUSTOM;
139 iwe.u.data.length = p - custom;
140 if (iwe.u.data.length)
141 start = iwe_stream_add_point(start, stop, &iwe, custom);
142
143 /* Add quality statistics */
144 /* TODO: Fix these values... */
145 iwe.cmd = IWEVQUAL;
146 iwe.u.qual.qual = network->stats.signal;
147 iwe.u.qual.level = network->stats.rssi;
148 iwe.u.qual.noise = network->stats.noise;
149 iwe.u.qual.updated = network->stats.mask & IEEE80211_STATMASK_WEMASK;
150 if (!(network->stats.mask & IEEE80211_STATMASK_RSSI))
151 iwe.u.qual.updated |= IW_QUAL_LEVEL_INVALID;
152 if (!(network->stats.mask & IEEE80211_STATMASK_NOISE))
153 iwe.u.qual.updated |= IW_QUAL_NOISE_INVALID;
154 if (!(network->stats.mask & IEEE80211_STATMASK_SIGNAL))
155 iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID;
156
157 start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN);
158
159 iwe.cmd = IWEVCUSTOM;
160 p = custom;
161
162 iwe.u.data.length = p - custom;
163 if (iwe.u.data.length)
164 start = iwe_stream_add_point(start, stop, &iwe, custom);
165
166 if (ieee->wpa_enabled && network->wpa_ie_len){
167 char buf[MAX_WPA_IE_LEN * 2 + 30];
168
169 u8 *p = buf;
170 p += sprintf(p, "wpa_ie=");
171 for (i = 0; i < network->wpa_ie_len; i++) {
172 p += sprintf(p, "%02x", network->wpa_ie[i]);
173 }
174
175 memset(&iwe, 0, sizeof(iwe));
176 iwe.cmd = IWEVCUSTOM;
177 iwe.u.data.length = strlen(buf);
178 start = iwe_stream_add_point(start, stop, &iwe, buf);
179 }
180
181 if (ieee->wpa_enabled && network->rsn_ie_len){
182 char buf[MAX_WPA_IE_LEN * 2 + 30];
183
184 u8 *p = buf;
185 p += sprintf(p, "rsn_ie=");
186 for (i = 0; i < network->rsn_ie_len; i++) {
187 p += sprintf(p, "%02x", network->rsn_ie[i]);
188 }
189
190 memset(&iwe, 0, sizeof(iwe));
191 iwe.cmd = IWEVCUSTOM;
192 iwe.u.data.length = strlen(buf);
193 start = iwe_stream_add_point(start, stop, &iwe, buf);
194 }
195
196 /* Add EXTRA: Age to display seconds since last beacon/probe response
197 * for given network. */
198 iwe.cmd = IWEVCUSTOM;
199 p = custom;
200 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
201 " Last beacon: %lums ago", (jiffies - network->last_scanned) / (HZ / 100));
202 iwe.u.data.length = p - custom;
203 if (iwe.u.data.length)
204 start = iwe_stream_add_point(start, stop, &iwe, custom);
205
206
207 return start;
208}
209
210int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
211 struct iw_request_info *info,
212 union iwreq_data *wrqu, char *extra)
213{
214 struct ieee80211_network *network;
215 unsigned long flags;
216
217 char *ev = extra;
218 char *stop = ev + IW_SCAN_MAX_DATA;
219 int i = 0;
220
221 IEEE80211_DEBUG_WX("Getting scan\n");
222
223 spin_lock_irqsave(&ieee->lock, flags);
224
225 list_for_each_entry(network, &ieee->network_list, list) {
226 i++;
227 if (ieee->scan_age == 0 ||
228 time_after(network->last_scanned + ieee->scan_age, jiffies))
229 ev = ipw2100_translate_scan(ieee, ev, stop, network);
230 else
231 IEEE80211_DEBUG_SCAN(
232 "Not showing network '%s ("
233 MAC_FMT ")' due to age (%lums).\n",
234 escape_essid(network->ssid,
235 network->ssid_len),
236 MAC_ARG(network->bssid),
237 (jiffies - network->last_scanned) / (HZ / 100));
238 }
239
240 spin_unlock_irqrestore(&ieee->lock, flags);
241
242 wrqu->data.length = ev - extra;
243 wrqu->data.flags = 0;
244
245 IEEE80211_DEBUG_WX("exit: %d networks returned.\n", i);
246
247 return 0;
248}
249
250int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
251 struct iw_request_info *info,
252 union iwreq_data *wrqu, char *keybuf)
253{
254 struct iw_point *erq = &(wrqu->encoding);
255 struct net_device *dev = ieee->dev;
256 struct ieee80211_security sec = {
257 .flags = 0
258 };
259 int i, key, key_provided, len;
260 struct ieee80211_crypt_data **crypt;
261
262 IEEE80211_DEBUG_WX("SET_ENCODE\n");
263
264 key = erq->flags & IW_ENCODE_INDEX;
265 if (key) {
266 if (key > WEP_KEYS)
267 return -EINVAL;
268 key--;
269 key_provided = 1;
270 } else {
271 key_provided = 0;
272 key = ieee->tx_keyidx;
273 }
274
275 IEEE80211_DEBUG_WX("Key: %d [%s]\n", key, key_provided ?
276 "provided" : "default");
277
278 crypt = &ieee->crypt[key];
279
280 if (erq->flags & IW_ENCODE_DISABLED) {
281 if (key_provided && *crypt) {
282 IEEE80211_DEBUG_WX("Disabling encryption on key %d.\n",
283 key);
284 ieee80211_crypt_delayed_deinit(ieee, crypt);
285 } else
286 IEEE80211_DEBUG_WX("Disabling encryption.\n");
287
288 /* Check all the keys to see if any are still configured,
289 * and if no key index was provided, de-init them all */
290 for (i = 0; i < WEP_KEYS; i++) {
291 if (ieee->crypt[i] != NULL) {
292 if (key_provided)
293 break;
294 ieee80211_crypt_delayed_deinit(
295 ieee, &ieee->crypt[i]);
296 }
297 }
298
299 if (i == WEP_KEYS) {
300 sec.enabled = 0;
301 sec.level = SEC_LEVEL_0;
302 sec.flags |= SEC_ENABLED | SEC_LEVEL;
303 }
304
305 goto done;
306 }
307
308
309
310 sec.enabled = 1;
311 sec.flags |= SEC_ENABLED;
312
313 if (*crypt != NULL && (*crypt)->ops != NULL &&
314 strcmp((*crypt)->ops->name, "WEP") != 0) {
315 /* changing to use WEP; deinit previously used algorithm
316 * on this key */
317 ieee80211_crypt_delayed_deinit(ieee, crypt);
318 }
319
320 if (*crypt == NULL) {
321 struct ieee80211_crypt_data *new_crypt;
322
323 /* take WEP into use */
324 new_crypt = kmalloc(sizeof(struct ieee80211_crypt_data),
325 GFP_KERNEL);
326 if (new_crypt == NULL)
327 return -ENOMEM;
328 memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
329 new_crypt->ops = ieee80211_get_crypto_ops("WEP");
330 if (!new_crypt->ops) {
331 request_module("ieee80211_crypt_wep");
332 new_crypt->ops = ieee80211_get_crypto_ops("WEP");
333 }
334
335 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
336 new_crypt->priv = new_crypt->ops->init(key);
337
338 if (!new_crypt->ops || !new_crypt->priv) {
339 kfree(new_crypt);
340 new_crypt = NULL;
341
342 printk(KERN_WARNING "%s: could not initialize WEP: "
343 "load module ieee80211_crypt_wep\n",
344 dev->name);
345 return -EOPNOTSUPP;
346 }
347 *crypt = new_crypt;
348 }
349
350 /* If a new key was provided, set it up */
351 if (erq->length > 0) {
352 len = erq->length <= 5 ? 5 : 13;
353 memcpy(sec.keys[key], keybuf, erq->length);
354 if (len > erq->length)
355 memset(sec.keys[key] + erq->length, 0,
356 len - erq->length);
357 IEEE80211_DEBUG_WX("Setting key %d to '%s' (%d:%d bytes)\n",
358 key, escape_essid(sec.keys[key], len),
359 erq->length, len);
360 sec.key_sizes[key] = len;
361 (*crypt)->ops->set_key(sec.keys[key], len, NULL,
362 (*crypt)->priv);
363 sec.flags |= (1 << key);
364 /* This ensures a key will be activated if no key is
365 * explicitely set */
366 if (key == sec.active_key)
367 sec.flags |= SEC_ACTIVE_KEY;
368 } else {
369 len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN,
370 NULL, (*crypt)->priv);
371 if (len == 0) {
372 /* Set a default key of all 0 */
373 IEEE80211_DEBUG_WX("Setting key %d to all zero.\n",
374 key);
375 memset(sec.keys[key], 0, 13);
376 (*crypt)->ops->set_key(sec.keys[key], 13, NULL,
377 (*crypt)->priv);
378 sec.key_sizes[key] = 13;
379 sec.flags |= (1 << key);
380 }
381
382 /* No key data - just set the default TX key index */
383 if (key_provided) {
384 IEEE80211_DEBUG_WX(
385 "Setting key %d to default Tx key.\n", key);
386 ieee->tx_keyidx = key;
387 sec.active_key = key;
388 sec.flags |= SEC_ACTIVE_KEY;
389 }
390 }
391
392 done:
393 ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED);
394 sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
395 sec.flags |= SEC_AUTH_MODE;
396 IEEE80211_DEBUG_WX("Auth: %s\n", sec.auth_mode == WLAN_AUTH_OPEN ?
397 "OPEN" : "SHARED KEY");
398
399 /* For now we just support WEP, so only set that security level...
400 * TODO: When WPA is added this is one place that needs to change */
401 sec.flags |= SEC_LEVEL;
402 sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */
403
404 if (ieee->set_security)
405 ieee->set_security(dev, &sec);
406
407 /* Do not reset port if card is in Managed mode since resetting will
408 * generate new IEEE 802.11 authentication which may end up in looping
409 * with IEEE 802.1X. If your hardware requires a reset after WEP
410 * configuration (for example... Prism2), implement the reset_port in
411 * the callbacks structures used to initialize the 802.11 stack. */
412 if (ieee->reset_on_keychange &&
413 ieee->iw_mode != IW_MODE_INFRA &&
414 ieee->reset_port && ieee->reset_port(dev)) {
415 printk(KERN_DEBUG "%s: reset_port failed\n", dev->name);
416 return -EINVAL;
417 }
418 return 0;
419}
420
421int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
422 struct iw_request_info *info,
423 union iwreq_data *wrqu, char *keybuf)
424{
425 struct iw_point *erq = &(wrqu->encoding);
426 int len, key;
427 struct ieee80211_crypt_data *crypt;
428
429 IEEE80211_DEBUG_WX("GET_ENCODE\n");
430
431 key = erq->flags & IW_ENCODE_INDEX;
432 if (key) {
433 if (key > WEP_KEYS)
434 return -EINVAL;
435 key--;
436 } else
437 key = ieee->tx_keyidx;
438
439 crypt = ieee->crypt[key];
440 erq->flags = key + 1;
441
442 if (crypt == NULL || crypt->ops == NULL) {
443 erq->length = 0;
444 erq->flags |= IW_ENCODE_DISABLED;
445 return 0;
446 }
447
448 if (strcmp(crypt->ops->name, "WEP") != 0) {
449 /* only WEP is supported with wireless extensions, so just
450 * report that encryption is used */
451 erq->length = 0;
452 erq->flags |= IW_ENCODE_ENABLED;
453 return 0;
454 }
455
456 len = crypt->ops->get_key(keybuf, WEP_KEY_LEN, NULL, crypt->priv);
457 erq->length = (len >= 0 ? len : 0);
458
459 erq->flags |= IW_ENCODE_ENABLED;
460
461 if (ieee->open_wep)
462 erq->flags |= IW_ENCODE_OPEN;
463 else
464 erq->flags |= IW_ENCODE_RESTRICTED;
465
466 return 0;
467}
468
469EXPORT_SYMBOL(ieee80211_wx_get_scan);
470EXPORT_SYMBOL(ieee80211_wx_set_encode);
471EXPORT_SYMBOL(ieee80211_wx_get_encode);