mirror of
https://github.com/vanhoefm/fragattacks.git
synced 2025-02-26 13:49:35 -05:00
WNM: Add BSS Transition Management Request for ESS Disassoc Imminent
"hostapd_cli ess_disassoc (STA addr) (URL)" can now be used to send an ESS Dissassociation Imminent notification to the STA. This event is shown in wpa_supplicant ctrl_iface monitors (e.g., wpa_cli): "WNM: ESS Disassociation Imminent - session_info_url=http://example.com/session/"
This commit is contained in:
parent
4fe9fa0d29
commit
71269b3708
@ -526,6 +526,57 @@ static int hostapd_ctrl_iface_wps_config(struct hostapd_data *hapd, char *txt)
|
|||||||
#endif /* CONFIG_WPS */
|
#endif /* CONFIG_WPS */
|
||||||
|
|
||||||
|
|
||||||
|
static int hostapd_ctrl_iface_ess_disassoc(struct hostapd_data *hapd,
|
||||||
|
const char *cmd)
|
||||||
|
{
|
||||||
|
u8 addr[ETH_ALEN];
|
||||||
|
const char *url;
|
||||||
|
u8 buf[1000], *pos;
|
||||||
|
struct ieee80211_mgmt *mgmt;
|
||||||
|
size_t url_len;
|
||||||
|
|
||||||
|
if (hwaddr_aton(cmd, addr))
|
||||||
|
return -1;
|
||||||
|
url = cmd + 17;
|
||||||
|
if (*url != ' ')
|
||||||
|
return -1;
|
||||||
|
url++;
|
||||||
|
url_len = os_strlen(url);
|
||||||
|
if (url_len > 255)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
os_memset(buf, 0, sizeof(buf));
|
||||||
|
mgmt = (struct ieee80211_mgmt *) buf;
|
||||||
|
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_WNM;
|
||||||
|
mgmt->u.action.u.bss_tm_req.action = WNM_BSS_TRANS_MGMT_REQ;
|
||||||
|
mgmt->u.action.u.bss_tm_req.dialog_token = 1;
|
||||||
|
mgmt->u.action.u.bss_tm_req.req_mode =
|
||||||
|
WNM_BSS_TM_REQ_ESS_DISASSOC_IMMINENT;
|
||||||
|
mgmt->u.action.u.bss_tm_req.disassoc_timer = host_to_le16(0);
|
||||||
|
mgmt->u.action.u.bss_tm_req.validity_interval = 0;
|
||||||
|
|
||||||
|
pos = mgmt->u.action.u.bss_tm_req.variable;
|
||||||
|
|
||||||
|
/* Session Information URL */
|
||||||
|
*pos++ = url_len;
|
||||||
|
os_memcpy(pos, url, url_len);
|
||||||
|
pos += url_len;
|
||||||
|
|
||||||
|
if (hostapd_drv_send_mlme(hapd, buf, pos - buf) < 0) {
|
||||||
|
wpa_printf(MSG_DEBUG, "Failed to send BSS Transition "
|
||||||
|
"Management Request frame");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int hostapd_ctrl_iface_get_config(struct hostapd_data *hapd,
|
static int hostapd_ctrl_iface_get_config(struct hostapd_data *hapd,
|
||||||
char *buf, size_t buflen)
|
char *buf, size_t buflen)
|
||||||
{
|
{
|
||||||
@ -879,6 +930,9 @@ static void hostapd_ctrl_iface_receive(int sock, void *eloop_ctx,
|
|||||||
if (hostapd_ctrl_iface_wps_config(hapd, buf + 11) < 0)
|
if (hostapd_ctrl_iface_wps_config(hapd, buf + 11) < 0)
|
||||||
reply_len = -1;
|
reply_len = -1;
|
||||||
#endif /* CONFIG_WPS */
|
#endif /* CONFIG_WPS */
|
||||||
|
} else if (os_strncmp(buf, "ESS_DISASSOC ", 13) == 0) {
|
||||||
|
if (hostapd_ctrl_iface_ess_disassoc(hapd, buf + 13))
|
||||||
|
reply_len = -1;
|
||||||
} else if (os_strcmp(buf, "GET_CONFIG") == 0) {
|
} else if (os_strcmp(buf, "GET_CONFIG") == 0) {
|
||||||
reply_len = hostapd_ctrl_iface_get_config(hapd, reply,
|
reply_len = hostapd_ctrl_iface_get_config(hapd, reply,
|
||||||
reply_size);
|
reply_size);
|
||||||
|
@ -515,6 +515,26 @@ static int hostapd_cli_cmd_wps_config(struct wpa_ctrl *ctrl, int argc,
|
|||||||
#endif /* CONFIG_WPS */
|
#endif /* CONFIG_WPS */
|
||||||
|
|
||||||
|
|
||||||
|
static int hostapd_cli_cmd_ess_disassoc(struct wpa_ctrl *ctrl, int argc,
|
||||||
|
char *argv[])
|
||||||
|
{
|
||||||
|
char buf[300];
|
||||||
|
int res;
|
||||||
|
|
||||||
|
if (argc < 2) {
|
||||||
|
printf("Invalid 'ess_disassoc' command - two arguments (STA "
|
||||||
|
"addr and URL) are needed\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = os_snprintf(buf, sizeof(buf), "ESS_DISASSOC %s %s",
|
||||||
|
argv[0], argv[1]);
|
||||||
|
if (res < 0 || res >= (int) sizeof(buf))
|
||||||
|
return -1;
|
||||||
|
return wpa_ctrl_command(ctrl, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int hostapd_cli_cmd_get_config(struct wpa_ctrl *ctrl, int argc,
|
static int hostapd_cli_cmd_get_config(struct wpa_ctrl *ctrl, int argc,
|
||||||
char *argv[])
|
char *argv[])
|
||||||
{
|
{
|
||||||
@ -728,6 +748,7 @@ static struct hostapd_cli_cmd hostapd_cli_commands[] = {
|
|||||||
{ "wps_ap_pin", hostapd_cli_cmd_wps_ap_pin },
|
{ "wps_ap_pin", hostapd_cli_cmd_wps_ap_pin },
|
||||||
{ "wps_config", hostapd_cli_cmd_wps_config },
|
{ "wps_config", hostapd_cli_cmd_wps_config },
|
||||||
#endif /* CONFIG_WPS */
|
#endif /* CONFIG_WPS */
|
||||||
|
{ "ess_disassoc", hostapd_cli_cmd_ess_disassoc },
|
||||||
{ "get_config", hostapd_cli_cmd_get_config },
|
{ "get_config", hostapd_cli_cmd_get_config },
|
||||||
{ "help", hostapd_cli_cmd_help },
|
{ "help", hostapd_cli_cmd_help },
|
||||||
{ "interface", hostapd_cli_cmd_interface },
|
{ "interface", hostapd_cli_cmd_interface },
|
||||||
|
@ -240,6 +240,8 @@
|
|||||||
#define WLAN_ACTION_FT 6
|
#define WLAN_ACTION_FT 6
|
||||||
#define WLAN_ACTION_HT 7
|
#define WLAN_ACTION_HT 7
|
||||||
#define WLAN_ACTION_SA_QUERY 8
|
#define WLAN_ACTION_SA_QUERY 8
|
||||||
|
#define WLAN_ACTION_WNM 10
|
||||||
|
#define WLAN_ACTION_UNPROTECTED_WNM 11
|
||||||
#define WLAN_ACTION_TDLS 12
|
#define WLAN_ACTION_TDLS 12
|
||||||
#define WLAN_ACTION_WMM 17 /* WMM Specification 1.1 */
|
#define WLAN_ACTION_WMM 17 /* WMM Specification 1.1 */
|
||||||
#define WLAN_ACTION_VENDOR_SPECIFIC 127
|
#define WLAN_ACTION_VENDOR_SPECIFIC 127
|
||||||
@ -455,6 +457,18 @@ struct ieee80211_mgmt {
|
|||||||
/* Vendor-specific content */
|
/* Vendor-specific content */
|
||||||
u8 variable[0];
|
u8 variable[0];
|
||||||
} STRUCT_PACKED vs_public_action;
|
} STRUCT_PACKED vs_public_action;
|
||||||
|
struct {
|
||||||
|
u8 action; /* 7 */
|
||||||
|
u8 dialog_token;
|
||||||
|
u8 req_mode;
|
||||||
|
le16 disassoc_timer;
|
||||||
|
u8 validity_interval;
|
||||||
|
/* BSS Termination Duration (optional),
|
||||||
|
* Session Information URL (optional),
|
||||||
|
* BSS Transition Candidate List
|
||||||
|
* Entries */
|
||||||
|
u8 variable[0];
|
||||||
|
} STRUCT_PACKED bss_tm_req;
|
||||||
} u;
|
} u;
|
||||||
} STRUCT_PACKED action;
|
} STRUCT_PACKED action;
|
||||||
} u;
|
} u;
|
||||||
@ -816,4 +830,44 @@ enum p2p_sd_status {
|
|||||||
#define WLAN_AKM_SUITE_8021X 0x000FAC01
|
#define WLAN_AKM_SUITE_8021X 0x000FAC01
|
||||||
#define WLAN_AKM_SUITE_PSK 0x000FAC02
|
#define WLAN_AKM_SUITE_PSK 0x000FAC02
|
||||||
|
|
||||||
|
|
||||||
|
/* IEEE 802.11v - WNM Action field values */
|
||||||
|
enum wnm_action {
|
||||||
|
WNM_EVENT_REQ = 0,
|
||||||
|
WNM_EVENT_REPORT = 1,
|
||||||
|
WNM_DIAGNOSTIC_REQ = 2,
|
||||||
|
WNM_DIAGNOSTIC_REPORT = 3,
|
||||||
|
WNM_LOCATION_CFG_REQ = 4,
|
||||||
|
WNM_LOCATION_CFG_RESP = 5,
|
||||||
|
WNM_BSS_TRANS_MGMT_QUERY = 6,
|
||||||
|
WNM_BSS_TRANS_MGMT_REQ = 7,
|
||||||
|
WNM_BSS_TRANS_MGMT_RESP = 8,
|
||||||
|
WNM_FMS_REQ = 9,
|
||||||
|
WNM_FMS_RESP = 10,
|
||||||
|
WNM_COLLOCATED_INTERFERENCE_REQ = 11,
|
||||||
|
WNM_COLLOCATED_INTERFERENCE_REPORT = 12,
|
||||||
|
WNM_TFS_REQ = 13,
|
||||||
|
WNM_TFS_RESP = 14,
|
||||||
|
WNM_TFS_NOTIFY = 15,
|
||||||
|
WNM_SLEEP_MODE_REQ = 16,
|
||||||
|
WNM_SLEEP_MODE_RESP = 17,
|
||||||
|
WNM_TIM_BROADCAST_REQ = 18,
|
||||||
|
WNM_TIM_BROADCAST_RESP = 19,
|
||||||
|
WNM_QOS_TRAFFIC_CAPAB_UPDATE = 20,
|
||||||
|
WNM_CHANNEL_USAGE_REQ = 21,
|
||||||
|
WNM_CHANNEL_USAGE_RESP = 22,
|
||||||
|
WNM_DMS_REQ = 23,
|
||||||
|
WNM_DMS_RESP = 24,
|
||||||
|
WNM_TIMING_MEASUREMENT_REQ = 25,
|
||||||
|
WNM_NOTIFICATION_REQ = 26,
|
||||||
|
WNM_NOTIFICATION_RESP = 27
|
||||||
|
};
|
||||||
|
|
||||||
|
/* IEEE 802.11v - BSS Transition Management Request - Request Mode */
|
||||||
|
#define WNM_BSS_TM_REQ_PREF_CAND_LIST_INCLUDED BIT(0)
|
||||||
|
#define WNM_BSS_TM_REQ_ABRIDGED BIT(1)
|
||||||
|
#define WNM_BSS_TM_REQ_DISASSOC_IMMINENT BIT(2)
|
||||||
|
#define WNM_BSS_TM_REQ_BSS_TERMINATION_INCLUDED BIT(3)
|
||||||
|
#define WNM_BSS_TM_REQ_ESS_DISASSOC_IMMINENT BIT(4)
|
||||||
|
|
||||||
#endif /* IEEE802_11_DEFS_H */
|
#endif /* IEEE802_11_DEFS_H */
|
||||||
|
@ -2312,6 +2312,10 @@ static int nl80211_register_action_frames(struct wpa_driver_nl80211_data *drv)
|
|||||||
drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_FT |
|
drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_FT |
|
||||||
WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK;
|
WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK;
|
||||||
|
|
||||||
|
/* WNM - BSS Transition Management Request */
|
||||||
|
if (nl80211_register_action_frame(drv, (u8 *) "\x0a\x07", 2) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1774,6 +1774,50 @@ static void wpa_supplicant_event_unprot_disassoc(struct wpa_supplicant *wpa_s,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void wnm_action_rx(struct wpa_supplicant *wpa_s, struct rx_action *rx)
|
||||||
|
{
|
||||||
|
u8 action, mode;
|
||||||
|
const u8 *pos, *end;
|
||||||
|
|
||||||
|
if (rx->data == NULL || rx->len == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
pos = rx->data;
|
||||||
|
end = pos + rx->len;
|
||||||
|
action = *pos++;
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "WNM: RX action %u from " MACSTR,
|
||||||
|
action, MAC2STR(rx->sa));
|
||||||
|
switch (action) {
|
||||||
|
case WNM_BSS_TRANS_MGMT_REQ:
|
||||||
|
if (pos + 5 > end)
|
||||||
|
break;
|
||||||
|
wpa_printf(MSG_DEBUG, "WNM: BSS Transition Management "
|
||||||
|
"Request: dialog_token=%u request_mode=0x%x "
|
||||||
|
"disassoc_timer=%u validity_interval=%u",
|
||||||
|
pos[0], pos[1], WPA_GET_LE16(pos + 2), pos[4]);
|
||||||
|
mode = pos[1];
|
||||||
|
pos += 5;
|
||||||
|
if (mode & 0x08)
|
||||||
|
pos += 12; /* BSS Termination Duration */
|
||||||
|
if (mode & 0x10) {
|
||||||
|
char url[256];
|
||||||
|
if (pos + 1 > end || pos + 1 + pos[0] > end) {
|
||||||
|
wpa_printf(MSG_DEBUG, "WNM: Invalid BSS "
|
||||||
|
"Transition Management Request "
|
||||||
|
"(URL)");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
os_memcpy(url, pos + 1, pos[0]);
|
||||||
|
url[pos[0]] = '\0';
|
||||||
|
wpa_msg(wpa_s, MSG_INFO, "WNM: ESS Disassociation "
|
||||||
|
"Imminent - session_info_url=%s", url);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
|
void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
|
||||||
union wpa_event_data *data)
|
union wpa_event_data *data)
|
||||||
{
|
{
|
||||||
@ -2048,6 +2092,10 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
|
|||||||
data->rx_action.freq) == 0)
|
data->rx_action.freq) == 0)
|
||||||
break;
|
break;
|
||||||
#endif /* CONFIG_GAS */
|
#endif /* CONFIG_GAS */
|
||||||
|
if (data->rx_action.category == WLAN_ACTION_WNM) {
|
||||||
|
wnm_action_rx(wpa_s, &data->rx_action);
|
||||||
|
break;
|
||||||
|
}
|
||||||
#ifdef CONFIG_P2P
|
#ifdef CONFIG_P2P
|
||||||
wpas_p2p_rx_action(wpa_s, data->rx_action.da,
|
wpas_p2p_rx_action(wpa_s, data->rx_action.da,
|
||||||
data->rx_action.sa,
|
data->rx_action.sa,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user