Add REGISTER_FRAME hostapd control interface command for testing purposes

This can be used to register reception of new types of Management frames
through nl80211.

Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
Jouni Malinen 2021-03-22 12:32:16 +02:00
parent 60974eb3f6
commit b8673baeab
4 changed files with 70 additions and 0 deletions

View file

@ -2564,6 +2564,34 @@ static int hostapd_ctrl_get_pmk(struct hostapd_data *hapd, const char *cmd,
return wpa_snprintf_hex(buf, buflen, pmk, pmk_len);
}
static int hostapd_ctrl_register_frame(struct hostapd_data *hapd,
const char *cmd)
{
u16 type;
char *pos, *end;
u8 match[10];
size_t match_len;
bool multicast = false;
type = strtol(cmd, &pos, 16);
if (*pos != ' ')
return -1;
pos++;
end = os_strchr(pos, ' ');
if (end) {
match_len = end - pos;
multicast = os_strstr(end, "multicast") != NULL;
} else {
match_len = os_strlen(pos) / 2;
}
if (hexstr2bin(pos, match, match_len))
return -1;
return hostapd_drv_register_frame(hapd, type, match, match_len,
multicast);
}
#endif /* CONFIG_TESTING_OPTIONS */
@ -3648,6 +3676,9 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
} else if (os_strncmp(buf, "GET_PMK ", 8) == 0) {
reply_len = hostapd_ctrl_get_pmk(hapd, buf + 8, reply,
reply_size);
} else if (os_strncmp(buf, "REGISTER_FRAME ", 15) == 0) {
if (hostapd_ctrl_register_frame(hapd, buf + 16) < 0)
reply_len = -1;
#endif /* CONFIG_TESTING_OPTIONS */
} else if (os_strncmp(buf, "CHAN_SWITCH ", 12) == 0) {
if (hostapd_ctrl_iface_chan_switch(hapd->iface, buf + 12))

View file

@ -403,4 +403,17 @@ static inline int hostapd_drv_driver_cmd(struct hostapd_data *hapd,
}
#endif /* ANDROID */
#ifdef CONFIG_TESTING_OPTIONS
static inline int
hostapd_drv_register_frame(struct hostapd_data *hapd, u16 type,
const u8 *match, size_t match_len,
bool multicast)
{
if (!hapd->driver || !hapd->drv_priv || !hapd->driver->register_frame)
return -1;
return hapd->driver->register_frame(hapd->drv_priv, type, match,
match_len, multicast);
}
#endif /* CONFIG_TESTING_OPTIONS */
#endif /* AP_DRV_OPS */

View file

@ -4553,6 +4553,12 @@ struct wpa_driver_ops {
* explicitly allow reception of broadcast Public Action frames.
*/
int (*dpp_listen)(void *priv, bool enable);
#ifdef CONFIG_TESTING_OPTIONS
int (*register_frame)(void *priv, u16 type,
const u8 *match, size_t match_len,
bool multicast);
#endif /* CONFIG_TESTING_OPTIONS */
};
/**

View file

@ -12035,6 +12035,23 @@ static int nl80211_dpp_listen(void *priv, bool enable)
#endif /* CONFIG_DPP */
#ifdef CONFIG_TESTING_OPTIONS
static int testing_nl80211_register_frame(void *priv, u16 type,
const u8 *match, size_t match_len,
bool multicast)
{
struct i802_bss *bss = priv;
struct nl_sock *handle;
if (!bss->nl_mgmt)
return -1;
handle = (void *) (((intptr_t) bss->nl_mgmt) ^ ELOOP_SOCKET_INVALID);
return nl80211_register_frame(bss, handle, type, match, match_len,
multicast);
}
#endif /* CONFIG_TESTING_OPTIONS */
const struct wpa_driver_ops wpa_driver_nl80211_ops = {
.name = "nl80211",
.desc = "Linux nl80211/cfg80211",
@ -12173,4 +12190,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
#ifdef CONFIG_DPP
.dpp_listen = nl80211_dpp_listen,
#endif /* CONFIG_DPP */
#ifdef CONFIG_TESTING_OPTIONS
.register_frame = testing_nl80211_register_frame,
#endif /* CONFIG_TESTING_OPTIONS */
};