]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Remove unnecessary EVENT_RX_ACTION
authorJouni Malinen <j@w1.fi>
Sun, 29 Dec 2013 09:22:23 +0000 (11:22 +0200)
committerJouni Malinen <j@w1.fi>
Sun, 29 Dec 2013 15:18:17 +0000 (17:18 +0200)
This driver event was used separately for some Action frames, but all
the driver wrappers converted to this from information that would have
been enough to indicate an EVENT_RX_MGMT event. In addition, the
received event was then converted back to a full IEEE 802.11 management
frame for processing in most cases. This is unnecessary complexity, so
get rid of the extra path and use EVENT_RX_MGMT for Action frames as
well as other management frame subtypes.

Signed-hostap: Jouni Malinen <j@w1.fi>

src/ap/drv_callbacks.c
src/ap/ieee802_11.c
src/ap/wnm_ap.c
src/ap/wnm_ap.h
src/drivers/driver.h
src/drivers/driver_atheros.c
src/drivers/driver_common.c
src/drivers/driver_nl80211.c
wpa_supplicant/events.c
wpa_supplicant/wnm_sta.c
wpa_supplicant/wnm_sta.h

index 60d8268a14e508d6a7ccb6a1dc7593ff47019ce1..9af964686a82c204d433aa509d292d223f7d30ca 100644 (file)
@@ -558,39 +558,48 @@ fail:
 
 
 static void hostapd_action_rx(struct hostapd_data *hapd,
-                             struct rx_action *action)
+                             struct rx_mgmt *drv_mgmt)
 {
+       struct ieee80211_mgmt *mgmt;
        struct sta_info *sta;
+       size_t plen __maybe_unused;
+       u16 fc;
+
+       if (drv_mgmt->frame_len < 24 + 1)
+               return;
+
+       plen = drv_mgmt->frame_len - 24 - 1;
+
+       mgmt = (struct ieee80211_mgmt *) drv_mgmt->frame;
+       fc = le_to_host16(mgmt->frame_control);
+       if (WLAN_FC_GET_STYPE(fc) != WLAN_FC_STYPE_ACTION)
+               return; /* handled by the driver */
 
         wpa_printf(MSG_DEBUG, "RX_ACTION cat %d action plen %d",
-                  action->category, (int) action->len);
+                  mgmt->u.action.category, (int) plen);
 
-       sta = ap_get_sta(hapd, action->sa);
+       sta = ap_get_sta(hapd, mgmt->sa);
        if (sta == NULL) {
                wpa_printf(MSG_DEBUG, "%s: station not found", __func__);
                return;
        }
 #ifdef CONFIG_IEEE80211R
