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