OSDN Git Service

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