mirror of
https://github.com/vanhoefm/fragattacks.git
synced 2024-11-29 10:48:22 -05:00
wext: Fix scan result signal levels when driver reports in dBm
wpa_supplicant showed signal levels incorrectly with some drivers: Jun 6 16:29:36 rupert wpa_supplicant[18945]: Current BSS: 00:0d:97:11:40:d6 level=190 Jun 6 16:29:36 rupert wpa_supplicant[18945]: Selected BSS: 00:0d:97:11:50:09 level=192 Judging from output from other tools (iwlist) and the min_diff block at the end of wpa_supplicant_need_to_roam, it seems these values should actually be negative. Specifically, if one treats that number as a signed char instead of unsigned, everything matches up. To be honest, I've little to no understanding of wireless, but looking at the source code for wireless-tools (iw_print_stats in iwlib.c), it seems that the fields of the iw_quality struct need to be decoded differently depending on various flags. I guess src/drivers/driver_wext.c should have similar logic in wext_get_scan_qual. I wrote a patch that attempts to replicate some of that logic, although it may be more complicated than is necessary; I think some of the complexity is for backwards-compatibility, which might not be necessary depending on wpa_supplicant's dependencies? In any case, it is attached. Again, I don't know how any of this works, so it's likely the patch is a bit off. But I think at least the logic to determine min_diff in wpa_supplicant_need_to_roam would be more accurate if level were determined correctly.
This commit is contained in:
parent
8602b0f213
commit
32f4e7b124
@ -1117,7 +1117,8 @@ static void wext_get_scan_freq(struct iw_event *iwe,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void wext_get_scan_qual(struct iw_event *iwe,
|
static void wext_get_scan_qual(struct wpa_driver_wext_data *drv,
|
||||||
|
struct iw_event *iwe,
|
||||||
struct wext_scan_data *res)
|
struct wext_scan_data *res)
|
||||||
{
|
{
|
||||||
res->res.qual = iwe->u.qual.qual;
|
res->res.qual = iwe->u.qual.qual;
|
||||||
@ -1131,6 +1132,14 @@ static void wext_get_scan_qual(struct iw_event *iwe,
|
|||||||
res->res.flags |= WPA_SCAN_NOISE_INVALID;
|
res->res.flags |= WPA_SCAN_NOISE_INVALID;
|
||||||
if (iwe->u.qual.updated & IW_QUAL_DBM)
|
if (iwe->u.qual.updated & IW_QUAL_DBM)
|
||||||
res->res.flags |= WPA_SCAN_LEVEL_DBM;
|
res->res.flags |= WPA_SCAN_LEVEL_DBM;
|
||||||
|
if ((iwe->u.qual.updated & IW_QUAL_DBM) ||
|
||||||
|
((iwe->u.qual.level != 0) &&
|
||||||
|
(iwe->u.qual.level > drv->max_level))) {
|
||||||
|
if (iwe->u.qual.level >= 64)
|
||||||
|
res->res.level -= 0x100;
|
||||||
|
if (iwe->u.qual.noise >= 64)
|
||||||
|
res->res.noise -= 0x100;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1406,7 +1415,7 @@ struct wpa_scan_results * wpa_driver_wext_get_scan_results(void *priv)
|
|||||||
wext_get_scan_freq(iwe, &data);
|
wext_get_scan_freq(iwe, &data);
|
||||||
break;
|
break;
|
||||||
case IWEVQUAL:
|
case IWEVQUAL:
|
||||||
wext_get_scan_qual(iwe, &data);
|
wext_get_scan_qual(drv, iwe, &data);
|
||||||
break;
|
break;
|
||||||
case SIOCGIWENCODE:
|
case SIOCGIWENCODE:
|
||||||
wext_get_scan_encode(iwe, &data);
|
wext_get_scan_encode(iwe, &data);
|
||||||
@ -1504,6 +1513,8 @@ static int wpa_driver_wext_get_range(void *priv)
|
|||||||
"assuming WPA is not supported");
|
"assuming WPA is not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
drv->max_level = range->max_qual.level;
|
||||||
|
|
||||||
os_free(range);
|
os_free(range);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,8 @@ struct wpa_driver_wext_data {
|
|||||||
int scan_complete_events;
|
int scan_complete_events;
|
||||||
|
|
||||||
int cfg80211; /* whether driver is using cfg80211 */
|
int cfg80211; /* whether driver is using cfg80211 */
|
||||||
|
|
||||||
|
u8 max_level;
|
||||||
};
|
};
|
||||||
|
|
||||||
int wpa_driver_wext_get_bssid(void *priv, u8 *bssid);
|
int wpa_driver_wext_get_bssid(void *priv, u8 *bssid);
|
||||||
|
Loading…
Reference in New Issue
Block a user