diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c index 75db754bb..d2e264278 100644 --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c @@ -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) { struct wpa_channel_info ci; - u8 op_class, channel; + int reply_len = -1; if (hostapd_drv_channel_info(hapd, &ci) != 0 || - ieee80211_chaninfo_to_channel(ci.frequency, ci.chanwidth, - ci.sec_channel, &op_class, - &channel) < 0) { + chaninfo_to_string(&ci, buf, buflen, &reply_len) < 0) { wpa_printf(MSG_WARNING, "Failed to get channel info from drive, falling " "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; } diff --git a/research/client.conf b/research/client.conf index 8ba01fbd7..d551a9463 100644 --- a/research/client.conf +++ b/research/client.conf @@ -13,6 +13,10 @@ network={ # Might be useful in very noisy environments #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 diff --git a/research/fraginternals.py b/research/fraginternals.py index 46faaff0c..8f01686e3 100644 --- a/research/fraginternals.py +++ b/research/fraginternals.py @@ -825,19 +825,20 @@ class Daemon(metaclass=abc.ABCMeta): def follow_channel(self): # 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. - channel = int(self.wpaspy_command("GET_CHANNEL")) + channel = self.wpaspy_command("GET_CHANNEL").strip() if self.options.inject: - set_channel(self.nic_mon, 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) + elif self.options.hwsim: log(STATUS, f"{self.nic_hwsim}: 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": - 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}") + set_channel(self.options.inject_test, channel) # When explicitly testing we can afford a longer timeout. Otherwise we should avoid it. time.sleep(0.5) diff --git a/research/libwifi b/research/libwifi index 37b5f2465..967494454 160000 --- a/research/libwifi +++ b/research/libwifi @@ -1 +1 @@ -Subproject commit 37b5f24658906023f7299a651ae2563595500431 +Subproject commit 967494454578ffc22dea235055c440685f2afeaf diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c index c90e04ce7..db503d33d 100644 --- a/src/common/ieee802_11_common.c +++ b/src/common/ieee802_11_common.c @@ -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[] = { "US", "CA", NULL }; diff --git a/src/common/ieee802_11_common.h b/src/common/ieee802_11_common.h index 6bbe3b7a3..293c1abdc 100644 --- a/src/common/ieee802_11_common.h +++ b/src/common/ieee802_11_common.h @@ -11,6 +11,7 @@ #include "defs.h" #include "ieee802_11_defs.h" +#include "drivers/driver.h" struct element { u8 id; @@ -214,6 +215,8 @@ enum hostapd_hw_mode ieee80211_freq_to_channel_ext(unsigned int freq, u8 *op_class, u8 *channel); int ieee80211_chaninfo_to_channel(unsigned int freq, enum chan_width chanwidth, 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, u16 num_modes); enum phy_type ieee80211_get_phy_type(int freq, int ht, int vht); diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 866a924b5..40d7a5eb0 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -9774,20 +9774,20 @@ static int wpa_supplicant_ctrl_iface_get_channel(struct wpa_supplicant *wpa_s, char *buf, size_t buflen) { struct wpa_channel_info ci; - u8 op_class, channel; + int reply_len = -1; if (wpa_drv_channel_info(wpa_s, &ci) != 0 || - ieee80211_chaninfo_to_channel(ci.frequency, ci.chanwidth, - ci.sec_channel, &op_class, - &channel) < 0) { + chaninfo_to_string(&ci, buf, buflen, &reply_len) < 0) { + u8 op_class, channel; 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); if (ieee80211_chaninfo_to_channel(wpa_s->assoc_freq, CHAN_WIDTH_20, 0, &op_class, &channel) < 0) return -1; + return os_snprintf(buf, buflen, "%d\n", channel); } - return os_snprintf(buf, buflen, "%d\n", channel); + return reply_len; }