driver_test.c
Go to the documentation of this file.
00001 /*
00002  * Testing driver interface for a simulated network driver
00003  * Copyright (c) 2004-2010, Jouni Malinen <j@w1.fi>
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License version 2 as
00007  * published by the Free Software Foundation.
00008  *
00009  * Alternatively, this software may be distributed under the terms of BSD
00010  * license.
00011  *
00012  * See README and COPYING for more details.
00013  */
00014 
00015 /* Make sure we get winsock2.h for Windows build to get sockaddr_storage */
00016 #include "build_config.h"
00017 #ifdef CONFIG_NATIVE_WINDOWS
00018 #include <winsock2.h>
00019 #endif /* CONFIG_NATIVE_WINDOWS */
00020 
00021 #include "utils/includes.h"
00022 
00023 #ifndef CONFIG_NATIVE_WINDOWS
00024 #include <sys/un.h>
00025 #include <dirent.h>
00026 #include <sys/stat.h>
00027 #define DRIVER_TEST_UNIX
00028 #endif /* CONFIG_NATIVE_WINDOWS */
00029 
00030 #include "utils/common.h"
00031 #include "utils/eloop.h"
00032 #include "utils/list.h"
00033 #include "utils/trace.h"
00034 #include "common/ieee802_11_defs.h"
00035 #include "crypto/sha1.h"
00036 #include "l2_packet/l2_packet.h"
00037 #include "driver.h"
00038 
00039 
00040 struct test_client_socket {
00041         struct test_client_socket *next;
00042         u8 addr[ETH_ALEN];
00043         struct sockaddr_un un;
00044         socklen_t unlen;
00045         struct test_driver_bss *bss;
00046 };
00047 
00048 struct test_driver_bss {
00049         struct wpa_driver_test_data *drv;
00050         struct dl_list list;
00051         void *bss_ctx;
00052         char ifname[IFNAMSIZ];
00053         u8 bssid[ETH_ALEN];
00054         u8 *ie;
00055         size_t ielen;
00056         u8 *wps_beacon_ie;
00057         size_t wps_beacon_ie_len;
00058         u8 *wps_probe_resp_ie;
00059         size_t wps_probe_resp_ie_len;
00060         u8 ssid[32];
00061         size_t ssid_len;
00062         int privacy;
00063 };
00064 
00065 struct wpa_driver_test_global {
00066         int bss_add_used;
00067         u8 req_addr[ETH_ALEN];
00068 };
00069 
00070 struct wpa_driver_test_data {
00071         struct wpa_driver_test_global *global;
00072         void *ctx;
00073         WPA_TRACE_REF(ctx);
00074         u8 own_addr[ETH_ALEN];
00075         int test_socket;
00076 #ifdef DRIVER_TEST_UNIX
00077         struct sockaddr_un hostapd_addr;
00078 #endif /* DRIVER_TEST_UNIX */
00079         int hostapd_addr_set;
00080         struct sockaddr_in hostapd_addr_udp;
00081         int hostapd_addr_udp_set;
00082         char *own_socket_path;
00083         char *test_dir;
00084 #define MAX_SCAN_RESULTS 30
00085         struct wpa_scan_res *scanres[MAX_SCAN_RESULTS];
00086         size_t num_scanres;
00087         int use_associnfo;
00088         u8 assoc_wpa_ie[80];
00089         size_t assoc_wpa_ie_len;
00090         int use_mlme;
00091         int associated;
00092         u8 *probe_req_ie;
00093         size_t probe_req_ie_len;
00094         u8 probe_req_ssid[32];
00095         size_t probe_req_ssid_len;
00096         int ibss;
00097         int ap;
00098 
00099         struct test_client_socket *cli;
00100         struct dl_list bss;
00101         int udp_port;
00102 
00103         int alloc_iface_idx;
00104 
00105         int probe_req_report;
00106         unsigned int remain_on_channel_freq;
00107         unsigned int remain_on_channel_duration;
00108 
00109         int current_freq;
00110 };
00111 
00112 
00113 static void wpa_driver_test_deinit(void *priv);
00114 static int wpa_driver_test_attach(struct wpa_driver_test_data *drv,
00115                                   const char *dir, int ap);
00116 static void wpa_driver_test_close_test_socket(
00117         struct wpa_driver_test_data *drv);
00118 static void test_remain_on_channel_timeout(void *eloop_ctx, void *timeout_ctx);
00119 
00120 
00121 static void test_driver_free_bss(struct test_driver_bss *bss)
00122 {
00123         os_free(bss->ie);
00124         os_free(bss->wps_beacon_ie);
00125         os_free(bss->wps_probe_resp_ie);
00126         os_free(bss);
00127 }
00128 
00129 
00130 static void test_driver_free_bsses(struct wpa_driver_test_data *drv)
00131 {
00132         struct test_driver_bss *bss, *tmp;
00133 
00134         dl_list_for_each_safe(bss, tmp, &drv->bss, struct test_driver_bss,
00135                               list) {
00136                 dl_list_del(&bss->list);
00137                 test_driver_free_bss(bss);
00138         }
00139 }
00140 
00141 
00142 static struct test_client_socket *
00143 test_driver_get_cli(struct wpa_driver_test_data *drv, struct sockaddr_un *from,
00144                     socklen_t fromlen)
00145 {
00146         struct test_client_socket *cli = drv->cli;
00147 
00148         while (cli) {
00149                 if (cli->unlen == fromlen &&
00150                     strncmp(cli->un.sun_path, from->sun_path,
00151                             fromlen - sizeof(cli->un.sun_family)) == 0)
00152                         return cli;
00153                 cli = cli->next;
00154         }
00155 
00156         return NULL;
00157 }
00158 
00159 
00160 static int test_driver_send_eapol(void *priv, const u8 *addr, const u8 *data,
00161                                   size_t data_len, int encrypt,
00162                                   const u8 *own_addr)
00163 {
00164         struct test_driver_bss *dbss = priv;
00165         struct wpa_driver_test_data *drv = dbss->drv;
00166         struct test_client_socket *cli;
00167         struct msghdr msg;
00168         struct iovec io[3];
00169         struct l2_ethhdr eth;
00170 
00171         if (drv->test_socket < 0)
00172                 return -1;
00173 
00174         cli = drv->cli;
00175         while (cli) {
00176                 if (memcmp(cli->addr, addr, ETH_ALEN) == 0)
00177                         break;
00178                 cli = cli->next;
00179         }
00180 
00181         if (!cli) {
00182                 wpa_printf(MSG_DEBUG, "%s: no destination client entry",
00183                            __func__);
00184                 return -1;
00185         }
00186 
00187         memcpy(eth.h_dest, addr, ETH_ALEN);
00188         memcpy(eth.h_source, own_addr, ETH_ALEN);
00189         eth.h_proto = host_to_be16(ETH_P_EAPOL);
00190 
00191         io[0].iov_base = "EAPOL ";
00192         io[0].iov_len = 6;
00193         io[1].iov_base = &eth;
00194         io[1].iov_len = sizeof(eth);
00195         io[2].iov_base = (u8 *) data;
00196         io[2].iov_len = data_len;
00197 
00198         memset(&msg, 0, sizeof(msg));
00199         msg.msg_iov = io;
00200         msg.msg_iovlen = 3;
00201         msg.msg_name = &cli->un;
00202         msg.msg_namelen = cli->unlen;
00203         return sendmsg(drv->test_socket, &msg, 0);
00204 }
00205 
00206 
00207 static int test_driver_send_ether(void *priv, const u8 *dst, const u8 *src,
00208                                   u16 proto, const u8 *data, size_t data_len)
00209 {
00210         struct test_driver_bss *dbss = priv;
00211         struct wpa_driver_test_data *drv = dbss->drv;
00212         struct msghdr msg;
00213         struct iovec io[3];
00214         struct l2_ethhdr eth;
00215         char desttxt[30];
00216         struct sockaddr_un addr;
00217         struct dirent *dent;
00218         DIR *dir;
00219         int ret = 0, broadcast = 0, count = 0;
00220 
00221         if (drv->test_socket < 0 || drv->test_dir == NULL) {
00222                 wpa_printf(MSG_DEBUG, "%s: invalid parameters (sock=%d "
00223                            "test_dir=%p)",
00224                            __func__, drv->test_socket, drv->test_dir);
00225                 return -1;
00226         }
00227 
00228         broadcast = memcmp(dst, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) == 0;
00229         snprintf(desttxt, sizeof(desttxt), MACSTR, MAC2STR(dst));
00230 
00231         memcpy(eth.h_dest, dst, ETH_ALEN);
00232         memcpy(eth.h_source, src, ETH_ALEN);
00233         eth.h_proto = host_to_be16(proto);
00234 
00235         io[0].iov_base = "ETHER ";
00236         io[0].iov_len = 6;
00237         io[1].iov_base = &eth;
00238         io[1].iov_len = sizeof(eth);
00239         io[2].iov_base = (u8 *) data;
00240         io[2].iov_len = data_len;
00241 
00242         memset(&msg, 0, sizeof(msg));
00243         msg.msg_iov = io;
00244         msg.msg_iovlen = 3;
00245 
00246         dir = opendir(drv->test_dir);
00247         if (dir == NULL) {
00248                 perror("test_driver: opendir");
00249                 return -1;
00250         }
00251         while ((dent = readdir(dir))) {
00252 #ifdef _DIRENT_HAVE_D_TYPE
00253                 /* Skip the file if it is not a socket. Also accept
00254                  * DT_UNKNOWN (0) in case the C library or underlying file
00255                  * system does not support d_type. */
00256                 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
00257                         continue;
00258 #endif /* _DIRENT_HAVE_D_TYPE */
00259                 if (strcmp(dent->d_name, ".") == 0 ||
00260                     strcmp(dent->d_name, "..") == 0)
00261                         continue;
00262 
00263                 memset(&addr, 0, sizeof(addr));
00264                 addr.sun_family = AF_UNIX;
00265                 snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/%s",
00266                          drv->test_dir, dent->d_name);
00267 
00268                 if (strcmp(addr.sun_path, drv->own_socket_path) == 0)
00269                         continue;
00270                 if (!broadcast && strstr(dent->d_name, desttxt) == NULL)
00271                         continue;
00272 
00273                 wpa_printf(MSG_DEBUG, "%s: Send ether frame to %s",
00274                            __func__, dent->d_name);
00275 
00276                 msg.msg_name = &addr;
00277                 msg.msg_namelen = sizeof(addr);
00278                 ret = sendmsg(drv->test_socket, &msg, 0);
00279                 if (ret < 0)
00280                         perror("driver_test: sendmsg");
00281                 count++;
00282         }
00283         closedir(dir);
00284 
00285         if (!broadcast && count == 0) {
00286                 wpa_printf(MSG_DEBUG, "%s: Destination " MACSTR " not found",
00287                            __func__, MAC2STR(dst));
00288                 return -1;
00289         }
00290 
00291         return ret;
00292 }
00293 
00294 
00295 static int wpa_driver_test_send_mlme(void *priv, const u8 *data,
00296                                      size_t data_len)
00297 {
00298         struct test_driver_bss *dbss = priv;
00299         struct wpa_driver_test_data *drv = dbss->drv;
00300         struct msghdr msg;
00301         struct iovec io[2];
00302         const u8 *dest;
00303         struct sockaddr_un addr;
00304         struct dirent *dent;
00305         DIR *dir;
00306         int broadcast;
00307         int ret = 0;
00308         struct ieee80211_hdr *hdr;
00309         u16 fc;
00310         char cmd[50];
00311         int freq;
00312 #ifdef HOSTAPD
00313         char desttxt[30];
00314 #endif /* HOSTAPD */
00315         union wpa_event_data event;
00316 
00317         wpa_hexdump(MSG_MSGDUMP, "test_send_mlme", data, data_len);
00318         if (drv->test_socket < 0 || data_len < 10) {
00319                 wpa_printf(MSG_DEBUG, "%s: invalid parameters (sock=%d len=%lu"
00320                            " test_dir=%p)",
00321                            __func__, drv->test_socket,
00322                            (unsigned long) data_len,
00323                            drv->test_dir);
00324                 return -1;
00325         }
00326 
00327         dest = data + 4;
00328         broadcast = os_memcmp(dest, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) == 0;
00329 
00330 #ifdef HOSTAPD
00331         snprintf(desttxt, sizeof(desttxt), MACSTR, MAC2STR(dest));
00332 #endif /* HOSTAPD */
00333 
00334         if (drv->remain_on_channel_freq)
00335                 freq = drv->remain_on_channel_freq;
00336         else
00337                 freq = drv->current_freq;
00338         wpa_printf(MSG_DEBUG, "test_driver(%s): MLME TX on freq %d MHz",
00339                    dbss->ifname, freq);
00340         os_snprintf(cmd, sizeof(cmd), "MLME freq=%d ", freq);
00341         io[0].iov_base = cmd;
00342         io[0].iov_len = os_strlen(cmd);
00343         io[1].iov_base = (void *) data;
00344         io[1].iov_len = data_len;
00345 
00346         os_memset(&msg, 0, sizeof(msg));
00347         msg.msg_iov = io;
00348         msg.msg_iovlen = 2;
00349 
00350 #ifdef HOSTAPD
00351         if (drv->test_dir == NULL) {
00352                 wpa_printf(MSG_DEBUG, "%s: test_dir == NULL", __func__);
00353                 return -1;
00354         }
00355 
00356         dir = opendir(drv->test_dir);
00357         if (dir == NULL) {
00358                 perror("test_driver: opendir");
00359                 return -1;
00360         }
00361         while ((dent = readdir(dir))) {
00362 #ifdef _DIRENT_HAVE_D_TYPE
00363                 /* Skip the file if it is not a socket. Also accept
00364                  * DT_UNKNOWN (0) in case the C library or underlying file
00365                  * system does not support d_type. */
00366                 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
00367                         continue;
00368 #endif /* _DIRENT_HAVE_D_TYPE */
00369                 if (os_strcmp(dent->d_name, ".") == 0 ||
00370                     os_strcmp(dent->d_name, "..") == 0)
00371                         continue;
00372 
00373                 os_memset(&addr, 0, sizeof(addr));
00374                 addr.sun_family = AF_UNIX;
00375                 os_snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/%s",
00376                             drv->test_dir, dent->d_name);
00377 
00378                 if (os_strcmp(addr.sun_path, drv->own_socket_path) == 0)
00379                         continue;
00380                 if (!broadcast && os_strstr(dent->d_name, desttxt) == NULL)
00381                         continue;
00382 
00383                 wpa_printf(MSG_DEBUG, "%s: Send management frame to %s",
00384                            __func__, dent->d_name);
00385 
00386                 msg.msg_name = &addr;
00387                 msg.msg_namelen = sizeof(addr);
00388                 ret = sendmsg(drv->test_socket, &msg, 0);
00389                 if (ret < 0)
00390                         perror("driver_test: sendmsg(test_socket)");
00391         }
00392         closedir(dir);
00393 #else /* HOSTAPD */
00394 
00395         if (os_memcmp(dest, dbss->bssid, ETH_ALEN) == 0 ||
00396             drv->test_dir == NULL) {
00397                 if (drv->hostapd_addr_udp_set) {
00398                         msg.msg_name = &drv->hostapd_addr_udp;
00399                         msg.msg_namelen = sizeof(drv->hostapd_addr_udp);
00400                 } else {
00401 #ifdef DRIVER_TEST_UNIX
00402                         msg.msg_name = &drv->hostapd_addr;
00403                         msg.msg_namelen = sizeof(drv->hostapd_addr);
00404 #endif /* DRIVER_TEST_UNIX */
00405                 }
00406         } else if (broadcast) {
00407                 dir = opendir(drv->test_dir);
00408                 if (dir == NULL)
00409                         return -1;
00410                 while ((dent = readdir(dir))) {
00411 #ifdef _DIRENT_HAVE_D_TYPE
00412                         /* Skip the file if it is not a socket.
00413                          * Also accept DT_UNKNOWN (0) in case
00414                          * the C library or underlying file
00415                          * system does not support d_type. */
00416                         if (dent->d_type != DT_SOCK &&
00417                             dent->d_type != DT_UNKNOWN)
00418                                 continue;
00419 #endif /* _DIRENT_HAVE_D_TYPE */
00420                         if (os_strcmp(dent->d_name, ".") == 0 ||
00421                             os_strcmp(dent->d_name, "..") == 0)
00422                                 continue;
00423                         wpa_printf(MSG_DEBUG, "%s: Send broadcast MLME to %s",
00424                                    __func__, dent->d_name);
00425                         os_memset(&addr, 0, sizeof(addr));
00426                         addr.sun_family = AF_UNIX;
00427                         os_snprintf(addr.sun_path, sizeof(addr.sun_path),
00428                                     "%s/%s", drv->test_dir, dent->d_name);
00429 
00430                         msg.msg_name = &addr;
00431                         msg.msg_namelen = sizeof(addr);
00432 
00433                         ret = sendmsg(drv->test_socket, &msg, 0);
00434                         if (ret < 0)
00435                                 perror("driver_test: sendmsg(test_socket)");
00436                 }
00437                 closedir(dir);
00438                 return ret;
00439         } else {
00440                 struct stat st;
00441                 os_memset(&addr, 0, sizeof(addr));
00442                 addr.sun_family = AF_UNIX;
00443                 os_snprintf(addr.sun_path, sizeof(addr.sun_path),
00444                             "%s/AP-" MACSTR, drv->test_dir, MAC2STR(dest));
00445                 if (stat(addr.sun_path, &st) < 0) {
00446                         os_snprintf(addr.sun_path, sizeof(addr.sun_path),
00447                                     "%s/STA-" MACSTR,
00448                                     drv->test_dir, MAC2STR(dest));
00449                 }
00450                 msg.msg_name = &addr;
00451                 msg.msg_namelen = sizeof(addr);
00452         }
00453 
00454         if (sendmsg(drv->test_socket, &msg, 0) < 0) {
00455                 perror("sendmsg(test_socket)");
00456                 return -1;
00457         }
00458 #endif /* HOSTAPD */
00459 
00460         hdr = (struct ieee80211_hdr *) data;
00461         fc = le_to_host16(hdr->frame_control);
00462 
00463         os_memset(&event, 0, sizeof(event));
00464         event.tx_status.type = WLAN_FC_GET_TYPE(fc);
00465         event.tx_status.stype = WLAN_FC_GET_STYPE(fc);
00466         event.tx_status.dst = hdr->addr1;
00467         event.tx_status.data = data;
00468         event.tx_status.data_len = data_len;
00469         event.tx_status.ack = ret >= 0;
00470         wpa_supplicant_event(drv->ctx, EVENT_TX_STATUS, &event);
00471 
00472         return ret;
00473 }
00474 
00475 
00476 static void test_driver_scan(struct wpa_driver_test_data *drv,
00477                              struct sockaddr_un *from, socklen_t fromlen,
00478                              char *data)
00479 {
00480         char buf[512], *pos, *end;
00481         int ret;
00482         struct test_driver_bss *bss;
00483         u8 sa[ETH_ALEN];
00484         u8 ie[512];
00485         size_t ielen;
00486         union wpa_event_data event;
00487 
00488         /* data: optional [ ' ' | STA-addr | ' ' | IEs(hex) ] */
00489 
00490         wpa_printf(MSG_DEBUG, "test_driver: SCAN");
00491 
00492         if (*data) {
00493                 if (*data != ' ' ||
00494                     hwaddr_aton(data + 1, sa)) {
00495                         wpa_printf(MSG_DEBUG, "test_driver: Unexpected SCAN "
00496                                    "command format");
00497                         return;
00498                 }
00499 
00500                 data += 18;
00501                 while (*data == ' ')
00502                         data++;
00503                 ielen = os_strlen(data) / 2;
00504                 if (ielen > sizeof(ie))
00505                         ielen = sizeof(ie);
00506                 if (hexstr2bin(data, ie, ielen) < 0)
00507                         ielen = 0;
00508 
00509                 wpa_printf(MSG_DEBUG, "test_driver: Scan from " MACSTR,
00510                            MAC2STR(sa));
00511                 wpa_hexdump(MSG_MSGDUMP, "test_driver: scan IEs", ie, ielen);
00512 
00513                 os_memset(&event, 0, sizeof(event));
00514                 event.rx_probe_req.sa = sa;
00515                 event.rx_probe_req.ie = ie;
00516                 event.rx_probe_req.ie_len = ielen;
00517                 wpa_supplicant_event(drv->ctx, EVENT_RX_PROBE_REQ, &event);
00518         }
00519 
00520         dl_list_for_each(bss, &drv->bss, struct test_driver_bss, list) {
00521                 pos = buf;
00522                 end = buf + sizeof(buf);
00523 
00524                 /* reply: SCANRESP BSSID SSID IEs */
00525                 ret = snprintf(pos, end - pos, "SCANRESP " MACSTR " ",
00526                                MAC2STR(bss->bssid));
00527                 if (ret < 0 || ret >= end - pos)
00528                         return;
00529                 pos += ret;
00530                 pos += wpa_snprintf_hex(pos, end - pos,
00531                                         bss->ssid, bss->ssid_len);
00532                 ret = snprintf(pos, end - pos, " ");
00533                 if (ret < 0 || ret >= end - pos)
00534                         return;
00535                 pos += ret;
00536                 pos += wpa_snprintf_hex(pos, end - pos, bss->ie, bss->ielen);
00537                 pos += wpa_snprintf_hex(pos, end - pos, bss->wps_probe_resp_ie,
00538                                         bss->wps_probe_resp_ie_len);
00539 
00540                 if (bss->privacy) {
00541                         ret = snprintf(pos, end - pos, " PRIVACY");
00542                         if (ret < 0 || ret >= end - pos)
00543                                 return;
00544                         pos += ret;
00545                 }
00546 
00547                 sendto(drv->test_socket, buf, pos - buf, 0,
00548                        (struct sockaddr *) from, fromlen);
00549         }
00550 }
00551 
00552 
00553 static void test_driver_assoc(struct wpa_driver_test_data *drv,
00554                               struct sockaddr_un *from, socklen_t fromlen,
00555                               char *data)
00556 {
00557         struct test_client_socket *cli;
00558         u8 ie[256], ssid[32];
00559         size_t ielen, ssid_len = 0;
00560         char *pos, *pos2, cmd[50];
00561         struct test_driver_bss *bss, *tmp;
00562 
00563         /* data: STA-addr SSID(hex) IEs(hex) */
00564 
00565         cli = os_zalloc(sizeof(*cli));
00566         if (cli == NULL)
00567                 return;
00568 
00569         if (hwaddr_aton(data, cli->addr)) {
00570                 printf("test_socket: Invalid MAC address '%s' in ASSOC\n",
00571                        data);
00572                 os_free(cli);
00573                 return;
00574         }
00575         pos = data + 17;
00576         while (*pos == ' ')
00577                 pos++;
00578         pos2 = strchr(pos, ' ');
00579         ielen = 0;
00580         if (pos2) {
00581                 ssid_len = (pos2 - pos) / 2;
00582                 if (hexstr2bin(pos, ssid, ssid_len) < 0) {
00583                         wpa_printf(MSG_DEBUG, "%s: Invalid SSID", __func__);
00584                         os_free(cli);
00585                         return;
00586                 }
00587                 wpa_hexdump_ascii(MSG_DEBUG, "test_driver_assoc: SSID",
00588                                   ssid, ssid_len);
00589 
00590                 pos = pos2 + 1;
00591                 ielen = strlen(pos) / 2;
00592                 if (ielen > sizeof(ie))
00593                         ielen = sizeof(ie);
00594                 if (hexstr2bin(pos, ie, ielen) < 0)
00595                         ielen = 0;
00596         }
00597 
00598         bss = NULL;
00599         dl_list_for_each(tmp, &drv->bss, struct test_driver_bss, list) {
00600                 if (tmp->ssid_len == ssid_len &&
00601                     os_memcmp(tmp->ssid, ssid, ssid_len) == 0) {
00602                         bss = tmp;
00603                         break;
00604                 }
00605         }
00606         if (bss == NULL) {
00607                 wpa_printf(MSG_DEBUG, "%s: No matching SSID found from "
00608                            "configured BSSes", __func__);
00609                 os_free(cli);
00610                 return;
00611         }
00612 
00613         cli->bss = bss;
00614         memcpy(&cli->un, from, sizeof(cli->un));
00615         cli->unlen = fromlen;
00616         cli->next = drv->cli;
00617         drv->cli = cli;
00618         wpa_hexdump_ascii(MSG_DEBUG, "test_socket: ASSOC sun_path",
00619                           (const u8 *) cli->un.sun_path,
00620                           cli->unlen - sizeof(cli->un.sun_family));
00621 
00622         snprintf(cmd, sizeof(cmd), "ASSOCRESP " MACSTR " 0",
00623                  MAC2STR(bss->bssid));
00624         sendto(drv->test_socket, cmd, strlen(cmd), 0,
00625                (struct sockaddr *) from, fromlen);
00626 
00627         drv_event_assoc(bss->bss_ctx, cli->addr, ie, ielen);
00628 }
00629 
00630 
00631 static void test_driver_disassoc(struct wpa_driver_test_data *drv,
00632                                  struct sockaddr_un *from, socklen_t fromlen)
00633 {
00634         struct test_client_socket *cli;
00635 
00636         cli = test_driver_get_cli(drv, from, fromlen);
00637         if (!cli)
00638                 return;
00639 
00640         drv_event_disassoc(drv->ctx, cli->addr);
00641 }
00642 
00643 
00644 static void test_driver_eapol(struct wpa_driver_test_data *drv,
00645                               struct sockaddr_un *from, socklen_t fromlen,
00646                               u8 *data, size_t datalen)
00647 {
00648 #ifdef HOSTAPD
00649         struct test_client_socket *cli;
00650 #endif /* HOSTAPD */
00651         const u8 *src = NULL;
00652 
00653         if (datalen > 14) {
00654                 /* Skip Ethernet header */
00655                 src = data + ETH_ALEN;
00656                 wpa_printf(MSG_DEBUG, "test_driver: dst=" MACSTR " src="
00657                            MACSTR " proto=%04x",
00658                            MAC2STR(data), MAC2STR(src),
00659                            WPA_GET_BE16(data + 2 * ETH_ALEN));
00660                 data += 14;
00661                 datalen -= 14;
00662         }
00663 
00664 #ifdef HOSTAPD
00665         cli = test_driver_get_cli(drv, from, fromlen);
00666         if (cli) {
00667                 drv_event_eapol_rx(cli->bss->bss_ctx, cli->addr, data,
00668                                    datalen);
00669         } else {
00670                 wpa_printf(MSG_DEBUG, "test_socket: EAPOL from unknown "
00671                            "client");
00672         }
00673 #else /* HOSTAPD */
00674         if (src)
00675                 drv_event_eapol_rx(drv->ctx, src, data, datalen);
00676 #endif /* HOSTAPD */
00677 }
00678 
00679 
00680 static void test_driver_ether(struct wpa_driver_test_data *drv,
00681                               struct sockaddr_un *from, socklen_t fromlen,
00682                               u8 *data, size_t datalen)
00683 {
00684         struct l2_ethhdr *eth;
00685 
00686         if (datalen < sizeof(*eth))
00687                 return;
00688 
00689         eth = (struct l2_ethhdr *) data;
00690         wpa_printf(MSG_DEBUG, "test_driver: RX ETHER dst=" MACSTR " src="
00691                    MACSTR " proto=%04x",
00692                    MAC2STR(eth->h_dest), MAC2STR(eth->h_source),
00693                    be_to_host16(eth->h_proto));
00694 
00695 #ifdef CONFIG_IEEE80211R
00696         if (be_to_host16(eth->h_proto) == ETH_P_RRB) {
00697                 union wpa_event_data ev;
00698                 os_memset(&ev, 0, sizeof(ev));
00699                 ev.ft_rrb_rx.src = eth->h_source;
00700                 ev.ft_rrb_rx.data = data + sizeof(*eth);
00701                 ev.ft_rrb_rx.data_len = datalen - sizeof(*eth);
00702         }
00703 #endif /* CONFIG_IEEE80211R */
00704 }
00705 
00706 
00707 static void test_driver_mlme(struct wpa_driver_test_data *drv,
00708                              struct sockaddr_un *from, socklen_t fromlen,
00709                              u8 *data, size_t datalen)
00710 {
00711         struct ieee80211_hdr *hdr;
00712         u16 fc;
00713         union wpa_event_data event;
00714         int freq = 0, own_freq;
00715         struct test_driver_bss *bss;
00716 
00717         bss = dl_list_first(&drv->bss, struct test_driver_bss, list);
00718 
00719         if (datalen > 6 && os_memcmp(data, "freq=", 5) == 0) {
00720                 size_t pos;
00721                 for (pos = 5; pos < datalen; pos++) {
00722                         if (data[pos] == ' ')
00723                                 break;
00724                 }
00725                 if (pos < datalen) {
00726                         freq = atoi((const char *) &data[5]);
00727                         wpa_printf(MSG_DEBUG, "test_driver(%s): MLME RX on "
00728                                    "freq %d MHz", bss->ifname, freq);
00729                         pos++;
00730                         data += pos;
00731                         datalen -= pos;
00732                 }
00733         }
00734 
00735         if (drv->remain_on_channel_freq)
00736                 own_freq = drv->remain_on_channel_freq;
00737         else
00738                 own_freq = drv->current_freq;
00739 
00740         if (freq && own_freq && freq != own_freq) {
00741                 wpa_printf(MSG_DEBUG, "test_driver(%s): Ignore MLME RX on "
00742                            "another frequency %d MHz (own %d MHz)",
00743                            bss->ifname, freq, own_freq);
00744                 return;
00745         }
00746 
00747         hdr = (struct ieee80211_hdr *) data;
00748 
00749         if (test_driver_get_cli(drv, from, fromlen) == NULL && datalen >= 16) {
00750                 struct test_client_socket *cli;
00751                 cli = os_zalloc(sizeof(*cli));
00752                 if (cli == NULL)
00753                         return;
00754                 wpa_printf(MSG_DEBUG, "Adding client entry for " MACSTR,
00755                            MAC2STR(hdr->addr2));
00756                 memcpy(cli->addr, hdr->addr2, ETH_ALEN);
00757                 memcpy(&cli->un, from, sizeof(cli->un));
00758                 cli->unlen = fromlen;
00759                 cli->next = drv->cli;
00760                 drv->cli = cli;
00761         }
00762 
00763         wpa_hexdump(MSG_MSGDUMP, "test_driver_mlme: received frame",
00764                     data, datalen);
00765         fc = le_to_host16(hdr->frame_control);
00766         if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT) {
00767                 wpa_printf(MSG_ERROR, "%s: received non-mgmt frame",
00768                            __func__);
00769                 return;
00770         }
00771 
00772         os_memset(&event, 0, sizeof(event));
00773         event.rx_mgmt.frame = data;
00774         event.rx_mgmt.frame_len = datalen;
00775         wpa_supplicant_event(drv->ctx, EVENT_RX_MGMT, &event);
00776 }
00777 
00778 
00779 static void test_driver_receive_unix(int sock, void *eloop_ctx, void *sock_ctx)
00780 {
00781         struct wpa_driver_test_data *drv = eloop_ctx;
00782         char buf[2000];
00783         int res;
00784         struct sockaddr_un from;
00785         socklen_t fromlen = sizeof(from);
00786 
00787         res = recvfrom(sock, buf, sizeof(buf) - 1, 0,
00788                        (struct sockaddr *) &from, &fromlen);
00789         if (res < 0) {
00790                 perror("recvfrom(test_socket)");
00791                 return;
00792         }
00793         buf[res] = '\0';
00794 
00795         wpa_printf(MSG_DEBUG, "test_driver: received %u bytes", res);
00796 
00797         if (strncmp(buf, "SCAN", 4) == 0) {
00798                 test_driver_scan(drv, &from, fromlen, buf + 4);
00799         } else if (strncmp(buf, "ASSOC ", 6) == 0) {
00800                 test_driver_assoc(drv, &from, fromlen, buf + 6);
00801         } else if (strcmp(buf, "DISASSOC") == 0) {
00802                 test_driver_disassoc(drv, &from, fromlen);
00803         } else if (strncmp(buf, "EAPOL ", 6) == 0) {
00804                 test_driver_eapol(drv, &from, fromlen, (u8 *) buf + 6,
00805                                   res - 6);
00806         } else if (strncmp(buf, "ETHER ", 6) == 0) {
00807                 test_driver_ether(drv, &from, fromlen, (u8 *) buf + 6,
00808                                   res - 6);
00809         } else if (strncmp(buf, "MLME ", 5) == 0) {
00810                 test_driver_mlme(drv, &from, fromlen, (u8 *) buf + 5, res - 5);
00811         } else {
00812                 wpa_hexdump_ascii(MSG_DEBUG, "Unknown test_socket command",
00813                                   (u8 *) buf, res);
00814         }
00815 }
00816 
00817 
00818 static int test_driver_set_generic_elem(void *priv,
00819                                         const u8 *elem, size_t elem_len)
00820 {
00821         struct test_driver_bss *bss = priv;
00822 
00823         os_free(bss->ie);
00824 
00825         if (elem == NULL) {
00826                 bss->ie = NULL;
00827                 bss->ielen = 0;
00828                 return 0;
00829         }
00830 
00831         bss->ie = os_malloc(elem_len);
00832         if (bss->ie == NULL) {
00833                 bss->ielen = 0;
00834                 return -1;
00835         }
00836 
00837         memcpy(bss->ie, elem, elem_len);
00838         bss->ielen = elem_len;
00839         return 0;
00840 }
00841 
00842 
00843 static int test_driver_set_ap_wps_ie(void *priv, const struct wpabuf *beacon,
00844                                      const struct wpabuf *proberesp)
00845 {
00846         struct test_driver_bss *bss = priv;
00847 
00848         if (beacon == NULL)
00849                 wpa_printf(MSG_DEBUG, "test_driver: Clear Beacon WPS IE");
00850         else
00851                 wpa_hexdump_buf(MSG_DEBUG, "test_driver: Beacon WPS IE",
00852                                 beacon);
00853 
00854         os_free(bss->wps_beacon_ie);
00855 
00856         if (beacon == NULL) {
00857                 bss->wps_beacon_ie = NULL;
00858                 bss->wps_beacon_ie_len = 0;
00859         } else {
00860                 bss->wps_beacon_ie = os_malloc(wpabuf_len(beacon));
00861                 if (bss->wps_beacon_ie == NULL) {
00862                         bss->wps_beacon_ie_len = 0;
00863                         return -1;
00864                 }
00865 
00866                 os_memcpy(bss->wps_beacon_ie, wpabuf_head(beacon),
00867                           wpabuf_len(beacon));
00868                 bss->wps_beacon_ie_len = wpabuf_len(beacon);
00869         }
00870 
00871         if (proberesp == NULL)
00872                 wpa_printf(MSG_DEBUG, "test_driver: Clear Probe Response WPS "
00873                            "IE");
00874         else
00875                 wpa_hexdump_buf(MSG_DEBUG, "test_driver: Probe Response WPS "
00876                                 "IE", proberesp);
00877 
00878         os_free(bss->wps_probe_resp_ie);
00879 
00880         if (proberesp == NULL) {
00881                 bss->wps_probe_resp_ie = NULL;
00882                 bss->wps_probe_resp_ie_len = 0;
00883         } else {
00884                 bss->wps_probe_resp_ie = os_malloc(wpabuf_len(proberesp));
00885                 if (bss->wps_probe_resp_ie == NULL) {
00886                         bss->wps_probe_resp_ie_len = 0;
00887                         return -1;
00888                 }
00889 
00890                 os_memcpy(bss->wps_probe_resp_ie, wpabuf_head(proberesp),
00891                           wpabuf_len(proberesp));
00892                 bss->wps_probe_resp_ie_len = wpabuf_len(proberesp);
00893         }
00894 
00895         return 0;
00896 }
00897 
00898 
00899 static int test_driver_sta_deauth(void *priv, const u8 *own_addr,
00900                                   const u8 *addr, int reason)
00901 {
00902         struct test_driver_bss *dbss = priv;
00903         struct wpa_driver_test_data *drv = dbss->drv;
00904         struct test_client_socket *cli;
00905 
00906         if (drv->test_socket < 0)
00907                 return -1;
00908 
00909         cli = drv->cli;
00910         while (cli) {
00911                 if (memcmp(cli->addr, addr, ETH_ALEN) == 0)
00912                         break;
00913                 cli = cli->next;
00914         }
00915 
00916         if (!cli)
00917                 return -1;
00918 
00919         return sendto(drv->test_socket, "DEAUTH", 6, 0,
00920                       (struct sockaddr *) &cli->un, cli->unlen);
00921 }
00922 
00923 
00924 static int test_driver_sta_disassoc(void *priv, const u8 *own_addr,
00925                                     const u8 *addr, int reason)
00926 {
00927         struct test_driver_bss *dbss = priv;
00928         struct wpa_driver_test_data *drv = dbss->drv;
00929         struct test_client_socket *cli;
00930 
00931         if (drv->test_socket < 0)
00932                 return -1;
00933 
00934         cli = drv->cli;
00935         while (cli) {
00936                 if (memcmp(cli->addr, addr, ETH_ALEN) == 0)
00937                         break;
00938                 cli = cli->next;
00939         }
00940 
00941         if (!cli)
00942                 return -1;
00943 
00944         return sendto(drv->test_socket, "DISASSOC", 8, 0,
00945                       (struct sockaddr *) &cli->un, cli->unlen);
00946 }
00947 
00948 
00949 static int test_driver_bss_add(void *priv, const char *ifname, const u8 *bssid,
00950                                void *bss_ctx, void **drv_priv)
00951 {
00952         struct test_driver_bss *dbss = priv;
00953         struct wpa_driver_test_data *drv = dbss->drv;
00954         struct test_driver_bss *bss;
00955 
00956         wpa_printf(MSG_DEBUG, "%s(ifname=%s bssid=" MACSTR ")",
00957                    __func__, ifname, MAC2STR(bssid));
00958 
00959         bss = os_zalloc(sizeof(*bss));
00960         if (bss == NULL)
00961                 return -1;
00962 
00963         bss->bss_ctx = bss_ctx;
00964         bss->drv = drv;
00965         os_strlcpy(bss->ifname, ifname, IFNAMSIZ);
00966         os_memcpy(bss->bssid, bssid, ETH_ALEN);
00967 
00968         dl_list_add(&drv->bss, &bss->list);
00969         if (drv->global) {
00970                 drv->global->bss_add_used = 1;
00971                 os_memcpy(drv->global->req_addr, bssid, ETH_ALEN);
00972         }
00973 
00974         if (drv_priv)
00975                 *drv_priv = bss;
00976 
00977         return 0;
00978 }
00979 
00980 
00981 static int test_driver_bss_remove(void *priv, const char *ifname)
00982 {
00983         struct test_driver_bss *dbss = priv;
00984         struct wpa_driver_test_data *drv = dbss->drv;
00985         struct test_driver_bss *bss;
00986         struct test_client_socket *cli, *prev_c;
00987 
00988         wpa_printf(MSG_DEBUG, "%s(ifname=%s)", __func__, ifname);
00989 
00990         dl_list_for_each(bss, &drv->bss, struct test_driver_bss, list) {
00991                 if (strcmp(bss->ifname, ifname) != 0)
00992                         continue;
00993 
00994                 for (prev_c = NULL, cli = drv->cli; cli;
00995                      prev_c = cli, cli = cli->next) {
00996                         if (cli->bss != bss)
00997                                 continue;
00998                         if (prev_c)
00999                                 prev_c->next = cli->next;
01000                         else
01001                                 drv->cli = cli->next;
01002                         os_free(cli);
01003                         break;
01004                 }
01005 
01006                 dl_list_del(&bss->list);
01007                 test_driver_free_bss(bss);
01008                 return 0;
01009         }
01010 
01011         return -1;
01012 }
01013 
01014 
01015 static int test_driver_if_add(void *priv, enum wpa_driver_if_type type,
01016                               const char *ifname, const u8 *addr,
01017                               void *bss_ctx, void **drv_priv,
01018                               char *force_ifname, u8 *if_addr)
01019 {
01020         struct test_driver_bss *dbss = priv;
01021         struct wpa_driver_test_data *drv = dbss->drv;
01022 
01023         wpa_printf(MSG_DEBUG, "%s(type=%d ifname=%s bss_ctx=%p)",
01024                    __func__, type, ifname, bss_ctx);
01025         if (addr)
01026                 os_memcpy(if_addr, addr, ETH_ALEN);
01027         else {
01028                 drv->alloc_iface_idx++;
01029                 if_addr[0] = 0x02; /* locally administered */
01030                 sha1_prf(drv->own_addr, ETH_ALEN,
01031                          "hostapd test addr generation",
01032                          (const u8 *) &drv->alloc_iface_idx,
01033                          sizeof(drv->alloc_iface_idx),
01034                          if_addr + 1, ETH_ALEN - 1);
01035         }
01036         if (type == WPA_IF_AP_BSS)
01037                 return test_driver_bss_add(priv, ifname, if_addr, bss_ctx,
01038                                            drv_priv);
01039         return 0;
01040 }
01041 
01042 
01043 static int test_driver_if_remove(void *priv, enum wpa_driver_if_type type,
01044                                  const char *ifname)
01045 {
01046         wpa_printf(MSG_DEBUG, "%s(type=%d ifname=%s)", __func__, type, ifname);
01047         if (type == WPA_IF_AP_BSS)
01048                 return test_driver_bss_remove(priv, ifname);
01049         return 0;
01050 }
01051 
01052 
01053 static int test_driver_valid_bss_mask(void *priv, const u8 *addr,
01054                                       const u8 *mask)
01055 {
01056         return 0;
01057 }
01058 
01059 
01060 static int test_driver_set_ssid(void *priv, const u8 *buf, int len)
01061 {
01062         struct test_driver_bss *bss = priv;
01063 
01064         wpa_printf(MSG_DEBUG, "%s(ifname=%s)", __func__, bss->ifname);
01065         wpa_hexdump_ascii(MSG_DEBUG, "test_driver_set_ssid: SSID", buf, len);
01066 
01067         if (len < 0 || (size_t) len > sizeof(bss->ssid))
01068                 return -1;
01069 
01070         os_memcpy(bss->ssid, buf, len);
01071         bss->ssid_len = len;
01072 
01073         return 0;
01074 }
01075 
01076 
01077 static int test_driver_set_privacy(void *priv, int enabled)
01078 {
01079         struct test_driver_bss *dbss = priv;
01080 
01081         wpa_printf(MSG_DEBUG, "%s(enabled=%d)",  __func__, enabled);
01082         dbss->privacy = enabled;
01083 
01084         return 0;
01085 }
01086 
01087 
01088 static int test_driver_set_sta_vlan(void *priv, const u8 *addr,
01089                                     const char *ifname, int vlan_id)
01090 {
01091         wpa_printf(MSG_DEBUG, "%s(addr=" MACSTR " ifname=%s vlan_id=%d)",
01092                    __func__, MAC2STR(addr), ifname, vlan_id);
01093         return 0;
01094 }
01095 
01096 
01097 static int test_driver_sta_add(void *priv,
01098                                struct hostapd_sta_add_params *params)
01099 {
01100         struct test_driver_bss *bss = priv;
01101         struct wpa_driver_test_data *drv = bss->drv;
01102         struct test_client_socket *cli;
01103 
01104         wpa_printf(MSG_DEBUG, "%s(ifname=%s addr=" MACSTR " aid=%d "
01105                    "capability=0x%x listen_interval=%d)",
01106                    __func__, bss->ifname, MAC2STR(params->addr), params->aid,
01107                    params->capability, params->listen_interval);
01108         wpa_hexdump(MSG_DEBUG, "test_driver_sta_add - supp_rates",
01109                     params->supp_rates, params->supp_rates_len);
01110 
01111         cli = drv->cli;
01112         while (cli) {
01113                 if (os_memcmp(cli->addr, params->addr, ETH_ALEN) == 0)
01114                         break;
01115                 cli = cli->next;
01116         }
01117         if (!cli) {
01118                 wpa_printf(MSG_DEBUG, "%s: no matching client entry",
01119                            __func__);
01120                 return -1;
01121         }
01122 
01123         cli->bss = bss;
01124 
01125         return 0;
01126 }
01127 
01128 
01129 static struct wpa_driver_test_data * test_alloc_data(void *ctx,
01130                                                      const char *ifname)
01131 {
01132         struct wpa_driver_test_data *drv;
01133         struct test_driver_bss *bss;
01134 
01135         drv = os_zalloc(sizeof(struct wpa_driver_test_data));
01136         if (drv == NULL) {
01137                 wpa_printf(MSG_ERROR, "Could not allocate memory for test "
01138                            "driver data");
01139                 return NULL;
01140         }
01141 
01142         bss = os_zalloc(sizeof(struct test_driver_bss));
01143         if (bss == NULL) {
01144                 os_free(drv);
01145                 return NULL;
01146         }
01147 
01148         drv->ctx = ctx;
01149         wpa_trace_add_ref(drv, ctx, ctx);
01150         dl_list_init(&drv->bss);
01151         dl_list_add(&drv->bss, &bss->list);
01152         os_strlcpy(bss->ifname, ifname, IFNAMSIZ);
01153         bss->bss_ctx = ctx;
01154         bss->drv = drv;
01155 
01156         /* Generate a MAC address to help testing with multiple STAs */
01157         drv->own_addr[0] = 0x02; /* locally administered */
01158         sha1_prf((const u8 *) ifname, os_strlen(ifname),
01159                  "test mac addr generation",
01160                  NULL, 0, drv->own_addr + 1, ETH_ALEN - 1);
01161 
01162         return drv;
01163 }
01164 
01165 
01166 static void * test_driver_init(struct hostapd_data *hapd,
01167                                struct wpa_init_params *params)
01168 {
01169         struct wpa_driver_test_data *drv;
01170         struct sockaddr_un addr_un;
01171         struct sockaddr_in addr_in;
01172         struct sockaddr *addr;
01173         socklen_t alen;
01174         struct test_driver_bss *bss;
01175 
01176         drv = test_alloc_data(hapd, params->ifname);
01177         if (drv == NULL)
01178                 return NULL;
01179         drv->ap = 1;
01180         bss = dl_list_first(&drv->bss, struct test_driver_bss, list);
01181 
01182         bss->bss_ctx = hapd;
01183         os_memcpy(bss->bssid, drv->own_addr, ETH_ALEN);
01184         os_memcpy(params->own_addr, drv->own_addr, ETH_ALEN);
01185 
01186         if (params->test_socket) {
01187                 if (os_strlen(params->test_socket) >=
01188                     sizeof(addr_un.sun_path)) {
01189                         printf("Too long test_socket path\n");
01190                         wpa_driver_test_deinit(bss);
01191                         return NULL;
01192                 }
01193                 if (strncmp(params->test_socket, "DIR:", 4) == 0) {
01194                         size_t len = strlen(params->test_socket) + 30;
01195                         drv->test_dir = os_strdup(params->test_socket + 4);
01196                         drv->own_socket_path = os_malloc(len);
01197                         if (drv->own_socket_path) {
01198                                 snprintf(drv->own_socket_path, len,
01199                                          "%s/AP-" MACSTR,
01200                                          params->test_socket + 4,
01201                                          MAC2STR(params->own_addr));
01202                         }
01203                 } else if (strncmp(params->test_socket, "UDP:", 4) == 0) {
01204                         drv->udp_port = atoi(params->test_socket + 4);
01205                 } else {
01206                         drv->own_socket_path = os_strdup(params->test_socket);
01207                 }
01208                 if (drv->own_socket_path == NULL && drv->udp_port == 0) {
01209                         wpa_driver_test_deinit(bss);
01210                         return NULL;
01211                 }
01212 
01213                 drv->test_socket = socket(drv->udp_port ? PF_INET : PF_UNIX,
01214                                           SOCK_DGRAM, 0);
01215                 if (drv->test_socket < 0) {
01216                         perror("socket");
01217                         wpa_driver_test_deinit(bss);
01218                         return NULL;
01219                 }
01220 
01221                 if (drv->udp_port) {
01222                         os_memset(&addr_in, 0, sizeof(addr_in));
01223                         addr_in.sin_family = AF_INET;
01224                         addr_in.sin_port = htons(drv->udp_port);
01225                         addr = (struct sockaddr *) &addr_in;
01226                         alen = sizeof(addr_in);
01227                 } else {
01228                         os_memset(&addr_un, 0, sizeof(addr_un));
01229                         addr_un.sun_family = AF_UNIX;
01230                         os_strlcpy(addr_un.sun_path, drv->own_socket_path,
01231                                    sizeof(addr_un.sun_path));
01232                         addr = (struct sockaddr *) &addr_un;
01233                         alen = sizeof(addr_un);
01234                 }
01235                 if (bind(drv->test_socket, addr, alen) < 0) {
01236                         perror("bind(PF_UNIX)");
01237                         close(drv->test_socket);
01238                         if (drv->own_socket_path)
01239                                 unlink(drv->own_socket_path);
01240                         wpa_driver_test_deinit(bss);
01241                         return NULL;
01242                 }
01243                 eloop_register_read_sock(drv->test_socket,
01244                                          test_driver_receive_unix, drv, NULL);
01245         } else
01246                 drv->test_socket = -1;
01247 
01248         return bss;
01249 }
01250 
01251 
01252 static void wpa_driver_test_poll(void *eloop_ctx, void *timeout_ctx)
01253 {
01254         struct wpa_driver_test_data *drv = eloop_ctx;
01255 
01256 #ifdef DRIVER_TEST_UNIX
01257         if (drv->associated && drv->hostapd_addr_set) {
01258                 struct stat st;
01259                 if (stat(drv->hostapd_addr.sun_path, &st) < 0) {
01260                         wpa_printf(MSG_DEBUG, "%s: lost connection to AP: %s",
01261                                    __func__, strerror(errno));
01262                         drv->associated = 0;
01263                         wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL);
01264                 }
01265         }
01266 #endif /* DRIVER_TEST_UNIX */
01267 
01268         eloop_register_timeout(1, 0, wpa_driver_test_poll, drv, NULL);
01269 }
01270 
01271 
01272 static void wpa_driver_test_scan_timeout(void *eloop_ctx, void *timeout_ctx)
01273 {
01274         wpa_printf(MSG_DEBUG, "Scan timeout - try to get results");
01275         wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL);
01276 }
01277 
01278 
01279 #ifdef DRIVER_TEST_UNIX
01280 static void wpa_driver_scan_dir(struct wpa_driver_test_data *drv,
01281                                 const char *path)
01282 {
01283         struct dirent *dent;
01284         DIR *dir;
01285         struct sockaddr_un addr;
01286         char cmd[512], *pos, *end;
01287         int ret;
01288 
01289         dir = opendir(path);
01290         if (dir == NULL)
01291                 return;
01292 
01293         end = cmd + sizeof(cmd);
01294         pos = cmd;
01295         ret = os_snprintf(pos, end - pos, "SCAN " MACSTR,
01296                           MAC2STR(drv->own_addr));
01297         if (ret >= 0 && ret < end - pos)
01298                 pos += ret;
01299         if (drv->probe_req_ie) {
01300                 ret = os_snprintf(pos, end - pos, " ");
01301                 if (ret >= 0 && ret < end - pos)
01302                         pos += ret;
01303                 pos += wpa_snprintf_hex(pos, end - pos, drv->probe_req_ie,
01304                                         drv->probe_req_ie_len);
01305         }
01306         if (drv->probe_req_ssid_len) {
01307                 /* Add SSID IE */
01308                 ret = os_snprintf(pos, end - pos, "%02x%02x",
01309                                   WLAN_EID_SSID,
01310                                   (unsigned int) drv->probe_req_ssid_len);
01311                 if (ret >= 0 && ret < end - pos)
01312                         pos += ret;
01313                 pos += wpa_snprintf_hex(pos, end - pos, drv->probe_req_ssid,
01314                                         drv->probe_req_ssid_len);
01315         }
01316         end[-1] = '\0';
01317 
01318         while ((dent = readdir(dir))) {
01319                 if (os_strncmp(dent->d_name, "AP-", 3) != 0 &&
01320                     os_strncmp(dent->d_name, "STA-", 4) != 0)
01321                         continue;
01322                 if (drv->own_socket_path) {
01323                         size_t olen, dlen;
01324                         olen = os_strlen(drv->own_socket_path);
01325                         dlen = os_strlen(dent->d_name);
01326                         if (olen >= dlen &&
01327                             os_strcmp(dent->d_name,
01328                                       drv->own_socket_path + olen - dlen) == 0)
01329                                 continue;
01330                 }
01331                 wpa_printf(MSG_DEBUG, "%s: SCAN %s", __func__, dent->d_name);
01332 
01333                 os_memset(&addr, 0, sizeof(addr));
01334                 addr.sun_family = AF_UNIX;
01335                 os_snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/%s",
01336                             path, dent->d_name);
01337 
01338                 if (sendto(drv->test_socket, cmd, os_strlen(cmd), 0,
01339                            (struct sockaddr *) &addr, sizeof(addr)) < 0) {
01340                         perror("sendto(test_socket)");
01341                 }
01342         }
01343         closedir(dir);
01344 }
01345 #endif /* DRIVER_TEST_UNIX */
01346 
01347 
01348 static int wpa_driver_test_scan(void *priv,
01349                                 struct wpa_driver_scan_params *params)
01350 {
01351         struct test_driver_bss *dbss = priv;
01352         struct wpa_driver_test_data *drv = dbss->drv;
01353         size_t i;
01354 
01355         wpa_printf(MSG_DEBUG, "%s: priv=%p", __func__, priv);
01356 
01357         os_free(drv->probe_req_ie);
01358         if (params->extra_ies) {
01359                 drv->probe_req_ie = os_malloc(params->extra_ies_len);
01360                 if (drv->probe_req_ie == NULL) {
01361                         drv->probe_req_ie_len = 0;
01362                         return -1;
01363                 }
01364                 os_memcpy(drv->probe_req_ie, params->extra_ies,
01365                           params->extra_ies_len);
01366                 drv->probe_req_ie_len = params->extra_ies_len;
01367         } else {
01368                 drv->probe_req_ie = NULL;
01369                 drv->probe_req_ie_len = 0;
01370         }
01371 
01372         for (i = 0; i < params->num_ssids; i++)
01373                 wpa_hexdump(MSG_DEBUG, "Scan SSID",
01374                             params->ssids[i].ssid, params->ssids[i].ssid_len);
01375         drv->probe_req_ssid_len = 0;
01376         if (params->num_ssids) {
01377                 os_memcpy(drv->probe_req_ssid, params->ssids[0].ssid,
01378                           params->ssids[0].ssid_len);
01379                 drv->probe_req_ssid_len = params->ssids[0].ssid_len;
01380         }
01381         wpa_hexdump(MSG_DEBUG, "Scan extra IE(s)",
01382                     params->extra_ies, params->extra_ies_len);
01383 
01384         drv->num_scanres = 0;
01385 
01386 #ifdef DRIVER_TEST_UNIX
01387         if (drv->test_socket >= 0 && drv->test_dir)
01388                 wpa_driver_scan_dir(drv, drv->test_dir);
01389 
01390         if (drv->test_socket >= 0 && drv->hostapd_addr_set &&
01391             sendto(drv->test_socket, "SCAN", 4, 0,
01392                    (struct sockaddr *) &drv->hostapd_addr,
01393                    sizeof(drv->hostapd_addr)) < 0) {
01394                 perror("sendto(test_socket)");
01395         }
01396 #endif /* DRIVER_TEST_UNIX */
01397 
01398         if (drv->test_socket >= 0 && drv->hostapd_addr_udp_set &&
01399             sendto(drv->test_socket, "SCAN", 4, 0,
01400                    (struct sockaddr *) &drv->hostapd_addr_udp,
01401                    sizeof(drv->hostapd_addr_udp)) < 0) {
01402                 perror("sendto(test_socket)");
01403         }
01404 
01405         eloop_cancel_timeout(wpa_driver_test_scan_timeout, drv, drv->ctx);
01406         eloop_register_timeout(1, 0, wpa_driver_test_scan_timeout, drv,
01407                                drv->ctx);
01408         return 0;
01409 }
01410 
01411 
01412 static struct wpa_scan_results * wpa_driver_test_get_scan_results2(void *priv)
01413 {
01414         struct test_driver_bss *dbss = priv;
01415         struct wpa_driver_test_data *drv = dbss->drv;
01416         struct wpa_scan_results *res;
01417         size_t i;
01418 
01419         res = os_zalloc(sizeof(*res));
01420         if (res == NULL)
01421                 return NULL;
01422 
01423         res->res = os_zalloc(drv->num_scanres * sizeof(struct wpa_scan_res *));
01424         if (res->res == NULL) {
01425                 os_free(res);
01426                 return NULL;
01427         }
01428 
01429         for (i = 0; i < drv->num_scanres; i++) {
01430                 struct wpa_scan_res *r;
01431                 if (drv->scanres[i] == NULL)
01432                         continue;
01433                 r = os_malloc(sizeof(*r) + drv->scanres[i]->ie_len);
01434                 if (r == NULL)
01435                         break;
01436                 os_memcpy(r, drv->scanres[i],
01437                           sizeof(*r) + drv->scanres[i]->ie_len);
01438                 res->res[res->num++] = r;
01439         }
01440 
01441         return res;
01442 }
01443 
01444 
01445 static int wpa_driver_test_set_key(const char *ifname, void *priv,
01446                                    enum wpa_alg alg, const u8 *addr,
01447                                    int key_idx, int set_tx,
01448                                    const u8 *seq, size_t seq_len,
01449                                    const u8 *key, size_t key_len)
01450 {
01451         wpa_printf(MSG_DEBUG, "%s: ifname=%s priv=%p alg=%d key_idx=%d "
01452                    "set_tx=%d",
01453                    __func__, ifname, priv, alg, key_idx, set_tx);
01454         if (addr)
01455                 wpa_printf(MSG_DEBUG, "   addr=" MACSTR, MAC2STR(addr));
01456         if (seq)
01457                 wpa_hexdump(MSG_DEBUG, "   seq", seq, seq_len);
01458         if (key)
01459                 wpa_hexdump_key(MSG_DEBUG, "   key", key, key_len);
01460         return 0;
01461 }
01462 
01463 
01464 static int wpa_driver_update_mode(struct wpa_driver_test_data *drv, int ap)
01465 {
01466         if (ap && !drv->ap) {
01467                 wpa_driver_test_close_test_socket(drv);
01468                 wpa_driver_test_attach(drv, drv->test_dir, 1);
01469                 drv->ap = 1;
01470         } else if (!ap && drv->ap) {
01471                 wpa_driver_test_close_test_socket(drv);
01472                 wpa_driver_test_attach(drv, drv->test_dir, 0);
01473                 drv->ap = 0;
01474         }
01475 
01476         return 0;
01477 }
01478 
01479 
01480 static int wpa_driver_test_associate(
01481         void *priv, struct wpa_driver_associate_params *params)
01482 {
01483         struct test_driver_bss *dbss = priv;
01484         struct wpa_driver_test_data *drv = dbss->drv;
01485         wpa_printf(MSG_DEBUG, "%s: priv=%p freq=%d pairwise_suite=%d "
01486                    "group_suite=%d key_mgmt_suite=%d auth_alg=%d mode=%d",
01487                    __func__, priv, params->freq, params->pairwise_suite,
01488                    params->group_suite, params->key_mgmt_suite,
01489                    params->auth_alg, params->mode);
01490         if (params->bssid) {
01491                 wpa_printf(MSG_DEBUG, "   bssid=" MACSTR,
01492                            MAC2STR(params->bssid));
01493         }
01494         if (params->ssid) {
01495                 wpa_hexdump_ascii(MSG_DEBUG, "   ssid",
01496                                   params->ssid, params->ssid_len);
01497         }
01498         if (params->wpa_ie) {
01499                 wpa_hexdump(MSG_DEBUG, "   wpa_ie",
01500                             params->wpa_ie, params->wpa_ie_len);
01501                 drv->assoc_wpa_ie_len = params->wpa_ie_len;
01502                 if (drv->assoc_wpa_ie_len > sizeof(drv->assoc_wpa_ie))
01503                         drv->assoc_wpa_ie_len = sizeof(drv->assoc_wpa_ie);
01504                 os_memcpy(drv->assoc_wpa_ie, params->wpa_ie,
01505                           drv->assoc_wpa_ie_len);
01506         } else
01507                 drv->assoc_wpa_ie_len = 0;
01508 
01509         wpa_driver_update_mode(drv, params->mode == IEEE80211_MODE_AP);
01510 
01511         drv->ibss = params->mode == IEEE80211_MODE_IBSS;
01512         dbss->privacy = params->key_mgmt_suite &
01513                 (WPA_KEY_MGMT_IEEE8021X |
01514                  WPA_KEY_MGMT_PSK |
01515                  WPA_KEY_MGMT_WPA_NONE |
01516                  WPA_KEY_MGMT_FT_IEEE8021X |
01517                  WPA_KEY_MGMT_FT_PSK |
01518                  WPA_KEY_MGMT_IEEE8021X_SHA256 |
01519                  WPA_KEY_MGMT_PSK_SHA256);
01520         if (params->wep_key_len[params->wep_tx_keyidx])
01521                 dbss->privacy = 1;
01522 
01523 #ifdef DRIVER_TEST_UNIX
01524         if (drv->test_dir && params->bssid &&
01525             params->mode != IEEE80211_MODE_IBSS) {
01526                 os_memset(&drv->hostapd_addr, 0, sizeof(drv->hostapd_addr));
01527                 drv->hostapd_addr.sun_family = AF_UNIX;
01528                 os_snprintf(drv->hostapd_addr.sun_path,
01529                             sizeof(drv->hostapd_addr.sun_path),
01530                             "%s/AP-" MACSTR,
01531                             drv->test_dir, MAC2STR(params->bssid));
01532                 drv->hostapd_addr_set = 1;
01533         }
01534 #endif /* DRIVER_TEST_UNIX */
01535 
01536         if (params->mode == IEEE80211_MODE_AP) {
01537                 os_memcpy(dbss->ssid, params->ssid, params->ssid_len);
01538                 dbss->ssid_len = params->ssid_len;
01539                 os_memcpy(dbss->bssid, drv->own_addr, ETH_ALEN);
01540                 if (params->wpa_ie && params->wpa_ie_len) {
01541                         dbss->ie = os_malloc(params->wpa_ie_len);
01542                         if (dbss->ie) {
01543                                 os_memcpy(dbss->ie, params->wpa_ie,
01544                                           params->wpa_ie_len);
01545                                 dbss->ielen = params->wpa_ie_len;
01546                         }
01547                 }
01548         } else if (drv->test_socket >= 0 &&
01549                    (drv->hostapd_addr_set || drv->hostapd_addr_udp_set)) {
01550                 char cmd[200], *pos, *end;
01551                 int ret;
01552                 end = cmd + sizeof(cmd);
01553                 pos = cmd;
01554                 ret = os_snprintf(pos, end - pos, "ASSOC " MACSTR " ",
01555                                   MAC2STR(drv->own_addr));
01556                 if (ret >= 0 && ret < end - pos)
01557                         pos += ret;
01558                 pos += wpa_snprintf_hex(pos, end - pos, params->ssid,
01559                                         params->ssid_len);
01560                 ret = os_snprintf(pos, end - pos, " ");
01561                 if (ret >= 0 && ret < end - pos)
01562                         pos += ret;
01563                 pos += wpa_snprintf_hex(pos, end - pos, params->wpa_ie,
01564                                         params->wpa_ie_len);
01565                 end[-1] = '\0';
01566 #ifdef DRIVER_TEST_UNIX
01567                 if (drv->hostapd_addr_set &&
01568                     sendto(drv->test_socket, cmd, os_strlen(cmd), 0,
01569                            (struct sockaddr *) &drv->hostapd_addr,
01570                            sizeof(drv->hostapd_addr)) < 0) {
01571                         perror("sendto(test_socket)");
01572                         return -1;
01573                 }
01574 #endif /* DRIVER_TEST_UNIX */
01575                 if (drv->hostapd_addr_udp_set &&
01576                     sendto(drv->test_socket, cmd, os_strlen(cmd), 0,
01577                            (struct sockaddr *) &drv->hostapd_addr_udp,
01578                            sizeof(drv->hostapd_addr_udp)) < 0) {
01579                         perror("sendto(test_socket)");
01580                         return -1;
01581                 }
01582 
01583                 os_memcpy(dbss->ssid, params->ssid, params->ssid_len);
01584                 dbss->ssid_len = params->ssid_len;
01585         } else {
01586                 drv->associated = 1;
01587                 if (params->mode == IEEE80211_MODE_IBSS) {
01588                         os_memcpy(dbss->ssid, params->ssid, params->ssid_len);
01589                         dbss->ssid_len = params->ssid_len;
01590                         if (params->bssid)
01591                                 os_memcpy(dbss->bssid, params->bssid,
01592                                           ETH_ALEN);
01593                         else {
01594                                 os_get_random(dbss->bssid, ETH_ALEN);
01595                                 dbss->bssid[0] &= ~0x01;
01596                                 dbss->bssid[0] |= 0x02;
01597                         }
01598                 }
01599                 wpa_supplicant_event(drv->ctx, EVENT_ASSOC, NULL);
01600         }
01601 
01602         return 0;
01603 }
01604 
01605 
01606 static int wpa_driver_test_get_bssid(void *priv, u8 *bssid)
01607 {
01608         struct test_driver_bss *dbss = priv;
01609         os_memcpy(bssid, dbss->bssid, ETH_ALEN);
01610         return 0;
01611 }
01612 
01613 
01614 static int wpa_driver_test_get_ssid(void *priv, u8 *ssid)
01615 {
01616         struct test_driver_bss *dbss = priv;
01617         os_memcpy(ssid, dbss->ssid, 32);
01618         return dbss->ssid_len;
01619 }
01620 
01621 
01622 static int wpa_driver_test_send_disassoc(struct wpa_driver_test_data *drv)
01623 {
01624 #ifdef DRIVER_TEST_UNIX
01625         if (drv->test_socket >= 0 &&
01626             sendto(drv->test_socket, "DISASSOC", 8, 0,
01627                    (struct sockaddr *) &drv->hostapd_addr,
01628                    sizeof(drv->hostapd_addr)) < 0) {
01629                 perror("sendto(test_socket)");
01630                 return -1;
01631         }
01632 #endif /* DRIVER_TEST_UNIX */
01633         if (drv->test_socket >= 0 && drv->hostapd_addr_udp_set &&
01634             sendto(drv->test_socket, "DISASSOC", 8, 0,
01635                    (struct sockaddr *) &drv->hostapd_addr_udp,
01636                    sizeof(drv->hostapd_addr_udp)) < 0) {
01637                 perror("sendto(test_socket)");
01638                 return -1;
01639         }
01640         return 0;
01641 }
01642 
01643 
01644 static int wpa_driver_test_deauthenticate(void *priv, const u8 *addr,
01645                                           int reason_code)
01646 {
01647         struct test_driver_bss *dbss = priv;
01648         struct wpa_driver_test_data *drv = dbss->drv;
01649         wpa_printf(MSG_DEBUG, "%s addr=" MACSTR " reason_code=%d",
01650                    __func__, MAC2STR(addr), reason_code);
01651         os_memset(dbss->bssid, 0, ETH_ALEN);
01652         drv->associated = 0;
01653         wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL);
01654         return wpa_driver_test_send_disassoc(drv);
01655 }
01656 
01657 
01658 static int wpa_driver_test_disassociate(void *priv, const u8 *addr,
01659                                         int reason_code)
01660 {
01661         struct test_driver_bss *dbss = priv;
01662         struct wpa_driver_test_data *drv = dbss->drv;
01663         wpa_printf(MSG_DEBUG, "%s addr=" MACSTR " reason_code=%d",
01664                    __func__, MAC2STR(addr), reason_code);
01665         os_memset(dbss->bssid, 0, ETH_ALEN);
01666         drv->associated = 0;
01667         wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL);
01668         return wpa_driver_test_send_disassoc(drv);
01669 }
01670 
01671 
01672 static const u8 * wpa_scan_get_ie(const struct wpa_scan_res *res, u8 ie)
01673 {
01674         const u8 *end, *pos;
01675 
01676         pos = (const u8 *) (res + 1);
01677         end = pos + res->ie_len;
01678 
01679         while (pos + 1 < end) {
01680                 if (pos + 2 + pos[1] > end)
01681                         break;
01682                 if (pos[0] == ie)
01683                         return pos;
01684                 pos += 2 + pos[1];
01685         }
01686 
01687         return NULL;
01688 }
01689 
01690 
01691 static void wpa_driver_test_scanresp(struct wpa_driver_test_data *drv,
01692                                      struct sockaddr *from,
01693                                      socklen_t fromlen,
01694                                      const char *data)
01695 {
01696         struct wpa_scan_res *res;
01697         const char *pos, *pos2;
01698         size_t len;
01699         u8 *ie_pos, *ie_start, *ie_end;
01700 #define MAX_IE_LEN 1000
01701         const u8 *ds_params;
01702 
01703         wpa_printf(MSG_DEBUG, "test_driver: SCANRESP %s", data);
01704         if (drv->num_scanres >= MAX_SCAN_RESULTS) {
01705                 wpa_printf(MSG_DEBUG, "test_driver: No room for the new scan "
01706                            "result");
01707                 return;
01708         }
01709 
01710         /* SCANRESP BSSID SSID IEs */
01711 
01712         res = os_zalloc(sizeof(*res) + MAX_IE_LEN);
01713         if (res == NULL)
01714                 return;
01715         ie_start = ie_pos = (u8 *) (res + 1);
01716         ie_end = ie_pos + MAX_IE_LEN;
01717 
01718         if (hwaddr_aton(data, res->bssid)) {
01719                 wpa_printf(MSG_DEBUG, "test_driver: invalid BSSID in scanres");
01720                 os_free(res);
01721                 return;
01722         }
01723 
01724         pos = data + 17;
01725         while (*pos == ' ')
01726                 pos++;
01727         pos2 = os_strchr(pos, ' ');
01728         if (pos2 == NULL) {
01729                 wpa_printf(MSG_DEBUG, "test_driver: invalid SSID termination "
01730                            "in scanres");
01731                 os_free(res);
01732                 return;
01733         }
01734         len = (pos2 - pos) / 2;
01735         if (len > 32)
01736                 len = 32;
01737         /*
01738          * Generate SSID IE from the SSID field since this IE is not included
01739          * in the main IE field.
01740          */
01741         *ie_pos++ = WLAN_EID_SSID;
01742         *ie_pos++ = len;
01743         if (hexstr2bin(pos, ie_pos, len) < 0) {
01744                 wpa_printf(MSG_DEBUG, "test_driver: invalid SSID in scanres");
01745                 os_free(res);
01746                 return;
01747         }
01748         ie_pos += len;
01749 
01750         pos = pos2 + 1;
01751         pos2 = os_strchr(pos, ' ');
01752         if (pos2 == NULL)
01753                 len = os_strlen(pos) / 2;
01754         else
01755                 len = (pos2 - pos) / 2;
01756         if ((int) len > ie_end - ie_pos)
01757                 len = ie_end - ie_pos;
01758         if (hexstr2bin(pos, ie_pos, len) < 0) {
01759                 wpa_printf(MSG_DEBUG, "test_driver: invalid IEs in scanres");
01760                 os_free(res);
01761                 return;
01762         }
01763         ie_pos += len;
01764         res->ie_len = ie_pos - ie_start;
01765 
01766         if (pos2) {
01767                 pos = pos2 + 1;
01768                 while (*pos == ' ')
01769                         pos++;
01770                 if (os_strstr(pos, "PRIVACY"))
01771                         res->caps |= IEEE80211_CAP_PRIVACY;
01772                 if (os_strstr(pos, "IBSS"))
01773                         res->caps |= IEEE80211_CAP_IBSS;
01774         }
01775 
01776         ds_params = wpa_scan_get_ie(res, WLAN_EID_DS_PARAMS);
01777         if (ds_params && ds_params[1] > 0) {
01778                 if (ds_params[2] >= 1 && ds_params[2] <= 13)
01779                         res->freq = 2407 + ds_params[2] * 5;
01780         }
01781 
01782         os_free(drv->scanres[drv->num_scanres]);
01783         drv->scanres[drv->num_scanres++] = res;
01784 }
01785 
01786 
01787 static void wpa_driver_test_assocresp(struct wpa_driver_test_data *drv,
01788                                       struct sockaddr *from,
01789                                       socklen_t fromlen,
01790                                       const char *data)
01791 {
01792         struct test_driver_bss *bss;
01793 
01794         bss = dl_list_first(&drv->bss, struct test_driver_bss, list);
01795 
01796         /* ASSOCRESP BSSID <res> */
01797         if (hwaddr_aton(data, bss->bssid)) {
01798                 wpa_printf(MSG_DEBUG, "test_driver: invalid BSSID in "
01799                            "assocresp");
01800         }
01801         if (drv->use_associnfo) {
01802                 union wpa_event_data event;
01803                 os_memset(&event, 0, sizeof(event));
01804                 event.assoc_info.req_ies = drv->assoc_wpa_ie;
01805                 event.assoc_info.req_ies_len = drv->assoc_wpa_ie_len;
01806                 wpa_supplicant_event(drv->ctx, EVENT_ASSOCINFO, &event);
01807         }
01808         drv->associated = 1;
01809         wpa_supplicant_event(drv->ctx, EVENT_ASSOC, NULL);
01810 }
01811 
01812 
01813 static void wpa_driver_test_disassoc(struct wpa_driver_test_data *drv,
01814                                      struct sockaddr *from,
01815                                      socklen_t fromlen)
01816 {
01817         drv->associated = 0;
01818         wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL);
01819 }
01820 
01821 
01822 static void wpa_driver_test_eapol(struct wpa_driver_test_data *drv,
01823                                   struct sockaddr *from,
01824                                   socklen_t fromlen,
01825                                   const u8 *data, size_t data_len)
01826 {
01827         const u8 *src;
01828         struct test_driver_bss *bss;
01829 
01830         bss = dl_list_first(&drv->bss, struct test_driver_bss, list);
01831 
01832         if (data_len > 14) {
01833                 /* Skip Ethernet header */
01834                 src = data + ETH_ALEN;
01835                 data += 14;
01836                 data_len -= 14;
01837         } else
01838                 src = bss->bssid;
01839 
01840         drv_event_eapol_rx(drv->ctx, src, data, data_len);
01841 }
01842 
01843 
01844 static void wpa_driver_test_mlme(struct wpa_driver_test_data *drv,
01845                                  struct sockaddr *from,
01846                                  socklen_t fromlen,
01847                                  const u8 *data, size_t data_len)
01848 {
01849         int freq = 0, own_freq;
01850         union wpa_event_data event;
01851         struct test_driver_bss *bss;
01852 
01853         bss = dl_list_first(&drv->bss, struct test_driver_bss, list);
01854         if (data_len > 6 && os_memcmp(data, "freq=", 5) == 0) {
01855                 size_t pos;
01856                 for (pos = 5; pos < data_len; pos++) {
01857                         if (data[pos] == ' ')
01858                                 break;
01859                 }
01860                 if (pos < data_len) {
01861                         freq = atoi((const char *) &data[5]);
01862                         wpa_printf(MSG_DEBUG, "test_driver(%s): MLME RX on "
01863                                    "freq %d MHz", bss->ifname, freq);
01864                         pos++;
01865                         data += pos;
01866                         data_len -= pos;
01867                 }
01868         }
01869 
01870         if (drv->remain_on_channel_freq)
01871                 own_freq = drv->remain_on_channel_freq;
01872         else
01873                 own_freq = drv->current_freq;
01874 
01875         if (freq && own_freq && freq != own_freq) {
01876                 wpa_printf(MSG_DEBUG, "test_driver(%s): Ignore MLME RX on "
01877                            "another frequency %d MHz (own %d MHz)",
01878                            bss->ifname, freq, own_freq);
01879                 return;
01880         }
01881 
01882         os_memset(&event, 0, sizeof(event));
01883         event.mlme_rx.buf = data;
01884         event.mlme_rx.len = data_len;
01885         event.mlme_rx.freq = freq;
01886         wpa_supplicant_event(drv->ctx, EVENT_MLME_RX, &event);
01887 
01888         if (drv->probe_req_report && data_len >= 24) {
01889                 const struct ieee80211_mgmt *mgmt;
01890                 u16 fc;
01891 
01892                 mgmt = (const struct ieee80211_mgmt *) data;
01893                 fc = le_to_host16(mgmt->frame_control);
01894                 if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
01895                     WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_PROBE_REQ) {
01896                         os_memset(&event, 0, sizeof(event));
01897                         event.rx_probe_req.sa = mgmt->sa;
01898                         event.rx_probe_req.ie = mgmt->u.probe_req.variable;
01899                         event.rx_probe_req.ie_len =
01900                                 data_len - (mgmt->u.probe_req.variable - data);
01901                         wpa_supplicant_event(drv->ctx, EVENT_RX_PROBE_REQ,
01902                                              &event);
01903                 }
01904         }
01905 }
01906 
01907 
01908 static void wpa_driver_test_scan_cmd(struct wpa_driver_test_data *drv,
01909                                      struct sockaddr *from,
01910                                      socklen_t fromlen,
01911                                      const u8 *data, size_t data_len)
01912 {
01913         char buf[512], *pos, *end;
01914         int ret;
01915         struct test_driver_bss *bss;
01916 
01917         bss = dl_list_first(&drv->bss, struct test_driver_bss, list);
01918 
01919         /* data: optional [ STA-addr | ' ' | IEs(hex) ] */
01920 
01921         if (!drv->ibss)
01922                 return;
01923 
01924         pos = buf;
01925         end = buf + sizeof(buf);
01926 
01927         /* reply: SCANRESP BSSID SSID IEs */
01928         ret = snprintf(pos, end - pos, "SCANRESP " MACSTR " ",
01929                        MAC2STR(bss->bssid));
01930         if (ret < 0 || ret >= end - pos)
01931                 return;
01932         pos += ret;
01933         pos += wpa_snprintf_hex(pos, end - pos,
01934                                 bss->ssid, bss->ssid_len);
01935         ret = snprintf(pos, end - pos, " ");
01936         if (ret < 0 || ret >= end - pos)
01937                 return;
01938         pos += ret;
01939         pos += wpa_snprintf_hex(pos, end - pos, drv->assoc_wpa_ie,
01940                                 drv->assoc_wpa_ie_len);
01941 
01942         if (bss->privacy) {
01943                 ret = snprintf(pos, end - pos, " PRIVACY");
01944                 if (ret < 0 || ret >= end - pos)
01945                         return;
01946                 pos += ret;
01947         }
01948 
01949         ret = snprintf(pos, end - pos, " IBSS");
01950         if (ret < 0 || ret >= end - pos)
01951                 return;
01952         pos += ret;
01953 
01954         sendto(drv->test_socket, buf, pos - buf, 0,
01955                (struct sockaddr *) from, fromlen);
01956 }
01957 
01958 
01959 static void wpa_driver_test_receive_unix(int sock, void *eloop_ctx,
01960                                          void *sock_ctx)
01961 {
01962         struct wpa_driver_test_data *drv = eloop_ctx;
01963         char *buf;
01964         int res;
01965         struct sockaddr_storage from;
01966         socklen_t fromlen = sizeof(from);
01967         const size_t buflen = 2000;
01968 
01969         if (drv->ap) {
01970                 test_driver_receive_unix(sock, eloop_ctx, sock_ctx);
01971                 return;
01972         }
01973 
01974         buf = os_malloc(buflen);
01975         if (buf == NULL)
01976                 return;
01977         res = recvfrom(sock, buf, buflen - 1, 0,
01978                        (struct sockaddr *) &from, &fromlen);
01979         if (res < 0) {
01980                 perror("recvfrom(test_socket)");
01981                 os_free(buf);
01982                 return;
01983         }
01984         buf[res] = '\0';
01985 
01986         wpa_printf(MSG_DEBUG, "test_driver: received %u bytes", res);
01987 
01988         if (os_strncmp(buf, "SCANRESP ", 9) == 0) {
01989                 wpa_driver_test_scanresp(drv, (struct sockaddr *) &from,
01990                                          fromlen, buf + 9);
01991         } else if (os_strncmp(buf, "ASSOCRESP ", 10) == 0) {
01992                 wpa_driver_test_assocresp(drv, (struct sockaddr *) &from,
01993                                           fromlen, buf + 10);
01994         } else if (os_strcmp(buf, "DISASSOC") == 0) {
01995                 wpa_driver_test_disassoc(drv, (struct sockaddr *) &from,
01996                                          fromlen);
01997         } else if (os_strcmp(buf, "DEAUTH") == 0) {
01998                 wpa_driver_test_disassoc(drv, (struct sockaddr *) &from,
01999                                          fromlen);
02000         } else if (os_strncmp(buf, "EAPOL ", 6) == 0) {
02001                 wpa_driver_test_eapol(drv, (struct sockaddr *) &from, fromlen,
02002                                       (const u8 *) buf + 6, res - 6);
02003         } else if (os_strncmp(buf, "MLME ", 5) == 0) {
02004                 wpa_driver_test_mlme(drv, (struct sockaddr *) &from, fromlen,
02005                                      (const u8 *) buf + 5, res - 5);
02006         } else if (os_strncmp(buf, "SCAN ", 5) == 0) {
02007                 wpa_driver_test_scan_cmd(drv, (struct sockaddr *) &from,
02008                                          fromlen,
02009                                          (const u8 *) buf + 5, res - 5);
02010         } else {
02011                 wpa_hexdump_ascii(MSG_DEBUG, "Unknown test_socket command",
02012                                   (u8 *) buf, res);
02013         }
02014         os_free(buf);
02015 }
02016 
02017 
02018 static void * wpa_driver_test_init2(void *ctx, const char *ifname,
02019                                     void *global_priv)
02020 {
02021         struct wpa_driver_test_data *drv;
02022         struct wpa_driver_test_global *global = global_priv;
02023         struct test_driver_bss *bss;
02024 
02025         drv = test_alloc_data(ctx, ifname);
02026         if (drv == NULL)
02027                 return NULL;
02028         bss = dl_list_first(&drv->bss, struct test_driver_bss, list);
02029         drv->global = global_priv;
02030         drv->test_socket = -1;
02031 
02032         /* Set dummy BSSID and SSID for testing. */
02033         bss->bssid[0] = 0x02;
02034         bss->bssid[1] = 0x00;
02035         bss->bssid[2] = 0x00;
02036         bss->bssid[3] = 0x00;
02037         bss->bssid[4] = 0x00;
02038         bss->bssid[5] = 0x01;
02039         os_memcpy(bss->ssid, "test", 5);
02040         bss->ssid_len = 4;
02041 
02042         if (global->bss_add_used) {
02043                 os_memcpy(drv->own_addr, global->req_addr, ETH_ALEN);
02044                 global->bss_add_used = 0;
02045         }
02046 
02047         eloop_register_timeout(1, 0, wpa_driver_test_poll, drv, NULL);
02048 
02049         return bss;
02050 }
02051 
02052 
02053 static void wpa_driver_test_close_test_socket(struct wpa_driver_test_data *drv)
02054 {
02055         if (drv->test_socket >= 0) {
02056                 eloop_unregister_read_sock(drv->test_socket);
02057                 close(drv->test_socket);
02058                 drv->test_socket = -1;
02059         }
02060 
02061         if (drv->own_socket_path) {
02062                 unlink(drv->own_socket_path);
02063                 os_free(drv->own_socket_path);
02064                 drv->own_socket_path = NULL;
02065         }
02066 }
02067 
02068 
02069 static void wpa_driver_test_deinit(void *priv)
02070 {
02071         struct test_driver_bss *dbss = priv;
02072         struct wpa_driver_test_data *drv = dbss->drv;
02073         struct test_client_socket *cli, *prev;
02074         int i;
02075 
02076         cli = drv->cli;
02077         while (cli) {
02078                 prev = cli;
02079                 cli = cli->next;
02080                 os_free(prev);
02081         }
02082 
02083 #ifdef HOSTAPD
02084         /* There should be only one BSS remaining at this point. */
02085         if (dl_list_len(&drv->bss) != 1)
02086                 wpa_printf(MSG_ERROR, "%s: %u remaining BSS entries",
02087                            __func__, dl_list_len(&drv->bss));
02088 #endif /* HOSTAPD */
02089 
02090         test_driver_free_bsses(drv);
02091 
02092         wpa_driver_test_close_test_socket(drv);
02093         eloop_cancel_timeout(wpa_driver_test_scan_timeout, drv, drv->ctx);
02094         eloop_cancel_timeout(wpa_driver_test_poll, drv, NULL);
02095         eloop_cancel_timeout(test_remain_on_channel_timeout, drv, NULL);
02096         os_free(drv->test_dir);
02097         for (i = 0; i < MAX_SCAN_RESULTS; i++)
02098                 os_free(drv->scanres[i]);
02099         os_free(drv->probe_req_ie);
02100         wpa_trace_remove_ref(drv, ctx, drv->ctx);
02101         os_free(drv);
02102 }
02103 
02104 
02105 static int wpa_driver_test_attach(struct wpa_driver_test_data *drv,
02106                                   const char *dir, int ap)
02107 {
02108 #ifdef DRIVER_TEST_UNIX
02109         static unsigned int counter = 0;
02110         struct sockaddr_un addr;
02111         size_t len;
02112 
02113         os_free(drv->own_socket_path);
02114         if (dir) {
02115                 len = os_strlen(dir) + 30;
02116                 drv->own_socket_path = os_malloc(len);
02117                 if (drv->own_socket_path == NULL)
02118                         return -1;
02119                 os_snprintf(drv->own_socket_path, len, "%s/%s-" MACSTR,
02120                             dir, ap ? "AP" : "STA", MAC2STR(drv->own_addr));
02121         } else {
02122                 drv->own_socket_path = os_malloc(100);
02123                 if (drv->own_socket_path == NULL)
02124                         return -1;
02125                 os_snprintf(drv->own_socket_path, 100,
02126                             "/tmp/wpa_supplicant_test-%d-%d",
02127                             getpid(), counter++);
02128         }
02129 
02130         drv->test_socket = socket(PF_UNIX, SOCK_DGRAM, 0);
02131         if (drv->test_socket < 0) {
02132                 perror("socket(PF_UNIX)");
02133                 os_free(drv->own_socket_path);
02134                 drv->own_socket_path = NULL;
02135                 return -1;
02136         }
02137 
02138         os_memset(&addr, 0, sizeof(addr));
02139         addr.sun_family = AF_UNIX;
02140         os_strlcpy(addr.sun_path, drv->own_socket_path, sizeof(addr.sun_path));
02141         if (bind(drv->test_socket, (struct sockaddr *) &addr,
02142                  sizeof(addr)) < 0) {
02143                 perror("bind(PF_UNIX)");
02144                 close(drv->test_socket);
02145                 unlink(drv->own_socket_path);
02146                 os_free(drv->own_socket_path);
02147                 drv->own_socket_path = NULL;
02148                 return -1;
02149         }
02150 
02151         eloop_register_read_sock(drv->test_socket,
02152                                  wpa_driver_test_receive_unix, drv, NULL);
02153 
02154         return 0;
02155 #else /* DRIVER_TEST_UNIX */
02156         return -1;
02157 #endif /* DRIVER_TEST_UNIX */
02158 }
02159 
02160 
02161 static int wpa_driver_test_attach_udp(struct wpa_driver_test_data *drv,
02162                                       char *dst)
02163 {
02164         char *pos;
02165 
02166         pos = os_strchr(dst, ':');
02167         if (pos == NULL)
02168                 return -1;
02169         *pos++ = '\0';
02170         wpa_printf(MSG_DEBUG, "%s: addr=%s port=%s", __func__, dst, pos);
02171 
02172         drv->test_socket = socket(PF_INET, SOCK_DGRAM, 0);
02173         if (drv->test_socket < 0) {
02174                 perror("socket(PF_INET)");
02175                 return -1;
02176         }
02177 
02178         os_memset(&drv->hostapd_addr_udp, 0, sizeof(drv->hostapd_addr_udp));
02179         drv->hostapd_addr_udp.sin_family = AF_INET;
02180 #if defined(CONFIG_NATIVE_WINDOWS) || defined(CONFIG_ANSI_C_EXTRA)
02181         {
02182                 int a[4];
02183                 u8 *pos;
02184                 sscanf(dst, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]);
02185                 pos = (u8 *) &drv->hostapd_addr_udp.sin_addr;
02186                 *pos++ = a[0];
02187                 *pos++ = a[1];
02188                 *pos++ = a[2];
02189                 *pos++ = a[3];
02190         }
02191 #else /* CONFIG_NATIVE_WINDOWS or CONFIG_ANSI_C_EXTRA */
02192         inet_aton(dst, &drv->hostapd_addr_udp.sin_addr);
02193 #endif /* CONFIG_NATIVE_WINDOWS or CONFIG_ANSI_C_EXTRA */
02194         drv->hostapd_addr_udp.sin_port = htons(atoi(pos));
02195 
02196         drv->hostapd_addr_udp_set = 1;
02197 
02198         eloop_register_read_sock(drv->test_socket,
02199                                  wpa_driver_test_receive_unix, drv, NULL);
02200 
02201         return 0;
02202 }
02203 
02204 
02205 static int wpa_driver_test_set_param(void *priv, const char *param)
02206 {
02207         struct test_driver_bss *dbss = priv;
02208         struct wpa_driver_test_data *drv = dbss->drv;
02209         const char *pos;
02210 
02211         wpa_printf(MSG_DEBUG, "%s: param='%s'", __func__, param);
02212         if (param == NULL)
02213                 return 0;
02214 
02215         wpa_driver_test_close_test_socket(drv);
02216 
02217 #ifdef DRIVER_TEST_UNIX
02218         pos = os_strstr(param, "test_socket=");
02219         if (pos) {
02220                 const char *pos2;
02221                 size_t len;
02222 
02223                 pos += 12;
02224                 pos2 = os_strchr(pos, ' ');
02225                 if (pos2)
02226                         len = pos2 - pos;
02227                 else
02228                         len = os_strlen(pos);
02229                 if (len > sizeof(drv->hostapd_addr.sun_path))
02230                         return -1;
02231                 os_memset(&drv->hostapd_addr, 0, sizeof(drv->hostapd_addr));
02232                 drv->hostapd_addr.sun_family = AF_UNIX;
02233                 os_memcpy(drv->hostapd_addr.sun_path, pos, len);
02234                 drv->hostapd_addr_set = 1;
02235         }
02236 #endif /* DRIVER_TEST_UNIX */
02237 
02238         pos = os_strstr(param, "test_dir=");
02239         if (pos) {
02240                 char *end;
02241                 os_free(drv->test_dir);
02242                 drv->test_dir = os_strdup(pos + 9);
02243                 if (drv->test_dir == NULL)
02244                         return -1;
02245                 end = os_strchr(drv->test_dir, ' ');
02246                 if (end)
02247                         *end = '\0';
02248                 if (wpa_driver_test_attach(drv, drv->test_dir, 0))
02249                         return -1;
02250         } else {
02251                 pos = os_strstr(param, "test_udp=");
02252                 if (pos) {
02253                         char *dst, *epos;
02254                         dst = os_strdup(pos + 9);
02255                         if (dst == NULL)
02256                                 return -1;
02257                         epos = os_strchr(dst, ' ');
02258                         if (epos)
02259                                 *epos = '\0';
02260                         if (wpa_driver_test_attach_udp(drv, dst))
02261                                 return -1;
02262                         os_free(dst);
02263                 } else if (wpa_driver_test_attach(drv, NULL, 0))
02264                         return -1;
02265         }
02266 
02267         if (os_strstr(param, "use_associnfo=1")) {
02268                 wpa_printf(MSG_DEBUG, "test_driver: Use AssocInfo events");
02269                 drv->use_associnfo = 1;
02270         }
02271 
02272 #ifdef CONFIG_CLIENT_MLME
02273         if (os_strstr(param, "use_mlme=1")) {
02274                 wpa_printf(MSG_DEBUG, "test_driver: Use internal MLME");
02275                 drv->use_mlme = 1;
02276         }
02277 #endif /* CONFIG_CLIENT_MLME */
02278 
02279         return 0;
02280 }
02281 
02282 
02283 static const u8 * wpa_driver_test_get_mac_addr(void *priv)
02284 {
02285         struct test_driver_bss *dbss = priv;
02286         struct wpa_driver_test_data *drv = dbss->drv;
02287         wpa_printf(MSG_DEBUG, "%s", __func__);
02288         return drv->own_addr;
02289 }
02290 
02291 
02292 static int wpa_driver_test_send_eapol(void *priv, const u8 *dest, u16 proto,
02293                                       const u8 *data, size_t data_len)
02294 {
02295         struct test_driver_bss *dbss = priv;
02296         struct wpa_driver_test_data *drv = dbss->drv;
02297         char *msg;
02298         size_t msg_len;
02299         struct l2_ethhdr eth;
02300         struct sockaddr *addr;
02301         socklen_t alen;
02302 #ifdef DRIVER_TEST_UNIX
02303         struct sockaddr_un addr_un;
02304 #endif /* DRIVER_TEST_UNIX */
02305 
02306         wpa_hexdump(MSG_MSGDUMP, "test_send_eapol TX frame", data, data_len);
02307 
02308         os_memset(&eth, 0, sizeof(eth));
02309         os_memcpy(eth.h_dest, dest, ETH_ALEN);
02310         os_memcpy(eth.h_source, drv->own_addr, ETH_ALEN);
02311         eth.h_proto = host_to_be16(proto);
02312 
02313         msg_len = 6 + sizeof(eth) + data_len;
02314         msg = os_malloc(msg_len);
02315         if (msg == NULL)
02316                 return -1;
02317         os_memcpy(msg, "EAPOL ", 6);
02318         os_memcpy(msg + 6, &eth, sizeof(eth));
02319         os_memcpy(msg + 6 + sizeof(eth), data, data_len);
02320 
02321         if (os_memcmp(dest, dbss->bssid, ETH_ALEN) == 0 ||
02322             drv->test_dir == NULL) {
02323                 if (drv->hostapd_addr_udp_set) {
02324                         addr = (struct sockaddr *) &drv->hostapd_addr_udp;
02325                         alen = sizeof(drv->hostapd_addr_udp);
02326                 } else {
02327 #ifdef DRIVER_TEST_UNIX
02328                         addr = (struct sockaddr *) &drv->hostapd_addr;
02329                         alen = sizeof(drv->hostapd_addr);
02330 #else /* DRIVER_TEST_UNIX */
02331                         os_free(msg);
02332                         return -1;
02333 #endif /* DRIVER_TEST_UNIX */
02334                 }
02335         } else {
02336 #ifdef DRIVER_TEST_UNIX
02337                 struct stat st;
02338                 os_memset(&addr_un, 0, sizeof(addr_un));
02339                 addr_un.sun_family = AF_UNIX;
02340                 os_snprintf(addr_un.sun_path, sizeof(addr_un.sun_path),
02341                             "%s/STA-" MACSTR, drv->test_dir, MAC2STR(dest));
02342                 if (stat(addr_un.sun_path, &st) < 0) {
02343                         os_snprintf(addr_un.sun_path, sizeof(addr_un.sun_path),
02344                                     "%s/AP-" MACSTR,
02345                                     drv->test_dir, MAC2STR(dest));
02346                 }
02347                 addr = (struct sockaddr *) &addr_un;
02348                 alen = sizeof(addr_un);
02349 #else /* DRIVER_TEST_UNIX */
02350                 os_free(msg);
02351                 return -1;
02352 #endif /* DRIVER_TEST_UNIX */
02353         }
02354 
02355         if (sendto(drv->test_socket, msg, msg_len, 0, addr, alen) < 0) {
02356                 perror("sendmsg(test_socket)");
02357                 os_free(msg);
02358                 return -1;
02359         }
02360 
02361         os_free(msg);
02362         return 0;
02363 }
02364 
02365 
02366 static int wpa_driver_test_get_capa(void *priv, struct wpa_driver_capa *capa)
02367 {
02368         struct test_driver_bss *dbss = priv;
02369         struct wpa_driver_test_data *drv = dbss->drv;
02370         os_memset(capa, 0, sizeof(*capa));
02371         capa->key_mgmt = WPA_DRIVER_CAPA_KEY_MGMT_WPA |
02372                 WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
02373                 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
02374                 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK |
02375                 WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE |
02376                 WPA_DRIVER_CAPA_KEY_MGMT_FT |
02377                 WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK;
02378         capa->enc = WPA_DRIVER_CAPA_ENC_WEP40 |
02379                 WPA_DRIVER_CAPA_ENC_WEP104 |
02380                 WPA_DRIVER_CAPA_ENC_TKIP |
02381                 WPA_DRIVER_CAPA_ENC_CCMP;
02382         capa->auth = WPA_DRIVER_AUTH_OPEN |
02383                 WPA_DRIVER_AUTH_SHARED |
02384                 WPA_DRIVER_AUTH_LEAP;
02385         if (drv->use_mlme)
02386                 capa->flags |= WPA_DRIVER_FLAGS_USER_SPACE_MLME;
02387         capa->flags |= WPA_DRIVER_FLAGS_AP;
02388         capa->max_scan_ssids = 2;
02389         capa->max_remain_on_chan = 60000;
02390 
02391         return 0;
02392 }
02393 
02394 
02395 static int wpa_driver_test_mlme_setprotection(void *priv, const u8 *addr,
02396                                               int protect_type,
02397                                               int key_type)
02398 {
02399         wpa_printf(MSG_DEBUG, "%s: protect_type=%d key_type=%d",
02400                    __func__, protect_type, key_type);
02401 
02402         if (addr) {
02403                 wpa_printf(MSG_DEBUG, "%s: addr=" MACSTR,
02404                            __func__, MAC2STR(addr));
02405         }
02406 
02407         return 0;
02408 }
02409 
02410 
02411 static int wpa_driver_test_set_channel(void *priv,
02412                                        enum hostapd_hw_mode phymode,
02413                                        int chan, int freq)
02414 {
02415         struct test_driver_bss *dbss = priv;
02416         struct wpa_driver_test_data *drv = dbss->drv;
02417         wpa_printf(MSG_DEBUG, "%s: phymode=%d chan=%d freq=%d",
02418                    __func__, phymode, chan, freq);
02419         drv->current_freq = freq;
02420         return 0;
02421 }
02422 
02423 
02424 static int wpa_driver_test_mlme_add_sta(void *priv, const u8 *addr,
02425                                         const u8 *supp_rates,
02426                                         size_t supp_rates_len)
02427 {
02428         wpa_printf(MSG_DEBUG, "%s: addr=" MACSTR, __func__, MAC2STR(addr));
02429         return 0;
02430 }
02431 
02432 
02433 static int wpa_driver_test_mlme_remove_sta(void *priv, const u8 *addr)
02434 {
02435         wpa_printf(MSG_DEBUG, "%s: addr=" MACSTR, __func__, MAC2STR(addr));
02436         return 0;
02437 }
02438 
02439 
02440 static int wpa_driver_test_set_ssid(void *priv, const u8 *ssid,
02441                                     size_t ssid_len)
02442 {
02443         wpa_printf(MSG_DEBUG, "%s", __func__);
02444         return 0;
02445 }
02446 
02447 
02448 static int wpa_driver_test_set_bssid(void *priv, const u8 *bssid)
02449 {
02450         wpa_printf(MSG_DEBUG, "%s: bssid=" MACSTR, __func__, MAC2STR(bssid));
02451         return 0;
02452 }
02453 
02454 
02455 static void * wpa_driver_test_global_init(void)
02456 {
02457         struct wpa_driver_test_global *global;
02458 
02459         global = os_zalloc(sizeof(*global));
02460         return global;
02461 }
02462 
02463 
02464 static void wpa_driver_test_global_deinit(void *priv)
02465 {
02466         struct wpa_driver_test_global *global = priv;
02467         os_free(global);
02468 }
02469 
02470 
02471 static struct wpa_interface_info *
02472 wpa_driver_test_get_interfaces(void *global_priv)
02473 {
02474         /* struct wpa_driver_test_global *global = priv; */
02475         struct wpa_interface_info *iface;
02476 
02477         iface = os_zalloc(sizeof(*iface));
02478         if (iface == NULL)
02479                 return iface;
02480         iface->ifname = os_strdup("sta0");
02481         iface->desc = os_strdup("test interface 0");
02482         iface->drv_name = "test";
02483         iface->next = os_zalloc(sizeof(*iface));
02484         if (iface->next) {
02485                 iface->next->ifname = os_strdup("sta1");
02486                 iface->next->desc = os_strdup("test interface 1");
02487                 iface->next->drv_name = "test";
02488         }
02489 
02490         return iface;
02491 }
02492 
02493 
02494 static struct hostapd_hw_modes *
02495 wpa_driver_test_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags)
02496 {
02497         struct hostapd_hw_modes *modes;
02498         size_t i;
02499 
02500         *num_modes = 3;
02501         *flags = 0;
02502         modes = os_zalloc(*num_modes * sizeof(struct hostapd_hw_modes));
02503         if (modes == NULL)
02504                 return NULL;
02505         modes[0].mode = HOSTAPD_MODE_IEEE80211G;
02506         modes[0].num_channels = 11;
02507         modes[0].num_rates = 12;
02508         modes[0].channels =
02509                 os_zalloc(11 * sizeof(struct hostapd_channel_data));
02510         modes[0].rates = os_zalloc(modes[0].num_rates * sizeof(int));
02511         if (modes[0].channels == NULL || modes[0].rates == NULL)
02512                 goto fail;
02513         for (i = 0; i < 11; i++) {
02514                 modes[0].channels[i].chan = i + 1;
02515                 modes[0].channels[i].freq = 2412 + 5 * i;
02516                 modes[0].channels[i].flag = 0;
02517         }
02518         modes[0].rates[0] = 10;
02519         modes[0].rates[1] = 20;
02520         modes[0].rates[2] = 55;
02521         modes[0].rates[3] = 110;
02522         modes[0].rates[4] = 60;
02523         modes[0].rates[5] = 90;
02524         modes[0].rates[6] = 120;
02525         modes[0].rates[7] = 180;
02526         modes[0].rates[8] = 240;
02527         modes[0].rates[9] = 360;
02528         modes[0].rates[10] = 480;
02529         modes[0].rates[11] = 540;
02530 
02531         modes[1].mode = HOSTAPD_MODE_IEEE80211B;
02532         modes[1].num_channels = 11;
02533         modes[1].num_rates = 4;
02534         modes[1].channels =
02535                 os_zalloc(11 * sizeof(struct hostapd_channel_data));
02536         modes[1].rates = os_zalloc(modes[1].num_rates * sizeof(int));
02537         if (modes[1].channels == NULL || modes[1].rates == NULL)
02538                 goto fail;
02539         for (i = 0; i < 11; i++) {
02540                 modes[1].channels[i].chan = i + 1;
02541                 modes[1].channels[i].freq = 2412 + 5 * i;
02542                 modes[1].channels[i].flag = 0;
02543         }
02544         modes[1].rates[0] = 10;
02545         modes[1].rates[1] = 20;
02546         modes[1].rates[2] = 55;
02547         modes[1].rates[3] = 110;
02548 
02549         modes[2].mode = HOSTAPD_MODE_IEEE80211A;
02550         modes[2].num_channels = 1;
02551         modes[2].num_rates = 8;
02552         modes[2].channels = os_zalloc(sizeof(struct hostapd_channel_data));
02553         modes[2].rates = os_zalloc(modes[2].num_rates * sizeof(int));
02554         if (modes[2].channels == NULL || modes[2].rates == NULL)
02555                 goto fail;
02556         modes[2].channels[0].chan = 60;
02557         modes[2].channels[0].freq = 5300;
02558         modes[2].channels[0].flag = 0;
02559         modes[2].rates[0] = 60;
02560         modes[2].rates[1] = 90;
02561         modes[2].rates[2] = 120;
02562         modes[2].rates[3] = 180;
02563         modes[2].rates[4] = 240;
02564         modes[2].rates[5] = 360;
02565         modes[2].rates[6] = 480;
02566         modes[2].rates[7] = 540;
02567 
02568         return modes;
02569 
02570 fail:
02571         if (modes) {
02572                 for (i = 0; i < *num_modes; i++) {
02573                         os_free(modes[i].channels);
02574                         os_free(modes[i].rates);
02575                 }
02576                 os_free(modes);
02577         }
02578         return NULL;
02579 }
02580 
02581 
02582 static int wpa_driver_test_set_freq(void *priv,
02583                                     struct hostapd_freq_params *freq)
02584 {
02585         struct test_driver_bss *dbss = priv;
02586         struct wpa_driver_test_data *drv = dbss->drv;
02587         wpa_printf(MSG_DEBUG, "test: set_freq %u MHz", freq->freq);
02588         drv->current_freq = freq->freq;
02589         return 0;
02590 }
02591 
02592 
02593 static int wpa_driver_test_send_action(void *priv, unsigned int freq,
02594                                        const u8 *dst, const u8 *src,
02595                                        const u8 *bssid,
02596                                        const u8 *data, size_t data_len)
02597 {
02598         struct test_driver_bss *dbss = priv;
02599         struct wpa_driver_test_data *drv = dbss->drv;
02600         int ret = -1;
02601         u8 *buf;
02602         struct ieee80211_hdr *hdr;
02603 
02604         wpa_printf(MSG_DEBUG, "test: Send Action frame");
02605 
02606         if ((drv->remain_on_channel_freq &&
02607              freq != drv->remain_on_channel_freq) ||
02608             (drv->remain_on_channel_freq == 0 &&
02609              freq != (unsigned int) drv->current_freq)) {
02610                 wpa_printf(MSG_DEBUG, "test: Reject Action frame TX on "
02611                            "unexpected channel: freq=%u MHz (current_freq=%u "
02612                            "MHz, remain-on-channel freq=%u MHz)",
02613                            freq, drv->current_freq,
02614                            drv->remain_on_channel_freq);
02615                 return -1;
02616         }
02617 
02618         buf = os_zalloc(24 + data_len);
02619         if (buf == NULL)
02620                 return ret;
02621         os_memcpy(buf + 24, data, data_len);
02622         hdr = (struct ieee80211_hdr *) buf;
02623         hdr->frame_control =
02624                 IEEE80211_FC(WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_ACTION);
02625         os_memcpy(hdr->addr1, dst, ETH_ALEN);
02626         os_memcpy(hdr->addr2, src, ETH_ALEN);
02627         os_memcpy(hdr->addr3, bssid, ETH_ALEN);
02628 
02629         ret = wpa_driver_test_send_mlme(priv, buf, 24 + data_len);
02630         os_free(buf);
02631         return ret;
02632 }
02633 
02634 
02635 static void test_remain_on_channel_timeout(void *eloop_ctx, void *timeout_ctx)
02636 {
02637         struct wpa_driver_test_data *drv = eloop_ctx;
02638         union wpa_event_data data;
02639 
02640         wpa_printf(MSG_DEBUG, "test: Remain-on-channel timeout");
02641 
02642         os_memset(&data, 0, sizeof(data));
02643         data.remain_on_channel.freq = drv->remain_on_channel_freq;
02644         data.remain_on_channel.duration = drv->remain_on_channel_duration;
02645         wpa_supplicant_event(drv->ctx, EVENT_CANCEL_REMAIN_ON_CHANNEL, &data);
02646 
02647         drv->remain_on_channel_freq = 0;
02648 }
02649 
02650 
02651 static int wpa_driver_test_remain_on_channel(void *priv, unsigned int freq,
02652                                              unsigned int duration)
02653 {
02654         struct test_driver_bss *dbss = priv;
02655         struct wpa_driver_test_data *drv = dbss->drv;
02656         union wpa_event_data data;
02657 
02658         wpa_printf(MSG_DEBUG, "%s(freq=%u, duration=%u)",
02659                    __func__, freq, duration);
02660         if (drv->remain_on_channel_freq &&
02661             drv->remain_on_channel_freq != freq) {
02662                 wpa_printf(MSG_DEBUG, "test: Refuse concurrent "
02663                            "remain_on_channel request");
02664                 return -1;
02665         }
02666 
02667         drv->remain_on_channel_freq = freq;
02668         drv->remain_on_channel_duration = duration;
02669         eloop_cancel_timeout(test_remain_on_channel_timeout, drv, NULL);
02670         eloop_register_timeout(duration / 1000, (duration % 1000) * 1000,
02671                                test_remain_on_channel_timeout, drv, NULL);
02672 
02673         os_memset(&data, 0, sizeof(data));
02674         data.remain_on_channel.freq = freq;
02675         data.remain_on_channel.duration = duration;
02676         wpa_supplicant_event(drv->ctx, EVENT_REMAIN_ON_CHANNEL, &data);
02677 
02678         return 0;
02679 }
02680 
02681 
02682 static int wpa_driver_test_cancel_remain_on_channel(void *priv)
02683 {
02684         struct test_driver_bss *dbss = priv;
02685         struct wpa_driver_test_data *drv = dbss->drv;
02686         wpa_printf(MSG_DEBUG, "%s", __func__);
02687         if (!drv->remain_on_channel_freq)
02688                 return -1;
02689         drv->remain_on_channel_freq = 0;
02690         eloop_cancel_timeout(test_remain_on_channel_timeout, drv, NULL);
02691         return 0;
02692 }
02693 
02694 
02695 static int wpa_driver_test_probe_req_report(void *priv, int report)
02696 {
02697         struct test_driver_bss *dbss = priv;
02698         struct wpa_driver_test_data *drv = dbss->drv;
02699         wpa_printf(MSG_DEBUG, "%s(report=%d)", __func__, report);
02700         drv->probe_req_report = report;
02701         return 0;
02702 }
02703 
02704 
02705 const struct wpa_driver_ops wpa_driver_test_ops = {
02706         "test",
02707         "wpa_supplicant test driver",
02708         .hapd_init = test_driver_init,
02709         .hapd_deinit = wpa_driver_test_deinit,
02710         .hapd_send_eapol = test_driver_send_eapol,
02711         .send_mlme = wpa_driver_test_send_mlme,
02712         .set_generic_elem = test_driver_set_generic_elem,
02713         .sta_deauth = test_driver_sta_deauth,
02714         .sta_disassoc = test_driver_sta_disassoc,
02715         .get_hw_feature_data = wpa_driver_test_get_hw_feature_data,
02716         .if_add = test_driver_if_add,
02717         .if_remove = test_driver_if_remove,
02718         .valid_bss_mask = test_driver_valid_bss_mask,
02719         .hapd_set_ssid = test_driver_set_ssid,
02720         .set_privacy = test_driver_set_privacy,
02721         .set_sta_vlan = test_driver_set_sta_vlan,
02722         .sta_add = test_driver_sta_add,
02723         .send_ether = test_driver_send_ether,
02724         .set_ap_wps_ie = test_driver_set_ap_wps_ie,
02725         .get_bssid = wpa_driver_test_get_bssid,
02726         .get_ssid = wpa_driver_test_get_ssid,
02727         .set_key = wpa_driver_test_set_key,
02728         .deinit = wpa_driver_test_deinit,
02729         .set_param = wpa_driver_test_set_param,
02730         .deauthenticate = wpa_driver_test_deauthenticate,
02731         .disassociate = wpa_driver_test_disassociate,
02732         .associate = wpa_driver_test_associate,
02733         .get_capa = wpa_driver_test_get_capa,
02734         .get_mac_addr = wpa_driver_test_get_mac_addr,
02735         .send_eapol = wpa_driver_test_send_eapol,
02736         .mlme_setprotection = wpa_driver_test_mlme_setprotection,
02737         .set_channel = wpa_driver_test_set_channel,
02738         .set_ssid = wpa_driver_test_set_ssid,
02739         .set_bssid = wpa_driver_test_set_bssid,
02740         .mlme_add_sta = wpa_driver_test_mlme_add_sta,
02741         .mlme_remove_sta = wpa_driver_test_mlme_remove_sta,
02742         .get_scan_results2 = wpa_driver_test_get_scan_results2,
02743         .global_init = wpa_driver_test_global_init,
02744         .global_deinit = wpa_driver_test_global_deinit,
02745         .init2 = wpa_driver_test_init2,
02746         .get_interfaces = wpa_driver_test_get_interfaces,
02747         .scan2 = wpa_driver_test_scan,
02748         .set_freq = wpa_driver_test_set_freq,
02749         .send_action = wpa_driver_test_send_action,
02750         .remain_on_channel = wpa_driver_test_remain_on_channel,
02751         .cancel_remain_on_channel = wpa_driver_test_cancel_remain_on_channel,
02752         .probe_req_report = wpa_driver_test_probe_req_report,
02753 };


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