diff options
author | Jouni Malinen <j@w1.fi> | 2010-08-28 12:36:10 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-09-24 15:54:27 -0400 |
commit | 8dcb20038ade81f9a87c024e7f12ec74f0e95f33 (patch) | |
tree | fe970ab661be7ec61165bdcb5db2c4422a1822fd /net | |
parent | 29ad2facd47f8e37eab8b156e2c384fa181c8b4a (diff) |
mac80211: Filter ProbeReq SuppRates based on TX rate mask
If the TX rate set has been masked, the removed rates can also be
removed from the Supported Rates and Extended Supported Rates IEs in
Probe Request frames.
Signed-off-by: Jouni Malinen <j@w1.fi>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/ieee80211_i.h | 2 | ||||
-rw-r--r-- | net/mac80211/scan.c | 2 | ||||
-rw-r--r-- | net/mac80211/util.c | 37 |
3 files changed, 24 insertions, 17 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 9346a6b0f400..3641563d90f8 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -1256,7 +1256,7 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, | |||
1256 | const u8 *key, u8 key_len, u8 key_idx); | 1256 | const u8 *key, u8 key_len, u8 key_idx); |
1257 | int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, | 1257 | int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, |
1258 | const u8 *ie, size_t ie_len, | 1258 | const u8 *ie, size_t ie_len, |
1259 | enum ieee80211_band band); | 1259 | enum ieee80211_band band, u32 rate_mask); |
1260 | void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, | 1260 | void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, |
1261 | const u8 *ssid, size_t ssid_len, | 1261 | const u8 *ssid, size_t ssid_len, |
1262 | const u8 *ie, size_t ie_len); | 1262 | const u8 *ie, size_t ie_len); |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index d60389ba9b95..1623e9d2086e 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -242,7 +242,7 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local) | |||
242 | local->hw_scan_req->n_channels = n_chans; | 242 | local->hw_scan_req->n_channels = n_chans; |
243 | 243 | ||
244 | ielen = ieee80211_build_preq_ies(local, (u8 *)local->hw_scan_req->ie, | 244 | ielen = ieee80211_build_preq_ies(local, (u8 *)local->hw_scan_req->ie, |
245 | req->ie, req->ie_len, band); | 245 | req->ie, req->ie_len, band, (u32) -1); |
246 | local->hw_scan_req->ie_len = ielen; | 246 | local->hw_scan_req->ie_len = ielen; |
247 | 247 | ||
248 | return true; | 248 | return true; |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 737f4267c335..bfd19d76667a 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -895,26 +895,33 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, | |||
895 | 895 | ||
896 | int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, | 896 | int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, |
897 | const u8 *ie, size_t ie_len, | 897 | const u8 *ie, size_t ie_len, |
898 | enum ieee80211_band band) | 898 | enum ieee80211_band band, u32 rate_mask) |
899 | { | 899 | { |
900 | struct ieee80211_supported_band *sband; | 900 | struct ieee80211_supported_band *sband; |
901 | u8 *pos; | 901 | u8 *pos; |
902 | size_t offset = 0, noffset; | 902 | size_t offset = 0, noffset; |
903 | int supp_rates_len, i; | 903 | int supp_rates_len, i; |
904 | u8 rates[32]; | ||
905 | int num_rates; | ||
906 | int ext_rates_len; | ||
904 | 907 | ||
905 | sband = local->hw.wiphy->bands[band]; | 908 | sband = local->hw.wiphy->bands[band]; |
906 | 909 | ||
907 | pos = buffer; | 910 | pos = buffer; |
908 | 911 | ||
909 | supp_rates_len = min_t(int, sband->n_bitrates, 8); | 912 | num_rates = 0; |
913 | for (i = 0; i < sband->n_bitrates; i++) { | ||
914 | if ((BIT(i) & rate_mask) == 0) | ||
915 | continue; /* skip rate */ | ||
916 | rates[num_rates++] = (u8) (sband->bitrates[i].bitrate / 5); | ||
917 | } | ||
918 | |||
919 | supp_rates_len = min_t(int, num_rates, 8); | ||
910 | 920 | ||
911 | *pos++ = WLAN_EID_SUPP_RATES; | 921 | *pos++ = WLAN_EID_SUPP_RATES; |
912 | *pos++ = supp_rates_len; | 922 | *pos++ = supp_rates_len; |
913 | 923 | memcpy(pos, rates, supp_rates_len); | |
914 | for (i = 0; i < supp_rates_len; i++) { | 924 | pos += supp_rates_len; |
915 | int rate = sband->bitrates[i].bitrate; | ||
916 | *pos++ = (u8) (rate / 5); | ||
917 | } | ||
918 | 925 | ||
919 | /* insert "request information" if in custom IEs */ | 926 | /* insert "request information" if in custom IEs */ |
920 | if (ie && ie_len) { | 927 | if (ie && ie_len) { |
@@ -932,14 +939,12 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, | |||
932 | offset = noffset; | 939 | offset = noffset; |
933 | } | 940 | } |
934 | 941 | ||
935 | if (sband->n_bitrates > i) { | 942 | ext_rates_len = num_rates - supp_rates_len; |
943 | if (ext_rates_len > 0) { | ||
936 | *pos++ = WLAN_EID_EXT_SUPP_RATES; | 944 | *pos++ = WLAN_EID_EXT_SUPP_RATES; |
937 | *pos++ = sband->n_bitrates - i; | 945 | *pos++ = ext_rates_len; |
938 | 946 | memcpy(pos, rates + supp_rates_len, ext_rates_len); | |
939 | for (; i < sband->n_bitrates; i++) { | 947 | pos += ext_rates_len; |
940 | int rate = sband->bitrates[i].bitrate; | ||
941 | *pos++ = (u8) (rate / 5); | ||
942 | } | ||
943 | } | 948 | } |
944 | 949 | ||
945 | /* insert custom IEs that go before HT */ | 950 | /* insert custom IEs that go before HT */ |
@@ -1018,7 +1023,9 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, | |||
1018 | } | 1023 | } |
1019 | 1024 | ||
1020 | buf_len = ieee80211_build_preq_ies(local, buf, ie, ie_len, | 1025 | buf_len = ieee80211_build_preq_ies(local, buf, ie, ie_len, |
1021 | local->hw.conf.channel->band); | 1026 | local->hw.conf.channel->band, |
1027 | sdata->rc_rateidx_mask | ||
1028 | [local->hw.conf.channel->band]); | ||
1022 | 1029 | ||
1023 | skb = ieee80211_probereq_get(&local->hw, &sdata->vif, | 1030 | skb = ieee80211_probereq_get(&local->hw, &sdata->vif, |
1024 | ssid, ssid_len, | 1031 | ssid, ssid_len, |