2 #include <linux/slab.h>
3 #include <linux/export.h>
5 #include <linux/if_arp.h>
13 static unsigned char rfc1042_header[] =
14 { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
16 static unsigned char bridge_tunnel_header[] =
17 { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
65 struct hostap_interface *iface;
67 int hdrlen, phdrlen, head_need, tail_need;
69 int prism_header,
ret;
72 iface = netdev_priv(dev);
76 if (local->monitor_type == PRISM2_MONITOR_PRISM) {
96 "version %d\n", dev->
name, fc & IEEE80211_FCTL_VERS);
107 #ifdef PRISM2_ADD_BOGUS_CRC
111 head_need -= skb_headroom(skb);
112 tail_need -= skb_tailroom(skb);
114 if (head_need > 0 || tail_need > 0) {
116 tail_need > 0 ? tail_need : 0,
119 "reallocate skb buffer\n", dev->
name);
128 #ifdef PRISM2_ADD_BOGUS_CRC
132 if (prism_header == 1) {
138 hdr->
msglen =
sizeof(*hdr);
140 #define LWNG_SETVAL(f,i,s,l,d) \
141 hdr->f.did = LWNG_CAP_DID_BASE | (i << 12); \
142 hdr->f.status = s; hdr->f.len = l; hdr->f.data = d
154 }
else if (prism_header == 2) {
173 }
else if (prism_header == 3) {
178 hdr->
hdr.it_present =
193 ret = skb->
len - phdrlen;
195 skb_reset_mac_header(skb);
201 memset(skb->cb, 0,
sizeof(skb->cb));
215 dev->
stats.rx_packets++;
216 dev->
stats.rx_bytes += len;
221 static struct prism2_frag_entry *
222 prism2_frag_cache_find(
local_info_t *local,
unsigned int seq,
225 struct prism2_frag_entry *
entry;
228 for (i = 0; i < PRISM2_FRAG_CACHE_LEN; i++) {
229 entry = &local->frag_cache[
i];
230 if (entry->skb !=
NULL &&
233 "seq=%u last_frag=%u\n",
234 local->
dev->name, entry->seq, entry->last_frag);
235 dev_kfree_skb(entry->skb);
239 if (entry->skb !=
NULL && entry->seq == seq &&
240 (entry->last_frag + 1 == frag || frag == -1) &&
256 unsigned int frag, seq;
257 struct prism2_frag_entry *
entry;
265 skb = dev_alloc_skb(local->
dev->mtu +
273 entry = &local->frag_cache[local->frag_next_idx];
274 local->frag_next_idx++;
275 if (local->frag_next_idx >= PRISM2_FRAG_CACHE_LEN)
276 local->frag_next_idx = 0;
278 if (entry->skb !=
NULL)
279 dev_kfree_skb(entry->skb);
281 entry->first_frag_time =
jiffies;
283 entry->last_frag =
frag;
290 entry = prism2_frag_cache_find(local, seq, frag, hdr->
addr2,
293 entry->last_frag =
frag;
303 static int prism2_frag_cache_invalidate(
local_info_t *local,
308 struct prism2_frag_entry *
entry;
313 entry = prism2_frag_cache_find(local, seq, -1, hdr->
addr2, hdr->
addr1);
318 local->
dev->name, seq);
328 u8 *
ssid,
size_t ssid_len)
331 struct hostap_bss_info *bss;
337 (ssid_len == bss->ssid_len &&
338 memcmp(ssid, bss->ssid, ssid_len) == 0))) {
339 list_move(&bss->list, &local->bss_list);
348 static struct hostap_bss_info *__hostap_add_bss(
local_info_t *local,
u8 *bssid,
349 u8 *ssid,
size_t ssid_len)
351 struct hostap_bss_info *bss;
353 if (local->num_bss_info >= HOSTAP_MAX_BSS_COUNT) {
355 struct hostap_bss_info,
list);
357 local->num_bss_info--;
364 memset(bss, 0,
sizeof(*bss));
366 memcpy(bss->ssid, ssid, ssid_len);
367 bss->ssid_len = ssid_len;
368 local->num_bss_info++;
369 list_add(&bss->list, &local->bss_list);
376 struct hostap_bss_info *bss;
378 while (local->num_bss_info > 0) {
380 struct hostap_bss_info,
list);
385 local->num_bss_info--;
400 size_t ssid_len = 0, wpa_len = 0, rsn_len = 0;
401 struct hostap_bss_info *bss;
408 left = skb->
len - (pos - skb->
data);
411 if (2 + pos[1] > left)
420 pos[2] == 0x00 && pos[3] == 0x50 &&
421 pos[4] == 0xf2 && pos[5] == 1) {
423 wpa_len = pos[1] + 2;
428 rsn_len = pos[1] + 2;
443 if (ssid_len >
sizeof(bss->ssid))
444 ssid_len =
sizeof(bss->ssid);
446 spin_lock(&local->lock);
447 bss = __hostap_get_bss(local, mgmt->
bssid, ssid, ssid_len);
449 bss = __hostap_add_bss(local, mgmt->
bssid, ssid, ssid_len);
455 memcpy(bss->wpa_ie, wpa, wpa_len);
456 bss->wpa_ie_len = wpa_len;
460 memcpy(bss->rsn_ie, rsn, rsn_len);
461 bss->rsn_ie_len = rsn_len;
466 __hostap_expire_bss(local);
467 spin_unlock(&local->lock);
492 local->apdevstats.rx_packets++;
493 local->apdevstats.rx_bytes += skb->
len;
494 if (local->apdev ==
NULL)
504 "(type=0x%02x, stype=0x%02x) dropped\n",
505 skb->
dev->name, type >> 2, stype >> 4);
514 hostap_rx_sta_beacon(local, skb, stype);
525 " management frame in non-Host AP mode (type=%d:%d)\n",
526 skb->
dev->name, type >> 2, stype >> 4);
536 struct hostap_interface *iface =
NULL;
542 if (iface->type == HOSTAP_INTERFACE_WDS &&
549 return iface ? iface->dev :
NULL;
567 (hdr->
addr1[0] != 0xff || hdr->
addr1[1] != 0xff ||
568 hdr->
addr1[2] != 0xff || hdr->
addr1[3] != 0xff ||
569 hdr->
addr1[4] != 0xff || hdr->
addr1[5] != 0xff)) {
571 PDEBUG(DEBUG_EXTRA2,
"%s: received WDS frame with "
572 "not own or broadcast %s=%pM\n",
580 *wds = prism2_rx_get_wds(local, hdr->
addr2);
583 !(local->wds_type & HOSTAP_WDS_AP_CLIENT) ||
587 PDEBUG(DEBUG_EXTRA,
"%s: received WDS[4 addr] frame "
588 "from unknown TA=%pM\n",
590 if (local->ap && local->ap->autom_ap_wds)
623 if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
624 IEEE80211_FCTL_TODS &&
628 }
else if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
629 IEEE80211_FCTL_FROMDS &&
635 if (skb->
len < 24 + 8)
639 pos = skb->
data + 24;
640 ethertype = (pos[6] << 8) | pos[7];
656 if (crypt ==
NULL || crypt->
ops->decrypt_mpdu ==
NULL)
662 if (local->tkip_countermeasures &&
666 "received packet from %pM\n",
673 res = crypt->
ops->decrypt_mpdu(skb, hdrlen, crypt->
priv);
678 local->comm_tallies.rx_discards_wep_undecryptable++;
694 if (crypt ==
NULL || crypt->
ops->decrypt_msdu ==
NULL)
701 res = crypt->
ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->
priv);
705 " (SA=%pM keyidx=%d)\n",
706 local->
dev->name, hdr->
addr2, keyidx);
720 struct hostap_interface *iface;
730 int frame_authorized = 0;
731 int from_assoc_ap = 0;
738 iface = netdev_priv(dev);
739 local = iface->local;
740 iface->stats.rx_packets++;
741 iface->stats.rx_bytes += skb->
len;
746 iface = netdev_priv(dev);
762 #ifdef IW_WIRELESS_SPY
764 if (iface->spy_data.spy_number > 0) {
777 monitor_rx(dev, skb, rx_stats);
781 if (local->host_decrypt) {
783 if (skb->
len >= hdrlen + 3)
784 idx = skb->
data[hdrlen + 3] >> 6;
785 crypt = local->crypt_info.crypt[
idx];
795 if (!(hdr->
addr1[0] & 0x01) || local->bcrx_sta_key)
801 if (crypt && (crypt->
ops ==
NULL ||
802 crypt->
ops->decrypt_mpdu ==
NULL))
815 local->comm_tallies.rx_discards_wep_undecryptable++;
824 (keyidx = hostap_rx_frame_decrypt(local, skb, crypt)) < 0)
833 if (hostap_rx_frame_mgmt(local, skb, rx_stats, type, stype))
843 switch (fc & (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
844 case IEEE80211_FCTL_FROMDS:
848 case IEEE80211_FCTL_TODS:
852 case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
864 if (hostap_rx_frame_wds(local, hdr, fc, &wds))
867 skb->
dev = dev = wds;
870 (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
871 IEEE80211_FCTL_FROMDS &&
875 skb->
dev = dev = local->stadev;
885 frame_authorized = 0;
888 frame_authorized = 1;
905 "with no data (type=0x%02x, subtype=0x%02x)\n",
906 dev->
name, type >> 2, stype >> 4);
913 (keyidx = hostap_rx_frame_decrypt(local, skb, crypt)) < 0)
919 if (local->host_decrypt && (fc & IEEE80211_FCTL_PROTECTED) &&
923 prism2_frag_cache_get(local, hdr);
926 "fragment cache (morefrag=%d seq=%u frag=%u)\n",
936 if (frag_skb->
tail + flen > frag_skb->
end) {
938 "reassembled frame did not fit skb\n",
940 prism2_frag_cache_invalidate(local, hdr);
947 skb_copy_from_linear_data(skb,
skb_put(frag_skb, flen),
952 skb_copy_from_linear_data_offset(skb, hdrlen,
970 prism2_frag_cache_invalidate(local, hdr);
976 if (local->host_decrypt && (fc & IEEE80211_FCTL_PROTECTED) &&
977 hostap_rx_frame_decrypt_msdu(local, skb, keyidx, crypt))
981 if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && !local->open_wep) {
982 if (local->ieee_802_1x &&
983 hostap_is_eapol_frame(local, skb)) {
986 PDEBUG(DEBUG_EXTRA2,
"%s: RX: IEEE 802.1X - passing "
987 "unencrypted EAPOL frame\n", local->
dev->name);
990 "frame not encrypted (SA=%pM)\n",
996 if (local->drop_unencrypted && !(fc & IEEE80211_FCTL_PROTECTED) &&
997 !hostap_is_eapol_frame(local, skb)) {
1000 "frame from %pM (drop_unencrypted=1)\n",
1009 ethertype = (payload[6] << 8) | payload[7];
1015 PDEBUG(DEBUG_EXTRA2,
"%s: RX: IEEE 802.1X frame\n",
1017 if (local->hostapd && local->apdev) {
1022 local->apdevstats.rx_packets++;
1023 local->apdevstats.rx_bytes += skb->
len;
1026 }
else if (!frame_authorized) {
1028 "unauthorized port (IEEE 802.1X): "
1029 "ethertype=0x%04x\n",
1030 dev->
name, ethertype);
1036 if (skb->
len - hdrlen >= 8 &&
1037 ((
memcmp(payload, rfc1042_header, 6) == 0 &&
1039 memcmp(payload, bridge_tunnel_header, 6) == 0)) {
1055 if (wds && ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
1056 IEEE80211_FCTL_TODS) &&
1060 skb_copy_from_linear_data_offset(skb, skb->
len -
ETH_ALEN,
1066 dev->
stats.rx_packets++;
1070 local->ap->bridge_packets) {
1071 if (dst[0] & 0x01) {
1074 local->ap->bridged_multicast++;
1078 "multicast frame\n", dev->
name);
1082 local->ap->bridged_unicast++;
1092 skb_reset_mac_header(skb2);
1093 skb_reset_network_header(skb2);
1100 memset(skb->cb, 0,
sizeof(skb->cb));
1112 dev->
stats.rx_dropped++;