📄 rx.c
字号:
/* * Copyright 2002-2005, Instant802 Networks, Inc. * Copyright 2005-2006, Devicescape Software, Inc. * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */#include <linux/kernel.h>#include <linux/skbuff.h>#include <linux/netdevice.h>#include <linux/etherdevice.h>#include <linux/rcupdate.h>#include <net/mac80211.h>#include <net/ieee80211_radiotap.h>#include "ieee80211_i.h"#include "ieee80211_led.h"#include "wep.h"#include "wpa.h"#include "tkip.h"#include "wme.h"/* * monitor mode reception * * This function cleans up the SKB, i.e. it removes all the stuff * only useful for monitoring. */static struct sk_buff *remove_monitor_info(struct ieee80211_local *local, struct sk_buff *skb, int rtap_len){ skb_pull(skb, rtap_len); if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) { if (likely(skb->len > FCS_LEN)) skb_trim(skb, skb->len - FCS_LEN); else { /* driver bug */ WARN_ON(1); dev_kfree_skb(skb); skb = NULL; } } return skb;}static inline int should_drop_frame(struct ieee80211_rx_status *status, struct sk_buff *skb, int present_fcs_len, int radiotap_len){ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; if (status->flag & (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC)) return 1; if (unlikely(skb->len < 16 + present_fcs_len + radiotap_len)) return 1; if ((hdr->frame_control & cpu_to_le16(IEEE80211_FCTL_FTYPE)) == cpu_to_le16(IEEE80211_FTYPE_CTL)) return 1; return 0;}/* * This function copies a received frame to all monitor interfaces and * returns a cleaned-up SKB that no longer includes the FCS nor the * radiotap header the driver might have added. */static struct sk_buff *ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, struct ieee80211_rx_status *status){ struct ieee80211_sub_if_data *sdata; struct ieee80211_rate *rate; int needed_headroom = 0; struct ieee80211_rtap_hdr { struct ieee80211_radiotap_header hdr; u8 flags; u8 rate; __le16 chan_freq; __le16 chan_flags; u8 antsignal; u8 padding_for_rxflags; __le16 rx_flags; } __attribute__ ((packed)) *rthdr; struct sk_buff *skb, *skb2; struct net_device *prev_dev = NULL; int present_fcs_len = 0; int rtap_len = 0; /* * First, we may need to make a copy of the skb because * (1) we need to modify it for radiotap (if not present), and * (2) the other RX handlers will modify the skb we got. * * We don't need to, of course, if we aren't going to return * the SKB because it has a bad FCS/PLCP checksum. */ if (status->flag & RX_FLAG_RADIOTAP) rtap_len = ieee80211_get_radiotap_len(origskb->data); else needed_headroom = sizeof(*rthdr); if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) present_fcs_len = FCS_LEN; if (!local->monitors) { if (should_drop_frame(status, origskb, present_fcs_len, rtap_len)) { dev_kfree_skb(origskb); return NULL; } return remove_monitor_info(local, origskb, rtap_len); } if (should_drop_frame(status, origskb, present_fcs_len, rtap_len)) { /* only need to expand headroom if necessary */ skb = origskb; origskb = NULL; /* * This shouldn't trigger often because most devices have an * RX header they pull before we get here, and that should * be big enough for our radiotap information. We should * probably export the length to drivers so that we can have * them allocate enough headroom to start with. */ if (skb_headroom(skb) < needed_headroom && pskb_expand_head(skb, sizeof(*rthdr), 0, GFP_ATOMIC)) { dev_kfree_skb(skb); return NULL; } } else { /* * Need to make a copy and possibly remove radiotap header * and FCS from the original. */ skb = skb_copy_expand(origskb, needed_headroom, 0, GFP_ATOMIC); origskb = remove_monitor_info(local, origskb, rtap_len); if (!skb) return origskb; } /* if necessary, prepend radiotap information */ if (!(status->flag & RX_FLAG_RADIOTAP)) { rthdr = (void *) skb_push(skb, sizeof(*rthdr)); memset(rthdr, 0, sizeof(*rthdr)); rthdr->hdr.it_len = cpu_to_le16(sizeof(*rthdr)); rthdr->hdr.it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | (1 << IEEE80211_RADIOTAP_RATE) | (1 << IEEE80211_RADIOTAP_CHANNEL) | (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) | (1 << IEEE80211_RADIOTAP_RX_FLAGS)); rthdr->flags = local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS ? IEEE80211_RADIOTAP_F_FCS : 0; /* FIXME: when radiotap gets a 'bad PLCP' flag use it here */ rthdr->rx_flags = 0; if (status->flag & (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC)) rthdr->rx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_RX_BADFCS); rate = ieee80211_get_rate(local, status->phymode, status->rate); if (rate) rthdr->rate = rate->rate / 5; rthdr->chan_freq = cpu_to_le16(status->freq); if (status->phymode == MODE_IEEE80211A) rthdr->chan_flags = cpu_to_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ); else rthdr->chan_flags = cpu_to_le16(IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ); rthdr->antsignal = status->ssi; } skb_set_mac_header(skb, 0); skb->ip_summed = CHECKSUM_UNNECESSARY; skb->pkt_type = PACKET_OTHERHOST; skb->protocol = htons(ETH_P_802_2); list_for_each_entry_rcu(sdata, &local->interfaces, list) { if (!netif_running(sdata->dev)) continue; if (sdata->type != IEEE80211_IF_TYPE_MNTR) continue; if (prev_dev) { skb2 = skb_clone(skb, GFP_ATOMIC); if (skb2) { skb2->dev = prev_dev; netif_rx(skb2); } } prev_dev = sdata->dev; sdata->dev->stats.rx_packets++; sdata->dev->stats.rx_bytes += skb->len; } if (prev_dev) { skb->dev = prev_dev; netif_rx(skb); } else dev_kfree_skb(skb); return origskb;}/* pre-rx handlers * * these don't have dev/sdata fields in the rx data * The sta value should also not be used because it may * be NULL even though a STA (in IBSS mode) will be added. */static ieee80211_txrx_resultieee80211_rx_h_parse_qos(struct ieee80211_txrx_data *rx){ u8 *data = rx->skb->data; int tid; /* does the frame have a qos control field? */ if (WLAN_FC_IS_QOS_DATA(rx->fc)) { u8 *qc = data + ieee80211_get_hdrlen(rx->fc) - QOS_CONTROL_LEN; /* frame has qos control */ tid = qc[0] & QOS_CONTROL_TID_MASK; } else { if (unlikely((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT)) { /* Separate TID for management frames */ tid = NUM_RX_DATA_QUEUES - 1; } else { /* no qos control present */ tid = 0; /* 802.1d - Best Effort */ } } I802_DEBUG_INC(rx->local->wme_rx_queue[tid]); /* only a debug counter, sta might not be assigned properly yet */ if (rx->sta) I802_DEBUG_INC(rx->sta->wme_rx_queue[tid]); rx->u.rx.queue = tid; /* Set skb->priority to 1d tag if highest order bit of TID is not set. * For now, set skb->priority to 0 for other cases. */ rx->skb->priority = (tid > 7) ? 0 : tid; return TXRX_CONTINUE;}static ieee80211_txrx_resultieee80211_rx_h_load_stats(struct ieee80211_txrx_data *rx){ struct ieee80211_local *local = rx->local; struct sk_buff *skb = rx->skb; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; u32 load = 0, hdrtime; struct ieee80211_rate *rate; struct ieee80211_hw_mode *mode = local->hw.conf.mode; int i; /* Estimate total channel use caused by this frame */ if (unlikely(mode->num_rates < 0)) return TXRX_CONTINUE; rate = &mode->rates[0]; for (i = 0; i < mode->num_rates; i++) { if (mode->rates[i].val == rx->u.rx.status->rate) { rate = &mode->rates[i]; break; } } /* 1 bit at 1 Mbit/s takes 1 usec; in channel_use values, * 1 usec = 1/8 * (1080 / 10) = 13.5 */ if (mode->mode == MODE_IEEE80211A || (mode->mode == MODE_IEEE80211G && rate->flags & IEEE80211_RATE_ERP)) hdrtime = CHAN_UTIL_HDR_SHORT; else hdrtime = CHAN_UTIL_HDR_LONG; load = hdrtime; if (!is_multicast_ether_addr(hdr->addr1)) load += hdrtime; load += skb->len * rate->rate_inv; /* Divide channel_use by 8 to avoid wrapping around the counter */ load >>= CHAN_UTIL_SHIFT; local->channel_use_raw += load; rx->u.rx.load = load; return TXRX_CONTINUE;}ieee80211_rx_handler ieee80211_rx_pre_handlers[] ={ ieee80211_rx_h_parse_qos, ieee80211_rx_h_load_stats, NULL};/* rx handlers */static ieee80211_txrx_resultieee80211_rx_h_if_stats(struct ieee80211_txrx_data *rx){ if (rx->sta) rx->sta->channel_use_raw += rx->u.rx.load; rx->sdata->channel_use_raw += rx->u.rx.load; return TXRX_CONTINUE;}static ieee80211_txrx_resultieee80211_rx_h_passive_scan(struct ieee80211_txrx_data *rx){ struct ieee80211_local *local = rx->local; struct sk_buff *skb = rx->skb; if (unlikely(local->sta_scanning != 0)) { ieee80211_sta_rx_scan(rx->dev, skb, rx->u.rx.status); return TXRX_QUEUED; } if (unlikely(rx->flags & IEEE80211_TXRXD_RXIN_SCAN)) { /* scanning finished during invoking of handlers */ I802_DEBUG_INC(local->rx_handlers_drop_passive_scan); return TXRX_DROP; } return TXRX_CONTINUE;}static ieee80211_txrx_resultieee80211_rx_h_check(struct ieee80211_txrx_data *rx){ struct ieee80211_hdr *hdr; hdr = (struct ieee80211_hdr *) rx->skb->data; /* Drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.2.9) */ if (rx->sta && !is_multicast_ether_addr(hdr->addr1)) { if (unlikely(rx->fc & IEEE80211_FCTL_RETRY && rx->sta->last_seq_ctrl[rx->u.rx.queue] == hdr->seq_ctrl)) { if (rx->flags & IEEE80211_TXRXD_RXRA_MATCH) { rx->local->dot11FrameDuplicateCount++; rx->sta->num_duplicates++; } return TXRX_DROP; } else rx->sta->last_seq_ctrl[rx->u.rx.queue] = hdr->seq_ctrl; } if (unlikely(rx->skb->len < 16)) { I802_DEBUG_INC(rx->local->rx_handlers_drop_short); return TXRX_DROP; } if (!(rx->flags & IEEE80211_TXRXD_RXRA_MATCH)) rx->skb->pkt_type = PACKET_OTHERHOST; else if (compare_ether_addr(rx->dev->dev_addr, hdr->addr1) == 0) rx->skb->pkt_type = PACKET_HOST; else if (is_multicast_ether_addr(hdr->addr1)) { if (is_broadcast_ether_addr(hdr->addr1)) rx->skb->pkt_type = PACKET_BROADCAST; else rx->skb->pkt_type = PACKET_MULTICAST; } else rx->skb->pkt_type = PACKET_OTHERHOST; /* Drop disallowed frame classes based on STA auth/assoc state; * IEEE 802.11, Chap 5.5. * * 80211.o does filtering only based on association state, i.e., it * drops Class 3 frames from not associated stations. hostapd sends * deauth/disassoc frames when needed. In addition, hostapd is * responsible for filtering on both auth and assoc states. */ if (unlikely(((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA || ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL && (rx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL)) && rx->sdata->type != IEEE80211_IF_TYPE_IBSS && (!rx->sta || !(rx->sta->flags & WLAN_STA_ASSOC)))) { if ((!(rx->fc & IEEE80211_FCTL_FROMDS) && !(rx->fc & IEEE80211_FCTL_TODS) && (rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) || !(rx->flags & IEEE80211_TXRXD_RXRA_MATCH)) { /* Drop IBSS frames and frames for other hosts * silently. */ return TXRX_DROP; } return TXRX_DROP; } return TXRX_CONTINUE;}static ieee80211_txrx_resultieee80211_rx_h_decrypt(struct ieee80211_txrx_data *rx){ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; int keyidx; int hdrlen; ieee80211_txrx_result result = TXRX_DROP; struct ieee80211_key *stakey = NULL; /* * Key selection 101 * * There are three types of keys: * - GTK (group keys) * - PTK (pairwise keys) * - STK (station-to-station pairwise keys) * * When selecting a key, we have to distinguish between multicast * (including broadcast) and unicast frames, the latter can only * use PTKs and STKs while the former always use GTKs. Unless, of * course, actual WEP keys ("pre-RSNA") are used, then unicast * frames can also use key indizes like GTKs. Hence, if we don't * have a PTK/STK we check the key index for a WEP key. * * Note that in a regular BSS, multicast frames are sent by the * AP only, associated stations unicast the frame to the AP first * which then multicasts it on their behalf. * * There is also a slight problem in IBSS mode: GTKs are negotiated * with each station, that is something we don't currently handle. * The spec seems to expect that one negotiates the same key with * every station but there's no such requirement; VLANs could be * possible. */ if (!(rx->fc & IEEE80211_FCTL_PROTECTED)) return TXRX_CONTINUE; /* * No point in finding a key and decrypting if the frame is neither * addressed to us nor a multicast frame. */ if (!(rx->flags & IEEE80211_TXRXD_RXRA_MATCH)) return TXRX_CONTINUE; if (rx->sta) stakey = rcu_dereference(rx->sta->key); if (!is_multicast_ether_addr(hdr->addr1) && stakey) { rx->key = stakey; } else { /* * The device doesn't give us the IV so we won't be * able to look up the key. That's ok though, we * don't need to decrypt the frame, we just won't * be able to keep statistics accurate. * Except for key threshold notifications, should * we somehow allow the driver to tell us which key * the hardware used if this flag is set? */ if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) && (rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED)) return TXRX_CONTINUE; hdrlen = ieee80211_get_hdrlen(rx->fc); if (rx->skb->len < 8 + hdrlen) return TXRX_DROP; /* TODO: count this? */ /* * no need to call ieee80211_wep_get_keyidx, * it verifies a bunch of things we've done already */ keyidx = rx->skb->data[hdrlen + 3] >> 6; rx->key = rcu_dereference(rx->sdata->keys[keyidx]); /* * RSNA-protected unicast frames should always be sent with * pairwise or station-to-station keys, but for WEP we allow * using a key index as well. */ if (rx->key && rx->key->conf.alg != ALG_WEP && !is_multicast_ether_addr(hdr->addr1)) rx->key = NULL; } if (rx->key) { rx->key->tx_rx_count++; /* TODO: add threshold stuff again */ } else {#ifdef CONFIG_MAC80211_DEBUG if (net_ratelimit()) printk(KERN_DEBUG "%s: RX protected frame," " but have no key\n", rx->dev->name);#endif /* CONFIG_MAC80211_DEBUG */ return TXRX_DROP; } /* Check for weak IVs if possible */ if (rx->sta && rx->key->conf.alg == ALG_WEP && ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) && (!(rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED) || !(rx->u.rx.status->flag & RX_FLAG_DECRYPTED)) && ieee80211_wep_is_weak_iv(rx->skb, rx->key)) rx->sta->wep_weak_iv_count++; switch (rx->key->conf.alg) { case ALG_WEP: result = ieee80211_crypto_wep_decrypt(rx); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -