Add new wpa_supplicant driver op for setting 802.1X port status
[wpasupplicant] / src / drivers / driver_ndis.c
index b22109b..e45b231 100644 (file)
@@ -56,6 +56,10 @@ static int wpa_driver_ndis_adapter_open(struct wpa_driver_ndis_data *drv);
 static void wpa_driver_ndis_adapter_close(struct wpa_driver_ndis_data *drv);
 
 
+static const u8 pae_group_addr[ETH_ALEN] =
+{ 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03 };
+
+
 /* FIX: to be removed once this can be compiled with the complete NDIS
  * header files */
 #ifndef OID_802_11_BSSID
@@ -349,6 +353,47 @@ typedef struct NDIS_802_11_PMKID_CANDIDATE_LIST {
 #endif /* OID_802_11_CAPABILITY */
 
 
+#ifndef OID_DOT11_CURRENT_OPERATION_MODE
+/* Native 802.11 OIDs */
+#define OID_DOT11_NDIS_START 0x0D010300
+#define OID_DOT11_CURRENT_OPERATION_MODE (OID_DOT11_NDIS_START + 8)
+#define OID_DOT11_SCAN_REQUEST (OID_DOT11_NDIS_START + 11)
+
+typedef enum _DOT11_BSS_TYPE {
+       dot11_BSS_type_infrastructure = 1,
+       dot11_BSS_type_independent = 2,
+       dot11_BSS_type_any = 3
+} DOT11_BSS_TYPE, * PDOT11_BSS_TYPE;
+
+typedef UCHAR DOT11_MAC_ADDRESS[6];
+typedef DOT11_MAC_ADDRESS * PDOT11_MAC_ADDRESS;
+
+typedef enum _DOT11_SCAN_TYPE {
+       dot11_scan_type_active = 1,
+       dot11_scan_type_passive = 2,
+       dot11_scan_type_auto = 3,
+       dot11_scan_type_forced = 0x80000000
+} DOT11_SCAN_TYPE, * PDOT11_SCAN_TYPE;
+
+typedef struct _DOT11_SCAN_REQUEST_V2 {
+       DOT11_BSS_TYPE dot11BSSType;
+       DOT11_MAC_ADDRESS dot11BSSID;
+       DOT11_SCAN_TYPE dot11ScanType;
+       BOOLEAN bRestrictedScan;
+       ULONG udot11SSIDsOffset;
+       ULONG uNumOfdot11SSIDs;
+       BOOLEAN bUseRequestIE;
+       ULONG uRequestIDsOffset;
+       ULONG uNumOfRequestIDs;
+       ULONG uPhyTypeInfosOffset;
+       ULONG uNumOfPhyTypeInfos;
+       ULONG uIEsOffset;
+       ULONG uIEsLength;
+       UCHAR ucBuffer[1];
+} DOT11_SCAN_REQUEST_V2, * PDOT11_SCAN_REQUEST_V2;
+
+#endif /* OID_DOT11_CURRENT_OPERATION_MODE */
+
 #ifdef CONFIG_USE_NDISUIO
 #ifndef _WIN32_WCE
 #ifdef __MINGW32_VERSION
@@ -610,12 +655,7 @@ static int wpa_driver_ndis_get_bssid(void *priv, u8 *bssid)
                 * Report PAE group address as the "BSSID" for wired
                 * connection.
                 */
-               bssid[0] = 0x01;
-               bssid[1] = 0x80;
-               bssid[2] = 0xc2;
-               bssid[3] = 0x00;
-               bssid[4] = 0x00;
-               bssid[5] = 0x03;
+               os_memcpy(bssid, pae_group_addr, ETH_ALEN);
                return 0;
        }
 
