nl80211: Add debug prints for BSS status in scan results

Print what the kernel believes the current BSS status (authenticated
or associated) is in scan results. In addition, check whether this
matches with the state that wpa_supplicant believes the driver to be
in.

This does not change the actual behavior, but will provide information
that will help in debugging potential issues where cfg80211/mac80211
seems to get into a different state from wpa_supplicant. In addition,
this provides an easy location for a workaround that could be added to
clear cfg80211/mac80211 state for unknown BSSes.
This commit is contained in:
Jouni Malinen 2009-12-02 16:45:31 +02:00 committed by Jouni Malinen
parent d8222ae38c
commit e6b8efeba0
2 changed files with 69 additions and 0 deletions

View file

@ -73,6 +73,8 @@ struct hostapd_hw_modes {
#define WPA_SCAN_NOISE_INVALID BIT(1)
#define WPA_SCAN_LEVEL_INVALID BIT(2)
#define WPA_SCAN_LEVEL_DBM BIT(3)
#define WPA_SCAN_AUTHENTICATED BIT(4)
#define WPA_SCAN_ASSOCIATED BIT(5)
/**
* struct wpa_scan_res - Scan result for an BSS/IBSS

View file

@ -88,6 +88,7 @@ struct wpa_driver_nl80211_data {
struct nl_cb *nl_cb;
struct genl_family *nl80211;
u8 auth_bssid[ETH_ALEN];
u8 bssid[ETH_ALEN];
int associated;
u8 ssid[32];
@ -653,6 +654,7 @@ static void mlme_event_auth(struct wpa_driver_nl80211_data *drv,
return;
}
os_memcpy(drv->auth_bssid, mgmt->sa, ETH_ALEN);
os_memset(&event, 0, sizeof(event));
os_memcpy(event.auth.peer, mgmt->sa, ETH_ALEN);
event.auth.auth_type = le_to_host16(mgmt->u.auth.auth_alg);
@ -1616,6 +1618,7 @@ static int bss_info_handler(struct nl_msg *msg, void *arg)
[NL80211_BSS_INFORMATION_ELEMENTS] = { .type = NLA_UNSPEC },
[NL80211_BSS_SIGNAL_MBM] = { .type = NLA_U32 },
[NL80211_BSS_SIGNAL_UNSPEC] = { .type = NLA_U8 },
[NL80211_BSS_STATUS] = { .type = NLA_U32 },
[NL80211_BSS_SEEN_MS_AGO] = { .type = NLA_U32 },
};
struct wpa_scan_results *res = arg;
@ -1669,6 +1672,21 @@ static int bss_info_handler(struct nl_msg *msg, void *arg)
if (ie)
os_memcpy(r + 1, ie, ie_len);
if (bss[NL80211_BSS_STATUS]) {
enum nl80211_bss_status status;
status = nla_get_u32(bss[NL80211_BSS_STATUS]);
switch (status) {
case NL80211_BSS_STATUS_AUTHENTICATED:
r->flags |= WPA_SCAN_AUTHENTICATED;
break;
case NL80211_BSS_STATUS_ASSOCIATED:
r->flags |= WPA_SCAN_ASSOCIATED;
break;
default:
break;
}
}
tmp = os_realloc(res->res,
(res->num + 1) * sizeof(struct wpa_scan_res *));
if (tmp == NULL) {
@ -1682,6 +1700,53 @@ static int bss_info_handler(struct nl_msg *msg, void *arg)
}
static void wpa_driver_nl80211_check_bss_status(
struct wpa_driver_nl80211_data *drv, struct wpa_scan_results *res)
{
size_t i;
for (i = 0; i < res->num; i++) {
struct wpa_scan_res *r = res->res[i];
if (r->flags & WPA_SCAN_AUTHENTICATED) {
wpa_printf(MSG_DEBUG, "nl80211: Scan results "
"indicates BSS status with " MACSTR
" as authenticated",
MAC2STR(r->bssid));
if (drv->nlmode == NL80211_IFTYPE_STATION &&
os_memcmp(r->bssid, drv->bssid, ETH_ALEN) != 0 &&
os_memcmp(r->bssid, drv->auth_bssid, ETH_ALEN) !=
0) {
wpa_printf(MSG_DEBUG, "nl80211: Unknown BSSID"
" in local state (auth=" MACSTR
" assoc=" MACSTR ")",
MAC2STR(drv->auth_bssid),
MAC2STR(drv->bssid));
}
}
if (r->flags & WPA_SCAN_ASSOCIATED) {
wpa_printf(MSG_DEBUG, "nl80211: Scan results "
"indicate BSS status with " MACSTR
" as associated",
MAC2STR(r->bssid));
if (drv->nlmode == NL80211_IFTYPE_STATION &&
!drv->associated) {
wpa_printf(MSG_DEBUG, "nl80211: Local state "
"(not associated) does not match "
"with BSS state");
} else if (drv->nlmode == NL80211_IFTYPE_STATION &&
os_memcmp(drv->bssid, r->bssid, ETH_ALEN) !=
0) {
wpa_printf(MSG_DEBUG, "nl80211: Local state "
"(associated with " MACSTR ") does "
"not match with BSS state",
MAC2STR(r->bssid));
}
}
}
}
/**
* wpa_driver_nl80211_get_scan_results - Fetch the latest scan results
* @priv: Pointer to private wext data from wpa_driver_nl80211_init()
@ -1711,6 +1776,7 @@ wpa_driver_nl80211_get_scan_results(void *priv)
if (ret == 0) {
wpa_printf(MSG_DEBUG, "Received scan results (%lu BSSes)",
(unsigned long) res->num);
wpa_driver_nl80211_check_bss_status(drv, res);
return res;
}
wpa_printf(MSG_DEBUG, "nl80211: Scan result fetch failed: ret=%d "
@ -2018,6 +2084,7 @@ static int wpa_driver_nl80211_authenticate(
int count = 0;
drv->associated = 0;
os_memset(drv->auth_bssid, 0, ETH_ALEN);
if (wpa_driver_nl80211_set_mode(drv, IEEE80211_MODE_INFRA) < 0)
return -1;