1/* 2 * WPA Supplicant - testing driver interface 3 * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 * 9 * Alternatively, this software may be distributed under the terms of BSD 10 * license. 11 * 12 * See README and COPYING for more details. 13 */ 14 15/* Make dure we get winsock2.h for Windows build to get sockaddr_storage */ 16#include "build_config.h" 17#ifdef CONFIG_NATIVE_WINDOWS 18#include <winsock2.h> 19#endif /* CONFIG_NATIVE_WINDOWS */ 20 21#include "includes.h" 22 23#ifndef CONFIG_NATIVE_WINDOWS 24#include <sys/un.h> 25#include <dirent.h> 26#include <sys/stat.h> 27#define DRIVER_TEST_UNIX 28#endif /* CONFIG_NATIVE_WINDOWS */ 29 30#include "common.h" 31#include "driver.h" 32#include "l2_packet/l2_packet.h" 33#include "eloop.h" 34#include "sha1.h" 35#include "ieee802_11_defs.h" 36 37 38struct wpa_driver_test_global { 39 int dummy; 40}; 41 42struct wpa_driver_test_data { 43 struct wpa_driver_test_global *global; 44 void *ctx; 45 u8 own_addr[ETH_ALEN]; 46 int test_socket; 47#ifdef DRIVER_TEST_UNIX 48 struct sockaddr_un hostapd_addr; 49#endif /* DRIVER_TEST_UNIX */ 50 int hostapd_addr_set; 51 struct sockaddr_in hostapd_addr_udp; 52 int hostapd_addr_udp_set; 53 char *own_socket_path; 54 char *test_dir; 55 u8 bssid[ETH_ALEN]; 56 u8 ssid[32]; 57 size_t ssid_len; 58#define MAX_SCAN_RESULTS 30 59 struct wpa_scan_res *scanres[MAX_SCAN_RESULTS]; 60 size_t num_scanres; 61 int use_associnfo; 62 u8 assoc_wpa_ie[80]; 63 size_t assoc_wpa_ie_len; 64 int use_mlme; 65 int associated; 66 u8 *probe_req_ie; 67 size_t probe_req_ie_len; 68}; 69 70 71static void wpa_driver_test_poll(void *eloop_ctx, void *timeout_ctx) 72{ 73 struct wpa_driver_test_data *drv = eloop_ctx; 74 75#ifdef DRIVER_TEST_UNIX 76 if (drv->associated && drv->hostapd_addr_set) { 77 struct stat st; 78 if (stat(drv->hostapd_addr.sun_path, &st) < 0) { 79 wpa_printf(MSG_DEBUG, "%s: lost connection to AP: %s", 80 __func__, strerror(errno)); 81 drv->associated = 0; 82 wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL); 83 } 84 } 85#endif /* DRIVER_TEST_UNIX */ 86 87 eloop_register_timeout(1, 0, wpa_driver_test_poll, drv, NULL); 88} 89 90 91static int wpa_driver_test_set_wpa(void *priv, int enabled) 92{ 93 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled); 94 return 0; 95} 96 97 98static void wpa_driver_test_scan_timeout(void *eloop_ctx, void *timeout_ctx) 99{ 100 wpa_printf(MSG_DEBUG, "Scan timeout - try to get results"); 101 wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL); 102} 103 104 105#ifdef DRIVER_TEST_UNIX 106static void wpa_driver_scan_dir(struct wpa_driver_test_data *drv, 107 const char *path) 108{ 109 struct dirent *dent; 110 DIR *dir; 111 struct sockaddr_un addr; 112 char cmd[512], *pos, *end; 113 int ret; 114 115 dir = opendir(path); 116 if (dir == NULL) 117 return; 118 119 end = cmd + sizeof(cmd); 120 pos = cmd; 121 ret = os_snprintf(pos, end - pos, "SCAN " MACSTR, 122 MAC2STR(drv->own_addr)); 123 if (ret >= 0 && ret < end - pos) 124 pos += ret; 125 if (drv->probe_req_ie) { 126 ret = os_snprintf(pos, end - pos, " "); 127 if (ret >= 0 && ret < end - pos) 128 pos += ret; 129 pos += wpa_snprintf_hex(pos, end - pos, drv->probe_req_ie, 130 drv->probe_req_ie_len); 131 } 132 end[-1] = '\0'; 133 134 while ((dent = readdir(dir))) { 135 if (os_strncmp(dent->d_name, "AP-", 3) != 0) 136 continue; 137 wpa_printf(MSG_DEBUG, "%s: SCAN %s", __func__, dent->d_name); 138 139 os_memset(&addr, 0, sizeof(addr)); 140 addr.sun_family = AF_UNIX; 141 os_snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/%s", 142 path, dent->d_name); 143 144 if (sendto(drv->test_socket, cmd, os_strlen(cmd), 0, 145 (struct sockaddr *) &addr, sizeof(addr)) < 0) { 146 perror("sendto(test_socket)"); 147 } 148 } 149 closedir(dir); 150} 151#endif /* DRIVER_TEST_UNIX */ 152 153 154static int wpa_driver_test_scan(void *priv, const u8 *ssid, size_t ssid_len) 155{ 156 struct wpa_driver_test_data *drv = priv; 157 wpa_printf(MSG_DEBUG, "%s: priv=%p", __func__, priv); 158 159 drv->num_scanres = 0; 160 161#ifdef DRIVER_TEST_UNIX 162 if (drv->test_socket >= 0 && drv->test_dir) 163 wpa_driver_scan_dir(drv, drv->test_dir); 164 165 if (drv->test_socket >= 0 && drv->hostapd_addr_set && 166 sendto(drv->test_socket, "SCAN", 4, 0, 167 (struct sockaddr *) &drv->hostapd_addr, 168 sizeof(drv->hostapd_addr)) < 0) { 169 perror("sendto(test_socket)"); 170 } 171#endif /* DRIVER_TEST_UNIX */ 172 173 if (drv->test_socket >= 0 && drv->hostapd_addr_udp_set && 174 sendto(drv->test_socket, "SCAN", 4, 0, 175 (struct sockaddr *) &drv->hostapd_addr_udp, 176 sizeof(drv->hostapd_addr_udp)) < 0) { 177 perror("sendto(test_socket)"); 178 } 179 180 eloop_cancel_timeout(wpa_driver_test_scan_timeout, drv, drv->ctx); 181 eloop_register_timeout(1, 0, wpa_driver_test_scan_timeout, drv, 182 drv->ctx); 183 return 0; 184} 185 186 187static struct wpa_scan_results * wpa_driver_test_get_scan_results2(void *priv) 188{ 189 struct wpa_driver_test_data *drv = priv; 190 struct wpa_scan_results *res; 191 size_t i; 192 193 res = os_zalloc(sizeof(*res)); 194 if (res == NULL) 195 return NULL; 196 197 res->res = os_zalloc(drv->num_scanres * sizeof(struct wpa_scan_res *)); 198 if (res->res == NULL) { 199 os_free(res); 200 return NULL; 201 } 202 203 for (i = 0; i < drv->num_scanres; i++) { 204 struct wpa_scan_res *r; 205 if (drv->scanres[i] == NULL) 206 continue; 207 r = os_malloc(sizeof(*r) + drv->scanres[i]->ie_len); 208 if (r == NULL) 209 break; 210 os_memcpy(r, drv->scanres[i], 211 sizeof(*r) + drv->scanres[i]->ie_len); 212 res->res[res->num++] = r; 213 } 214 215 return res; 216} 217 218 219static int wpa_driver_test_set_key(void *priv, wpa_alg alg, const u8 *addr, 220 int key_idx, int set_tx, 221 const u8 *seq, size_t seq_len, 222 const u8 *key, size_t key_len) 223{ 224 wpa_printf(MSG_DEBUG, "%s: priv=%p alg=%d key_idx=%d set_tx=%d", 225 __func__, priv, alg, key_idx, set_tx); 226 if (addr) { 227 wpa_printf(MSG_DEBUG, " addr=" MACSTR, MAC2STR(addr)); 228 } 229 if (seq) { 230 wpa_hexdump(MSG_DEBUG, " seq", seq, seq_len); 231 } 232 if (key) { 233 wpa_hexdump(MSG_DEBUG, " key", key, key_len); 234 } 235 return 0; 236} 237 238 239static int wpa_driver_test_associate( 240 void *priv, struct wpa_driver_associate_params *params) 241{ 242 struct wpa_driver_test_data *drv = priv; 243 wpa_printf(MSG_DEBUG, "%s: priv=%p freq=%d pairwise_suite=%d " 244 "group_suite=%d key_mgmt_suite=%d auth_alg=%d mode=%d", 245 __func__, priv, params->freq, params->pairwise_suite, 246 params->group_suite, params->key_mgmt_suite, 247 params->auth_alg, params->mode); 248 if (params->bssid) { 249 wpa_printf(MSG_DEBUG, " bssid=" MACSTR, 250 MAC2STR(params->bssid)); 251 } 252 if (params->ssid) { 253 wpa_hexdump_ascii(MSG_DEBUG, " ssid", 254 params->ssid, params->ssid_len); 255 } 256 if (params->wpa_ie) { 257 wpa_hexdump(MSG_DEBUG, " wpa_ie", 258 params->wpa_ie, params->wpa_ie_len); 259 drv->assoc_wpa_ie_len = params->wpa_ie_len; 260 if (drv->assoc_wpa_ie_len > sizeof(drv->assoc_wpa_ie)) 261 drv->assoc_wpa_ie_len = sizeof(drv->assoc_wpa_ie); 262 os_memcpy(drv->assoc_wpa_ie, params->wpa_ie, 263 drv->assoc_wpa_ie_len); 264 } else 265 drv->assoc_wpa_ie_len = 0; 266 267#ifdef DRIVER_TEST_UNIX 268 if (drv->test_dir && params->bssid) { 269 os_memset(&drv->hostapd_addr, 0, sizeof(drv->hostapd_addr)); 270 drv->hostapd_addr.sun_family = AF_UNIX; 271 os_snprintf(drv->hostapd_addr.sun_path, 272 sizeof(drv->hostapd_addr.sun_path), 273 "%s/AP-" MACSTR, 274 drv->test_dir, MAC2STR(params->bssid)); 275 drv->hostapd_addr_set = 1; 276 } 277#endif /* DRIVER_TEST_UNIX */ 278 279 if (drv->test_socket >= 0 && 280 (drv->hostapd_addr_set || drv->hostapd_addr_udp_set)) { 281 char cmd[200], *pos, *end; 282 int ret; 283 end = cmd + sizeof(cmd); 284 pos = cmd; 285 ret = os_snprintf(pos, end - pos, "ASSOC " MACSTR " ", 286 MAC2STR(drv->own_addr)); 287 if (ret >= 0 && ret < end - pos) 288 pos += ret; 289 pos += wpa_snprintf_hex(pos, end - pos, params->ssid, 290 params->ssid_len); 291 ret = os_snprintf(pos, end - pos, " "); 292 if (ret >= 0 && ret < end - pos) 293 pos += ret; 294 pos += wpa_snprintf_hex(pos, end - pos, params->wpa_ie, 295 params->wpa_ie_len); 296 end[-1] = '\0'; 297#ifdef DRIVER_TEST_UNIX 298 if (drv->hostapd_addr_set && 299 sendto(drv->test_socket, cmd, os_strlen(cmd), 0, 300 (struct sockaddr *) &drv->hostapd_addr, 301 sizeof(drv->hostapd_addr)) < 0) { 302 perror("sendto(test_socket)"); 303 return -1; 304 } 305#endif /* DRIVER_TEST_UNIX */ 306 if (drv->hostapd_addr_udp_set && 307 sendto(drv->test_socket, cmd, os_strlen(cmd), 0, 308 (struct sockaddr *) &drv->hostapd_addr_udp, 309 sizeof(drv->hostapd_addr_udp)) < 0) { 310 perror("sendto(test_socket)"); 311 return -1; 312 } 313 314 os_memcpy(drv->ssid, params->ssid, params->ssid_len); 315 drv->ssid_len = params->ssid_len; 316 } else { 317 drv->associated = 1; 318 wpa_supplicant_event(drv->ctx, EVENT_ASSOC, NULL); 319 } 320 321 return 0; 322} 323 324 325static int wpa_driver_test_get_bssid(void *priv, u8 *bssid) 326{ 327 struct wpa_driver_test_data *drv = priv; 328 os_memcpy(bssid, drv->bssid, ETH_ALEN); 329 return 0; 330} 331 332 333static int wpa_driver_test_get_ssid(void *priv, u8 *ssid) 334{ 335 struct wpa_driver_test_data *drv = priv; 336 os_memcpy(ssid, drv->ssid, 32); 337 return drv->ssid_len; 338} 339 340 341static int wpa_driver_test_send_disassoc(struct wpa_driver_test_data *drv) 342{ 343#ifdef DRIVER_TEST_UNIX 344 if (drv->test_socket >= 0 && 345 sendto(drv->test_socket, "DISASSOC", 8, 0, 346 (struct sockaddr *) &drv->hostapd_addr, 347 sizeof(drv->hostapd_addr)) < 0) { 348 perror("sendto(test_socket)"); 349 return -1; 350 } 351#endif /* DRIVER_TEST_UNIX */ 352 if (drv->test_socket >= 0 && drv->hostapd_addr_udp_set && 353 sendto(drv->test_socket, "DISASSOC", 8, 0, 354 (struct sockaddr *) &drv->hostapd_addr_udp, 355 sizeof(drv->hostapd_addr_udp)) < 0) { 356 perror("sendto(test_socket)"); 357 return -1; 358 } 359 return 0; 360} 361 362 363static int wpa_driver_test_deauthenticate(void *priv, const u8 *addr, 364 int reason_code) 365{ 366 struct wpa_driver_test_data *drv = priv; 367 wpa_printf(MSG_DEBUG, "%s addr=" MACSTR " reason_code=%d", 368 __func__, MAC2STR(addr), reason_code); 369 os_memset(drv->bssid, 0, ETH_ALEN); 370 drv->associated = 0; 371 wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL); 372 return wpa_driver_test_send_disassoc(drv); 373} 374 375 376static int wpa_driver_test_disassociate(void *priv, const u8 *addr, 377 int reason_code) 378{ 379 struct wpa_driver_test_data *drv = priv; 380 wpa_printf(MSG_DEBUG, "%s addr=" MACSTR " reason_code=%d", 381 __func__, MAC2STR(addr), reason_code); 382 os_memset(drv->bssid, 0, ETH_ALEN); 383 drv->associated = 0; 384 wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL); 385 return wpa_driver_test_send_disassoc(drv); 386} 387 388 389static void wpa_driver_test_scanresp(struct wpa_driver_test_data *drv, 390 struct sockaddr *from, 391 socklen_t fromlen, 392 const char *data) 393{ 394 struct wpa_scan_res *res; 395 const char *pos, *pos2; 396 size_t len; 397 u8 *ie_pos, *ie_start, *ie_end; 398#define MAX_IE_LEN 1000 399 400 wpa_printf(MSG_DEBUG, "test_driver: SCANRESP %s", data); 401 if (drv->num_scanres >= MAX_SCAN_RESULTS) { 402 wpa_printf(MSG_DEBUG, "test_driver: No room for the new scan " 403 "result"); 404 return; 405 } 406 407 /* SCANRESP BSSID SSID IEs */ 408 409 res = os_zalloc(sizeof(*res) + MAX_IE_LEN); 410 if (res == NULL) 411 return; 412 ie_start = ie_pos = (u8 *) (res + 1); 413 ie_end = ie_pos + MAX_IE_LEN; 414 415 if (hwaddr_aton(data, res->bssid)) { 416 wpa_printf(MSG_DEBUG, "test_driver: invalid BSSID in scanres"); 417 os_free(res); 418 return; 419 } 420 421 pos = data + 17; 422 while (*pos == ' ') 423 pos++; 424 pos2 = os_strchr(pos, ' '); 425 if (pos2 == NULL) { 426 wpa_printf(MSG_DEBUG, "test_driver: invalid SSID termination " 427 "in scanres"); 428 os_free(res); 429 return; 430 } 431 len = (pos2 - pos) / 2; 432 if (len > 32) 433 len = 32; 434 /* 435 * Generate SSID IE from the SSID field since this IE is not included 436 * in the main IE field. 437 */ 438 *ie_pos++ = WLAN_EID_SSID; 439 *ie_pos++ = len; 440 if (hexstr2bin(pos, ie_pos, len) < 0) { 441 wpa_printf(MSG_DEBUG, "test_driver: invalid SSID in scanres"); 442 os_free(res); 443 return; 444 } 445 ie_pos += len; 446 447 pos = pos2 + 1; 448 pos2 = os_strchr(pos, ' '); 449 if (pos2 == NULL) 450 len = os_strlen(pos) / 2; 451 else 452 len = (pos2 - pos) / 2; 453 if ((int) len > ie_end - ie_pos) 454 len = ie_end - ie_pos; 455 if (hexstr2bin(pos, ie_pos, len) < 0) { 456 wpa_printf(MSG_DEBUG, "test_driver: invalid IEs in scanres"); 457 os_free(res); 458 return; 459 } 460 ie_pos += len; 461 res->ie_len = ie_pos - ie_start; 462 463 if (pos2) { 464 pos = pos2 + 1; 465 while (*pos == ' ') 466 pos++; 467 if (os_strncmp(pos, "PRIVACY", 7) == 0) 468 res->caps |= IEEE80211_CAP_PRIVACY; 469 } 470 471 os_free(drv->scanres[drv->num_scanres]); 472 drv->scanres[drv->num_scanres++] = res; 473} 474 475 476static void wpa_driver_test_assocresp(struct wpa_driver_test_data *drv, 477 struct sockaddr *from, 478 socklen_t fromlen, 479 const char *data) 480{ 481 /* ASSOCRESP BSSID <res> */ 482 if (hwaddr_aton(data, drv->bssid)) { 483 wpa_printf(MSG_DEBUG, "test_driver: invalid BSSID in " 484 "assocresp"); 485 } 486 if (drv->use_associnfo) { 487 union wpa_event_data event; 488 os_memset(&event, 0, sizeof(event)); 489 event.assoc_info.req_ies = drv->assoc_wpa_ie; 490 event.assoc_info.req_ies_len = drv->assoc_wpa_ie_len; 491 wpa_supplicant_event(drv->ctx, EVENT_ASSOCINFO, &event); 492 } 493 drv->associated = 1; 494 wpa_supplicant_event(drv->ctx, EVENT_ASSOC, NULL); 495} 496 497 498static void wpa_driver_test_disassoc(struct wpa_driver_test_data *drv, 499 struct sockaddr *from, 500 socklen_t fromlen) 501{ 502 drv->associated = 0; 503 wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL); 504} 505 506 507static void wpa_driver_test_eapol(struct wpa_driver_test_data *drv, 508 struct sockaddr *from, 509 socklen_t fromlen, 510 const u8 *data, size_t data_len) 511{ 512 const u8 *src = drv->bssid; 513 514 if (data_len > 14) { 515 /* Skip Ethernet header */ 516 src = data + ETH_ALEN; 517 data += 14; 518 data_len -= 14; 519 } 520 wpa_supplicant_rx_eapol(drv->ctx, src, data, data_len); 521} 522 523 524static void wpa_driver_test_mlme(struct wpa_driver_test_data *drv, 525 struct sockaddr *from, 526 socklen_t fromlen, 527 const u8 *data, size_t data_len) 528{ 529#ifdef CONFIG_CLIENT_MLME 530 struct ieee80211_rx_status rx_status; 531 os_memset(&rx_status, 0, sizeof(rx_status)); 532 wpa_supplicant_sta_rx(drv->ctx, data, data_len, &rx_status); 533#endif /* CONFIG_CLIENT_MLME */ 534} 535 536 537static void wpa_driver_test_receive_unix(int sock, void *eloop_ctx, 538 void *sock_ctx) 539{ 540 struct wpa_driver_test_data *drv = eloop_ctx; 541 char *buf; 542 int res; 543 struct sockaddr_storage from; 544 socklen_t fromlen = sizeof(from); 545 const size_t buflen = 2000; 546 547 buf = os_malloc(buflen); 548 if (buf == NULL) 549 return; 550 res = recvfrom(sock, buf, buflen - 1, 0, 551 (struct sockaddr *) &from, &fromlen); 552 if (res < 0) { 553 perror("recvfrom(test_socket)"); 554 os_free(buf); 555 return; 556 } 557 buf[res] = '\0'; 558 559 wpa_printf(MSG_DEBUG, "test_driver: received %u bytes", res); 560 561 if (os_strncmp(buf, "SCANRESP ", 9) == 0) { 562 wpa_driver_test_scanresp(drv, (struct sockaddr *) &from, 563 fromlen, buf + 9); 564 } else if (os_strncmp(buf, "ASSOCRESP ", 10) == 0) { 565 wpa_driver_test_assocresp(drv, (struct sockaddr *) &from, 566 fromlen, buf + 10); 567 } else if (os_strcmp(buf, "DISASSOC") == 0) { 568 wpa_driver_test_disassoc(drv, (struct sockaddr *) &from, 569 fromlen); 570 } else if (os_strcmp(buf, "DEAUTH") == 0) { 571 wpa_driver_test_disassoc(drv, (struct sockaddr *) &from, 572 fromlen); 573 } else if (os_strncmp(buf, "EAPOL ", 6) == 0) { 574 wpa_driver_test_eapol(drv, (struct sockaddr *) &from, fromlen, 575 (const u8 *) buf + 6, res - 6); 576 } else if (os_strncmp(buf, "MLME ", 5) == 0) { 577 wpa_driver_test_mlme(drv, (struct sockaddr *) &from, fromlen, 578 (const u8 *) buf + 5, res - 5); 579 } else { 580 wpa_hexdump_ascii(MSG_DEBUG, "Unknown test_socket command", 581 (u8 *) buf, res); 582 } 583 os_free(buf); 584} 585 586 587static void * wpa_driver_test_init2(void *ctx, const char *ifname, 588 void *global_priv) 589{ 590 struct wpa_driver_test_data *drv; 591 592 drv = os_zalloc(sizeof(*drv)); 593 if (drv == NULL) 594 return NULL; 595 drv->global = global_priv; 596 drv->ctx = ctx; 597 drv->test_socket = -1; 598 599 /* Set dummy BSSID and SSID for testing. */ 600 drv->bssid[0] = 0x02; 601 drv->bssid[1] = 0x00; 602 drv->bssid[2] = 0x00; 603 drv->bssid[3] = 0x00; 604 drv->bssid[4] = 0x00; 605 drv->bssid[5] = 0x01; 606 os_memcpy(drv->ssid, "test", 5); 607 drv->ssid_len = 4; 608 609 /* Generate a MAC address to help testing with multiple STAs */ 610 drv->own_addr[0] = 0x02; /* locally administered */ 611 sha1_prf((const u8 *) ifname, os_strlen(ifname), 612 "wpa_supplicant test mac addr generation", 613 NULL, 0, drv->own_addr + 1, ETH_ALEN - 1); 614 eloop_register_timeout(1, 0, wpa_driver_test_poll, drv, NULL); 615 616 return drv; 617} 618 619 620static void wpa_driver_test_close_test_socket(struct wpa_driver_test_data *drv) 621{ 622 if (drv->test_socket >= 0) { 623 eloop_unregister_read_sock(drv->test_socket); 624 close(drv->test_socket); 625 drv->test_socket = -1; 626 } 627 628 if (drv->own_socket_path) { 629 unlink(drv->own_socket_path); 630 os_free(drv->own_socket_path); 631 drv->own_socket_path = NULL; 632 } 633} 634 635 636static void wpa_driver_test_deinit(void *priv) 637{ 638 struct wpa_driver_test_data *drv = priv; 639 int i; 640 wpa_driver_test_close_test_socket(drv); 641 eloop_cancel_timeout(wpa_driver_test_scan_timeout, drv, drv->ctx); 642 eloop_cancel_timeout(wpa_driver_test_poll, drv, NULL); 643 os_free(drv->test_dir); 644 for (i = 0; i < MAX_SCAN_RESULTS; i++) 645 os_free(drv->scanres[i]); 646 os_free(drv->probe_req_ie); 647 os_free(drv); 648} 649 650 651static int wpa_driver_test_attach(struct wpa_driver_test_data *drv, 652 const char *dir) 653{ 654#ifdef DRIVER_TEST_UNIX 655 static unsigned int counter = 0; 656 struct sockaddr_un addr; 657 size_t len; 658 659 os_free(drv->own_socket_path); 660 if (dir) { 661 len = os_strlen(dir) + 30; 662 drv->own_socket_path = os_malloc(len); 663 if (drv->own_socket_path == NULL) 664 return -1; 665 os_snprintf(drv->own_socket_path, len, "%s/STA-" MACSTR, 666 dir, MAC2STR(drv->own_addr)); 667 } else { 668 drv->own_socket_path = os_malloc(100); 669 if (drv->own_socket_path == NULL) 670 return -1; 671 os_snprintf(drv->own_socket_path, 100, 672 "/tmp/wpa_supplicant_test-%d-%d", 673 getpid(), counter++); 674 } 675 676 drv->test_socket = socket(PF_UNIX, SOCK_DGRAM, 0); 677 if (drv->test_socket < 0) { 678 perror("socket(PF_UNIX)"); 679 os_free(drv->own_socket_path); 680 drv->own_socket_path = NULL; 681 return -1; 682 } 683 684 os_memset(&addr, 0, sizeof(addr)); 685 addr.sun_family = AF_UNIX; 686 os_strlcpy(addr.sun_path, drv->own_socket_path, sizeof(addr.sun_path)); 687 if (bind(drv->test_socket, (struct sockaddr *) &addr, 688 sizeof(addr)) < 0) { 689 perror("bind(PF_UNIX)"); 690 close(drv->test_socket); 691 unlink(drv->own_socket_path); 692 os_free(drv->own_socket_path); 693 drv->own_socket_path = NULL; 694 return -1; 695 } 696 697 eloop_register_read_sock(drv->test_socket, 698 wpa_driver_test_receive_unix, drv, NULL); 699 700 return 0; 701#else /* DRIVER_TEST_UNIX */ 702 return -1; 703#endif /* DRIVER_TEST_UNIX */ 704} 705 706 707static int wpa_driver_test_attach_udp(struct wpa_driver_test_data *drv, 708 char *dst) 709{ 710 char *pos; 711 712 pos = os_strchr(dst, ':'); 713 if (pos == NULL) 714 return -1; 715 *pos++ = '\0'; 716 wpa_printf(MSG_DEBUG, "%s: addr=%s port=%s", __func__, dst, pos); 717 718 drv->test_socket = socket(PF_INET, SOCK_DGRAM, 0); 719 if (drv->test_socket < 0) { 720 perror("socket(PF_INET)"); 721 return -1; 722 } 723 724 os_memset(&drv->hostapd_addr_udp, 0, sizeof(drv->hostapd_addr_udp)); 725 drv->hostapd_addr_udp.sin_family = AF_INET; 726#if defined(CONFIG_NATIVE_WINDOWS) || defined(CONFIG_ANSI_C_EXTRA) 727 { 728 int a[4]; 729 u8 *pos; 730 sscanf(dst, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]); 731 pos = (u8 *) &drv->hostapd_addr_udp.sin_addr; 732 *pos++ = a[0]; 733 *pos++ = a[1]; 734 *pos++ = a[2]; 735 *pos++ = a[3]; 736 } 737#else /* CONFIG_NATIVE_WINDOWS or CONFIG_ANSI_C_EXTRA */ 738 inet_aton(dst, &drv->hostapd_addr_udp.sin_addr); 739#endif /* CONFIG_NATIVE_WINDOWS or CONFIG_ANSI_C_EXTRA */ 740 drv->hostapd_addr_udp.sin_port = htons(atoi(pos)); 741 742 drv->hostapd_addr_udp_set = 1; 743 744 eloop_register_read_sock(drv->test_socket, 745 wpa_driver_test_receive_unix, drv, NULL); 746 747 return 0; 748} 749 750 751static int wpa_driver_test_set_param(void *priv, const char *param) 752{ 753 struct wpa_driver_test_data *drv = priv; 754 const char *pos; 755 756 wpa_printf(MSG_DEBUG, "%s: param='%s'", __func__, param); 757 if (param == NULL) 758 return 0; 759 760 wpa_driver_test_close_test_socket(drv); 761 762#ifdef DRIVER_TEST_UNIX 763 pos = os_strstr(param, "test_socket="); 764 if (pos) { 765 const char *pos2; 766 size_t len; 767 768 pos += 12; 769 pos2 = os_strchr(pos, ' '); 770 if (pos2) 771 len = pos2 - pos; 772 else 773 len = os_strlen(pos); 774 if (len > sizeof(drv->hostapd_addr.sun_path)) 775 return -1; 776 os_memset(&drv->hostapd_addr, 0, sizeof(drv->hostapd_addr)); 777 drv->hostapd_addr.sun_family = AF_UNIX; 778 os_memcpy(drv->hostapd_addr.sun_path, pos, len); 779 drv->hostapd_addr_set = 1; 780 } 781#endif /* DRIVER_TEST_UNIX */ 782 783 pos = os_strstr(param, "test_dir="); 784 if (pos) { 785 char *end; 786 os_free(drv->test_dir); 787 drv->test_dir = os_strdup(pos + 9); 788 if (drv->test_dir == NULL) 789 return -1; 790 end = os_strchr(drv->test_dir, ' '); 791 if (end) 792 *end = '\0'; 793 if (wpa_driver_test_attach(drv, drv->test_dir)) 794 return -1; 795 } else { 796 pos = os_strstr(param, "test_udp="); 797 if (pos) { 798 char *dst, *epos; 799 dst = os_strdup(pos + 9); 800 if (dst == NULL) 801 return -1; 802 epos = os_strchr(dst, ' '); 803 if (epos) 804 *epos = '\0'; 805 if (wpa_driver_test_attach_udp(drv, dst)) 806 return -1; 807 os_free(dst); 808 } else if (wpa_driver_test_attach(drv, NULL)) 809 return -1; 810 } 811 812 if (os_strstr(param, "use_associnfo=1")) { 813 wpa_printf(MSG_DEBUG, "test_driver: Use AssocInfo events"); 814 drv->use_associnfo = 1; 815 } 816 817#ifdef CONFIG_CLIENT_MLME 818 if (os_strstr(param, "use_mlme=1")) { 819 wpa_printf(MSG_DEBUG, "test_driver: Use internal MLME"); 820 drv->use_mlme = 1; 821 } 822#endif /* CONFIG_CLIENT_MLME */ 823 824 return 0; 825} 826 827 828static const u8 * wpa_driver_test_get_mac_addr(void *priv) 829{ 830 struct wpa_driver_test_data *drv = priv; 831 wpa_printf(MSG_DEBUG, "%s", __func__); 832 return drv->own_addr; 833} 834 835 836static int wpa_driver_test_send_eapol(void *priv, const u8 *dest, u16 proto, 837 const u8 *data, size_t data_len) 838{ 839 struct wpa_driver_test_data *drv = priv; 840 char *msg; 841 size_t msg_len; 842 struct l2_ethhdr eth; 843 struct sockaddr *addr; 844 socklen_t alen; 845#ifdef DRIVER_TEST_UNIX 846 struct sockaddr_un addr_un; 847#endif /* DRIVER_TEST_UNIX */ 848 849 wpa_hexdump(MSG_MSGDUMP, "test_send_eapol TX frame", data, data_len); 850 851 os_memset(ð, 0, sizeof(eth)); 852 os_memcpy(eth.h_dest, dest, ETH_ALEN); 853 os_memcpy(eth.h_source, drv->own_addr, ETH_ALEN); 854 eth.h_proto = host_to_be16(proto); 855 856 msg_len = 6 + sizeof(eth) + data_len; 857 msg = os_malloc(msg_len); 858 if (msg == NULL) 859 return -1; 860 os_memcpy(msg, "EAPOL ", 6); 861 os_memcpy(msg + 6, ð, sizeof(eth)); 862 os_memcpy(msg + 6 + sizeof(eth), data, data_len); 863 864 if (os_memcmp(dest, drv->bssid, ETH_ALEN) == 0 || 865 drv->test_dir == NULL) { 866 if (drv->hostapd_addr_udp_set) { 867 addr = (struct sockaddr *) &drv->hostapd_addr_udp; 868 alen = sizeof(drv->hostapd_addr_udp); 869 } else { 870#ifdef DRIVER_TEST_UNIX 871 addr = (struct sockaddr *) &drv->hostapd_addr; 872 alen = sizeof(drv->hostapd_addr); 873#else /* DRIVER_TEST_UNIX */ 874 os_free(msg); 875 return -1; 876#endif /* DRIVER_TEST_UNIX */ 877 } 878 } else { 879#ifdef DRIVER_TEST_UNIX 880 struct stat st; 881 os_memset(&addr_un, 0, sizeof(addr_un)); 882 addr_un.sun_family = AF_UNIX; 883 os_snprintf(addr_un.sun_path, sizeof(addr_un.sun_path), 884 "%s/STA-" MACSTR, drv->test_dir, MAC2STR(dest)); 885 if (stat(addr_un.sun_path, &st) < 0) { 886 os_snprintf(addr_un.sun_path, sizeof(addr_un.sun_path), 887 "%s/AP-" MACSTR, 888 drv->test_dir, MAC2STR(dest)); 889 } 890 addr = (struct sockaddr *) &addr_un; 891 alen = sizeof(addr_un); 892#else /* DRIVER_TEST_UNIX */ 893 os_free(msg); 894 return -1; 895#endif /* DRIVER_TEST_UNIX */ 896 } 897 898 if (sendto(drv->test_socket, msg, msg_len, 0, addr, alen) < 0) { 899 perror("sendmsg(test_socket)"); 900 os_free(msg); 901 return -1; 902 } 903 904 os_free(msg); 905 return 0; 906} 907 908 909static int wpa_driver_test_get_capa(void *priv, struct wpa_driver_capa *capa) 910{ 911 struct wpa_driver_test_data *drv = priv; 912 os_memset(capa, 0, sizeof(*capa)); 913 capa->key_mgmt = WPA_DRIVER_CAPA_KEY_MGMT_WPA | 914 WPA_DRIVER_CAPA_KEY_MGMT_WPA2 | 915 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK | 916 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK | 917 WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE | 918 WPA_DRIVER_CAPA_KEY_MGMT_FT | 919 WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK; 920 capa->enc = WPA_DRIVER_CAPA_ENC_WEP40 | 921 WPA_DRIVER_CAPA_ENC_WEP104 | 922 WPA_DRIVER_CAPA_ENC_TKIP | 923 WPA_DRIVER_CAPA_ENC_CCMP; 924 capa->auth = WPA_DRIVER_AUTH_OPEN | 925 WPA_DRIVER_AUTH_SHARED | 926 WPA_DRIVER_AUTH_LEAP; 927 if (drv->use_mlme) 928 capa->flags |= WPA_DRIVER_FLAGS_USER_SPACE_MLME; 929 930 return 0; 931} 932 933 934static int wpa_driver_test_mlme_setprotection(void *priv, const u8 *addr, 935 int protect_type, 936 int key_type) 937{ 938 wpa_printf(MSG_DEBUG, "%s: protect_type=%d key_type=%d", 939 __func__, protect_type, key_type); 940 941 if (addr) { 942 wpa_printf(MSG_DEBUG, "%s: addr=" MACSTR, 943 __func__, MAC2STR(addr)); 944 } 945 946 return 0; 947} 948 949 950#ifdef CONFIG_CLIENT_MLME 951static struct wpa_hw_modes * 952wpa_driver_test_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags) 953{ 954 struct wpa_hw_modes *modes; 955 956 *num_modes = 1; 957 *flags = 0; 958 modes = os_zalloc(*num_modes * sizeof(struct wpa_hw_modes)); 959 if (modes == NULL) 960 return NULL; 961 modes[0].mode = WPA_MODE_IEEE80211G; 962 modes[0].num_channels = 1; 963 modes[0].num_rates = 1; 964 modes[0].channels = os_zalloc(sizeof(struct wpa_channel_data)); 965 modes[0].rates = os_zalloc(sizeof(struct wpa_rate_data)); 966 if (modes[0].channels == NULL || modes[0].rates == NULL) { 967 wpa_supplicant_sta_free_hw_features(modes, *num_modes); 968 return NULL; 969 } 970 modes[0].channels[0].chan = 1; 971 modes[0].channels[0].freq = 2412; 972 modes[0].channels[0].flag = WPA_CHAN_W_SCAN | WPA_CHAN_W_ACTIVE_SCAN; 973 modes[0].rates[0].rate = 10; 974 modes[0].rates[0].flags = WPA_RATE_BASIC | WPA_RATE_SUPPORTED | 975 WPA_RATE_CCK | WPA_RATE_MANDATORY; 976 977 return modes; 978} 979 980 981static int wpa_driver_test_set_channel(void *priv, wpa_hw_mode phymode, 982 int chan, int freq) 983{ 984 wpa_printf(MSG_DEBUG, "%s: phymode=%d chan=%d freq=%d", 985 __func__, phymode, chan, freq); 986 return 0; 987} 988 989 990static int wpa_driver_test_send_mlme(void *priv, const u8 *data, 991 size_t data_len) 992{ 993 struct wpa_driver_test_data *drv = priv; 994 struct msghdr msg; 995 struct iovec io[2]; 996 struct sockaddr_un addr; 997 const u8 *dest; 998 struct dirent *dent; 999 DIR *dir; 1000 1001 wpa_hexdump(MSG_MSGDUMP, "test_send_mlme", data, data_len); 1002 if (data_len < 10) 1003 return -1; 1004 dest = data + 4; 1005 1006 io[0].iov_base = "MLME "; 1007 io[0].iov_len = 5; 1008 io[1].iov_base = (u8 *) data; 1009 io[1].iov_len = data_len; 1010 1011 os_memset(&msg, 0, sizeof(msg)); 1012 msg.msg_iov = io; 1013 msg.msg_iovlen = 2; 1014 if (os_memcmp(dest, drv->bssid, ETH_ALEN) == 0 || 1015 drv->test_dir == NULL) { 1016 if (drv->hostapd_addr_udp_set) { 1017 msg.msg_name = &drv->hostapd_addr_udp; 1018 msg.msg_namelen = sizeof(drv->hostapd_addr_udp); 1019 } else { 1020#ifdef DRIVER_TEST_UNIX 1021 msg.msg_name = &drv->hostapd_addr; 1022 msg.msg_namelen = sizeof(drv->hostapd_addr); 1023#endif /* DRIVER_TEST_UNIX */ 1024 } 1025 } else if (os_memcmp(dest, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) == 0) 1026 { 1027 dir = opendir(drv->test_dir); 1028 if (dir == NULL) 1029 return -1; 1030 while ((dent = readdir(dir))) { 1031#ifdef _DIRENT_HAVE_D_TYPE 1032 /* Skip the file if it is not a socket. 1033 * Also accept DT_UNKNOWN (0) in case 1034 * the C library or underlying file 1035 * system does not support d_type. */ 1036 if (dent->d_type != DT_SOCK && 1037 dent->d_type != DT_UNKNOWN) 1038 continue; 1039#endif /* _DIRENT_HAVE_D_TYPE */ 1040 if (os_strcmp(dent->d_name, ".") == 0 || 1041 os_strcmp(dent->d_name, "..") == 0) 1042 continue; 1043 wpa_printf(MSG_DEBUG, "%s: Send broadcast MLME to %s", 1044 __func__, dent->d_name); 1045 os_memset(&addr, 0, sizeof(addr)); 1046 addr.sun_family = AF_UNIX; 1047 os_snprintf(addr.sun_path, sizeof(addr.sun_path), 1048 "%s/%s", drv->test_dir, dent->d_name); 1049 1050 msg.msg_name = &addr; 1051 msg.msg_namelen = sizeof(addr); 1052 1053 if (sendmsg(drv->test_socket, &msg, 0) < 0) 1054 perror("sendmsg(test_socket)"); 1055 } 1056 closedir(dir); 1057 return 0; 1058 } else { 1059 struct stat st; 1060 os_memset(&addr, 0, sizeof(addr)); 1061 addr.sun_family = AF_UNIX; 1062 os_snprintf(addr.sun_path, sizeof(addr.sun_path), 1063 "%s/AP-" MACSTR, drv->test_dir, MAC2STR(dest)); 1064 if (stat(addr.sun_path, &st) < 0) { 1065 os_snprintf(addr.sun_path, sizeof(addr.sun_path), 1066 "%s/STA-" MACSTR, 1067 drv->test_dir, MAC2STR(dest)); 1068 } 1069 msg.msg_name = &addr; 1070 msg.msg_namelen = sizeof(addr); 1071 } 1072 1073 if (sendmsg(drv->test_socket, &msg, 0) < 0) { 1074 perror("sendmsg(test_socket)"); 1075 return -1; 1076 } 1077 1078 return 0; 1079} 1080 1081 1082static int wpa_driver_test_mlme_add_sta(void *priv, const u8 *addr, 1083 const u8 *supp_rates, 1084 size_t supp_rates_len) 1085{ 1086 wpa_printf(MSG_DEBUG, "%s: addr=" MACSTR, __func__, MAC2STR(addr)); 1087 return 0; 1088} 1089 1090 1091static int wpa_driver_test_mlme_remove_sta(void *priv, const u8 *addr) 1092{ 1093 wpa_printf(MSG_DEBUG, "%s: addr=" MACSTR, __func__, MAC2STR(addr)); 1094 return 0; 1095} 1096 1097 1098static int wpa_driver_test_set_ssid(void *priv, const u8 *ssid, 1099 size_t ssid_len) 1100{ 1101 wpa_printf(MSG_DEBUG, "%s", __func__); 1102 return 0; 1103} 1104 1105 1106static int wpa_driver_test_set_bssid(void *priv, const u8 *bssid) 1107{ 1108 wpa_printf(MSG_DEBUG, "%s: bssid=" MACSTR, __func__, MAC2STR(bssid)); 1109 return 0; 1110} 1111#endif /* CONFIG_CLIENT_MLME */ 1112 1113 1114static int wpa_driver_test_set_probe_req_ie(void *priv, const u8 *ies, 1115 size_t ies_len) 1116{ 1117 struct wpa_driver_test_data *drv = priv; 1118 1119 os_free(drv->probe_req_ie); 1120 if (ies) { 1121 drv->probe_req_ie = os_malloc(ies_len); 1122 if (drv->probe_req_ie == NULL) { 1123 drv->probe_req_ie_len = 0; 1124 return -1; 1125 } 1126 os_memcpy(drv->probe_req_ie, ies, ies_len); 1127 drv->probe_req_ie_len = ies_len; 1128 } else { 1129 drv->probe_req_ie = NULL; 1130 drv->probe_req_ie_len = 0; 1131 } 1132 return 0; 1133} 1134 1135 1136static void * wpa_driver_test_global_init(void) 1137{ 1138 struct wpa_driver_test_global *global; 1139 1140 global = os_zalloc(sizeof(*global)); 1141 return global; 1142} 1143 1144 1145static void wpa_driver_test_global_deinit(void *priv) 1146{ 1147 struct wpa_driver_test_global *global = priv; 1148 os_free(global); 1149} 1150 1151 1152static struct wpa_interface_info * 1153wpa_driver_test_get_interfaces(void *global_priv) 1154{ 1155 /* struct wpa_driver_test_global *global = priv; */ 1156 struct wpa_interface_info *iface; 1157 1158 iface = os_zalloc(sizeof(*iface)); 1159 if (iface == NULL) 1160 return iface; 1161 iface->ifname = os_strdup("sta0"); 1162 iface->desc = os_strdup("test interface 0"); 1163 iface->drv_name = "test"; 1164 iface->next = os_zalloc(sizeof(*iface)); 1165 if (iface->next) { 1166 iface->next->ifname = os_strdup("sta1"); 1167 iface->next->desc = os_strdup("test interface 1"); 1168 iface->next->drv_name = "test"; 1169 } 1170 1171 return iface; 1172} 1173 1174#ifdef ANDROID 1175int wpa_driver_test_driver_cmd( void *priv, char *cmd, char *buf, size_t buf_len ) 1176{ 1177 struct wpa_driver_test_data *drv = (struct wpa_driver_test_data *)priv; 1178 int ret = -1; 1179 1180 wpa_printf(MSG_DEBUG, "%s %s", __func__, cmd); 1181 if( os_strncasecmp(cmd, "start", 5) == 0 ) { 1182 wpa_printf(MSG_DEBUG,"Start command"); 1183 ret = 0; 1184 } 1185 else if( os_strncasecmp(cmd, "stop", 4) == 0 ) { 1186 wpa_printf(MSG_DEBUG,"Stop command"); 1187 ret = 0; 1188 } 1189 else if( os_strncasecmp(cmd, "macaddr", 7) == 0 ) { 1190 u8 *macaddr = (u8 *)wpa_driver_test_get_mac_addr(priv); 1191 wpa_printf(MSG_DEBUG,"Macaddr command"); 1192 wpa_printf(MSG_DEBUG, " Macaddr = " MACSTR, MAC2STR(macaddr)); 1193 ret = os_snprintf(buf, buf_len, "Macaddr = " MACSTR "\n", MAC2STR(macaddr)); 1194 } 1195 else if( os_strncasecmp(cmd, "rssi", 4) == 0 ) { 1196 wpa_printf(MSG_DEBUG,"RSSI command"); 1197 ret = os_snprintf(buf, buf_len, MACSTR " Rssi %d\n", MAC2STR(drv->bssid), -10); 1198 } else if (os_strncasecmp(cmd, "linkspeed", 9) == 0) { 1199 wpa_printf(MSG_DEBUG, "LinkSpeed command"); 1200 ret = os_snprintf(buf, buf_len, "LinkSpeed %u\n", 11); 1201 } 1202 return ret; 1203} 1204#endif 1205 1206const struct wpa_driver_ops wpa_driver_test_ops = { 1207 "test", 1208 "wpa_supplicant test driver", 1209 wpa_driver_test_get_bssid, 1210 wpa_driver_test_get_ssid, 1211 wpa_driver_test_set_wpa, 1212 wpa_driver_test_set_key, 1213 NULL /* init */, 1214 wpa_driver_test_deinit, 1215 wpa_driver_test_set_param, 1216 NULL /* set_countermeasures */, 1217 NULL /* set_drop_unencrypted */, 1218 wpa_driver_test_scan, 1219 NULL /* get_scan_results */, 1220 wpa_driver_test_deauthenticate, 1221 wpa_driver_test_disassociate, 1222 wpa_driver_test_associate, 1223 NULL /* set_auth_alg */, 1224 NULL /* add_pmkid */, 1225 NULL /* remove_pmkid */, 1226 NULL /* flush_pmkid */, 1227 wpa_driver_test_get_capa, 1228 NULL /* poll */, 1229 NULL /* get_ifname */, 1230 wpa_driver_test_get_mac_addr, 1231 wpa_driver_test_send_eapol, 1232 NULL /* set_operstate */, 1233 wpa_driver_test_mlme_setprotection, 1234#ifdef CONFIG_CLIENT_MLME 1235 wpa_driver_test_get_hw_feature_data, 1236 wpa_driver_test_set_channel, 1237 wpa_driver_test_set_ssid, 1238 wpa_driver_test_set_bssid, 1239 wpa_driver_test_send_mlme, 1240 wpa_driver_test_mlme_add_sta, 1241 wpa_driver_test_mlme_remove_sta, 1242#else /* CONFIG_CLIENT_MLME */ 1243 NULL /* get_hw_feature_data */, 1244 NULL /* set_channel */, 1245 NULL /* set_ssid */, 1246 NULL /* set_bssid */, 1247 NULL /* send_mlme */, 1248 NULL /* mlme_add_sta */, 1249 NULL /* mlme_remove_sta */, 1250#endif /* CONFIG_CLIENT_MLME */ 1251 NULL /* update_ft_ies */, 1252 NULL /* send_ft_action */, 1253 wpa_driver_test_get_scan_results2, 1254 wpa_driver_test_set_probe_req_ie, 1255 NULL /* set_mode */, 1256 NULL /* set_country */, 1257 wpa_driver_test_global_init, 1258 wpa_driver_test_global_deinit, 1259 wpa_driver_test_init2, 1260 wpa_driver_test_get_interfaces, 1261#ifdef ANDROID 1262 wpa_driver_test_driver_cmd 1263#endif 1264}; 1265