WNM: Minimal processing of BSS Transition Management Query/Response
This adds first steps at processing a BSS Transition Management Query on the AP side. Mainly, the message is parsed and printed out in the debug log and a minimal BSS Transition Management Request frame is sent as a response. BSS Transition Management Response frame is also parsed and details printed out in the debug log. Signed-hostap: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
2cd0f6a429
commit
28ab64af9b
1 changed files with 128 additions and 7 deletions
135
src/ap/wnm_ap.c
135
src/ap/wnm_ap.c
|
@ -243,6 +243,126 @@ static void ieee802_11_rx_wnmsleep_req(struct hostapd_data *hapd,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int ieee802_11_send_bss_trans_mgmt_request(struct hostapd_data *hapd,
|
||||||
|
const u8 *addr,
|
||||||
|
u8 dialog_token,
|
||||||
|
const char *url)
|
||||||
|
{
|
||||||
|
struct ieee80211_mgmt *mgmt;
|
||||||
|
size_t url_len, len;
|
||||||
|
u8 *pos;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
if (url)
|
||||||
|
url_len = os_strlen(url);
|
||||||
|
else
|
||||||
|
url_len = 0;
|
||||||
|
|
||||||
|
mgmt = os_zalloc(sizeof(*mgmt) + (url_len ? 1 + url_len : 0));
|
||||||
|
if (mgmt == NULL)
|
||||||
|
return -1;
|
||||||
|
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->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
|
||||||
|
WLAN_FC_STYPE_ACTION);
|
||||||
|
mgmt->u.action.category = WLAN_ACTION_WNM;
|
||||||
|
mgmt->u.action.u.bss_tm_req.action = WNM_BSS_TRANS_MGMT_REQ;
|
||||||
|
mgmt->u.action.u.bss_tm_req.dialog_token = dialog_token;
|
||||||
|
mgmt->u.action.u.bss_tm_req.req_mode = 0;
|
||||||
|
mgmt->u.action.u.bss_tm_req.disassoc_timer = host_to_le16(0);
|
||||||
|
mgmt->u.action.u.bss_tm_req.validity_interval = 1;
|
||||||
|
pos = mgmt->u.action.u.bss_tm_req.variable;
|
||||||
|
if (url) {
|
||||||
|
*pos++ += url_len;
|
||||||
|
os_memcpy(pos, url, url_len);
|
||||||
|
pos += url_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "WNM: Send BSS Transition Management Request to "
|
||||||
|
MACSTR " dialog_token=%u req_mode=0x%x disassoc_timer=%u "
|
||||||
|
"validity_interval=%u",
|
||||||
|
MAC2STR(addr), dialog_token,
|
||||||
|
mgmt->u.action.u.bss_tm_req.req_mode,
|
||||||
|
le_to_host16(mgmt->u.action.u.bss_tm_req.disassoc_timer),
|
||||||
|
mgmt->u.action.u.bss_tm_req.validity_interval);
|
||||||
|
|
||||||
|
len = pos - &mgmt->u.action.category;
|
||||||
|
res = hostapd_drv_send_action(hapd, hapd->iface->freq, 0,
|
||||||
|
mgmt->da, &mgmt->u.action.category, len);
|
||||||
|
os_free(mgmt);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void ieee802_11_rx_bss_trans_mgmt_query(struct hostapd_data *hapd,
|
||||||
|
const u8 *addr, const u8 *frm,
|
||||||
|
size_t len)
|
||||||
|
{
|
||||||
|
u8 dialog_token, reason;
|
||||||
|
const u8 *pos, *end;
|
||||||
|
|
||||||
|
if (len < 2) {
|
||||||
|
wpa_printf(MSG_DEBUG, "WNM: Ignore too short BSS Transition Management Query from "
|
||||||
|
MACSTR, MAC2STR(addr));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos = frm;
|
||||||
|
end = pos + len;
|
||||||
|
dialog_token = *pos++;
|
||||||
|
reason = *pos++;
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "WNM: BSS Transition Management Query from "
|
||||||
|
MACSTR " dialog_token=%u reason=%u",
|
||||||
|
MAC2STR(addr), dialog_token, reason);
|
||||||
|
|
||||||
|
wpa_hexdump(MSG_DEBUG, "WNM: BSS Transition Candidate List Entries",
|
||||||
|
pos, end - pos);
|
||||||
|
|
||||||
|
ieee802_11_send_bss_trans_mgmt_request(hapd, addr, dialog_token, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void ieee802_11_rx_bss_trans_mgmt_resp(struct hostapd_data *hapd,
|
||||||
|
const u8 *addr, const u8 *frm,
|
||||||
|
size_t len)
|
||||||
|
{
|
||||||
|
u8 dialog_token, status_code, bss_termination_delay;
|
||||||
|
const u8 *pos, *end;
|
||||||
|
|
||||||
|
if (len < 3) {
|
||||||
|
wpa_printf(MSG_DEBUG, "WNM: Ignore too short BSS Transition Management Response from "
|
||||||
|
MACSTR, MAC2STR(addr));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos = frm;
|
||||||
|
end = pos + len;
|
||||||
|
dialog_token = *pos++;
|
||||||
|
status_code = *pos++;
|
||||||
|
bss_termination_delay = *pos++;
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "WNM: BSS Transition Management Response from "
|
||||||
|
MACSTR " dialog_token=%u status_code=%u "
|
||||||
|
"bss_termination_delay=%u", MAC2STR(addr), dialog_token,
|
||||||
|
status_code, bss_termination_delay);
|
||||||
|
|
||||||
|
if (status_code == WNM_BSS_TM_ACCEPT) {
|
||||||
|
if (end - pos < ETH_ALEN) {
|
||||||
|
wpa_printf(MSG_DEBUG, "WNM: not enough room for Target BSSID field");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
wpa_printf(MSG_DEBUG, "WNM: Target BSSID: " MACSTR,
|
||||||
|
MAC2STR(pos));
|
||||||
|
pos += ETH_ALEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
wpa_hexdump(MSG_DEBUG, "WNM: BSS Transition Candidate List Entries",
|
||||||
|
pos, end - pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int ieee802_11_rx_wnm_action_ap(struct hostapd_data *hapd,
|
int ieee802_11_rx_wnm_action_ap(struct hostapd_data *hapd,
|
||||||
struct rx_action *action)
|
struct rx_action *action)
|
||||||
{
|
{
|
||||||
|
@ -251,14 +371,15 @@ int ieee802_11_rx_wnm_action_ap(struct hostapd_data *hapd,
|
||||||
|
|
||||||
switch (action->data[0]) {
|
switch (action->data[0]) {
|
||||||
case WNM_BSS_TRANS_MGMT_QUERY:
|
case WNM_BSS_TRANS_MGMT_QUERY:
|
||||||
wpa_printf(MSG_DEBUG, "WNM: BSS Transition Management Query");
|
ieee802_11_rx_bss_trans_mgmt_query(hapd, action->sa,
|
||||||
/* TODO */
|
action->data + 1,
|
||||||
return -1;
|
action->len - 1);
|
||||||
|
return 0;
|
||||||
case WNM_BSS_TRANS_MGMT_RESP:
|
case WNM_BSS_TRANS_MGMT_RESP:
|
||||||
wpa_printf(MSG_DEBUG, "WNM: BSS Transition Management "
|
ieee802_11_rx_bss_trans_mgmt_resp(hapd, action->sa,
|
||||||
"Response");
|
action->data + 1,
|
||||||
/* TODO */
|
action->len - 1);
|
||||||
return -1;
|
return 0;
|
||||||
case WNM_SLEEP_MODE_REQ:
|
case WNM_SLEEP_MODE_REQ:
|
||||||
ieee802_11_rx_wnmsleep_req(hapd, action->sa, action->data + 1,
|
ieee802_11_rx_wnmsleep_req(hapd, action->sa, action->data + 1,
|
||||||
action->len - 1);
|
action->len - 1);
|
||||||
|
|
Loading…
Reference in a new issue