1 #include <linux/etherdevice.h>
3 #include "hostap_80211.h"
6 void hostap_dump_rx_80211(const char *name
, struct sk_buff
*skb
,
7 struct hostap_80211_rx_status
*rx_stats
)
9 struct hostap_ieee80211_hdr
*hdr
;
12 hdr
= (struct hostap_ieee80211_hdr
*) skb
->data
;
14 printk(KERN_DEBUG
"%s: RX signal=%d noise=%d rate=%d len=%d "
16 name
, rx_stats
->signal
, rx_stats
->noise
, rx_stats
->rate
,
22 fc
= le16_to_cpu(hdr
->frame_control
);
23 printk(KERN_DEBUG
" FC=0x%04x (type=%d:%d)%s%s",
24 fc
, WLAN_FC_GET_TYPE(fc
), WLAN_FC_GET_STYPE(fc
),
25 fc
& WLAN_FC_TODS
? " [ToDS]" : "",
26 fc
& WLAN_FC_FROMDS
? " [FromDS]" : "");
28 if (skb
->len
< IEEE80211_DATA_HDR3_LEN
) {
33 printk(" dur=0x%04x seq=0x%04x\n", le16_to_cpu(hdr
->duration_id
),
34 le16_to_cpu(hdr
->seq_ctrl
));
36 printk(KERN_DEBUG
" A1=" MACSTR
" A2=" MACSTR
" A3=" MACSTR
,
37 MAC2STR(hdr
->addr1
), MAC2STR(hdr
->addr2
), MAC2STR(hdr
->addr3
));
39 printk(" A4=" MACSTR
, MAC2STR(hdr
->addr4
));
44 /* Send RX frame to netif with 802.11 (and possible prism) header.
45 * Called from hardware or software IRQ context. */
46 int prism2_rx_80211(struct net_device
*dev
, struct sk_buff
*skb
,
47 struct hostap_80211_rx_status
*rx_stats
, int type
)
49 struct hostap_interface
*iface
;
51 int hdrlen
, phdrlen
, head_need
, tail_need
;
53 int prism_header
, ret
;
54 struct hostap_ieee80211_hdr
*hdr
;
56 iface
= netdev_priv(dev
);
58 dev
->last_rx
= jiffies
;
60 if (dev
->type
== ARPHRD_IEEE80211_PRISM
) {
61 if (local
->monitor_type
== PRISM2_MONITOR_PRISM
) {
63 phdrlen
= sizeof(struct linux_wlan_ng_prism_hdr
);
64 } else { /* local->monitor_type == PRISM2_MONITOR_CAPHDR */
66 phdrlen
= sizeof(struct linux_wlan_ng_cap_hdr
);
73 hdr
= (struct hostap_ieee80211_hdr
*) skb
->data
;
74 fc
= le16_to_cpu(hdr
->frame_control
);
76 if (type
== PRISM2_RX_MGMT
&& (fc
& WLAN_FC_PVER
)) {
77 printk(KERN_DEBUG
"%s: dropped management frame with header "
78 "version %d\n", dev
->name
, fc
& WLAN_FC_PVER
);
79 dev_kfree_skb_any(skb
);
83 hdrlen
= hostap_80211_get_hdrlen(fc
);
85 /* check if there is enough room for extra data; if not, expand skb
86 * buffer to be large enough for the changes */
89 #ifdef PRISM2_ADD_BOGUS_CRC
91 #endif /* PRISM2_ADD_BOGUS_CRC */
93 head_need
-= skb_headroom(skb
);
94 tail_need
-= skb_tailroom(skb
);
96 if (head_need
> 0 || tail_need
> 0) {
97 if (pskb_expand_head(skb
, head_need
> 0 ? head_need
: 0,
98 tail_need
> 0 ? tail_need
: 0,
100 printk(KERN_DEBUG
"%s: prism2_rx_80211 failed to "
101 "reallocate skb buffer\n", dev
->name
);
102 dev_kfree_skb_any(skb
);
107 /* We now have an skb with enough head and tail room, so just insert
110 #ifdef PRISM2_ADD_BOGUS_CRC
111 memset(skb_put(skb
, 4), 0xff, 4); /* Prism2 strips CRC */
112 #endif /* PRISM2_ADD_BOGUS_CRC */
114 if (prism_header
== 1) {
115 struct linux_wlan_ng_prism_hdr
*hdr
;
116 hdr
= (struct linux_wlan_ng_prism_hdr
*)
117 skb_push(skb
, phdrlen
);
118 memset(hdr
, 0, phdrlen
);
119 hdr
->msgcode
= LWNG_CAP_DID_BASE
;
120 hdr
->msglen
= sizeof(*hdr
);
121 memcpy(hdr
->devname
, dev
->name
, sizeof(hdr
->devname
));
122 #define LWNG_SETVAL(f,i,s,l,d) \
123 hdr->f.did = LWNG_CAP_DID_BASE | (i << 12); \
124 hdr->f.status = s; hdr->f.len = l; hdr->f.data = d
125 LWNG_SETVAL(hosttime
, 1, 0, 4, jiffies
);
126 LWNG_SETVAL(mactime
, 2, 0, 0, rx_stats
->mac_time
);
127 LWNG_SETVAL(channel
, 3, 1 /* no value */, 4, 0);
128 LWNG_SETVAL(rssi
, 4, 1 /* no value */, 4, 0);
129 LWNG_SETVAL(sq
, 5, 1 /* no value */, 4, 0);
130 LWNG_SETVAL(signal
, 6, 0, 4, rx_stats
->signal
);
131 LWNG_SETVAL(noise
, 7, 0, 4, rx_stats
->noise
);
132 LWNG_SETVAL(rate
, 8, 0, 4, rx_stats
->rate
/ 5);
133 LWNG_SETVAL(istx
, 9, 0, 4, 0);
134 LWNG_SETVAL(frmlen
, 10, 0, 4, skb
->len
- phdrlen
);
136 } else if (prism_header
== 2) {
137 struct linux_wlan_ng_cap_hdr
*hdr
;
138 hdr
= (struct linux_wlan_ng_cap_hdr
*)
139 skb_push(skb
, phdrlen
);
140 memset(hdr
, 0, phdrlen
);
141 hdr
->version
= htonl(LWNG_CAPHDR_VERSION
);
142 hdr
->length
= htonl(phdrlen
);
143 hdr
->mactime
= __cpu_to_be64(rx_stats
->mac_time
);
144 hdr
->hosttime
= __cpu_to_be64(jiffies
);
145 hdr
->phytype
= htonl(4); /* dss_dot11_b */
146 hdr
->channel
= htonl(local
->channel
);
147 hdr
->datarate
= htonl(rx_stats
->rate
);
148 hdr
->antenna
= htonl(0); /* unknown */
149 hdr
->priority
= htonl(0); /* unknown */
150 hdr
->ssi_type
= htonl(3); /* raw */
151 hdr
->ssi_signal
= htonl(rx_stats
->signal
);
152 hdr
->ssi_noise
= htonl(rx_stats
->noise
);
153 hdr
->preamble
= htonl(0); /* unknown */
154 hdr
->encoding
= htonl(1); /* cck */
157 ret
= skb
->len
- phdrlen
;
159 skb
->mac
.raw
= skb
->data
;
160 skb_pull(skb
, hdrlen
);
162 skb_pull(skb
, phdrlen
);
163 skb
->pkt_type
= PACKET_OTHERHOST
;
164 skb
->protocol
= __constant_htons(ETH_P_802_2
);
165 memset(skb
->cb
, 0, sizeof(skb
->cb
));
172 /* Called only as a tasklet (software IRQ) */
173 static void monitor_rx(struct net_device
*dev
, struct sk_buff
*skb
,
174 struct hostap_80211_rx_status
*rx_stats
)
176 struct net_device_stats
*stats
;
179 len
= prism2_rx_80211(dev
, skb
, rx_stats
, PRISM2_RX_MONITOR
);
180 stats
= hostap_get_stats(dev
);
182 stats
->rx_bytes
+= len
;
186 /* Called only as a tasklet (software IRQ) */
187 static struct prism2_frag_entry
*
188 prism2_frag_cache_find(local_info_t
*local
, unsigned int seq
,
189 unsigned int frag
, u8
*src
, u8
*dst
)
191 struct prism2_frag_entry
*entry
;
194 for (i
= 0; i
< PRISM2_FRAG_CACHE_LEN
; i
++) {
195 entry
= &local
->frag_cache
[i
];
196 if (entry
->skb
!= NULL
&&
197 time_after(jiffies
, entry
->first_frag_time
+ 2 * HZ
)) {
198 printk(KERN_DEBUG
"%s: expiring fragment cache entry "
199 "seq=%u last_frag=%u\n",
200 local
->dev
->name
, entry
->seq
, entry
->last_frag
);
201 dev_kfree_skb(entry
->skb
);
205 if (entry
->skb
!= NULL
&& entry
->seq
== seq
&&
206 (entry
->last_frag
+ 1 == frag
|| frag
== -1) &&
207 memcmp(entry
->src_addr
, src
, ETH_ALEN
) == 0 &&
208 memcmp(entry
->dst_addr
, dst
, ETH_ALEN
) == 0)
216 /* Called only as a tasklet (software IRQ) */
217 static struct sk_buff
*
218 prism2_frag_cache_get(local_info_t
*local
, struct hostap_ieee80211_hdr
*hdr
)
220 struct sk_buff
*skb
= NULL
;
222 unsigned int frag
, seq
;
223 struct prism2_frag_entry
*entry
;
225 sc
= le16_to_cpu(hdr
->seq_ctrl
);
226 frag
= WLAN_GET_SEQ_FRAG(sc
);
227 seq
= WLAN_GET_SEQ_SEQ(sc
);
230 /* Reserve enough space to fit maximum frame length */
231 skb
= dev_alloc_skb(local
->dev
->mtu
+
232 sizeof(struct hostap_ieee80211_hdr
) +
235 8 /* WEP */ + ETH_ALEN
/* WDS */);
239 entry
= &local
->frag_cache
[local
->frag_next_idx
];
240 local
->frag_next_idx
++;
241 if (local
->frag_next_idx
>= PRISM2_FRAG_CACHE_LEN
)
242 local
->frag_next_idx
= 0;
244 if (entry
->skb
!= NULL
)
245 dev_kfree_skb(entry
->skb
);
247 entry
->first_frag_time
= jiffies
;
249 entry
->last_frag
= frag
;
251 memcpy(entry
->src_addr
, hdr
->addr2
, ETH_ALEN
);
252 memcpy(entry
->dst_addr
, hdr
->addr1
, ETH_ALEN
);
254 /* received a fragment of a frame for which the head fragment
255 * should have already been received */
256 entry
= prism2_frag_cache_find(local
, seq
, frag
, hdr
->addr2
,
259 entry
->last_frag
= frag
;
268 /* Called only as a tasklet (software IRQ) */
269 static int prism2_frag_cache_invalidate(local_info_t
*local
,
270 struct hostap_ieee80211_hdr
*hdr
)
274 struct prism2_frag_entry
*entry
;
276 sc
= le16_to_cpu(hdr
->seq_ctrl
);
277 seq
= WLAN_GET_SEQ_SEQ(sc
);
279 entry
= prism2_frag_cache_find(local
, seq
, -1, hdr
->addr2
, hdr
->addr1
);
282 printk(KERN_DEBUG
"%s: could not invalidate fragment cache "
284 local
->dev
->name
, seq
);
293 static struct hostap_bss_info
*__hostap_get_bss(local_info_t
*local
, u8
*bssid
,
294 u8
*ssid
, size_t ssid_len
)
296 struct list_head
*ptr
;
297 struct hostap_bss_info
*bss
;
299 list_for_each(ptr
, &local
->bss_list
) {
300 bss
= list_entry(ptr
, struct hostap_bss_info
, list
);
301 if (memcmp(bss
->bssid
, bssid
, ETH_ALEN
) == 0 &&
303 (ssid_len
== bss
->ssid_len
&&
304 memcmp(ssid
, bss
->ssid
, ssid_len
) == 0))) {
305 list_move(&bss
->list
, &local
->bss_list
);
314 static struct hostap_bss_info
*__hostap_add_bss(local_info_t
*local
, u8
*bssid
,
315 u8
*ssid
, size_t ssid_len
)
317 struct hostap_bss_info
*bss
;
319 if (local
->num_bss_info
>= HOSTAP_MAX_BSS_COUNT
) {
320 bss
= list_entry(local
->bss_list
.prev
,
321 struct hostap_bss_info
, list
);
322 list_del(&bss
->list
);
323 local
->num_bss_info
--;
325 bss
= (struct hostap_bss_info
*)
326 kmalloc(sizeof(*bss
), GFP_ATOMIC
);
331 memset(bss
, 0, sizeof(*bss
));
332 memcpy(bss
->bssid
, bssid
, ETH_ALEN
);
333 memcpy(bss
->ssid
, ssid
, ssid_len
);
334 bss
->ssid_len
= ssid_len
;
335 local
->num_bss_info
++;
336 list_add(&bss
->list
, &local
->bss_list
);
341 static void __hostap_expire_bss(local_info_t
*local
)
343 struct hostap_bss_info
*bss
;
345 while (local
->num_bss_info
> 0) {
346 bss
= list_entry(local
->bss_list
.prev
,
347 struct hostap_bss_info
, list
);
348 if (!time_after(jiffies
, bss
->last_update
+ 60 * HZ
))
351 list_del(&bss
->list
);
352 local
->num_bss_info
--;
358 /* Both IEEE 802.11 Beacon and Probe Response frames have similar structure, so
359 * the same routine can be used to parse both of them. */
360 static void hostap_rx_sta_beacon(local_info_t
*local
, struct sk_buff
*skb
,
363 struct hostap_ieee80211_mgmt
*mgmt
;
366 u8
*ssid
= NULL
, *wpa
= NULL
, *rsn
= NULL
;
367 size_t ssid_len
= 0, wpa_len
= 0, rsn_len
= 0;
368 struct hostap_bss_info
*bss
;
370 if (skb
->len
< IEEE80211_MGMT_HDR_LEN
+ sizeof(mgmt
->u
.beacon
))
373 mgmt
= (struct hostap_ieee80211_mgmt
*) skb
->data
;
374 pos
= mgmt
->u
.beacon
.variable
;
375 left
= skb
->len
- (pos
- skb
->data
);
378 if (2 + pos
[1] > left
)
379 return; /* parse failed */
385 case WLAN_EID_GENERIC
:
387 pos
[2] == 0x00 && pos
[3] == 0x50 &&
388 pos
[4] == 0xf2 && pos
[5] == 1) {
390 wpa_len
= pos
[1] + 2;
395 rsn_len
= pos
[1] + 2;
397 case WLAN_EID_DS_PARAMS
:
406 if (wpa_len
> MAX_WPA_IE_LEN
)
407 wpa_len
= MAX_WPA_IE_LEN
;
408 if (rsn_len
> MAX_WPA_IE_LEN
)
409 rsn_len
= MAX_WPA_IE_LEN
;
410 if (ssid_len
> sizeof(bss
->ssid
))
411 ssid_len
= sizeof(bss
->ssid
);
413 spin_lock(&local
->lock
);
414 bss
= __hostap_get_bss(local
, mgmt
->bssid
, ssid
, ssid_len
);
416 bss
= __hostap_add_bss(local
, mgmt
->bssid
, ssid
, ssid_len
);
418 bss
->last_update
= jiffies
;
420 bss
->capab_info
= le16_to_cpu(mgmt
->u
.beacon
.capab_info
);
422 memcpy(bss
->wpa_ie
, wpa
, wpa_len
);
423 bss
->wpa_ie_len
= wpa_len
;
427 memcpy(bss
->rsn_ie
, rsn
, rsn_len
);
428 bss
->rsn_ie_len
= rsn_len
;
433 __hostap_expire_bss(local
);
434 spin_unlock(&local
->lock
);
439 hostap_rx_frame_mgmt(local_info_t
*local
, struct sk_buff
*skb
,
440 struct hostap_80211_rx_status
*rx_stats
, u16 type
,
443 if (local
->iw_mode
== IW_MODE_MASTER
) {
444 hostap_update_sta_ps(local
, (struct hostap_ieee80211_hdr
*)
448 if (local
->hostapd
&& type
== WLAN_FC_TYPE_MGMT
) {
449 if (stype
== WLAN_FC_STYPE_BEACON
&&
450 local
->iw_mode
== IW_MODE_MASTER
) {
451 struct sk_buff
*skb2
;
452 /* Process beacon frames also in kernel driver to
453 * update STA(AP) table statistics */
454 skb2
= skb_clone(skb
, GFP_ATOMIC
);
456 hostap_rx(skb2
->dev
, skb2
, rx_stats
);
459 /* send management frames to the user space daemon for
461 local
->apdevstats
.rx_packets
++;
462 local
->apdevstats
.rx_bytes
+= skb
->len
;
463 if (local
->apdev
== NULL
)
465 prism2_rx_80211(local
->apdev
, skb
, rx_stats
, PRISM2_RX_MGMT
);
469 if (local
->iw_mode
== IW_MODE_MASTER
) {
470 if (type
!= WLAN_FC_TYPE_MGMT
&& type
!= WLAN_FC_TYPE_CTRL
) {
471 printk(KERN_DEBUG
"%s: unknown management frame "
472 "(type=0x%02x, stype=0x%02x) dropped\n",
473 skb
->dev
->name
, type
, stype
);
477 hostap_rx(skb
->dev
, skb
, rx_stats
);
479 } else if (type
== WLAN_FC_TYPE_MGMT
&&
480 (stype
== WLAN_FC_STYPE_BEACON
||
481 stype
== WLAN_FC_STYPE_PROBE_RESP
)) {
482 hostap_rx_sta_beacon(local
, skb
, stype
);
484 } else if (type
== WLAN_FC_TYPE_MGMT
&&
485 (stype
== WLAN_FC_STYPE_ASSOC_RESP
||
486 stype
== WLAN_FC_STYPE_REASSOC_RESP
)) {
487 /* Ignore (Re)AssocResp silently since these are not currently
488 * needed but are still received when WPA/RSN mode is enabled.
492 printk(KERN_DEBUG
"%s: hostap_rx_frame_mgmt: dropped unhandled"
493 " management frame in non-Host AP mode (type=%d:%d)\n",
494 skb
->dev
->name
, type
, stype
);
500 /* Called only as a tasklet (software IRQ) */
501 static inline struct net_device
*prism2_rx_get_wds(local_info_t
*local
,
504 struct hostap_interface
*iface
= NULL
;
505 struct list_head
*ptr
;
507 read_lock_bh(&local
->iface_lock
);
508 list_for_each(ptr
, &local
->hostap_interfaces
) {
509 iface
= list_entry(ptr
, struct hostap_interface
, list
);
510 if (iface
->type
== HOSTAP_INTERFACE_WDS
&&
511 memcmp(iface
->u
.wds
.remote_addr
, addr
, ETH_ALEN
) == 0)
515 read_unlock_bh(&local
->iface_lock
);
517 return iface
? iface
->dev
: NULL
;
522 hostap_rx_frame_wds(local_info_t
*local
, struct hostap_ieee80211_hdr
*hdr
,
523 u16 fc
, struct net_device
**wds
)
525 /* FIX: is this really supposed to accept WDS frames only in Master
526 * mode? What about Repeater or Managed with WDS frames? */
527 if ((fc
& (WLAN_FC_TODS
| WLAN_FC_FROMDS
)) !=
528 (WLAN_FC_TODS
| WLAN_FC_FROMDS
) &&
529 (local
->iw_mode
!= IW_MODE_MASTER
|| !(fc
& WLAN_FC_TODS
)))
530 return 0; /* not a WDS frame */
532 /* Possible WDS frame: either IEEE 802.11 compliant (if FromDS)
533 * or own non-standard frame with 4th address after payload */
534 if (memcmp(hdr
->addr1
, local
->dev
->dev_addr
, ETH_ALEN
) != 0 &&
535 (hdr
->addr1
[0] != 0xff || hdr
->addr1
[1] != 0xff ||
536 hdr
->addr1
[2] != 0xff || hdr
->addr1
[3] != 0xff ||
537 hdr
->addr1
[4] != 0xff || hdr
->addr1
[5] != 0xff)) {
538 /* RA (or BSSID) is not ours - drop */
539 PDEBUG(DEBUG_EXTRA
, "%s: received WDS frame with "
540 "not own or broadcast %s=" MACSTR
"\n",
541 local
->dev
->name
, fc
& WLAN_FC_FROMDS
? "RA" : "BSSID",
542 MAC2STR(hdr
->addr1
));
546 /* check if the frame came from a registered WDS connection */
547 *wds
= prism2_rx_get_wds(local
, hdr
->addr2
);
548 if (*wds
== NULL
&& fc
& WLAN_FC_FROMDS
&&
549 (local
->iw_mode
!= IW_MODE_INFRA
||
550 !(local
->wds_type
& HOSTAP_WDS_AP_CLIENT
) ||
551 memcmp(hdr
->addr2
, local
->bssid
, ETH_ALEN
) != 0)) {
552 /* require that WDS link has been registered with TA or the
553 * frame is from current AP when using 'AP client mode' */
554 PDEBUG(DEBUG_EXTRA
, "%s: received WDS[4 addr] frame "
555 "from unknown TA=" MACSTR
"\n",
556 local
->dev
->name
, MAC2STR(hdr
->addr2
));
557 if (local
->ap
&& local
->ap
->autom_ap_wds
)
558 hostap_wds_link_oper(local
, hdr
->addr2
, WDS_ADD
);
562 if (*wds
&& !(fc
& WLAN_FC_FROMDS
) && local
->ap
&&
563 hostap_is_sta_assoc(local
->ap
, hdr
->addr2
)) {
564 /* STA is actually associated with us even though it has a
565 * registered WDS link. Assume it is in 'AP client' mode.
566 * Since this is a 3-addr frame, assume it is not (bogus) WDS
567 * frame and process it like any normal ToDS frame from
576 static int hostap_is_eapol_frame(local_info_t
*local
, struct sk_buff
*skb
)
578 struct net_device
*dev
= local
->dev
;
580 struct hostap_ieee80211_hdr
*hdr
;
586 hdr
= (struct hostap_ieee80211_hdr
*) skb
->data
;
587 fc
= le16_to_cpu(hdr
->frame_control
);
589 /* check that the frame is unicast frame to us */
590 if ((fc
& (WLAN_FC_TODS
| WLAN_FC_FROMDS
)) == WLAN_FC_TODS
&&
591 memcmp(hdr
->addr1
, dev
->dev_addr
, ETH_ALEN
) == 0 &&
592 memcmp(hdr
->addr3
, dev
->dev_addr
, ETH_ALEN
) == 0) {
593 /* ToDS frame with own addr BSSID and DA */
594 } else if ((fc
& (WLAN_FC_TODS
| WLAN_FC_FROMDS
)) == WLAN_FC_FROMDS
&&
595 memcmp(hdr
->addr1
, dev
->dev_addr
, ETH_ALEN
) == 0) {
596 /* FromDS frame with own addr as DA */
600 if (skb
->len
< 24 + 8)
603 /* check for port access entity Ethernet type */
604 pos
= skb
->data
+ 24;
605 ethertype
= (pos
[6] << 8) | pos
[7];
606 if (ethertype
== ETH_P_PAE
)
613 /* Called only as a tasklet (software IRQ) */
615 hostap_rx_frame_decrypt(local_info_t
*local
, struct sk_buff
*skb
,
616 struct prism2_crypt_data
*crypt
)
618 struct hostap_ieee80211_hdr
*hdr
;
621 if (crypt
== NULL
|| crypt
->ops
->decrypt_mpdu
== NULL
)
624 hdr
= (struct hostap_ieee80211_hdr
*) skb
->data
;
625 hdrlen
= hostap_80211_get_hdrlen(le16_to_cpu(hdr
->frame_control
));
627 if (local
->tkip_countermeasures
&&
628 strcmp(crypt
->ops
->name
, "TKIP") == 0) {
629 if (net_ratelimit()) {
630 printk(KERN_DEBUG
"%s: TKIP countermeasures: dropped "
631 "received packet from " MACSTR
"\n",
632 local
->dev
->name
, MAC2STR(hdr
->addr2
));
637 atomic_inc(&crypt
->refcnt
);
638 res
= crypt
->ops
->decrypt_mpdu(skb
, hdrlen
, crypt
->priv
);
639 atomic_dec(&crypt
->refcnt
);
641 printk(KERN_DEBUG
"%s: decryption failed (SA=" MACSTR
643 local
->dev
->name
, MAC2STR(hdr
->addr2
), res
);
644 local
->comm_tallies
.rx_discards_wep_undecryptable
++;
652 /* Called only as a tasklet (software IRQ) */
654 hostap_rx_frame_decrypt_msdu(local_info_t
*local
, struct sk_buff
*skb
,
655 int keyidx
, struct prism2_crypt_data
*crypt
)
657 struct hostap_ieee80211_hdr
*hdr
;
660 if (crypt
== NULL
|| crypt
->ops
->decrypt_msdu
== NULL
)
663 hdr
= (struct hostap_ieee80211_hdr
*) skb
->data
;
664 hdrlen
= hostap_80211_get_hdrlen(le16_to_cpu(hdr
->frame_control
));
666 atomic_inc(&crypt
->refcnt
);
667 res
= crypt
->ops
->decrypt_msdu(skb
, keyidx
, hdrlen
, crypt
->priv
);
668 atomic_dec(&crypt
->refcnt
);
670 printk(KERN_DEBUG
"%s: MSDU decryption/MIC verification failed"
671 " (SA=" MACSTR
" keyidx=%d)\n",
672 local
->dev
->name
, MAC2STR(hdr
->addr2
), keyidx
);
680 /* All received frames are sent to this function. @skb contains the frame in
681 * IEEE 802.11 format, i.e., in the format it was sent over air.
682 * This function is called only as a tasklet (software IRQ). */
683 void hostap_80211_rx(struct net_device
*dev
, struct sk_buff
*skb
,
684 struct hostap_80211_rx_status
*rx_stats
)
686 struct hostap_interface
*iface
;
688 struct hostap_ieee80211_hdr
*hdr
;
690 u16 fc
, type
, stype
, sc
;
691 struct net_device
*wds
= NULL
;
692 struct net_device_stats
*stats
;
695 struct sk_buff
*skb2
= NULL
;
697 int frame_authorized
= 0;
698 int from_assoc_ap
= 0;
701 struct prism2_crypt_data
*crypt
= NULL
;
705 iface
= netdev_priv(dev
);
706 local
= iface
->local
;
707 iface
->stats
.rx_packets
++;
708 iface
->stats
.rx_bytes
+= skb
->len
;
710 /* dev is the master radio device; change this to be the default
711 * virtual interface (this may be changed to WDS device below) */
713 iface
= netdev_priv(dev
);
715 hdr
= (struct hostap_ieee80211_hdr
*) skb
->data
;
716 stats
= hostap_get_stats(dev
);
721 fc
= le16_to_cpu(hdr
->frame_control
);
722 type
= WLAN_FC_GET_TYPE(fc
);
723 stype
= WLAN_FC_GET_STYPE(fc
);
724 sc
= le16_to_cpu(hdr
->seq_ctrl
);
725 frag
= WLAN_GET_SEQ_FRAG(sc
);
726 hdrlen
= hostap_80211_get_hdrlen(fc
);
728 /* Put this code here so that we avoid duplicating it in all
729 * Rx paths. - Jean II */
730 #ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */
731 /* If spy monitoring on */
732 if (iface
->spy_data
.spy_number
> 0) {
733 struct iw_quality wstats
;
734 wstats
.level
= rx_stats
->signal
;
735 wstats
.noise
= rx_stats
->noise
;
736 wstats
.updated
= 6; /* No qual value */
737 /* Update spy records */
738 wireless_spy_update(dev
, hdr
->addr2
, &wstats
);
740 #endif /* IW_WIRELESS_SPY */
741 hostap_update_rx_stats(local
->ap
, hdr
, rx_stats
);
743 if (local
->iw_mode
== IW_MODE_MONITOR
) {
744 monitor_rx(dev
, skb
, rx_stats
);
748 if (local
->host_decrypt
) {
750 if (skb
->len
>= hdrlen
+ 3)
751 idx
= skb
->data
[hdrlen
+ 3] >> 6;
752 crypt
= local
->crypt
[idx
];
755 /* Use station specific key to override default keys if the
756 * receiver address is a unicast address ("individual RA"). If
757 * bcrx_sta_key parameter is set, station specific key is used
758 * even with broad/multicast targets (this is against IEEE
759 * 802.11, but makes it easier to use different keys with
760 * stations that do not support WEP key mapping). */
762 if (!(hdr
->addr1
[0] & 0x01) || local
->bcrx_sta_key
)
763 (void) hostap_handle_sta_crypto(local
, hdr
, &crypt
,
766 /* allow NULL decrypt to indicate an station specific override
767 * for default encryption */
768 if (crypt
&& (crypt
->ops
== NULL
||
769 crypt
->ops
->decrypt_mpdu
== NULL
))
772 if (!crypt
&& (fc
& WLAN_FC_ISWEP
)) {
774 /* This seems to be triggered by some (multicast?)
775 * frames from other than current BSS, so just drop the
776 * frames silently instead of filling system log with
778 printk(KERN_DEBUG
"%s: WEP decryption failed (not set)"
779 " (SA=" MACSTR
")\n",
780 local
->dev
->name
, MAC2STR(hdr
->addr2
));
782 local
->comm_tallies
.rx_discards_wep_undecryptable
++;
787 if (type
!= WLAN_FC_TYPE_DATA
) {
788 if (type
== WLAN_FC_TYPE_MGMT
&& stype
== WLAN_FC_STYPE_AUTH
&&
789 fc
& WLAN_FC_ISWEP
&& local
->host_decrypt
&&
790 (keyidx
= hostap_rx_frame_decrypt(local
, skb
, crypt
)) < 0)
792 printk(KERN_DEBUG
"%s: failed to decrypt mgmt::auth "
793 "from " MACSTR
"\n", dev
->name
,
794 MAC2STR(hdr
->addr2
));
795 /* TODO: could inform hostapd about this so that it
796 * could send auth failure report */
800 if (hostap_rx_frame_mgmt(local
, skb
, rx_stats
, type
, stype
))
806 /* Data frame - extract src/dst addresses */
807 if (skb
->len
< IEEE80211_DATA_HDR3_LEN
)
810 switch (fc
& (WLAN_FC_FROMDS
| WLAN_FC_TODS
)) {
812 memcpy(dst
, hdr
->addr1
, ETH_ALEN
);
813 memcpy(src
, hdr
->addr3
, ETH_ALEN
);
816 memcpy(dst
, hdr
->addr3
, ETH_ALEN
);
817 memcpy(src
, hdr
->addr2
, ETH_ALEN
);
819 case WLAN_FC_FROMDS
| WLAN_FC_TODS
:
820 if (skb
->len
< IEEE80211_DATA_HDR4_LEN
)
822 memcpy(dst
, hdr
->addr3
, ETH_ALEN
);
823 memcpy(src
, hdr
->addr4
, ETH_ALEN
);
826 memcpy(dst
, hdr
->addr1
, ETH_ALEN
);
827 memcpy(src
, hdr
->addr2
, ETH_ALEN
);
831 if (hostap_rx_frame_wds(local
, hdr
, fc
, &wds
))
834 skb
->dev
= dev
= wds
;
835 stats
= hostap_get_stats(dev
);
838 if (local
->iw_mode
== IW_MODE_MASTER
&& !wds
&&
839 (fc
& (WLAN_FC_TODS
| WLAN_FC_FROMDS
)) == WLAN_FC_FROMDS
&&
841 memcmp(hdr
->addr2
, local
->assoc_ap_addr
, ETH_ALEN
) == 0) {
842 /* Frame from BSSID of the AP for which we are a client */
843 skb
->dev
= dev
= local
->stadev
;
844 stats
= hostap_get_stats(dev
);
848 dev
->last_rx
= jiffies
;
850 if ((local
->iw_mode
== IW_MODE_MASTER
||
851 local
->iw_mode
== IW_MODE_REPEAT
) &&
853 switch (hostap_handle_sta_rx(local
, dev
, skb
, rx_stats
,
855 case AP_RX_CONTINUE_NOT_AUTHORIZED
:
856 frame_authorized
= 0;
859 frame_authorized
= 1;
868 /* Nullfunc frames may have PS-bit set, so they must be passed to
869 * hostap_handle_sta_rx() before being dropped here. */
870 if (stype
!= WLAN_FC_STYPE_DATA
&&
871 stype
!= WLAN_FC_STYPE_DATA_CFACK
&&
872 stype
!= WLAN_FC_STYPE_DATA_CFPOLL
&&
873 stype
!= WLAN_FC_STYPE_DATA_CFACKPOLL
) {
874 if (stype
!= WLAN_FC_STYPE_NULLFUNC
)
875 printk(KERN_DEBUG
"%s: RX: dropped data frame "
876 "with no data (type=0x%02x, subtype=0x%02x)\n",
877 dev
->name
, type
, stype
);
881 /* skb: hdr + (possibly fragmented, possibly encrypted) payload */
883 if (local
->host_decrypt
&& (fc
& WLAN_FC_ISWEP
) &&
884 (keyidx
= hostap_rx_frame_decrypt(local
, skb
, crypt
)) < 0)
886 hdr
= (struct hostap_ieee80211_hdr
*) skb
->data
;
888 /* skb: hdr + (possibly fragmented) plaintext payload */
890 if (local
->host_decrypt
&& (fc
& WLAN_FC_ISWEP
) &&
891 (frag
!= 0 || (fc
& WLAN_FC_MOREFRAG
))) {
893 struct sk_buff
*frag_skb
=
894 prism2_frag_cache_get(local
, hdr
);
896 printk(KERN_DEBUG
"%s: Rx cannot get skb from "
897 "fragment cache (morefrag=%d seq=%u frag=%u)\n",
898 dev
->name
, (fc
& WLAN_FC_MOREFRAG
) != 0,
899 WLAN_GET_SEQ_SEQ(sc
), frag
);
907 if (frag_skb
->tail
+ flen
> frag_skb
->end
) {
908 printk(KERN_WARNING
"%s: host decrypted and "
909 "reassembled frame did not fit skb\n",
911 prism2_frag_cache_invalidate(local
, hdr
);
916 /* copy first fragment (including full headers) into
917 * beginning of the fragment cache skb */
918 memcpy(skb_put(frag_skb
, flen
), skb
->data
, flen
);
920 /* append frame payload to the end of the fragment
922 memcpy(skb_put(frag_skb
, flen
), skb
->data
+ hdrlen
,
928 if (fc
& WLAN_FC_MOREFRAG
) {
929 /* more fragments expected - leave the skb in fragment
930 * cache for now; it will be delivered to upper layers
931 * after all fragments have been received */
935 /* this was the last fragment and the frame will be
936 * delivered, so remove skb from fragment cache */
938 hdr
= (struct hostap_ieee80211_hdr
*) skb
->data
;
939 prism2_frag_cache_invalidate(local
, hdr
);
942 /* skb: hdr + (possible reassembled) full MSDU payload; possibly still
943 * encrypted/authenticated */
945 if (local
->host_decrypt
&& (fc
& WLAN_FC_ISWEP
) &&
946 hostap_rx_frame_decrypt_msdu(local
, skb
, keyidx
, crypt
))
949 hdr
= (struct hostap_ieee80211_hdr
*) skb
->data
;
950 if (crypt
&& !(fc
& WLAN_FC_ISWEP
) && !local
->open_wep
) {
951 if (local
->ieee_802_1x
&&
952 hostap_is_eapol_frame(local
, skb
)) {
953 /* pass unencrypted EAPOL frames even if encryption is
955 PDEBUG(DEBUG_EXTRA2
, "%s: RX: IEEE 802.1X - passing "
956 "unencrypted EAPOL frame\n", local
->dev
->name
);
958 printk(KERN_DEBUG
"%s: encryption configured, but RX "
959 "frame not encrypted (SA=" MACSTR
")\n",
960 local
->dev
->name
, MAC2STR(hdr
->addr2
));
965 if (local
->drop_unencrypted
&& !(fc
& WLAN_FC_ISWEP
) &&
966 !hostap_is_eapol_frame(local
, skb
)) {
967 if (net_ratelimit()) {
968 printk(KERN_DEBUG
"%s: dropped unencrypted RX data "
969 "frame from " MACSTR
" (drop_unencrypted=1)\n",
970 dev
->name
, MAC2STR(hdr
->addr2
));
975 /* skb: hdr + (possible reassembled) full plaintext payload */
977 payload
= skb
->data
+ hdrlen
;
978 ethertype
= (payload
[6] << 8) | payload
[7];
980 /* If IEEE 802.1X is used, check whether the port is authorized to send
981 * the received frame. */
982 if (local
->ieee_802_1x
&& local
->iw_mode
== IW_MODE_MASTER
) {
983 if (ethertype
== ETH_P_PAE
) {
984 PDEBUG(DEBUG_EXTRA2
, "%s: RX: IEEE 802.1X frame\n",
986 if (local
->hostapd
&& local
->apdev
) {
987 /* Send IEEE 802.1X frames to the user
988 * space daemon for processing */
989 prism2_rx_80211(local
->apdev
, skb
, rx_stats
,
991 local
->apdevstats
.rx_packets
++;
992 local
->apdevstats
.rx_bytes
+= skb
->len
;
995 } else if (!frame_authorized
) {
996 printk(KERN_DEBUG
"%s: dropped frame from "
997 "unauthorized port (IEEE 802.1X): "
998 "ethertype=0x%04x\n",
999 dev
->name
, ethertype
);
1004 /* convert hdr + possible LLC headers into Ethernet header */
1005 if (skb
->len
- hdrlen
>= 8 &&
1006 ((memcmp(payload
, rfc1042_header
, 6) == 0 &&
1007 ethertype
!= ETH_P_AARP
&& ethertype
!= ETH_P_IPX
) ||
1008 memcmp(payload
, bridge_tunnel_header
, 6) == 0)) {
1009 /* remove RFC1042 or Bridge-Tunnel encapsulation and
1010 * replace EtherType */
1011 skb_pull(skb
, hdrlen
+ 6);
1012 memcpy(skb_push(skb
, ETH_ALEN
), src
, ETH_ALEN
);
1013 memcpy(skb_push(skb
, ETH_ALEN
), dst
, ETH_ALEN
);
1016 /* Leave Ethernet header part of hdr and full payload */
1017 skb_pull(skb
, hdrlen
);
1018 len
= htons(skb
->len
);
1019 memcpy(skb_push(skb
, 2), &len
, 2);
1020 memcpy(skb_push(skb
, ETH_ALEN
), src
, ETH_ALEN
);
1021 memcpy(skb_push(skb
, ETH_ALEN
), dst
, ETH_ALEN
);
1024 if (wds
&& ((fc
& (WLAN_FC_TODS
| WLAN_FC_FROMDS
)) == WLAN_FC_TODS
) &&
1025 skb
->len
>= ETH_HLEN
+ ETH_ALEN
) {
1026 /* Non-standard frame: get addr4 from its bogus location after
1028 memcpy(skb
->data
+ ETH_ALEN
,
1029 skb
->data
+ skb
->len
- ETH_ALEN
, ETH_ALEN
);
1030 skb_trim(skb
, skb
->len
- ETH_ALEN
);
1033 stats
->rx_packets
++;
1034 stats
->rx_bytes
+= skb
->len
;
1036 if (local
->iw_mode
== IW_MODE_MASTER
&& !wds
&&
1037 local
->ap
->bridge_packets
) {
1038 if (dst
[0] & 0x01) {
1039 /* copy multicast frame both to the higher layers and
1040 * to the wireless media */
1041 local
->ap
->bridged_multicast
++;
1042 skb2
= skb_clone(skb
, GFP_ATOMIC
);
1044 printk(KERN_DEBUG
"%s: skb_clone failed for "
1045 "multicast frame\n", dev
->name
);
1046 } else if (hostap_is_sta_authorized(local
->ap
, dst
)) {
1047 /* send frame directly to the associated STA using
1048 * wireless media and not passing to higher layers */
1049 local
->ap
->bridged_unicast
++;
1056 /* send to wireless media */
1057 skb2
->protocol
= __constant_htons(ETH_P_802_3
);
1058 skb2
->mac
.raw
= skb2
->nh
.raw
= skb2
->data
;
1059 /* skb2->nh.raw = skb2->data + ETH_HLEN; */
1061 dev_queue_xmit(skb2
);
1065 skb
->protocol
= eth_type_trans(skb
, dev
);
1066 memset(skb
->cb
, 0, sizeof(skb
->cb
));
1073 hostap_handle_sta_release(sta
);
1079 stats
->rx_dropped
++;
1084 EXPORT_SYMBOL(hostap_80211_rx
);