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