@@ -713,11 +753,33 @@ 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)
+{
+       DOT11_SCAN_REQUEST_V2 req;
+       int res;
+
+       os_memset(&req, 0, sizeof(req));
+       req.dot11BSSType = dot11_BSS_type_any;
+       os_memset(req.dot11BSSID, 0xff, ETH_ALEN);
+       req.dot11ScanType = dot11_scan_type_auto;
+       res = ndis_set_oid(drv, OID_DOT11_SCAN_REQUEST, (char *) &req,
+                          sizeof(req));
+       eloop_cancel_timeout(wpa_driver_ndis_scan_timeout, drv, drv->ctx);
+       eloop_register_timeout(7, 0, wpa_driver_ndis_scan_timeout, drv,
+                              drv->ctx);
+       return res;
+}
+
+
 static int wpa_driver_ndis_scan(void *priv, const u8 *ssid, size_t ssid_len)
 {
        struct wpa_driver_ndis_data *drv = priv;
        int res;
 
+       if (drv->native80211)
+               return wpa_driver_ndis_scan_native80211(drv, ssid, ssid_len);
+
        if (!drv->radio_enabled) {
                wpa_printf(MSG_DEBUG, "NDIS: turning radio on before the first"
                           " scan");
@@ -2704,6 +2766,19 @@ static void wpa_driver_ndis_adapter_close(struct wpa_driver_ndis_data *drv)
 }
 
 
+static int ndis_add_multicast(struct wpa_driver_ndis_data *drv)
+{
+       if (ndis_set_oid(drv, OID_802_3_MULTICAST_LIST,
+                        (const char *) pae_group_addr, ETH_ALEN) < 0) {
+               wpa_printf(MSG_DEBUG, "NDIS: Failed to add PAE group address "
+                          "to the multicast list");
+               return -1;
+       }
+
+       return 0;
+}
+
+
 static void * wpa_driver_ndis_init(void *ctx, const char *ifname)
 {
        struct wpa_driver_ndis_data *drv;
@@ -2789,16 +2864,32 @@ static void * wpa_driver_ndis_init(void *ctx, const char *ifname)
        mode = Ndis802_11Infrastructure;
        if (ndis_set_oid(drv, OID_802_11_INFRASTRUCTURE_MODE,
                         (char *) &mode, sizeof(mode)) < 0) {
+               char buf[8];
+               int res;
                wpa_printf(MSG_DEBUG, "NDIS: Failed to set "
                           "OID_802_11_INFRASTRUCTURE_MODE (%d)",
                           (int) mode);
                /* Try to continue anyway */
 
-               if (!drv->has_capability && drv->capa.enc == 0) {
+               res = ndis_get_oid(drv, OID_DOT11_CURRENT_OPERATION_MODE, buf,
+                                  sizeof(buf));
+               if (res > 0) {
+                       wpa_printf(MSG_INFO, "NDIS: The driver seems to use "
+                                  "Native 802.11 OIDs. These are not yet "
+                                  "fully supported.");
+                       drv->native80211 = 1;
+               } else if (!drv->has_capability || drv->capa.enc == 0) {
+                       /*
+                        * Note: This will also happen with NDIS 6 drivers with
+                        * Vista.
+                        */
                        wpa_printf(MSG_DEBUG, "NDIS: Driver did not provide "
                                   "any wireless capabilities - assume it is "
                                   "a wired interface");
                        drv->wired = 1;
+                       drv->capa.flags |= WPA_DRIVER_FLAGS_WIRED;
+                       drv->has_capability = 1;
+                       ndis_add_multicast(drv);
                }
        }
 
@@ -3122,5 +3213,57 @@ const struct wpa_driver_ops wpa_driver_ndis_ops = {
        NULL /* global_init */,
        NULL /* global_deinit */,
        NULL /* init2 */,
-       wpa_driver_ndis_get_interfaces
+       wpa_driver_ndis_get_interfaces,
+       NULL /* scan2 */,
+       NULL /* authenticate */,
+       NULL /* set_beacon */,
+       NULL /* set_beacon_int */,
+       NULL /* hapd_init */,
+       NULL /* hapd_deinit */,
+       NULL /* set_ieee8021x */,
+       NULL /* set_privacy */,
+       NULL /* hapd_set_key */,
+       NULL /* get_seqnum */,
+       NULL /* get_seqnum_igtk */,
+       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_ieee80211d */,
+       NULL /* hapd_set_beacon */,
+       NULL /* set_internal_bridge */,
+       NULL /* set_broadcast_ssid */,
+       NULL /* set_cts_protect */,
+       NULL /* set_preamble */,
+       NULL /* set_short_slot_time */,
+       NULL /* set_tx_queue_params */,
+       NULL /* bss_add */,
+       NULL /* bss_remove */,
+       NULL /* valid_bss_mask */,
+       NULL /* if_add */,
+       NULL /* if_update */,
+       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_wps_beacon_ie */,
+       NULL /* set_wps_probe_resp_ie */,
+       NULL /* set_supp_port */
 };