diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c index 2d0379f3b..427c0546c 100644 --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c @@ -994,6 +994,10 @@ static int hostapd_ctrl_iface_set(struct hostapd_data *hapd, char *cmd) else hapd->gas_frag_limit = val; #endif /* CONFIG_INTERWORKING */ +#ifdef CONFIG_TESTING_OPTIONS + } else if (os_strcasecmp(cmd, "ext_mgmt_frame_handling") == 0) { + hapd->ext_mgmt_frame_handling = atoi(value); +#endif /* CONFIG_TESTING_OPTIONS */ } else { ret = hostapd_set_iface(hapd->iconf, hapd->conf, cmd, value); } @@ -1051,6 +1055,7 @@ static int hostapd_ctrl_iface_disable(struct hostapd_iface *iface) #ifdef CONFIG_TESTING_OPTIONS + static int hostapd_ctrl_iface_radar(struct hostapd_data *hapd, char *cmd) { union wpa_event_data data; @@ -1108,6 +1113,35 @@ static int hostapd_ctrl_iface_radar(struct hostapd_data *hapd, char *cmd) return 0; } + + +static int hostapd_ctrl_iface_mgmt_tx(struct hostapd_data *hapd, char *cmd) +{ + size_t len; + u8 *buf; + int res; + + wpa_printf(MSG_DEBUG, "External MGMT TX: %s", cmd); + + len = os_strlen(cmd); + if (len & 1) + return -1; + len /= 2; + + buf = os_malloc(len); + if (buf == NULL) + return -1; + + if (hexstr2bin(cmd, buf, len) < 0) { + os_free(buf); + return -1; + } + + res = hostapd_drv_send_mlme(hapd, buf, len, 0); + os_free(buf); + return res; +} + #endif /* CONFIG_TESTING_OPTIONS */ @@ -1312,6 +1346,9 @@ static void hostapd_ctrl_iface_receive(int sock, void *eloop_ctx, } else if (os_strncmp(buf, "RADAR ", 6) == 0) { if (hostapd_ctrl_iface_radar(hapd, buf + 6)) reply_len = -1; + } else if (os_strncmp(buf, "MGMT_TX ", 8) == 0) { + if (hostapd_ctrl_iface_mgmt_tx(hapd, buf + 8)) + reply_len = -1; #endif /* CONFIG_TESTING_OPTIONS */ } else if (os_strncmp(buf, "CHAN_SWITCH ", 12) == 0) { if (hostapd_ctrl_iface_chan_switch(hapd, buf + 12)) diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h index d4f275ec3..489ab1652 100644 --- a/src/ap/hostapd.h +++ b/src/ap/hostapd.h @@ -240,6 +240,10 @@ struct hostapd_data { u8 sae_token_key[8]; struct os_reltime last_sae_token_key_update; #endif /* CONFIG_SAE */ + +#ifdef CONFIG_TESTING_OPTIONS + int ext_mgmt_frame_handling; +#endif /* CONFIG_TESTING_OPTIONS */ }; diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index 88f575a59..7c550e462 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -1725,6 +1725,19 @@ void ieee802_11_mgmt(struct hostapd_data *hapd, const u8 *buf, size_t len, int broadcast; u16 fc, stype; +#ifdef CONFIG_TESTING_OPTIONS + if (hapd->ext_mgmt_frame_handling) { + size_t hex_len = 2 * len + 1; + char *hex = os_malloc(hex_len); + if (hex) { + wpa_snprintf_hex(hex, hex_len, buf, len); + wpa_msg(hapd->msg_ctx, MSG_INFO, "MGMT-RX %s", hex); + os_free(hex); + } + return; + } +#endif /* CONFIG_TESTING_OPTIONS */ + if (len < 24) return; @@ -2074,6 +2087,14 @@ void ieee802_11_mgmt_cb(struct hostapd_data *hapd, const u8 *buf, size_t len, const struct ieee80211_mgmt *mgmt; mgmt = (const struct ieee80211_mgmt *) buf; +#ifdef CONFIG_TESTING_OPTIONS + if (hapd->ext_mgmt_frame_handling) { + wpa_msg(hapd->msg_ctx, MSG_INFO, "MGMT-TX-STATUS stype=%u ok=%d", + stype, ok); + return; + } +#endif /* CONFIG_TESTING_OPTIONS */ + switch (stype) { case WLAN_FC_STYPE_AUTH: wpa_printf(MSG_DEBUG, "mgmt::auth cb");