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
= host_to_be16(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
= host_to_be16(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 (hapd
->conf
->wps_state
&& ie
[0] == 0xdd && ie
[1] >= 4 &&
466 os_memcmp(ie
+ 2, "\x00\x50\xf2\x04", 4) == 0) {
467 sta
->flags
|= WLAN_STA_WPS
;
471 if (sta
->wpa_sm
== NULL
)
472 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
474 if (sta
->wpa_sm
== NULL
) {
475 printf("test_driver: Failed to initialize WPA state "
479 res
= wpa_validate_wpa_ie(hapd
->wpa_auth
, sta
->wpa_sm
,
481 if (res
!= WPA_IE_OK
) {
482 printf("WPA/RSN information element rejected? "
484 wpa_hexdump(MSG_DEBUG
, "IE", ie
, ielen
);
490 new_assoc
= (sta
->flags
& WLAN_STA_ASSOC
) == 0;
491 sta
->flags
|= WLAN_STA_AUTH
| WLAN_STA_ASSOC
;
492 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC
);
494 hostapd_new_assoc_sta(hapd
, sta
, !new_assoc
);
496 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 1);
502 static void test_driver_assoc(struct test_driver_data
*drv
,
503 struct sockaddr_un
*from
, socklen_t fromlen
,
506 struct test_client_socket
*cli
;
507 u8 ie
[256], ssid
[32];
508 size_t ielen
, ssid_len
= 0;
509 char *pos
, *pos2
, cmd
[50];
510 struct test_driver_bss
*bss
;
512 /* data: STA-addr SSID(hex) IEs(hex) */
514 cli
= os_zalloc(sizeof(*cli
));
518 if (hwaddr_aton(data
, cli
->addr
)) {
519 printf("test_socket: Invalid MAC address '%s' in ASSOC\n",
527 pos2
= strchr(pos
, ' ');
530 ssid_len
= (pos2
- pos
) / 2;
531 if (hexstr2bin(pos
, ssid
, ssid_len
) < 0) {
532 wpa_printf(MSG_DEBUG
, "%s: Invalid SSID", __func__
);
536 wpa_hexdump_ascii(MSG_DEBUG
, "test_driver_assoc: SSID",
540 ielen
= strlen(pos
) / 2;
541 if (ielen
> sizeof(ie
))
543 if (hexstr2bin(pos
, ie
, ielen
) < 0)
547 for (bss
= drv
->bss
; bss
; bss
= bss
->next
) {
548 if (bss
->ssid_len
== ssid_len
&&
549 memcmp(bss
->ssid
, ssid
, ssid_len
) == 0)
553 wpa_printf(MSG_DEBUG
, "%s: No matching SSID found from "
554 "configured BSSes", __func__
);
560 memcpy(&cli
->un
, from
, sizeof(cli
->un
));
561 cli
->unlen
= fromlen
;
562 cli
->next
= drv
->cli
;
564 wpa_hexdump_ascii(MSG_DEBUG
, "test_socket: ASSOC sun_path",
565 (const u8
*) cli
->un
.sun_path
,
566 cli
->unlen
- sizeof(cli
->un
.sun_family
));
568 snprintf(cmd
, sizeof(cmd
), "ASSOCRESP " MACSTR
" 0",
569 MAC2STR(bss
->bssid
));
570 sendto(drv
->test_socket
, cmd
, strlen(cmd
), 0,
571 (struct sockaddr
*) from
, fromlen
);
573 if (test_driver_new_sta(drv
, bss
, cli
->addr
, ie
, ielen
) < 0) {
574 wpa_printf(MSG_DEBUG
, "test_driver: failed to add new STA");
579 static void test_driver_disassoc(struct test_driver_data
*drv
,
580 struct sockaddr_un
*from
, socklen_t fromlen
)
582 struct test_client_socket
*cli
;
583 struct sta_info
*sta
;
585 cli
= test_driver_get_cli(drv
, from
, fromlen
);
589 hostapd_logger(drv
->hapd
, cli
->addr
, HOSTAPD_MODULE_IEEE80211
,
590 HOSTAPD_LEVEL_INFO
, "disassociated");
592 sta
= ap_get_sta(drv
->hapd
, cli
->addr
);
594 sta
->flags
&= ~WLAN_STA_ASSOC
;
595 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DISASSOC
);
596 sta
->acct_terminate_cause
=
597 RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
598 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
599 ap_free_sta(drv
->hapd
, sta
);
604 static void test_driver_eapol(struct test_driver_data
*drv
,
605 struct sockaddr_un
*from
, socklen_t fromlen
,
606 u8
*data
, size_t datalen
)
608 struct test_client_socket
*cli
;
610 /* Skip Ethernet header */
611 wpa_printf(MSG_DEBUG
, "test_driver: dst=" MACSTR
" src="
612 MACSTR
" proto=%04x",
613 MAC2STR(data
), MAC2STR(data
+ ETH_ALEN
),
614 WPA_GET_BE16(data
+ 2 * ETH_ALEN
));
618 cli
= test_driver_get_cli(drv
, from
, fromlen
);
620 struct hostapd_data
*hapd
;
621 hapd
= test_driver_get_hapd(drv
, cli
->bss
);
624 ieee802_1x_receive(hapd
, cli
->addr
, data
, datalen
);
626 wpa_printf(MSG_DEBUG
, "test_socket: EAPOL from unknown "
632 static void test_driver_ether(struct test_driver_data
*drv
,
633 struct sockaddr_un
*from
, socklen_t fromlen
,
634 u8
*data
, size_t datalen
)
636 struct l2_ethhdr
*eth
;
638 if (datalen
< sizeof(*eth
))
641 eth
= (struct l2_ethhdr
*) data
;
642 wpa_printf(MSG_DEBUG
, "test_driver: RX ETHER dst=" MACSTR
" src="
643 MACSTR
" proto=%04x",
644 MAC2STR(eth
->h_dest
), MAC2STR(eth
->h_source
),
645 be_to_host16(eth
->h_proto
));
647 #ifdef CONFIG_IEEE80211R
648 if (be_to_host16(eth
->h_proto
) == ETH_P_RRB
) {
649 wpa_ft_rrb_rx(drv
->hapd
->wpa_auth
, eth
->h_source
,
650 data
+ sizeof(*eth
), datalen
- sizeof(*eth
));
652 #endif /* CONFIG_IEEE80211R */
656 static void test_driver_mlme(struct test_driver_data
*drv
,
657 struct sockaddr_un
*from
, socklen_t fromlen
,
658 u8
*data
, size_t datalen
)
660 struct ieee80211_hdr
*hdr
;
663 hdr
= (struct ieee80211_hdr
*) data
;
665 if (test_driver_get_cli(drv
, from
, fromlen
) == NULL
&& datalen
>= 16) {
666 struct test_client_socket
*cli
;
667 cli
= os_zalloc(sizeof(*cli
));
670 wpa_printf(MSG_DEBUG
, "Adding client entry for " MACSTR
,
671 MAC2STR(hdr
->addr2
));
672 memcpy(cli
->addr
, hdr
->addr2
, ETH_ALEN
);
673 memcpy(&cli
->un
, from
, sizeof(cli
->un
));
674 cli
->unlen
= fromlen
;
675 cli
->next
= drv
->cli
;
679 wpa_hexdump(MSG_MSGDUMP
, "test_driver_mlme: received frame",
681 fc
= le_to_host16(hdr
->frame_control
);
682 if (WLAN_FC_GET_TYPE(fc
) != WLAN_FC_TYPE_MGMT
) {
683 wpa_printf(MSG_ERROR
, "%s: received non-mgmt frame",
687 ieee802_11_mgmt(drv
->hapd
, data
, datalen
, WLAN_FC_GET_STYPE(fc
), NULL
);
691 static void test_driver_receive_unix(int sock
, void *eloop_ctx
, void *sock_ctx
)
693 struct test_driver_data
*drv
= eloop_ctx
;
696 struct sockaddr_un from
;
697 socklen_t fromlen
= sizeof(from
);
699 res
= recvfrom(sock
, buf
, sizeof(buf
) - 1, 0,
700 (struct sockaddr
*) &from
, &fromlen
);
702 perror("recvfrom(test_socket)");
707 wpa_printf(MSG_DEBUG
, "test_driver: received %u bytes", res
);
709 if (strncmp(buf
, "SCAN", 4) == 0) {
710 test_driver_scan(drv
, &from
, fromlen
, buf
+ 4);
711 } else if (strncmp(buf
, "ASSOC ", 6) == 0) {
712 test_driver_assoc(drv
, &from
, fromlen
, buf
+ 6);
713 } else if (strcmp(buf
, "DISASSOC") == 0) {
714 test_driver_disassoc(drv
, &from
, fromlen
);
715 } else if (strncmp(buf
, "EAPOL ", 6) == 0) {
716 test_driver_eapol(drv
, &from
, fromlen
, (u8
*) buf
+ 6,
718 } else if (strncmp(buf
, "ETHER ", 6) == 0) {
719 test_driver_ether(drv
, &from
, fromlen
, (u8
*) buf
+ 6,
721 } else if (strncmp(buf
, "MLME ", 5) == 0) {
722 test_driver_mlme(drv
, &from
, fromlen
, (u8
*) buf
+ 5, res
- 5);
724 wpa_hexdump_ascii(MSG_DEBUG
, "Unknown test_socket command",
730 static struct test_driver_bss
*
731 test_driver_get_bss(struct test_driver_data
*drv
, const char *ifname
)
733 struct test_driver_bss
*bss
;
735 for (bss
= drv
->bss
; bss
; bss
= bss
->next
) {
736 if (strcmp(bss
->ifname
, ifname
) == 0)
743 static int test_driver_set_generic_elem(const char *ifname
, void *priv
,
744 const u8
*elem
, size_t elem_len
)
746 struct test_driver_data
*drv
= priv
;
747 struct test_driver_bss
*bss
;
749 bss
= test_driver_get_bss(drv
, ifname
);
761 bss
->ie
= malloc(elem_len
);
762 if (bss
->ie
== NULL
) {
767 memcpy(bss
->ie
, elem
, elem_len
);
768 bss
->ielen
= elem_len
;
773 static int test_driver_set_wps_beacon_ie(const char *ifname
, void *priv
,
774 const u8
*ie
, size_t len
)
776 struct test_driver_data
*drv
= priv
;
777 struct test_driver_bss
*bss
;
779 wpa_hexdump(MSG_DEBUG
, "test_driver: Beacon WPS IE", ie
, len
);
780 bss
= test_driver_get_bss(drv
, ifname
);
784 free(bss
->wps_beacon_ie
);
787 bss
->wps_beacon_ie
= NULL
;
788 bss
->wps_beacon_ie_len
= 0;
792 bss
->wps_beacon_ie
= malloc(len
);
793 if (bss
->wps_beacon_ie
== NULL
) {
794 bss
->wps_beacon_ie_len
= 0;
798 memcpy(bss
->wps_beacon_ie
, ie
, len
);
799 bss
->wps_beacon_ie_len
= len
;
804 static int test_driver_set_wps_probe_resp_ie(const char *ifname
, void *priv
,
805 const u8
*ie
, size_t len
)
807 struct test_driver_data
*drv
= priv
;
808 struct test_driver_bss
*bss
;
810 wpa_hexdump(MSG_DEBUG
, "test_driver: ProbeResp WPS IE", ie
, len
);
811 bss
= test_driver_get_bss(drv
, ifname
);
815 free(bss
->wps_probe_resp_ie
);
818 bss
->wps_probe_resp_ie
= NULL
;
819 bss
->wps_probe_resp_ie_len
= 0;
823 bss
->wps_probe_resp_ie
= malloc(len
);
824 if (bss
->wps_probe_resp_ie
== NULL
) {
825 bss
->wps_probe_resp_ie_len
= 0;
829 memcpy(bss
->wps_probe_resp_ie
, ie
, len
);
830 bss
->wps_probe_resp_ie_len
= len
;
835 static int test_driver_sta_deauth(void *priv
, const u8
*addr
, int reason
)
837 struct test_driver_data
*drv
= priv
;
838 struct test_client_socket
*cli
;
840 if (drv
->test_socket
< 0)
845 if (memcmp(cli
->addr
, addr
, ETH_ALEN
) == 0)
853 return sendto(drv
->test_socket
, "DEAUTH", 6, 0,
854 (struct sockaddr
*) &cli
->un
, cli
->unlen
);
858 static int test_driver_sta_disassoc(void *priv
, const u8
*addr
, int reason
)
860 struct test_driver_data
*drv
= priv
;
861 struct test_client_socket
*cli
;
863 if (drv
->test_socket
< 0)
868 if (memcmp(cli
->addr
, addr
, ETH_ALEN
) == 0)
876 return sendto(drv
->test_socket
, "DISASSOC", 8, 0,
877 (struct sockaddr
*) &cli
->un
, cli
->unlen
);
881 static struct hostapd_hw_modes
*
882 test_driver_get_hw_feature_data(void *priv
, u16
*num_modes
, u16
*flags
)
884 struct hostapd_hw_modes
*modes
;
888 modes
= os_zalloc(*num_modes
* sizeof(struct hostapd_hw_modes
));
891 modes
[0].mode
= HOSTAPD_MODE_IEEE80211G
;
892 modes
[0].num_channels
= 1;
893 modes
[0].num_rates
= 1;
894 modes
[0].channels
= os_zalloc(sizeof(struct hostapd_channel_data
));
895 modes
[0].rates
= os_zalloc(sizeof(struct hostapd_rate_data
));
896 if (modes
[0].channels
== NULL
|| modes
[0].rates
== NULL
) {
897 hostapd_free_hw_features(modes
, *num_modes
);
900 modes
[0].channels
[0].chan
= 1;
901 modes
[0].channels
[0].freq
= 2412;
902 modes
[0].channels
[0].flag
= 0;
903 modes
[0].rates
[0].rate
= 10;
904 modes
[0].rates
[0].flags
= HOSTAPD_RATE_BASIC
| HOSTAPD_RATE_SUPPORTED
|
905 HOSTAPD_RATE_CCK
| HOSTAPD_RATE_MANDATORY
;
907 modes
[1].mode
= HOSTAPD_MODE_IEEE80211B
;
908 modes
[1].num_channels
= 1;
909 modes
[1].num_rates
= 1;
910 modes
[1].channels
= os_zalloc(sizeof(struct hostapd_channel_data
));
911 modes
[1].rates
= os_zalloc(sizeof(struct hostapd_rate_data
));
912 if (modes
[1].channels
== NULL
|| modes
[1].rates
== NULL
) {
913 hostapd_free_hw_features(modes
, *num_modes
);
916 modes
[1].channels
[0].chan
= 1;
917 modes
[1].channels
[0].freq
= 2412;
918 modes
[1].channels
[0].flag
= 0;
919 modes
[1].rates
[0].rate
= 10;
920 modes
[1].rates
[0].flags
= HOSTAPD_RATE_BASIC
| HOSTAPD_RATE_SUPPORTED
|
921 HOSTAPD_RATE_CCK
| HOSTAPD_RATE_MANDATORY
;
923 modes
[2].mode
= HOSTAPD_MODE_IEEE80211A
;
924 modes
[2].num_channels
= 1;
925 modes
[2].num_rates
= 1;
926 modes
[2].channels
= os_zalloc(sizeof(struct hostapd_channel_data
));
927 modes
[2].rates
= os_zalloc(sizeof(struct hostapd_rate_data
));
928 if (modes
[2].channels
== NULL
|| modes
[2].rates
== NULL
) {
929 hostapd_free_hw_features(modes
, *num_modes
);
932 modes
[2].channels
[0].chan
= 60;
933 modes
[2].channels
[0].freq
= 5300;
934 modes
[2].channels
[0].flag
= 0;
935 modes
[2].rates
[0].rate
= 60;
936 modes
[2].rates
[0].flags
= HOSTAPD_RATE_BASIC
| HOSTAPD_RATE_SUPPORTED
|
937 HOSTAPD_RATE_MANDATORY
;
943 static int test_driver_bss_add(void *priv
, const char *ifname
, const u8
*bssid
)
945 struct test_driver_data
*drv
= priv
;
946 struct test_driver_bss
*bss
;
948 wpa_printf(MSG_DEBUG
, "%s(ifname=%s bssid=" MACSTR
")",
949 __func__
, ifname
, MAC2STR(bssid
));
951 bss
= os_zalloc(sizeof(*bss
));
955 os_strlcpy(bss
->ifname
, ifname
, IFNAMSIZ
);
956 memcpy(bss
->bssid
, bssid
, ETH_ALEN
);
958 bss
->next
= drv
->bss
;
965 static int test_driver_bss_remove(void *priv
, const char *ifname
)
967 struct test_driver_data
*drv
= priv
;
968 struct test_driver_bss
*bss
, *prev
;
969 struct test_client_socket
*cli
, *prev_c
;
971 wpa_printf(MSG_DEBUG
, "%s(ifname=%s)", __func__
, ifname
);
973 for (prev
= NULL
, bss
= drv
->bss
; bss
; prev
= bss
, bss
= bss
->next
) {
974 if (strcmp(bss
->ifname
, ifname
) != 0)
978 prev
->next
= bss
->next
;
980 drv
->bss
= bss
->next
;
982 for (prev_c
= NULL
, cli
= drv
->cli
; cli
;
983 prev_c
= cli
, cli
= cli
->next
) {
987 prev_c
->next
= cli
->next
;
989 drv
->cli
= cli
->next
;
994 test_driver_free_bss(bss
);
1002 static int test_driver_if_add(const char *iface
, void *priv
,
1003 enum hostapd_driver_if_type type
, char *ifname
,
1006 wpa_printf(MSG_DEBUG
, "%s(iface=%s type=%d ifname=%s)",
1007 __func__
, iface
, type
, ifname
);
1012 static int test_driver_if_update(void *priv
, enum hostapd_driver_if_type type
,
1013 char *ifname
, const u8
*addr
)
1015 wpa_printf(MSG_DEBUG
, "%s(type=%d ifname=%s)", __func__
, type
, ifname
);
1020 static int test_driver_if_remove(void *priv
, enum hostapd_driver_if_type type
,
1021 const char *ifname
, const u8
*addr
)
1023 wpa_printf(MSG_DEBUG
, "%s(type=%d ifname=%s)", __func__
, type
, ifname
);
1028 static int test_driver_valid_bss_mask(void *priv
, const u8
*addr
,
1035 static int test_driver_set_ssid(const char *ifname
, void *priv
, const u8
*buf
,
1038 struct test_driver_data
*drv
= priv
;
1039 struct test_driver_bss
*bss
;
1041 wpa_printf(MSG_DEBUG
, "%s(ifname=%s)", __func__
, ifname
);
1042 wpa_hexdump_ascii(MSG_DEBUG
, "test_driver_set_ssid: SSID", buf
, len
);
1044 for (bss
= drv
->bss
; bss
; bss
= bss
->next
) {
1045 if (strcmp(bss
->ifname
, ifname
) != 0)
1048 if (len
< 0 || (size_t) len
> sizeof(bss
->ssid
))
1051 memcpy(bss
->ssid
, buf
, len
);
1052 bss
->ssid_len
= len
;
1061 static int test_driver_set_privacy(const char *ifname
, void *priv
, int enabled
)
1063 struct test_driver_data
*drv
= priv
;
1064 struct test_driver_bss
*bss
;
1066 wpa_printf(MSG_DEBUG
, "%s(ifname=%s enabled=%d)",
1067 __func__
, ifname
, enabled
);
1069 for (bss
= drv
->bss
; bss
; bss
= bss
->next
) {
1070 if (strcmp(bss
->ifname
, ifname
) != 0)
1073 bss
->privacy
= enabled
;
1082 static int test_driver_set_encryption(const char *iface
, void *priv
,
1083 const char *alg
, const u8
*addr
, int idx
,
1084 const u8
*key
, size_t key_len
, int txkey
)
1086 wpa_printf(MSG_DEBUG
, "%s(iface=%s alg=%s idx=%d txkey=%d)",
1087 __func__
, iface
, alg
, idx
, txkey
);
1089 wpa_printf(MSG_DEBUG
, " addr=" MACSTR
, MAC2STR(addr
));
1091 wpa_hexdump_key(MSG_DEBUG
, " key", key
, key_len
);
1096 static int test_driver_set_sta_vlan(void *priv
, const u8
*addr
,
1097 const char *ifname
, int vlan_id
)
1099 wpa_printf(MSG_DEBUG
, "%s(addr=" MACSTR
" ifname=%s vlan_id=%d)",
1100 __func__
, MAC2STR(addr
), ifname
, vlan_id
);
1105 static int test_driver_sta_add(const char *ifname
, void *priv
, const u8
*addr
,
1106 u16 aid
, u16 capability
, u8
*supp_rates
,
1107 size_t supp_rates_len
, int flags
,
1108 u16 listen_interval
)
1110 struct test_driver_data
*drv
= priv
;
1111 struct test_client_socket
*cli
;
1112 struct test_driver_bss
*bss
;
1114 wpa_printf(MSG_DEBUG
, "%s(ifname=%s addr=" MACSTR
" aid=%d "
1115 "capability=0x%x flags=0x%x listen_interval=%d)",
1116 __func__
, ifname
, MAC2STR(addr
), aid
, capability
, flags
,
1118 wpa_hexdump(MSG_DEBUG
, "test_driver_sta_add - supp_rates",
1119 supp_rates
, supp_rates_len
);
1123 if (memcmp(cli
->addr
, addr
, ETH_ALEN
) == 0)
1128 wpa_printf(MSG_DEBUG
, "%s: no matching client entry",
1133 for (bss
= drv
->bss
; bss
; bss
= bss
->next
) {
1134 if (strcmp(ifname
, bss
->ifname
) == 0)
1138 wpa_printf(MSG_DEBUG
, "%s: No matching interface found from "
1139 "configured BSSes", __func__
);
1149 static void * test_driver_init(struct hostapd_data
*hapd
)
1151 struct test_driver_data
*drv
;
1152 struct sockaddr_un addr_un
;
1153 struct sockaddr_in addr_in
;
1154 struct sockaddr
*addr
;
1157 drv
= os_zalloc(sizeof(struct test_driver_data
));
1159 printf("Could not allocate memory for test driver data\n");
1162 drv
->bss
= os_zalloc(sizeof(*drv
->bss
));
1163 if (drv
->bss
== NULL
) {
1164 printf("Could not allocate memory for test driver BSS data\n");
1171 /* Generate a MAC address to help testing with multiple APs */
1172 hapd
->own_addr
[0] = 0x02; /* locally administered */
1173 sha1_prf((const u8
*) hapd
->conf
->iface
, strlen(hapd
->conf
->iface
),
1174 "hostapd test bssid generation",
1175 (const u8
*) hapd
->conf
->ssid
.ssid
, hapd
->conf
->ssid
.ssid_len
,
1176 hapd
->own_addr
+ 1, ETH_ALEN
- 1);
1178 os_strlcpy(drv
->bss
->ifname
, hapd
->conf
->iface
, IFNAMSIZ
);
1179 memcpy(drv
->bss
->bssid
, hapd
->own_addr
, ETH_ALEN
);
1181 if (hapd
->conf
->test_socket
) {
1182 if (strlen(hapd
->conf
->test_socket
) >=
1183 sizeof(addr_un
.sun_path
)) {
1184 printf("Too long test_socket path\n");
1185 test_driver_free_priv(drv
);
1188 if (strncmp(hapd
->conf
->test_socket
, "DIR:", 4) == 0) {
1189 size_t len
= strlen(hapd
->conf
->test_socket
) + 30;
1190 drv
->socket_dir
= strdup(hapd
->conf
->test_socket
+ 4);
1191 drv
->own_socket_path
= malloc(len
);
1192 if (drv
->own_socket_path
) {
1193 snprintf(drv
->own_socket_path
, len
,
1195 hapd
->conf
->test_socket
+ 4,
1196 MAC2STR(hapd
->own_addr
));
1198 } else if (strncmp(hapd
->conf
->test_socket
, "UDP:", 4) == 0) {
1199 drv
->udp_port
= atoi(hapd
->conf
->test_socket
+ 4);
1201 drv
->own_socket_path
= strdup(hapd
->conf
->test_socket
);
1203 if (drv
->own_socket_path
== NULL
&& drv
->udp_port
== 0) {
1204 test_driver_free_priv(drv
);
1208 drv
->test_socket
= socket(drv
->udp_port
? PF_INET
: PF_UNIX
,
1210 if (drv
->test_socket
< 0) {
1212 test_driver_free_priv(drv
);
1216 if (drv
->udp_port
) {
1217 os_memset(&addr_in
, 0, sizeof(addr_in
));
1218 addr_in
.sin_family
= AF_INET
;
1219 addr_in
.sin_port
= htons(drv
->udp_port
);
1220 addr
= (struct sockaddr
*) &addr_in
;
1221 alen
= sizeof(addr_in
);
1223 os_memset(&addr_un
, 0, sizeof(addr_un
));
1224 addr_un
.sun_family
= AF_UNIX
;
1225 os_strlcpy(addr_un
.sun_path
, drv
->own_socket_path
,
1226 sizeof(addr_un
.sun_path
));
1227 addr
= (struct sockaddr
*) &addr_un
;
1228 alen
= sizeof(addr_un
);
1230 if (bind(drv
->test_socket
, addr
, alen
) < 0) {
1231 perror("bind(PF_UNIX)");
1232 close(drv
->test_socket
);
1233 if (drv
->own_socket_path
)
1234 unlink(drv
->own_socket_path
);
1235 test_driver_free_priv(drv
);
1238 eloop_register_read_sock(drv
->test_socket
,
1239 test_driver_receive_unix
, drv
, NULL
);
1241 drv
->test_socket
= -1;
1247 static void test_driver_deinit(void *priv
)
1249 struct test_driver_data
*drv
= priv
;
1250 struct test_client_socket
*cli
, *prev
;
1259 if (drv
->test_socket
>= 0) {
1260 eloop_unregister_read_sock(drv
->test_socket
);
1261 close(drv
->test_socket
);
1262 if (drv
->own_socket_path
)
1263 unlink(drv
->own_socket_path
);
1266 /* There should be only one BSS remaining at this point. */
1267 if (drv
->bss
== NULL
)
1268 wpa_printf(MSG_ERROR
, "%s: drv->bss == NULL", __func__
);
1269 else if (drv
->bss
->next
)
1270 wpa_printf(MSG_ERROR
, "%s: drv->bss->next != NULL", __func__
);
1272 test_driver_free_priv(drv
);
1276 const struct wpa_driver_ops wpa_driver_test_ops
= {
1278 .init
= test_driver_init
,
1279 .deinit
= test_driver_deinit
,
1280 .send_eapol
= test_driver_send_eapol
,
1281 .send_mgmt_frame
= test_driver_send_mgmt_frame
,
1282 .set_generic_elem
= test_driver_set_generic_elem
,
1283 .sta_deauth
= test_driver_sta_deauth
,
1284 .sta_disassoc
= test_driver_sta_disassoc
,
1285 .get_hw_feature_data
= test_driver_get_hw_feature_data
,
1286 .bss_add
= test_driver_bss_add
,
1287 .bss_remove
= test_driver_bss_remove
,
1288 .if_add
= test_driver_if_add
,
1289 .if_update
= test_driver_if_update
,
1290 .if_remove
= test_driver_if_remove
,
1291 .valid_bss_mask
= test_driver_valid_bss_mask
,
1292 .set_ssid
= test_driver_set_ssid
,
1293 .set_privacy
= test_driver_set_privacy
,
1294 .set_encryption
= test_driver_set_encryption
,
1295 .set_sta_vlan
= test_driver_set_sta_vlan
,
1296 .sta_add
= test_driver_sta_add
,
1297 .send_ether
= test_driver_send_ether
,
1298 .set_wps_beacon_ie
= test_driver_set_wps_beacon_ie
,
1299 .set_wps_probe_resp_ie
= test_driver_set_wps_probe_resp_ie
,