]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - contrib/hostapd/driver_test.c
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / contrib / hostapd / driver_test.c
1 /*
2  * hostapd / Driver interface for development testing
3  * Copyright (c) 2004-2007, 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/ioctl.h>
17 #include <sys/un.h>
18 #include <dirent.h>
19
20 #include "hostapd.h"
21 #include "driver.h"
22 #include "sha1.h"
23 #include "eloop.h"
24 #include "ieee802_1x.h"
25 #include "sta_info.h"
26 #include "eapol_sm.h"
27 #include "wpa.h"
28 #include "accounting.h"
29 #include "radius.h"
30 #include "l2_packet.h"
31 #include "ieee802_11.h"
32 #include "hw_features.h"
33
34
35 struct test_client_socket {
36         struct test_client_socket *next;
37         u8 addr[ETH_ALEN];
38         struct sockaddr_un un;
39         socklen_t unlen;
40         struct test_driver_bss *bss;
41 };
42
43 struct test_driver_bss {
44         struct test_driver_bss *next;
45         char ifname[IFNAMSIZ + 1];
46         u8 bssid[ETH_ALEN];
47         u8 *ie;
48         size_t ielen;
49         u8 ssid[32];
50         size_t ssid_len;
51         int privacy;
52 };
53
54 struct test_driver_data {
55         struct driver_ops ops;
56         struct hostapd_data *hapd;
57         struct test_client_socket *cli;
58         int test_socket;
59         struct test_driver_bss *bss;
60         char *socket_dir;
61         char *own_socket_path;
62 };
63
64 static const struct driver_ops test_driver_ops;
65
66
67 static void test_driver_free_bss(struct test_driver_bss *bss)
68 {
69         free(bss->ie);
70         free(bss);
71 }
72
73
74 static void test_driver_free_priv(struct test_driver_data *drv)
75 {
76         struct test_driver_bss *bss, *prev;
77
78         if (drv == NULL)
79                 return;
80
81         bss = drv->bss;
82         while (bss) {
83                 prev = bss;
84                 bss = bss->next;
85                 test_driver_free_bss(prev);
86         }
87         free(drv->own_socket_path);
88         free(drv->socket_dir);
89         free(drv);
90 }
91
92
93 static struct test_client_socket *
94 test_driver_get_cli(struct test_driver_data *drv, struct sockaddr_un *from,
95                     socklen_t fromlen)
96 {
97         struct test_client_socket *cli = drv->cli;
98
99         while (cli) {
100                 if (cli->unlen == fromlen &&
101                     strncmp(cli->un.sun_path, from->sun_path,
102                             fromlen - sizeof(cli->un.sun_family)) == 0)
103                         return cli;
104                 cli = cli->next;
105         }
106
107         return NULL;
108 }
109
110
111 static int test_driver_send_eapol(void *priv, const u8 *addr, const u8 *data,
112                                   size_t data_len, int encrypt,
113                                   const u8 *own_addr)
114 {
115         struct test_driver_data *drv = priv;
116         struct test_client_socket *cli;
117         struct msghdr msg;
118         struct iovec io[3];
119         struct l2_ethhdr eth;
120
121         if (drv->test_socket < 0)
122                 return -1;
123
124         cli = drv->cli;
125         while (cli) {
126                 if (memcmp(cli->addr, addr, ETH_ALEN) == 0)
127                         break;
128                 cli = cli->next;
129         }
130
131         if (!cli) {
132                 wpa_printf(MSG_DEBUG, "%s: no destination client entry",
133                            __func__);
134                 return -1;
135         }
136
137         memcpy(eth.h_dest, addr, ETH_ALEN);
138         memcpy(eth.h_source, own_addr, ETH_ALEN);
139         eth.h_proto = htons(ETH_P_EAPOL);
140
141         io[0].iov_base = "EAPOL ";
142         io[0].iov_len = 6;
143         io[1].iov_base = &eth;
144         io[1].iov_len = sizeof(eth);
145         io[2].iov_base = (u8 *) data;
146         io[2].iov_len = data_len;
147
148         memset(&msg, 0, sizeof(msg));
149         msg.msg_iov = io;
150         msg.msg_iovlen = 3;
151         msg.msg_name = &cli->un;
152         msg.msg_namelen = cli->unlen;
153         return sendmsg(drv->test_socket, &msg, 0);
154 }
155
156
157 static int test_driver_send_mgmt_frame(void *priv, const void *buf,
158                                        size_t len, int flags)
159 {
160         struct test_driver_data *drv = priv;
161         struct msghdr msg;
162         struct iovec io[2];
163         const u8 *dest;
164         int ret = 0, broadcast = 0;
165         char desttxt[30];
166         struct sockaddr_un addr;
167         struct dirent *dent;
168         DIR *dir;
169         struct ieee80211_hdr *hdr;
170         u16 fc;
171
172         if (drv->test_socket < 0 || len < 10 || drv->socket_dir == NULL) {
173                 wpa_printf(MSG_DEBUG, "%s: invalid parameters (sock=%d len=%lu"
174                            " socket_dir=%p)",
175                            __func__, drv->test_socket, (unsigned long) len,
176                            drv->socket_dir);
177                 return -1;
178         }
179
180         dest = buf;
181         dest += 4;
182         broadcast = memcmp(dest, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) == 0;
183         snprintf(desttxt, sizeof(desttxt), MACSTR, MAC2STR(dest));
184
185         io[0].iov_base = "MLME ";
186         io[0].iov_len = 5;
187         io[1].iov_base = (void *) buf;
188         io[1].iov_len = len;
189
190         memset(&msg, 0, sizeof(msg));
191         msg.msg_iov = io;
192         msg.msg_iovlen = 2;
193
194         dir = opendir(drv->socket_dir);
195         if (dir == NULL) {
196                 perror("test_driver: opendir");
197                 return -1;
198         }
199         while ((dent = readdir(dir))) {
200 #ifdef _DIRENT_HAVE_D_TYPE
201                 /* Skip the file if it is not a socket. Also accept
202                  * DT_UNKNOWN (0) in case the C library or underlying file
203                  * system does not support d_type. */
204                 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
205                         continue;
206 #endif /* _DIRENT_HAVE_D_TYPE */
207                 if (strcmp(dent->d_name, ".") == 0 ||
208                     strcmp(dent->d_name, "..") == 0)
209                         continue;
210
211                 memset(&addr, 0, sizeof(addr));
212                 addr.sun_family = AF_UNIX;
213                 snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/%s",
214                          drv->socket_dir, dent->d_name);
215
216                 if (strcmp(addr.sun_path, drv->own_socket_path) == 0)
217                         continue;
218                 if (!broadcast && strstr(dent->d_name, desttxt) == NULL)
219                         continue;
220
221                 wpa_printf(MSG_DEBUG, "%s: Send management frame to %s",
222                            __func__, dent->d_name);
223
224                 msg.msg_name = &addr;
225                 msg.msg_namelen = sizeof(addr);
226                 ret = sendmsg(drv->test_socket, &msg, 0);
227                 if (ret < 0)
228                         perror("driver_test: sendmsg");
229         }
230         closedir(dir);
231
232         hdr = (struct ieee80211_hdr *) buf;
233         fc = le_to_host16(hdr->frame_control);
234         ieee802_11_mgmt_cb(drv->hapd, (u8 *) buf, len, WLAN_FC_GET_STYPE(fc),
235                            ret >= 0);
236
237         return ret;
238 }
239
240
241 static void test_driver_scan(struct test_driver_data *drv,
242                              struct sockaddr_un *from, socklen_t fromlen)
243 {
244         char buf[512], *pos, *end;
245         int ret;
246         struct test_driver_bss *bss;
247
248         wpa_printf(MSG_DEBUG, "test_driver: SCAN");
249
250         for (bss = drv->bss; bss; bss = bss->next) {
251                 pos = buf;
252                 end = buf + sizeof(buf);
253
254                 /* reply: SCANRESP BSSID SSID IEs */
255                 ret = snprintf(pos, end - pos, "SCANRESP " MACSTR " ",
256                                MAC2STR(bss->bssid));
257                 if (ret < 0 || ret >= end - pos)
258                         return;
259                 pos += ret;
260                 pos += wpa_snprintf_hex(pos, end - pos,
261                                         bss->ssid, bss->ssid_len);
262                 ret = snprintf(pos, end - pos, " ");
263                 if (ret < 0 || ret >= end - pos)
264                         return;
265                 pos += ret;
266                 pos += wpa_snprintf_hex(pos, end - pos, bss->ie, bss->ielen);
267
268                 if (bss->privacy) {
269                         ret = snprintf(pos, end - pos, " PRIVACY");
270                         if (ret < 0 || ret >= end - pos)
271                                 return;
272                         pos += ret;
273                 }
274
275                 sendto(drv->test_socket, buf, pos - buf, 0,
276                        (struct sockaddr *) from, fromlen);
277         }
278 }
279
280
281 static struct hostapd_data * test_driver_get_hapd(struct test_driver_data *drv,
282                                                   struct test_driver_bss *bss)
283 {
284         struct hostapd_iface *iface = drv->hapd->iface;
285         struct hostapd_data *hapd = NULL;
286         size_t i;
287
288         if (bss == NULL) {
289                 wpa_printf(MSG_DEBUG, "%s: bss == NULL", __func__);
290                 return NULL;
291         }
292
293         for (i = 0; i < iface->num_bss; i++) {
294                 hapd = iface->bss[i];
295                 if (memcmp(hapd->own_addr, bss->bssid, ETH_ALEN) == 0)
296                         break;
297         }
298         if (i == iface->num_bss) {
299                 wpa_printf(MSG_DEBUG, "%s: no matching interface entry found "
300                            "for BSSID " MACSTR, __func__, MAC2STR(bss->bssid));
301                 return NULL;
302         }
303
304         return hapd;
305 }
306
307
308 static int test_driver_new_sta(struct test_driver_data *drv,
309                                struct test_driver_bss *bss, const u8 *addr,
310                                const u8 *ie, size_t ielen)
311 {
312         struct hostapd_data *hapd;
313         struct sta_info *sta;
314         int new_assoc, res;
315
316         hapd = test_driver_get_hapd(drv, bss);
317         if (hapd == NULL)
318                 return -1;
319
320         hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
321                 HOSTAPD_LEVEL_INFO, "associated");
322
323         sta = ap_get_sta(hapd, addr);
324         if (sta) {
325                 accounting_sta_stop(hapd, sta);
326         } else {
327                 sta = ap_sta_add(hapd, addr);
328                 if (sta == NULL)
329                         return -1;
330         }
331         accounting_sta_get_id(hapd, sta);
332
333         if (hapd->conf->wpa) {
334                 if (ie == NULL || ielen == 0) {
335                         printf("test_driver: no IE from STA\n");
336                         return -1;
337                 }
338                 if (sta->wpa_sm == NULL)
339                         sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
340                                                         sta->addr);
341                 if (sta->wpa_sm == NULL) {
342                         printf("test_driver: Failed to initialize WPA state "
343                                "machine\n");
344                         return -1;
345                 }
346                 res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
347                                           ie, ielen);
348                 if (res != WPA_IE_OK) {
349                         printf("WPA/RSN information element rejected? "
350                                "(res %u)\n", res);
351                         return -1;
352                 }
353         }
354
355         new_assoc = (sta->flags & WLAN_STA_ASSOC) == 0;
356         sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC;
357         wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC);
358
359         hostapd_new_assoc_sta(hapd, sta, !new_assoc);
360
361         ieee802_1x_notify_port_enabled(sta->eapol_sm, 1);
362
363         return 0;
364 }
365
366
367 static void test_driver_assoc(struct test_driver_data *drv,
368                               struct sockaddr_un *from, socklen_t fromlen,
369                               char *data)
370 {
371         struct test_client_socket *cli;
372         u8 ie[256], ssid[32];
373         size_t ielen, ssid_len = 0;
374         char *pos, *pos2, cmd[50];
375         struct test_driver_bss *bss;
376
377         /* data: STA-addr SSID(hex) IEs(hex) */
378
379         cli = wpa_zalloc(sizeof(*cli));
380         if (cli == NULL)
381                 return;
382
383         if (hwaddr_aton(data, cli->addr)) {
384                 printf("test_socket: Invalid MAC address '%s' in ASSOC\n",
385                        data);
386                 free(cli);
387                 return;
388         }
389         pos = data + 17;
390         while (*pos == ' ')
391                 pos++;
392         pos2 = strchr(pos, ' ');
393         ielen = 0;
394         if (pos2) {
395                 ssid_len = (pos2 - pos) / 2;
396                 if (hexstr2bin(pos, ssid, ssid_len) < 0) {
397                         wpa_printf(MSG_DEBUG, "%s: Invalid SSID", __func__);
398                         free(cli);
399                         return;
400                 }
401                 wpa_hexdump_ascii(MSG_DEBUG, "test_driver_assoc: SSID",
402                                   ssid, ssid_len);
403
404                 pos = pos2 + 1;
405                 ielen = strlen(pos) / 2;
406                 if (ielen > sizeof(ie))
407                         ielen = sizeof(ie);
408                 if (hexstr2bin(pos, ie, ielen) < 0)
409                         ielen = 0;
410         }
411
412         for (bss = drv->bss; bss; bss = bss->next) {
413                 if (bss->ssid_len == ssid_len &&
414                     memcmp(bss->ssid, ssid, ssid_len) == 0)
415                         break;
416         }
417         if (bss == NULL) {
418                 wpa_printf(MSG_DEBUG, "%s: No matching SSID found from "
419                            "configured BSSes", __func__);
420                 free(cli);
421                 return;
422         }
423
424         cli->bss = bss;
425         memcpy(&cli->un, from, sizeof(cli->un));
426         cli->unlen = fromlen;
427         cli->next = drv->cli;
428         drv->cli = cli;
429         wpa_hexdump_ascii(MSG_DEBUG, "test_socket: ASSOC sun_path",
430                           (const u8 *) cli->un.sun_path,
431                           cli->unlen - sizeof(cli->un.sun_family));
432
433         snprintf(cmd, sizeof(cmd), "ASSOCRESP " MACSTR " 0",
434                  MAC2STR(bss->bssid));
435         sendto(drv->test_socket, cmd, strlen(cmd), 0,
436                (struct sockaddr *) from, fromlen);
437
438         if (test_driver_new_sta(drv, bss, cli->addr, ie, ielen) < 0) {
439                 wpa_printf(MSG_DEBUG, "test_driver: failed to add new STA");
440         }
441 }
442
443
444 static void test_driver_disassoc(struct test_driver_data *drv,
445                                  struct sockaddr_un *from, socklen_t fromlen)
446 {
447         struct test_client_socket *cli;
448         struct sta_info *sta;
449
450         cli = test_driver_get_cli(drv, from, fromlen);
451         if (!cli)
452                 return;
453
454         hostapd_logger(drv->hapd, cli->addr, HOSTAPD_MODULE_IEEE80211,
455                        HOSTAPD_LEVEL_INFO, "disassociated");
456
457         sta = ap_get_sta(drv->hapd, cli->addr);
458         if (sta != NULL) {
459                 sta->flags &= ~WLAN_STA_ASSOC;
460                 wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);
461                 sta->acct_terminate_cause =
462                         RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
463                 ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
464                 ap_free_sta(drv->hapd, sta);
465         }
466 }
467
468
469 static void test_driver_eapol(struct test_driver_data *drv,
470                               struct sockaddr_un *from, socklen_t fromlen,
471                               u8 *data, size_t datalen)
472 {
473         struct test_client_socket *cli;
474         if (datalen > 14) {
475                 u8 *proto = data + 2 * ETH_ALEN;
476                 /* Skip Ethernet header */
477                 wpa_printf(MSG_DEBUG, "test_driver: dst=" MACSTR " src="
478                            MACSTR " proto=%04x",
479                            MAC2STR(data), MAC2STR(data + ETH_ALEN),
480                            (proto[0] << 8) | proto[1]);
481                 data += 14;
482                 datalen -= 14;
483         }
484         cli = test_driver_get_cli(drv, from, fromlen);
485         if (cli) {
486                 struct hostapd_data *hapd;
487                 hapd = test_driver_get_hapd(drv, cli->bss);
488                 if (hapd == NULL)
489                         return;
490                 ieee802_1x_receive(hapd, cli->addr, data, datalen);
491         } else {
492                 wpa_printf(MSG_DEBUG, "test_socket: EAPOL from unknown "
493                            "client");
494         }
495 }
496
497
498 static void test_driver_mlme(struct test_driver_data *drv,
499                              struct sockaddr_un *from, socklen_t fromlen,
500                              u8 *data, size_t datalen)
501 {
502         struct ieee80211_hdr *hdr;
503         u16 fc;
504
505         hdr = (struct ieee80211_hdr *) data;
506
507         if (test_driver_get_cli(drv, from, fromlen) == NULL && datalen >= 16) {
508                 struct test_client_socket *cli;
509                 cli = wpa_zalloc(sizeof(*cli));
510                 if (cli == NULL)
511                         return;
512                 wpa_printf(MSG_DEBUG, "Adding client entry for " MACSTR,
513                            MAC2STR(hdr->addr2));
514                 memcpy(cli->addr, hdr->addr2, ETH_ALEN);
515                 memcpy(&cli->un, from, sizeof(cli->un));
516                 cli->unlen = fromlen;
517                 cli->next = drv->cli;
518                 drv->cli = cli;
519         }
520
521         wpa_hexdump(MSG_MSGDUMP, "test_driver_mlme: received frame",
522                     data, datalen);
523         fc = le_to_host16(hdr->frame_control);
524         if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT) {
525                 wpa_printf(MSG_ERROR, "%s: received non-mgmt frame",
526                            __func__);
527                 return;
528         }
529         ieee802_11_mgmt(drv->hapd, data, datalen, WLAN_FC_GET_STYPE(fc), NULL);
530 }
531
532
533 static void test_driver_receive_unix(int sock, void *eloop_ctx, void *sock_ctx)
534 {
535         struct test_driver_data *drv = eloop_ctx;
536         char buf[2000];
537         int res;
538         struct sockaddr_un from;
539         socklen_t fromlen = sizeof(from);
540
541         res = recvfrom(sock, buf, sizeof(buf) - 1, 0,
542                        (struct sockaddr *) &from, &fromlen);
543         if (res < 0) {
544                 perror("recvfrom(test_socket)");
545                 return;
546         }
547         buf[res] = '\0';
548
549         wpa_printf(MSG_DEBUG, "test_driver: received %u bytes", res);
550
551         if (strcmp(buf, "SCAN") == 0) {
552                 test_driver_scan(drv, &from, fromlen);
553         } else if (strncmp(buf, "ASSOC ", 6) == 0) {
554                 test_driver_assoc(drv, &from, fromlen, buf + 6);
555         } else if (strcmp(buf, "DISASSOC") == 0) {
556                 test_driver_disassoc(drv, &from, fromlen);
557         } else if (strncmp(buf, "EAPOL ", 6) == 0) {
558                 test_driver_eapol(drv, &from, fromlen, (u8 *) buf + 6,
559                                   res - 6);
560         } else if (strncmp(buf, "MLME ", 5) == 0) {
561                 test_driver_mlme(drv, &from, fromlen, (u8 *) buf + 5, res - 5);
562         } else {
563                 wpa_hexdump_ascii(MSG_DEBUG, "Unknown test_socket command",
564                                   (u8 *) buf, res);
565         }
566 }
567
568
569 static int test_driver_set_generic_elem(const char *ifname, void *priv,
570                                         const u8 *elem, size_t elem_len)
571 {
572         struct test_driver_data *drv = priv;
573         struct test_driver_bss *bss;
574
575         for (bss = drv->bss; bss; bss = bss->next) {
576                 if (strcmp(bss->ifname, ifname) != 0)
577                         continue;
578
579                 free(bss->ie);
580
581                 if (elem == NULL) {
582                         bss->ie = NULL;
583                         bss->ielen = 0;
584                         return 0;
585                 }
586
587                 bss->ie = malloc(elem_len);
588                 if (bss->ie) {
589                         memcpy(bss->ie, elem, elem_len);
590                         bss->ielen = elem_len;
591                         return 0;
592                 } else {
593                         bss->ielen = 0;
594                         return -1;
595                 }
596         }
597
598         return -1;
599 }
600
601
602 static int test_driver_sta_deauth(void *priv, const u8 *addr, int reason)
603 {
604         struct test_driver_data *drv = priv;
605         struct test_client_socket *cli;
606
607         if (drv->test_socket < 0)
608                 return -1;
609
610         cli = drv->cli;
611         while (cli) {
612                 if (memcmp(cli->addr, addr, ETH_ALEN) == 0)
613                         break;
614                 cli = cli->next;
615         }
616
617         if (!cli)
618                 return -1;
619
620         return sendto(drv->test_socket, "DEAUTH", 6, 0,
621                       (struct sockaddr *) &cli->un, cli->unlen);
622 }
623
624
625 static int test_driver_sta_disassoc(void *priv, const u8 *addr, int reason)
626 {
627         struct test_driver_data *drv = priv;
628         struct test_client_socket *cli;
629
630         if (drv->test_socket < 0)
631                 return -1;
632
633         cli = drv->cli;
634         while (cli) {
635                 if (memcmp(cli->addr, addr, ETH_ALEN) == 0)
636                         break;
637                 cli = cli->next;
638         }
639
640         if (!cli)
641                 return -1;
642
643         return sendto(drv->test_socket, "DISASSOC", 8, 0,
644                       (struct sockaddr *) &cli->un, cli->unlen);
645 }
646
647
648 static struct hostapd_hw_modes *
649 test_driver_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags)
650 {
651         struct hostapd_hw_modes *modes;
652
653         *num_modes = 3;
654         *flags = 0;
655         modes = wpa_zalloc(*num_modes * sizeof(struct hostapd_hw_modes));
656         if (modes == NULL)
657                 return NULL;
658         modes[0].mode = HOSTAPD_MODE_IEEE80211G;
659         modes[0].num_channels = 1;
660         modes[0].num_rates = 1;
661         modes[0].channels = wpa_zalloc(sizeof(struct hostapd_channel_data));
662         modes[0].rates = wpa_zalloc(sizeof(struct hostapd_rate_data));
663         if (modes[0].channels == NULL || modes[0].rates == NULL) {
664                 hostapd_free_hw_features(modes, *num_modes);
665                 return NULL;
666         }
667         modes[0].channels[0].chan = 1;
668         modes[0].channels[0].freq = 2412;
669         modes[0].channels[0].flag = HOSTAPD_CHAN_W_SCAN |
670                 HOSTAPD_CHAN_W_ACTIVE_SCAN;
671         modes[0].rates[0].rate = 10;
672         modes[0].rates[0].flags = HOSTAPD_RATE_BASIC | HOSTAPD_RATE_SUPPORTED |
673                 HOSTAPD_RATE_CCK | HOSTAPD_RATE_MANDATORY;
674
675         modes[1].mode = HOSTAPD_MODE_IEEE80211B;
676         modes[1].num_channels = 1;
677         modes[1].num_rates = 1;
678         modes[1].channels = wpa_zalloc(sizeof(struct hostapd_channel_data));
679         modes[1].rates = wpa_zalloc(sizeof(struct hostapd_rate_data));
680         if (modes[1].channels == NULL || modes[1].rates == NULL) {
681                 hostapd_free_hw_features(modes, *num_modes);
682                 return NULL;
683         }
684         modes[1].channels[0].chan = 1;
685         modes[1].channels[0].freq = 2412;
686         modes[1].channels[0].flag = HOSTAPD_CHAN_W_SCAN |
687                 HOSTAPD_CHAN_W_ACTIVE_SCAN;
688         modes[1].rates[0].rate = 10;
689         modes[1].rates[0].flags = HOSTAPD_RATE_BASIC | HOSTAPD_RATE_SUPPORTED |
690                 HOSTAPD_RATE_CCK | HOSTAPD_RATE_MANDATORY;
691
692         modes[2].mode = HOSTAPD_MODE_IEEE80211A;
693         modes[2].num_channels = 1;
694         modes[2].num_rates = 1;
695         modes[2].channels = wpa_zalloc(sizeof(struct hostapd_channel_data));
696         modes[2].rates = wpa_zalloc(sizeof(struct hostapd_rate_data));
697         if (modes[2].channels == NULL || modes[2].rates == NULL) {
698                 hostapd_free_hw_features(modes, *num_modes);
699                 return NULL;
700         }
701         modes[2].channels[0].chan = 60;
702         modes[2].channels[0].freq = 5300;
703         modes[2].channels[0].flag = HOSTAPD_CHAN_W_SCAN |
704                 HOSTAPD_CHAN_W_ACTIVE_SCAN;
705         modes[2].rates[0].rate = 60;
706         modes[2].rates[0].flags = HOSTAPD_RATE_BASIC | HOSTAPD_RATE_SUPPORTED |
707                 HOSTAPD_RATE_MANDATORY;
708
709         return modes;
710 }
711
712
713 static int test_driver_bss_add(void *priv, const char *ifname, const u8 *bssid)
714 {
715         struct test_driver_data *drv = priv;
716         struct test_driver_bss *bss;
717
718         wpa_printf(MSG_DEBUG, "%s(ifname=%s bssid=" MACSTR ")",
719                    __func__, ifname, MAC2STR(bssid));
720
721         bss = wpa_zalloc(sizeof(*bss));
722         if (bss == NULL)
723                 return -1;
724
725         strncpy(bss->ifname, ifname, IFNAMSIZ);
726         memcpy(bss->bssid, bssid, ETH_ALEN);
727
728         bss->next = drv->bss;
729         drv->bss = bss;
730
731         return 0;
732 }
733
734
735 static int test_driver_bss_remove(void *priv, const char *ifname)
736 {
737         struct test_driver_data *drv = priv;
738         struct test_driver_bss *bss, *prev;
739         struct test_client_socket *cli, *prev_c;
740
741         wpa_printf(MSG_DEBUG, "%s(ifname=%s)", __func__, ifname);
742
743         for (prev = NULL, bss = drv->bss; bss; prev = bss, bss = bss->next) {
744                 if (strcmp(bss->ifname, ifname) != 0)
745                         continue;
746
747                 if (prev)
748                         prev->next = bss->next;
749                 else
750                         drv->bss = bss->next;
751
752                 for (prev_c = NULL, cli = drv->cli; cli;
753                      prev_c = cli, cli = cli->next) {
754                         if (cli->bss != bss)
755                                 continue;
756                         if (prev_c)
757                                 prev_c->next = cli->next;
758                         else
759                                 drv->cli = cli->next;
760                         free(cli);
761                         break;
762                 }
763
764                 test_driver_free_bss(bss);
765                 return 0;
766         }
767
768         return -1;
769 }
770
771
772 static int test_driver_if_add(const char *iface, void *priv,
773                               enum hostapd_driver_if_type type, char *ifname,
774                               const u8 *addr)
775 {
776         wpa_printf(MSG_DEBUG, "%s(iface=%s type=%d ifname=%s)",
777                    __func__, iface, type, ifname);
778         return 0;
779 }
780
781
782 static int test_driver_if_update(void *priv, enum hostapd_driver_if_type type,
783                                  char *ifname, const u8 *addr)
784 {
785         wpa_printf(MSG_DEBUG, "%s(type=%d ifname=%s)", __func__, type, ifname);
786         return 0;
787 }
788
789
790 static int test_driver_if_remove(void *priv, enum hostapd_driver_if_type type,
791                                  const char *ifname, const u8 *addr)
792 {
793         wpa_printf(MSG_DEBUG, "%s(type=%d ifname=%s)", __func__, type, ifname);
794         return 0;
795 }
796
797
798 static int test_driver_valid_bss_mask(void *priv, const u8 *addr,
799                                       const u8 *mask)
800 {
801         return 0;
802 }
803
804
805 static int test_driver_set_ssid(const char *ifname, void *priv, const u8 *buf,
806                                 int len)
807 {
808         struct test_driver_data *drv = priv;
809         struct test_driver_bss *bss;
810
811         wpa_printf(MSG_DEBUG, "%s(ifname=%s)", __func__, ifname);
812         wpa_hexdump_ascii(MSG_DEBUG, "test_driver_set_ssid: SSID", buf, len);
813
814         for (bss = drv->bss; bss; bss = bss->next) {
815                 if (strcmp(bss->ifname, ifname) != 0)
816                         continue;
817
818                 if (len < 0 || (size_t) len > sizeof(bss->ssid))
819                         return -1;
820
821                 memcpy(bss->ssid, buf, len);
822                 bss->ssid_len = len;
823
824                 return 0;
825         }
826
827         return -1;
828 }
829
830
831 static int test_driver_set_privacy(const char *ifname, void *priv, int enabled)
832 {
833         struct test_driver_data *drv = priv;
834         struct test_driver_bss *bss;
835
836         wpa_printf(MSG_DEBUG, "%s(ifname=%s enabled=%d)",
837                    __func__, ifname, enabled);
838
839         for (bss = drv->bss; bss; bss = bss->next) {
840                 if (strcmp(bss->ifname, ifname) != 0)
841                         continue;
842
843                 bss->privacy = enabled;
844
845                 return 0;
846         }
847
848         return -1;
849 }
850
851
852 static int test_driver_set_encryption(const char *iface, void *priv,
853                                       const char *alg, const u8 *addr, int idx,
854                                       const u8 *key, size_t key_len, int txkey)
855 {
856         wpa_printf(MSG_DEBUG, "%s(iface=%s alg=%s idx=%d txkey=%d)",
857                    __func__, iface, alg, idx, txkey);
858         if (addr)
859                 wpa_printf(MSG_DEBUG, "   addr=" MACSTR, MAC2STR(addr));
860         if (key)
861                 wpa_hexdump_key(MSG_DEBUG, "   key", key, key_len);
862         return 0;
863 }
864
865
866 static int test_driver_set_sta_vlan(void *priv, const u8 *addr,
867                                     const char *ifname, int vlan_id)
868 {
869         wpa_printf(MSG_DEBUG, "%s(addr=" MACSTR " ifname=%s vlan_id=%d)",
870                    __func__, MAC2STR(addr), ifname, vlan_id);
871         return 0;
872 }
873
874
875 static int test_driver_sta_add(const char *ifname, void *priv, const u8 *addr,
876                                u16 aid, u16 capability, u8 *supp_rates,
877                                size_t supp_rates_len, int flags)
878 {
879         struct test_driver_data *drv = priv;
880         struct test_client_socket *cli;
881         struct test_driver_bss *bss;
882
883         wpa_printf(MSG_DEBUG, "%s(ifname=%s addr=" MACSTR " aid=%d "
884                    "capability=0x%x flags=0x%x",
885                    __func__, ifname, MAC2STR(addr), aid, capability, flags);
886         wpa_hexdump(MSG_DEBUG, "test_driver_sta_add - supp_rates",
887                     supp_rates, supp_rates_len);
888
889         cli = drv->cli;
890         while (cli) {
891                 if (memcmp(cli->addr, addr, ETH_ALEN) == 0)
892                         break;
893                 cli = cli->next;
894         }
895         if (!cli) {
896                 wpa_printf(MSG_DEBUG, "%s: no matching client entry",
897                            __func__);
898                 return -1;
899         }
900
901         for (bss = drv->bss; bss; bss = bss->next) {
902                 if (strcmp(ifname, bss->ifname) == 0)
903                         break;
904         }
905         if (bss == NULL) {
906                 wpa_printf(MSG_DEBUG, "%s: No matching interface found from "
907                            "configured BSSes", __func__);
908                 return -1;
909         }
910
911         cli->bss = bss;
912
913         return 0;
914 }
915
916
917 static int test_driver_init(struct hostapd_data *hapd)
918 {
919         struct test_driver_data *drv;
920         struct sockaddr_un addr;
921
922         drv = wpa_zalloc(sizeof(struct test_driver_data));
923         if (drv == NULL) {
924                 printf("Could not allocate memory for test driver data\n");
925                 return -1;
926         }
927         drv->bss = wpa_zalloc(sizeof(*drv->bss));
928         if (drv->bss == NULL) {
929                 printf("Could not allocate memory for test driver BSS data\n");
930                 free(drv);
931                 return -1;
932         }
933
934         drv->ops = test_driver_ops;
935         drv->hapd = hapd;
936
937         /* Generate a MAC address to help testing with multiple APs */
938         hapd->own_addr[0] = 0x02; /* locally administered */
939         sha1_prf((const u8 *) hapd->conf->iface, strlen(hapd->conf->iface),
940                  "hostapd test bssid generation",
941                  (const u8 *) hapd->conf->ssid.ssid, hapd->conf->ssid.ssid_len,
942                  hapd->own_addr + 1, ETH_ALEN - 1);
943
944         strncpy(drv->bss->ifname, hapd->conf->iface, IFNAMSIZ);
945         memcpy(drv->bss->bssid, hapd->own_addr, ETH_ALEN);
946
947         if (hapd->conf->test_socket) {
948                 if (strlen(hapd->conf->test_socket) >= sizeof(addr.sun_path)) {
949                         printf("Too long test_socket path\n");
950                         test_driver_free_priv(drv);
951                         return -1;
952                 }
953                 if (strncmp(hapd->conf->test_socket, "DIR:", 4) == 0) {
954                         size_t len = strlen(hapd->conf->test_socket) + 30;
955                         drv->socket_dir = strdup(hapd->conf->test_socket + 4);
956                         drv->own_socket_path = malloc(len);
957                         if (drv->own_socket_path) {
958                                 snprintf(drv->own_socket_path, len,
959                                          "%s/AP-" MACSTR,
960                                          hapd->conf->test_socket + 4,
961                                          MAC2STR(hapd->own_addr));
962                         }
963                 } else {
964                         drv->own_socket_path = strdup(hapd->conf->test_socket);
965                 }
966                 if (drv->own_socket_path == NULL) {
967                         test_driver_free_priv(drv);
968                         return -1;
969                 }
970
971                 drv->test_socket = socket(PF_UNIX, SOCK_DGRAM, 0);
972                 if (drv->test_socket < 0) {
973                         perror("socket(PF_UNIX)");
974                         test_driver_free_priv(drv);
975                         return -1;
976                 }
977
978                 memset(&addr, 0, sizeof(addr));
979                 addr.sun_family = AF_UNIX;
980                 strncpy(addr.sun_path, drv->own_socket_path,
981                         sizeof(addr.sun_path));
982                 if (bind(drv->test_socket, (struct sockaddr *) &addr,
983                          sizeof(addr)) < 0) {
984                         perror("bind(PF_UNIX)");
985                         close(drv->test_socket);
986                         unlink(drv->own_socket_path);
987                         test_driver_free_priv(drv);
988                         return -1;
989                 }
990                 eloop_register_read_sock(drv->test_socket,
991                                          test_driver_receive_unix, drv, NULL);
992         } else
993                 drv->test_socket = -1;
994
995         hapd->driver = &drv->ops;
996         return 0;
997 }
998
999
1000 static void test_driver_deinit(void *priv)
1001 {
1002         struct test_driver_data *drv = priv;
1003         struct test_client_socket *cli, *prev;
1004
1005         cli = drv->cli;
1006         while (cli) {
1007                 prev = cli;
1008                 cli = cli->next;
1009                 free(prev);
1010         }
1011
1012         if (drv->test_socket >= 0) {
1013                 eloop_unregister_read_sock(drv->test_socket);
1014                 close(drv->test_socket);
1015                 unlink(drv->own_socket_path);
1016         }
1017
1018         drv->hapd->driver = NULL;
1019
1020         /* There should be only one BSS remaining at this point. */
1021         if (drv->bss == NULL)
1022                 wpa_printf(MSG_ERROR, "%s: drv->bss == NULL", __func__);
1023         else if (drv->bss->next)
1024                 wpa_printf(MSG_ERROR, "%s: drv->bss->next != NULL", __func__);
1025
1026         test_driver_free_priv(drv);
1027 }
1028
1029
1030 static const struct driver_ops test_driver_ops = {
1031         .name = "test",
1032         .init = test_driver_init,
1033         .deinit = test_driver_deinit,
1034         .send_eapol = test_driver_send_eapol,
1035         .send_mgmt_frame = test_driver_send_mgmt_frame,
1036         .set_generic_elem = test_driver_set_generic_elem,
1037         .sta_deauth = test_driver_sta_deauth,
1038         .sta_disassoc = test_driver_sta_disassoc,
1039         .get_hw_feature_data = test_driver_get_hw_feature_data,
1040         .bss_add = test_driver_bss_add,
1041         .bss_remove = test_driver_bss_remove,
1042         .if_add = test_driver_if_add,
1043         .if_update = test_driver_if_update,
1044         .if_remove = test_driver_if_remove,
1045         .valid_bss_mask = test_driver_valid_bss_mask,
1046         .set_ssid = test_driver_set_ssid,
1047         .set_privacy = test_driver_set_privacy,
1048         .set_encryption = test_driver_set_encryption,
1049         .set_sta_vlan = test_driver_set_sta_vlan,
1050         .sta_add = test_driver_sta_add,
1051 };
1052
1053
1054 void test_driver_register(void)
1055 {
1056         driver_register(test_driver_ops.name, &test_driver_ops);
1057 }