driver_ralink.c
Go to the documentation of this file.
00001 /*
00002  * WPA Supplicant - driver interaction with Ralink Wireless Client
00003  * Copyright (c) 2003-2006, Jouni Malinen <j@w1.fi>
00004  * Copyright (c) 2007, Snowpin Lee <snowpin_lee@ralinktech.com.tw>
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License version 2 as
00008  * published by the Free Software Foundation.
00009  *
00010  * Alternatively, this software may be distributed under the terms of BSD
00011  * license.
00012  *
00013  * See README and COPYING for more details.
00014  *
00015  */
00016 
00017 #include "includes.h"
00018 #include <sys/ioctl.h>
00019 
00020 #include "wireless_copy.h"
00021 #include "common.h"
00022 #include "driver.h"
00023 #include "l2_packet/l2_packet.h"
00024 #include "eloop.h"
00025 #include "common/ieee802_11_defs.h"
00026 #include "priv_netlink.h"
00027 #include "netlink.h"
00028 #include "linux_ioctl.h"
00029 #include "driver_ralink.h"
00030 
00031 static void wpa_driver_ralink_scan_timeout(void *eloop_ctx, void *timeout_ctx);
00032 
00033 #define MAX_SSID_LEN 32
00034 
00035 struct wpa_driver_ralink_data {
00036         void *ctx;
00037         int ioctl_sock;
00038         struct netlink_data *netlink;
00039         char ifname[IFNAMSIZ + 1];
00040         u8 *assoc_req_ies;
00041         size_t assoc_req_ies_len;
00042         u8 *assoc_resp_ies;
00043         size_t assoc_resp_ies_len;
00044         int no_of_pmkid;
00045         struct ndis_pmkid_entry *pmkid;
00046         int we_version_compiled;
00047         int ap_scan;
00048         int scanning_done;
00049         u8 g_driver_down;
00050         BOOLEAN bAddWepKey;
00051 };
00052 
00053 static int ralink_set_oid(struct wpa_driver_ralink_data *drv,
00054                           unsigned short oid, char *data, int len)
00055 {
00056         char *buf;
00057         struct iwreq iwr;
00058 
00059         buf = os_zalloc(len);
00060         if (buf == NULL)
00061                 return -1;
00062         os_memset(&iwr, 0, sizeof(iwr));
00063         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
00064         iwr.u.data.flags = oid;
00065         iwr.u.data.flags |= OID_GET_SET_TOGGLE;
00066 
00067         if (data)
00068                 os_memcpy(buf, data, len);
00069 
00070         iwr.u.data.pointer = (caddr_t) buf;
00071         iwr.u.data.length = len;
00072 
00073         if (ioctl(drv->ioctl_sock, RT_PRIV_IOCTL, &iwr) < 0) {
00074                 wpa_printf(MSG_DEBUG, "%s: oid=0x%x len (%d) failed",
00075                            __func__, oid, len);
00076                 os_free(buf);
00077                 return -1;
00078         }
00079         os_free(buf);
00080         return 0;
00081 }
00082 
00083 static int
00084 ralink_get_new_driver_flag(struct wpa_driver_ralink_data *drv)
00085 {
00086         struct iwreq iwr;
00087         UCHAR enabled = 0;
00088 
00089         os_memset(&iwr, 0, sizeof(iwr));
00090         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
00091         iwr.u.data.pointer = (UCHAR*) &enabled;
00092         iwr.u.data.flags = RT_OID_NEW_DRIVER;
00093 
00094         if (ioctl(drv->ioctl_sock, RT_PRIV_IOCTL, &iwr) < 0) {
00095                 wpa_printf(MSG_DEBUG, "%s: failed", __func__);
00096                 return 0;
00097         }
00098 
00099         return (enabled == 1) ? 1 : 0;
00100 }
00101 
00102 static int wpa_driver_ralink_get_bssid(void *priv, u8 *bssid)
00103 {
00104         struct wpa_driver_ralink_data *drv = priv;
00105         struct iwreq iwr;
00106         int ret = 0;
00107 
00108         if (drv->g_driver_down == 1)
00109                 return -1;
00110 
00111         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
00112 
00113         os_memset(&iwr, 0, sizeof(iwr));
00114         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
00115 
00116         if (ioctl(drv->ioctl_sock, SIOCGIWAP, &iwr) < 0) {
00117                 perror("ioctl[SIOCGIWAP]");
00118                 ret = -1;
00119         }
00120         os_memcpy(bssid, iwr.u.ap_addr.sa_data, ETH_ALEN);
00121 
00122         return ret;
00123 }
00124 
00125 static int wpa_driver_ralink_get_ssid(void *priv, u8 *ssid)
00126 {
00127         struct wpa_driver_ralink_data *drv = priv;
00128 #if 0
00129         struct wpa_supplicant *wpa_s = drv->ctx;
00130         struct wpa_ssid *entry;
00131 #endif
00132         int ssid_len;
00133         u8 bssid[ETH_ALEN];
00134         u8 ssid_str[MAX_SSID_LEN];
00135         struct iwreq iwr;
00136 #if 0
00137         int result = 0;
00138 #endif
00139         int ret = 0;
00140 #if 0
00141         BOOLEAN ieee8021x_mode = FALSE;
00142         BOOLEAN ieee8021x_required_key = FALSE;
00143 #endif
00144 
00145         if (drv->g_driver_down == 1)
00146                 return -1;
00147 
00148         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
00149 
00150         os_memset(&iwr, 0, sizeof(iwr));
00151         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
00152         iwr.u.essid.pointer = (caddr_t) ssid;
00153         iwr.u.essid.length = 32;
00154 
00155         if (ioctl(drv->ioctl_sock, SIOCGIWESSID, &iwr) < 0) {
00156                 perror("ioctl[SIOCGIWESSID]");
00157                 ret = -1;
00158         } else
00159                 ret = iwr.u.essid.length;
00160 
00161         if (ret <= 0)
00162                 return ret;
00163 
00164         ssid_len = ret;
00165         os_memset(ssid_str, 0, MAX_SSID_LEN);
00166         os_memcpy(ssid_str, ssid, ssid_len);
00167 
00168         if (drv->ap_scan == 0) {
00169                 /* Read BSSID form driver */
00170                 if (wpa_driver_ralink_get_bssid(priv, bssid) < 0) {
00171                         wpa_printf(MSG_WARNING, "Could not read BSSID from "
00172                                    "driver.");
00173                         return ret;
00174                 }
00175 
00176 #if 0
00177                 entry = wpa_s->conf->ssid;
00178                 while (entry) {
00179                         if (!entry->disabled && ssid_len == entry->ssid_len &&
00180                             os_memcmp(ssid_str, entry->ssid, ssid_len) == 0 &&
00181                             (!entry->bssid_set ||
00182                              os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0)) {
00183                                 /* match the config of driver */
00184                                 result = 1;
00185                                 break;
00186                         }
00187                         entry = entry->next;
00188                 }
00189 
00190                 if (result) {
00191                         wpa_printf(MSG_DEBUG, "Ready to set 802.1x mode and "
00192                                    "ieee_required_keys parameters to driver");
00193 
00194                         /* set 802.1x mode and ieee_required_keys parameter */
00195                         if (entry->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
00196                                 if ((entry->eapol_flags & (EAPOL_FLAG_REQUIRE_KEY_UNICAST | EAPOL_FLAG_REQUIRE_KEY_BROADCAST)))
00197                                                 ieee8021x_required_key = TRUE;
00198                                 ieee8021x_mode = TRUE;
00199                         }
00200 
00201                         if (ralink_set_oid(drv, OID_802_11_SET_IEEE8021X, (char *) &ieee8021x_mode, sizeof(BOOLEAN)) < 0)
00202                         {
00203                                 wpa_printf(MSG_DEBUG, "RALINK: Failed to set OID_802_11_SET_IEEE8021X(%d)", (int) ieee8021x_mode);
00204                         }
00205                         else
00206                         {
00207                                 wpa_printf(MSG_DEBUG, "ieee8021x_mode is %s", ieee8021x_mode ? "TRUE" : "FALSE");
00208                         }
00209 
00210                         if (ralink_set_oid(drv, OID_802_11_SET_IEEE8021X_REQUIRE_KEY, (char *) &ieee8021x_required_key, sizeof(BOOLEAN)) < 0)
00211                         {
00212                                 wpa_printf(MSG_DEBUG, "ERROR: Failed to set OID_802_11_SET_IEEE8021X_REQUIRE_KEY(%d)", (int) ieee8021x_required_key);
00213                         }
00214                         else
00215                         {
00216                                 wpa_printf(MSG_DEBUG, "ieee8021x_required_key is %s and eapol_flag(%d)", ieee8021x_required_key ? "TRUE" : "FALSE",
00217                                                                                                                                                                                                 entry->eapol_flags);
00218                         }
00219                 }
00220 #endif
00221         }
00222 
00223         return ret;
00224 }
00225 
00226 static int wpa_driver_ralink_set_ssid(struct wpa_driver_ralink_data *drv,
00227                                       const u8 *ssid, size_t ssid_len)
00228 {
00229         NDIS_802_11_SSID *buf;
00230         int ret = 0;
00231         struct iwreq iwr;
00232 
00233         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
00234 
00235         buf = os_zalloc(sizeof(NDIS_802_11_SSID));
00236         if (buf == NULL)
00237                 return -1;
00238         os_memset(buf, 0, sizeof(buf));
00239         buf->SsidLength = ssid_len;
00240         os_memcpy(buf->Ssid, ssid, ssid_len);
00241         os_memset(&iwr, 0, sizeof(iwr));
00242         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
00243 
00244         iwr.u.data.flags = OID_802_11_SSID;
00245         iwr.u.data.flags |= OID_GET_SET_TOGGLE;
00246         iwr.u.data.pointer = (caddr_t) buf;
00247         iwr.u.data.length = sizeof(NDIS_802_11_SSID);
00248 
00249         if (ioctl(drv->ioctl_sock, RT_PRIV_IOCTL, &iwr) < 0) {
00250                 perror("ioctl[RT_PRIV_IOCTL] -- OID_802_11_SSID");
00251                 ret = -1;
00252         }
00253         os_free(buf);
00254         return ret;
00255 }
00256 
00257 static void wpa_driver_ralink_event_pmkid(struct wpa_driver_ralink_data *drv,
00258                                           const u8 *data, size_t data_len)
00259 {
00260         NDIS_802_11_PMKID_CANDIDATE_LIST *pmkid;
00261         size_t i;
00262         union wpa_event_data event;
00263 
00264         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
00265 
00266         if (data_len < 8) {
00267                 wpa_printf(MSG_DEBUG, "RALINK: Too short PMKID Candidate List "
00268                            "Event (len=%lu)", (unsigned long) data_len);
00269                 return;
00270         }
00271         pmkid = (NDIS_802_11_PMKID_CANDIDATE_LIST *) data;
00272         wpa_printf(MSG_DEBUG, "RALINK: PMKID Candidate List Event - Version %d"
00273                    " NumCandidates %d",
00274                    (int) pmkid->Version, (int) pmkid->NumCandidates);
00275 
00276         if (pmkid->Version != 1) {
00277                 wpa_printf(MSG_DEBUG, "RALINK: Unsupported PMKID Candidate "
00278                            "List Version %d", (int) pmkid->Version);
00279                 return;
00280         }
00281 
00282         if (data_len < 8 + pmkid->NumCandidates * sizeof(PMKID_CANDIDATE)) {
00283                 wpa_printf(MSG_DEBUG, "RALINK: PMKID Candidate List "
00284                            "underflow");
00285 
00286                 return;
00287         }
00288 
00289 
00290 
00291         os_memset(&event, 0, sizeof(event));
00292         for (i = 0; i < pmkid->NumCandidates; i++) {
00293                 PMKID_CANDIDATE *p = &pmkid->CandidateList[i];
00294                 wpa_printf(MSG_DEBUG, "RALINK: %lu: " MACSTR " Flags 0x%x",
00295                            (unsigned long) i, MAC2STR(p->BSSID),
00296                            (int) p->Flags);
00297                 os_memcpy(event.pmkid_candidate.bssid, p->BSSID, ETH_ALEN);
00298                 event.pmkid_candidate.index = i;
00299                 event.pmkid_candidate.preauth =
00300                         p->Flags & NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED;
00301                 wpa_supplicant_event(drv->ctx, EVENT_PMKID_CANDIDATE,
00302                                      &event);
00303         }
00304 }
00305 
00306 static int wpa_driver_ralink_set_pmkid(struct wpa_driver_ralink_data *drv)
00307 {
00308         int len, count, i, ret;
00309         struct ndis_pmkid_entry *entry;
00310         NDIS_802_11_PMKID *p;
00311 
00312         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
00313 
00314         count = 0;
00315         entry = drv->pmkid;
00316         while (entry) {
00317                 count++;
00318                 if (count >= drv->no_of_pmkid)
00319                         break;
00320                 entry = entry->next;
00321         }
00322         len = 8 + count * sizeof(BSSID_INFO);
00323         p = os_zalloc(len);
00324         if (p == NULL)
00325                 return -1;
00326         p->Length = len;
00327         p->BSSIDInfoCount = count;
00328         entry = drv->pmkid;
00329         for (i = 0; i < count; i++) {
00330                 os_memcpy(&p->BSSIDInfo[i].BSSID, entry->bssid, ETH_ALEN);
00331                 os_memcpy(&p->BSSIDInfo[i].PMKID, entry->pmkid, 16);
00332                 entry = entry->next;
00333         }
00334         wpa_hexdump(MSG_MSGDUMP, "NDIS: OID_802_11_PMKID",
00335                     (const u8 *) p, len);
00336         ret = ralink_set_oid(drv, OID_802_11_PMKID, (char *) p, len);
00337         os_free(p);
00338         return ret;
00339 }
00340 
00341 static int wpa_driver_ralink_add_pmkid(void *priv, const u8 *bssid,
00342                                        const u8 *pmkid)
00343 {
00344         struct wpa_driver_ralink_data *drv = priv;
00345         struct ndis_pmkid_entry *entry, *prev;
00346 
00347         if (drv->g_driver_down == 1)
00348                 return -1;
00349 
00350         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
00351 
00352         if (drv->no_of_pmkid == 0)
00353                 return 0;
00354 
00355         prev = NULL;
00356         entry = drv->pmkid;
00357         while (entry) {
00358                 if (os_memcmp(entry->bssid, bssid, ETH_ALEN) == 0)
00359                         break;
00360                 prev = entry;
00361                 entry = entry->next;
00362         }
00363 
00364         if (entry) {
00365                 /* Replace existing entry for this BSSID and move it into the
00366                  * beginning of the list. */
00367                 os_memcpy(entry->pmkid, pmkid, 16);
00368                 if (prev) {
00369                         prev->next = entry->next;
00370                         entry->next = drv->pmkid;
00371                         drv->pmkid = entry;
00372                 }
00373         } else {
00374                 entry = os_malloc(sizeof(*entry));
00375                 if (entry) {
00376                         os_memcpy(entry->bssid, bssid, ETH_ALEN);
00377                         os_memcpy(entry->pmkid, pmkid, 16);
00378                         entry->next = drv->pmkid;
00379                         drv->pmkid = entry;
00380                 }
00381         }
00382 
00383         return wpa_driver_ralink_set_pmkid(drv);
00384 }
00385 
00386 
00387 static int wpa_driver_ralink_remove_pmkid(void *priv, const u8 *bssid,
00388                                           const u8 *pmkid)
00389 {
00390         struct wpa_driver_ralink_data *drv = priv;
00391         struct ndis_pmkid_entry *entry, *prev;
00392 
00393         if (drv->g_driver_down == 1)
00394                 return -1;
00395 
00396         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
00397 
00398         if (drv->no_of_pmkid == 0)
00399                 return 0;
00400 
00401         entry = drv->pmkid;
00402         prev = NULL;
00403         drv->pmkid = NULL;
00404         while (entry) {
00405                 if (os_memcmp(entry->bssid, bssid, ETH_ALEN) == 0 &&
00406                     os_memcmp(entry->pmkid, pmkid, 16) == 0) {
00407                         if (prev)
00408                                 prev->next = entry->next;
00409                         else
00410                                 drv->pmkid = entry->next;
00411                         os_free(entry);
00412                         break;
00413                 }
00414                 prev = entry;
00415                 entry = entry->next;
00416         }
00417         return wpa_driver_ralink_set_pmkid(drv);
00418 }
00419 
00420 
00421 static int wpa_driver_ralink_flush_pmkid(void *priv)
00422 {
00423         struct wpa_driver_ralink_data *drv = priv;
00424         NDIS_802_11_PMKID p;
00425         struct ndis_pmkid_entry *pmkid, *prev;
00426 
00427         if (drv->g_driver_down == 1)
00428                 return -1;
00429 
00430         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
00431 
00432         if (drv->no_of_pmkid == 0)
00433                 return 0;
00434 
00435         pmkid = drv->pmkid;
00436         drv->pmkid = NULL;
00437         while (pmkid) {
00438                 prev = pmkid;
00439                 pmkid = pmkid->next;
00440                 os_free(prev);
00441         }
00442 
00443         os_memset(&p, 0, sizeof(p));
00444         p.Length = 8;
00445         p.BSSIDInfoCount = 0;
00446         wpa_hexdump(MSG_MSGDUMP, "NDIS: OID_802_11_PMKID (flush)",
00447                     (const u8 *) &p, 8);
00448         return ralink_set_oid(drv, OID_802_11_PMKID, (char *) &p, 8);
00449 }
00450 
00451 static void
00452 wpa_driver_ralink_event_wireless_custom(struct wpa_driver_ralink_data *drv,
00453                                         void *ctx, char *custom)
00454 {
00455         union wpa_event_data data;
00456         u8 *req_ies = NULL, *resp_ies = NULL;
00457 
00458         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
00459 
00460         wpa_printf(MSG_DEBUG, "Custom wireless event: '%s'", custom);
00461 
00462         os_memset(&data, 0, sizeof(data));
00463         /* Host AP driver */
00464         if (os_strncmp(custom, "MLME-MICHAELMICFAILURE.indication", 33) == 0) {
00465                 /* receive a MICFAILURE report */
00466                 data.michael_mic_failure.unicast =
00467                         os_strstr(custom, " unicast") != NULL;
00468                 /* TODO: parse parameters(?) */
00469                 wpa_supplicant_event(ctx, EVENT_MICHAEL_MIC_FAILURE, &data);
00470         } else if (os_strncmp(custom, "ASSOCINFO_ReqIEs=", 17) == 0) {
00471                 /* receive assoc. req. IEs */
00472                 char *spos;
00473                 int bytes;
00474 
00475                 spos = custom + 17;
00476                 /*get IE's length */
00477                 /*
00478                  * bytes = strlen(spos); ==> bug, bytes may less than original
00479                  * size by using this way to get size. snowpin 20070312
00480                  * if (!bytes)
00481                  *      return;
00482                  */
00483                 bytes = drv->assoc_req_ies_len;
00484 
00485                 req_ies = os_malloc(bytes);
00486                 if (req_ies == NULL)
00487                         return;
00488                 os_memcpy(req_ies, spos, bytes);
00489                 data.assoc_info.req_ies = req_ies;
00490                 data.assoc_info.req_ies_len = bytes;
00491 
00492                 /* skip the '\0' byte */
00493                 spos += bytes + 1;
00494 
00495                 data.assoc_info.resp_ies = NULL;
00496                 data.assoc_info.resp_ies_len = 0;
00497 
00498                 if (os_strncmp(spos, " RespIEs=", 9) == 0) {
00499                         /* receive assoc. resp. IEs */
00500                         spos += 9;
00501                         /* get IE's length */
00502                         bytes = os_strlen(spos);
00503                         if (!bytes)
00504                                 goto done;
00505 
00506                         resp_ies = os_malloc(bytes);
00507                         if (resp_ies == NULL)
00508                                 goto done;
00509                         os_memcpy(resp_ies, spos, bytes);
00510                         data.assoc_info.resp_ies = resp_ies;
00511                         data.assoc_info.resp_ies_len = bytes;
00512                 }
00513 
00514                 wpa_supplicant_event(ctx, EVENT_ASSOCINFO, &data);
00515 
00516         done:
00517                 /* free allocated memory */
00518                 os_free(resp_ies);
00519                 os_free(req_ies);
00520         }
00521 }
00522 
00523 static void ralink_interface_up(struct wpa_driver_ralink_data *drv)
00524 {
00525         union wpa_event_data event;
00526         int enable_wpa_supplicant = 0;
00527         drv->g_driver_down = 0;
00528         os_memset(&event, 0, sizeof(event));
00529         os_snprintf(event.interface_status.ifname,
00530                     sizeof(event.interface_status.ifname), "%s", drv->ifname);
00531 
00532         event.interface_status.ievent = EVENT_INTERFACE_ADDED;
00533         wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS, &event);
00534 
00535         if (drv->ap_scan == 1)
00536                 enable_wpa_supplicant = 1;
00537         else
00538                 enable_wpa_supplicant = 2;
00539         /* trigger driver support wpa_supplicant */
00540         if (ralink_set_oid(drv, RT_OID_WPA_SUPPLICANT_SUPPORT,
00541                            (PCHAR) &enable_wpa_supplicant, sizeof(UCHAR)) < 0)
00542         {
00543                 wpa_printf(MSG_INFO, "RALINK: Failed to set "
00544                            "RT_OID_WPA_SUPPLICANT_SUPPORT(%d)",
00545                            (int) enable_wpa_supplicant);
00546                 wpa_printf(MSG_ERROR, "ralink. Driver does not support "
00547                            "wpa_supplicant");
00548         }
00549 }
00550 
00551 static void
00552 wpa_driver_ralink_event_wireless(struct wpa_driver_ralink_data *drv,
00553                                  void *ctx, char *data, int len)
00554 {
00555         struct iw_event iwe_buf, *iwe = &iwe_buf;
00556         char *pos, *end, *custom, *buf, *assoc_info_buf, *info_pos;
00557 #if 0
00558         BOOLEAN ieee8021x_required_key = FALSE;
00559 #endif
00560 
00561         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
00562 
00563         assoc_info_buf = info_pos = NULL;
00564         pos = data;
00565         end = data + len;
00566 
00567         while (pos + IW_EV_LCP_LEN <= end) {
00568                 /* Event data may be unaligned, so make a local, aligned copy
00569                  * before processing. */
00570                 os_memcpy(&iwe_buf, pos, IW_EV_LCP_LEN);
00571                 wpa_printf(MSG_DEBUG, "Wireless event: cmd=0x%x len=%d",
00572                            iwe->cmd, iwe->len);
00573                 if (iwe->len <= IW_EV_LCP_LEN)
00574                         return;
00575 
00576                 custom = pos + IW_EV_POINT_LEN;
00577 
00578                 if (drv->we_version_compiled > 18 && iwe->cmd == IWEVCUSTOM) {
00579                         /* WE-19 removed the pointer from struct iw_point */
00580                         char *dpos = (char *) &iwe_buf.u.data.length;
00581                         int dlen = dpos - (char *) &iwe_buf;
00582                         os_memcpy(dpos, pos + IW_EV_LCP_LEN,
00583                                   sizeof(struct iw_event) - dlen);
00584                 } else {
00585                         os_memcpy(&iwe_buf, pos, sizeof(struct iw_event));
00586                         custom += IW_EV_POINT_OFF;
00587                 }
00588 
00589                 switch (iwe->cmd) {
00590                 case IWEVCUSTOM:
00591                         if (custom + iwe->u.data.length > end)
00592                                 return;
00593                         buf = os_malloc(iwe->u.data.length + 1);
00594                         if (buf == NULL)
00595                                 return;
00596                         os_memcpy(buf, custom, iwe->u.data.length);
00597                         buf[iwe->u.data.length] = '\0';
00598 
00599                         if (drv->ap_scan == 1) {
00600                                 if ((iwe->u.data.flags == RT_ASSOC_EVENT_FLAG)
00601                                     || (iwe->u.data.flags ==
00602                                         RT_REQIE_EVENT_FLAG) ||
00603                                     (iwe->u.data.flags == RT_RESPIE_EVENT_FLAG)
00604                                     || (iwe->u.data.flags ==
00605                                         RT_ASSOCINFO_EVENT_FLAG)) {
00606                                         if (drv->scanning_done == 0) {
00607                                                 os_free(buf);
00608                                                 return;
00609                                         }
00610                                 }
00611                         }
00612 
00613                         if (iwe->u.data.flags == RT_ASSOC_EVENT_FLAG) {
00614                                 wpa_supplicant_event(ctx, EVENT_ASSOC, NULL);
00615                                 wpa_printf(MSG_DEBUG, "Custom wireless event: "
00616                                            "receive ASSOCIATED_EVENT !!!");
00617                         } else if (iwe->u.data.flags == RT_REQIE_EVENT_FLAG) {
00618                                 wpa_printf(MSG_DEBUG, "Custom wireless event: "
00619                                            "receive ReqIEs !!!");
00620                                 drv->assoc_req_ies =
00621                                         os_malloc(iwe->u.data.length);
00622                                 if (drv->assoc_req_ies == NULL) {
00623                                         os_free(buf);
00624                                         return;
00625                                 }
00626 
00627                                 drv->assoc_req_ies_len = iwe->u.data.length;
00628                                 os_memcpy(drv->assoc_req_ies, custom,
00629                                           iwe->u.data.length);
00630                         } else if (iwe->u.data.flags == RT_RESPIE_EVENT_FLAG) {
00631                                 wpa_printf(MSG_DEBUG, "Custom wireless event: "
00632                                            "receive RespIEs !!!");
00633                                 drv->assoc_resp_ies =
00634                                         os_malloc(iwe->u.data.length);
00635                                 if (drv->assoc_resp_ies == NULL) {
00636                                         os_free(drv->assoc_req_ies);
00637                                         drv->assoc_req_ies = NULL;
00638                                         os_free(buf);
00639                                         return;
00640                                 }
00641 
00642                                 drv->assoc_resp_ies_len = iwe->u.data.length;
00643                                 os_memcpy(drv->assoc_resp_ies, custom,
00644                                           iwe->u.data.length);
00645                         } else if (iwe->u.data.flags ==
00646                                    RT_ASSOCINFO_EVENT_FLAG) {
00647                                 wpa_printf(MSG_DEBUG, "Custom wireless event: "
00648                                            "receive ASSOCINFO_EVENT !!!");
00649 
00650                                 assoc_info_buf =
00651                                         os_zalloc(drv->assoc_req_ies_len +
00652                                                   drv->assoc_resp_ies_len + 1);
00653 
00654                                 if (assoc_info_buf == NULL) {
00655                                         os_free(drv->assoc_req_ies);
00656                                         drv->assoc_req_ies = NULL;
00657                                         os_free(drv->assoc_resp_ies);
00658                                         drv->assoc_resp_ies = NULL;
00659                                         os_free(buf);
00660                                         return;
00661                                 }
00662 
00663                                 if (drv->assoc_req_ies) {
00664                                         os_memcpy(assoc_info_buf,
00665                                                   drv->assoc_req_ies,
00666                                                   drv->assoc_req_ies_len);
00667                                 }
00668                                 info_pos = assoc_info_buf +
00669                                         drv->assoc_req_ies_len;
00670                                 if (drv->assoc_resp_ies) {
00671                                         os_memcpy(info_pos,
00672                                                   drv->assoc_resp_ies,
00673                                                   drv->assoc_resp_ies_len);
00674                                 }
00675                                 assoc_info_buf[drv->assoc_req_ies_len +
00676                                                drv->assoc_resp_ies_len] = '\0';
00677                                 wpa_driver_ralink_event_wireless_custom(
00678                                         drv, ctx, assoc_info_buf);
00679                                 os_free(drv->assoc_req_ies);
00680                                 drv->assoc_req_ies = NULL;
00681                                 os_free(drv->assoc_resp_ies);
00682                                 drv->assoc_resp_ies = NULL;
00683                                 os_free(assoc_info_buf);
00684                         } else if (iwe->u.data.flags == RT_DISASSOC_EVENT_FLAG)
00685                         {
00686                                 wpa_printf(MSG_DEBUG, "Custom wireless event: "
00687                                            "receive DISASSOCIATED_EVENT !!!");
00688                                 wpa_supplicant_event(ctx, EVENT_DISASSOC,
00689                                                      NULL);
00690                         } else if (iwe->u.data.flags == RT_PMKIDCAND_FLAG) {
00691                                 wpa_printf(MSG_DEBUG, "Custom wireless event: "
00692                                            "receive PMKIDCAND_EVENT !!!");
00693                                 wpa_driver_ralink_event_pmkid(
00694                                         drv, (const u8 *) custom,
00695                                         iwe->u.data.length);
00696                         } else if (iwe->u.data.flags == RT_INTERFACE_DOWN) {
00697                                 drv->g_driver_down = 1;
00698                                 eloop_terminate();
00699                         } else if (iwe->u.data.flags == RT_INTERFACE_UP) {
00700                                 ralink_interface_up(drv);
00701                         } else {
00702                                 wpa_driver_ralink_event_wireless_custom(
00703                                         drv, ctx, buf);
00704                         }
00705                         os_free(buf);
00706                         break;
00707                 }
00708 
00709                 pos += iwe->len;
00710         }
00711 }
00712 
00713 static void
00714 wpa_driver_ralink_event_rtm_newlink(void *ctx, struct ifinfomsg *ifi, 
00715                                     u8 *buf, size_t len)
00716 {
00717         struct wpa_driver_ralink_data *drv = ctx;
00718         int attrlen, rta_len;
00719         struct rtattr *attr;
00720 
00721         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
00722 
00723         wpa_hexdump(MSG_DEBUG, "ifi: ", (u8 *) ifi, sizeof(struct ifinfomsg));
00724 
00725         attrlen = len;
00726         wpa_printf(MSG_DEBUG, "attrlen=%d", attrlen);
00727         attr = (struct rtattr *) buf;
00728         wpa_hexdump(MSG_DEBUG, "attr1: ", (u8 *) attr, sizeof(struct rtattr));
00729         rta_len = RTA_ALIGN(sizeof(struct rtattr));
00730         wpa_hexdump(MSG_DEBUG, "attr2: ", (u8 *)attr,rta_len);
00731         while (RTA_OK(attr, attrlen)) {
00732                 wpa_printf(MSG_DEBUG, "rta_type=%02x\n", attr->rta_type);
00733                 if (attr->rta_type == IFLA_WIRELESS) {
00734                         wpa_driver_ralink_event_wireless(
00735                                 drv, ctx,
00736                                 ((char *) attr) + rta_len,
00737                                 attr->rta_len - rta_len);
00738                 }
00739                 attr = RTA_NEXT(attr, attrlen);
00740                 wpa_hexdump(MSG_DEBUG, "attr3: ",
00741                             (u8 *) attr, sizeof(struct rtattr));
00742         }
00743 }
00744 
00745 static int
00746 ralink_get_we_version_compiled(struct wpa_driver_ralink_data *drv)
00747 {
00748         struct iwreq iwr;
00749         UINT we_version_compiled = 0;
00750 
00751         os_memset(&iwr, 0, sizeof(iwr));
00752         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
00753         iwr.u.data.pointer = (caddr_t) &we_version_compiled;
00754         iwr.u.data.flags = RT_OID_WE_VERSION_COMPILED;
00755 
00756         if (ioctl(drv->ioctl_sock, RT_PRIV_IOCTL, &iwr) < 0) {
00757                 wpa_printf(MSG_DEBUG, "%s: failed", __func__);
00758                 return -1;
00759         }
00760 
00761         drv->we_version_compiled = we_version_compiled;
00762 
00763         return 0;
00764 }
00765 
00766 static void * wpa_driver_ralink_init(void *ctx, const char *ifname)
00767 {
00768         int s;
00769         struct wpa_driver_ralink_data *drv;
00770         struct ifreq ifr;
00771         UCHAR enable_wpa_supplicant = 0;
00772         struct netlink_config *cfg;
00773 
00774         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
00775 
00776         /* open socket to kernel */
00777         if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
00778                 perror("socket");
00779                 return NULL;
00780         }
00781         /* do it */
00782         os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
00783 
00784         if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) {
00785                 perror(ifr.ifr_name);
00786                 return NULL;
00787         }
00788 
00789         drv = os_zalloc(sizeof(*drv));
00790         if (drv == NULL)
00791                 return NULL;
00792 
00793         drv->scanning_done = 1;
00794         drv->ap_scan = 1; /* for now - let's assume ap_scan=1 is used */
00795         drv->ctx = ctx;
00796         os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname));
00797         drv->ioctl_sock = s;
00798         drv->g_driver_down = 0;
00799 
00800         cfg = os_zalloc(sizeof(*cfg));
00801         if (cfg == NULL) {
00802                 close(drv->ioctl_sock);
00803                 os_free(drv);
00804                 return NULL;
00805         }
00806         cfg->ctx = drv;
00807         cfg->newlink_cb = wpa_driver_ralink_event_rtm_newlink;
00808         drv->netlink = netlink_init(cfg);
00809         if (drv->netlink == NULL) {
00810                 os_free(cfg);
00811                 close(drv->ioctl_sock);
00812                 os_free(drv);
00813                 return NULL;
00814         }
00815 
00816         drv->no_of_pmkid = 4; /* Number of PMKID saved supported */
00817 
00818         linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 1);
00819         ralink_get_we_version_compiled(drv);
00820         wpa_driver_ralink_flush_pmkid(drv);
00821 
00822         if (drv->ap_scan == 1)
00823                 enable_wpa_supplicant = 1;
00824         else
00825                 enable_wpa_supplicant = 2;
00826         /* trigger driver support wpa_supplicant */
00827         if (ralink_set_oid(drv, RT_OID_WPA_SUPPLICANT_SUPPORT,
00828                            (PCHAR) &enable_wpa_supplicant, sizeof(UCHAR)) < 0)
00829         {
00830                 wpa_printf(MSG_DEBUG, "RALINK: Failed to set "
00831                            "RT_OID_WPA_SUPPLICANT_SUPPORT(%d)",
00832                            (int) enable_wpa_supplicant);
00833                 wpa_printf(MSG_ERROR, "RALINK: Driver does not support "
00834                            "wpa_supplicant");
00835                 close(s);
00836                 close(drv->ioctl_sock);
00837                 os_free(drv);
00838                 return NULL;
00839         }
00840 
00841         if (drv->ap_scan == 1)
00842                 drv->scanning_done = 0;
00843 
00844         return drv;
00845 }
00846 
00847 static void wpa_driver_ralink_deinit(void *priv)
00848 {
00849         struct wpa_driver_ralink_data *drv = priv;
00850         UCHAR enable_wpa_supplicant;
00851 
00852         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
00853 
00854         enable_wpa_supplicant = 0;
00855 
00856         if (drv->g_driver_down == 0) {
00857                 /* trigger driver disable wpa_supplicant support */
00858                 if (ralink_set_oid(drv, RT_OID_WPA_SUPPLICANT_SUPPORT,
00859                                    (char *) &enable_wpa_supplicant,
00860                                    sizeof(BOOLEAN)) < 0) {
00861                         wpa_printf(MSG_DEBUG, "RALINK: Failed to set "
00862                                    "RT_OID_WPA_SUPPLICANT_SUPPORT(%d)",
00863                                    (int) enable_wpa_supplicant);
00864                 }
00865 
00866                 wpa_driver_ralink_flush_pmkid(drv);
00867 
00868                 sleep(1);
00869                 /* linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 0); */
00870         }
00871 
00872         eloop_cancel_timeout(wpa_driver_ralink_scan_timeout, drv, drv->ctx);
00873         netlink_deinit(drv->netlink);
00874         close(drv->ioctl_sock);
00875         os_free(drv);
00876 }
00877 
00878 static void wpa_driver_ralink_scan_timeout(void *eloop_ctx, void *timeout_ctx)
00879 {
00880         struct wpa_driver_ralink_data *drv = eloop_ctx;
00881 
00882         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
00883 
00884         wpa_printf(MSG_DEBUG, "Scan timeout - try to get results");
00885         wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL);
00886 
00887         drv->scanning_done = 1;
00888 
00889 }
00890 
00891 static int wpa_driver_ralink_scan(void *priv,
00892                                   struct wpa_driver_scan_params *params)
00893 {
00894         struct wpa_driver_ralink_data *drv = priv;
00895         struct iwreq iwr;
00896         int ret = 0;
00897 
00898         if (drv->g_driver_down == 1)
00899                 return -1;
00900 
00901         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
00902 
00903 #if 0
00904         if (ssid_len > IW_ESSID_MAX_SIZE) {
00905                 wpa_printf(MSG_DEBUG, "%s: too long SSID (%lu)",
00906                            __FUNCTION__, (unsigned long) ssid_len);
00907                 return -1;
00908         }
00909 
00910         /* wpa_driver_ralink_set_ssid(drv, ssid, ssid_len); */
00911 #endif
00912 
00913         if (ralink_set_oid(drv, RT_OID_WPS_PROBE_REQ_IE,
00914                            (char *) params->extra_ies, params->extra_ies_len) <
00915             0) {
00916                 wpa_printf(MSG_DEBUG, "RALINK: Failed to set "
00917                            "RT_OID_WPS_PROBE_REQ_IE");
00918         }
00919 
00920         os_memset(&iwr, 0, sizeof(iwr));
00921         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
00922 
00923         if (ioctl(drv->ioctl_sock, SIOCSIWSCAN, &iwr) < 0) {
00924                 perror("ioctl[SIOCSIWSCAN]");
00925                 ret = -1;
00926         }
00927 
00928         /* Not all drivers generate "scan completed" wireless event, so try to
00929          * read results after a timeout. */
00930         eloop_cancel_timeout(wpa_driver_ralink_scan_timeout, drv, drv->ctx);
00931         eloop_register_timeout(4, 0, wpa_driver_ralink_scan_timeout, drv,
00932                                drv->ctx);
00933 
00934         drv->scanning_done = 0;
00935 
00936         return ret;
00937 }
00938 
00939 static struct wpa_scan_results *
00940 wpa_driver_ralink_get_scan_results(void *priv)
00941 {
00942         struct wpa_driver_ralink_data *drv = priv;
00943         UCHAR *buf = NULL;
00944         size_t buf_len;
00945         NDIS_802_11_BSSID_LIST_EX *wsr;
00946         NDIS_WLAN_BSSID_EX *wbi;
00947         struct iwreq iwr;
00948         size_t ap_num;
00949         u8 *pos;
00950         struct wpa_scan_results *res;
00951 
00952         if (drv->g_driver_down == 1)
00953                 return NULL;
00954         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
00955 
00956         if (drv->we_version_compiled >= 17)
00957                 buf_len = 8192;
00958         else
00959                 buf_len = 4096;
00960 
00961         for (;;) {
00962                 buf = os_zalloc(buf_len);
00963                 iwr.u.data.length = buf_len;
00964                 if (buf == NULL)
00965                         return NULL;
00966 
00967                 wsr = (NDIS_802_11_BSSID_LIST_EX *) buf;
00968 
00969                 wsr->NumberOfItems = 0;
00970                 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
00971                 iwr.u.data.pointer = (void *) buf;
00972                 iwr.u.data.flags = OID_802_11_BSSID_LIST;
00973 
00974                 if (ioctl(drv->ioctl_sock, RT_PRIV_IOCTL, &iwr) == 0)
00975                         break;
00976 
00977                 if (errno == E2BIG && buf_len < 65535) {
00978                         os_free(buf);
00979                         buf = NULL;
00980                         buf_len *= 2;
00981                         if (buf_len > 65535)
00982                                 buf_len = 65535; /* 16-bit length field */
00983                         wpa_printf(MSG_DEBUG, "Scan results did not fit - "
00984                                    "trying larger buffer (%lu bytes)",
00985                                    (unsigned long) buf_len);
00986                 } else {
00987                         perror("ioctl[RT_PRIV_IOCTL]");
00988                         os_free(buf);
00989                         return NULL;
00990                 }
00991         }
00992 
00993         res = os_zalloc(sizeof(*res));
00994         if (res == NULL) {
00995                 os_free(buf);
00996                 return NULL;
00997         }
00998 
00999         res->res = os_zalloc(wsr->NumberOfItems *
01000                              sizeof(struct wpa_scan_res *));
01001         if (res->res == NULL) {
01002                 os_free(res);
01003                 os_free(buf);
01004                 return NULL;
01005         }
01006 
01007         for (ap_num = 0, wbi = wsr->Bssid; ap_num < wsr->NumberOfItems;
01008              ++ap_num) {
01009                 struct wpa_scan_res *r = NULL;
01010                 size_t extra_len = 0, var_ie_len = 0;
01011                 u8 *pos2;
01012 
01013                 /* SSID data element */
01014                 extra_len += 2 + wbi->Ssid.SsidLength;
01015                 var_ie_len = wbi->IELength - sizeof(NDIS_802_11_FIXED_IEs);
01016                 r = os_zalloc(sizeof(*r) + extra_len + var_ie_len);
01017                 if (r == NULL)
01018                         break;
01019                 res->res[res->num++] = r;
01020 
01021                 wpa_printf(MSG_DEBUG, "SSID - %s", wbi->Ssid.Ssid);
01022                 /* get ie's */
01023                 wpa_hexdump(MSG_DEBUG, "RALINK: AP IEs",
01024                             (u8 *) &wbi->IEs[0], wbi->IELength);
01025 
01026                 os_memcpy(r->bssid, wbi->MacAddress, ETH_ALEN);
01027 
01028                 extra_len += (2 + wbi->Ssid.SsidLength);
01029                 r->ie_len = extra_len + var_ie_len;
01030                 pos2 = (u8 *) (r + 1);
01031 
01032                 /*
01033                  * Generate a fake SSID IE since the driver did not report
01034                  * a full IE list.
01035                  */
01036                 *pos2++ = WLAN_EID_SSID;
01037                 *pos2++ = wbi->Ssid.SsidLength;
01038                 os_memcpy(pos2, wbi->Ssid.Ssid, wbi->Ssid.SsidLength);
01039                 pos2 += wbi->Ssid.SsidLength;
01040 
01041                 r->freq = (wbi->Configuration.DSConfig / 1000);
01042 
01043                 pos = (u8 *) wbi + sizeof(*wbi) - 1;
01044 
01045                 pos += sizeof(NDIS_802_11_FIXED_IEs) - 2;
01046                 os_memcpy(&(r->caps), pos, 2);
01047                 pos += 2;
01048 
01049                 if (wbi->IELength > sizeof(NDIS_802_11_FIXED_IEs))
01050                         os_memcpy(pos2, pos, var_ie_len);
01051 
01052                 wbi = (NDIS_WLAN_BSSID_EX *) ((u8 *) wbi + wbi->Length);
01053         }
01054 
01055         os_free(buf);
01056         return res;
01057 }
01058 
01059 static int ralink_set_auth_mode(struct wpa_driver_ralink_data *drv,
01060                                 NDIS_802_11_AUTHENTICATION_MODE mode)
01061 {
01062         NDIS_802_11_AUTHENTICATION_MODE auth_mode = mode;
01063 
01064         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
01065 
01066         if (ralink_set_oid(drv, OID_802_11_AUTHENTICATION_MODE,
01067                            (char *) &auth_mode, sizeof(auth_mode)) < 0) {
01068                 wpa_printf(MSG_DEBUG, "RALINK: Failed to set "
01069                            "OID_802_11_AUTHENTICATION_MODE (%d)",
01070                            (int) auth_mode);
01071                 return -1;
01072         }
01073         return 0;
01074 }
01075 
01076 static int ralink_set_encr_type(struct wpa_driver_ralink_data *drv,
01077                                 NDIS_802_11_WEP_STATUS encr_type)
01078 {
01079         NDIS_802_11_WEP_STATUS wep_status = encr_type;
01080 
01081         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
01082 
01083         if (ralink_set_oid(drv, OID_802_11_WEP_STATUS,
01084                            (char *) &wep_status, sizeof(wep_status)) < 0) {
01085                 wpa_printf(MSG_DEBUG, "RALINK: Failed to set "
01086                            "OID_802_11_WEP_STATUS (%d)",
01087                            (int) wep_status);
01088                 return -1;
01089         }
01090         return 0;
01091 }
01092 
01093 
01094 static int wpa_driver_ralink_remove_key(struct wpa_driver_ralink_data *drv,
01095                                         int key_idx, const u8 *addr,
01096                                         const u8 *bssid, int pairwise)
01097 {
01098         NDIS_802_11_REMOVE_KEY rkey;
01099         NDIS_802_11_KEY_INDEX _index;
01100         int res, res2;
01101 
01102         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
01103 
01104         os_memset(&rkey, 0, sizeof(rkey));
01105 
01106         rkey.Length = sizeof(rkey);
01107         rkey.KeyIndex = key_idx;
01108 
01109         if (pairwise)
01110                 rkey.KeyIndex |= 1 << 30;
01111 
01112         os_memcpy(rkey.BSSID, bssid, ETH_ALEN);
01113 
01114         res = ralink_set_oid(drv, OID_802_11_REMOVE_KEY, (char *) &rkey,
01115                              sizeof(rkey));
01116 
01117         /* AlbertY@20060210 removed it */
01118         if (0 /* !pairwise */) {
01119                 res2 = ralink_set_oid(drv, OID_802_11_REMOVE_WEP,
01120                                       (char *) &_index, sizeof(_index));
01121         } else
01122                 res2 = 0;
01123 
01124         if (res < 0 && res2 < 0)
01125                 return res;
01126         return 0;
01127 }
01128 
01129 static int wpa_driver_ralink_add_wep(struct wpa_driver_ralink_data *drv,
01130                                      int pairwise, int key_idx, int set_tx,
01131                                      const u8 *key, size_t key_len)
01132 {
01133         NDIS_802_11_WEP *wep;
01134         size_t len;
01135         int res;
01136 
01137         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
01138 
01139         len = 12 + key_len;
01140         wep = os_zalloc(len);
01141         if (wep == NULL)
01142                 return -1;
01143 
01144         wep->Length = len;
01145         wep->KeyIndex = key_idx;
01146 
01147         if (set_tx)
01148                 wep->KeyIndex |= 0x80000000;
01149 
01150         wep->KeyLength = key_len;
01151         os_memcpy(wep->KeyMaterial, key, key_len);
01152 
01153         wpa_hexdump_key(MSG_MSGDUMP, "RALINK: OID_802_11_ADD_WEP",
01154                         (const u8 *) wep, len);
01155         res = ralink_set_oid(drv, OID_802_11_ADD_WEP, (char *) wep, len);
01156 
01157         os_free(wep);
01158 
01159         return res;
01160 }
01161 
01162 static int wpa_driver_ralink_set_key(const char *ifname, void *priv,
01163                                      enum wpa_alg alg, const u8 *addr,
01164                                      int key_idx, int set_tx,
01165                                      const u8 *seq, size_t seq_len,
01166                                      const u8 *key, size_t key_len)
01167 {
01168         struct wpa_driver_ralink_data *drv = priv;
01169         size_t len, i;
01170         NDIS_802_11_KEY *nkey;
01171         int res, pairwise;
01172         u8 bssid[ETH_ALEN];
01173 
01174         if (drv->g_driver_down == 1)
01175                 return -1;
01176 
01177         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
01178 
01179         drv->bAddWepKey = FALSE;
01180 
01181         if (addr == NULL || os_memcmp(addr, "\xff\xff\xff\xff\xff\xff",
01182                                       ETH_ALEN) == 0) {
01183                 /* Group Key */
01184                 pairwise = 0;
01185                 wpa_driver_ralink_get_bssid(drv, bssid);
01186         } else {
01187                 /* Pairwise Key */
01188                 pairwise = 1;
01189                 os_memcpy(bssid, addr, ETH_ALEN);
01190         }
01191 
01192         if (alg == WPA_ALG_NONE || key_len == 0) {
01193                 return wpa_driver_ralink_remove_key(drv, key_idx, addr, bssid,
01194                                                     pairwise);
01195         }
01196 
01197         if (alg == WPA_ALG_WEP) {
01198                 drv->bAddWepKey = TRUE;
01199                 return wpa_driver_ralink_add_wep(drv, pairwise, key_idx,
01200                                                  set_tx, key, key_len);
01201         }
01202 
01203         len = 12 + 6 + 6 + 8 + key_len;
01204 
01205         nkey = os_zalloc(len);
01206         if (nkey == NULL)
01207                 return -1;
01208 
01209         nkey->Length = len;
01210         nkey->KeyIndex = key_idx;
01211 
01212         if (set_tx)
01213                 nkey->KeyIndex |= 1 << 31;
01214 
01215         if (pairwise)
01216                 nkey->KeyIndex |= 1 << 30;
01217 
01218         if (seq && seq_len)
01219                 nkey->KeyIndex |= 1 << 29;
01220 
01221         nkey->KeyLength = key_len;
01222         os_memcpy(nkey->BSSID, bssid, ETH_ALEN);
01223 
01224         if (seq && seq_len) {
01225                 for (i = 0; i < seq_len; i++)
01226                         nkey->KeyRSC |= seq[i] << (i * 8);
01227         }
01228         if (alg == WPA_ALG_TKIP && key_len == 32) {
01229                 os_memcpy(nkey->KeyMaterial, key, 16);
01230                 os_memcpy(nkey->KeyMaterial + 16, key + 24, 8);
01231                 os_memcpy(nkey->KeyMaterial + 24, key + 16, 8);
01232         } else {
01233                 os_memcpy(nkey->KeyMaterial, key, key_len);
01234         }
01235 
01236         wpa_printf(MSG_DEBUG, "%s: alg=%d key_idx=%d set_tx=%d seq_len=%lu "
01237                    "key_len=%lu", __FUNCTION__, alg, key_idx, set_tx,
01238                    (unsigned long) seq_len, (unsigned long) key_len);
01239 
01240         wpa_hexdump_key(MSG_MSGDUMP, "RALINK: OID_802_11_ADD_KEY",
01241                         (const u8 *) nkey, len);
01242         res = ralink_set_oid(drv, OID_802_11_ADD_KEY, (char *) nkey, len);
01243         os_free(nkey);
01244 
01245         return res;
01246 }
01247 
01248 static int wpa_driver_ralink_disassociate(void *priv, const u8 *addr,
01249                                         int reason_code)
01250 {
01251         struct wpa_driver_ralink_data *drv = priv;
01252 
01253         if (drv->g_driver_down == 1)
01254                 return -1;
01255         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
01256         if (ralink_set_oid(drv, OID_802_11_DISASSOCIATE, "    ", 4) < 0) {
01257                 wpa_printf(MSG_DEBUG, "RALINK: Failed to set "
01258                            "OID_802_11_DISASSOCIATE");
01259         }
01260 
01261         return 0;
01262 }
01263 
01264 static int wpa_driver_ralink_deauthenticate(void *priv, const u8 *addr,
01265                                           int reason_code)
01266 {
01267         struct wpa_driver_ralink_data *drv = priv;
01268 
01269         wpa_printf(MSG_DEBUG, "g_driver_down = %d", drv->g_driver_down);
01270 
01271         if (drv->g_driver_down == 1)
01272                 return -1;
01273 
01274         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
01275         if (ralink_get_new_driver_flag(drv) == 0) {
01276                 return wpa_driver_ralink_disassociate(priv, addr, reason_code);
01277         } else {
01278                 MLME_DEAUTH_REQ_STRUCT mlme;
01279                 os_memset(&mlme, 0, sizeof(MLME_DEAUTH_REQ_STRUCT));
01280                 mlme.Reason = reason_code;
01281                 os_memcpy(mlme.Addr, addr, MAC_ADDR_LEN);
01282                 return ralink_set_oid(drv, OID_802_11_DEAUTHENTICATION,
01283                                       (char *) &mlme,
01284                                       sizeof(MLME_DEAUTH_REQ_STRUCT));
01285         }
01286 }
01287 
01288 static int wpa_driver_ralink_set_gen_ie(void *priv, const u8 *ie,
01289                                         size_t ie_len)
01290 {
01291         struct wpa_driver_ralink_data *drv = priv;
01292         struct iwreq iwr;
01293         int ret = 0;
01294 
01295         os_memset(&iwr, 0, sizeof(iwr));
01296         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
01297         iwr.u.data.pointer = (caddr_t) ie;
01298         iwr.u.data.length = ie_len;
01299 
01300         wpa_hexdump(MSG_DEBUG, "wpa_driver_ralink_set_gen_ie: ",
01301                     (u8 *) ie, ie_len);
01302 
01303         if (ioctl(drv->ioctl_sock, SIOCSIWGENIE, &iwr) < 0) {
01304                 perror("ioctl[SIOCSIWGENIE]");
01305                 ret = -1;
01306         }
01307 
01308         return ret;
01309 }
01310 
01311 static int
01312 wpa_driver_ralink_associate(void *priv,
01313                             struct wpa_driver_associate_params *params)
01314 {
01315         struct wpa_driver_ralink_data *drv = priv;
01316 
01317         NDIS_802_11_NETWORK_INFRASTRUCTURE mode;
01318         NDIS_802_11_AUTHENTICATION_MODE auth_mode;
01319         NDIS_802_11_WEP_STATUS encr;
01320         BOOLEAN         ieee8021xMode;
01321         BOOLEAN         ieee8021x_required_key = TRUE;
01322 
01323         if (drv->g_driver_down == 1)
01324                 return -1;
01325         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
01326 
01327         if (params->mode == IEEE80211_MODE_IBSS)
01328                 mode = Ndis802_11IBSS;
01329         else
01330                 mode = Ndis802_11Infrastructure;
01331 
01332         if (ralink_set_oid(drv, OID_802_11_INFRASTRUCTURE_MODE,
01333                          (char *) &mode, sizeof(mode)) < 0) {
01334                 wpa_printf(MSG_DEBUG, "RALINK: Failed to set "
01335                            "OID_802_11_INFRASTRUCTURE_MODE (%d)",
01336                            (int) mode);
01337                 /* Try to continue anyway */
01338         }
01339 
01340         if (params->key_mgmt_suite == KEY_MGMT_WPS) {
01341                 UCHAR enable_wps = 0x80;
01342                 /* trigger driver support wpa_supplicant */
01343                 if (ralink_set_oid(drv, RT_OID_WPA_SUPPLICANT_SUPPORT,
01344                                    (PCHAR) &enable_wps, sizeof(UCHAR)) < 0) {
01345                         wpa_printf(MSG_INFO, "RALINK: Failed to set "
01346                                    "RT_OID_WPA_SUPPLICANT_SUPPORT (%d)",
01347                                    (int) enable_wps);
01348                 }
01349 
01350                 wpa_driver_ralink_set_gen_ie(priv, params->wpa_ie,
01351                                              params->wpa_ie_len);
01352 
01353                 ralink_set_auth_mode(drv, Ndis802_11AuthModeOpen);
01354 
01355                 ralink_set_encr_type(drv, Ndis802_11EncryptionDisabled);
01356         } else {
01357 #ifdef CONFIG_WPS
01358                 UCHAR enable_wpa_supplicant;
01359 
01360                 if (drv->ap_scan == 1)
01361                         enable_wpa_supplicant = 0x01;
01362                 else
01363                         enable_wpa_supplicant = 0x02;
01364 
01365                 /* trigger driver support wpa_supplicant */
01366                 if (ralink_set_oid(drv, RT_OID_WPA_SUPPLICANT_SUPPORT,
01367                                    (PCHAR) &enable_wpa_supplicant,
01368                                    sizeof(UCHAR)) < 0) {
01369                         wpa_printf(MSG_DEBUG, "RALINK: Failed to set "
01370                                    "RT_OID_WPA_SUPPLICANT_SUPPORT (%d)",
01371                                    (int) enable_wpa_supplicant);
01372                 }
01373 
01374                 wpa_driver_ralink_set_gen_ie(priv, (u8 *) "", 0);
01375 #endif /* CONFIG_WPS */
01376 
01377                 if (params->wpa_ie == NULL || params->wpa_ie_len == 0) {
01378                         if (params->auth_alg & WPA_AUTH_ALG_SHARED) {
01379                                 if (params->auth_alg & WPA_AUTH_ALG_OPEN)
01380                                         auth_mode = Ndis802_11AuthModeAutoSwitch;
01381                                 else
01382                                         auth_mode = Ndis802_11AuthModeShared;
01383                         } else
01384                                 auth_mode = Ndis802_11AuthModeOpen;
01385                 } else if (params->wpa_ie[0] == WLAN_EID_RSN) {
01386                         if (params->key_mgmt_suite == KEY_MGMT_PSK)
01387                                 auth_mode = Ndis802_11AuthModeWPA2PSK;
01388                         else
01389                                 auth_mode = Ndis802_11AuthModeWPA2;
01390                 } else {
01391                         if (params->key_mgmt_suite == KEY_MGMT_WPA_NONE)
01392                                 auth_mode = Ndis802_11AuthModeWPANone;
01393                         else if (params->key_mgmt_suite == KEY_MGMT_PSK)
01394                                 auth_mode = Ndis802_11AuthModeWPAPSK;
01395                         else
01396                                 auth_mode = Ndis802_11AuthModeWPA;
01397                 }
01398 
01399                 switch (params->pairwise_suite) {
01400                 case CIPHER_CCMP:
01401                         encr = Ndis802_11Encryption3Enabled;
01402                         break;
01403                 case CIPHER_TKIP:
01404                         encr = Ndis802_11Encryption2Enabled;
01405                         break;
01406                 case CIPHER_WEP40:
01407                 case CIPHER_WEP104:
01408                         encr = Ndis802_11Encryption1Enabled;
01409                         break;
01410                 case CIPHER_NONE:
01411                         if (params->group_suite == CIPHER_CCMP)
01412                                 encr = Ndis802_11Encryption3Enabled;
01413                         else if (params->group_suite == CIPHER_TKIP)
01414                                 encr = Ndis802_11Encryption2Enabled;
01415                         else
01416                                 encr = Ndis802_11EncryptionDisabled;
01417                         break;
01418                 default:
01419                         encr = Ndis802_11EncryptionDisabled;
01420                         break;
01421                 }
01422 
01423                 ralink_set_auth_mode(drv, auth_mode);
01424 
01425                 /* notify driver that IEEE8021x mode is enabled */
01426                 if (params->key_mgmt_suite == KEY_MGMT_802_1X_NO_WPA) {
01427                         ieee8021xMode = TRUE;
01428                         if (drv->bAddWepKey)
01429                                 ieee8021x_required_key = FALSE;
01430                 } else
01431                         ieee8021xMode = FALSE;
01432 
01433                 if (ralink_set_oid(drv, OID_802_11_SET_IEEE8021X_REQUIRE_KEY,
01434                                    (char *) &ieee8021x_required_key,
01435                                    sizeof(BOOLEAN)) < 0) {
01436                         wpa_printf(MSG_DEBUG, "ERROR: Failed to set "
01437                                    "OID_802_11_SET_IEEE8021X_REQUIRE_KEY(%d)",
01438                                    (int) ieee8021x_required_key);
01439                 } else {
01440                         wpa_printf(MSG_DEBUG, "ieee8021x_required_key is %s",
01441                                    ieee8021x_required_key ? "TRUE" : "FALSE");
01442                 }
01443 
01444                 if (ralink_set_oid(drv, OID_802_11_SET_IEEE8021X,
01445                                    (char *) &ieee8021xMode, sizeof(BOOLEAN)) <
01446                     0) {
01447                         wpa_printf(MSG_DEBUG, "RALINK: Failed to set "
01448                                    "OID_802_11_SET_IEEE8021X(%d)",
01449                                    (int) ieee8021xMode);
01450                 }
01451 
01452                 ralink_set_encr_type(drv, encr);
01453 
01454                 if ((ieee8021xMode == FALSE) &&
01455                     (encr == Ndis802_11Encryption1Enabled)) {
01456                         /* static WEP */
01457                         int enabled = 0;
01458                         if (ralink_set_oid(drv, OID_802_11_DROP_UNENCRYPTED,
01459                                            (char *) &enabled, sizeof(enabled))
01460                             < 0) {
01461                                 wpa_printf(MSG_DEBUG, "RALINK: Failed to set "
01462                                            "OID_802_11_DROP_UNENCRYPTED(%d)",
01463                                            (int) encr);
01464                         }
01465                 }
01466         }
01467 
01468         return wpa_driver_ralink_set_ssid(drv, params->ssid, params->ssid_len);
01469 }
01470 
01471 static int
01472 wpa_driver_ralink_set_countermeasures(void *priv, int enabled)
01473 {
01474         struct wpa_driver_ralink_data *drv = priv;
01475         if (drv->g_driver_down == 1)
01476                 return -1;
01477         wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled);
01478         return ralink_set_oid(drv, OID_SET_COUNTERMEASURES, (char *) &enabled,
01479                               sizeof(int));
01480 }
01481 
01482 const struct wpa_driver_ops wpa_driver_ralink_ops = {
01483         .name = "ralink",
01484         .desc = "Ralink Wireless Client driver",
01485         .get_bssid = wpa_driver_ralink_get_bssid,
01486         .get_ssid = wpa_driver_ralink_get_ssid,
01487         .set_key = wpa_driver_ralink_set_key,
01488         .init = wpa_driver_ralink_init,
01489         .deinit = wpa_driver_ralink_deinit,
01490         .set_countermeasures    = wpa_driver_ralink_set_countermeasures,
01491         .scan2 = wpa_driver_ralink_scan,
01492         .get_scan_results2 = wpa_driver_ralink_get_scan_results,
01493         .deauthenticate = wpa_driver_ralink_deauthenticate,
01494         .disassociate = wpa_driver_ralink_disassociate,
01495         .associate = wpa_driver_ralink_associate,
01496         .add_pmkid = wpa_driver_ralink_add_pmkid,
01497         .remove_pmkid = wpa_driver_ralink_remove_pmkid,
01498         .flush_pmkid = wpa_driver_ralink_flush_pmkid,
01499 };


wpa_supplicant
Author(s): Package maintained by Blaise Gassend
autogenerated on Thu Apr 24 2014 15:34:34