0001
0002 #include <linux/etherdevice.h>
0003 #include <linux/slab.h>
0004 #include <linux/export.h>
0005 #include <net/lib80211.h>
0006 #include <linux/if_arp.h>
0007
0008 #include "hostap_80211.h"
0009 #include "hostap.h"
0010 #include "hostap_ap.h"
0011
0012
0013
0014 static unsigned char rfc1042_header[] =
0015 { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
0016
0017 static unsigned char bridge_tunnel_header[] =
0018 { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
0019
0020
0021 void hostap_dump_rx_80211(const char *name, struct sk_buff *skb,
0022 struct hostap_80211_rx_status *rx_stats)
0023 {
0024 struct ieee80211_hdr *hdr;
0025 u16 fc;
0026
0027 hdr = (struct ieee80211_hdr *) skb->data;
0028
0029 printk(KERN_DEBUG "%s: RX signal=%d noise=%d rate=%d len=%d "
0030 "jiffies=%ld\n",
0031 name, rx_stats->signal, rx_stats->noise, rx_stats->rate,
0032 skb->len, jiffies);
0033
0034 if (skb->len < 2)
0035 return;
0036
0037 fc = le16_to_cpu(hdr->frame_control);
0038 printk(KERN_DEBUG " FC=0x%04x (type=%d:%d)%s%s",
0039 fc, (fc & IEEE80211_FCTL_FTYPE) >> 2,
0040 (fc & IEEE80211_FCTL_STYPE) >> 4,
0041 fc & IEEE80211_FCTL_TODS ? " [ToDS]" : "",
0042 fc & IEEE80211_FCTL_FROMDS ? " [FromDS]" : "");
0043
0044 if (skb->len < IEEE80211_DATA_HDR3_LEN) {
0045 printk("\n");
0046 return;
0047 }
0048
0049 printk(" dur=0x%04x seq=0x%04x\n", le16_to_cpu(hdr->duration_id),
0050 le16_to_cpu(hdr->seq_ctrl));
0051
0052 printk(KERN_DEBUG " A1=%pM", hdr->addr1);
0053 printk(" A2=%pM", hdr->addr2);
0054 printk(" A3=%pM", hdr->addr3);
0055 if (skb->len >= 30)
0056 printk(" A4=%pM", hdr->addr4);
0057 printk("\n");
0058 }
0059
0060
0061
0062
0063 int prism2_rx_80211(struct net_device *dev, struct sk_buff *skb,
0064 struct hostap_80211_rx_status *rx_stats, int type)
0065 {
0066 struct hostap_interface *iface;
0067 local_info_t *local;
0068 int hdrlen, phdrlen, head_need, tail_need;
0069 u16 fc;
0070 int prism_header, ret;
0071 struct ieee80211_hdr *fhdr;
0072
0073 iface = netdev_priv(dev);
0074 local = iface->local;
0075
0076 if (dev->type == ARPHRD_IEEE80211_PRISM) {
0077 if (local->monitor_type == PRISM2_MONITOR_PRISM) {
0078 prism_header = 1;
0079 phdrlen = sizeof(struct linux_wlan_ng_prism_hdr);
0080 } else {
0081 prism_header = 2;
0082 phdrlen = sizeof(struct linux_wlan_ng_cap_hdr);
0083 }
0084 } else if (dev->type == ARPHRD_IEEE80211_RADIOTAP) {
0085 prism_header = 3;
0086 phdrlen = sizeof(struct hostap_radiotap_rx);
0087 } else {
0088 prism_header = 0;
0089 phdrlen = 0;
0090 }
0091
0092 fhdr = (struct ieee80211_hdr *) skb->data;
0093 fc = le16_to_cpu(fhdr->frame_control);
0094
0095 if (type == PRISM2_RX_MGMT && (fc & IEEE80211_FCTL_VERS)) {
0096 printk(KERN_DEBUG "%s: dropped management frame with header "
0097 "version %d\n", dev->name, fc & IEEE80211_FCTL_VERS);
0098 dev_kfree_skb_any(skb);
0099 return 0;
0100 }
0101
0102 hdrlen = hostap_80211_get_hdrlen(fhdr->frame_control);
0103
0104
0105
0106 head_need = phdrlen;
0107 tail_need = 0;
0108 #ifdef PRISM2_ADD_BOGUS_CRC
0109 tail_need += 4;
0110 #endif
0111
0112 head_need -= skb_headroom(skb);
0113 tail_need -= skb_tailroom(skb);
0114
0115 if (head_need > 0 || tail_need > 0) {
0116 if (pskb_expand_head(skb, head_need > 0 ? head_need : 0,
0117 tail_need > 0 ? tail_need : 0,
0118 GFP_ATOMIC)) {
0119 printk(KERN_DEBUG "%s: prism2_rx_80211 failed to "
0120 "reallocate skb buffer\n", dev->name);
0121 dev_kfree_skb_any(skb);
0122 return 0;
0123 }
0124 }
0125
0126
0127
0128
0129 #ifdef PRISM2_ADD_BOGUS_CRC
0130 memset(skb_put(skb, 4), 0xff, 4);
0131 #endif
0132
0133 if (prism_header == 1) {
0134 struct linux_wlan_ng_prism_hdr *hdr;
0135 hdr = skb_push(skb, phdrlen);
0136 memset(hdr, 0, phdrlen);
0137 hdr->msgcode = LWNG_CAP_DID_BASE;
0138 hdr->msglen = sizeof(*hdr);
0139 memcpy(hdr->devname, dev->name, sizeof(hdr->devname));
0140 #define LWNG_SETVAL(f,i,s,l,d) \
0141 hdr->f.did = LWNG_CAP_DID_BASE | (i << 12); \
0142 hdr->f.status = s; hdr->f.len = l; hdr->f.data = d
0143 LWNG_SETVAL(hosttime, 1, 0, 4, jiffies);
0144 LWNG_SETVAL(mactime, 2, 0, 4, rx_stats->mac_time);
0145 LWNG_SETVAL(channel, 3, 1 , 4, 0);
0146 LWNG_SETVAL(rssi, 4, 1 , 4, 0);
0147 LWNG_SETVAL(sq, 5, 1 , 4, 0);
0148 LWNG_SETVAL(signal, 6, 0, 4, rx_stats->signal);
0149 LWNG_SETVAL(noise, 7, 0, 4, rx_stats->noise);
0150 LWNG_SETVAL(rate, 8, 0, 4, rx_stats->rate / 5);
0151 LWNG_SETVAL(istx, 9, 0, 4, 0);
0152 LWNG_SETVAL(frmlen, 10, 0, 4, skb->len - phdrlen);
0153 #undef LWNG_SETVAL
0154 } else if (prism_header == 2) {
0155 struct linux_wlan_ng_cap_hdr *hdr;
0156 hdr = skb_push(skb, phdrlen);
0157 memset(hdr, 0, phdrlen);
0158 hdr->version = htonl(LWNG_CAPHDR_VERSION);
0159 hdr->length = htonl(phdrlen);
0160 hdr->mactime = __cpu_to_be64(rx_stats->mac_time);
0161 hdr->hosttime = __cpu_to_be64(jiffies);
0162 hdr->phytype = htonl(4);
0163 hdr->channel = htonl(local->channel);
0164 hdr->datarate = htonl(rx_stats->rate);
0165 hdr->antenna = htonl(0);
0166 hdr->priority = htonl(0);
0167 hdr->ssi_type = htonl(3);
0168 hdr->ssi_signal = htonl(rx_stats->signal);
0169 hdr->ssi_noise = htonl(rx_stats->noise);
0170 hdr->preamble = htonl(0);
0171 hdr->encoding = htonl(1);
0172 } else if (prism_header == 3) {
0173 struct hostap_radiotap_rx *hdr;
0174 hdr = skb_push(skb, phdrlen);
0175 memset(hdr, 0, phdrlen);
0176 hdr->hdr.it_len = cpu_to_le16(phdrlen);
0177 hdr->hdr.it_present =
0178 cpu_to_le32((1 << IEEE80211_RADIOTAP_TSFT) |
0179 (1 << IEEE80211_RADIOTAP_CHANNEL) |
0180 (1 << IEEE80211_RADIOTAP_RATE) |
0181 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |
0182 (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE));
0183 hdr->tsft = cpu_to_le64(rx_stats->mac_time);
0184 hdr->chan_freq = cpu_to_le16(freq_list[local->channel - 1]);
0185 hdr->chan_flags = cpu_to_le16(IEEE80211_CHAN_CCK |
0186 IEEE80211_CHAN_2GHZ);
0187 hdr->rate = rx_stats->rate / 5;
0188 hdr->dbm_antsignal = rx_stats->signal;
0189 hdr->dbm_antnoise = rx_stats->noise;
0190 }
0191
0192 ret = skb->len - phdrlen;
0193 skb->dev = dev;
0194 skb_reset_mac_header(skb);
0195 skb_pull(skb, hdrlen);
0196 if (prism_header)
0197 skb_pull(skb, phdrlen);
0198 skb->pkt_type = PACKET_OTHERHOST;
0199 skb->protocol = cpu_to_be16(ETH_P_802_2);
0200 memset(skb->cb, 0, sizeof(skb->cb));
0201 netif_rx(skb);
0202
0203 return ret;
0204 }
0205
0206
0207
0208 static void monitor_rx(struct net_device *dev, struct sk_buff *skb,
0209 struct hostap_80211_rx_status *rx_stats)
0210 {
0211 int len;
0212
0213 len = prism2_rx_80211(dev, skb, rx_stats, PRISM2_RX_MONITOR);
0214 dev->stats.rx_packets++;
0215 dev->stats.rx_bytes += len;
0216 }
0217
0218
0219
0220 static struct prism2_frag_entry *
0221 prism2_frag_cache_find(local_info_t *local, unsigned int seq,
0222 unsigned int frag, u8 *src, u8 *dst)
0223 {
0224 struct prism2_frag_entry *entry;
0225 int i;
0226
0227 for (i = 0; i < PRISM2_FRAG_CACHE_LEN; i++) {
0228 entry = &local->frag_cache[i];
0229 if (entry->skb != NULL &&
0230 time_after(jiffies, entry->first_frag_time + 2 * HZ)) {
0231 printk(KERN_DEBUG "%s: expiring fragment cache entry "
0232 "seq=%u last_frag=%u\n",
0233 local->dev->name, entry->seq, entry->last_frag);
0234 dev_kfree_skb(entry->skb);
0235 entry->skb = NULL;
0236 }
0237
0238 if (entry->skb != NULL && entry->seq == seq &&
0239 (entry->last_frag + 1 == frag || frag == -1) &&
0240 memcmp(entry->src_addr, src, ETH_ALEN) == 0 &&
0241 memcmp(entry->dst_addr, dst, ETH_ALEN) == 0)
0242 return entry;
0243 }
0244
0245 return NULL;
0246 }
0247
0248
0249
0250 static struct sk_buff *
0251 prism2_frag_cache_get(local_info_t *local, struct ieee80211_hdr *hdr)
0252 {
0253 struct sk_buff *skb = NULL;
0254 u16 sc;
0255 unsigned int frag, seq;
0256 struct prism2_frag_entry *entry;
0257
0258 sc = le16_to_cpu(hdr->seq_ctrl);
0259 frag = sc & IEEE80211_SCTL_FRAG;
0260 seq = (sc & IEEE80211_SCTL_SEQ) >> 4;
0261
0262 if (frag == 0) {
0263
0264 skb = dev_alloc_skb(local->dev->mtu +
0265 sizeof(struct ieee80211_hdr) +
0266 8 +
0267 2 +
0268 8 + ETH_ALEN );
0269 if (skb == NULL)
0270 return NULL;
0271
0272 entry = &local->frag_cache[local->frag_next_idx];
0273 local->frag_next_idx++;
0274 if (local->frag_next_idx >= PRISM2_FRAG_CACHE_LEN)
0275 local->frag_next_idx = 0;
0276
0277 if (entry->skb != NULL)
0278 dev_kfree_skb(entry->skb);
0279
0280 entry->first_frag_time = jiffies;
0281 entry->seq = seq;
0282 entry->last_frag = frag;
0283 entry->skb = skb;
0284 memcpy(entry->src_addr, hdr->addr2, ETH_ALEN);
0285 memcpy(entry->dst_addr, hdr->addr1, ETH_ALEN);
0286 } else {
0287
0288
0289 entry = prism2_frag_cache_find(local, seq, frag, hdr->addr2,
0290 hdr->addr1);
0291 if (entry != NULL) {
0292 entry->last_frag = frag;
0293 skb = entry->skb;
0294 }
0295 }
0296
0297 return skb;
0298 }
0299
0300
0301
0302 static int prism2_frag_cache_invalidate(local_info_t *local,
0303 struct ieee80211_hdr *hdr)
0304 {
0305 u16 sc;
0306 unsigned int seq;
0307 struct prism2_frag_entry *entry;
0308
0309 sc = le16_to_cpu(hdr->seq_ctrl);
0310 seq = (sc & IEEE80211_SCTL_SEQ) >> 4;
0311
0312 entry = prism2_frag_cache_find(local, seq, -1, hdr->addr2, hdr->addr1);
0313
0314 if (entry == NULL) {
0315 printk(KERN_DEBUG "%s: could not invalidate fragment cache "
0316 "entry (seq=%u)\n",
0317 local->dev->name, seq);
0318 return -1;
0319 }
0320
0321 entry->skb = NULL;
0322 return 0;
0323 }
0324
0325
0326 static struct hostap_bss_info *__hostap_get_bss(local_info_t *local, u8 *bssid,
0327 u8 *ssid, size_t ssid_len)
0328 {
0329 struct list_head *ptr;
0330 struct hostap_bss_info *bss;
0331
0332 list_for_each(ptr, &local->bss_list) {
0333 bss = list_entry(ptr, struct hostap_bss_info, list);
0334 if (memcmp(bss->bssid, bssid, ETH_ALEN) == 0 &&
0335 (ssid == NULL ||
0336 (ssid_len == bss->ssid_len &&
0337 memcmp(ssid, bss->ssid, ssid_len) == 0))) {
0338 list_move(&bss->list, &local->bss_list);
0339 return bss;
0340 }
0341 }
0342
0343 return NULL;
0344 }
0345
0346
0347 static struct hostap_bss_info *__hostap_add_bss(local_info_t *local, u8 *bssid,
0348 u8 *ssid, size_t ssid_len)
0349 {
0350 struct hostap_bss_info *bss;
0351
0352 if (local->num_bss_info >= HOSTAP_MAX_BSS_COUNT) {
0353 bss = list_entry(local->bss_list.prev,
0354 struct hostap_bss_info, list);
0355 list_del(&bss->list);
0356 local->num_bss_info--;
0357 } else {
0358 bss = kmalloc(sizeof(*bss), GFP_ATOMIC);
0359 if (bss == NULL)
0360 return NULL;
0361 }
0362
0363 memset(bss, 0, sizeof(*bss));
0364 memcpy(bss->bssid, bssid, ETH_ALEN);
0365 memcpy(bss->ssid, ssid, ssid_len);
0366 bss->ssid_len = ssid_len;
0367 local->num_bss_info++;
0368 list_add(&bss->list, &local->bss_list);
0369 return bss;
0370 }
0371
0372
0373 static void __hostap_expire_bss(local_info_t *local)
0374 {
0375 struct hostap_bss_info *bss;
0376
0377 while (local->num_bss_info > 0) {
0378 bss = list_entry(local->bss_list.prev,
0379 struct hostap_bss_info, list);
0380 if (!time_after(jiffies, bss->last_update + 60 * HZ))
0381 break;
0382
0383 list_del(&bss->list);
0384 local->num_bss_info--;
0385 kfree(bss);
0386 }
0387 }
0388
0389
0390
0391
0392 static void hostap_rx_sta_beacon(local_info_t *local, struct sk_buff *skb,
0393 int stype)
0394 {
0395 struct hostap_ieee80211_mgmt *mgmt;
0396 int left, chan = 0;
0397 u8 *pos;
0398 u8 *ssid = NULL, *wpa = NULL, *rsn = NULL;
0399 size_t ssid_len = 0, wpa_len = 0, rsn_len = 0;
0400 struct hostap_bss_info *bss;
0401
0402 if (skb->len < IEEE80211_MGMT_HDR_LEN + sizeof(mgmt->u.beacon))
0403 return;
0404
0405 mgmt = (struct hostap_ieee80211_mgmt *) skb->data;
0406 pos = mgmt->u.beacon.variable;
0407 left = skb->len - (pos - skb->data);
0408
0409 while (left >= 2) {
0410 if (2 + pos[1] > left)
0411 return;
0412 switch (*pos) {
0413 case WLAN_EID_SSID:
0414 ssid = pos + 2;
0415 ssid_len = pos[1];
0416 break;
0417 case WLAN_EID_VENDOR_SPECIFIC:
0418 if (pos[1] >= 4 &&
0419 pos[2] == 0x00 && pos[3] == 0x50 &&
0420 pos[4] == 0xf2 && pos[5] == 1) {
0421 wpa = pos;
0422 wpa_len = pos[1] + 2;
0423 }
0424 break;
0425 case WLAN_EID_RSN:
0426 rsn = pos;
0427 rsn_len = pos[1] + 2;
0428 break;
0429 case WLAN_EID_DS_PARAMS:
0430 if (pos[1] >= 1)
0431 chan = pos[2];
0432 break;
0433 }
0434 left -= 2 + pos[1];
0435 pos += 2 + pos[1];
0436 }
0437
0438 if (wpa_len > MAX_WPA_IE_LEN)
0439 wpa_len = MAX_WPA_IE_LEN;
0440 if (rsn_len > MAX_WPA_IE_LEN)
0441 rsn_len = MAX_WPA_IE_LEN;
0442 if (ssid_len > sizeof(bss->ssid))
0443 ssid_len = sizeof(bss->ssid);
0444
0445 spin_lock(&local->lock);
0446 bss = __hostap_get_bss(local, mgmt->bssid, ssid, ssid_len);
0447 if (bss == NULL)
0448 bss = __hostap_add_bss(local, mgmt->bssid, ssid, ssid_len);
0449 if (bss) {
0450 bss->last_update = jiffies;
0451 bss->count++;
0452 bss->capab_info = le16_to_cpu(mgmt->u.beacon.capab_info);
0453 if (wpa) {
0454 memcpy(bss->wpa_ie, wpa, wpa_len);
0455 bss->wpa_ie_len = wpa_len;
0456 } else
0457 bss->wpa_ie_len = 0;
0458 if (rsn) {
0459 memcpy(bss->rsn_ie, rsn, rsn_len);
0460 bss->rsn_ie_len = rsn_len;
0461 } else
0462 bss->rsn_ie_len = 0;
0463 bss->chan = chan;
0464 }
0465 __hostap_expire_bss(local);
0466 spin_unlock(&local->lock);
0467 }
0468
0469
0470 static int
0471 hostap_rx_frame_mgmt(local_info_t *local, struct sk_buff *skb,
0472 struct hostap_80211_rx_status *rx_stats, u16 type,
0473 u16 stype)
0474 {
0475 if (local->iw_mode == IW_MODE_MASTER)
0476 hostap_update_sta_ps(local, (struct ieee80211_hdr *) skb->data);
0477
0478 if (local->hostapd && type == IEEE80211_FTYPE_MGMT) {
0479 if (stype == IEEE80211_STYPE_BEACON &&
0480 local->iw_mode == IW_MODE_MASTER) {
0481 struct sk_buff *skb2;
0482
0483
0484 skb2 = skb_clone(skb, GFP_ATOMIC);
0485 if (skb2)
0486 hostap_rx(skb2->dev, skb2, rx_stats);
0487 }
0488
0489
0490
0491 local->apdevstats.rx_packets++;
0492 local->apdevstats.rx_bytes += skb->len;
0493 if (local->apdev == NULL)
0494 return -1;
0495 prism2_rx_80211(local->apdev, skb, rx_stats, PRISM2_RX_MGMT);
0496 return 0;
0497 }
0498
0499 if (local->iw_mode == IW_MODE_MASTER) {
0500 if (type != IEEE80211_FTYPE_MGMT &&
0501 type != IEEE80211_FTYPE_CTL) {
0502 printk(KERN_DEBUG "%s: unknown management frame "
0503 "(type=0x%02x, stype=0x%02x) dropped\n",
0504 skb->dev->name, type >> 2, stype >> 4);
0505 return -1;
0506 }
0507
0508 hostap_rx(skb->dev, skb, rx_stats);
0509 return 0;
0510 } else if (type == IEEE80211_FTYPE_MGMT &&
0511 (stype == IEEE80211_STYPE_BEACON ||
0512 stype == IEEE80211_STYPE_PROBE_RESP)) {
0513 hostap_rx_sta_beacon(local, skb, stype);
0514 return -1;
0515 } else if (type == IEEE80211_FTYPE_MGMT &&
0516 (stype == IEEE80211_STYPE_ASSOC_RESP ||
0517 stype == IEEE80211_STYPE_REASSOC_RESP)) {
0518
0519
0520
0521 return -1;
0522 } else {
0523 printk(KERN_DEBUG "%s: hostap_rx_frame_mgmt: dropped unhandled"
0524 " management frame in non-Host AP mode (type=%d:%d)\n",
0525 skb->dev->name, type >> 2, stype >> 4);
0526 return -1;
0527 }
0528 }
0529
0530
0531
0532 static struct net_device *prism2_rx_get_wds(local_info_t *local,
0533 u8 *addr)
0534 {
0535 struct hostap_interface *iface = NULL;
0536 struct list_head *ptr;
0537
0538 read_lock_bh(&local->iface_lock);
0539 list_for_each(ptr, &local->hostap_interfaces) {
0540 iface = list_entry(ptr, struct hostap_interface, list);
0541 if (iface->type == HOSTAP_INTERFACE_WDS &&
0542 memcmp(iface->u.wds.remote_addr, addr, ETH_ALEN) == 0)
0543 break;
0544 iface = NULL;
0545 }
0546 read_unlock_bh(&local->iface_lock);
0547
0548 return iface ? iface->dev : NULL;
0549 }
0550
0551
0552 static int
0553 hostap_rx_frame_wds(local_info_t *local, struct ieee80211_hdr *hdr, u16 fc,
0554 struct net_device **wds)
0555 {
0556
0557
0558 if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) !=
0559 (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS) &&
0560 (local->iw_mode != IW_MODE_MASTER || !(fc & IEEE80211_FCTL_TODS)))
0561 return 0;
0562
0563
0564
0565 if (!ether_addr_equal(hdr->addr1, local->dev->dev_addr) &&
0566 (hdr->addr1[0] != 0xff || hdr->addr1[1] != 0xff ||
0567 hdr->addr1[2] != 0xff || hdr->addr1[3] != 0xff ||
0568 hdr->addr1[4] != 0xff || hdr->addr1[5] != 0xff)) {
0569
0570 PDEBUG(DEBUG_EXTRA2, "%s: received WDS frame with "
0571 "not own or broadcast %s=%pM\n",
0572 local->dev->name,
0573 fc & IEEE80211_FCTL_FROMDS ? "RA" : "BSSID",
0574 hdr->addr1);
0575 return -1;
0576 }
0577
0578
0579 *wds = prism2_rx_get_wds(local, hdr->addr2);
0580 if (*wds == NULL && fc & IEEE80211_FCTL_FROMDS &&
0581 (local->iw_mode != IW_MODE_INFRA ||
0582 !(local->wds_type & HOSTAP_WDS_AP_CLIENT) ||
0583 memcmp(hdr->addr2, local->bssid, ETH_ALEN) != 0)) {
0584
0585
0586 PDEBUG(DEBUG_EXTRA, "%s: received WDS[4 addr] frame "
0587 "from unknown TA=%pM\n",
0588 local->dev->name, hdr->addr2);
0589 if (local->ap && local->ap->autom_ap_wds)
0590 hostap_wds_link_oper(local, hdr->addr2, WDS_ADD);
0591 return -1;
0592 }
0593
0594 if (*wds && !(fc & IEEE80211_FCTL_FROMDS) && local->ap &&
0595 hostap_is_sta_assoc(local->ap, hdr->addr2)) {
0596
0597
0598
0599
0600
0601 *wds = NULL;
0602 }
0603
0604 return 0;
0605 }
0606
0607
0608 static int hostap_is_eapol_frame(local_info_t *local, struct sk_buff *skb)
0609 {
0610 struct net_device *dev = local->dev;
0611 u16 fc, ethertype;
0612 struct ieee80211_hdr *hdr;
0613 u8 *pos;
0614
0615 if (skb->len < 24)
0616 return 0;
0617
0618 hdr = (struct ieee80211_hdr *) skb->data;
0619 fc = le16_to_cpu(hdr->frame_control);
0620
0621
0622 if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
0623 IEEE80211_FCTL_TODS &&
0624 ether_addr_equal(hdr->addr1, dev->dev_addr) &&
0625 ether_addr_equal(hdr->addr3, dev->dev_addr)) {
0626
0627 } else if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
0628 IEEE80211_FCTL_FROMDS &&
0629 ether_addr_equal(hdr->addr1, dev->dev_addr)) {
0630
0631 } else
0632 return 0;
0633
0634 if (skb->len < 24 + 8)
0635 return 0;
0636
0637
0638 pos = skb->data + 24;
0639 ethertype = (pos[6] << 8) | pos[7];
0640 if (ethertype == ETH_P_PAE)
0641 return 1;
0642
0643 return 0;
0644 }
0645
0646
0647
0648 static int
0649 hostap_rx_frame_decrypt(local_info_t *local, struct sk_buff *skb,
0650 struct lib80211_crypt_data *crypt)
0651 {
0652 struct ieee80211_hdr *hdr;
0653 int res, hdrlen;
0654
0655 if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
0656 return 0;
0657
0658 hdr = (struct ieee80211_hdr *) skb->data;
0659 hdrlen = hostap_80211_get_hdrlen(hdr->frame_control);
0660
0661 if (local->tkip_countermeasures &&
0662 strcmp(crypt->ops->name, "TKIP") == 0) {
0663 if (net_ratelimit()) {
0664 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
0665 "received packet from %pM\n",
0666 local->dev->name, hdr->addr2);
0667 }
0668 return -1;
0669 }
0670
0671 atomic_inc(&crypt->refcnt);
0672 res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv);
0673 atomic_dec(&crypt->refcnt);
0674 if (res < 0) {
0675 printk(KERN_DEBUG "%s: decryption failed (SA=%pM) res=%d\n",
0676 local->dev->name, hdr->addr2, res);
0677 local->comm_tallies.rx_discards_wep_undecryptable++;
0678 return -1;
0679 }
0680
0681 return res;
0682 }
0683
0684
0685
0686 static int
0687 hostap_rx_frame_decrypt_msdu(local_info_t *local, struct sk_buff *skb,
0688 int keyidx, struct lib80211_crypt_data *crypt)
0689 {
0690 struct ieee80211_hdr *hdr;
0691 int res, hdrlen;
0692
0693 if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
0694 return 0;
0695
0696 hdr = (struct ieee80211_hdr *) skb->data;
0697 hdrlen = hostap_80211_get_hdrlen(hdr->frame_control);
0698
0699 atomic_inc(&crypt->refcnt);
0700 res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv);
0701 atomic_dec(&crypt->refcnt);
0702 if (res < 0) {
0703 printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
0704 " (SA=%pM keyidx=%d)\n",
0705 local->dev->name, hdr->addr2, keyidx);
0706 return -1;
0707 }
0708
0709 return 0;
0710 }
0711
0712
0713
0714
0715
0716 void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
0717 struct hostap_80211_rx_status *rx_stats)
0718 {
0719 struct hostap_interface *iface;
0720 local_info_t *local;
0721 struct ieee80211_hdr *hdr;
0722 size_t hdrlen;
0723 u16 fc, type, stype, sc;
0724 struct net_device *wds = NULL;
0725 unsigned int frag;
0726 u8 *payload;
0727 struct sk_buff *skb2 = NULL;
0728 u16 ethertype;
0729 int frame_authorized = 0;
0730 int from_assoc_ap = 0;
0731 u8 dst[ETH_ALEN];
0732 u8 src[ETH_ALEN];
0733 struct lib80211_crypt_data *crypt = NULL;
0734 void *sta = NULL;
0735 int keyidx = 0;
0736
0737 iface = netdev_priv(dev);
0738 local = iface->local;
0739 iface->stats.rx_packets++;
0740 iface->stats.rx_bytes += skb->len;
0741
0742
0743
0744 dev = local->ddev;
0745 iface = netdev_priv(dev);
0746
0747 hdr = (struct ieee80211_hdr *) skb->data;
0748
0749 if (skb->len < 10)
0750 goto rx_dropped;
0751
0752 fc = le16_to_cpu(hdr->frame_control);
0753 type = fc & IEEE80211_FCTL_FTYPE;
0754 stype = fc & IEEE80211_FCTL_STYPE;
0755 sc = le16_to_cpu(hdr->seq_ctrl);
0756 frag = sc & IEEE80211_SCTL_FRAG;
0757 hdrlen = hostap_80211_get_hdrlen(hdr->frame_control);
0758
0759
0760
0761 #ifdef IW_WIRELESS_SPY
0762
0763 if (iface->spy_data.spy_number > 0) {
0764 struct iw_quality wstats;
0765 wstats.level = rx_stats->signal;
0766 wstats.noise = rx_stats->noise;
0767 wstats.updated = IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_UPDATED
0768 | IW_QUAL_QUAL_INVALID | IW_QUAL_DBM;
0769
0770 wireless_spy_update(dev, hdr->addr2, &wstats);
0771 }
0772 #endif
0773 hostap_update_rx_stats(local->ap, hdr, rx_stats);
0774
0775 if (local->iw_mode == IW_MODE_MONITOR) {
0776 monitor_rx(dev, skb, rx_stats);
0777 return;
0778 }
0779
0780 if (local->host_decrypt) {
0781 int idx = 0;
0782 if (skb->len >= hdrlen + 3)
0783 idx = skb->data[hdrlen + 3] >> 6;
0784 crypt = local->crypt_info.crypt[idx];
0785 sta = NULL;
0786
0787
0788
0789
0790
0791
0792
0793
0794 if (!(hdr->addr1[0] & 0x01) || local->bcrx_sta_key)
0795 (void) hostap_handle_sta_crypto(local, hdr, &crypt,
0796 &sta);
0797
0798
0799
0800 if (crypt && (crypt->ops == NULL ||
0801 crypt->ops->decrypt_mpdu == NULL))
0802 crypt = NULL;
0803
0804 if (!crypt && (fc & IEEE80211_FCTL_PROTECTED)) {
0805 #if 0
0806
0807
0808
0809
0810 printk(KERN_DEBUG "%s: WEP decryption failed (not set)"
0811 " (SA=%pM)\n",
0812 local->dev->name, hdr->addr2);
0813 #endif
0814 local->comm_tallies.rx_discards_wep_undecryptable++;
0815 goto rx_dropped;
0816 }
0817 }
0818
0819 if (type != IEEE80211_FTYPE_DATA) {
0820 if (type == IEEE80211_FTYPE_MGMT &&
0821 stype == IEEE80211_STYPE_AUTH &&
0822 fc & IEEE80211_FCTL_PROTECTED && local->host_decrypt &&
0823 (keyidx = hostap_rx_frame_decrypt(local, skb, crypt)) < 0)
0824 {
0825 printk(KERN_DEBUG "%s: failed to decrypt mgmt::auth "
0826 "from %pM\n", dev->name, hdr->addr2);
0827
0828
0829 goto rx_dropped;
0830 }
0831
0832 if (hostap_rx_frame_mgmt(local, skb, rx_stats, type, stype))
0833 goto rx_dropped;
0834 else
0835 goto rx_exit;
0836 }
0837
0838
0839 if (skb->len < IEEE80211_DATA_HDR3_LEN)
0840 goto rx_dropped;
0841
0842 switch (fc & (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
0843 case IEEE80211_FCTL_FROMDS:
0844 memcpy(dst, hdr->addr1, ETH_ALEN);
0845 memcpy(src, hdr->addr3, ETH_ALEN);
0846 break;
0847 case IEEE80211_FCTL_TODS:
0848 memcpy(dst, hdr->addr3, ETH_ALEN);
0849 memcpy(src, hdr->addr2, ETH_ALEN);
0850 break;
0851 case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
0852 if (skb->len < IEEE80211_DATA_HDR4_LEN)
0853 goto rx_dropped;
0854 memcpy(dst, hdr->addr3, ETH_ALEN);
0855 memcpy(src, hdr->addr4, ETH_ALEN);
0856 break;
0857 default:
0858 memcpy(dst, hdr->addr1, ETH_ALEN);
0859 memcpy(src, hdr->addr2, ETH_ALEN);
0860 break;
0861 }
0862
0863 if (hostap_rx_frame_wds(local, hdr, fc, &wds))
0864 goto rx_dropped;
0865 if (wds)
0866 skb->dev = dev = wds;
0867
0868 if (local->iw_mode == IW_MODE_MASTER && !wds &&
0869 (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
0870 IEEE80211_FCTL_FROMDS &&
0871 local->stadev &&
0872 memcmp(hdr->addr2, local->assoc_ap_addr, ETH_ALEN) == 0) {
0873
0874 skb->dev = dev = local->stadev;
0875 from_assoc_ap = 1;
0876 }
0877
0878 if ((local->iw_mode == IW_MODE_MASTER ||
0879 local->iw_mode == IW_MODE_REPEAT) &&
0880 !from_assoc_ap) {
0881 switch (hostap_handle_sta_rx(local, dev, skb, rx_stats,
0882 wds != NULL)) {
0883 case AP_RX_CONTINUE_NOT_AUTHORIZED:
0884 frame_authorized = 0;
0885 break;
0886 case AP_RX_CONTINUE:
0887 frame_authorized = 1;
0888 break;
0889 case AP_RX_DROP:
0890 goto rx_dropped;
0891 case AP_RX_EXIT:
0892 goto rx_exit;
0893 }
0894 }
0895
0896
0897
0898 if (stype != IEEE80211_STYPE_DATA &&
0899 stype != IEEE80211_STYPE_DATA_CFACK &&
0900 stype != IEEE80211_STYPE_DATA_CFPOLL &&
0901 stype != IEEE80211_STYPE_DATA_CFACKPOLL) {
0902 if (stype != IEEE80211_STYPE_NULLFUNC)
0903 printk(KERN_DEBUG "%s: RX: dropped data frame "
0904 "with no data (type=0x%02x, subtype=0x%02x)\n",
0905 dev->name, type >> 2, stype >> 4);
0906 goto rx_dropped;
0907 }
0908
0909
0910
0911 if (local->host_decrypt && (fc & IEEE80211_FCTL_PROTECTED) &&
0912 (keyidx = hostap_rx_frame_decrypt(local, skb, crypt)) < 0)
0913 goto rx_dropped;
0914 hdr = (struct ieee80211_hdr *) skb->data;
0915
0916
0917
0918 if (local->host_decrypt && (fc & IEEE80211_FCTL_PROTECTED) &&
0919 (frag != 0 || (fc & IEEE80211_FCTL_MOREFRAGS))) {
0920 int flen;
0921 struct sk_buff *frag_skb =
0922 prism2_frag_cache_get(local, hdr);
0923 if (!frag_skb) {
0924 printk(KERN_DEBUG "%s: Rx cannot get skb from "
0925 "fragment cache (morefrag=%d seq=%u frag=%u)\n",
0926 dev->name, (fc & IEEE80211_FCTL_MOREFRAGS) != 0,
0927 (sc & IEEE80211_SCTL_SEQ) >> 4, frag);
0928 goto rx_dropped;
0929 }
0930
0931 flen = skb->len;
0932 if (frag != 0)
0933 flen -= hdrlen;
0934
0935 if (frag_skb->tail + flen > frag_skb->end) {
0936 printk(KERN_WARNING "%s: host decrypted and "
0937 "reassembled frame did not fit skb\n",
0938 dev->name);
0939 prism2_frag_cache_invalidate(local, hdr);
0940 goto rx_dropped;
0941 }
0942
0943 if (frag == 0) {
0944
0945
0946 skb_copy_from_linear_data(skb, skb_put(frag_skb, flen),
0947 flen);
0948 } else {
0949
0950
0951 skb_copy_from_linear_data_offset(skb, hdrlen,
0952 skb_put(frag_skb,
0953 flen), flen);
0954 }
0955 dev_kfree_skb(skb);
0956 skb = NULL;
0957
0958 if (fc & IEEE80211_FCTL_MOREFRAGS) {
0959
0960
0961
0962 goto rx_exit;
0963 }
0964
0965
0966
0967 skb = frag_skb;
0968 hdr = (struct ieee80211_hdr *) skb->data;
0969 prism2_frag_cache_invalidate(local, hdr);
0970 }
0971
0972
0973
0974
0975 if (local->host_decrypt && (fc & IEEE80211_FCTL_PROTECTED) &&
0976 hostap_rx_frame_decrypt_msdu(local, skb, keyidx, crypt))
0977 goto rx_dropped;
0978
0979 hdr = (struct ieee80211_hdr *) skb->data;
0980 if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && !local->open_wep) {
0981 if (local->ieee_802_1x &&
0982 hostap_is_eapol_frame(local, skb)) {
0983
0984
0985 PDEBUG(DEBUG_EXTRA2, "%s: RX: IEEE 802.1X - passing "
0986 "unencrypted EAPOL frame\n", local->dev->name);
0987 } else {
0988 printk(KERN_DEBUG "%s: encryption configured, but RX "
0989 "frame not encrypted (SA=%pM)\n",
0990 local->dev->name, hdr->addr2);
0991 goto rx_dropped;
0992 }
0993 }
0994
0995 if (local->drop_unencrypted && !(fc & IEEE80211_FCTL_PROTECTED) &&
0996 !hostap_is_eapol_frame(local, skb)) {
0997 if (net_ratelimit()) {
0998 printk(KERN_DEBUG "%s: dropped unencrypted RX data "
0999 "frame from %pM (drop_unencrypted=1)\n",
1000 dev->name, hdr->addr2);
1001 }
1002 goto rx_dropped;
1003 }
1004
1005
1006
1007 payload = skb->data + hdrlen;
1008 ethertype = (payload[6] << 8) | payload[7];
1009
1010
1011
1012 if (local->ieee_802_1x && local->iw_mode == IW_MODE_MASTER) {
1013 if (ethertype == ETH_P_PAE) {
1014 PDEBUG(DEBUG_EXTRA2, "%s: RX: IEEE 802.1X frame\n",
1015 dev->name);
1016 if (local->hostapd && local->apdev) {
1017
1018
1019 prism2_rx_80211(local->apdev, skb, rx_stats,
1020 PRISM2_RX_MGMT);
1021 local->apdevstats.rx_packets++;
1022 local->apdevstats.rx_bytes += skb->len;
1023 goto rx_exit;
1024 }
1025 } else if (!frame_authorized) {
1026 printk(KERN_DEBUG "%s: dropped frame from "
1027 "unauthorized port (IEEE 802.1X): "
1028 "ethertype=0x%04x\n",
1029 dev->name, ethertype);
1030 goto rx_dropped;
1031 }
1032 }
1033
1034
1035 if (skb->len - hdrlen >= 8 &&
1036 ((memcmp(payload, rfc1042_header, 6) == 0 &&
1037 ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
1038 memcmp(payload, bridge_tunnel_header, 6) == 0)) {
1039
1040
1041 skb_pull(skb, hdrlen + 6);
1042 memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
1043 memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
1044 } else {
1045 __be16 len;
1046
1047 skb_pull(skb, hdrlen);
1048 len = htons(skb->len);
1049 memcpy(skb_push(skb, 2), &len, 2);
1050 memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
1051 memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
1052 }
1053
1054 if (wds && ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
1055 IEEE80211_FCTL_TODS) &&
1056 skb->len >= ETH_HLEN + ETH_ALEN) {
1057
1058
1059 skb_copy_from_linear_data_offset(skb, skb->len - ETH_ALEN,
1060 skb->data + ETH_ALEN,
1061 ETH_ALEN);
1062 skb_trim(skb, skb->len - ETH_ALEN);
1063 }
1064
1065 dev->stats.rx_packets++;
1066 dev->stats.rx_bytes += skb->len;
1067
1068 if (local->iw_mode == IW_MODE_MASTER && !wds &&
1069 local->ap->bridge_packets) {
1070 if (dst[0] & 0x01) {
1071
1072
1073 local->ap->bridged_multicast++;
1074 skb2 = skb_clone(skb, GFP_ATOMIC);
1075 if (skb2 == NULL)
1076 printk(KERN_DEBUG "%s: skb_clone failed for "
1077 "multicast frame\n", dev->name);
1078 } else if (hostap_is_sta_authorized(local->ap, dst)) {
1079
1080
1081 local->ap->bridged_unicast++;
1082 skb2 = skb;
1083 skb = NULL;
1084 }
1085 }
1086
1087 if (skb2 != NULL) {
1088
1089 skb2->dev = dev;
1090 skb2->protocol = cpu_to_be16(ETH_P_802_3);
1091 skb_reset_mac_header(skb2);
1092 skb_reset_network_header(skb2);
1093
1094 dev_queue_xmit(skb2);
1095 }
1096
1097 if (skb) {
1098 skb->protocol = eth_type_trans(skb, dev);
1099 memset(skb->cb, 0, sizeof(skb->cb));
1100 netif_rx(skb);
1101 }
1102
1103 rx_exit:
1104 if (sta)
1105 hostap_handle_sta_release(sta);
1106 return;
1107
1108 rx_dropped:
1109 dev_kfree_skb(skb);
1110
1111 dev->stats.rx_dropped++;
1112 goto rx_exit;
1113 }
1114
1115
1116 EXPORT_SYMBOL(hostap_80211_rx);