static int wpa_supplicant_ctrl_iface_enable_network( struct wpa_supplicant *wpa_s, char *cmd) { int id; struct wpa_ssid *ssid; /* cmd: "<network id>" */ id = atoi(cmd); wpa_printf(MSG_DEBUG, "CTRL_IFACE: ENABLE_NETWORK id=%d", id); ssid = wpa_config_get_network(wpa_s->conf, id); if (ssid == NULL) { wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network " "id=%d", id); return -1; } if (wpa_s->current_ssid == NULL && ssid->disabled) { /* * Try to reassociate since there is no current configuration * and a new network was made available. */ wpa_s->reassociate = 1; #ifdef ANDROID wpa_supplicant_req_scan(wpa_s, 2, 0); #else wpa_supplicant_req_scan(wpa_s, 0, 0); #endif } ssid->disabled = 0; return 0; }
int wpas_wps_eapol_cb(struct wpa_supplicant *wpa_s) { if (!wpa_s->wps_success && wpa_s->current_ssid && eap_is_wps_pin_enrollee(&wpa_s->current_ssid->eap)) { const u8 *bssid = wpa_s->bssid; if (is_zero_ether_addr(bssid)) bssid = wpa_s->pending_bssid; wpa_printf(MSG_DEBUG, "WPS: PIN registration with " MACSTR " did not succeed - continue trying to find " "suitable AP", MAC2STR(bssid)); wpa_blacklist_add(wpa_s, bssid); wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); wpa_s->reassociate = 1; wpa_supplicant_req_scan(wpa_s, wpa_s->blacklist_cleared ? 5 : 0, 0); wpa_s->blacklist_cleared = 0; return 1; } eloop_cancel_timeout(wpas_wps_timeout, wpa_s, NULL); if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS && !wpa_s->wps_success) wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_FAIL); if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS && wpa_s->current_ssid && !(wpa_s->current_ssid->key_mgmt & WPA_KEY_MGMT_WPS)) { int disabled = wpa_s->current_ssid->disabled; wpa_printf(MSG_DEBUG, "WPS: Network configuration replaced - " "try to associate with the received credential"); wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); if (disabled) { wpa_printf(MSG_DEBUG, "WPS: Current network is " "disabled - wait for user to enable"); return 1; } wpa_s->after_wps = 5; wpa_s->wps_freq = wpa_s->assoc_freq; wpa_s->normal_scans = 0; wpa_s->reassociate = 1; wpa_supplicant_req_scan(wpa_s, 0, 0); return 1; } if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS && wpa_s->current_ssid) { wpa_printf(MSG_DEBUG, "WPS: Registration completed - waiting " "for external credential processing"); wpas_clear_wps(wpa_s); wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); return 1; } return 0; }
static void request_scan(struct wpa_supplicant *wpa_s) { wpa_s->scan_req = 2; if (wpa_supplicant_req_sched_scan(wpa_s)) wpa_supplicant_req_scan(wpa_s, wpa_s->scan_interval, 0); }
void hs20_start_osu_scan(struct wpa_supplicant *wpa_s) { wpa_s->num_osu_scans++; wpa_s->scan_req = MANUAL_SCAN_REQ; wpa_s->scan_res_handler = hs20_osu_scan_res_handler; wpa_supplicant_req_scan(wpa_s, 0, 0); }
void sme_event_assoc_timed_out(struct wpa_supplicant *wpa_s, union wpa_event_data *data) { wpa_printf(MSG_DEBUG, "SME: Association timed out"); wpa_supplicant_mark_disassoc(wpa_s); wpa_supplicant_req_scan(wpa_s, 5, 0); }
static void wpa_supplicant_assoc_try(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) { while (ssid) { if (!ssid->disabled) break; ssid = ssid->next; } /* ap_scan=2 mode - try to associate with each SSID. */ if (ssid == NULL) { wpa_dbg(wpa_s, MSG_DEBUG, "wpa_supplicant_assoc_try: Reached " "end of scan list - go back to beginning"); wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN; wpa_supplicant_req_scan(wpa_s, 0, 0); return; } if (ssid->next) { /* Continue from the next SSID on the next attempt. */ wpa_s->prev_scan_ssid = ssid; } else { /* Start from the beginning of the SSID list. */ wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN; } wpa_supplicant_associate(wpa_s, NULL, ssid); }
static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s) { const u8 *bssid; if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) { /* * At least Host AP driver and a Prism3 card seemed to be * generating streams of disconnected events when configuring * IBSS for WPA-None. Ignore them for now. */ wpa_printf(MSG_DEBUG, "Disconnect event - ignore in " "IBSS/WPA-None mode"); return; } if (wpa_s->wpa_state == WPA_4WAY_HANDSHAKE && wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) { wpa_msg(wpa_s, MSG_INFO, "WPA: 4-Way Handshake failed - " "pre-shared key may be incorrect"); } if (wpa_s->wpa_state >= WPA_ASSOCIATED) wpa_supplicant_req_scan(wpa_s, 0, 100000); bssid = wpa_s->bssid; if (is_zero_ether_addr(bssid)) bssid = wpa_s->pending_bssid; wpa_blacklist_add(wpa_s, bssid); wpa_sm_notify_disassoc(wpa_s->wpa); wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "- Disconnect event - " "remove keys"); if (wpa_supplicant_dynamic_keys(wpa_s)) { wpa_s->keys_cleared = 0; wpa_clear_keys(wpa_s, wpa_s->bssid); } wpa_supplicant_mark_disassoc(wpa_s); }
/** * wpas_dbus_iface_scan - Request a wireless scan on an interface * @message: Pointer to incoming dbus message * @wpa_s: wpa_supplicant structure for a network interface * Returns: a dbus message containing a UINT32 indicating success (1) or * failure (0) * * Handler function for "scan" method call of a network device. Requests * that wpa_supplicant perform a wireless scan as soon as possible * on a particular wireless interface. */ DBusMessage * wpas_dbus_iface_scan(DBusMessage *message, struct wpa_supplicant *wpa_s) { wpa_s->scan_req = 2; wpa_supplicant_req_scan(wpa_s, 0, 0); return wpas_dbus_new_success_reply(message); }
static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s) { const u8 *bssid; #ifdef CONFIG_SME int authenticating; u8 prev_pending_bssid[ETH_ALEN]; authenticating = wpa_s->wpa_state == WPA_AUTHENTICATING; os_memcpy(prev_pending_bssid, wpa_s->pending_bssid, ETH_ALEN); #endif /* CONFIG_SME */ if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) { /* * At least Host AP driver and a Prism3 card seemed to be * generating streams of disconnected events when configuring * IBSS for WPA-None. Ignore them for now. */ wpa_printf(MSG_DEBUG, "Disconnect event - ignore in " "IBSS/WPA-None mode"); return; } if (wpa_s->wpa_state == WPA_4WAY_HANDSHAKE && wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) { wpa_msg(wpa_s, MSG_INFO, "WPA: 4-Way Handshake failed - " "pre-shared key may be incorrect"); } if (wpa_s->wpa_state >= WPA_ASSOCIATED) wpa_supplicant_req_scan(wpa_s, 0, 100000); bssid = wpa_s->bssid; if (is_zero_ether_addr(bssid)) bssid = wpa_s->pending_bssid; wpa_blacklist_add(wpa_s, bssid); wpa_sm_notify_disassoc(wpa_s->wpa); wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "- Disconnect event - " "remove keys"); if (wpa_supplicant_dynamic_keys(wpa_s)) { wpa_s->keys_cleared = 0; wpa_clear_keys(wpa_s, wpa_s->bssid); } wpa_supplicant_mark_disassoc(wpa_s); bgscan_deinit(wpa_s); #ifdef CONFIG_SME if (authenticating && (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)) { /* * mac80211-workaround to force deauth on failed auth cmd, * requires us to remain in authenticating state to allow the * second authentication attempt to be continued properly. */ wpa_printf(MSG_DEBUG, "SME: Allow pending authentication to " "proceed after disconnection event"); wpa_supplicant_set_state(wpa_s, WPA_AUTHENTICATING); os_memcpy(wpa_s->pending_bssid, prev_pending_bssid, ETH_ALEN); } #endif /* CONFIG_SME */ }
static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s, u16 reason_code) { const u8 *bssid; int authenticating; u8 prev_pending_bssid[ETH_ALEN]; authenticating = wpa_s->wpa_state == WPA_AUTHENTICATING; os_memcpy(prev_pending_bssid, wpa_s->pending_bssid, ETH_ALEN); if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) { /* * At least Host AP driver and a Prism3 card seemed to be * generating streams of disconnected events when configuring * IBSS for WPA-None. Ignore them for now. */ wpa_printf(MSG_DEBUG, "Disconnect event - ignore in " "IBSS/WPA-None mode"); return; } if (wpa_s->wpa_state == WPA_4WAY_HANDSHAKE && wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) { wpa_msg(wpa_s, MSG_INFO, "WPA: 4-Way Handshake failed - " "pre-shared key may be incorrect"); } if (wpa_s->wpa_state >= WPA_ASSOCIATED) wpa_supplicant_req_scan(wpa_s, 0, 100000); bssid = wpa_s->bssid; if (is_zero_ether_addr(bssid)) bssid = wpa_s->pending_bssid; wpas_connection_failed(wpa_s, bssid); wpa_sm_notify_disassoc(wpa_s->wpa); wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "bssid=" MACSTR " reason=%d", MAC2STR(bssid), reason_code); if (wpa_supplicant_dynamic_keys(wpa_s)) { wpa_printf(MSG_DEBUG, "Disconnect event - remove keys"); wpa_s->keys_cleared = 0; wpa_clear_keys(wpa_s, wpa_s->bssid); } if (wpa_s->wpa_state == WPA_DISCONNECTED) { wpa_s->disconnect_count++; if (!eloop_is_timeout_registered(wpa_disconnect_spam_handle, wpa_s, NULL)) { eloop_register_timeout(6, 0, wpa_disconnect_spam_handle, wpa_s, NULL); wpa_printf(MSG_DEBUG, "%s: scheduled DISCONNECT spam handler", __FUNCTION__); } } wpa_supplicant_mark_disassoc(wpa_s); bgscan_deinit(wpa_s); wpa_s->bgscan_ssid = NULL; if (authenticating && (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)) sme_disassoc_while_authenticating(wpa_s, prev_pending_bssid); }
static int wpa_supplicant_ctrl_iface_select_network( struct wpa_supplicant *wpa_s, char *cmd) { int id; struct wpa_ssid *ssid; /* cmd: "<network id>" or "any" */ if (os_strcmp(cmd, "any") == 0) { wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK any"); ssid = wpa_s->conf->ssid; while (ssid) { ssid->disabled = 0; ssid = ssid->next; } wpa_s->reassociate = 1; wpa_supplicant_req_scan(wpa_s, 0, 0); return 0; } id = atoi(cmd); wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK id=%d", id); ssid = wpa_config_get_network(wpa_s->conf, id); if (ssid == NULL) { wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network " "id=%d", id); return -1; } if (ssid != wpa_s->current_ssid && wpa_s->current_ssid) wpa_supplicant_disassociate(wpa_s, REASON_DEAUTH_LEAVING); /* Mark all other networks disabled and trigger reassociation */ ssid = wpa_s->conf->ssid; while (ssid) { ssid->disabled = id != ssid->id; ssid = ssid->next; } wpa_s->reassociate = 1; wpa_s->prev_scan_ssid = BROADCAST_SSID_SCAN; wpa_supplicant_req_scan(wpa_s, 0, 0); return 0; }
static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s, u16 reason_code) { const u8 *bssid; #ifdef CONFIG_SME int authenticating; u8 prev_pending_bssid[ETH_ALEN]; authenticating = wpa_s->wpa_state == WPA_AUTHENTICATING; os_memcpy(prev_pending_bssid, wpa_s->pending_bssid, ETH_ALEN); #endif /* CONFIG_SME */ if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) { /* * At least Host AP driver and a Prism3 card seemed to be * generating streams of disconnected events when configuring * IBSS for WPA-None. Ignore them for now. */ wpa_printf(MSG_DEBUG, "Disconnect event - ignore in " "IBSS/WPA-None mode"); return; } if (wpa_s->wpa_state == WPA_4WAY_HANDSHAKE && wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) { wpa_msg(wpa_s, MSG_INFO, "WPA: 4-Way Handshake failed - " "pre-shared key may be incorrect"); } if (!wpa_s->auto_reconnect_disabled || wpa_s->key_mgmt == WPA_KEY_MGMT_WPS) { wpa_printf(MSG_DEBUG, "WPA: Auto connect enabled: try to " "reconnect (wps=%d)", wpa_s->key_mgmt == WPA_KEY_MGMT_WPS); if (wpa_s->wpa_state >= WPA_ASSOCIATING) wpa_supplicant_req_scan(wpa_s, 0, 100000); } else { wpa_printf(MSG_DEBUG, "WPA: Auto connect disabled: do not try " "to re-connect"); wpa_s->reassociate = 0; wpa_s->disconnected = 1; } bssid = wpa_s->bssid; if (is_zero_ether_addr(bssid)) bssid = wpa_s->pending_bssid; wpa_blacklist_add(wpa_s, bssid); wpa_sm_notify_disassoc(wpa_s->wpa); wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "bssid=" MACSTR " reason=%d", MAC2STR(bssid), reason_code); if (wpa_supplicant_dynamic_keys(wpa_s)) { wpa_printf(MSG_DEBUG, "Disconnect event - remove keys"); wpa_s->keys_cleared = 0; wpa_clear_keys(wpa_s, wpa_s->bssid); } wpa_supplicant_mark_disassoc(wpa_s); }
void sme_associate(struct wpa_supplicant *wpa_s, enum wpas_mode mode, const u8 *bssid, u16 auth_type) { struct wpa_driver_associate_params params; struct ieee802_11_elems elems; os_memset(¶ms, 0, sizeof(params)); params.bssid = bssid; params.ssid = wpa_s->sme.ssid; params.ssid_len = wpa_s->sme.ssid_len; params.freq = wpa_s->sme.freq; params.wpa_ie = wpa_s->sme.assoc_req_ie_len ? wpa_s->sme.assoc_req_ie : NULL; params.wpa_ie_len = wpa_s->sme.assoc_req_ie_len; #ifdef CONFIG_IEEE80211R if (auth_type == WLAN_AUTH_FT && wpa_s->sme.ft_ies) { params.wpa_ie = wpa_s->sme.ft_ies; params.wpa_ie_len = wpa_s->sme.ft_ies_len; } #endif /* CONFIG_IEEE80211R */ params.mode = mode; params.mgmt_frame_protection = wpa_s->sme.mfp; if (wpa_s->sme.prev_bssid_set) params.prev_bssid = wpa_s->sme.prev_bssid; wpa_msg(wpa_s, MSG_INFO, "Trying to associate with " MACSTR " (SSID='%s' freq=%d MHz)", MAC2STR(params.bssid), params.ssid ? wpa_ssid_txt(params.ssid, params.ssid_len) : "", params.freq); wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING); if (params.wpa_ie == NULL || ieee802_11_parse_elems(params.wpa_ie, params.wpa_ie_len, &elems, 0) < 0) { wpa_printf(MSG_DEBUG, "SME: Could not parse own IEs?!"); os_memset(&elems, 0, sizeof(elems)); } if (elems.rsn_ie) wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, elems.rsn_ie - 2, elems.rsn_ie_len + 2); else if (elems.wpa_ie) wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, elems.wpa_ie - 2, elems.wpa_ie_len + 2); else wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0); if (wpa_drv_associate(wpa_s, ¶ms) < 0) { wpa_msg(wpa_s, MSG_INFO, "Association request to the driver " "failed"); wpa_supplicant_req_scan(wpa_s, 5, 0); return; } /* TODO: add timeout on association */ }
static void wpa_supplicant_delayed_sched_scan_timeout(void *eloop_ctx, void *timeout_ctx) { struct wpa_supplicant *wpa_s = eloop_ctx; wpa_dbg(wpa_s, MSG_DEBUG, "Starting delayed sched scan"); if (wpa_supplicant_req_sched_scan(wpa_s)) wpa_supplicant_req_scan(wpa_s, 0, 0); }
static int wpa_supplicant_ctrl_iface_enable_network( struct wpa_supplicant *wpa_s, char *cmd) { int id; struct wpa_ssid *ssid; /* cmd: "<network id>" or "all" */ if (os_strcmp(cmd, "all") == 0) { wpa_printf(MSG_DEBUG, "CTRL_IFACE: ENABLE_NETWORK all"); ssid = wpa_s->conf->ssid; while (ssid) { if (ssid == wpa_s->current_ssid && ssid->disabled) wpa_s->reassociate = 1; ssid->disabled = 0; ssid = ssid->next; } if (wpa_s->reassociate) wpa_supplicant_req_scan(wpa_s, 0, 0); return 0; } id = atoi(cmd); wpa_printf(MSG_DEBUG, "CTRL_IFACE: ENABLE_NETWORK id=%d", id); ssid = wpa_config_get_network(wpa_s->conf, id); if (ssid == NULL) { wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network " "id=%d", id); return -1; } if (wpa_s->current_ssid == NULL && ssid->disabled) { /* * Try to reassociate since there is no current configuration * and a new network was made available. */ wpa_s->reassociate = 1; wpa_supplicant_req_scan(wpa_s, 0, 0); } ssid->disabled = 0; return 0; }
/* ARGSUSED */ static void wpa_supplicant_timeout(void *eloop_ctx, void *timeout_ctx) { struct wpa_supplicant *wpa_s = eloop_ctx; wpa_printf(MSG_INFO, "Authentication with " MACSTR " timed out.", MAC2STR(wpa_s->bssid)); wpa_s->reassociate = 1; wpa_supplicant_req_scan(wpa_s, 0, 0); }
static void wpa_supplicant_stop_countermeasures(void *eloop_ctx, void *sock_ctx) { struct wpa_supplicant *wpa_s = eloop_ctx; if (wpa_s->countermeasures) { wpa_s->countermeasures = 0; wpa_drv_set_countermeasures(wpa_s, 0); wpa_msg(wpa_s, MSG_INFO, "WPA: TKIP countermeasures stopped"); wpa_supplicant_req_scan(wpa_s, 0, 0); } }
int interworking_select(struct wpa_supplicant *wpa_s, int auto_select) { interworking_stop_fetch_anqp(wpa_s); wpa_s->network_select = 1; wpa_s->auto_select = !!auto_select; wpa_printf(MSG_DEBUG, "Interworking: Start scan for network " "selection"); wpa_s->scan_res_handler = interworking_scan_res_handler; wpa_s->scan_req = 2; wpa_supplicant_req_scan(wpa_s, 0, 0); return 0; }
void sme_event_assoc_reject(struct wpa_supplicant *wpa_s, union wpa_event_data *data) { int bssid_changed; int timeout = 5000; wpa_printf(MSG_DEBUG, "SME: Association with " MACSTR " failed: " "status code %d", MAC2STR(wpa_s->pending_bssid), data->assoc_reject.status_code); bssid_changed = !is_zero_ether_addr(wpa_s->bssid); /* * For now, unconditionally terminate the previous authentication. In * theory, this should not be needed, but mac80211 gets quite confused * if the authentication is left pending.. Some roaming cases might * benefit from using the previous authentication, so this could be * optimized in the future. */ if (wpa_drv_deauthenticate(wpa_s, wpa_s->pending_bssid, WLAN_REASON_DEAUTH_LEAVING) < 0) { wpa_msg(wpa_s, MSG_INFO, "Deauth request to the driver failed"); } wpa_s->sme.prev_bssid_set = 0; if (wpa_blacklist_add(wpa_s, wpa_s->pending_bssid) == 0) { struct wpa_blacklist *b; b = wpa_blacklist_get(wpa_s, wpa_s->pending_bssid); if (b && b->count < 3) { /* * Speed up next attempt if there could be other APs * that could accept association. */ timeout = 100; } } wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); os_memset(wpa_s->bssid, 0, ETH_ALEN); os_memset(wpa_s->pending_bssid, 0, ETH_ALEN); if (bssid_changed) wpas_notify_bssid_changed(wpa_s); /* * TODO: if more than one possible AP is available in scan results, * could try the other ones before requesting a new scan. */ wpa_supplicant_req_scan(wpa_s, timeout / 1000, 1000 * (timeout % 1000)); }
static void wpa_supplicant_req_new_scan(struct wpa_supplicant *wpa_s, int timeout_sec, int timeout_usec) { if (!wpa_supplicant_enabled_networks(wpa_s->conf)) { /* * No networks are enabled; short-circuit request so * we don't wait timeout seconds before transitioning * to INACTIVE state. */ wpa_supplicant_set_state(wpa_s, WPA_INACTIVE); return; } wpa_supplicant_req_scan(wpa_s, timeout_sec, timeout_usec); }
/* * wpa_event_handler - report a driver event for wpa_supplicant * @wpa_s: pointer to wpa_supplicant data; this is the @ctx variable registered * with wpa_driver_events_init() * @event: event type (defined above) * * Driver wrapper code should call this function whenever an event is received * from the driver. */ void wpa_event_handler(void *cookie, wpa_event_type event) { struct wpa_supplicant *wpa_s = cookie; uint8_t bssid[IEEE80211_ADDR_LEN]; switch (event) { case EVENT_ASSOC: wpa_s->wpa_state = WPA_ASSOCIATED; wpa_printf(MSG_DEBUG, "\nAssociation event - clear replay " "counter\n"); (void) memset(wpa_s->rx_replay_counter, 0, WPA_REPLAY_COUNTER_LEN); wpa_s->rx_replay_counter_set = 0; wpa_s->renew_snonce = 1; if (wpa_s->driver->get_bssid(wpa_s->linkid, (char *)bssid) >= 0 && memcmp(bssid, wpa_s->bssid, IEEE80211_ADDR_LEN) != 0) { wpa_printf(MSG_DEBUG, "Associated to a new BSS: " "BSSID=" MACSTR, MAC2STR(bssid)); (void) memcpy(wpa_s->bssid, bssid, IEEE80211_ADDR_LEN); if (wpa_s->key_mgmt != WPA_KEY_MGMT_NONE) wpa_clear_keys(wpa_s, bssid); } wpa_s->eapol_received = 0; if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE) { wpa_supplicant_cancel_auth_timeout(wpa_s); } else { /* Timeout for receiving the first EAPOL packet */ wpa_supplicant_req_auth_timeout(wpa_s, 10, 0); } break; case EVENT_DISASSOC: if (wpa_s->wpa_state >= WPA_ASSOCIATED) wpa_supplicant_req_scan(wpa_s, 0, 100000); wpa_supplicant_mark_disassoc(wpa_s); wpa_printf(MSG_DEBUG, "Disconnect event - remove keys"); if (wpa_s->key_mgmt != WPA_KEY_MGMT_NONE) wpa_clear_keys(wpa_s, wpa_s->bssid); break; case EVENT_SCAN_RESULTS: wpa_supplicant_scan_results(wpa_s); break; default: wpa_printf(MSG_INFO, "Unknown event %d", event); break; } }
/** * wpas_dbus_iface_enable_network - Mark a configured network as enabled * @message: Pointer to incoming dbus message * @wpa_s: wpa_supplicant structure for a network interface * @ssid: wpa_ssid structure for a configured network * Returns: A dbus message containing a UINT32 indicating success (1) or * failure (0) * * Handler function for "enable" method call of a configured network. */ DBusMessage * wpas_dbus_iface_enable_network(DBusMessage *message, struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) { if (wpa_s->current_ssid == NULL && ssid->disabled) { /* * Try to reassociate since there is no current configuration * and a new network was made available. */ wpa_s->reassociate = 1; wpa_supplicant_req_scan(wpa_s, 0, 0); } ssid->disabled = 0; return wpas_dbus_new_success_reply(message); }
static void wpas_wps_reassoc(struct wpa_supplicant *wpa_s, struct wpa_ssid *selected, const u8 *bssid) { struct wpa_ssid *ssid; struct wpa_bss *bss; wpa_s->known_wps_freq = 0; if (bssid) { bss = wpa_bss_get_bssid(wpa_s, bssid); if (bss && bss->freq > 0) { wpa_s->known_wps_freq = 1; wpa_s->wps_freq = bss->freq; } } if (wpa_s->current_ssid) wpa_supplicant_deauthenticate( wpa_s, WLAN_REASON_DEAUTH_LEAVING); /* Mark all other networks disabled and trigger reassociation */ ssid = wpa_s->conf->ssid; while (ssid) { int was_disabled = ssid->disabled; /* * In case the network object corresponds to a persistent group * then do not send out network disabled signal. In addition, * do not change disabled status of persistent network objects * from 2 to 1 should we connect to another network. */ if (was_disabled != 2) { ssid->disabled = ssid != selected; if (was_disabled != ssid->disabled) wpas_notify_network_enabled_changed(wpa_s, ssid); } ssid = ssid->next; } wpa_s->disconnected = 0; wpa_s->reassociate = 1; wpa_s->scan_runs = 0; wpa_s->normal_scans = 0; wpa_s->wps_success = 0; wpa_s->blacklist_cleared = 0; wpa_supplicant_req_scan(wpa_s, 0, 0); }
static void wpas_wps_reassoc(struct wpa_supplicant *wpa_s, struct wpa_ssid *selected) { struct wpa_ssid *ssid; /* Mark all other networks disabled and trigger reassociation */ ssid = wpa_s->conf->ssid; while (ssid) { ssid->disabled = ssid != selected; ssid = ssid->next; } wpa_s->disconnected = 0; wpa_s->reassociate = 1; wpa_s->scan_runs = 0; wpa_s->wps_success = 0; wpa_s->blacklist_cleared = 0; wpa_supplicant_req_scan(wpa_s, 0, 0); }
static void wpa_supplicant_req_new_scan(struct wpa_supplicant *wpa_s, int timeout) { if (wpa_s->scan_res_tried == 1 && wpa_s->conf->ap_scan == 1) { /* * Quick recovery if the initial scan results were not * complete when fetched before the first scan request. */ wpa_s->scan_res_tried++; timeout = 0; } else if (!wpa_supplicant_enabled_networks(wpa_s->conf)) { /* * No networks are enabled; short-circuit request so * we don't wait timeout seconds before transitioning * to INACTIVE state. */ wpa_supplicant_set_state(wpa_s, WPA_INACTIVE); return; } wpa_supplicant_req_scan(wpa_s, timeout, 0); }
void wpas_notify_resume(struct wpa_global *global) { struct os_time now; int slept; struct wpa_supplicant *wpa_s; if (global->suspend_time.sec == 0) slept = -1; else { os_get_time(&now); slept = now.sec - global->suspend_time.sec; } wpa_printf(MSG_DEBUG, "System resume notification (slept %d seconds)", slept); for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) { wpa_drv_resume(wpa_s); if (wpa_s->wpa_state == WPA_DISCONNECTED) wpa_supplicant_req_scan(wpa_s, 0, 100000); } }
static int wpa_supplicant_driver_init(const char *link, struct wpa_supplicant *wpa_s) { wpa_s->l2 = l2_packet_init(link, ETHERTYPE_EAPOL, wpa_supplicant_rx_eapol, wpa_s); if (wpa_s->l2 == NULL) return (-1); if (l2_packet_get_own_addr(wpa_s->l2, wpa_s->own_addr)) { (void) fprintf(stderr, "Failed to get own L2 address\n"); return (-1); } if (wpa_s->driver->set_wpa(wpa_s->linkid, 1) < 0) { wpa_printf(MSG_ERROR, "Failed to enable WPA in the driver."); return (-1); } wpa_clear_keys(wpa_s, NULL); wpa_supplicant_req_scan(wpa_s, 0, 100000); return (0); }
static void wpa_supplicant_scan_results(struct wpa_supplicant *wpa_s) { dladm_wlan_ess_t results[MAX_SCANRESULTS]; int num; dladm_wlan_ess_t *selected = NULL; struct wpa_ssid *ssid; (void) memset(results, 0, sizeof (dladm_wlan_ess_t) * MAX_SCANRESULTS); num = wpa_s->driver->get_scan_results(wpa_s->linkid, results, MAX_SCANRESULTS); wpa_printf(MSG_DEBUG, "Scan results: %d", num); if (num < 0) return; if (num > MAX_SCANRESULTS) { wpa_printf(MSG_INFO, "Not enough room for all APs (%d < %d)", num, MAX_SCANRESULTS); num = MAX_SCANRESULTS; } selected = wpa_supplicant_select_bss(wpa_s, wpa_s->conf->ssid, results, num, &ssid); if (selected) { if (wpa_s->reassociate || memcmp(selected->we_bssid.wb_bytes, wpa_s->bssid, IEEE80211_ADDR_LEN) != 0) { wpa_supplicant_associate(wpa_s, selected, ssid); } else { wpa_printf(MSG_DEBUG, "Already associated with the " "selected AP."); } } else { wpa_printf(MSG_DEBUG, "No suitable AP found."); wpa_supplicant_req_scan(wpa_s, 5, 0); /* wait 5 seconds */ } }
char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, char *buf, size_t *resp_len) { char *reply; const int reply_size = 4096; int ctrl_rsp = 0; int reply_len; if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0 || os_strncmp(buf, "SET_NETWORK ", 12) == 0) { wpa_hexdump_ascii_key(MSG_DEBUG, "RX ctrl_iface", (const u8 *) buf, os_strlen(buf)); } else { if (os_strcmp(buf, "PING") != 0) wpa_hexdump_ascii(MSG_DEBUG, "RX ctrl_iface", (const u8 *) buf, os_strlen(buf)); } reply = os_malloc(reply_size); if (reply == NULL) { *resp_len = 1; return NULL; } os_memcpy(reply, "OK\n", 3); reply_len = 3; if (os_strcmp(buf, "PING") == 0) { os_memcpy(reply, "PONG\n", 5); reply_len = 5; } else if (os_strcmp(buf, "MIB") == 0) { reply_len = wpa_sm_get_mib(wpa_s->wpa, reply, reply_size); if (reply_len >= 0) { int res; res = eapol_sm_get_mib(wpa_s->eapol, reply + reply_len, reply_size - reply_len); if (res < 0) reply_len = -1; else reply_len += res; } } else if (os_strncmp(buf, "STATUS", 6) == 0) { reply_len = wpa_supplicant_ctrl_iface_status( wpa_s, buf + 6, reply, reply_size); } else if (os_strcmp(buf, "PMKSA") == 0) { reply_len = pmksa_cache_list(wpa_s->wpa, reply, reply_size); } else if (os_strncmp(buf, "SET ", 4) == 0) { if (wpa_supplicant_ctrl_iface_set(wpa_s, buf + 4)) reply_len = -1; } else if (os_strcmp(buf, "LOGON") == 0) { eapol_sm_notify_logoff(wpa_s->eapol, FALSE); } else if (os_strcmp(buf, "LOGOFF") == 0) { eapol_sm_notify_logoff(wpa_s->eapol, TRUE); } else if (os_strcmp(buf, "REASSOCIATE") == 0) { wpa_s->disconnected = 0; wpa_s->reassociate = 1; wpa_supplicant_req_scan(wpa_s, 0, 0); } else if (os_strcmp(buf, "RECONNECT") == 0) { if (wpa_s->disconnected) { wpa_s->disconnected = 0; wpa_s->reassociate = 1; wpa_supplicant_req_scan(wpa_s, 0, 0); } #ifdef IEEE8021X_EAPOL } else if (os_strncmp(buf, "PREAUTH ", 8) == 0) { if (wpa_supplicant_ctrl_iface_preauth(wpa_s, buf + 8)) reply_len = -1; #endif /* IEEE8021X_EAPOL */ #ifdef CONFIG_PEERKEY } else if (os_strncmp(buf, "STKSTART ", 9) == 0) { if (wpa_supplicant_ctrl_iface_stkstart(wpa_s, buf + 9)) reply_len = -1; #endif /* CONFIG_PEERKEY */ } else if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0) { if (wpa_supplicant_ctrl_iface_ctrl_rsp( wpa_s, buf + os_strlen(WPA_CTRL_RSP))) reply_len = -1; else ctrl_rsp = 1; } else if (os_strcmp(buf, "RECONFIGURE") == 0) { if (wpa_supplicant_reload_configuration(wpa_s)) reply_len = -1; } else if (os_strcmp(buf, "TERMINATE") == 0) { eloop_terminate(); } else if (os_strncmp(buf, "BSSID ", 6) == 0) { if (wpa_supplicant_ctrl_iface_bssid(wpa_s, buf + 6)) reply_len = -1; #ifdef ANDROID } else if (os_strncmp(buf, "BLACKLIST", 9) == 0) { reply_len = wpa_supplicant_ctrl_iface_blacklist( wpa_s, buf + 9, reply, reply_size); if (os_strlen(buf) > 10 && reply_len == 0) { struct wpa_blacklist *bl = wpa_s->blacklist; if (os_strncmp(buf+10, "clear", 5) == 0 || (bl != NULL && os_memcmp(bl->bssid, wpa_s->bssid, ETH_ALEN) == 0)) { wpa_s->disconnected = 0; wpa_s->reassociate = 1; wpa_supplicant_req_scan(wpa_s, 0, 0); } } #endif } else if (os_strcmp(buf, "LIST_NETWORKS") == 0) { reply_len = wpa_supplicant_ctrl_iface_list_networks( wpa_s, reply, reply_size); } else if (os_strcmp(buf, "DISCONNECT") == 0) { wpa_s->reassociate = 0; wpa_s->disconnected = 1; wpa_supplicant_disassociate(wpa_s, REASON_DEAUTH_LEAVING); } else if (os_strcmp(buf, "SCAN") == 0) { #ifdef ANDROID if (!wpa_s->scan_ongoing && ((wpa_s->wpa_state <= WPA_SCANNING) || (wpa_s->wpa_state >= WPA_COMPLETED))) { #endif wpa_s->scan_req = 2; wpa_supplicant_req_scan(wpa_s, 0, 0); #ifdef ANDROID } else { wpa_printf(MSG_DEBUG, "Ongoing Scan action..."); } #endif } else if (os_strcmp(buf, "SCAN_RESULTS") == 0) { reply_len = wpa_supplicant_ctrl_iface_scan_results( wpa_s, reply, reply_size); } else if (os_strncmp(buf, "SELECT_NETWORK ", 15) == 0) { if (wpa_supplicant_ctrl_iface_select_network(wpa_s, buf + 15)) reply_len = -1; } else if (os_strncmp(buf, "ENABLE_NETWORK ", 15) == 0) { if (wpa_supplicant_ctrl_iface_enable_network(wpa_s, buf + 15)) reply_len = -1; } else if (os_strncmp(buf, "DISABLE_NETWORK ", 16) == 0) { if (wpa_supplicant_ctrl_iface_disable_network(wpa_s, buf + 16)) reply_len = -1; } else if (os_strcmp(buf, "ADD_NETWORK") == 0) { reply_len = wpa_supplicant_ctrl_iface_add_network( wpa_s, reply, reply_size); } else if (os_strncmp(buf, "REMOVE_NETWORK ", 15) == 0) { if (wpa_supplicant_ctrl_iface_remove_network(wpa_s, buf + 15)) reply_len = -1; } else if (os_strncmp(buf, "SET_NETWORK ", 12) == 0) { if (wpa_supplicant_ctrl_iface_set_network(wpa_s, buf + 12)) reply_len = -1; } else if (os_strncmp(buf, "GET_NETWORK ", 12) == 0) { reply_len = wpa_supplicant_ctrl_iface_get_network( wpa_s, buf + 12, reply, reply_size); } else if (os_strcmp(buf, "SAVE_CONFIG") == 0) { if (wpa_supplicant_ctrl_iface_save_config(wpa_s)) reply_len = -1; } else if (os_strncmp(buf, "GET_CAPABILITY ", 15) == 0) { reply_len = wpa_supplicant_ctrl_iface_get_capability( wpa_s, buf + 15, reply, reply_size); } else if (os_strncmp(buf, "AP_SCAN ", 8) == 0) { if (wpa_supplicant_ctrl_iface_ap_scan(wpa_s, buf + 8)) reply_len = -1; } else if (os_strcmp(buf, "INTERFACES") == 0) { reply_len = wpa_supplicant_global_iface_interfaces( wpa_s->global, reply, reply_size); } else if (os_strncmp(buf, "DRIVER ", 7) == 0) { reply_len = wpa_supplicant_driver_cmd(wpa_s, buf + 7, reply, reply_size); } else { os_memcpy(reply, "UNKNOWN COMMAND\n", 16); reply_len = 16; } if (reply_len < 0) { os_memcpy(reply, "FAIL\n", 5); reply_len = 5; } if (ctrl_rsp) eapol_sm_notify_ctrl_response(wpa_s->eapol); *resp_len = reply_len; return reply; }
static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx) { struct wpa_supplicant *wpa_s = eloop_ctx; struct wpa_ssid *ssid; int scan_req = 0, ret; struct wpabuf *wps_ie = NULL; const u8 *extra_ie = NULL; size_t extra_ie_len = 0; int wps = 0; #ifdef CONFIG_WPS enum wps_request_type req_type = WPS_REQ_ENROLLEE_INFO; #endif /* CONFIG_WPS */ wpa_printf(MSG_DEBUG, "%s: scan_req = %d, ap_scan = %d", __func__, wpa_s->scan_req, wpa_s->conf->ap_scan); #if ICS_LEGACY_WLAN_SUPPORT if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) { wpa_printf(MSG_DEBUG, "Skip scan - interface disabled"); return; } #endif if (wpa_s->disconnected && !wpa_s->scan_req) { wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); return; } if (!wpa_supplicant_enabled_networks(wpa_s->conf) && !wpa_s->scan_req) { wpa_printf(MSG_DEBUG, "No enabled networks - do not scan"); wpa_supplicant_set_state(wpa_s, WPA_INACTIVE); return; } scan_req = wpa_s->scan_req; wpa_s->scan_req = 0; if (wpa_s->conf->ap_scan != 0 && wpa_s->driver && IS_WIRED(wpa_s->driver)) { wpa_printf(MSG_DEBUG, "Using wired authentication - " "overriding ap_scan configuration"); wpa_s->conf->ap_scan = 0; } if (wpa_s->conf->ap_scan == 0) { wpa_supplicant_gen_assoc_event(wpa_s); return; } if (wpa_s->wpa_state == WPA_DISCONNECTED || wpa_s->wpa_state == WPA_INACTIVE) wpa_supplicant_set_state(wpa_s, WPA_SCANNING); ssid = wpa_s->conf->ssid; if (wpa_s->prev_scan_ssid != BROADCAST_SSID_SCAN) { while (ssid) { if (ssid == wpa_s->prev_scan_ssid) { ssid = ssid->next; break; } ssid = ssid->next; } } while (ssid) { //MTK_OP01_PROTECT_START #ifdef CONFIG_CMCC_SUPPORT /* CMCC */ if ( #else //MTK_OP01_PROTECT_END if (!ssid->disabled && //MTK_OP01_PROTECT_START #endif //MTK_OP01_PROTECT_END (ssid->scan_ssid || wpa_s->conf->ap_scan == 2)) break; ssid = ssid->next; } if (scan_req != 2 && wpa_s->conf->ap_scan == 2) { /* * ap_scan=2 mode - try to associate with each SSID instead of * scanning for each scan_ssid=1 network. */ if (ssid == NULL) { wpa_printf(MSG_DEBUG, "wpa_supplicant_scan: Reached " "end of scan list - go back to beginning"); wpa_s->prev_scan_ssid = BROADCAST_SSID_SCAN; wpa_supplicant_req_scan(wpa_s, 0, 0); return; } if (ssid->next) { /* Continue from the next SSID on the next attempt. */ wpa_s->prev_scan_ssid = ssid; } else { /* Start from the beginning of the SSID list. */ wpa_s->prev_scan_ssid = BROADCAST_SSID_SCAN; } wpa_supplicant_associate(wpa_s, NULL, ssid); return; } #ifdef CONFIG_WPS wps = wpas_wps_in_use(wpa_s->conf, &req_type); #endif /* CONFIG_WPS */ if (wpa_s->scan_res_tried == 0 && wpa_s->conf->ap_scan == 1 && !wpa_s->use_client_mlme && wps != 2) { wpa_s->scan_res_tried++; wpa_s->scan_req = scan_req; wpa_printf(MSG_DEBUG, "Trying to get current scan results " "first without requesting a new scan to speed up " "initial association"); wpa_supplicant_event(wpa_s, EVENT_SCAN_RESULTS, NULL); return; } #ifdef CONFIG_WPS if (wps) { wps_ie = wps_build_probe_req_ie(wps == 2, &wpa_s->wps->dev, wpa_s->wps->uuid, req_type); if (wps_ie) { extra_ie = wpabuf_head(wps_ie); extra_ie_len = wpabuf_len(wps_ie); } } #endif /* CONFIG_WPS */ wpa_supplicant_notify_scanning(wpa_s, 1); wpa_printf(MSG_DEBUG, "Starting AP scan (%s SSID)", ssid ? "specific": "broadcast"); if (ssid) { wpa_hexdump_ascii(MSG_DEBUG, "Scan SSID", ssid->ssid, ssid->ssid_len); wpa_s->prev_scan_ssid = ssid; } else wpa_s->prev_scan_ssid = BROADCAST_SSID_SCAN; if (wpa_s->use_client_mlme) { ieee80211_sta_set_probe_req_ie(wpa_s, extra_ie, extra_ie_len); ret = ieee80211_sta_req_scan(wpa_s, ssid ? ssid->ssid : NULL, ssid ? ssid->ssid_len : 0); } else { wpa_drv_set_probe_req_ie(wpa_s, extra_ie, extra_ie_len); ret = wpa_drv_scan(wpa_s, &ssid); } wpabuf_free(wps_ie); if (ret) { wpa_printf(MSG_WARNING, "Failed to initiate AP scan."); wpa_supplicant_notify_scanning(wpa_s, 0); wpa_supplicant_req_scan(wpa_s, 10, 0); } else { wpa_s->scan_runs++; } }