2 * hostapd / Driver interface for development testing
3 * Copyright (c) 2004-2008, 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.
23 #include "ieee802_1x.h"
26 #include "accounting.h"
27 #include "radius/radius.h"
28 #include "l2_packet/l2_packet.h"
29 #include "ieee802_11.h"
30 #include "hw_features.h"
31 #include "wps_hostapd.h"
34 struct test_client_socket {
35 struct test_client_socket *next;
37 struct sockaddr_un un;
39 struct test_driver_bss *bss;
42 struct test_driver_bss {
43 struct test_driver_bss *next;
44 char ifname[IFNAMSIZ + 1];
49 size_t wps_beacon_ie_len;
50 u8 *wps_probe_resp_ie;
51 size_t wps_probe_resp_ie_len;
57 struct test_driver_data {
58 struct hostapd_data *hapd;
59 struct test_client_socket *cli;
61 struct test_driver_bss *bss;
63 char *own_socket_path;
68 static void test_driver_free_bss(struct test_driver_bss *bss)
71 free(bss->wps_beacon_ie);
72 free(bss->wps_probe_resp_ie);
77 static void test_driver_free_priv(struct test_driver_data *drv)
79 struct test_driver_bss *bss, *prev;
88 test_driver_free_bss(prev);
90 free(drv->own_socket_path);
91 free(drv->socket_dir);
96 static struct test_client_socket *
97 test_driver_get_cli(struct test_driver_data *drv, struct sockaddr_un *from,
100 struct test_client_socket *cli = drv->cli;
103 if (cli->unlen == fromlen &&
104 strncmp(cli->un.sun_path, from->sun_path,
105 fromlen - sizeof(cli->un.sun_family)) == 0)
114 static int test_driver_send_eapol(void *priv, const u8 *addr, const u8 *data,
115 size_t data_len, int encrypt,
118 struct test_driver_data *drv = priv;
119 struct test_client_socket *cli;
122 struct l2_ethhdr eth;
124 if (drv->test_socket < 0)
129 if (memcmp(cli->addr, addr, ETH_ALEN) == 0)
135 wpa_printf(MSG_DEBUG, "%s: no destination client entry",
140 memcpy(eth.h_dest, addr, ETH_ALEN);
141 memcpy(eth.h_source, own_addr, ETH_ALEN);
142 eth.h_proto = htons(ETH_P_EAPOL);
144 io[0].iov_base = "EAPOL ";
146 io[1].iov_base = ð
147 io[1].iov_len = sizeof(eth);
148 io[2].iov_base = (u8 *) data;
149 io[2].iov_len = data_len;
151 memset(&msg, 0, sizeof(msg));
154 msg.msg_name = &cli->un;
155 msg.msg_namelen = cli->unlen;
156 return sendmsg(drv->test_socket, &msg, 0);
160 static int test_driver_send_ether(void *priv, const u8 *dst, const u8 *src,
161 u16 proto, const u8 *data, size_t data_len)
163 struct test_driver_data *drv = priv;
166 struct l2_ethhdr eth;
168 struct sockaddr_un addr;
171 int ret = 0, broadcast = 0, count = 0;
173 if (drv->test_socket < 0 || drv->socket_dir == NULL) {
174 wpa_printf(MSG_DEBUG, "%s: invalid parameters (sock=%d "
176 __func__, drv->test_socket, drv->socket_dir);
180 broadcast = memcmp(dst, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) == 0;
181 snprintf(desttxt, sizeof(desttxt), MACSTR, MAC2STR(dst));
183 memcpy(eth.h_dest, dst, ETH_ALEN);
184 memcpy(eth.h_source, src, ETH_ALEN);
185 eth.h_proto = htons(proto);
187 io[0].iov_base = "ETHER ";
189 io[1].iov_base = ð
190 io[1].iov_len = sizeof(eth);
191 io[2].iov_base = (u8 *) data;
192 io[2].iov_len = data_len;
194 memset(&msg, 0, sizeof(msg));
198 dir = opendir(drv->socket_dir);
200 perror("test_driver: opendir");
203 while ((dent = readdir(dir))) {
204 #ifdef _DIRENT_HAVE_D_TYPE
205 /* Skip the file if it is not a socket. Also accept
206 * DT_UNKNOWN (0) in case the C library or underlying file
207 * system does not support d_type. */
208 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
210 #endif /* _DIRENT_HAVE_D_TYPE */
211 if (strcmp(dent->d_name, ".") == 0 ||
212 strcmp(dent->d_name, "..") == 0)
215 memset(&addr, 0, sizeof(addr));
216 addr.sun_family = AF_UNIX;
217 snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/%s",
218 drv->socket_dir, dent->d_name);
220 if (strcmp(addr.sun_path, drv->own_socket_path) == 0)
222 if (!broadcast && strstr(dent->d_name, desttxt) == NULL)
225 wpa_printf(MSG_DEBUG, "%s: Send ether frame to %s",
226 __func__, dent->d_name);
228 msg.msg_name = &addr;
229 msg.msg_namelen = sizeof(addr);
230 ret = sendmsg(drv->test_socket, &msg, 0);
232 perror("driver_test: sendmsg");
237 if (!broadcast && count == 0) {
238 wpa_printf(MSG_DEBUG, "%s: Destination " MACSTR " not found",
239 __func__, MAC2STR(dst));
247 static int test_driver_send_mgmt_frame(void *priv, const void *buf,
248 size_t len, int flags)
250 struct test_driver_data *drv = priv;
254 int ret = 0, broadcast = 0;
256 struct sockaddr_un addr;
259 struct ieee80211_hdr *hdr;
262 if (drv->test_socket < 0 || len < 10 || drv->socket_dir == NULL) {
263 wpa_printf(MSG_DEBUG, "%s: invalid parameters (sock=%d len=%lu"
265 __func__, drv->test_socket, (unsigned long) len,
272 broadcast = memcmp(dest, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) == 0;
273 snprintf(desttxt, sizeof(desttxt), MACSTR, MAC2STR(dest));
275 io[0].iov_base = "MLME ";
277 io[1].iov_base = (void *) buf;
280 memset(&msg, 0, sizeof(msg));
284 dir = opendir(drv->socket_dir);
286 perror("test_driver: opendir");
289 while ((dent = readdir(dir))) {
290 #ifdef _DIRENT_HAVE_D_TYPE
291 /* Skip the file if it is not a socket. Also accept
292 * DT_UNKNOWN (0) in case the C library or underlying file
293 * system does not support d_type. */
294 if (dent->d_type != DT_SOCK && dent->d_type != DT_UNKNOWN)
296 #endif /* _DIRENT_HAVE_D_TYPE */
297 if (strcmp(dent->d_name, ".") == 0 ||
298 strcmp(dent->d_name, "..") == 0)
301 memset(&addr, 0, sizeof(addr));
302 addr.sun_family = AF_UNIX;
303 snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/%s",
304 drv->socket_dir, dent->d_name);
306 if (strcmp(addr.sun_path, drv->own_socket_path) == 0)
308 if (!broadcast && strstr(dent->d_name, desttxt) == NULL)
311 wpa_printf(MSG_DEBUG, "%s: Send management frame to %s",
312 __func__, dent->d_name);
314 msg.msg_name = &addr;
315 msg.msg_namelen = sizeof(addr);
316 ret = sendmsg(drv->test_socket, &msg, 0);
318 perror("driver_test: sendmsg");
322 hdr = (struct ieee80211_hdr *) buf;
323 fc = le_to_host16(hdr->frame_control);
324 ieee802_11_mgmt_cb(drv->hapd, (u8 *) buf, len, WLAN_FC_GET_STYPE(fc),
331 static void test_driver_scan(struct test_driver_data *drv,
332 struct sockaddr_un *from, socklen_t fromlen,
335 char buf[512], *pos, *end;
337 struct test_driver_bss *bss;
342 /* data: optional [ ' ' | STA-addr | ' ' | IEs(hex) ] */
344 wpa_printf(MSG_DEBUG, "test_driver: SCAN");
348 hwaddr_aton(data + 1, sa)) {
349 wpa_printf(MSG_DEBUG, "test_driver: Unexpected SCAN "
357 ielen = os_strlen(data) / 2;
358 if (ielen > sizeof(ie))
360 if (hexstr2bin(data, ie, ielen) < 0)
363 wpa_printf(MSG_DEBUG, "test_driver: Scan from " MACSTR,
365 wpa_hexdump(MSG_MSGDUMP, "test_driver: scan IEs", ie, ielen);
367 hostapd_wps_probe_req_rx(drv->hapd, sa, ie, ielen);
370 for (bss = drv->bss; bss; bss = bss->next) {
372 end = buf + sizeof(buf);
374 /* reply: SCANRESP BSSID SSID IEs */
375 ret = snprintf(pos, end - pos, "SCANRESP " MACSTR " ",
376 MAC2STR(bss->bssid));
377 if (ret < 0 || ret >= end - pos)
380 pos += wpa_snprintf_hex(pos, end - pos,
381 bss->ssid, bss->ssid_len);
382 ret = snprintf(pos, end - pos, " ");
383 if (ret < 0 || ret >= end - pos)
386 pos += wpa_snprintf_hex(pos, end - pos, bss->ie, bss->ielen);
387 pos += wpa_snprintf_hex(pos, end - pos, bss->wps_probe_resp_ie,
388 bss->wps_probe_resp_ie_len);
391 ret = snprintf(pos, end - pos, " PRIVACY");
392 if (ret < 0 || ret >= end - pos)
397 sendto(drv->test_socket, buf, pos - buf, 0,
398 (struct sockaddr *) from, fromlen);
403 static struct hostapd_data * test_driver_get_hapd(struct test_driver_data *drv,
404 struct test_driver_bss *bss)
406 struct hostapd_iface *iface = drv->hapd->iface;
407 struct hostapd_data *hapd = NULL;
411 wpa_printf(MSG_DEBUG, "%s: bss == NULL", __func__);
415 for (i = 0; i < iface->num_bss; i++) {
416 hapd = iface->bss[i];
417 if (memcmp(hapd->own_addr, bss->bssid, ETH_ALEN) == 0)
420 if (i == iface->num_bss) {
421 wpa_printf(MSG_DEBUG, "%s: no matching interface entry found "
422 "for BSSID " MACSTR, __func__, MAC2STR(bss->bssid));
430 static int test_driver_new_sta(struct test_driver_data *drv,
431 struct test_driver_bss *bss, const u8 *addr,
432 const u8 *ie, size_t ielen)
434 struct hostapd_data *hapd;
435 struct sta_info *sta;
438 hapd = test_driver_get_hapd(drv, bss);
442 hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
443 HOSTAPD_LEVEL_INFO, "associated");
445 sta = ap_get_sta(hapd, addr);
447 accounting_sta_stop(hapd, sta);
449 sta = ap_sta_add(hapd, addr);
453 sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS);
455 if (hapd->conf->wpa) {
456 if (ie == NULL || ielen == 0) {
457 if (hapd->conf->wps_state) {
458 sta->flags |= WLAN_STA_WPS;
462 printf("test_driver: no IE from STA\n");
465 if (sta->wpa_sm == NULL)
466 sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
468 if (sta->wpa_sm == NULL) {
469 printf("test_driver: Failed to initialize WPA state "
473 res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
475 if (res != WPA_IE_OK) {
476 printf("WPA/RSN information element rejected? "
483 new_assoc = (sta->flags & WLAN_STA_ASSOC) == 0;
484 sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC;
485 wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC);
487 hostapd_new_assoc_sta(hapd, sta, !new_assoc);
489 ieee802_1x_notify_port_enabled(sta->eapol_sm, 1);
495 static void test_driver_assoc(struct test_driver_data *drv,
496 struct sockaddr_un *from, socklen_t fromlen,
499 struct test_client_socket *cli;
500 u8 ie[256], ssid[32];
501 size_t ielen, ssid_len = 0;
502 char *pos, *pos2, cmd[50];
503 struct test_driver_bss *bss;
505 /* data: STA-addr SSID(hex) IEs(hex) */
507 cli = os_zalloc(sizeof(*cli));
511 if (hwaddr_aton(data, cli->addr)) {
512 printf("test_socket: Invalid MAC address '%s' in ASSOC\n",
520 pos2 = strchr(pos, ' ');
523 ssid_len = (pos2 - pos) / 2;
524 if (hexstr2bin(pos, ssid, ssid_len) < 0) {
525 wpa_printf(MSG_DEBUG, "%s: Invalid SSID", __func__);
529 wpa_hexdump_ascii(MSG_DEBUG, "test_driver_assoc: SSID",
533 ielen = strlen(pos) / 2;
534 if (ielen > sizeof(ie))
536 if (hexstr2bin(pos, ie, ielen) < 0)
540 for (bss = drv->bss; bss; bss = bss->next) {
541 if (bss->ssid_len == ssid_len &&
542 memcmp(bss->ssid, ssid, ssid_len) == 0)
546 wpa_printf(MSG_DEBUG, "%s: No matching SSID found from "
547 "configured BSSes", __func__);
553 memcpy(&cli->un, from, sizeof(cli->un));
554 cli->unlen = fromlen;
555 cli->next = drv->cli;
557 wpa_hexdump_ascii(MSG_DEBUG, "test_socket: ASSOC sun_path",
558 (const u8 *) cli->un.sun_path,
559 cli->unlen - sizeof(cli->un.sun_family));
561 snprintf(cmd, sizeof(cmd), "ASSOCRESP " MACSTR " 0",
562 MAC2STR(bss->bssid));
563 sendto(drv->test_socket, cmd, strlen(cmd), 0,
564 (struct sockaddr *) from, fromlen);
566 if (test_driver_new_sta(drv, bss, cli->addr, ie, ielen) < 0) {
567 wpa_printf(MSG_DEBUG, "test_driver: failed to add new STA");
572 static void test_driver_disassoc(struct test_driver_data *drv,
573 struct sockaddr_un *from, socklen_t fromlen)
575 struct test_client_socket *cli;
576 struct sta_info *sta;
578 cli = test_driver_get_cli(drv, from, fromlen);
582 hostapd_logger(drv->hapd, cli->addr, HOSTAPD_MODULE_IEEE80211,
583 HOSTAPD_LEVEL_INFO, "disassociated");
585 sta = ap_get_sta(drv->hapd, cli->addr);
587 sta->flags &= ~WLAN_STA_ASSOC;
588 wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);
589 sta->acct_terminate_cause =
590 RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
591 ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
592 ap_free_sta(drv->hapd, sta);
597 static void test_driver_eapol(struct test_driver_data *drv,
598 struct sockaddr_un *from, socklen_t fromlen,
599 u8 *data, size_t datalen)
601 struct test_client_socket *cli;
603 u8 *proto = data + 2 * ETH_ALEN;
604 /* Skip Ethernet header */
605 wpa_printf(MSG_DEBUG, "test_driver: dst=" MACSTR " src="
606 MACSTR " proto=%04x",
607 MAC2STR(data), MAC2STR(data + ETH_ALEN),
608 WPA_GET_BE16(proto));
612 cli = test_driver_get_cli(drv, from, fromlen);
614 struct hostapd_data *hapd;
615 hapd = test_driver_get_hapd(drv, cli->bss);
618 ieee802_1x_receive(hapd, cli->addr, data, datalen);
620 wpa_printf(MSG_DEBUG, "test_socket: EAPOL from unknown "
626 static void test_driver_ether(struct test_driver_data *drv,
627 struct sockaddr_un *from, socklen_t fromlen,
628 u8 *data, size_t datalen)
630 struct l2_ethhdr *eth;
632 if (datalen < sizeof(*eth))
635 eth = (struct l2_ethhdr *) data;
636 wpa_printf(MSG_DEBUG, "test_driver: RX ETHER dst=" MACSTR " src="
637 MACSTR " proto=%04x",
638 MAC2STR(eth->h_dest), MAC2STR(eth->h_source),
639 be_to_host16(eth->h_proto));
641 #ifdef CONFIG_IEEE80211R
642 if (be_to_host16(eth->h_proto) == ETH_P_RRB) {
643 wpa_ft_rrb_rx(drv->hapd->wpa_auth, eth->h_source,
644 data + sizeof(*eth), datalen - sizeof(*eth));
646 #endif /* CONFIG_IEEE80211R */
650 static void test_driver_mlme(struct test_driver_data *drv,
651 struct sockaddr_un *from, socklen_t fromlen,
652 u8 *data, size_t datalen)
654 struct ieee80211_hdr *hdr;
657 hdr = (struct ieee80211_hdr *) data;
659 if (test_driver_get_cli(drv, from, fromlen) == NULL && datalen >= 16) {
660 struct test_client_socket *cli;
661 cli = os_zalloc(sizeof(*cli));
664 wpa_printf(MSG_DEBUG, "Adding client entry for " MACSTR,
665 MAC2STR(hdr->addr2));
666 memcpy(cli->addr, hdr->addr2, ETH_ALEN);
667 memcpy(&cli->un, from, sizeof(cli->un));
668 cli->unlen = fromlen;
669 cli->next = drv->cli;
673 wpa_hexdump(MSG_MSGDUMP, "test_driver_mlme: received frame",
675 fc = le_to_host16(hdr->frame_control);
676 if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT) {
677 wpa_printf(MSG_ERROR, "%s: received non-mgmt frame",
681 ieee802_11_mgmt(drv->hapd, data, datalen, WLAN_FC_GET_STYPE(fc), NULL);
685 static void test_driver_receive_unix(int sock, void *eloop_ctx, void *sock_ctx)
687 struct test_driver_data *drv = eloop_ctx;
690 struct sockaddr_un from;
691 socklen_t fromlen = sizeof(from);
693 res = recvfrom(sock, buf, sizeof(buf) - 1, 0,
694 (struct sockaddr *) &from, &fromlen);
696 perror("recvfrom(test_socket)");
701 wpa_printf(MSG_DEBUG, "test_driver: received %u bytes", res);
703 if (strncmp(buf, "SCAN", 4) == 0) {
704 test_driver_scan(drv, &from, fromlen, buf + 4);
705 } else if (strncmp(buf, "ASSOC ", 6) == 0) {
706 test_driver_assoc(drv, &from, fromlen, buf + 6);
707 } else if (strcmp(buf, "DISASSOC") == 0) {
708 test_driver_disassoc(drv, &from, fromlen);
709 } else if (strncmp(buf, "EAPOL ", 6) == 0) {
710 test_driver_eapol(drv, &from, fromlen, (u8 *) buf + 6,
712 } else if (strncmp(buf, "ETHER ", 6) == 0) {
713 test_driver_ether(drv, &from, fromlen, (u8 *) buf + 6,
715 } else if (strncmp(buf, "MLME ", 5) == 0) {
716 test_driver_mlme(drv, &from, fromlen, (u8 *) buf + 5, res - 5);
718 wpa_hexdump_ascii(MSG_DEBUG, "Unknown test_socket command",
724 static struct test_driver_bss *
725 test_driver_get_bss(struct test_driver_data *drv, const char *ifname)
727 struct test_driver_bss *bss;
729 for (bss = drv->bss; bss; bss = bss->next) {
730 if (strcmp(bss->ifname, ifname) == 0)
737 static int test_driver_set_generic_elem(const char *ifname, void *priv,
738 const u8 *elem, size_t elem_len)
740 struct test_driver_data *drv = priv;
741 struct test_driver_bss *bss;
743 bss = test_driver_get_bss(drv, ifname);
755 bss->ie = malloc(elem_len);
756 if (bss->ie == NULL) {
761 memcpy(bss->ie, elem, elem_len);
762 bss->ielen = elem_len;
767 static int test_driver_set_wps_beacon_ie(const char *ifname, void *priv,
768 const u8 *ie, size_t len)
770 struct test_driver_data *drv = priv;
771 struct test_driver_bss *bss;
773 wpa_hexdump(MSG_DEBUG, "test_driver: Beacon WPS IE", ie, len);
774 bss = test_driver_get_bss(drv, ifname);
778 free(bss->wps_beacon_ie);
781 bss->wps_beacon_ie = NULL;
782 bss->wps_beacon_ie_len = 0;
786 bss->wps_beacon_ie = malloc(len);
787 if (bss->wps_beacon_ie == NULL) {
788 bss->wps_beacon_ie_len = 0;
792 memcpy(bss->wps_beacon_ie, ie, len);
793 bss->wps_beacon_ie_len = len;
798 static int test_driver_set_wps_probe_resp_ie(const char *ifname, void *priv,
799 const u8 *ie, size_t len)
801 struct test_driver_data *drv = priv;
802 struct test_driver_bss *bss;
804 wpa_hexdump(MSG_DEBUG, "test_driver: ProbeResp WPS IE", ie, len);
805 bss = test_driver_get_bss(drv, ifname);
809 free(bss->wps_probe_resp_ie);
812 bss->wps_probe_resp_ie = NULL;
813 bss->wps_probe_resp_ie_len = 0;
817 bss->wps_probe_resp_ie = malloc(len);
818 if (bss->wps_probe_resp_ie == NULL) {
819 bss->wps_probe_resp_ie_len = 0;
823 memcpy(bss->wps_probe_resp_ie, ie, len);
824 bss->wps_probe_resp_ie_len = len;
829 static int test_driver_sta_deauth(void *priv, const u8 *addr, int reason)
831 struct test_driver_data *drv = priv;
832 struct test_client_socket *cli;
834 if (drv->test_socket < 0)
839 if (memcmp(cli->addr, addr, ETH_ALEN) == 0)
847 return sendto(drv->test_socket, "DEAUTH", 6, 0,
848 (struct sockaddr *) &cli->un, cli->unlen);
852 static int test_driver_sta_disassoc(void *priv, const u8 *addr, int reason)
854 struct test_driver_data *drv = priv;
855 struct test_client_socket *cli;
857 if (drv->test_socket < 0)
862 if (memcmp(cli->addr, addr, ETH_ALEN) == 0)
870 return sendto(drv->test_socket, "DISASSOC", 8, 0,
871 (struct sockaddr *) &cli->un, cli->unlen);
875 static struct hostapd_hw_modes *
876 test_driver_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags)
878 struct hostapd_hw_modes *modes;
882 modes = os_zalloc(*num_modes * sizeof(struct hostapd_hw_modes));
885 modes[0].mode = HOSTAPD_MODE_IEEE80211G;
886 modes[0].num_channels = 1;
887 modes[0].num_rates = 1;
888 modes[0].channels = os_zalloc(sizeof(struct hostapd_channel_data));
889 modes[0].rates = os_zalloc(sizeof(struct hostapd_rate_data));
890 if (modes[0].channels == NULL || modes[0].rates == NULL) {
891 hostapd_free_hw_features(modes, *num_modes);
894 modes[0].channels[0].chan = 1;
895 modes[0].channels[0].freq = 2412;
896 modes[0].channels[0].flag = 0;
897 modes[0].rates[0].rate = 10;
898 modes[0].rates[0].flags = HOSTAPD_RATE_BASIC | HOSTAPD_RATE_SUPPORTED |
899 HOSTAPD_RATE_CCK | HOSTAPD_RATE_MANDATORY;
901 modes[1].mode = HOSTAPD_MODE_IEEE80211B;
902 modes[1].num_channels = 1;
903 modes[1].num_rates = 1;
904 modes[1].channels = os_zalloc(sizeof(struct hostapd_channel_data));
905 modes[1].rates = os_zalloc(sizeof(struct hostapd_rate_data));
906 if (modes[1].channels == NULL || modes[1].rates == NULL) {
907 hostapd_free_hw_features(modes, *num_modes);
910 modes[1].channels[0].chan = 1;
911 modes[1].channels[0].freq = 2412;
912 modes[1].channels[0].flag = 0;
913 modes[1].rates[0].rate = 10;
914 modes[1].rates[0].flags = HOSTAPD_RATE_BASIC | HOSTAPD_RATE_SUPPORTED |
915 HOSTAPD_RATE_CCK | HOSTAPD_RATE_MANDATORY;
917 modes[2].mode = HOSTAPD_MODE_IEEE80211A;
918 modes[2].num_channels = 1;
919 modes[2].num_rates = 1;
920 modes[2].channels = os_zalloc(sizeof(struct hostapd_channel_data));
921 modes[2].rates = os_zalloc(sizeof(struct hostapd_rate_data));
922 if (modes[2].channels == NULL || modes[2].rates == NULL) {
923 hostapd_free_hw_features(modes, *num_modes);
926 modes[2].channels[0].chan = 60;
927 modes[2].channels[0].freq = 5300;
928 modes[2].channels[0].flag = 0;
929 modes[2].rates[0].rate = 60;
930 modes[2].rates[0].flags = HOSTAPD_RATE_BASIC | HOSTAPD_RATE_SUPPORTED |
931 HOSTAPD_RATE_MANDATORY;
937 static int test_driver_bss_add(void *priv, const char *ifname, const u8 *bssid)
939 struct test_driver_data *drv = priv;
940 struct test_driver_bss *bss;
942 wpa_printf(MSG_DEBUG, "%s(ifname=%s bssid=" MACSTR ")",
943 __func__, ifname, MAC2STR(bssid));
945 bss = os_zalloc(sizeof(*bss));
949 os_strlcpy(bss->ifname, ifname, IFNAMSIZ);
950 memcpy(bss->bssid, bssid, ETH_ALEN);
952 bss->next = drv->bss;
959 static int test_driver_bss_remove(void *priv, const char *ifname)
961 struct test_driver_data *drv = priv;
962 struct test_driver_bss *bss, *prev;
963 struct test_client_socket *cli, *prev_c;
965 wpa_printf(MSG_DEBUG, "%s(ifname=%s)", __func__, ifname);
967 for (prev = NULL, bss = drv->bss; bss; prev = bss, bss = bss->next) {
968 if (strcmp(bss->ifname, ifname) != 0)
972 prev->next = bss->next;
974 drv->bss = bss->next;
976 for (prev_c = NULL, cli = drv->cli; cli;
977 prev_c = cli, cli = cli->next) {
981 prev_c->next = cli->next;
983 drv->cli = cli->next;
988 test_driver_free_bss(bss);
996 static int test_driver_if_add(const char *iface, void *priv,
997 enum hostapd_driver_if_type type, char *ifname,
1000 wpa_printf(MSG_DEBUG, "%s(iface=%s type=%d ifname=%s)",
1001 __func__, iface, type, ifname);
1006 static int test_driver_if_update(void *priv, enum hostapd_driver_if_type type,
1007 char *ifname, const u8 *addr)
1009 wpa_printf(MSG_DEBUG, "%s(type=%d ifname=%s)", __func__, type, ifname);
1014 static int test_driver_if_remove(void *priv, enum hostapd_driver_if_type type,
1015 const char *ifname, const u8 *addr)
1017 wpa_printf(MSG_DEBUG, "%s(type=%d ifname=%s)", __func__, type, ifname);
1022 static int test_driver_valid_bss_mask(void *priv, const u8 *addr,
1029 static int test_driver_set_ssid(const char *ifname, void *priv, const u8 *buf,
1032 struct test_driver_data *drv = priv;
1033 struct test_driver_bss *bss;
1035 wpa_printf(MSG_DEBUG, "%s(ifname=%s)", __func__, ifname);
1036 wpa_hexdump_ascii(MSG_DEBUG, "test_driver_set_ssid: SSID", buf, len);
1038 for (bss = drv->bss; bss; bss = bss->next) {
1039 if (strcmp(bss->ifname, ifname) != 0)
1042 if (len < 0 || (size_t) len > sizeof(bss->ssid))
1045 memcpy(bss->ssid, buf, len);
1046 bss->ssid_len = len;
1055 static int test_driver_set_privacy(const char *ifname, void *priv, int enabled)
1057 struct test_driver_data *drv = priv;
1058 struct test_driver_bss *bss;
1060 wpa_printf(MSG_DEBUG, "%s(ifname=%s enabled=%d)",
1061 __func__, ifname, enabled);
1063 for (bss = drv->bss; bss; bss = bss->next) {
1064 if (strcmp(bss->ifname, ifname) != 0)
1067 bss->privacy = enabled;
1076 static int test_driver_set_encryption(const char *iface, void *priv,
1077 const char *alg, const u8 *addr, int idx,
1078 const u8 *key, size_t key_len, int txkey)
1080 wpa_printf(MSG_DEBUG, "%s(iface=%s alg=%s idx=%d txkey=%d)",
1081 __func__, iface, alg, idx, txkey);
1083 wpa_printf(MSG_DEBUG, " addr=" MACSTR, MAC2STR(addr));
1085 wpa_hexdump_key(MSG_DEBUG, " key", key, key_len);
1090 static int test_driver_set_sta_vlan(void *priv, const u8 *addr,
1091 const char *ifname, int vlan_id)
1093 wpa_printf(MSG_DEBUG, "%s(addr=" MACSTR " ifname=%s vlan_id=%d)",
1094 __func__, MAC2STR(addr), ifname, vlan_id);
1099 static int test_driver_sta_add(const char *ifname, void *priv, const u8 *addr,
1100 u16 aid, u16 capability, u8 *supp_rates,
1101 size_t supp_rates_len, int flags,
1102 u16 listen_interval)
1104 struct test_driver_data *drv = priv;
1105 struct test_client_socket *cli;
1106 struct test_driver_bss *bss;
1108 wpa_printf(MSG_DEBUG, "%s(ifname=%s addr=" MACSTR " aid=%d "
1109 "capability=0x%x flags=0x%x listen_interval=%d)",
1110 __func__, ifname, MAC2STR(addr), aid, capability, flags,
1112 wpa_hexdump(MSG_DEBUG, "test_driver_sta_add - supp_rates",
1113 supp_rates, supp_rates_len);
1117 if (memcmp(cli->addr, addr, ETH_ALEN) == 0)
1122 wpa_printf(MSG_DEBUG, "%s: no matching client entry",
1127 for (bss = drv->bss; bss; bss = bss->next) {
1128 if (strcmp(ifname, bss->ifname) == 0)
1132 wpa_printf(MSG_DEBUG, "%s: No matching interface found from "
1133 "configured BSSes", __func__);
1143 static void * test_driver_init(struct hostapd_data *hapd)
1145 struct test_driver_data *drv;
1146 struct sockaddr_un addr_un;
1147 struct sockaddr_in addr_in;
1148 struct sockaddr *addr;
1151 drv = os_zalloc(sizeof(struct test_driver_data));
1153 printf("Could not allocate memory for test driver data\n");
1156 drv->bss = os_zalloc(sizeof(*drv->bss));
1157 if (drv->bss == NULL) {
1158 printf("Could not allocate memory for test driver BSS data\n");
1165 /* Generate a MAC address to help testing with multiple APs */
1166 hapd->own_addr[0] = 0x02; /* locally administered */
1167 sha1_prf((const u8 *) hapd->conf->iface, strlen(hapd->conf->iface),
1168 "hostapd test bssid generation",
1169 (const u8 *) hapd->conf->ssid.ssid, hapd->conf->ssid.ssid_len,
1170 hapd->own_addr + 1, ETH_ALEN - 1);
1172 os_strlcpy(drv->bss->ifname, hapd->conf->iface, IFNAMSIZ);
1173 memcpy(drv->bss->bssid, hapd->own_addr, ETH_ALEN);
1175 if (hapd->conf->test_socket) {
1176 if (strlen(hapd->conf->test_socket) >=
1177 sizeof(addr_un.sun_path)) {
1178 printf("Too long test_socket path\n");
1179 test_driver_free_priv(drv);
1182 if (strncmp(hapd->conf->test_socket, "DIR:", 4) == 0) {
1183 size_t len = strlen(hapd->conf->test_socket) + 30;
1184 drv->socket_dir = strdup(hapd->conf->test_socket + 4);
1185 drv->own_socket_path = malloc(len);
1186 if (drv->own_socket_path) {
1187 snprintf(drv->own_socket_path, len,
1189 hapd->conf->test_socket + 4,
1190 MAC2STR(hapd->own_addr));
1192 } else if (strncmp(hapd->conf->test_socket, "UDP:", 4) == 0) {
1193 drv->udp_port = atoi(hapd->conf->test_socket + 4);
1195 drv->own_socket_path = strdup(hapd->conf->test_socket);
1197 if (drv->own_socket_path == NULL && drv->udp_port == 0) {
1198 test_driver_free_priv(drv);
1202 drv->test_socket = socket(drv->udp_port ? PF_INET : PF_UNIX,
1204 if (drv->test_socket < 0) {
1206 test_driver_free_priv(drv);
1210 if (drv->udp_port) {
1211 os_memset(&addr_in, 0, sizeof(addr_in));
1212 addr_in.sin_family = AF_INET;
1213 addr_in.sin_port = htons(drv->udp_port);
1214 addr = (struct sockaddr *) &addr_in;
1215 alen = sizeof(addr_in);
1217 os_memset(&addr_un, 0, sizeof(addr_un));
1218 addr_un.sun_family = AF_UNIX;
1219 os_strlcpy(addr_un.sun_path, drv->own_socket_path,
1220 sizeof(addr_un.sun_path));
1221 addr = (struct sockaddr *) &addr_un;
1222 alen = sizeof(addr_un);
1224 if (bind(drv->test_socket, addr, alen) < 0) {
1225 perror("bind(PF_UNIX)");
1226 close(drv->test_socket);
1227 if (drv->own_socket_path)
1228 unlink(drv->own_socket_path);
1229 test_driver_free_priv(drv);
1232 eloop_register_read_sock(drv->test_socket,
1233 test_driver_receive_unix, drv, NULL);
1235 drv->test_socket = -1;
1241 static void test_driver_deinit(void *priv)
1243 struct test_driver_data *drv = priv;
1244 struct test_client_socket *cli, *prev;
1253 if (drv->test_socket >= 0) {
1254 eloop_unregister_read_sock(drv->test_socket);
1255 close(drv->test_socket);
1256 if (drv->own_socket_path)
1257 unlink(drv->own_socket_path);
1260 /* There should be only one BSS remaining at this point. */
1261 if (drv->bss == NULL)
1262 wpa_printf(MSG_ERROR, "%s: drv->bss == NULL", __func__);
1263 else if (drv->bss->next)
1264 wpa_printf(MSG_ERROR, "%s: drv->bss->next != NULL", __func__);
1266 test_driver_free_priv(drv);
1270 const struct wpa_driver_ops wpa_driver_test_ops = {
1272 .init = test_driver_init,
1273 .deinit = test_driver_deinit,
1274 .send_eapol = test_driver_send_eapol,
1275 .send_mgmt_frame = test_driver_send_mgmt_frame,
1276 .set_generic_elem = test_driver_set_generic_elem,
1277 .sta_deauth = test_driver_sta_deauth,
1278 .sta_disassoc = test_driver_sta_disassoc,
1279 .get_hw_feature_data = test_driver_get_hw_feature_data,
1280 .bss_add = test_driver_bss_add,
1281 .bss_remove = test_driver_bss_remove,
1282 .if_add = test_driver_if_add,
1283 .if_update = test_driver_if_update,
1284 .if_remove = test_driver_if_remove,
1285 .valid_bss_mask = test_driver_valid_bss_mask,
1286 .set_ssid = test_driver_set_ssid,
1287 .set_privacy = test_driver_set_privacy,
1288 .set_encryption = test_driver_set_encryption,
1289 .set_sta_vlan = test_driver_set_sta_vlan,
1290 .sta_add = test_driver_sta_add,
1291 .send_ether = test_driver_send_ether,
1292 .set_wps_beacon_ie = test_driver_set_wps_beacon_ie,
1293 .set_wps_probe_resp_ie = test_driver_set_wps_probe_resp_ie,