-       if (action->category == WLAN_ACTION_FT) {
-               wpa_printf(MSG_DEBUG, "%s: FT_ACTION length %d",
-                          __func__, (int) action->len);
-               wpa_ft_action_rx(sta->wpa_sm, action->data, action->len);
+       if (mgmt->u.action.category == WLAN_ACTION_FT) {
+               const u8 *payload = drv_mgmt->frame + 24 + 1;
+               wpa_ft_action_rx(sta->wpa_sm, payload, plen);
        }
 #endif /* CONFIG_IEEE80211R */
 #ifdef CONFIG_IEEE80211W
-       if (action->category == WLAN_ACTION_SA_QUERY && action->len >= 4) {
-               wpa_printf(MSG_DEBUG, "%s: SA_QUERY_ACTION length %d",
-                          __func__, (int) action->len);
-               ieee802_11_sa_query_action(hapd, action->sa,
-                                          *(action->data + 1),
-                                          action->data + 2);
+       if (mgmt->u.action.category == WLAN_ACTION_SA_QUERY && plen >= 4) {
+               ieee802_11_sa_query_action(
+                       hapd, mgmt->sa,
+                       mgmt->u.action.u.sa_query_resp.action,
+                       mgmt->u.action.u.sa_query_resp.trans_id);
        }
 #endif /* CONFIG_IEEE80211W */
 #ifdef CONFIG_WNM
-       if (action->category == WLAN_ACTION_WNM) {
-               wpa_printf(MSG_DEBUG, "%s: WNM_ACTION length %d",
-                          __func__, (int) action->len);
-               ieee802_11_rx_wnm_action_ap(hapd, action);
+       if (mgmt->u.action.category == WLAN_ACTION_WNM) {
+               ieee802_11_rx_wnm_action_ap(hapd, mgmt, drv_mgmt->frame_len);
        }
 #endif /* CONFIG_WNM */
 }
@@ -683,51 +692,6 @@ static int hostapd_mgmt_rx(struct hostapd_data *hapd, struct rx_mgmt *rx_mgmt)
 }
 
 
-static int hostapd_rx_action(struct hostapd_data *hapd,
-                            struct rx_action *rx_action)
-{
-       struct rx_mgmt rx_mgmt;
-       u8 *buf;
-       struct ieee80211_hdr *hdr;
-       int ret;
-
-       wpa_printf(MSG_DEBUG, "EVENT_RX_ACTION DA=" MACSTR " SA=" MACSTR
-                  " BSSID=" MACSTR " category=%u",
-                  MAC2STR(rx_action->da), MAC2STR(rx_action->sa),
-                  MAC2STR(rx_action->bssid), rx_action->category);
-       wpa_hexdump(MSG_MSGDUMP, "Received action frame contents",
-                   rx_action->data, rx_action->len);
-
-       buf = os_zalloc(24 + 1 + rx_action->len);
-       if (buf == NULL)
-               return -1;
-       hdr = (struct ieee80211_hdr *) buf;
-       hdr->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
-                                         WLAN_FC_STYPE_ACTION);
-       if (rx_action->protected == 1)
-               hdr->frame_control |= host_to_le16(WLAN_FC_ISWEP);
-       else if (rx_action->category == WLAN_ACTION_SA_QUERY) {
-               /*
-                * Assume frame was protected; it would have been dropped if
-                * not.
-                */
-               hdr->frame_control |= host_to_le16(WLAN_FC_ISWEP);
-       }
-       os_memcpy(hdr->addr1, rx_action->da, ETH_ALEN);
-       os_memcpy(hdr->addr2, rx_action->sa, ETH_ALEN);
-       os_memcpy(hdr->addr3, rx_action->bssid, ETH_ALEN);
-       buf[24] = rx_action->category;
-       os_memcpy(buf + 24 + 1, rx_action->data, rx_action->len);
-       os_memset(&rx_mgmt, 0, sizeof(rx_mgmt));
-       rx_mgmt.frame = buf;
-       rx_mgmt.frame_len = 24 + 1 + rx_action->len;
-       ret = hostapd_mgmt_rx(hapd, &rx_mgmt);
-       os_free(buf);
-
-       return ret;
-}
-
-
 static void hostapd_mgmt_tx_cb(struct hostapd_data *hapd, const u8 *buf,
                               size_t len, u16 stype, int ok)
 {
@@ -966,10 +930,14 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
                                            data->rx_from_unknown.addr,
                                            data->rx_from_unknown.wds);
                break;
+#endif /* NEED_AP_MLME */
        case EVENT_RX_MGMT:
-               hostapd_mgmt_rx(hapd, &data->rx_mgmt);
-               break;
+#ifdef NEED_AP_MLME
+               if (hostapd_mgmt_rx(hapd, &data->rx_mgmt) > 0)
+                       break;
 #endif /* NEED_AP_MLME */
+               hostapd_action_rx(hapd, &data->rx_mgmt);
+               break;
        case EVENT_RX_PROBE_REQ:
                if (data->rx_probe_req.sa == NULL ||
                    data->rx_probe_req.ie == NULL)
@@ -1008,16 +976,6 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
                        break;
                hostapd_event_sta_low_ack(hapd, data->low_ack.addr);
                break;
-       case EVENT_RX_ACTION:
-               if (data->rx_action.da == NULL || data->rx_action.sa == NULL ||
-                   data->rx_action.bssid == NULL)
-                       break;
-#ifdef NEED_AP_MLME
-               if (hostapd_rx_action(hapd, &data->rx_action) > 0)
-                       break;
-#endif /* NEED_AP_MLME */
-               hostapd_action_rx(hapd, &data->rx_action);
-               break;
        case EVENT_AUTH:
                hostapd_notif_auth(hapd, &data->auth);
                break;
index 8fee2f9601c259e313ff669cae1e8c1a25191a0e..1e3693d161b5ef84544c395182a65aa7f0514852 100644 (file)
@@ -1564,27 +1564,6 @@ static int robust_action_frame(u8 category)
 #endif /* CONFIG_IEEE80211W */
 
 
-#ifdef CONFIG_WNM
-static int hostapd_wnm_action(struct hostapd_data *hapd, struct sta_info *sta,
-                             const struct ieee80211_mgmt *mgmt, size_t len)
-{
-       struct rx_action action;
-       if (len < IEEE80211_HDRLEN + 2)
-               return 0;
-       os_memset(&action, 0, sizeof(action));
-       action.da = mgmt->da;
-       action.sa = mgmt->sa;
-       action.bssid = mgmt->bssid;
-       action.category = mgmt->u.action.category;
-       action.data = (const u8 *) &mgmt->u.action.u.wnm_sleep_req.action;
-       action.len = len - IEEE80211_HDRLEN - 1;
-       action.freq = hapd->iface->freq;
-       ieee802_11_rx_wnm_action_ap(hapd, &action);
-       return 1;
-}
-#endif /* CONFIG_WNM */
-
-
 static int handle_action(struct hostapd_data *hapd,
                         const struct ieee80211_mgmt *mgmt, size_t len)
 {
@@ -1636,7 +1615,8 @@ static int handle_action(struct hostapd_data *hapd,
 #endif /* CONFIG_IEEE80211W */
 #ifdef CONFIG_WNM
        case WLAN_ACTION_WNM:
-               return hostapd_wnm_action(hapd, sta, mgmt, len);
+               ieee802_11_rx_wnm_action_ap(hapd, mgmt, len);
+               return 1;
 #endif /* CONFIG_WNM */
        case WLAN_ACTION_PUBLIC:
                if (hapd->public_action_cb) {
index 417fd0e5c1c0af0d0e4d3b572ec80c85c4aa1ab9..825520464eac6c096a24f46cee011b275e60296f 100644 (file)
@@ -367,30 +367,36 @@ static void ieee802_11_rx_bss_trans_mgmt_resp(struct hostapd_data *hapd,
 
 
 int ieee802_11_rx_wnm_action_ap(struct hostapd_data *hapd,
-                               struct rx_action *action)
+                               const struct ieee80211_mgmt *mgmt, size_t len)
 {
-       if (action->len < 1 || action->data == NULL)
+       u8 action;
+       const u8 *payload;
+       size_t plen;
+
+       if (len < IEEE80211_HDRLEN + 2)
                return -1;
 
-       switch (action->data[0]) {
+       payload = &mgmt->u.action.category;
+       payload++;
+       action = *payload++;
+       plen = (((const u8 *) mgmt) + len) - payload;
+
+       switch (action) {
        case WNM_BSS_TRANS_MGMT_QUERY:
-               ieee802_11_rx_bss_trans_mgmt_query(hapd, action->sa,
-                                                  action->data + 1,
-                                                  action->len - 1);
+               ieee802_11_rx_bss_trans_mgmt_query(hapd, mgmt->sa, payload,
+                                                  plen);
                return 0;
        case WNM_BSS_TRANS_MGMT_RESP:
-               ieee802_11_rx_bss_trans_mgmt_resp(hapd, action->sa,
-                                                 action->data + 1,
-                                                 action->len - 1);
+               ieee802_11_rx_bss_trans_mgmt_resp(hapd, mgmt->sa, payload,
+                                                 plen);
                return 0;
        case WNM_SLEEP_MODE_REQ:
-               ieee802_11_rx_wnmsleep_req(hapd, action->sa, action->data + 1,
-                                          action->len - 1);
+               ieee802_11_rx_wnmsleep_req(hapd, mgmt->sa, payload, plen);
                return 0;
        }
 
        wpa_printf(MSG_DEBUG, "WNM: Unsupported WNM Action %u from " MACSTR,
-                  action->data[0], MAC2STR(action->sa));
+                  action, MAC2STR(mgmt->sa));
        return -1;
 }
 
index 78b1c6be64e33c6fe4d261b4482da457e1773aca..eeaf5eca3a45c115efec9658c288f83b5f704f90 100644 (file)
@@ -9,11 +9,10 @@
 #ifndef WNM_AP_H
 #define WNM_AP_H
 
-struct rx_action;
 struct sta_info;
 
 int ieee802_11_rx_wnm_action_ap(struct hostapd_data *hapd,
-                               struct rx_action *action);
+                               const struct ieee80211_mgmt *mgmt, size_t len);
 int wnm_send_disassoc_imminent(struct hostapd_data *hapd,
                               struct sta_info *sta, int disassoc_timer);
 int wnm_send_ess_disassoc_imminent(struct hostapd_data *hapd,
index 03a5b570566ce9adfe936e4fc51dc2b0a2bfc97a..3a598513633f4e318ce73cd33fddb2316b3dc601 100644 (file)
@@ -2216,7 +2216,7 @@ struct wpa_driver_ops {
         *
         * This command is used to request the driver to remain awake on the
         * specified channel for the specified duration and report received
-        * Action frames with EVENT_RX_ACTION events. Optionally, received
+        * Action frames with EVENT_RX_MGMT events. Optionally, received
         * Probe Request frames may also be requested to be reported by calling
         * probe_req_report(). These will be reported with EVENT_RX_PROBE_REQ.
         *
@@ -3101,15 +3101,6 @@ enum wpa_event_type {
         */
        EVENT_RX_MGMT,
 
-       /**
-        * EVENT_RX_ACTION - Action frame received
-        *
-        * This event is used to indicate when an Action frame has been
-        * received. Information about the received frame is included in
-        * union wpa_event_data::rx_action.
-        */
-       EVENT_RX_ACTION,
-
        /**
         * EVENT_REMAIN_ON_CHANNEL - Remain-on-channel duration started
         *
@@ -3763,42 +3754,6 @@ union wpa_event_data {
                const u8 *frame;
                size_t frame_len;
                u32 datarate;
-               int ssi_signal; /* dBm */
-       } rx_mgmt;
-
-       /**
-        * struct rx_action - Data for EVENT_RX_ACTION events
-        */
-       struct rx_action {
-               /**
-                * da - Destination address of the received Action frame
-                */
-               const u8 *da;
-
-               /**
-                * sa - Source address of the received Action frame
-                */
-               const u8 *sa;
-
-               /**
-                * bssid - Address 3 of the received Action frame
-                */
-               const u8 *bssid;
-
-               /**
-                * category - Action frame category
-                */
-               u8 category;
-
-               /**
-                * data - Action frame body after category field
-                */
-               const u8 *data;
-
-               /**
-                * len - Length of data in octets
-                */
-               size_t len;
 
                /**
                 * freq - Frequency (in MHz) on which the frame was received
@@ -3809,14 +3764,7 @@ union wpa_event_data {
                 * ssi_signal - Signal strength in dBm (or 0 if not available)
                 */
                int ssi_signal;
-
-               /**
-                * protected - Whether frame was protected (PMF)
-                *
-                * 0 = unknown, 1 = yes, -1 = not
-                */
-               int protected;
-       } rx_action;
+       } rx_mgmt;
 
        /**
         * struct remain_on_channel - Data for EVENT_REMAIN_ON_CHANNEL events
index 7d301f790f8d9ea67eedfd7fce2f8bf853064cd4..23a4e2b95e4e2dd56e5182da6e9b10c99d574381 100644 (file)
@@ -806,16 +806,10 @@ static void atheros_raw_recv_11r(void *ctx, const u8 *src_addr, const u8 *buf,
                drv_event_assoc(drv->hapd, mgmt->sa, iebuf, ielen, 1);
                break;
        case WLAN_FC_STYPE_ACTION:
-               if (&mgmt->u.action.category > buf + len)
-                       break;
                os_memset(&event, 0, sizeof(event));
-               event.rx_action.da = mgmt->da;
-               event.rx_action.sa = mgmt->sa;
-               event.rx_action.bssid = mgmt->bssid;
-               event.rx_action.category = mgmt->u.action.category;
-               event.rx_action.data = &mgmt->u.action.category;
-               event.rx_action.len = buf + len - event.rx_action.data;
-               wpa_supplicant_event(drv->hapd, EVENT_RX_ACTION, &event);
+               event.rx_mgmt.frame = buf;
+               event.rx_mgmt.frame_len = len;
+               wpa_supplicant_event(drv->hapd, EVENT_RX_MGMT, &event);
                break;
        case WLAN_FC_STYPE_AUTH:
                if (len - IEEE80211_HDRLEN < sizeof(mgmt->u.auth))
@@ -954,16 +948,10 @@ static void atheros_raw_recv_11v(void *ctx, const u8 *src_addr, const u8 *buf,
 
        switch (stype) {
        case WLAN_FC_STYPE_ACTION:
-               if (&mgmt->u.action.category > buf + len)
-                       break;
                os_memset(&event, 0, sizeof(event));
-               event.rx_action.da = mgmt->da;
-               event.rx_action.sa = mgmt->sa;
-               event.rx_action.bssid = mgmt->bssid;
-               event.rx_action.category = mgmt->u.action.category;
-               event.rx_action.data = &mgmt->u.action.category;
-               event.rx_action.len = buf + len - event.rx_action.data;
-               wpa_supplicant_event(drv->hapd, EVENT_RX_ACTION, &event);
+               event.rx_mgmt.frame = buf;
+               event.rx_mgmt.frame_len = len;
+               wpa_supplicant_event(drv->hapd, EVENT_RX_MGMT, &event);
                break;
        default:
                break;
index 8a6b438a10a8e9e4bc204b2780dd45ee6b00e7ba..c07ec57193c2e28bf216c6d2cb39a06701e4b52a 100644 (file)
@@ -49,7 +49,6 @@ const char * event_to_string(enum wpa_event_type event)
        E2S(TX_STATUS);
        E2S(RX_FROM_UNKNOWN);
        E2S(RX_MGMT);
-       E2S(RX_ACTION);
        E2S(REMAIN_ON_CHANNEL);
        E2S(CANCEL_REMAIN_ON_CHANNEL);
        E2S(MLME_RX);
index b605ccaaeaeb79d136436ea28cc26415786bb4d0..e1f586009b2e78510f661bb4d2b43a4b0348e54e 100644 (file)
@@ -1602,7 +1602,7 @@ static void mlme_event_mgmt(struct wpa_driver_nl80211_data *drv,
        wpa_printf(MSG_MSGDUMP, "nl80211: Frame event");
        mgmt = (const struct ieee80211_mgmt *) frame;
        if (len < 24) {
-               wpa_printf(MSG_DEBUG, "nl80211: Too short action frame");
+               wpa_printf(MSG_DEBUG, "nl80211: Too short management frame");
                return;
        }
 
@@ -1614,31 +1614,16 @@ static void mlme_event_mgmt(struct wpa_driver_nl80211_data *drv,
 
        os_memset(&event, 0, sizeof(event));
        if (freq) {
-               event.rx_action.freq = nla_get_u32(freq);
-               rx_freq = drv->last_mgmt_freq = event.rx_action.freq;
+               event.rx_mgmt.freq = nla_get_u32(freq);
+               rx_freq = drv->last_mgmt_freq = event.rx_mgmt.freq;
        }
        wpa_printf(MSG_DEBUG,
                   "nl80211: RX frame freq=%d ssi_signal=%d stype=%u len=%u",
                   rx_freq, ssi_signal, stype, (unsigned int) len);
-       if (stype == WLAN_FC_STYPE_ACTION) {
-               event.rx_action.da = mgmt->da;
-               event.rx_action.sa = mgmt->sa;
-               event.rx_action.bssid = mgmt->bssid;
-               event.rx_action.category = mgmt->u.action.category;
-               event.rx_action.data = &mgmt->u.action.category + 1;
-               event.rx_action.len = frame + len - event.rx_action.data;
-               event.rx_action.ssi_signal = ssi_signal;
-               if (host_to_le16(WLAN_FC_ISWEP) & mgmt->frame_control)
-                       event.rx_action.protected = 1;
-               else
-                       event.rx_action.protected = -1;
-               wpa_supplicant_event(drv->ctx, EVENT_RX_ACTION, &event);
-       } else {
-               event.rx_mgmt.frame = frame;
-               event.rx_mgmt.frame_len = len;
-               event.rx_mgmt.ssi_signal = ssi_signal;
-               wpa_supplicant_event(drv->ctx, EVENT_RX_MGMT, &event);
-       }
+       event.rx_mgmt.frame = frame;
+       event.rx_mgmt.frame_len = len;
+       event.rx_mgmt.ssi_signal = ssi_signal;
+       wpa_supplicant_event(drv->ctx, EVENT_RX_MGMT, &event);
 }
 
 
index ae05a37e390868541dc6cb2410cdd8767fe32505..f9e2d19e97dcbcd17911e876c388ee84dbd11db2 100644 (file)
@@ -2707,6 +2707,87 @@ static void wpa_supplicant_update_channel_list(struct wpa_supplicant *wpa_s)
 }
 
 
+static void wpas_event_rx_mgmt_action(struct wpa_supplicant *wpa_s,
+                                     const struct ieee80211_mgmt *mgmt,
+                                     size_t len, int freq)
+{
+       const u8 *payload;
+       size_t plen;
+       u8 category;
+
+       if (len < IEEE80211_HDRLEN + 2)
+               return;
+
+       payload = &mgmt->u.action.category;
+       category = *payload++;
+       plen = (((const u8 *) mgmt) + len) - payload;
+
+       wpa_dbg(wpa_s, MSG_DEBUG, "Received Action frame: SA=" MACSTR
+               " Category=%u DataLen=%d freq=%d MHz",
+               MAC2STR(mgmt->sa), category, (int) plen, freq);
+
+#ifdef CONFIG_IEEE80211R
+       if (category == WLAN_ACTION_FT) {
+               ft_rx_action(wpa_s, payload, plen);
+               return;
+       }
+#endif /* CONFIG_IEEE80211R */
+
+#ifdef CONFIG_IEEE80211W
+#ifdef CONFIG_SME
+       if (category == WLAN_ACTION_SA_QUERY) {
+               sme_sa_query_rx(wpa_s, mgmt->sa, payload, plen);
+               return;
+       }
+#endif /* CONFIG_SME */
+#endif /* CONFIG_IEEE80211W */
+
+#ifdef CONFIG_WNM
+       if (mgmt->u.action.category == WLAN_ACTION_WNM) {
+               ieee802_11_rx_wnm_action(wpa_s, mgmt, len);
+               return;
+       }
+#endif /* CONFIG_WNM */
+
+#ifdef CONFIG_GAS
+       if (mgmt->u.action.category == WLAN_ACTION_PUBLIC &&
+           gas_query_rx(wpa_s->gas, mgmt->da, mgmt->sa, mgmt->bssid,
+                        payload, plen, freq) == 0)
+               return;
+#endif /* CONFIG_GAS */
+
+#ifdef CONFIG_TDLS
+       if (category == WLAN_ACTION_PUBLIC && plen >= 4 &&
+           payload[0] == WLAN_TDLS_DISCOVERY_RESPONSE) {
+               wpa_dbg(wpa_s, MSG_DEBUG,
+                       "TDLS: Received Discovery Response from " MACSTR,
+                       MAC2STR(mgmt->sa));
+               return;
+       }
+#endif /* CONFIG_TDLS */
+
+#ifdef CONFIG_INTERWORKING
+       if (category == WLAN_ACTION_QOS && plen >= 1 &&
+           payload[0] == QOS_QOS_MAP_CONFIG) {
+               const u8 *pos = payload + 1;
+               size_t qlen = plen - 1;
+               wpa_dbg(wpa_s, MSG_DEBUG, "Interworking: Received QoS Map Configure frame from "
+                       MACSTR, MAC2STR(mgmt->sa));
+               if (os_memcmp(mgmt->sa, wpa_s->bssid, ETH_ALEN) == 0 &&
+                   qlen > 2 && pos[0] == WLAN_EID_QOS_MAP_SET &&
+                   pos[1] <= qlen - 2 && pos[1] >= 16)
+                       wpas_qos_map_set(wpa_s, pos + 2, pos[1]);
+               return;
+       }
+#endif /* CONFIG_INTERWORKING */
+
+#ifdef CONFIG_P2P
+       wpas_p2p_rx_action(wpa_s, mgmt->da, mgmt->sa, mgmt->bssid,
+                          category, payload, plen, freq);
+#endif /* CONFIG_P2P */
+}
+
+
 void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
                          union wpa_event_data *data)
 {
@@ -2956,7 +3037,6 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
                                  data->ch_switch.cf2);
                break;
 #endif /* CONFIG_AP */
-#if defined(CONFIG_AP) || defined(CONFIG_IBSS_RSN)
        case EVENT_RX_MGMT: {
                u16 fc, stype;
                const struct ieee80211_mgmt *mgmt;
@@ -2991,6 +3071,14 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
                                break;
                        }
 #endif /* CONFIG_IBSS_RSN */
+
+                       if (stype == WLAN_FC_STYPE_ACTION) {
+                               wpas_event_rx_mgmt_action(
+                                       wpa_s, mgmt, data->rx_mgmt.frame_len,
+                                       data->rx_mgmt.freq);
+                               break;
+                       }
+
                        wpa_dbg(wpa_s, MSG_DEBUG, "AP: ignore received "
                                "management frame in non-AP mode");
                        break;
@@ -3013,79 +3101,6 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
 #endif /* CONFIG_AP */
                break;
                }
