aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2013-12-29 09:22:23 (GMT)
committerJouni Malinen <j@w1.fi>2013-12-29 15:18:17 (GMT)
commitdbfb8e82ff69e6c7969b7cd23e53fd39b3e896e7 (patch)
tree9085718b8765d48b9d911d8bac162126c283a88d /wpa_supplicant
parent1450e1e3199bb26fe6944bfb4474755523b0cc88 (diff)
downloadhostap-dbfb8e82ff69e6c7969b7cd23e53fd39b3e896e7.zip
hostap-dbfb8e82ff69e6c7969b7cd23e53fd39b3e896e7.tar.gz
hostap-dbfb8e82ff69e6c7969b7cd23e53fd39b3e896e7.tar.bz2
Remove unnecessary EVENT_RX_ACTION
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>
Diffstat (limited to 'wpa_supplicant')
-rw-r--r--wpa_supplicant/events.c163
-rw-r--r--wpa_supplicant/wnm_sta.c27
-rw-r--r--wpa_supplicant/wnm_sta.h5
3 files changed, 104 insertions, 91 deletions
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index ae05a37..f9e2d19 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -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)
diff --git a/wpa_supplicant/wnm_sta.c b/wpa_supplicant/wnm_sta.c
index 1c6c715..65b2783 100644
--- a/wpa_supplicant/wnm_sta.c
+++ b/wpa_supplicant/wnm_sta.c
@@ -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");
diff --git a/wpa_supplicant/wnm_sta.h b/wpa_supplicant/wnm_sta.h
index 2933926..de87301 100644
--- a/wpa_supplicant/wnm_sta.h
+++ b/wpa_supplicant/wnm_sta.h
@@ -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);