Branch data Line data Source code
1 : : /*
2 : : * Testing driver interface for a simulated network driver
3 : : * Copyright (c) 2004-2010, Jouni Malinen <j@w1.fi>
4 : : *
5 : : * This software may be distributed under the terms of the BSD license.
6 : : * See README for more details.
7 : : */
8 : :
9 : : /* Make sure we get winsock2.h for Windows build to get sockaddr_storage */
10 : : #include "build_config.h"
11 : : #ifdef CONFIG_NATIVE_WINDOWS
12 : : #include <winsock2.h>
13 : : #endif /* CONFIG_NATIVE_WINDOWS */
14 : :
15 : : #include "utils/includes.h"
16 : :
17 : : #ifndef CONFIG_NATIVE_WINDOWS
18 : : #include <sys/un.h>
19 : : #include <dirent.h>
20 : : #include <sys/stat.h>
21 : : #define DRIVER_TEST_UNIX
22 : : #endif /* CONFIG_NATIVE_WINDOWS */
23 : :
24 : : #include "utils/common.h"
25 : : #include "utils/eloop.h"
26 : : #include "utils/list.h"
27 : : #include "utils/trace.h"
28 : : #include "common/ieee802_11_defs.h"
29 : : #include "crypto/sha1.h"
30 : : #include "l2_packet/l2_packet.h"
31 : : #include "p2p/p2p.h"
32 : : #include "wps/wps.h"
33 : : #include "driver.h"
34 : :
35 : :
36 : : struct test_client_socket {
37 : : struct test_client_socket *next;
38 : : u8 addr[ETH_ALEN];
39 : : struct sockaddr_un un;
40 : : socklen_t unlen;
41 : : struct test_driver_bss *bss;
42 : : };
43 : :
44 : : struct test_driver_bss {
45 : : struct wpa_driver_test_data *drv;
46 : : struct dl_list list;
47 : : void *bss_ctx;
48 : : char ifname[IFNAMSIZ];
49 : : u8 bssid[ETH_ALEN];
50 : : u8 *ie;
51 : : size_t ielen;
52 : : u8 *wps_beacon_ie;
53 : : size_t wps_beacon_ie_len;
54 : : u8 *wps_probe_resp_ie;
55 : : size_t wps_probe_resp_ie_len;
56 : : u8 ssid[32];
57 : : size_t ssid_len;
58 : : int privacy;
59 : : };
60 : :
61 : : struct wpa_driver_test_global {
62 : : int bss_add_used;
63 : : u8 req_addr[ETH_ALEN];
64 : : };
65 : :
66 : : struct wpa_driver_test_data {
67 : : struct wpa_driver_test_global *global;
68 : : void *ctx;
69 : : WPA_TRACE_REF(ctx);
70 : : u8 own_addr[ETH_ALEN];
71 : : int test_socket;
72 : : #ifdef DRIVER_TEST_UNIX
73 : : struct sockaddr_un hostapd_addr;
74 : : #endif /* DRIVER_TEST_UNIX */
75 : : int hostapd_addr_set;
76 : : struct sockaddr_in hostapd_addr_udp;
77 : : int hostapd_addr_udp_set;
78 : : char *own_socket_path;
79 : : char *test_dir;
80 : : #define MAX_SCAN_RESULTS 30
81 : : struct wpa_scan_res *scanres[MAX_SCAN_RESULTS];
82 : : size_t num_scanres;
83 : : int use_associnfo;
84 : : u8 assoc_wpa_ie[80];
85 : : size_t assoc_wpa_ie_len;
86 : : int associated;
87 : : u8 *probe_req_ie;
88 : : size_t probe_req_ie_len;
89 : : u8 probe_req_ssid[32];
90 : : size_t probe_req_ssid_len;
91 : : int ibss;
92 : : int ap;
93 : :
94 : : struct test_client_socket *cli;
95 : : struct dl_list bss;
96 : : int udp_port;
97 : :
98 : : int alloc_iface_idx;
99 : :
100 : : int probe_req_report;
101 : : unsigned int remain_on_channel_freq;
102 : : unsigned int remain_on_channel_duration;
103 : :
104 : : int current_freq;
105 : :
106 : : struct p2p_data *p2p;
107 : : unsigned int off_channel_freq;
108 : : struct wpabuf *pending_action_tx;
109 : : u8 pending_action_src[ETH_ALEN];
110 : : u8 pending_action_dst[ETH_ALEN];
111 : : u8 pending_action_bssid[ETH_ALEN];
112 : : unsigned int pending_action_freq;
113 : : unsigned int pending_action_no_cck;
114 : : unsigned int pending_listen_freq;
115 : : unsigned int pending_listen_duration;
116 : : int pending_p2p_scan;
117 : : struct sockaddr *probe_from;
118 : : socklen_t probe_from_len;
119 : : };
120 : :
121 : :
122 : : static void wpa_driver_test_deinit(void *priv);
123 : : static int wpa_driver_test_attach(struct wpa_driver_test_data *drv,
124 : : const char *dir, int ap);
125 : : static void wpa_driver_test_close_test_socket(
126 : : struct wpa_driver_test_data *drv);
127 : : static void test_remain_on_channel_timeout(void *eloop_ctx, void *timeout_ctx);
128 : : static int wpa_driver_test_init_p2p(struct wpa_driver_test_data *drv);
129 : :
130 : :
131 : 0 : static void test_driver_free_bss(struct test_driver_bss *bss)
132 : : {
133 : 0 : os_free(bss->ie);
134 : 0 : os_free(bss->wps_beacon_ie);
135 : 0 : os_free(bss->wps_probe_resp_ie);
136 : 0 : os_free(bss);
137 : 0 : }
138 : :
139 : :
140 : 0 : static void test_driver_free_bsses(struct wpa_driver_test_data *drv)
141 : : {
142 : : struct test_driver_bss *bss, *tmp;
143 : :
144 [ # # ]: 0 : dl_list_for_each_safe(bss, tmp, &drv->bss, struct test_driver_bss,
145 : : list) {
146 : 0 : dl_list_del(&bss->list);
147 : 0 : test_driver_free_bss(bss);
148 : : }
149 : 0 : }
150 : :
151 : :
152 : : static struct test_client_socket *
153 : 0 : test_driver_get_cli(struct wpa_driver_test_data *drv, struct sockaddr_un *from,
154 : : socklen_t fromlen)
155 : : {
156 : 0 : struct test_client_socket *cli = drv->cli;
157 : :
158 [ # # ]: 0 : while (cli) {
159 [ # # ][ # # ]: 0 : if (cli->unlen == fromlen &&
160 : 0 : strncmp(cli->un.sun_path, from->sun_path,
161 : : fromlen - sizeof(cli->un.sun_family)) == 0)
162 : 0 : return cli;
163 : 0 : cli = cli->next;
164 : : }
165 : :
166 : 0 : return NULL;
167 : : }
168 : :
169 : :
170 : 0 : static int test_driver_send_eapol(void *priv, const u8 *addr, const u8 *data,
171 : : size_t data_len, int encrypt,
172 : : const u8 *own_addr, u32 flags)
173 : : {
174 : 0 : struct test_driver_bss *dbss = priv;
175 : 0 : struct wpa_driver_test_data *drv = dbss->drv;
176 : : struct test_client_socket *cli;
177 : : struct msghdr msg;
178 : : struct iovec io[3];
179 : : struct l2_ethhdr eth;
180 : :
181 [ # # ]: 0 : if (drv->test_socket < 0)
182 : 0 : return -1;
183 : :
184 : 0 : cli = drv->cli;
185 [ # # ]: 0 : while (cli) {
186 [ # # ]: 0 : if (memcmp(cli->addr, addr, ETH_ALEN) == 0)
187 : 0 : break;
188 : 0 : cli = cli->next;
189 : : }
190 : :
191 [ # # ]: 0 : if (!cli) {
192 : 0 : wpa_printf(MSG_DEBUG, "%s: no destination client entry",
193 : : __func__);
194 : 0 : return -1;
195 : : }
196 : :
197 : 0 : memcpy(eth.h_dest, addr, ETH_ALEN);
198 : 0 : memcpy(eth.h_source, own_addr, ETH_ALEN);
199 : 0 : eth.h_proto = host_to_be16(ETH_P_EAPOL);
200 : :
201 : 0 : io[0].iov_base = "EAPOL ";
202 : 0 : io[0].iov_len = 6;
203 : 0 : io[1].iov_base = ð
204 : 0 : io[1].iov_len = sizeof(eth);
205 : 0 : io[2].iov_base = (u8 *) data;
206 : 0 : io[2].iov_len = data_len;
207 : :
208 : 0 : memset(&msg, 0, sizeof(msg));
209 : 0 : msg.msg_iov = io;
210 : 0 : msg.msg_iovlen = 3;
211 : 0 : msg.msg_name = &cli->un;
212 : 0 : msg.msg_namelen = cli->unlen;
213 : 0 : return sendmsg(drv->test_socket, &msg, 0);
214 : : }
215 : :
216 : :
217 : 0 : static int test_driver_send_ether(void *priv, const u8 *dst, const u8 *src,
218 : : u16 proto, const u8 *data, size_t data_len)
219 : : {
220 : 0 : struct test_driver_bss *dbss = priv;
221 : 0 : struct wpa_driver_test_data *drv = dbss->drv;
222 : : struct msghdr msg;
223 : : struct iovec io[3];
224 : : struct l2_ethhdr eth;
225 : : char desttxt[30];
226 : : struct sockaddr_un addr;
227 : : struct dirent *dent;
228 : : DIR *dir;
229 : 0 : int ret = 0, broadcast = 0, count = 0;
230 : :
231 [ # # ][ # # ]: 0 : if (drv->test_socket < 0 || drv->test_dir == NULL) {
232 : 0 : wpa_printf(MSG_DEBUG, "%s: invalid parameters (sock=%d "
233 : : "test_dir=%p)",
234 : : __func__, drv->test_socket, drv->test_dir);
235 : 0 : return -1;
236 : : }
237 : :
238 : 0 : broadcast = memcmp(dst, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) == 0;
239 : 0 : snprintf(desttxt, sizeof(desttxt), MACSTR, MAC2STR(dst));
240 : :
241 : 0 : memcpy(eth.h_dest, dst, ETH_ALEN);
242 : 0 : memcpy(eth.h_source, src, ETH_ALEN);
243 : 0 : eth.h_proto = host_to_be16(proto);
244 : :
245 : 0 : io[0].iov_base = "ETHER ";
246 : 0 : io[0].iov_len = 6;
247 : 0 : io[1].iov_base = ð
248 : 0 : io[1].iov_len = sizeof(eth);
249 : 0 : io[2].iov_base = (u8 *) data;
250 : 0 : io[2].iov_len = data_len;
251 : :
252 : 0 : memset(&msg, 0, sizeof(msg));
253 : 0 : msg.msg_iov = io;
254 : 0 : msg.msg_iovlen = 3;
255 : :
256 : 0 : dir = opendir(drv->test_dir);
257 [ # # ]: 0 : if (dir == NULL) {
258 : 0 : perror("test_driver: opendir");
259 : 0 : return -1;
260 : : }
261 [ # # ]: 0 : while ((dent = readdir(dir))) {
262 : : #ifdef _DIRENT_HAVE_D_TYPE
263 : : /* Skip the file if it is not a socket. Also accept
264 : : * DT_UNKNOWN (0) in case the C library or underlying file
265 : : * system does not support d_type. */
266 [ # # ][ # # ]: 0 : if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
267 : 0 : continue;
268 : : #endif /* _DIRENT_HAVE_D_TYPE */
269 [ # # ][ # # ]: 0 : if (strcmp(dent->d_name, ".") == 0 ||
270 : 0 : strcmp(dent->d_name, "..") == 0)
271 : 0 : continue;
272 : :
273 : 0 : memset(&addr, 0, sizeof(addr));
274 : 0 : addr.sun_family = AF_UNIX;
275 : 0 : snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/%s",
276 : 0 : drv->test_dir, dent->d_name);
277 : :
278 [ # # ]: 0 : if (strcmp(addr.sun_path, drv->own_socket_path) == 0)
279 : 0 : continue;
280 [ # # ][ # # ]: 0 : if (!broadcast && strstr(dent->d_name, desttxt) == NULL)
281 : 0 : continue;
282 : :
283 : 0 : wpa_printf(MSG_DEBUG, "%s: Send ether frame to %s",
284 : 0 : __func__, dent->d_name);
285 : :
286 : 0 : msg.msg_name = &addr;
287 : 0 : msg.msg_namelen = sizeof(addr);
288 : 0 : ret = sendmsg(drv->test_socket, &msg, 0);
289 [ # # ]: 0 : if (ret < 0)
290 : 0 : perror("driver_test: sendmsg");
291 : 0 : count++;
292 : : }
293 : 0 : closedir(dir);
294 : :
295 [ # # ][ # # ]: 0 : if (!broadcast && count == 0) {
296 : 0 : wpa_printf(MSG_DEBUG, "%s: Destination " MACSTR " not found",
297 : 0 : __func__, MAC2STR(dst));
298 : 0 : return -1;
299 : : }
300 : :
301 : 0 : return ret;
302 : : }
303 : :
304 : :
305 : 0 : static int wpa_driver_test_send_mlme(void *priv, const u8 *data,
306 : : size_t data_len, int noack)
307 : : {
308 : 0 : struct test_driver_bss *dbss = priv;
309 : 0 : struct wpa_driver_test_data *drv = dbss->drv;
310 : : struct msghdr msg;
311 : : struct iovec io[2];
312 : : const u8 *dest;
313 : : struct sockaddr_un addr;
314 : : struct dirent *dent;
315 : : DIR *dir;
316 : : int broadcast;
317 : 0 : int ret = 0;
318 : : struct ieee80211_hdr *hdr;
319 : : u16 fc;
320 : : char cmd[50];
321 : : int freq;
322 : : #ifdef HOSTAPD
323 : : char desttxt[30];
324 : : #endif /* HOSTAPD */
325 : : union wpa_event_data event;
326 : :
327 : 0 : wpa_hexdump(MSG_MSGDUMP, "test_send_mlme", data, data_len);
328 [ # # ][ # # ]: 0 : if (drv->test_socket < 0 || data_len < 10) {
329 : 0 : wpa_printf(MSG_DEBUG, "%s: invalid parameters (sock=%d len=%lu"
330 : : " test_dir=%p)",
331 : : __func__, drv->test_socket,
332 : : (unsigned long) data_len,
333 : : drv->test_dir);
334 : 0 : return -1;
335 : : }
336 : :
337 : 0 : dest = data + 4;
338 : 0 : broadcast = os_memcmp(dest, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) == 0;
339 : :
340 : : #ifdef HOSTAPD
341 : 0 : snprintf(desttxt, sizeof(desttxt), MACSTR, MAC2STR(dest));
342 : : #endif /* HOSTAPD */
343 : :
344 [ # # ]: 0 : if (drv->remain_on_channel_freq)
345 : 0 : freq = drv->remain_on_channel_freq;
346 : : else
347 : 0 : freq = drv->current_freq;
348 : 0 : wpa_printf(MSG_DEBUG, "test_driver(%s): MLME TX on freq %d MHz",
349 : 0 : dbss->ifname, freq);
350 : 0 : os_snprintf(cmd, sizeof(cmd), "MLME freq=%d ", freq);
351 : 0 : io[0].iov_base = cmd;
352 : 0 : io[0].iov_len = os_strlen(cmd);
353 : 0 : io[1].iov_base = (void *) data;
354 : 0 : io[1].iov_len = data_len;
355 : :
356 : 0 : os_memset(&msg, 0, sizeof(msg));
357 : 0 : msg.msg_iov = io;
358 : 0 : msg.msg_iovlen = 2;
359 : :
360 : : #ifdef HOSTAPD
361 [ # # ]: 0 : if (drv->test_dir == NULL) {
362 : 0 : wpa_printf(MSG_DEBUG, "%s: test_dir == NULL", __func__);
363 : 0 : return -1;
364 : : }
365 : :
366 : 0 : dir = opendir(drv->test_dir);
367 [ # # ]: 0 : if (dir == NULL) {
368 : 0 : perror("test_driver: opendir");
369 : 0 : return -1;
370 : : }
371 [ # # ]: 0 : while ((dent = readdir(dir))) {
372 : : #ifdef _DIRENT_HAVE_D_TYPE
373 : : /* Skip the file if it is not a socket. Also accept
374 : : * DT_UNKNOWN (0) in case the C library or underlying file
375 : : * system does not support d_type. */
376 [ # # ][ # # ]: 0 : if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
377 : 0 : continue;
378 : : #endif /* _DIRENT_HAVE_D_TYPE */
379 [ # # ][ # # ]: 0 : if (os_strcmp(dent->d_name, ".") == 0 ||
380 : 0 : os_strcmp(dent->d_name, "..") == 0)
381 : 0 : continue;
382 : :
383 : 0 : os_memset(&addr, 0, sizeof(addr));
384 : 0 : addr.sun_family = AF_UNIX;
385 : 0 : os_snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/%s",
386 : 0 : drv->test_dir, dent->d_name);
387 : :
388 [ # # ]: 0 : if (os_strcmp(addr.sun_path, drv->own_socket_path) == 0)
389 : 0 : continue;
390 [ # # ][ # # ]: 0 : if (!broadcast && os_strstr(dent->d_name, desttxt) == NULL)
391 : 0 : continue;
392 : :
393 : 0 : wpa_printf(MSG_DEBUG, "%s: Send management frame to %s",
394 : 0 : __func__, dent->d_name);
395 : :
396 : 0 : msg.msg_name = &addr;
397 : 0 : msg.msg_namelen = sizeof(addr);
398 : 0 : ret = sendmsg(drv->test_socket, &msg, 0);
399 [ # # ]: 0 : if (ret < 0)
400 : 0 : perror("driver_test: sendmsg(test_socket)");
401 : : }
402 : 0 : closedir(dir);
403 : : #else /* HOSTAPD */
404 : :
405 : : if (os_memcmp(dest, dbss->bssid, ETH_ALEN) == 0 ||
406 : : drv->test_dir == NULL) {
407 : : if (drv->hostapd_addr_udp_set) {
408 : : msg.msg_name = &drv->hostapd_addr_udp;
409 : : msg.msg_namelen = sizeof(drv->hostapd_addr_udp);
410 : : } else {
411 : : #ifdef DRIVER_TEST_UNIX
412 : : msg.msg_name = &drv->hostapd_addr;
413 : : msg.msg_namelen = sizeof(drv->hostapd_addr);
414 : : #endif /* DRIVER_TEST_UNIX */
415 : : }
416 : : } else if (broadcast) {
417 : : dir = opendir(drv->test_dir);
418 : : if (dir == NULL)
419 : : return -1;
420 : : while ((dent = readdir(dir))) {
421 : : #ifdef _DIRENT_HAVE_D_TYPE
422 : : /* Skip the file if it is not a socket.
423 : : * Also accept DT_UNKNOWN (0) in case
424 : : * the C library or underlying file
425 : : * system does not support d_type. */
426 : : if (dent->d_type != DT_SOCK &&
427 : : dent->d_type != DT_UNKNOWN)
428 : : continue;
429 : : #endif /* _DIRENT_HAVE_D_TYPE */
430 : : if (os_strcmp(dent->d_name, ".") == 0 ||
431 : : os_strcmp(dent->d_name, "..") == 0)
432 : : continue;
433 : : wpa_printf(MSG_DEBUG, "%s: Send broadcast MLME to %s",
434 : : __func__, dent->d_name);
435 : : os_memset(&addr, 0, sizeof(addr));
436 : : addr.sun_family = AF_UNIX;
437 : : os_snprintf(addr.sun_path, sizeof(addr.sun_path),
438 : : "%s/%s", drv->test_dir, dent->d_name);
439 : :
440 : : msg.msg_name = &addr;
441 : : msg.msg_namelen = sizeof(addr);
442 : :
443 : : ret = sendmsg(drv->test_socket, &msg, 0);
444 : : if (ret < 0)
445 : : perror("driver_test: sendmsg(test_socket)");
446 : : }
447 : : closedir(dir);
448 : : return ret;
449 : : } else {
450 : : struct stat st;
451 : : os_memset(&addr, 0, sizeof(addr));
452 : : addr.sun_family = AF_UNIX;
453 : : os_snprintf(addr.sun_path, sizeof(addr.sun_path),
454 : : "%s/AP-" MACSTR, drv->test_dir, MAC2STR(dest));
455 : : if (stat(addr.sun_path, &st) < 0) {
456 : : os_snprintf(addr.sun_path, sizeof(addr.sun_path),
457 : : "%s/STA-" MACSTR,
458 : : drv->test_dir, MAC2STR(dest));
459 : : }
460 : : msg.msg_name = &addr;
461 : : msg.msg_namelen = sizeof(addr);
462 : : }
463 : :
464 : : if (sendmsg(drv->test_socket, &msg, 0) < 0) {
465 : : perror("sendmsg(test_socket)");
466 : : return -1;
467 : : }
468 : : #endif /* HOSTAPD */
469 : :
470 : 0 : hdr = (struct ieee80211_hdr *) data;
471 : 0 : fc = le_to_host16(hdr->frame_control);
472 : :
473 : 0 : os_memset(&event, 0, sizeof(event));
474 : 0 : event.tx_status.type = WLAN_FC_GET_TYPE(fc);
475 : 0 : event.tx_status.stype = WLAN_FC_GET_STYPE(fc);
476 : 0 : event.tx_status.dst = hdr->addr1;
477 : 0 : event.tx_status.data = data;
478 : 0 : event.tx_status.data_len = data_len;
479 : 0 : event.tx_status.ack = ret >= 0;
480 : 0 : wpa_supplicant_event(drv->ctx, EVENT_TX_STATUS, &event);
481 : :
482 : : #ifdef CONFIG_P2P
483 : : if (drv->p2p &&
484 : : WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
485 : : WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_ACTION) {
486 : : if (drv->pending_action_tx == NULL) {
487 : : wpa_printf(MSG_DEBUG, "P2P: Ignore Action TX status - "
488 : : "no pending operation");
489 : : return ret;
490 : : }
491 : :
492 : : if (os_memcmp(hdr->addr1, drv->pending_action_dst, ETH_ALEN) !=
493 : : 0) {
494 : : wpa_printf(MSG_DEBUG, "P2P: Ignore Action TX status - "
495 : : "unknown destination address");
496 : : return ret;
497 : : }
498 : :
499 : : wpabuf_free(drv->pending_action_tx);
500 : : drv->pending_action_tx = NULL;
501 : :
502 : : p2p_send_action_cb(drv->p2p, drv->pending_action_freq,
503 : : drv->pending_action_dst,
504 : : drv->pending_action_src,
505 : : drv->pending_action_bssid,
506 : : ret >= 0);
507 : : }
508 : : #endif /* CONFIG_P2P */
509 : :
510 : 0 : return ret;
511 : : }
512 : :
513 : :
514 : 0 : static void test_driver_scan(struct wpa_driver_test_data *drv,
515 : : struct sockaddr_un *from, socklen_t fromlen,
516 : : char *data)
517 : : {
518 : : char buf[512], *pos, *end;
519 : : int ret;
520 : : struct test_driver_bss *bss;
521 : : u8 sa[ETH_ALEN];
522 : : u8 ie[512];
523 : : size_t ielen;
524 : : union wpa_event_data event;
525 : :
526 : : /* data: optional [ ' ' | STA-addr | ' ' | IEs(hex) ] */
527 : :
528 : 0 : wpa_printf(MSG_DEBUG, "test_driver: SCAN");
529 : :
530 [ # # ]: 0 : if (*data) {
531 [ # # # # ]: 0 : if (*data != ' ' ||
532 : 0 : hwaddr_aton(data + 1, sa)) {
533 : 0 : wpa_printf(MSG_DEBUG, "test_driver: Unexpected SCAN "
534 : : "command format");
535 : 0 : return;
536 : : }
537 : :
538 : 0 : data += 18;
539 [ # # ]: 0 : while (*data == ' ')
540 : 0 : data++;
541 : 0 : ielen = os_strlen(data) / 2;
542 [ # # ]: 0 : if (ielen > sizeof(ie))
543 : 0 : ielen = sizeof(ie);
544 [ # # ]: 0 : if (hexstr2bin(data, ie, ielen) < 0)
545 : 0 : ielen = 0;
546 : :
547 : 0 : wpa_printf(MSG_DEBUG, "test_driver: Scan from " MACSTR,
548 : 0 : MAC2STR(sa));
549 : 0 : wpa_hexdump(MSG_MSGDUMP, "test_driver: scan IEs", ie, ielen);
550 : :
551 : 0 : os_memset(&event, 0, sizeof(event));
552 : 0 : event.rx_probe_req.sa = sa;
553 : 0 : event.rx_probe_req.ie = ie;
554 : 0 : event.rx_probe_req.ie_len = ielen;
555 : 0 : wpa_supplicant_event(drv->ctx, EVENT_RX_PROBE_REQ, &event);
556 : : #ifdef CONFIG_P2P
557 : : if (drv->p2p)
558 : : p2p_probe_req_rx(drv->p2p, sa, NULL, NULL, ie, ielen);
559 : : #endif /* CONFIG_P2P */
560 : : }
561 : :
562 [ # # ]: 0 : dl_list_for_each(bss, &drv->bss, struct test_driver_bss, list) {
563 : 0 : pos = buf;
564 : 0 : end = buf + sizeof(buf);
565 : :
566 : : /* reply: SCANRESP BSSID SSID IEs */
567 : 0 : ret = snprintf(pos, end - pos, "SCANRESP " MACSTR " ",
568 : 0 : MAC2STR(bss->bssid));
569 [ # # ][ # # ]: 0 : if (ret < 0 || ret >= end - pos)
570 : 0 : return;
571 : 0 : pos += ret;
572 : 0 : pos += wpa_snprintf_hex(pos, end - pos,
573 : 0 : bss->ssid, bss->ssid_len);
574 : 0 : ret = snprintf(pos, end - pos, " ");
575 [ # # ][ # # ]: 0 : if (ret < 0 || ret >= end - pos)
576 : 0 : return;
577 : 0 : pos += ret;
578 : 0 : pos += wpa_snprintf_hex(pos, end - pos, bss->ie, bss->ielen);
579 : 0 : pos += wpa_snprintf_hex(pos, end - pos, bss->wps_probe_resp_ie,
580 : : bss->wps_probe_resp_ie_len);
581 : :
582 [ # # ]: 0 : if (bss->privacy) {
583 : 0 : ret = snprintf(pos, end - pos, " PRIVACY");
584 [ # # ][ # # ]: 0 : if (ret < 0 || ret >= end - pos)
585 : 0 : return;
586 : 0 : pos += ret;
587 : : }
588 : :
589 : 0 : sendto(drv->test_socket, buf, pos - buf, 0,
590 : : (struct sockaddr *) from, fromlen);
591 : : }
592 : : }
593 : :
594 : :
595 : 0 : static void test_driver_assoc(struct wpa_driver_test_data *drv,
596 : : struct sockaddr_un *from, socklen_t fromlen,
597 : : char *data)
598 : : {
599 : : struct test_client_socket *cli;
600 : : u8 ie[256], ssid[32];
601 : 0 : size_t ielen, ssid_len = 0;
602 : : char *pos, *pos2, cmd[50];
603 : : struct test_driver_bss *bss, *tmp;
604 : :
605 : : /* data: STA-addr SSID(hex) IEs(hex) */
606 : :
607 : 0 : cli = os_zalloc(sizeof(*cli));
608 [ # # ]: 0 : if (cli == NULL)
609 : 0 : return;
610 : :
611 [ # # ]: 0 : if (hwaddr_aton(data, cli->addr)) {
612 : 0 : printf("test_socket: Invalid MAC address '%s' in ASSOC\n",
613 : : data);
614 : 0 : os_free(cli);
615 : 0 : return;
616 : : }
617 : 0 : pos = data + 17;
618 [ # # ]: 0 : while (*pos == ' ')
619 : 0 : pos++;
620 : 0 : pos2 = strchr(pos, ' ');
621 : 0 : ielen = 0;
622 [ # # ]: 0 : if (pos2) {
623 : 0 : ssid_len = (pos2 - pos) / 2;
624 [ # # ]: 0 : if (hexstr2bin(pos, ssid, ssid_len) < 0) {
625 : 0 : wpa_printf(MSG_DEBUG, "%s: Invalid SSID", __func__);
626 : 0 : os_free(cli);
627 : 0 : return;
628 : : }
629 : 0 : wpa_hexdump_ascii(MSG_DEBUG, "test_driver_assoc: SSID",
630 : : ssid, ssid_len);
631 : :
632 : 0 : pos = pos2 + 1;
633 : 0 : ielen = strlen(pos) / 2;
634 [ # # ]: 0 : if (ielen > sizeof(ie))
635 : 0 : ielen = sizeof(ie);
636 [ # # ]: 0 : if (hexstr2bin(pos, ie, ielen) < 0)
637 : 0 : ielen = 0;
638 : : }
639 : :
640 : 0 : bss = NULL;
641 [ # # ]: 0 : dl_list_for_each(tmp, &drv->bss, struct test_driver_bss, list) {
642 [ # # ][ # # ]: 0 : if (tmp->ssid_len == ssid_len &&
643 : 0 : os_memcmp(tmp->ssid, ssid, ssid_len) == 0) {
644 : 0 : bss = tmp;
645 : 0 : break;
646 : : }
647 : : }
648 [ # # ]: 0 : if (bss == NULL) {
649 : 0 : wpa_printf(MSG_DEBUG, "%s: No matching SSID found from "
650 : : "configured BSSes", __func__);
651 : 0 : os_free(cli);
652 : 0 : return;
653 : : }
654 : :
655 : 0 : cli->bss = bss;
656 : 0 : memcpy(&cli->un, from, sizeof(cli->un));
657 : 0 : cli->unlen = fromlen;
658 : 0 : cli->next = drv->cli;
659 : 0 : drv->cli = cli;
660 : 0 : wpa_hexdump_ascii(MSG_DEBUG, "test_socket: ASSOC sun_path",
661 : 0 : (const u8 *) cli->un.sun_path,
662 : 0 : cli->unlen - sizeof(cli->un.sun_family));
663 : :
664 : 0 : snprintf(cmd, sizeof(cmd), "ASSOCRESP " MACSTR " 0",
665 : 0 : MAC2STR(bss->bssid));
666 : 0 : sendto(drv->test_socket, cmd, strlen(cmd), 0,
667 : : (struct sockaddr *) from, fromlen);
668 : :
669 : 0 : drv_event_assoc(bss->bss_ctx, cli->addr, ie, ielen, 0);
670 : : }
671 : :
672 : :
673 : 0 : static void test_driver_disassoc(struct wpa_driver_test_data *drv,
674 : : struct sockaddr_un *from, socklen_t fromlen)
675 : : {
676 : : struct test_client_socket *cli;
677 : :
678 : 0 : cli = test_driver_get_cli(drv, from, fromlen);
679 [ # # ]: 0 : if (!cli)
680 : 0 : return;
681 : :
682 : 0 : drv_event_disassoc(drv->ctx, cli->addr);
683 : : }
684 : :
685 : :
686 : 0 : static void test_driver_eapol(struct wpa_driver_test_data *drv,
687 : : struct sockaddr_un *from, socklen_t fromlen,
688 : : u8 *data, size_t datalen)
689 : : {
690 : : #ifdef HOSTAPD
691 : : struct test_client_socket *cli;
692 : : #endif /* HOSTAPD */
693 : 0 : const u8 *src = NULL;
694 : :
695 [ # # ]: 0 : if (datalen > 14) {
696 : : /* Skip Ethernet header */
697 : 0 : src = data + ETH_ALEN;
698 : 0 : wpa_printf(MSG_DEBUG, "test_driver: dst=" MACSTR " src="
699 : : MACSTR " proto=%04x",
700 : 0 : MAC2STR(data), MAC2STR(src),
701 : 0 : WPA_GET_BE16(data + 2 * ETH_ALEN));
702 : 0 : data += 14;
703 : 0 : datalen -= 14;
704 : : }
705 : :
706 : : #ifdef HOSTAPD
707 : 0 : cli = test_driver_get_cli(drv, from, fromlen);
708 [ # # ]: 0 : if (cli) {
709 : 0 : drv_event_eapol_rx(cli->bss->bss_ctx, cli->addr, data,
710 : : datalen);
711 : : } else {
712 : 0 : wpa_printf(MSG_DEBUG, "test_socket: EAPOL from unknown "
713 : : "client");
714 : : }
715 : : #else /* HOSTAPD */
716 : : if (src)
717 : : drv_event_eapol_rx(drv->ctx, src, data, datalen);
718 : : #endif /* HOSTAPD */
719 : 0 : }
720 : :
721 : :
722 : 0 : static void test_driver_ether(struct wpa_driver_test_data *drv,
723 : : struct sockaddr_un *from, socklen_t fromlen,
724 : : u8 *data, size_t datalen)
725 : : {
726 : : struct l2_ethhdr *eth;
727 : :
728 [ # # ]: 0 : if (datalen < sizeof(*eth))
729 : 0 : return;
730 : :
731 : 0 : eth = (struct l2_ethhdr *) data;
732 : 0 : wpa_printf(MSG_DEBUG, "test_driver: RX ETHER dst=" MACSTR " src="
733 : : MACSTR " proto=%04x",
734 : 0 : MAC2STR(eth->h_dest), MAC2STR(eth->h_source),
735 : 0 : be_to_host16(eth->h_proto));
736 : :
737 : : #ifdef CONFIG_IEEE80211R
738 [ # # ]: 0 : if (be_to_host16(eth->h_proto) == ETH_P_RRB) {
739 : : union wpa_event_data ev;
740 : 0 : os_memset(&ev, 0, sizeof(ev));
741 : 0 : ev.ft_rrb_rx.src = eth->h_source;
742 : 0 : ev.ft_rrb_rx.data = data + sizeof(*eth);
743 : 0 : ev.ft_rrb_rx.data_len = datalen - sizeof(*eth);
744 : : }
745 : : #endif /* CONFIG_IEEE80211R */
746 : : }
747 : :
748 : :
749 : 0 : static void test_driver_mlme(struct wpa_driver_test_data *drv,
750 : : struct sockaddr_un *from, socklen_t fromlen,
751 : : u8 *data, size_t datalen)
752 : : {
753 : : struct ieee80211_hdr *hdr;
754 : : u16 fc;
755 : : union wpa_event_data event;
756 : 0 : int freq = 0, own_freq;
757 : : struct test_driver_bss *bss;
758 : :
759 [ # # ]: 0 : bss = dl_list_first(&drv->bss, struct test_driver_bss, list);
760 : :
761 [ # # ][ # # ]: 0 : if (datalen > 6 && os_memcmp(data, "freq=", 5) == 0) {
762 : : size_t pos;
763 [ # # ]: 0 : for (pos = 5; pos < datalen; pos++) {
764 [ # # ]: 0 : if (data[pos] == ' ')
765 : 0 : break;
766 : : }
767 [ # # ]: 0 : if (pos < datalen) {
768 : 0 : freq = atoi((const char *) &data[5]);
769 : 0 : wpa_printf(MSG_DEBUG, "test_driver(%s): MLME RX on "
770 : 0 : "freq %d MHz", bss->ifname, freq);
771 : 0 : pos++;
772 : 0 : data += pos;
773 : 0 : datalen -= pos;
774 : : }
775 : : }
776 : :
777 [ # # ]: 0 : if (drv->remain_on_channel_freq)
778 : 0 : own_freq = drv->remain_on_channel_freq;
779 : : else
780 : 0 : own_freq = drv->current_freq;
781 : :
782 [ # # ][ # # ]: 0 : if (freq && own_freq && freq != own_freq) {
[ # # ]
783 : 0 : wpa_printf(MSG_DEBUG, "test_driver(%s): Ignore MLME RX on "
784 : : "another frequency %d MHz (own %d MHz)",
785 : 0 : bss->ifname, freq, own_freq);
786 : 0 : return;
787 : : }
788 : :
789 : 0 : hdr = (struct ieee80211_hdr *) data;
790 : :
791 [ # # ][ # # ]: 0 : if (test_driver_get_cli(drv, from, fromlen) == NULL && datalen >= 16) {
792 : : struct test_client_socket *cli;
793 : 0 : cli = os_zalloc(sizeof(*cli));
794 [ # # ]: 0 : if (cli == NULL)
795 : 0 : return;
796 : 0 : wpa_printf(MSG_DEBUG, "Adding client entry for " MACSTR,
797 : 0 : MAC2STR(hdr->addr2));
798 : 0 : memcpy(cli->addr, hdr->addr2, ETH_ALEN);
799 : 0 : memcpy(&cli->un, from, sizeof(cli->un));
800 : 0 : cli->unlen = fromlen;
801 : 0 : cli->next = drv->cli;
802 : 0 : drv->cli = cli;
803 : : }
804 : :
805 : 0 : wpa_hexdump(MSG_MSGDUMP, "test_driver_mlme: received frame",
806 : : data, datalen);
807 : 0 : fc = le_to_host16(hdr->frame_control);
808 [ # # ]: 0 : if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT) {
809 : 0 : wpa_printf(MSG_ERROR, "%s: received non-mgmt frame",
810 : : __func__);
811 : 0 : return;
812 : : }
813 : :
814 : 0 : os_memset(&event, 0, sizeof(event));
815 : 0 : event.rx_mgmt.frame = data;
816 : 0 : event.rx_mgmt.frame_len = datalen;
817 : 0 : wpa_supplicant_event(drv->ctx, EVENT_RX_MGMT, &event);
818 : : }
819 : :
820 : :
821 : 0 : static void test_driver_receive_unix(int sock, void *eloop_ctx, void *sock_ctx)
822 : : {
823 : 0 : struct wpa_driver_test_data *drv = eloop_ctx;
824 : : char buf[2000];
825 : : int res;
826 : : struct sockaddr_un from;
827 : 0 : socklen_t fromlen = sizeof(from);
828 : :
829 : 0 : res = recvfrom(sock, buf, sizeof(buf) - 1, 0,
830 : : (struct sockaddr *) &from, &fromlen);
831 [ # # ]: 0 : if (res < 0) {
832 : 0 : perror("recvfrom(test_socket)");
833 : 0 : return;
834 : : }
835 : 0 : buf[res] = '\0';
836 : :
837 : 0 : wpa_printf(MSG_DEBUG, "test_driver: received %u bytes", res);
838 : :
839 [ # # ]: 0 : if (strncmp(buf, "SCAN", 4) == 0) {
840 : 0 : test_driver_scan(drv, &from, fromlen, buf + 4);
841 [ # # ]: 0 : } else if (strncmp(buf, "ASSOC ", 6) == 0) {
842 : 0 : test_driver_assoc(drv, &from, fromlen, buf + 6);
843 [ # # ]: 0 : } else if (strcmp(buf, "DISASSOC") == 0) {
844 : 0 : test_driver_disassoc(drv, &from, fromlen);
845 [ # # ]: 0 : } else if (strncmp(buf, "EAPOL ", 6) == 0) {
846 : 0 : test_driver_eapol(drv, &from, fromlen, (u8 *) buf + 6,
847 : 0 : res - 6);
848 [ # # ]: 0 : } else if (strncmp(buf, "ETHER ", 6) == 0) {
849 : 0 : test_driver_ether(drv, &from, fromlen, (u8 *) buf + 6,
850 : 0 : res - 6);
851 [ # # ]: 0 : } else if (strncmp(buf, "MLME ", 5) == 0) {
852 : 0 : test_driver_mlme(drv, &from, fromlen, (u8 *) buf + 5, res - 5);
853 : : } else {
854 : 0 : wpa_hexdump_ascii(MSG_DEBUG, "Unknown test_socket command",
855 : : (u8 *) buf, res);
856 : : }
857 : : }
858 : :
859 : :
860 : 0 : static int test_driver_set_generic_elem(void *priv,
861 : : const u8 *elem, size_t elem_len)
862 : : {
863 : 0 : struct test_driver_bss *bss = priv;
864 : :
865 : 0 : os_free(bss->ie);
866 : :
867 [ # # ]: 0 : if (elem == NULL) {
868 : 0 : bss->ie = NULL;
869 : 0 : bss->ielen = 0;
870 : 0 : return 0;
871 : : }
872 : :
873 : 0 : bss->ie = os_malloc(elem_len);
874 [ # # ]: 0 : if (bss->ie == NULL) {
875 : 0 : bss->ielen = 0;
876 : 0 : return -1;
877 : : }
878 : :
879 : 0 : memcpy(bss->ie, elem, elem_len);
880 : 0 : bss->ielen = elem_len;
881 : 0 : return 0;
882 : : }
883 : :
884 : :
885 : 0 : static int test_driver_set_ap_wps_ie(void *priv, const struct wpabuf *beacon,
886 : : const struct wpabuf *proberesp,
887 : : const struct wpabuf *assocresp)
888 : : {
889 : 0 : struct test_driver_bss *bss = priv;
890 : :
891 [ # # ]: 0 : if (beacon == NULL)
892 : 0 : wpa_printf(MSG_DEBUG, "test_driver: Clear Beacon WPS IE");
893 : : else
894 : 0 : wpa_hexdump_buf(MSG_DEBUG, "test_driver: Beacon WPS IE",
895 : : beacon);
896 : :
897 : 0 : os_free(bss->wps_beacon_ie);
898 : :
899 [ # # ]: 0 : if (beacon == NULL) {
900 : 0 : bss->wps_beacon_ie = NULL;
901 : 0 : bss->wps_beacon_ie_len = 0;
902 : : } else {
903 : 0 : bss->wps_beacon_ie = os_malloc(wpabuf_len(beacon));
904 [ # # ]: 0 : if (bss->wps_beacon_ie == NULL) {
905 : 0 : bss->wps_beacon_ie_len = 0;
906 : 0 : return -1;
907 : : }
908 : :
909 : 0 : os_memcpy(bss->wps_beacon_ie, wpabuf_head(beacon),
910 : : wpabuf_len(beacon));
911 : 0 : bss->wps_beacon_ie_len = wpabuf_len(beacon);
912 : : }
913 : :
914 [ # # ]: 0 : if (proberesp == NULL)
915 : 0 : wpa_printf(MSG_DEBUG, "test_driver: Clear Probe Response WPS "
916 : : "IE");
917 : : else
918 : 0 : wpa_hexdump_buf(MSG_DEBUG, "test_driver: Probe Response WPS "
919 : : "IE", proberesp);
920 : :
921 : 0 : os_free(bss->wps_probe_resp_ie);
922 : :
923 [ # # ]: 0 : if (proberesp == NULL) {
924 : 0 : bss->wps_probe_resp_ie = NULL;
925 : 0 : bss->wps_probe_resp_ie_len = 0;
926 : : } else {
927 : 0 : bss->wps_probe_resp_ie = os_malloc(wpabuf_len(proberesp));
928 [ # # ]: 0 : if (bss->wps_probe_resp_ie == NULL) {
929 : 0 : bss->wps_probe_resp_ie_len = 0;
930 : 0 : return -1;
931 : : }
932 : :
933 : 0 : os_memcpy(bss->wps_probe_resp_ie, wpabuf_head(proberesp),
934 : : wpabuf_len(proberesp));
935 : 0 : bss->wps_probe_resp_ie_len = wpabuf_len(proberesp);
936 : : }
937 : :
938 : 0 : return 0;
939 : : }
940 : :
941 : :
942 : 0 : static int test_driver_sta_deauth(void *priv, const u8 *own_addr,
943 : : const u8 *addr, int reason)
944 : : {
945 : 0 : struct test_driver_bss *dbss = priv;
946 : 0 : struct wpa_driver_test_data *drv = dbss->drv;
947 : : struct test_client_socket *cli;
948 : :
949 [ # # ]: 0 : if (drv->test_socket < 0)
950 : 0 : return -1;
951 : :
952 : 0 : cli = drv->cli;
953 [ # # ]: 0 : while (cli) {
954 [ # # ]: 0 : if (memcmp(cli->addr, addr, ETH_ALEN) == 0)
955 : 0 : break;
956 : 0 : cli = cli->next;
957 : : }
958 : :
959 [ # # ]: 0 : if (!cli)
960 : 0 : return -1;
961 : :
962 : 0 : return sendto(drv->test_socket, "DEAUTH", 6, 0,
963 : 0 : (struct sockaddr *) &cli->un, cli->unlen);
964 : : }
965 : :
966 : :
967 : 0 : static int test_driver_sta_disassoc(void *priv, const u8 *own_addr,
968 : : const u8 *addr, int reason)
969 : : {
970 : 0 : struct test_driver_bss *dbss = priv;
971 : 0 : struct wpa_driver_test_data *drv = dbss->drv;
972 : : struct test_client_socket *cli;
973 : :
974 [ # # ]: 0 : if (drv->test_socket < 0)
975 : 0 : return -1;
976 : :
977 : 0 : cli = drv->cli;
978 [ # # ]: 0 : while (cli) {
979 [ # # ]: 0 : if (memcmp(cli->addr, addr, ETH_ALEN) == 0)
980 : 0 : break;
981 : 0 : cli = cli->next;
982 : : }
983 : :
984 [ # # ]: 0 : if (!cli)
985 : 0 : return -1;
986 : :
987 : 0 : return sendto(drv->test_socket, "DISASSOC", 8, 0,
988 : 0 : (struct sockaddr *) &cli->un, cli->unlen);
989 : : }
990 : :
991 : :
992 : 0 : static int test_driver_bss_add(void *priv, const char *ifname, const u8 *bssid,
993 : : void *bss_ctx, void **drv_priv)
994 : : {
995 : 0 : struct test_driver_bss *dbss = priv;
996 : 0 : struct wpa_driver_test_data *drv = dbss->drv;
997 : : struct test_driver_bss *bss;
998 : :
999 : 0 : wpa_printf(MSG_DEBUG, "%s(ifname=%s bssid=" MACSTR ")",
1000 : 0 : __func__, ifname, MAC2STR(bssid));
1001 : :
1002 : 0 : bss = os_zalloc(sizeof(*bss));
1003 [ # # ]: 0 : if (bss == NULL)
1004 : 0 : return -1;
1005 : :
1006 : 0 : bss->bss_ctx = bss_ctx;
1007 : 0 : bss->drv = drv;
1008 : 0 : os_strlcpy(bss->ifname, ifname, IFNAMSIZ);
1009 : 0 : os_memcpy(bss->bssid, bssid, ETH_ALEN);
1010 : :
1011 : 0 : dl_list_add(&drv->bss, &bss->list);
1012 [ # # ]: 0 : if (drv->global) {
1013 : 0 : drv->global->bss_add_used = 1;
1014 : 0 : os_memcpy(drv->global->req_addr, bssid, ETH_ALEN);
1015 : : }
1016 : :
1017 [ # # ]: 0 : if (drv_priv)
1018 : 0 : *drv_priv = bss;
1019 : :
1020 : 0 : return 0;
1021 : : }
1022 : :
1023 : :
1024 : 0 : static int test_driver_bss_remove(void *priv, const char *ifname)
1025 : : {
1026 : 0 : struct test_driver_bss *dbss = priv;
1027 : 0 : struct wpa_driver_test_data *drv = dbss->drv;
1028 : : struct test_driver_bss *bss;
1029 : : struct test_client_socket *cli, *prev_c;
1030 : :
1031 : 0 : wpa_printf(MSG_DEBUG, "%s(ifname=%s)", __func__, ifname);
1032 : :
1033 [ # # ]: 0 : dl_list_for_each(bss, &drv->bss, struct test_driver_bss, list) {
1034 [ # # ]: 0 : if (strcmp(bss->ifname, ifname) != 0)
1035 : 0 : continue;
1036 : :
1037 [ # # ]: 0 : for (prev_c = NULL, cli = drv->cli; cli;
1038 : 0 : prev_c = cli, cli = cli->next) {
1039 [ # # ]: 0 : if (cli->bss != bss)
1040 : 0 : continue;
1041 [ # # ]: 0 : if (prev_c)
1042 : 0 : prev_c->next = cli->next;
1043 : : else
1044 : 0 : drv->cli = cli->next;
1045 : 0 : os_free(cli);
1046 : 0 : break;
1047 : : }
1048 : :
1049 : 0 : dl_list_del(&bss->list);
1050 : 0 : test_driver_free_bss(bss);
1051 : 0 : return 0;
1052 : : }
1053 : :
1054 : 0 : return -1;
1055 : : }
1056 : :
1057 : :
1058 : 0 : static int test_driver_if_add(void *priv, enum wpa_driver_if_type type,
1059 : : const char *ifname, const u8 *addr,
1060 : : void *bss_ctx, void **drv_priv,
1061 : : char *force_ifname, u8 *if_addr,
1062 : : const char *bridge, int use_existing)
1063 : : {
1064 : 0 : struct test_driver_bss *dbss = priv;
1065 : 0 : struct wpa_driver_test_data *drv = dbss->drv;
1066 : :
1067 : 0 : wpa_printf(MSG_DEBUG, "%s(type=%d ifname=%s bss_ctx=%p)",
1068 : : __func__, type, ifname, bss_ctx);
1069 [ # # ]: 0 : if (addr)
1070 : 0 : os_memcpy(if_addr, addr, ETH_ALEN);
1071 : : else {
1072 : 0 : drv->alloc_iface_idx++;
1073 : 0 : if_addr[0] = 0x02; /* locally administered */
1074 : 0 : sha1_prf(drv->own_addr, ETH_ALEN,
1075 : : "hostapd test addr generation",
1076 : 0 : (const u8 *) &drv->alloc_iface_idx,
1077 : : sizeof(drv->alloc_iface_idx),
1078 : : if_addr + 1, ETH_ALEN - 1);
1079 : : }
1080 [ # # ][ # # ]: 0 : if (type == WPA_IF_AP_BSS || type == WPA_IF_P2P_GO ||
[ # # ]
1081 [ # # ]: 0 : type == WPA_IF_P2P_CLIENT || type == WPA_IF_P2P_GROUP)
1082 : 0 : return test_driver_bss_add(priv, ifname, if_addr, bss_ctx,
1083 : : drv_priv);
1084 : 0 : return 0;
1085 : : }
1086 : :
1087 : :
1088 : 0 : static int test_driver_if_remove(void *priv, enum wpa_driver_if_type type,
1089 : : const char *ifname)
1090 : : {
1091 : 0 : wpa_printf(MSG_DEBUG, "%s(type=%d ifname=%s)", __func__, type, ifname);
1092 [ # # ][ # # ]: 0 : if (type == WPA_IF_AP_BSS || type == WPA_IF_P2P_GO ||
[ # # ]
1093 [ # # ]: 0 : type == WPA_IF_P2P_CLIENT || type == WPA_IF_P2P_GROUP)
1094 : 0 : return test_driver_bss_remove(priv, ifname);
1095 : 0 : return 0;
1096 : : }
1097 : :
1098 : :
1099 : 0 : static int test_driver_set_ssid(void *priv, const u8 *buf, int len)
1100 : : {
1101 : 0 : struct test_driver_bss *bss = priv;
1102 : :
1103 : 0 : wpa_printf(MSG_DEBUG, "%s(ifname=%s)", __func__, bss->ifname);
1104 [ # # ]: 0 : if (len < 0)
1105 : 0 : return -1;
1106 : 0 : wpa_hexdump_ascii(MSG_DEBUG, "test_driver_set_ssid: SSID", buf, len);
1107 : :
1108 [ # # ]: 0 : if ((size_t) len > sizeof(bss->ssid))
1109 : 0 : return -1;
1110 : :
1111 : 0 : os_memcpy(bss->ssid, buf, len);
1112 : 0 : bss->ssid_len = len;
1113 : :
1114 : 0 : return 0;
1115 : : }
1116 : :
1117 : :
1118 : 0 : static int test_driver_set_privacy(void *priv, int enabled)
1119 : : {
1120 : 0 : struct test_driver_bss *dbss = priv;
1121 : :
1122 : 0 : wpa_printf(MSG_DEBUG, "%s(enabled=%d)", __func__, enabled);
1123 : 0 : dbss->privacy = enabled;
1124 : :
1125 : 0 : return 0;
1126 : : }
1127 : :
1128 : :
1129 : 0 : static int test_driver_set_sta_vlan(void *priv, const u8 *addr,
1130 : : const char *ifname, int vlan_id)
1131 : : {
1132 : 0 : wpa_printf(MSG_DEBUG, "%s(addr=" MACSTR " ifname=%s vlan_id=%d)",
1133 : 0 : __func__, MAC2STR(addr), ifname, vlan_id);
1134 : 0 : return 0;
1135 : : }
1136 : :
1137 : :
1138 : 0 : static int test_driver_sta_add(void *priv,
1139 : : struct hostapd_sta_add_params *params)
1140 : : {
1141 : 0 : struct test_driver_bss *bss = priv;
1142 : 0 : struct wpa_driver_test_data *drv = bss->drv;
1143 : : struct test_client_socket *cli;
1144 : :
1145 : 0 : wpa_printf(MSG_DEBUG, "%s(ifname=%s addr=" MACSTR " aid=%d "
1146 : : "capability=0x%x listen_interval=%d)",
1147 : 0 : __func__, bss->ifname, MAC2STR(params->addr), params->aid,
1148 : 0 : params->capability, params->listen_interval);
1149 : 0 : wpa_hexdump(MSG_DEBUG, "test_driver_sta_add - supp_rates",
1150 : 0 : params->supp_rates, params->supp_rates_len);
1151 : :
1152 : 0 : cli = drv->cli;
1153 [ # # ]: 0 : while (cli) {
1154 [ # # ]: 0 : if (os_memcmp(cli->addr, params->addr, ETH_ALEN) == 0)
1155 : 0 : break;
1156 : 0 : cli = cli->next;
1157 : : }
1158 [ # # ]: 0 : if (!cli) {
1159 : 0 : wpa_printf(MSG_DEBUG, "%s: no matching client entry",
1160 : : __func__);
1161 : 0 : return -1;
1162 : : }
1163 : :
1164 : 0 : cli->bss = bss;
1165 : :
1166 : 0 : return 0;
1167 : : }
1168 : :
1169 : :
1170 : 0 : static struct wpa_driver_test_data * test_alloc_data(void *ctx,
1171 : : const char *ifname)
1172 : : {
1173 : : struct wpa_driver_test_data *drv;
1174 : : struct test_driver_bss *bss;
1175 : :
1176 : 0 : drv = os_zalloc(sizeof(struct wpa_driver_test_data));
1177 [ # # ]: 0 : if (drv == NULL) {
1178 : 0 : wpa_printf(MSG_ERROR, "Could not allocate memory for test "
1179 : : "driver data");
1180 : 0 : return NULL;
1181 : : }
1182 : :
1183 : 0 : bss = os_zalloc(sizeof(struct test_driver_bss));
1184 [ # # ]: 0 : if (bss == NULL) {
1185 : 0 : os_free(drv);
1186 : 0 : return NULL;
1187 : : }
1188 : :
1189 : 0 : drv->ctx = ctx;
1190 : 0 : wpa_trace_add_ref(drv, ctx, ctx);
1191 : 0 : dl_list_init(&drv->bss);
1192 : 0 : dl_list_add(&drv->bss, &bss->list);
1193 : 0 : os_strlcpy(bss->ifname, ifname, IFNAMSIZ);
1194 : 0 : bss->bss_ctx = ctx;
1195 : 0 : bss->drv = drv;
1196 : :
1197 : : /* Generate a MAC address to help testing with multiple STAs */
1198 : 0 : drv->own_addr[0] = 0x02; /* locally administered */
1199 : 0 : sha1_prf((const u8 *) ifname, os_strlen(ifname),
1200 : : "test mac addr generation",
1201 : : NULL, 0, drv->own_addr + 1, ETH_ALEN - 1);
1202 : :
1203 : 0 : return drv;
1204 : : }
1205 : :
1206 : :
1207 : 0 : static void * test_driver_init(struct hostapd_data *hapd,
1208 : : struct wpa_init_params *params)
1209 : : {
1210 : : struct wpa_driver_test_data *drv;
1211 : : struct sockaddr_un addr_un;
1212 : : struct sockaddr_in addr_in;
1213 : : struct sockaddr *addr;
1214 : : socklen_t alen;
1215 : : struct test_driver_bss *bss;
1216 : :
1217 : 0 : drv = test_alloc_data(hapd, params->ifname);
1218 [ # # ]: 0 : if (drv == NULL)
1219 : 0 : return NULL;
1220 : 0 : drv->ap = 1;
1221 [ # # ]: 0 : bss = dl_list_first(&drv->bss, struct test_driver_bss, list);
1222 : 0 : drv->global = params->global_priv;
1223 : :
1224 : 0 : bss->bss_ctx = hapd;
1225 : 0 : os_memcpy(bss->bssid, drv->own_addr, ETH_ALEN);
1226 : 0 : os_memcpy(params->own_addr, drv->own_addr, ETH_ALEN);
1227 : :
1228 [ # # ]: 0 : if (params->test_socket) {
1229 [ # # ]: 0 : if (os_strlen(params->test_socket) >=
1230 : : sizeof(addr_un.sun_path)) {
1231 : 0 : printf("Too long test_socket path\n");
1232 : 0 : wpa_driver_test_deinit(bss);
1233 : 0 : return NULL;
1234 : : }
1235 [ # # ]: 0 : if (strncmp(params->test_socket, "DIR:", 4) == 0) {
1236 : 0 : size_t len = strlen(params->test_socket) + 30;
1237 : 0 : drv->test_dir = os_strdup(params->test_socket + 4);
1238 : 0 : drv->own_socket_path = os_malloc(len);
1239 [ # # ]: 0 : if (drv->own_socket_path) {
1240 : 0 : snprintf(drv->own_socket_path, len,
1241 : : "%s/AP-" MACSTR,
1242 : 0 : params->test_socket + 4,
1243 : 0 : MAC2STR(params->own_addr));
1244 : : }
1245 [ # # ]: 0 : } else if (strncmp(params->test_socket, "UDP:", 4) == 0) {
1246 : 0 : drv->udp_port = atoi(params->test_socket + 4);
1247 : : } else {
1248 : 0 : drv->own_socket_path = os_strdup(params->test_socket);
1249 : : }
1250 [ # # ][ # # ]: 0 : if (drv->own_socket_path == NULL && drv->udp_port == 0) {
1251 : 0 : wpa_driver_test_deinit(bss);
1252 : 0 : return NULL;
1253 : : }
1254 : :
1255 [ # # ]: 0 : drv->test_socket = socket(drv->udp_port ? PF_INET : PF_UNIX,
1256 : : SOCK_DGRAM, 0);
1257 [ # # ]: 0 : if (drv->test_socket < 0) {
1258 : 0 : perror("socket");
1259 : 0 : wpa_driver_test_deinit(bss);
1260 : 0 : return NULL;
1261 : : }
1262 : :
1263 [ # # ]: 0 : if (drv->udp_port) {
1264 : 0 : os_memset(&addr_in, 0, sizeof(addr_in));
1265 : 0 : addr_in.sin_family = AF_INET;
1266 : 0 : addr_in.sin_port = htons(drv->udp_port);
1267 : 0 : addr = (struct sockaddr *) &addr_in;
1268 : 0 : alen = sizeof(addr_in);
1269 : : } else {
1270 : 0 : os_memset(&addr_un, 0, sizeof(addr_un));
1271 : 0 : addr_un.sun_family = AF_UNIX;
1272 : 0 : os_strlcpy(addr_un.sun_path, drv->own_socket_path,
1273 : : sizeof(addr_un.sun_path));
1274 : 0 : addr = (struct sockaddr *) &addr_un;
1275 : 0 : alen = sizeof(addr_un);
1276 : : }
1277 [ # # ]: 0 : if (bind(drv->test_socket, addr, alen) < 0) {
1278 : 0 : perror("test-driver-init: bind(PF_UNIX)");
1279 : 0 : close(drv->test_socket);
1280 [ # # ]: 0 : if (drv->own_socket_path)
1281 : 0 : unlink(drv->own_socket_path);
1282 : 0 : wpa_driver_test_deinit(bss);
1283 : 0 : return NULL;
1284 : : }
1285 : 0 : eloop_register_read_sock(drv->test_socket,
1286 : : test_driver_receive_unix, drv, NULL);
1287 : : } else
1288 : 0 : drv->test_socket = -1;
1289 : :
1290 : 0 : return bss;
1291 : : }
1292 : :
1293 : :
1294 : 0 : static void wpa_driver_test_poll(void *eloop_ctx, void *timeout_ctx)
1295 : : {
1296 : 0 : struct wpa_driver_test_data *drv = eloop_ctx;
1297 : :
1298 : : #ifdef DRIVER_TEST_UNIX
1299 [ # # ][ # # ]: 0 : if (drv->associated && drv->hostapd_addr_set) {
1300 : : struct stat st;
1301 [ # # ]: 0 : if (stat(drv->hostapd_addr.sun_path, &st) < 0) {
1302 : 0 : wpa_printf(MSG_DEBUG, "%s: lost connection to AP: %s",
1303 : 0 : __func__, strerror(errno));
1304 : 0 : drv->associated = 0;
1305 : 0 : wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL);
1306 : : }
1307 : : }
1308 : : #endif /* DRIVER_TEST_UNIX */
1309 : :
1310 : 0 : eloop_register_timeout(1, 0, wpa_driver_test_poll, drv, NULL);
1311 : 0 : }
1312 : :
1313 : :
1314 : 0 : static void wpa_driver_test_scan_timeout(void *eloop_ctx, void *timeout_ctx)
1315 : : {
1316 : 0 : struct wpa_driver_test_data *drv = eloop_ctx;
1317 : 0 : wpa_printf(MSG_DEBUG, "Scan timeout - try to get results");
1318 [ # # ][ # # ]: 0 : if (drv->pending_p2p_scan && drv->p2p) {
1319 : : #ifdef CONFIG_P2P
1320 : : size_t i;
1321 : : struct os_reltime now;
1322 : : os_get_reltime(&now);
1323 : : for (i = 0; i < drv->num_scanres; i++) {
1324 : : struct wpa_scan_res *bss = drv->scanres[i];
1325 : : if (p2p_scan_res_handler(drv->p2p, bss->bssid,
1326 : : bss->freq, &now, bss->level,
1327 : : (const u8 *) (bss + 1),
1328 : : bss->ie_len) > 0)
1329 : : return;
1330 : : }
1331 : : p2p_scan_res_handled(drv->p2p);
1332 : : #endif /* CONFIG_P2P */
1333 : 0 : return;
1334 : : }
1335 : 0 : wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL);
1336 : : }
1337 : :
1338 : :
1339 : : #ifdef DRIVER_TEST_UNIX
1340 : 0 : static void wpa_driver_scan_dir(struct wpa_driver_test_data *drv,
1341 : : const char *path)
1342 : : {
1343 : : struct dirent *dent;
1344 : : DIR *dir;
1345 : : struct sockaddr_un addr;
1346 : : char cmd[512], *pos, *end;
1347 : : int ret;
1348 : :
1349 : 0 : dir = opendir(path);
1350 [ # # ]: 0 : if (dir == NULL)
1351 : 0 : return;
1352 : :
1353 : 0 : end = cmd + sizeof(cmd);
1354 : 0 : pos = cmd;
1355 : 0 : ret = os_snprintf(pos, end - pos, "SCAN " MACSTR,
1356 : 0 : MAC2STR(drv->own_addr));
1357 [ # # ][ # # ]: 0 : if (ret >= 0 && ret < end - pos)
1358 : 0 : pos += ret;
1359 [ # # ]: 0 : if (drv->probe_req_ie) {
1360 : 0 : ret = os_snprintf(pos, end - pos, " ");
1361 [ # # ][ # # ]: 0 : if (ret >= 0 && ret < end - pos)
1362 : 0 : pos += ret;
1363 : 0 : pos += wpa_snprintf_hex(pos, end - pos, drv->probe_req_ie,
1364 : : drv->probe_req_ie_len);
1365 : : }
1366 [ # # ]: 0 : if (drv->probe_req_ssid_len) {
1367 : : /* Add SSID IE */
1368 : 0 : ret = os_snprintf(pos, end - pos, "%02x%02x",
1369 : : WLAN_EID_SSID,
1370 : 0 : (unsigned int) drv->probe_req_ssid_len);
1371 [ # # ][ # # ]: 0 : if (ret >= 0 && ret < end - pos)
1372 : 0 : pos += ret;
1373 : 0 : pos += wpa_snprintf_hex(pos, end - pos, drv->probe_req_ssid,
1374 : : drv->probe_req_ssid_len);
1375 : : }
1376 : 0 : end[-1] = '\0';
1377 : :
1378 [ # # ]: 0 : while ((dent = readdir(dir))) {
1379 [ # # ][ # # ]: 0 : if (os_strncmp(dent->d_name, "AP-", 3) != 0 &&
1380 : 0 : os_strncmp(dent->d_name, "STA-", 4) != 0)
1381 : 0 : continue;
1382 [ # # ]: 0 : if (drv->own_socket_path) {
1383 : : size_t olen, dlen;
1384 : 0 : olen = os_strlen(drv->own_socket_path);
1385 : 0 : dlen = os_strlen(dent->d_name);
1386 [ # # ][ # # ]: 0 : if (olen >= dlen &&
1387 : 0 : os_strcmp(dent->d_name,
1388 : : drv->own_socket_path + olen - dlen) == 0)
1389 : 0 : continue;
1390 : : }
1391 : 0 : wpa_printf(MSG_DEBUG, "%s: SCAN %s", __func__, dent->d_name);
1392 : :
1393 : 0 : os_memset(&addr, 0, sizeof(addr));
1394 : 0 : addr.sun_family = AF_UNIX;
1395 : 0 : os_snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/%s",
1396 : 0 : path, dent->d_name);
1397 : :
1398 [ # # ]: 0 : if (sendto(drv->test_socket, cmd, os_strlen(cmd), 0,
1399 : : (struct sockaddr *) &addr, sizeof(addr)) < 0) {
1400 : 0 : perror("sendto(test_socket)");
1401 : : }
1402 : : }
1403 : 0 : closedir(dir);
1404 : : }
1405 : : #endif /* DRIVER_TEST_UNIX */
1406 : :
1407 : :
1408 : 0 : static int wpa_driver_test_scan(void *priv,
1409 : : struct wpa_driver_scan_params *params)
1410 : : {
1411 : 0 : struct test_driver_bss *dbss = priv;
1412 : 0 : struct wpa_driver_test_data *drv = dbss->drv;
1413 : : size_t i;
1414 : :
1415 : 0 : wpa_printf(MSG_DEBUG, "%s: priv=%p", __func__, priv);
1416 : :
1417 : 0 : os_free(drv->probe_req_ie);
1418 [ # # ]: 0 : if (params->extra_ies) {
1419 : 0 : drv->probe_req_ie = os_malloc(params->extra_ies_len);
1420 [ # # ]: 0 : if (drv->probe_req_ie == NULL) {
1421 : 0 : drv->probe_req_ie_len = 0;
1422 : 0 : return -1;
1423 : : }
1424 : 0 : os_memcpy(drv->probe_req_ie, params->extra_ies,
1425 : : params->extra_ies_len);
1426 : 0 : drv->probe_req_ie_len = params->extra_ies_len;
1427 : : } else {
1428 : 0 : drv->probe_req_ie = NULL;
1429 : 0 : drv->probe_req_ie_len = 0;
1430 : : }
1431 : :
1432 [ # # ]: 0 : for (i = 0; i < params->num_ssids; i++)
1433 : 0 : wpa_hexdump(MSG_DEBUG, "Scan SSID",
1434 : 0 : params->ssids[i].ssid, params->ssids[i].ssid_len);
1435 : 0 : drv->probe_req_ssid_len = 0;
1436 [ # # ]: 0 : if (params->num_ssids) {
1437 : 0 : os_memcpy(drv->probe_req_ssid, params->ssids[0].ssid,
1438 : : params->ssids[0].ssid_len);
1439 : 0 : drv->probe_req_ssid_len = params->ssids[0].ssid_len;
1440 : : }
1441 : 0 : wpa_hexdump(MSG_DEBUG, "Scan extra IE(s)",
1442 : 0 : params->extra_ies, params->extra_ies_len);
1443 : :
1444 : 0 : drv->num_scanres = 0;
1445 : :
1446 : : #ifdef DRIVER_TEST_UNIX
1447 [ # # ][ # # ]: 0 : if (drv->test_socket >= 0 && drv->test_dir)
1448 : 0 : wpa_driver_scan_dir(drv, drv->test_dir);
1449 : :
1450 [ # # ]: 0 : if (drv->test_socket >= 0 && drv->hostapd_addr_set &&
[ # # # # ]
1451 : 0 : sendto(drv->test_socket, "SCAN", 4, 0,
1452 : 0 : (struct sockaddr *) &drv->hostapd_addr,
1453 : : sizeof(drv->hostapd_addr)) < 0) {
1454 : 0 : perror("sendto(test_socket)");
1455 : : }
1456 : : #endif /* DRIVER_TEST_UNIX */
1457 : :
1458 [ # # ]: 0 : if (drv->test_socket >= 0 && drv->hostapd_addr_udp_set &&
[ # # # # ]
1459 : 0 : sendto(drv->test_socket, "SCAN", 4, 0,
1460 : 0 : (struct sockaddr *) &drv->hostapd_addr_udp,
1461 : : sizeof(drv->hostapd_addr_udp)) < 0) {
1462 : 0 : perror("sendto(test_socket)");
1463 : : }
1464 : :
1465 : 0 : eloop_cancel_timeout(wpa_driver_test_scan_timeout, drv, drv->ctx);
1466 : 0 : eloop_register_timeout(1, 0, wpa_driver_test_scan_timeout, drv,
1467 : : drv->ctx);
1468 : 0 : return 0;
1469 : : }
1470 : :
1471 : :
1472 : 0 : static struct wpa_scan_results * wpa_driver_test_get_scan_results2(void *priv)
1473 : : {
1474 : 0 : struct test_driver_bss *dbss = priv;
1475 : 0 : struct wpa_driver_test_data *drv = dbss->drv;
1476 : : struct wpa_scan_results *res;
1477 : : size_t i;
1478 : :
1479 : 0 : res = os_zalloc(sizeof(*res));
1480 [ # # ]: 0 : if (res == NULL)
1481 : 0 : return NULL;
1482 : :
1483 : 0 : res->res = os_calloc(drv->num_scanres, sizeof(struct wpa_scan_res *));
1484 [ # # ]: 0 : if (res->res == NULL) {
1485 : 0 : os_free(res);
1486 : 0 : return NULL;
1487 : : }
1488 : :
1489 [ # # ]: 0 : for (i = 0; i < drv->num_scanres; i++) {
1490 : : struct wpa_scan_res *r;
1491 [ # # ]: 0 : if (drv->scanres[i] == NULL)
1492 : 0 : continue;
1493 : 0 : r = os_malloc(sizeof(*r) + drv->scanres[i]->ie_len);
1494 [ # # ]: 0 : if (r == NULL)
1495 : 0 : break;
1496 : 0 : os_memcpy(r, drv->scanres[i],
1497 : : sizeof(*r) + drv->scanres[i]->ie_len);
1498 : 0 : res->res[res->num++] = r;
1499 : : }
1500 : :
1501 : 0 : return res;
1502 : : }
1503 : :
1504 : :
1505 : 0 : static int wpa_driver_test_set_key(const char *ifname, void *priv,
1506 : : enum wpa_alg alg, const u8 *addr,
1507 : : int key_idx, int set_tx,
1508 : : const u8 *seq, size_t seq_len,
1509 : : const u8 *key, size_t key_len)
1510 : : {
1511 : 0 : wpa_printf(MSG_DEBUG, "%s: ifname=%s priv=%p alg=%d key_idx=%d "
1512 : : "set_tx=%d",
1513 : : __func__, ifname, priv, alg, key_idx, set_tx);
1514 [ # # ]: 0 : if (addr)
1515 : 0 : wpa_printf(MSG_DEBUG, " addr=" MACSTR, MAC2STR(addr));
1516 [ # # ]: 0 : if (seq)
1517 : 0 : wpa_hexdump(MSG_DEBUG, " seq", seq, seq_len);
1518 [ # # ]: 0 : if (key)
1519 : 0 : wpa_hexdump_key(MSG_DEBUG, " key", key, key_len);
1520 : 0 : return 0;
1521 : : }
1522 : :
1523 : :
1524 : 0 : static int wpa_driver_update_mode(struct wpa_driver_test_data *drv, int ap)
1525 : : {
1526 [ # # ][ # # ]: 0 : if (ap && !drv->ap) {
1527 : 0 : wpa_driver_test_close_test_socket(drv);
1528 : 0 : wpa_driver_test_attach(drv, drv->test_dir, 1);
1529 : 0 : drv->ap = 1;
1530 [ # # ][ # # ]: 0 : } else if (!ap && drv->ap) {
1531 : 0 : wpa_driver_test_close_test_socket(drv);
1532 : 0 : wpa_driver_test_attach(drv, drv->test_dir, 0);
1533 : 0 : drv->ap = 0;
1534 : : }
1535 : :
1536 : 0 : return 0;
1537 : : }
1538 : :
1539 : :
1540 : 0 : static int wpa_driver_test_associate(
1541 : : void *priv, struct wpa_driver_associate_params *params)
1542 : : {
1543 : 0 : struct test_driver_bss *dbss = priv;
1544 : 0 : struct wpa_driver_test_data *drv = dbss->drv;
1545 : 0 : wpa_printf(MSG_DEBUG, "%s: priv=%p freq=%d pairwise_suite=%d "
1546 : : "group_suite=%d key_mgmt_suite=%d auth_alg=%d mode=%d",
1547 : 0 : __func__, priv, params->freq, params->pairwise_suite,
1548 : 0 : params->group_suite, params->key_mgmt_suite,
1549 : : params->auth_alg, params->mode);
1550 : 0 : wpa_driver_update_mode(drv, params->mode == IEEE80211_MODE_AP);
1551 [ # # ]: 0 : if (params->bssid) {
1552 : 0 : wpa_printf(MSG_DEBUG, " bssid=" MACSTR,
1553 : 0 : MAC2STR(params->bssid));
1554 : : }
1555 [ # # ]: 0 : if (params->ssid) {
1556 : 0 : wpa_hexdump_ascii(MSG_DEBUG, " ssid",
1557 : 0 : params->ssid, params->ssid_len);
1558 : : }
1559 [ # # ]: 0 : if (params->wpa_ie) {
1560 : 0 : wpa_hexdump(MSG_DEBUG, " wpa_ie",
1561 : 0 : params->wpa_ie, params->wpa_ie_len);
1562 : 0 : drv->assoc_wpa_ie_len = params->wpa_ie_len;
1563 [ # # ]: 0 : if (drv->assoc_wpa_ie_len > sizeof(drv->assoc_wpa_ie))
1564 : 0 : drv->assoc_wpa_ie_len = sizeof(drv->assoc_wpa_ie);
1565 : 0 : os_memcpy(drv->assoc_wpa_ie, params->wpa_ie,
1566 : : drv->assoc_wpa_ie_len);
1567 : : } else
1568 : 0 : drv->assoc_wpa_ie_len = 0;
1569 : :
1570 : 0 : wpa_driver_update_mode(drv, params->mode == IEEE80211_MODE_AP);
1571 : :
1572 : 0 : drv->ibss = params->mode == IEEE80211_MODE_IBSS;
1573 : 0 : dbss->privacy = params->key_mgmt_suite &
1574 : : (WPA_KEY_MGMT_IEEE8021X |
1575 : : WPA_KEY_MGMT_PSK |
1576 : : WPA_KEY_MGMT_WPA_NONE |
1577 : : WPA_KEY_MGMT_FT_IEEE8021X |
1578 : : WPA_KEY_MGMT_FT_PSK |
1579 : : WPA_KEY_MGMT_IEEE8021X_SHA256 |
1580 : : WPA_KEY_MGMT_PSK_SHA256);
1581 [ # # ]: 0 : if (params->wep_key_len[params->wep_tx_keyidx])
1582 : 0 : dbss->privacy = 1;
1583 : :
1584 : : #ifdef DRIVER_TEST_UNIX
1585 [ # # ][ # # ]: 0 : if (drv->test_dir && params->bssid &&
[ # # ]
1586 : 0 : params->mode != IEEE80211_MODE_IBSS) {
1587 : 0 : os_memset(&drv->hostapd_addr, 0, sizeof(drv->hostapd_addr));
1588 : 0 : drv->hostapd_addr.sun_family = AF_UNIX;
1589 : 0 : os_snprintf(drv->hostapd_addr.sun_path,
1590 : : sizeof(drv->hostapd_addr.sun_path),
1591 : : "%s/AP-" MACSTR,
1592 : 0 : drv->test_dir, MAC2STR(params->bssid));
1593 : 0 : drv->hostapd_addr_set = 1;
1594 : : }
1595 : : #endif /* DRIVER_TEST_UNIX */
1596 : :
1597 [ # # ]: 0 : if (params->mode == IEEE80211_MODE_AP) {
1598 : 0 : os_memcpy(dbss->ssid, params->ssid, params->ssid_len);
1599 : 0 : dbss->ssid_len = params->ssid_len;
1600 : 0 : os_memcpy(dbss->bssid, drv->own_addr, ETH_ALEN);
1601 [ # # ][ # # ]: 0 : if (params->wpa_ie && params->wpa_ie_len) {
1602 : 0 : dbss->ie = os_malloc(params->wpa_ie_len);
1603 [ # # ]: 0 : if (dbss->ie) {
1604 : 0 : os_memcpy(dbss->ie, params->wpa_ie,
1605 : : params->wpa_ie_len);
1606 : 0 : dbss->ielen = params->wpa_ie_len;
1607 : : }
1608 : : }
1609 [ # # ][ # # ]: 0 : } else if (drv->test_socket >= 0 &&
1610 [ # # ]: 0 : (drv->hostapd_addr_set || drv->hostapd_addr_udp_set)) {
1611 : : char cmd[200], *pos, *end;
1612 : : int ret;
1613 : 0 : end = cmd + sizeof(cmd);
1614 : 0 : pos = cmd;
1615 : 0 : ret = os_snprintf(pos, end - pos, "ASSOC " MACSTR " ",
1616 : 0 : MAC2STR(drv->own_addr));
1617 [ # # ][ # # ]: 0 : if (ret >= 0 && ret < end - pos)
1618 : 0 : pos += ret;
1619 : 0 : pos += wpa_snprintf_hex(pos, end - pos, params->ssid,
1620 : : params->ssid_len);
1621 : 0 : ret = os_snprintf(pos, end - pos, " ");
1622 [ # # ][ # # ]: 0 : if (ret >= 0 && ret < end - pos)
1623 : 0 : pos += ret;
1624 : 0 : pos += wpa_snprintf_hex(pos, end - pos, params->wpa_ie,
1625 : : params->wpa_ie_len);
1626 : 0 : end[-1] = '\0';
1627 : : #ifdef DRIVER_TEST_UNIX
1628 [ # # # # ]: 0 : if (drv->hostapd_addr_set &&
1629 : 0 : sendto(drv->test_socket, cmd, os_strlen(cmd), 0,
1630 : 0 : (struct sockaddr *) &drv->hostapd_addr,
1631 : : sizeof(drv->hostapd_addr)) < 0) {
1632 : 0 : perror("sendto(test_socket)");
1633 : 0 : return -1;
1634 : : }
1635 : : #endif /* DRIVER_TEST_UNIX */
1636 [ # # # # ]: 0 : if (drv->hostapd_addr_udp_set &&
1637 : 0 : sendto(drv->test_socket, cmd, os_strlen(cmd), 0,
1638 : 0 : (struct sockaddr *) &drv->hostapd_addr_udp,
1639 : : sizeof(drv->hostapd_addr_udp)) < 0) {
1640 : 0 : perror("sendto(test_socket)");
1641 : 0 : return -1;
1642 : : }
1643 : :
1644 : 0 : os_memcpy(dbss->ssid, params->ssid, params->ssid_len);
1645 : 0 : dbss->ssid_len = params->ssid_len;
1646 : : } else {
1647 : 0 : drv->associated = 1;
1648 [ # # ]: 0 : if (params->mode == IEEE80211_MODE_IBSS) {
1649 : 0 : os_memcpy(dbss->ssid, params->ssid, params->ssid_len);
1650 : 0 : dbss->ssid_len = params->ssid_len;
1651 [ # # ]: 0 : if (params->bssid)
1652 : 0 : os_memcpy(dbss->bssid, params->bssid,
1653 : : ETH_ALEN);
1654 : : else {
1655 : 0 : os_get_random(dbss->bssid, ETH_ALEN);
1656 : 0 : dbss->bssid[0] &= ~0x01;
1657 : 0 : dbss->bssid[0] |= 0x02;
1658 : : }
1659 : : }
1660 : 0 : wpa_supplicant_event(drv->ctx, EVENT_ASSOC, NULL);
1661 : : }
1662 : :
1663 : 0 : return 0;
1664 : : }
1665 : :
1666 : :
1667 : 0 : static int wpa_driver_test_get_bssid(void *priv, u8 *bssid)
1668 : : {
1669 : 0 : struct test_driver_bss *dbss = priv;
1670 : 0 : os_memcpy(bssid, dbss->bssid, ETH_ALEN);
1671 : 0 : return 0;
1672 : : }
1673 : :
1674 : :
1675 : 0 : static int wpa_driver_test_get_ssid(void *priv, u8 *ssid)
1676 : : {
1677 : 0 : struct test_driver_bss *dbss = priv;
1678 : 0 : os_memcpy(ssid, dbss->ssid, 32);
1679 : 0 : return dbss->ssid_len;
1680 : : }
1681 : :
1682 : :
1683 : 0 : static int wpa_driver_test_send_disassoc(struct wpa_driver_test_data *drv)
1684 : : {
1685 : : #ifdef DRIVER_TEST_UNIX
1686 [ # # # # ]: 0 : if (drv->test_socket >= 0 &&
1687 : 0 : sendto(drv->test_socket, "DISASSOC", 8, 0,
1688 : 0 : (struct sockaddr *) &drv->hostapd_addr,
1689 : : sizeof(drv->hostapd_addr)) < 0) {
1690 : 0 : perror("sendto(test_socket)");
1691 : 0 : return -1;
1692 : : }
1693 : : #endif /* DRIVER_TEST_UNIX */
1694 [ # # ]: 0 : if (drv->test_socket >= 0 && drv->hostapd_addr_udp_set &&
[ # # # # ]
1695 : 0 : sendto(drv->test_socket, "DISASSOC", 8, 0,
1696 : 0 : (struct sockaddr *) &drv->hostapd_addr_udp,
1697 : : sizeof(drv->hostapd_addr_udp)) < 0) {
1698 : 0 : perror("sendto(test_socket)");
1699 : 0 : return -1;
1700 : : }
1701 : 0 : return 0;
1702 : : }
1703 : :
1704 : :
1705 : 0 : static int wpa_driver_test_deauthenticate(void *priv, const u8 *addr,
1706 : : int reason_code)
1707 : : {
1708 : 0 : struct test_driver_bss *dbss = priv;
1709 : 0 : struct wpa_driver_test_data *drv = dbss->drv;
1710 : 0 : wpa_printf(MSG_DEBUG, "%s addr=" MACSTR " reason_code=%d",
1711 : 0 : __func__, MAC2STR(addr), reason_code);
1712 : 0 : os_memset(dbss->bssid, 0, ETH_ALEN);
1713 : 0 : drv->associated = 0;
1714 : 0 : wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL);
1715 : 0 : return wpa_driver_test_send_disassoc(drv);
1716 : : }
1717 : :
1718 : :
1719 : 0 : static const u8 * wpa_scan_get_ie(const struct wpa_scan_res *res, u8 ie)
1720 : : {
1721 : : const u8 *end, *pos;
1722 : :
1723 : 0 : pos = (const u8 *) (res + 1);
1724 : 0 : end = pos + res->ie_len;
1725 : :
1726 [ # # ]: 0 : while (pos + 1 < end) {
1727 [ # # ]: 0 : if (pos + 2 + pos[1] > end)
1728 : 0 : break;
1729 [ # # ]: 0 : if (pos[0] == ie)
1730 : 0 : return pos;
1731 : 0 : pos += 2 + pos[1];
1732 : : }
1733 : :
1734 : 0 : return NULL;
1735 : : }
1736 : :
1737 : :
1738 : 0 : static void wpa_driver_test_scanresp(struct wpa_driver_test_data *drv,
1739 : : struct sockaddr *from,
1740 : : socklen_t fromlen,
1741 : : const char *data)
1742 : : {
1743 : : struct wpa_scan_res *res;
1744 : : const char *pos, *pos2;
1745 : : size_t len;
1746 : : u8 *ie_pos, *ie_start, *ie_end;
1747 : : #define MAX_IE_LEN 1000
1748 : : const u8 *ds_params;
1749 : :
1750 : 0 : wpa_printf(MSG_DEBUG, "test_driver: SCANRESP %s", data);
1751 [ # # ]: 0 : if (drv->num_scanres >= MAX_SCAN_RESULTS) {
1752 : 0 : wpa_printf(MSG_DEBUG, "test_driver: No room for the new scan "
1753 : : "result");
1754 : 0 : return;
1755 : : }
1756 : :
1757 : : /* SCANRESP BSSID SSID IEs */
1758 : :
1759 : 0 : res = os_zalloc(sizeof(*res) + MAX_IE_LEN);
1760 [ # # ]: 0 : if (res == NULL)
1761 : 0 : return;
1762 : 0 : ie_start = ie_pos = (u8 *) (res + 1);
1763 : 0 : ie_end = ie_pos + MAX_IE_LEN;
1764 : :
1765 [ # # ]: 0 : if (hwaddr_aton(data, res->bssid)) {
1766 : 0 : wpa_printf(MSG_DEBUG, "test_driver: invalid BSSID in scanres");
1767 : 0 : os_free(res);
1768 : 0 : return;
1769 : : }
1770 : :
1771 : 0 : pos = data + 17;
1772 [ # # ]: 0 : while (*pos == ' ')
1773 : 0 : pos++;
1774 : 0 : pos2 = os_strchr(pos, ' ');
1775 [ # # ]: 0 : if (pos2 == NULL) {
1776 : 0 : wpa_printf(MSG_DEBUG, "test_driver: invalid SSID termination "
1777 : : "in scanres");
1778 : 0 : os_free(res);
1779 : 0 : return;
1780 : : }
1781 : 0 : len = (pos2 - pos) / 2;
1782 [ # # ]: 0 : if (len > 32)
1783 : 0 : len = 32;
1784 : : /*
1785 : : * Generate SSID IE from the SSID field since this IE is not included
1786 : : * in the main IE field.
1787 : : */
1788 : 0 : *ie_pos++ = WLAN_EID_SSID;
1789 : 0 : *ie_pos++ = len;
1790 [ # # ]: 0 : if (hexstr2bin(pos, ie_pos, len) < 0) {
1791 : 0 : wpa_printf(MSG_DEBUG, "test_driver: invalid SSID in scanres");
1792 : 0 : os_free(res);
1793 : 0 : return;
1794 : : }
1795 : 0 : ie_pos += len;
1796 : :
1797 : 0 : pos = pos2 + 1;
1798 : 0 : pos2 = os_strchr(pos, ' ');
1799 [ # # ]: 0 : if (pos2 == NULL)
1800 : 0 : len = os_strlen(pos) / 2;
1801 : : else
1802 : 0 : len = (pos2 - pos) / 2;
1803 [ # # ]: 0 : if ((int) len > ie_end - ie_pos)
1804 : 0 : len = ie_end - ie_pos;
1805 [ # # ]: 0 : if (hexstr2bin(pos, ie_pos, len) < 0) {
1806 : 0 : wpa_printf(MSG_DEBUG, "test_driver: invalid IEs in scanres");
1807 : 0 : os_free(res);
1808 : 0 : return;
1809 : : }
1810 : 0 : ie_pos += len;
1811 : 0 : res->ie_len = ie_pos - ie_start;
1812 : :
1813 [ # # ]: 0 : if (pos2) {
1814 : 0 : pos = pos2 + 1;
1815 [ # # ]: 0 : while (*pos == ' ')
1816 : 0 : pos++;
1817 [ # # ]: 0 : if (os_strstr(pos, "PRIVACY"))
1818 : 0 : res->caps |= IEEE80211_CAP_PRIVACY;
1819 [ # # ]: 0 : if (os_strstr(pos, "IBSS"))
1820 : 0 : res->caps |= IEEE80211_CAP_IBSS;
1821 : : }
1822 : :
1823 : 0 : ds_params = wpa_scan_get_ie(res, WLAN_EID_DS_PARAMS);
1824 [ # # ][ # # ]: 0 : if (ds_params && ds_params[1] > 0) {
1825 [ # # ][ # # ]: 0 : if (ds_params[2] >= 1 && ds_params[2] <= 13)
1826 : 0 : res->freq = 2407 + ds_params[2] * 5;
1827 : : }
1828 : :
1829 : 0 : os_free(drv->scanres[drv->num_scanres]);
1830 : 0 : drv->scanres[drv->num_scanres++] = res;
1831 : : }
1832 : :
1833 : :
1834 : 0 : static void wpa_driver_test_assocresp(struct wpa_driver_test_data *drv,
1835 : : struct sockaddr *from,
1836 : : socklen_t fromlen,
1837 : : const char *data)
1838 : : {
1839 : : struct test_driver_bss *bss;
1840 : :
1841 [ # # ]: 0 : bss = dl_list_first(&drv->bss, struct test_driver_bss, list);
1842 : :
1843 : : /* ASSOCRESP BSSID <res> */
1844 [ # # ]: 0 : if (hwaddr_aton(data, bss->bssid)) {
1845 : 0 : wpa_printf(MSG_DEBUG, "test_driver: invalid BSSID in "
1846 : : "assocresp");
1847 : : }
1848 [ # # ]: 0 : if (drv->use_associnfo) {
1849 : : union wpa_event_data event;
1850 : 0 : os_memset(&event, 0, sizeof(event));
1851 : 0 : event.assoc_info.req_ies = drv->assoc_wpa_ie;
1852 : 0 : event.assoc_info.req_ies_len = drv->assoc_wpa_ie_len;
1853 : 0 : wpa_supplicant_event(drv->ctx, EVENT_ASSOCINFO, &event);
1854 : : }
1855 : 0 : drv->associated = 1;
1856 : 0 : wpa_supplicant_event(drv->ctx, EVENT_ASSOC, NULL);
1857 : 0 : }
1858 : :
1859 : :
1860 : 0 : static void wpa_driver_test_disassoc(struct wpa_driver_test_data *drv,
1861 : : struct sockaddr *from,
1862 : : socklen_t fromlen)
1863 : : {
1864 : 0 : drv->associated = 0;
1865 : 0 : wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL);
1866 : 0 : }
1867 : :
1868 : :
1869 : 0 : static void wpa_driver_test_eapol(struct wpa_driver_test_data *drv,
1870 : : struct sockaddr *from,
1871 : : socklen_t fromlen,
1872 : : const u8 *data, size_t data_len)
1873 : : {
1874 : : const u8 *src;
1875 : : struct test_driver_bss *bss;
1876 : :
1877 [ # # ]: 0 : bss = dl_list_first(&drv->bss, struct test_driver_bss, list);
1878 : :
1879 [ # # ]: 0 : if (data_len > 14) {
1880 : : /* Skip Ethernet header */
1881 : 0 : src = data + ETH_ALEN;
1882 : 0 : data += 14;
1883 : 0 : data_len -= 14;
1884 : : } else
1885 : 0 : src = bss->bssid;
1886 : :
1887 : 0 : drv_event_eapol_rx(drv->ctx, src, data, data_len);
1888 : 0 : }
1889 : :
1890 : :
1891 : 0 : static void wpa_driver_test_mlme(struct wpa_driver_test_data *drv,
1892 : : struct sockaddr *from,
1893 : : socklen_t fromlen,
1894 : : const u8 *data, size_t data_len)
1895 : : {
1896 : 0 : int freq = 0, own_freq;
1897 : : union wpa_event_data event;
1898 : : const struct ieee80211_mgmt *mgmt;
1899 : : u16 fc;
1900 : : struct test_driver_bss *bss;
1901 : :
1902 [ # # ]: 0 : bss = dl_list_first(&drv->bss, struct test_driver_bss, list);
1903 [ # # ][ # # ]: 0 : if (data_len > 6 && os_memcmp(data, "freq=", 5) == 0) {
1904 : : size_t pos;
1905 [ # # ]: 0 : for (pos = 5; pos < data_len; pos++) {
1906 [ # # ]: 0 : if (data[pos] == ' ')
1907 : 0 : break;
1908 : : }
1909 [ # # ]: 0 : if (pos < data_len) {
1910 : 0 : freq = atoi((const char *) &data[5]);
1911 : 0 : wpa_printf(MSG_DEBUG, "test_driver(%s): MLME RX on "
1912 : 0 : "freq %d MHz", bss->ifname, freq);
1913 : 0 : pos++;
1914 : 0 : data += pos;
1915 : 0 : data_len -= pos;
1916 : : }
1917 : : }
1918 : :
1919 [ # # ]: 0 : if (drv->remain_on_channel_freq)
1920 : 0 : own_freq = drv->remain_on_channel_freq;
1921 : : else
1922 : 0 : own_freq = drv->current_freq;
1923 : :
1924 [ # # ][ # # ]: 0 : if (freq && own_freq && freq != own_freq) {
[ # # ]
1925 : 0 : wpa_printf(MSG_DEBUG, "test_driver(%s): Ignore MLME RX on "
1926 : : "another frequency %d MHz (own %d MHz)",
1927 : 0 : bss->ifname, freq, own_freq);
1928 : 0 : return;
1929 : : }
1930 : :
1931 : 0 : os_memset(&event, 0, sizeof(event));
1932 : 0 : event.mlme_rx.buf = data;
1933 : 0 : event.mlme_rx.len = data_len;
1934 : 0 : event.mlme_rx.freq = freq;
1935 : 0 : wpa_supplicant_event(drv->ctx, EVENT_MLME_RX, &event);
1936 : :
1937 : 0 : mgmt = (const struct ieee80211_mgmt *) data;
1938 : 0 : fc = le_to_host16(mgmt->frame_control);
1939 : :
1940 [ # # ][ # # ]: 0 : if (drv->probe_req_report && data_len >= 24) {
1941 [ # # ][ # # ]: 0 : if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
1942 : 0 : WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_PROBE_REQ) {
1943 : 0 : os_memset(&event, 0, sizeof(event));
1944 : 0 : event.rx_probe_req.sa = mgmt->sa;
1945 : 0 : event.rx_probe_req.da = mgmt->da;
1946 : 0 : event.rx_probe_req.bssid = mgmt->bssid;
1947 : 0 : event.rx_probe_req.ie = mgmt->u.probe_req.variable;
1948 : 0 : event.rx_probe_req.ie_len =
1949 : 0 : data_len - (mgmt->u.probe_req.variable - data);
1950 : 0 : wpa_supplicant_event(drv->ctx, EVENT_RX_PROBE_REQ,
1951 : : &event);
1952 : : #ifdef CONFIG_P2P
1953 : : if (drv->p2p)
1954 : : p2p_probe_req_rx(drv->p2p, mgmt->sa,
1955 : : mgmt->da, mgmt->bssid,
1956 : : event.rx_probe_req.ie,
1957 : : event.rx_probe_req.ie_len);
1958 : : #endif /* CONFIG_P2P */
1959 : : }
1960 : : }
1961 : :
1962 : : #ifdef CONFIG_P2P
1963 : : if (drv->p2p &&
1964 : : WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
1965 : : WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_ACTION) {
1966 : : size_t hdr_len;
1967 : : hdr_len = (const u8 *)
1968 : : &mgmt->u.action.u.vs_public_action.action - data;
1969 : : p2p_rx_action(drv->p2p, mgmt->da, mgmt->sa, mgmt->bssid,
1970 : : mgmt->u.action.category,
1971 : : &mgmt->u.action.u.vs_public_action.action,
1972 : : data_len - hdr_len, freq);
1973 : : }
1974 : : #endif /* CONFIG_P2P */
1975 : :
1976 : : }
1977 : :
1978 : :
1979 : 0 : static void wpa_driver_test_scan_cmd(struct wpa_driver_test_data *drv,
1980 : : struct sockaddr *from,
1981 : : socklen_t fromlen,
1982 : : const u8 *data, size_t data_len)
1983 : : {
1984 : : char buf[512], *pos, *end;
1985 : : int ret;
1986 : : struct test_driver_bss *bss;
1987 : :
1988 [ # # ]: 0 : bss = dl_list_first(&drv->bss, struct test_driver_bss, list);
1989 : :
1990 : : /* data: optional [ STA-addr | ' ' | IEs(hex) ] */
1991 : : #ifdef CONFIG_P2P
1992 : : if (drv->probe_req_report && drv->p2p && data_len) {
1993 : : const char *d = (const char *) data;
1994 : : u8 sa[ETH_ALEN];
1995 : : u8 ie[512];
1996 : : size_t ielen;
1997 : :
1998 : : if (hwaddr_aton(d, sa))
1999 : : return;
2000 : : d += 18;
2001 : : while (*d == ' ')
2002 : : d++;
2003 : : ielen = os_strlen(d) / 2;
2004 : : if (ielen > sizeof(ie))
2005 : : ielen = sizeof(ie);
2006 : : if (hexstr2bin(d, ie, ielen) < 0)
2007 : : ielen = 0;
2008 : : drv->probe_from = from;
2009 : : drv->probe_from_len = fromlen;
2010 : : p2p_probe_req_rx(drv->p2p, sa, NULL, NULL, ie, ielen);
2011 : : drv->probe_from = NULL;
2012 : : }
2013 : : #endif /* CONFIG_P2P */
2014 : :
2015 [ # # ]: 0 : if (!drv->ibss)
2016 : 0 : return;
2017 : :
2018 : 0 : pos = buf;
2019 : 0 : end = buf + sizeof(buf);
2020 : :
2021 : : /* reply: SCANRESP BSSID SSID IEs */
2022 : 0 : ret = snprintf(pos, end - pos, "SCANRESP " MACSTR " ",
2023 : 0 : MAC2STR(bss->bssid));
2024 [ # # ][ # # ]: 0 : if (ret < 0 || ret >= end - pos)
2025 : 0 : return;
2026 : 0 : pos += ret;
2027 : 0 : pos += wpa_snprintf_hex(pos, end - pos,
2028 : 0 : bss->ssid, bss->ssid_len);
2029 : 0 : ret = snprintf(pos, end - pos, " ");
2030 [ # # ][ # # ]: 0 : if (ret < 0 || ret >= end - pos)
2031 : 0 : return;
2032 : 0 : pos += ret;
2033 : 0 : pos += wpa_snprintf_hex(pos, end - pos, drv->assoc_wpa_ie,
2034 : : drv->assoc_wpa_ie_len);
2035 : :
2036 [ # # ]: 0 : if (bss->privacy) {
2037 : 0 : ret = snprintf(pos, end - pos, " PRIVACY");
2038 [ # # ][ # # ]: 0 : if (ret < 0 || ret >= end - pos)
2039 : 0 : return;
2040 : 0 : pos += ret;
2041 : : }
2042 : :
2043 : 0 : ret = snprintf(pos, end - pos, " IBSS");
2044 [ # # ][ # # ]: 0 : if (ret < 0 || ret >= end - pos)
2045 : 0 : return;
2046 : 0 : pos += ret;
2047 : :
2048 : 0 : sendto(drv->test_socket, buf, pos - buf, 0,
2049 : : (struct sockaddr *) from, fromlen);
2050 : : }
2051 : :
2052 : :
2053 : 0 : static void wpa_driver_test_receive_unix(int sock, void *eloop_ctx,
2054 : : void *sock_ctx)
2055 : : {
2056 : 0 : struct wpa_driver_test_data *drv = eloop_ctx;
2057 : : char *buf;
2058 : : int res;
2059 : : struct sockaddr_storage from;
2060 : 0 : socklen_t fromlen = sizeof(from);
2061 : 0 : const size_t buflen = 2000;
2062 : :
2063 [ # # ]: 0 : if (drv->ap) {
2064 : 0 : test_driver_receive_unix(sock, eloop_ctx, sock_ctx);
2065 : 0 : return;
2066 : : }
2067 : :
2068 : 0 : buf = os_malloc(buflen);
2069 [ # # ]: 0 : if (buf == NULL)
2070 : 0 : return;
2071 : 0 : res = recvfrom(sock, buf, buflen - 1, 0,
2072 : : (struct sockaddr *) &from, &fromlen);
2073 [ # # ]: 0 : if (res < 0) {
2074 : 0 : perror("recvfrom(test_socket)");
2075 : 0 : os_free(buf);
2076 : 0 : return;
2077 : : }
2078 : 0 : buf[res] = '\0';
2079 : :
2080 : 0 : wpa_printf(MSG_DEBUG, "test_driver: received %u bytes", res);
2081 : :
2082 [ # # ]: 0 : if (os_strncmp(buf, "SCANRESP ", 9) == 0) {
2083 : 0 : wpa_driver_test_scanresp(drv, (struct sockaddr *) &from,
2084 : : fromlen, buf + 9);
2085 [ # # ]: 0 : } else if (os_strncmp(buf, "ASSOCRESP ", 10) == 0) {
2086 : 0 : wpa_driver_test_assocresp(drv, (struct sockaddr *) &from,
2087 : : fromlen, buf + 10);
2088 [ # # ]: 0 : } else if (os_strcmp(buf, "DISASSOC") == 0) {
2089 : 0 : wpa_driver_test_disassoc(drv, (struct sockaddr *) &from,
2090 : : fromlen);
2091 [ # # ]: 0 : } else if (os_strcmp(buf, "DEAUTH") == 0) {
2092 : 0 : wpa_driver_test_disassoc(drv, (struct sockaddr *) &from,
2093 : : fromlen);
2094 [ # # ]: 0 : } else if (os_strncmp(buf, "EAPOL ", 6) == 0) {
2095 : 0 : wpa_driver_test_eapol(drv, (struct sockaddr *) &from, fromlen,
2096 : 0 : (const u8 *) buf + 6, res - 6);
2097 [ # # ]: 0 : } else if (os_strncmp(buf, "MLME ", 5) == 0) {
2098 : 0 : wpa_driver_test_mlme(drv, (struct sockaddr *) &from, fromlen,
2099 : 0 : (const u8 *) buf + 5, res - 5);
2100 [ # # ]: 0 : } else if (os_strncmp(buf, "SCAN ", 5) == 0) {
2101 : 0 : wpa_driver_test_scan_cmd(drv, (struct sockaddr *) &from,
2102 : : fromlen,
2103 : 0 : (const u8 *) buf + 5, res - 5);
2104 : : } else {
2105 : 0 : wpa_hexdump_ascii(MSG_DEBUG, "Unknown test_socket command",
2106 : : (u8 *) buf, res);
2107 : : }
2108 : 0 : os_free(buf);
2109 : : }
2110 : :
2111 : :
2112 : 0 : static void * wpa_driver_test_init2(void *ctx, const char *ifname,
2113 : : void *global_priv)
2114 : : {
2115 : : struct wpa_driver_test_data *drv;
2116 : 0 : struct wpa_driver_test_global *global = global_priv;
2117 : : struct test_driver_bss *bss;
2118 : :
2119 : 0 : drv = test_alloc_data(ctx, ifname);
2120 [ # # ]: 0 : if (drv == NULL)
2121 : 0 : return NULL;
2122 [ # # ]: 0 : bss = dl_list_first(&drv->bss, struct test_driver_bss, list);
2123 : 0 : drv->global = global_priv;
2124 : 0 : drv->test_socket = -1;
2125 : :
2126 : : /* Set dummy BSSID and SSID for testing. */
2127 : 0 : bss->bssid[0] = 0x02;
2128 : 0 : bss->bssid[1] = 0x00;
2129 : 0 : bss->bssid[2] = 0x00;
2130 : 0 : bss->bssid[3] = 0x00;
2131 : 0 : bss->bssid[4] = 0x00;
2132 : 0 : bss->bssid[5] = 0x01;
2133 : 0 : os_memcpy(bss->ssid, "test", 5);
2134 : 0 : bss->ssid_len = 4;
2135 : :
2136 [ # # ]: 0 : if (global->bss_add_used) {
2137 : 0 : os_memcpy(drv->own_addr, global->req_addr, ETH_ALEN);
2138 : 0 : global->bss_add_used = 0;
2139 : : }
2140 : :
2141 : 0 : eloop_register_timeout(1, 0, wpa_driver_test_poll, drv, NULL);
2142 : :
2143 : 0 : return bss;
2144 : : }
2145 : :
2146 : :
2147 : 0 : static void wpa_driver_test_close_test_socket(struct wpa_driver_test_data *drv)
2148 : : {
2149 [ # # ]: 0 : if (drv->test_socket >= 0) {
2150 : 0 : eloop_unregister_read_sock(drv->test_socket);
2151 : 0 : close(drv->test_socket);
2152 : 0 : drv->test_socket = -1;
2153 : : }
2154 : :
2155 [ # # ]: 0 : if (drv->own_socket_path) {
2156 : 0 : unlink(drv->own_socket_path);
2157 : 0 : os_free(drv->own_socket_path);
2158 : 0 : drv->own_socket_path = NULL;
2159 : : }
2160 : 0 : }
2161 : :
2162 : :
2163 : 0 : static void wpa_driver_test_deinit(void *priv)
2164 : : {
2165 : 0 : struct test_driver_bss *dbss = priv;
2166 : 0 : struct wpa_driver_test_data *drv = dbss->drv;
2167 : : struct test_client_socket *cli, *prev;
2168 : : int i;
2169 : :
2170 : : #ifdef CONFIG_P2P
2171 : : if (drv->p2p)
2172 : : p2p_deinit(drv->p2p);
2173 : : wpabuf_free(drv->pending_action_tx);
2174 : : #endif /* CONFIG_P2P */
2175 : :
2176 : 0 : cli = drv->cli;
2177 [ # # ]: 0 : while (cli) {
2178 : 0 : prev = cli;
2179 : 0 : cli = cli->next;
2180 : 0 : os_free(prev);
2181 : : }
2182 : :
2183 : : #ifdef HOSTAPD
2184 : : /* There should be only one BSS remaining at this point. */
2185 [ # # ]: 0 : if (dl_list_len(&drv->bss) != 1)
2186 : 0 : wpa_printf(MSG_ERROR, "%s: %u remaining BSS entries",
2187 : : __func__, dl_list_len(&drv->bss));
2188 : : #endif /* HOSTAPD */
2189 : :
2190 : 0 : test_driver_free_bsses(drv);
2191 : :
2192 : 0 : wpa_driver_test_close_test_socket(drv);
2193 : 0 : eloop_cancel_timeout(wpa_driver_test_scan_timeout, drv, drv->ctx);
2194 : 0 : eloop_cancel_timeout(wpa_driver_test_poll, drv, NULL);
2195 : 0 : eloop_cancel_timeout(test_remain_on_channel_timeout, drv, NULL);
2196 : 0 : os_free(drv->test_dir);
2197 [ # # ]: 0 : for (i = 0; i < MAX_SCAN_RESULTS; i++)
2198 : 0 : os_free(drv->scanres[i]);
2199 : 0 : os_free(drv->probe_req_ie);
2200 [ # # ]: 0 : wpa_trace_remove_ref(drv, ctx, drv->ctx);
2201 : 0 : os_free(drv);
2202 : 0 : }
2203 : :
2204 : :
2205 : 0 : static int wpa_driver_test_attach(struct wpa_driver_test_data *drv,
2206 : : const char *dir, int ap)
2207 : : {
2208 : : #ifdef DRIVER_TEST_UNIX
2209 : : static unsigned int counter = 0;
2210 : : struct sockaddr_un addr;
2211 : : size_t len;
2212 : :
2213 : 0 : os_free(drv->own_socket_path);
2214 [ # # ]: 0 : if (dir) {
2215 : 0 : len = os_strlen(dir) + 30;
2216 : 0 : drv->own_socket_path = os_malloc(len);
2217 [ # # ]: 0 : if (drv->own_socket_path == NULL)
2218 : 0 : return -1;
2219 [ # # ]: 0 : os_snprintf(drv->own_socket_path, len, "%s/%s-" MACSTR,
2220 : 0 : dir, ap ? "AP" : "STA", MAC2STR(drv->own_addr));
2221 : : } else {
2222 : 0 : drv->own_socket_path = os_malloc(100);
2223 [ # # ]: 0 : if (drv->own_socket_path == NULL)
2224 : 0 : return -1;
2225 : 0 : os_snprintf(drv->own_socket_path, 100,
2226 : : "/tmp/wpa_supplicant_test-%d-%d",
2227 : : getpid(), counter++);
2228 : : }
2229 : :
2230 : 0 : drv->test_socket = socket(PF_UNIX, SOCK_DGRAM, 0);
2231 [ # # ]: 0 : if (drv->test_socket < 0) {
2232 : 0 : perror("socket(PF_UNIX)");
2233 : 0 : os_free(drv->own_socket_path);
2234 : 0 : drv->own_socket_path = NULL;
2235 : 0 : return -1;
2236 : : }
2237 : :
2238 : 0 : os_memset(&addr, 0, sizeof(addr));
2239 : 0 : addr.sun_family = AF_UNIX;
2240 : 0 : os_strlcpy(addr.sun_path, drv->own_socket_path, sizeof(addr.sun_path));
2241 [ # # ]: 0 : if (bind(drv->test_socket, (struct sockaddr *) &addr,
2242 : : sizeof(addr)) < 0) {
2243 : 0 : perror("test-driver-attach: bind(PF_UNIX)");
2244 : 0 : close(drv->test_socket);
2245 : 0 : unlink(drv->own_socket_path);
2246 : 0 : os_free(drv->own_socket_path);
2247 : 0 : drv->own_socket_path = NULL;
2248 : 0 : return -1;
2249 : : }
2250 : :
2251 : 0 : eloop_register_read_sock(drv->test_socket,
2252 : : wpa_driver_test_receive_unix, drv, NULL);
2253 : :
2254 : 0 : return 0;
2255 : : #else /* DRIVER_TEST_UNIX */
2256 : : return -1;
2257 : : #endif /* DRIVER_TEST_UNIX */
2258 : : }
2259 : :
2260 : :
2261 : 0 : static int wpa_driver_test_attach_udp(struct wpa_driver_test_data *drv,
2262 : : char *dst)
2263 : : {
2264 : : char *pos;
2265 : :
2266 : 0 : pos = os_strchr(dst, ':');
2267 [ # # ]: 0 : if (pos == NULL)
2268 : 0 : return -1;
2269 : 0 : *pos++ = '\0';
2270 : 0 : wpa_printf(MSG_DEBUG, "%s: addr=%s port=%s", __func__, dst, pos);
2271 : :
2272 : 0 : drv->test_socket = socket(PF_INET, SOCK_DGRAM, 0);
2273 [ # # ]: 0 : if (drv->test_socket < 0) {
2274 : 0 : perror("socket(PF_INET)");
2275 : 0 : return -1;
2276 : : }
2277 : :
2278 : 0 : os_memset(&drv->hostapd_addr_udp, 0, sizeof(drv->hostapd_addr_udp));
2279 : 0 : drv->hostapd_addr_udp.sin_family = AF_INET;
2280 : : #if defined(CONFIG_NATIVE_WINDOWS) || defined(CONFIG_ANSI_C_EXTRA)
2281 : : {
2282 : : int a[4];
2283 : : u8 *pos;
2284 : : sscanf(dst, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]);
2285 : : pos = (u8 *) &drv->hostapd_addr_udp.sin_addr;
2286 : : *pos++ = a[0];
2287 : : *pos++ = a[1];
2288 : : *pos++ = a[2];
2289 : : *pos++ = a[3];
2290 : : }
2291 : : #else /* CONFIG_NATIVE_WINDOWS or CONFIG_ANSI_C_EXTRA */
2292 : 0 : inet_aton(dst, &drv->hostapd_addr_udp.sin_addr);
2293 : : #endif /* CONFIG_NATIVE_WINDOWS or CONFIG_ANSI_C_EXTRA */
2294 : 0 : drv->hostapd_addr_udp.sin_port = htons(atoi(pos));
2295 : :
2296 : 0 : drv->hostapd_addr_udp_set = 1;
2297 : :
2298 : 0 : eloop_register_read_sock(drv->test_socket,
2299 : : wpa_driver_test_receive_unix, drv, NULL);
2300 : :
2301 : 0 : return 0;
2302 : : }
2303 : :
2304 : :
2305 : 0 : static int wpa_driver_test_set_param(void *priv, const char *param)
2306 : : {
2307 : 0 : struct test_driver_bss *dbss = priv;
2308 : 0 : struct wpa_driver_test_data *drv = dbss->drv;
2309 : : const char *pos;
2310 : :
2311 : 0 : wpa_printf(MSG_DEBUG, "%s: param='%s'", __func__, param);
2312 [ # # ]: 0 : if (param == NULL)
2313 : 0 : return 0;
2314 : :
2315 : 0 : wpa_driver_test_close_test_socket(drv);
2316 : :
2317 : : #ifdef DRIVER_TEST_UNIX
2318 : 0 : pos = os_strstr(param, "test_socket=");
2319 [ # # ]: 0 : if (pos) {
2320 : : const char *pos2;
2321 : : size_t len;
2322 : :
2323 : 0 : pos += 12;
2324 : 0 : pos2 = os_strchr(pos, ' ');
2325 [ # # ]: 0 : if (pos2)
2326 : 0 : len = pos2 - pos;
2327 : : else
2328 : 0 : len = os_strlen(pos);
2329 [ # # ]: 0 : if (len > sizeof(drv->hostapd_addr.sun_path))
2330 : 0 : return -1;
2331 : 0 : os_memset(&drv->hostapd_addr, 0, sizeof(drv->hostapd_addr));
2332 : 0 : drv->hostapd_addr.sun_family = AF_UNIX;
2333 : 0 : os_memcpy(drv->hostapd_addr.sun_path, pos, len);
2334 : 0 : drv->hostapd_addr_set = 1;
2335 : : }
2336 : : #endif /* DRIVER_TEST_UNIX */
2337 : :
2338 : 0 : pos = os_strstr(param, "test_dir=");
2339 [ # # ]: 0 : if (pos) {
2340 : : char *end;
2341 : 0 : os_free(drv->test_dir);
2342 : 0 : drv->test_dir = os_strdup(pos + 9);
2343 [ # # ]: 0 : if (drv->test_dir == NULL)
2344 : 0 : return -1;
2345 : 0 : end = os_strchr(drv->test_dir, ' ');
2346 [ # # ]: 0 : if (end)
2347 : 0 : *end = '\0';
2348 [ # # ]: 0 : if (wpa_driver_test_attach(drv, drv->test_dir, 0))
2349 : 0 : return -1;
2350 : : } else {
2351 : 0 : pos = os_strstr(param, "test_udp=");
2352 [ # # ]: 0 : if (pos) {
2353 : : char *dst, *epos;
2354 : 0 : dst = os_strdup(pos + 9);
2355 [ # # ]: 0 : if (dst == NULL)
2356 : 0 : return -1;
2357 : 0 : epos = os_strchr(dst, ' ');
2358 [ # # ]: 0 : if (epos)
2359 : 0 : *epos = '\0';
2360 [ # # ]: 0 : if (wpa_driver_test_attach_udp(drv, dst))
2361 : 0 : return -1;
2362 : 0 : os_free(dst);
2363 [ # # ]: 0 : } else if (wpa_driver_test_attach(drv, NULL, 0))
2364 : 0 : return -1;
2365 : : }
2366 : :
2367 [ # # ]: 0 : if (os_strstr(param, "use_associnfo=1")) {
2368 : 0 : wpa_printf(MSG_DEBUG, "test_driver: Use AssocInfo events");
2369 : 0 : drv->use_associnfo = 1;
2370 : : }
2371 : :
2372 [ # # ]: 0 : if (os_strstr(param, "p2p_mgmt=1")) {
2373 : 0 : wpa_printf(MSG_DEBUG, "test_driver: Use internal P2P "
2374 : : "management");
2375 [ # # ]: 0 : if (wpa_driver_test_init_p2p(drv) < 0)
2376 : 0 : return -1;
2377 : : }
2378 : :
2379 : 0 : return 0;
2380 : : }
2381 : :
2382 : :
2383 : 0 : static const u8 * wpa_driver_test_get_mac_addr(void *priv)
2384 : : {
2385 : 0 : struct test_driver_bss *dbss = priv;
2386 : 0 : struct wpa_driver_test_data *drv = dbss->drv;
2387 : 0 : wpa_printf(MSG_DEBUG, "%s", __func__);
2388 : 0 : return drv->own_addr;
2389 : : }
2390 : :
2391 : :
2392 : 0 : static int wpa_driver_test_send_eapol(void *priv, const u8 *dest, u16 proto,
2393 : : const u8 *data, size_t data_len)
2394 : : {
2395 : 0 : struct test_driver_bss *dbss = priv;
2396 : 0 : struct wpa_driver_test_data *drv = dbss->drv;
2397 : : char *msg;
2398 : : size_t msg_len;
2399 : : struct l2_ethhdr eth;
2400 : : struct sockaddr *addr;
2401 : : socklen_t alen;
2402 : : #ifdef DRIVER_TEST_UNIX
2403 : : struct sockaddr_un addr_un;
2404 : : #endif /* DRIVER_TEST_UNIX */
2405 : :
2406 : 0 : wpa_hexdump(MSG_MSGDUMP, "test_send_eapol TX frame", data, data_len);
2407 : :
2408 : 0 : os_memset(ð, 0, sizeof(eth));
2409 : 0 : os_memcpy(eth.h_dest, dest, ETH_ALEN);
2410 : 0 : os_memcpy(eth.h_source, drv->own_addr, ETH_ALEN);
2411 : 0 : eth.h_proto = host_to_be16(proto);
2412 : :
2413 : 0 : msg_len = 6 + sizeof(eth) + data_len;
2414 : 0 : msg = os_malloc(msg_len);
2415 [ # # ]: 0 : if (msg == NULL)
2416 : 0 : return -1;
2417 : 0 : os_memcpy(msg, "EAPOL ", 6);
2418 : 0 : os_memcpy(msg + 6, ð, sizeof(eth));
2419 : 0 : os_memcpy(msg + 6 + sizeof(eth), data, data_len);
2420 : :
2421 [ # # ][ # # ]: 0 : if (os_memcmp(dest, dbss->bssid, ETH_ALEN) == 0 ||
2422 : 0 : drv->test_dir == NULL) {
2423 [ # # ]: 0 : if (drv->hostapd_addr_udp_set) {
2424 : 0 : addr = (struct sockaddr *) &drv->hostapd_addr_udp;
2425 : 0 : alen = sizeof(drv->hostapd_addr_udp);
2426 : : } else {
2427 : : #ifdef DRIVER_TEST_UNIX
2428 : 0 : addr = (struct sockaddr *) &drv->hostapd_addr;
2429 : 0 : alen = sizeof(drv->hostapd_addr);
2430 : : #else /* DRIVER_TEST_UNIX */
2431 : : os_free(msg);
2432 : : return -1;
2433 : : #endif /* DRIVER_TEST_UNIX */
2434 : : }
2435 : : } else {
2436 : : #ifdef DRIVER_TEST_UNIX
2437 : : struct stat st;
2438 : 0 : os_memset(&addr_un, 0, sizeof(addr_un));
2439 : 0 : addr_un.sun_family = AF_UNIX;
2440 : 0 : os_snprintf(addr_un.sun_path, sizeof(addr_un.sun_path),
2441 : 0 : "%s/STA-" MACSTR, drv->test_dir, MAC2STR(dest));
2442 [ # # ]: 0 : if (stat(addr_un.sun_path, &st) < 0) {
2443 : 0 : os_snprintf(addr_un.sun_path, sizeof(addr_un.sun_path),
2444 : : "%s/AP-" MACSTR,
2445 : 0 : drv->test_dir, MAC2STR(dest));
2446 : : }
2447 : 0 : addr = (struct sockaddr *) &addr_un;
2448 : 0 : alen = sizeof(addr_un);
2449 : : #else /* DRIVER_TEST_UNIX */
2450 : : os_free(msg);
2451 : : return -1;
2452 : : #endif /* DRIVER_TEST_UNIX */
2453 : : }
2454 : :
2455 [ # # ]: 0 : if (sendto(drv->test_socket, msg, msg_len, 0, addr, alen) < 0) {
2456 : 0 : perror("sendmsg(test_socket)");
2457 : 0 : os_free(msg);
2458 : 0 : return -1;
2459 : : }
2460 : :
2461 : 0 : os_free(msg);
2462 : 0 : return 0;
2463 : : }
2464 : :
2465 : :
2466 : 0 : static int wpa_driver_test_get_capa(void *priv, struct wpa_driver_capa *capa)
2467 : : {
2468 : 0 : struct test_driver_bss *dbss = priv;
2469 : 0 : struct wpa_driver_test_data *drv = dbss->drv;
2470 : 0 : os_memset(capa, 0, sizeof(*capa));
2471 : 0 : capa->key_mgmt = WPA_DRIVER_CAPA_KEY_MGMT_WPA |
2472 : : WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
2473 : : WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
2474 : : WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK |
2475 : : WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE |
2476 : : WPA_DRIVER_CAPA_KEY_MGMT_FT |
2477 : : WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK;
2478 : 0 : capa->enc = WPA_DRIVER_CAPA_ENC_WEP40 |
2479 : : WPA_DRIVER_CAPA_ENC_WEP104 |
2480 : : WPA_DRIVER_CAPA_ENC_TKIP |
2481 : : WPA_DRIVER_CAPA_ENC_CCMP;
2482 : 0 : capa->auth = WPA_DRIVER_AUTH_OPEN |
2483 : : WPA_DRIVER_AUTH_SHARED |
2484 : : WPA_DRIVER_AUTH_LEAP;
2485 [ # # ]: 0 : if (drv->p2p)
2486 : 0 : capa->flags |= WPA_DRIVER_FLAGS_P2P_MGMT;
2487 : 0 : capa->flags |= WPA_DRIVER_FLAGS_AP;
2488 : 0 : capa->flags |= WPA_DRIVER_FLAGS_P2P_CONCURRENT;
2489 : 0 : capa->flags |= WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE;
2490 : 0 : capa->flags |= WPA_DRIVER_FLAGS_P2P_CAPABLE;
2491 : 0 : capa->max_scan_ssids = 2;
2492 : 0 : capa->max_remain_on_chan = 60000;
2493 : :
2494 : 0 : return 0;
2495 : : }
2496 : :
2497 : :
2498 : 0 : static int wpa_driver_test_mlme_setprotection(void *priv, const u8 *addr,
2499 : : int protect_type,
2500 : : int key_type)
2501 : : {
2502 : 0 : wpa_printf(MSG_DEBUG, "%s: protect_type=%d key_type=%d",
2503 : : __func__, protect_type, key_type);
2504 : :
2505 [ # # ]: 0 : if (addr) {
2506 : 0 : wpa_printf(MSG_DEBUG, "%s: addr=" MACSTR,
2507 : 0 : __func__, MAC2STR(addr));
2508 : : }
2509 : :
2510 : 0 : return 0;
2511 : : }
2512 : :
2513 : :
2514 : 0 : static void * wpa_driver_test_global_init(void)
2515 : : {
2516 : : struct wpa_driver_test_global *global;
2517 : :
2518 : 0 : global = os_zalloc(sizeof(*global));
2519 : 0 : return global;
2520 : : }
2521 : :
2522 : :
2523 : 0 : static void wpa_driver_test_global_deinit(void *priv)
2524 : : {
2525 : 0 : struct wpa_driver_test_global *global = priv;
2526 : 0 : os_free(global);
2527 : 0 : }
2528 : :
2529 : :
2530 : : static struct wpa_interface_info *
2531 : 0 : wpa_driver_test_get_interfaces(void *global_priv)
2532 : : {
2533 : : /* struct wpa_driver_test_global *global = priv; */
2534 : : struct wpa_interface_info *iface;
2535 : :
2536 : 0 : iface = os_zalloc(sizeof(*iface));
2537 [ # # ]: 0 : if (iface == NULL)
2538 : 0 : return iface;
2539 : 0 : iface->ifname = os_strdup("sta0");
2540 : 0 : iface->desc = os_strdup("test interface 0");
2541 : 0 : iface->drv_name = "test";
2542 : 0 : iface->next = os_zalloc(sizeof(*iface));
2543 [ # # ]: 0 : if (iface->next) {
2544 : 0 : iface->next->ifname = os_strdup("sta1");
2545 : 0 : iface->next->desc = os_strdup("test interface 1");
2546 : 0 : iface->next->drv_name = "test";
2547 : : }
2548 : :
2549 : 0 : return iface;
2550 : : }
2551 : :
2552 : :
2553 : : static struct hostapd_hw_modes *
2554 : 0 : wpa_driver_test_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags)
2555 : : {
2556 : : struct hostapd_hw_modes *modes;
2557 : : size_t i;
2558 : :
2559 : 0 : *num_modes = 3;
2560 : 0 : *flags = 0;
2561 : 0 : modes = os_calloc(*num_modes, sizeof(struct hostapd_hw_modes));
2562 [ # # ]: 0 : if (modes == NULL)
2563 : 0 : return NULL;
2564 : 0 : modes[0].mode = HOSTAPD_MODE_IEEE80211G;
2565 : 0 : modes[0].num_channels = 11;
2566 : 0 : modes[0].num_rates = 12;
2567 : 0 : modes[0].channels = os_calloc(11, sizeof(struct hostapd_channel_data));
2568 : 0 : modes[0].rates = os_calloc(modes[0].num_rates, sizeof(int));
2569 [ # # ][ # # ]: 0 : if (modes[0].channels == NULL || modes[0].rates == NULL)
2570 : : goto fail;
2571 [ # # ]: 0 : for (i = 0; i < 11; i++) {
2572 : 0 : modes[0].channels[i].chan = i + 1;
2573 : 0 : modes[0].channels[i].freq = 2412 + 5 * i;
2574 : 0 : modes[0].channels[i].flag = 0;
2575 : : }
2576 : 0 : modes[0].rates[0] = 10;
2577 : 0 : modes[0].rates[1] = 20;
2578 : 0 : modes[0].rates[2] = 55;
2579 : 0 : modes[0].rates[3] = 110;
2580 : 0 : modes[0].rates[4] = 60;
2581 : 0 : modes[0].rates[5] = 90;
2582 : 0 : modes[0].rates[6] = 120;
2583 : 0 : modes[0].rates[7] = 180;
2584 : 0 : modes[0].rates[8] = 240;
2585 : 0 : modes[0].rates[9] = 360;
2586 : 0 : modes[0].rates[10] = 480;
2587 : 0 : modes[0].rates[11] = 540;
2588 : :
2589 : 0 : modes[1].mode = HOSTAPD_MODE_IEEE80211B;
2590 : 0 : modes[1].num_channels = 11;
2591 : 0 : modes[1].num_rates = 4;
2592 : 0 : modes[1].channels = os_calloc(11, sizeof(struct hostapd_channel_data));
2593 : 0 : modes[1].rates = os_calloc(modes[1].num_rates, sizeof(int));
2594 [ # # ][ # # ]: 0 : if (modes[1].channels == NULL || modes[1].rates == NULL)
2595 : : goto fail;
2596 [ # # ]: 0 : for (i = 0; i < 11; i++) {
2597 : 0 : modes[1].channels[i].chan = i + 1;
2598 : 0 : modes[1].channels[i].freq = 2412 + 5 * i;
2599 : 0 : modes[1].channels[i].flag = 0;
2600 : : }
2601 : 0 : modes[1].rates[0] = 10;
2602 : 0 : modes[1].rates[1] = 20;
2603 : 0 : modes[1].rates[2] = 55;
2604 : 0 : modes[1].rates[3] = 110;
2605 : :
2606 : 0 : modes[2].mode = HOSTAPD_MODE_IEEE80211A;
2607 : 0 : modes[2].num_channels = 1;
2608 : 0 : modes[2].num_rates = 8;
2609 : 0 : modes[2].channels = os_calloc(1, sizeof(struct hostapd_channel_data));
2610 : 0 : modes[2].rates = os_calloc(modes[2].num_rates, sizeof(int));
2611 [ # # ][ # # ]: 0 : if (modes[2].channels == NULL || modes[2].rates == NULL)
2612 : : goto fail;
2613 : 0 : modes[2].channels[0].chan = 60;
2614 : 0 : modes[2].channels[0].freq = 5300;
2615 : 0 : modes[2].channels[0].flag = 0;
2616 : 0 : modes[2].rates[0] = 60;
2617 : 0 : modes[2].rates[1] = 90;
2618 : 0 : modes[2].rates[2] = 120;
2619 : 0 : modes[2].rates[3] = 180;
2620 : 0 : modes[2].rates[4] = 240;
2621 : 0 : modes[2].rates[5] = 360;
2622 : 0 : modes[2].rates[6] = 480;
2623 : 0 : modes[2].rates[7] = 540;
2624 : :
2625 : 0 : return modes;
2626 : :
2627 : : fail:
2628 [ # # ]: 0 : if (modes) {
2629 [ # # ]: 0 : for (i = 0; i < *num_modes; i++) {
2630 : 0 : os_free(modes[i].channels);
2631 : 0 : os_free(modes[i].rates);
2632 : : }
2633 : 0 : os_free(modes);
2634 : : }
2635 : 0 : return NULL;
2636 : : }
2637 : :
2638 : :
2639 : 0 : static int wpa_driver_test_set_freq(void *priv,
2640 : : struct hostapd_freq_params *freq)
2641 : : {
2642 : 0 : struct test_driver_bss *dbss = priv;
2643 : 0 : struct wpa_driver_test_data *drv = dbss->drv;
2644 : 0 : wpa_printf(MSG_DEBUG, "test: set_freq %u MHz", freq->freq);
2645 : 0 : drv->current_freq = freq->freq;
2646 : 0 : return 0;
2647 : : }
2648 : :
2649 : :
2650 : 0 : static int wpa_driver_test_send_action(void *priv, unsigned int freq,
2651 : : unsigned int wait,
2652 : : const u8 *dst, const u8 *src,
2653 : : const u8 *bssid,
2654 : : const u8 *data, size_t data_len,
2655 : : int no_cck)
2656 : : {
2657 : 0 : struct test_driver_bss *dbss = priv;
2658 : 0 : struct wpa_driver_test_data *drv = dbss->drv;
2659 : 0 : int ret = -1;
2660 : : u8 *buf;
2661 : : struct ieee80211_hdr *hdr;
2662 : :
2663 : 0 : wpa_printf(MSG_DEBUG, "test: Send Action frame");
2664 : :
2665 [ # # ][ # # ]: 0 : if ((drv->remain_on_channel_freq &&
2666 [ # # ]: 0 : freq != drv->remain_on_channel_freq) ||
2667 [ # # ]: 0 : (drv->remain_on_channel_freq == 0 &&
2668 : 0 : freq != (unsigned int) drv->current_freq)) {
2669 : 0 : wpa_printf(MSG_DEBUG, "test: Reject Action frame TX on "
2670 : : "unexpected channel: freq=%u MHz (current_freq=%u "
2671 : : "MHz, remain-on-channel freq=%u MHz)",
2672 : : freq, drv->current_freq,
2673 : : drv->remain_on_channel_freq);
2674 : 0 : return -1;
2675 : : }
2676 : :
2677 : 0 : buf = os_zalloc(24 + data_len);
2678 [ # # ]: 0 : if (buf == NULL)
2679 : 0 : return ret;
2680 : 0 : os_memcpy(buf + 24, data, data_len);
2681 : 0 : hdr = (struct ieee80211_hdr *) buf;
2682 : 0 : hdr->frame_control =
2683 : : IEEE80211_FC(WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_ACTION);
2684 : 0 : os_memcpy(hdr->addr1, dst, ETH_ALEN);
2685 : 0 : os_memcpy(hdr->addr2, src, ETH_ALEN);
2686 : 0 : os_memcpy(hdr->addr3, bssid, ETH_ALEN);
2687 : :
2688 : 0 : ret = wpa_driver_test_send_mlme(priv, buf, 24 + data_len, 0);
2689 : 0 : os_free(buf);
2690 : 0 : return ret;
2691 : : }
2692 : :
2693 : :
2694 : : #ifdef CONFIG_P2P
2695 : : static void test_send_action_cb(void *eloop_ctx, void *timeout_ctx)
2696 : : {
2697 : : struct wpa_driver_test_data *drv = eloop_ctx;
2698 : :
2699 : : if (drv->pending_action_tx == NULL)
2700 : : return;
2701 : :
2702 : : if (drv->off_channel_freq != drv->pending_action_freq) {
2703 : : wpa_printf(MSG_DEBUG, "P2P: Pending Action frame TX "
2704 : : "waiting for another freq=%u",
2705 : : drv->pending_action_freq);
2706 : : return;
2707 : : }
2708 : : wpa_printf(MSG_DEBUG, "P2P: Sending pending Action frame to "
2709 : : MACSTR, MAC2STR(drv->pending_action_dst));
2710 : : wpa_driver_test_send_action(drv, drv->pending_action_freq, 0,
2711 : : drv->pending_action_dst,
2712 : : drv->pending_action_src,
2713 : : drv->pending_action_bssid,
2714 : : wpabuf_head(drv->pending_action_tx),
2715 : : wpabuf_len(drv->pending_action_tx),
2716 : : drv->pending_action_no_cck);
2717 : : }
2718 : : #endif /* CONFIG_P2P */
2719 : :
2720 : :
2721 : 0 : static void test_remain_on_channel_timeout(void *eloop_ctx, void *timeout_ctx)
2722 : : {
2723 : 0 : struct wpa_driver_test_data *drv = eloop_ctx;
2724 : : union wpa_event_data data;
2725 : :
2726 : 0 : wpa_printf(MSG_DEBUG, "test: Remain-on-channel timeout");
2727 : :
2728 : 0 : os_memset(&data, 0, sizeof(data));
2729 : 0 : data.remain_on_channel.freq = drv->remain_on_channel_freq;
2730 : 0 : data.remain_on_channel.duration = drv->remain_on_channel_duration;
2731 : :
2732 [ # # ]: 0 : if (drv->p2p)
2733 : 0 : drv->off_channel_freq = 0;
2734 : :
2735 : 0 : drv->remain_on_channel_freq = 0;
2736 : :
2737 : 0 : wpa_supplicant_event(drv->ctx, EVENT_CANCEL_REMAIN_ON_CHANNEL, &data);
2738 : 0 : }
2739 : :
2740 : :
2741 : 0 : static int wpa_driver_test_remain_on_channel(void *priv, unsigned int freq,
2742 : : unsigned int duration)
2743 : : {
2744 : 0 : struct test_driver_bss *dbss = priv;
2745 : 0 : struct wpa_driver_test_data *drv = dbss->drv;
2746 : : union wpa_event_data data;
2747 : :
2748 : 0 : wpa_printf(MSG_DEBUG, "%s(freq=%u, duration=%u)",
2749 : : __func__, freq, duration);
2750 [ # # ][ # # ]: 0 : if (drv->remain_on_channel_freq &&
2751 : 0 : drv->remain_on_channel_freq != freq) {
2752 : 0 : wpa_printf(MSG_DEBUG, "test: Refuse concurrent "
2753 : : "remain_on_channel request");
2754 : 0 : return -1;
2755 : : }
2756 : :
2757 : 0 : drv->remain_on_channel_freq = freq;
2758 : 0 : drv->remain_on_channel_duration = duration;
2759 : 0 : eloop_cancel_timeout(test_remain_on_channel_timeout, drv, NULL);
2760 : 0 : eloop_register_timeout(duration / 1000, (duration % 1000) * 1000,
2761 : : test_remain_on_channel_timeout, drv, NULL);
2762 : :
2763 : 0 : os_memset(&data, 0, sizeof(data));
2764 : 0 : data.remain_on_channel.freq = freq;
2765 : 0 : data.remain_on_channel.duration = duration;
2766 : 0 : wpa_supplicant_event(drv->ctx, EVENT_REMAIN_ON_CHANNEL, &data);
2767 : :
2768 : : #ifdef CONFIG_P2P
2769 : : if (drv->p2p) {
2770 : : drv->off_channel_freq = drv->remain_on_channel_freq;
2771 : : test_send_action_cb(drv, NULL);
2772 : : if (drv->off_channel_freq == drv->pending_listen_freq) {
2773 : : p2p_listen_cb(drv->p2p, drv->pending_listen_freq,
2774 : : drv->pending_listen_duration);
2775 : : drv->pending_listen_freq = 0;
2776 : : }
2777 : : }
2778 : : #endif /* CONFIG_P2P */
2779 : :
2780 : 0 : return 0;
2781 : : }
2782 : :
2783 : :
2784 : 0 : static int wpa_driver_test_cancel_remain_on_channel(void *priv)
2785 : : {
2786 : 0 : struct test_driver_bss *dbss = priv;
2787 : 0 : struct wpa_driver_test_data *drv = dbss->drv;
2788 : 0 : wpa_printf(MSG_DEBUG, "%s", __func__);
2789 [ # # ]: 0 : if (!drv->remain_on_channel_freq)
2790 : 0 : return -1;
2791 : 0 : drv->remain_on_channel_freq = 0;
2792 : 0 : eloop_cancel_timeout(test_remain_on_channel_timeout, drv, NULL);
2793 : 0 : return 0;
2794 : : }
2795 : :
2796 : :
2797 : 0 : static int wpa_driver_test_probe_req_report(void *priv, int report)
2798 : : {
2799 : 0 : struct test_driver_bss *dbss = priv;
2800 : 0 : struct wpa_driver_test_data *drv = dbss->drv;
2801 : 0 : wpa_printf(MSG_DEBUG, "%s(report=%d)", __func__, report);
2802 : 0 : drv->probe_req_report = report;
2803 : 0 : return 0;
2804 : : }
2805 : :
2806 : :
2807 : : #ifdef CONFIG_P2P
2808 : :
2809 : : static int wpa_driver_test_p2p_find(void *priv, unsigned int timeout, int type)
2810 : : {
2811 : : struct test_driver_bss *dbss = priv;
2812 : : struct wpa_driver_test_data *drv = dbss->drv;
2813 : : wpa_printf(MSG_DEBUG, "%s(timeout=%u)", __func__, timeout);
2814 : : if (!drv->p2p)
2815 : : return -1;
2816 : : return p2p_find(drv->p2p, timeout, type, 0, NULL, NULL, 0);
2817 : : }
2818 : :
2819 : :
2820 : : static int wpa_driver_test_p2p_stop_find(void *priv)
2821 : : {
2822 : : struct test_driver_bss *dbss = priv;
2823 : : struct wpa_driver_test_data *drv = dbss->drv;
2824 : : wpa_printf(MSG_DEBUG, "%s", __func__);
2825 : : if (!drv->p2p)
2826 : : return -1;
2827 : : p2p_stop_find(drv->p2p);
2828 : : return 0;
2829 : : }
2830 : :
2831 : :
2832 : : static int wpa_driver_test_p2p_listen(void *priv, unsigned int timeout)
2833 : : {
2834 : : struct test_driver_bss *dbss = priv;
2835 : : struct wpa_driver_test_data *drv = dbss->drv;
2836 : : wpa_printf(MSG_DEBUG, "%s(timeout=%u)", __func__, timeout);
2837 : : if (!drv->p2p)
2838 : : return -1;
2839 : : return p2p_listen(drv->p2p, timeout);
2840 : : }
2841 : :
2842 : :
2843 : : static int wpa_driver_test_p2p_connect(void *priv, const u8 *peer_addr,
2844 : : int wps_method, int go_intent,
2845 : : const u8 *own_interface_addr,
2846 : : unsigned int force_freq,
2847 : : int persistent_group)
2848 : : {
2849 : : struct test_driver_bss *dbss = priv;
2850 : : struct wpa_driver_test_data *drv = dbss->drv;
2851 : : wpa_printf(MSG_DEBUG, "%s(peer_addr=" MACSTR " wps_method=%d "
2852 : : "go_intent=%d "
2853 : : "own_interface_addr=" MACSTR " force_freq=%u "
2854 : : "persistent_group=%d)",
2855 : : __func__, MAC2STR(peer_addr), wps_method, go_intent,
2856 : : MAC2STR(own_interface_addr), force_freq, persistent_group);
2857 : : if (!drv->p2p)
2858 : : return -1;
2859 : : return p2p_connect(drv->p2p, peer_addr, wps_method, go_intent,
2860 : : own_interface_addr, force_freq, persistent_group,
2861 : : NULL, 0, 0, 0);
2862 : : }
2863 : :
2864 : :
2865 : : static int wpa_driver_test_wps_success_cb(void *priv, const u8 *peer_addr)
2866 : : {
2867 : : struct test_driver_bss *dbss = priv;
2868 : : struct wpa_driver_test_data *drv = dbss->drv;
2869 : : wpa_printf(MSG_DEBUG, "%s(peer_addr=" MACSTR ")",
2870 : : __func__, MAC2STR(peer_addr));
2871 : : if (!drv->p2p)
2872 : : return -1;
2873 : : p2p_wps_success_cb(drv->p2p, peer_addr);
2874 : : return 0;
2875 : : }
2876 : :
2877 : :
2878 : : static int wpa_driver_test_p2p_group_formation_failed(void *priv)
2879 : : {
2880 : : struct test_driver_bss *dbss = priv;
2881 : : struct wpa_driver_test_data *drv = dbss->drv;
2882 : : wpa_printf(MSG_DEBUG, "%s", __func__);
2883 : : if (!drv->p2p)
2884 : : return -1;
2885 : : p2p_group_formation_failed(drv->p2p);
2886 : : return 0;
2887 : : }
2888 : :
2889 : :
2890 : : static int wpa_driver_test_p2p_set_params(void *priv,
2891 : : const struct p2p_params *params)
2892 : : {
2893 : : struct test_driver_bss *dbss = priv;
2894 : : struct wpa_driver_test_data *drv = dbss->drv;
2895 : : wpa_printf(MSG_DEBUG, "%s", __func__);
2896 : : if (!drv->p2p)
2897 : : return -1;
2898 : : if (p2p_set_dev_name(drv->p2p, params->dev_name) < 0 ||
2899 : : p2p_set_pri_dev_type(drv->p2p, params->pri_dev_type) < 0 ||
2900 : : p2p_set_sec_dev_types(drv->p2p, params->sec_dev_type,
2901 : : params->num_sec_dev_types) < 0)
2902 : : return -1;
2903 : : return 0;
2904 : : }
2905 : :
2906 : :
2907 : : static int test_p2p_scan(void *ctx, enum p2p_scan_type type, int freq,
2908 : : unsigned int num_req_dev_types,
2909 : : const u8 *req_dev_types, const u8 *dev_id, u16 pw_id)
2910 : : {
2911 : : struct wpa_driver_test_data *drv = ctx;
2912 : : struct wpa_driver_scan_params params;
2913 : : int ret;
2914 : : struct wpabuf *wps_ie, *ies;
2915 : : int social_channels[] = { 2412, 2437, 2462, 0, 0 };
2916 : : size_t ielen;
2917 : :
2918 : : wpa_printf(MSG_DEBUG, "%s(type=%d freq=%d)",
2919 : : __func__, type, freq);
2920 : :
2921 : : os_memset(¶ms, 0, sizeof(params));
2922 : :
2923 : : /* P2P Wildcard SSID */
2924 : : params.num_ssids = 1;
2925 : : params.ssids[0].ssid = (u8 *) P2P_WILDCARD_SSID;
2926 : : params.ssids[0].ssid_len = P2P_WILDCARD_SSID_LEN;
2927 : :
2928 : : #if 0 /* TODO: WPS IE */
2929 : : wpa_s->wps->dev.p2p = 1;
2930 : : wps_ie = wps_build_probe_req_ie(pw_id, &wpa_s->wps->dev,
2931 : : wpa_s->wps->uuid, WPS_REQ_ENROLLEE);
2932 : : #else
2933 : : wps_ie = wpabuf_alloc(1);
2934 : : #endif
2935 : : if (wps_ie == NULL)
2936 : : return -1;
2937 : :
2938 : : ielen = p2p_scan_ie_buf_len(drv->p2p);
2939 : : ies = wpabuf_alloc(wpabuf_len(wps_ie) + ielen);
2940 : : if (ies == NULL) {
2941 : : wpabuf_free(wps_ie);
2942 : : return -1;
2943 : : }
2944 : : wpabuf_put_buf(ies, wps_ie);
2945 : : wpabuf_free(wps_ie);
2946 : :
2947 : : p2p_scan_ie(drv->p2p, ies, dev_id);
2948 : :
2949 : : params.extra_ies = wpabuf_head(ies);
2950 : : params.extra_ies_len = wpabuf_len(ies);
2951 : :
2952 : : switch (type) {
2953 : : case P2P_SCAN_SOCIAL:
2954 : : params.freqs = social_channels;
2955 : : break;
2956 : : case P2P_SCAN_FULL:
2957 : : break;
2958 : : case P2P_SCAN_SOCIAL_PLUS_ONE:
2959 : : social_channels[3] = freq;
2960 : : params.freqs = social_channels;
2961 : : break;
2962 : : }
2963 : :
2964 : : drv->pending_p2p_scan = 1;
2965 : : ret = wpa_driver_test_scan(drv, ¶ms);
2966 : :
2967 : : wpabuf_free(ies);
2968 : :
2969 : : return ret;
2970 : : }
2971 : :
2972 : :
2973 : : static int test_send_action(void *ctx, unsigned int freq, const u8 *dst,
2974 : : const u8 *src, const u8 *bssid, const u8 *buf,
2975 : : size_t len, unsigned int wait_time)
2976 : : {
2977 : : struct wpa_driver_test_data *drv = ctx;
2978 : :
2979 : : wpa_printf(MSG_DEBUG, "%s(freq=%u dst=" MACSTR " src=" MACSTR
2980 : : " bssid=" MACSTR " len=%d",
2981 : : __func__, freq, MAC2STR(dst), MAC2STR(src), MAC2STR(bssid),
2982 : : (int) len);
2983 : : if (freq <= 0) {
2984 : : wpa_printf(MSG_WARNING, "P2P: No frequency specified for "
2985 : : "action frame TX");
2986 : : return -1;
2987 : : }
2988 : :
2989 : : if (drv->pending_action_tx) {
2990 : : wpa_printf(MSG_DEBUG, "P2P: Dropped pending Action frame TX "
2991 : : "to " MACSTR, MAC2STR(drv->pending_action_dst));
2992 : : wpabuf_free(drv->pending_action_tx);
2993 : : }
2994 : : drv->pending_action_tx = wpabuf_alloc(len);
2995 : : if (drv->pending_action_tx == NULL)
2996 : : return -1;
2997 : : wpabuf_put_data(drv->pending_action_tx, buf, len);
2998 : : os_memcpy(drv->pending_action_src, src, ETH_ALEN);
2999 : : os_memcpy(drv->pending_action_dst, dst, ETH_ALEN);
3000 : : os_memcpy(drv->pending_action_bssid, bssid, ETH_ALEN);
3001 : : drv->pending_action_freq = freq;
3002 : : drv->pending_action_no_cck = 1;
3003 : :
3004 : : if (drv->off_channel_freq == freq) {
3005 : : /* Already on requested channel; send immediately */
3006 : : /* TODO: Would there ever be need to extend the current
3007 : : * duration on the channel? */
3008 : : eloop_cancel_timeout(test_send_action_cb, drv, NULL);
3009 : : eloop_register_timeout(0, 0, test_send_action_cb, drv, NULL);
3010 : : return 0;
3011 : : }
3012 : :
3013 : : wpa_printf(MSG_DEBUG, "P2P: Schedule Action frame to be transmitted "
3014 : : "once the driver gets to the requested channel");
3015 : : if (wpa_driver_test_remain_on_channel(drv, freq, wait_time) < 0) {
3016 : : wpa_printf(MSG_DEBUG, "P2P: Failed to request driver "
3017 : : "to remain on channel (%u MHz) for Action "
3018 : : "Frame TX", freq);
3019 : : return -1;
3020 : : }
3021 : :
3022 : : return 0;
3023 : : }
3024 : :
3025 : :
3026 : : static void test_send_action_done(void *ctx)
3027 : : {
3028 : : wpa_printf(MSG_DEBUG, "%s", __func__);
3029 : : /* TODO */
3030 : : }
3031 : :
3032 : :
3033 : : static void test_go_neg_completed(void *ctx, struct p2p_go_neg_results *res)
3034 : : {
3035 : : struct wpa_driver_test_data *drv = ctx;
3036 : : union wpa_event_data event;
3037 : : wpa_printf(MSG_DEBUG, "%s", __func__);
3038 : : os_memset(&event, 0, sizeof(event));
3039 : : event.p2p_go_neg_completed.res = res;
3040 : : wpa_supplicant_event(drv->ctx, EVENT_P2P_GO_NEG_COMPLETED, &event);
3041 : : }
3042 : :
3043 : :
3044 : : static void test_go_neg_req_rx(void *ctx, const u8 *src, u16 dev_passwd_id)
3045 : : {
3046 : : struct wpa_driver_test_data *drv = ctx;
3047 : : union wpa_event_data event;
3048 : : wpa_printf(MSG_DEBUG, "%s(src=" MACSTR ")", __func__, MAC2STR(src));
3049 : : os_memset(&event, 0, sizeof(event));
3050 : : event.p2p_go_neg_req_rx.src = src;
3051 : : event.p2p_go_neg_req_rx.dev_passwd_id = dev_passwd_id;
3052 : : wpa_supplicant_event(drv->ctx, EVENT_P2P_GO_NEG_REQ_RX, &event);
3053 : : }
3054 : :
3055 : :
3056 : : static void test_dev_found(void *ctx, const u8 *addr,
3057 : : const struct p2p_peer_info *info, int new_device)
3058 : : {
3059 : : struct wpa_driver_test_data *drv = ctx;
3060 : : union wpa_event_data event;
3061 : : char devtype[WPS_DEV_TYPE_BUFSIZE];
3062 : : wpa_printf(MSG_DEBUG, "%s(" MACSTR " p2p_dev_addr=" MACSTR
3063 : : " pri_dev_type=%s name='%s' config_methods=0x%x "
3064 : : "dev_capab=0x%x group_capab=0x%x)",
3065 : : __func__, MAC2STR(addr), MAC2STR(info->p2p_device_addr),
3066 : : wps_dev_type_bin2str(info->pri_dev_type, devtype,
3067 : : sizeof(devtype)),
3068 : : info->device_name, info->config_methods, info->dev_capab,
3069 : : info->group_capab);
3070 : :
3071 : : os_memset(&event, 0, sizeof(event));
3072 : : event.p2p_dev_found.addr = addr;
3073 : : event.p2p_dev_found.dev_addr = info->p2p_device_addr;
3074 : : event.p2p_dev_found.pri_dev_type = info->pri_dev_type;
3075 : : event.p2p_dev_found.dev_name = info->device_name;
3076 : : event.p2p_dev_found.config_methods = info->config_methods;
3077 : : event.p2p_dev_found.dev_capab = info->dev_capab;
3078 : : event.p2p_dev_found.group_capab = info->group_capab;
3079 : : wpa_supplicant_event(drv->ctx, EVENT_P2P_DEV_FOUND, &event);
3080 : : }
3081 : :
3082 : :
3083 : : static int test_start_listen(void *ctx, unsigned int freq,
3084 : : unsigned int duration,
3085 : : const struct wpabuf *probe_resp_ie)
3086 : : {
3087 : : struct wpa_driver_test_data *drv = ctx;
3088 : :
3089 : : wpa_printf(MSG_DEBUG, "%s(freq=%u duration=%u)",
3090 : : __func__, freq, duration);
3091 : :
3092 : : if (wpa_driver_test_probe_req_report(drv, 1) < 0)
3093 : : return -1;
3094 : :
3095 : : drv->pending_listen_freq = freq;
3096 : : drv->pending_listen_duration = duration;
3097 : :
3098 : : if (wpa_driver_test_remain_on_channel(drv, freq, duration) < 0) {
3099 : : drv->pending_listen_freq = 0;
3100 : : return -1;
3101 : : }
3102 : :
3103 : : return 0;
3104 : : }
3105 : :
3106 : :
3107 : : static void test_stop_listen(void *ctx)
3108 : : {
3109 : : wpa_printf(MSG_DEBUG, "%s", __func__);
3110 : : /* TODO */
3111 : : }
3112 : :
3113 : :
3114 : : static int test_send_probe_resp(void *ctx, const struct wpabuf *buf)
3115 : : {
3116 : : struct wpa_driver_test_data *drv = ctx;
3117 : : char resp[512], *pos, *end;
3118 : : int ret;
3119 : : const struct ieee80211_mgmt *mgmt;
3120 : : const u8 *ie, *ie_end;
3121 : :
3122 : : wpa_printf(MSG_DEBUG, "%s", __func__);
3123 : : wpa_hexdump_buf(MSG_MSGDUMP, "Probe Response", buf);
3124 : : if (wpabuf_len(buf) < 24)
3125 : : return -1;
3126 : : if (!drv->probe_from) {
3127 : : wpa_printf(MSG_DEBUG, "%s: probe_from not set", __func__);
3128 : : return -1;
3129 : : }
3130 : :
3131 : : pos = resp;
3132 : : end = resp + sizeof(resp);
3133 : :
3134 : : mgmt = wpabuf_head(buf);
3135 : :
3136 : : /* reply: SCANRESP BSSID SSID IEs */
3137 : : ret = os_snprintf(pos, end - pos, "SCANRESP " MACSTR " ",
3138 : : MAC2STR(mgmt->bssid));
3139 : : if (ret < 0 || ret >= end - pos)
3140 : : return -1;
3141 : : pos += ret;
3142 : :
3143 : : ie = mgmt->u.probe_resp.variable;
3144 : : ie_end = wpabuf_head_u8(buf) + wpabuf_len(buf);
3145 : : if (ie_end - ie < 2 || ie[0] != WLAN_EID_SSID ||
3146 : : ie + 2 + ie[1] > ie_end)
3147 : : return -1;
3148 : : pos += wpa_snprintf_hex(pos, end - pos, ie + 2, ie[1]);
3149 : :
3150 : : ret = os_snprintf(pos, end - pos, " ");
3151 : : if (ret < 0 || ret >= end - pos)
3152 : : return -1;
3153 : : pos += ret;
3154 : : pos += wpa_snprintf_hex(pos, end - pos, ie, ie_end - ie);
3155 : :
3156 : : sendto(drv->test_socket, resp, pos - resp, 0,
3157 : : drv->probe_from, drv->probe_from_len);
3158 : :
3159 : : return 0;
3160 : : }
3161 : :
3162 : :
3163 : : static void test_sd_request(void *ctx, int freq, const u8 *sa, u8 dialog_token,
3164 : : u16 update_indic, const u8 *tlvs, size_t tlvs_len)
3165 : : {
3166 : : wpa_printf(MSG_DEBUG, "%s", __func__);
3167 : : /* TODO */
3168 : : }
3169 : :
3170 : :
3171 : : static void test_sd_response(void *ctx, const u8 *sa, u16 update_indic,
3172 : : const u8 *tlvs, size_t tlvs_len)
3173 : : {
3174 : : wpa_printf(MSG_DEBUG, "%s", __func__);
3175 : : /* TODO */
3176 : : }
3177 : :
3178 : :
3179 : : static void test_prov_disc_req(void *ctx, const u8 *peer, u16 config_methods,
3180 : : const u8 *dev_addr, const u8 *pri_dev_type,
3181 : : const char *dev_name, u16 supp_config_methods,
3182 : : u8 dev_capab, u8 group_capab,
3183 : : const u8 *group_id, size_t group_id_len)
3184 : : {
3185 : : wpa_printf(MSG_DEBUG, "%s(peer=" MACSTR " config_methods=0x%x)",
3186 : : __func__, MAC2STR(peer), config_methods);
3187 : : /* TODO */
3188 : : }
3189 : :
3190 : :
3191 : : static void test_prov_disc_resp(void *ctx, const u8 *peer, u16 config_methods)
3192 : : {
3193 : : wpa_printf(MSG_DEBUG, "%s(peer=" MACSTR " config_methods=0x%x)",
3194 : : __func__, MAC2STR(peer), config_methods);
3195 : : /* TODO */
3196 : : }
3197 : :
3198 : :
3199 : : static void test_p2p_debug_print(void *ctx, int level, const char *msg)
3200 : : {
3201 : : wpa_printf(level, "P2P: %s", msg);
3202 : : }
3203 : :
3204 : : #endif /* CONFIG_P2P */
3205 : :
3206 : :
3207 : 0 : static int wpa_driver_test_init_p2p(struct wpa_driver_test_data *drv)
3208 : : {
3209 : : #ifdef CONFIG_P2P
3210 : : struct p2p_config p2p;
3211 : : unsigned int r;
3212 : : int i;
3213 : :
3214 : : os_memset(&p2p, 0, sizeof(p2p));
3215 : : p2p.cb_ctx = drv;
3216 : : p2p.debug_print = test_p2p_debug_print;
3217 : : p2p.p2p_scan = test_p2p_scan;
3218 : : p2p.send_action = test_send_action;
3219 : : p2p.send_action_done = test_send_action_done;
3220 : : p2p.go_neg_completed = test_go_neg_completed;
3221 : : p2p.go_neg_req_rx = test_go_neg_req_rx;
3222 : : p2p.dev_found = test_dev_found;
3223 : : p2p.start_listen = test_start_listen;
3224 : : p2p.stop_listen = test_stop_listen;
3225 : : p2p.send_probe_resp = test_send_probe_resp;
3226 : : p2p.sd_request = test_sd_request;
3227 : : p2p.sd_response = test_sd_response;
3228 : : p2p.prov_disc_req = test_prov_disc_req;
3229 : : p2p.prov_disc_resp = test_prov_disc_resp;
3230 : :
3231 : : os_memcpy(p2p.dev_addr, drv->own_addr, ETH_ALEN);
3232 : :
3233 : : p2p.reg_class = 12; /* TODO: change depending on location */
3234 : : /*
3235 : : * Pick one of the social channels randomly as the listen
3236 : : * channel.
3237 : : */
3238 : : os_get_random((u8 *) &r, sizeof(r));
3239 : : p2p.channel = 1 + (r % 3) * 5;
3240 : :
3241 : : /* TODO: change depending on location */
3242 : : p2p.op_reg_class = 12;
3243 : : /*
3244 : : * For initial tests, pick the operation channel randomly.
3245 : : * TODO: Use scan results (etc.) to select the best channel.
3246 : : */
3247 : : p2p.op_channel = 1 + r % 11;
3248 : :
3249 : : os_memcpy(p2p.country, "US ", 3);
3250 : :
3251 : : /* FIX: fetch available channels from the driver */
3252 : : p2p.channels.reg_classes = 1;
3253 : : p2p.channels.reg_class[0].reg_class = 12; /* US/12 = 2.4 GHz band */
3254 : : p2p.channels.reg_class[0].channels = 11;
3255 : : for (i = 0; i < 11; i++)
3256 : : p2p.channels.reg_class[0].channel[i] = i + 1;
3257 : :
3258 : : p2p.max_peers = 100;
3259 : :
3260 : : drv->p2p = p2p_init(&p2p);
3261 : : if (drv->p2p == NULL)
3262 : : return -1;
3263 : : return 0;
3264 : : #else /* CONFIG_P2P */
3265 : 0 : wpa_printf(MSG_INFO, "driver_test: P2P support not included");
3266 : 0 : return -1;
3267 : : #endif /* CONFIG_P2P */
3268 : : }
3269 : :
3270 : :
3271 : : const struct wpa_driver_ops wpa_driver_test_ops = {
3272 : : "test",
3273 : : "wpa_supplicant test driver",
3274 : : .hapd_init = test_driver_init,
3275 : : .hapd_deinit = wpa_driver_test_deinit,
3276 : : .hapd_send_eapol = test_driver_send_eapol,
3277 : : .send_mlme = wpa_driver_test_send_mlme,
3278 : : .set_generic_elem = test_driver_set_generic_elem,
3279 : : .sta_deauth = test_driver_sta_deauth,
3280 : : .sta_disassoc = test_driver_sta_disassoc,
3281 : : .get_hw_feature_data = wpa_driver_test_get_hw_feature_data,
3282 : : .if_add = test_driver_if_add,
3283 : : .if_remove = test_driver_if_remove,
3284 : : .hapd_set_ssid = test_driver_set_ssid,
3285 : : .set_privacy = test_driver_set_privacy,
3286 : : .set_sta_vlan = test_driver_set_sta_vlan,
3287 : : .sta_add = test_driver_sta_add,
3288 : : .send_ether = test_driver_send_ether,
3289 : : .set_ap_wps_ie = test_driver_set_ap_wps_ie,
3290 : : .get_bssid = wpa_driver_test_get_bssid,
3291 : : .get_ssid = wpa_driver_test_get_ssid,
3292 : : .set_key = wpa_driver_test_set_key,
3293 : : .deinit = wpa_driver_test_deinit,
3294 : : .set_param = wpa_driver_test_set_param,
3295 : : .deauthenticate = wpa_driver_test_deauthenticate,
3296 : : .associate = wpa_driver_test_associate,
3297 : : .get_capa = wpa_driver_test_get_capa,
3298 : : .get_mac_addr = wpa_driver_test_get_mac_addr,
3299 : : .send_eapol = wpa_driver_test_send_eapol,
3300 : : .mlme_setprotection = wpa_driver_test_mlme_setprotection,
3301 : : .get_scan_results2 = wpa_driver_test_get_scan_results2,
3302 : : .global_init = wpa_driver_test_global_init,
3303 : : .global_deinit = wpa_driver_test_global_deinit,
3304 : : .init2 = wpa_driver_test_init2,
3305 : : .get_interfaces = wpa_driver_test_get_interfaces,
3306 : : .scan2 = wpa_driver_test_scan,
3307 : : .set_freq = wpa_driver_test_set_freq,
3308 : : .send_action = wpa_driver_test_send_action,
3309 : : .remain_on_channel = wpa_driver_test_remain_on_channel,
3310 : : .cancel_remain_on_channel = wpa_driver_test_cancel_remain_on_channel,
3311 : : .probe_req_report = wpa_driver_test_probe_req_report,
3312 : : #ifdef CONFIG_P2P
3313 : : .p2p_find = wpa_driver_test_p2p_find,
3314 : : .p2p_stop_find = wpa_driver_test_p2p_stop_find,
3315 : : .p2p_listen = wpa_driver_test_p2p_listen,
3316 : : .p2p_connect = wpa_driver_test_p2p_connect,
3317 : : .wps_success_cb = wpa_driver_test_wps_success_cb,
3318 : : .p2p_group_formation_failed =
3319 : : wpa_driver_test_p2p_group_formation_failed,
3320 : : .p2p_set_params = wpa_driver_test_p2p_set_params,
3321 : : #endif /* CONFIG_P2P */
3322 : : };
|