Re-initialize hostapd/wpa_supplicant git repository based on 0.6.3 release
This commit is contained in:
commit
6fc6879bd5
589 changed files with 213408 additions and 0 deletions
148
src/drivers/scan_helpers.c
Normal file
148
src/drivers/scan_helpers.c
Normal file
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* WPA Supplicant - Helper functions for scan result processing
|
||||
* Copyright (c) 2007, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of BSD
|
||||
* license.
|
||||
*
|
||||
* See README and COPYING for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "drivers/driver.h"
|
||||
#include "ieee802_11_defs.h"
|
||||
|
||||
|
||||
const u8 * wpa_scan_get_ie(const struct wpa_scan_res *res, u8 ie)
|
||||
{
|
||||
const u8 *end, *pos;
|
||||
|
||||
pos = (const u8 *) (res + 1);
|
||||
end = pos + res->ie_len;
|
||||
|
||||
while (pos + 1 < end) {
|
||||
if (pos + 2 + pos[1] > end)
|
||||
break;
|
||||
if (pos[0] == ie)
|
||||
return pos;
|
||||
pos += 2 + pos[1];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
const u8 * wpa_scan_get_vendor_ie(const struct wpa_scan_res *res,
|
||||
u32 vendor_type)
|
||||
{
|
||||
const u8 *end, *pos;
|
||||
|
||||
pos = (const u8 *) (res + 1);
|
||||
end = pos + res->ie_len;
|
||||
|
||||
while (pos + 1 < end) {
|
||||
if (pos + 2 + pos[1] > end)
|
||||
break;
|
||||
if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
|
||||
vendor_type == WPA_GET_BE32(&pos[2]))
|
||||
return pos;
|
||||
pos += 2 + pos[1];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int wpa_scan_get_max_rate(const struct wpa_scan_res *res)
|
||||
{
|
||||
int rate = 0;
|
||||
const u8 *ie;
|
||||
int i;
|
||||
|
||||
ie = wpa_scan_get_ie(res, WLAN_EID_SUPP_RATES);
|
||||
for (i = 0; ie && i < ie[1]; i++) {
|
||||
if (ie[i + 2] > rate)
|
||||
rate = ie[i + 2];
|
||||
}
|
||||
|
||||
ie = wpa_scan_get_ie(res, WLAN_EID_EXT_SUPP_RATES);
|
||||
for (i = 0; ie && i < ie[1]; i++) {
|
||||
if (ie[i + 2] > rate)
|
||||
rate = ie[i + 2];
|
||||
}
|
||||
|
||||
return rate;
|
||||
}
|
||||
|
||||
|
||||
void wpa_scan_results_free(struct wpa_scan_results *res)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (res == NULL)
|
||||
return;
|
||||
|
||||
for (i = 0; i < res->num; i++)
|
||||
os_free(res->res[i]);
|
||||
os_free(res->res);
|
||||
os_free(res);
|
||||
}
|
||||
|
||||
|
||||
/* Compare function for sorting scan results. Return >0 if @b is considered
|
||||
* better. */
|
||||
static int wpa_scan_result_compar(const void *a, const void *b)
|
||||
{
|
||||
struct wpa_scan_res **_wa = (void *) a;
|
||||
struct wpa_scan_res **_wb = (void *) b;
|
||||
struct wpa_scan_res *wa = *_wa;
|
||||
struct wpa_scan_res *wb = *_wb;
|
||||
int wpa_a, wpa_b, maxrate_a, maxrate_b;
|
||||
|
||||
/* WPA/WPA2 support preferred */
|
||||
wpa_a = wpa_scan_get_vendor_ie(wa, WPA_IE_VENDOR_TYPE) != NULL ||
|
||||
wpa_scan_get_ie(wa, WLAN_EID_RSN) != NULL;
|
||||
wpa_b = wpa_scan_get_vendor_ie(wb, WPA_IE_VENDOR_TYPE) != NULL ||
|
||||
wpa_scan_get_ie(wb, WLAN_EID_RSN) != NULL;
|
||||
|
||||
if (wpa_b && !wpa_a)
|
||||
return 1;
|
||||
if (!wpa_b && wpa_a)
|
||||
return -1;
|
||||
|
||||
/* privacy support preferred */
|
||||
if ((wa->caps & IEEE80211_CAP_PRIVACY) == 0 &&
|
||||
(wb->caps & IEEE80211_CAP_PRIVACY))
|
||||
return 1;
|
||||
if ((wa->caps & IEEE80211_CAP_PRIVACY) &&
|
||||
(wb->caps & IEEE80211_CAP_PRIVACY) == 0)
|
||||
return -1;
|
||||
|
||||
/* best/max rate preferred if signal level close enough XXX */
|
||||
maxrate_a = wpa_scan_get_max_rate(wa);
|
||||
maxrate_b = wpa_scan_get_max_rate(wb);
|
||||
if (maxrate_a != maxrate_b && abs(wb->level - wa->level) < 5)
|
||||
return maxrate_b - maxrate_a;
|
||||
|
||||
/* use freq for channel preference */
|
||||
|
||||
/* all things being equal, use signal level; if signal levels are
|
||||
* identical, use quality values since some drivers may only report
|
||||
* that value and leave the signal level zero */
|
||||
if (wb->level == wa->level)
|
||||
return wb->qual - wa->qual;
|
||||
return wb->level - wa->level;
|
||||
}
|
||||
|
||||
|
||||
void wpa_scan_sort_results(struct wpa_scan_results *res)
|
||||
{
|
||||
qsort(res->res, res->num, sizeof(struct wpa_scan_res *),
|
||||
wpa_scan_result_compar);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue