diff options
author | Aviya Erenfeld <aviya.erenfeld@intel.com> | 2016-08-29 16:25:16 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2016-09-12 05:44:52 -0400 |
commit | 42bd20d99857e69e368d5421ea402127d5835cd3 (patch) | |
tree | 1ca2460a76e67311a2f5fa9cb0acda1c0a0e32d5 /net/mac80211/rx.c | |
parent | 480dd46b9d6812e5fb7172c305ee0f1154c26eed (diff) |
mac80211: add support for MU-MIMO air sniffer
add support to MU-MIMO air sniffer according groupID:
in monitor mode, use a given MU-MIMO groupID to monitor stations
that belongs to that group using MU-MIMO.
add support for following a station according to its MAC address
using VHT MU-MIMO sniffer:
the monitors wait until they get an action MU-MIMO notification
frame, then parses it in order to find the groupID that corresponds
to the given MAC address and monitors packets destined to that
groupID using VHT MU-MIMO.
Signed-off-by: Aviya Erenfeld <aviya.erenfeld@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r-- | net/mac80211/rx.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 708c3b1e49a1..6a265aa73a46 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -485,6 +485,9 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, | |||
485 | struct net_device *prev_dev = NULL; | 485 | struct net_device *prev_dev = NULL; |
486 | int present_fcs_len = 0; | 486 | int present_fcs_len = 0; |
487 | unsigned int rtap_vendor_space = 0; | 487 | unsigned int rtap_vendor_space = 0; |
488 | struct ieee80211_mgmt *mgmt; | ||
489 | struct ieee80211_sub_if_data *monitor_sdata = | ||
490 | rcu_dereference(local->monitor_sdata); | ||
488 | 491 | ||
489 | if (unlikely(status->flag & RX_FLAG_RADIOTAP_VENDOR_DATA)) { | 492 | if (unlikely(status->flag & RX_FLAG_RADIOTAP_VENDOR_DATA)) { |
490 | struct ieee80211_vendor_radiotap *rtap = (void *)origskb->data; | 493 | struct ieee80211_vendor_radiotap *rtap = (void *)origskb->data; |
@@ -585,6 +588,23 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, | |||
585 | ieee80211_rx_stats(sdata->dev, skb->len); | 588 | ieee80211_rx_stats(sdata->dev, skb->len); |
586 | } | 589 | } |
587 | 590 | ||
591 | mgmt = (void *)skb->data; | ||
592 | if (monitor_sdata && | ||
593 | skb->len >= IEEE80211_MIN_ACTION_SIZE + 1 + VHT_MUMIMO_GROUPS_DATA_LEN && | ||
594 | ieee80211_is_action(mgmt->frame_control) && | ||
595 | mgmt->u.action.category == WLAN_CATEGORY_VHT && | ||
596 | mgmt->u.action.u.vht_group_notif.action_code == WLAN_VHT_ACTION_GROUPID_MGMT && | ||
597 | is_valid_ether_addr(monitor_sdata->u.mntr.mu_follow_addr) && | ||
598 | ether_addr_equal(mgmt->da, monitor_sdata->u.mntr.mu_follow_addr)) { | ||
599 | struct sk_buff *mu_skb = skb_copy(skb, GFP_ATOMIC); | ||
600 | |||
601 | if (mu_skb) { | ||
602 | mu_skb->pkt_type = IEEE80211_SDATA_QUEUE_TYPE_FRAME; | ||
603 | skb_queue_tail(&monitor_sdata->skb_queue, mu_skb); | ||
604 | ieee80211_queue_work(&local->hw, &monitor_sdata->work); | ||
605 | } | ||
606 | } | ||
607 | |||
588 | if (prev_dev) { | 608 | if (prev_dev) { |
589 | skb->dev = prev_dev; | 609 | skb->dev = prev_dev; |
590 | netif_receive_skb(skb); | 610 | netif_receive_skb(skb); |