Added ctrl_interface command for sending a SA Query request
This can be useful for testing IEEE 802.11w functionality, so provide means for manual request to send a SA Query request.
This commit is contained in:
parent
3f732d1fc3
commit
88b4b4246d
5 changed files with 74 additions and 24 deletions
|
@ -218,6 +218,26 @@ static int hostapd_ctrl_iface_new_sta(struct hostapd_data *hapd,
|
|||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_IEEE80211W
|
||||
static int hostapd_ctrl_iface_sa_query(struct hostapd_data *hapd,
|
||||
const char *txtaddr)
|
||||
{
|
||||
u8 addr[ETH_ALEN];
|
||||
u8 trans_id[WLAN_SA_QUERY_TR_ID_LEN];
|
||||
|
||||
wpa_printf(MSG_DEBUG, "CTRL_IFACE SA_QUERY %s", txtaddr);
|
||||
|
||||
if (hwaddr_aton(txtaddr, addr))
|
||||
return -1;
|
||||
|
||||
os_get_random(trans_id, WLAN_SA_QUERY_TR_ID_LEN);
|
||||
ieee802_11_send_sa_query_req(hapd, addr, trans_id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_IEEE80211W */
|
||||
|
||||
|
||||
#ifdef CONFIG_WPS
|
||||
static int hostapd_ctrl_iface_wps_pin(struct hostapd_data *hapd, char *txt)
|
||||
{
|
||||
|
@ -313,6 +333,11 @@ static void hostapd_ctrl_iface_receive(int sock, void *eloop_ctx,
|
|||
} else if (os_strncmp(buf, "NEW_STA ", 8) == 0) {
|
||||
if (hostapd_ctrl_iface_new_sta(hapd, buf + 8))
|
||||
reply_len = -1;
|
||||
#ifdef CONFIG_IEEE80211W
|
||||
} else if (os_strncmp(buf, "SA_QUERY ", 9) == 0) {
|
||||
if (hostapd_ctrl_iface_sa_query(hapd, buf + 9))
|
||||
reply_len = -1;
|
||||
#endif /* CONFIG_IEEE80211W */
|
||||
#ifdef CONFIG_WPS
|
||||
} else if (os_strncmp(buf, "WPS_PIN ", 8) == 0) {
|
||||
if (hostapd_ctrl_iface_wps_pin(hapd, buf + 8))
|
||||
|
|
|
@ -83,6 +83,9 @@ static const char *commands_help =
|
|||
" sta <addr> get MIB variables for one station\n"
|
||||
" all_sta get MIB variables for all stations\n"
|
||||
" new_sta <addr> add a new station\n"
|
||||
#ifdef CONFIG_IEEE80211W
|
||||
" sa_query <addr> send SA Query to a station\n"
|
||||
#endif /* CONFIG_IEEE80211W */
|
||||
#ifdef CONFIG_WPS
|
||||
" wps_pin <uuid> <pin> add WPS Enrollee PIN (Device Password)\n"
|
||||
" wps_pbc indicate button pushed to initiate PBC\n"
|
||||
|
@ -234,6 +237,22 @@ static int hostapd_cli_cmd_new_sta(struct wpa_ctrl *ctrl, int argc,
|
|||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_IEEE80211W
|
||||
static int hostapd_cli_cmd_sa_query(struct wpa_ctrl *ctrl, int argc,
|
||||
char *argv[])
|
||||
{
|
||||
char buf[64];
|
||||
if (argc != 1) {
|
||||
printf("Invalid 'sa_query' command - exactly one argument, "
|
||||
"STA address, is required.\n");
|
||||
return -1;
|
||||
}
|
||||
snprintf(buf, sizeof(buf), "SA_QUERY %s", argv[0]);
|
||||
return wpa_ctrl_command(ctrl, buf);
|
||||
}
|
||||
#endif /* CONFIG_IEEE80211W */
|
||||
|
||||
|
||||
#ifdef CONFIG_WPS
|
||||
static int hostapd_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc,
|
||||
char *argv[])
|
||||
|
@ -405,6 +424,9 @@ static struct hostapd_cli_cmd hostapd_cli_commands[] = {
|
|||
{ "sta", hostapd_cli_cmd_sta },
|
||||
{ "all_sta", hostapd_cli_cmd_all_sta },
|
||||
{ "new_sta", hostapd_cli_cmd_new_sta },
|
||||
#ifdef CONFIG_IEEE80211W
|
||||
{ "sa_query", hostapd_cli_cmd_sa_query },
|
||||
#endif /* CONFIG_IEEE80211W */
|
||||
#ifdef CONFIG_WPS
|
||||
{ "wps_pin", hostapd_cli_cmd_wps_pin },
|
||||
{ "wps_pbc", hostapd_cli_cmd_wps_pbc },
|
||||
|
|
|
@ -1250,6 +1250,31 @@ static void handle_beacon(struct hostapd_data *hapd,
|
|||
|
||||
|
||||
#ifdef CONFIG_IEEE80211W
|
||||
|
||||
/* MLME-SAQuery.request */
|
||||
void ieee802_11_send_sa_query_req(struct hostapd_data *hapd,
|
||||
const u8 *addr, const u8 *trans_id)
|
||||
{
|
||||
struct ieee80211_mgmt mgmt;
|
||||
u8 *end;
|
||||
|
||||
os_memset(&mgmt, 0, sizeof(mgmt));
|
||||
mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
|
||||
WLAN_FC_STYPE_ACTION);
|
||||
os_memcpy(mgmt.da, addr, ETH_ALEN);
|
||||
os_memcpy(mgmt.sa, hapd->own_addr, ETH_ALEN);
|
||||
os_memcpy(mgmt.bssid, hapd->own_addr, ETH_ALEN);
|
||||
mgmt.u.action.category = WLAN_ACTION_SA_QUERY;
|
||||
mgmt.u.action.u.sa_query_req.action = WLAN_SA_QUERY_REQUEST;
|
||||
os_memcpy(mgmt.u.action.u.sa_query_req.trans_id, trans_id,
|
||||
WLAN_SA_QUERY_TR_ID_LEN);
|
||||
end = mgmt.u.action.u.sa_query_req.trans_id + WLAN_SA_QUERY_TR_ID_LEN;
|
||||
if (hostapd_send_mgmt_frame(hapd, &mgmt, IEEE80211_HDRLEN +
|
||||
end - (u8 *) &mgmt, 0) < 0)
|
||||
perror("ieee802_11_send_sa_query_req: send");
|
||||
}
|
||||
|
||||
|
||||
static void hostapd_sa_query_action(struct hostapd_data *hapd,
|
||||
struct ieee80211_mgmt *mgmt, size_t len)
|
||||
{
|
||||
|
|
|
@ -50,5 +50,7 @@ u8 * hostapd_eid_ext_supp_rates(struct hostapd_data *hapd, u8 *eid);
|
|||
u8 * hostapd_eid_ht_capabilities_info(struct hostapd_data *hapd, u8 *eid);
|
||||
u8 * hostapd_eid_ht_operation(struct hostapd_data *hapd, u8 *eid);
|
||||
int hostapd_ht_operation_update(struct hostapd_iface *iface);
|
||||
void ieee802_11_send_sa_query_req(struct hostapd_data *hapd,
|
||||
const u8 *addr, const u8 *trans_id);
|
||||
|
||||
#endif /* IEEE802_11_H */
|
||||
|
|
|
@ -613,30 +613,6 @@ int ap_sta_bind_vlan(struct hostapd_data *hapd, struct sta_info *sta,
|
|||
|
||||
#ifdef CONFIG_IEEE80211W
|
||||
|
||||
/* MLME-SAQuery.request */
|
||||
static void ieee802_11_send_sa_query_req(struct hostapd_data *hapd,
|
||||
const u8 *addr, const u8 *trans_id)
|
||||
{
|
||||
struct ieee80211_mgmt mgmt;
|
||||
u8 *end;
|
||||
|
||||
os_memset(&mgmt, 0, sizeof(mgmt));
|
||||
mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
|
||||
WLAN_FC_STYPE_ACTION);
|
||||
os_memcpy(mgmt.da, addr, ETH_ALEN);
|
||||
os_memcpy(mgmt.sa, hapd->own_addr, ETH_ALEN);
|
||||
os_memcpy(mgmt.bssid, hapd->own_addr, ETH_ALEN);
|
||||
mgmt.u.action.category = WLAN_ACTION_SA_QUERY;
|
||||
mgmt.u.action.u.sa_query_req.action = WLAN_SA_QUERY_REQUEST;
|
||||
os_memcpy(mgmt.u.action.u.sa_query_req.trans_id, trans_id,
|
||||
WLAN_SA_QUERY_TR_ID_LEN);
|
||||
end = mgmt.u.action.u.sa_query_req.trans_id + WLAN_SA_QUERY_TR_ID_LEN;
|
||||
if (hostapd_send_mgmt_frame(hapd, &mgmt, IEEE80211_HDRLEN +
|
||||
end - (u8 *) &mgmt, 0) < 0)
|
||||
perror("ieee802_11_send_sa_query_req: send");
|
||||
}
|
||||
|
||||
|
||||
int ap_check_sa_query_timeout(struct hostapd_data *hapd, struct sta_info *sta)
|
||||
{
|
||||
u32 tu;
|
||||
|
|
Loading…
Reference in a new issue