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"
33 struct test_client_socket
{
34 struct test_client_socket
*next
;
36 struct sockaddr_un un
;
38 struct test_driver_bss
*bss
;
41 struct test_driver_bss
{
42 struct test_driver_bss
*next
;
43 char ifname
[IFNAMSIZ
+ 1];
52 struct test_driver_data
{
53 struct hostapd_data
*hapd
;
54 struct test_client_socket
*cli
;
56 struct test_driver_bss
*bss
;
58 char *own_socket_path
;
62 static void test_driver_free_bss(struct test_driver_bss
*bss
)
69 static void test_driver_free_priv(struct test_driver_data
*drv
)
71 struct test_driver_bss
*bss
, *prev
;
80 test_driver_free_bss(prev
);
82 free(drv
->own_socket_path
);
83 free(drv
->socket_dir
);
88 static struct test_client_socket
*
89 test_driver_get_cli(struct test_driver_data
*drv
, struct sockaddr_un
*from
,
92 struct test_client_socket
*cli
= drv
->cli
;
95 if (cli
->unlen
== fromlen
&&
96 strncmp(cli
->un
.sun_path
, from
->sun_path
,
97 fromlen
- sizeof(cli
->un
.sun_family
)) == 0)
106 static int test_driver_send_eapol(void *priv
, const u8
*addr
, const u8
*data
,
107 size_t data_len
, int encrypt
,
110 struct test_driver_data
*drv
= priv
;
111 struct test_client_socket
*cli
;
114 struct l2_ethhdr eth
;
116 if (drv
->test_socket
< 0)
121 if (memcmp(cli
->addr
, addr
, ETH_ALEN
) == 0)
127 wpa_printf(MSG_DEBUG
, "%s: no destination client entry",
132 memcpy(eth
.h_dest
, addr
, ETH_ALEN
);
133 memcpy(eth
.h_source
, own_addr
, ETH_ALEN
);
134 eth
.h_proto
= htons(ETH_P_EAPOL
);
136 io
[0].iov_base
= "EAPOL ";
138 io
[1].iov_base
= ð
;
139 io
[1].iov_len
= sizeof(eth
);
140 io
[2].iov_base
= (u8
*) data
;
141 io
[2].iov_len
= data_len
;
143 memset(&msg
, 0, sizeof(msg
));
146 msg
.msg_name
= &cli
->un
;
147 msg
.msg_namelen
= cli
->unlen
;
148 return sendmsg(drv
->test_socket
, &msg
, 0);
152 static int test_driver_send_ether(void *priv
, const u8
*dst
, const u8
*src
,
153 u16 proto
, const u8
*data
, size_t data_len
)
155 struct test_driver_data
*drv
= priv
;
158 struct l2_ethhdr eth
;
160 struct sockaddr_un addr
;
163 int ret
= 0, broadcast
= 0, count
= 0;
165 if (drv
->test_socket
< 0 || drv
->socket_dir
== NULL
) {
166 wpa_printf(MSG_DEBUG
, "%s: invalid parameters (sock=%d "
168 __func__
, drv
->test_socket
, drv
->socket_dir
);
172 broadcast
= memcmp(dst
, "\xff\xff\xff\xff\xff\xff", ETH_ALEN
) == 0;
173 snprintf(desttxt
, sizeof(desttxt
), MACSTR
, MAC2STR(dst
));
175 memcpy(eth
.h_dest
, dst
, ETH_ALEN
);
176 memcpy(eth
.h_source
, src
, ETH_ALEN
);
177 eth
.h_proto
= htons(proto
);
179 io
[0].iov_base
= "ETHER ";
181 io
[1].iov_base
= ð
;
182 io
[1].iov_len
= sizeof(eth
);
183 io
[2].iov_base
= (u8
*) data
;
184 io
[2].iov_len
= data_len
;
186 memset(&msg
, 0, sizeof(msg
));
190 dir
= opendir(drv
->socket_dir
);
192 perror("test_driver: opendir");
195 while ((dent
= readdir(dir
))) {
196 #ifdef _DIRENT_HAVE_D_TYPE
197 /* Skip the file if it is not a socket. Also accept
198 * DT_UNKNOWN (0) in case the C library or underlying file
199 * system does not support d_type. */
200 if (dent
->d_type
!= DT_SOCK
&& dent
->d_type
!= DT_UNKNOWN
)
202 #endif /* _DIRENT_HAVE_D_TYPE */
203 if (strcmp(dent
->d_name
, ".") == 0 ||
204 strcmp(dent
->d_name
, "..") == 0)
207 memset(&addr
, 0, sizeof(addr
));
208 addr
.sun_family
= AF_UNIX
;
209 snprintf(addr
.sun_path
, sizeof(addr
.sun_path
), "%s/%s",
210 drv
->socket_dir
, dent
->d_name
);
212 if (strcmp(addr
.sun_path
, drv
->own_socket_path
) == 0)
214 if (!broadcast
&& strstr(dent
->d_name
, desttxt
) == NULL
)
217 wpa_printf(MSG_DEBUG
, "%s: Send ether frame to %s",
218 __func__
, dent
->d_name
);
220 msg
.msg_name
= &addr
;
221 msg
.msg_namelen
= sizeof(addr
);
222 ret
= sendmsg(drv
->test_socket
, &msg
, 0);
224 perror("driver_test: sendmsg");
229 if (!broadcast
&& count
== 0) {
230 wpa_printf(MSG_DEBUG
, "%s: Destination " MACSTR
" not found",
231 __func__
, MAC2STR(dst
));
239 static int test_driver_send_mgmt_frame(void *priv
, const void *buf
,
240 size_t len
, int flags
)
242 struct test_driver_data
*drv
= priv
;
246 int ret
= 0, broadcast
= 0;
248 struct sockaddr_un addr
;
251 struct ieee80211_hdr
*hdr
;
254 if (drv
->test_socket
< 0 || len
< 10 || drv
->socket_dir
== NULL
) {
255 wpa_printf(MSG_DEBUG
, "%s: invalid parameters (sock=%d len=%lu"
257 __func__
, drv
->test_socket
, (unsigned long) len
,
264 broadcast
= memcmp(dest
, "\xff\xff\xff\xff\xff\xff", ETH_ALEN
) == 0;
265 snprintf(desttxt
, sizeof(desttxt
), MACSTR
, MAC2STR(dest
));
267 io
[0].iov_base
= "MLME ";
269 io
[1].iov_base
= (void *) buf
;
272 memset(&msg
, 0, sizeof(msg
));
276 dir
= opendir(drv
->socket_dir
);
278 perror("test_driver: opendir");
281 while ((dent
= readdir(dir
))) {
282 #ifdef _DIRENT_HAVE_D_TYPE
283 /* Skip the file if it is not a socket. Also accept
284 * DT_UNKNOWN (0) in case the C library or underlying file
285 * system does not support d_type. */
286 if (dent
->d_type
!= DT_SOCK
&& dent
->d_type
!= DT_UNKNOWN
)
288 #endif /* _DIRENT_HAVE_D_TYPE */
289 if (strcmp(dent
->d_name
, ".") == 0 ||
290 strcmp(dent
->d_name
, "..") == 0)
293 memset(&addr
, 0, sizeof(addr
));
294 addr
.sun_family
= AF_UNIX
;
295 snprintf(addr
.sun_path
, sizeof(addr
.sun_path
), "%s/%s",
296 drv
->socket_dir
, dent
->d_name
);
298 if (strcmp(addr
.sun_path
, drv
->own_socket_path
) == 0)
300 if (!broadcast
&& strstr(dent
->d_name
, desttxt
) == NULL
)
303 wpa_printf(MSG_DEBUG
, "%s: Send management frame to %s",
304 __func__
, dent
->d_name
);
306 msg
.msg_name
= &addr
;
307 msg
.msg_namelen
= sizeof(addr
);
308 ret
= sendmsg(drv
->test_socket
, &msg
, 0);
310 perror("driver_test: sendmsg");
314 hdr
= (struct ieee80211_hdr
*) buf
;
315 fc
= le_to_host16(hdr
->frame_control
);
316 ieee802_11_mgmt_cb(drv
->hapd
, (u8
*) buf
, len
, WLAN_FC_GET_STYPE(fc
),
323 static void test_driver_scan(struct test_driver_data
*drv
,
324 struct sockaddr_un
*from
, socklen_t fromlen
)
326 char buf
[512], *pos
, *end
;
328 struct test_driver_bss
*bss
;
330 wpa_printf(MSG_DEBUG
, "test_driver: SCAN");
332 for (bss
= drv
->bss
; bss
; bss
= bss
->next
) {
334 end
= buf
+ sizeof(buf
);
336 /* reply: SCANRESP BSSID SSID IEs */
337 ret
= snprintf(pos
, end
- pos
, "SCANRESP " MACSTR
" ",
338 MAC2STR(bss
->bssid
));
339 if (ret
< 0 || ret
>= end
- pos
)
342 pos
+= wpa_snprintf_hex(pos
, end
- pos
,
343 bss
->ssid
, bss
->ssid_len
);
344 ret
= snprintf(pos
, end
- pos
, " ");
345 if (ret
< 0 || ret
>= end
- pos
)
348 pos
+= wpa_snprintf_hex(pos
, end
- pos
, bss
->ie
, bss
->ielen
);
351 ret
= snprintf(pos
, end
- pos
, " PRIVACY");
352 if (ret
< 0 || ret
>= end
- pos
)
357 sendto(drv
->test_socket
, buf
, pos
- buf
, 0,
358 (struct sockaddr
*) from
, fromlen
);
363 static struct hostapd_data
* test_driver_get_hapd(struct test_driver_data
*drv
,
364 struct test_driver_bss
*bss
)
366 struct hostapd_iface
*iface
= drv
->hapd
->iface
;
367 struct hostapd_data
*hapd
= NULL
;
371 wpa_printf(MSG_DEBUG
, "%s: bss == NULL", __func__
);
375 for (i
= 0; i
< iface
->num_bss
; i
++) {
376 hapd
= iface
->bss
[i
];
377 if (memcmp(hapd
->own_addr
, bss
->bssid
, ETH_ALEN
) == 0)
380 if (i
== iface
->num_bss
) {
381 wpa_printf(MSG_DEBUG
, "%s: no matching interface entry found "
382 "for BSSID " MACSTR
, __func__
, MAC2STR(bss
->bssid
));
390 static int test_driver_new_sta(struct test_driver_data
*drv
,
391 struct test_driver_bss
*bss
, const u8
*addr
,
392 const u8
*ie
, size_t ielen
)
394 struct hostapd_data
*hapd
;
395 struct sta_info
*sta
;
398 hapd
= test_driver_get_hapd(drv
, bss
);
402 hostapd_logger(hapd
, addr
, HOSTAPD_MODULE_IEEE80211
,
403 HOSTAPD_LEVEL_INFO
, "associated");
405 sta
= ap_get_sta(hapd
, addr
);
407 accounting_sta_stop(hapd
, sta
);
409 sta
= ap_sta_add(hapd
, addr
);
413 accounting_sta_get_id(hapd
, sta
);
415 if (hapd
->conf
->wpa
) {
416 if (ie
== NULL
|| ielen
== 0) {
417 printf("test_driver: no IE from STA\n");
420 if (sta
->wpa_sm
== NULL
)
421 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
423 if (sta
->wpa_sm
== NULL
) {
424 printf("test_driver: Failed to initialize WPA state "
428 res
= wpa_validate_wpa_ie(hapd
->wpa_auth
, sta
->wpa_sm
,
430 if (res
!= WPA_IE_OK
) {
431 printf("WPA/RSN information element rejected? "
437 new_assoc
= (sta
->flags
& WLAN_STA_ASSOC
) == 0;
438 sta
->flags
|= WLAN_STA_AUTH
| WLAN_STA_ASSOC
;
439 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC
);
441 hostapd_new_assoc_sta(hapd
, sta
, !new_assoc
);
443 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 1);
449 static void test_driver_assoc(struct test_driver_data
*drv
,
450 struct sockaddr_un
*from
, socklen_t fromlen
,
453 struct test_client_socket
*cli
;
454 u8 ie
[256], ssid
[32];
455 size_t ielen
, ssid_len
= 0;
456 char *pos
, *pos2
, cmd
[50];
457 struct test_driver_bss
*bss
;
459 /* data: STA-addr SSID(hex) IEs(hex) */
461 cli
= os_zalloc(sizeof(*cli
));
465 if (hwaddr_aton(data
, cli
->addr
)) {
466 printf("test_socket: Invalid MAC address '%s' in ASSOC\n",
474 pos2
= strchr(pos
, ' ');
477 ssid_len
= (pos2
- pos
) / 2;
478 if (hexstr2bin(pos
, ssid
, ssid_len
) < 0) {
479 wpa_printf(MSG_DEBUG
, "%s: Invalid SSID", __func__
);
483 wpa_hexdump_ascii(MSG_DEBUG
, "test_driver_assoc: SSID",
487 ielen
= strlen(pos
) / 2;
488 if (ielen
> sizeof(ie
))
490 if (hexstr2bin(pos
, ie
, ielen
) < 0)
494 for (bss
= drv
->bss
; bss
; bss
= bss
->next
) {
495 if (bss
->ssid_len
== ssid_len
&&
496 memcmp(bss
->ssid
, ssid
, ssid_len
) == 0)
500 wpa_printf(MSG_DEBUG
, "%s: No matching SSID found from "
501 "configured BSSes", __func__
);
507 memcpy(&cli
->un
, from
, sizeof(cli
->un
));
508 cli
->unlen
= fromlen
;
509 cli
->next
= drv
->cli
;
511 wpa_hexdump_ascii(MSG_DEBUG
, "test_socket: ASSOC sun_path",
512 (const u8
*) cli
->un
.sun_path
,
513 cli
->unlen
- sizeof(cli
->un
.sun_family
));
515 snprintf(cmd
, sizeof(cmd
), "ASSOCRESP " MACSTR
" 0",
516 MAC2STR(bss
->bssid
));
517 sendto(drv
->test_socket
, cmd
, strlen(cmd
), 0,
518 (struct sockaddr
*) from
, fromlen
);
520 if (test_driver_new_sta(drv
, bss
, cli
->addr
, ie
, ielen
) < 0) {
521 wpa_printf(MSG_DEBUG
, "test_driver: failed to add new STA");
526 static void test_driver_disassoc(struct test_driver_data
*drv
,
527 struct sockaddr_un
*from
, socklen_t fromlen
)
529 struct test_client_socket
*cli
;
530 struct sta_info
*sta
;
532 cli
= test_driver_get_cli(drv
, from
, fromlen
);
536 hostapd_logger(drv
->hapd
, cli
->addr
, HOSTAPD_MODULE_IEEE80211
,
537 HOSTAPD_LEVEL_INFO
, "disassociated");
539 sta
= ap_get_sta(drv
->hapd
, cli
->addr
);
541 sta
->flags
&= ~WLAN_STA_ASSOC
;
542 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DISASSOC
);
543 sta
->acct_terminate_cause
=
544 RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
545 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
546 ap_free_sta(drv
->hapd
, sta
);
551 static void test_driver_eapol(struct test_driver_data
*drv
,
552 struct sockaddr_un
*from
, socklen_t fromlen
,
553 u8
*data
, size_t datalen
)
555 struct test_client_socket
*cli
;
557 u8
*proto
= data
+ 2 * ETH_ALEN
;
558 /* Skip Ethernet header */
559 wpa_printf(MSG_DEBUG
, "test_driver: dst=" MACSTR
" src="
560 MACSTR
" proto=%04x",
561 MAC2STR(data
), MAC2STR(data
+ ETH_ALEN
),
562 WPA_GET_BE16(proto
));
566 cli
= test_driver_get_cli(drv
, from
, fromlen
);
568 struct hostapd_data
*hapd
;
569 hapd
= test_driver_get_hapd(drv
, cli
->bss
);
572 ieee802_1x_receive(hapd
, cli
->addr
, data
, datalen
);
574 wpa_printf(MSG_DEBUG
, "test_socket: EAPOL from unknown "
580 static void test_driver_ether(struct test_driver_data
*drv
,
581 struct sockaddr_un
*from
, socklen_t fromlen
,
582 u8
*data
, size_t datalen
)
584 struct l2_ethhdr
*eth
;
586 if (datalen
< sizeof(*eth
))
589 eth
= (struct l2_ethhdr
*) data
;
590 wpa_printf(MSG_DEBUG
, "test_driver: RX ETHER dst=" MACSTR
" src="
591 MACSTR
" proto=%04x",
592 MAC2STR(eth
->h_dest
), MAC2STR(eth
->h_source
),
593 be_to_host16(eth
->h_proto
));
595 #ifdef CONFIG_IEEE80211R
596 if (be_to_host16(eth
->h_proto
) == ETH_P_RRB
) {
597 wpa_ft_rrb_rx(drv
->hapd
->wpa_auth
, eth
->h_source
,
598 data
+ sizeof(*eth
), datalen
- sizeof(*eth
));
600 #endif /* CONFIG_IEEE80211R */
604 static void test_driver_mlme(struct test_driver_data
*drv
,
605 struct sockaddr_un
*from
, socklen_t fromlen
,
606 u8
*data
, size_t datalen
)
608 struct ieee80211_hdr
*hdr
;
611 hdr
= (struct ieee80211_hdr
*) data
;
613 if (test_driver_get_cli(drv
, from
, fromlen
) == NULL
&& datalen
>= 16) {
614 struct test_client_socket
*cli
;
615 cli
= os_zalloc(sizeof(*cli
));
618 wpa_printf(MSG_DEBUG
, "Adding client entry for " MACSTR
,
619 MAC2STR(hdr
->addr2
));
620 memcpy(cli
->addr
, hdr
->addr2
, ETH_ALEN
);
621 memcpy(&cli
->un
, from
, sizeof(cli
->un
));
622 cli
->unlen
= fromlen
;
623 cli
->next
= drv
->cli
;
627 wpa_hexdump(MSG_MSGDUMP
, "test_driver_mlme: received frame",
629 fc
= le_to_host16(hdr
->frame_control
);
630 if (WLAN_FC_GET_TYPE(fc
) != WLAN_FC_TYPE_MGMT
) {
631 wpa_printf(MSG_ERROR
, "%s: received non-mgmt frame",
635 ieee802_11_mgmt(drv
->hapd
, data
, datalen
, WLAN_FC_GET_STYPE(fc
), NULL
);
639 static void test_driver_receive_unix(int sock
, void *eloop_ctx
, void *sock_ctx
)
641 struct test_driver_data
*drv
= eloop_ctx
;
644 struct sockaddr_un from
;
645 socklen_t fromlen
= sizeof(from
);
647 res
= recvfrom(sock
, buf
, sizeof(buf
) - 1, 0,
648 (struct sockaddr
*) &from
, &fromlen
);
650 perror("recvfrom(test_socket)");
655 wpa_printf(MSG_DEBUG
, "test_driver: received %u bytes", res
);
657 if (strcmp(buf
, "SCAN") == 0) {
658 test_driver_scan(drv
, &from
, fromlen
);
659 } else if (strncmp(buf
, "ASSOC ", 6) == 0) {
660 test_driver_assoc(drv
, &from
, fromlen
, buf
+ 6);
661 } else if (strcmp(buf
, "DISASSOC") == 0) {
662 test_driver_disassoc(drv
, &from
, fromlen
);
663 } else if (strncmp(buf
, "EAPOL ", 6) == 0) {
664 test_driver_eapol(drv
, &from
, fromlen
, (u8
*) buf
+ 6,
666 } else if (strncmp(buf
, "ETHER ", 6) == 0) {
667 test_driver_ether(drv
, &from
, fromlen
, (u8
*) buf
+ 6,
669 } else if (strncmp(buf
, "MLME ", 5) == 0) {
670 test_driver_mlme(drv
, &from
, fromlen
, (u8
*) buf
+ 5, res
- 5);
672 wpa_hexdump_ascii(MSG_DEBUG
, "Unknown test_socket command",
678 static struct test_driver_bss
*
679 test_driver_get_bss(struct test_driver_data
*drv
, const char *ifname
)
681 struct test_driver_bss
*bss
;
683 for (bss
= drv
->bss
; bss
; bss
= bss
->next
) {
684 if (strcmp(bss
->ifname
, ifname
) == 0)
691 static int test_driver_set_generic_elem(const char *ifname
, void *priv
,
692 const u8
*elem
, size_t elem_len
)
694 struct test_driver_data
*drv
= priv
;
695 struct test_driver_bss
*bss
;
697 bss
= test_driver_get_bss(drv
, ifname
);
709 bss
->ie
= malloc(elem_len
);
710 if (bss
->ie
== NULL
) {
715 memcpy(bss
->ie
, elem
, elem_len
);
716 bss
->ielen
= elem_len
;
721 static int test_driver_sta_deauth(void *priv
, const u8
*addr
, int reason
)
723 struct test_driver_data
*drv
= priv
;
724 struct test_client_socket
*cli
;
726 if (drv
->test_socket
< 0)
731 if (memcmp(cli
->addr
, addr
, ETH_ALEN
) == 0)
739 return sendto(drv
->test_socket
, "DEAUTH", 6, 0,
740 (struct sockaddr
*) &cli
->un
, cli
->unlen
);
744 static int test_driver_sta_disassoc(void *priv
, const u8
*addr
, int reason
)
746 struct test_driver_data
*drv
= priv
;
747 struct test_client_socket
*cli
;
749 if (drv
->test_socket
< 0)
754 if (memcmp(cli
->addr
, addr
, ETH_ALEN
) == 0)
762 return sendto(drv
->test_socket
, "DISASSOC", 8, 0,
763 (struct sockaddr
*) &cli
->un
, cli
->unlen
);
767 static struct hostapd_hw_modes
*
768 test_driver_get_hw_feature_data(void *priv
, u16
*num_modes
, u16
*flags
)
770 struct hostapd_hw_modes
*modes
;
774 modes
= os_zalloc(*num_modes
* sizeof(struct hostapd_hw_modes
));
777 modes
[0].mode
= HOSTAPD_MODE_IEEE80211G
;
778 modes
[0].num_channels
= 1;
779 modes
[0].num_rates
= 1;
780 modes
[0].channels
= os_zalloc(sizeof(struct hostapd_channel_data
));
781 modes
[0].rates
= os_zalloc(sizeof(struct hostapd_rate_data
));
782 if (modes
[0].channels
== NULL
|| modes
[0].rates
== NULL
) {
783 hostapd_free_hw_features(modes
, *num_modes
);
786 modes
[0].channels
[0].chan
= 1;
787 modes
[0].channels
[0].freq
= 2412;
788 modes
[0].channels
[0].flag
= HOSTAPD_CHAN_W_SCAN
|
789 HOSTAPD_CHAN_W_ACTIVE_SCAN
;
790 modes
[0].rates
[0].rate
= 10;
791 modes
[0].rates
[0].flags
= HOSTAPD_RATE_BASIC
| HOSTAPD_RATE_SUPPORTED
|
792 HOSTAPD_RATE_CCK
| HOSTAPD_RATE_MANDATORY
;
794 modes
[1].mode
= HOSTAPD_MODE_IEEE80211B
;
795 modes
[1].num_channels
= 1;
796 modes
[1].num_rates
= 1;
797 modes
[1].channels
= os_zalloc(sizeof(struct hostapd_channel_data
));
798 modes
[1].rates
= os_zalloc(sizeof(struct hostapd_rate_data
));
799 if (modes
[1].channels
== NULL
|| modes
[1].rates
== NULL
) {
800 hostapd_free_hw_features(modes
, *num_modes
);
803 modes
[1].channels
[0].chan
= 1;
804 modes
[1].channels
[0].freq
= 2412;
805 modes
[1].channels
[0].flag
= HOSTAPD_CHAN_W_SCAN
|
806 HOSTAPD_CHAN_W_ACTIVE_SCAN
;
807 modes
[1].rates
[0].rate
= 10;
808 modes
[1].rates
[0].flags
= HOSTAPD_RATE_BASIC
| HOSTAPD_RATE_SUPPORTED
|
809 HOSTAPD_RATE_CCK
| HOSTAPD_RATE_MANDATORY
;
811 modes
[2].mode
= HOSTAPD_MODE_IEEE80211A
;
812 modes
[2].num_channels
= 1;
813 modes
[2].num_rates
= 1;
814 modes
[2].channels
= os_zalloc(sizeof(struct hostapd_channel_data
));
815 modes
[2].rates
= os_zalloc(sizeof(struct hostapd_rate_data
));
816 if (modes
[2].channels
== NULL
|| modes
[2].rates
== NULL
) {
817 hostapd_free_hw_features(modes
, *num_modes
);
820 modes
[2].channels
[0].chan
= 60;
821 modes
[2].channels
[0].freq
= 5300;
822 modes
[2].channels
[0].flag
= HOSTAPD_CHAN_W_SCAN
|
823 HOSTAPD_CHAN_W_ACTIVE_SCAN
;
824 modes
[2].rates
[0].rate
= 60;
825 modes
[2].rates
[0].flags
= HOSTAPD_RATE_BASIC
| HOSTAPD_RATE_SUPPORTED
|
826 HOSTAPD_RATE_MANDATORY
;
832 static int test_driver_bss_add(void *priv
, const char *ifname
, const u8
*bssid
)
834 struct test_driver_data
*drv
= priv
;
835 struct test_driver_bss
*bss
;
837 wpa_printf(MSG_DEBUG
, "%s(ifname=%s bssid=" MACSTR
")",
838 __func__
, ifname
, MAC2STR(bssid
));
840 bss
= os_zalloc(sizeof(*bss
));
844 os_strlcpy(bss
->ifname
, ifname
, IFNAMSIZ
);
845 memcpy(bss
->bssid
, bssid
, ETH_ALEN
);
847 bss
->next
= drv
->bss
;
854 static int test_driver_bss_remove(void *priv
, const char *ifname
)
856 struct test_driver_data
*drv
= priv
;
857 struct test_driver_bss
*bss
, *prev
;
858 struct test_client_socket
*cli
, *prev_c
;
860 wpa_printf(MSG_DEBUG
, "%s(ifname=%s)", __func__
, ifname
);
862 for (prev
= NULL
, bss
= drv
->bss
; bss
; prev
= bss
, bss
= bss
->next
) {
863 if (strcmp(bss
->ifname
, ifname
) != 0)
867 prev
->next
= bss
->next
;
869 drv
->bss
= bss
->next
;
871 for (prev_c
= NULL
, cli
= drv
->cli
; cli
;
872 prev_c
= cli
, cli
= cli
->next
) {
876 prev_c
->next
= cli
->next
;
878 drv
->cli
= cli
->next
;
883 test_driver_free_bss(bss
);
891 static int test_driver_if_add(const char *iface
, void *priv
,
892 enum hostapd_driver_if_type type
, char *ifname
,
895 wpa_printf(MSG_DEBUG
, "%s(iface=%s type=%d ifname=%s)",
896 __func__
, iface
, type
, ifname
);
901 static int test_driver_if_update(void *priv
, enum hostapd_driver_if_type type
,
902 char *ifname
, const u8
*addr
)
904 wpa_printf(MSG_DEBUG
, "%s(type=%d ifname=%s)", __func__
, type
, ifname
);
909 static int test_driver_if_remove(void *priv
, enum hostapd_driver_if_type type
,
910 const char *ifname
, const u8
*addr
)
912 wpa_printf(MSG_DEBUG
, "%s(type=%d ifname=%s)", __func__
, type
, ifname
);
917 static int test_driver_valid_bss_mask(void *priv
, const u8
*addr
,
924 static int test_driver_set_ssid(const char *ifname
, void *priv
, const u8
*buf
,
927 struct test_driver_data
*drv
= priv
;
928 struct test_driver_bss
*bss
;
930 wpa_printf(MSG_DEBUG
, "%s(ifname=%s)", __func__
, ifname
);
931 wpa_hexdump_ascii(MSG_DEBUG
, "test_driver_set_ssid: SSID", buf
, len
);
933 for (bss
= drv
->bss
; bss
; bss
= bss
->next
) {
934 if (strcmp(bss
->ifname
, ifname
) != 0)
937 if (len
< 0 || (size_t) len
> sizeof(bss
->ssid
))
940 memcpy(bss
->ssid
, buf
, len
);
950 static int test_driver_set_privacy(const char *ifname
, void *priv
, int enabled
)
952 struct test_driver_data
*drv
= priv
;
953 struct test_driver_bss
*bss
;
955 wpa_printf(MSG_DEBUG
, "%s(ifname=%s enabled=%d)",
956 __func__
, ifname
, enabled
);
958 for (bss
= drv
->bss
; bss
; bss
= bss
->next
) {
959 if (strcmp(bss
->ifname
, ifname
) != 0)
962 bss
->privacy
= enabled
;
971 static int test_driver_set_encryption(const char *iface
, void *priv
,
972 const char *alg
, const u8
*addr
, int idx
,
973 const u8
*key
, size_t key_len
, int txkey
)
975 wpa_printf(MSG_DEBUG
, "%s(iface=%s alg=%s idx=%d txkey=%d)",
976 __func__
, iface
, alg
, idx
, txkey
);
978 wpa_printf(MSG_DEBUG
, " addr=" MACSTR
, MAC2STR(addr
));
980 wpa_hexdump_key(MSG_DEBUG
, " key", key
, key_len
);
985 static int test_driver_set_sta_vlan(void *priv
, const u8
*addr
,
986 const char *ifname
, int vlan_id
)
988 wpa_printf(MSG_DEBUG
, "%s(addr=" MACSTR
" ifname=%s vlan_id=%d)",
989 __func__
, MAC2STR(addr
), ifname
, vlan_id
);
994 static int test_driver_sta_add(const char *ifname
, void *priv
, const u8
*addr
,
995 u16 aid
, u16 capability
, u8
*supp_rates
,
996 size_t supp_rates_len
, int flags
,
999 struct test_driver_data
*drv
= priv
;
1000 struct test_client_socket
*cli
;
1001 struct test_driver_bss
*bss
;
1003 wpa_printf(MSG_DEBUG
, "%s(ifname=%s addr=" MACSTR
" aid=%d "
1004 "capability=0x%x flags=0x%x listen_interval=%d)",
1005 __func__
, ifname
, MAC2STR(addr
), aid
, capability
, flags
,
1007 wpa_hexdump(MSG_DEBUG
, "test_driver_sta_add - supp_rates",
1008 supp_rates
, supp_rates_len
);
1012 if (memcmp(cli
->addr
, addr
, ETH_ALEN
) == 0)
1017 wpa_printf(MSG_DEBUG
, "%s: no matching client entry",
1022 for (bss
= drv
->bss
; bss
; bss
= bss
->next
) {
1023 if (strcmp(ifname
, bss
->ifname
) == 0)
1027 wpa_printf(MSG_DEBUG
, "%s: No matching interface found from "
1028 "configured BSSes", __func__
);
1038 static void * test_driver_init(struct hostapd_data
*hapd
)
1040 struct test_driver_data
*drv
;
1041 struct sockaddr_un addr
;
1043 drv
= os_zalloc(sizeof(struct test_driver_data
));
1045 printf("Could not allocate memory for test driver data\n");
1048 drv
->bss
= os_zalloc(sizeof(*drv
->bss
));
1049 if (drv
->bss
== NULL
) {
1050 printf("Could not allocate memory for test driver BSS data\n");
1057 /* Generate a MAC address to help testing with multiple APs */
1058 hapd
->own_addr
[0] = 0x02; /* locally administered */
1059 sha1_prf((const u8
*) hapd
->conf
->iface
, strlen(hapd
->conf
->iface
),
1060 "hostapd test bssid generation",
1061 (const u8
*) hapd
->conf
->ssid
.ssid
, hapd
->conf
->ssid
.ssid_len
,
1062 hapd
->own_addr
+ 1, ETH_ALEN
- 1);
1064 os_strlcpy(drv
->bss
->ifname
, hapd
->conf
->iface
, IFNAMSIZ
);
1065 memcpy(drv
->bss
->bssid
, hapd
->own_addr
, ETH_ALEN
);
1067 if (hapd
->conf
->test_socket
) {
1068 if (strlen(hapd
->conf
->test_socket
) >= sizeof(addr
.sun_path
)) {
1069 printf("Too long test_socket path\n");
1070 test_driver_free_priv(drv
);
1073 if (strncmp(hapd
->conf
->test_socket
, "DIR:", 4) == 0) {
1074 size_t len
= strlen(hapd
->conf
->test_socket
) + 30;
1075 drv
->socket_dir
= strdup(hapd
->conf
->test_socket
+ 4);
1076 drv
->own_socket_path
= malloc(len
);
1077 if (drv
->own_socket_path
) {
1078 snprintf(drv
->own_socket_path
, len
,
1080 hapd
->conf
->test_socket
+ 4,
1081 MAC2STR(hapd
->own_addr
));
1084 drv
->own_socket_path
= strdup(hapd
->conf
->test_socket
);
1086 if (drv
->own_socket_path
== NULL
) {
1087 test_driver_free_priv(drv
);
1091 drv
->test_socket
= socket(PF_UNIX
, SOCK_DGRAM
, 0);
1092 if (drv
->test_socket
< 0) {
1093 perror("socket(PF_UNIX)");
1094 test_driver_free_priv(drv
);
1098 memset(&addr
, 0, sizeof(addr
));
1099 addr
.sun_family
= AF_UNIX
;
1100 os_strlcpy(addr
.sun_path
, drv
->own_socket_path
,
1101 sizeof(addr
.sun_path
));
1102 if (bind(drv
->test_socket
, (struct sockaddr
*) &addr
,
1103 sizeof(addr
)) < 0) {
1104 perror("bind(PF_UNIX)");
1105 close(drv
->test_socket
);
1106 unlink(drv
->own_socket_path
);
1107 test_driver_free_priv(drv
);
1110 eloop_register_read_sock(drv
->test_socket
,
1111 test_driver_receive_unix
, drv
, NULL
);
1113 drv
->test_socket
= -1;
1119 static void test_driver_deinit(void *priv
)
1121 struct test_driver_data
*drv
= priv
;
1122 struct test_client_socket
*cli
, *prev
;
1131 if (drv
->test_socket
>= 0) {
1132 eloop_unregister_read_sock(drv
->test_socket
);
1133 close(drv
->test_socket
);
1134 unlink(drv
->own_socket_path
);
1137 /* There should be only one BSS remaining at this point. */
1138 if (drv
->bss
== NULL
)
1139 wpa_printf(MSG_ERROR
, "%s: drv->bss == NULL", __func__
);
1140 else if (drv
->bss
->next
)
1141 wpa_printf(MSG_ERROR
, "%s: drv->bss->next != NULL", __func__
);
1143 test_driver_free_priv(drv
);
1147 const struct wpa_driver_ops wpa_driver_test_ops
= {
1149 .init
= test_driver_init
,
1150 .deinit
= test_driver_deinit
,
1151 .send_eapol
= test_driver_send_eapol
,
1152 .send_mgmt_frame
= test_driver_send_mgmt_frame
,
1153 .set_generic_elem
= test_driver_set_generic_elem
,
1154 .sta_deauth
= test_driver_sta_deauth
,
1155 .sta_disassoc
= test_driver_sta_disassoc
,
1156 .get_hw_feature_data
= test_driver_get_hw_feature_data
,
1157 .bss_add
= test_driver_bss_add
,
1158 .bss_remove
= test_driver_bss_remove
,
1159 .if_add
= test_driver_if_add
,
1160 .if_update
= test_driver_if_update
,
1161 .if_remove
= test_driver_if_remove
,
1162 .valid_bss_mask
= test_driver_valid_bss_mask
,
1163 .set_ssid
= test_driver_set_ssid
,
1164 .set_privacy
= test_driver_set_privacy
,
1165 .set_encryption
= test_driver_set_encryption
,
1166 .set_sta_vlan
= test_driver_set_sta_vlan
,
1167 .sta_add
= test_driver_sta_add
,
1168 .send_ether
= test_driver_send_ether
,