1 /******************************************************************************
3 Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
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.
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
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.
18 The full GNU General Public License is included in this distribution in the
22 James P. Ketrenos <ipw2100-admin@linux.intel.com>
23 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
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>
33 #include <linux/kernel.h>
34 #include <linux/module.h>
35 #include <linux/netdevice.h>
36 #include <linux/proc_fs.h>
37 #include <linux/skbuff.h>
38 #include <linux/slab.h>
39 #include <linux/tcp.h>
40 #include <linux/types.h>
41 #include <linux/version.h>
42 #include <linux/wireless.h>
43 #include <linux/etherdevice.h>
44 #include <asm/uaccess.h>
46 #include <net/ieee80211.h>
52 ,-------------------------------------------------------------------.
53 Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 |
54 |------|------|---------|---------|---------|------|---------|------|
55 Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | Frame | fcs |
56 | | tion | (BSSID) | | | ence | data | |
57 `--------------------------------------------------| |------'
58 Total: 28 non-data bytes `----.----'
60 .- 'Frame data' expands to <---------------------------'
63 ,---------------------------------------------------.
64 Bytes | 1 | 1 | 1 | 3 | 2 | 0-2304 |
65 |------|------|---------|----------|------|---------|
66 Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP |
67 | DSAP | SSAP | | | | Packet |
68 | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8| | |
69 `-----------------------------------------| |
70 Total: 8 non-data bytes `----.----'
72 .- 'IP Packet' expands, if WEP enabled, to <--'
75 ,-----------------------.
76 Bytes | 4 | 0-2296 | 4 |
77 |-----|-----------|-----|
78 Desc. | IV | Encrypted | ICV |
80 `-----------------------'
81 Total: 8 non-data bytes
83 802.3 Ethernet Data Frame
85 ,-----------------------------------------.
86 Bytes | 6 | 6 | 2 | Variable | 4 |
87 |-------|-------|------|-----------|------|
88 Desc. | Dest. | Source| Type | IP Packet | fcs |
90 `-----------------------------------------'
91 Total: 18 non-data bytes
93 In the event that fragmentation is required, the incoming payload is split into
94 N parts of size ieee->fts. The first fragment contains the SNAP header and the
95 remaining packets are just data.
97 If encryption is enabled, each fragment payload size is reduced by enough space
98 to add the prefix and postfix (IV and ICV totalling 8 bytes in the case of WEP)
99 So if you have 1500 bytes of payload with ieee->fts set to 500 without
100 encryption it will take 3 frames. With WEP it will take 4 frames as the
101 payload of each frame is reduced to 492 bytes.
107 * | ETHERNET HEADER ,-<-- PAYLOAD
108 * | | 14 bytes from skb->data
109 * | 2 bytes for Type --> ,T. | (sizeof ethhdr)
111 * |,-Dest.--. ,--Src.---. | | |
112 * | 6 bytes| | 6 bytes | | | |
115 * 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
118 * | | | | `T' <---- 2 bytes for Type
120 * | | '---SNAP--' <-------- 6 bytes for SNAP
122 * `-IV--' <-------------------- 4 bytes for IV (WEP)
128 static u8 P802_1H_OUI
[P80211_OUI_LEN
] = { 0x00, 0x00, 0xf8 };
129 static u8 RFC1042_OUI
[P80211_OUI_LEN
] = { 0x00, 0x00, 0x00 };
131 static inline int ieee80211_copy_snap(u8
* data
, u16 h_proto
)
133 struct ieee80211_snap_hdr
*snap
;
136 snap
= (struct ieee80211_snap_hdr
*)data
;
141 if (h_proto
== 0x8137 || h_proto
== 0x80f3)
145 snap
->oui
[0] = oui
[0];
146 snap
->oui
[1] = oui
[1];
147 snap
->oui
[2] = oui
[2];
149 *(u16
*) (data
+ SNAP_SIZE
) = htons(h_proto
);
151 return SNAP_SIZE
+ sizeof(u16
);
154 static inline int ieee80211_encrypt_fragment(struct ieee80211_device
*ieee
,
155 struct sk_buff
*frag
, int hdr_len
)
157 struct ieee80211_crypt_data
*crypt
= ieee
->crypt
[ieee
->tx_keyidx
];
160 /* To encrypt, frame format is:
161 * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */
162 atomic_inc(&crypt
->refcnt
);
164 if (crypt
->ops
->encrypt_mpdu
)
165 res
= crypt
->ops
->encrypt_mpdu(frag
, hdr_len
, crypt
->priv
);
167 atomic_dec(&crypt
->refcnt
);
169 printk(KERN_INFO
"%s: Encryption failed: len=%d.\n",
170 ieee
->dev
->name
, frag
->len
);
171 ieee
->ieee_stats
.tx_discards
++;
178 void ieee80211_txb_free(struct ieee80211_txb
*txb
)
183 for (i
= 0; i
< txb
->nr_frags
; i
++)
184 if (txb
->fragments
[i
])
185 dev_kfree_skb_any(txb
->fragments
[i
]);
189 static struct ieee80211_txb
*ieee80211_alloc_txb(int nr_frags
, int txb_size
,
192 struct ieee80211_txb
*txb
;
194 txb
= kmalloc(sizeof(struct ieee80211_txb
) + (sizeof(u8
*) * nr_frags
),
199 memset(txb
, 0, sizeof(struct ieee80211_txb
));
200 txb
->nr_frags
= nr_frags
;
201 txb
->frag_size
= txb_size
;
203 for (i
= 0; i
< nr_frags
; i
++) {
204 txb
->fragments
[i
] = dev_alloc_skb(txb_size
);
205 if (unlikely(!txb
->fragments
[i
])) {
210 if (unlikely(i
!= nr_frags
)) {
212 dev_kfree_skb_any(txb
->fragments
[i
--]);
219 /* Incoming skb is converted to a txb which consists of
220 * a block of 802.11 fragment packets (stored as skbs) */
221 int ieee80211_xmit(struct sk_buff
*skb
, struct net_device
*dev
)
223 struct ieee80211_device
*ieee
= netdev_priv(dev
);
224 struct ieee80211_txb
*txb
= NULL
;
225 struct ieee80211_hdr_3addr
*frag_hdr
;
226 int i
, bytes_per_frag
, nr_frags
, bytes_last_frag
, frag_size
,
229 struct net_device_stats
*stats
= &ieee
->stats
;
230 int ether_type
, encrypt
, host_encrypt
, host_encrypt_msdu
;
231 int bytes
, fc
, hdr_len
;
232 struct sk_buff
*skb_frag
;
233 struct ieee80211_hdr_3addr header
= { /* Ensure zero initialized */
237 u8 dest
[ETH_ALEN
], src
[ETH_ALEN
];
238 struct ieee80211_crypt_data
*crypt
;
241 spin_lock_irqsave(&ieee
->lock
, flags
);
243 /* If there is no driver handler to take the TXB, dont' bother
245 if (!ieee
->hard_start_xmit
) {
246 printk(KERN_WARNING
"%s: No xmit handler.\n", ieee
->dev
->name
);
250 if (unlikely(skb
->len
< SNAP_SIZE
+ sizeof(u16
))) {
251 printk(KERN_WARNING
"%s: skb too small (%d).\n",
252 ieee
->dev
->name
, skb
->len
);
256 ether_type
= ntohs(((struct ethhdr
*)skb
->data
)->h_proto
);
258 crypt
= ieee
->crypt
[ieee
->tx_keyidx
];
260 encrypt
= !(ether_type
== ETH_P_PAE
&& ieee
->ieee802_1x
) &&
262 host_encrypt
= ieee
->host_encrypt
&& encrypt
;
263 host_encrypt_msdu
= ieee
->host_encrypt_msdu
&& encrypt
;
265 if (!encrypt
&& ieee
->ieee802_1x
&&
266 ieee
->drop_unencrypted
&& ether_type
!= ETH_P_PAE
) {
271 /* Save source and destination addresses */
272 memcpy(dest
, skb
->data
, ETH_ALEN
);
273 memcpy(src
, skb
->data
+ ETH_ALEN
, ETH_ALEN
);
275 /* Advance the SKB to the start of the payload */
276 skb_pull(skb
, sizeof(struct ethhdr
));
278 /* Determine total amount of storage required for TXB packets */
279 bytes
= skb
->len
+ SNAP_SIZE
+ sizeof(u16
);
282 fc
= IEEE80211_FTYPE_DATA
| IEEE80211_STYPE_DATA
|
283 IEEE80211_FCTL_PROTECTED
;
285 fc
= IEEE80211_FTYPE_DATA
| IEEE80211_STYPE_DATA
;
287 if (ieee
->iw_mode
== IW_MODE_INFRA
) {
288 fc
|= IEEE80211_FCTL_TODS
;
289 /* To DS: Addr1 = BSSID, Addr2 = SA, Addr3 = DA */
290 memcpy(header
.addr1
, ieee
->bssid
, ETH_ALEN
);
291 memcpy(header
.addr2
, src
, ETH_ALEN
);
292 memcpy(header
.addr3
, dest
, ETH_ALEN
);
293 } else if (ieee
->iw_mode
== IW_MODE_ADHOC
) {
294 /* not From/To DS: Addr1 = DA, Addr2 = SA, Addr3 = BSSID */
295 memcpy(header
.addr1
, dest
, ETH_ALEN
);
296 memcpy(header
.addr2
, src
, ETH_ALEN
);
297 memcpy(header
.addr3
, ieee
->bssid
, ETH_ALEN
);
299 header
.frame_ctl
= cpu_to_le16(fc
);
300 hdr_len
= IEEE80211_3ADDR_LEN
;
302 /* Encrypt msdu first on the whole data packet. */
303 if ((host_encrypt
|| host_encrypt_msdu
) &&
304 crypt
&& crypt
->ops
&& crypt
->ops
->encrypt_msdu
) {
306 int len
= bytes
+ hdr_len
+ crypt
->ops
->extra_msdu_prefix_len
+
307 crypt
->ops
->extra_msdu_postfix_len
;
308 struct sk_buff
*skb_new
= dev_alloc_skb(len
);
309 if (unlikely(!skb_new
))
311 skb_reserve(skb_new
, crypt
->ops
->extra_msdu_prefix_len
);
312 memcpy(skb_put(skb_new
, hdr_len
), &header
, hdr_len
);
314 ieee80211_copy_snap(skb_put(skb_new
, SNAP_SIZE
+ sizeof(u16
)),
316 memcpy(skb_put(skb_new
, skb
->len
), skb
->data
, skb
->len
);
317 res
= crypt
->ops
->encrypt_msdu(skb_new
, hdr_len
, crypt
->priv
);
319 IEEE80211_ERROR("msdu encryption failed\n");
320 dev_kfree_skb_any(skb_new
);
323 dev_kfree_skb_any(skb
);
325 bytes
+= crypt
->ops
->extra_msdu_prefix_len
+
326 crypt
->ops
->extra_msdu_postfix_len
;
327 skb_pull(skb
, hdr_len
);
330 if (host_encrypt
|| ieee
->host_open_frag
) {
331 /* Determine fragmentation size based on destination (multicast
332 * and broadcast are not fragmented) */
333 if (is_multicast_ether_addr(dest
))
334 frag_size
= MAX_FRAG_THRESHOLD
;
336 frag_size
= ieee
->fts
;
338 /* Determine amount of payload per fragment. Regardless of if
339 * this stack is providing the full 802.11 header, one will
340 * eventually be affixed to this fragment -- so we must account
341 * for it when determining the amount of payload space. */
342 bytes_per_frag
= frag_size
- IEEE80211_3ADDR_LEN
;
344 (CFG_IEEE80211_COMPUTE_FCS
| CFG_IEEE80211_RESERVE_FCS
))
345 bytes_per_frag
-= IEEE80211_FCS_LEN
;
347 /* Each fragment may need to have room for encryptiong
350 bytes_per_frag
-= crypt
->ops
->extra_mpdu_prefix_len
+
351 crypt
->ops
->extra_mpdu_postfix_len
;
353 /* Number of fragments is the total
354 * bytes_per_frag / payload_per_fragment */
355 nr_frags
= bytes
/ bytes_per_frag
;
356 bytes_last_frag
= bytes
% bytes_per_frag
;
360 bytes_last_frag
= bytes_per_frag
;
363 bytes_per_frag
= bytes_last_frag
= bytes
;
364 frag_size
= bytes
+ IEEE80211_3ADDR_LEN
;
367 rts_required
= (frag_size
> ieee
->rts
368 && ieee
->config
& CFG_IEEE80211_RTS
);
372 /* When we allocate the TXB we allocate enough space for the reserve
373 * and full fragment bytes (bytes_per_frag doesn't include prefix,
374 * postfix, header, FCS, etc.) */
375 txb
= ieee80211_alloc_txb(nr_frags
, frag_size
, GFP_ATOMIC
);
376 if (unlikely(!txb
)) {
377 printk(KERN_WARNING
"%s: Could not allocate TXB\n",
381 txb
->encrypted
= encrypt
;
383 txb
->payload_size
= frag_size
* (nr_frags
- 1) +
386 txb
->payload_size
= bytes
;
389 skb_frag
= txb
->fragments
[0];
391 (struct ieee80211_hdr_3addr
*)skb_put(skb_frag
, hdr_len
);
394 * Set header frame_ctl to the RTS.
397 cpu_to_le16(IEEE80211_FTYPE_CTL
| IEEE80211_STYPE_RTS
);
398 memcpy(frag_hdr
, &header
, hdr_len
);
401 * Restore header frame_ctl to the original data setting.
403 header
.frame_ctl
= cpu_to_le16(fc
);
406 (CFG_IEEE80211_COMPUTE_FCS
| CFG_IEEE80211_RESERVE_FCS
))
407 skb_put(skb_frag
, 4);
409 txb
->rts_included
= 1;
414 for (; i
< nr_frags
; i
++) {
415 skb_frag
= txb
->fragments
[i
];
418 skb_reserve(skb_frag
,
419 crypt
->ops
->extra_mpdu_prefix_len
);
422 (struct ieee80211_hdr_3addr
*)skb_put(skb_frag
, hdr_len
);
423 memcpy(frag_hdr
, &header
, hdr_len
);
425 /* If this is not the last fragment, then add the MOREFRAGS
426 * bit to the frame control */
427 if (i
!= nr_frags
- 1) {
428 frag_hdr
->frame_ctl
=
429 cpu_to_le16(fc
| IEEE80211_FCTL_MOREFRAGS
);
430 bytes
= bytes_per_frag
;
432 /* The last fragment takes the remaining length */
433 bytes
= bytes_last_frag
;
436 if (i
== 0 && !snapped
) {
437 ieee80211_copy_snap(skb_put
438 (skb_frag
, SNAP_SIZE
+ sizeof(u16
)),
440 bytes
-= SNAP_SIZE
+ sizeof(u16
);
443 memcpy(skb_put(skb_frag
, bytes
), skb
->data
, bytes
);
445 /* Advance the SKB... */
446 skb_pull(skb
, bytes
);
448 /* Encryption routine will move the header forward in order
449 * to insert the IV between the header and the payload */
451 ieee80211_encrypt_fragment(ieee
, skb_frag
, hdr_len
);
454 (CFG_IEEE80211_COMPUTE_FCS
| CFG_IEEE80211_RESERVE_FCS
))
455 skb_put(skb_frag
, 4);
459 spin_unlock_irqrestore(&ieee
->lock
, flags
);
461 dev_kfree_skb_any(skb
);
464 int ret
= (*ieee
->hard_start_xmit
) (txb
, dev
);
467 stats
->tx_bytes
+= txb
->payload_size
;
470 ieee80211_txb_free(txb
);
476 spin_unlock_irqrestore(&ieee
->lock
, flags
);
477 netif_stop_queue(dev
);
482 /* Incoming 802.11 strucure is converted to a TXB
483 * a block of 802.11 fragment packets (stored as skbs) */
484 int ieee80211_tx_frame(struct ieee80211_device
*ieee
,
485 struct ieee80211_hdr
*frame
, int len
)
487 struct ieee80211_txb
*txb
= NULL
;
489 struct net_device_stats
*stats
= &ieee
->stats
;
490 struct sk_buff
*skb_frag
;
492 spin_lock_irqsave(&ieee
->lock
, flags
);
494 /* If there is no driver handler to take the TXB, dont' bother
496 if (!ieee
->hard_start_xmit
) {
497 printk(KERN_WARNING
"%s: No xmit handler.\n", ieee
->dev
->name
);
501 if (unlikely(len
< 24)) {
502 printk(KERN_WARNING
"%s: skb too small (%d).\n",
503 ieee
->dev
->name
, len
);
507 /* When we allocate the TXB we allocate enough space for the reserve
508 * and full fragment bytes (bytes_per_frag doesn't include prefix,
509 * postfix, header, FCS, etc.) */
510 txb
= ieee80211_alloc_txb(1, len
, GFP_ATOMIC
);
511 if (unlikely(!txb
)) {
512 printk(KERN_WARNING
"%s: Could not allocate TXB\n",
517 txb
->payload_size
= len
;
519 skb_frag
= txb
->fragments
[0];
521 memcpy(skb_put(skb_frag
, len
), frame
, len
);
524 (CFG_IEEE80211_COMPUTE_FCS
| CFG_IEEE80211_RESERVE_FCS
))
525 skb_put(skb_frag
, 4);
528 spin_unlock_irqrestore(&ieee
->lock
, flags
);
531 if ((*ieee
->hard_start_xmit
) (txb
, ieee
->dev
) == 0) {
533 stats
->tx_bytes
+= txb
->payload_size
;
536 ieee80211_txb_free(txb
);
541 spin_unlock_irqrestore(&ieee
->lock
, flags
);
546 EXPORT_SYMBOL(ieee80211_tx_frame
);
547 EXPORT_SYMBOL(ieee80211_txb_free
);