mirror of
https://github.com/vanhoefm/fragattacks.git
synced 2025-01-29 08:14:02 -05:00
nl80211: Add support for STA opmode change events
The nl80211 driver can report STA_OPMODE notification event as soon as it receives an HT/VHT Action frame about modification of station's SMPS mode/bandwidth/RX NSS. Add support to parse such events. Signed-off-by: Tamizh chelvam <tamizhr@codeaurora.org>
This commit is contained in:
parent
72123a84cb
commit
e8ada1600f
@ -1877,6 +1877,17 @@ enum wnm_oper {
|
|||||||
WNM_SLEEP_TFS_IE_DEL /* AP delete the TFS IE */
|
WNM_SLEEP_TFS_IE_DEL /* AP delete the TFS IE */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* enum smps_mode - SMPS mode definitions */
|
||||||
|
enum smps_mode {
|
||||||
|
SMPS_AUTOMATIC,
|
||||||
|
SMPS_OFF,
|
||||||
|
SMPS_DYNAMIC,
|
||||||
|
SMPS_STATIC,
|
||||||
|
|
||||||
|
/* Keep last */
|
||||||
|
SMPS_INVALID,
|
||||||
|
};
|
||||||
|
|
||||||
/* enum chan_width - Channel width definitions */
|
/* enum chan_width - Channel width definitions */
|
||||||
enum chan_width {
|
enum chan_width {
|
||||||
CHAN_WIDTH_20_NOHT,
|
CHAN_WIDTH_20_NOHT,
|
||||||
@ -4568,6 +4579,12 @@ enum wpa_event_type {
|
|||||||
* indicates the completion of IEEE 802.11 association.
|
* indicates the completion of IEEE 802.11 association.
|
||||||
*/
|
*/
|
||||||
EVENT_PORT_AUTHORIZED,
|
EVENT_PORT_AUTHORIZED,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EVENT_STATION_OPMODE_CHANGED - Notify STA's HT/VHT operation mode
|
||||||
|
* change event.
|
||||||
|
*/
|
||||||
|
EVENT_STATION_OPMODE_CHANGED,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -5373,6 +5390,22 @@ union wpa_event_data {
|
|||||||
|
|
||||||
/* For EVENT_EXTERNAL_AUTH */
|
/* For EVENT_EXTERNAL_AUTH */
|
||||||
struct external_auth external_auth;
|
struct external_auth external_auth;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct sta_opmode - Station's operation mode change event
|
||||||
|
* @addr: The station MAC address
|
||||||
|
* @smps_mode: SMPS mode of the station
|
||||||
|
* @chan_width: Channel width of the station
|
||||||
|
* @rx_nss: RX_NSS of the station
|
||||||
|
*
|
||||||
|
* This is used as data with EVENT_STATION_OPMODE_CHANGED.
|
||||||
|
*/
|
||||||
|
struct sta_opmode {
|
||||||
|
const u8 *addr;
|
||||||
|
enum smps_mode smps_mode;
|
||||||
|
enum chan_width chan_width;
|
||||||
|
u8 rx_nss;
|
||||||
|
} sta_opmode;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -84,6 +84,7 @@ const char * event_to_string(enum wpa_event_type event)
|
|||||||
E2S(DFS_PRE_CAC_EXPIRED);
|
E2S(DFS_PRE_CAC_EXPIRED);
|
||||||
E2S(EXTERNAL_AUTH);
|
E2S(EXTERNAL_AUTH);
|
||||||
E2S(PORT_AUTHORIZED);
|
E2S(PORT_AUTHORIZED);
|
||||||
|
E2S(STATION_OPMODE_CHANGED);
|
||||||
}
|
}
|
||||||
|
|
||||||
return "UNKNOWN";
|
return "UNKNOWN";
|
||||||
|
@ -132,6 +132,7 @@ static const char * nl80211_command_to_string(enum nl80211_commands cmd)
|
|||||||
C2S(NL80211_CMD_ADD_TX_TS)
|
C2S(NL80211_CMD_ADD_TX_TS)
|
||||||
C2S(NL80211_CMD_DEL_TX_TS)
|
C2S(NL80211_CMD_DEL_TX_TS)
|
||||||
C2S(NL80211_CMD_EXTERNAL_AUTH)
|
C2S(NL80211_CMD_EXTERNAL_AUTH)
|
||||||
|
C2S(NL80211_CMD_STA_OPMODE_CHANGED)
|
||||||
default:
|
default:
|
||||||
return "NL80211_CMD_UNKNOWN";
|
return "NL80211_CMD_UNKNOWN";
|
||||||
}
|
}
|
||||||
@ -2246,6 +2247,76 @@ static void nl80211_port_authorized(struct wpa_driver_nl80211_data *drv,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void nl80211_sta_opmode_change_event(struct wpa_driver_nl80211_data *drv,
|
||||||
|
struct nlattr **tb)
|
||||||
|
{
|
||||||
|
union wpa_event_data ed;
|
||||||
|
u8 smps_mode, max_bw;
|
||||||
|
|
||||||
|
if (!tb[NL80211_ATTR_MAC] ||
|
||||||
|
(!tb[NL80211_ATTR_CHANNEL_WIDTH] &&
|
||||||
|
!tb[NL80211_ATTR_SMPS_MODE] &&
|
||||||
|
!tb[NL80211_ATTR_NSS]))
|
||||||
|
return;
|
||||||
|
|
||||||
|
ed.sta_opmode.smps_mode = SMPS_INVALID;
|
||||||
|
ed.sta_opmode.chan_width = CHAN_WIDTH_UNKNOWN;
|
||||||
|
ed.sta_opmode.rx_nss = 0xff;
|
||||||
|
ed.sta_opmode.addr = nla_data(tb[NL80211_ATTR_MAC]);
|
||||||
|
|
||||||
|
if (tb[NL80211_ATTR_SMPS_MODE]) {
|
||||||
|
smps_mode = nla_get_u32(tb[NL80211_ATTR_SMPS_MODE]);
|
||||||
|
switch (smps_mode) {
|
||||||
|
case NL80211_SMPS_OFF:
|
||||||
|
ed.sta_opmode.smps_mode = SMPS_OFF;
|
||||||
|
break;
|
||||||
|
case NL80211_SMPS_STATIC:
|
||||||
|
ed.sta_opmode.smps_mode = SMPS_STATIC;
|
||||||
|
break;
|
||||||
|
case NL80211_SMPS_DYNAMIC:
|
||||||
|
ed.sta_opmode.smps_mode = SMPS_DYNAMIC;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ed.sta_opmode.smps_mode = SMPS_INVALID;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tb[NL80211_ATTR_CHANNEL_WIDTH]) {
|
||||||
|
max_bw = nla_get_u32(tb[NL80211_ATTR_CHANNEL_WIDTH]);
|
||||||
|
switch (max_bw) {
|
||||||
|
case NL80211_CHAN_WIDTH_20_NOHT:
|
||||||
|
ed.sta_opmode.chan_width = CHAN_WIDTH_20_NOHT;
|
||||||
|
break;
|
||||||
|
case NL80211_CHAN_WIDTH_20:
|
||||||
|
ed.sta_opmode.chan_width = CHAN_WIDTH_20;
|
||||||
|
break;
|
||||||
|
case NL80211_CHAN_WIDTH_40:
|
||||||
|
ed.sta_opmode.chan_width = CHAN_WIDTH_40;
|
||||||
|
break;
|
||||||
|
case NL80211_CHAN_WIDTH_80:
|
||||||
|
ed.sta_opmode.chan_width = CHAN_WIDTH_80;
|
||||||
|
break;
|
||||||
|
case NL80211_CHAN_WIDTH_80P80:
|
||||||
|
ed.sta_opmode.chan_width = CHAN_WIDTH_80P80;
|
||||||
|
break;
|
||||||
|
case NL80211_CHAN_WIDTH_160:
|
||||||
|
ed.sta_opmode.chan_width = CHAN_WIDTH_160;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ed.sta_opmode.chan_width = CHAN_WIDTH_UNKNOWN;
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tb[NL80211_ATTR_NSS])
|
||||||
|
ed.sta_opmode.rx_nss = nla_get_u8(tb[NL80211_ATTR_NSS]);
|
||||||
|
|
||||||
|
wpa_supplicant_event(drv->ctx, EVENT_STATION_OPMODE_CHANGED, &ed);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void do_process_drv_event(struct i802_bss *bss, int cmd,
|
static void do_process_drv_event(struct i802_bss *bss, int cmd,
|
||||||
struct nlattr **tb)
|
struct nlattr **tb)
|
||||||
{
|
{
|
||||||
@ -2447,6 +2518,9 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd,
|
|||||||
case NL80211_CMD_PORT_AUTHORIZED:
|
case NL80211_CMD_PORT_AUTHORIZED:
|
||||||
nl80211_port_authorized(drv, tb);
|
nl80211_port_authorized(drv, tb);
|
||||||
break;
|
break;
|
||||||
|
case NL80211_CMD_STA_OPMODE_CHANGED:
|
||||||
|
nl80211_sta_opmode_change_event(drv, tb);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Ignored unknown event "
|
wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Ignored unknown event "
|
||||||
"(cmd=%d)", cmd);
|
"(cmd=%d)", cmd);
|
||||||
|
Loading…
Reference in New Issue
Block a user