-#endif /* CONFIG_AP || CONFIG_IBSS_RSN */
-       case EVENT_RX_ACTION:
-               wpa_dbg(wpa_s, MSG_DEBUG, "Received Action frame: SA=" MACSTR
-                       " Category=%u DataLen=%d freq=%d MHz",
-                       MAC2STR(data->rx_action.sa),
-                       data->rx_action.category, (int) data->rx_action.len,
-                       data->rx_action.freq);
-#ifdef CONFIG_IEEE80211R
-               if (data->rx_action.category == WLAN_ACTION_FT) {
-                       ft_rx_action(wpa_s, data->rx_action.data,
-                                    data->rx_action.len);
-                       break;
-               }
-#endif /* CONFIG_IEEE80211R */
-#ifdef CONFIG_IEEE80211W
-#ifdef CONFIG_SME
-               if (data->rx_action.category == WLAN_ACTION_SA_QUERY) {
-                       sme_sa_query_rx(wpa_s, data->rx_action.sa,
-                                       data->rx_action.data,
-                                       data->rx_action.len);
-                       break;
-               }
-#endif /* CONFIG_SME */
-#endif /* CONFIG_IEEE80211W */
-#ifdef CONFIG_WNM
-               if (data->rx_action.category == WLAN_ACTION_WNM) {
-                       ieee802_11_rx_wnm_action(wpa_s, &data->rx_action);
-                       break;
-               }
-#endif /* CONFIG_WNM */
-#ifdef CONFIG_GAS
-               if (data->rx_action.category == WLAN_ACTION_PUBLIC &&
-                   gas_query_rx(wpa_s->gas, data->rx_action.da,
-                                data->rx_action.sa, data->rx_action.bssid,
-                                data->rx_action.data, data->rx_action.len,
-                                data->rx_action.freq) == 0)
-                       break;
-#endif /* CONFIG_GAS */
-#ifdef CONFIG_TDLS
-               if (data->rx_action.category == WLAN_ACTION_PUBLIC &&
-                   data->rx_action.len >= 4 &&
-                   data->rx_action.data[0] == WLAN_TDLS_DISCOVERY_RESPONSE) {
-                       wpa_dbg(wpa_s, MSG_DEBUG, "TDLS: Received Discovery "
-                               "Response from " MACSTR,
-                               MAC2STR(data->rx_action.sa));
-                       break;
-               }
-#endif /* CONFIG_TDLS */
-#ifdef CONFIG_INTERWORKING
-               if (data->rx_action.category == WLAN_ACTION_QOS &&
-                   data->rx_action.len >= 1 &&
-                   data->rx_action.data[0] == QOS_QOS_MAP_CONFIG) {
-                       const u8 *pos = data->rx_action.data + 1;
-                       size_t len = data->rx_action.len - 1;
-                       wpa_dbg(wpa_s, MSG_DEBUG, "Interworking: Received QoS Map Configure frame from "
-                               MACSTR, MAC2STR(data->rx_action.sa));
-                       if (os_memcmp(data->rx_action.sa, wpa_s->bssid,
-                                     ETH_ALEN) == 0 &&
-                           len > 2 && pos[0] == WLAN_EID_QOS_MAP_SET &&
-                           pos[1] <= len - 2 && pos[1] >= 16)
-                               wpas_qos_map_set(wpa_s, pos + 2, pos[1]);
-                       break;
-               }
-#endif /* CONFIG_INTERWORKING */
-#ifdef CONFIG_P2P
-               wpas_p2p_rx_action(wpa_s, data->rx_action.da,
-                                  data->rx_action.sa,
-                                  data->rx_action.bssid,
-                                  data->rx_action.category,
-                                  data->rx_action.data,
-                                  data->rx_action.len, data->rx_action.freq);
-#endif /* CONFIG_P2P */
-               break;
        case EVENT_RX_PROBE_REQ:
                if (data->rx_probe_req.sa == NULL ||
                    data->rx_probe_req.ie == NULL)
