2 * WPA Supplicant - 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>
22 #include "ieee802_11_defs.h"
27 #include <net/if_ether.h>
28 #define COMPAT_FREEBSD_NET80211
30 #include <net/ethernet.h>
32 #include <net/route.h>
34 #include <net80211/ieee80211.h>
35 #include <net80211/ieee80211_crypto.h>
36 #include <net80211/ieee80211_ioctl.h>
38 #include <net80211/ieee80211_freebsd.h>
41 #include <net80211/ieee80211_netbsd.h>
47 * Avoid conflicts with hostapd definitions by undefining couple of defines
48 * from net80211 header files.
54 #include "l2_packet/l2_packet.h"
55 #include "../../hostapd/hostapd.h"
56 #include "../../hostapd/config.h"
57 #include "../../hostapd/eapol_sm.h"
58 #include "../../hostapd/sta_flags.h"
60 struct bsd_driver_data
{
61 struct hostapd_data
*hapd
; /* back pointer */
63 char iface
[IFNAMSIZ
+ 1];
64 struct l2_packet_data
*sock_xmit
; /* raw packet xmit socket */
65 int ioctl_sock
; /* socket for ioctl() use */
66 int wext_sock
; /* socket for wireless events */
69 static int bsd_sta_deauth(void *priv
, const u8
*own_addr
, const u8
*addr
,
73 set80211var(struct bsd_driver_data
*drv
, int op
, const void *arg
, int arg_len
)
75 struct ieee80211req ireq
;
77 memset(&ireq
, 0, sizeof(ireq
));
78 os_strlcpy(ireq
.i_name
, drv
->iface
, IFNAMSIZ
);
81 ireq
.i_data
= (void *) arg
;
83 if (ioctl(drv
->ioctl_sock
, SIOCS80211
, &ireq
) < 0) {
84 perror("ioctl[SIOCS80211]");
91 get80211var(struct bsd_driver_data
*drv
, int op
, void *arg
, int arg_len
)
93 struct ieee80211req ireq
;
95 memset(&ireq
, 0, sizeof(ireq
));
96 os_strlcpy(ireq
.i_name
, drv
->iface
, IFNAMSIZ
);
101 if (ioctl(drv
->ioctl_sock
, SIOCG80211
, &ireq
) < 0) {
102 perror("ioctl[SIOCG80211]");
109 set80211param(struct bsd_driver_data
*drv
, int op
, int arg
)
111 struct ieee80211req ireq
;
113 memset(&ireq
, 0, sizeof(ireq
));
114 os_strlcpy(ireq
.i_name
, drv
->iface
, IFNAMSIZ
);
118 if (ioctl(drv
->ioctl_sock
, SIOCS80211
, &ireq
) < 0) {
119 perror("ioctl[SIOCS80211]");
126 ether_sprintf(const u8
*addr
)
128 static char buf
[sizeof(MACSTR
)];
131 snprintf(buf
, sizeof(buf
), MACSTR
, MAC2STR(addr
));
133 snprintf(buf
, sizeof(buf
), MACSTR
, 0,0,0,0,0,0);
138 * Configure WPA parameters.
141 bsd_configure_wpa(struct bsd_driver_data
*drv
)
143 static const char *ciphernames
[] =
144 { "WEP", "TKIP", "AES-OCB", "AES-CCM", "CKIP", "NONE" };
145 struct hostapd_data
*hapd
= drv
->hapd
;
146 struct hostapd_bss_config
*conf
= hapd
->conf
;
149 switch (conf
->wpa_group
) {
150 case WPA_CIPHER_CCMP
:
151 v
= IEEE80211_CIPHER_AES_CCM
;
153 case WPA_CIPHER_TKIP
:
154 v
= IEEE80211_CIPHER_TKIP
;
156 case WPA_CIPHER_WEP104
:
157 v
= IEEE80211_CIPHER_WEP
;
159 case WPA_CIPHER_WEP40
:
160 v
= IEEE80211_CIPHER_WEP
;
162 case WPA_CIPHER_NONE
:
163 v
= IEEE80211_CIPHER_NONE
;
166 printf("Unknown group key cipher %u\n",
170 wpa_printf(MSG_DEBUG
, "%s: group key cipher=%s (%u)",
171 __func__
, ciphernames
[v
], v
);
172 if (set80211param(drv
, IEEE80211_IOC_MCASTCIPHER
, v
)) {
173 printf("Unable to set group key cipher to %u (%s)\n",
177 if (v
== IEEE80211_CIPHER_WEP
) {
178 /* key length is done only for specific ciphers */
179 v
= (conf
->wpa_group
== WPA_CIPHER_WEP104
? 13 : 5);
180 if (set80211param(drv
, IEEE80211_IOC_MCASTKEYLEN
, v
)) {
181 printf("Unable to set group key length to %u\n", v
);
187 if (conf
->wpa_pairwise
& WPA_CIPHER_CCMP
)
188 v
|= 1<<IEEE80211_CIPHER_AES_CCM
;
189 if (conf
->wpa_pairwise
& WPA_CIPHER_TKIP
)
190 v
|= 1<<IEEE80211_CIPHER_TKIP
;
191 if (conf
->wpa_pairwise
& WPA_CIPHER_NONE
)
192 v
|= 1<<IEEE80211_CIPHER_NONE
;
193 wpa_printf(MSG_DEBUG
, "%s: pairwise key ciphers=0x%x", __func__
, v
);
194 if (set80211param(drv
, IEEE80211_IOC_UCASTCIPHERS
, v
)) {
195 printf("Unable to set pairwise key ciphers to 0x%x\n", v
);
199 wpa_printf(MSG_DEBUG
, "%s: key management algorithms=0x%x",
200 __func__
, conf
->wpa_key_mgmt
);
201 if (set80211param(drv
, IEEE80211_IOC_KEYMGTALGS
, conf
->wpa_key_mgmt
)) {
202 printf("Unable to set key management algorithms to 0x%x\n",
208 if (conf
->rsn_preauth
)
210 wpa_printf(MSG_DEBUG
, "%s: rsn capabilities=0x%x",
211 __func__
, conf
->rsn_preauth
);
212 if (set80211param(drv
, IEEE80211_IOC_RSNCAPS
, v
)) {
213 printf("Unable to set RSN capabilities to 0x%x\n", v
);
217 wpa_printf(MSG_DEBUG
, "%s: enable WPA= 0x%x", __func__
, conf
->wpa
);
218 if (set80211param(drv
, IEEE80211_IOC_WPA
, conf
->wpa
)) {
219 printf("Unable to set WPA to %u\n", conf
->wpa
);
227 bsd_set_iface_flags(void *priv
, int dev_up
)
229 struct bsd_driver_data
*drv
= priv
;
232 wpa_printf(MSG_DEBUG
, "%s: dev_up=%d", __func__
, dev_up
);
234 if (drv
->ioctl_sock
< 0)
237 memset(&ifr
, 0, sizeof(ifr
));
238 os_strlcpy(ifr
.ifr_name
, drv
->iface
, IFNAMSIZ
);
240 if (ioctl(drv
->ioctl_sock
, SIOCGIFFLAGS
, &ifr
) != 0) {
241 perror("ioctl[SIOCGIFFLAGS]");
246 ifr
.ifr_flags
|= IFF_UP
;
248 ifr
.ifr_flags
&= ~IFF_UP
;
250 if (ioctl(drv
->ioctl_sock
, SIOCSIFFLAGS
, &ifr
) != 0) {
251 perror("ioctl[SIOCSIFFLAGS]");
256 memset(&ifr
, 0, sizeof(ifr
));
257 os_strlcpy(ifr
.ifr_name
, drv
->iface
, IFNAMSIZ
);
258 ifr
.ifr_mtu
= HOSTAPD_MTU
;
259 if (ioctl(drv
->ioctl_sock
, SIOCSIFMTU
, &ifr
) != 0) {
260 perror("ioctl[SIOCSIFMTU]");
261 printf("Setting MTU failed - trying to survive with "
270 bsd_set_ieee8021x(const char *ifname
, void *priv
, int enabled
)
272 struct bsd_driver_data
*drv
= priv
;
273 struct hostapd_data
*hapd
= drv
->hapd
;
274 struct hostapd_bss_config
*conf
= hapd
->conf
;
276 wpa_printf(MSG_DEBUG
, "%s: enabled=%d", __func__
, enabled
);
279 /* XXX restore state */
280 return set80211param(priv
, IEEE80211_IOC_AUTHMODE
,
281 IEEE80211_AUTH_AUTO
);
283 if (!conf
->wpa
&& !conf
->ieee802_1x
) {
284 hostapd_logger(hapd
, NULL
, HOSTAPD_MODULE_DRIVER
,
285 HOSTAPD_LEVEL_WARNING
, "No 802.1X or WPA enabled!");
288 if (conf
->wpa
&& bsd_configure_wpa(drv
) != 0) {
289 hostapd_logger(hapd
, NULL
, HOSTAPD_MODULE_DRIVER
,
290 HOSTAPD_LEVEL_WARNING
, "Error configuring WPA state!");
293 if (set80211param(priv
, IEEE80211_IOC_AUTHMODE
,
294 (conf
->wpa
? IEEE80211_AUTH_WPA
: IEEE80211_AUTH_8021X
))) {
295 hostapd_logger(hapd
, NULL
, HOSTAPD_MODULE_DRIVER
,
296 HOSTAPD_LEVEL_WARNING
, "Error enabling WPA/802.1X!");
299 return bsd_set_iface_flags(priv
, 1);
303 bsd_set_privacy(const char *ifname
, void *priv
, int enabled
)
305 struct bsd_driver_data
*drv
= priv
;
307 wpa_printf(MSG_DEBUG
, "%s: enabled=%d", __func__
, enabled
);
309 return set80211param(drv
, IEEE80211_IOC_PRIVACY
, enabled
);
313 bsd_set_sta_authorized(void *priv
, const u8
*addr
, int authorized
)
315 struct bsd_driver_data
*drv
= priv
;
316 struct ieee80211req_mlme mlme
;
318 wpa_printf(MSG_DEBUG
, "%s: addr=%s authorized=%d",
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(drv
, IEEE80211_IOC_MLME
, &mlme
, sizeof(mlme
));
331 bsd_sta_set_flags(void *priv
, const u8
*addr
, int total_flags
, int flags_or
,
334 /* For now, only support setting Authorized flag */
335 if (flags_or
& WLAN_STA_AUTHORIZED
)
336 return bsd_set_sta_authorized(priv
, addr
, 1);
337 if (!(flags_and
& WLAN_STA_AUTHORIZED
))
338 return bsd_set_sta_authorized(priv
, addr
, 0);
343 bsd_del_key(void *priv
, const u8
*addr
, int key_idx
)
345 struct bsd_driver_data
*drv
= priv
;
346 struct ieee80211req_del_key wk
;
348 wpa_printf(MSG_DEBUG
, "%s: addr=%s key_idx=%d",
349 __func__
, ether_sprintf(addr
), key_idx
);
351 memset(&wk
, 0, sizeof(wk
));
353 memcpy(wk
.idk_macaddr
, addr
, IEEE80211_ADDR_LEN
);
354 wk
.idk_keyix
= (u_int8_t
) IEEE80211_KEYIX_NONE
; /* XXX */
356 wk
.idk_keyix
= key_idx
;
359 return set80211var(drv
, IEEE80211_IOC_DELKEY
, &wk
, sizeof(wk
));
363 bsd_set_key(const char *ifname
, void *priv
, wpa_alg alg
,
364 const u8
*addr
, int key_idx
, int set_tx
, const u8
*seq
,
365 size_t seq_len
, const u8
*key
, size_t key_len
)
367 struct bsd_driver_data
*drv
= priv
;
368 struct ieee80211req_key wk
;
371 if (alg
== WPA_ALG_NONE
)
372 return bsd_del_key(drv
, addr
, key_idx
);
374 wpa_printf(MSG_DEBUG
, "%s: alg=%d addr=%s key_idx=%d",
375 __func__
, alg
, ether_sprintf(addr
), key_idx
);
377 if (alg
== WPA_ALG_WEP
)
378 cipher
= IEEE80211_CIPHER_WEP
;
379 else if (alg
== WPA_ALG_TKIP
)
380 cipher
= IEEE80211_CIPHER_TKIP
;
381 else if (alg
== WPA_ALG_CCMP
)
382 cipher
= IEEE80211_CIPHER_AES_CCM
;
384 printf("%s: unknown/unsupported algorithm %d\n",
389 if (key_len
> sizeof(wk
.ik_keydata
)) {
390 printf("%s: key length %d too big\n", __func__
, (int) key_len
);
394 memset(&wk
, 0, sizeof(wk
));
396 wk
.ik_flags
= IEEE80211_KEY_RECV
| IEEE80211_KEY_XMIT
;
398 memset(wk
.ik_macaddr
, 0xff, IEEE80211_ADDR_LEN
);
399 wk
.ik_keyix
= key_idx
;
400 wk
.ik_flags
|= IEEE80211_KEY_DEFAULT
;
402 memcpy(wk
.ik_macaddr
, addr
, IEEE80211_ADDR_LEN
);
403 wk
.ik_keyix
= IEEE80211_KEYIX_NONE
;
405 wk
.ik_keylen
= key_len
;
406 memcpy(wk
.ik_keydata
, key
, key_len
);
408 return set80211var(drv
, IEEE80211_IOC_WPAKEY
, &wk
, sizeof(wk
));
413 bsd_get_seqnum(const char *ifname
, void *priv
, const u8
*addr
, int idx
,
416 struct bsd_driver_data
*drv
= priv
;
417 struct ieee80211req_key wk
;
419 wpa_printf(MSG_DEBUG
, "%s: addr=%s idx=%d",
420 __func__
, ether_sprintf(addr
), idx
);
422 memset(&wk
, 0, sizeof(wk
));
424 memset(wk
.ik_macaddr
, 0xff, IEEE80211_ADDR_LEN
);
426 memcpy(wk
.ik_macaddr
, addr
, IEEE80211_ADDR_LEN
);
429 if (get80211var(drv
, IEEE80211_IOC_WPAKEY
, &wk
, sizeof(wk
)) < 0) {
430 printf("Failed to get encryption.\n");
434 #ifdef WORDS_BIGENDIAN
437 * wk.ik_keytsc is in host byte order (big endian), need to
438 * swap it to match with the byte order used in WPA.
441 u8 tmp
[WPA_KEY_RSC_LEN
];
442 memcpy(tmp
, &wk
.ik_keytsc
, sizeof(wk
.ik_keytsc
));
443 for (i
= 0; i
< WPA_KEY_RSC_LEN
; i
++) {
444 seq
[i
] = tmp
[WPA_KEY_RSC_LEN
- i
- 1];
447 #else /* WORDS_BIGENDIAN */
448 memcpy(seq
, &wk
.ik_keytsc
, sizeof(wk
.ik_keytsc
));
449 #endif /* WORDS_BIGENDIAN */
455 bsd_flush(void *priv
)
457 u8 allsta
[IEEE80211_ADDR_LEN
];
459 memset(allsta
, 0xff, IEEE80211_ADDR_LEN
);
460 return bsd_sta_deauth(priv
, NULL
, allsta
, IEEE80211_REASON_AUTH_LEAVE
);
465 bsd_read_sta_driver_data(void *priv
, struct hostap_sta_driver_data
*data
,
468 struct bsd_driver_data
*drv
= priv
;
469 struct ieee80211req_sta_stats stats
;
471 memcpy(stats
.is_u
.macaddr
, addr
, IEEE80211_ADDR_LEN
);
472 if (get80211var(drv
, IEEE80211_IOC_STA_STATS
, &stats
, sizeof(stats
)) > 0) {
473 /* XXX? do packets counts include non-data frames? */
474 data
->rx_packets
= stats
.is_stats
.ns_rx_data
;
475 data
->rx_bytes
= stats
.is_stats
.ns_rx_bytes
;
476 data
->tx_packets
= stats
.is_stats
.ns_tx_data
;
477 data
->tx_bytes
= stats
.is_stats
.ns_tx_bytes
;
483 bsd_set_opt_ie(const char *ifname
, void *priv
, const u8
*ie
, size_t ie_len
)
486 * Do nothing; we setup parameters at startup that define the
487 * contents of the beacon information element.
493 bsd_sta_deauth(void *priv
, const u8
*own_addr
, const u8
*addr
, int reason_code
)
495 struct bsd_driver_data
*drv
= priv
;
496 struct ieee80211req_mlme mlme
;
498 wpa_printf(MSG_DEBUG
, "%s: addr=%s reason_code=%d",
499 __func__
, ether_sprintf(addr
), reason_code
);
501 mlme
.im_op
= IEEE80211_MLME_DEAUTH
;
502 mlme
.im_reason
= reason_code
;
503 memcpy(mlme
.im_macaddr
, addr
, IEEE80211_ADDR_LEN
);
504 return set80211var(drv
, IEEE80211_IOC_MLME
, &mlme
, sizeof(mlme
));
508 bsd_sta_disassoc(void *priv
, const u8
*own_addr
, const u8
*addr
,
511 struct bsd_driver_data
*drv
= priv
;
512 struct ieee80211req_mlme mlme
;
514 wpa_printf(MSG_DEBUG
, "%s: addr=%s reason_code=%d",
515 __func__
, ether_sprintf(addr
), reason_code
);
517 mlme
.im_op
= IEEE80211_MLME_DISASSOC
;
518 mlme
.im_reason
= reason_code
;
519 memcpy(mlme
.im_macaddr
, addr
, IEEE80211_ADDR_LEN
);
520 return set80211var(drv
, IEEE80211_IOC_MLME
, &mlme
, sizeof(mlme
));
524 bsd_new_sta(struct bsd_driver_data
*drv
, u8 addr
[IEEE80211_ADDR_LEN
])
526 struct hostapd_data
*hapd
= drv
->hapd
;
527 struct ieee80211req_wpaie ie
;
532 * Fetch and validate any negotiated WPA/RSN parameters.
534 memset(&ie
, 0, sizeof(ie
));
535 memcpy(ie
.wpa_macaddr
, addr
, IEEE80211_ADDR_LEN
);
536 if (get80211var(drv
, IEEE80211_IOC_WPAIE
, &ie
, sizeof(ie
)) < 0) {
537 printf("Failed to get WPA/RSN information element.\n");
541 ielen
= ie
.wpa_ie
[1];
548 return hostapd_notif_assoc(hapd
, addr
, iebuf
, ielen
);
552 bsd_wireless_event_receive(int sock
, void *ctx
, void *sock_ctx
)
554 struct bsd_driver_data
*drv
= ctx
;
555 struct hostapd_data
*hapd
= drv
->hapd
;
557 struct if_announcemsghdr
*ifan
;
558 struct rt_msghdr
*rtm
;
559 struct ieee80211_michael_event
*mic
;
560 struct ieee80211_join_event
*join
;
561 struct ieee80211_leave_event
*leave
;
564 n
= read(sock
, buf
, sizeof(buf
));
566 if (errno
!= EINTR
&& errno
!= EAGAIN
)
567 perror("read(PF_ROUTE)");
571 rtm
= (struct rt_msghdr
*) buf
;
572 if (rtm
->rtm_version
!= RTM_VERSION
) {
573 wpa_printf(MSG_DEBUG
, "Routing message version %d not "
574 "understood\n", rtm
->rtm_version
);
577 ifan
= (struct if_announcemsghdr
*) rtm
;
578 switch (rtm
->rtm_type
) {
580 switch (ifan
->ifan_what
) {
581 case RTM_IEEE80211_ASSOC
:
582 case RTM_IEEE80211_REASSOC
:
583 case RTM_IEEE80211_DISASSOC
:
584 case RTM_IEEE80211_SCAN
:
586 case RTM_IEEE80211_LEAVE
:
587 leave
= (struct ieee80211_leave_event
*) &ifan
[1];
588 hostapd_notif_disassoc(drv
->hapd
, leave
->iev_addr
);
590 case RTM_IEEE80211_JOIN
:
591 #ifdef RTM_IEEE80211_REJOIN
592 case RTM_IEEE80211_REJOIN
:
594 join
= (struct ieee80211_join_event
*) &ifan
[1];
595 bsd_new_sta(drv
, join
->iev_addr
);
597 case RTM_IEEE80211_REPLAY
:
600 case RTM_IEEE80211_MICHAEL
:
601 mic
= (struct ieee80211_michael_event
*) &ifan
[1];
602 wpa_printf(MSG_DEBUG
,
603 "Michael MIC failure wireless event: "
604 "keyix=%u src_addr=" MACSTR
, mic
->iev_keyix
,
605 MAC2STR(mic
->iev_src
));
606 hostapd_michael_mic_failure(hapd
, mic
->iev_src
);
614 bsd_wireless_event_init(struct bsd_driver_data
*drv
)
620 s
= socket(PF_ROUTE
, SOCK_RAW
, 0);
622 perror("socket(PF_ROUTE,SOCK_RAW)");
625 eloop_register_read_sock(s
, bsd_wireless_event_receive
, drv
, NULL
);
632 bsd_wireless_event_deinit(struct bsd_driver_data
*drv
)
634 if (drv
->wext_sock
< 0)
636 eloop_unregister_read_sock(drv
->wext_sock
);
637 close(drv
->wext_sock
);
642 bsd_send_eapol(void *priv
, const u8
*addr
, const u8
*data
, size_t data_len
,
643 int encrypt
, const u8
*own_addr
)
645 struct bsd_driver_data
*drv
= priv
;
646 unsigned char buf
[3000];
647 unsigned char *bp
= buf
;
648 struct l2_ethhdr
*eth
;
653 * Prepend the Etherent header. If the caller left us
654 * space at the front we could just insert it but since
655 * we don't know we copy to a local buffer. Given the frequency
656 * and size of frames this probably doesn't matter.
658 len
= data_len
+ sizeof(struct l2_ethhdr
);
659 if (len
> sizeof(buf
)) {
662 printf("EAPOL frame discarded, cannot malloc temp "
663 "buffer of size %u!\n", (unsigned int) len
);
667 eth
= (struct l2_ethhdr
*) bp
;
668 memcpy(eth
->h_dest
, addr
, ETH_ALEN
);
669 memcpy(eth
->h_source
, own_addr
, ETH_ALEN
);
670 eth
->h_proto
= htons(ETH_P_EAPOL
);
671 memcpy(eth
+1, data
, data_len
);
673 wpa_hexdump(MSG_MSGDUMP
, "TX EAPOL", bp
, len
);
675 status
= l2_packet_send(drv
->sock_xmit
, addr
, ETH_P_EAPOL
, bp
, len
);
683 handle_read(void *ctx
, const u8
*src_addr
, const u8
*buf
, size_t len
)
685 struct bsd_driver_data
*drv
= ctx
;
686 hostapd_eapol_receive(drv
->hapd
, src_addr
,
687 buf
+ sizeof(struct l2_ethhdr
),
688 len
- sizeof(struct l2_ethhdr
));
692 bsd_get_ssid(const char *ifname
, void *priv
, u8
*buf
, int len
)
694 struct bsd_driver_data
*drv
= priv
;
695 int ssid_len
= get80211var(drv
, IEEE80211_IOC_SSID
, buf
, len
);
697 wpa_printf(MSG_DEBUG
, "%s: ssid=\"%.*s\"", __func__
, ssid_len
, buf
);
703 bsd_set_ssid(const char *ifname
, void *priv
, const u8
*buf
, int len
)
705 struct bsd_driver_data
*drv
= priv
;
707 wpa_printf(MSG_DEBUG
, "%s: ssid=\"%.*s\"", __func__
, len
, buf
);
709 return set80211var(drv
, IEEE80211_IOC_SSID
, buf
, len
);
713 bsd_init(struct hostapd_data
*hapd
, struct wpa_init_params
*params
)
715 struct bsd_driver_data
*drv
;
717 drv
= os_zalloc(sizeof(struct bsd_driver_data
));
719 printf("Could not allocate memory for bsd driver data\n");
724 drv
->ioctl_sock
= socket(PF_INET
, SOCK_DGRAM
, 0);
725 if (drv
->ioctl_sock
< 0) {
726 perror("socket[PF_INET,SOCK_DGRAM]");
729 memcpy(drv
->iface
, params
->ifname
, sizeof(drv
->iface
));
731 drv
->sock_xmit
= l2_packet_init(drv
->iface
, NULL
, ETH_P_EAPOL
,
732 handle_read
, drv
, 1);
733 if (drv
->sock_xmit
== NULL
)
735 if (l2_packet_get_own_addr(drv
->sock_xmit
, params
->own_addr
))
738 bsd_set_iface_flags(drv
, 0); /* mark down during setup */
739 if (bsd_wireless_event_init(drv
))
744 if (drv
->sock_xmit
!= NULL
)
745 l2_packet_deinit(drv
->sock_xmit
);
746 if (drv
->ioctl_sock
>= 0)
747 close(drv
->ioctl_sock
);
755 bsd_deinit(void *priv
)
757 struct bsd_driver_data
*drv
= priv
;
759 bsd_wireless_event_deinit(drv
);
760 (void) bsd_set_iface_flags(drv
, 0);
761 if (drv
->ioctl_sock
>= 0)
762 close(drv
->ioctl_sock
);
763 if (drv
->sock_xmit
!= NULL
)
764 l2_packet_deinit(drv
->sock_xmit
);
768 const struct wpa_driver_ops wpa_driver_bsd_ops
= {
770 .hapd_init
= bsd_init
,
771 .hapd_deinit
= bsd_deinit
,
772 .set_ieee8021x
= bsd_set_ieee8021x
,
773 .set_privacy
= bsd_set_privacy
,
774 .hapd_set_key
= bsd_set_key
,
775 .get_seqnum
= bsd_get_seqnum
,
777 .set_generic_elem
= bsd_set_opt_ie
,
778 .sta_set_flags
= bsd_sta_set_flags
,
779 .read_sta_data
= bsd_read_sta_driver_data
,
780 .hapd_send_eapol
= bsd_send_eapol
,
781 .sta_disassoc
= bsd_sta_disassoc
,
782 .sta_deauth
= bsd_sta_deauth
,
783 .hapd_set_ssid
= bsd_set_ssid
,
784 .hapd_get_ssid
= bsd_get_ssid
,
789 struct wpa_driver_bsd_data
{
790 int sock
; /* open socket for 802.11 ioctls */
791 int route
; /* routing socket for events */
792 char ifname
[IFNAMSIZ
+1]; /* interface name */
793 unsigned int ifindex
; /* interface index */
795 int prev_roaming
; /* roaming state to restore on deinit */
796 int prev_privacy
; /* privacy state to restore on deinit */
797 int prev_wpa
; /* wpa state to restore on deinit */
801 set80211var(struct wpa_driver_bsd_data
*drv
, int op
, const void *arg
, int arg_len
)
803 struct ieee80211req ireq
;
805 os_memset(&ireq
, 0, sizeof(ireq
));
806 os_strlcpy(ireq
.i_name
, drv
->ifname
, IFNAMSIZ
);
808 ireq
.i_len
= arg_len
;
809 ireq
.i_data
= (void *) arg
;
811 if (ioctl(drv
->sock
, SIOCS80211
, &ireq
) < 0) {
812 fprintf(stderr
, "ioctl[SIOCS80211, op %u, len %u]: %s\n",
813 op
, arg_len
, strerror(errno
));
820 get80211var(struct wpa_driver_bsd_data
*drv
, int op
, void *arg
, int arg_len
)
822 struct ieee80211req ireq
;
824 os_memset(&ireq
, 0, sizeof(ireq
));
825 os_strlcpy(ireq
.i_name
, drv
->ifname
, IFNAMSIZ
);
827 ireq
.i_len
= arg_len
;
830 if (ioctl(drv
->sock
, SIOCG80211
, &ireq
) < 0) {
831 fprintf(stderr
, "ioctl[SIOCG80211, op %u, len %u]: %s\n",
832 op
, arg_len
, strerror(errno
));
839 set80211param(struct wpa_driver_bsd_data
*drv
, int op
, int arg
)
841 struct ieee80211req ireq
;
843 os_memset(&ireq
, 0, sizeof(ireq
));
844 os_strlcpy(ireq
.i_name
, drv
->ifname
, IFNAMSIZ
);
848 if (ioctl(drv
->sock
, SIOCS80211
, &ireq
) < 0) {
849 fprintf(stderr
, "ioctl[SIOCS80211, op %u, arg 0x%x]: %s\n",
850 op
, arg
, strerror(errno
));
857 get80211param(struct wpa_driver_bsd_data
*drv
, int op
)
859 struct ieee80211req ireq
;
861 os_memset(&ireq
, 0, sizeof(ireq
));
862 os_strlcpy(ireq
.i_name
, drv
->ifname
, IFNAMSIZ
);
865 if (ioctl(drv
->sock
, SIOCG80211
, &ireq
) < 0) {
866 fprintf(stderr
, "ioctl[SIOCG80211, op %u]: %s\n",
867 op
, strerror(errno
));
874 getifflags(struct wpa_driver_bsd_data
*drv
, int *flags
)
878 os_memset(&ifr
, 0, sizeof(ifr
));
879 os_strlcpy(ifr
.ifr_name
, drv
->ifname
, sizeof(ifr
.ifr_name
));
880 if (ioctl(drv
->sock
, SIOCGIFFLAGS
, (caddr_t
)&ifr
) < 0) {
881 perror("SIOCGIFFLAGS");
884 *flags
= ifr
.ifr_flags
& 0xffff;
889 setifflags(struct wpa_driver_bsd_data
*drv
, int flags
)
893 os_memset(&ifr
, 0, sizeof(ifr
));
894 os_strlcpy(ifr
.ifr_name
, drv
->ifname
, sizeof(ifr
.ifr_name
));
895 ifr
.ifr_flags
= flags
& 0xffff;
896 if (ioctl(drv
->sock
, SIOCSIFFLAGS
, (caddr_t
)&ifr
) < 0) {
897 perror("SIOCSIFFLAGS");
904 wpa_driver_bsd_get_bssid(void *priv
, u8
*bssid
)
906 struct wpa_driver_bsd_data
*drv
= priv
;
908 struct ieee80211_bssid bs
;
910 os_strncpy(bs
.i_name
, drv
->ifname
, sizeof(bs
.i_name
));
911 if (ioctl(drv
->sock
, SIOCG80211BSSID
, &bs
) < 0)
913 os_memcpy(bssid
, bs
.i_bssid
, sizeof(bs
.i_bssid
));
916 return get80211var(drv
, IEEE80211_IOC_BSSID
,
917 bssid
, IEEE80211_ADDR_LEN
) < 0 ? -1 : 0;
923 wpa_driver_bsd_set_bssid(void *priv
, const char *bssid
)
925 struct wpa_driver_bsd_data
*drv
= priv
;
927 return set80211var(drv
, IEEE80211_IOC_BSSID
,
928 bssid
, IEEE80211_ADDR_LEN
);
933 wpa_driver_bsd_get_ssid(void *priv
, u8
*ssid
)
935 struct wpa_driver_bsd_data
*drv
= priv
;
937 struct ieee80211_nwid nwid
;
940 os_memset(&ifr
, 0, sizeof(ifr
));
941 os_strncpy(ifr
.ifr_name
, drv
->ifname
, sizeof(ifr
.ifr_name
));
942 ifr
.ifr_data
= (void *)&nwid
;
943 if (ioctl(drv
->sock
, SIOCG80211NWID
, &ifr
) < 0 ||
944 nwid
.i_len
> IEEE80211_NWID_LEN
)
946 os_memcpy(ssid
, nwid
.i_nwid
, nwid
.i_len
);
949 return get80211var(drv
, IEEE80211_IOC_SSID
,
950 ssid
, IEEE80211_NWID_LEN
);
955 wpa_driver_bsd_set_ssid(void *priv
, const u8
*ssid
,
958 struct wpa_driver_bsd_data
*drv
= priv
;
960 struct ieee80211_nwid nwid
;
963 os_memcpy(nwid
.i_nwid
, ssid
, ssid_len
);
964 nwid
.i_len
= ssid_len
;
965 os_memset(&ifr
, 0, sizeof(ifr
));
966 os_strncpy(ifr
.ifr_name
, drv
->ifname
, sizeof(ifr
.ifr_name
));
967 ifr
.ifr_data
= (void *)&nwid
;
968 return ioctl(drv
->sock
, SIOCS80211NWID
, &ifr
);
970 return set80211var(drv
, IEEE80211_IOC_SSID
, ssid
, ssid_len
);
975 wpa_driver_bsd_set_wpa_ie(struct wpa_driver_bsd_data
*drv
,
976 const u8
*wpa_ie
, size_t wpa_ie_len
)
978 return set80211var(drv
, IEEE80211_IOC_OPTIE
, wpa_ie
, wpa_ie_len
);
982 wpa_driver_bsd_set_wpa_internal(void *priv
, int wpa
, int privacy
)
984 struct wpa_driver_bsd_data
*drv
= priv
;
987 wpa_printf(MSG_DEBUG
, "%s: wpa=%d privacy=%d",
988 __FUNCTION__
, wpa
, privacy
);
990 if (!wpa
&& wpa_driver_bsd_set_wpa_ie(drv
, NULL
, 0) < 0)
992 if (set80211param(drv
, IEEE80211_IOC_PRIVACY
, privacy
) < 0)
994 if (set80211param(drv
, IEEE80211_IOC_WPA
, wpa
) < 0)
1001 wpa_driver_bsd_set_wpa(void *priv
, int enabled
)
1003 wpa_printf(MSG_DEBUG
, "%s: enabled=%d", __FUNCTION__
, enabled
);
1005 return wpa_driver_bsd_set_wpa_internal(priv
, enabled
? 3 : 0, enabled
);
1009 wpa_driver_bsd_del_key(struct wpa_driver_bsd_data
*drv
, int key_idx
,
1010 const unsigned char *addr
)
1012 struct ieee80211req_del_key wk
;
1014 os_memset(&wk
, 0, sizeof(wk
));
1016 bcmp(addr
, "\xff\xff\xff\xff\xff\xff", IEEE80211_ADDR_LEN
) != 0) {
1017 struct ether_addr ea
;
1019 os_memcpy(&ea
, addr
, IEEE80211_ADDR_LEN
);
1020 wpa_printf(MSG_DEBUG
, "%s: addr=%s keyidx=%d",
1021 __func__
, ether_ntoa(&ea
), key_idx
);
1022 os_memcpy(wk
.idk_macaddr
, addr
, IEEE80211_ADDR_LEN
);
1023 wk
.idk_keyix
= (uint8_t) IEEE80211_KEYIX_NONE
;
1025 wpa_printf(MSG_DEBUG
, "%s: keyidx=%d", __func__
, key_idx
);
1026 wk
.idk_keyix
= key_idx
;
1028 return set80211var(drv
, IEEE80211_IOC_DELKEY
, &wk
, sizeof(wk
));
1032 wpa_driver_bsd_set_key(void *priv
, wpa_alg alg
,
1033 const unsigned char *addr
, int key_idx
, int set_tx
,
1034 const u8
*seq
, size_t seq_len
,
1035 const u8
*key
, size_t key_len
)
1037 struct wpa_driver_bsd_data
*drv
= priv
;
1038 struct ieee80211req_key wk
;
1039 struct ether_addr ea
;
1043 if (alg
== WPA_ALG_NONE
)
1044 return wpa_driver_bsd_del_key(drv
, key_idx
, addr
);
1049 cipher
= IEEE80211_CIPHER_WEP
;
1053 cipher
= IEEE80211_CIPHER_TKIP
;
1057 cipher
= IEEE80211_CIPHER_AES_CCM
;
1060 wpa_printf(MSG_DEBUG
, "%s: unknown/unsupported algorithm %d",
1065 os_memcpy(&ea
, addr
, IEEE80211_ADDR_LEN
);
1066 wpa_printf(MSG_DEBUG
,
1067 "%s: alg=%s addr=%s key_idx=%d set_tx=%d seq_len=%zu key_len=%zu",
1068 __func__
, alg_name
, ether_ntoa(&ea
), key_idx
, set_tx
,
1071 if (seq_len
> sizeof(u_int64_t
)) {
1072 wpa_printf(MSG_DEBUG
, "%s: seq_len %zu too big",
1076 if (key_len
> sizeof(wk
.ik_keydata
)) {
1077 wpa_printf(MSG_DEBUG
, "%s: key length %zu too big",
1082 os_memset(&wk
, 0, sizeof(wk
));
1083 wk
.ik_type
= cipher
;
1084 wk
.ik_flags
= IEEE80211_KEY_RECV
;
1086 wk
.ik_flags
|= IEEE80211_KEY_XMIT
;
1087 os_memcpy(wk
.ik_macaddr
, addr
, IEEE80211_ADDR_LEN
);
1089 * Deduce whether group/global or unicast key by checking
1090 * the address (yech). Note also that we can only mark global
1091 * keys default; doing this for a unicast key is an error.
1093 if (bcmp(addr
, "\xff\xff\xff\xff\xff\xff", IEEE80211_ADDR_LEN
) == 0) {
1094 wk
.ik_flags
|= IEEE80211_KEY_GROUP
;
1095 wk
.ik_keyix
= key_idx
;
1097 wk
.ik_keyix
= (key_idx
== 0 ? IEEE80211_KEYIX_NONE
: key_idx
);
1099 if (wk
.ik_keyix
!= IEEE80211_KEYIX_NONE
&& set_tx
)
1100 wk
.ik_flags
|= IEEE80211_KEY_DEFAULT
;
1101 wk
.ik_keylen
= key_len
;
1102 os_memcpy(&wk
.ik_keyrsc
, seq
, seq_len
);
1103 os_memcpy(wk
.ik_keydata
, key
, key_len
);
1105 return set80211var(drv
, IEEE80211_IOC_WPAKEY
, &wk
, sizeof(wk
));
1109 wpa_driver_bsd_set_countermeasures(void *priv
, int enabled
)
1111 struct wpa_driver_bsd_data
*drv
= priv
;
1113 wpa_printf(MSG_DEBUG
, "%s: enabled=%d", __func__
, enabled
);
1114 return set80211param(drv
, IEEE80211_IOC_COUNTERMEASURES
, enabled
);
1119 wpa_driver_bsd_set_drop_unencrypted(void *priv
, int enabled
)
1121 struct wpa_driver_bsd_data
*drv
= priv
;
1123 wpa_printf(MSG_DEBUG
, "%s: enabled=%d", __func__
, enabled
);
1124 return set80211param(drv
, IEEE80211_IOC_DROPUNENCRYPTED
, enabled
);
1128 wpa_driver_bsd_deauthenticate(void *priv
, const u8
*addr
, int reason_code
)
1130 struct wpa_driver_bsd_data
*drv
= priv
;
1131 struct ieee80211req_mlme mlme
;
1133 wpa_printf(MSG_DEBUG
, "%s", __func__
);
1134 os_memset(&mlme
, 0, sizeof(mlme
));
1135 mlme
.im_op
= IEEE80211_MLME_DEAUTH
;
1136 mlme
.im_reason
= reason_code
;
1137 os_memcpy(mlme
.im_macaddr
, addr
, IEEE80211_ADDR_LEN
);
1138 return set80211var(drv
, IEEE80211_IOC_MLME
, &mlme
, sizeof(mlme
));
1142 wpa_driver_bsd_disassociate(void *priv
, const u8
*addr
, int reason_code
)
1144 struct wpa_driver_bsd_data
*drv
= priv
;
1145 struct ieee80211req_mlme mlme
;
1147 wpa_printf(MSG_DEBUG
, "%s", __func__
);
1148 os_memset(&mlme
, 0, sizeof(mlme
));
1149 mlme
.im_op
= IEEE80211_MLME_DISASSOC
;
1150 mlme
.im_reason
= reason_code
;
1151 os_memcpy(mlme
.im_macaddr
, addr
, IEEE80211_ADDR_LEN
);
1152 return set80211var(drv
, IEEE80211_IOC_MLME
, &mlme
, sizeof(mlme
));
1156 wpa_driver_bsd_associate(void *priv
, struct wpa_driver_associate_params
*params
)
1158 struct wpa_driver_bsd_data
*drv
= priv
;
1159 struct ieee80211req_mlme mlme
;
1162 wpa_printf(MSG_DEBUG
,
1163 "%s: ssid '%.*s' wpa ie len %u pairwise %u group %u key mgmt %u"
1165 , (unsigned int) params
->ssid_len
, params
->ssid
1166 , (unsigned int) params
->wpa_ie_len
1167 , params
->pairwise_suite
1168 , params
->group_suite
1169 , params
->key_mgmt_suite
1172 /* XXX error handling is wrong but unclear what to do... */
1173 if (wpa_driver_bsd_set_wpa_ie(drv
, params
->wpa_ie
, params
->wpa_ie_len
) < 0)
1175 #ifndef NEW_FREEBSD_MLME_ASSOC
1176 if (wpa_driver_bsd_set_ssid(drv
, params
->ssid
, params
->ssid_len
) < 0)
1180 privacy
= !(params
->pairwise_suite
== CIPHER_NONE
&&
1181 params
->group_suite
== CIPHER_NONE
&&
1182 params
->key_mgmt_suite
== KEY_MGMT_NONE
&&
1183 params
->wpa_ie_len
== 0);
1184 wpa_printf(MSG_DEBUG
, "%s: set PRIVACY %u", __func__
, privacy
);
1186 if (set80211param(drv
, IEEE80211_IOC_PRIVACY
, privacy
) < 0)
1189 if (params
->wpa_ie_len
&&
1190 set80211param(drv
, IEEE80211_IOC_WPA
,
1191 params
->wpa_ie
[0] == WLAN_EID_RSN
? 2 : 1) < 0)
1194 os_memset(&mlme
, 0, sizeof(mlme
));
1195 mlme
.im_op
= IEEE80211_MLME_ASSOC
;
1196 #ifdef NEW_FREEBSD_MLME_ASSOC
1197 if (params
->ssid
!= NULL
)
1198 os_memcpy(mlme
.im_ssid
, params
->ssid
, params
->ssid_len
);
1199 mlme
.im_ssid_len
= params
->ssid_len
;
1201 if (params
->bssid
!= NULL
)
1202 os_memcpy(mlme
.im_macaddr
, params
->bssid
, IEEE80211_ADDR_LEN
);
1203 if (set80211var(drv
, IEEE80211_IOC_MLME
, &mlme
, sizeof(mlme
)) < 0)
1209 wpa_driver_bsd_set_auth_alg(void *priv
, int auth_alg
)
1211 struct wpa_driver_bsd_data
*drv
= priv
;
1214 if ((auth_alg
& AUTH_ALG_OPEN_SYSTEM
) &&
1215 (auth_alg
& AUTH_ALG_SHARED_KEY
))
1216 authmode
= IEEE80211_AUTH_AUTO
;
1217 else if (auth_alg
& AUTH_ALG_SHARED_KEY
)
1218 authmode
= IEEE80211_AUTH_SHARED
;
1220 authmode
= IEEE80211_AUTH_OPEN
;
1222 return set80211param(drv
, IEEE80211_IOC_AUTHMODE
, authmode
);
1226 wpa_driver_bsd_scan(void *priv
, const u8
*ssid
, size_t ssid_len
)
1228 struct wpa_driver_bsd_data
*drv
= priv
;
1231 /* NB: interface must be marked UP to do a scan */
1232 if (getifflags(drv
, &flags
) != 0 || setifflags(drv
, flags
| IFF_UP
) != 0)
1235 /* set desired ssid before scan */
1236 if (wpa_driver_bsd_set_ssid(drv
, ssid
, ssid_len
) < 0)
1239 /* NB: net80211 delivers a scan complete event so no need to poll */
1240 return set80211param(drv
, IEEE80211_IOC_SCAN_REQ
, 0);
1244 wpa_driver_bsd_event_receive(int sock
, void *ctx
, void *sock_ctx
)
1246 struct wpa_driver_bsd_data
*drv
= sock_ctx
;
1248 struct if_announcemsghdr
*ifan
;
1249 struct if_msghdr
*ifm
;
1250 struct rt_msghdr
*rtm
;
1251 union wpa_event_data event
;
1252 struct ieee80211_michael_event
*mic
;
1255 n
= read(sock
, buf
, sizeof(buf
));
1257 if (errno
!= EINTR
&& errno
!= EAGAIN
)
1258 perror("read(PF_ROUTE)");
1262 rtm
= (struct rt_msghdr
*) buf
;
1263 if (rtm
->rtm_version
!= RTM_VERSION
) {
1264 wpa_printf(MSG_DEBUG
, "Routing message version %d not "
1265 "understood\n", rtm
->rtm_version
);
1268 os_memset(&event
, 0, sizeof(event
));
1269 switch (rtm
->rtm_type
) {
1270 case RTM_IFANNOUNCE
:
1271 ifan
= (struct if_announcemsghdr
*) rtm
;
1272 if (ifan
->ifan_index
!= drv
->ifindex
)
1274 strlcpy(event
.interface_status
.ifname
, drv
->ifname
,
1275 sizeof(event
.interface_status
.ifname
));
1276 switch (ifan
->ifan_what
) {
1277 case IFAN_DEPARTURE
:
1278 event
.interface_status
.ievent
= EVENT_INTERFACE_REMOVED
;
1282 wpa_printf(MSG_DEBUG
, "RTM_IFANNOUNCE: Interface '%s' %s",
1283 event
.interface_status
.ifname
,
1284 ifan
->ifan_what
== IFAN_DEPARTURE
?
1285 "removed" : "added");
1286 wpa_supplicant_event(ctx
, EVENT_INTERFACE_STATUS
, &event
);
1289 ifan
= (struct if_announcemsghdr
*) rtm
;
1290 if (ifan
->ifan_index
!= drv
->ifindex
)
1292 switch (ifan
->ifan_what
) {
1293 case RTM_IEEE80211_ASSOC
:
1294 case RTM_IEEE80211_REASSOC
:
1295 wpa_supplicant_event(ctx
, EVENT_ASSOC
, NULL
);
1297 case RTM_IEEE80211_DISASSOC
:
1298 wpa_supplicant_event(ctx
, EVENT_DISASSOC
, NULL
);
1300 case RTM_IEEE80211_SCAN
:
1301 wpa_supplicant_event(ctx
, EVENT_SCAN_RESULTS
, NULL
);
1303 case RTM_IEEE80211_REPLAY
:
1306 case RTM_IEEE80211_MICHAEL
:
1307 mic
= (struct ieee80211_michael_event
*) &ifan
[1];
1308 wpa_printf(MSG_DEBUG
,
1309 "Michael MIC failure wireless event: "
1310 "keyix=%u src_addr=" MACSTR
, mic
->iev_keyix
,
1311 MAC2STR(mic
->iev_src
));
1313 os_memset(&event
, 0, sizeof(event
));
1314 event
.michael_mic_failure
.unicast
=
1315 !IEEE80211_IS_MULTICAST(mic
->iev_dst
);
1316 wpa_supplicant_event(ctx
, EVENT_MICHAEL_MIC_FAILURE
,
1322 ifm
= (struct if_msghdr
*) rtm
;
1323 if (ifm
->ifm_index
!= drv
->ifindex
)
1325 if ((rtm
->rtm_flags
& RTF_UP
) == 0) {
1326 strlcpy(event
.interface_status
.ifname
, drv
->ifname
,
1327 sizeof(event
.interface_status
.ifname
));
1328 event
.interface_status
.ievent
= EVENT_INTERFACE_REMOVED
;
1329 wpa_printf(MSG_DEBUG
, "RTM_IFINFO: Interface '%s' DOWN",
1330 event
.interface_status
.ifname
);
1331 wpa_supplicant_event(ctx
, EVENT_INTERFACE_STATUS
, &event
);
1338 wpa_driver_bsd_add_scan_entry(struct wpa_scan_results
*res
,
1339 struct ieee80211req_scan_result
*sr
)
1341 struct wpa_scan_res
*result
, **tmp
;
1345 extra_len
= 2 + sr
->isr_ssid_len
;
1346 extra_len
+= 2 + sr
->isr_nrates
;
1347 extra_len
+= 3; /* ERP IE */
1348 extra_len
+= sr
->isr_ie_len
;
1350 result
= os_zalloc(sizeof(*result
) + extra_len
);
1353 os_memcpy(result
->bssid
, sr
->isr_bssid
, ETH_ALEN
);
1354 result
->freq
= sr
->isr_freq
;
1355 result
->beacon_int
= sr
->isr_intval
;
1356 result
->caps
= sr
->isr_capinfo
;
1357 result
->qual
= sr
->isr_rssi
;
1358 result
->noise
= sr
->isr_noise
;
1360 pos
= (u8
*)(result
+ 1);
1362 *pos
++ = WLAN_EID_SSID
;
1363 *pos
++ = sr
->isr_ssid_len
;
1364 os_memcpy(pos
, sr
+ 1, sr
->isr_ssid_len
);
1365 pos
+= sr
->isr_ssid_len
;
1368 * Deal all rates as supported rate.
1369 * Because net80211 doesn't report extended supported rate or not.
1371 *pos
++ = WLAN_EID_SUPP_RATES
;
1372 *pos
++ = sr
->isr_nrates
;
1373 os_memcpy(pos
, sr
->isr_rates
, sr
->isr_nrates
);
1374 pos
+= sr
->isr_nrates
;
1376 *pos
++ = WLAN_EID_ERP_INFO
;
1378 *pos
++ = sr
->isr_erp
;
1380 os_memcpy(pos
, (u8
*)(sr
+ 1) + sr
->isr_ssid_len
, sr
->isr_ie_len
);
1381 pos
+= sr
->isr_ie_len
;
1383 result
->ie_len
= pos
- (u8
*)(result
+ 1);
1385 tmp
= os_realloc(res
->res
,
1386 (res
->num
+ 1) * sizeof(struct wpa_scan_res
*));
1391 tmp
[res
->num
++] = result
;
1395 struct wpa_scan_results
*
1396 wpa_driver_bsd_get_scan_results2(void *priv
)
1398 struct wpa_driver_bsd_data
*drv
= priv
;
1399 struct ieee80211req_scan_result
*sr
;
1400 struct wpa_scan_results
*res
;
1402 uint8_t buf
[24*1024], *pos
;
1404 len
= get80211var(drv
, IEEE80211_IOC_SCAN_RESULTS
, buf
, 24*1024);
1408 res
= os_zalloc(sizeof(*res
));
1414 while (rest
>= sizeof(struct ieee80211req_scan_result
)) {
1415 sr
= (struct ieee80211req_scan_result
*)pos
;
1416 wpa_driver_bsd_add_scan_entry(res
, sr
);
1418 rest
-= sr
->isr_len
;
1421 wpa_printf(MSG_DEBUG
, "Received %d bytes of scan results (%lu BSSes)",
1422 len
, (unsigned long)res
->num
);
1428 wpa_driver_bsd_init(void *ctx
, const char *ifname
)
1430 #define GETPARAM(drv, param, v) \
1431 (((v) = get80211param(drv, param)) != -1)
1432 struct wpa_driver_bsd_data
*drv
;
1434 drv
= os_zalloc(sizeof(*drv
));
1438 * NB: We require the interface name be mappable to an index.
1439 * This implies we do not support having wpa_supplicant
1440 * wait for an interface to appear. This seems ok; that
1441 * doesn't belong here; it's really the job of devd.
1443 drv
->ifindex
= if_nametoindex(ifname
);
1444 if (drv
->ifindex
== 0) {
1445 wpa_printf(MSG_DEBUG
, "%s: interface %s does not exist",
1449 drv
->sock
= socket(PF_INET
, SOCK_DGRAM
, 0);
1452 drv
->route
= socket(PF_ROUTE
, SOCK_RAW
, 0);
1455 eloop_register_read_sock(drv
->route
,
1456 wpa_driver_bsd_event_receive
, ctx
, drv
);
1459 os_strlcpy(drv
->ifname
, ifname
, sizeof(drv
->ifname
));
1461 if (!GETPARAM(drv
, IEEE80211_IOC_ROAMING
, drv
->prev_roaming
)) {
1462 wpa_printf(MSG_DEBUG
, "%s: failed to get roaming state: %s",
1463 __func__
, strerror(errno
));
1466 if (!GETPARAM(drv
, IEEE80211_IOC_PRIVACY
, drv
->prev_privacy
)) {
1467 wpa_printf(MSG_DEBUG
, "%s: failed to get privacy state: %s",
1468 __func__
, strerror(errno
));
1471 if (!GETPARAM(drv
, IEEE80211_IOC_WPA
, drv
->prev_wpa
)) {
1472 wpa_printf(MSG_DEBUG
, "%s: failed to get wpa state: %s",
1473 __func__
, strerror(errno
));
1476 if (set80211param(drv
, IEEE80211_IOC_ROAMING
, IEEE80211_ROAMING_MANUAL
) < 0) {
1477 wpa_printf(MSG_DEBUG
, "%s: failed to set wpa_supplicant-based "
1478 "roaming: %s", __func__
, strerror(errno
));
1482 if (set80211param(drv
, IEEE80211_IOC_WPA
, 1+2) < 0) {
1483 wpa_printf(MSG_DEBUG
, "%s: failed to enable WPA support %s",
1484 __func__
, strerror(errno
));
1498 wpa_driver_bsd_deinit(void *priv
)
1500 struct wpa_driver_bsd_data
*drv
= priv
;
1503 eloop_unregister_read_sock(drv
->route
);
1505 /* NB: mark interface down */
1506 if (getifflags(drv
, &flags
) == 0)
1507 (void) setifflags(drv
, flags
&~ IFF_UP
);
1509 wpa_driver_bsd_set_wpa_internal(drv
, drv
->prev_wpa
, drv
->prev_privacy
);
1510 if (set80211param(drv
, IEEE80211_IOC_ROAMING
, drv
->prev_roaming
) < 0)
1511 wpa_printf(MSG_DEBUG
, "%s: failed to restore roaming state",
1514 (void) close(drv
->route
); /* ioctl socket */
1515 (void) close(drv
->sock
); /* event socket */
1520 const struct wpa_driver_ops wpa_driver_bsd_ops
= {
1522 .desc
= "BSD 802.11 support (Atheros, etc.)",
1523 .init
= wpa_driver_bsd_init
,
1524 .deinit
= wpa_driver_bsd_deinit
,
1525 .get_bssid
= wpa_driver_bsd_get_bssid
,
1526 .get_ssid
= wpa_driver_bsd_get_ssid
,
1527 .set_wpa
= wpa_driver_bsd_set_wpa
,
1528 .set_key
= wpa_driver_bsd_set_key
,
1529 .set_countermeasures
= wpa_driver_bsd_set_countermeasures
,
1530 .set_drop_unencrypted
= wpa_driver_bsd_set_drop_unencrypted
,
1531 .scan
= wpa_driver_bsd_scan
,
1532 .get_scan_results2
= wpa_driver_bsd_get_scan_results2
,
1533 .deauthenticate
= wpa_driver_bsd_deauthenticate
,
1534 .disassociate
= wpa_driver_bsd_disassociate
,
1535 .associate
= wpa_driver_bsd_associate
,
1536 .set_auth_alg
= wpa_driver_bsd_set_auth_alg
,
1539 #endif /* HOSTAPD */