OCV: Use more granular error codes for OCI validation failures

Enhance the return values of ocv_verify_tx_params with enum to indicate
different OCI verification failures to caller.

Signed-off-by: Veerendranath Jakkam <vjakkam@codeaurora.org>
This commit is contained in:
Veerendranath Jakkam 2020-09-03 00:25:28 +05:30 committed by Jouni Malinen
parent 10c3e58b27
commit 5ecb45a41c
12 changed files with 40 additions and 27 deletions

View file

@ -3563,7 +3563,8 @@ static int check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta,
return WLAN_STATUS_UNSPECIFIED_FAILURE;
if (ocv_verify_tx_params(elems.oci, elems.oci_len, &ci,
tx_chanwidth, tx_seg1_idx) != 0) {
tx_chanwidth, tx_seg1_idx) !=
OCI_SUCCESS) {
wpa_printf(MSG_WARNING, "FILS: OCV failed: %s",
ocv_errorstr);
wpa_msg(hapd->msg_ctx, MSG_INFO, OCV_FAILURE "addr="

View file

@ -275,7 +275,8 @@ void ieee802_11_sa_query_action(struct hostapd_data *hapd,
return;
if (ocv_verify_tx_params(elems.oci, elems.oci_len, &ci,
tx_chanwidth, tx_seg1_idx) != 0) {
tx_chanwidth, tx_seg1_idx) !=
OCI_SUCCESS) {
wpa_msg(hapd->msg_ctx, MSG_INFO, OCV_FAILURE "addr="
MACSTR " frame=saquery%s error=%s",
MAC2STR(sa),

View file

@ -326,7 +326,7 @@ static void ieee802_11_rx_wnmsleep_req(struct hostapd_data *hapd,
if (ocv_verify_tx_params(oci_ie, oci_ie_len, &ci,
channel_width_to_int(ci.chanwidth),
ci.seg1_idx) != 0) {
ci.seg1_idx) != OCI_SUCCESS) {
wpa_msg(hapd, MSG_WARNING, "WNM: OCV failed: %s",
ocv_errorstr);
return;

View file

@ -3051,7 +3051,8 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
return;
if (ocv_verify_tx_params(kde.oci, kde.oci_len, &ci,
tx_chanwidth, tx_seg1_idx) != 0) {
tx_chanwidth, tx_seg1_idx) !=
OCI_SUCCESS) {
wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO,
"OCV failed: %s", ocv_errorstr);
if (wpa_auth->conf.msg_ctx)
@ -3913,7 +3914,8 @@ SM_STATE(WPA_PTK_GROUP, REKEYESTABLISHED)
return;
if (ocv_verify_tx_params(kde.oci, kde.oci_len, &ci,
tx_chanwidth, tx_seg1_idx) != 0) {
tx_chanwidth, tx_seg1_idx) !=
OCI_SUCCESS) {
wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO,
"OCV failed: %s", ocv_errorstr);
if (wpa_auth->conf.msg_ctx)

View file

@ -3519,7 +3519,8 @@ int wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies,
return WLAN_STATUS_UNSPECIFIED_FAILURE;
if (ocv_verify_tx_params(parse.oci, parse.oci_len, &ci,
tx_chanwidth, tx_seg1_idx) != 0) {
tx_chanwidth, tx_seg1_idx) !=
OCI_SUCCESS) {
wpa_printf(MSG_WARNING, "OCV failed: %s", ocv_errorstr);
if (sm->wpa_auth->conf.msg_ctx)
wpa_msg(sm->wpa_auth->conf.msg_ctx, MSG_INFO,

View file

@ -95,23 +95,24 @@ int ocv_insert_extended_oci(struct wpa_channel_info *ci, u8 *pos)
}
int ocv_verify_tx_params(const u8 *oci_ie, size_t oci_ie_len,
struct wpa_channel_info *ci, int tx_chanwidth,
int tx_seg1_idx)
enum oci_verify_result
ocv_verify_tx_params(const u8 *oci_ie, size_t oci_ie_len,
struct wpa_channel_info *ci, int tx_chanwidth,
int tx_seg1_idx)
{
struct oci_info oci;
if (!oci_ie) {
os_snprintf(ocv_errorstr, sizeof(ocv_errorstr),
"did not receive mandatory OCI");
return -1;
return OCI_NOT_FOUND;
}
if (oci_ie_len != 3) {
os_snprintf(ocv_errorstr, sizeof(ocv_errorstr),
"received OCI of unexpected length (%d)",
(int) oci_ie_len);
return -1;
return OCI_INVALID_LENGTH;
}
os_memset(&oci, 0, sizeof(oci));
@ -121,7 +122,7 @@ int ocv_verify_tx_params(const u8 *oci_ie, size_t oci_ie_len,
if (ocv_derive_all_parameters(&oci) != 0) {
os_snprintf(ocv_errorstr, sizeof(ocv_errorstr),
"unable to interpret received OCI");
return -1;
return OCI_PARSE_ERROR;
}
/* Primary frequency used to send frames to STA must match the STA's */
@ -129,7 +130,7 @@ int ocv_verify_tx_params(const u8 *oci_ie, size_t oci_ie_len,
os_snprintf(ocv_errorstr, sizeof(ocv_errorstr),
"primary channel mismatch in received OCI (we use %d but receiver is using %d)",
ci->frequency, oci.freq);
return -1;
return OCI_PRIMARY_FREQ_MISMATCH;
}
/* We shouldn't transmit with a higher bandwidth than the STA supports
@ -138,7 +139,7 @@ int ocv_verify_tx_params(const u8 *oci_ie, size_t oci_ie_len,
os_snprintf(ocv_errorstr, sizeof(ocv_errorstr),
"channel bandwidth mismatch in received OCI (we use %d but receiver only supports %d)",
tx_chanwidth, oci.chanwidth);
return -1;
return OCI_CHANNEL_WIDTH_MISMATCH;
}
/*
@ -152,7 +153,7 @@ int ocv_verify_tx_params(const u8 *oci_ie, size_t oci_ie_len,
os_snprintf(ocv_errorstr, sizeof(ocv_errorstr),
"secondary channel mismatch in received OCI (we use %d but receiver is using %d)",
ci->sec_channel, oci.sec_channel);
return -1;
return OCI_SECONDARY_FREQ_MISMATCH;
}
/*
@ -165,8 +166,8 @@ int ocv_verify_tx_params(const u8 *oci_ie, size_t oci_ie_len,
os_snprintf(ocv_errorstr, sizeof(ocv_errorstr),
"frequency segment 1 mismatch in received OCI (we use %d but receiver is using %d)",
tx_seg1_idx, oci.seg1_idx);
return -1;
return OCI_SEG_1_INDEX_MISMATCH;
}
return 0;
return OCI_SUCCESS;
}

View file

@ -27,14 +27,21 @@ struct oci_info {
#define OCV_OCI_EXTENDED_LEN (3 + OCV_OCI_LEN)
#define OCV_OCI_KDE_LEN (2 + RSN_SELECTOR_LEN + OCV_OCI_LEN)
enum oci_verify_result {
OCI_SUCCESS, OCI_NOT_FOUND, OCI_INVALID_LENGTH, OCI_PARSE_ERROR,
OCI_PRIMARY_FREQ_MISMATCH, OCI_CHANNEL_WIDTH_MISMATCH,
OCI_SECONDARY_FREQ_MISMATCH, OCI_SEG_1_INDEX_MISMATCH
};
extern char ocv_errorstr[256];
int ocv_derive_all_parameters(struct oci_info *oci);
int ocv_insert_oci(struct wpa_channel_info *ci, u8 **argpos);
int ocv_insert_oci_kde(struct wpa_channel_info *ci, u8 **argpos);
int ocv_insert_extended_oci(struct wpa_channel_info *ci, u8 *pos);
int ocv_verify_tx_params(const u8 *oci_ie, size_t oci_ie_len,
struct wpa_channel_info *ci, int tx_chanwidth,
int tx_seg1_idx);
enum oci_verify_result
ocv_verify_tx_params(const u8 *oci_ie, size_t oci_ie_len,
struct wpa_channel_info *ci, int tx_chanwidth,
int tx_seg1_idx);
#endif /* OCV_H */

View file

@ -1717,7 +1717,7 @@ static void wpa_supplicant_process_3_of_4(struct wpa_sm *sm,
if (ocv_verify_tx_params(ie.oci, ie.oci_len, &ci,
channel_width_to_int(ci.chanwidth),
ci.seg1_idx) != 0) {
ci.seg1_idx) != OCI_SUCCESS) {
wpa_msg(sm->ctx->msg_ctx, MSG_INFO, OCV_FAILURE
"addr=" MACSTR " frame=eapol-key-m3 error=%s",
MAC2STR(sm->bssid), ocv_errorstr);
@ -1865,7 +1865,7 @@ static int wpa_supplicant_process_1_of_2_rsn(struct wpa_sm *sm,
if (ocv_verify_tx_params(ie.oci, ie.oci_len, &ci,
channel_width_to_int(ci.chanwidth),
ci.seg1_idx) != 0) {
ci.seg1_idx) != OCI_SUCCESS) {
wpa_msg(sm->ctx->msg_ctx, MSG_INFO, OCV_FAILURE
"addr=" MACSTR " frame=eapol-key-g1 error=%s",
MAC2STR(sm->bssid), ocv_errorstr);
@ -4799,7 +4799,7 @@ int fils_process_assoc_resp(struct wpa_sm *sm, const u8 *resp, size_t len)
if (ocv_verify_tx_params(elems.oci, elems.oci_len, &ci,
channel_width_to_int(ci.chanwidth),
ci.seg1_idx) != 0) {
ci.seg1_idx) != OCI_SUCCESS) {
wpa_msg(sm->ctx->msg_ctx, MSG_INFO, OCV_FAILURE
"addr=" MACSTR " frame=fils-assoc error=%s",
MAC2STR(sm->bssid), ocv_errorstr);

View file

@ -1167,7 +1167,7 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies,
if (ocv_verify_tx_params(parse.oci, parse.oci_len, &ci,
channel_width_to_int(ci.chanwidth),
ci.seg1_idx) != 0) {
ci.seg1_idx) != OCI_SUCCESS) {
wpa_msg(sm->ctx->msg_ctx, MSG_INFO, OCV_FAILURE
"addr=" MACSTR " frame=ft-assoc error=%s",
MAC2STR(sm->bssid), ocv_errorstr);

View file

@ -1292,7 +1292,7 @@ void mesh_mpm_action_rx(struct wpa_supplicant *wpa_s,
if (ocv_verify_tx_params(elems.oci, elems.oci_len, &ci,
tx_chanwidth, tx_seg1_idx) !=
0) {
OCI_SUCCESS) {
wpa_printf(MSG_WARNING, "MPM: OCV failed: %s",
ocv_errorstr);
return;

View file

@ -2915,7 +2915,7 @@ void sme_sa_query_rx(struct wpa_supplicant *wpa_s, const u8 *sa,
if (ocv_verify_tx_params(elems.oci, elems.oci_len, &ci,
channel_width_to_int(ci.chanwidth),
ci.seg1_idx) != 0) {
ci.seg1_idx) != OCI_SUCCESS) {
wpa_msg(wpa_s, MSG_INFO, OCV_FAILURE "addr=" MACSTR
" frame=saquery%s error=%s",
MAC2STR(sa), data[0] == WLAN_SA_QUERY_REQUEST ?

View file

@ -383,7 +383,7 @@ static void ieee802_11_rx_wnmsleep_resp(struct wpa_supplicant *wpa_s,
if (ocv_verify_tx_params(oci_ie, oci_ie_len, &ci,
channel_width_to_int(ci.chanwidth),
ci.seg1_idx) != 0) {
ci.seg1_idx) != OCI_SUCCESS) {
wpa_msg(wpa_s, MSG_WARNING, "WNM: OCV failed: %s",
ocv_errorstr);
return;