diff options
Diffstat (limited to 'net/wireless/scan.c')
-rw-r--r-- | net/wireless/scan.c | 41 |
1 files changed, 36 insertions, 5 deletions
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 2936cb809152..dc23b31594e0 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/etherdevice.h> | 12 | #include <linux/etherdevice.h> |
13 | #include <net/arp.h> | 13 | #include <net/arp.h> |
14 | #include <net/cfg80211.h> | 14 | #include <net/cfg80211.h> |
15 | #include <net/cfg80211-wext.h> | ||
15 | #include <net/iw_handler.h> | 16 | #include <net/iw_handler.h> |
16 | #include "core.h" | 17 | #include "core.h" |
17 | #include "nl80211.h" | 18 | #include "nl80211.h" |
@@ -227,21 +228,51 @@ const u8 *cfg80211_find_ie(u8 eid, const u8 *ies, int len) | |||
227 | } | 228 | } |
228 | EXPORT_SYMBOL(cfg80211_find_ie); | 229 | EXPORT_SYMBOL(cfg80211_find_ie); |
229 | 230 | ||
231 | const u8 *cfg80211_find_vendor_ie(unsigned int oui, u8 oui_type, | ||
232 | const u8 *ies, int len) | ||
233 | { | ||
234 | struct ieee80211_vendor_ie *ie; | ||
235 | const u8 *pos = ies, *end = ies + len; | ||
236 | int ie_oui; | ||
237 | |||
238 | while (pos < end) { | ||
239 | pos = cfg80211_find_ie(WLAN_EID_VENDOR_SPECIFIC, pos, | ||
240 | end - pos); | ||
241 | if (!pos) | ||
242 | return NULL; | ||
243 | |||
244 | if (end - pos < sizeof(*ie)) | ||
245 | return NULL; | ||
246 | |||
247 | ie = (struct ieee80211_vendor_ie *)pos; | ||
248 | ie_oui = ie->oui[0] << 16 | ie->oui[1] << 8 | ie->oui[2]; | ||
249 | if (ie_oui == oui && ie->oui_type == oui_type) | ||
250 | return pos; | ||
251 | |||
252 | pos += 2 + ie->len; | ||
253 | } | ||
254 | return NULL; | ||
255 | } | ||
256 | EXPORT_SYMBOL(cfg80211_find_vendor_ie); | ||
257 | |||
230 | static int cmp_ies(u8 num, u8 *ies1, size_t len1, u8 *ies2, size_t len2) | 258 | static int cmp_ies(u8 num, u8 *ies1, size_t len1, u8 *ies2, size_t len2) |
231 | { | 259 | { |
232 | const u8 *ie1 = cfg80211_find_ie(num, ies1, len1); | 260 | const u8 *ie1 = cfg80211_find_ie(num, ies1, len1); |
233 | const u8 *ie2 = cfg80211_find_ie(num, ies2, len2); | 261 | const u8 *ie2 = cfg80211_find_ie(num, ies2, len2); |
234 | int r; | ||
235 | 262 | ||
263 | /* equal if both missing */ | ||
236 | if (!ie1 && !ie2) | 264 | if (!ie1 && !ie2) |
237 | return 0; | 265 | return 0; |
238 | if (!ie1 || !ie2) | 266 | /* sort missing IE before (left of) present IE */ |
267 | if (!ie1) | ||
239 | return -1; | 268 | return -1; |
269 | if (!ie2) | ||
270 | return 1; | ||
240 | 271 | ||
241 | r = memcmp(ie1 + 2, ie2 + 2, min(ie1[1], ie2[1])); | 272 | /* sort by length first, then by contents */ |
242 | if (r == 0 && ie1[1] != ie2[1]) | 273 | if (ie1[1] != ie2[1]) |
243 | return ie2[1] - ie1[1]; | 274 | return ie2[1] - ie1[1]; |
244 | return r; | 275 | return memcmp(ie1 + 2, ie2 + 2, ie1[1]); |
245 | } | 276 | } |
246 | 277 | ||
247 | static bool is_bss(struct cfg80211_bss *a, | 278 | static bool is_bss(struct cfg80211_bss *a, |