2 * hostapd / 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.
17 #include <sys/ioctl.h>
21 #include <net80211/ieee80211.h>
22 #include <net80211/ieee80211_crypto.h>
23 #include <net80211/ieee80211_ioctl.h>
26 * Avoid conflicts with hostapd definitions by undefining couple of defines
27 * from net80211 header files.
36 #include "ieee802_1x.h"
39 #include "l2_packet/l2_packet.h"
43 #include "radius/radius.h"
44 #include "ieee802_11.h"
47 struct bsd_driver_data
{
48 struct hostapd_data
*hapd
; /* back pointer */
50 char iface
[IFNAMSIZ
+ 1];
51 struct l2_packet_data
*sock_xmit
; /* raw packet xmit socket */
52 int ioctl_sock
; /* socket for ioctl() use */
53 int wext_sock
; /* socket for wireless events */
56 static int bsd_sta_deauth(void *priv
, const u8
*addr
, int reason_code
);
59 set80211var(struct bsd_driver_data
*drv
, int op
, const void *arg
, int arg_len
)
61 struct ieee80211req ireq
;
63 memset(&ireq
, 0, sizeof(ireq
));
64 os_strlcpy(ireq
.i_name
, drv
->iface
, IFNAMSIZ
);
67 ireq
.i_data
= (void *) arg
;
69 if (ioctl(drv
->ioctl_sock
, SIOCS80211
, &ireq
) < 0) {
70 perror("ioctl[SIOCS80211]");
77 get80211var(struct bsd_driver_data
*drv
, int op
, void *arg
, int arg_len
)
79 struct ieee80211req ireq
;
81 memset(&ireq
, 0, sizeof(ireq
));
82 os_strlcpy(ireq
.i_name
, drv
->iface
, IFNAMSIZ
);
87 if (ioctl(drv
->ioctl_sock
, SIOCG80211
, &ireq
) < 0) {
88 perror("ioctl[SIOCG80211]");
95 set80211param(struct bsd_driver_data
*drv
, int op
, int arg
)
97 struct ieee80211req ireq
;
99 memset(&ireq
, 0, sizeof(ireq
));
100 os_strlcpy(ireq
.i_name
, drv
->iface
, IFNAMSIZ
);
104 if (ioctl(drv
->ioctl_sock
, SIOCS80211
, &ireq
) < 0) {
105 perror("ioctl[SIOCS80211]");
112 ether_sprintf(const u8
*addr
)
114 static char buf
[sizeof(MACSTR
)];
117 snprintf(buf
, sizeof(buf
), MACSTR
, MAC2STR(addr
));
119 snprintf(buf
, sizeof(buf
), MACSTR
, 0,0,0,0,0,0);
124 * Configure WPA parameters.
127 bsd_configure_wpa(struct bsd_driver_data
*drv
)
129 static const char *ciphernames
[] =
130 { "WEP", "TKIP", "AES-OCB", "AES-CCM", "CKIP", "NONE" };
131 struct hostapd_data
*hapd
= drv
->hapd
;
132 struct hostapd_bss_config
*conf
= hapd
->conf
;
135 switch (conf
->wpa_group
) {
136 case WPA_CIPHER_CCMP
:
137 v
= IEEE80211_CIPHER_AES_CCM
;
139 case WPA_CIPHER_TKIP
:
140 v
= IEEE80211_CIPHER_TKIP
;
142 case WPA_CIPHER_WEP104
:
143 v
= IEEE80211_CIPHER_WEP
;
145 case WPA_CIPHER_WEP40
:
146 v
= IEEE80211_CIPHER_WEP
;
148 case WPA_CIPHER_NONE
:
149 v
= IEEE80211_CIPHER_NONE
;
152 printf("Unknown group key cipher %u\n",
156 wpa_printf(MSG_DEBUG
, "%s: group key cipher=%s (%u)",
157 __func__
, ciphernames
[v
], v
);
158 if (set80211param(drv
, IEEE80211_IOC_MCASTCIPHER
, v
)) {
159 printf("Unable to set group key cipher to %u (%s)\n",
163 if (v
== IEEE80211_CIPHER_WEP
) {
164 /* key length is done only for specific ciphers */
165 v
= (conf
->wpa_group
== WPA_CIPHER_WEP104
? 13 : 5);
166 if (set80211param(drv
, IEEE80211_IOC_MCASTKEYLEN
, v
)) {
167 printf("Unable to set group key length to %u\n", v
);
173 if (conf
->wpa_pairwise
& WPA_CIPHER_CCMP
)
174 v
|= 1<<IEEE80211_CIPHER_AES_CCM
;
175 if (conf
->wpa_pairwise
& WPA_CIPHER_TKIP
)
176 v
|= 1<<IEEE80211_CIPHER_TKIP
;
177 if (conf
->wpa_pairwise
& WPA_CIPHER_NONE
)
178 v
|= 1<<IEEE80211_CIPHER_NONE
;
179 wpa_printf(MSG_DEBUG
, "%s: pairwise key ciphers=0x%x", __func__
, v
);
180 if (set80211param(drv
, IEEE80211_IOC_UCASTCIPHERS
, v
)) {
181 printf("Unable to set pairwise key ciphers to 0x%x\n", v
);
185 wpa_printf(MSG_DEBUG
, "%s: key management algorithms=0x%x",
186 __func__
, conf
->wpa_key_mgmt
);
187 if (set80211param(drv
, IEEE80211_IOC_KEYMGTALGS
, conf
->wpa_key_mgmt
)) {
188 printf("Unable to set key management algorithms to 0x%x\n",
194 if (conf
->rsn_preauth
)
196 wpa_printf(MSG_DEBUG
, "%s: rsn capabilities=0x%x",
197 __func__
, conf
->rsn_preauth
);
198 if (set80211param(drv
, IEEE80211_IOC_RSNCAPS
, v
)) {
199 printf("Unable to set RSN capabilities to 0x%x\n", v
);
203 wpa_printf(MSG_DEBUG
, "%s: enable WPA= 0x%x", __func__
, conf
->wpa
);
204 if (set80211param(drv
, IEEE80211_IOC_WPA
, conf
->wpa
)) {
205 printf("Unable to set WPA to %u\n", conf
->wpa
);
213 bsd_set_iface_flags(void *priv
, int dev_up
)
215 struct bsd_driver_data
*drv
= priv
;
218 wpa_printf(MSG_DEBUG
, "%s: dev_up=%d", __func__
, dev_up
);
220 if (drv
->ioctl_sock
< 0)
223 memset(&ifr
, 0, sizeof(ifr
));
224 os_strlcpy(ifr
.ifr_name
, drv
->iface
, IFNAMSIZ
);
226 if (ioctl(drv
->ioctl_sock
, SIOCGIFFLAGS
, &ifr
) != 0) {
227 perror("ioctl[SIOCGIFFLAGS]");
232 ifr
.ifr_flags
|= IFF_UP
;
234 ifr
.ifr_flags
&= ~IFF_UP
;
236 if (ioctl(drv
->ioctl_sock
, SIOCSIFFLAGS
, &ifr
) != 0) {
237 perror("ioctl[SIOCSIFFLAGS]");
242 memset(&ifr
, 0, sizeof(ifr
));
243 os_strlcpy(ifr
.ifr_name
, drv
->iface
, IFNAMSIZ
);
244 ifr
.ifr_mtu
= HOSTAPD_MTU
;
245 if (ioctl(drv
->ioctl_sock
, SIOCSIFMTU
, &ifr
) != 0) {
246 perror("ioctl[SIOCSIFMTU]");
247 printf("Setting MTU failed - trying to survive with "
256 bsd_set_ieee8021x(const char *ifname
, void *priv
, int enabled
)
258 struct bsd_driver_data
*drv
= priv
;
259 struct hostapd_data
*hapd
= drv
->hapd
;
260 struct hostapd_bss_config
*conf
= hapd
->conf
;
262 wpa_printf(MSG_DEBUG
, "%s: enabled=%d", __func__
, enabled
);
265 /* XXX restore state */
266 return set80211param(priv
, IEEE80211_IOC_AUTHMODE
,
267 IEEE80211_AUTH_AUTO
);
269 if (!conf
->wpa
&& !conf
->ieee802_1x
) {
270 hostapd_logger(hapd
, NULL
, HOSTAPD_MODULE_DRIVER
,
271 HOSTAPD_LEVEL_WARNING
, "No 802.1X or WPA enabled!");
274 if (conf
->wpa
&& bsd_configure_wpa(drv
) != 0) {
275 hostapd_logger(hapd
, NULL
, HOSTAPD_MODULE_DRIVER
,
276 HOSTAPD_LEVEL_WARNING
, "Error configuring WPA state!");
279 if (set80211param(priv
, IEEE80211_IOC_AUTHMODE
,
280 (conf
->wpa
? IEEE80211_AUTH_WPA
: IEEE80211_AUTH_8021X
))) {
281 hostapd_logger(hapd
, NULL
, HOSTAPD_MODULE_DRIVER
,
282 HOSTAPD_LEVEL_WARNING
, "Error enabling WPA/802.1X!");
285 return bsd_set_iface_flags(priv
, 1);
289 bsd_set_privacy(const char *ifname
, void *priv
, int enabled
)
291 struct bsd_driver_data
*drv
= priv
;
293 wpa_printf(MSG_DEBUG
, "%s: enabled=%d", __func__
, enabled
);
295 return set80211param(drv
, IEEE80211_IOC_PRIVACY
, enabled
);
299 bsd_set_sta_authorized(void *priv
, const u8
*addr
, int authorized
)
301 struct bsd_driver_data
*drv
= priv
;
302 struct ieee80211req_mlme mlme
;
304 wpa_printf(MSG_DEBUG
, "%s: addr=%s authorized=%d",
305 __func__
, ether_sprintf(addr
), authorized
);
308 mlme
.im_op
= IEEE80211_MLME_AUTHORIZE
;
310 mlme
.im_op
= IEEE80211_MLME_UNAUTHORIZE
;
312 memcpy(mlme
.im_macaddr
, addr
, IEEE80211_ADDR_LEN
);
313 return set80211var(drv
, IEEE80211_IOC_MLME
, &mlme
, sizeof(mlme
));
317 bsd_sta_set_flags(void *priv
, const u8
*addr
, int total_flags
, int flags_or
,
320 /* For now, only support setting Authorized flag */
321 if (flags_or
& WLAN_STA_AUTHORIZED
)
322 return bsd_set_sta_authorized(priv
, addr
, 1);
323 if (!(flags_and
& WLAN_STA_AUTHORIZED
))
324 return bsd_set_sta_authorized(priv
, addr
, 0);
329 bsd_del_key(void *priv
, const u8
*addr
, int key_idx
)
331 struct bsd_driver_data
*drv
= priv
;
332 struct ieee80211req_del_key wk
;
334 wpa_printf(MSG_DEBUG
, "%s: addr=%s key_idx=%d",
335 __func__
, ether_sprintf(addr
), key_idx
);
337 memset(&wk
, 0, sizeof(wk
));
339 memcpy(wk
.idk_macaddr
, addr
, IEEE80211_ADDR_LEN
);
340 wk
.idk_keyix
= (u_int8_t
) IEEE80211_KEYIX_NONE
; /* XXX */
342 wk
.idk_keyix
= key_idx
;
345 return set80211var(drv
, IEEE80211_IOC_DELKEY
, &wk
, sizeof(wk
));
349 bsd_set_key(const char *ifname
, void *priv
, const char *alg
,
350 const u8
*addr
, int key_idx
,
351 const u8
*key
, size_t key_len
, int txkey
)
353 struct bsd_driver_data
*drv
= priv
;
354 struct ieee80211req_key wk
;
357 if (strcmp(alg
, "none") == 0)
358 return bsd_del_key(drv
, addr
, key_idx
);
360 wpa_printf(MSG_DEBUG
, "%s: alg=%s addr=%s key_idx=%d",
361 __func__
, alg
, ether_sprintf(addr
), key_idx
);
363 if (strcmp(alg
, "WEP") == 0)
364 cipher
= IEEE80211_CIPHER_WEP
;
365 else if (strcmp(alg
, "TKIP") == 0)
366 cipher
= IEEE80211_CIPHER_TKIP
;
367 else if (strcmp(alg
, "CCMP") == 0)
368 cipher
= IEEE80211_CIPHER_AES_CCM
;
370 printf("%s: unknown/unsupported algorithm %s\n",
375 if (key_len
> sizeof(wk
.ik_keydata
)) {
376 printf("%s: key length %d too big\n", __func__
, key_len
);
380 memset(&wk
, 0, sizeof(wk
));
382 wk
.ik_flags
= IEEE80211_KEY_RECV
| IEEE80211_KEY_XMIT
;
384 memset(wk
.ik_macaddr
, 0xff, IEEE80211_ADDR_LEN
);
385 wk
.ik_keyix
= key_idx
;
386 wk
.ik_flags
|= IEEE80211_KEY_DEFAULT
;
388 memcpy(wk
.ik_macaddr
, addr
, IEEE80211_ADDR_LEN
);
389 wk
.ik_keyix
= IEEE80211_KEYIX_NONE
;
391 wk
.ik_keylen
= key_len
;
392 memcpy(wk
.ik_keydata
, key
, key_len
);
394 return set80211var(drv
, IEEE80211_IOC_WPAKEY
, &wk
, sizeof(wk
));
399 bsd_get_seqnum(const char *ifname
, void *priv
, const u8
*addr
, int idx
,
402 struct bsd_driver_data
*drv
= priv
;
403 struct ieee80211req_key wk
;
405 wpa_printf(MSG_DEBUG
, "%s: addr=%s idx=%d",
406 __func__
, ether_sprintf(addr
), idx
);
408 memset(&wk
, 0, sizeof(wk
));
410 memset(wk
.ik_macaddr
, 0xff, IEEE80211_ADDR_LEN
);
412 memcpy(wk
.ik_macaddr
, addr
, IEEE80211_ADDR_LEN
);
415 if (get80211var(drv
, IEEE80211_IOC_WPAKEY
, &wk
, sizeof(wk
)) < 0) {
416 printf("Failed to get encryption.\n");
420 #ifdef WORDS_BIGENDIAN
423 * wk.ik_keytsc is in host byte order (big endian), need to
424 * swap it to match with the byte order used in WPA.
427 u8 tmp
[WPA_KEY_RSC_LEN
];
428 memcpy(tmp
, &wk
.ik_keytsc
, sizeof(wk
.ik_keytsc
));
429 for (i
= 0; i
< WPA_KEY_RSC_LEN
; i
++) {
430 seq
[i
] = tmp
[WPA_KEY_RSC_LEN
- i
- 1];
433 #else /* WORDS_BIGENDIAN */
434 memcpy(seq
, &wk
.ik_keytsc
, sizeof(wk
.ik_keytsc
));
435 #endif /* WORDS_BIGENDIAN */
441 bsd_flush(void *priv
)
443 u8 allsta
[IEEE80211_ADDR_LEN
];
445 memset(allsta
, 0xff, IEEE80211_ADDR_LEN
);
446 return bsd_sta_deauth(priv
, allsta
, IEEE80211_REASON_AUTH_LEAVE
);
451 bsd_read_sta_driver_data(void *priv
, struct hostap_sta_driver_data
*data
,
454 struct bsd_driver_data
*drv
= priv
;
455 struct ieee80211req_sta_stats stats
;
457 memcpy(stats
.is_u
.macaddr
, addr
, IEEE80211_ADDR_LEN
);
458 if (get80211var(drv
, IEEE80211_IOC_STA_STATS
, &stats
, sizeof(stats
)) > 0) {
459 /* XXX? do packets counts include non-data frames? */
460 data
->rx_packets
= stats
.is_stats
.ns_rx_data
;
461 data
->rx_bytes
= stats
.is_stats
.ns_rx_bytes
;
462 data
->tx_packets
= stats
.is_stats
.ns_tx_data
;
463 data
->tx_bytes
= stats
.is_stats
.ns_tx_bytes
;
469 bsd_set_opt_ie(const char *ifname
, void *priv
, const u8
*ie
, size_t ie_len
)
472 * Do nothing; we setup parameters at startup that define the
473 * contents of the beacon information element.
479 bsd_sta_deauth(void *priv
, const u8
*addr
, int reason_code
)
481 struct bsd_driver_data
*drv
= priv
;
482 struct ieee80211req_mlme mlme
;
484 wpa_printf(MSG_DEBUG
, "%s: addr=%s reason_code=%d",
485 __func__
, ether_sprintf(addr
), reason_code
);
487 mlme
.im_op
= IEEE80211_MLME_DEAUTH
;
488 mlme
.im_reason
= reason_code
;
489 memcpy(mlme
.im_macaddr
, addr
, IEEE80211_ADDR_LEN
);
490 return set80211var(drv
, IEEE80211_IOC_MLME
, &mlme
, sizeof(mlme
));
494 bsd_sta_disassoc(void *priv
, const u8
*addr
, int reason_code
)
496 struct bsd_driver_data
*drv
= priv
;
497 struct ieee80211req_mlme mlme
;
499 wpa_printf(MSG_DEBUG
, "%s: addr=%s reason_code=%d",
500 __func__
, ether_sprintf(addr
), reason_code
);
502 mlme
.im_op
= IEEE80211_MLME_DISASSOC
;
503 mlme
.im_reason
= reason_code
;
504 memcpy(mlme
.im_macaddr
, addr
, IEEE80211_ADDR_LEN
);
505 return set80211var(drv
, IEEE80211_IOC_MLME
, &mlme
, sizeof(mlme
));
509 bsd_del_sta(struct bsd_driver_data
*drv
, u8 addr
[IEEE80211_ADDR_LEN
])
511 struct hostapd_data
*hapd
= drv
->hapd
;
512 struct hostapd_bss_config
*conf
= hapd
->conf
;
513 struct sta_info
*sta
;
515 hostapd_logger(hapd
, addr
, HOSTAPD_MODULE_IEEE80211
,
516 HOSTAPD_LEVEL_INFO
, "deassociated");
518 sta
= ap_get_sta(hapd
, addr
);
520 sta
->flags
&= ~(WLAN_STA_AUTH
| WLAN_STA_ASSOC
);
522 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DISASSOC
);
523 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
524 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
525 ap_free_sta(hapd
, sta
);
531 bsd_new_sta(struct bsd_driver_data
*drv
, u8 addr
[IEEE80211_ADDR_LEN
])
533 struct hostapd_data
*hapd
= drv
->hapd
;
534 struct hostapd_bss_config
*conf
= hapd
->conf
;
535 struct sta_info
*sta
;
536 struct ieee80211req_wpaie ie
;
537 int new_assoc
, ielen
, res
;
539 hostapd_logger(hapd
, addr
, HOSTAPD_MODULE_IEEE80211
,
540 HOSTAPD_LEVEL_INFO
, "associated");
542 sta
= ap_sta_add(hapd
, addr
);
546 * Fetch and validate any negotiated WPA/RSN parameters.
549 memset(&ie
, 0, sizeof(ie
));
550 memcpy(ie
.wpa_macaddr
, addr
, IEEE80211_ADDR_LEN
);
551 if (get80211var(drv
, IEEE80211_IOC_WPAIE
, &ie
, sizeof(ie
)) < 0) {
552 printf("Failed to get WPA/RSN information element.\n");
553 return -1; /* XXX not right */
555 ielen
= ie
.wpa_ie
[1];
557 printf("No WPA/RSN information element for station!\n");
558 return -1; /* XXX not right */
561 if (sta
->wpa_sm
== NULL
)
562 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
564 if (sta
->wpa_sm
== NULL
) {
565 printf("Failed to initialize WPA state machine\n");
568 res
= wpa_validate_wpa_ie(hapd
->wpa_auth
, sta
->wpa_sm
,
569 ie
.wpa_ie
, ielen
, NULL
, 0);
570 if (res
!= WPA_IE_OK
) {
571 printf("WPA/RSN information element rejected? "
578 * Now that the internal station state is setup
579 * kick the authenticator into action.
581 new_assoc
= (sta
->flags
& WLAN_STA_ASSOC
) == 0;
582 sta
->flags
|= WLAN_STA_AUTH
| WLAN_STA_ASSOC
;
583 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC
);
584 hostapd_new_assoc_sta(hapd
, sta
, !new_assoc
);
585 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 1);
589 #include <net/route.h>
590 #include <net80211/ieee80211_freebsd.h>
593 bsd_wireless_event_receive(int sock
, void *ctx
, void *sock_ctx
)
595 struct bsd_driver_data
*drv
= ctx
;
596 struct hostapd_data
*hapd
= drv
->hapd
;
598 struct if_announcemsghdr
*ifan
;
599 struct rt_msghdr
*rtm
;
600 struct ieee80211_michael_event
*mic
;
601 struct ieee80211_join_event
*join
;
602 struct ieee80211_leave_event
*leave
;
605 n
= read(sock
, buf
, sizeof(buf
));
607 if (errno
!= EINTR
&& errno
!= EAGAIN
)
608 perror("read(PF_ROUTE)");
612 rtm
= (struct rt_msghdr
*) buf
;
613 if (rtm
->rtm_version
!= RTM_VERSION
) {
614 wpa_printf(MSG_DEBUG
, "Routing message version %d not "
615 "understood\n", rtm
->rtm_version
);
618 ifan
= (struct if_announcemsghdr
*) rtm
;
619 switch (rtm
->rtm_type
) {
621 switch (ifan
->ifan_what
) {
622 case RTM_IEEE80211_ASSOC
:
623 case RTM_IEEE80211_REASSOC
:
624 case RTM_IEEE80211_DISASSOC
:
625 case RTM_IEEE80211_SCAN
:
627 case RTM_IEEE80211_LEAVE
:
628 leave
= (struct ieee80211_leave_event
*) &ifan
[1];
629 bsd_del_sta(drv
, leave
->iev_addr
);
631 case RTM_IEEE80211_JOIN
:
632 #ifdef RTM_IEEE80211_REJOIN
633 case RTM_IEEE80211_REJOIN
:
635 join
= (struct ieee80211_join_event
*) &ifan
[1];
636 bsd_new_sta(drv
, join
->iev_addr
);
638 case RTM_IEEE80211_REPLAY
:
641 case RTM_IEEE80211_MICHAEL
:
642 mic
= (struct ieee80211_michael_event
*) &ifan
[1];
643 wpa_printf(MSG_DEBUG
,
644 "Michael MIC failure wireless event: "
645 "keyix=%u src_addr=" MACSTR
, mic
->iev_keyix
,
646 MAC2STR(mic
->iev_src
));
647 ieee80211_michael_mic_failure(hapd
, mic
->iev_src
, 1);
655 bsd_wireless_event_init(void *priv
)
657 struct bsd_driver_data
*drv
= priv
;
662 s
= socket(PF_ROUTE
, SOCK_RAW
, 0);
664 perror("socket(PF_ROUTE,SOCK_RAW)");
667 eloop_register_read_sock(s
, bsd_wireless_event_receive
, drv
, NULL
);
674 bsd_wireless_event_deinit(void *priv
)
676 struct bsd_driver_data
*drv
= priv
;
679 if (drv
->wext_sock
< 0)
681 eloop_unregister_read_sock(drv
->wext_sock
);
682 close(drv
->wext_sock
);
688 bsd_send_eapol(void *priv
, const u8
*addr
, const u8
*data
, size_t data_len
,
689 int encrypt
, const u8
*own_addr
)
691 struct bsd_driver_data
*drv
= priv
;
692 unsigned char buf
[3000];
693 unsigned char *bp
= buf
;
694 struct l2_ethhdr
*eth
;
699 * Prepend the Etherent header. If the caller left us
700 * space at the front we could just insert it but since
701 * we don't know we copy to a local buffer. Given the frequency
702 * and size of frames this probably doesn't matter.
704 len
= data_len
+ sizeof(struct l2_ethhdr
);
705 if (len
> sizeof(buf
)) {
708 printf("EAPOL frame discarded, cannot malloc temp "
709 "buffer of size %u!\n", len
);
713 eth
= (struct l2_ethhdr
*) bp
;
714 memcpy(eth
->h_dest
, addr
, ETH_ALEN
);
715 memcpy(eth
->h_source
, own_addr
, ETH_ALEN
);
716 eth
->h_proto
= htons(ETH_P_EAPOL
);
717 memcpy(eth
+1, data
, data_len
);
719 wpa_hexdump(MSG_MSGDUMP
, "TX EAPOL", bp
, len
);
721 status
= l2_packet_send(drv
->sock_xmit
, addr
, ETH_P_EAPOL
, bp
, len
);
729 handle_read(void *ctx
, const u8
*src_addr
, const u8
*buf
, size_t len
)
731 struct bsd_driver_data
*drv
= ctx
;
732 struct hostapd_data
*hapd
= drv
->hapd
;
733 struct sta_info
*sta
;
735 sta
= ap_get_sta(hapd
, src_addr
);
736 if (!sta
|| !(sta
->flags
& WLAN_STA_ASSOC
)) {
737 printf("Data frame from not associated STA %s\n",
738 ether_sprintf(src_addr
));
739 /* XXX cannot happen */
742 ieee802_1x_receive(hapd
, src_addr
, buf
+ sizeof(struct l2_ethhdr
),
743 len
- sizeof(struct l2_ethhdr
));
747 bsd_get_ssid(const char *ifname
, void *priv
, u8
*buf
, int len
)
749 struct bsd_driver_data
*drv
= priv
;
750 int ssid_len
= get80211var(drv
, IEEE80211_IOC_SSID
, buf
, len
);
752 wpa_printf(MSG_DEBUG
, "%s: ssid=\"%.*s\"", __func__
, ssid_len
, buf
);
758 bsd_set_ssid(const char *ifname
, void *priv
, const u8
*buf
, int len
)
760 struct bsd_driver_data
*drv
= priv
;
762 wpa_printf(MSG_DEBUG
, "%s: ssid=\"%.*s\"", __func__
, len
, buf
);
764 return set80211var(drv
, IEEE80211_IOC_SSID
, buf
, len
);
768 bsd_init(struct hostapd_data
*hapd
)
770 struct bsd_driver_data
*drv
;
772 drv
= os_zalloc(sizeof(struct bsd_driver_data
));
774 printf("Could not allocate memory for bsd driver data\n");
779 drv
->ioctl_sock
= socket(PF_INET
, SOCK_DGRAM
, 0);
780 if (drv
->ioctl_sock
< 0) {
781 perror("socket[PF_INET,SOCK_DGRAM]");
784 memcpy(drv
->iface
, hapd
->conf
->iface
, sizeof(drv
->iface
));
786 drv
->sock_xmit
= l2_packet_init(drv
->iface
, NULL
, ETH_P_EAPOL
,
787 handle_read
, drv
, 1);
788 if (drv
->sock_xmit
== NULL
)
790 if (l2_packet_get_own_addr(drv
->sock_xmit
, hapd
->own_addr
))
793 bsd_set_iface_flags(drv
, 0); /* mark down during setup */
797 if (drv
->sock_xmit
!= NULL
)
798 l2_packet_deinit(drv
->sock_xmit
);
799 if (drv
->ioctl_sock
>= 0)
800 close(drv
->ioctl_sock
);
808 bsd_deinit(void *priv
)
810 struct bsd_driver_data
*drv
= priv
;
812 (void) bsd_set_iface_flags(drv
, 0);
813 if (drv
->ioctl_sock
>= 0)
814 close(drv
->ioctl_sock
);
815 if (drv
->sock_xmit
!= NULL
)
816 l2_packet_deinit(drv
->sock_xmit
);
820 const struct wpa_driver_ops wpa_driver_bsd_ops
= {
823 .deinit
= bsd_deinit
,
824 .set_ieee8021x
= bsd_set_ieee8021x
,
825 .set_privacy
= bsd_set_privacy
,
826 .set_encryption
= bsd_set_key
,
827 .get_seqnum
= bsd_get_seqnum
,
829 .set_generic_elem
= bsd_set_opt_ie
,
830 .wireless_event_init
= bsd_wireless_event_init
,
831 .wireless_event_deinit
= bsd_wireless_event_deinit
,
832 .sta_set_flags
= bsd_sta_set_flags
,
833 .read_sta_data
= bsd_read_sta_driver_data
,
834 .send_eapol
= bsd_send_eapol
,
835 .sta_disassoc
= bsd_sta_disassoc
,
836 .sta_deauth
= bsd_sta_deauth
,
837 .set_ssid
= bsd_set_ssid
,
838 .get_ssid
= bsd_get_ssid
,