2 * Host AP - driver interaction with BSD net80211 layer
3 * Copyright (c) 2004, Sam Leffler <sam@errno.com>
4 * Copyright (c) 2004, 2Wire, Inc
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
10 * Alternatively, this software may be distributed under the terms of BSD
13 * See README and COPYING for more details.
15 * $FreeBSD: src/usr.sbin/wpa/hostapd/driver_freebsd.c,v 1.2.2.2 2006/09/02 17:31:08 sam Exp $
16 * $DragonFly: src/usr.sbin/802_11/hostapd/driver_dragonfly.c,v 1.2 2006/09/03 02:24:45 sephe Exp $
18 #include <sys/endian.h>
23 #include <sys/ioctl.h>
26 #include <sys/socket.h>
28 #include <netinet/in.h>
30 #include <netproto/802_11/ieee80211.h>
31 #include <netproto/802_11/ieee80211_crypto.h>
32 #include <netproto/802_11/ieee80211_ioctl.h>
36 #include "ieee802_1x.h"
39 #include "l2_packet.h"
44 #include "ieee802_11.h"
46 #include "hostap_common.h"
48 struct bsd_driver_data
{
49 struct driver_ops ops
; /* base class */
50 struct hostapd_data
*hapd
; /* back pointer */
52 char iface
[IFNAMSIZ
+ 1];
53 struct l2_packet_data
*sock_xmit
; /* raw packet xmit socket */
54 int ioctl_sock
; /* socket for ioctl() use */
55 int wext_sock
; /* socket for wireless events */
58 static const struct driver_ops bsd_driver_ops
;
60 static int bsd_sta_deauth(void *priv
, u8
*addr
, int reason_code
);
63 set80211var(struct bsd_driver_data
*drv
, int op
, const void *arg
, int arg_len
)
65 struct ieee80211req ireq
;
67 memset(&ireq
, 0, sizeof(ireq
));
68 strncpy(ireq
.i_name
, drv
->iface
, IFNAMSIZ
);
71 ireq
.i_data
= (void *) arg
;
73 if (ioctl(drv
->ioctl_sock
, SIOCS80211
, &ireq
) < 0) {
74 perror("ioctl[SIOCS80211]");
81 get80211var(struct bsd_driver_data
*drv
, int op
, void *arg
, int arg_len
)
83 struct ieee80211req ireq
;
85 memset(&ireq
, 0, sizeof(ireq
));
86 strncpy(ireq
.i_name
, drv
->iface
, IFNAMSIZ
);
91 if (ioctl(drv
->ioctl_sock
, SIOCG80211
, &ireq
) < 0) {
92 perror("ioctl[SIOCG80211]");
99 set80211param(struct bsd_driver_data
*drv
, int op
, int arg
)
101 struct ieee80211req ireq
;
103 memset(&ireq
, 0, sizeof(ireq
));
104 strncpy(ireq
.i_name
, drv
->iface
, IFNAMSIZ
);
108 if (ioctl(drv
->ioctl_sock
, SIOCS80211
, &ireq
) < 0) {
109 perror("ioctl[SIOCS80211]");
116 ether_sprintf(const u8
*addr
)
118 static char buf
[sizeof(MACSTR
)];
121 snprintf(buf
, sizeof(buf
), MACSTR
, MAC2STR(addr
));
123 snprintf(buf
, sizeof(buf
), MACSTR
, 0,0,0,0,0,0);
128 * Configure WPA parameters.
131 bsd_configure_wpa(struct bsd_driver_data
*drv
)
133 static const char *ciphernames
[] =
134 { "WEP", "TKIP", "AES-OCB", "AES-CCM", "*BAD*", "CKIP", "NONE" };
135 hostapd
*hapd
= drv
->hapd
;
136 struct hostapd_config
*conf
= hapd
->conf
;
139 switch (conf
->wpa_group
) {
140 case WPA_CIPHER_CCMP
:
141 v
= IEEE80211_CIPHER_AES_CCM
;
143 case WPA_CIPHER_TKIP
:
144 v
= IEEE80211_CIPHER_TKIP
;
146 case WPA_CIPHER_WEP104
:
147 v
= IEEE80211_CIPHER_WEP
;
149 case WPA_CIPHER_WEP40
:
150 v
= IEEE80211_CIPHER_WEP
;
152 case WPA_CIPHER_NONE
:
153 v
= IEEE80211_CIPHER_NONE
;
156 printf("Unknown group key cipher %u\n",
160 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
,
161 "%s: group key cipher=%s (%u)\n", __func__
, ciphernames
[v
], v
);
162 if (set80211param(drv
, IEEE80211_IOC_MCASTCIPHER
, v
)) {
163 printf("Unable to set group key cipher to %u (%s)\n",
167 if (v
== IEEE80211_CIPHER_WEP
) {
168 /* key length is done only for specific ciphers */
169 v
= (conf
->wpa_group
== WPA_CIPHER_WEP104
? 13 : 5);
170 if (set80211param(drv
, IEEE80211_IOC_MCASTKEYLEN
, v
)) {
171 printf("Unable to set group key length to %u\n", v
);
177 if (conf
->wpa_pairwise
& WPA_CIPHER_CCMP
)
178 v
|= 1<<IEEE80211_CIPHER_AES_CCM
;
179 if (conf
->wpa_pairwise
& WPA_CIPHER_TKIP
)
180 v
|= 1<<IEEE80211_CIPHER_TKIP
;
181 if (conf
->wpa_pairwise
& WPA_CIPHER_NONE
)
182 v
|= 1<<IEEE80211_CIPHER_NONE
;
183 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
,
184 "%s: pairwise key ciphers=0x%x\n", __func__
, v
);
185 if (set80211param(drv
, IEEE80211_IOC_UCASTCIPHERS
, v
)) {
186 printf("Unable to set pairwise key ciphers to 0x%x\n", v
);
190 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
,
191 "%s: key management algorithms=0x%x\n",
192 __func__
, conf
->wpa_key_mgmt
);
193 if (set80211param(drv
, IEEE80211_IOC_KEYMGTALGS
, conf
->wpa_key_mgmt
)) {
194 printf("Unable to set key management algorithms to 0x%x\n",
200 if (conf
->rsn_preauth
)
202 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
,
203 "%s: rsn capabilities=0x%x\n", __func__
, conf
->rsn_preauth
);
204 if (set80211param(drv
, IEEE80211_IOC_RSNCAPS
, v
)) {
205 printf("Unable to set RSN capabilities to 0x%x\n", v
);
209 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
,
210 "%s: enable WPA= 0x%x\n", __func__
, conf
->wpa
);
211 if (set80211param(drv
, IEEE80211_IOC_WPA
, conf
->wpa
)) {
212 printf("Unable to set WPA to %u\n", conf
->wpa
);
220 bsd_set_iface_flags(void *priv
, int dev_up
)
222 struct bsd_driver_data
*drv
= priv
;
223 hostapd
*hapd
= drv
->hapd
;
226 HOSTAPD_DEBUG(HOSTAPD_DEBUG_VERBOSE
,
227 "%s: dev_up=%d\n", __func__
, dev_up
);
229 if (drv
->ioctl_sock
< 0)
232 memset(&ifr
, 0, sizeof(ifr
));
233 snprintf(ifr
.ifr_name
, IFNAMSIZ
, "%s", drv
->iface
);
235 if (ioctl(drv
->ioctl_sock
, SIOCGIFFLAGS
, &ifr
) != 0) {
236 perror("ioctl[SIOCGIFFLAGS]");
241 ifr
.ifr_flags
|= IFF_UP
;
243 ifr
.ifr_flags
&= ~IFF_UP
;
245 if (ioctl(drv
->ioctl_sock
, SIOCSIFFLAGS
, &ifr
) != 0) {
246 perror("ioctl[SIOCSIFFLAGS]");
251 memset(&ifr
, 0, sizeof(ifr
));
252 snprintf(ifr
.ifr_name
, IFNAMSIZ
, "%s", drv
->iface
);
253 ifr
.ifr_mtu
= HOSTAPD_MTU
;
254 if (ioctl(drv
->ioctl_sock
, SIOCSIFMTU
, &ifr
) != 0) {
255 perror("ioctl[SIOCSIFMTU]");
256 printf("Setting MTU failed - trying to survive with "
265 bsd_set_ieee8021x(void *priv
, int enabled
)
267 struct bsd_driver_data
*drv
= priv
;
268 hostapd
*hapd
= drv
->hapd
;
269 struct hostapd_config
*conf
= hapd
->conf
;
271 HOSTAPD_DEBUG(HOSTAPD_DEBUG_VERBOSE
,
272 "%s: enabled=%d\n", __func__
, enabled
);
275 /* XXX restore state */
276 return set80211param(priv
, IEEE80211_IOC_AUTHMODE
,
277 IEEE80211_AUTH_AUTO
);
279 if (!conf
->wpa
&& !conf
->ieee802_1x
) {
280 hostapd_logger(hapd
, NULL
, HOSTAPD_MODULE_DRIVER
,
281 HOSTAPD_LEVEL_WARNING
, "No 802.1X or WPA enabled!");
284 if (conf
->wpa
&& bsd_configure_wpa(drv
) != 0) {
285 hostapd_logger(hapd
, NULL
, HOSTAPD_MODULE_DRIVER
,
286 HOSTAPD_LEVEL_WARNING
, "Error configuring WPA state!");
289 if (set80211param(priv
, IEEE80211_IOC_AUTHMODE
,
290 (conf
->wpa
? IEEE80211_AUTH_WPA
: IEEE80211_AUTH_8021X
))) {
291 hostapd_logger(hapd
, NULL
, HOSTAPD_MODULE_DRIVER
,
292 HOSTAPD_LEVEL_WARNING
, "Error enabling WPA/802.1X!");
295 return bsd_set_iface_flags(priv
, 1);
299 bsd_set_privacy(void *priv
, int enabled
)
301 struct bsd_driver_data
*drv
= priv
;
302 hostapd
*hapd
= drv
->hapd
;
304 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
,
305 "%s: enabled=%d\n", __func__
, enabled
);
307 return set80211param(priv
, IEEE80211_IOC_PRIVACY
, enabled
);
311 bsd_set_sta_authorized(void *priv
, u8
*addr
, int authorized
)
313 struct bsd_driver_data
*drv
= priv
;
314 hostapd
*hapd
= drv
->hapd
;
315 struct ieee80211req_mlme mlme
;
317 HOSTAPD_DEBUG(HOSTAPD_DEBUG_VERBOSE
,
318 "%s: addr=%s authorized=%d\n",
319 __func__
, ether_sprintf(addr
), authorized
);
322 mlme
.im_op
= IEEE80211_MLME_AUTHORIZE
;
324 mlme
.im_op
= IEEE80211_MLME_UNAUTHORIZE
;
326 memcpy(mlme
.im_macaddr
, addr
, IEEE80211_ADDR_LEN
);
327 return set80211var(priv
, IEEE80211_IOC_MLME
, &mlme
, sizeof(mlme
));
331 bsd_del_key(void *priv
, unsigned char *addr
, int key_idx
)
333 struct bsd_driver_data
*drv
= priv
;
334 hostapd
*hapd
= drv
->hapd
;
335 struct ieee80211req_del_key wk
;
337 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
,
338 "%s: addr=%s key_idx=%d\n",
339 __func__
, ether_sprintf(addr
), key_idx
);
341 memset(&wk
, 0, sizeof(wk
));
343 memcpy(wk
.idk_macaddr
, addr
, IEEE80211_ADDR_LEN
);
344 wk
.idk_keyix
= (u_int8_t
) IEEE80211_KEYIX_NONE
; /* XXX */
346 wk
.idk_keyix
= key_idx
;
349 return set80211var(priv
, IEEE80211_IOC_DELKEY
, &wk
, sizeof(wk
));
353 bsd_set_key(void *priv
, const char *alg
,
354 unsigned char *addr
, int key_idx
,
355 u8
*key
, size_t key_len
)
357 struct bsd_driver_data
*drv
= priv
;
358 hostapd
*hapd
= drv
->hapd
;
359 struct ieee80211req_key wk
;
362 if (strcmp(alg
, "none") == 0)
363 return bsd_del_key(priv
, addr
, key_idx
);
365 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
,
366 "%s: alg=%s addr=%s key_idx=%d\n",
367 __func__
, alg
, ether_sprintf(addr
), key_idx
);
369 if (strcmp(alg
, "WEP") == 0)
370 cipher
= IEEE80211_CIPHER_WEP
;
371 else if (strcmp(alg
, "TKIP") == 0)
372 cipher
= IEEE80211_CIPHER_TKIP
;
373 else if (strcmp(alg
, "CCMP") == 0)
374 cipher
= IEEE80211_CIPHER_AES_CCM
;
376 printf("%s: unknown/unsupported algorithm %s\n",
381 if (key_len
> sizeof(wk
.ik_keydata
)) {
382 printf("%s: key length %d too big\n", __func__
, key_len
);
386 memset(&wk
, 0, sizeof(wk
));
388 wk
.ik_flags
= IEEE80211_KEY_RECV
| IEEE80211_KEY_XMIT
;
390 memset(wk
.ik_macaddr
, 0xff, IEEE80211_ADDR_LEN
);
391 wk
.ik_keyix
= key_idx
;
392 wk
.ik_flags
|= IEEE80211_KEY_DEFAULT
| IEEE80211_KEY_GROUP
;
394 memcpy(wk
.ik_macaddr
, addr
, IEEE80211_ADDR_LEN
);
395 wk
.ik_keyix
= IEEE80211_KEYIX_NONE
;
397 wk
.ik_keylen
= key_len
;
398 memcpy(wk
.ik_keydata
, key
, key_len
);
400 return set80211var(priv
, IEEE80211_IOC_WPAKEY
, &wk
, sizeof(wk
));
405 bsd_get_seqnum(void *priv
, u8
*addr
, int idx
, u8
*seq
)
407 struct bsd_driver_data
*drv
= priv
;
408 hostapd
*hapd
= drv
->hapd
;
409 struct ieee80211req_key wk
;
411 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
,
412 "%s: addr=%s idx=%d\n", __func__
, ether_sprintf(addr
), idx
);
414 memset(&wk
, 0, sizeof(wk
));
416 memset(wk
.ik_macaddr
, 0xff, IEEE80211_ADDR_LEN
);
418 memcpy(wk
.ik_macaddr
, addr
, IEEE80211_ADDR_LEN
);
421 if (get80211var(drv
, IEEE80211_IOC_WPAKEY
, &wk
, sizeof(wk
)) < 0) {
422 printf("Failed to get encryption.\n");
425 /* NB: upper layer expects tsc in network order */
426 wk
.ik_keytsc
= htole64(wk
.ik_keytsc
);
427 memcpy(seq
, &wk
.ik_keytsc
, sizeof(wk
.ik_keytsc
));
434 bsd_flush(void *priv
)
436 u8 allsta
[IEEE80211_ADDR_LEN
];
438 memset(allsta
, 0xff, IEEE80211_ADDR_LEN
);
439 return bsd_sta_deauth(priv
, allsta
, IEEE80211_REASON_AUTH_LEAVE
);
444 bsd_read_sta_driver_data(void *priv
, struct hostap_sta_driver_data
*data
,
447 struct bsd_driver_data
*drv
= priv
;
448 struct ieee80211req_sta_stats stats
;
450 memcpy(stats
.is_u
.macaddr
, addr
, IEEE80211_ADDR_LEN
);
451 if (get80211var(drv
, IEEE80211_IOC_STA_STATS
, &stats
, sizeof(stats
)) > 0) {
452 /* XXX? do packets counts include non-data frames? */
453 data
->rx_packets
= stats
.is_stats
.ns_rx_data
;
454 data
->rx_bytes
= stats
.is_stats
.ns_rx_bytes
;
455 data
->tx_packets
= stats
.is_stats
.ns_tx_data
;
456 data
->tx_bytes
= stats
.is_stats
.ns_tx_bytes
;
462 bsd_sta_clear_stats(void *priv
, u8
*addr
)
464 struct bsd_driver_data
*drv
= priv
;
465 hostapd
*hapd
= drv
->hapd
;
466 struct ieee80211req_sta_stats stats
;
468 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
, "%s: addr=%s\n",
469 __func__
, ether_sprintf(addr
));
471 /* zero station statistics */
472 memset(&stats
, 0, sizeof(stats
));
473 memcpy(stats
.is_u
.macaddr
, addr
, IEEE80211_ADDR_LEN
);
474 return set80211var(drv
, IEEE80211_IOC_STA_STATS
, &stats
, sizeof(stats
));
478 bsd_set_opt_ie(void *priv
, const u8
*ie
, size_t ie_len
)
481 * Do nothing; we setup parameters at startup that define the
482 * contents of the beacon information element.
488 bsd_sta_deauth(void *priv
, u8
*addr
, int reason_code
)
490 struct bsd_driver_data
*drv
= priv
;
491 hostapd
*hapd
= drv
->hapd
;
492 struct ieee80211req_mlme mlme
;
494 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
,
495 "%s: addr=%s reason_code=%d\n",
496 __func__
, ether_sprintf(addr
), reason_code
);
498 mlme
.im_op
= IEEE80211_MLME_DEAUTH
;
499 mlme
.im_reason
= reason_code
;
500 memcpy(mlme
.im_macaddr
, addr
, IEEE80211_ADDR_LEN
);
501 return set80211var(priv
, IEEE80211_IOC_MLME
, &mlme
, sizeof(mlme
));
505 bsd_sta_disassoc(void *priv
, u8
*addr
, int reason_code
)
507 struct bsd_driver_data
*drv
= priv
;
508 hostapd
*hapd
= drv
->hapd
;
509 struct ieee80211req_mlme mlme
;
511 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
,
512 "%s: addr=%s reason_code=%d\n",
513 __func__
, ether_sprintf(addr
), reason_code
);
515 mlme
.im_reason
= reason_code
;
516 memcpy(mlme
.im_macaddr
, addr
, IEEE80211_ADDR_LEN
);
517 return set80211var(priv
, IEEE80211_IOC_MLME
, &mlme
, sizeof(mlme
));
521 bsd_del_sta(struct bsd_driver_data
*drv
, u8 addr
[IEEE80211_ADDR_LEN
])
523 struct hostapd_data
*hapd
= drv
->hapd
;
524 struct hostapd_config
*conf
= hapd
->conf
;
525 struct sta_info
*sta
;
527 hostapd_logger(hapd
, addr
, HOSTAPD_MODULE_IEEE80211
,
528 HOSTAPD_LEVEL_INFO
, "deassociated");
530 sta
= ap_get_sta(hapd
, addr
);
532 sta
->flags
&= ~WLAN_STA_ASSOC
;
534 wpa_sm_event(hapd
, sta
, WPA_DISASSOC
);
535 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
536 ieee802_1x_set_port_enabled(hapd
, sta
, 0);
537 ap_free_sta(hapd
, sta
);
543 bsd_new_sta(struct bsd_driver_data
*drv
, u8 addr
[IEEE80211_ADDR_LEN
])
545 struct hostapd_data
*hapd
= drv
->hapd
;
546 struct hostapd_config
*conf
= hapd
->conf
;
547 struct sta_info
*sta
;
548 struct ieee80211req_wpaie ie
;
549 int new_assoc
, ielen
, res
;
551 hostapd_logger(hapd
, addr
, HOSTAPD_MODULE_IEEE80211
,
552 HOSTAPD_LEVEL_INFO
, "associated");
554 sta
= ap_sta_add(hapd
, addr
);
558 * Fetch and validate any negotiated WPA/RSN parameters.
561 memset(&ie
, 0, sizeof(ie
));
562 memcpy(ie
.wpa_macaddr
, addr
, IEEE80211_ADDR_LEN
);
563 if (get80211var(drv
, IEEE80211_IOC_WPAIE
, &ie
, sizeof(ie
)) < 0) {
564 printf("Failed to get WPA/RSN information element.\n");
565 return -1; /* XXX not right */
567 ielen
= ie
.wpa_ie
[1];
569 printf("No WPA/RSN information element for station!\n");
570 return -1; /* XXX not right */
573 res
= wpa_validate_wpa_ie(hapd
, sta
, ie
.wpa_ie
, ielen
,
574 ie
.wpa_ie
[0] == WLAN_EID_RSN
?
575 HOSTAPD_WPA_VERSION_WPA2
:
576 HOSTAPD_WPA_VERSION_WPA
);
577 if (res
!= WPA_IE_OK
) {
578 printf("WPA/RSN information element rejected? "
582 if (sta
->wpa_ie
!= NULL
)
584 sta
->wpa_ie
= malloc(ielen
);
585 if (sta
->wpa_ie
== NULL
) {
586 printf("No memory for WPA/RSN information element!\n");
589 memcpy(sta
->wpa_ie
, ie
.wpa_ie
, ielen
);
590 sta
->wpa_ie_len
= ielen
;
592 if (sta
->wpa_ie
!= NULL
)
599 * Now that the internal station state is setup
600 * kick the authenticator into action.
602 new_assoc
= (sta
->flags
& WLAN_STA_ASSOC
) == 0;
603 sta
->flags
|= WLAN_STA_ASSOC
;
606 wpa_sm_event(hapd
, sta
, WPA_ASSOC
);
607 hostapd_new_assoc_sta(hapd
, sta
, !new_assoc
);
610 wpa_sm_event(hapd
, sta
, WPA_REAUTH
);
612 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 1);
616 #include <net/route.h>
617 #include <netproto/802_11/ieee80211_dragonfly.h>
620 bsd_wireless_event_receive(int sock
, void *ctx
, void *sock_ctx
)
622 struct bsd_driver_data
*drv
= ctx
;
623 struct hostapd_data
*hapd
= drv
->hapd
;
625 struct if_announcemsghdr
*ifan
;
626 struct rt_msghdr
*rtm
;
627 struct ieee80211_michael_event
*mic
;
628 struct ieee80211_join_event
*join
;
629 struct ieee80211_leave_event
*leave
;
632 n
= read(sock
, buf
, sizeof(buf
));
634 if (errno
!= EINTR
&& errno
!= EAGAIN
)
635 perror("read(PF_ROUTE)");
639 rtm
= (struct rt_msghdr
*) buf
;
640 if (rtm
->rtm_version
!= RTM_VERSION
) {
641 wpa_printf(MSG_DEBUG
, "Routing message version %d not "
642 "understood\n", rtm
->rtm_version
);
645 ifan
= (struct if_announcemsghdr
*) rtm
;
646 switch (rtm
->rtm_type
) {
648 switch (ifan
->ifan_what
) {
649 case RTM_IEEE80211_ASSOC
:
650 case RTM_IEEE80211_REASSOC
:
651 case RTM_IEEE80211_DISASSOC
:
652 case RTM_IEEE80211_SCAN
:
654 case RTM_IEEE80211_LEAVE
:
655 leave
= (struct ieee80211_leave_event
*) &ifan
[1];
656 bsd_del_sta(drv
, leave
->iev_addr
);
658 case RTM_IEEE80211_JOIN
:
659 #ifdef RTM_IEEE80211_REJOIN
660 case RTM_IEEE80211_REJOIN
:
662 join
= (struct ieee80211_join_event
*) &ifan
[1];
663 bsd_new_sta(drv
, join
->iev_addr
);
665 case RTM_IEEE80211_REPLAY
:
668 case RTM_IEEE80211_MICHAEL
:
669 mic
= (struct ieee80211_michael_event
*) &ifan
[1];
670 wpa_printf(MSG_DEBUG
,
671 "Michael MIC failure wireless event: "
672 "keyix=%u src_addr=" MACSTR
, mic
->iev_keyix
,
673 MAC2STR(mic
->iev_src
));
674 ieee80211_michael_mic_failure(hapd
, mic
->iev_src
, 1);
682 bsd_wireless_event_init(void *priv
)
684 struct bsd_driver_data
*drv
= priv
;
689 s
= socket(PF_ROUTE
, SOCK_RAW
, 0);
691 perror("socket(PF_ROUTE,SOCK_RAW)");
694 eloop_register_read_sock(s
, bsd_wireless_event_receive
, drv
, NULL
);
701 bsd_wireless_event_deinit(void *priv
)
703 struct bsd_driver_data
*drv
= priv
;
706 if (drv
->wext_sock
< 0)
708 eloop_unregister_read_sock(drv
->wext_sock
);
709 close(drv
->wext_sock
);
715 bsd_send_eapol(void *priv
, u8
*addr
, u8
*data
, size_t data_len
, int encrypt
)
717 struct bsd_driver_data
*drv
= priv
;
718 hostapd
*hapd
= drv
->hapd
;
719 unsigned char buf
[3000];
720 unsigned char *bp
= buf
;
721 struct l2_ethhdr
*eth
;
726 * Prepend the Etherent header. If the caller left us
727 * space at the front we could just insert it but since
728 * we don't know we copy to a local buffer. Given the frequency
729 * and size of frames this probably doesn't matter.
731 len
= data_len
+ sizeof(struct l2_ethhdr
);
732 if (len
> sizeof(buf
)) {
735 printf("EAPOL frame discarded, cannot malloc temp "
736 "buffer of size %u!\n", len
);
740 eth
= (struct l2_ethhdr
*) bp
;
741 memcpy(eth
->h_dest
, addr
, ETH_ALEN
);
742 memcpy(eth
->h_source
, drv
->hapd
->own_addr
, ETH_ALEN
);
743 eth
->h_proto
= htons(ETH_P_EAPOL
);
744 memcpy(eth
+1, data
, data_len
);
746 if (HOSTAPD_DEBUG_COND(HOSTAPD_DEBUG_MSGDUMPS
))
747 hostapd_hexdump("TX EAPOL", bp
, len
);
749 status
= l2_packet_send(drv
->sock_xmit
, addr
, ETH_P_EAPOL
, bp
, len
);
757 handle_read(void *ctx
, const u8
*src_addr
, const u8
*buf
, size_t len
)
759 struct bsd_driver_data
*drv
= ctx
;
760 hostapd
*hapd
= drv
->hapd
;
761 struct sta_info
*sta
;
763 sta
= ap_get_sta(hapd
, src_addr
);
764 if (!sta
|| !(sta
->flags
& WLAN_STA_ASSOC
)) {
765 printf("Data frame from not associated STA %s\n",
766 ether_sprintf(src_addr
));
767 /* XXX cannot happen */
770 ieee802_1x_receive(hapd
, src_addr
, buf
+ sizeof(struct l2_ethhdr
),
771 len
- sizeof(struct l2_ethhdr
));
775 bsd_get_ssid(void *priv
, u8
*buf
, int len
)
777 struct bsd_driver_data
*drv
= priv
;
778 hostapd
*hapd
= drv
->hapd
;
779 int ssid_len
= get80211var(priv
, IEEE80211_IOC_SSID
, buf
, len
);
781 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
, "%s: ssid=\"%.*s\"\n",
782 __func__
, ssid_len
, buf
);
788 bsd_set_ssid(void *priv
, u8
*buf
, int len
)
790 struct bsd_driver_data
*drv
= priv
;
791 hostapd
*hapd
= drv
->hapd
;
793 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
, "%s: ssid=\"%.*s\"\n",
796 return set80211var(priv
, IEEE80211_IOC_SSID
, buf
, len
);
800 bsd_set_countermeasures(void *priv
, int enabled
)
802 struct bsd_driver_data
*drv
= priv
;
804 wpa_printf(MSG_DEBUG
, "%s: enabled=%d", __FUNCTION__
, enabled
);
805 return set80211param(drv
, IEEE80211_IOC_COUNTERMEASURES
, enabled
);
809 bsd_init(struct hostapd_data
*hapd
)
811 struct bsd_driver_data
*drv
;
813 drv
= malloc(sizeof(struct bsd_driver_data
));
815 printf("Could not allocate memory for bsd driver data\n");
819 memset(drv
, 0, sizeof(*drv
));
820 drv
->ops
= bsd_driver_ops
;
822 drv
->ioctl_sock
= socket(PF_INET
, SOCK_DGRAM
, 0);
823 if (drv
->ioctl_sock
< 0) {
824 perror("socket[PF_INET,SOCK_DGRAM]");
827 memcpy(drv
->iface
, hapd
->conf
->iface
, sizeof(drv
->iface
));
829 drv
->sock_xmit
= l2_packet_init(drv
->iface
, NULL
, ETH_P_EAPOL
,
830 handle_read
, drv
, 1);
831 if (drv
->sock_xmit
== NULL
)
833 if (l2_packet_get_own_addr(drv
->sock_xmit
, hapd
->own_addr
))
836 bsd_set_iface_flags(drv
, 0); /* mark down during setup */
838 hapd
->driver
= &drv
->ops
;
842 if (drv
->sock_xmit
!= NULL
)
843 l2_packet_deinit(drv
->sock_xmit
);
844 if (drv
->ioctl_sock
>= 0)
845 close(drv
->ioctl_sock
);
853 bsd_deinit(void *priv
)
855 struct bsd_driver_data
*drv
= priv
;
857 drv
->hapd
->driver
= NULL
;
859 (void) bsd_set_iface_flags(drv
, 0);
860 if (drv
->ioctl_sock
>= 0)
861 close(drv
->ioctl_sock
);
862 if (drv
->sock_xmit
!= NULL
)
863 l2_packet_deinit(drv
->sock_xmit
);
867 static const struct driver_ops bsd_driver_ops
= {
870 .deinit
= bsd_deinit
,
871 .set_ieee8021x
= bsd_set_ieee8021x
,
872 .set_privacy
= bsd_set_privacy
,
873 .set_encryption
= bsd_set_key
,
874 .get_seqnum
= bsd_get_seqnum
,
876 .set_generic_elem
= bsd_set_opt_ie
,
877 .wireless_event_init
= bsd_wireless_event_init
,
878 .wireless_event_deinit
= bsd_wireless_event_deinit
,
879 .set_sta_authorized
= bsd_set_sta_authorized
,
880 .read_sta_data
= bsd_read_sta_driver_data
,
881 .send_eapol
= bsd_send_eapol
,
882 .sta_disassoc
= bsd_sta_disassoc
,
883 .sta_deauth
= bsd_sta_deauth
,
884 .set_ssid
= bsd_set_ssid
,
885 .get_ssid
= bsd_get_ssid
,
886 .set_countermeasures
= bsd_set_countermeasures
,
887 .sta_clear_stats
= bsd_sta_clear_stats
,
890 void bsd_driver_register(void)
892 driver_register(bsd_driver_ops
.name
, &bsd_driver_ops
);