Merge commit 'garage/master'
[wpasupplicant] / wpa_supplicant / wpa_supplicant.c
index 45ef15a..d03e9da 100644 (file)
 #include "common.h"
 #include "eapol_supp/eapol_supp_sm.h"
 #include "eap_peer/eap.h"
+#include "eap_server/eap_methods.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"
@@ -41,6 +42,7 @@
 #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"
@@ -113,6 +115,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,
@@ -412,6 +415,10 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
        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 */
 }
 
 
@@ -504,6 +511,9 @@ void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s, wpa_states state)
                   wpa_supplicant_state_txt(wpa_s->wpa_state),
                   wpa_supplicant_state_txt(state));
 
+       if (state != WPA_SCANNING)
+               wpa_supplicant_notify_scanning(wpa_s, 0);
+
        wpa_supplicant_dbus_notify_state_change(wpa_s, state,
                                                wpa_s->wpa_state);
 
@@ -940,6 +950,21 @@ 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;
@@ -1274,7 +1299,6 @@ void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s,
                                   int reason_code)
 {
        u8 *addr = NULL;
-       wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
        if (!is_zero_ether_addr(wpa_s->bssid)) {
                if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME)
                        ieee80211_sta_deauthenticate(wpa_s, reason_code);
@@ -1284,11 +1308,10 @@ void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s,
                addr = wpa_s->bssid;
        }
        wpa_clear_keys(wpa_s, addr);
+       wpa_supplicant_mark_disassoc(wpa_s);
        wpa_s->current_ssid = NULL;
        wpa_sm_set_config(wpa_s->wpa, NULL);
        eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
-       eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
-       eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
 }
 
 
@@ -1512,7 +1535,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;
@@ -1520,7 +1543,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;
        }
 
@@ -1529,11 +1552,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;
                }
        }
@@ -1551,6 +1574,13 @@ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
        wpa_printf(MSG_DEBUG, "RX EAPOL from " MACSTR, MAC2STR(src_addr));
        wpa_hexdump(MSG_MSGDUMP, "RX EAPOL", buf, len);
 
+#ifdef CONFIG_AP
+       if (wpa_s->ap_iface) {
+               wpa_supplicant_ap_rx_eapol(wpa_s, src_addr, buf, len);
+               return;
+       }
+#endif /* CONFIG_AP */
+
        if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE) {
                wpa_printf(MSG_DEBUG, "Ignored received EAPOL frame since "
                           "no key management is configured");
@@ -1610,13 +1640,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)
 {
@@ -2099,6 +2122,17 @@ struct wpa_global * wpa_supplicant_init(struct wpa_params *params)
                return NULL;
        }
 
+#ifdef CONFIG_AP
+       ret = eap_server_register_methods();
+       if (ret) {
+               wpa_printf(MSG_ERROR, "Failed to register EAP server methods");
+               if (ret == -2)
+                       wpa_printf(MSG_ERROR, "Two or more EAP methods used "
+                                  "the same EAP type.");
+               return NULL;
+       }
+#endif /* CONFIG_AP */
+
        global = os_zalloc(sizeof(*global));
        if (global == NULL)
                return NULL;
@@ -2138,7 +2172,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");
@@ -2150,13 +2184,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;
                }
@@ -2222,11 +2256,14 @@ void wpa_supplicant_deinit(struct wpa_global *global)
                wpa_supplicant_dbus_ctrl_iface_deinit(global->dbus_ctrl_iface);
 
        eap_peer_unregister_methods();
+#ifdef CONFIG_AP
+       eap_server_unregister_methods();
+#endif /* CONFIG_AP */
 
-       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);