Implement channel sanity check for hostapd_cli chan_switch command. Verify provided values for bandwidth, frequencies, and secondary channel offset. Reject requested channel switch operation if basic constraints on frequencies and bandwidth are not fulfilled. Signed-off-by: Sergey Matyukevich <sergey.matyukevich.os@xxxxxxxxxxxxx> --- hostapd/ctrl_iface.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c index 090d4f0f6..4ea22e3d2 100644 --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c @@ -2390,6 +2390,113 @@ static int hostapd_ctrl_resend_group_m1(struct hostapd_data *hapd, #endif /* CONFIG_TESTING_OPTIONS */ +static int hostapd_ctrl_check_freq_params(struct hostapd_freq_params *params) +{ + switch (params->bandwidth) { + case 0: + /* bandwidth not specified: use 20MHz by default */ + /* fall-through */ + case 20: + if (params->center_freq1 && + params->center_freq1 != params->freq) + return 1; + + if (params->center_freq2) + return 1; + + if (params->sec_channel_offset) + return 1; + break; + case 40: + if (!params->center_freq1) + return 1; + + if (params->center_freq2) + return 1; + + if (!params->sec_channel_offset) + return 1; + + switch(params->sec_channel_offset) { + case 1: + if (params->freq + 10 != params->center_freq1) + return 1; + break; + case -1: + if (params->freq - 10 != params->center_freq1) + return 1; + break; + default: + return 1; + } + + break; + case 80: + if (!params->center_freq1) + return 1; + + if (!params->sec_channel_offset) + return 1; + + switch(params->sec_channel_offset) { + case 1: + if ((params->freq - 10 != params->center_freq1) && + (params->freq + 30 != params->center_freq1)) + return 1; + break; + case -1: + if ((params->freq + 10 != params->center_freq1) && + (params->freq - 30 != params->center_freq1)) + return 1; + break; + default: + return 1; + } + + /* adjacent and overlapped are not allowed for 80+80 */ + if (params->center_freq2) { + if (params->center_freq1 - params->center_freq2 <= 80 && + params->center_freq2 - params->center_freq1 <= 80) + return 1; + } + + break; + case 160: + if (!params->center_freq1) + return 1; + + if (params->center_freq2) + return 1; + + if (!params->sec_channel_offset) + return 1; + + switch(params->sec_channel_offset) { + case 1: + if ((params->freq + 70 != params->center_freq1) && + (params->freq + 30 != params->center_freq1) && + (params->freq - 10 != params->center_freq1) && + (params->freq - 50 != params->center_freq1)) + return 1; + break; + case -1: + if ((params->freq + 50 != params->center_freq1) && + (params->freq + 10 != params->center_freq1) && + (params->freq - 30 != params->center_freq1) && + (params->freq - 70 != params->center_freq1)) + return 1; + break; + default: + return 1; + } + + break; + default: + return 1; + } + + return 0; +} static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface, char *pos) @@ -2403,6 +2510,12 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface, if (ret) return ret; + ret = hostapd_ctrl_check_freq_params(&settings.freq_params); + if (ret) { + wpa_printf(MSG_ERROR, "chanswitch: invalid frequency settings provided"); + return ret; + } + for (i = 0; i < iface->num_bss; i++) { /* Save CHAN_SWITCH VHT config */ -- 2.11.0 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap