X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=wpa_supplicant%2Fctrl_iface.c;h=d814fdf7fd2d4e46cfae369967152e5c39f60e49;hb=746e5c2565e28a8659052e63012647bda4cc6443;hp=3c97819e24c9d0c09aba543c41d6bdb3f4e6e715;hpb=cf667c66aceb796da6c5ee952a140cd7b009b9cc;p=mech_eap.git diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 3c97819..d814fdf 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -15,6 +15,7 @@ #include "utils/common.h" #include "utils/eloop.h" #include "utils/uuid.h" +#include "utils/module_tests.h" #include "common/version.h" #include "common/ieee802_11_defs.h" #include "common/ieee802_11_common.h" @@ -420,7 +421,6 @@ static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s, #ifdef CONFIG_TDLS #ifdef CONFIG_TDLS_TESTING } else if (os_strcasecmp(cmd, "tdls_testing") == 0) { - extern unsigned int tdls_testing; tdls_testing = strtol(value, NULL, 0); wpa_printf(MSG_DEBUG, "TDLS: tdls_testing=0x%x", tdls_testing); #endif /* CONFIG_TDLS_TESTING */ @@ -511,6 +511,12 @@ static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s, wpa_s->test_failure = atoi(value); } else if (os_strcasecmp(cmd, "p2p_go_csa_on_inv") == 0) { wpa_s->p2p_go_csa_on_inv = !!atoi(value); + } else if (os_strcasecmp(cmd, "ignore_auth_resp") == 0) { + wpa_s->ignore_auth_resp = !!atoi(value); + } else if (os_strcasecmp(cmd, "ignore_assoc_disallow") == 0) { + wpa_s->ignore_assoc_disallow = !!atoi(value); + } else if (os_strcasecmp(cmd, "reject_btm_req_reason") == 0) { + wpa_s->reject_btm_req_reason = atoi(value); #endif /* CONFIG_TESTING_OPTIONS */ #ifndef CONFIG_NO_CONFIG_BLOBS } else if (os_strcmp(cmd, "blob") == 0) { @@ -1886,6 +1892,10 @@ static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s, "mode=P2P GO - group " "formation\n"); break; + case WPAS_MODE_MESH: + ret = os_snprintf(pos, end - pos, + "mode=mesh\n"); + break; default: ret = 0; break; @@ -2919,15 +2929,10 @@ static int wpa_supplicant_ctrl_iface_add_network( wpa_printf(MSG_DEBUG, "CTRL_IFACE: ADD_NETWORK"); - ssid = wpa_config_add_network(wpa_s->conf); + ssid = wpa_supplicant_add_network(wpa_s); if (ssid == NULL) return -1; - wpas_notify_network_added(wpa_s, ssid); - - ssid->disabled = 1; - wpa_config_set_network_defaults(ssid); - ret = os_snprintf(buf, buflen, "%d\n", ssid->id); if (os_snprintf_error(buflen, ret)) return -1; @@ -2940,7 +2945,7 @@ static int wpa_supplicant_ctrl_iface_remove_network( { int id; struct wpa_ssid *ssid; - int was_disabled; + int result; /* cmd: "" or "all" */ if (os_strcmp(cmd, "all") == 0) { @@ -2976,54 +2981,17 @@ static int wpa_supplicant_ctrl_iface_remove_network( id = atoi(cmd); wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_NETWORK id=%d", id); - ssid = wpa_config_get_network(wpa_s->conf, id); - if (ssid) - wpas_notify_network_removed(wpa_s, ssid); - if (ssid == NULL) { + result = wpa_supplicant_remove_network(wpa_s, id); + if (result == -1) { wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network " "id=%d", id); return -1; } - - if (wpa_s->last_ssid == ssid) - wpa_s->last_ssid = NULL; - - if (ssid == wpa_s->current_ssid || wpa_s->current_ssid == NULL) { -#ifdef CONFIG_SME - wpa_s->sme.prev_bssid_set = 0; -#endif /* CONFIG_SME */ - /* - * Invalidate the EAP session cache if the current or - * previously used network is removed. - */ - eapol_sm_invalidate_cached_session(wpa_s->eapol); - } - - if (ssid == wpa_s->current_ssid) { - wpa_sm_set_config(wpa_s->wpa, NULL); - eapol_sm_notify_config(wpa_s->eapol, NULL, NULL); - - if (wpa_s->wpa_state >= WPA_AUTHENTICATING) - wpa_s->own_disconnect_req = 1; - wpa_supplicant_deauthenticate(wpa_s, - WLAN_REASON_DEAUTH_LEAVING); - } - - was_disabled = ssid->disabled; - - if (wpa_config_remove_network(wpa_s->conf, id) < 0) { + if (result == -2) { wpa_printf(MSG_DEBUG, "CTRL_IFACE: Not able to remove the " "network id=%d", id); return -1; } - - if (!was_disabled && wpa_s->sched_scanning) { - wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan to remove " - "network from filters"); - wpa_supplicant_cancel_sched_scan(wpa_s); - wpa_supplicant_req_scan(wpa_s, 0, 0); - } - return 0; } @@ -4298,9 +4266,10 @@ static int print_bss_info(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, if (mask & WPA_BSS_MASK_P2P_SCAN) { ie = (const u8 *) (bss + 1); ret = wpas_p2p_scan_result_text(ie, bss->ie_len, pos, end); - if (ret < 0 || ret >= end - pos) + if (ret >= end - pos) return 0; - pos += ret; + if (ret > 0) + pos += ret; } #endif /* CONFIG_P2P */ @@ -4381,9 +4350,10 @@ static int print_bss_info(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, if (mask & WPA_BSS_MASK_MESH_SCAN) { ie = (const u8 *) (bss + 1); ret = wpas_mesh_scan_result_text(ie, bss->ie_len, pos, end); - if (ret < 0 || ret >= end - pos) + if (ret >= end - pos) return 0; - pos += ret; + if (ret > 0) + pos += ret; } #endif /* CONFIG_MESH */ @@ -5098,6 +5068,8 @@ static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd, wps_method = WPS_PIN_DISPLAY; } else if (os_strncmp(pos, "pbc", 3) == 0) { wps_method = WPS_PBC; + } else if (os_strstr(pos, "p2ps") != NULL) { + wps_method = WPS_P2PS; } else { pin = pos; pos = os_strchr(pin, ' '); @@ -5106,8 +5078,6 @@ static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd, *pos++ = '\0'; if (os_strncmp(pos, "display", 7) == 0) wps_method = WPS_PIN_DISPLAY; - else if (os_strncmp(pos, "p2ps", 4) == 0) - wps_method = WPS_P2PS; } if (!wps_pin_str_valid(pin)) { os_memcpy(buf, "FAIL-INVALID-PIN\n", 17); @@ -5834,6 +5804,29 @@ static int p2p_ctrl_group_add(struct wpa_supplicant *wpa_s, char *cmd) } +static int p2p_ctrl_group_member(struct wpa_supplicant *wpa_s, const char *cmd, + char *buf, size_t buflen) +{ + u8 dev_addr[ETH_ALEN]; + struct wpa_ssid *ssid; + int res; + const u8 *iaddr; + + ssid = wpa_s->current_ssid; + if (!wpa_s->global->p2p || !ssid || ssid->mode != WPAS_MODE_P2P_GO || + hwaddr_aton(cmd, dev_addr)) + return -1; + + iaddr = p2p_group_get_client_interface_addr(wpa_s->p2p_group, dev_addr); + if (!iaddr) + return -1; + res = os_snprintf(buf, buflen, MACSTR, MAC2STR(iaddr)); + if (os_snprintf_error(buflen, res)) + return -1; + return res; +} + + static int p2p_ctrl_peer(struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen) { @@ -6258,6 +6251,21 @@ static int p2p_ctrl_remove_client(struct wpa_supplicant *wpa_s, const char *cmd) return 0; } + +static int p2p_ctrl_iface_p2p_lo_start(struct wpa_supplicant *wpa_s, char *cmd) +{ + int freq = 0, period = 0, interval = 0, count = 0; + + if (sscanf(cmd, "%d %d %d %d", &freq, &period, &interval, &count) != 4) + { + wpa_printf(MSG_DEBUG, + "CTRL: Invalid P2P LO Start parameter: '%s'", cmd); + return -1; + } + + return wpas_p2p_lo_start(wpa_s, freq, period, interval, count); +} + #endif /* CONFIG_P2P */ @@ -6375,6 +6383,7 @@ static int get_anqp(struct wpa_supplicant *wpa_s, char *dst) u16 id[MAX_ANQP_INFO_ID]; size_t num_id = 0; u32 subtypes = 0; + int get_cell_pref = 0; used = hwaddr_aton2(dst, dst_addr); if (used < 0) @@ -6392,6 +6401,15 @@ static int get_anqp(struct wpa_supplicant *wpa_s, char *dst) #else /* CONFIG_HS20 */ return -1; #endif /* CONFIG_HS20 */ + } else if (os_strncmp(pos, "mbo:", 4) == 0) { +#ifdef CONFIG_MBO + int num = atoi(pos + 4); + if (num != MBO_ANQP_SUBTYPE_CELL_CONN_PREF) + return -1; + get_cell_pref = 1; +#else /* CONFIG_MBO */ + return -1; +#endif /* CONFIG_MBO */ } else { id[num_id] = atoi(pos); if (id[num_id]) @@ -6406,7 +6424,8 @@ static int get_anqp(struct wpa_supplicant *wpa_s, char *dst) if (num_id == 0) return -1; - return anqp_send_req(wpa_s, dst_addr, id, num_id, subtypes); + return anqp_send_req(wpa_s, dst_addr, id, num_id, subtypes, + get_cell_pref); } @@ -6958,6 +6977,34 @@ static int wpas_ctrl_iface_get_pref_freq_list( } +static int wpas_ctrl_iface_driver_flags(struct wpa_supplicant *wpa_s, + char *buf, size_t buflen) +{ + int ret, i; + char *pos, *end; + + ret = os_snprintf(buf, buflen, "%016llX:\n", + (long long unsigned) wpa_s->drv_flags); + if (os_snprintf_error(buflen, ret)) + return -1; + + pos = buf + ret; + end = buf + buflen; + + for (i = 0; i < 64; i++) { + if (wpa_s->drv_flags & (1LLU << i)) { + ret = os_snprintf(pos, end - pos, "%s\n", + driver_flag_to_string(1LLU << i)); + if (os_snprintf_error(end - pos, ret)) + return -1; + pos += ret; + } + } + + return pos - buf; +} + + static int wpa_supplicant_pktcnt_poll(struct wpa_supplicant *wpa_s, char *buf, size_t buflen) { @@ -7112,7 +7159,6 @@ static void wpa_supplicant_ctrl_iface_flush(struct wpa_supplicant *wpa_s) #ifdef CONFIG_TDLS #ifdef CONFIG_TDLS_TESTING - extern unsigned int tdls_testing; tdls_testing = 0; #endif /* CONFIG_TDLS_TESTING */ wpa_drv_tdls_oper(wpa_s, TDLS_ENABLE, NULL); @@ -7170,6 +7216,9 @@ static void wpa_supplicant_ctrl_iface_flush(struct wpa_supplicant *wpa_s) wpa_s->extra_roc_dur = 0; wpa_s->test_failure = WPAS_TEST_FAILURE_NONE; wpa_s->p2p_go_csa_on_inv = 0; + wpa_s->ignore_auth_resp = 0; + wpa_s->ignore_assoc_disallow = 0; + wpa_s->reject_btm_req_reason = 0; wpa_sm_set_test_assoc_ie(wpa_s->wpa, NULL); #endif /* CONFIG_TESTING_OPTIONS */ @@ -7189,6 +7238,10 @@ static void wpa_supplicant_ctrl_iface_flush(struct wpa_supplicant *wpa_s) eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL); wpa_s->wnmsleep_used = 0; + +#ifdef CONFIG_SME + wpa_s->sme.last_unprot_disconnect.sec = 0; +#endif /* CONFIG_SME */ } @@ -7245,6 +7298,13 @@ static void wpas_ctrl_radio_work_cb(struct wpa_radio_work *work, int deinit) eloop_cancel_timeout(wpas_ctrl_radio_work_timeout, work, NULL); + /* + * work->type points to a buffer in ework, so need to replace + * that here with a fixed string to avoid use of freed memory + * in debug prints. + */ + work->type = "freed-ext-work"; + work->ctx = NULL; os_free(ework); return; } @@ -7694,6 +7754,76 @@ static void wpas_ctrl_iface_mgmt_tx_done(struct wpa_supplicant *wpa_s) } +static int wpas_ctrl_iface_mgmt_rx_process(struct wpa_supplicant *wpa_s, + char *cmd) +{ + char *pos, *param; + size_t len; + u8 *buf; + int freq = 0, datarate = 0, ssi_signal = 0; + union wpa_event_data event; + + if (!wpa_s->ext_mgmt_frame_handling) + return -1; + + /* freq= datarate= ssi_signal= frame= */ + + wpa_printf(MSG_DEBUG, "External MGMT RX process: %s", cmd); + + pos = cmd; + param = os_strstr(pos, "freq="); + if (param) { + param += 5; + freq = atoi(param); + } + + param = os_strstr(pos, " datarate="); + if (param) { + param += 10; + datarate = atoi(param); + } + + param = os_strstr(pos, " ssi_signal="); + if (param) { + param += 12; + ssi_signal = atoi(param); + } + + param = os_strstr(pos, " frame="); + if (param == NULL) + return -1; + param += 7; + + len = os_strlen(param); + if (len & 1) + return -1; + len /= 2; + + buf = os_malloc(len); + if (buf == NULL) + return -1; + + if (hexstr2bin(param, buf, len) < 0) { + os_free(buf); + return -1; + } + + os_memset(&event, 0, sizeof(event)); + event.rx_mgmt.freq = freq; + event.rx_mgmt.frame = buf; + event.rx_mgmt.frame_len = len; + event.rx_mgmt.ssi_signal = ssi_signal; + event.rx_mgmt.datarate = datarate; + wpa_s->ext_mgmt_frame_handling = 0; + wpa_supplicant_event(wpa_s, EVENT_RX_MGMT, &event); + wpa_s->ext_mgmt_frame_handling = 1; + + os_free(buf); + + return 0; +} + + static int wpas_ctrl_iface_driver_event(struct wpa_supplicant *wpa_s, char *cmd) { char *pos, *param; @@ -7793,7 +7923,8 @@ static u16 ipv4_hdr_checksum(const void *buf, size_t len) #define HWSIM_PACKETLEN 1500 #define HWSIM_IP_LEN (HWSIM_PACKETLEN - sizeof(struct ether_header)) -void wpas_data_test_rx(void *ctx, const u8 *src_addr, const u8 *buf, size_t len) +static void wpas_data_test_rx(void *ctx, const u8 *src_addr, const u8 *buf, + size_t len) { struct wpa_supplicant *wpa_s = ctx; const struct ether_header *eth; @@ -7969,8 +8100,6 @@ done: static int wpas_ctrl_test_alloc_fail(struct wpa_supplicant *wpa_s, char *cmd) { #ifdef WPA_TRACE_BFD - extern char wpa_trace_fail_func[256]; - extern unsigned int wpa_trace_fail_after; char *pos; wpa_trace_fail_after = atoi(cmd); @@ -7993,9 +8122,6 @@ static int wpas_ctrl_get_alloc_fail(struct wpa_supplicant *wpa_s, char *buf, size_t buflen) { #ifdef WPA_TRACE_BFD - extern char wpa_trace_fail_func[256]; - extern unsigned int wpa_trace_fail_after; - return os_snprintf(buf, buflen, "%u:%s", wpa_trace_fail_after, wpa_trace_fail_func); #else /* WPA_TRACE_BFD */ @@ -8007,8 +8133,6 @@ static int wpas_ctrl_get_alloc_fail(struct wpa_supplicant *wpa_s, static int wpas_ctrl_test_fail(struct wpa_supplicant *wpa_s, char *cmd) { #ifdef WPA_TRACE_BFD - extern char wpa_trace_test_fail_func[256]; - extern unsigned int wpa_trace_test_fail_after; char *pos; wpa_trace_test_fail_after = atoi(cmd); @@ -8031,9 +8155,6 @@ static int wpas_ctrl_get_fail(struct wpa_supplicant *wpa_s, char *buf, size_t buflen) { #ifdef WPA_TRACE_BFD - extern char wpa_trace_test_fail_func[256]; - extern unsigned int wpa_trace_test_fail_after; - return os_snprintf(buf, buflen, "%u:%s", wpa_trace_test_fail_after, wpa_trace_test_fail_func); #else /* WPA_TRACE_BFD */ @@ -8454,10 +8575,7 @@ static int wpas_ctrl_iface_mac_rand_scan(struct wpa_supplicant *wpa_s, } } else if (wpa_s->sched_scanning && (type & MAC_ADDR_RAND_SCHED_SCAN)) { - /* simulate timeout to restart the sched scan */ - wpa_s->sched_scan_timed_out = 1; - wpa_s->prev_sched_ssid = NULL; - wpa_supplicant_cancel_sched_scan(wpa_s); + wpas_scan_restart_sched_scan(wpa_s); } return 0; } @@ -8483,12 +8601,8 @@ static int wpas_ctrl_iface_mac_rand_scan(struct wpa_supplicant *wpa_s, wpas_mac_addr_rand_scan_set(wpa_s, MAC_ADDR_RAND_SCHED_SCAN, addr, mask); - if (wpa_s->sched_scanning && !wpa_s->pno) { - /* simulate timeout to restart the sched scan */ - wpa_s->sched_scan_timed_out = 1; - wpa_s->prev_sched_ssid = NULL; - wpa_supplicant_cancel_sched_scan(wpa_s); - } + if (wpa_s->sched_scanning && !wpa_s->pno) + wpas_scan_restart_sched_scan(wpa_s); } if (type & MAC_ADDR_RAND_PNO) { @@ -8808,6 +8922,9 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, } else if (os_strncmp(buf, "P2P_GROUP_ADD ", 14) == 0) { if (p2p_ctrl_group_add(wpa_s, buf + 14)) reply_len = -1; + } else if (os_strncmp(buf, "P2P_GROUP_MEMBER ", 17) == 0) { + reply_len = p2p_ctrl_group_member(wpa_s, buf + 17, reply, + reply_size); } else if (os_strncmp(buf, "P2P_PROV_DISC ", 14) == 0) { if (p2p_ctrl_prov_disc(wpa_s, buf + 14)) reply_len = -1; @@ -8873,6 +8990,12 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, } else if (os_strncmp(buf, "P2P_REMOVE_CLIENT ", 18) == 0) { if (p2p_ctrl_remove_client(wpa_s, buf + 18) < 0) reply_len = -1; + } else if (os_strncmp(buf, "P2P_LO_START ", 13) == 0) { + if (p2p_ctrl_iface_p2p_lo_start(wpa_s, buf + 13)) + reply_len = -1; + } else if (os_strcmp(buf, "P2P_LO_STOP") == 0) { + if (wpas_p2p_lo_stop(wpa_s)) + reply_len = -1; #endif /* CONFIG_P2P */ #ifdef CONFIG_WIFI_DISPLAY } else if (os_strncmp(buf, "WFD_SUBELEM_SET ", 16) == 0) { @@ -8937,7 +9060,10 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, if (del_hs20_icon(wpa_s, buf + 14) < 0) reply_len = -1; } else if (os_strcmp(buf, "FETCH_OSU") == 0) { - if (hs20_fetch_osu(wpa_s) < 0) + if (hs20_fetch_osu(wpa_s, 0) < 0) + reply_len = -1; + } else if (os_strcmp(buf, "FETCH_OSU no-scan") == 0) { + if (hs20_fetch_osu(wpa_s, 1) < 0) reply_len = -1; } else if (os_strcmp(buf, "CANCEL_FETCH_OSU") == 0) { hs20_cancel_fetch_osu(wpa_s); @@ -8976,16 +9102,7 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, reply_len = wpa_supplicant_ctrl_iface_list_networks( wpa_s, NULL, reply, reply_size); } else if (os_strcmp(buf, "DISCONNECT") == 0) { -#ifdef CONFIG_SME - wpa_s->sme.prev_bssid_set = 0; -#endif /* CONFIG_SME */ - wpa_s->reassociate = 0; - wpa_s->disconnected = 1; - wpa_supplicant_cancel_sched_scan(wpa_s); - wpa_supplicant_cancel_scan(wpa_s); - wpa_supplicant_deauthenticate(wpa_s, - WLAN_REASON_DEAUTH_LEAVING); - eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL); + wpas_request_disconnection(wpa_s); } else if (os_strcmp(buf, "SCAN") == 0) { wpas_ctrl_scan(wpa_s, NULL, reply, reply_size, &reply_len); } else if (os_strncmp(buf, "SCAN ", 5) == 0) { @@ -9148,6 +9265,9 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, if (wpa_supplicant_ctrl_iface_autoscan(wpa_s, buf + 9)) reply_len = -1; #endif /* CONFIG_AUTOSCAN */ + } else if (os_strcmp(buf, "DRIVER_FLAGS") == 0) { + reply_len = wpas_ctrl_iface_driver_flags(wpa_s, reply, + reply_size); #ifdef ANDROID } else if (os_strncmp(buf, "DRIVER ", 7) == 0) { reply_len = wpa_supplicant_driver_cmd(wpa_s, buf + 7, reply, @@ -9178,6 +9298,9 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, reply_len = -1; } else if (os_strcmp(buf, "MGMT_TX_DONE") == 0) { wpas_ctrl_iface_mgmt_tx_done(wpa_s); + } else if (os_strncmp(buf, "MGMT_RX_PROCESS ", 16) == 0) { + if (wpas_ctrl_iface_mgmt_rx_process(wpa_s, buf + 16) < 0) + reply_len = -1; } else if (os_strncmp(buf, "DRIVER_EVENT ", 13) == 0) { if (wpas_ctrl_iface_driver_event(wpa_s, buf + 13) < 0) reply_len = -1; @@ -9552,6 +9675,7 @@ static char * wpas_global_ctrl_iface_redir_p2p(struct wpa_global *global, "P2P_LISTEN ", "P2P_GROUP_REMOVE ", "P2P_GROUP_ADD ", + "P2P_GROUP_MEMBER ", "P2P_PROV_DISC ", "P2P_SERV_DISC_REQ ", "P2P_SERV_DISC_CANCEL_REQ ", @@ -9923,7 +10047,6 @@ char * wpa_supplicant_global_ctrl_iface_process(struct wpa_global *global, reply_size); #ifdef CONFIG_MODULE_TESTS } else if (os_strcmp(buf, "MODULE_TESTS") == 0) { - int wpas_module_tests(void); if (wpas_module_tests() < 0) reply_len = -1; #endif /* CONFIG_MODULE_TESTS */