#include "driver.h"
#include "l2_packet/l2_packet.h"
#include "eloop.h"
-#include "ieee802_11_defs.h"
+#include "common/ieee802_11_defs.h"
#include "priv_netlink.h"
+#include "netlink.h"
+#include "linux_ioctl.h"
#include "driver_ralink.h"
static void wpa_driver_ralink_scan_timeout(void *eloop_ctx, void *timeout_ctx);
struct wpa_driver_ralink_data {
void *ctx;
int ioctl_sock;
- int event_sock;
+ struct netlink_data *netlink;
char ifname[IFNAMSIZ + 1];
u8 *assoc_req_ies;
size_t assoc_req_ies_len;
int ap_scan;
int scanning_done;
u8 g_driver_down;
+ BOOLEAN bAddWepKey;
};
static int ralink_set_oid(struct wpa_driver_ralink_data *drv,
if (buf == NULL)
return -1;
os_memset(&iwr, 0, sizeof(iwr));
- os_strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
+ os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
iwr.u.data.flags = oid;
iwr.u.data.flags |= OID_GET_SET_TOGGLE;
UCHAR enabled = 0;
os_memset(&iwr, 0, sizeof(iwr));
- os_strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
+ os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
iwr.u.data.pointer = (UCHAR*) &enabled;
iwr.u.data.flags = RT_OID_NEW_DRIVER;
wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
os_memset(&iwr, 0, sizeof(iwr));
- os_strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
+ os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
if (ioctl(drv->ioctl_sock, SIOCGIWAP, &iwr) < 0) {
perror("ioctl[SIOCGIWAP]");
wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
os_memset(&iwr, 0, sizeof(iwr));
- os_strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
+ os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
iwr.u.essid.pointer = (caddr_t) ssid;
iwr.u.essid.length = 32;
buf->SsidLength = ssid_len;
os_memcpy(buf->Ssid, ssid, ssid_len);
os_memset(&iwr, 0, sizeof(iwr));
- os_strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
+ os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
iwr.u.data.flags = OID_802_11_SSID;
iwr.u.data.flags |= OID_GET_SET_TOGGLE;
os_memset(&event, 0, sizeof(event));
for (i = 0; i < pmkid->NumCandidates; i++) {
PMKID_CANDIDATE *p = &pmkid->CandidateList[i];
- wpa_printf(MSG_DEBUG, "RALINK: %d: " MACSTR " Flags 0x%x",
- i, MAC2STR(p->BSSID), (int) p->Flags);
+ wpa_printf(MSG_DEBUG, "RALINK: %lu: " MACSTR " Flags 0x%x",
+ (unsigned long) i, MAC2STR(p->BSSID),
+ (int) p->Flags);
os_memcpy(event.pmkid_candidate.bssid, p->BSSID, ETH_ALEN);
event.pmkid_candidate.index = i;
event.pmkid_candidate.preauth =
void *ctx, char *custom)
{
union wpa_event_data data;
+ u8 *req_ies = NULL, *resp_ies = NULL;
wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
*/
bytes = drv->assoc_req_ies_len;
- data.assoc_info.req_ies = os_malloc(bytes);
- if (data.assoc_info.req_ies == NULL)
+ req_ies = os_malloc(bytes);
+ if (req_ies == NULL)
return;
-
+ os_memcpy(req_ies, spos, bytes);
+ data.assoc_info.req_ies = req_ies;
data.assoc_info.req_ies_len = bytes;
- os_memcpy(data.assoc_info.req_ies, spos, bytes);
/* skip the '\0' byte */
spos += bytes + 1;
if (!bytes)
goto done;
-
- data.assoc_info.resp_ies = os_malloc(bytes);
- if (data.assoc_info.resp_ies == NULL)
+ resp_ies = os_malloc(bytes);
+ if (resp_ies == NULL)
goto done;
-
+ os_memcpy(resp_ies, spos, bytes);
+ data.assoc_info.resp_ies = resp_ies;
data.assoc_info.resp_ies_len = bytes;
- os_memcpy(data.assoc_info.resp_ies, spos, bytes);
}
wpa_supplicant_event(ctx, EVENT_ASSOCINFO, &data);
- /* free allocated memory */
done:
- os_free(data.assoc_info.resp_ies);
- os_free(data.assoc_info.req_ies);
+ /* free allocated memory */
+ os_free(resp_ies);
+ os_free(req_ies);
+ }
+}
+
+static void ralink_interface_up(struct wpa_driver_ralink_data *drv)
+{
+ union wpa_event_data event;
+ int enable_wpa_supplicant = 0;
+ drv->g_driver_down = 0;
+ os_memset(&event, 0, sizeof(event));
+ os_snprintf(event.interface_status.ifname,
+ sizeof(event.interface_status.ifname), "%s", drv->ifname);
+
+ event.interface_status.ievent = EVENT_INTERFACE_ADDED;
+ wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS, &event);
+
+ if (drv->ap_scan == 1)
+ enable_wpa_supplicant = 1;
+ else
+ enable_wpa_supplicant = 2;
+ /* trigger driver support wpa_supplicant */
+ if (ralink_set_oid(drv, RT_OID_WPA_SUPPLICANT_SUPPORT,
+ (PCHAR) &enable_wpa_supplicant, sizeof(UCHAR)) < 0)
+ {
+ wpa_printf(MSG_INFO, "RALINK: Failed to set "
+ "RT_OID_WPA_SUPPLICANT_SUPPORT(%d)",
+ (int) enable_wpa_supplicant);
+ wpa_printf(MSG_ERROR, "ralink. Driver does not support "
+ "wpa_supplicant");
}
}
}
if (iwe->u.data.flags == RT_ASSOC_EVENT_FLAG) {
+ wpa_supplicant_event(ctx, EVENT_ASSOC, NULL);
wpa_printf(MSG_DEBUG, "Custom wireless event: "
"receive ASSOCIATED_EVENT !!!");
- /* determine whether the dynamic-WEP is used or
- * not */
-#if 0
- if (wpa_s && wpa_s->current_ssid &&
- wpa_s->current_ssid->key_mgmt ==
- WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
- if ((wpa_s->current_ssid->eapol_flags &
- (EAPOL_FLAG_REQUIRE_KEY_UNICAST | EAPOL_FLAG_REQUIRE_KEY_BROADCAST))) {
- //wpa_printf(MSG_DEBUG, "The current ssid - (%s), eapol_flag = %d.\n",
- // wpa_ssid_txt(wpa_s->current_ssid->ssid, wpa_s->current_ssid->ssid_len),wpa_s->current_ssid->eapol_flags);
- ieee8021x_required_key = TRUE;
- }
-
- if (ralink_set_oid(drv, OID_802_11_SET_IEEE8021X_REQUIRE_KEY, (char *) &ieee8021x_required_key, sizeof(BOOLEAN)) < 0)
- {
- wpa_printf(MSG_DEBUG, "ERROR: Failed to set OID_802_11_SET_IEEE8021X_REQUIRE_KEY(%d)",
- (int) ieee8021x_required_key);
- }
-
- wpa_printf(MSG_DEBUG, "ieee8021x_required_key is %s and eapol_flag(%d).\n", ieee8021x_required_key ? "TRUE" : "FALSE",
- wpa_s->current_ssid->eapol_flags);
- }
-#endif
-
- wpa_supplicant_event(ctx, EVENT_ASSOC, NULL);
} else if (iwe->u.data.flags == RT_REQIE_EVENT_FLAG) {
wpa_printf(MSG_DEBUG, "Custom wireless event: "
"receive ReqIEs !!!");
"receive ASSOCINFO_EVENT !!!");
assoc_info_buf =
- os_malloc(drv->assoc_req_ies_len +
+ os_zalloc(drv->assoc_req_ies_len +
drv->assoc_resp_ies_len + 1);
if (assoc_info_buf == NULL) {
return;
}
- os_memcpy(assoc_info_buf, drv->assoc_req_ies,
- drv->assoc_req_ies_len);
+ if (drv->assoc_req_ies) {
+ os_memcpy(assoc_info_buf,
+ drv->assoc_req_ies,
+ drv->assoc_req_ies_len);
+ }
info_pos = assoc_info_buf +
drv->assoc_req_ies_len;
- os_memcpy(info_pos, drv->assoc_resp_ies,
- drv->assoc_resp_ies_len);
+ if (drv->assoc_resp_ies) {
+ os_memcpy(info_pos,
+ drv->assoc_resp_ies,
+ drv->assoc_resp_ies_len);
+ }
assoc_info_buf[drv->assoc_req_ies_len +
drv->assoc_resp_ies_len] = '\0';
wpa_driver_ralink_event_wireless_custom(
drv, ctx, assoc_info_buf);
os_free(drv->assoc_req_ies);
+ drv->assoc_req_ies = NULL;
os_free(drv->assoc_resp_ies);
+ drv->assoc_resp_ies = NULL;
os_free(assoc_info_buf);
} else if (iwe->u.data.flags == RT_DISASSOC_EVENT_FLAG)
{
} else if (iwe->u.data.flags == RT_INTERFACE_DOWN) {
drv->g_driver_down = 1;
eloop_terminate();
- } else if (iwe->u.data.flags == RT_REPORT_AP_INFO) {
- if (drv->ap_scan != 1) {
- typedef struct PACKED {
- UCHAR bssid[MAC_ADDR_LEN];
- UCHAR ssid[MAX_LEN_OF_SSID];
- INT ssid_len;
- UCHAR wpa_ie[40];
- INT wpa_ie_len;
- UCHAR rsn_ie[40];
- INT rsn_ie_len;
- INT freq;
- USHORT caps;
- } *PAPINFO;
-
- wpa_printf(MSG_DEBUG, "Custom wireless"
- " event: receive "
- "RT_REPORT_AP_INFO !!!");
- //printf("iwe->u.data.length = %d\n", iwe->u.data.length);
- //wpa_hexdump(MSG_DEBUG, "AP_Info: ", buf, iwe->u.data.length);
-#if 0
- wpa_s->num_scan_results = 1;
- if (wpa_s->scan_results)
- os_free(wpa_s->scan_results);
- wpa_s->scan_results = os_malloc(sizeof(struct wpa_scan_result) + 1);
- if (wpa_s->scan_results) {
- PAPINFO pApInfo = (PAPINFO)buf;
- os_memcpy(wpa_s->scan_results[0].bssid, pApInfo->bssid, ETH_ALEN);
- os_memcpy(wpa_s->scan_results[0].ssid, pApInfo->ssid, pApInfo->ssid_len);
- wpa_s->scan_results[0].ssid_len = pApInfo->ssid_len;
- if (pApInfo->wpa_ie_len > 0) {
- os_memcpy(wpa_s->scan_results[0].wpa_ie, pApInfo->wpa_ie, pApInfo->wpa_ie_len);
- wpa_s->scan_results[0].wpa_ie_len = pApInfo->wpa_ie_len;
- } else if (pApInfo->rsn_ie_len > 0) {
- os_memcpy(wpa_s->scan_results[0].rsn_ie, pApInfo->rsn_ie, pApInfo->rsn_ie_len);
- wpa_s->scan_results[0].rsn_ie_len = pApInfo->rsn_ie_len;
- }
- wpa_s->scan_results[0].caps = pApInfo->caps;
- wpa_s->scan_results[0].freq = pApInfo->freq;
- } else {
- wpa_printf("wpa_s->scan_"
- "results fail to "
- "os_malloc!!\n");
- }
-#endif
- }
+ } else if (iwe->u.data.flags == RT_INTERFACE_UP) {
+ ralink_interface_up(drv);
} else {
wpa_driver_ralink_event_wireless_custom(
drv, ctx, buf);
}
static void
-wpa_driver_ralink_event_rtm_newlink(struct wpa_driver_ralink_data *drv,
- void *ctx, struct nlmsghdr *h, int len)
+wpa_driver_ralink_event_rtm_newlink(void *ctx, struct ifinfomsg *ifi,
+ u8 *buf, size_t len)
{
- struct ifinfomsg *ifi;
- int attrlen, nlmsg_len, rta_len;
- struct rtattr * attr;
+ struct wpa_driver_ralink_data *drv = ctx;
+ int attrlen, rta_len;
+ struct rtattr *attr;
wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
- if (len < (int) sizeof(*ifi))
- return;
-
- ifi = NLMSG_DATA(h);
wpa_hexdump(MSG_DEBUG, "ifi: ", (u8 *) ifi, sizeof(struct ifinfomsg));
- nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg));
-
- attrlen = h->nlmsg_len - nlmsg_len;
+ attrlen = len;
wpa_printf(MSG_DEBUG, "attrlen=%d", attrlen);
- if (attrlen < 0)
- return;
-
- attr = (struct rtattr *) (((char *) ifi) + nlmsg_len);
+ attr = (struct rtattr *) buf;
wpa_hexdump(MSG_DEBUG, "attr1: ", (u8 *) attr, sizeof(struct rtattr));
rta_len = RTA_ALIGN(sizeof(struct rtattr));
wpa_hexdump(MSG_DEBUG, "attr2: ", (u8 *)attr,rta_len);
}
}
-static void wpa_driver_ralink_event_receive(int sock, void *ctx,
- void *sock_ctx)
-{
- char buf[8192];
- int left;
- struct sockaddr_nl from;
- socklen_t fromlen;
- struct nlmsghdr *h;
-
- wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
-
- fromlen = sizeof(from);
- left = recvfrom(sock, buf, sizeof(buf), MSG_DONTWAIT,
- (struct sockaddr *) &from, &fromlen);
-
- if (left < 0) {
- if (errno != EINTR && errno != EAGAIN)
- perror("recvfrom(netlink)");
- return;
- }
-
- h = (struct nlmsghdr *) buf;
- wpa_hexdump(MSG_DEBUG, "h: ", (u8 *)h, h->nlmsg_len);
-
- while (left >= (int) sizeof(*h)) {
- int len, plen;
-
- len = h->nlmsg_len;
- plen = len - sizeof(*h);
- if (len > left || plen < 0) {
- wpa_printf(MSG_DEBUG, "Malformed netlink message: "
- "len=%d left=%d plen=%d", len, left, plen);
- break;
- }
-
- switch (h->nlmsg_type) {
- case RTM_NEWLINK:
- wpa_driver_ralink_event_rtm_newlink(ctx, sock_ctx, h,
- plen);
- break;
- }
-
- len = NLMSG_ALIGN(len);
- left -= len;
- h = (struct nlmsghdr *) ((char *) h + len);
- }
-
- if (left > 0) {
- wpa_printf(MSG_DEBUG, "%d extra bytes in the end of netlink "
- "message", left);
- }
-
-}
-
static int
ralink_get_we_version_compiled(struct wpa_driver_ralink_data *drv)
{
UINT we_version_compiled = 0;
os_memset(&iwr, 0, sizeof(iwr));
- os_strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
+ os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
iwr.u.data.pointer = (caddr_t) &we_version_compiled;
iwr.u.data.flags = RT_OID_WE_VERSION_COMPILED;
return 0;
}
-static int
-ralink_set_iface_flags(void *priv, int dev_up)
-{
- struct wpa_driver_ralink_data *drv = priv;
- struct ifreq ifr;
-
- wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
-
- if (drv->ioctl_sock < 0)
- return -1;
-
- os_memset(&ifr, 0, sizeof(ifr));
- os_snprintf(ifr.ifr_name, IFNAMSIZ, "%s", drv->ifname);
-
- if (ioctl(drv->ioctl_sock, SIOCGIFFLAGS, &ifr) != 0) {
- perror("ioctl[SIOCGIFFLAGS]");
- return -1;
- }
-
- if (dev_up)
- ifr.ifr_flags |= IFF_UP;
- else
- ifr.ifr_flags &= ~IFF_UP;
-
- if (ioctl(drv->ioctl_sock, SIOCSIFFLAGS, &ifr) != 0) {
- perror("ioctl[SIOCSIFFLAGS]");
- return -1;
- }
-
- return 0;
-}
-
static void * wpa_driver_ralink_init(void *ctx, const char *ifname)
{
int s;
struct wpa_driver_ralink_data *drv;
struct ifreq ifr;
- struct sockaddr_nl local;
UCHAR enable_wpa_supplicant = 0;
+ struct netlink_config *cfg;
wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
return NULL;
}
/* do it */
- os_strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
+ os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) {
perror(ifr.ifr_name);
drv->scanning_done = 1;
drv->ap_scan = 1; /* for now - let's assume ap_scan=1 is used */
drv->ctx = ctx;
- os_strncpy(drv->ifname, ifname, sizeof(drv->ifname));
+ os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname));
drv->ioctl_sock = s;
drv->g_driver_down = 0;
- s = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
- if (s < 0) {
- perror("socket(PF_NETLINK,SOCK_RAW,NETLINK_ROUTE)");
+ cfg = os_zalloc(sizeof(*cfg));
+ if (cfg == NULL) {
close(drv->ioctl_sock);
os_free(drv);
return NULL;
}
-
- os_memset(&local, 0, sizeof(local));
- local.nl_family = AF_NETLINK;
- local.nl_groups = RTMGRP_LINK;
-
- if (bind(s, (struct sockaddr *) &local, sizeof(local)) < 0) {
- perror("bind(netlink)");
- close(s);
+ cfg->ctx = drv;
+ cfg->newlink_cb = wpa_driver_ralink_event_rtm_newlink;
+ drv->netlink = netlink_init(cfg);
+ if (drv->netlink == NULL) {
+ os_free(cfg);
close(drv->ioctl_sock);
os_free(drv);
return NULL;
}
- eloop_register_read_sock(s, wpa_driver_ralink_event_receive, drv, ctx);
- drv->event_sock = s;
drv->no_of_pmkid = 4; /* Number of PMKID saved supported */
- ralink_set_iface_flags(drv, 1); /* mark up during setup */
+ linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 1);
ralink_get_we_version_compiled(drv);
wpa_driver_ralink_flush_pmkid(drv);
wpa_driver_ralink_flush_pmkid(drv);
sleep(1);
- ralink_set_iface_flags(drv, 0);
+ /* linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 0); */
}
eloop_cancel_timeout(wpa_driver_ralink_scan_timeout, drv, drv->ctx);
- eloop_unregister_read_sock(drv->event_sock);
- close(drv->event_sock);
+ netlink_deinit(drv->netlink);
close(drv->ioctl_sock);
os_free(drv);
}
}
-static int wpa_driver_ralink_scan(void *priv, const u8 *ssid, size_t ssid_len)
+static int wpa_driver_ralink_scan(void *priv,
+ struct wpa_driver_scan_params *params)
{
struct wpa_driver_ralink_data *drv = priv;
struct iwreq iwr;
wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
+#if 0
if (ssid_len > IW_ESSID_MAX_SIZE) {
wpa_printf(MSG_DEBUG, "%s: too long SSID (%lu)",
__FUNCTION__, (unsigned long) ssid_len);
}
/* wpa_driver_ralink_set_ssid(drv, ssid, ssid_len); */
+#endif
+
+ if (ralink_set_oid(drv, RT_OID_WPS_PROBE_REQ_IE,
+ (char *) params->extra_ies, params->extra_ies_len) <
+ 0) {
+ wpa_printf(MSG_DEBUG, "RALINK: Failed to set "
+ "RT_OID_WPS_PROBE_REQ_IE");
+ }
os_memset(&iwr, 0, sizeof(iwr));
- os_strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
+ os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
if (ioctl(drv->ioctl_sock, SIOCSIWSCAN, &iwr) < 0) {
perror("ioctl[SIOCSIWSCAN]");
return ret;
}
-static int
-wpa_driver_ralink_get_scan_results(void *priv,
- struct wpa_scan_result *results,
- size_t max_size)
+static struct wpa_scan_results *
+wpa_driver_ralink_get_scan_results(void *priv)
{
struct wpa_driver_ralink_data *drv = priv;
UCHAR *buf = NULL;
+ size_t buf_len;
NDIS_802_11_BSSID_LIST_EX *wsr;
NDIS_WLAN_BSSID_EX *wbi;
struct iwreq iwr;
- int rv = 0;
size_t ap_num;
- u8 *pos, *end;
+ u8 *pos;
+ struct wpa_scan_results *res;
if (drv->g_driver_down == 1)
- return -1;
+ return NULL;
wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
- if (drv->we_version_compiled >= 17) {
- buf = os_zalloc(8192);
- iwr.u.data.length = 8192;
- } else {
- buf = os_zalloc(4096);
- iwr.u.data.length = 4096;
- }
- if (buf == NULL)
- return -1;
+ if (drv->we_version_compiled >= 17)
+ buf_len = 8192;
+ else
+ buf_len = 4096;
+
+ for (;;) {
+ buf = os_zalloc(buf_len);
+ iwr.u.data.length = buf_len;
+ if (buf == NULL)
+ return NULL;
- wsr = (NDIS_802_11_BSSID_LIST_EX *) buf;
+ wsr = (NDIS_802_11_BSSID_LIST_EX *) buf;
- wsr->NumberOfItems = 0;
- os_strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
- iwr.u.data.pointer = (void *) buf;
- iwr.u.data.flags = OID_802_11_BSSID_LIST;
+ wsr->NumberOfItems = 0;
+ os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
+ iwr.u.data.pointer = (void *) buf;
+ iwr.u.data.flags = OID_802_11_BSSID_LIST;
- if ((rv = ioctl(drv->ioctl_sock, RT_PRIV_IOCTL, &iwr)) < 0) {
- wpa_printf(MSG_DEBUG, "ioctl fail: rv = %d", rv);
+ if (ioctl(drv->ioctl_sock, RT_PRIV_IOCTL, &iwr) == 0)
+ break;
+
+ if (errno == E2BIG && buf_len < 65535) {
+ os_free(buf);
+ buf = NULL;
+ buf_len *= 2;
+ if (buf_len > 65535)
+ buf_len = 65535; /* 16-bit length field */
+ wpa_printf(MSG_DEBUG, "Scan results did not fit - "
+ "trying larger buffer (%lu bytes)",
+ (unsigned long) buf_len);
+ } else {
+ perror("ioctl[RT_PRIV_IOCTL]");
+ os_free(buf);
+ return NULL;
+ }
+ }
+
+ res = os_zalloc(sizeof(*res));
+ if (res == NULL) {
os_free(buf);
- return -1;
+ return NULL;
}
- os_memset(results, 0, max_size * sizeof(struct wpa_scan_result));
+ res->res = os_zalloc(wsr->NumberOfItems *
+ sizeof(struct wpa_scan_res *));
+ if (res->res == NULL) {
+ os_free(res);
+ os_free(buf);
+ return NULL;
+ }
for (ap_num = 0, wbi = wsr->Bssid; ap_num < wsr->NumberOfItems;
++ap_num) {
- os_memcpy(results[ap_num].bssid, &wbi->MacAddress, ETH_ALEN);
- os_memcpy(results[ap_num].ssid, wbi->Ssid.Ssid,
- wbi->Ssid.SsidLength);
- results[ap_num].ssid_len = wbi->Ssid.SsidLength;
- results[ap_num].freq = (wbi->Configuration.DSConfig / 1000);
+ struct wpa_scan_res *r = NULL;
+ size_t extra_len = 0, var_ie_len = 0;
+ u8 *pos2;
+
+ /* SSID data element */
+ extra_len += 2 + wbi->Ssid.SsidLength;
+ var_ie_len = wbi->IELength - sizeof(NDIS_802_11_FIXED_IEs);
+ r = os_zalloc(sizeof(*r) + extra_len + var_ie_len);
+ if (r == NULL)
+ break;
+ res->res[res->num++] = r;
+ wpa_printf(MSG_DEBUG, "SSID - %s", wbi->Ssid.Ssid);
/* get ie's */
wpa_hexdump(MSG_DEBUG, "RALINK: AP IEs",
- (u8 *) wbi + sizeof(*wbi) - 1, wbi->IELength);
+ (u8 *) &wbi->IEs[0], wbi->IELength);
- pos = (u8 *) wbi + sizeof(*wbi) - 1;
- end = (u8 *) wbi + sizeof(*wbi) + wbi->IELength;
+ os_memcpy(r->bssid, wbi->MacAddress, ETH_ALEN);
- if (wbi->IELength < sizeof(NDIS_802_11_FIXED_IEs))
- break;
+ extra_len += (2 + wbi->Ssid.SsidLength);
+ r->ie_len = extra_len + var_ie_len;
+ pos2 = (u8 *) (r + 1);
- pos += sizeof(NDIS_802_11_FIXED_IEs) - 2;
- os_memcpy(&results[ap_num].caps, pos, 2);
- pos += 2;
+ /*
+ * Generate a fake SSID IE since the driver did not report
+ * a full IE list.
+ */
+ *pos2++ = WLAN_EID_SSID;
+ *pos2++ = wbi->Ssid.SsidLength;
+ os_memcpy(pos2, wbi->Ssid.Ssid, wbi->Ssid.SsidLength);
+ pos2 += wbi->Ssid.SsidLength;
- while (pos + 1 < end && pos + 2 + pos[1] <= end) {
- u8 ielen = 2 + pos[1];
+ r->freq = (wbi->Configuration.DSConfig / 1000);
- if (ielen > SSID_MAX_WPA_IE_LEN) {
- pos += ielen;
- continue;
- }
+ pos = (u8 *) wbi + sizeof(*wbi) - 1;
- if (pos[0] == WLAN_EID_VENDOR_SPECIFIC &&
- pos[1] >= 4 &&
- os_memcmp(pos + 2, "\x00\x50\xf2\x01", 4) == 0) {
- os_memcpy(results[ap_num].wpa_ie, pos, ielen);
- results[ap_num].wpa_ie_len = ielen;
- } else if (pos[0] == WLAN_EID_RSN) {
- os_memcpy(results[ap_num].rsn_ie, pos, ielen);
- results[ap_num].rsn_ie_len = ielen;
- }
- pos += ielen;
- }
+ pos += sizeof(NDIS_802_11_FIXED_IEs) - 2;
+ os_memcpy(&(r->caps), pos, 2);
+ pos += 2;
+
+ if (wbi->IELength > sizeof(NDIS_802_11_FIXED_IEs))
+ os_memcpy(pos2, pos, var_ie_len);
wbi = (NDIS_WLAN_BSSID_EX *) ((u8 *) wbi + wbi->Length);
}
os_free(buf);
- return ap_num;
+ return res;
}
static int ralink_set_auth_mode(struct wpa_driver_ralink_data *drv,
return 0;
}
+static int ralink_set_encr_type(struct wpa_driver_ralink_data *drv,
+ NDIS_802_11_WEP_STATUS encr_type)
+{
+ NDIS_802_11_WEP_STATUS wep_status = encr_type;
+
+ wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
+
+ if (ralink_set_oid(drv, OID_802_11_WEP_STATUS,
+ (char *) &wep_status, sizeof(wep_status)) < 0) {
+ wpa_printf(MSG_DEBUG, "RALINK: Failed to set "
+ "OID_802_11_WEP_STATUS (%d)",
+ (int) wep_status);
+ return -1;
+ }
+ return 0;
+}
+
+
static int wpa_driver_ralink_remove_key(struct wpa_driver_ralink_data *drv,
int key_idx, const u8 *addr,
const u8 *bssid, int pairwise)
return res;
}
-static int wpa_driver_ralink_set_key(void *priv, wpa_alg alg, const u8 *addr,
+static int wpa_driver_ralink_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)
wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
+ drv->bAddWepKey = FALSE;
+
if (addr == NULL || os_memcmp(addr, "\xff\xff\xff\xff\xff\xff",
ETH_ALEN) == 0) {
/* Group Key */
}
if (alg == WPA_ALG_WEP) {
+ drv->bAddWepKey = TRUE;
return wpa_driver_ralink_add_wep(drv, pairwise, key_idx,
set_tx, key, key_len);
}
}
}
+static int wpa_driver_ralink_set_gen_ie(void *priv, const u8 *ie,
+ size_t ie_len)
+{
+ struct wpa_driver_ralink_data *drv = priv;
+ struct iwreq iwr;
+ int ret = 0;
+
+ os_memset(&iwr, 0, sizeof(iwr));
+ os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
+ iwr.u.data.pointer = (caddr_t) ie;
+ iwr.u.data.length = ie_len;
+
+ wpa_hexdump(MSG_DEBUG, "wpa_driver_ralink_set_gen_ie: ",
+ (u8 *) ie, ie_len);
+
+ if (ioctl(drv->ioctl_sock, SIOCSIWGENIE, &iwr) < 0) {
+ perror("ioctl[SIOCSIWGENIE]");
+ ret = -1;
+ }
+
+ return ret;
+}
+
static int
wpa_driver_ralink_associate(void *priv,
struct wpa_driver_associate_params *params)
NDIS_802_11_AUTHENTICATION_MODE auth_mode;
NDIS_802_11_WEP_STATUS encr;
BOOLEAN ieee8021xMode;
+ BOOLEAN ieee8021x_required_key = TRUE;
if (drv->g_driver_down == 1)
return -1;
/* Try to continue anyway */
}
- 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)
- auth_mode = Ndis802_11AuthModeAutoSwitch;
- else
- auth_mode = Ndis802_11AuthModeShared;
- } else
- auth_mode = Ndis802_11AuthModeOpen;
- } else if (params->wpa_ie[0] == WLAN_EID_RSN) {
- if (params->key_mgmt_suite == KEY_MGMT_PSK)
- auth_mode = Ndis802_11AuthModeWPA2PSK;
- else
- auth_mode = Ndis802_11AuthModeWPA2;
+ if (params->key_mgmt_suite == KEY_MGMT_WPS) {
+ UCHAR enable_wps = 0x80;
+ /* trigger driver support wpa_supplicant */
+ if (ralink_set_oid(drv, RT_OID_WPA_SUPPLICANT_SUPPORT,
+ (PCHAR) &enable_wps, sizeof(UCHAR)) < 0) {
+ wpa_printf(MSG_INFO, "RALINK: Failed to set "
+ "RT_OID_WPA_SUPPLICANT_SUPPORT (%d)",
+ (int) enable_wps);
+ }
+
+ wpa_driver_ralink_set_gen_ie(priv, params->wpa_ie,
+ params->wpa_ie_len);
+
+ ralink_set_auth_mode(drv, Ndis802_11AuthModeOpen);
+
+ ralink_set_encr_type(drv, Ndis802_11EncryptionDisabled);
} else {
- if (params->key_mgmt_suite == KEY_MGMT_WPA_NONE)
- auth_mode = Ndis802_11AuthModeWPANone;
- else if (params->key_mgmt_suite == KEY_MGMT_PSK)
- auth_mode = Ndis802_11AuthModeWPAPSK;
+#ifdef CONFIG_WPS
+ UCHAR enable_wpa_supplicant;
+
+ if (drv->ap_scan == 1)
+ enable_wpa_supplicant = 0x01;
else
- auth_mode = Ndis802_11AuthModeWPA;
- }
+ enable_wpa_supplicant = 0x02;
- switch (params->pairwise_suite) {
- case CIPHER_CCMP:
- encr = Ndis802_11Encryption3Enabled;
- break;
- case CIPHER_TKIP:
- encr = Ndis802_11Encryption2Enabled;
- break;
- case CIPHER_WEP40:
- case CIPHER_WEP104:
- encr = Ndis802_11Encryption1Enabled;
- break;
- case CIPHER_NONE:
- if (params->group_suite == CIPHER_CCMP)
+ /* trigger driver support wpa_supplicant */
+ if (ralink_set_oid(drv, RT_OID_WPA_SUPPLICANT_SUPPORT,
+ (PCHAR) &enable_wpa_supplicant,
+ sizeof(UCHAR)) < 0) {
+ wpa_printf(MSG_DEBUG, "RALINK: Failed to set "
+ "RT_OID_WPA_SUPPLICANT_SUPPORT (%d)",
+ (int) enable_wpa_supplicant);
+ }
+
+ wpa_driver_ralink_set_gen_ie(priv, (u8 *) "", 0);
+#endif /* CONFIG_WPS */
+
+ if (params->wpa_ie == NULL || params->wpa_ie_len == 0) {
+ 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;
+ } else
+ auth_mode = Ndis802_11AuthModeOpen;
+ } else if (params->wpa_ie[0] == WLAN_EID_RSN) {
+ if (params->key_mgmt_suite == KEY_MGMT_PSK)
+ auth_mode = Ndis802_11AuthModeWPA2PSK;
+ else
+ auth_mode = Ndis802_11AuthModeWPA2;
+ } else {
+ if (params->key_mgmt_suite == KEY_MGMT_WPA_NONE)
+ auth_mode = Ndis802_11AuthModeWPANone;
+ else if (params->key_mgmt_suite == KEY_MGMT_PSK)
+ auth_mode = Ndis802_11AuthModeWPAPSK;
+ else
+ auth_mode = Ndis802_11AuthModeWPA;
+ }
+
+ switch (params->pairwise_suite) {
+ case CIPHER_CCMP:
encr = Ndis802_11Encryption3Enabled;
- else if (params->group_suite == CIPHER_TKIP)
+ break;
+ case CIPHER_TKIP:
encr = Ndis802_11Encryption2Enabled;
- else
+ break;
+ case CIPHER_WEP40:
+ case CIPHER_WEP104:
+ encr = Ndis802_11Encryption1Enabled;
+ break;
+ case CIPHER_NONE:
+ if (params->group_suite == CIPHER_CCMP)
+ encr = Ndis802_11Encryption3Enabled;
+ else if (params->group_suite == CIPHER_TKIP)
+ encr = Ndis802_11Encryption2Enabled;
+ else
+ encr = Ndis802_11EncryptionDisabled;
+ break;
+ default:
encr = Ndis802_11EncryptionDisabled;
- break;
- default:
- encr = Ndis802_11EncryptionDisabled;
- break;
- }
-
- ralink_set_auth_mode(drv, auth_mode);
+ break;
+ }
- /* notify driver that IEEE8021x mode is enabled */
- if (params->key_mgmt_suite == KEY_MGMT_802_1X_NO_WPA)
- ieee8021xMode = TRUE;
- else
- ieee8021xMode = FALSE;
+ ralink_set_auth_mode(drv, auth_mode);
- if (ralink_set_oid(drv, OID_802_11_SET_IEEE8021X,
- (char *) &ieee8021xMode, sizeof(BOOLEAN)) < 0) {
- wpa_printf(MSG_DEBUG, "RALINK: Failed to set "
- "OID_802_11_SET_IEEE8021X(%d)",
- (int) ieee8021xMode);
- }
+ /* notify driver that IEEE8021x mode is enabled */
+ if (params->key_mgmt_suite == KEY_MGMT_802_1X_NO_WPA) {
+ ieee8021xMode = TRUE;
+ if (drv->bAddWepKey)
+ ieee8021x_required_key = FALSE;
+ } else
+ ieee8021xMode = FALSE;
- if (ralink_set_oid(drv, OID_802_11_WEP_STATUS,
- (char *) &encr, sizeof(encr)) < 0) {
- wpa_printf(MSG_DEBUG, "RALINK: Failed to set "
- "OID_802_11_WEP_STATUS(%d)",
- (int) encr);
- }
+ if (ralink_set_oid(drv, OID_802_11_SET_IEEE8021X_REQUIRE_KEY,
+ (char *) &ieee8021x_required_key,
+ sizeof(BOOLEAN)) < 0) {
+ wpa_printf(MSG_DEBUG, "ERROR: Failed to set "
+ "OID_802_11_SET_IEEE8021X_REQUIRE_KEY(%d)",
+ (int) ieee8021x_required_key);
+ } else {
+ wpa_printf(MSG_DEBUG, "ieee8021x_required_key is %s",
+ ieee8021x_required_key ? "TRUE" : "FALSE");
+ }
- if ((ieee8021xMode == FALSE) &&
- (encr == Ndis802_11Encryption1Enabled)) {
- /* static WEP */
- int enabled = 0;
- if (ralink_set_oid(drv, OID_802_11_DROP_UNENCRYPTED,
- (char *) &enabled, sizeof(enabled)) < 0) {
+ if (ralink_set_oid(drv, OID_802_11_SET_IEEE8021X,
+ (char *) &ieee8021xMode, sizeof(BOOLEAN)) <
+ 0) {
wpa_printf(MSG_DEBUG, "RALINK: Failed to set "
- "OID_802_11_DROP_UNENCRYPTED(%d)",
- (int) encr);
+ "OID_802_11_SET_IEEE8021X(%d)",
+ (int) ieee8021xMode);
+ }
+
+ ralink_set_encr_type(drv, encr);
+
+ if ((ieee8021xMode == FALSE) &&
+ (encr == Ndis802_11Encryption1Enabled)) {
+ /* static WEP */
+ int enabled = 0;
+ if (ralink_set_oid(drv, OID_802_11_DROP_UNENCRYPTED,
+ (char *) &enabled, sizeof(enabled))
+ < 0) {
+ wpa_printf(MSG_DEBUG, "RALINK: Failed to set "
+ "OID_802_11_DROP_UNENCRYPTED(%d)",
+ (int) encr);
+ }
}
}
.init = wpa_driver_ralink_init,
.deinit = wpa_driver_ralink_deinit,
.set_countermeasures = wpa_driver_ralink_set_countermeasures,
- .scan = wpa_driver_ralink_scan,
- .get_scan_results = wpa_driver_ralink_get_scan_results,
+ .scan2 = wpa_driver_ralink_scan,
+ .get_scan_results2 = wpa_driver_ralink_get_scan_results,
.deauthenticate = wpa_driver_ralink_deauthenticate,
.disassociate = wpa_driver_ralink_disassociate,
.associate = wpa_driver_ralink_associate,