}
+static const char * wps_event_fail_reason[NUM_WPS_EI_VALUES] = {
+ "No Error", /* WPS_EI_NO_ERROR */
+ "TKIP Only Prohibited", /* WPS_EI_SECURITY_TKIP_ONLY_PROHIBITED */
+ "WEP Prohibited" /* WPS_EI_SECURITY_WEP_PROHIBITED */
+};
+
static void hostapd_wps_event_fail(struct hostapd_data *hapd,
struct wps_event_fail *fail)
{
- wpa_msg(hapd->msg_ctx, MSG_INFO,
- WPS_EVENT_FAIL "msg=%d config_error=%d",
- fail->msg, fail->config_error);
+ if (fail->error_indication > 0 &&
+ fail->error_indication < NUM_WPS_EI_VALUES) {
+ wpa_msg(hapd->msg_ctx, MSG_INFO,
+ WPS_EVENT_FAIL "msg=%d config_error=%d reason=%d (%s)",
+ fail->msg, fail->config_error, fail->error_indication,
+ wps_event_fail_reason[fail->error_indication]);
+ } else {
+ wpa_msg(hapd->msg_ctx, MSG_INFO,
+ WPS_EVENT_FAIL "msg=%d config_error=%d",
+ fail->msg, fail->config_error);
+ }
}
struct wps_event_fail {
int msg;
u16 config_error;
+ u16 error_indication;
} fail;
struct wps_event_pwd_auth_fail {
void wps_fail_event(struct wps_context *wps, enum wps_msg_type msg,
- u16 config_error)
+ u16 config_error, u16 error_indication)
{
union wps_event_data data;
os_memset(&data, 0, sizeof(data));
data.fail.msg = msg;
data.fail.config_error = config_error;
+ data.fail.error_indication = error_indication;
wps->event_cb(wps->cb_ctx, WPS_EV_FAIL, &data);
}
WPS_CFG_DEV_PASSWORD_AUTH_FAILURE = 18
};
+/* Vendor specific Error Indication for WPS event messages */
+enum wps_error_indication {
+ WPS_EI_NO_ERROR,
+ WPS_EI_SECURITY_TKIP_ONLY_PROHIBITED,
+ WPS_EI_SECURITY_WEP_PROHIBITED,
+ NUM_WPS_EI_VALUES
+};
+
/* RF Bands */
#define WPS_RF_24GHZ 0x01
#define WPS_RF_50GHZ 0x02
if (wps->cred.encr_type & WPS_ENCR_WEP) {
wpa_printf(MSG_INFO, "WPS: Reject Credential "
"due to WEP configuration");
+ wps->error_indication = WPS_EI_SECURITY_WEP_PROHIBITED;
return -2;
}
if (cred.encr_type & WPS_ENCR_WEP) {
wpa_printf(MSG_INFO, "WPS: Reject new AP settings "
"due to WEP configuration");
+ wps->error_indication = WPS_EI_SECURITY_WEP_PROHIBITED;
return -1;
}
WPS_AUTH_WPAPSK) {
wpa_printf(MSG_INFO, "WPS-STRICT: Invalid WSC 2.0 "
"AP Settings: WPA-Personal/TKIP only");
+ wps->error_indication =
+ WPS_EI_SECURITY_TKIP_ONLY_PROHIBITED;
return -1;
}
}
return WPS_FAILURE;
ret = wps_process_m4(wps, msg, &attr);
if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
- wps_fail_event(wps->wps, WPS_M4, wps->config_error);
+ wps_fail_event(wps->wps, WPS_M4, wps->config_error,
+ wps->error_indication);
break;
case WPS_M6:
if (wps_validate_m6(msg) < 0)
return WPS_FAILURE;
ret = wps_process_m6(wps, msg, &attr);
if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
- wps_fail_event(wps->wps, WPS_M6, wps->config_error);
+ wps_fail_event(wps->wps, WPS_M6, wps->config_error,
+ wps->error_indication);
break;
case WPS_M8:
if (wps_validate_m8(msg) < 0)
return WPS_FAILURE;
ret = wps_process_m8(wps, msg, &attr);
if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
- wps_fail_event(wps->wps, WPS_M8, wps->config_error);
+ wps_fail_event(wps->wps, WPS_M8, wps->config_error,
+ wps->error_indication);
break;
default:
wpa_printf(MSG_DEBUG, "WPS: Unsupported Message Type %d",
switch (wps->state) {
case RECV_M4:
- wps_fail_event(wps->wps, WPS_M3, config_error);
+ wps_fail_event(wps->wps, WPS_M3, config_error,
+ wps->error_indication);
break;
case RECV_M6:
- wps_fail_event(wps->wps, WPS_M5, config_error);
+ wps_fail_event(wps->wps, WPS_M5, config_error,
+ wps->error_indication);
break;
case RECV_M8:
- wps_fail_event(wps->wps, WPS_M7, config_error);
+ wps_fail_event(wps->wps, WPS_M7, config_error,
+ wps->error_indication);
break;
default:
break;
* config_error - Configuration Error value to be used in NACK
*/
u16 config_error;
+ u16 error_indication;
int ext_reg;
int int_reg;
struct wpabuf * wps_decrypt_encr_settings(struct wps_data *wps, const u8 *encr,
size_t encr_len);
void wps_fail_event(struct wps_context *wps, enum wps_msg_type msg,
- u16 config_error);
+ u16 config_error, u16 error_indication);
void wps_success_event(struct wps_context *wps);
void wps_pwd_auth_fail_event(struct wps_context *wps, int enrollee, int part);
void wps_pbc_overlap_event(struct wps_context *wps);
return WPS_FAILURE;
ret = wps_process_m3(wps, msg, &attr);
if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
- wps_fail_event(wps->wps, WPS_M3, wps->config_error);
+ wps_fail_event(wps->wps, WPS_M3, wps->config_error,
+ wps->error_indication);
break;
case WPS_M5:
if (wps_validate_m5(msg) < 0)
return WPS_FAILURE;
ret = wps_process_m5(wps, msg, &attr);
if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
- wps_fail_event(wps->wps, WPS_M5, wps->config_error);
+ wps_fail_event(wps->wps, WPS_M5, wps->config_error,
+ wps->error_indication);
break;
case WPS_M7:
if (wps_validate_m7(msg) < 0)
return WPS_FAILURE;
ret = wps_process_m7(wps, msg, &attr);
if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
- wps_fail_event(wps->wps, WPS_M7, wps->config_error);
+ wps_fail_event(wps->wps, WPS_M7, wps->config_error,
+ wps->error_indication);
break;
default:
wpa_printf(MSG_DEBUG, "WPS: Unsupported Message Type %d",
switch (old_state) {
case RECV_M3:
- wps_fail_event(wps->wps, WPS_M2, config_error);
+ wps_fail_event(wps->wps, WPS_M2, config_error,
+ wps->error_indication);
break;
case RECV_M5:
- wps_fail_event(wps->wps, WPS_M4, config_error);
+ wps_fail_event(wps->wps, WPS_M4, config_error,
+ wps->error_indication);
break;
case RECV_M7:
- wps_fail_event(wps->wps, WPS_M6, config_error);
+ wps_fail_event(wps->wps, WPS_M6, config_error,
+ wps->error_indication);
break;
case RECV_DONE:
- wps_fail_event(wps->wps, WPS_M8, config_error);
+ wps_fail_event(wps->wps, WPS_M8, config_error,
+ wps->error_indication);
break;
default:
break;
if (ret == WPS_FAILURE) {
wps->state = SEND_WSC_NACK;
wps_fail_event(wps->wps, WPS_WSC_DONE,
- wps->config_error);
+ wps->config_error,
+ wps->error_indication);
}
return ret;
default:
}
+static const char * wps_event_fail_reason[NUM_WPS_EI_VALUES] = {
+ "No Error", /* WPS_EI_NO_ERROR */
+ "TKIP Only Prohibited", /* WPS_EI_SECURITY_TKIP_ONLY_PROHIBITED */
+ "WEP Prohibited" /* WPS_EI_SECURITY_WEP_PROHIBITED */
+};
+
static void wpa_supplicant_wps_event_fail(struct wpa_supplicant *wpa_s,
struct wps_event_fail *fail)
{
- wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_FAIL "msg=%d config_error=%d",
- fail->msg, fail->config_error);
- if (wpa_s->parent && wpa_s->parent != wpa_s)
- wpa_msg(wpa_s->parent, MSG_INFO, WPS_EVENT_FAIL
- "msg=%d config_error=%d",
+ if (fail->error_indication > 0 &&
+ fail->error_indication < NUM_WPS_EI_VALUES) {
+ wpa_msg(wpa_s, MSG_INFO,
+ WPS_EVENT_FAIL "msg=%d config_error=%d reason=%d (%s)",
+ fail->msg, fail->config_error, fail->error_indication,
+ wps_event_fail_reason[fail->error_indication]);
+ if (wpa_s->parent && wpa_s->parent != wpa_s)
+ wpa_msg(wpa_s->parent, MSG_INFO, WPS_EVENT_FAIL
+ "msg=%d config_error=%d reason=%d (%s)",
+ fail->msg, fail->config_error,
+ fail->error_indication,
+ wps_event_fail_reason[fail->error_indication]);
+ } else {
+ wpa_msg(wpa_s, MSG_INFO,
+ WPS_EVENT_FAIL "msg=%d config_error=%d",
fail->msg, fail->config_error);
+ if (wpa_s->parent && wpa_s->parent != wpa_s)
+ wpa_msg(wpa_s->parent, MSG_INFO, WPS_EVENT_FAIL
+ "msg=%d config_error=%d",
+ fail->msg, fail->config_error);
+ }
wpas_clear_wps(wpa_s);
wpas_notify_wps_event_fail(wpa_s, fail);
}