}
-static void hostapd_mgmt_rx(struct hostapd_data *hapd, struct rx_mgmt *rx_mgmt)
+static int hostapd_mgmt_rx(struct hostapd_data *hapd, struct rx_mgmt *rx_mgmt)
{
struct hostapd_iface *iface = hapd->iface;
const struct ieee80211_hdr *hdr;
const u8 *bssid;
struct hostapd_frame_info fi;
+ int ret;
hdr = (const struct ieee80211_hdr *) rx_mgmt->frame;
bssid = get_hdr_bssid(hdr, rx_mgmt->frame_len);
if (bssid == NULL)
- return;
+ return 0;
hapd = get_hapd_bssid(iface, bssid);
if (hapd == NULL) {
WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON)
hapd = iface->bss[0];
else
- return;
+ return 0;
}
os_memset(&fi, 0, sizeof(fi));
if (hapd == HAPD_BROADCAST) {
size_t i;
- for (i = 0; i < iface->num_bss; i++)
- ieee802_11_mgmt(iface->bss[i], rx_mgmt->frame,
- rx_mgmt->frame_len, &fi);
+ ret = 0;
+ for (i = 0; i < iface->num_bss; i++) {
+ if (ieee802_11_mgmt(iface->bss[i], rx_mgmt->frame,
+ rx_mgmt->frame_len, &fi) > 0)
+ ret = 1;
+ }
} else
- ieee802_11_mgmt(hapd, rx_mgmt->frame, rx_mgmt->frame_len, &fi);
+ ret = ieee802_11_mgmt(hapd, rx_mgmt->frame, rx_mgmt->frame_len,
+ &fi);
random_add_randomness(&fi, sizeof(fi));
+
+ return ret;
}
-static void hostapd_rx_action(struct hostapd_data *hapd,
- struct rx_action *rx_action)
+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",
buf = os_zalloc(24 + 1 + rx_action->len);
if (buf == NULL)
- return;
+ return -1;
hdr = (struct ieee80211_hdr *) buf;
hdr->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
WLAN_FC_STYPE_ACTION);
os_memset(&rx_mgmt, 0, sizeof(rx_mgmt));
rx_mgmt.frame = buf;
rx_mgmt.frame_len = 24 + 1 + rx_action->len;
- hostapd_mgmt_rx(hapd, &rx_mgmt);
+ ret = hostapd_mgmt_rx(hapd, &rx_mgmt);
os_free(buf);
+
+ return ret;
}
data->rx_action.bssid == NULL)
break;
#ifdef NEED_AP_MLME
- hostapd_rx_action(hapd, &data->rx_action);
+ if (hostapd_rx_action(hapd, &data->rx_action) > 0)
+ break;
#endif /* NEED_AP_MLME */
hostapd_action_rx(hapd, &data->rx_action);
break;
#ifdef CONFIG_IEEE80211W
-static void hostapd_sa_query_action(struct hostapd_data *hapd,
- const struct ieee80211_mgmt *mgmt,
- size_t len)
+static int hostapd_sa_query_action(struct hostapd_data *hapd,
+ const struct ieee80211_mgmt *mgmt,
+ size_t len)
{
const u8 *end;
if (((u8 *) mgmt) + len < end) {
wpa_printf(MSG_DEBUG, "IEEE 802.11: Too short SA Query Action "
"frame (len=%lu)", (unsigned long) len);
- return;
+ return 0;
}
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);
+ return 1;
}
#ifdef CONFIG_WNM
-static void hostapd_wnm_action(struct hostapd_data *hapd, struct sta_info *sta,
- const struct ieee80211_mgmt *mgmt,
- size_t len)
+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;
+ return 0;
os_memset(&action, 0, sizeof(action));
action.da = mgmt->da;
action.sa = mgmt->sa;
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 void handle_action(struct hostapd_data *hapd,
- const struct ieee80211_mgmt *mgmt, size_t len)
+static int handle_action(struct hostapd_data *hapd,
+ const struct ieee80211_mgmt *mgmt, size_t len)
{
struct sta_info *sta;
sta = ap_get_sta(hapd, mgmt->sa);
HOSTAPD_LEVEL_DEBUG,
"handle_action - too short payload (len=%lu)",
(unsigned long) len);
- return;
+ return 0;
}
if (mgmt->u.action.category != WLAN_ACTION_PUBLIC &&
wpa_printf(MSG_DEBUG, "IEEE 802.11: Ignored Action "
"frame (category=%u) from unassociated STA " MACSTR,
MAC2STR(mgmt->sa), mgmt->u.action.category);
- return;
+ return 0;
}
#ifdef CONFIG_IEEE80211W
HOSTAPD_LEVEL_DEBUG,
"Dropped unprotected Robust Action frame from "
"an MFP STA");
- return;
+ return 0;
}
#endif /* CONFIG_IEEE80211W */
if (wpa_ft_action_rx(sta->wpa_sm, (u8 *) &mgmt->u.action,
len - IEEE80211_HDRLEN))
break;
- return;
+ return 1;
#endif /* CONFIG_IEEE80211R */
case WLAN_ACTION_WMM:
hostapd_wmm_action(hapd, mgmt, len);
- return;
+ return 1;
#ifdef CONFIG_IEEE80211W
case WLAN_ACTION_SA_QUERY:
- hostapd_sa_query_action(hapd, mgmt, len);
- return;
+ return hostapd_sa_query_action(hapd, mgmt, len);
#endif /* CONFIG_IEEE80211W */
#ifdef CONFIG_WNM
case WLAN_ACTION_WNM:
- hostapd_wnm_action(hapd, sta, mgmt, len);
- return;
+ return hostapd_wnm_action(hapd, sta, mgmt, len);
#endif /* CONFIG_WNM */
case WLAN_ACTION_PUBLIC:
if (hapd->public_action_cb) {
hapd->iface->freq);
}
if (hapd->public_action_cb || hapd->public_action_cb2)
- return;
+ return 1;
break;
case WLAN_ACTION_VENDOR_SPECIFIC:
if (hapd->vendor_action_cb) {
if (hapd->vendor_action_cb(hapd->vendor_action_cb_ctx,
(u8 *) mgmt, len,
hapd->iface->freq) == 0)
- return;
+ return 1;
}
break;
}
"frame back to sender");
resp = os_malloc(len);
if (resp == NULL)
- return;
+ return 0;
os_memcpy(resp, mgmt, len);
os_memcpy(resp->da, resp->sa, ETH_ALEN);
os_memcpy(resp->sa, hapd->own_addr, ETH_ALEN);
}
os_free(resp);
}
+
+ return 1;
}
* addition, it can be called to re-inserted pending frames (e.g., when using
* external RADIUS server as an MAC ACL).
*/
-void ieee802_11_mgmt(struct hostapd_data *hapd, const u8 *buf, size_t len,
- struct hostapd_frame_info *fi)
+int ieee802_11_mgmt(struct hostapd_data *hapd, const u8 *buf, size_t len,
+ struct hostapd_frame_info *fi)
{
struct ieee80211_mgmt *mgmt;
int broadcast;
u16 fc, stype;
+ int ret = 0;
#ifdef CONFIG_TESTING_OPTIONS
if (hapd->ext_mgmt_frame_handling) {
wpa_msg(hapd->msg_ctx, MSG_INFO, "MGMT-RX %s", hex);
os_free(hex);
}
- return;
+ return 1;
}
#endif /* CONFIG_TESTING_OPTIONS */
if (len < 24)
- return;
+ return 0;
mgmt = (struct ieee80211_mgmt *) buf;
fc = le_to_host16(mgmt->frame_control);
if (stype == WLAN_FC_STYPE_BEACON) {
handle_beacon(hapd, mgmt, len, fi);
- return;
+ return 1;
}
broadcast = mgmt->bssid[0] == 0xff && mgmt->bssid[1] == 0xff &&
os_memcmp(mgmt->bssid, hapd->own_addr, ETH_ALEN) != 0) {
wpa_printf(MSG_INFO, "MGMT: BSSID=" MACSTR " not our address",
MAC2STR(mgmt->bssid));
- return;
+ return 0;
}
if (stype == WLAN_FC_STYPE_PROBE_REQ) {
handle_probe_req(hapd, mgmt, len, fi->ssi_signal);
- return;
+ return 1;
}
if (os_memcmp(mgmt->da, hapd->own_addr, ETH_ALEN) != 0) {
HOSTAPD_LEVEL_DEBUG,
"MGMT: DA=" MACSTR " not our address",
MAC2STR(mgmt->da));
- return;
+ return 0;
}
switch (stype) {
case WLAN_FC_STYPE_AUTH:
wpa_printf(MSG_DEBUG, "mgmt::auth");
handle_auth(hapd, mgmt, len);
+ ret = 1;
break;
case WLAN_FC_STYPE_ASSOC_REQ:
wpa_printf(MSG_DEBUG, "mgmt::assoc_req");
handle_assoc(hapd, mgmt, len, 0);
+ ret = 1;
break;
case WLAN_FC_STYPE_REASSOC_REQ:
wpa_printf(MSG_DEBUG, "mgmt::reassoc_req");
handle_assoc(hapd, mgmt, len, 1);
+ ret = 1;
break;
case WLAN_FC_STYPE_DISASSOC:
wpa_printf(MSG_DEBUG, "mgmt::disassoc");
handle_disassoc(hapd, mgmt, len);
+ ret = 1;
break;
case WLAN_FC_STYPE_DEAUTH:
wpa_msg(hapd->msg_ctx, MSG_DEBUG, "mgmt::deauth");
handle_deauth(hapd, mgmt, len);
+ ret = 1;
break;
case WLAN_FC_STYPE_ACTION:
wpa_printf(MSG_DEBUG, "mgmt::action");
- handle_action(hapd, mgmt, len);
+ ret = handle_action(hapd, mgmt, len);
break;
default:
hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
"unknown mgmt frame subtype %d", stype);
break;
}
+
+ return ret;
}