2 * hostapd / Driver interface for development testing
3 * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
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.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
16 #include <sys/ioctl.h>
24 #include "ieee802_1x.h"
28 #include "accounting.h"
30 #include "l2_packet.h"
31 #include "ieee802_11.h"
32 #include "hw_features.h"
35 struct test_client_socket {
36 struct test_client_socket *next;
38 struct sockaddr_un un;
40 struct test_driver_bss *bss;
43 struct test_driver_bss {
44 struct test_driver_bss *next;
45 char ifname[IFNAMSIZ + 1];
54 struct test_driver_data {
55 struct driver_ops ops;
56 struct hostapd_data *hapd;
57 struct test_client_socket *cli;
59 struct test_driver_bss *bss;
61 char *own_socket_path;
64 static const struct driver_ops test_driver_ops;
67 static void test_driver_free_bss(struct test_driver_bss *bss)
74 static void test_driver_free_priv(struct test_driver_data *drv)
76 struct test_driver_bss *bss, *prev;
85 test_driver_free_bss(prev);
87 free(drv->own_socket_path);
88 free(drv->socket_dir);
93 static struct test_client_socket *
94 test_driver_get_cli(struct test_driver_data *drv, struct sockaddr_un *from,
97 struct test_client_socket *cli = drv->cli;
100 if (cli->unlen == fromlen &&
101 strncmp(cli->un.sun_path, from->sun_path,
102 fromlen - sizeof(cli->un.sun_family)) == 0)
111 static int test_driver_send_eapol(void *priv, const u8 *addr, const u8 *data,
112 size_t data_len, int encrypt,
115 struct test_driver_data *drv = priv;
116 struct test_client_socket *cli;
119 struct l2_ethhdr eth;
121 if (drv->test_socket < 0)
126 if (memcmp(cli->addr, addr, ETH_ALEN) == 0)
132 wpa_printf(MSG_DEBUG, "%s: no destination client entry",
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);
141 io[0].iov_base = "EAPOL ";
143 io[1].iov_base = ð
144 io[1].iov_len = sizeof(eth);
145 io[2].iov_base = (u8 *) data;
146 io[2].iov_len = data_len;
148 memset(&msg, 0, sizeof(msg));
151 msg.msg_name = &cli->un;
152 msg.msg_namelen = cli->unlen;
153 return sendmsg(drv->test_socket, &msg, 0);
157 static int test_driver_send_mgmt_frame(void *priv, const void *buf,
158 size_t len, int flags)
160 struct test_driver_data *drv = priv;
164 int ret = 0, broadcast = 0;
166 struct sockaddr_un addr;
169 struct ieee80211_hdr *hdr;
172 if (drv->test_socket < 0 || len < 10 || drv->socket_dir == NULL) {
173 wpa_printf(MSG_DEBUG, "%s: invalid parameters (sock=%d len=%d "
175 __func__, drv->test_socket, len, drv->socket_dir);
181 broadcast = memcmp(dest, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) == 0;
182 snprintf(desttxt, sizeof(desttxt), MACSTR, MAC2STR(dest));
184 io[0].iov_base = "MLME ";
186 io[1].iov_base = (void *) buf;
189 memset(&msg, 0, sizeof(msg));
193 dir = opendir(drv->socket_dir);
195 perror("test_driver: opendir");
198 while ((dent = readdir(dir))) {
199 #ifdef _DIRENT_HAVE_D_TYPE
200 /* Skip the file if it is not a socket. Also accept
201 * DT_UNKNOWN (0) in case the C library or underlying file
202 * system does not support d_type. */
203 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
205 #endif /* _DIRENT_HAVE_D_TYPE */
206 if (strcmp(dent->d_name, ".") == 0 ||
207 strcmp(dent->d_name, "..") == 0)
210 memset(&addr, 0, sizeof(addr));
211 addr.sun_family = AF_UNIX;
212 snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/%s",
213 drv->socket_dir, dent->d_name);
215 if (strcmp(addr.sun_path, drv->own_socket_path) == 0)
217 if (!broadcast && strstr(dent->d_name, desttxt) == NULL)
220 wpa_printf(MSG_DEBUG, "%s: Send management frame to %s",
221 __func__, dent->d_name);
223 msg.msg_name = &addr;
224 msg.msg_namelen = sizeof(addr);
225 ret = sendmsg(drv->test_socket, &msg, 0);
227 perror("driver_test: sendmsg");
231 hdr = (struct ieee80211_hdr *) buf;
232 fc = le_to_host16(hdr->frame_control);
233 ieee802_11_mgmt_cb(drv->hapd, (u8 *) buf, len, WLAN_FC_GET_STYPE(fc),
240 static void test_driver_scan(struct test_driver_data *drv,
241 struct sockaddr_un *from, socklen_t fromlen)
243 char buf[512], *pos, *end;
245 struct test_driver_bss *bss;
247 wpa_printf(MSG_DEBUG, "test_driver: SCAN");
249 for (bss = drv->bss; bss; bss = bss->next) {
251 end = buf + sizeof(buf);
253 /* reply: SCANRESP BSSID SSID IEs */
254 ret = snprintf(pos, end - pos, "SCANRESP " MACSTR " ",
255 MAC2STR(bss->bssid));
256 if (ret < 0 || ret >= end - pos)
259 pos += wpa_snprintf_hex(pos, end - pos,
260 bss->ssid, bss->ssid_len);
261 ret = snprintf(pos, end - pos, " ");
262 if (ret < 0 || ret >= end - pos)
265 pos += wpa_snprintf_hex(pos, end - pos, bss->ie, bss->ielen);
268 ret = snprintf(pos, end - pos, " PRIVACY");
269 if (ret < 0 || ret >= end - pos)
274 sendto(drv->test_socket, buf, pos - buf, 0,
275 (struct sockaddr *) from, fromlen);
280 static struct hostapd_data * test_driver_get_hapd(struct test_driver_data *drv,
281 struct test_driver_bss *bss)
283 struct hostapd_iface *iface = drv->hapd->iface;
284 struct hostapd_data *hapd = NULL;
288 wpa_printf(MSG_DEBUG, "%s: bss == NULL", __func__);
292 for (i = 0; i < iface->num_bss; i++) {
293 hapd = iface->bss[i];
294 if (memcmp(hapd->own_addr, bss->bssid, ETH_ALEN) == 0)
297 if (i == iface->num_bss) {
298 wpa_printf(MSG_DEBUG, "%s: no matching interface entry found "
299 "for BSSID " MACSTR, __func__, MAC2STR(bss->bssid));
307 static int test_driver_new_sta(struct test_driver_data *drv,
308 struct test_driver_bss *bss, const u8 *addr,
309 const u8 *ie, size_t ielen)
311 struct hostapd_data *hapd;
312 struct sta_info *sta;
315 hapd = test_driver_get_hapd(drv, bss);
319 hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
320 HOSTAPD_LEVEL_INFO, "associated");
322 sta = ap_get_sta(hapd, addr);
324 accounting_sta_stop(hapd, sta);
326 sta = ap_sta_add(hapd, addr);
330 accounting_sta_get_id(hapd, sta);
332 if (hapd->conf->wpa) {
333 if (ie == NULL || ielen == 0) {
334 printf("test_driver: no IE from STA\n");
337 if (sta->wpa_sm == NULL)
338 sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
340 if (sta->wpa_sm == NULL) {
341 printf("test_driver: Failed to initialize WPA state "
345 res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
347 if (res != WPA_IE_OK) {
348 printf("WPA/RSN information element rejected? "
354 new_assoc = (sta->flags & WLAN_STA_ASSOC) == 0;
355 sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC;
356 wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC);
358 hostapd_new_assoc_sta(hapd, sta, !new_assoc);
360 ieee802_1x_notify_port_enabled(sta->eapol_sm, 1);
366 static void test_driver_assoc(struct test_driver_data *drv,
367 struct sockaddr_un *from, socklen_t fromlen,
370 struct test_client_socket *cli;
371 u8 ie[256], ssid[32];
372 size_t ielen, ssid_len = 0;
373 char *pos, *pos2, cmd[50];
374 struct test_driver_bss *bss;
376 /* data: STA-addr SSID(hex) IEs(hex) */
378 cli = wpa_zalloc(sizeof(*cli));
382 if (hwaddr_aton(data, cli->addr)) {
383 printf("test_socket: Invalid MAC address '%s' in ASSOC\n",
391 pos2 = strchr(pos, ' ');
394 ssid_len = (pos2 - pos) / 2;
395 if (hexstr2bin(pos, ssid, ssid_len) < 0) {
396 wpa_printf(MSG_DEBUG, "%s: Invalid SSID", __func__);
400 wpa_hexdump_ascii(MSG_DEBUG, "test_driver_assoc: SSID",
404 ielen = strlen(pos) / 2;
405 if (ielen > sizeof(ie))
407 if (hexstr2bin(pos, ie, ielen) < 0)
411 for (bss = drv->bss; bss; bss = bss->next) {
412 if (bss->ssid_len == ssid_len &&
413 memcmp(bss->ssid, ssid, ssid_len) == 0)
417 wpa_printf(MSG_DEBUG, "%s: No matching SSID found from "
418 "configured BSSes", __func__);
424 memcpy(&cli->un, from, sizeof(cli->un));
425 cli->unlen = fromlen;
426 cli->next = drv->cli;
428 wpa_hexdump_ascii(MSG_DEBUG, "test_socket: ASSOC sun_path",
429 (const u8 *) cli->un.sun_path,
430 cli->unlen - sizeof(cli->un.sun_family));
432 snprintf(cmd, sizeof(cmd), "ASSOCRESP " MACSTR " 0",
433 MAC2STR(bss->bssid));
434 sendto(drv->test_socket, cmd, strlen(cmd), 0,
435 (struct sockaddr *) from, fromlen);
437 if (test_driver_new_sta(drv, bss, cli->addr, ie, ielen) < 0) {
438 wpa_printf(MSG_DEBUG, "test_driver: failed to add new STA");
443 static void test_driver_disassoc(struct test_driver_data *drv,
444 struct sockaddr_un *from, socklen_t fromlen)
446 struct test_client_socket *cli;
447 struct sta_info *sta;
449 cli = test_driver_get_cli(drv, from, fromlen);
453 hostapd_logger(drv->hapd, cli->addr, HOSTAPD_MODULE_IEEE80211,
454 HOSTAPD_LEVEL_INFO, "disassociated");
456 sta = ap_get_sta(drv->hapd, cli->addr);
458 sta->flags &= ~WLAN_STA_ASSOC;
459 wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);
460 sta->acct_terminate_cause =
461 RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
462 ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
463 ap_free_sta(drv->hapd, sta);
468 static void test_driver_eapol(struct test_driver_data *drv,
469 struct sockaddr_un *from, socklen_t fromlen,
470 u8 *data, size_t datalen)
472 struct test_client_socket *cli;
474 u8 *proto = data + 2 * ETH_ALEN;
475 /* Skip Ethernet header */
476 wpa_printf(MSG_DEBUG, "test_driver: dst=" MACSTR " src="
477 MACSTR " proto=%04x",
478 MAC2STR(data), MAC2STR(data + ETH_ALEN),
479 (proto[0] << 8) | proto[1]);
483 cli = test_driver_get_cli(drv, from, fromlen);
485 struct hostapd_data *hapd;
486 hapd = test_driver_get_hapd(drv, cli->bss);
489 ieee802_1x_receive(hapd, cli->addr, data, datalen);
491 wpa_printf(MSG_DEBUG, "test_socket: EAPOL from unknown "
497 static void test_driver_mlme(struct test_driver_data *drv,
498 struct sockaddr_un *from, socklen_t fromlen,
499 u8 *data, size_t datalen)
501 struct ieee80211_hdr *hdr;
504 hdr = (struct ieee80211_hdr *) data;
506 if (test_driver_get_cli(drv, from, fromlen) == NULL && datalen >= 16) {
507 struct test_client_socket *cli;
508 cli = wpa_zalloc(sizeof(*cli));
511 wpa_printf(MSG_DEBUG, "Adding client entry for " MACSTR,
512 MAC2STR(hdr->addr2));
513 memcpy(cli->addr, hdr->addr2, ETH_ALEN);
514 memcpy(&cli->un, from, sizeof(cli->un));
515 cli->unlen = fromlen;
516 cli->next = drv->cli;
520 wpa_hexdump(MSG_MSGDUMP, "test_driver_mlme: received frame",
522 fc = le_to_host16(hdr->frame_control);
523 if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT) {
524 wpa_printf(MSG_ERROR, "%s: received non-mgmt frame",
528 ieee802_11_mgmt(drv->hapd, data, datalen, WLAN_FC_GET_STYPE(fc), NULL);
532 static void test_driver_receive_unix(int sock, void *eloop_ctx, void *sock_ctx)
534 struct test_driver_data *drv = eloop_ctx;
537 struct sockaddr_un from;
538 socklen_t fromlen = sizeof(from);
540 res = recvfrom(sock, buf, sizeof(buf) - 1, 0,
541 (struct sockaddr *) &from, &fromlen);
543 perror("recvfrom(test_socket)");
548 wpa_printf(MSG_DEBUG, "test_driver: received %u bytes", res);
550 if (strcmp(buf, "SCAN") == 0) {
551 test_driver_scan(drv, &from, fromlen);
552 } else if (strncmp(buf, "ASSOC ", 6) == 0) {
553 test_driver_assoc(drv, &from, fromlen, buf + 6);
554 } else if (strcmp(buf, "DISASSOC") == 0) {
555 test_driver_disassoc(drv, &from, fromlen);
556 } else if (strncmp(buf, "EAPOL ", 6) == 0) {
557 test_driver_eapol(drv, &from, fromlen, (u8 *) buf + 6,
559 } else if (strncmp(buf, "MLME ", 5) == 0) {
560 test_driver_mlme(drv, &from, fromlen, (u8 *) buf + 5, res - 5);
562 wpa_hexdump_ascii(MSG_DEBUG, "Unknown test_socket command",
568 static int test_driver_set_generic_elem(const char *ifname, void *priv,
569 const u8 *elem, size_t elem_len)
571 struct test_driver_data *drv = priv;
572 struct test_driver_bss *bss;
574 for (bss = drv->bss; bss; bss = bss->next) {
575 if (strcmp(bss->ifname, ifname) != 0)
586 bss->ie = malloc(elem_len);
588 memcpy(bss->ie, elem, elem_len);
589 bss->ielen = elem_len;
601 static int test_driver_sta_deauth(void *priv, const u8 *addr, int reason)
603 struct test_driver_data *drv = priv;
604 struct test_client_socket *cli;
606 if (drv->test_socket < 0)
611 if (memcmp(cli->addr, addr, ETH_ALEN) == 0)
619 return sendto(drv->test_socket, "DEAUTH", 6, 0,
620 (struct sockaddr *) &cli->un, cli->unlen);
624 static int test_driver_sta_disassoc(void *priv, const u8 *addr, int reason)
626 struct test_driver_data *drv = priv;
627 struct test_client_socket *cli;
629 if (drv->test_socket < 0)
634 if (memcmp(cli->addr, addr, ETH_ALEN) == 0)
642 return sendto(drv->test_socket, "DISASSOC", 8, 0,
643 (struct sockaddr *) &cli->un, cli->unlen);
647 static struct hostapd_hw_modes *
648 test_driver_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags)
650 struct hostapd_hw_modes *modes;
654 modes = wpa_zalloc(*num_modes * sizeof(struct hostapd_hw_modes));
657 modes[0].mode = HOSTAPD_MODE_IEEE80211G;
658 modes[0].num_channels = 1;
659 modes[0].num_rates = 1;
660 modes[0].channels = wpa_zalloc(sizeof(struct hostapd_channel_data));
661 modes[0].rates = wpa_zalloc(sizeof(struct hostapd_rate_data));
662 if (modes[0].channels == NULL || modes[0].rates == NULL) {
663 hostapd_free_hw_features(modes, *num_modes);
666 modes[0].channels[0].chan = 1;
667 modes[0].channels[0].freq = 2412;
668 modes[0].channels[0].flag = HOSTAPD_CHAN_W_SCAN |
669 HOSTAPD_CHAN_W_ACTIVE_SCAN;
670 modes[0].rates[0].rate = 10;
671 modes[0].rates[0].flags = HOSTAPD_RATE_BASIC | HOSTAPD_RATE_SUPPORTED |
672 HOSTAPD_RATE_CCK | HOSTAPD_RATE_MANDATORY;
674 modes[1].mode = HOSTAPD_MODE_IEEE80211B;
675 modes[1].num_channels = 1;
676 modes[1].num_rates = 1;
677 modes[1].channels = wpa_zalloc(sizeof(struct hostapd_channel_data));
678 modes[1].rates = wpa_zalloc(sizeof(struct hostapd_rate_data));
679 if (modes[1].channels == NULL || modes[1].rates == NULL) {
680 hostapd_free_hw_features(modes, *num_modes);
683 modes[1].channels[0].chan = 1;
684 modes[1].channels[0].freq = 2412;
685 modes[1].channels[0].flag = HOSTAPD_CHAN_W_SCAN |
686 HOSTAPD_CHAN_W_ACTIVE_SCAN;
687 modes[1].rates[0].rate = 10;
688 modes[1].rates[0].flags = HOSTAPD_RATE_BASIC | HOSTAPD_RATE_SUPPORTED |
689 HOSTAPD_RATE_CCK | HOSTAPD_RATE_MANDATORY;
691 modes[2].mode = HOSTAPD_MODE_IEEE80211A;
692 modes[2].num_channels = 1;
693 modes[2].num_rates = 1;
694 modes[2].channels = wpa_zalloc(sizeof(struct hostapd_channel_data));
695 modes[2].rates = wpa_zalloc(sizeof(struct hostapd_rate_data));
696 if (modes[2].channels == NULL || modes[2].rates == NULL) {
697 hostapd_free_hw_features(modes, *num_modes);
700 modes[2].channels[0].chan = 60;
701 modes[2].channels[0].freq = 5300;
702 modes[2].channels[0].flag = HOSTAPD_CHAN_W_SCAN |
703 HOSTAPD_CHAN_W_ACTIVE_SCAN;
704 modes[2].rates[0].rate = 60;
705 modes[2].rates[0].flags = HOSTAPD_RATE_BASIC | HOSTAPD_RATE_SUPPORTED |
706 HOSTAPD_RATE_MANDATORY;
712 static int test_driver_bss_add(void *priv, const char *ifname, const u8 *bssid)
714 struct test_driver_data *drv = priv;
715 struct test_driver_bss *bss;
717 wpa_printf(MSG_DEBUG, "%s(ifname=%s bssid=" MACSTR ")",
718 __func__, ifname, MAC2STR(bssid));
720 bss = wpa_zalloc(sizeof(*bss));
724 strncpy(bss->ifname, ifname, IFNAMSIZ);
725 memcpy(bss->bssid, bssid, ETH_ALEN);
727 bss->next = drv->bss;
734 static int test_driver_bss_remove(void *priv, const char *ifname)
736 struct test_driver_data *drv = priv;
737 struct test_driver_bss *bss, *prev;
738 struct test_client_socket *cli, *prev_c;
740 wpa_printf(MSG_DEBUG, "%s(ifname=%s)", __func__, ifname);
742 for (prev = NULL, bss = drv->bss; bss; prev = bss, bss = bss->next) {
743 if (strcmp(bss->ifname, ifname) != 0)
747 prev->next = bss->next;
749 drv->bss = bss->next;
751 for (prev_c = NULL, cli = drv->cli; cli;
752 prev_c = cli, cli = cli->next) {
756 prev_c->next = cli->next;
758 drv->cli = cli->next;
763 test_driver_free_bss(bss);
771 static int test_driver_if_add(const char *iface, void *priv,
772 enum hostapd_driver_if_type type, char *ifname,
775 wpa_printf(MSG_DEBUG, "%s(iface=%s type=%d ifname=%s)",
776 __func__, iface, type, ifname);
781 static int test_driver_if_update(void *priv, enum hostapd_driver_if_type type,
782 char *ifname, const u8 *addr)
784 wpa_printf(MSG_DEBUG, "%s(type=%d ifname=%s)", __func__, type, ifname);
789 static int test_driver_if_remove(void *priv, enum hostapd_driver_if_type type,
790 const char *ifname, const u8 *addr)
792 wpa_printf(MSG_DEBUG, "%s(type=%d ifname=%s)", __func__, type, ifname);
797 static int test_driver_valid_bss_mask(void *priv, const u8 *addr,
804 static int test_driver_set_ssid(const char *ifname, void *priv, const u8 *buf,
807 struct test_driver_data *drv = priv;
808 struct test_driver_bss *bss;
810 wpa_printf(MSG_DEBUG, "%s(ifname=%s)", __func__, ifname);
811 wpa_hexdump_ascii(MSG_DEBUG, "test_driver_set_ssid: SSID", buf, len);
813 for (bss = drv->bss; bss; bss = bss->next) {
814 if (strcmp(bss->ifname, ifname) != 0)
817 if (len < 0 || (size_t) len > sizeof(bss->ssid))
820 memcpy(bss->ssid, buf, len);
830 static int test_driver_set_privacy(const char *ifname, void *priv, int enabled)
832 struct test_driver_data *drv = priv;
833 struct test_driver_bss *bss;
835 wpa_printf(MSG_DEBUG, "%s(ifname=%s enabled=%d)",
836 __func__, ifname, enabled);
838 for (bss = drv->bss; bss; bss = bss->next) {
839 if (strcmp(bss->ifname, ifname) != 0)
842 bss->privacy = enabled;
851 static int test_driver_set_encryption(const char *iface, void *priv,
852 const char *alg, const u8 *addr, int idx,
853 const u8 *key, size_t key_len, int txkey)
855 wpa_printf(MSG_DEBUG, "%s(iface=%s alg=%s idx=%d txkey=%d)",
856 __func__, iface, alg, idx, txkey);
858 wpa_printf(MSG_DEBUG, " addr=" MACSTR, MAC2STR(addr));
860 wpa_hexdump_key(MSG_DEBUG, " key", key, key_len);
865 static int test_driver_set_sta_vlan(void *priv, const u8 *addr,
866 const char *ifname, int vlan_id)
868 wpa_printf(MSG_DEBUG, "%s(addr=" MACSTR " ifname=%s vlan_id=%d)",
869 __func__, MAC2STR(addr), ifname, vlan_id);
874 static int test_driver_sta_add(const char *ifname, void *priv, const u8 *addr,
875 u16 aid, u16 capability, u8 *supp_rates,
876 size_t supp_rates_len, int flags)
878 struct test_driver_data *drv = priv;
879 struct test_client_socket *cli;
880 struct test_driver_bss *bss;
882 wpa_printf(MSG_DEBUG, "%s(ifname=%s addr=" MACSTR " aid=%d "
883 "capability=0x%x flags=0x%x",
884 __func__, ifname, MAC2STR(addr), aid, capability, flags);
885 wpa_hexdump(MSG_DEBUG, "test_driver_sta_add - supp_rates",
886 supp_rates, supp_rates_len);
890 if (memcmp(cli->addr, addr, ETH_ALEN) == 0)
895 wpa_printf(MSG_DEBUG, "%s: no matching client entry",
900 for (bss = drv->bss; bss; bss = bss->next) {
901 if (strcmp(ifname, bss->ifname) == 0)
905 wpa_printf(MSG_DEBUG, "%s: No matching interface found from "
906 "configured BSSes", __func__);
916 static int test_driver_init(struct hostapd_data *hapd)
918 struct test_driver_data *drv;
919 struct sockaddr_un addr;
921 drv = wpa_zalloc(sizeof(struct test_driver_data));
923 printf("Could not allocate memory for test driver data\n");
926 drv->bss = wpa_zalloc(sizeof(*drv->bss));
927 if (drv->bss == NULL) {
928 printf("Could not allocate memory for test driver BSS data\n");
933 drv->ops = test_driver_ops;
936 /* Generate a MAC address to help testing with multiple APs */
937 hapd->own_addr[0] = 0x02; /* locally administered */
938 sha1_prf((const u8 *) hapd->conf->iface, strlen(hapd->conf->iface),
939 "hostapd test bssid generation",
940 (const u8 *) hapd->conf->ssid.ssid, hapd->conf->ssid.ssid_len,
941 hapd->own_addr + 1, ETH_ALEN - 1);
943 strncpy(drv->bss->ifname, hapd->conf->iface, IFNAMSIZ);
944 memcpy(drv->bss->bssid, hapd->own_addr, ETH_ALEN);
946 if (hapd->conf->test_socket) {
947 if (strlen(hapd->conf->test_socket) >= sizeof(addr.sun_path)) {
948 printf("Too long test_socket path\n");
949 test_driver_free_priv(drv);
952 if (strncmp(hapd->conf->test_socket, "DIR:", 4) == 0) {
953 size_t len = strlen(hapd->conf->test_socket) + 30;
954 drv->socket_dir = strdup(hapd->conf->test_socket + 4);
955 drv->own_socket_path = malloc(len);
956 if (drv->own_socket_path) {
957 snprintf(drv->own_socket_path, len,
959 hapd->conf->test_socket + 4,
960 MAC2STR(hapd->own_addr));
963 drv->own_socket_path = strdup(hapd->conf->test_socket);
965 if (drv->own_socket_path == NULL) {
966 test_driver_free_priv(drv);
970 drv->test_socket = socket(PF_UNIX, SOCK_DGRAM, 0);
971 if (drv->test_socket < 0) {
972 perror("socket(PF_UNIX)");
973 test_driver_free_priv(drv);
977 memset(&addr, 0, sizeof(addr));
978 addr.sun_family = AF_UNIX;
979 strncpy(addr.sun_path, drv->own_socket_path,
980 sizeof(addr.sun_path));
981 if (bind(drv->test_socket, (struct sockaddr *) &addr,
983 perror("bind(PF_UNIX)");
984 close(drv->test_socket);
985 unlink(drv->own_socket_path);
986 test_driver_free_priv(drv);
989 eloop_register_read_sock(drv->test_socket,
990 test_driver_receive_unix, drv, NULL);
992 drv->test_socket = -1;
994 hapd->driver = &drv->ops;
999 static void test_driver_deinit(void *priv)
1001 struct test_driver_data *drv = priv;
1002 struct test_client_socket *cli, *prev;
1011 if (drv->test_socket >= 0) {
1012 eloop_unregister_read_sock(drv->test_socket);
1013 close(drv->test_socket);
1014 unlink(drv->own_socket_path);
1017 drv->hapd->driver = NULL;
1019 /* There should be only one BSS remaining at this point. */
1020 if (drv->bss == NULL)
1021 wpa_printf(MSG_ERROR, "%s: drv->bss == NULL", __func__);
1022 else if (drv->bss->next)
1023 wpa_printf(MSG_ERROR, "%s: drv->bss->next != NULL", __func__);
1025 test_driver_free_priv(drv);
1029 static const struct driver_ops test_driver_ops = {
1031 .init = test_driver_init,
1032 .deinit = test_driver_deinit,
1033 .send_eapol = test_driver_send_eapol,
1034 .send_mgmt_frame = test_driver_send_mgmt_frame,
1035 .set_generic_elem = test_driver_set_generic_elem,
1036 .sta_deauth = test_driver_sta_deauth,
1037 .sta_disassoc = test_driver_sta_disassoc,
1038 .get_hw_feature_data = test_driver_get_hw_feature_data,
1039 .bss_add = test_driver_bss_add,
1040 .bss_remove = test_driver_bss_remove,
1041 .if_add = test_driver_if_add,
1042 .if_update = test_driver_if_update,
1043 .if_remove = test_driver_if_remove,
1044 .valid_bss_mask = test_driver_valid_bss_mask,
1045 .set_ssid = test_driver_set_ssid,
1046 .set_privacy = test_driver_set_privacy,
1047 .set_encryption = test_driver_set_encryption,
1048 .set_sta_vlan = test_driver_set_sta_vlan,
1049 .sta_add = test_driver_sta_add,
1053 void test_driver_register(void)
1055 driver_register(test_driver_ops.name, &test_driver_ops);