Add test command for disabling/enabling A-MPDU aggregation
[libeap.git] / src / drivers / driver_ndis.c
index 0501d9a..ed00e98 100644 (file)
@@ -40,7 +40,7 @@ int close(int fd);
 #include "common.h"
 #include "driver.h"
 #include "eloop.h"
-#include "ieee802_11_defs.h"
+#include "common/ieee802_11_defs.h"
 #include "driver_ndis.h"
 
 int wpa_driver_register_event_cb(struct wpa_driver_ndis_data *drv);
@@ -739,13 +739,6 @@ static int wpa_driver_ndis_disassociate(void *priv, const u8 *addr,
 }
 
 
-static int wpa_driver_ndis_set_wpa(void *priv, int enabled)
-{
-       wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled);
-       return 0;
-}
-
-
 static void wpa_driver_ndis_scan_timeout(void *eloop_ctx, void *timeout_ctx)
 {
        wpa_printf(MSG_DEBUG, "Scan timeout - try to get results");
@@ -753,8 +746,9 @@ static void wpa_driver_ndis_scan_timeout(void *eloop_ctx, void *timeout_ctx)
 }
 
 
-static int wpa_driver_ndis_scan_native80211(struct wpa_driver_ndis_data *drv,
-                                           const u8 *ssid, size_t ssid_len)
+static int wpa_driver_ndis_scan_native80211(
+       struct wpa_driver_ndis_data *drv,
+       struct wpa_driver_scan_params *params)
 {
        DOT11_SCAN_REQUEST_V2 req;
        int res;
@@ -772,13 +766,14 @@ static int wpa_driver_ndis_scan_native80211(struct wpa_driver_ndis_data *drv,
 }
 
 
-static int wpa_driver_ndis_scan(void *priv, const u8 *ssid, size_t ssid_len)
+static int wpa_driver_ndis_scan(void *priv,
+                               struct wpa_driver_scan_params *params)
 {
        struct wpa_driver_ndis_data *drv = priv;
        int res;
 
        if (drv->native80211)
-               return wpa_driver_ndis_scan_native80211(drv, ssid, ssid_len);
+               return wpa_driver_ndis_scan_native80211(drv, params);
 
        if (!drv->radio_enabled) {
                wpa_printf(MSG_DEBUG, "NDIS: turning radio on before the first"
@@ -797,6 +792,25 @@ static int wpa_driver_ndis_scan(void *priv, const u8 *ssid, size_t ssid_len)
 }
 
 
+static const u8 * wpa_scan_get_ie(const struct wpa_scan_res *res, u8 ie)
+{
+       const u8 *end, *pos;
+
+       pos = (const u8 *) (res + 1);
+       end = pos + res->ie_len;
+
+       while (pos + 1 < end) {
+               if (pos + 2 + pos[1] > end)
+                       break;
+               if (pos[0] == ie)
+                       return pos;
+               pos += 2 + pos[1];
+       }
+
+       return NULL;
+}
+
+
 static struct wpa_scan_res * wpa_driver_ndis_add_scan_ssid(
        struct wpa_scan_res *r, NDIS_802_11_SSID *ssid)
 {
@@ -975,7 +989,8 @@ static int wpa_driver_ndis_add_wep(struct wpa_driver_ndis_data *drv,
 }
 
 
-static int wpa_driver_ndis_set_key(void *priv, wpa_alg alg, const u8 *addr,
+static int wpa_driver_ndis_set_key(const char *ifname, void *priv,
+                                  enum wpa_alg alg, const u8 *addr,
                                   int key_idx, int set_tx,
                                   const u8 *seq, size_t seq_len,
                                   const u8 *key, size_t key_len)
@@ -1051,6 +1066,7 @@ wpa_driver_ndis_associate(void *priv,
 {
        struct wpa_driver_ndis_data *drv = priv;
        u32 auth_mode, encr, priv_mode, mode;
+       u8 bcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 
        drv->mode = params->mode;
 
@@ -1076,14 +1092,14 @@ wpa_driver_ndis_associate(void *priv,
        if (params->key_mgmt_suite == KEY_MGMT_NONE ||
            params->key_mgmt_suite == KEY_MGMT_802_1X_NO_WPA) {
                /* Re-set WEP keys if static WEP configuration is used. */
-               u8 bcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
                int i;
                for (i = 0; i < 4; i++) {
                        if (!params->wep_key[i])
                                continue;
                        wpa_printf(MSG_DEBUG, "NDIS: Re-setting static WEP "
                                   "key %d", i);
-                       wpa_driver_ndis_set_key(drv, WPA_ALG_WEP, bcast, i,
+                       wpa_driver_ndis_set_key(drv->ifname, drv, WPA_ALG_WEP,
+                                               bcast, i,
                                                i == params->wep_tx_keyidx,
                                                NULL, 0, params->wep_key[i],
                                                params->wep_key_len[i]);
@@ -1091,8 +1107,8 @@ wpa_driver_ndis_associate(void *priv,
        }
 
        if (params->wpa_ie == NULL || params->wpa_ie_len == 0) {
-               if (params->auth_alg & AUTH_ALG_SHARED_KEY) {
-                       if (params->auth_alg & AUTH_ALG_OPEN_SYSTEM)
+               if (params->auth_alg & WPA_AUTH_ALG_SHARED) {
+                       if (params->auth_alg & WPA_AUTH_ALG_OPEN)
                                auth_mode = Ndis802_11AuthModeAutoSwitch;
                        else
                                auth_mode = Ndis802_11AuthModeShared;
@@ -1109,6 +1125,22 @@ wpa_driver_ndis_associate(void *priv,
        } else if (params->key_mgmt_suite == KEY_MGMT_WPS) {
                auth_mode = Ndis802_11AuthModeOpen;
                priv_mode = Ndis802_11PrivFilterAcceptAll;
+               if (params->wps == WPS_MODE_PRIVACY) {
+                       u8 dummy_key[5] = { 0x11, 0x22, 0x33, 0x44, 0x55 };
+                       /*
+                        * Some NDIS drivers refuse to associate in open mode
+                        * configuration due to Privacy field mismatch, so use
+                        * a workaround to make the configuration look like
+                        * matching one for WPS provisioning.
+                        */
+                       wpa_printf(MSG_DEBUG, "NDIS: Set dummy WEP key as a "
+                                  "workaround to allow driver to associate "
+                                  "for WPS");
+                       wpa_driver_ndis_set_key(drv->ifname, drv, WPA_ALG_WEP,
+                                               bcast, 0, 1,
+                                               NULL, 0, dummy_key,
+                                               sizeof(dummy_key));
+               }
 #endif /* CONFIG_WPS */
        } else {
                priv_mode = Ndis802_11PrivFilter8021xWEP;
@@ -1132,6 +1164,12 @@ wpa_driver_ndis_associate(void *priv,
                encr = Ndis802_11Encryption1Enabled;
                break;
        case CIPHER_NONE:
+#ifdef CONFIG_WPS
+               if (params->wps == WPS_MODE_PRIVACY) {
+                       encr = Ndis802_11Encryption1Enabled;
+                       break;
+               }
+#endif /* CONFIG_WPS */
                if (params->group_suite == CIPHER_CCMP)
                        encr = Ndis802_11Encryption3Enabled;
                else if (params->group_suite == CIPHER_TKIP)
@@ -1140,7 +1178,14 @@ wpa_driver_ndis_associate(void *priv,
                        encr = Ndis802_11EncryptionDisabled;
                break;
        default:
+#ifdef CONFIG_WPS
+               if (params->wps == WPS_MODE_PRIVACY) {
+                       encr = Ndis802_11Encryption1Enabled;
+                       break;
+               }
+#endif /* CONFIG_WPS */
                encr = Ndis802_11EncryptionDisabled;
+               break;
        };
 
        if (ndis_set_oid(drv, OID_802_11_PRIVACY_FILTER,
@@ -3174,19 +3219,14 @@ const struct wpa_driver_ops wpa_driver_ndis_ops = {
        "Windows NDIS driver",
        wpa_driver_ndis_get_bssid,
        wpa_driver_ndis_get_ssid,
-       wpa_driver_ndis_set_wpa,
        wpa_driver_ndis_set_key,
        wpa_driver_ndis_init,
        wpa_driver_ndis_deinit,
        NULL /* set_param */,
        NULL /* set_countermeasures */,
-       NULL /* set_drop_unencrypted */,
-       wpa_driver_ndis_scan,
-       NULL /* get_scan_results */,
        wpa_driver_ndis_deauthenticate,
        wpa_driver_ndis_disassociate,
        wpa_driver_ndis_associate,
-       NULL /* set_auth_alg */,
        wpa_driver_ndis_add_pmkid,
        wpa_driver_ndis_remove_pmkid,
        wpa_driver_ndis_flush_pmkid,
@@ -3207,15 +3247,66 @@ const struct wpa_driver_ops wpa_driver_ndis_ops = {
        NULL /* update_ft_ies */,
        NULL /* send_ft_action */,
        wpa_driver_ndis_get_scan_results,
-       NULL /* set_probe_req_ie */,
-       NULL /* set_mode */,
        NULL /* set_country */,
        NULL /* global_init */,
        NULL /* global_deinit */,
        NULL /* init2 */,
        wpa_driver_ndis_get_interfaces,
-       NULL /* scan2 */,
+       wpa_driver_ndis_scan,
        NULL /* authenticate */,
        NULL /* set_beacon */,
-       NULL /* set_beacon_int */
+       NULL /* hapd_init */,
+       NULL /* hapd_deinit */,
+       NULL /* set_ieee8021x */,
+       NULL /* set_privacy */,
+       NULL /* get_seqnum */,
+       NULL /* flush */,
+       NULL /* set_generic_elem */,
+       NULL /* read_sta_data */,
+       NULL /* hapd_send_eapol */,
+       NULL /* sta_deauth */,
+       NULL /* sta_disassoc */,
+       NULL /* sta_remove */,
+       NULL /* hapd_get_ssid */,
+       NULL /* hapd_set_ssid */,
+       NULL /* hapd_set_countermeasures */,
+       NULL /* sta_add */,
+       NULL /* get_inact_sec */,
+       NULL /* sta_clear_stats */,
+       NULL /* set_freq */,
+       NULL /* set_rts */,
+       NULL /* set_frag */,
+       NULL /* sta_set_flags */,
+       NULL /* set_rate_sets */,
+       NULL /* set_cts_protect */,
+       NULL /* set_preamble */,
+       NULL /* set_short_slot_time */,
+       NULL /* set_tx_queue_params */,
+       NULL /* valid_bss_mask */,
+       NULL /* if_add */,
+       NULL /* if_remove */,
+       NULL /* set_sta_vlan */,
+       NULL /* commit */,
+       NULL /* send_ether */,
+       NULL /* set_radius_acl_auth */,
+       NULL /* set_radius_acl_expire */,
+       NULL /* set_ht_params */,
+       NULL /* set_ap_wps_ie */,
+       NULL /* set_supp_port */,
+       NULL /* set_wds_sta */,
+       NULL /* send_action */,
+       NULL /* remain_on_channel */,
+       NULL /* cancel_remain_on_channel */,
+       NULL /* probe_req_report */,
+       NULL /* disable_11b_rates */,
+       NULL /* deinit_ap */,
+       NULL /* suspend */,
+       NULL /* resume */,
+       NULL /* signal_monitor */,
+       NULL /* send_frame */,
+       NULL /* shared_freq */,
+       NULL /* get_noa */,
+       NULL /* set_noa */,
+       NULL /* set_p2p_powersave */,
+       NULL /* ampdu */
 };