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 }; |