index 1c6c715df8ba673aed41a744ba3e9dff71dc1682..65b2783839ee4648701e2e442a0dbd4ab8a59928 100644 (file)
@@ -181,7 +181,7 @@ static void wnm_sleep_mode_exit_success(struct wpa_supplicant *wpa_s,
        /* Install GTK/IGTK */
 
        /* point to key data field */
-       ptr = (u8 *) frm + 1 + 1 + 2;
+       ptr = (u8 *) frm + 1 + 2;
        end = ptr + key_len_total;
        wpa_hexdump_key(MSG_DEBUG, "WNM: Key Data", ptr, key_len_total);
 
@@ -237,16 +237,16 @@ static void ieee802_11_rx_wnmsleep_resp(struct wpa_supplicant *wpa_s,
         * Action [1] | Diaglog Token [1] | Key Data Len [2] | Key Data |
         * WNM-Sleep Mode IE | TFS Response IE
         */
-       u8 *pos = (u8 *) frm; /* point to action field */
+       u8 *pos = (u8 *) frm; /* point to payload after the action field */
        u16 key_len_total = le_to_host16(*((u16 *)(frm+2)));
        struct wnm_sleep_element *wnmsleep_ie = NULL;
        /* multiple TFS Resp IE (assuming consecutive) */
        u8 *tfsresp_ie_start = NULL;
        u8 *tfsresp_ie_end = NULL;
 
-       wpa_printf(MSG_DEBUG, "action=%d token = %d key_len_total = %d",
-                  frm[0], frm[1], key_len_total);
-       pos += 4 + key_len_total;
+       wpa_printf(MSG_DEBUG, "WNM-Sleep Mode Response token=%u key_len_total=%d",
+                  frm[0], key_len_total);
+       pos += 3 + key_len_total;
        if (pos > frm + len) {
                wpa_printf(MSG_INFO, "WNM: Too short frame for Key Data field");
                return;
@@ -752,22 +752,23 @@ int wnm_send_bss_transition_mgmt_query(struct wpa_supplicant *wpa_s,
 
 
 void ieee802_11_rx_wnm_action(struct wpa_supplicant *wpa_s,
-                             struct rx_action *action)
+                             const struct ieee80211_mgmt *mgmt, size_t len)
 {
        const u8 *pos, *end;
        u8 act;
 
-       if (action->data == NULL || action->len == 0)
+       if (len < IEEE80211_HDRLEN + 2)
                return;
 
-       pos = action->data;
-       end = pos + action->len;
+       pos = &mgmt->u.action.category;
+       pos++;
        act = *pos++;
+       end = ((const u8 *) mgmt) + len;
 
        wpa_printf(MSG_DEBUG, "WNM: RX action %u from " MACSTR,
-                  act, MAC2STR(action->sa));
+                  act, MAC2STR(mgmt->sa));
        if (wpa_s->wpa_state < WPA_ASSOCIATED ||
-           os_memcmp(action->sa, wpa_s->bssid, ETH_ALEN) != 0) {
+           os_memcmp(mgmt->sa, wpa_s->bssid, ETH_ALEN) != 0) {
                wpa_printf(MSG_DEBUG, "WNM: Ignore unexpected WNM Action "
                           "frame");
                return;
@@ -776,10 +777,10 @@ void ieee802_11_rx_wnm_action(struct wpa_supplicant *wpa_s,
        switch (act) {
        case WNM_BSS_TRANS_MGMT_REQ:
                ieee802_11_rx_bss_trans_mgmt_req(wpa_s, pos, end,
-                                                !(action->da[0] & 0x01));
+                                                !(mgmt->da[0] & 0x01));
                break;
        case WNM_SLEEP_MODE_RESP:
-               ieee802_11_rx_wnmsleep_resp(wpa_s, action->data, action->len);
+               ieee802_11_rx_wnmsleep_resp(wpa_s, pos, end - pos);
                break;
        default:
                wpa_printf(MSG_ERROR, "WNM: Unknown request");
index 2933926c0908d003d02ac1bb262a7a9460ab6151..de87301560da0ed9e79fec8b7c2c4ac2d0668ea1 100644 (file)
@@ -9,9 +9,6 @@
 #ifndef WNM_STA_H
 #define WNM_STA_H
 
-struct rx_action;
-struct wpa_supplicant;
-
 struct tsf_info {
        u8 present;
        u8 tsf_offset[2];
@@ -78,7 +75,7 @@ int ieee802_11_send_wnmsleep_req(struct wpa_supplicant *wpa_s,
                                 u8 action, u16 intval, struct wpabuf *tfs_req);
 
 void ieee802_11_rx_wnm_action(struct wpa_supplicant *wpa_s,
-                             struct rx_action *action);
+                             const struct ieee80211_mgmt *mgmt, size_t len);
 
 void wnm_scan_response(struct wpa_supplicant *wpa_s,
                       struct wpa_scan_results *scan_res);