events.c
Go to the documentation of this file.
00001 /*
00002  * WPA Supplicant - Driver event processing
00003  * Copyright (c) 2003-2010, Jouni Malinen <j@w1.fi>
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License version 2 as
00007  * published by the Free Software Foundation.
00008  *
00009  * Alternatively, this software may be distributed under the terms of BSD
00010  * license.
00011  *
00012  * See README and COPYING for more details.
00013  */
00014 
00015 #include "includes.h"
00016 
00017 #include "common.h"
00018 #include "eapol_supp/eapol_supp_sm.h"
00019 #include "rsn_supp/wpa.h"
00020 #include "eloop.h"
00021 #include "config.h"
00022 #include "l2_packet/l2_packet.h"
00023 #include "wpa_supplicant_i.h"
00024 #include "driver_i.h"
00025 #include "pcsc_funcs.h"
00026 #include "rsn_supp/preauth.h"
00027 #include "rsn_supp/pmksa_cache.h"
00028 #include "common/wpa_ctrl.h"
00029 #include "eap_peer/eap.h"
00030 #include "ap/hostapd.h"
00031 #include "notify.h"
00032 #include "common/ieee802_11_defs.h"
00033 #include "blacklist.h"
00034 #include "wpas_glue.h"
00035 #include "wps_supplicant.h"
00036 #include "ibss_rsn.h"
00037 #include "sme.h"
00038 #include "bgscan.h"
00039 #include "ap.h"
00040 #include "bss.h"
00041 #include "mlme.h"
00042 #include "scan.h"
00043 
00044 
00045 static int wpa_supplicant_select_config(struct wpa_supplicant *wpa_s)
00046 {
00047         struct wpa_ssid *ssid, *old_ssid;
00048 
00049         if (wpa_s->conf->ap_scan == 1 && wpa_s->current_ssid)
00050                 return 0;
00051 
00052         wpa_printf(MSG_DEBUG, "Select network based on association "
00053                    "information");
00054         ssid = wpa_supplicant_get_ssid(wpa_s);
00055         if (ssid == NULL) {
00056                 wpa_printf(MSG_INFO, "No network configuration found for the "
00057                            "current AP");
00058                 return -1;
00059         }
00060 
00061         if (ssid->disabled) {
00062                 wpa_printf(MSG_DEBUG, "Selected network is disabled");
00063                 return -1;
00064         }
00065 
00066         wpa_printf(MSG_DEBUG, "Network configuration found for the current "
00067                    "AP");
00068         if (ssid->key_mgmt & (WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_IEEE8021X |
00069                               WPA_KEY_MGMT_WPA_NONE |
00070                               WPA_KEY_MGMT_FT_PSK | WPA_KEY_MGMT_FT_IEEE8021X |
00071                               WPA_KEY_MGMT_PSK_SHA256 |
00072                               WPA_KEY_MGMT_IEEE8021X_SHA256)) {
00073                 u8 wpa_ie[80];
00074                 size_t wpa_ie_len = sizeof(wpa_ie);
00075                 wpa_supplicant_set_suites(wpa_s, NULL, ssid,
00076                                           wpa_ie, &wpa_ie_len);
00077         } else {
00078                 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
00079         }
00080 
00081         if (wpa_s->current_ssid && wpa_s->current_ssid != ssid)
00082                 eapol_sm_invalidate_cached_session(wpa_s->eapol);
00083         old_ssid = wpa_s->current_ssid;
00084         wpa_s->current_ssid = ssid;
00085         wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
00086         wpa_supplicant_initiate_eapol(wpa_s);
00087         if (old_ssid != wpa_s->current_ssid)
00088                 wpas_notify_network_changed(wpa_s);
00089 
00090         return 0;
00091 }
00092 
00093 
00094 static void wpa_supplicant_stop_countermeasures(void *eloop_ctx,
00095                                                 void *sock_ctx)
00096 {
00097         struct wpa_supplicant *wpa_s = eloop_ctx;
00098 
00099         if (wpa_s->countermeasures) {
00100                 wpa_s->countermeasures = 0;
00101                 wpa_drv_set_countermeasures(wpa_s, 0);
00102                 wpa_msg(wpa_s, MSG_INFO, "WPA: TKIP countermeasures stopped");
00103                 wpa_supplicant_req_scan(wpa_s, 0, 0);
00104         }
00105 }
00106 
00107 
00108 void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s)
00109 {
00110         int bssid_changed;
00111 
00112         wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
00113         bssid_changed = !is_zero_ether_addr(wpa_s->bssid);
00114         os_memset(wpa_s->bssid, 0, ETH_ALEN);
00115         os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
00116         wpa_s->current_bss = NULL;
00117         if (bssid_changed)
00118                 wpas_notify_bssid_changed(wpa_s);
00119 
00120         eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
00121         eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
00122         if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt))
00123                 eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
00124         wpa_s->ap_ies_from_associnfo = 0;
00125 }
00126 
00127 
00128 static void wpa_find_assoc_pmkid(struct wpa_supplicant *wpa_s)
00129 {
00130         struct wpa_ie_data ie;
00131         int pmksa_set = -1;
00132         size_t i;
00133 
00134         if (wpa_sm_parse_own_wpa_ie(wpa_s->wpa, &ie) < 0 ||
00135             ie.pmkid == NULL)
00136                 return;
00137 
00138         for (i = 0; i < ie.num_pmkid; i++) {
00139                 pmksa_set = pmksa_cache_set_current(wpa_s->wpa,
00140                                                     ie.pmkid + i * PMKID_LEN,
00141                                                     NULL, NULL, 0);
00142                 if (pmksa_set == 0) {
00143                         eapol_sm_notify_pmkid_attempt(wpa_s->eapol, 1);
00144                         break;
00145                 }
00146         }
00147 
00148         wpa_printf(MSG_DEBUG, "RSN: PMKID from assoc IE %sfound from PMKSA "
00149                    "cache", pmksa_set == 0 ? "" : "not ");
00150 }
00151 
00152 
00153 static void wpa_supplicant_event_pmkid_candidate(struct wpa_supplicant *wpa_s,
00154                                                  union wpa_event_data *data)
00155 {
00156         if (data == NULL) {
00157                 wpa_printf(MSG_DEBUG, "RSN: No data in PMKID candidate event");
00158                 return;
00159         }
00160         wpa_printf(MSG_DEBUG, "RSN: PMKID candidate event - bssid=" MACSTR
00161                    " index=%d preauth=%d",
00162                    MAC2STR(data->pmkid_candidate.bssid),
00163                    data->pmkid_candidate.index,
00164                    data->pmkid_candidate.preauth);
00165 
00166         pmksa_candidate_add(wpa_s->wpa, data->pmkid_candidate.bssid,
00167                             data->pmkid_candidate.index,
00168                             data->pmkid_candidate.preauth);
00169 }
00170 
00171 
00172 static int wpa_supplicant_dynamic_keys(struct wpa_supplicant *wpa_s)
00173 {
00174         if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
00175             wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE)
00176                 return 0;
00177 
00178 #ifdef IEEE8021X_EAPOL
00179         if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA &&
00180             wpa_s->current_ssid &&
00181             !(wpa_s->current_ssid->eapol_flags &
00182               (EAPOL_FLAG_REQUIRE_KEY_UNICAST |
00183                EAPOL_FLAG_REQUIRE_KEY_BROADCAST))) {
00184                 /* IEEE 802.1X, but not using dynamic WEP keys (i.e., either
00185                  * plaintext or static WEP keys). */
00186                 return 0;
00187         }
00188 #endif /* IEEE8021X_EAPOL */
00189 
00190         return 1;
00191 }
00192 
00193 
00203 int wpa_supplicant_scard_init(struct wpa_supplicant *wpa_s,
00204                               struct wpa_ssid *ssid)
00205 {
00206 #ifdef IEEE8021X_EAPOL
00207         int aka = 0, sim = 0, type;
00208 
00209         if (ssid->eap.pcsc == NULL || wpa_s->scard != NULL)
00210                 return 0;
00211 
00212         if (ssid->eap.eap_methods == NULL) {
00213                 sim = 1;
00214                 aka = 1;
00215         } else {
00216                 struct eap_method_type *eap = ssid->eap.eap_methods;
00217                 while (eap->vendor != EAP_VENDOR_IETF ||
00218                        eap->method != EAP_TYPE_NONE) {
00219                         if (eap->vendor == EAP_VENDOR_IETF) {
00220                                 if (eap->method == EAP_TYPE_SIM)
00221                                         sim = 1;
00222                                 else if (eap->method == EAP_TYPE_AKA)
00223                                         aka = 1;
00224                         }
00225                         eap++;
00226                 }
00227         }
00228 
00229         if (eap_peer_get_eap_method(EAP_VENDOR_IETF, EAP_TYPE_SIM) == NULL)
00230                 sim = 0;
00231         if (eap_peer_get_eap_method(EAP_VENDOR_IETF, EAP_TYPE_AKA) == NULL)
00232                 aka = 0;
00233 
00234         if (!sim && !aka) {
00235                 wpa_printf(MSG_DEBUG, "Selected network is configured to use "
00236                            "SIM, but neither EAP-SIM nor EAP-AKA are enabled");
00237                 return 0;
00238         }
00239 
00240         wpa_printf(MSG_DEBUG, "Selected network is configured to use SIM "
00241                    "(sim=%d aka=%d) - initialize PCSC", sim, aka);
00242         if (sim && aka)
00243                 type = SCARD_TRY_BOTH;
00244         else if (aka)
00245                 type = SCARD_USIM_ONLY;
00246         else
00247                 type = SCARD_GSM_SIM_ONLY;
00248 
00249         wpa_s->scard = scard_init(type);
00250         if (wpa_s->scard == NULL) {
00251                 wpa_printf(MSG_WARNING, "Failed to initialize SIM "
00252                            "(pcsc-lite)");
00253                 return -1;
00254         }
00255         wpa_sm_set_scard_ctx(wpa_s->wpa, wpa_s->scard);
00256         eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard);
00257 #endif /* IEEE8021X_EAPOL */
00258 
00259         return 0;
00260 }
00261 
00262 
00263 #ifndef CONFIG_NO_SCAN_PROCESSING
00264 static int wpa_supplicant_match_privacy(struct wpa_scan_res *bss,
00265                                         struct wpa_ssid *ssid)
00266 {
00267         int i, privacy = 0;
00268 
00269         if (ssid->mixed_cell)
00270                 return 1;
00271 
00272 #ifdef CONFIG_WPS
00273         if (ssid->key_mgmt & WPA_KEY_MGMT_WPS)
00274                 return 1;
00275 #endif /* CONFIG_WPS */
00276 
00277         for (i = 0; i < NUM_WEP_KEYS; i++) {
00278                 if (ssid->wep_key_len[i]) {
00279                         privacy = 1;
00280                         break;
00281                 }
00282         }
00283 #ifdef IEEE8021X_EAPOL
00284         if ((ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) &&
00285             ssid->eapol_flags & (EAPOL_FLAG_REQUIRE_KEY_UNICAST |
00286                                  EAPOL_FLAG_REQUIRE_KEY_BROADCAST))
00287                 privacy = 1;
00288 #endif /* IEEE8021X_EAPOL */
00289 
00290         if (bss->caps & IEEE80211_CAP_PRIVACY)
00291                 return privacy;
00292         return !privacy;
00293 }
00294 
00295 
00296 static int wpa_supplicant_ssid_bss_match(struct wpa_supplicant *wpa_s,
00297                                          struct wpa_ssid *ssid,
00298                                          struct wpa_scan_res *bss)
00299 {
00300         struct wpa_ie_data ie;
00301         int proto_match = 0;
00302         const u8 *rsn_ie, *wpa_ie;
00303         int ret;
00304 
00305         ret = wpas_wps_ssid_bss_match(wpa_s, ssid, bss);
00306         if (ret >= 0)
00307                 return ret;
00308 
00309         rsn_ie = wpa_scan_get_ie(bss, WLAN_EID_RSN);
00310         while ((ssid->proto & WPA_PROTO_RSN) && rsn_ie) {
00311                 proto_match++;
00312 
00313                 if (wpa_parse_wpa_ie(rsn_ie, 2 + rsn_ie[1], &ie)) {
00314                         wpa_printf(MSG_DEBUG, "   skip RSN IE - parse failed");
00315                         break;
00316                 }
00317                 if (!(ie.proto & ssid->proto)) {
00318                         wpa_printf(MSG_DEBUG, "   skip RSN IE - proto "
00319                                    "mismatch");
00320                         break;
00321                 }
00322 
00323                 if (!(ie.pairwise_cipher & ssid->pairwise_cipher)) {
00324                         wpa_printf(MSG_DEBUG, "   skip RSN IE - PTK cipher "
00325                                    "mismatch");
00326                         break;
00327                 }
00328 
00329                 if (!(ie.group_cipher & ssid->group_cipher)) {
00330                         wpa_printf(MSG_DEBUG, "   skip RSN IE - GTK cipher "
00331                                    "mismatch");
00332                         break;
00333                 }
00334 
00335                 if (!(ie.key_mgmt & ssid->key_mgmt)) {
00336                         wpa_printf(MSG_DEBUG, "   skip RSN IE - key mgmt "
00337                                    "mismatch");
00338                         break;
00339                 }
00340 
00341 #ifdef CONFIG_IEEE80211W
00342                 if (!(ie.capabilities & WPA_CAPABILITY_MFPC) &&
00343                     ssid->ieee80211w == MGMT_FRAME_PROTECTION_REQUIRED) {
00344                         wpa_printf(MSG_DEBUG, "   skip RSN IE - no mgmt frame "
00345                                    "protection");
00346                         break;
00347                 }
00348 #endif /* CONFIG_IEEE80211W */
00349 
00350                 wpa_printf(MSG_DEBUG, "   selected based on RSN IE");
00351                 return 1;
00352         }
00353 
00354         wpa_ie = wpa_scan_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
00355         while ((ssid->proto & WPA_PROTO_WPA) && wpa_ie) {
00356                 proto_match++;
00357 
00358                 if (wpa_parse_wpa_ie(wpa_ie, 2 + wpa_ie[1], &ie)) {
00359                         wpa_printf(MSG_DEBUG, "   skip WPA IE - parse failed");
00360                         break;
00361                 }
00362                 if (!(ie.proto & ssid->proto)) {
00363                         wpa_printf(MSG_DEBUG, "   skip WPA IE - proto "
00364                                    "mismatch");
00365                         break;
00366                 }
00367 
00368                 if (!(ie.pairwise_cipher & ssid->pairwise_cipher)) {
00369                         wpa_printf(MSG_DEBUG, "   skip WPA IE - PTK cipher "
00370                                    "mismatch");
00371                         break;
00372                 }
00373 
00374                 if (!(ie.group_cipher & ssid->group_cipher)) {
00375                         wpa_printf(MSG_DEBUG, "   skip WPA IE - GTK cipher "
00376                                    "mismatch");
00377                         break;
00378                 }
00379 
00380                 if (!(ie.key_mgmt & ssid->key_mgmt)) {
00381                         wpa_printf(MSG_DEBUG, "   skip WPA IE - key mgmt "
00382                                    "mismatch");
00383                         break;
00384                 }
00385 
00386                 wpa_printf(MSG_DEBUG, "   selected based on WPA IE");
00387                 return 1;
00388         }
00389 
00390         if (proto_match == 0)
00391                 wpa_printf(MSG_DEBUG, "   skip - no WPA/RSN proto match");
00392 
00393         return 0;
00394 }
00395 
00396 
00397 static int freq_allowed(int *freqs, int freq)
00398 {
00399         int i;
00400 
00401         if (freqs == NULL)
00402                 return 1;
00403 
00404         for (i = 0; freqs[i]; i++)
00405                 if (freqs[i] == freq)
00406                         return 1;
00407         return 0;
00408 }
00409 
00410 
00411 static struct wpa_bss *
00412 wpa_supplicant_select_bss_wpa(struct wpa_supplicant *wpa_s,
00413                               struct wpa_scan_results *scan_res,
00414                               struct wpa_ssid *group,
00415                               struct wpa_ssid **selected_ssid)
00416 {
00417         struct wpa_ssid *ssid;
00418         struct wpa_scan_res *bss;
00419         size_t i;
00420         struct wpa_blacklist *e;
00421         const u8 *ie;
00422 
00423         wpa_printf(MSG_DEBUG, "Try to find WPA-enabled AP");
00424         for (i = 0; i < scan_res->num; i++) {
00425                 const u8 *ssid_;
00426                 u8 wpa_ie_len, rsn_ie_len, ssid_len;
00427                 bss = scan_res->res[i];
00428 
00429                 ie = wpa_scan_get_ie(bss, WLAN_EID_SSID);
00430                 ssid_ = ie ? ie + 2 : (u8 *) "";
00431                 ssid_len = ie ? ie[1] : 0;
00432 
00433                 ie = wpa_scan_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
00434                 wpa_ie_len = ie ? ie[1] : 0;
00435 
00436                 ie = wpa_scan_get_ie(bss, WLAN_EID_RSN);
00437                 rsn_ie_len = ie ? ie[1] : 0;
00438 
00439                 wpa_printf(MSG_DEBUG, "%d: " MACSTR " ssid='%s' "
00440                            "wpa_ie_len=%u rsn_ie_len=%u caps=0x%x",
00441                            (int) i, MAC2STR(bss->bssid),
00442                            wpa_ssid_txt(ssid_, ssid_len),
00443                            wpa_ie_len, rsn_ie_len, bss->caps);
00444 
00445                 e = wpa_blacklist_get(wpa_s, bss->bssid);
00446                 if (e && e->count > 1) {
00447                         wpa_printf(MSG_DEBUG, "   skip - blacklisted");
00448                         continue;
00449                 }
00450 
00451                 if (ssid_len == 0) {
00452                         wpa_printf(MSG_DEBUG, "   skip - SSID not known");
00453                         continue;
00454                 }
00455 
00456                 if (wpa_ie_len == 0 && rsn_ie_len == 0) {
00457                         wpa_printf(MSG_DEBUG, "   skip - no WPA/RSN IE");
00458                         continue;
00459                 }
00460 
00461                 for (ssid = group; ssid; ssid = ssid->pnext) {
00462                         int check_ssid = 1;
00463 
00464                         if (ssid->disabled) {
00465                                 wpa_printf(MSG_DEBUG, "   skip - disabled");
00466                                 continue;
00467                         }
00468 
00469 #ifdef CONFIG_WPS
00470                         if (ssid->ssid_len == 0 &&
00471                             wpas_wps_ssid_wildcard_ok(wpa_s, ssid, bss))
00472                                 check_ssid = 0;
00473 #endif /* CONFIG_WPS */
00474 
00475                         if (check_ssid &&
00476                             (ssid_len != ssid->ssid_len ||
00477                              os_memcmp(ssid_, ssid->ssid, ssid_len) != 0)) {
00478                                 wpa_printf(MSG_DEBUG, "   skip - "
00479                                            "SSID mismatch");
00480                                 continue;
00481                         }
00482 
00483                         if (ssid->bssid_set &&
00484                             os_memcmp(bss->bssid, ssid->bssid, ETH_ALEN) != 0)
00485                         {
00486                                 wpa_printf(MSG_DEBUG, "   skip - "
00487                                            "BSSID mismatch");
00488                                 continue;
00489                         }
00490 
00491                         if (!wpa_supplicant_ssid_bss_match(wpa_s, ssid, bss))
00492                                 continue;
00493 
00494                         if (!freq_allowed(ssid->freq_list, bss->freq)) {
00495                                 wpa_printf(MSG_DEBUG, "   skip - "
00496                                            "frequency not allowed");
00497                                 continue;
00498                         }
00499 
00500                         wpa_printf(MSG_DEBUG, "   selected WPA AP "
00501                                    MACSTR " ssid='%s'",
00502                                    MAC2STR(bss->bssid),
00503                                    wpa_ssid_txt(ssid_, ssid_len));
00504                         *selected_ssid = ssid;
00505                         return wpa_bss_get(wpa_s, bss->bssid, ssid_, ssid_len);
00506                 }
00507         }
00508 
00509         return NULL;
00510 }
00511 
00512 
00513 static struct wpa_bss *
00514 wpa_supplicant_select_bss_non_wpa(struct wpa_supplicant *wpa_s,
00515                                   struct wpa_scan_results *scan_res,
00516                                   struct wpa_ssid *group,
00517                                   struct wpa_ssid **selected_ssid)
00518 {
00519         struct wpa_ssid *ssid;
00520         struct wpa_scan_res *bss;
00521         size_t i;
00522         struct wpa_blacklist *e;
00523         const u8 *ie;
00524 
00525         wpa_printf(MSG_DEBUG, "Try to find non-WPA AP");
00526         for (i = 0; i < scan_res->num; i++) {
00527                 const u8 *ssid_;
00528                 u8 wpa_ie_len, rsn_ie_len, ssid_len;
00529                 bss = scan_res->res[i];
00530 
00531                 ie = wpa_scan_get_ie(bss, WLAN_EID_SSID);
00532                 ssid_ = ie ? ie + 2 : (u8 *) "";
00533                 ssid_len = ie ? ie[1] : 0;
00534 
00535                 ie = wpa_scan_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
00536                 wpa_ie_len = ie ? ie[1] : 0;
00537 
00538                 ie = wpa_scan_get_ie(bss, WLAN_EID_RSN);
00539                 rsn_ie_len = ie ? ie[1] : 0;
00540 
00541                 wpa_printf(MSG_DEBUG, "%d: " MACSTR " ssid='%s' "
00542                            "wpa_ie_len=%u rsn_ie_len=%u caps=0x%x",
00543                            (int) i, MAC2STR(bss->bssid),
00544                            wpa_ssid_txt(ssid_, ssid_len),
00545                            wpa_ie_len, rsn_ie_len, bss->caps);
00546 
00547                 e = wpa_blacklist_get(wpa_s, bss->bssid);
00548                 if (e && e->count > 1) {
00549                         wpa_printf(MSG_DEBUG, "   skip - blacklisted");
00550                         continue;
00551                 }
00552 
00553                 if (ssid_len == 0) {
00554                         wpa_printf(MSG_DEBUG, "   skip - SSID not known");
00555                         continue;
00556                 }
00557 
00558                 for (ssid = group; ssid; ssid = ssid->pnext) {
00559                         int check_ssid = ssid->ssid_len != 0;
00560 
00561                         if (ssid->disabled) {
00562                                 wpa_printf(MSG_DEBUG, "   skip - disabled");
00563                                 continue;
00564                         }
00565 
00566 #ifdef CONFIG_WPS
00567                         if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
00568                                 /* Only allow wildcard SSID match if an AP
00569                                  * advertises active WPS operation that matches
00570                                  * with our mode. */
00571                                 check_ssid = 1;
00572                                 if (ssid->ssid_len == 0 &&
00573                                     wpas_wps_ssid_wildcard_ok(wpa_s, ssid,
00574                                                               bss))
00575                                         check_ssid = 0;
00576                         }
00577 #endif /* CONFIG_WPS */
00578 
00579                         if (check_ssid &&
00580                             (ssid_len != ssid->ssid_len ||
00581                              os_memcmp(ssid_, ssid->ssid, ssid_len) != 0)) {
00582                                 wpa_printf(MSG_DEBUG, "   skip - "
00583                                            "SSID mismatch");
00584                                 continue;
00585                         }
00586 
00587                         if (ssid->bssid_set &&
00588                             os_memcmp(bss->bssid, ssid->bssid, ETH_ALEN) != 0)
00589                         {
00590                                 wpa_printf(MSG_DEBUG, "   skip - "
00591                                            "BSSID mismatch");
00592                                 continue;
00593                         }
00594 
00595                         if (!(ssid->key_mgmt & WPA_KEY_MGMT_NONE) &&
00596                             !(ssid->key_mgmt & WPA_KEY_MGMT_WPS) &&
00597                             !(ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA))
00598                         {
00599                                 wpa_printf(MSG_DEBUG, "   skip - "
00600                                            "non-WPA network not allowed");
00601                                 continue;
00602                         }
00603 
00604                         if ((ssid->key_mgmt &
00605                              (WPA_KEY_MGMT_IEEE8021X | WPA_KEY_MGMT_PSK |
00606                               WPA_KEY_MGMT_FT_IEEE8021X | WPA_KEY_MGMT_FT_PSK |
00607                               WPA_KEY_MGMT_IEEE8021X_SHA256 |
00608                               WPA_KEY_MGMT_PSK_SHA256)) &&
00609                             (wpa_ie_len != 0 || rsn_ie_len != 0)) {
00610                                 wpa_printf(MSG_DEBUG, "   skip - "
00611                                            "WPA network");
00612                                 continue;
00613                         }
00614 
00615                         if (!wpa_supplicant_match_privacy(bss, ssid)) {
00616                                 wpa_printf(MSG_DEBUG, "   skip - "
00617                                            "privacy mismatch");
00618                                 continue;
00619                         }
00620 
00621                         if (bss->caps & IEEE80211_CAP_IBSS) {
00622                                 wpa_printf(MSG_DEBUG, "   skip - "
00623                                            "IBSS (adhoc) network");
00624                                 continue;
00625                         }
00626 
00627                         if (!freq_allowed(ssid->freq_list, bss->freq)) {
00628                                 wpa_printf(MSG_DEBUG, "   skip - "
00629                                            "frequency not allowed");
00630                                 continue;
00631                         }
00632 
00633                         wpa_printf(MSG_DEBUG, "   selected non-WPA AP "
00634                                    MACSTR " ssid='%s'",
00635                                    MAC2STR(bss->bssid),
00636                                    wpa_ssid_txt(ssid_, ssid_len));
00637                         *selected_ssid = ssid;
00638                         return wpa_bss_get(wpa_s, bss->bssid, ssid_, ssid_len);
00639                 }
00640         }
00641 
00642         return NULL;
00643 }
00644 
00645 
00646 static struct wpa_bss *
00647 wpa_supplicant_select_bss(struct wpa_supplicant *wpa_s,
00648                           struct wpa_scan_results *scan_res,
00649                           struct wpa_ssid *group,
00650                           struct wpa_ssid **selected_ssid)
00651 {
00652         struct wpa_bss *selected;
00653 
00654         wpa_printf(MSG_DEBUG, "Selecting BSS from priority group %d",
00655                    group->priority);
00656 
00657         /* First, try to find WPA-enabled AP */
00658         selected = wpa_supplicant_select_bss_wpa(wpa_s, scan_res, group,
00659                                                  selected_ssid);
00660         if (selected)
00661                 return selected;
00662 
00663         /* If no WPA-enabled AP found, try to find non-WPA AP, if configuration
00664          * allows this. */
00665         return wpa_supplicant_select_bss_non_wpa(wpa_s, scan_res, group,
00666                                                  selected_ssid);
00667 }
00668 
00669 
00670 static struct wpa_bss *
00671 wpa_supplicant_pick_network(struct wpa_supplicant *wpa_s,
00672                             struct wpa_scan_results *scan_res,
00673                             struct wpa_ssid **selected_ssid)
00674 {
00675         struct wpa_bss *selected = NULL;
00676         int prio;
00677 
00678         while (selected == NULL) {
00679                 for (prio = 0; prio < wpa_s->conf->num_prio; prio++) {
00680                         selected = wpa_supplicant_select_bss(
00681                                 wpa_s, scan_res, wpa_s->conf->pssid[prio],
00682                                 selected_ssid);
00683                         if (selected)
00684                                 break;
00685                 }
00686 
00687                 if (selected == NULL && wpa_s->blacklist) {
00688                         wpa_printf(MSG_DEBUG, "No APs found - clear blacklist "
00689                                    "and try again");
00690                         wpa_blacklist_clear(wpa_s);
00691                         wpa_s->blacklist_cleared++;
00692                 } else if (selected == NULL)
00693                         break;
00694         }
00695 
00696         return selected;
00697 }
00698 
00699 
00700 static void wpa_supplicant_req_new_scan(struct wpa_supplicant *wpa_s,
00701                                         int timeout_sec, int timeout_usec)
00702 {
00703         if (wpa_s->scan_res_tried == 1 && wpa_s->conf->ap_scan == 1) {
00704                 /*
00705                  * Quick recovery if the initial scan results were not
00706                  * complete when fetched before the first scan request.
00707                  */
00708                 wpa_s->scan_res_tried++;
00709                 timeout_sec = 0;
00710                 timeout_usec = 0;
00711         } else if (!wpa_supplicant_enabled_networks(wpa_s->conf)) {
00712                 /*
00713                  * No networks are enabled; short-circuit request so
00714                  * we don't wait timeout seconds before transitioning
00715                  * to INACTIVE state.
00716                  */
00717                 wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
00718                 return;
00719         }
00720         wpa_supplicant_req_scan(wpa_s, timeout_sec, timeout_usec);
00721 }
00722 
00723 
00724 void wpa_supplicant_connect(struct wpa_supplicant *wpa_s,
00725                             struct wpa_bss *selected,
00726                             struct wpa_ssid *ssid)
00727 {
00728         if (wpas_wps_scan_pbc_overlap(wpa_s, selected, ssid)) {
00729                 wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_OVERLAP
00730                         "PBC session overlap");
00731                 wpa_supplicant_req_new_scan(wpa_s, 10, 0);
00732                 return;
00733         }
00734 
00735         /*
00736          * Do not trigger new association unless the BSSID has changed or if
00737          * reassociation is requested. If we are in process of associating with
00738          * the selected BSSID, do not trigger new attempt.
00739          */
00740         if (wpa_s->reassociate ||
00741             (os_memcmp(selected->bssid, wpa_s->bssid, ETH_ALEN) != 0 &&
00742              (wpa_s->wpa_state != WPA_ASSOCIATING ||
00743               os_memcmp(selected->bssid, wpa_s->pending_bssid, ETH_ALEN) !=
00744               0))) {
00745                 if (wpa_supplicant_scard_init(wpa_s, ssid)) {
00746                         wpa_supplicant_req_new_scan(wpa_s, 10, 0);
00747                         return;
00748                 }
00749                 wpa_supplicant_associate(wpa_s, selected, ssid);
00750         } else {
00751                 wpa_printf(MSG_DEBUG, "Already associated with the selected "
00752                            "AP");
00753         }
00754 }
00755 
00756 
00757 static struct wpa_ssid *
00758 wpa_supplicant_pick_new_network(struct wpa_supplicant *wpa_s)
00759 {
00760         int prio;
00761         struct wpa_ssid *ssid;
00762 
00763         for (prio = 0; prio < wpa_s->conf->num_prio; prio++) {
00764                 for (ssid = wpa_s->conf->pssid[prio]; ssid; ssid = ssid->pnext)
00765                 {
00766                         if (ssid->disabled)
00767                                 continue;
00768                         if (ssid->mode == IEEE80211_MODE_IBSS ||
00769                             ssid->mode == IEEE80211_MODE_AP)
00770                                 return ssid;
00771                 }
00772         }
00773         return NULL;
00774 }
00775 
00776 
00777 /* TODO: move the rsn_preauth_scan_result*() to be called from notify.c based
00778  * on BSS added and BSS changed events */
00779 static void wpa_supplicant_rsn_preauth_scan_results(
00780         struct wpa_supplicant *wpa_s, struct wpa_scan_results *scan_res)
00781 {
00782         int i;
00783 
00784         if (rsn_preauth_scan_results(wpa_s->wpa) < 0)
00785                 return;
00786 
00787         for (i = scan_res->num - 1; i >= 0; i--) {
00788                 const u8 *ssid, *rsn;
00789                 struct wpa_scan_res *r;
00790 
00791                 r = scan_res->res[i];
00792 
00793                 ssid = wpa_scan_get_ie(r, WLAN_EID_SSID);
00794                 if (ssid == NULL)
00795                         continue;
00796 
00797                 rsn = wpa_scan_get_ie(r, WLAN_EID_RSN);
00798                 if (rsn == NULL)
00799                         continue;
00800 
00801                 rsn_preauth_scan_result(wpa_s->wpa, r->bssid, ssid, rsn);
00802         }
00803 
00804 }
00805 
00806 
00807 static int wpa_supplicant_need_to_roam(struct wpa_supplicant *wpa_s,
00808                                        struct wpa_bss *selected,
00809                                        struct wpa_ssid *ssid,
00810                                        struct wpa_scan_results *scan_res)
00811 {
00812         size_t i;
00813         struct wpa_scan_res *current_bss = NULL;
00814         int min_diff;
00815 
00816         if (wpa_s->reassociate)
00817                 return 1; /* explicit request to reassociate */
00818         if (wpa_s->wpa_state < WPA_ASSOCIATED)
00819                 return 1; /* we are not associated; continue */
00820         if (wpa_s->current_ssid == NULL)
00821                 return 1; /* unknown current SSID */
00822         if (wpa_s->current_ssid != ssid)
00823                 return 1; /* different network block */
00824 
00825         for (i = 0; i < scan_res->num; i++) {
00826                 struct wpa_scan_res *res = scan_res->res[i];
00827                 const u8 *ie;
00828                 if (os_memcmp(res->bssid, wpa_s->bssid, ETH_ALEN) != 0)
00829                         continue;
00830 
00831                 ie = wpa_scan_get_ie(res, WLAN_EID_SSID);
00832                 if (ie == NULL)
00833                         continue;
00834                 if (ie[1] != wpa_s->current_ssid->ssid_len ||
00835                     os_memcmp(ie + 2, wpa_s->current_ssid->ssid, ie[1]) != 0)
00836                         continue;
00837                 current_bss = res;
00838                 break;
00839         }
00840 
00841         if (!current_bss)
00842                 return 1; /* current BSS not seen in scan results */
00843 
00844         wpa_printf(MSG_DEBUG, "Considering within-ESS reassociation");
00845         wpa_printf(MSG_DEBUG, "Current BSS: " MACSTR " level=%d",
00846                    MAC2STR(current_bss->bssid), current_bss->level);
00847         wpa_printf(MSG_DEBUG, "Selected BSS: " MACSTR " level=%d",
00848                    MAC2STR(selected->bssid), selected->level);
00849 
00850         if (wpa_s->current_ssid->bssid_set &&
00851             os_memcmp(selected->bssid, wpa_s->current_ssid->bssid, ETH_ALEN) ==
00852             0) {
00853                 wpa_printf(MSG_DEBUG, "Allow reassociation - selected BSS has "
00854                            "preferred BSSID");
00855                 return 1;
00856         }
00857 
00858         min_diff = 2;
00859         if (current_bss->level < 0) {
00860                 if (current_bss->level < -85)
00861                         min_diff = 1;
00862                 else if (current_bss->level < -80)
00863                         min_diff = 2;
00864                 else if (current_bss->level < -75)
00865                         min_diff = 3;
00866                 else if (current_bss->level < -70)
00867                         min_diff = 4;
00868                 else
00869                         min_diff = 5;
00870         }
00871         if (abs(current_bss->level - selected->level) < min_diff) {
00872                 wpa_printf(MSG_DEBUG, "Skip roam - too small difference in "
00873                            "signal level");
00874                 return 0;
00875         }
00876 
00877         return 1;
00878 }
00879 
00880 
00881 static void wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
00882                                               union wpa_event_data *data)
00883 {
00884         struct wpa_bss *selected;
00885         struct wpa_ssid *ssid = NULL;
00886         struct wpa_scan_results *scan_res;
00887 
00888         wpa_supplicant_notify_scanning(wpa_s, 0);
00889 
00890         scan_res = wpa_supplicant_get_scan_results(wpa_s,
00891                                                    data ? &data->scan_info :
00892                                                    NULL, 1);
00893         if (scan_res == NULL) {
00894                 if (wpa_s->conf->ap_scan == 2)
00895                         return;
00896                 wpa_printf(MSG_DEBUG, "Failed to get scan results - try "
00897                            "scanning again");
00898                 wpa_supplicant_req_new_scan(wpa_s, 1, 0);
00899                 return;
00900         }
00901 
00902         if (wpa_s->scan_res_handler) {
00903                 wpa_s->scan_res_handler(wpa_s, scan_res);
00904                 wpa_s->scan_res_handler = NULL;
00905                 wpa_scan_results_free(scan_res);
00906                 return;
00907         }
00908 
00909         /*
00910          * Don't post the results if this was the initial cached
00911          * and there were no results.
00912          */
00913         if (wpa_s->scan_res_tried == 1 && wpa_s->conf->ap_scan == 1 &&
00914             scan_res->num == 0) {
00915                 wpa_msg(wpa_s, MSG_DEBUG, "Cached scan results are "
00916                         "empty - not posting");
00917         } else {
00918                 wpa_printf(MSG_DEBUG, "New scan results available");
00919                 wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SCAN_RESULTS);
00920                 wpas_notify_scan_results(wpa_s);
00921         }
00922 
00923         wpas_notify_scan_done(wpa_s, 1);
00924 
00925         if ((wpa_s->conf->ap_scan == 2 && !wpas_wps_searching(wpa_s))) {
00926                 wpa_scan_results_free(scan_res);
00927                 return;
00928         }
00929 
00930         if (wpa_s->disconnected) {
00931                 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
00932                 wpa_scan_results_free(scan_res);
00933                 return;
00934         }
00935 
00936         if (bgscan_notify_scan(wpa_s) == 1) {
00937                 wpa_scan_results_free(scan_res);
00938                 return;
00939         }
00940 
00941         wpa_supplicant_rsn_preauth_scan_results(wpa_s, scan_res);
00942 
00943         selected = wpa_supplicant_pick_network(wpa_s, scan_res, &ssid);
00944 
00945         if (selected) {
00946                 int skip;
00947                 wpa_s->more_bss_to_try = 1;
00948                 skip = !wpa_supplicant_need_to_roam(wpa_s, selected, ssid,
00949                                                     scan_res);
00950                 wpa_scan_results_free(scan_res);
00951                 if (skip)
00952                         return;
00953                 wpa_supplicant_connect(wpa_s, selected, ssid);
00954         } else {
00955                 wpa_s->more_bss_to_try = 0;
00956                 wpa_scan_results_free(scan_res);
00957                 wpa_printf(MSG_DEBUG, "No suitable network found");
00958                 ssid = wpa_supplicant_pick_new_network(wpa_s);
00959                 if (ssid) {
00960                         wpa_printf(MSG_DEBUG, "Setup a new network");
00961                         wpa_supplicant_associate(wpa_s, NULL, ssid);
00962                 } else {
00963                         int timeout_sec = 1;
00964                         int timeout_usec = 0;
00965                         wpa_supplicant_req_new_scan(wpa_s, timeout_sec,
00966                                                     timeout_usec);
00967                 }
00968         }
00969 }
00970 #endif /* CONFIG_NO_SCAN_PROCESSING */
00971 
00972 
00973 static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s,
00974                                           union wpa_event_data *data)
00975 {
00976         int l, len, found = 0, wpa_found, rsn_found;
00977         const u8 *p;
00978 
00979         wpa_printf(MSG_DEBUG, "Association info event");
00980         if (data->assoc_info.req_ies)
00981                 wpa_hexdump(MSG_DEBUG, "req_ies", data->assoc_info.req_ies,
00982                             data->assoc_info.req_ies_len);
00983         if (data->assoc_info.resp_ies)
00984                 wpa_hexdump(MSG_DEBUG, "resp_ies", data->assoc_info.resp_ies,
00985                             data->assoc_info.resp_ies_len);
00986         if (data->assoc_info.beacon_ies)
00987                 wpa_hexdump(MSG_DEBUG, "beacon_ies",
00988                             data->assoc_info.beacon_ies,
00989                             data->assoc_info.beacon_ies_len);
00990         if (data->assoc_info.freq)
00991                 wpa_printf(MSG_DEBUG, "freq=%u MHz", data->assoc_info.freq);
00992 
00993         p = data->assoc_info.req_ies;
00994         l = data->assoc_info.req_ies_len;
00995 
00996         /* Go through the IEs and make a copy of the WPA/RSN IE, if present. */
00997         while (p && l >= 2) {
00998                 len = p[1] + 2;
00999                 if (len > l) {
01000                         wpa_hexdump(MSG_DEBUG, "Truncated IE in assoc_info",
01001                                     p, l);
01002                         break;
01003                 }
01004                 if ((p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 6 &&
01005                      (os_memcmp(&p[2], "\x00\x50\xF2\x01\x01\x00", 6) == 0)) ||
01006                     (p[0] == WLAN_EID_RSN && p[1] >= 2)) {
01007                         if (wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, p, len))
01008                                 break;
01009                         found = 1;
01010                         wpa_find_assoc_pmkid(wpa_s);
01011                         break;
01012                 }
01013                 l -= len;
01014                 p += len;
01015         }
01016         if (!found && data->assoc_info.req_ies)
01017                 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
01018 
01019 #ifdef CONFIG_IEEE80211R
01020 #ifdef CONFIG_SME
01021         if (wpa_s->sme.auth_alg == WPA_AUTH_ALG_FT) {
01022                 u8 bssid[ETH_ALEN];
01023                 if (wpa_drv_get_bssid(wpa_s, bssid) < 0 ||
01024                     wpa_ft_validate_reassoc_resp(wpa_s->wpa,
01025                                                  data->assoc_info.resp_ies,
01026                                                  data->assoc_info.resp_ies_len,
01027                                                  bssid) < 0) {
01028                         wpa_printf(MSG_DEBUG, "FT: Validation of "
01029                                    "Reassociation Response failed");
01030                         wpa_supplicant_deauthenticate(
01031                                 wpa_s, WLAN_REASON_INVALID_IE);
01032                         return -1;
01033                 }
01034         }
01035 
01036         p = data->assoc_info.resp_ies;
01037         l = data->assoc_info.resp_ies_len;
01038 
01039         /* Go through the IEs and make a copy of the MDIE, if present. */
01040         while (p && l >= 2) {
01041                 len = p[1] + 2;
01042                 if (len > l) {
01043                         wpa_hexdump(MSG_DEBUG, "Truncated IE in assoc_info",
01044                                     p, l);
01045                         break;
01046                 }
01047                 if (p[0] == WLAN_EID_MOBILITY_DOMAIN &&
01048                     p[1] >= MOBILITY_DOMAIN_ID_LEN) {
01049                         wpa_s->sme.ft_used = 1;
01050                         os_memcpy(wpa_s->sme.mobility_domain, p + 2,
01051                                   MOBILITY_DOMAIN_ID_LEN);
01052                         break;
01053                 }
01054                 l -= len;
01055                 p += len;
01056         }
01057 #endif /* CONFIG_SME */
01058 
01059         wpa_sm_set_ft_params(wpa_s->wpa, data->assoc_info.resp_ies,
01060                              data->assoc_info.resp_ies_len);
01061 #endif /* CONFIG_IEEE80211R */
01062 
01063         /* WPA/RSN IE from Beacon/ProbeResp */
01064         p = data->assoc_info.beacon_ies;
01065         l = data->assoc_info.beacon_ies_len;
01066 
01067         /* Go through the IEs and make a copy of the WPA/RSN IEs, if present.
01068          */
01069         wpa_found = rsn_found = 0;
01070         while (p && l >= 2) {
01071                 len = p[1] + 2;
01072                 if (len > l) {
01073                         wpa_hexdump(MSG_DEBUG, "Truncated IE in beacon_ies",
01074                                     p, l);
01075                         break;
01076                 }
01077                 if (!wpa_found &&
01078                     p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 6 &&
01079                     os_memcmp(&p[2], "\x00\x50\xF2\x01\x01\x00", 6) == 0) {
01080                         wpa_found = 1;
01081                         wpa_sm_set_ap_wpa_ie(wpa_s->wpa, p, len);
01082                 }
01083 
01084                 if (!rsn_found &&
01085                     p[0] == WLAN_EID_RSN && p[1] >= 2) {
01086                         rsn_found = 1;
01087                         wpa_sm_set_ap_rsn_ie(wpa_s->wpa, p, len);
01088                 }
01089 
01090                 l -= len;
01091                 p += len;
01092         }
01093 
01094         if (!wpa_found && data->assoc_info.beacon_ies)
01095                 wpa_sm_set_ap_wpa_ie(wpa_s->wpa, NULL, 0);
01096         if (!rsn_found && data->assoc_info.beacon_ies)
01097                 wpa_sm_set_ap_rsn_ie(wpa_s->wpa, NULL, 0);
01098         if (wpa_found || rsn_found)
01099                 wpa_s->ap_ies_from_associnfo = 1;
01100 
01101         wpa_s->assoc_freq = data->assoc_info.freq;
01102 
01103         return 0;
01104 }
01105 
01106 
01107 static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
01108                                        union wpa_event_data *data)
01109 {
01110         u8 bssid[ETH_ALEN];
01111         int ft_completed;
01112         int bssid_changed;
01113         struct wpa_driver_capa capa;
01114 
01115 #ifdef CONFIG_AP
01116         if (wpa_s->ap_iface) {
01117                 hostapd_notif_assoc(wpa_s->ap_iface->bss[0],
01118                                     data->assoc_info.addr,
01119                                     data->assoc_info.req_ies,
01120                                     data->assoc_info.req_ies_len);
01121                 return;
01122         }
01123 #endif /* CONFIG_AP */
01124 
01125         ft_completed = wpa_ft_is_completed(wpa_s->wpa);
01126         if (data && wpa_supplicant_event_associnfo(wpa_s, data) < 0)
01127                 return;
01128 
01129         wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATED);
01130         if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME)
01131                 os_memcpy(bssid, wpa_s->bssid, ETH_ALEN);
01132         if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) ||
01133             (wpa_drv_get_bssid(wpa_s, bssid) >= 0 &&
01134              os_memcmp(bssid, wpa_s->bssid, ETH_ALEN) != 0)) {
01135                 wpa_msg(wpa_s, MSG_DEBUG, "Associated to a new BSS: BSSID="
01136                         MACSTR, MAC2STR(bssid));
01137                 bssid_changed = os_memcmp(wpa_s->bssid, bssid, ETH_ALEN);
01138                 os_memcpy(wpa_s->bssid, bssid, ETH_ALEN);
01139                 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
01140                 if (bssid_changed)
01141                         wpas_notify_bssid_changed(wpa_s);
01142 
01143                 if (wpa_supplicant_dynamic_keys(wpa_s) && !ft_completed) {
01144                         wpa_clear_keys(wpa_s, bssid);
01145                 }
01146                 if (wpa_supplicant_select_config(wpa_s) < 0) {
01147                         wpa_supplicant_disassociate(
01148                                 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
01149                         return;
01150                 }
01151                 if (wpa_s->current_ssid) {
01152                         struct wpa_bss *bss = NULL;
01153                         struct wpa_ssid *ssid = wpa_s->current_ssid;
01154                         if (ssid->ssid_len > 0)
01155                                 bss = wpa_bss_get(wpa_s, bssid,
01156                                                   ssid->ssid, ssid->ssid_len);
01157                         if (!bss)
01158                                 bss = wpa_bss_get_bssid(wpa_s, bssid);
01159                         if (bss)
01160                                 wpa_s->current_bss = bss;
01161                 }
01162         }
01163 
01164 #ifdef CONFIG_SME
01165         os_memcpy(wpa_s->sme.prev_bssid, bssid, ETH_ALEN);
01166         wpa_s->sme.prev_bssid_set = 1;
01167 #endif /* CONFIG_SME */
01168 
01169         wpa_msg(wpa_s, MSG_INFO, "Associated with " MACSTR, MAC2STR(bssid));
01170         if (wpa_s->current_ssid) {
01171                 /* When using scanning (ap_scan=1), SIM PC/SC interface can be
01172                  * initialized before association, but for other modes,
01173                  * initialize PC/SC here, if the current configuration needs
01174                  * smartcard or SIM/USIM. */
01175                 wpa_supplicant_scard_init(wpa_s, wpa_s->current_ssid);
01176         }
01177         wpa_sm_notify_assoc(wpa_s->wpa, bssid);
01178         l2_packet_notify_auth_start(wpa_s->l2);
01179 
01180         /*
01181          * Set portEnabled first to FALSE in order to get EAP state machine out
01182          * of the SUCCESS state and eapSuccess cleared. Without this, EAPOL PAE
01183          * state machine may transit to AUTHENTICATING state based on obsolete
01184          * eapSuccess and then trigger BE_AUTH to SUCCESS and PAE to
01185          * AUTHENTICATED without ever giving chance to EAP state machine to
01186          * reset the state.
01187          */
01188         if (!ft_completed) {
01189                 eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
01190                 eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
01191         }
01192         if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) || ft_completed)
01193                 eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
01194         /* 802.1X::portControl = Auto */
01195         eapol_sm_notify_portEnabled(wpa_s->eapol, TRUE);
01196         wpa_s->eapol_received = 0;
01197         if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
01198             wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE ||
01199             (wpa_s->current_ssid &&
01200              wpa_s->current_ssid->mode == IEEE80211_MODE_IBSS)) {
01201                 wpa_supplicant_cancel_auth_timeout(wpa_s);
01202                 wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
01203         } else if (!ft_completed) {
01204                 /* Timeout for receiving the first EAPOL packet */
01205                 wpa_supplicant_req_auth_timeout(wpa_s, 10, 0);
01206         }
01207         wpa_supplicant_cancel_scan(wpa_s);
01208 
01209         if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
01210             wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) {
01211                 /*
01212                  * We are done; the driver will take care of RSN 4-way
01213                  * handshake.
01214                  */
01215                 wpa_supplicant_cancel_auth_timeout(wpa_s);
01216                 wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
01217                 eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
01218                 eapol_sm_notify_eap_success(wpa_s->eapol, TRUE);
01219         }
01220 
01221         if (wpa_s->pending_eapol_rx) {
01222                 struct os_time now, age;
01223                 os_get_time(&now);
01224                 os_time_sub(&now, &wpa_s->pending_eapol_rx_time, &age);
01225                 if (age.sec == 0 && age.usec < 100000 &&
01226                     os_memcmp(wpa_s->pending_eapol_rx_src, bssid, ETH_ALEN) ==
01227                     0) {
01228                         wpa_printf(MSG_DEBUG, "Process pending EAPOL frame "
01229                                    "that was received just before association "
01230                                    "notification");
01231                         wpa_supplicant_rx_eapol(
01232                                 wpa_s, wpa_s->pending_eapol_rx_src,
01233                                 wpabuf_head(wpa_s->pending_eapol_rx),
01234                                 wpabuf_len(wpa_s->pending_eapol_rx));
01235                 }
01236                 wpabuf_free(wpa_s->pending_eapol_rx);
01237                 wpa_s->pending_eapol_rx = NULL;
01238         }
01239 
01240 #ifdef CONFIG_BGSCAN
01241         if (wpa_s->current_ssid != wpa_s->bgscan_ssid) {
01242                 bgscan_deinit(wpa_s);
01243                 if (wpa_s->current_ssid && wpa_s->current_ssid->bgscan) {
01244                         if (bgscan_init(wpa_s, wpa_s->current_ssid)) {
01245                                 wpa_printf(MSG_DEBUG, "Failed to initialize "
01246                                            "bgscan");
01247                                 /*
01248                                  * Live without bgscan; it is only used as a
01249                                  * roaming optimization, so the initial
01250                                  * connection is not affected.
01251                                  */
01252                         } else
01253                                 wpa_s->bgscan_ssid = wpa_s->current_ssid;
01254                 } else
01255                         wpa_s->bgscan_ssid = NULL;
01256         }
01257 #endif /* CONFIG_BGSCAN */
01258 
01259         if ((wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
01260              wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) &&
01261             wpa_s->current_ssid && wpa_drv_get_capa(wpa_s, &capa) == 0 &&
01262             capa.flags & WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC_DONE) {
01263                 /* Set static WEP keys again */
01264                 wpa_set_wep_keys(wpa_s, wpa_s->current_ssid);
01265         }
01266 }
01267 
01268 
01269 static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s,
01270                                           u16 reason_code)
01271 {
01272         const u8 *bssid;
01273 #ifdef CONFIG_SME
01274         int authenticating;
01275         u8 prev_pending_bssid[ETH_ALEN];
01276 
01277         authenticating = wpa_s->wpa_state == WPA_AUTHENTICATING;
01278         os_memcpy(prev_pending_bssid, wpa_s->pending_bssid, ETH_ALEN);
01279 #endif /* CONFIG_SME */
01280 
01281         if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
01282                 /*
01283                  * At least Host AP driver and a Prism3 card seemed to be
01284                  * generating streams of disconnected events when configuring
01285                  * IBSS for WPA-None. Ignore them for now.
01286                  */
01287                 wpa_printf(MSG_DEBUG, "Disconnect event - ignore in "
01288                            "IBSS/WPA-None mode");
01289                 return;
01290         }
01291 
01292         if (wpa_s->wpa_state == WPA_4WAY_HANDSHAKE &&
01293             wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) {
01294                 wpa_msg(wpa_s, MSG_INFO, "WPA: 4-Way Handshake failed - "
01295                         "pre-shared key may be incorrect");
01296         }
01297         if (wpa_s->wpa_state >= WPA_ASSOCIATED)
01298                 wpa_supplicant_req_scan(wpa_s, 0, 100000);
01299         bssid = wpa_s->bssid;
01300         if (is_zero_ether_addr(bssid))
01301                 bssid = wpa_s->pending_bssid;
01302         wpa_blacklist_add(wpa_s, bssid);
01303         wpa_sm_notify_disassoc(wpa_s->wpa);
01304         wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "bssid=" MACSTR
01305                 " reason=%d",
01306                 MAC2STR(bssid), reason_code);
01307         if (wpa_supplicant_dynamic_keys(wpa_s)) {
01308                 wpa_printf(MSG_DEBUG, "Disconnect event - remove keys");
01309                 wpa_s->keys_cleared = 0;
01310                 wpa_clear_keys(wpa_s, wpa_s->bssid);
01311         }
01312         wpa_supplicant_mark_disassoc(wpa_s);
01313         bgscan_deinit(wpa_s);
01314 #ifdef CONFIG_SME
01315 //      if (authenticating &&
01316 //          (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)) {
01317 //              /*
01318 //               * mac80211-workaround to force deauth on failed auth cmd,
01319 //               * requires us to remain in authenticating state to allow the
01320 //               * second authentication attempt to be continued properly.
01321 //               */
01322 //              wpa_printf(MSG_DEBUG, "SME: Allow pending authentication to "
01323 //                         "proceed after disconnection event");
01324 //              wpa_supplicant_set_state(wpa_s, WPA_AUTHENTICATING);
01325 //              os_memcpy(wpa_s->pending_bssid, prev_pending_bssid, ETH_ALEN);
01326 //      }
01327 #endif /* CONFIG_SME */
01328 }
01329 
01330 
01331 #ifdef CONFIG_DELAYED_MIC_ERROR_REPORT
01332 static void wpa_supplicant_delayed_mic_error_report(void *eloop_ctx,
01333                                                     void *sock_ctx)
01334 {
01335         struct wpa_supplicant *wpa_s = eloop_ctx;
01336 
01337         if (!wpa_s->pending_mic_error_report)
01338                 return;
01339 
01340         wpa_printf(MSG_DEBUG, "WPA: Sending pending MIC error report");
01341         wpa_sm_key_request(wpa_s->wpa, 1, wpa_s->pending_mic_error_pairwise);
01342         wpa_s->pending_mic_error_report = 0;
01343 }
01344 #endif /* CONFIG_DELAYED_MIC_ERROR_REPORT */
01345 
01346 
01347 static void
01348 wpa_supplicant_event_michael_mic_failure(struct wpa_supplicant *wpa_s,
01349                                          union wpa_event_data *data)
01350 {
01351         int pairwise;
01352         struct os_time t;
01353 
01354         wpa_msg(wpa_s, MSG_WARNING, "Michael MIC failure detected");
01355         pairwise = (data && data->michael_mic_failure.unicast);
01356         os_get_time(&t);
01357         if ((wpa_s->last_michael_mic_error &&
01358              t.sec - wpa_s->last_michael_mic_error <= 60) ||
01359             wpa_s->pending_mic_error_report) {
01360                 if (wpa_s->pending_mic_error_report) {
01361                         /*
01362                          * Send the pending MIC error report immediately since
01363                          * we are going to start countermeasures and AP better
01364                          * do the same.
01365                          */
01366                         wpa_sm_key_request(wpa_s->wpa, 1,
01367                                            wpa_s->pending_mic_error_pairwise);
01368                 }
01369 
01370                 /* Send the new MIC error report immediately since we are going
01371                  * to start countermeasures and AP better do the same.
01372                  */
01373                 wpa_sm_key_request(wpa_s->wpa, 1, pairwise);
01374 
01375                 /* initialize countermeasures */
01376                 wpa_s->countermeasures = 1;
01377                 wpa_msg(wpa_s, MSG_WARNING, "TKIP countermeasures started");
01378 
01379                 /*
01380                  * Need to wait for completion of request frame. We do not get
01381                  * any callback for the message completion, so just wait a
01382                  * short while and hope for the best. */
01383                 os_sleep(0, 10000);
01384 
01385                 wpa_drv_set_countermeasures(wpa_s, 1);
01386                 wpa_supplicant_deauthenticate(wpa_s,
01387                                               WLAN_REASON_MICHAEL_MIC_FAILURE);
01388                 eloop_cancel_timeout(wpa_supplicant_stop_countermeasures,
01389                                      wpa_s, NULL);
01390                 eloop_register_timeout(60, 0,
01391                                        wpa_supplicant_stop_countermeasures,
01392                                        wpa_s, NULL);
01393                 /* TODO: mark the AP rejected for 60 second. STA is
01394                  * allowed to associate with another AP.. */
01395         } else {
01396 #ifdef CONFIG_DELAYED_MIC_ERROR_REPORT
01397                 if (wpa_s->mic_errors_seen) {
01398                         /*
01399                          * Reduce the effectiveness of Michael MIC error
01400                          * reports as a means for attacking against TKIP if
01401                          * more than one MIC failure is noticed with the same
01402                          * PTK. We delay the transmission of the reports by a
01403                          * random time between 0 and 60 seconds in order to
01404                          * force the attacker wait 60 seconds before getting
01405                          * the information on whether a frame resulted in a MIC
01406                          * failure.
01407                          */
01408                         u8 rval[4];
01409                         int sec;
01410 
01411                         if (os_get_random(rval, sizeof(rval)) < 0)
01412                                 sec = os_random() % 60;
01413                         else
01414                                 sec = WPA_GET_BE32(rval) % 60;
01415                         wpa_printf(MSG_DEBUG, "WPA: Delay MIC error report %d "
01416                                    "seconds", sec);
01417                         wpa_s->pending_mic_error_report = 1;
01418                         wpa_s->pending_mic_error_pairwise = pairwise;
01419                         eloop_cancel_timeout(
01420                                 wpa_supplicant_delayed_mic_error_report,
01421                                 wpa_s, NULL);
01422                         eloop_register_timeout(
01423                                 sec, os_random() % 1000000,
01424                                 wpa_supplicant_delayed_mic_error_report,
01425                                 wpa_s, NULL);
01426                 } else {
01427                         wpa_sm_key_request(wpa_s->wpa, 1, pairwise);
01428                 }
01429 #else /* CONFIG_DELAYED_MIC_ERROR_REPORT */
01430                 wpa_sm_key_request(wpa_s->wpa, 1, pairwise);
01431 #endif /* CONFIG_DELAYED_MIC_ERROR_REPORT */
01432         }
01433         wpa_s->last_michael_mic_error = t.sec;
01434         wpa_s->mic_errors_seen++;
01435 }
01436 
01437 
01438 #ifdef CONFIG_TERMINATE_ONLASTIF
01439 static int any_interfaces(struct wpa_supplicant *head)
01440 {
01441         struct wpa_supplicant *wpa_s;
01442 
01443         for (wpa_s = head; wpa_s != NULL; wpa_s = wpa_s->next)
01444                 if (!wpa_s->interface_removed)
01445                         return 1;
01446         return 0;
01447 }
01448 #endif /* CONFIG_TERMINATE_ONLASTIF */
01449 
01450 
01451 static void
01452 wpa_supplicant_event_interface_status(struct wpa_supplicant *wpa_s,
01453                                       union wpa_event_data *data)
01454 {
01455         if (os_strcmp(wpa_s->ifname, data->interface_status.ifname) != 0)
01456                 return;
01457 
01458         switch (data->interface_status.ievent) {
01459         case EVENT_INTERFACE_ADDED:
01460                 if (!wpa_s->interface_removed)
01461                         break;
01462                 wpa_s->interface_removed = 0;
01463                 wpa_printf(MSG_DEBUG, "Configured interface was added.");
01464                 if (wpa_supplicant_driver_init(wpa_s) < 0) {
01465                         wpa_printf(MSG_INFO, "Failed to initialize the driver "
01466                                    "after interface was added.");
01467                 }
01468                 break;
01469         case EVENT_INTERFACE_REMOVED:
01470                 wpa_printf(MSG_DEBUG, "Configured interface was removed.");
01471                 wpa_s->interface_removed = 1;
01472                 wpa_supplicant_mark_disassoc(wpa_s);
01473                 l2_packet_deinit(wpa_s->l2);
01474                 wpa_s->l2 = NULL;
01475 #ifdef CONFIG_TERMINATE_ONLASTIF
01476                 /* check if last interface */
01477                 if (!any_interfaces(wpa_s->global->ifaces))
01478                         eloop_terminate();
01479 #endif /* CONFIG_TERMINATE_ONLASTIF */
01480                 break;
01481         }
01482 }
01483 
01484 
01485 #ifdef CONFIG_PEERKEY
01486 static void
01487 wpa_supplicant_event_stkstart(struct wpa_supplicant *wpa_s,
01488                               union wpa_event_data *data)
01489 {
01490         if (data == NULL)
01491                 return;
01492         wpa_sm_stkstart(wpa_s->wpa, data->stkstart.peer);
01493 }
01494 #endif /* CONFIG_PEERKEY */
01495 
01496 
01497 #ifdef CONFIG_IEEE80211R
01498 static void
01499 wpa_supplicant_event_ft_response(struct wpa_supplicant *wpa_s,
01500                                  union wpa_event_data *data)
01501 {
01502         if (data == NULL)
01503                 return;
01504 
01505         if (wpa_ft_process_response(wpa_s->wpa, data->ft_ies.ies,
01506                                     data->ft_ies.ies_len,
01507                                     data->ft_ies.ft_action,
01508                                     data->ft_ies.target_ap,
01509                                     data->ft_ies.ric_ies,
01510                                     data->ft_ies.ric_ies_len) < 0) {
01511                 /* TODO: prevent MLME/driver from trying to associate? */
01512         }
01513 }
01514 #endif /* CONFIG_IEEE80211R */
01515 
01516 
01517 #ifdef CONFIG_IBSS_RSN
01518 static void wpa_supplicant_event_ibss_rsn_start(struct wpa_supplicant *wpa_s,
01519                                                 union wpa_event_data *data)
01520 {
01521         if (data == NULL)
01522                 return;
01523         ibss_rsn_start(wpa_s->ibss_rsn, data->ibss_rsn_start.peer);
01524 }
01525 #endif /* CONFIG_IBSS_RSN */
01526 
01527 
01528 #ifdef CONFIG_IEEE80211R
01529 static void ft_rx_action(struct wpa_supplicant *wpa_s, const u8 *data,
01530                          size_t len)
01531 {
01532         const u8 *sta_addr, *target_ap_addr;
01533         u16 status;
01534 
01535         wpa_hexdump(MSG_MSGDUMP, "FT: RX Action", data, len);
01536         if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME))
01537                 return; /* only SME case supported for now */
01538         if (len < 1 + 2 * ETH_ALEN + 2)
01539                 return;
01540         if (data[0] != 2)
01541                 return; /* Only FT Action Response is supported for now */
01542         sta_addr = data + 1;
01543         target_ap_addr = data + 1 + ETH_ALEN;
01544         status = WPA_GET_LE16(data + 1 + 2 * ETH_ALEN);
01545         wpa_printf(MSG_DEBUG, "FT: Received FT Action Response: STA " MACSTR
01546                    " TargetAP " MACSTR " status %u",
01547                    MAC2STR(sta_addr), MAC2STR(target_ap_addr), status);
01548 
01549         if (os_memcmp(sta_addr, wpa_s->own_addr, ETH_ALEN) != 0) {
01550                 wpa_printf(MSG_DEBUG, "FT: Foreign STA Address " MACSTR
01551                            " in FT Action Response", MAC2STR(sta_addr));
01552                 return;
01553         }
01554 
01555         if (status) {
01556                 wpa_printf(MSG_DEBUG, "FT: FT Action Response indicates "
01557                            "failure (status code %d)", status);
01558                 /* TODO: report error to FT code(?) */
01559                 return;
01560         }
01561 
01562         if (wpa_ft_process_response(wpa_s->wpa, data + 1 + 2 * ETH_ALEN + 2,
01563                                     len - (1 + 2 * ETH_ALEN + 2), 1,
01564                                     target_ap_addr, NULL, 0) < 0)
01565                 return;
01566 
01567 #ifdef CONFIG_SME
01568         {
01569                 struct wpa_bss *bss;
01570                 bss = wpa_bss_get_bssid(wpa_s, target_ap_addr);
01571                 if (bss)
01572                         wpa_s->sme.freq = bss->freq;
01573                 wpa_s->sme.auth_alg = WPA_AUTH_ALG_FT;
01574                 sme_associate(wpa_s, WPAS_MODE_INFRA, target_ap_addr,
01575                               WLAN_AUTH_FT);
01576         }
01577 #endif /* CONFIG_SME */
01578 }
01579 #endif /* CONFIG_IEEE80211R */
01580 
01581 
01582 void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
01583                           union wpa_event_data *data)
01584 {
01585         struct wpa_supplicant *wpa_s = ctx;
01586         u16 reason_code = 0;
01587 
01588         switch (event) {
01589         case EVENT_AUTH:
01590                 sme_event_auth(wpa_s, data);
01591                 break;
01592         case EVENT_ASSOC:
01593                 wpa_supplicant_event_assoc(wpa_s, data);
01594                 break;
01595         case EVENT_DISASSOC:
01596                 wpa_printf(MSG_DEBUG, "Disassociation notification");
01597 #ifdef CONFIG_AP
01598                 if (wpa_s->ap_iface && data) {
01599                         hostapd_notif_disassoc(wpa_s->ap_iface->bss[0],
01600                                                data->disassoc_info.addr);
01601                         break;
01602                 }
01603 #endif /* CONFIG_AP */
01604                 if (data)
01605                         reason_code = data->deauth_info.reason_code;
01606                 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)
01607                         sme_event_disassoc(wpa_s, data);
01608                 /* fall through */
01609         case EVENT_DEAUTH:
01610                 if (event == EVENT_DEAUTH) {
01611                         wpa_printf(MSG_DEBUG, "Deauthentication notification");
01612                         if (data)
01613                                 reason_code = data->deauth_info.reason_code;
01614                 }
01615 #ifdef CONFIG_AP
01616                 if (wpa_s->ap_iface && data) {
01617                         hostapd_notif_disassoc(wpa_s->ap_iface->bss[0],
01618                                                data->deauth_info.addr);
01619                         break;
01620                 }
01621 #endif /* CONFIG_AP */
01622                 wpa_supplicant_event_disassoc(wpa_s, reason_code);
01623                 break;
01624         case EVENT_MICHAEL_MIC_FAILURE:
01625                 wpa_supplicant_event_michael_mic_failure(wpa_s, data);
01626                 break;
01627 #ifndef CONFIG_NO_SCAN_PROCESSING
01628         case EVENT_SCAN_RESULTS:
01629                 wpa_supplicant_event_scan_results(wpa_s, data);
01630                 break;
01631 #endif /* CONFIG_NO_SCAN_PROCESSING */
01632         case EVENT_ASSOCINFO:
01633                 wpa_supplicant_event_associnfo(wpa_s, data);
01634                 break;
01635         case EVENT_INTERFACE_STATUS:
01636                 wpa_supplicant_event_interface_status(wpa_s, data);
01637                 break;
01638         case EVENT_PMKID_CANDIDATE:
01639                 wpa_supplicant_event_pmkid_candidate(wpa_s, data);
01640                 break;
01641 #ifdef CONFIG_PEERKEY
01642         case EVENT_STKSTART:
01643                 wpa_supplicant_event_stkstart(wpa_s, data);
01644                 break;
01645 #endif /* CONFIG_PEERKEY */
01646 #ifdef CONFIG_IEEE80211R
01647         case EVENT_FT_RESPONSE:
01648                 wpa_supplicant_event_ft_response(wpa_s, data);
01649                 break;
01650 #endif /* CONFIG_IEEE80211R */
01651 #ifdef CONFIG_IBSS_RSN
01652         case EVENT_IBSS_RSN_START:
01653                 wpa_supplicant_event_ibss_rsn_start(wpa_s, data);
01654                 break;
01655 #endif /* CONFIG_IBSS_RSN */
01656         case EVENT_ASSOC_REJECT:
01657                 sme_event_assoc_reject(wpa_s, data);
01658                 break;
01659         case EVENT_AUTH_TIMED_OUT:
01660                 sme_event_auth_timed_out(wpa_s, data);
01661                 break;
01662         case EVENT_ASSOC_TIMED_OUT:
01663                 sme_event_assoc_timed_out(wpa_s, data);
01664                 break;
01665 #ifdef CONFIG_AP
01666         case EVENT_TX_STATUS:
01667                 if (wpa_s->ap_iface == NULL)
01668                         break;
01669                 switch (data->tx_status.type) {
01670                 case WLAN_FC_TYPE_MGMT:
01671                         ap_mgmt_tx_cb(wpa_s, data->tx_status.data,
01672                                       data->tx_status.data_len,
01673                                       data->tx_status.stype,
01674                                       data->tx_status.ack);
01675                         break;
01676                 case WLAN_FC_TYPE_DATA:
01677                         ap_tx_status(wpa_s, data->tx_status.dst,
01678                                      data->tx_status.data,
01679                                      data->tx_status.data_len,
01680                                      data->tx_status.ack);
01681                         break;
01682                 }
01683                 break;
01684         case EVENT_RX_FROM_UNKNOWN:
01685                 if (wpa_s->ap_iface == NULL)
01686                         break;
01687                 ap_rx_from_unknown_sta(wpa_s, data->rx_from_unknown.frame,
01688                                        data->rx_from_unknown.len);
01689                 break;
01690         case EVENT_RX_MGMT:
01691                 if (wpa_s->ap_iface == NULL)
01692                         break;
01693                 ap_mgmt_rx(wpa_s, &data->rx_mgmt);
01694                 break;
01695 #endif /* CONFIG_AP */
01696         case EVENT_RX_ACTION:
01697                 wpa_printf(MSG_DEBUG, "Received Action frame: SA=" MACSTR
01698                            " Category=%u DataLen=%d freq=%d MHz",
01699                            MAC2STR(data->rx_action.sa),
01700                            data->rx_action.category, (int) data->rx_action.len,
01701                            data->rx_action.freq);
01702 #ifdef CONFIG_IEEE80211R
01703                 if (data->rx_action.category == WLAN_ACTION_FT) {
01704                         ft_rx_action(wpa_s, data->rx_action.data,
01705                                      data->rx_action.len);
01706                         break;
01707                 }
01708 #endif /* CONFIG_IEEE80211R */
01709                 break;
01710 #ifdef CONFIG_CLIENT_MLME
01711         case EVENT_MLME_RX: {
01712                 struct ieee80211_rx_status rx_status;
01713                 os_memset(&rx_status, 0, sizeof(rx_status));
01714                 rx_status.freq = data->mlme_rx.freq;
01715                 rx_status.channel = data->mlme_rx.channel;
01716                 rx_status.ssi = data->mlme_rx.ssi;
01717                 ieee80211_sta_rx(wpa_s, data->mlme_rx.buf, data->mlme_rx.len,
01718                                  &rx_status);
01719                 break;
01720         }
01721 #endif /* CONFIG_CLIENT_MLME */
01722         case EVENT_EAPOL_RX:
01723                 wpa_supplicant_rx_eapol(wpa_s, data->eapol_rx.src,
01724                                         data->eapol_rx.data,
01725                                         data->eapol_rx.data_len);
01726                 break;
01727         case EVENT_SIGNAL_CHANGE:
01728                 bgscan_notify_signal_change(
01729                         wpa_s, data->signal_change.above_threshold);
01730                 break;
01731         default:
01732                 wpa_printf(MSG_INFO, "Unknown event %d", event);
01733                 break;
01734         }
01735 }


wpa_supplicant
Author(s): Package maintained by Blaise Gassend
autogenerated on Thu Apr 24 2014 15:34:35