Beacon frame protection event for incorrect protection

Define a driver interface event for Beacon frame protection failures.
Report such events over the control interface and send a
WNM-Notification Request frame to the AP as well.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
Jouni Malinen 2020-04-01 16:07:25 +03:00 committed by Jouni Malinen
parent 7c8f540ee0
commit 0e794989e5
5 changed files with 61 additions and 0 deletions

View file

@ -1881,6 +1881,13 @@ enum wnm_sleep_mode_subelement_id {
WNM_SLEEP_SUBELEM_BIGTK = 2,
};
/* WNM notification type (IEEE P802.11-REVmd/D3.0, Table 9-430) */
enum wnm_notification_Type {
WNM_NOTIF_TYPE_FIRMWARE_UPDATE = 0,
WNM_NOTIF_TYPE_BEACON_PROTECTION_FAILURE = 2,
WNM_NOTIF_TYPE_VENDOR_SPECIFIC = 221,
};
/* Channel Switch modes (802.11h) */
#define CHAN_SWITCH_MODE_ALLOW_TX 0
#define CHAN_SWITCH_MODE_BLOCK_TX 1

View file

@ -95,6 +95,8 @@ extern "C" {
/** SAE authentication failed due to unknown password identifier */
#define WPA_EVENT_SAE_UNKNOWN_PASSWORD_IDENTIFIER \
"CTRL-EVENT-SAE-UNKNOWN-PASSWORD-IDENTIFIER "
/** Unprotected Beacon frame dropped */
#define WPA_EVENT_UNPROT_BEACON "CTRL-EVENT-UNPROT-BEACON "
/** IP subnet status change notification
*

View file

@ -4970,6 +4970,15 @@ enum wpa_event_type {
* EVENT_UPDATE_DH - Notification of updated DH information
*/
EVENT_UPDATE_DH,
/**
* EVENT_UNPROT_BEACON - Unprotected Beacon frame received
*
* This event should be called when a Beacon frame is dropped due to it
* not being protected correctly. union wpa_event_data::unprot_beacon
* is required to provide more details of the frame.
*/
EVENT_UNPROT_BEACON,
};
@ -5822,6 +5831,13 @@ union wpa_event_data {
const u8 *ie;
size_t ie_len;
} update_dh;
/**
* struct unprot_beacon - Data for EVENT_UNPROT_BEACON
*/
struct unprot_beacon {
const u8 *sa;
} unprot_beacon;
};
/**

View file

@ -89,6 +89,7 @@ const char * event_to_string(enum wpa_event_type event)
E2S(INTERFACE_MAC_CHANGED);
E2S(WDS_STA_INTERFACE_STATUS);
E2S(UPDATE_DH);
E2S(UNPROT_BEACON);
}
return "UNKNOWN";

View file

@ -4467,6 +4467,38 @@ static void wpas_event_assoc_reject(struct wpa_supplicant *wpa_s,
}
static void wpas_event_unprot_beacon(struct wpa_supplicant *wpa_s,
struct unprot_beacon *data)
{
struct wpabuf *buf;
int res;
if (!data || wpa_s->wpa_state != WPA_COMPLETED ||
os_memcmp(data->sa, wpa_s->bssid, ETH_ALEN) != 0)
return;
wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_UNPROT_BEACON MACSTR,
MAC2STR(data->sa));
buf = wpabuf_alloc(4);
if (!buf)
return;
wpabuf_put_u8(buf, WLAN_ACTION_WNM);
wpabuf_put_u8(buf, WNM_NOTIFICATION_REQ);
wpabuf_put_u8(buf, 1); /* Dialog Token */
wpabuf_put_u8(buf, WNM_NOTIF_TYPE_BEACON_PROTECTION_FAILURE);
res = wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
wpa_s->own_addr, wpa_s->bssid,
wpabuf_head(buf), wpabuf_len(buf), 0);
if (res < 0)
wpa_printf(MSG_DEBUG,
"Failed to send WNM-Notification Request frame");
wpabuf_free(buf);
}
void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
union wpa_event_data *data)
{
@ -5271,6 +5303,9 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
data->sta_opmode.rx_nss);
#endif /* CONFIG_AP */
break;
case EVENT_UNPROT_BEACON:
wpas_event_unprot_beacon(wpa_s, &data->unprot_beacon);
break;
default:
wpa_msg(wpa_s, MSG_INFO, "Unknown event %d", event);
break;