nl80211: Delete Beacon information on deinit in wpa_supplicant AP mode
[wpasupplicant] / wpa_supplicant / wpa_supplicant.c
index c9584ca..a10358e 100644 (file)
 #include "eap_peer/eap.h"
 #include "wpa.h"
 #include "eloop.h"
-#include "drivers/driver.h"
 #include "config.h"
 #include "l2_packet/l2_packet.h"
 #include "wpa_supplicant_i.h"
+#include "driver_i.h"
 #include "ctrl_iface.h"
 #include "ctrl_iface_dbus.h"
 #include "pcsc_funcs.h"
@@ -40,6 +40,8 @@
 #include "wpas_glue.h"
 #include "wps_supplicant.h"
 #include "ibss_rsn.h"
+#include "sme.h"
+#include "ap.h"
 
 const char *wpa_supplicant_version =
 "wpa_supplicant v" VERSION_STR "\n"
@@ -112,6 +114,7 @@ const char *wpa_supplicant_full_license5 =
 extern int wpa_debug_level;
 extern int wpa_debug_show_keys;
 extern int wpa_debug_timestamp;
+extern struct wpa_driver_ops *wpa_drivers[];
 
 /* Configure default/group WEP keys for static WEP */
 static int wpa_set_wep_keys(struct wpa_supplicant *wpa_s,
@@ -211,7 +214,8 @@ static void wpa_supplicant_timeout(void *eloop_ctx, void *timeout_ctx)
 void wpa_supplicant_req_auth_timeout(struct wpa_supplicant *wpa_s,
                                     int sec, int usec)
 {
-       if (wpa_s->conf && wpa_s->conf->ap_scan == 0 && wpa_s->drv_wired)
+       if (wpa_s->conf && wpa_s->conf->ap_scan == 0 &&
+           (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED))
                return;
 
        wpa_msg(wpa_s, MSG_DEBUG, "Setting authentication timeout: %d sec "
@@ -286,7 +290,7 @@ void wpa_supplicant_initiate_eapol(struct wpa_supplicant *wpa_s)
                                EAPOL_REQUIRE_KEY_BROADCAST;
                }
 
-               if (wpa_s->conf && wpa_s->drv_wired)
+               if (wpa_s->conf && (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED))
                        eapol_conf.required_keys = 0;
        }
        if (wpa_s->conf)
@@ -404,6 +408,16 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
        ibss_rsn_deinit(wpa_s->ibss_rsn);
        wpa_s->ibss_rsn = NULL;
 #endif /* CONFIG_IBSS_RSN */
+
+#ifdef CONFIG_SME
+       os_free(wpa_s->sme.ft_ies);
+       wpa_s->sme.ft_ies = NULL;
+       wpa_s->sme.ft_ies_len = 0;
+#endif /* CONFIG_SME */
+
+#ifdef CONFIG_AP
+       wpa_supplicant_ap_deinit(wpa_s);
+#endif /* CONFIG_AP */
 }
 
 
@@ -464,6 +478,8 @@ const char * wpa_supplicant_state_txt(int state)
                return "INACTIVE";
        case WPA_SCANNING:
                return "SCANNING";
+       case WPA_AUTHENTICATING:
+               return "AUTHENTICATING";
        case WPA_ASSOCIATING:
                return "ASSOCIATING";
        case WPA_ASSOCIATED:
@@ -930,6 +946,26 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
        struct wpa_driver_capa capa;
        int assoc_failed = 0;
 
+       if (ssid->mode == 2) {
+#ifdef CONFIG_AP
+               if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_AP)) {
+                       wpa_printf(MSG_INFO, "Driver does not support AP "
+                                  "mode");
+                       return;
+               }
+               wpa_supplicant_create_ap(wpa_s, ssid);
+#else /* CONFIG_AP */
+               wpa_printf(MSG_ERROR, "AP mode support not included in the "
+                          "build");
+#endif /* CONFIG_AP */
+               return;
+       }
+
+       if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) {
+               sme_authenticate(wpa_s, bss, ssid);
+               return;
+       }
+
        wpa_s->reassociate = 0;
        if (bss) {
 #ifdef CONFIG_IEEE80211R
@@ -1119,7 +1155,7 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
        }
        params.wep_tx_keyidx = ssid->wep_tx_keyidx;
 
