aboutsummaryrefslogtreecommitdiffstats
path: root/src
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 /src
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 'src')
-rw-r--r--src/ap/drv_callbacks.c106
-rw-r--r--src/ap/ieee802_11.c24
-rw-r--r--src/ap/wnm_ap.c30
-rw-r--r--src/ap/wnm_ap.h3
-rw-r--r--src/drivers/driver.h56
-rw-r--r--src/drivers/driver_atheros.c24
-rw-r--r--src/drivers/driver_common.c1
-rw-r--r--src/drivers/driver_nl80211.c29
8 files changed, 68 insertions, 205 deletions
diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c
index 60d8268..9af9646 100644
--- a/src/ap/drv_callbacks.c
+++ b/src/ap/drv_callbacks.c
@@ -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;
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index 8fee2f9..1e3693d 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -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) {
diff --git a/src/ap/wnm_ap.c b/src/ap/wnm_ap.c
index 417fd0e..8255204 100644
--- a/src/ap/wnm_ap.c
+++ b/src/ap/wnm_ap.c
@@ -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;
}
diff --git a/src/ap/wnm_ap.h b/src/ap/wnm_ap.h
index 78b1c6b..eeaf5ec 100644
--- a/src/ap/wnm_ap.h
+++ b/src/ap/wnm_ap.h
@@ -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,
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 03a5b57..3a59851 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -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.
*
@@ -3102,15 +3102,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
*
* This event is used to indicate when the driver has started the
@@ -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
diff --git a/src/drivers/driver_atheros.c b/src/drivers/driver_atheros.c
index 7d301f7..23a4e2b 100644
--- a/src/drivers/driver_atheros.c
+++ b/src/drivers/driver_atheros.c
@@ -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;
diff --git a/src/drivers/driver_common.c b/src/drivers/driver_common.c
index 8a6b438..c07ec57 100644
--- a/src/drivers/driver_common.c
+++ b/src/drivers/driver_common.c
@@ -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);
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index b605cca..e1f5860 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -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);
}