]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Beacon frame protection event for incorrect protection
authorJouni Malinen <jouni@codeaurora.org>
Wed, 1 Apr 2020 13:07:25 +0000 (16:07 +0300)
committerJouni Malinen <j@w1.fi>
Wed, 1 Apr 2020 13:22:48 +0000 (16:22 +0300)
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>
src/common/ieee802_11_defs.h
src/common/wpa_ctrl.h
src/drivers/driver.h
src/drivers/driver_common.c
wpa_supplicant/events.c

index 8dc4698813ad7c06e48cf0aa912c18f7de63a751..7f31e09a10c51872ac896df1dc9db671b080efde 100644 (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
index 0b04130685a63773cf6d3c774c93cfc1a1f69c35..ca1c35f8523289d64df2fbc08d7aeaf566795576 100644 (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
  *
index 6ffa7fece1468ef96cf1041cddbfd941e8cf1d71..032bbd8921966240c498da6376e8b2ac6b5b48a6 100644 (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;
 };
 
 /**
index 2e03b66766b0ad23c83e91f27b689371babadb13..63846db2e2182e99a86f42cb38bf4943859cc48b 100644 (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";
index e8b8a9c98b4907349b96d55c63dd956f004b0c87..19a883bee02e99b534d46f5f7fc5834d77c637a3 100644 (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;