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.
35 #include "ieee802_1x.h"
38 #include "l2_packet/l2_packet.h"
42 #include "radius/radius.h"
43 #include "ieee802_11.h"
46 struct bsd_driver_data
{
47 struct hostapd_data
*hapd
; /* back pointer */
49 char iface
[IFNAMSIZ
+ 1];
50 struct l2_packet_data
*sock_xmit
; /* raw packet xmit socket */
51 int ioctl_sock
; /* socket for ioctl() use */
52 int wext_sock
; /* socket for wireless events */
55 static int bsd_sta_deauth(void *priv
, const u8
*addr
, int reason_code
);
58 set80211var(struct bsd_driver_data
*drv
, int op
, const void *arg
, int arg_len
)
60 struct ieee80211req ireq
;
62 memset(&ireq
, 0, sizeof(ireq
));
63 os_strlcpy(ireq
.i_name
, drv
->iface
, IFNAMSIZ
);
66 ireq
.i_data
= (void *) arg
;
68 if (ioctl(drv
->ioctl_sock
, SIOCS80211
, &ireq
) < 0) {
69 perror("ioctl[SIOCS80211]");
76 get80211var(struct bsd_driver_data
*drv
, int op
, void *arg
, int arg_len
)
78 struct ieee80211req ireq
;
80 memset(&ireq
, 0, sizeof(ireq
));
81 os_strlcpy(ireq
.i_name
, drv
->iface
, IFNAMSIZ
);
86 if (ioctl(drv
->ioctl_sock
, SIOCG80211
, &ireq
) < 0) {
87 perror("ioctl[SIOCG80211]");
94 set80211param(struct bsd_driver_data
*drv
, int op
, int arg
)
96 struct ieee80211req ireq
;
98 memset(&ireq
, 0, sizeof(ireq
));
99 os_strlcpy(ireq
.i_name
, drv
->iface
, IFNAMSIZ
);
103 if (ioctl(drv
->ioctl_sock
, SIOCS80211
, &ireq
) < 0) {
104 perror("ioctl[SIOCS80211]");
111 ether_sprintf(const u8
*addr
)
113 static char buf
[sizeof(MACSTR
)];
116 snprintf(buf
, sizeof(buf
), MACSTR
, MAC2STR(addr
));
118 snprintf(buf
, sizeof(buf
), MACSTR
, 0,0,0,0,0,0);
123 * Configure WPA parameters.
126 bsd_configure_wpa(struct bsd_driver_data
*drv
)
128 static const char *ciphernames
[] =
129 { "WEP", "TKIP", "AES-OCB", "AES-CCM", "CKIP", "NONE" };
130 struct hostapd_data
*hapd
= drv
->hapd
;
131 struct hostapd_bss_config
*conf
= hapd
->conf
;
134 switch (conf
->wpa_group
) {
135 case WPA_CIPHER_CCMP
:
136 v
= IEEE80211_CIPHER_AES_CCM
;
138 case WPA_CIPHER_TKIP
:
139 v
= IEEE80211_CIPHER_TKIP
;
141 case WPA_CIPHER_WEP104
:
142 v
= IEEE80211_CIPHER_WEP
;
144 case WPA_CIPHER_WEP40
:
145 v
= IEEE80211_CIPHER_WEP
;
147 case WPA_CIPHER_NONE
:
148 v
= IEEE80211_CIPHER_NONE
;
151 printf("Unknown group key cipher %u\n",
155 wpa_printf(MSG_DEBUG
, "%s: group key cipher=%s (%u)",
156 __func__
, ciphernames
[v
], v
);
157 if (set80211param(drv
, IEEE80211_IOC_MCASTCIPHER
, v
)) {
158 printf("Unable to set group key cipher to %u (%s)\n",
162 if (v
== IEEE80211_CIPHER_WEP
) {
163 /* key length is done only for specific ciphers */
164 v
= (conf
->wpa_group
== WPA_CIPHER_WEP104
? 13 : 5);
165 if (set80211param(drv
, IEEE80211_IOC_MCASTKEYLEN
, v
)) {
166 printf("Unable to set group key length to %u\n", v
);
172 if (conf
->wpa_pairwise
& WPA_CIPHER_CCMP
)
173 v
|= 1<<IEEE80211_CIPHER_AES_CCM
;
174 if (conf
->wpa_pairwise
& WPA_CIPHER_TKIP
)
175 v
|= 1<<IEEE80211_CIPHER_TKIP
;
176 if (conf
->wpa_pairwise
& WPA_CIPHER_NONE
)
177 v
|= 1<<IEEE80211_CIPHER_NONE
;
178 wpa_printf(MSG_DEBUG
, "%s: pairwise key ciphers=0x%x", __func__
, v
);
179 if (set80211param(drv
, IEEE80211_IOC_UCASTCIPHERS
, v
)) {
180 printf("Unable to set pairwise key ciphers to 0x%x\n", v
);
184 wpa_printf(MSG_DEBUG
, "%s: key management algorithms=0x%x",
185 __func__
, conf
->wpa_key_mgmt
);
186 if (set80211param(drv
, IEEE80211_IOC_KEYMGTALGS
, conf
->wpa_key_mgmt
)) {
187 printf("Unable to set key management algorithms to 0x%x\n",
193 if (conf
->rsn_preauth
)
195 wpa_printf(MSG_DEBUG
, "%s: rsn capabilities=0x%x",
196 __func__
, conf
->rsn_preauth
);
197 if (set80211param(drv
, IEEE80211_IOC_RSNCAPS
, v
)) {
198 printf("Unable to set RSN capabilities to 0x%x\n", v
);
202 wpa_printf(MSG_DEBUG
, "%s: enable WPA= 0x%x", __func__
, conf
->wpa
);
203 if (set80211param(drv
, IEEE80211_IOC_WPA
, conf
->wpa
)) {
204 printf("Unable to set WPA to %u\n", conf
->wpa
);
212 bsd_set_iface_flags(void *priv
, int dev_up
)
214 struct bsd_driver_data
*drv
= priv
;
217 wpa_printf(MSG_DEBUG
, "%s: dev_up=%d", __func__
, dev_up
);
219 if (drv
->ioctl_sock
< 0)
222 memset(&ifr
, 0, sizeof(ifr
));
223 os_strlcpy(ifr
.ifr_name
, drv
->iface
, IFNAMSIZ
);
225 if (ioctl(drv
->ioctl_sock
, SIOCGIFFLAGS
, &ifr
) != 0) {
226 perror("ioctl[SIOCGIFFLAGS]");
231 ifr
.ifr_flags
|= IFF_UP
;
233 ifr
.ifr_flags
&= ~IFF_UP
;
235 if (ioctl(drv
->ioctl_sock
, SIOCSIFFLAGS
, &ifr
) != 0) {
236 perror("ioctl[SIOCSIFFLAGS]");
241 memset(&ifr
, 0, sizeof(ifr
));
242 os_strlcpy(ifr
.ifr_name
, drv
->iface
, IFNAMSIZ
);
243 ifr
.ifr_mtu
= HOSTAPD_MTU
;
244 if (ioctl(drv
->ioctl_sock
, SIOCSIFMTU
, &ifr
) != 0) {
245 perror("ioctl[SIOCSIFMTU]");
246 printf("Setting MTU failed - trying to survive with "
255 bsd_set_ieee8021x(const char *ifname
, void *priv
, int enabled
)
257 struct bsd_driver_data
*drv
= priv
;
258 struct hostapd_data
*hapd
= drv
->hapd
;
259 struct hostapd_bss_config
*conf
= hapd
->conf
;
261 wpa_printf(MSG_DEBUG
, "%s: enabled=%d", __func__
, enabled
);
264 /* XXX restore state */
265 return set80211param(priv
, IEEE80211_IOC_AUTHMODE
,
266 IEEE80211_AUTH_AUTO
);
268 if (!conf
->wpa
&& !conf
->ieee802_1x
) {
269 hostapd_logger(hapd
, NULL
, HOSTAPD_MODULE_DRIVER
,
270 HOSTAPD_LEVEL_WARNING
, "No 802.1X or WPA enabled!");
273 if (conf
->wpa
&& bsd_configure_wpa(drv
) != 0) {
274 hostapd_logger(hapd
, NULL
, HOSTAPD_MODULE_DRIVER
,
275 HOSTAPD_LEVEL_WARNING
, "Error configuring WPA state!");
278 if (set80211param(priv
, IEEE80211_IOC_AUTHMODE
,
279 (conf
->wpa
? IEEE80211_AUTH_WPA
: IEEE80211_AUTH_8021X
))) {
280 hostapd_logger(hapd
, NULL
, HOSTAPD_MODULE_DRIVER
,
281 HOSTAPD_LEVEL_WARNING
, "Error enabling WPA/802.1X!");
284 return bsd_set_iface_flags(priv
, 1);
288 bsd_set_privacy(const char *ifname
, void *priv
, int enabled
)
290 struct bsd_driver_data
*drv
= priv
;
292 wpa_printf(MSG_DEBUG
, "%s: enabled=%d", __func__
, enabled
);
294 return set80211param(drv
, IEEE80211_IOC_PRIVACY
, enabled
);
298 bsd_set_sta_authorized(void *priv
, const u8
*addr
, int authorized
)
300 struct bsd_driver_data
*drv
= priv
;
301 struct ieee80211req_mlme mlme
;
303 wpa_printf(MSG_DEBUG
, "%s: addr=%s authorized=%d",
304 __func__
, ether_sprintf(addr
), authorized
);
307 mlme
.im_op
= IEEE80211_MLME_AUTHORIZE
;
309 mlme
.im_op
= IEEE80211_MLME_UNAUTHORIZE
;
311 memcpy(mlme
.im_macaddr
, addr
, IEEE80211_ADDR_LEN
);
312 return set80211var(drv
, IEEE80211_IOC_MLME
, &mlme
, sizeof(mlme
));
316 bsd_sta_set_flags(void *priv
, const u8
*addr
, int total_flags
, int flags_or
,
319 /* For now, only support setting Authorized flag */
320 if (flags_or
& WLAN_STA_AUTHORIZED
)
321 return bsd_set_sta_authorized(priv
, addr
, 1);
322 if (!(flags_and
& WLAN_STA_AUTHORIZED
))
323 return bsd_set_sta_authorized(priv
, addr
, 0);
328 bsd_del_key(void *priv
, const u8
*addr
, int key_idx
)
330 struct bsd_driver_data
*drv
= priv
;
331 struct ieee80211req_del_key wk
;
333 wpa_printf(MSG_DEBUG
, "%s: addr=%s key_idx=%d",
334 __func__
, ether_sprintf(addr
), key_idx
);
336 memset(&wk
, 0, sizeof(wk
));
338 memcpy(wk
.idk_macaddr
, addr
, IEEE80211_ADDR_LEN
);
339 wk
.idk_keyix
= (u_int8_t
) IEEE80211_KEYIX_NONE
; /* XXX */
341 wk
.idk_keyix
= key_idx
;
344 return set80211var(drv
, IEEE80211_IOC_DELKEY
, &wk
, sizeof(wk
));
348 bsd_set_key(const char *ifname
, void *priv
, const char *alg
,
349 const u8
*addr
, int key_idx
,
350 const u8
*key
, size_t key_len
, int txkey
)
352 struct bsd_driver_data
*drv
= priv
;
353 struct ieee80211req_key wk
;
356 if (strcmp(alg
, "none") == 0)
357 return bsd_del_key(drv
, addr
, key_idx
);
359 wpa_printf(MSG_DEBUG
, "%s: alg=%s addr=%s key_idx=%d",
360 __func__
, alg
, ether_sprintf(addr
), key_idx
);
362 if (strcmp(alg
, "WEP") == 0)
363 cipher
= IEEE80211_CIPHER_WEP
;
364 else if (strcmp(alg
, "TKIP") == 0)
365 cipher
= IEEE80211_CIPHER_TKIP
;
366 else if (strcmp(alg
, "CCMP") == 0)
367 cipher
= IEEE80211_CIPHER_AES_CCM
;
369 printf("%s: unknown/unsupported algorithm %s\n",
374 if (key_len
> sizeof(wk
.ik_keydata
)) {
375 printf("%s: key length %d too big\n", __func__
, key_len
);
379 memset(&wk
, 0, sizeof(wk
));
381 wk
.ik_flags
= IEEE80211_KEY_RECV
| IEEE80211_KEY_XMIT
;
383 memset(wk
.ik_macaddr
, 0xff, IEEE80211_ADDR_LEN
);
384 wk
.ik_keyix
= key_idx
;
385 wk
.ik_flags
|= IEEE80211_KEY_DEFAULT
;
387 memcpy(wk
.ik_macaddr
, addr
, IEEE80211_ADDR_LEN
);
388 wk
.ik_keyix
= IEEE80211_KEYIX_NONE
;
390 wk
.ik_keylen
= key_len
;
391 memcpy(wk
.ik_keydata
, key
, key_len
);
393 return set80211var(drv
, IEEE80211_IOC_WPAKEY
, &wk
, sizeof(wk
));
398 bsd_get_seqnum(const char *ifname
, void *priv
, const u8
*addr
, int idx
,
401 struct bsd_driver_data
*drv
= priv
;
402 struct ieee80211req_key wk
;
404 wpa_printf(MSG_DEBUG
, "%s: addr=%s idx=%d",
405 __func__
, ether_sprintf(addr
), idx
);
407 memset(&wk
, 0, sizeof(wk
));
409 memset(wk
.ik_macaddr
, 0xff, IEEE80211_ADDR_LEN
);
411 memcpy(wk
.ik_macaddr
, addr
, IEEE80211_ADDR_LEN
);
414 if (get80211var(drv
, IEEE80211_IOC_WPAKEY
, &wk
, sizeof(wk
)) < 0) {
415 printf("Failed to get encryption.\n");
419 #ifdef WORDS_BIGENDIAN
422 * wk.ik_keytsc is in host byte order (big endian), need to
423 * swap it to match with the byte order used in WPA.
426 u8 tmp
[WPA_KEY_RSC_LEN
];
427 memcpy(tmp
, &wk
.ik_keytsc
, sizeof(wk
.ik_keytsc
));
428 for (i
= 0; i
< WPA_KEY_RSC_LEN
; i
++) {
429 seq
[i
] = tmp
[WPA_KEY_RSC_LEN
- i
- 1];
432 #else /* WORDS_BIGENDIAN */
433 memcpy(seq
, &wk
.ik_keytsc
, sizeof(wk
.ik_keytsc
));
434 #endif /* WORDS_BIGENDIAN */
440 bsd_flush(void *priv
)
442 u8 allsta
[IEEE80211_ADDR_LEN
];
444 memset(allsta
, 0xff, IEEE80211_ADDR_LEN
);
445 return bsd_sta_deauth(priv
, allsta
, IEEE80211_REASON_AUTH_LEAVE
);
450 bsd_read_sta_driver_data(void *priv
, struct hostap_sta_driver_data
*data
,
453 struct bsd_driver_data
*drv
= priv
;
454 struct ieee80211req_sta_stats stats
;
456 memcpy(stats
.is_u
.macaddr
, addr
, IEEE80211_ADDR_LEN
);
457 if (get80211var(drv
, IEEE80211_IOC_STA_STATS
, &stats
, sizeof(stats
)) > 0) {
458 /* XXX? do packets counts include non-data frames? */
459 data
->rx_packets
= stats
.is_stats
.ns_rx_data
;
460 data
->rx_bytes
= stats
.is_stats
.ns_rx_bytes
;
461 data
->tx_packets
= stats
.is_stats
.ns_tx_data
;
462 data
->tx_bytes
= stats
.is_stats
.ns_tx_bytes
;
468 bsd_set_opt_ie(const char *ifname
, void *priv
, const u8
*ie
, size_t ie_len
)
471 * Do nothing; we setup parameters at startup that define the
472 * contents of the beacon information element.
478 bsd_sta_deauth(void *priv
, const u8
*addr
, int reason_code
)
480 struct bsd_driver_data
*drv
= priv
;
481 struct ieee80211req_mlme mlme
;
483 wpa_printf(MSG_DEBUG
, "%s: addr=%s reason_code=%d",
484 __func__
, ether_sprintf(addr
), reason_code
);
486 mlme
.im_op
= IEEE80211_MLME_DEAUTH
;
487 mlme
.im_reason
= reason_code
;
488 memcpy(mlme
.im_macaddr
, addr
, IEEE80211_ADDR_LEN
);
489 return set80211var(drv
, IEEE80211_IOC_MLME
, &mlme
, sizeof(mlme
));
493 bsd_sta_disassoc(void *priv
, 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_DISASSOC
;
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_del_sta(struct bsd_driver_data
*drv
, u8 addr
[IEEE80211_ADDR_LEN
])
510 struct hostapd_data
*hapd
= drv
->hapd
;
511 struct hostapd_bss_config
*conf
= hapd
->conf
;
512 struct sta_info
*sta
;
514 hostapd_logger(hapd
, addr
, HOSTAPD_MODULE_IEEE80211
,
515 HOSTAPD_LEVEL_INFO
, "deassociated");
517 sta
= ap_get_sta(hapd
, addr
);
519 sta
->flags
&= ~(WLAN_STA_AUTH
| WLAN_STA_ASSOC
);
521 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DISASSOC
);
522 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
523 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
524 ap_free_sta(hapd
, sta
);
530 bsd_new_sta(struct bsd_driver_data
*drv
, u8 addr
[IEEE80211_ADDR_LEN
])
532 struct hostapd_data
*hapd
= drv
->hapd
;
533 struct hostapd_bss_config
*conf
= hapd
->conf
;
534 struct sta_info
*sta
;
535 struct ieee80211req_wpaie ie
;
536 int new_assoc
, ielen
, res
;
538 hostapd_logger(hapd
, addr
, HOSTAPD_MODULE_IEEE80211
,
539 HOSTAPD_LEVEL_INFO
, "associated");
541 sta
= ap_sta_add(hapd
, addr
);
545 * Fetch and validate any negotiated WPA/RSN parameters.
548 memset(&ie
, 0, sizeof(ie
));
549 memcpy(ie
.wpa_macaddr
, addr
, IEEE80211_ADDR_LEN
);
550 if (get80211var(drv
, IEEE80211_IOC_WPAIE
, &ie
, sizeof(ie
)) < 0) {
551 printf("Failed to get WPA/RSN information element.\n");
552 return -1; /* XXX not right */
554 ielen
= ie
.wpa_ie
[1];
556 printf("No WPA/RSN information element for station!\n");
557 return -1; /* XXX not right */
560 if (sta
->wpa_sm
== NULL
)
561 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
563 if (sta
->wpa_sm
== NULL
) {
564 printf("Failed to initialize WPA state machine\n");
567 res
= wpa_validate_wpa_ie(hapd
->wpa_auth
, sta
->wpa_sm
,
568 ie
.wpa_ie
, ielen
, NULL
, 0);
569 if (res
!= WPA_IE_OK
) {
570 printf("WPA/RSN information element rejected? "
577 * Now that the internal station state is setup
578 * kick the authenticator into action.
580 new_assoc
= (sta
->flags
& WLAN_STA_ASSOC
) == 0;
581 sta
->flags
|= WLAN_STA_AUTH
| WLAN_STA_ASSOC
;
582 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC
);
583 hostapd_new_assoc_sta(hapd
, sta
, !new_assoc
);
584 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 1);
588 #include <net/route.h>
589 #if defined(__NetBSD__)
590 #include <net80211/ieee80211_netbsd.h>
591 #elif defined(__FreeBSD__)
592 #include <net80211/ieee80211_freebsd.h>
594 #error "Unsupported OS"
598 bsd_wireless_event_receive(int sock
, void *ctx
, void *sock_ctx
)
600 struct bsd_driver_data
*drv
= ctx
;
601 struct hostapd_data
*hapd
= drv
->hapd
;
603 struct if_announcemsghdr
*ifan
;
604 struct rt_msghdr
*rtm
;
605 struct ieee80211_michael_event
*mic
;
606 struct ieee80211_join_event
*join
;
607 struct ieee80211_leave_event
*leave
;
610 n
= read(sock
, buf
, sizeof(buf
));
612 if (errno
!= EINTR
&& errno
!= EAGAIN
)
613 perror("read(PF_ROUTE)");
617 rtm
= (struct rt_msghdr
*) buf
;
618 if (rtm
->rtm_version
!= RTM_VERSION
) {
619 wpa_printf(MSG_DEBUG
, "Routing message version %d not "
620 "understood\n", rtm
->rtm_version
);
623 ifan
= (struct if_announcemsghdr
*) rtm
;
624 switch (rtm
->rtm_type
) {
626 switch (ifan
->ifan_what
) {
627 case RTM_IEEE80211_ASSOC
:
628 case RTM_IEEE80211_REASSOC
:
629 case RTM_IEEE80211_DISASSOC
:
630 case RTM_IEEE80211_SCAN
:
632 case RTM_IEEE80211_LEAVE
:
633 leave
= (struct ieee80211_leave_event
*) &ifan
[1];
634 bsd_del_sta(drv
, leave
->iev_addr
);
636 case RTM_IEEE80211_JOIN
:
637 #ifdef RTM_IEEE80211_REJOIN
638 case RTM_IEEE80211_REJOIN
:
640 join
= (struct ieee80211_join_event
*) &ifan
[1];
641 bsd_new_sta(drv
, join
->iev_addr
);
643 case RTM_IEEE80211_REPLAY
:
646 case RTM_IEEE80211_MICHAEL
:
647 mic
= (struct ieee80211_michael_event
*) &ifan
[1];
648 wpa_printf(MSG_DEBUG
,
649 "Michael MIC failure wireless event: "
650 "keyix=%u src_addr=" MACSTR
, mic
->iev_keyix
,
651 MAC2STR(mic
->iev_src
));
652 ieee80211_michael_mic_failure(hapd
, mic
->iev_src
, 1);
660 bsd_wireless_event_init(void *priv
)
662 struct bsd_driver_data
*drv
= priv
;
667 s
= socket(PF_ROUTE
, SOCK_RAW
, 0);
669 perror("socket(PF_ROUTE,SOCK_RAW)");
672 eloop_register_read_sock(s
, bsd_wireless_event_receive
, drv
, NULL
);
679 bsd_wireless_event_deinit(void *priv
)
681 struct bsd_driver_data
*drv
= priv
;
684 if (drv
->wext_sock
< 0)
686 eloop_unregister_read_sock(drv
->wext_sock
);
687 close(drv
->wext_sock
);
693 bsd_send_eapol(void *priv
, const u8
*addr
, const u8
*data
, size_t data_len
,
694 int encrypt
, const u8
*own_addr
)
696 struct bsd_driver_data
*drv
= priv
;
697 unsigned char buf
[3000];
698 unsigned char *bp
= buf
;
699 struct l2_ethhdr
*eth
;
704 * Prepend the Etherent header. If the caller left us
705 * space at the front we could just insert it but since
706 * we don't know we copy to a local buffer. Given the frequency
707 * and size of frames this probably doesn't matter.
709 len
= data_len
+ sizeof(struct l2_ethhdr
);
710 if (len
> sizeof(buf
)) {
713 printf("EAPOL frame discarded, cannot malloc temp "
714 "buffer of size %u!\n", len
);
718 eth
= (struct l2_ethhdr
*) bp
;
719 memcpy(eth
->h_dest
, addr
, ETH_ALEN
);
720 memcpy(eth
->h_source
, own_addr
, ETH_ALEN
);
721 eth
->h_proto
= htons(ETH_P_EAPOL
);
722 memcpy(eth
+1, data
, data_len
);
724 wpa_hexdump(MSG_MSGDUMP
, "TX EAPOL", bp
, len
);
726 status
= l2_packet_send(drv
->sock_xmit
, addr
, ETH_P_EAPOL
, bp
, len
);
734 handle_read(void *ctx
, const u8
*src_addr
, const u8
*buf
, size_t len
)
736 struct bsd_driver_data
*drv
= ctx
;
737 struct hostapd_data
*hapd
= drv
->hapd
;
738 struct sta_info
*sta
;
740 sta
= ap_get_sta(hapd
, src_addr
);
741 if (!sta
|| !(sta
->flags
& WLAN_STA_ASSOC
)) {
742 printf("Data frame from not associated STA %s\n",
743 ether_sprintf(src_addr
));
744 /* XXX cannot happen */
747 ieee802_1x_receive(hapd
, src_addr
, buf
+ sizeof(struct l2_ethhdr
),
748 len
- sizeof(struct l2_ethhdr
));
752 bsd_get_ssid(const char *ifname
, void *priv
, u8
*buf
, int len
)
754 struct bsd_driver_data
*drv
= priv
;
757 #if defined(IEEE80211_IOC_SSID)
758 ssid_len
= get80211var(drv
, IEEE80211_IOC_SSID
, buf
, len
);
759 #elif defined(SIOCG80211NWID)
760 struct ieee80211_nwid nwid
;
763 (void)memset(&ifr
, 0, sizeof(ifr
));
764 strncpy(ifr
.ifr_name
, ifname
, sizeof(ifr
.ifr_name
));
765 ifr
.ifr_data
= (void *)&nwid
;
766 if (ioctl(drv
->ioctl_sock
, SIOCG80211NWID
, &ifr
) < 0 ||
767 nwid
.i_len
> IEEE80211_NWID_LEN
)
769 if (nwid
.i_len
> len
)
771 (void)memcpy(buf
, nwid
.i_nwid
, nwid
.i_len
);
772 ssid_len
= nwid
.i_len
;
774 #error "Cannot find get ssid call"
776 wpa_printf(MSG_DEBUG
, "%s: ssid=\"%.*s\"", __func__
, ssid_len
, buf
);
781 bsd_set_ssid(const char *ifname
, void *priv
, const u8
*buf
, int len
)
783 struct bsd_driver_data
*drv
= priv
;
785 wpa_printf(MSG_DEBUG
, "%s: ssid=\"%.*s\"", __func__
, len
, buf
);
787 #if defined(IEEE80211_IOC_SSID)
788 return set80211var(drv
, IEEE80211_IOC_SSID
, buf
, len
);
789 #elif defined(SIOCS80211NWID)
791 struct ieee80211_nwid nwid
;
794 (void)memcpy(nwid
.i_nwid
, buf
, len
);
796 (void)memset(&ifr
, 0, sizeof(ifr
));
797 (void)strncpy(ifr
.ifr_name
, ifname
, sizeof(ifr
.ifr_name
));
798 ifr
.ifr_data
= (void *)&nwid
;
799 return ioctl(drv
->ioctl_sock
, SIOCS80211NWID
, &ifr
);
802 #error "Cannot find set ssid call"
807 bsd_init(struct hostapd_data
*hapd
)
809 struct bsd_driver_data
*drv
;
811 drv
= os_zalloc(sizeof(struct bsd_driver_data
));
813 printf("Could not allocate memory for bsd driver data\n");
818 drv
->ioctl_sock
= socket(PF_INET
, SOCK_DGRAM
, 0);
819 if (drv
->ioctl_sock
< 0) {
820 perror("socket[PF_INET,SOCK_DGRAM]");
823 memcpy(drv
->iface
, hapd
->conf
->iface
, sizeof(drv
->iface
));
825 drv
->sock_xmit
= l2_packet_init(drv
->iface
, NULL
, ETH_P_EAPOL
,
826 handle_read
, drv
, 1);
827 if (drv
->sock_xmit
== NULL
)
829 if (l2_packet_get_own_addr(drv
->sock_xmit
, hapd
->own_addr
))
832 bsd_set_iface_flags(drv
, 0); /* mark down during setup */
836 if (drv
->sock_xmit
!= NULL
)
837 l2_packet_deinit(drv
->sock_xmit
);
838 if (drv
->ioctl_sock
>= 0)
839 close(drv
->ioctl_sock
);
847 bsd_deinit(void *priv
)
849 struct bsd_driver_data
*drv
= priv
;
851 (void) bsd_set_iface_flags(drv
, 0);
852 if (drv
->ioctl_sock
>= 0)
853 close(drv
->ioctl_sock
);
854 if (drv
->sock_xmit
!= NULL
)
855 l2_packet_deinit(drv
->sock_xmit
);
859 const struct wpa_driver_ops wpa_driver_bsd_ops
= {
862 .deinit
= bsd_deinit
,
863 .set_ieee8021x
= bsd_set_ieee8021x
,
864 .set_privacy
= bsd_set_privacy
,
865 .set_encryption
= bsd_set_key
,
866 .get_seqnum
= bsd_get_seqnum
,
868 .set_generic_elem
= bsd_set_opt_ie
,
869 .wireless_event_init
= bsd_wireless_event_init
,
870 .wireless_event_deinit
= bsd_wireless_event_deinit
,
871 .sta_set_flags
= bsd_sta_set_flags
,
872 .read_sta_data
= bsd_read_sta_driver_data
,
873 .send_eapol
= bsd_send_eapol
,
874 .sta_disassoc
= bsd_sta_disassoc
,
875 .sta_deauth
= bsd_sta_deauth
,
876 .set_ssid
= bsd_set_ssid
,
877 .get_ssid
= bsd_get_ssid
,