diff options
| author | Denis Vlasenko <vda@ilport.com.ua> | 2006-01-24 09:57:11 -0500 |
|---|---|---|
| committer | John W. Linville <linville@tuxdriver.com> | 2006-03-22 22:16:58 -0500 |
| commit | 1a995b45a52871af42aa1111da4c74c4b85e09c5 (patch) | |
| tree | 59d43235b1e5bc76bbf2f108d4e7a9f016db0ea3 | |
| parent | 4c718cfd7df4ac34ca8a4add555c374de61c42e8 (diff) | |
[PATCH] ieee80211_rx_any: filter out packets, call ieee80211_rx or ieee80211_rx_mgt
Version 2 of the patch. Added checks for version 0
and proper from/to DS bits. Even in promisc
mode we won't receive packets from another BSSes.
bcm43xx_rx() contains code to filter out packets from
foreign BSSes and decide whether to call ieee80211_rx
or ieee80211_rx_mgt. This is not bcm specific.
Patch adapts that code and adds it to 80211
as ieee80211_rx_any() function.
Signed-off-by: Denis Vlasenko <vda@ilport.com.ua>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
| -rw-r--r-- | net/ieee80211/ieee80211_rx.c | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c index a7f2a642a512..604b7b0097bc 100644 --- a/net/ieee80211/ieee80211_rx.c +++ b/net/ieee80211/ieee80211_rx.c | |||
| @@ -780,6 +780,80 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, | |||
| 780 | return 0; | 780 | return 0; |
| 781 | } | 781 | } |
| 782 | 782 | ||
| 783 | /* Filter out unrelated packets, call ieee80211_rx[_mgt] */ | ||
| 784 | int ieee80211_rx_any(struct ieee80211_device *ieee, | ||
| 785 | struct sk_buff *skb, struct ieee80211_rx_stats *stats) | ||
| 786 | { | ||
| 787 | struct ieee80211_hdr_4addr *hdr; | ||
| 788 | int is_packet_for_us; | ||
| 789 | u16 fc; | ||
| 790 | |||
| 791 | if (ieee->iw_mode == IW_MODE_MONITOR) | ||
| 792 | return ieee80211_rx(ieee, skb, stats) ? 0 : -EINVAL; | ||
| 793 | |||
| 794 | hdr = (struct ieee80211_hdr_4addr *)skb->data; | ||
| 795 | fc = le16_to_cpu(hdr->frame_ctl); | ||
| 796 | |||
| 797 | if ((fc & IEEE80211_FCTL_VERS) != 0) | ||
| 798 | return -EINVAL; | ||
| 799 | |||
| 800 | switch (fc & IEEE80211_FCTL_FTYPE) { | ||
| 801 | case IEEE80211_FTYPE_MGMT: | ||
| 802 | ieee80211_rx_mgt(ieee, hdr, stats); | ||
| 803 | return 0; | ||
| 804 | case IEEE80211_FTYPE_DATA: | ||
| 805 | break; | ||
| 806 | case IEEE80211_FTYPE_CTL: | ||
| 807 | return 0; | ||
| 808 | default: | ||
| 809 | return -EINVAL; | ||
| 810 | } | ||
| 811 | |||
| 812 | is_packet_for_us = 0; | ||
| 813 | switch (ieee->iw_mode) { | ||
| 814 | case IW_MODE_ADHOC: | ||
| 815 | /* our BSS and not from/to DS */ | ||
| 816 | if (memcmp(hdr->addr3, ieee->bssid, ETH_ALEN) == 0) | ||
| 817 | if ((fc & (IEEE80211_FCTL_TODS+IEEE80211_FCTL_FROMDS)) == 0) { | ||
| 818 | /* promisc: get all */ | ||
| 819 | if (ieee->dev->flags & IFF_PROMISC) | ||
| 820 | is_packet_for_us = 1; | ||
| 821 | /* to us */ | ||
| 822 | else if (memcmp(hdr->addr1, ieee->dev->dev_addr, ETH_ALEN) == 0) | ||
| 823 | is_packet_for_us = 1; | ||
| 824 | /* mcast */ | ||
| 825 | else if (is_multicast_ether_addr(hdr->addr1)) | ||
| 826 | is_packet_for_us = 1; | ||
| 827 | } | ||
| 828 | break; | ||
| 829 | case IW_MODE_INFRA: | ||
| 830 | /* our BSS (== from our AP) and from DS */ | ||
| 831 | if (memcmp(hdr->addr2, ieee->bssid, ETH_ALEN) == 0) | ||
| 832 | if ((fc & (IEEE80211_FCTL_TODS+IEEE80211_FCTL_FROMDS)) == IEEE80211_FCTL_FROMDS) { | ||
| 833 | /* promisc: get all */ | ||
| 834 | if (ieee->dev->flags & IFF_PROMISC) | ||
| 835 | is_packet_for_us = 1; | ||
| 836 | /* to us */ | ||
| 837 | else if (memcmp(hdr->addr1, ieee->dev->dev_addr, ETH_ALEN) == 0) | ||
| 838 | is_packet_for_us = 1; | ||
| 839 | /* mcast */ | ||
| 840 | else if (is_multicast_ether_addr(hdr->addr1)) { | ||
| 841 | /* not our own packet bcasted from AP */ | ||
| 842 | if (memcmp(hdr->addr3, ieee->dev->dev_addr, ETH_ALEN)) | ||
| 843 | is_packet_for_us = 1; | ||
| 844 | } | ||
| 845 | } | ||
| 846 | break; | ||
| 847 | default: | ||
| 848 | /* ? */ | ||
| 849 | break; | ||
| 850 | } | ||
| 851 | |||
| 852 | if (is_packet_for_us) | ||
| 853 | return (ieee80211_rx(ieee, skb, stats) ? 0 : -EINVAL); | ||
| 854 | return 0; | ||
| 855 | } | ||
| 856 | |||
| 783 | #define MGMT_FRAME_FIXED_PART_LENGTH 0x24 | 857 | #define MGMT_FRAME_FIXED_PART_LENGTH 0x24 |
| 784 | 858 | ||
| 785 | static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 }; | 859 | static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 }; |
