hostapd: Allow external management frame processing or testing
This enables more convenient protocol testing of station side functionality in various error cases and unexpected sequences without having to implement each test scenario within hostapd. ext_mgmt_frame_handle parameter can be set to 1 to move all management frame processing into an external program through control interface events (MGMT-RX and MGMT-TX-STATUS) and command (MGMT_TX). Signed-hostap: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
e4a44b3c09
commit
93827f456a
3 changed files with 62 additions and 0 deletions
|
@ -994,6 +994,10 @@ static int hostapd_ctrl_iface_set(struct hostapd_data *hapd, char *cmd)
|
||||||
else
|
else
|
||||||
hapd->gas_frag_limit = val;
|
hapd->gas_frag_limit = val;
|
||||||
#endif /* CONFIG_INTERWORKING */
|
#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 {
|
} else {
|
||||||
ret = hostapd_set_iface(hapd->iconf, hapd->conf, cmd, value);
|
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
|
#ifdef CONFIG_TESTING_OPTIONS
|
||||||
|
|
||||||
static int hostapd_ctrl_iface_radar(struct hostapd_data *hapd, char *cmd)
|
static int hostapd_ctrl_iface_radar(struct hostapd_data *hapd, char *cmd)
|
||||||
{
|
{
|
||||||
union wpa_event_data data;
|
union wpa_event_data data;
|
||||||
|
@ -1108,6 +1113,35 @@ static int hostapd_ctrl_iface_radar(struct hostapd_data *hapd, char *cmd)
|
||||||
|
|
||||||
return 0;
|
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 */
|
#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) {
|
} else if (os_strncmp(buf, "RADAR ", 6) == 0) {
|
||||||
if (hostapd_ctrl_iface_radar(hapd, buf + 6))
|
if (hostapd_ctrl_iface_radar(hapd, buf + 6))
|
||||||
reply_len = -1;
|
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 */
|
#endif /* CONFIG_TESTING_OPTIONS */
|
||||||
} else if (os_strncmp(buf, "CHAN_SWITCH ", 12) == 0) {
|
} else if (os_strncmp(buf, "CHAN_SWITCH ", 12) == 0) {
|
||||||
if (hostapd_ctrl_iface_chan_switch(hapd, buf + 12))
|
if (hostapd_ctrl_iface_chan_switch(hapd, buf + 12))
|
||||||
|
|
|
@ -240,6 +240,10 @@ struct hostapd_data {
|
||||||
u8 sae_token_key[8];
|
u8 sae_token_key[8];
|
||||||
struct os_reltime last_sae_token_key_update;
|
struct os_reltime last_sae_token_key_update;
|
||||||
#endif /* CONFIG_SAE */
|
#endif /* CONFIG_SAE */
|
||||||
|
|
||||||
|
#ifdef CONFIG_TESTING_OPTIONS
|
||||||
|
int ext_mgmt_frame_handling;
|
||||||
|
#endif /* CONFIG_TESTING_OPTIONS */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1725,6 +1725,19 @@ void ieee802_11_mgmt(struct hostapd_data *hapd, const u8 *buf, size_t len,
|
||||||
int broadcast;
|
int broadcast;
|
||||||
u16 fc, stype;
|
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)
|
if (len < 24)
|
||||||
return;
|
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;
|
const struct ieee80211_mgmt *mgmt;
|
||||||
mgmt = (const struct ieee80211_mgmt *) buf;
|
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) {
|
switch (stype) {
|
||||||
case WLAN_FC_STYPE_AUTH:
|
case WLAN_FC_STYPE_AUTH:
|
||||||
wpa_printf(MSG_DEBUG, "mgmt::auth cb");
|
wpa_printf(MSG_DEBUG, "mgmt::auth cb");
|
||||||
|
|
Loading…
Reference in a new issue