📄 ieee80211_rx.c
字号:
u16 sc; unsigned int seq; struct ieee80211_frag_entry *entry; sc = le16_to_cpu(hdr->seq_ctrl); seq = WLAN_GET_SEQ_SEQ(sc); entry = ieee80211_frag_cache_find(ieee, seq, -1, hdr->addr2, hdr->addr1); if (entry == NULL) { printk(KERN_DEBUG "%s: could not invalidate fragment cache " "entry (seq=%u)\n", ieee->dev->name, seq); return -1; } entry->skb = NULL; return 0;} static inline voidieee80211_rx_probe_rq(struct ieee80211_device *ieee, struct sk_buff *skb){ u8 dest[ETH_ALEN]; //IEEE80211DMESG("Rx probe"); ieee->ieee_stats.rx_probe++; //DMESG("Dest is "MACSTR, MAC2STR(dest)); if (probe_rq_parse(ieee, skb, dest)){ //IEEE80211DMESG("Was for me!"); ieee->ieee_stats.tx_probe++; ieee80211_resp_to_probe(ieee, dest); }}static inline voidieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb){ u8 dest[ETH_ALEN]; int status; //IEEE80211DMESG("Rx probe"); ieee->ieee_stats.rx_auth_rq++; if((status = auth_rq_parse(skb,dest))!= -1){ ieee80211_resp_to_auth(ieee,status,dest); } //DMESG("Dest is "MACSTR, MAC2STR(dest)); }static inline voidieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb){ u8 dest[ETH_ALEN]; unsigned long flags; ieee->ieee_stats.rx_assoc_rq++; if(assoc_rq_parse(skb,dest)!=-1){ ieee80211_resp_to_assoc_rq(ieee,dest); } IEEE80211DMESG("New client associated: "MACSTR, MAC2STR(dest)); spin_lock_irqsave(&ieee->lock,flags); add_associate(ieee,dest); spin_unlock_irqrestore(&ieee->lock,flags);}static inline intieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats, u16 type, u16 stype){ u16 errcode; #if 0 if (ieee->iw_mode == IW_MODE_MASTER) { printk(KERN_DEBUG "%s: Master mode not yet suppported.\n", ieee->dev->name); return 0; /* hostap_update_sta_ps(ieee, (struct hostap_ieee80211_hdr *) skb->data);*/ } #endif if (type == WLAN_FC_TYPE_MGMT) { if (stype == IEEE802_11_STYPE_BEACON || stype == IEEE802_11_STYPE_PROBE_RESP){ // struct sk_buff *skb2; /* Process beacon frames also in kernel driver to * update STA(AP) table statistics */ // skb2 = skb_clone(skb, GFP_ATOMIC); // if (skb2) /*if(ieee->link_state!=WLAN_LINK_ASSOCIATED)*/ if(ieee80211_rx_beacon(ieee, skb,rx_stats)) return -1; else return 1; } if(ieee->iw_mode == IW_MODE_MASTER && (stype == IEEE802_11_STYPE_ASSOC_REQ || stype == IEEE802_11_STYPE_REASSOC_REQ)) ieee80211_rx_assoc_rq(ieee, skb); if(ieee->iw_mode == IW_MODE_MASTER && stype == IEEE802_11_STYPE_AUTH) ieee80211_rx_auth_rq(ieee, skb); if(((ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER)&& ieee->link_state == WLAN_LINK_ASSOCIATED) && stype == IEEE802_11_STYPE_PROBE_REQ) ieee80211_rx_probe_rq(ieee, skb); if(ieee->link_state == WLAN_LINK_ASSOCIATED && ieee->iw_mode == IW_MODE_INFRA){ if(stype == IEEE802_11_STYPE_DISASSOC || stype == IEEE802_11_STYPE_DEAUTH){ ieee->func->data_poll_hard_stop(ieee->dev); ieee->link_state = WLAN_LINK_ASSOCIATING; ieee->ieee_stats.reassoc++; ieee80211_associate_step1(ieee); //queue_work(ieee->workqueue ,&ieee->associate_tasklet); } } if(ieee->link_state == WLAN_LINK_ASSOCIATING && ieee->iw_mode == IW_MODE_INFRA){ if(ieee->associate_state==ASSOC_AUTH) if(stype == IEEE802_11_STYPE_AUTH){ IEEE80211DMESG("Received authentication response"); if(0 == (errcode=auth_parse(skb))){ ieee->associate_state=ASSOC_REQ; ieee->ieee_stats.rx_aut_ok++; ieee80211_associate_step2(ieee); }else{ ieee->ieee_stats.rx_aut_err++; IEEE80211DMESG("Authentication respose status code 0x%x",errcode); ieee80211_associate_abort(ieee); } } if(ieee->associate_state==ASSOC_REQ) if(stype == IEEE802_11_STYPE_ASSOC_RESP){ IEEE80211DMESG("Received association response"); if(0 == (errcode=assoc_parse(skb))) { ieee->associate_state=ASSOC_SUCCESS; ieee->ieee_stats.rx_ass_ok++; ieee80211_associate_complete(ieee); }else{ ieee->ieee_stats.rx_ass_err++; IEEE80211DMESG("Association response status code 0x%x",errcode); ieee80211_associate_abort(ieee); } } } /* send management frames to the user space daemon for * processing */ //ieee->apdevstats.rx_packets++; //ieee->apdevstats.rx_bytes += skb->len; //prism2_rx_80211(ieee->apdev, skb, rx_stats, PRISM2_RX_MGMT); return 0; }#if 0 if (ieee->iw_mode == IW_MODE_MASTER) { if (type != WLAN_FC_TYPE_MGMT && type != WLAN_FC_TYPE_CTRL) { printk(KERN_DEBUG "%s: unknown management frame " "(type=0x%02x, stype=0x%02x) dropped\n", skb->dev->name, type, stype); return -1; } hostap_rx(skb->dev, skb, rx_stats); return 0; } #endif printk(KERN_DEBUG "%s: hostap_rx_frame_mgmt: management frame " "received in non-Host AP mode\n", skb->dev->name); return -1;}/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation *//* Ethernet-II snap header (RFC1042 for most EtherTypes) */static unsigned char rfc1042_header[] ={ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */static unsigned char bridge_tunnel_header[] ={ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };/* No encapsulation header if EtherType < 0x600 (=length) */#ifndef CONFIG_IEEE80211_NOWEP/* Called by ieee80211_rx_frame_decrypt */static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee, struct sk_buff *skb){ struct net_device *dev = ieee->dev; u16 fc, ethertype; struct ieee80211_hdr *hdr; u8 *pos; if (skb->len < 24) return 0; hdr = (struct ieee80211_hdr *) skb->data; fc = le16_to_cpu(hdr->frame_control); /* check that the frame is unicast frame to us */ if ((fc & (IEEE802_11_FCTL_TODS | IEEE802_11_FCTL_FROMDS)) == IEEE802_11_FCTL_TODS && memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0 && memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) { /* ToDS frame with own addr BSSID and DA */ } else if ((fc & (IEEE802_11_FCTL_TODS | IEEE802_11_FCTL_FROMDS)) == IEEE802_11_FCTL_FROMDS && memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) { /* FromDS frame with own addr as DA */ } else return 0; if (skb->len < 24 + 8) return 0; /* check for port access entity Ethernet type */ pos = skb->data + 24; ethertype = (pos[6] << 8) | pos[7]; if (ethertype == ETH_P_PAE) return 1; return 0;}/* Called only as a tasklet (software IRQ), by ieee80211_rx */static inline intieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb, struct ieee80211_crypt_data *crypt){ struct ieee80211_hdr *hdr; int res, hdrlen; if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL) return 0; hdr = (struct ieee80211_hdr *) skb->data; hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control));#ifdef NOT_YET if (ieee->tkip_countermeasures && strcmp(crypt->ops->name, "TKIP") == 0) { if (net_ratelimit()) { printk(KERN_DEBUG "%s: TKIP countermeasures: dropped " "received packet from " MACSTR "\n", ieee->dev->name, MAC2STR(hdr->addr2)); } return -1; }#endif atomic_inc(&crypt->refcnt); res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv); atomic_dec(&crypt->refcnt); if (res < 0) { printk(KERN_DEBUG "%s: decryption failed (SA=" MACSTR ") res=%d\n", ieee->dev->name, MAC2STR(hdr->addr2), res); if (res == -2) printk(KERN_DEBUG "%s: WEP decryption failed ICV mismatch\n", ieee->dev->name); ieee->ieee_stats.rx_discards_wep_undecryptable++; return -1; } return res;}/* Called only as a tasklet (software IRQ), by ieee80211_rx */static inline intieee80211_rx_frame_decrypt_msdu(struct ieee80211_device* ieee, struct sk_buff *skb, int keyidx, struct ieee80211_crypt_data *crypt){ struct ieee80211_hdr *hdr; int res, hdrlen; if (crypt == NULL || crypt->ops->decrypt_msdu == NULL) return 0; hdr = (struct ieee80211_hdr *) skb->data; hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control)); atomic_inc(&crypt->refcnt); res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv); atomic_dec(&crypt->refcnt); if (res < 0) { printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed" " (SA=" MACSTR " keyidx=%d)\n", ieee->dev->name, MAC2STR(hdr->addr2), keyidx); return -1; } return 0;}#endif /* CONFIG_IEEE80211_NOWEP *//* All received frames are sent to this function. @skb contains the frame in * IEEE 802.11 format, i.e., in the format it was sent over air. * This function is called only as a tasklet (software IRQ). */int ieee80211_r8180_rx(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats){ struct net_device *dev = ieee->dev; struct ieee80211_hdr *hdr; size_t hdrlen; u16 fc, type, stype, sc; struct net_device_stats *stats; unsigned int frag; u8 *payload; u16 ethertype; int err; struct sk_buff *skb2 = NULL; short unknow; unsigned long flags;#ifdef NOT_YET struct net_device *wds = NULL; struct net_device *wds = NULL; int frame_authorized = 0; int from_assoc_ap = 0; void *sta = NULL;#endif u8 dst[ETH_ALEN]; u8 src[ETH_ALEN];#ifndef CONFIG_IEEE80211_NOWEP struct ieee80211_crypt_data *crypt = NULL; int keyidx = 0;#endif /* CONFIG_IEEE80211_NOWEP */ hdr = (struct ieee80211_hdr *)skb->data; stats = &ieee->stats; if (skb->len < 10) { printk(KERN_INFO "%s: SKB length < 10\n", dev->name); goto rx_dropped; } fc = le16_to_cpu(hdr->frame_control); type = WLAN_FC_GET_TYPE(fc); stype = WLAN_FC_GET_STYPE(fc); sc = le16_to_cpu(hdr->seq_ctrl); frag = WLAN_GET_SEQ_FRAG(sc); hdrlen = ieee80211_get_hdrlen(fc);#ifdef NOT_YET#if WIRELESS_EXT > 15 /* Put this code here so that we avoid duplicating it in all * Rx paths. - Jean II */#ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */ /* If spy monitoring on */ if (iface->spy_data.spy_number > 0) { struct iw_quality wstats; wstats.level = rx_stats->signal; wstats.noise = rx_stats->noise; wstats.updated = 6; /* No qual value */ /* Update spy records */ wireless_spy_update(dev, hdr->addr2, &wstats); }#endif /* IW_WIRELESS_SPY */#endif /* WIRELESS_EXT > 15 */ hostap_update_rx_stats(local->ap, hdr, rx_stats);#endif#if WIRELESS_EXT > 15 if (ieee->iw_mode == IW_MODE_MONITOR) { ieee80211_monitor_rx(ieee, skb, rx_stats); stats->rx_packets++; stats->rx_bytes += skb->len;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -