fragattacks: basic support for 40 MHz channels

This commit is contained in:
Mathy Vanhoef 2021-05-07 13:30:47 +04:00
parent ad423fbab1
commit 0b99805f78
7 changed files with 47 additions and 17 deletions

View File

@ -2572,18 +2572,16 @@ static int hostapd_get_gtk(struct hostapd_data *hapd, char *buf, size_t buflen)
static int hostapd_get_channel(struct hostapd_data *hapd, char *buf, size_t buflen) static int hostapd_get_channel(struct hostapd_data *hapd, char *buf, size_t buflen)
{ {
struct wpa_channel_info ci; struct wpa_channel_info ci;
u8 op_class, channel; int reply_len = -1;
if (hostapd_drv_channel_info(hapd, &ci) != 0 || if (hostapd_drv_channel_info(hapd, &ci) != 0 ||
ieee80211_chaninfo_to_channel(ci.frequency, ci.chanwidth, chaninfo_to_string(&ci, buf, buflen, &reply_len) < 0) {
ci.sec_channel, &op_class,
&channel) < 0) {
wpa_printf(MSG_WARNING, "Failed to get channel info from drive, falling " wpa_printf(MSG_WARNING, "Failed to get channel info from drive, falling "
"back to channel provided in the current config."); "back to channel provided in the current config.");
channel = hapd->iconf->channel; return os_snprintf(buf, buflen, "%d\n", hapd->iconf->channel);
} }
return os_snprintf(buf, buflen, "%d\n", channel); return reply_len;
} }

View File

@ -13,6 +13,10 @@ network={
# Might be useful in very noisy environments # Might be useful in very noisy environments
#disable_ht=1 #disable_ht=1
# Some network cards don't properly support injection on non-20MHz
# channels. In that case uncomment this line to disable 40 MHz.
#disable_ht40=1
} }
# WPA3 home network # WPA3 home network

View File

@ -825,19 +825,20 @@ class Daemon(metaclass=abc.ABCMeta):
def follow_channel(self): def follow_channel(self):
# We use GET_CHANNEL of wpa_s/hostapd because it's more reliable than get_channel, # We use GET_CHANNEL of wpa_s/hostapd because it's more reliable than get_channel,
# which can fail on certain devices such as the AWUS036ACH. # which can fail on certain devices such as the AWUS036ACH.
channel = int(self.wpaspy_command("GET_CHANNEL")) channel = self.wpaspy_command("GET_CHANNEL").strip()
if self.options.inject: if self.options.inject:
set_channel(self.nic_mon, channel)
log(STATUS, f"{self.nic_mon}: setting to channel {channel}") log(STATUS, f"{self.nic_mon}: setting to channel {channel}")
elif self.options.hwsim:
set_channel(self.nic_hwsim, channel)
set_channel(self.nic_mon, channel) set_channel(self.nic_mon, channel)
elif self.options.hwsim:
log(STATUS, f"{self.nic_hwsim}: setting to channel {channel}") log(STATUS, f"{self.nic_hwsim}: setting to channel {channel}")
log(STATUS, f"{self.nic_mon}: setting to channel {channel}") log(STATUS, f"{self.nic_mon}: setting to channel {channel}")
set_channel(self.nic_hwsim, channel)
set_channel(self.nic_mon, channel)
if self.options.inject_test != None and self.options.inject_test != "self": if self.options.inject_test != None and self.options.inject_test != "self":
set_channel(self.options.inject_test, channel) # FIXME: When using 40 MHz channel this call tends to fail the first time
log(STATUS, f"{self.options.inject_test}: setting to channel {channel}") log(STATUS, f"{self.options.inject_test}: setting to channel {channel}")
set_channel(self.options.inject_test, channel)
# When explicitly testing we can afford a longer timeout. Otherwise we should avoid it. # When explicitly testing we can afford a longer timeout. Otherwise we should avoid it.
time.sleep(0.5) time.sleep(0.5)

