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.6 2007/07/09 16:26:48 sam Exp $
16 * $DragonFly: src/usr.sbin/802_11/hostapd/driver_dragonfly.c,v 1.3 2007/08/07 11:25:36 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
, const 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 struct hostapd_data
*hapd
= drv
->hapd
;
136 struct hostapd_bss_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 struct hostapd_data
*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(const char *ifname
, void *priv
, int enabled
)
267 struct bsd_driver_data
*drv
= priv
;
268 struct hostapd_data
*hapd
= drv
->hapd
;
269 struct hostapd_bss_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(const char *ifname
, void *priv
, int enabled
)
301 struct bsd_driver_data
*drv
= priv
;
302 struct hostapd_data
*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
, const u8
*addr
, int authorized
)
313 struct bsd_driver_data
*drv
= priv
;
314 struct hostapd_data
*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_sta_set_flags(void *priv
, const u8
*addr
, int flags_or
, int flags_and
)
333 /* For now, only support setting Authorized flag */
334 if (flags_or
& WLAN_STA_AUTHORIZED
)
335 return bsd_set_sta_authorized(priv
, addr
, 1);
336 if (!(flags_and
& WLAN_STA_AUTHORIZED
))
337 return bsd_set_sta_authorized(priv
, addr
, 0);
342 bsd_del_key(void *priv
, const unsigned char *addr
, int key_idx
)
344 struct bsd_driver_data
*drv
= priv
;
345 struct hostapd_data
*hapd
= drv
->hapd
;
346 struct ieee80211req_del_key wk
;
348 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
,
349 "%s: addr=%s key_idx=%d\n",
350 __func__
, ether_sprintf(addr
), key_idx
);
352 memset(&wk
, 0, sizeof(wk
));
354 memcpy(wk
.idk_macaddr
, addr
, IEEE80211_ADDR_LEN
);
355 wk
.idk_keyix
= (u_int8_t
) IEEE80211_KEYIX_NONE
; /* XXX */
357 wk
.idk_keyix
= key_idx
;
360 return set80211var(priv
, IEEE80211_IOC_DELKEY
, &wk
, sizeof(wk
));
364 bsd_set_key(const char *ifname
, void *priv
, const char *alg
,
365 const u8
*addr
, int key_idx
,
366 const u8
*key
, size_t key_len
, int txkey
)
368 struct bsd_driver_data
*drv
= priv
;
369 struct hostapd_data
*hapd
= drv
->hapd
;
370 struct ieee80211req_key wk
;
373 if (strcmp(alg
, "none") == 0)
374 return bsd_del_key(priv
, addr
, key_idx
);
376 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
,
377 "%s: alg=%s addr=%s key_idx=%d\n",
378 __func__
, alg
, ether_sprintf(addr
), key_idx
);
380 if (strcmp(alg
, "WEP") == 0)
381 cipher
= IEEE80211_CIPHER_WEP
;
382 else if (strcmp(alg
, "TKIP") == 0)
383 cipher
= IEEE80211_CIPHER_TKIP
;
384 else if (strcmp(alg
, "CCMP") == 0)
385 cipher
= IEEE80211_CIPHER_AES_CCM
;
387 printf("%s: unknown/unsupported algorithm %s\n",
392 if (key_len
> sizeof(wk
.ik_keydata
)) {
393 printf("%s: key length %d too big\n", __func__
, key_len
);
397 memset(&wk
, 0, sizeof(wk
));
399 wk
.ik_flags
= IEEE80211_KEY_RECV
| IEEE80211_KEY_XMIT
;
401 memset(wk
.ik_macaddr
, 0xff, IEEE80211_ADDR_LEN
);
402 wk
.ik_keyix
= key_idx
;
403 wk
.ik_flags
|= IEEE80211_KEY_DEFAULT
| IEEE80211_KEY_GROUP
;
405 memcpy(wk
.ik_macaddr
, addr
, IEEE80211_ADDR_LEN
);
406 wk
.ik_keyix
= IEEE80211_KEYIX_NONE
;
408 wk
.ik_keylen
= key_len
;
409 memcpy(wk
.ik_keydata
, key
, key_len
);
411 return set80211var(priv
, IEEE80211_IOC_WPAKEY
, &wk
, sizeof(wk
));
416 bsd_get_seqnum(const char *ifname
, void *priv
, const u8
*addr
, int idx
,
419 struct bsd_driver_data
*drv
= priv
;
420 struct hostapd_data
*hapd
= drv
->hapd
;
421 struct ieee80211req_key wk
;
423 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
,
424 "%s: addr=%s idx=%d\n", __func__
, ether_sprintf(addr
), idx
);
426 memset(&wk
, 0, sizeof(wk
));
428 memset(wk
.ik_macaddr
, 0xff, IEEE80211_ADDR_LEN
);
430 memcpy(wk
.ik_macaddr
, addr
, IEEE80211_ADDR_LEN
);
433 if (get80211var(drv
, IEEE80211_IOC_WPAKEY
, &wk
, sizeof(wk
)) < 0) {
434 printf("Failed to get encryption.\n");
437 /* NB: upper layer expects tsc in network order */
438 wk
.ik_keytsc
= htole64(wk
.ik_keytsc
);
439 memcpy(seq
, &wk
.ik_keytsc
, sizeof(wk
.ik_keytsc
));
446 bsd_flush(void *priv
)
448 u8 allsta
[IEEE80211_ADDR_LEN
];
450 memset(allsta
, 0xff, IEEE80211_ADDR_LEN
);
451 return bsd_sta_deauth(priv
, allsta
, IEEE80211_REASON_AUTH_LEAVE
);
456 bsd_read_sta_driver_data(void *priv
, struct hostap_sta_driver_data
*data
,
459 struct bsd_driver_data
*drv
= priv
;
460 struct ieee80211req_sta_stats stats
;
462 memcpy(stats
.is_u
.macaddr
, addr
, IEEE80211_ADDR_LEN
);
463 if (get80211var(drv
, IEEE80211_IOC_STA_STATS
, &stats
, sizeof(stats
)) > 0) {
464 /* XXX? do packets counts include non-data frames? */
465 data
->rx_packets
= stats
.is_stats
.ns_rx_data
;
466 data
->rx_bytes
= stats
.is_stats
.ns_rx_bytes
;
467 data
->tx_packets
= stats
.is_stats
.ns_tx_data
;
468 data
->tx_bytes
= stats
.is_stats
.ns_tx_bytes
;
474 bsd_sta_clear_stats(void *priv
, const u8
*addr
)
476 struct bsd_driver_data
*drv
= priv
;
477 struct hostapd_data
*hapd
= drv
->hapd
;
478 struct ieee80211req_sta_stats stats
;
480 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
, "%s: addr=%s\n",
481 __func__
, ether_sprintf(addr
));
483 /* zero station statistics */
484 memset(&stats
, 0, sizeof(stats
));
485 memcpy(stats
.is_u
.macaddr
, addr
, IEEE80211_ADDR_LEN
);
486 return set80211var(drv
, IEEE80211_IOC_STA_STATS
, &stats
, sizeof(stats
));
490 bsd_set_opt_ie(const char *ifname
, void *priv
, const u8
*ie
, size_t ie_len
)
493 * Do nothing; we setup parameters at startup that define the
494 * contents of the beacon information element.
500 bsd_sta_deauth(void *priv
, const u8
*addr
, int reason_code
)
502 struct bsd_driver_data
*drv
= priv
;
503 struct hostapd_data
*hapd
= drv
->hapd
;
504 struct ieee80211req_mlme mlme
;
506 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
,
507 "%s: addr=%s reason_code=%d\n",
508 __func__
, ether_sprintf(addr
), reason_code
);
510 mlme
.im_op
= IEEE80211_MLME_DEAUTH
;
511 mlme
.im_reason
= reason_code
;
512 memcpy(mlme
.im_macaddr
, addr
, IEEE80211_ADDR_LEN
);
513 return set80211var(priv
, IEEE80211_IOC_MLME
, &mlme
, sizeof(mlme
));
517 bsd_sta_disassoc(void *priv
, const u8
*addr
, int reason_code
)
519 struct bsd_driver_data
*drv
= priv
;
520 struct hostapd_data
*hapd
= drv
->hapd
;
521 struct ieee80211req_mlme mlme
;
523 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
,
524 "%s: addr=%s reason_code=%d\n",
525 __func__
, ether_sprintf(addr
), reason_code
);
527 mlme
.im_reason
= reason_code
;
528 memcpy(mlme
.im_macaddr
, addr
, IEEE80211_ADDR_LEN
);
529 return set80211var(priv
, IEEE80211_IOC_MLME
, &mlme
, sizeof(mlme
));
533 bsd_del_sta(struct bsd_driver_data
*drv
, u8 addr
[IEEE80211_ADDR_LEN
])
535 struct hostapd_data
*hapd
= drv
->hapd
;
536 struct hostapd_bss_config
*conf
= hapd
->conf
;
537 struct sta_info
*sta
;
539 hostapd_logger(hapd
, addr
, HOSTAPD_MODULE_IEEE80211
,
540 HOSTAPD_LEVEL_INFO
, "deassociated");
542 sta
= ap_get_sta(hapd
, addr
);
544 sta
->flags
&= ~(WLAN_STA_AUTH
| WLAN_STA_ASSOC
);
546 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DISASSOC
);
547 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
548 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
549 ap_free_sta(hapd
, sta
);
555 bsd_new_sta(struct bsd_driver_data
*drv
, u8 addr
[IEEE80211_ADDR_LEN
])
557 struct hostapd_data
*hapd
= drv
->hapd
;
558 struct hostapd_bss_config
*conf
= hapd
->conf
;
559 struct sta_info
*sta
;
560 struct ieee80211req_wpaie ie
;
561 int new_assoc
, ielen
, res
;
563 hostapd_logger(hapd
, addr
, HOSTAPD_MODULE_IEEE80211
,
564 HOSTAPD_LEVEL_INFO
, "associated");
566 sta
= ap_sta_add(hapd
, addr
);
570 * Fetch and validate any negotiated WPA/RSN parameters.
573 memset(&ie
, 0, sizeof(ie
));
574 memcpy(ie
.wpa_macaddr
, addr
, IEEE80211_ADDR_LEN
);
575 if (get80211var(drv
, IEEE80211_IOC_WPAIE
, &ie
, sizeof(ie
)) < 0) {
576 printf("Failed to get WPA/RSN information element.\n");
577 return -1; /* XXX not right */
579 if (ie
.wpa_ie
[1] == 0) {
580 printf("No WPA/RSN information element for station!\n");
581 return -1; /* XXX not right */
583 if (sta
->wpa_sm
== NULL
)
584 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
586 if (sta
->wpa_sm
== NULL
) {
587 printf("Failed to initialize WPA state machine\n");
590 ielen
= 2 + ie
.wpa_ie
[1];
591 res
= wpa_validate_wpa_ie(hapd
->wpa_auth
, sta
->wpa_sm
,
593 if (res
!= WPA_IE_OK
) {
594 printf("WPA/RSN information element rejected? "
601 * Now that the internal station state is setup
602 * kick the authenticator into action.
604 new_assoc
= (sta
->flags
& WLAN_STA_ASSOC
) == 0;
605 sta
->flags
|= WLAN_STA_AUTH
| WLAN_STA_ASSOC
;
606 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC
);
607 hostapd_new_assoc_sta(hapd
, sta
, !new_assoc
);
608 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 1);
613 #include <net/route.h>
614 #include <netproto/802_11/ieee80211_dragonfly.h>
617 bsd_wireless_event_receive(int sock
, void *ctx
, void *sock_ctx
)
619 struct bsd_driver_data
*drv
= ctx
;
620 struct hostapd_data
*hapd
= drv
->hapd
;
622 struct if_announcemsghdr
*ifan
;
623 struct rt_msghdr
*rtm
;
624 struct ieee80211_michael_event
*mic
;
625 struct ieee80211_join_event
*join
;
626 struct ieee80211_leave_event
*leave
;
629 n
= read(sock
, buf
, sizeof(buf
));
631 if (errno
!= EINTR
&& errno
!= EAGAIN
)
632 perror("read(PF_ROUTE)");
636 rtm
= (struct rt_msghdr
*) buf
;
637 if (rtm
->rtm_version
!= RTM_VERSION
) {
638 wpa_printf(MSG_DEBUG
, "Routing message version %d not "
639 "understood\n", rtm
->rtm_version
);
642 ifan
= (struct if_announcemsghdr
*) rtm
;
643 switch (rtm
->rtm_type
) {
645 switch (ifan
->ifan_what
) {
646 case RTM_IEEE80211_ASSOC
:
647 case RTM_IEEE80211_REASSOC
:
648 case RTM_IEEE80211_DISASSOC
:
649 case RTM_IEEE80211_SCAN
:
651 case RTM_IEEE80211_LEAVE
:
652 leave
= (struct ieee80211_leave_event
*) &ifan
[1];
653 bsd_del_sta(drv
, leave
->iev_addr
);
655 case RTM_IEEE80211_JOIN
:
656 #ifdef RTM_IEEE80211_REJOIN
657 case RTM_IEEE80211_REJOIN
:
659 join
= (struct ieee80211_join_event
*) &ifan
[1];
660 bsd_new_sta(drv
, join
->iev_addr
);
662 case RTM_IEEE80211_REPLAY
:
665 case RTM_IEEE80211_MICHAEL
:
666 mic
= (struct ieee80211_michael_event
*) &ifan
[1];
667 wpa_printf(MSG_DEBUG
,
668 "Michael MIC failure wireless event: "
669 "keyix=%u src_addr=" MACSTR
, mic
->iev_keyix
,
670 MAC2STR(mic
->iev_src
));
671 ieee80211_michael_mic_failure(hapd
, mic
->iev_src
, 1);
679 bsd_wireless_event_init(void *priv
)
681 struct bsd_driver_data
*drv
= priv
;
686 s
= socket(PF_ROUTE
, SOCK_RAW
, 0);
688 perror("socket(PF_ROUTE,SOCK_RAW)");
691 eloop_register_read_sock(s
, bsd_wireless_event_receive
, drv
, NULL
);
698 bsd_wireless_event_deinit(void *priv
)
700 struct bsd_driver_data
*drv
= priv
;
703 if (drv
->wext_sock
< 0)
705 eloop_unregister_read_sock(drv
->wext_sock
);
706 close(drv
->wext_sock
);
712 bsd_send_eapol(void *priv
, const u8
*addr
, const u8
*data
, size_t data_len
,
713 int encrypt
, const u8
*own_addr
)
715 struct bsd_driver_data
*drv
= priv
;
716 struct hostapd_data
*hapd
= drv
->hapd
;
717 unsigned char buf
[3000];
718 unsigned char *bp
= buf
;
719 struct l2_ethhdr
*eth
;
724 * Prepend the Etherent header. If the caller left us
725 * space at the front we could just insert it but since
726 * we don't know we copy to a local buffer. Given the frequency
727 * and size of frames this probably doesn't matter.
729 len
= data_len
+ sizeof(struct l2_ethhdr
);
730 if (len
> sizeof(buf
)) {
733 printf("EAPOL frame discarded, cannot malloc temp "
734 "buffer of size %u!\n", len
);
738 eth
= (struct l2_ethhdr
*) bp
;
739 memcpy(eth
->h_dest
, addr
, ETH_ALEN
);
740 memcpy(eth
->h_source
, own_addr
, ETH_ALEN
);
741 eth
->h_proto
= htons(ETH_P_EAPOL
);
742 memcpy(eth
+1, data
, data_len
);
744 wpa_hexdump(MSG_MSGDUMP
, "TX EAPOL", bp
, len
);
746 status
= l2_packet_send(drv
->sock_xmit
, addr
, ETH_P_EAPOL
, bp
, len
);
754 handle_read(void *ctx
, const u8
*src_addr
, const u8
*buf
, size_t len
)
756 struct bsd_driver_data
*drv
= ctx
;
757 struct hostapd_data
*hapd
= drv
->hapd
;
758 struct sta_info
*sta
;
760 sta
= ap_get_sta(hapd
, src_addr
);
761 if (!sta
|| !(sta
->flags
& WLAN_STA_ASSOC
)) {
762 printf("Data frame from not associated STA %s\n",
763 ether_sprintf(src_addr
));
764 /* XXX cannot happen */
767 ieee802_1x_receive(hapd
, src_addr
, buf
+ sizeof(struct l2_ethhdr
),
768 len
- sizeof(struct l2_ethhdr
));
772 bsd_get_ssid(const char *ifname
, void *priv
, u8
*buf
, int len
)
774 struct bsd_driver_data
*drv
= priv
;
775 struct hostapd_data
*hapd
= drv
->hapd
;
776 int ssid_len
= get80211var(priv
, IEEE80211_IOC_SSID
, buf
, len
);
778 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
, "%s: ssid=\"%.*s\"\n",
779 __func__
, ssid_len
, buf
);
785 bsd_set_ssid(const char *ifname
, void *priv
, const u8
*buf
, int len
)
787 struct bsd_driver_data
*drv
= priv
;
788 struct hostapd_data
*hapd
= drv
->hapd
;
790 HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL
, "%s: ssid=\"%.*s\"\n",
793 return set80211var(priv
, IEEE80211_IOC_SSID
, buf
, len
);
797 bsd_set_countermeasures(void *priv
, int enabled
)
799 struct bsd_driver_data
*drv
= priv
;
801 wpa_printf(MSG_DEBUG
, "%s: enabled=%d", __FUNCTION__
, enabled
);
802 return set80211param(drv
, IEEE80211_IOC_COUNTERMEASURES
, enabled
);
806 bsd_init(struct hostapd_data
*hapd
)
808 struct bsd_driver_data
*drv
;
810 drv
= malloc(sizeof(struct bsd_driver_data
));
812 printf("Could not allocate memory for bsd driver data\n");
816 memset(drv
, 0, sizeof(*drv
));
817 drv
->ops
= bsd_driver_ops
;
819 drv
->ioctl_sock
= socket(PF_INET
, SOCK_DGRAM
, 0);
820 if (drv
->ioctl_sock
< 0) {
821 perror("socket[PF_INET,SOCK_DGRAM]");
824 memcpy(drv
->iface
, hapd
->conf
->iface
, sizeof(drv
->iface
));
826 drv
->sock_xmit
= l2_packet_init(drv
->iface
, NULL
, ETH_P_EAPOL
,
827 handle_read
, drv
, 1);
828 if (drv
->sock_xmit
== NULL
)
830 if (l2_packet_get_own_addr(drv
->sock_xmit
, hapd
->own_addr
))
833 bsd_set_iface_flags(drv
, 0); /* mark down during setup */
835 hapd
->driver
= &drv
->ops
;
839 if (drv
->sock_xmit
!= NULL
)
840 l2_packet_deinit(drv
->sock_xmit
);
841 if (drv
->ioctl_sock
>= 0)
842 close(drv
->ioctl_sock
);
850 bsd_deinit(void *priv
)
852 struct bsd_driver_data
*drv
= priv
;
854 drv
->hapd
->driver
= NULL
;
856 (void) bsd_set_iface_flags(drv
, 0);
857 if (drv
->ioctl_sock
>= 0)
858 close(drv
->ioctl_sock
);
859 if (drv
->sock_xmit
!= NULL
)
860 l2_packet_deinit(drv
->sock_xmit
);
864 static const struct driver_ops bsd_driver_ops
= {
867 .deinit
= bsd_deinit
,
868 .set_ieee8021x
= bsd_set_ieee8021x
,
869 .set_privacy
= bsd_set_privacy
,
870 .set_encryption
= bsd_set_key
,
871 .get_seqnum
= bsd_get_seqnum
,
873 .set_generic_elem
= bsd_set_opt_ie
,
874 .wireless_event_init
= bsd_wireless_event_init
,
875 .wireless_event_deinit
= bsd_wireless_event_deinit
,
876 .sta_set_flags
= bsd_sta_set_flags
,
877 .read_sta_data
= bsd_read_sta_driver_data
,
878 .send_eapol
= bsd_send_eapol
,
879 .sta_disassoc
= bsd_sta_disassoc
,
880 .sta_deauth
= bsd_sta_deauth
,
881 .set_ssid
= bsd_set_ssid
,
882 .get_ssid
= bsd_get_ssid
,
883 .set_countermeasures
= bsd_set_countermeasures
,
884 .sta_clear_stats
= bsd_sta_clear_stats
,
887 void bsd_driver_register(void)
889 driver_register(bsd_driver_ops
.name
, &bsd_driver_ops
);