#else /* CONFIG_USE_NDISUIO */
#include <Packet32.h>
#endif /* CONFIG_USE_NDISUIO */
+#ifdef __MINGW32_VERSION
+#include <ddk/ntddndis.h>
+#else /* __MINGW32_VERSION */
#include <ntddndis.h>
+#endif /* __MINGW32_VERSION */
#ifdef _WIN32_WCE
#include <winioctl.h>
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
#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
char txt[50];
os_snprintf(txt, sizeof(txt), "NDIS: Set OID %08x", oid);
- wpa_hexdump_key(MSG_MSGDUMP, txt, data, len);
+ wpa_hexdump_key(MSG_MSGDUMP, txt, (const u8 *) data, len);
buflen = sizeof(*o) + len;
reallen = buflen - sizeof(o->Data);
char txt[50];
os_snprintf(txt, sizeof(txt), "NDIS: Set OID %08x", oid);
- wpa_hexdump_key(MSG_MSGDUMP, txt, data, len);
+ wpa_hexdump_key(MSG_MSGDUMP, txt, (const u8 *) data, len);
buf = os_zalloc(sizeof(*o) + len);
if (buf == NULL)
* 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;
}
- return ndis_get_oid(drv, OID_802_11_BSSID, bssid, ETH_ALEN) < 0 ?
- -1 : 0;
+ return ndis_get_oid(drv, OID_802_11_BSSID, (char *) bssid, ETH_ALEN) <
+ 0 ? -1 : 0;
}
int i;
for (i = 0; i < 32; i++)
ssid[i] = rand() & 0xff;
- return wpa_driver_ndis_set_ssid(drv, ssid, 32);
+ return wpa_driver_ndis_set_ssid(drv, (u8 *) ssid, 32);
}
}
+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");
os_memcpy(wep->KeyMaterial, key, key_len);
wpa_hexdump_key(MSG_MSGDUMP, "NDIS: OID_802_11_ADD_WEP",
- (char *) wep, len);
+ (u8 *) wep, len);
res = ndis_set_oid(drv, OID_802_11_ADD_WEP, (char *) wep, len);
os_free(wep);
}
wpa_hexdump_key(MSG_MSGDUMP, "NDIS: OID_802_11_ADD_KEY",
- (char *) nkey, len);
+ (u8 *) nkey, len);
res = ndis_set_oid(drv, OID_802_11_ADD_KEY, (char *) nkey, len);
os_free(nkey);
auth_mode = Ndis802_11AuthModeWPA2PSK;
else
auth_mode = Ndis802_11AuthModeWPA2;
+#ifdef CONFIG_WPS
+ } else if (params->key_mgmt_suite == KEY_MGMT_WPS) {
+ auth_mode = Ndis802_11AuthModeOpen;
+ priv_mode = Ndis802_11PrivFilterAcceptAll;
+#endif /* CONFIG_WPS */
} else {
priv_mode = Ndis802_11PrivFilter8021xWEP;
if (params->key_mgmt_suite == KEY_MGMT_WPA_NONE)
ndis_set_encr_status(drv, encr);
if (params->bssid) {
- ndis_set_oid(drv, OID_802_11_BSSID, params->bssid, ETH_ALEN);
+ ndis_set_oid(drv, OID_802_11_BSSID, (char *) params->bssid,
+ ETH_ALEN);
drv->oid_bssid_set = 1;
} else if (drv->oid_bssid_set) {
ndis_set_oid(drv, OID_802_11_BSSID, "\xff\xff\xff\xff\xff\xff",
os_memcpy(&p->BSSIDInfo[i].PMKID, entry->pmkid, 16);
entry = entry->next;
}
- wpa_hexdump(MSG_MSGDUMP, "NDIS: OID_802_11_PMKID", (char *) p, len);
+ wpa_hexdump(MSG_MSGDUMP, "NDIS: OID_802_11_PMKID", (u8 *) p, len);
ret = ndis_set_oid(drv, OID_802_11_PMKID, (char *) p, len);
os_free(p);
return ret;
p.Length = 8;
p.BSSIDInfoCount = 0;
wpa_hexdump(MSG_MSGDUMP, "NDIS: OID_802_11_PMKID (flush)",
- (char *) &p, 8);
+ (u8 *) &p, 8);
ret = ndis_set_oid(drv, OID_802_11_PMKID, (char *) &p, 8);
if (prev_authmode != Ndis802_11AuthModeWPA2)
len = sizeof(buf);
}
}
- wpa_hexdump(MSG_MSGDUMP, "NDIS: association information", buf, len);
+ wpa_hexdump(MSG_MSGDUMP, "NDIS: association information",
+ (u8 *) buf, len);
if (len < sizeof(*ai)) {
wpa_printf(MSG_DEBUG, "NDIS: too short association "
"information");
}
wpa_hexdump(MSG_MSGDUMP, "NDIS: Request IEs",
- buf + ai->OffsetRequestIEs, ai->RequestIELength);
+ (u8 *) buf + ai->OffsetRequestIEs, ai->RequestIELength);
wpa_hexdump(MSG_MSGDUMP, "NDIS: Response IEs",
- buf + ai->OffsetResponseIEs, ai->ResponseIELength);
+ (u8 *) buf + ai->OffsetResponseIEs, ai->ResponseIELength);
os_memset(&data, 0, sizeof(data));
- data.assoc_info.req_ies = buf + ai->OffsetRequestIEs;
+ data.assoc_info.req_ies = (u8 *) buf + ai->OffsetRequestIEs;
data.assoc_info.req_ies_len = ai->RequestIELength;
- data.assoc_info.resp_ies = buf + ai->OffsetResponseIEs;
+ data.assoc_info.resp_ies = (u8 *) buf + ai->OffsetResponseIEs;
data.assoc_info.resp_ies_len = ai->ResponseIELength;
blen = 65535;
return;
}
- wpa_hexdump(MSG_MSGDUMP, "OID_802_11_CAPABILITY", buf, len);
+ wpa_hexdump(MSG_MSGDUMP, "OID_802_11_CAPABILITY", (u8 *) buf, len);
c = (NDIS_802_11_CAPABILITY *) buf;
if (len < sizeof(*c) || c->Version != 2) {
wpa_printf(MSG_DEBUG, "NDIS: unsupported "
}
+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;
}
if (ndis_get_oid(drv, OID_802_3_CURRENT_ADDRESS,
- drv->own_addr, ETH_ALEN) < 0) {
+ (char *) drv->own_addr, ETH_ALEN) < 0) {
wpa_printf(MSG_DEBUG, "NDIS: Get OID_802_3_CURRENT_ADDRESS "
"failed");
wpa_driver_ndis_adapter_close(drv);
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);
}
}
}
+static struct wpa_interface_info *
+wpa_driver_ndis_get_interfaces(void *global_priv)
+{
+ struct wpa_interface_info *iface = NULL, *niface;
+
+#ifdef CONFIG_USE_NDISUIO
+ NDISUIO_QUERY_BINDING *b;
+ size_t blen = sizeof(*b) + 1024;
+ int i, error;
+ DWORD written;
+ char name[256], desc[256];
+ WCHAR *pos;
+ size_t j, len;
+ HANDLE ndisuio;
+
+ ndisuio = CreateFile(NDISUIO_DEVICE_NAME,
+ GENERIC_READ | GENERIC_WRITE, 0, NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
+ INVALID_HANDLE_VALUE);
+ if (ndisuio == INVALID_HANDLE_VALUE) {
+ wpa_printf(MSG_ERROR, "NDIS: Failed to open connection to "
+ "NDISUIO: %d", (int) GetLastError());
+ return NULL;
+ }
+
+#ifndef _WIN32_WCE
+ if (!DeviceIoControl(ndisuio, IOCTL_NDISUIO_BIND_WAIT, NULL, 0,
+ NULL, 0, &written, NULL)) {
+ wpa_printf(MSG_ERROR, "NDIS: IOCTL_NDISUIO_BIND_WAIT failed: "
+ "%d", (int) GetLastError());
+ CloseHandle(ndisuio);
+ return NULL;
+ }
+#endif /* _WIN32_WCE */
+
+ b = os_malloc(blen);
+ if (b == NULL) {
+ CloseHandle(ndisuio);
+ return NULL;
+ }
+
+ for (i = 0; ; i++) {
+ os_memset(b, 0, blen);
+ b->BindingIndex = i;
+ if (!DeviceIoControl(ndisuio, IOCTL_NDISUIO_QUERY_BINDING,
+ b, sizeof(NDISUIO_QUERY_BINDING), b, blen,
+ &written, NULL)) {
+ error = (int) GetLastError();
+ if (error == ERROR_NO_MORE_ITEMS)
+ break;
+ wpa_printf(MSG_DEBUG, "IOCTL_NDISUIO_QUERY_BINDING "
+ "failed: %d", error);
+ break;
+ }
+
+ pos = (WCHAR *) ((char *) b + b->DeviceNameOffset);
+ len = b->DeviceNameLength;
+ if (len >= sizeof(name))
+ len = sizeof(name) - 1;
+ for (j = 0; j < len; j++)
+ name[j] = (char) pos[j];
+ name[len] = '\0';
+
+ pos = (WCHAR *) ((char *) b + b->DeviceDescrOffset);
+ len = b->DeviceDescrLength;
+ if (len >= sizeof(desc))
+ len = sizeof(desc) - 1;
+ for (j = 0; j < len; j++)
+ desc[j] = (char) pos[j];
+ desc[len] = '\0';
+
+ wpa_printf(MSG_DEBUG, "NDIS: %d - %s - %s", i, name, desc);
+
+ niface = os_zalloc(sizeof(*niface));
+ if (niface == NULL)
+ break;
+ niface->drv_name = "ndis";
+ if (os_strncmp(name, "\\DEVICE\\", 8) == 0)
+ niface->ifname = os_strdup(name + 8);
+ else
+ niface->ifname = os_strdup(name);
+ if (niface->ifname == NULL) {
+ os_free(niface);
+ break;
+ }
+ niface->desc = os_strdup(desc);
+ niface->next = iface;
+ iface = niface;
+ }
+
+ os_free(b);
+ CloseHandle(ndisuio);
+#else /* CONFIG_USE_NDISUIO */
+ PTSTR _names;
+ char *names, *pos, *pos2;
+ ULONG len;
+ BOOLEAN res;
+ char *name[MAX_ADAPTERS];
+ char *desc[MAX_ADAPTERS];
+ int num_name, num_desc, i;
+
+ wpa_printf(MSG_DEBUG, "NDIS: Packet.dll version: %s",
+ PacketGetVersion());
+
+ len = 8192;
+ _names = os_zalloc(len);
+ if (_names == NULL)
+ return NULL;
+
+ res = PacketGetAdapterNames(_names, &len);
+ if (!res && len > 8192) {
+ os_free(_names);
+ _names = os_zalloc(len);
+ if (_names == NULL)
+ return NULL;
+ res = PacketGetAdapterNames(_names, &len);
+ }
+
+ if (!res) {
+ wpa_printf(MSG_ERROR, "NDIS: Failed to get adapter list "
+ "(PacketGetAdapterNames)");
+ os_free(_names);
+ return NULL;
+ }
+
+ names = (char *) _names;
+ if (names[0] && names[1] == '\0' && names[2] && names[3] == '\0') {
+ wpa_printf(MSG_DEBUG, "NDIS: Looks like adapter names are in "
+ "UNICODE");
+ /* Convert to ASCII */
+ pos2 = pos = names;
+ while (pos2 < names + len) {
+ if (pos2[0] == '\0' && pos2[1] == '\0' &&
+ pos2[2] == '\0' && pos2[3] == '\0') {
+ pos2 += 4;
+ break;
+ }
+ *pos++ = pos2[0];
+ pos2 += 2;
+ }
+ os_memcpy(pos + 2, names, pos - names);
+ pos += 2;
+ } else
+ pos = names;
+
+ num_name = 0;
+ while (pos < names + len) {
+ name[num_name] = pos;
+ while (*pos && pos < names + len)
+ pos++;
+ if (pos + 1 >= names + len) {
+ os_free(names);
+ return NULL;
+ }
+ pos++;
+ num_name++;
+ if (num_name >= MAX_ADAPTERS) {
+ wpa_printf(MSG_DEBUG, "NDIS: Too many adapters");
+ os_free(names);
+ return NULL;
+ }
+ if (*pos == '\0') {
+ wpa_printf(MSG_DEBUG, "NDIS: %d adapter names found",
+ num_name);
+ pos++;
+ break;
+ }
+ }
+
+ num_desc = 0;
+ while (pos < names + len) {
+ desc[num_desc] = pos;
+ while (*pos && pos < names + len)
+ pos++;
+ if (pos + 1 >= names + len) {
+ os_free(names);
+ return NULL;
+ }
+ pos++;
+ num_desc++;
+ if (num_desc >= MAX_ADAPTERS) {
+ wpa_printf(MSG_DEBUG, "NDIS: Too many adapter "
+ "descriptions");
+ os_free(names);
+ return NULL;
+ }
+ if (*pos == '\0') {
+ wpa_printf(MSG_DEBUG, "NDIS: %d adapter descriptions "
+ "found", num_name);
+ pos++;
+ break;
+ }
+ }
+
+ /*
+ * Windows 98 with Packet.dll 3.0 alpha3 does not include adapter
+ * descriptions. Fill in dummy descriptors to work around this.
+ */
+ while (num_desc < num_name)
+ desc[num_desc++] = "dummy description";
+
+ if (num_name != num_desc) {
+ wpa_printf(MSG_DEBUG, "NDIS: mismatch in adapter name and "
+ "description counts (%d != %d)",
+ num_name, num_desc);
+ os_free(names);
+ return NULL;
+ }
+
+ for (i = 0; i < num_name; i++) {
+ niface = os_zalloc(sizeof(*niface));
+ if (niface == NULL)
+ break;
+ niface->drv_name = "ndis";
+ if (os_strncmp(name[i], "\\Device\\NPF_", 12) == 0)
+ niface->ifname = os_strdup(name[i] + 12);
+ else
+ niface->ifname = os_strdup(name[i]);
+ if (niface->ifname == NULL) {
+ os_free(niface);
+ break;
+ }
+ niface->desc = os_strdup(desc[i]);
+ niface->next = iface;
+ iface = niface;
+ }
+
+#endif /* CONFIG_USE_NDISUIO */
+
+ return iface;
+}
+
+
const struct wpa_driver_ops wpa_driver_ndis_ops = {
"ndis",
"Windows NDIS driver",
NULL /* send_ft_action */,
wpa_driver_ndis_get_scan_results,
NULL /* set_probe_req_ie */,
- NULL /* set_mode */
+ NULL /* set_mode */,
+ NULL /* set_country */,
+ NULL /* global_init */,
+ NULL /* global_deinit */,
+ NULL /* init2 */,
+ 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 /* set_retry */,
+ NULL /* sta_set_flags */,
+ NULL /* set_rate_sets */,
+ NULL /* set_ieee80211d */,
+ NULL /* hapd_set_beacon */,
+ NULL /* set_internal_bridge */,
+ NULL /* hapd_set_beacon_int */,
+ 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 /* passive_scan */,
+ 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 /* get_neighbor_bss */
};