Home | History | Annotate | Download | only in wpa_supplicant
      1 /*
      2  * WPA Supplicant - testing driver interface
      3  * Copyright (c) 2004-2006, Jouni Malinen <j (at) 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 #include "includes.h"
     16 #include <sys/un.h>
     17 #include <dirent.h>
     18 #include <sys/stat.h>
     19 
     20 #include "common.h"
     21 #include "driver.h"
     22 #include "wpa_supplicant.h"
     23 #include "l2_packet.h"
     24 #include "eloop.h"
     25 #include "sha1.h"
     26 #include "wpa.h"
     27 #include "mlme.h"
     28 
     29 
     30 struct wpa_driver_test_data {
     31 	void *ctx;
     32 	u8 own_addr[ETH_ALEN];
     33 	int test_socket;
     34 	struct sockaddr_un hostapd_addr;
     35 	int hostapd_addr_set;
     36 	char *own_socket_path;
     37 	char *test_dir;
     38 	u8 bssid[ETH_ALEN];
     39 	u8 ssid[32];
     40 	size_t ssid_len;
     41 #define MAX_SCAN_RESULTS 30
     42 	struct wpa_scan_result scanres[MAX_SCAN_RESULTS];
     43 	size_t num_scanres;
     44 	int use_associnfo;
     45 	u8 assoc_wpa_ie[80];
     46 	size_t assoc_wpa_ie_len;
     47 	int use_mlme;
     48 };
     49 
     50 
     51 static int wpa_driver_test_set_wpa(void *priv, int enabled)
     52 {
     53 	wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled);
     54 	return 0;
     55 }
     56 
     57 
     58 static void wpa_driver_test_scan_timeout(void *eloop_ctx, void *timeout_ctx)
     59 {
     60 	wpa_printf(MSG_DEBUG, "Scan timeout - try to get results");
     61 	wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL);
     62 }
     63 
     64 
     65 static void wpa_driver_scan_dir(struct wpa_driver_test_data *drv,
     66 				const char *path)
     67 {
     68 	struct dirent *dent;
     69 	DIR *dir;
     70 	struct sockaddr_un addr;
     71 
     72 	dir = opendir(path);
     73 	if (dir == NULL)
     74 		return;
     75 
     76 	while ((dent = readdir(dir))) {
     77 		if (os_strncmp(dent->d_name, "AP-", 3) != 0)
     78 			continue;
     79 		wpa_printf(MSG_DEBUG, "%s: SCAN %s", __func__, dent->d_name);
     80 
     81 		os_memset(&addr, 0, sizeof(addr));
     82 		addr.sun_family = AF_UNIX;
     83 		os_snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/%s",
     84 			    path, dent->d_name);
     85 
     86 		if (sendto(drv->test_socket, "SCAN", 4, 0,
     87 			   (struct sockaddr *) &addr, sizeof(addr)) < 0) {
     88 			perror("sendto(test_socket)");
     89 		}
     90 	}
     91 	closedir(dir);
     92 }
     93 
     94 
     95 static int wpa_driver_test_scan(void *priv, const u8 *ssid, size_t ssid_len)
     96 {
     97 	struct wpa_driver_test_data *drv = priv;
     98 	wpa_printf(MSG_DEBUG, "%s: priv=%p", __func__, priv);
     99 
    100 	drv->num_scanres = 0;
    101 
    102 	if (drv->test_socket >= 0 && drv->test_dir)
    103 		wpa_driver_scan_dir(drv, drv->test_dir);
    104 
    105 	if (drv->test_socket >= 0 && drv->hostapd_addr_set &&
    106 	    sendto(drv->test_socket, "SCAN", 4, 0,
    107 		   (struct sockaddr *) &drv->hostapd_addr,
    108 		   sizeof(drv->hostapd_addr)) < 0) {
    109 		perror("sendto(test_socket)");
    110 	}
    111 
    112 	eloop_cancel_timeout(wpa_driver_test_scan_timeout, drv, drv->ctx);
    113 	eloop_register_timeout(1, 0, wpa_driver_test_scan_timeout, drv,
    114 			       drv->ctx);
    115 	return 0;
    116 }
    117 
    118 
    119 static int wpa_driver_test_get_scan_results(void *priv,
    120 					    struct wpa_scan_result *results,
    121 					    size_t max_size)
    122 {
    123 	struct wpa_driver_test_data *drv = priv;
    124 	size_t num = drv->num_scanres;
    125 	if (num > max_size)
    126 		num = max_size;
    127 	os_memcpy(results, &drv->scanres,
    128 		  num * sizeof(struct wpa_scan_result));
    129 	return num;
    130 }
    131 
    132 
    133 static int wpa_driver_test_set_key(void *priv, wpa_alg alg, const u8 *addr,
    134 				   int key_idx, int set_tx,
    135 				   const u8 *seq, size_t seq_len,
    136 				   const u8 *key, size_t key_len)
    137 {
    138 	wpa_printf(MSG_DEBUG, "%s: priv=%p alg=%d key_idx=%d set_tx=%d",
    139 		   __func__, priv, alg, key_idx, set_tx);
    140 	if (addr) {
    141 		wpa_printf(MSG_DEBUG, "   addr=" MACSTR, MAC2STR(addr));
    142 	}
    143 	if (seq) {
    144 		wpa_hexdump(MSG_DEBUG, "   seq", seq, seq_len);
    145 	}
    146 	if (key) {
    147 		wpa_hexdump(MSG_DEBUG, "   key", key, key_len);
    148 	}
    149 	return 0;
    150 }
    151 
    152 
    153 static int wpa_driver_test_associate(
    154 	void *priv, struct wpa_driver_associate_params *params)
    155 {
    156 	struct wpa_driver_test_data *drv = priv;
    157 	wpa_printf(MSG_DEBUG, "%s: priv=%p freq=%d pairwise_suite=%d "
    158 		   "group_suite=%d key_mgmt_suite=%d auth_alg=%d mode=%d",
    159 		   __func__, priv, params->freq, params->pairwise_suite,
    160 		   params->group_suite, params->key_mgmt_suite,
    161 		   params->auth_alg, params->mode);
    162 	if (params->bssid) {
    163 		wpa_printf(MSG_DEBUG, "   bssid=" MACSTR,
    164 			   MAC2STR(params->bssid));
    165 	}
    166 	if (params->ssid) {
    167 		wpa_hexdump_ascii(MSG_DEBUG, "   ssid",
    168 				  params->ssid, params->ssid_len);
    169 	}
    170 	if (params->wpa_ie) {
    171 		wpa_hexdump(MSG_DEBUG, "   wpa_ie",
    172 			    params->wpa_ie, params->wpa_ie_len);
    173 		drv->assoc_wpa_ie_len = params->wpa_ie_len;
    174 		if (drv->assoc_wpa_ie_len > sizeof(drv->assoc_wpa_ie))
    175 			drv->assoc_wpa_ie_len = sizeof(drv->assoc_wpa_ie);
    176 		os_memcpy(drv->assoc_wpa_ie, params->wpa_ie,
    177 			  drv->assoc_wpa_ie_len);
    178 	} else
    179 		drv->assoc_wpa_ie_len = 0;
    180 
    181 	if (drv->test_dir && params->bssid) {
    182 		os_memset(&drv->hostapd_addr, 0, sizeof(drv->hostapd_addr));
    183 		drv->hostapd_addr.sun_family = AF_UNIX;
    184 		os_snprintf(drv->hostapd_addr.sun_path,
    185 			    sizeof(drv->hostapd_addr.sun_path),
    186 			    "%s/AP-" MACSTR,
    187 			    drv->test_dir, MAC2STR(params->bssid));
    188 		drv->hostapd_addr_set = 1;
    189 	}
    190 
    191 	if (drv->test_socket >= 0 && drv->hostapd_addr_set) {
    192 		char cmd[200], *pos, *end;
    193 		int ret;
    194 		end = cmd + sizeof(cmd);
    195 		pos = cmd;
    196 		ret = os_snprintf(pos, end - pos, "ASSOC " MACSTR " ",
    197 				  MAC2STR(drv->own_addr));
    198 		if (ret >= 0 && ret < end - pos)
    199 			pos += ret;
    200 		pos += wpa_snprintf_hex(pos, end - pos, params->ssid,
    201 					params->ssid_len);
    202 		ret = os_snprintf(pos, end - pos, " ");
    203 		if (ret >= 0 && ret < end - pos)
    204 			pos += ret;
    205 		pos += wpa_snprintf_hex(pos, end - pos, params->wpa_ie,
    206 					params->wpa_ie_len);
    207 		end[-1] = '\0';
    208 		if (sendto(drv->test_socket, cmd, os_strlen(cmd), 0,
    209 			   (struct sockaddr *) &drv->hostapd_addr,
    210 			   sizeof(drv->hostapd_addr)) < 0) {
    211 			perror("sendto(test_socket)");
    212 			return -1;
    213 		}
    214 
    215 		os_memcpy(drv->ssid, params->ssid, params->ssid_len);
    216 		drv->ssid_len = params->ssid_len;
    217 	} else
    218 		wpa_supplicant_event(drv->ctx, EVENT_ASSOC, NULL);
    219 
    220 	return 0;
    221 }
    222 
    223 
    224 static int wpa_driver_test_get_bssid(void *priv, u8 *bssid)
    225 {
    226 	struct wpa_driver_test_data *drv = priv;
    227 	os_memcpy(bssid, drv->bssid, ETH_ALEN);
    228 	return 0;
    229 }
    230 
    231 
    232 static int wpa_driver_test_get_ssid(void *priv, u8 *ssid)
    233 {
    234 	struct wpa_driver_test_data *drv = priv;
    235 	os_memcpy(ssid, drv->ssid, 32);
    236 	return drv->ssid_len;
    237 }
    238 
    239 
    240 static int wpa_driver_test_send_disassoc(struct wpa_driver_test_data *drv)
    241 {
    242 	if (drv->test_socket >= 0 &&
    243 	    sendto(drv->test_socket, "DISASSOC", 8, 0,
    244 		   (struct sockaddr *) &drv->hostapd_addr,
    245 		   sizeof(drv->hostapd_addr)) < 0) {
    246 		perror("sendto(test_socket)");
    247 		return -1;
    248 	}
    249 	return 0;
    250 }
    251 
    252 
    253 static int wpa_driver_test_deauthenticate(void *priv, const u8 *addr,
    254 					  int reason_code)
    255 {
    256 	struct wpa_driver_test_data *drv = priv;
    257 	wpa_printf(MSG_DEBUG, "%s addr=" MACSTR " reason_code=%d",
    258 		   __func__, MAC2STR(addr), reason_code);
    259 	os_memset(drv->bssid, 0, ETH_ALEN);
    260 	wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL);
    261 	return wpa_driver_test_send_disassoc(drv);
    262 }
    263 
    264 
    265 static int wpa_driver_test_disassociate(void *priv, const u8 *addr,
    266 					int reason_code)
    267 {
    268 	struct wpa_driver_test_data *drv = priv;
    269 	wpa_printf(MSG_DEBUG, "%s addr=" MACSTR " reason_code=%d",
    270 		   __func__, MAC2STR(addr), reason_code);
    271 	os_memset(drv->bssid, 0, ETH_ALEN);
    272 	wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL);
    273 	return wpa_driver_test_send_disassoc(drv);
    274 }
    275 
    276 
    277 static void wpa_driver_test_scanresp(struct wpa_driver_test_data *drv,
    278 				     struct sockaddr_un *from,
    279 				     socklen_t fromlen,
    280 				     const char *data)
    281 {
    282 	struct wpa_scan_result *res;
    283 	const char *pos, *pos2;
    284 	size_t len;
    285 	u8 ie[200], *ipos, *end;
    286 
    287 	wpa_printf(MSG_DEBUG, "test_driver: SCANRESP %s", data);
    288 	if (drv->num_scanres >= MAX_SCAN_RESULTS) {
    289 		wpa_printf(MSG_DEBUG, "test_driver: No room for the new scan "
    290 			   "result");
    291 		return;
    292 	}
    293 
    294 	/* SCANRESP BSSID SSID IEs */
    295 	res = &drv->scanres[drv->num_scanres];
    296 
    297 	os_memset(res, 0, sizeof(*res));
    298 	if (hwaddr_aton(data, res->bssid)) {
    299 		wpa_printf(MSG_DEBUG, "test_driver: invalid BSSID in scanres");
    300 		return;
    301 	}
    302 
    303 	pos = data + 17;
    304 	while (*pos == ' ')
    305 		pos++;
    306 	pos2 = os_strchr(pos, ' ');
    307 	if (pos2 == NULL) {
    308 		wpa_printf(MSG_DEBUG, "test_driver: invalid SSID termination "
    309 			   "in scanres");
    310 		return;
    311 	}
    312 	len = (pos2 - pos) / 2;
    313 	if (len > sizeof(res->ssid))
    314 		len = sizeof(res->ssid);
    315 	if (hexstr2bin(pos, res->ssid, len) < 0) {
    316 		wpa_printf(MSG_DEBUG, "test_driver: invalid SSID in scanres");
    317 		return;
    318 	}
    319 	res->ssid_len = len;
    320 
    321 	pos = pos2 + 1;
    322 	pos2 = os_strchr(pos, ' ');
    323 	if (pos2 == NULL)
    324 		len = os_strlen(pos) / 2;
    325 	else
    326 		len = (pos2 - pos) / 2;
    327 	if (len > sizeof(ie))
    328 		len = sizeof(ie);
    329 	if (hexstr2bin(pos, ie, len) < 0) {
    330 		wpa_printf(MSG_DEBUG, "test_driver: invalid IEs in scanres");
    331 		return;
    332 	}
    333 
    334 	ipos = ie;
    335 	end = ipos + len;
    336 	while (ipos + 1 < end && ipos + 2 + ipos[1] <= end) {
    337 		len = 2 + ipos[1];
    338 		if (len > SSID_MAX_WPA_IE_LEN)
    339 			len = SSID_MAX_WPA_IE_LEN;
    340 		if (ipos[0] == RSN_INFO_ELEM) {
    341 			os_memcpy(res->rsn_ie, ipos, len);
    342 			res->rsn_ie_len = len;
    343 		} else if (ipos[0] == GENERIC_INFO_ELEM) {
    344 			os_memcpy(res->wpa_ie, ipos, len);
    345 			res->wpa_ie_len = len;
    346 		}
    347 
    348 		ipos += 2 + ipos[1];
    349 	}
    350 
    351 	if (pos2) {
    352 		pos = pos2 + 1;
    353 		while (*pos == ' ')
    354 			pos++;
    355 		if (os_strncmp(pos, "PRIVACY", 7) == 0)
    356 			res->caps |= IEEE80211_CAP_PRIVACY;
    357 	}
    358 
    359 	drv->num_scanres++;
    360 }
    361 
    362 
    363 static void wpa_driver_test_assocresp(struct wpa_driver_test_data *drv,
    364 				      struct sockaddr_un *from,
    365 				      socklen_t fromlen,
    366 				      const char *data)
    367 {
    368 	/* ASSOCRESP BSSID <res> */
    369 	if (hwaddr_aton(data, drv->bssid)) {
    370 		wpa_printf(MSG_DEBUG, "test_driver: invalid BSSID in "
    371 			   "assocresp");
    372 	}
    373 	if (drv->use_associnfo) {
    374 		union wpa_event_data event;
    375 		os_memset(&event, 0, sizeof(event));
    376 		event.assoc_info.req_ies = drv->assoc_wpa_ie;
    377 		event.assoc_info.req_ies_len = drv->assoc_wpa_ie_len;
    378 		wpa_supplicant_event(drv->ctx, EVENT_ASSOCINFO, &event);
    379 	}
    380 	wpa_supplicant_event(drv->ctx, EVENT_ASSOC, NULL);
    381 }
    382 
    383 
    384 static void wpa_driver_test_disassoc(struct wpa_driver_test_data *drv,
    385 				     struct sockaddr_un *from,
    386 				     socklen_t fromlen)
    387 {
    388 	wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL);
    389 }
    390 
    391 
    392 static void wpa_driver_test_eapol(struct wpa_driver_test_data *drv,
    393 				  struct sockaddr_un *from,
    394 				  socklen_t fromlen,
    395 				  const u8 *data, size_t data_len)
    396 {
    397 	const u8 *src = drv->bssid;
    398 
    399 	if (data_len > 14) {
    400 		/* Skip Ethernet header */
    401 		src = data + ETH_ALEN;
    402 		data += 14;
    403 		data_len -= 14;
    404 	}
    405 	wpa_supplicant_rx_eapol(drv->ctx, src, data, data_len);
    406 }
    407 
    408 
    409 static void wpa_driver_test_mlme(struct wpa_driver_test_data *drv,
    410 				 struct sockaddr_un *from,
    411 				 socklen_t fromlen,
    412 				 const u8 *data, size_t data_len)
    413 {
    414 	struct ieee80211_rx_status rx_status;
    415 	os_memset(&rx_status, 0, sizeof(rx_status));
    416 	ieee80211_sta_rx(drv->ctx, data, data_len, &rx_status);
    417 }
    418 
    419 
    420 static void wpa_driver_test_receive_unix(int sock, void *eloop_ctx,
    421 					 void *sock_ctx)
    422 {
    423 	struct wpa_driver_test_data *drv = eloop_ctx;
    424 	char *buf;
    425 	int res;
    426 	struct sockaddr_un from;
    427 	socklen_t fromlen = sizeof(from);
    428 	const size_t buflen = 2000;
    429 
    430 	buf = os_malloc(buflen);
    431 	if (buf == NULL)
    432 		return;
    433 	res = recvfrom(sock, buf, buflen - 1, 0,
    434 		       (struct sockaddr *) &from, &fromlen);
    435 	if (res < 0) {
    436 		perror("recvfrom(test_socket)");
    437 		os_free(buf);
    438 		return;
    439 	}
    440 	buf[res] = '\0';
    441 
    442 	wpa_printf(MSG_DEBUG, "test_driver: received %u bytes", res);
    443 
    444 	if (os_strncmp(buf, "SCANRESP ", 9) == 0) {
    445 		wpa_driver_test_scanresp(drv, &from, fromlen, buf + 9);
    446 	} else if (os_strncmp(buf, "ASSOCRESP ", 10) == 0) {
    447 		wpa_driver_test_assocresp(drv, &from, fromlen, buf + 10);
    448 	} else if (os_strcmp(buf, "DISASSOC") == 0) {
    449 		wpa_driver_test_disassoc(drv, &from, fromlen);
    450 	} else if (os_strcmp(buf, "DEAUTH") == 0) {
    451 		wpa_driver_test_disassoc(drv, &from, fromlen);
    452 	} else if (os_strncmp(buf, "EAPOL ", 6) == 0) {
    453 		wpa_driver_test_eapol(drv, &from, fromlen,
    454 				      (const u8 *) buf + 6, res - 6);
    455 	} else if (os_strncmp(buf, "MLME ", 5) == 0) {
    456 		wpa_driver_test_mlme(drv, &from, fromlen,
    457 				     (const u8 *) buf + 5, res - 5);
    458 	} else {
    459 		wpa_hexdump_ascii(MSG_DEBUG, "Unknown test_socket command",
    460 				  (u8 *) buf, res);
    461 	}
    462 	os_free(buf);
    463 }
    464 
    465 
    466 static void * wpa_driver_test_init(void *ctx, const char *ifname)
    467 {
    468 	struct wpa_driver_test_data *drv;
    469 
    470 	drv = os_zalloc(sizeof(*drv));
    471 	if (drv == NULL)
    472 		return NULL;
    473 	drv->ctx = ctx;
    474 	drv->test_socket = -1;
    475 
    476 	/* Set dummy BSSID and SSID for testing. */
    477 	drv->bssid[0] = 0x02;
    478 	drv->bssid[1] = 0x00;
    479 	drv->bssid[2] = 0x00;
    480 	drv->bssid[3] = 0x00;
    481 	drv->bssid[4] = 0x00;
    482 	drv->bssid[5] = 0x01;
    483 	os_memcpy(drv->ssid, "test", 5);
    484 	drv->ssid_len = 4;
    485 
    486 	/* Generate a MAC address to help testing with multiple STAs */
    487 	drv->own_addr[0] = 0x02; /* locally administered */
    488 	sha1_prf((const u8 *) ifname, os_strlen(ifname),
    489 		 "wpa_supplicant test mac addr generation",
    490 		 NULL, 0, drv->own_addr + 1, ETH_ALEN - 1);
    491 
    492 	return drv;
    493 }
    494 
    495 
    496 static void wpa_driver_test_close_test_socket(struct wpa_driver_test_data *drv)
    497 {
    498 	if (drv->test_socket >= 0) {
    499 		eloop_unregister_read_sock(drv->test_socket);
    500 		close(drv->test_socket);
    501 		drv->test_socket = -1;
    502 	}
    503 
    504 	if (drv->own_socket_path) {
    505 		unlink(drv->own_socket_path);
    506 		os_free(drv->own_socket_path);
    507 		drv->own_socket_path = NULL;
    508 	}
    509 }
    510 
    511 
    512 static void wpa_driver_test_deinit(void *priv)
    513 {
    514 	struct wpa_driver_test_data *drv = priv;
    515 	wpa_driver_test_close_test_socket(drv);
    516 	eloop_cancel_timeout(wpa_driver_test_scan_timeout, drv, drv->ctx);
    517 	os_free(drv->test_dir);
    518 	os_free(drv);
    519 }
    520 
    521 
    522 static int wpa_driver_test_attach(struct wpa_driver_test_data *drv,
    523 				  const char *dir)
    524 {
    525 	static unsigned int counter = 0;
    526 	struct sockaddr_un addr;
    527 	size_t len;
    528 
    529 	os_free(drv->own_socket_path);
    530 	if (dir) {
    531 		len = os_strlen(dir) + 30;
    532 		drv->own_socket_path = os_malloc(len);
    533 		if (drv->own_socket_path == NULL)
    534 			return -1;
    535 		os_snprintf(drv->own_socket_path, len, "%s/STA-" MACSTR,
    536 			    dir, MAC2STR(drv->own_addr));
    537 	} else {
    538 		drv->own_socket_path = os_malloc(100);
    539 		if (drv->own_socket_path == NULL)
    540 			return -1;
    541 		os_snprintf(drv->own_socket_path, 100,
    542 			    "/tmp/wpa_supplicant_test-%d-%d",
    543 			    getpid(), counter++);
    544 	}
    545 
    546 	drv->test_socket = socket(PF_UNIX, SOCK_DGRAM, 0);
    547 	if (drv->test_socket < 0) {
    548 		perror("socket(PF_UNIX)");
    549 		os_free(drv->own_socket_path);
    550 		drv->own_socket_path = NULL;
    551 		return -1;
    552 	}
    553 
    554 	os_memset(&addr, 0, sizeof(addr));
    555 	addr.sun_family = AF_UNIX;
    556 	os_strncpy(addr.sun_path, drv->own_socket_path, sizeof(addr.sun_path));
    557 	if (bind(drv->test_socket, (struct sockaddr *) &addr,
    558 		 sizeof(addr)) < 0) {
    559 		perror("bind(PF_UNIX)");
    560 		close(drv->test_socket);
    561 		unlink(drv->own_socket_path);
    562 		os_free(drv->own_socket_path);
    563 		drv->own_socket_path = NULL;
    564 		return -1;
    565 	}
    566 
    567 	eloop_register_read_sock(drv->test_socket,
    568 				 wpa_driver_test_receive_unix, drv, NULL);
    569 
    570 	return 0;
    571 }
    572 
    573 
    574 static int wpa_driver_test_set_param(void *priv, const char *param)
    575 {
    576 	struct wpa_driver_test_data *drv = priv;
    577 	const char *pos, *pos2;
    578 	size_t len;
    579 
    580 	wpa_printf(MSG_DEBUG, "%s: param='%s'", __func__, param);
    581 	if (param == NULL)
    582 		return 0;
    583 
    584 	wpa_driver_test_close_test_socket(drv);
    585 	pos = os_strstr(param, "test_socket=");
    586 	if (pos) {
    587 		pos += 12;
    588 		pos2 = os_strchr(pos, ' ');
    589 		if (pos2)
    590 			len = pos2 - pos;
    591 		else
    592 			len = os_strlen(pos);
    593 		if (len > sizeof(drv->hostapd_addr.sun_path))
    594 			return -1;
    595 		os_memset(&drv->hostapd_addr, 0, sizeof(drv->hostapd_addr));
    596 		drv->hostapd_addr.sun_family = AF_UNIX;
    597 		os_memcpy(drv->hostapd_addr.sun_path, pos, len);
    598 		drv->hostapd_addr_set = 1;
    599 	}
    600 
    601 	pos = os_strstr(param, "test_dir=");
    602 	if (pos) {
    603 		char *end;
    604 		os_free(drv->test_dir);
    605 		drv->test_dir = os_strdup(pos + 9);
    606 		if (drv->test_dir == NULL)
    607 			return -1;
    608 		end = os_strchr(drv->test_dir, ' ');
    609 		if (end)
    610 			*end = '\0';
    611 		wpa_driver_test_attach(drv, drv->test_dir);
    612 	} else
    613 		wpa_driver_test_attach(drv, NULL);
    614 
    615 	if (os_strstr(param, "use_associnfo=1")) {
    616 		wpa_printf(MSG_DEBUG, "test_driver: Use AssocInfo events");
    617 		drv->use_associnfo = 1;
    618 	}
    619 
    620 #ifdef CONFIG_CLIENT_MLME
    621 	if (os_strstr(param, "use_mlme=1")) {
    622 		wpa_printf(MSG_DEBUG, "test_driver: Use internal MLME");
    623 		drv->use_mlme = 1;
    624 	}
    625 #endif /* CONFIG_CLIENT_MLME */
    626 
    627 	return 0;
    628 }
    629 
    630 
    631 static const u8 * wpa_driver_test_get_mac_addr(void *priv)
    632 {
    633 	struct wpa_driver_test_data *drv = priv;
    634 	wpa_printf(MSG_DEBUG, "%s", __func__);
    635 	return drv->own_addr;
    636 }
    637 
    638 
    639 static int wpa_driver_test_send_eapol(void *priv, const u8 *dest, u16 proto,
    640 				      const u8 *data, size_t data_len)
    641 {
    642 	struct wpa_driver_test_data *drv = priv;
    643 	struct msghdr msg;
    644 	struct iovec io[3];
    645 	struct l2_ethhdr eth;
    646 	struct sockaddr_un addr;
    647 
    648 	wpa_hexdump(MSG_MSGDUMP, "test_send_eapol TX frame", data, data_len);
    649 
    650 	os_memset(&eth, 0, sizeof(eth));
    651 	os_memcpy(eth.h_dest, dest, ETH_ALEN);
    652 	os_memcpy(eth.h_source, drv->own_addr, ETH_ALEN);
    653 	eth.h_proto = host_to_be16(proto);
    654 
    655 	io[0].iov_base = "EAPOL ";
    656 	io[0].iov_len = 6;
    657 	io[1].iov_base = (u8 *) &eth;
    658 	io[1].iov_len = sizeof(eth);
    659 	io[2].iov_base = (u8 *) data;
    660 	io[2].iov_len = data_len;
    661 
    662 	os_memset(&msg, 0, sizeof(msg));
    663 	msg.msg_iov = io;
    664 	msg.msg_iovlen = 3;
    665 	if (os_memcmp(dest, drv->bssid, ETH_ALEN) == 0 ||
    666 	    drv->test_dir == NULL) {
    667 		msg.msg_name = &drv->hostapd_addr;
    668 		msg.msg_namelen = sizeof(drv->hostapd_addr);
    669 	} else {
    670 		struct stat st;
    671 		os_memset(&addr, 0, sizeof(addr));
    672 		addr.sun_family = AF_UNIX;
    673 		os_snprintf(addr.sun_path, sizeof(addr.sun_path),
    674 			    "%s/STA-" MACSTR, drv->test_dir, MAC2STR(dest));
    675 		if (stat(addr.sun_path, &st) < 0) {
    676 			os_snprintf(addr.sun_path, sizeof(addr.sun_path),
    677 				    "%s/AP-" MACSTR,
    678 				    drv->test_dir, MAC2STR(dest));
    679 		}
    680 		msg.msg_name = &addr;
    681 		msg.msg_namelen = sizeof(addr);
    682 	}
    683 
    684 	if (sendmsg(drv->test_socket, &msg, 0) < 0) {
    685 		perror("sendmsg(test_socket)");
    686 		return -1;
    687 	}
    688 
    689 	return 0;
    690 }
    691 
    692 
    693 static int wpa_driver_test_get_capa(void *priv, struct wpa_driver_capa *capa)
    694 {
    695 	struct wpa_driver_test_data *drv = priv;
    696 	os_memset(capa, 0, sizeof(*capa));
    697 	capa->key_mgmt = WPA_DRIVER_CAPA_KEY_MGMT_WPA |
    698 		WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
    699 		WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
    700 		WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK |
    701 		WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE;
    702 	capa->enc = WPA_DRIVER_CAPA_ENC_WEP40 |
    703 		WPA_DRIVER_CAPA_ENC_WEP104 |
    704 		WPA_DRIVER_CAPA_ENC_TKIP |
    705 		WPA_DRIVER_CAPA_ENC_CCMP;
    706 	capa->auth = WPA_DRIVER_AUTH_OPEN |
    707 		WPA_DRIVER_AUTH_SHARED |
    708 		WPA_DRIVER_AUTH_LEAP;
    709 	if (drv->use_mlme)
    710 		capa->flags |= WPA_DRIVER_FLAGS_USER_SPACE_MLME;
    711 
    712 	return 0;
    713 }
    714 
    715 
    716 static int wpa_driver_test_mlme_setprotection(void *priv, const u8 *addr,
    717 					      int protect_type,
    718 					      int key_type)
    719 {
    720 	wpa_printf(MSG_DEBUG, "%s: protect_type=%d key_type=%d",
    721 		   __func__, protect_type, key_type);
    722 
    723 	if (addr) {
    724 		wpa_printf(MSG_DEBUG, "%s: addr=" MACSTR,
    725 			   __func__, MAC2STR(addr));
    726 	}
    727 
    728 	return 0;
    729 }
    730 
    731 
    732 #ifdef CONFIG_CLIENT_MLME
    733 static struct wpa_hw_modes *
    734 wpa_driver_test_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags)
    735 {
    736 	struct wpa_hw_modes *modes;
    737 
    738 	*num_modes = 1;
    739 	*flags = 0;
    740 	modes = os_zalloc(*num_modes * sizeof(struct wpa_hw_modes));
    741 	if (modes == NULL)
    742 		return NULL;
    743 	modes[0].mode = WPA_MODE_IEEE80211G;
    744 	modes[0].num_channels = 1;
    745 	modes[0].num_rates = 1;
    746 	modes[0].channels = os_zalloc(sizeof(struct wpa_channel_data));
    747 	modes[0].rates = os_zalloc(sizeof(struct wpa_rate_data));
    748 	if (modes[0].channels == NULL || modes[0].rates == NULL) {
    749 		ieee80211_sta_free_hw_features(modes, *num_modes);
    750 		return NULL;
    751 	}
    752 	modes[0].channels[0].chan = 1;
    753 	modes[0].channels[0].freq = 2412;
    754 	modes[0].channels[0].flag = WPA_CHAN_W_SCAN | WPA_CHAN_W_ACTIVE_SCAN;
    755 	modes[0].rates[0].rate = 10;
    756 	modes[0].rates[0].flags = WPA_RATE_BASIC | WPA_RATE_SUPPORTED |
    757 		WPA_RATE_CCK | WPA_RATE_MANDATORY;
    758 
    759 	return modes;
    760 }
    761 
    762 
    763 int wpa_driver_test_set_channel(void *priv, wpa_hw_mode phymode, int chan,
    764 				int freq)
    765 {
    766 	wpa_printf(MSG_DEBUG, "%s: phymode=%d chan=%d freq=%d",
    767 		   __func__, phymode, chan, freq);
    768 	return 0;
    769 }
    770 
    771 
    772 static int wpa_driver_test_send_mlme(void *priv, const u8 *data,
    773 				     size_t data_len)
    774 {
    775 	struct wpa_driver_test_data *drv = priv;
    776 	struct msghdr msg;
    777 	struct iovec io[2];
    778 	struct sockaddr_un addr;
    779 	const u8 *dest;
    780 	struct dirent *dent;
    781 	DIR *dir;
    782 
    783 	wpa_hexdump(MSG_MSGDUMP, "test_send_mlme", data, data_len);
    784 	if (data_len < 10)
    785 		return -1;
    786 	dest = data + 4;
    787 
    788 	io[0].iov_base = "MLME ";
    789 	io[0].iov_len = 5;
    790 	io[1].iov_base = (u8 *) data;
    791 	io[1].iov_len = data_len;
    792 
    793 	os_memset(&msg, 0, sizeof(msg));
    794 	msg.msg_iov = io;
    795 	msg.msg_iovlen = 2;
    796 	if (os_memcmp(dest, drv->bssid, ETH_ALEN) == 0 ||
    797 	    drv->test_dir == NULL) {
    798 		msg.msg_name = &drv->hostapd_addr;
    799 		msg.msg_namelen = sizeof(drv->hostapd_addr);
    800 	} else if (os_memcmp(dest, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) == 0)
    801 	{
    802 		dir = opendir(drv->test_dir);
    803 		if (dir == NULL)
    804 			return -1;
    805 		while ((dent = readdir(dir))) {
    806 #ifdef _DIRENT_HAVE_D_TYPE
    807 			/* Skip the file if it is not a socket.
    808 			 * Also accept DT_UNKNOWN (0) in case
    809 			 * the C library or underlying file
    810 			 * system does not support d_type. */
    811 			if (dent->d_type != DT_SOCK &&
    812 			    dent->d_type != DT_UNKNOWN)
    813 				continue;
    814 #endif /* _DIRENT_HAVE_D_TYPE */
    815 			if (os_strcmp(dent->d_name, ".") == 0 ||
    816 			    os_strcmp(dent->d_name, "..") == 0)
    817 				continue;
    818 			wpa_printf(MSG_DEBUG, "%s: Send broadcast MLME to %s",
    819 				   __func__, dent->d_name);
    820 			os_memset(&addr, 0, sizeof(addr));
    821 			addr.sun_family = AF_UNIX;
    822 			os_snprintf(addr.sun_path, sizeof(addr.sun_path),
    823 				    "%s/%s", drv->test_dir, dent->d_name);
    824 
    825 			msg.msg_name = &addr;
    826 			msg.msg_namelen = sizeof(addr);
    827 
    828 			if (sendmsg(drv->test_socket, &msg, 0) < 0)
    829 				perror("sendmsg(test_socket)");
    830 		}
    831 		closedir(dir);
    832 		return 0;
    833 	} else {
    834 		struct stat st;
    835 		os_memset(&addr, 0, sizeof(addr));
    836 		addr.sun_family = AF_UNIX;
    837 		os_snprintf(addr.sun_path, sizeof(addr.sun_path),
    838 			    "%s/AP-" MACSTR, drv->test_dir, MAC2STR(dest));
    839 		if (stat(addr.sun_path, &st) < 0) {
    840 			os_snprintf(addr.sun_path, sizeof(addr.sun_path),
    841 				    "%s/STA-" MACSTR,
    842 				    drv->test_dir, MAC2STR(dest));
    843 		}
    844 		msg.msg_name = &addr;
    845 		msg.msg_namelen = sizeof(addr);
    846 	}
    847 
    848 	if (sendmsg(drv->test_socket, &msg, 0) < 0) {
    849 		perror("sendmsg(test_socket)");
    850 		return -1;
    851 	}
    852 
    853 	return 0;
    854 }
    855 
    856 
    857 static int wpa_driver_test_mlme_add_sta(void *priv, const u8 *addr,
    858 					const u8 *supp_rates,
    859 					size_t supp_rates_len)
    860 {
    861 	wpa_printf(MSG_DEBUG, "%s: addr=" MACSTR, __func__, MAC2STR(addr));
    862 	return 0;
    863 }
    864 
    865 
    866 static int wpa_driver_test_mlme_remove_sta(void *priv, const u8 *addr)
    867 {
    868 	wpa_printf(MSG_DEBUG, "%s: addr=" MACSTR, __func__, MAC2STR(addr));
    869 	return 0;
    870 }
    871 
    872 
    873 int wpa_driver_test_set_ssid(void *priv, const u8 *ssid, size_t ssid_len)
    874 {
    875 	wpa_printf(MSG_DEBUG, "%s", __func__);
    876 	return 0;
    877 }
    878 
    879 
    880 int wpa_driver_test_set_bssid(void *priv, const u8 *bssid)
    881 {
    882 	wpa_printf(MSG_DEBUG, "%s: bssid=" MACSTR, __func__, MAC2STR(bssid));
    883 	return 0;
    884 }
    885 #endif /* CONFIG_CLIENT_MLME */
    886 
    887 int wpa_driver_test_driver_cmd( void *priv, char *cmd, char *buf, size_t buf_len )
    888 {
    889     struct wpa_driver_test_data *drv = (struct wpa_driver_test_data *)priv;
    890     int ret = -1;
    891 
    892     wpa_printf(MSG_DEBUG, "%s %s", __func__, cmd);
    893     if( os_strncasecmp(cmd, "start", 5) == 0 ) {
    894         wpa_printf(MSG_DEBUG,"Start command");
    895         ret = 0;
    896     }
    897     else if( os_strncasecmp(cmd, "stop", 4) == 0 ) {
    898         wpa_printf(MSG_DEBUG,"Stop command");
    899         ret = 0;
    900     }
    901     else if( os_strncasecmp(cmd, "macaddr", 7) == 0 ) {
    902         u8 *macaddr = (u8 *)wpa_driver_test_get_mac_addr(priv);
    903         wpa_printf(MSG_DEBUG,"Macaddr command");
    904         wpa_printf(MSG_DEBUG, "   Macaddr = " MACSTR, MAC2STR(macaddr));
    905         ret = os_snprintf(buf, buf_len, "Macaddr = " MACSTR "\n", MAC2STR(macaddr));
    906     }
    907     else if( os_strncasecmp(cmd, "rssi", 4) == 0 ) {
    908         wpa_printf(MSG_DEBUG,"RSSI command");
    909         ret = os_snprintf(buf, buf_len, MACSTR " Rssi %d\n", MAC2STR(drv->bssid), -10);
    910     } else if (os_strncasecmp(cmd, "linkspeed", 9) == 0) {
    911     	wpa_printf(MSG_DEBUG, "LinkSpeed command");
    912     	ret = os_snprintf(buf, buf_len, "LinkSpeed %u\n", 11);
    913     }
    914     return ret;
    915 }
    916 
    917 const struct wpa_driver_ops wpa_driver_test_ops = {
    918 	"test",
    919 	"wpa_supplicant test driver",
    920 	wpa_driver_test_get_bssid,
    921 	wpa_driver_test_get_ssid,
    922 	wpa_driver_test_set_wpa,
    923 	wpa_driver_test_set_key,
    924 	wpa_driver_test_init,
    925 	wpa_driver_test_deinit,
    926 	wpa_driver_test_set_param,
    927 	NULL /* set_countermeasures */,
    928 	NULL /* set_drop_unencrypted */,
    929 	wpa_driver_test_scan,
    930 	wpa_driver_test_get_scan_results,
    931 	wpa_driver_test_deauthenticate,
    932 	wpa_driver_test_disassociate,
    933 	wpa_driver_test_associate,
    934 	NULL /* set_auth_alg */,
    935 	NULL /* add_pmkid */,
    936 	NULL /* remove_pmkid */,
    937 	NULL /* flush_pmkid */,
    938 	wpa_driver_test_get_capa,
    939 	NULL /* poll */,
    940 	NULL /* get_ifname */,
    941 	wpa_driver_test_get_mac_addr,
    942 	wpa_driver_test_send_eapol,
    943 	NULL /* set_operstate */,
    944 	wpa_driver_test_mlme_setprotection,
    945 #ifdef CONFIG_CLIENT_MLME
    946 	wpa_driver_test_get_hw_feature_data,
    947 	wpa_driver_test_set_channel,
    948 	wpa_driver_test_set_ssid,
    949 	wpa_driver_test_set_bssid,
    950 	wpa_driver_test_send_mlme,
    951 	wpa_driver_test_mlme_add_sta,
    952 	wpa_driver_test_mlme_remove_sta,
    953 #else /* CONFIG_CLIENT_MLME */
    954 	NULL /* get_hw_feature_data */,
    955 	NULL /* set_channel */,
    956 	NULL /* set_ssid */,
    957 	NULL /* set_bssid */,
    958 	NULL /* send_mlme */,
    959 	NULL /* mlme_add_sta */,
    960 	NULL /* mlme_remove_sta */,
    961 #endif /* CONFIG_CLIENT_MLME */
    962     wpa_driver_test_driver_cmd
    963 };
    964