aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/scan.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless/scan.c')
-rw-r--r--net/wireless/scan.c41
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}
228EXPORT_SYMBOL(cfg80211_find_ie); 229EXPORT_SYMBOL(cfg80211_find_ie);
229 230
231const 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}
256EXPORT_SYMBOL(cfg80211_find_vendor_ie);
257
230static int cmp_ies(u8 num, u8 *ies1, size_t len1, u8 *ies2, size_t len2) 258static 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
247static bool is_bss(struct cfg80211_bss *a, 278static bool is_bss(struct cfg80211_bss *a,