@ -1 +1 @@
Subproject commit 37b5f24658906023f7299a651ae2563595500431 Subproject commit 967494454578ffc22dea235055c440685f2afeaf

View File

@ -1159,6 +1159,30 @@ int ieee80211_chaninfo_to_channel(unsigned int freq, enum chan_width chanwidth,
} }
int chaninfo_to_string(struct wpa_channel_info *ci, char *buf, size_t buflen,
int *reply_len)
{
u8 op_class, channel;
if (ieee80211_chaninfo_to_channel(ci->frequency, ci->chanwidth,
ci->sec_channel, &op_class,
&channel) < 0)
return -1;
/* FIXME: Implement full support for all channels */
if (ci->chanwidth == CHAN_WIDTH_40) {
if (ci->sec_channel < 0)
*reply_len = os_snprintf(buf, buflen, "%d HT40-\n", channel);
else
*reply_len = os_snprintf(buf, buflen, "%d HT40+\n", channel);
} else {
*reply_len = os_snprintf(buf, buflen, "%d\n", channel);
}
return 0;
}
static const char *const us_op_class_cc[] = { static const char *const us_op_class_cc[] = {
"US", "CA", NULL "US", "CA", NULL
}; };

View File

@ -11,6 +11,7 @@
#include "defs.h" #include "defs.h"
#include "ieee802_11_defs.h" #include "ieee802_11_defs.h"
#include "drivers/driver.h"
struct element { struct element {
u8 id; u8 id;
@ -214,6 +215,8 @@ enum hostapd_hw_mode ieee80211_freq_to_channel_ext(unsigned int freq,
u8 *op_class, u8 *channel); u8 *op_class, u8 *channel);
int ieee80211_chaninfo_to_channel(unsigned int freq, enum chan_width chanwidth, int ieee80211_chaninfo_to_channel(unsigned int freq, enum chan_width chanwidth,
int sec_channel, u8 *op_class, u8 *channel); int sec_channel, u8 *op_class, u8 *channel);
int chaninfo_to_string(struct wpa_channel_info *ci, char *buf, size_t buflen,
int *reply_len);
int ieee80211_is_dfs(int freq, const struct hostapd_hw_modes *modes, int ieee80211_is_dfs(int freq, const struct hostapd_hw_modes *modes,
u16 num_modes); u16 num_modes);
enum phy_type ieee80211_get_phy_type(int freq, int ht, int vht); enum phy_type ieee80211_get_phy_type(int freq, int ht, int vht);

View File

@ -9774,20 +9774,20 @@ static int wpa_supplicant_ctrl_iface_get_channel(struct wpa_supplicant *wpa_s,
char *buf, size_t buflen) char *buf, size_t buflen)
{ {
struct wpa_channel_info ci; struct wpa_channel_info ci;
u8 op_class, channel; int reply_len = -1;
if (wpa_drv_channel_info(wpa_s, &ci) != 0 || if (wpa_drv_channel_info(wpa_s, &ci) != 0 ||
ieee80211_chaninfo_to_channel(ci.frequency, ci.chanwidth, chaninfo_to_string(&ci, buf, buflen, &reply_len) < 0) {
ci.sec_channel, &op_class, u8 op_class, channel;
&channel) < 0) {
wpa_printf(MSG_WARNING, "Failed to get channel info from drive, falling " wpa_printf(MSG_WARNING, "Failed to get channel info from drive, falling "
"back to channel provided in the current config. assoc_freq=%d", wpa_s->assoc_freq); "back to channel provided in the current config. assoc_freq=%d", wpa_s->assoc_freq);
if (ieee80211_chaninfo_to_channel(wpa_s->assoc_freq, CHAN_WIDTH_20, 0, if (ieee80211_chaninfo_to_channel(wpa_s->assoc_freq, CHAN_WIDTH_20, 0,
&op_class, &channel) < 0) &op_class, &channel) < 0)
return -1; return -1;
return os_snprintf(buf, buflen, "%d\n", channel);
} }
return os_snprintf(buf, buflen, "%d\n", channel); return reply_len;
} }