-       if (wpa_s->driver_4way_handshake &&
+       if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
            (params.key_mgmt_suite == KEY_MGMT_PSK ||
             params.key_mgmt_suite == KEY_MGMT_FT_PSK)) {
                params.passphrase = ssid->passphrase;
@@ -1127,6 +1163,8 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
                        params.psk = ssid->psk;
        }
 
+       params.drop_unencrypted = use_crypt;
+
 #ifdef CONFIG_IEEE80211W
        switch (ssid->ieee80211w) {
        case NO_IEEE80211W:
@@ -1153,7 +1191,7 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
        }
 #endif /* CONFIG_IEEE80211W */
 
-       if (wpa_s->use_client_mlme)
+       if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME)
                ret = ieee80211_sta_associate(wpa_s, &params);
        else
                ret = wpa_drv_associate(wpa_s, &params);
@@ -1231,7 +1269,7 @@ void wpa_supplicant_disassociate(struct wpa_supplicant *wpa_s,
 {
        u8 *addr = NULL;
        if (!is_zero_ether_addr(wpa_s->bssid)) {
-               if (wpa_s->use_client_mlme)
+               if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME)
                        ieee80211_sta_disassociate(wpa_s, reason_code);
                else
                        wpa_drv_disassociate(wpa_s, wpa_s->bssid, reason_code);
@@ -1259,7 +1297,7 @@ void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s,
        u8 *addr = NULL;
        wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
        if (!is_zero_ether_addr(wpa_s->bssid)) {
-               if (wpa_s->use_client_mlme)
+               if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME)
                        ieee80211_sta_deauthenticate(wpa_s, reason_code);
                else
                        wpa_drv_deauthenticate(wpa_s, wpa_s->bssid,
@@ -1395,7 +1433,7 @@ int wpa_supplicant_get_scan_results(struct wpa_supplicant *wpa_s)
 {
        int ret;
 
-       if (wpa_s->use_client_mlme) {
+       if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) {
                wpa_scan_results_free(wpa_s->scan_res);
                wpa_s->scan_res = ieee80211_sta_get_scan_results(wpa_s);
                if (wpa_s->scan_res == NULL) {
@@ -1436,7 +1474,7 @@ struct wpa_ssid * wpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s)
        u8 bssid[ETH_ALEN];
        int wired;
 
-       if (wpa_s->use_client_mlme) {
+       if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) {
                if (ieee80211_sta_get_ssid(wpa_s, ssid, &ssid_len)) {
                        wpa_printf(MSG_WARNING, "Could not read SSID from "
                                   "MLME.");
@@ -1452,14 +1490,15 @@ struct wpa_ssid * wpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s)
                ssid_len = res;
        }
 
-       if (wpa_s->use_client_mlme)
+       if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME)
                os_memcpy(bssid, wpa_s->bssid, ETH_ALEN);
        else if (wpa_drv_get_bssid(wpa_s, bssid) < 0) {
                wpa_printf(MSG_WARNING, "Could not read BSSID from driver.");
                return NULL;
        }
 
-       wired = wpa_s->conf->ap_scan == 0 && wpa_s->drv_wired;
+       wired = wpa_s->conf->ap_scan == 0 &&
+               (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED);
 
        entry = wpa_s->conf->ssid;
        while (entry) {
@@ -1494,7 +1533,7 @@ static int wpa_supplicant_set_driver(struct wpa_supplicant *wpa_s,
        if (wpa_s == NULL)
                return -1;
 
-       if (wpa_supplicant_drivers[0] == NULL) {
+       if (wpa_drivers[0] == NULL) {
                wpa_printf(MSG_ERROR, "No driver interfaces build into "
                           "wpa_supplicant.");
                return -1;
@@ -1502,7 +1541,7 @@ static int wpa_supplicant_set_driver(struct wpa_supplicant *wpa_s,
 
        if (name == NULL) {
                /* default to first driver in the list */
-               wpa_s->driver = wpa_supplicant_drivers[0];
+               wpa_s->driver = wpa_drivers[0];
                return 0;
        }
 
@@ -1511,11 +1550,11 @@ static int wpa_supplicant_set_driver(struct wpa_supplicant *wpa_s,
                len = pos - name;
        else
                len = os_strlen(name);
-       for (i = 0; wpa_supplicant_drivers[i]; i++) {
-               if (os_strlen(wpa_supplicant_drivers[i]->name) == len &&
-                   os_strncmp(name, wpa_supplicant_drivers[i]->name, len) ==
+       for (i = 0; wpa_drivers[i]; i++) {
+               if (os_strlen(wpa_drivers[i]->name) == len &&
+                   os_strncmp(name, wpa_drivers[i]->name, len) ==
                    0) {
-                       wpa_s->driver = wpa_supplicant_drivers[i];
+                       wpa_s->driver = wpa_drivers[i];
                        return 0;
                }
        }
@@ -1540,7 +1579,7 @@ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
        }
 
        if (wpa_s->eapol_received == 0 &&
-           (!wpa_s->driver_4way_handshake ||
+           (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) ||
             !wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) ||
             wpa_s->wpa_state != WPA_COMPLETED)) {
                /* Timeout for completing IEEE 802.1X and WPA authentication */
@@ -1578,7 +1617,7 @@ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
            eapol_sm_rx_eapol(wpa_s->eapol, src_addr, buf, len) > 0)
                return;
        wpa_drv_poll(wpa_s);
-       if (!wpa_s->driver_4way_handshake)
+       if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE))
                wpa_sm_rx_eapol(wpa_s->wpa, src_addr, buf, len);
        else if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
                /*
@@ -1592,13 +1631,6 @@ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
 }
 
 
-void wpa_supplicant_sta_free_hw_features(struct wpa_hw_modes *hw_features,
-                                        size_t num_hw_features)
-{
-       ieee80211_sta_free_hw_features(hw_features, num_hw_features);
-}
-
-
 void wpa_supplicant_sta_rx(void *ctx, const u8 *buf, size_t len,
                           struct ieee80211_rx_status *rx_status)
 {
@@ -1897,16 +1929,12 @@ next_driver:
        }
 
        if (wpa_drv_get_capa(wpa_s, &capa) == 0) {
+               wpa_s->drv_flags = capa.flags;
                if (capa.flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) {
-                       wpa_s->use_client_mlme = 1;
                        if (ieee80211_sta_init(wpa_s))
                                return -1;
                }
-               if (capa.flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE)
-                       wpa_s->driver_4way_handshake = 1;
                wpa_s->max_scan_ssids = capa.max_scan_ssids;
-               if (capa.flags & WPA_DRIVER_FLAGS_WIRED)
-                       wpa_s->drv_wired = 1;
        }
 
 #ifdef CONFIG_IBSS_RSN
@@ -2124,7 +2152,7 @@ struct wpa_global * wpa_supplicant_init(struct wpa_params *params)
                }
        }
 
-       for (i = 0; wpa_supplicant_drivers[i]; i++)
+       for (i = 0; wpa_drivers[i]; i++)
                global->drv_count++;
        if (global->drv_count == 0) {
                wpa_printf(MSG_ERROR, "No drivers enabled");
@@ -2136,13 +2164,13 @@ struct wpa_global * wpa_supplicant_init(struct wpa_params *params)
                wpa_supplicant_deinit(global);
                return NULL;
        }
-       for (i = 0; wpa_supplicant_drivers[i]; i++) {
-               if (!wpa_supplicant_drivers[i]->global_init)
+       for (i = 0; wpa_drivers[i]; i++) {
+               if (!wpa_drivers[i]->global_init)
                        continue;
-               global->drv_priv[i] = wpa_supplicant_drivers[i]->global_init();
+               global->drv_priv[i] = wpa_drivers[i]->global_init();
                if (global->drv_priv[i] == NULL) {
                        wpa_printf(MSG_ERROR, "Failed to initialize driver "
-                                  "'%s'", wpa_supplicant_drivers[i]->name);
+                                  "'%s'", wpa_drivers[i]->name);
                        wpa_supplicant_deinit(global);
                        return NULL;
                }
@@ -2209,10 +2237,10 @@ void wpa_supplicant_deinit(struct wpa_global *global)
 
        eap_peer_unregister_methods();
 
-       for (i = 0; wpa_supplicant_drivers[i] && global->drv_priv; i++) {
+       for (i = 0; wpa_drivers[i] && global->drv_priv; i++) {
                if (!global->drv_priv[i])
                        continue;
-               wpa_supplicant_drivers[i]->global_deinit(global->drv_priv[i]);
+               wpa_drivers[i]->global_deinit(global->drv_priv[i]);
        }
        os_free(global->drv_priv);