wlan - Update wlan from Adrian / FreeBSD
[dragonfly.git] / contrib / hostapd / src / drivers / driver_bsd.c
CommitLineData
a875087d
JL
1/*
2 * WPA Supplicant - driver interaction with BSD net80211 layer
3 * Copyright (c) 2004, Sam Leffler <sam@errno.com>
4781064b 4 * Copyright (c) 2004, 2Wire, Inc
a875087d 5 *
4781064b
JM
6 * This software may be distributed under the terms of the BSD license.
7 * See README for more details.
a875087d
JL
8 */
9
10#include "includes.h"
11#include <sys/ioctl.h>
4781064b 12#include <sys/sysctl.h>
a875087d
JL
13
14#include "common.h"
15#include "driver.h"
16#include "eloop.h"
4781064b
JM
17#include "common/ieee802_11_defs.h"
18#include "common/wpa_common.h"
a875087d
JL
19
20#include <net/if.h>
4781064b 21#include <net/if_media.h>
a875087d
JL
22
23#ifdef __NetBSD__
24#include <net/if_ether.h>
a875087d
JL
25#else
26#include <net/ethernet.h>
27#endif
4781064b 28#include <net/route.h>
a875087d 29
4781064b
JM
30#ifdef __DragonFly__
31#include <netproto/802_11/ieee80211_ioctl.h>
32#include <netproto/802_11/ieee80211_dragonfly.h>
33#else /* __DragonFly__ */
34#ifdef __GLIBC__
35#include <netinet/ether.h>
36#endif /* __GLIBC__ */
a875087d 37#include <net80211/ieee80211.h>
a875087d 38#include <net80211/ieee80211_ioctl.h>
4781064b
JM
39#include <net80211/ieee80211_crypto.h>
40#endif /* __DragonFly__ || __GLIBC__ */
41#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
42#include <net80211/ieee80211_freebsd.h>
43#endif
44#if __NetBSD__
45#include <net80211/ieee80211_netbsd.h>
46#endif
47
48#include "l2_packet/l2_packet.h"
49
50struct bsd_driver_data {
51 struct hostapd_data *hapd; /* back pointer */
a875087d 52
a875087d 53 int sock; /* open socket for 802.11 ioctls */
4781064b 54 struct l2_packet_data *sock_xmit;/* raw packet xmit socket */
a875087d
JL
55 int route; /* routing socket for events */
56 char ifname[IFNAMSIZ+1]; /* interface name */
57 unsigned int ifindex; /* interface index */
58 void *ctx;
4781064b
JM
59 struct wpa_driver_capa capa; /* driver capability */
60 int is_ap; /* Access point mode */
61 int prev_roaming; /* roaming state to restore on deinit */
62 int prev_privacy; /* privacy state to restore on deinit */
63 int prev_wpa; /* wpa state to restore on deinit */
64 enum ieee80211_opmode opmode; /* operation mode */
65 char *event_buf;
66 size_t event_buf_len;
a875087d
JL
67};
68
4781064b
JM
69/* Generic functions for hostapd and wpa_supplicant */
70
a875087d 71static int
4781064b 72bsd_set80211(void *priv, int op, int val, const void *arg, int arg_len)
a875087d 73{
4781064b 74 struct bsd_driver_data *drv = priv;
a875087d
JL
75 struct ieee80211req ireq;
76
77 os_memset(&ireq, 0, sizeof(ireq));
4781064b 78 os_strlcpy(ireq.i_name, drv->ifname, sizeof(ireq.i_name));
a875087d 79 ireq.i_type = op;
4781064b 80 ireq.i_val = val;
a875087d 81 ireq.i_data = (void *) arg;
4781064b 82 ireq.i_len = arg_len;
a875087d
JL
83
84 if (ioctl(drv->sock, SIOCS80211, &ireq) < 0) {
4781064b
JM
85 wpa_printf(MSG_ERROR, "ioctl[SIOCS80211, op=%u, val=%u, "
86 "arg_len=%u]: %s", op, val, arg_len,
87 strerror(errno));
88 return -1;
89 }
90 return 0;
91}
92
93static int
94bsd_get80211(void *priv, struct ieee80211req *ireq, int op, void *arg,
95 int arg_len)
96{
97 struct bsd_driver_data *drv = priv;
98
99 os_memset(ireq, 0, sizeof(*ireq));
100 os_strlcpy(ireq->i_name, drv->ifname, sizeof(ireq->i_name));
101 ireq->i_type = op;
102 ireq->i_len = arg_len;
103 ireq->i_data = arg;
104
105 if (ioctl(drv->sock, SIOCG80211, ireq) < 0) {
106 wpa_printf(MSG_ERROR, "ioctl[SIOCS80211, op=%u, "
107 "arg_len=%u]: %s", op, arg_len, strerror(errno));
108 return -1;
109 }
110 return 0;
111}
112
113static int
114get80211var(struct bsd_driver_data *drv, int op, void *arg, int arg_len)
115{
116 struct ieee80211req ireq;
117
118 if (bsd_get80211(drv, &ireq, op, arg, arg_len) < 0)
119 return -1;
120 return ireq.i_len;
121}
122
123static int
124set80211var(struct bsd_driver_data *drv, int op, const void *arg, int arg_len)
125{
126 return bsd_set80211(drv, op, 0, arg, arg_len);
127}
128
129static int
130set80211param(struct bsd_driver_data *drv, int op, int arg)
131{
132 return bsd_set80211(drv, op, arg, NULL, 0);
133}
134
135static int
136bsd_get_ssid(void *priv, u8 *ssid, int len)
137{
138 struct bsd_driver_data *drv = priv;
139#ifdef SIOCG80211NWID
140 struct ieee80211_nwid nwid;
141 struct ifreq ifr;
142
143 os_memset(&ifr, 0, sizeof(ifr));
144 os_strlcpy(ifr.ifr_name, drv->ifname, sizeof(ifr.ifr_name));
145 ifr.ifr_data = (void *)&nwid;
146 if (ioctl(drv->sock, SIOCG80211NWID, &ifr) < 0 ||
147 nwid.i_len > IEEE80211_NWID_LEN)
148 return -1;
149 os_memcpy(ssid, nwid.i_nwid, nwid.i_len);
150 return nwid.i_len;
151#else
152 return get80211var(drv, IEEE80211_IOC_SSID, ssid, IEEE80211_NWID_LEN);
153#endif
154}
155
156static int
157bsd_set_ssid(void *priv, const u8 *ssid, int ssid_len)
158{
159 struct bsd_driver_data *drv = priv;
160#ifdef SIOCS80211NWID
161 struct ieee80211_nwid nwid;
162 struct ifreq ifr;
163
164 os_memcpy(nwid.i_nwid, ssid, ssid_len);
165 nwid.i_len = ssid_len;
166 os_memset(&ifr, 0, sizeof(ifr));
167 os_strlcpy(ifr.ifr_name, drv->ifname, sizeof(ifr.ifr_name));
168 ifr.ifr_data = (void *)&nwid;
169 return ioctl(drv->sock, SIOCS80211NWID, &ifr);
170#else
171 return set80211var(drv, IEEE80211_IOC_SSID, ssid, ssid_len);
172#endif
173}
174
175static int
176bsd_get_if_media(void *priv)
177{
178 struct bsd_driver_data *drv = priv;
179 struct ifmediareq ifmr;
180
181 os_memset(&ifmr, 0, sizeof(ifmr));
182 os_strlcpy(ifmr.ifm_name, drv->ifname, sizeof(ifmr.ifm_name));
183
184 if (ioctl(drv->sock, SIOCGIFMEDIA, &ifmr) < 0) {
185 wpa_printf(MSG_ERROR, "%s: SIOCGIFMEDIA %s", __func__,
186 strerror(errno));
187 return -1;
188 }
189
190 return ifmr.ifm_current;
191}
192
193static int
194bsd_set_if_media(void *priv, int media)
195{
196 struct bsd_driver_data *drv = priv;
197 struct ifreq ifr;
198
199 os_memset(&ifr, 0, sizeof(ifr));
200 os_strlcpy(ifr.ifr_name, drv->ifname, sizeof(ifr.ifr_name));
201 ifr.ifr_media = media;
202
203 if (ioctl(drv->sock, SIOCSIFMEDIA, &ifr) < 0) {
204 wpa_printf(MSG_ERROR, "%s: SIOCSIFMEDIA %s", __func__,
205 strerror(errno));
206 return -1;
207 }
208
209 return 0;
210}
211
212static int
213bsd_set_mediaopt(void *priv, uint32_t mask, uint32_t mode)
214{
215 int media = bsd_get_if_media(priv);
216
217 if (media < 0)
218 return -1;
219 media &= ~mask;
220 media |= mode;
221 if (bsd_set_if_media(priv, media) < 0)
222 return -1;
223 return 0;
224}
225
226static int
227bsd_del_key(void *priv, const u8 *addr, int key_idx)
228{
229 struct ieee80211req_del_key wk;
230
231 os_memset(&wk, 0, sizeof(wk));
232 if (addr == NULL) {
233 wpa_printf(MSG_DEBUG, "%s: key_idx=%d", __func__, key_idx);
234 wk.idk_keyix = key_idx;
235 } else {
236 wpa_printf(MSG_DEBUG, "%s: addr=" MACSTR, __func__,
237 MAC2STR(addr));
238 os_memcpy(wk.idk_macaddr, addr, IEEE80211_ADDR_LEN);
239 wk.idk_keyix = (u_int8_t) IEEE80211_KEYIX_NONE; /* XXX */
240 }
241
242 return set80211var(priv, IEEE80211_IOC_DELKEY, &wk, sizeof(wk));
243}
244
245static int
246bsd_send_mlme_param(void *priv, const u8 op, const u16 reason, const u8 *addr)
247{
248 struct ieee80211req_mlme mlme;
249
250 os_memset(&mlme, 0, sizeof(mlme));
251 mlme.im_op = op;
252 mlme.im_reason = reason;
253 os_memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
254 return set80211var(priv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme));
255}
256
257static int
258bsd_ctrl_iface(void *priv, int enable)
259{
260 struct bsd_driver_data *drv = priv;
261 struct ifreq ifr;
262
263 os_memset(&ifr, 0, sizeof(ifr));
264 os_strlcpy(ifr.ifr_name, drv->ifname, sizeof(ifr.ifr_name));
265
266 if (ioctl(drv->sock, SIOCGIFFLAGS, &ifr) < 0) {
267 perror("ioctl[SIOCGIFFLAGS]");
268 return -1;
269 }
270
271 if (enable) {
272 if (ifr.ifr_flags & IFF_UP)
273 return 0;
274 ifr.ifr_flags |= IFF_UP;
275 } else {
276 if (!(ifr.ifr_flags & IFF_UP))
277 return 0;
278 ifr.ifr_flags &= ~IFF_UP;
279 }
280
281 if (ioctl(drv->sock, SIOCSIFFLAGS, &ifr) < 0) {
282 perror("ioctl[SIOCSIFFLAGS]");
283 return -1;
284 }
285
286 return 0;
287}
288
289static int
290bsd_set_key(const char *ifname, void *priv, enum wpa_alg alg,
291 const unsigned char *addr, int key_idx, int set_tx, const u8 *seq,
292 size_t seq_len, const u8 *key, size_t key_len)
293{
294 struct ieee80211req_key wk;
295#ifdef IEEE80211_KEY_NOREPLAY
296 struct bsd_driver_data *drv = priv;
297#endif /* IEEE80211_KEY_NOREPLAY */
298
299 wpa_printf(MSG_DEBUG, "%s: alg=%d addr=%p key_idx=%d set_tx=%d "
300 "seq_len=%zu key_len=%zu", __func__, alg, addr, key_idx,
301 set_tx, seq_len, key_len);
302
303 if (alg == WPA_ALG_NONE) {
304#ifndef HOSTAPD
305 if (addr == NULL || is_broadcast_ether_addr(addr))
306 return bsd_del_key(priv, NULL, key_idx);
307 else
308#endif /* HOSTAPD */
309 return bsd_del_key(priv, addr, key_idx);
310 }
311
312 os_memset(&wk, 0, sizeof(wk));
313 switch (alg) {
314 case WPA_ALG_WEP:
315 wk.ik_type = IEEE80211_CIPHER_WEP;
316 break;
317 case WPA_ALG_TKIP:
318 wk.ik_type = IEEE80211_CIPHER_TKIP;
319 break;
320 case WPA_ALG_CCMP:
321 wk.ik_type = IEEE80211_CIPHER_AES_CCM;
322 break;
323 default:
324 wpa_printf(MSG_ERROR, "%s: unknown alg=%d", __func__, alg);
325 return -1;
326 }
327
328 wk.ik_flags = IEEE80211_KEY_RECV;
329 if (set_tx)
330 wk.ik_flags |= IEEE80211_KEY_XMIT;
331
332 if (addr == NULL) {
333 os_memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN);
334 wk.ik_keyix = key_idx;
335 } else {
336 os_memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN);
337 /*
338 * Deduce whether group/global or unicast key by checking
339 * the address (yech). Note also that we can only mark global
340 * keys default; doing this for a unicast key is an error.
341 */
342 if (is_broadcast_ether_addr(addr)) {
343 wk.ik_flags |= IEEE80211_KEY_GROUP;
344 wk.ik_keyix = key_idx;
345 } else {
346 wk.ik_keyix = key_idx == 0 ? IEEE80211_KEYIX_NONE :
347 key_idx;
348 }
349 }
350 if (wk.ik_keyix != IEEE80211_KEYIX_NONE && set_tx)
351 wk.ik_flags |= IEEE80211_KEY_DEFAULT;
352#ifndef HOSTAPD
353#ifdef IEEE80211_KEY_NOREPLAY
354 /*
355 * Ignore replay failures in IBSS and AHDEMO mode.
356 */
357 if (drv->opmode == IEEE80211_M_IBSS ||
358 drv->opmode == IEEE80211_M_AHDEMO)
359 wk.ik_flags |= IEEE80211_KEY_NOREPLAY;
360#endif /* IEEE80211_KEY_NOREPLAY */
361#endif /* HOSTAPD */
362 wk.ik_keylen = key_len;
363 if (seq) {
364#ifdef WORDS_BIGENDIAN
365 /*
366 * wk.ik_keyrsc is in host byte order (big endian), need to
367 * swap it to match with the byte order used in WPA.
368 */
369 int i;
370 u8 *keyrsc = (u8 *) &wk.ik_keyrsc;
371 for (i = 0; i < seq_len; i++)
372 keyrsc[WPA_KEY_RSC_LEN - i - 1] = seq[i];
373#else /* WORDS_BIGENDIAN */
374 os_memcpy(&wk.ik_keyrsc, seq, seq_len);
375#endif /* WORDS_BIGENDIAN */
376 }
377 os_memcpy(wk.ik_keydata, key, key_len);
378
379 return set80211var(priv, IEEE80211_IOC_WPAKEY, &wk, sizeof(wk));
380}
381
382static int
383bsd_configure_wpa(void *priv, struct wpa_bss_params *params)
384{
385#ifndef IEEE80211_IOC_APPIE
386 static const char *ciphernames[] =
387 { "WEP", "TKIP", "AES-OCB", "AES-CCM", "CKIP", "NONE" };
388 int v;
389
390 switch (params->wpa_group) {
391 case WPA_CIPHER_CCMP:
392 v = IEEE80211_CIPHER_AES_CCM;
393 break;
394 case WPA_CIPHER_TKIP:
395 v = IEEE80211_CIPHER_TKIP;
396 break;
397 case WPA_CIPHER_WEP104:
398 v = IEEE80211_CIPHER_WEP;
399 break;
400 case WPA_CIPHER_WEP40:
401 v = IEEE80211_CIPHER_WEP;
402 break;
403 case WPA_CIPHER_NONE:
404 v = IEEE80211_CIPHER_NONE;
405 break;
406 default:
407 printf("Unknown group key cipher %u\n",
408 params->wpa_group);
409 return -1;
410 }
411 wpa_printf(MSG_DEBUG, "%s: group key cipher=%s (%u)",
412 __func__, ciphernames[v], v);
413 if (set80211param(priv, IEEE80211_IOC_MCASTCIPHER, v)) {
414 printf("Unable to set group key cipher to %u (%s)\n",
415 v, ciphernames[v]);
416 return -1;
417 }
418 if (v == IEEE80211_CIPHER_WEP) {
419 /* key length is done only for specific ciphers */
420 v = (params->wpa_group == WPA_CIPHER_WEP104 ? 13 : 5);
421 if (set80211param(priv, IEEE80211_IOC_MCASTKEYLEN, v)) {
422 printf("Unable to set group key length to %u\n", v);
423 return -1;
424 }
425 }
426
427 v = 0;
428 if (params->wpa_pairwise & WPA_CIPHER_CCMP)
429 v |= 1<<IEEE80211_CIPHER_AES_CCM;
430 if (params->wpa_pairwise & WPA_CIPHER_TKIP)
431 v |= 1<<IEEE80211_CIPHER_TKIP;
432 if (params->wpa_pairwise & WPA_CIPHER_NONE)
433 v |= 1<<IEEE80211_CIPHER_NONE;
434 wpa_printf(MSG_DEBUG, "%s: pairwise key ciphers=0x%x", __func__, v);
435 if (set80211param(priv, IEEE80211_IOC_UCASTCIPHERS, v)) {
436 printf("Unable to set pairwise key ciphers to 0x%x\n", v);
437 return -1;
438 }
439
440 wpa_printf(MSG_DEBUG, "%s: key management algorithms=0x%x",
441 __func__, params->wpa_key_mgmt);
442 if (set80211param(priv, IEEE80211_IOC_KEYMGTALGS,
443 params->wpa_key_mgmt)) {
444 printf("Unable to set key management algorithms to 0x%x\n",
445 params->wpa_key_mgmt);
446 return -1;
447 }
448
449 v = 0;
450 if (params->rsn_preauth)
451 v |= BIT(0);
452 wpa_printf(MSG_DEBUG, "%s: rsn capabilities=0x%x",
453 __func__, params->rsn_preauth);
454 if (set80211param(priv, IEEE80211_IOC_RSNCAPS, v)) {
455 printf("Unable to set RSN capabilities to 0x%x\n", v);
456 return -1;
457 }
458#endif /* IEEE80211_IOC_APPIE */
459
460 wpa_printf(MSG_DEBUG, "%s: enable WPA= 0x%x", __func__, params->wpa);
461 if (set80211param(priv, IEEE80211_IOC_WPA, params->wpa)) {
462 printf("Unable to set WPA to %u\n", params->wpa);
463 return -1;
464 }
465 return 0;
466}
467
468static int
469bsd_set_ieee8021x(void *priv, struct wpa_bss_params *params)
470{
471 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, params->enabled);
472
473 if (!params->enabled) {
474 /* XXX restore state */
475 return set80211param(priv, IEEE80211_IOC_AUTHMODE,
476 IEEE80211_AUTH_AUTO);
477 }
478 if (!params->wpa && !params->ieee802_1x) {
479 wpa_printf(MSG_ERROR, "%s: No 802.1X or WPA enabled",
480 __func__);
481 return -1;
482 }
483 if (params->wpa && bsd_configure_wpa(priv, params) != 0) {
484 wpa_printf(MSG_ERROR, "%s: Failed to configure WPA state",
485 __func__);
486 return -1;
487 }
488 if (set80211param(priv, IEEE80211_IOC_AUTHMODE,
489 (params->wpa ? IEEE80211_AUTH_WPA : IEEE80211_AUTH_8021X))) {
490 wpa_printf(MSG_ERROR, "%s: Failed to enable WPA/802.1X",
491 __func__);
492 return -1;
493 }
494 return bsd_ctrl_iface(priv, 1);
495}
496
497static void
498bsd_new_sta(void *priv, void *ctx, u8 addr[IEEE80211_ADDR_LEN])
499{
500 struct ieee80211req_wpaie ie;
501 int ielen = 0;
502 u8 *iebuf = NULL;
503
504 /*
505 * Fetch and validate any negotiated WPA/RSN parameters.
506 */
507 memset(&ie, 0, sizeof(ie));
508 memcpy(ie.wpa_macaddr, addr, IEEE80211_ADDR_LEN);
509 if (get80211var(priv, IEEE80211_IOC_WPAIE, &ie, sizeof(ie)) < 0) {
510 printf("Failed to get WPA/RSN information element.\n");
511 goto no_ie;
512 }
513 iebuf = ie.wpa_ie;
514 ielen = ie.wpa_ie[1];
515 if (ielen == 0)
516 iebuf = NULL;
517 else
518 ielen += 2;
519
520no_ie:
521 drv_event_assoc(ctx, addr, iebuf, ielen, 0);
522}
523
524static int
525bsd_send_eapol(void *priv, const u8 *addr, const u8 *data, size_t data_len,
526 int encrypt, const u8 *own_addr, u32 flags)
527{
528 struct bsd_driver_data *drv = priv;
529
530 wpa_hexdump(MSG_MSGDUMP, "TX EAPOL", data, data_len);
531
532 return l2_packet_send(drv->sock_xmit, addr, ETH_P_EAPOL, data,
533 data_len);
534}
535
536static int
537bsd_set_freq(void *priv, struct hostapd_freq_params *freq)
538{
539 struct bsd_driver_data *drv = priv;
540#ifdef SIOCS80211CHANNEL
541 struct ieee80211chanreq creq;
542#endif /* SIOCS80211CHANNEL */
543 u32 mode;
544 int channel = freq->channel;
545
546 if (channel < 14) {
547 mode =
548#ifdef CONFIG_IEEE80211N
549 freq->ht_enabled ? IFM_IEEE80211_11NG :
550#endif /* CONFIG_IEEE80211N */
551 IFM_IEEE80211_11G;
552 } else if (channel == 14) {
553 mode = IFM_IEEE80211_11B;
554 } else {
555 mode =
556#ifdef CONFIG_IEEE80211N
557 freq->ht_enabled ? IFM_IEEE80211_11NA :
558#endif /* CONFIG_IEEE80211N */
559 IFM_IEEE80211_11A;
560 }
561 if (bsd_set_mediaopt(drv, IFM_MMASK, mode) < 0) {
562 wpa_printf(MSG_ERROR, "%s: failed to set modulation mode",
563 __func__);
564 return -1;
565 }
566
567#ifdef SIOCS80211CHANNEL
568 os_memset(&creq, 0, sizeof(creq));
569 os_strlcpy(creq.i_name, drv->ifname, sizeof(creq.i_name));
570 creq.i_channel = (u_int16_t)channel;
571 return ioctl(drv->sock, SIOCS80211CHANNEL, &creq);
572#else /* SIOCS80211CHANNEL */
573 return set80211param(priv, IEEE80211_IOC_CHANNEL, channel);
574#endif /* SIOCS80211CHANNEL */
575}
576
577static int
578bsd_set_opt_ie(void *priv, const u8 *ie, size_t ie_len)
579{
580#ifdef IEEE80211_IOC_APPIE
581 wpa_printf(MSG_DEBUG, "%s: set WPA+RSN ie (len %lu)", __func__,
582 (unsigned long)ie_len);
583 return bsd_set80211(priv, IEEE80211_IOC_APPIE, IEEE80211_APPIE_WPA,
584 ie, ie_len);
585#endif /* IEEE80211_IOC_APPIE */
586 return 0;
587}
588
589static size_t
590rtbuf_len(void)
591{
592 size_t len;
593
594 int mib[6] = {CTL_NET, AF_ROUTE, 0, AF_INET, NET_RT_DUMP, 0};
595
596 if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {
597 wpa_printf(MSG_WARNING, "%s failed: %s\n", __func__,
598 strerror(errno));
599 len = 2048;
600 }
601
602 return len;
603}
604
605#ifdef HOSTAPD
606
607/*
608 * Avoid conflicts with hostapd definitions by undefining couple of defines
609 * from net80211 header files.
610 */
611#undef RSN_VERSION
612#undef WPA_VERSION
613#undef WPA_OUI_TYPE
614
615static int bsd_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr,
616 int reason_code);
617
085ff963 618const char *
4781064b
JM
619ether_sprintf(const u8 *addr)
620{
621 static char buf[sizeof(MACSTR)];
622
623 if (addr != NULL)
624 snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
625 else
626 snprintf(buf, sizeof(buf), MACSTR, 0,0,0,0,0,0);
627 return buf;
628}
629
630static int
631bsd_set_privacy(void *priv, int enabled)
632{
633 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled);
634
635 return set80211param(priv, IEEE80211_IOC_PRIVACY, enabled);
636}
637
638static int
639bsd_get_seqnum(const char *ifname, void *priv, const u8 *addr, int idx,
640 u8 *seq)
641{
642 struct ieee80211req_key wk;
643
644 wpa_printf(MSG_DEBUG, "%s: addr=%s idx=%d",
645 __func__, ether_sprintf(addr), idx);
646
647 memset(&wk, 0, sizeof(wk));
648 if (addr == NULL)
649 memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN);
650 else
651 memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN);
652 wk.ik_keyix = idx;
653
654 if (get80211var(priv, IEEE80211_IOC_WPAKEY, &wk, sizeof(wk)) < 0) {
655 printf("Failed to get encryption.\n");
a875087d
JL
656 return -1;
657 }
4781064b
JM
658
659#ifdef WORDS_BIGENDIAN
660 {
661 /*
662 * wk.ik_keytsc is in host byte order (big endian), need to
663 * swap it to match with the byte order used in WPA.
664 */
665 int i;
666 u8 tmp[WPA_KEY_RSC_LEN];
667 memcpy(tmp, &wk.ik_keytsc, sizeof(wk.ik_keytsc));
668 for (i = 0; i < WPA_KEY_RSC_LEN; i++) {
669 seq[i] = tmp[WPA_KEY_RSC_LEN - i - 1];
670 }
671 }
672#else /* WORDS_BIGENDIAN */
673 memcpy(seq, &wk.ik_keytsc, sizeof(wk.ik_keytsc));
674#endif /* WORDS_BIGENDIAN */
675 return 0;
676}
677
678
679static int
680bsd_flush(void *priv)
681{
682 u8 allsta[IEEE80211_ADDR_LEN];
683
684 memset(allsta, 0xff, IEEE80211_ADDR_LEN);
685 return bsd_sta_deauth(priv, NULL, allsta, IEEE80211_REASON_AUTH_LEAVE);
686}
687
688
689static int
690bsd_read_sta_driver_data(void *priv, struct hostap_sta_driver_data *data,
691 const u8 *addr)
692{
693 struct ieee80211req_sta_stats stats;
694
695 memcpy(stats.is_u.macaddr, addr, IEEE80211_ADDR_LEN);
696 if (get80211var(priv, IEEE80211_IOC_STA_STATS, &stats, sizeof(stats))
697 > 0) {
698 /* XXX? do packets counts include non-data frames? */
699 data->rx_packets = stats.is_stats.ns_rx_data;
700 data->rx_bytes = stats.is_stats.ns_rx_bytes;
701 data->tx_packets = stats.is_stats.ns_tx_data;
702 data->tx_bytes = stats.is_stats.ns_tx_bytes;
703 }
704 return 0;
705}
706
707static int
708bsd_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr, int reason_code)
709{
710 return bsd_send_mlme_param(priv, IEEE80211_MLME_DEAUTH, reason_code,
711 addr);
712}
713
714static int
715bsd_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr,
716 int reason_code)
717{
718 return bsd_send_mlme_param(priv, IEEE80211_MLME_DISASSOC, reason_code,
719 addr);
720}
721
722static void
723bsd_wireless_event_receive(int sock, void *ctx, void *sock_ctx)
724{
725 struct bsd_driver_data *drv = ctx;
726 struct if_announcemsghdr *ifan;
727 struct rt_msghdr *rtm;
728 struct ieee80211_michael_event *mic;
729 struct ieee80211_join_event *join;
730 struct ieee80211_leave_event *leave;
731 int n;
732 union wpa_event_data data;
733
734 n = read(sock, drv->event_buf, drv->event_buf_len);
735 if (n < 0) {
736 if (errno != EINTR && errno != EAGAIN)
737 wpa_printf(MSG_ERROR, "%s read() failed: %s\n",
738 __func__, strerror(errno));
739 return;
740 }
741
742 rtm = (struct rt_msghdr *) drv->event_buf;
743 if (rtm->rtm_version != RTM_VERSION) {
744 wpa_printf(MSG_DEBUG, "Invalid routing message version=%d",
745 rtm->rtm_version);
746 return;
747 }
748 ifan = (struct if_announcemsghdr *) rtm;
749 switch (rtm->rtm_type) {
750 case RTM_IEEE80211:
751 switch (ifan->ifan_what) {
752 case RTM_IEEE80211_ASSOC:
753 case RTM_IEEE80211_REASSOC:
754 case RTM_IEEE80211_DISASSOC:
755 case RTM_IEEE80211_SCAN:
756 break;
757 case RTM_IEEE80211_LEAVE:
758 leave = (struct ieee80211_leave_event *) &ifan[1];
759 drv_event_disassoc(drv->hapd, leave->iev_addr);
760 break;
761 case RTM_IEEE80211_JOIN:
762#ifdef RTM_IEEE80211_REJOIN
763 case RTM_IEEE80211_REJOIN:
764#endif
765 join = (struct ieee80211_join_event *) &ifan[1];
766 bsd_new_sta(drv, drv->hapd, join->iev_addr);
767 break;
768 case RTM_IEEE80211_REPLAY:
769 /* ignore */
770 break;
771 case RTM_IEEE80211_MICHAEL:
772 mic = (struct ieee80211_michael_event *) &ifan[1];
773 wpa_printf(MSG_DEBUG,
774 "Michael MIC failure wireless event: "
775 "keyix=%u src_addr=" MACSTR, mic->iev_keyix,
776 MAC2STR(mic->iev_src));
777 os_memset(&data, 0, sizeof(data));
778 data.michael_mic_failure.unicast = 1;
779 data.michael_mic_failure.src = mic->iev_src;
780 wpa_supplicant_event(drv->hapd,
781 EVENT_MICHAEL_MIC_FAILURE, &data);
782 break;
783 }
784 break;
785 }
a875087d
JL
786}
787
4781064b
JM
788static void
789handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len)
a875087d 790{
4781064b
JM
791 struct bsd_driver_data *drv = ctx;
792 drv_event_eapol_rx(drv->hapd, src_addr, buf, len);
793}
a875087d 794
4781064b
JM
795static void *
796bsd_init(struct hostapd_data *hapd, struct wpa_init_params *params)
797{
798 struct bsd_driver_data *drv;
a875087d 799
4781064b
JM
800 drv = os_zalloc(sizeof(struct bsd_driver_data));
801 if (drv == NULL) {
802 wpa_printf(MSG_ERROR, "Could not allocate memory for bsd driver data");
803 return NULL;
a875087d 804 }
a875087d 805
4781064b 806 drv->event_buf_len = rtbuf_len();
a875087d 807
4781064b
JM
808 drv->event_buf = os_malloc(drv->event_buf_len);
809 if (drv->event_buf == NULL) {
810 wpa_printf(MSG_ERROR, "%s: os_malloc() failed", __func__);
811 goto bad;
812 }
a875087d 813
4781064b
JM
814 drv->hapd = hapd;
815 drv->sock = socket(PF_INET, SOCK_DGRAM, 0);
816 if (drv->sock < 0) {
817 perror("socket[PF_INET,SOCK_DGRAM]");
818 goto bad;
a875087d 819 }
4781064b 820 os_strlcpy(drv->ifname, params->ifname, sizeof(drv->ifname));
a875087d 821
4781064b
JM
822 drv->sock_xmit = l2_packet_init(drv->ifname, NULL, ETH_P_EAPOL,
823 handle_read, drv, 0);
824 if (drv->sock_xmit == NULL)
825 goto bad;
826 if (l2_packet_get_own_addr(drv->sock_xmit, params->own_addr))
827 goto bad;
a875087d 828
4781064b
JM
829 /* mark down during setup */
830 if (bsd_ctrl_iface(drv, 0) < 0)
831 goto bad;
a875087d 832
4781064b
JM
833 drv->route = socket(PF_ROUTE, SOCK_RAW, 0);
834 if (drv->route < 0) {
835 perror("socket(PF_ROUTE,SOCK_RAW)");
836 goto bad;
a875087d 837 }
4781064b
JM
838 eloop_register_read_sock(drv->route, bsd_wireless_event_receive, drv,
839 NULL);
840
841 if (bsd_set_mediaopt(drv, IFM_OMASK, IFM_IEEE80211_HOSTAP) < 0) {
842 wpa_printf(MSG_ERROR, "%s: failed to set operation mode",
843 __func__);
844 goto bad;
845 }
846
847 return drv;
848bad:
849 if (drv->sock_xmit != NULL)
850 l2_packet_deinit(drv->sock_xmit);
851 if (drv->sock >= 0)
852 close(drv->sock);
853 os_free(drv->event_buf);
854 if (drv != NULL)
855 os_free(drv);
856 return NULL;
a875087d
JL
857}
858
4781064b
JM
859
860static void
861bsd_deinit(void *priv)
a875087d 862{
4781064b 863 struct bsd_driver_data *drv = priv;
a875087d 864
4781064b
JM
865 if (drv->route >= 0) {
866 eloop_unregister_read_sock(drv->route);
867 close(drv->route);
a875087d 868 }
4781064b
JM
869 bsd_ctrl_iface(drv, 0);
870 if (drv->sock >= 0)
871 close(drv->sock);
872 if (drv->sock_xmit != NULL)
873 l2_packet_deinit(drv->sock_xmit);
874 os_free(drv->event_buf);
875 os_free(drv);
a875087d
JL
876}
877
4781064b 878
a875087d 879static int
4781064b 880bsd_commit(void *priv)
a875087d 881{
4781064b 882 return bsd_ctrl_iface(priv, 1);
a875087d
JL
883}
884
4781064b 885
a875087d 886static int
4781064b
JM
887bsd_set_sta_authorized(void *priv, const u8 *addr,
888 int total_flags, int flags_or, int flags_and)
a875087d 889{
4781064b 890 int authorized = -1;
a875087d 891
4781064b
JM
892 /* For now, only support setting Authorized flag */
893 if (flags_or & WPA_STA_AUTHORIZED)
894 authorized = 1;
895 if (!(flags_and & WPA_STA_AUTHORIZED))
896 authorized = 0;
897
898 if (authorized < 0)
899 return 0;
900
901 return bsd_send_mlme_param(priv, authorized ?
902 IEEE80211_MLME_AUTHORIZE :
903 IEEE80211_MLME_UNAUTHORIZE, 0, addr);
a875087d 904}
4781064b 905#else /* HOSTAPD */
a875087d 906
a875087d 907static int
4781064b 908get80211param(struct bsd_driver_data *drv, int op)
a875087d 909{
4781064b 910 struct ieee80211req ireq;
a875087d 911
4781064b
JM
912 if (bsd_get80211(drv, &ireq, op, NULL, 0) < 0)
913 return -1;
914 return ireq.i_val;
a875087d 915}
a875087d
JL
916
917static int
4781064b 918wpa_driver_bsd_get_bssid(void *priv, u8 *bssid)
a875087d 919{
4781064b
JM
920 struct bsd_driver_data *drv = priv;
921#ifdef SIOCG80211BSSID
922 struct ieee80211_bssid bs;
a875087d 923
4781064b
JM
924 os_strlcpy(bs.i_name, drv->ifname, sizeof(bs.i_name));
925 if (ioctl(drv->sock, SIOCG80211BSSID, &bs) < 0)
926 return -1;
927 os_memcpy(bssid, bs.i_bssid, sizeof(bs.i_bssid));
928 return 0;
929#else
930 return get80211var(drv, IEEE80211_IOC_BSSID,
931 bssid, IEEE80211_ADDR_LEN) < 0 ? -1 : 0;
932#endif
a875087d
JL
933}
934
935static int
4781064b 936wpa_driver_bsd_get_ssid(void *priv, u8 *ssid)
a875087d 937{
4781064b
JM
938 struct bsd_driver_data *drv = priv;
939 return bsd_get_ssid(drv, ssid, 0);
a875087d
JL
940}
941
942static int
4781064b
JM
943wpa_driver_bsd_set_wpa_ie(struct bsd_driver_data *drv, const u8 *wpa_ie,
944 size_t wpa_ie_len)
a875087d 945{
4781064b
JM
946#ifdef IEEE80211_IOC_APPIE
947 return bsd_set_opt_ie(drv, wpa_ie, wpa_ie_len);
948#else /* IEEE80211_IOC_APPIE */
a875087d 949 return set80211var(drv, IEEE80211_IOC_OPTIE, wpa_ie, wpa_ie_len);
4781064b 950#endif /* IEEE80211_IOC_APPIE */
a875087d
JL
951}
952
953static int
954wpa_driver_bsd_set_wpa_internal(void *priv, int wpa, int privacy)
955{
a875087d
JL
956 int ret = 0;
957
958 wpa_printf(MSG_DEBUG, "%s: wpa=%d privacy=%d",
959 __FUNCTION__, wpa, privacy);
960
4781064b 961 if (!wpa && wpa_driver_bsd_set_wpa_ie(priv, NULL, 0) < 0)
a875087d 962 ret = -1;
4781064b 963 if (set80211param(priv, IEEE80211_IOC_PRIVACY, privacy) < 0)
a875087d 964 ret = -1;
4781064b 965 if (set80211param(priv, IEEE80211_IOC_WPA, wpa) < 0)
a875087d
JL
966 ret = -1;
967
968 return ret;
969}
970
971static int
972wpa_driver_bsd_set_wpa(void *priv, int enabled)
973{
974 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled);
975
976 return wpa_driver_bsd_set_wpa_internal(priv, enabled ? 3 : 0, enabled);
977}
978
a875087d
JL
979static int
980wpa_driver_bsd_set_countermeasures(void *priv, int enabled)
981{
a875087d 982 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled);
4781064b 983 return set80211param(priv, IEEE80211_IOC_COUNTERMEASURES, enabled);
a875087d
JL
984}
985
986
987static int
988wpa_driver_bsd_set_drop_unencrypted(void *priv, int enabled)
989{
a875087d 990 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled);
4781064b 991 return set80211param(priv, IEEE80211_IOC_DROPUNENCRYPTED, enabled);
a875087d
JL
992}
993
994static int
995wpa_driver_bsd_deauthenticate(void *priv, const u8 *addr, int reason_code)
996{
4781064b
JM
997 return bsd_send_mlme_param(priv, IEEE80211_MLME_DEAUTH, reason_code,
998 addr);
a875087d
JL
999}
1000
1001static int
4781064b 1002wpa_driver_bsd_set_auth_alg(void *priv, int auth_alg)
a875087d 1003{
4781064b 1004 int authmode;
a875087d 1005
4781064b
JM
1006 if ((auth_alg & WPA_AUTH_ALG_OPEN) &&
1007 (auth_alg & WPA_AUTH_ALG_SHARED))
1008 authmode = IEEE80211_AUTH_AUTO;
1009 else if (auth_alg & WPA_AUTH_ALG_SHARED)
1010 authmode = IEEE80211_AUTH_SHARED;
1011 else
1012 authmode = IEEE80211_AUTH_OPEN;
1013
1014 return set80211param(priv, IEEE80211_IOC_AUTHMODE, authmode);
1015}
1016
1017static void
1018handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len)
1019{
1020 struct bsd_driver_data *drv = ctx;
1021
1022 drv_event_eapol_rx(drv->ctx, src_addr, buf, len);
a875087d
JL
1023}
1024
1025static int
1026wpa_driver_bsd_associate(void *priv, struct wpa_driver_associate_params *params)
1027{
4781064b 1028 struct bsd_driver_data *drv = priv;
a875087d 1029 struct ieee80211req_mlme mlme;
4781064b 1030 u32 mode;
a875087d 1031 int privacy;
4781064b 1032 int ret = 0;
a875087d
JL
1033
1034 wpa_printf(MSG_DEBUG,
1035 "%s: ssid '%.*s' wpa ie len %u pairwise %u group %u key mgmt %u"
1036 , __func__
4781064b
JM
1037 , (unsigned int) params->ssid_len, params->ssid
1038 , (unsigned int) params->wpa_ie_len
a875087d
JL
1039 , params->pairwise_suite
1040 , params->group_suite
1041 , params->key_mgmt_suite
1042 );
1043
4781064b
JM
1044 switch (params->mode) {
1045 case IEEE80211_MODE_INFRA:
1046 mode = 0 /* STA */;
1047 break;
1048 case IEEE80211_MODE_IBSS:
1049 mode = IFM_IEEE80211_IBSS;
1050 break;
1051 case IEEE80211_MODE_AP:
1052 mode = IFM_IEEE80211_HOSTAP;
1053 break;
1054 default:
1055 wpa_printf(MSG_ERROR, "%s: unknown operation mode", __func__);
1056 return -1;
1057 }
1058 if (bsd_set_mediaopt(drv, IFM_OMASK, mode) < 0) {
1059 wpa_printf(MSG_ERROR, "%s: failed to set operation mode",
1060 __func__);
1061 return -1;
1062 }
1063
1064 if (params->mode == IEEE80211_MODE_AP) {
1065 drv->sock_xmit = l2_packet_init(drv->ifname, NULL, ETH_P_EAPOL,
1066 handle_read, drv, 0);
1067 if (drv->sock_xmit == NULL)
1068 return -1;
1069 drv->is_ap = 1;
1070 return 0;
1071 }
1072
1073 if (wpa_driver_bsd_set_drop_unencrypted(drv, params->drop_unencrypted)
1074 < 0)
1075 ret = -1;
1076 if (wpa_driver_bsd_set_auth_alg(drv, params->auth_alg) < 0)
1077 ret = -1;
a875087d
JL
1078 /* XXX error handling is wrong but unclear what to do... */
1079 if (wpa_driver_bsd_set_wpa_ie(drv, params->wpa_ie, params->wpa_ie_len) < 0)
1080 return -1;
1081
4781064b
JM
1082 privacy = !(params->pairwise_suite == WPA_CIPHER_NONE &&
1083 params->group_suite == WPA_CIPHER_NONE &&
1084 params->key_mgmt_suite == WPA_KEY_MGMT_NONE &&
a875087d
JL
1085 params->wpa_ie_len == 0);
1086 wpa_printf(MSG_DEBUG, "%s: set PRIVACY %u", __func__, privacy);
1087
1088 if (set80211param(drv, IEEE80211_IOC_PRIVACY, privacy) < 0)
1089 return -1;
1090
1091 if (params->wpa_ie_len &&
1092 set80211param(drv, IEEE80211_IOC_WPA,
1093 params->wpa_ie[0] == WLAN_EID_RSN ? 2 : 1) < 0)
1094 return -1;
1095
1096 os_memset(&mlme, 0, sizeof(mlme));
1097 mlme.im_op = IEEE80211_MLME_ASSOC;
1098 if (params->ssid != NULL)
1099 os_memcpy(mlme.im_ssid, params->ssid, params->ssid_len);
1100 mlme.im_ssid_len = params->ssid_len;
1101 if (params->bssid != NULL)
1102 os_memcpy(mlme.im_macaddr, params->bssid, IEEE80211_ADDR_LEN);
1103 if (set80211var(drv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme)) < 0)
1104 return -1;
4781064b 1105 return ret;
a875087d
JL
1106}
1107
1108static int
4781064b 1109wpa_driver_bsd_scan(void *priv, struct wpa_driver_scan_params *params)
a875087d 1110{
4781064b
JM
1111 struct bsd_driver_data *drv = priv;
1112#ifdef IEEE80211_IOC_SCAN_MAX_SSID
1113 struct ieee80211_scan_req sr;
1114 int i;
1115#endif /* IEEE80211_IOC_SCAN_MAX_SSID */
1116
1117 if (bsd_set_mediaopt(drv, IFM_OMASK, 0 /* STA */) < 0) {
1118 wpa_printf(MSG_ERROR, "%s: failed to set operation mode",
1119 __func__);
1120 return -1;
1121 }
a875087d 1122
4781064b
JM
1123 if (set80211param(drv, IEEE80211_IOC_ROAMING,
1124 IEEE80211_ROAMING_MANUAL) < 0) {
1125 wpa_printf(MSG_ERROR, "%s: failed to set "
1126 "wpa_supplicant-based roaming: %s", __func__,
1127 strerror(errno));
1128 return -1;
1129 }
a875087d 1130
4781064b
JM
1131 if (wpa_driver_bsd_set_wpa(drv, 1) < 0) {
1132 wpa_printf(MSG_ERROR, "%s: failed to set wpa: %s", __func__,
1133 strerror(errno));
1134 return -1;
1135 }
a875087d
JL
1136
1137 /* NB: interface must be marked UP to do a scan */
4781064b 1138 if (bsd_ctrl_iface(drv, 1) < 0)
a875087d
JL
1139 return -1;
1140
4781064b
JM
1141#ifdef IEEE80211_IOC_SCAN_MAX_SSID
1142 os_memset(&sr, 0, sizeof(sr));
1143 sr.sr_flags = IEEE80211_IOC_SCAN_ACTIVE | IEEE80211_IOC_SCAN_ONCE |
1144 IEEE80211_IOC_SCAN_NOJOIN;
1145 sr.sr_duration = IEEE80211_IOC_SCAN_FOREVER;
1146 if (params->num_ssids > 0) {
1147 sr.sr_nssid = params->num_ssids;
1148#if 0
1149 /* Boundary check is done by upper layer */
1150 if (sr.sr_nssid > IEEE80211_IOC_SCAN_MAX_SSID)
1151 sr.sr_nssid = IEEE80211_IOC_SCAN_MAX_SSID;
1152#endif
1153
1154 /* NB: check scan cache first */
1155 sr.sr_flags |= IEEE80211_IOC_SCAN_CHECK;
1156 }
1157 for (i = 0; i < sr.sr_nssid; i++) {
1158 sr.sr_ssid[i].len = params->ssids[i].ssid_len;
1159 os_memcpy(sr.sr_ssid[i].ssid, params->ssids[i].ssid,
1160 sr.sr_ssid[i].len);
1161 }
1162
1163 /* NB: net80211 delivers a scan complete event so no need to poll */
1164 return set80211var(drv, IEEE80211_IOC_SCAN_REQ, &sr, sizeof(sr));
1165#else /* IEEE80211_IOC_SCAN_MAX_SSID */
a875087d 1166 /* set desired ssid before scan */
4781064b
JM
1167 if (bsd_set_ssid(drv, params->ssids[0].ssid,
1168 params->ssids[0].ssid_len) < 0)
a875087d
JL
1169 return -1;
1170
1171 /* NB: net80211 delivers a scan complete event so no need to poll */
1172 return set80211param(drv, IEEE80211_IOC_SCAN_REQ, 0);
4781064b 1173#endif /* IEEE80211_IOC_SCAN_MAX_SSID */
a875087d
JL
1174}
1175
a875087d
JL
1176static void
1177wpa_driver_bsd_event_receive(int sock, void *ctx, void *sock_ctx)
1178{
4781064b 1179 struct bsd_driver_data *drv = sock_ctx;
a875087d
JL
1180 struct if_announcemsghdr *ifan;
1181 struct if_msghdr *ifm;
1182 struct rt_msghdr *rtm;
1183 union wpa_event_data event;
1184 struct ieee80211_michael_event *mic;
4781064b
JM
1185 struct ieee80211_leave_event *leave;
1186 struct ieee80211_join_event *join;
a875087d
JL
1187 int n;
1188
4781064b 1189 n = read(sock, drv->event_buf, drv->event_buf_len);
a875087d
JL
1190 if (n < 0) {
1191 if (errno != EINTR && errno != EAGAIN)
4781064b
JM
1192 wpa_printf(MSG_ERROR, "%s read() failed: %s\n",
1193 __func__, strerror(errno));
a875087d
JL
1194 return;
1195 }
1196
4781064b 1197 rtm = (struct rt_msghdr *) drv->event_buf;
a875087d 1198 if (rtm->rtm_version != RTM_VERSION) {
4781064b
JM
1199 wpa_printf(MSG_DEBUG, "Invalid routing message version=%d",
1200 rtm->rtm_version);
a875087d
JL
1201 return;
1202 }
1203 os_memset(&event, 0, sizeof(event));
1204 switch (rtm->rtm_type) {
1205 case RTM_IFANNOUNCE:
1206 ifan = (struct if_announcemsghdr *) rtm;
1207 if (ifan->ifan_index != drv->ifindex)
1208 break;
4781064b
JM
1209 os_strlcpy(event.interface_status.ifname, drv->ifname,
1210 sizeof(event.interface_status.ifname));
a875087d
JL
1211 switch (ifan->ifan_what) {
1212 case IFAN_DEPARTURE:
1213 event.interface_status.ievent = EVENT_INTERFACE_REMOVED;
1214 default:
1215 return;
1216 }
1217 wpa_printf(MSG_DEBUG, "RTM_IFANNOUNCE: Interface '%s' %s",
1218 event.interface_status.ifname,
1219 ifan->ifan_what == IFAN_DEPARTURE ?
1220 "removed" : "added");
1221 wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &event);
1222 break;
1223 case RTM_IEEE80211:
1224 ifan = (struct if_announcemsghdr *) rtm;
1225 if (ifan->ifan_index != drv->ifindex)
1226 break;
1227 switch (ifan->ifan_what) {
1228 case RTM_IEEE80211_ASSOC:
1229 case RTM_IEEE80211_REASSOC:
4781064b
JM
1230 if (drv->is_ap)
1231 break;
a875087d
JL
1232 wpa_supplicant_event(ctx, EVENT_ASSOC, NULL);
1233 break;
1234 case RTM_IEEE80211_DISASSOC:
4781064b
JM
1235 if (drv->is_ap)
1236 break;
a875087d
JL
1237 wpa_supplicant_event(ctx, EVENT_DISASSOC, NULL);
1238 break;
1239 case RTM_IEEE80211_SCAN:
4781064b
JM
1240 if (drv->is_ap)
1241 break;
a875087d
JL
1242 wpa_supplicant_event(ctx, EVENT_SCAN_RESULTS, NULL);
1243 break;
4781064b
JM
1244 case RTM_IEEE80211_LEAVE:
1245 leave = (struct ieee80211_leave_event *) &ifan[1];
1246 drv_event_disassoc(ctx, leave->iev_addr);
1247 break;
1248 case RTM_IEEE80211_JOIN:
1249#ifdef RTM_IEEE80211_REJOIN
1250 case RTM_IEEE80211_REJOIN:
1251#endif
1252 join = (struct ieee80211_join_event *) &ifan[1];
1253 bsd_new_sta(drv, ctx, join->iev_addr);
1254 break;
a875087d
JL
1255 case RTM_IEEE80211_REPLAY:
1256 /* ignore */
1257 break;
1258 case RTM_IEEE80211_MICHAEL:
1259 mic = (struct ieee80211_michael_event *) &ifan[1];
1260 wpa_printf(MSG_DEBUG,
1261 "Michael MIC failure wireless event: "
1262 "keyix=%u src_addr=" MACSTR, mic->iev_keyix,
1263 MAC2STR(mic->iev_src));
1264
1265 os_memset(&event, 0, sizeof(event));
1266 event.michael_mic_failure.unicast =
1267 !IEEE80211_IS_MULTICAST(mic->iev_dst);
1268 wpa_supplicant_event(ctx, EVENT_MICHAEL_MIC_FAILURE,
1269 &event);
1270 break;
1271 }
1272 break;
1273 case RTM_IFINFO:
1274 ifm = (struct if_msghdr *) rtm;
1275 if (ifm->ifm_index != drv->ifindex)
1276 break;
1277 if ((rtm->rtm_flags & RTF_UP) == 0) {
4781064b
JM
1278 os_strlcpy(event.interface_status.ifname, drv->ifname,
1279 sizeof(event.interface_status.ifname));
a875087d
JL
1280 event.interface_status.ievent = EVENT_INTERFACE_REMOVED;
1281 wpa_printf(MSG_DEBUG, "RTM_IFINFO: Interface '%s' DOWN",
1282 event.interface_status.ifname);
1283 wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &event);
1284 }
1285 break;
1286 }
1287}
1288
4781064b
JM
1289static void
1290wpa_driver_bsd_add_scan_entry(struct wpa_scan_results *res,
1291 struct ieee80211req_scan_result *sr)
a875087d 1292{
4781064b
JM
1293 struct wpa_scan_res *result, **tmp;
1294 size_t extra_len;
1295 u8 *pos;
a875087d 1296
4781064b
JM
1297 extra_len = 2 + sr->isr_ssid_len;
1298 extra_len += 2 + sr->isr_nrates;
1299 extra_len += 3; /* ERP IE */
1300 extra_len += sr->isr_ie_len;
a875087d 1301
4781064b
JM
1302 result = os_zalloc(sizeof(*result) + extra_len);
1303 if (result == NULL)
1304 return;
1305 os_memcpy(result->bssid, sr->isr_bssid, ETH_ALEN);
1306 result->freq = sr->isr_freq;
1307 result->beacon_int = sr->isr_intval;
1308 result->caps = sr->isr_capinfo;
1309 result->qual = sr->isr_rssi;
1310 result->noise = sr->isr_noise;
1311 /*
1312 * the rssi value reported by the kernel is in 0.5dB steps relative to
1313 * the reported noise floor. see ieee80211_node.h for details.
1314 */
1315 result->level = sr->isr_rssi / 2 + sr->isr_noise;
1316
1317 pos = (u8 *)(result + 1);
a875087d 1318
4781064b
JM
1319 *pos++ = WLAN_EID_SSID;
1320 *pos++ = sr->isr_ssid_len;
1321 os_memcpy(pos, sr + 1, sr->isr_ssid_len);
1322 pos += sr->isr_ssid_len;
a875087d 1323
4781064b
JM
1324 /*
1325 * Deal all rates as supported rate.
1326 * Because net80211 doesn't report extended supported rate or not.
1327 */
1328 *pos++ = WLAN_EID_SUPP_RATES;
1329 *pos++ = sr->isr_nrates;
1330 os_memcpy(pos, sr->isr_rates, sr->isr_nrates);
1331 pos += sr->isr_nrates;
1332
1333 *pos++ = WLAN_EID_ERP_INFO;
1334 *pos++ = 1;
1335 *pos++ = sr->isr_erp;
1336
1337 os_memcpy(pos, (u8 *)(sr + 1) + sr->isr_ssid_len, sr->isr_ie_len);
1338 pos += sr->isr_ie_len;
a875087d 1339
4781064b
JM
1340 result->ie_len = pos - (u8 *)(result + 1);
1341
1342 tmp = os_realloc_array(res->res, res->num + 1,
1343 sizeof(struct wpa_scan_res *));
1344 if (tmp == NULL) {
1345 os_free(result);
1346 return;
1347 }
1348 tmp[res->num++] = result;
1349 res->res = tmp;
a875087d
JL
1350}
1351
4781064b
JM
1352struct wpa_scan_results *
1353wpa_driver_bsd_get_scan_results2(void *priv)
a875087d 1354{
4781064b
JM
1355 struct ieee80211req_scan_result *sr;
1356 struct wpa_scan_results *res;
1357 int len, rest;
1358 uint8_t buf[24*1024], *pos;
1359
1360 len = get80211var(priv, IEEE80211_IOC_SCAN_RESULTS, buf, 24*1024);
1361 if (len < 0)
1362 return NULL;
a875087d 1363
4781064b
JM
1364 res = os_zalloc(sizeof(*res));
1365 if (res == NULL)
1366 return NULL;
1367
1368 pos = buf;
1369 rest = len;
1370 while (rest >= sizeof(struct ieee80211req_scan_result)) {
1371 sr = (struct ieee80211req_scan_result *)pos;
1372 wpa_driver_bsd_add_scan_entry(res, sr);
1373 pos += sr->isr_len;
1374 rest -= sr->isr_len;
a875087d 1375 }
a875087d 1376
4781064b
JM
1377 wpa_printf(MSG_DEBUG, "Received %d bytes of scan results (%lu BSSes)",
1378 len, (unsigned long)res->num);
1379
1380 return res;
1381}
a875087d 1382
4781064b 1383static int wpa_driver_bsd_capa(struct bsd_driver_data *drv)
a875087d 1384{
4781064b
JM
1385#ifdef IEEE80211_IOC_DEVCAPS
1386/* kernel definitions copied from net80211/ieee80211_var.h */
1387#define IEEE80211_CIPHER_WEP 0
1388#define IEEE80211_CIPHER_TKIP 1
1389#define IEEE80211_CIPHER_AES_CCM 3
1390#define IEEE80211_CRYPTO_WEP (1<<IEEE80211_CIPHER_WEP)
1391#define IEEE80211_CRYPTO_TKIP (1<<IEEE80211_CIPHER_TKIP)
1392#define IEEE80211_CRYPTO_AES_CCM (1<<IEEE80211_CIPHER_AES_CCM)
1393#define IEEE80211_C_HOSTAP 0x00000400 /* CAPABILITY: HOSTAP avail */
1394#define IEEE80211_C_WPA1 0x00800000 /* CAPABILITY: WPA1 avail */
1395#define IEEE80211_C_WPA2 0x01000000 /* CAPABILITY: WPA2 avail */
1396 struct ieee80211_devcaps_req devcaps;
1397
1398 if (get80211var(drv, IEEE80211_IOC_DEVCAPS, &devcaps,
1399 sizeof(devcaps)) < 0) {
1400 wpa_printf(MSG_ERROR, "failed to IEEE80211_IOC_DEVCAPS: %s",
1401 strerror(errno));
1402 return -1;
1403 }
1404
1405 wpa_printf(MSG_DEBUG, "%s: drivercaps=0x%08x,cryptocaps=0x%08x",
1406 __func__, devcaps.dc_drivercaps, devcaps.dc_cryptocaps);
1407
1408 if (devcaps.dc_drivercaps & IEEE80211_C_WPA1)
1409 drv->capa.key_mgmt = WPA_DRIVER_CAPA_KEY_MGMT_WPA |
1410 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK;
1411 if (devcaps.dc_drivercaps & IEEE80211_C_WPA2)
1412 drv->capa.key_mgmt = WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
1413 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK;
1414
1415 if (devcaps.dc_cryptocaps & IEEE80211_CRYPTO_WEP)
1416 drv->capa.enc |= WPA_DRIVER_CAPA_ENC_WEP40 |
1417 WPA_DRIVER_CAPA_ENC_WEP104;
1418 if (devcaps.dc_cryptocaps & IEEE80211_CRYPTO_TKIP)
1419 drv->capa.enc |= WPA_DRIVER_CAPA_ENC_TKIP;
1420 if (devcaps.dc_cryptocaps & IEEE80211_CRYPTO_AES_CCM)
1421 drv->capa.enc |= WPA_DRIVER_CAPA_ENC_CCMP;
1422
1423 if (devcaps.dc_drivercaps & IEEE80211_C_HOSTAP)
1424 drv->capa.flags |= WPA_DRIVER_FLAGS_AP;
1425#undef IEEE80211_CIPHER_WEP
1426#undef IEEE80211_CIPHER_TKIP
1427#undef IEEE80211_CIPHER_AES_CCM
1428#undef IEEE80211_CRYPTO_WEP
1429#undef IEEE80211_CRYPTO_TKIP
1430#undef IEEE80211_CRYPTO_AES_CCM
1431#undef IEEE80211_C_HOSTAP
1432#undef IEEE80211_C_WPA1
1433#undef IEEE80211_C_WPA2
1434#else /* IEEE80211_IOC_DEVCAPS */
1435 /* For now, assume TKIP, CCMP, WPA, WPA2 are supported */
1436 drv->capa.key_mgmt = WPA_DRIVER_CAPA_KEY_MGMT_WPA |
1437 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
1438 WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
1439 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK;
1440 drv->capa.enc = WPA_DRIVER_CAPA_ENC_WEP40 |
1441 WPA_DRIVER_CAPA_ENC_WEP104 |
1442 WPA_DRIVER_CAPA_ENC_TKIP |
1443 WPA_DRIVER_CAPA_ENC_CCMP;
1444 drv->capa.flags |= WPA_DRIVER_FLAGS_AP;
1445#endif /* IEEE80211_IOC_DEVCAPS */
1446#ifdef IEEE80211_IOC_SCAN_MAX_SSID
1447 drv->capa.max_scan_ssids = IEEE80211_IOC_SCAN_MAX_SSID;
1448#else /* IEEE80211_IOC_SCAN_MAX_SSID */
1449 drv->capa.max_scan_ssids = 1;
1450#endif /* IEEE80211_IOC_SCAN_MAX_SSID */
1451 drv->capa.auth = WPA_DRIVER_AUTH_OPEN |
1452 WPA_DRIVER_AUTH_SHARED |
1453 WPA_DRIVER_AUTH_LEAP;
1454 return 0;
a875087d
JL
1455}
1456
4781064b
JM
1457static enum ieee80211_opmode
1458get80211opmode(struct bsd_driver_data *drv)
a875087d 1459{
4781064b 1460 struct ifmediareq ifmr;
a875087d 1461
4781064b
JM
1462 (void) memset(&ifmr, 0, sizeof(ifmr));
1463 (void) os_strlcpy(ifmr.ifm_name, drv->ifname, sizeof(ifmr.ifm_name));
a875087d 1464
4781064b
JM
1465 if (ioctl(drv->sock, SIOCGIFMEDIA, (caddr_t)&ifmr) >= 0) {
1466 if (ifmr.ifm_current & IFM_IEEE80211_ADHOC) {
1467 if (ifmr.ifm_current & IFM_FLAG0)
1468 return IEEE80211_M_AHDEMO;
1469 else
1470 return IEEE80211_M_IBSS;
a875087d 1471 }
4781064b
JM
1472 if (ifmr.ifm_current & IFM_IEEE80211_HOSTAP)
1473 return IEEE80211_M_HOSTAP;
1474 if (ifmr.ifm_current & IFM_IEEE80211_MONITOR)
1475 return IEEE80211_M_MONITOR;
1476#ifdef IEEE80211_M_MBSS
1477 if (ifmr.ifm_current & IFM_IEEE80211_MBSS)
1478 return IEEE80211_M_MBSS;
1479#endif /* IEEE80211_M_MBSS */
a875087d 1480 }
4781064b 1481 return IEEE80211_M_STA;
a875087d
JL
1482}
1483
1484static void *
1485wpa_driver_bsd_init(void *ctx, const char *ifname)
1486{
1487#define GETPARAM(drv, param, v) \
1488 (((v) = get80211param(drv, param)) != -1)
4781064b 1489 struct bsd_driver_data *drv;
a875087d
JL
1490
1491 drv = os_zalloc(sizeof(*drv));
1492 if (drv == NULL)
1493 return NULL;
4781064b
JM
1494
1495 drv->event_buf_len = rtbuf_len();
1496
1497 drv->event_buf = os_malloc(drv->event_buf_len);
1498 if (drv->event_buf == NULL) {
1499 wpa_printf(MSG_ERROR, "%s: os_malloc() failed", __func__);
1500 goto fail1;
1501 }
1502
a875087d
JL
1503 /*
1504 * NB: We require the interface name be mappable to an index.
1505 * This implies we do not support having wpa_supplicant
1506 * wait for an interface to appear. This seems ok; that
1507 * doesn't belong here; it's really the job of devd.
1508 */
1509 drv->ifindex = if_nametoindex(ifname);
1510 if (drv->ifindex == 0) {
1511 wpa_printf(MSG_DEBUG, "%s: interface %s does not exist",
1512 __func__, ifname);
1513 goto fail1;
1514 }
1515 drv->sock = socket(PF_INET, SOCK_DGRAM, 0);
1516 if (drv->sock < 0)
1517 goto fail1;
4781064b
JM
1518
1519 os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname));
1520 /* Down interface during setup. */
1521 if (bsd_ctrl_iface(drv, 0) < 0)
1522 goto fail;
1523
a875087d
JL
1524 drv->route = socket(PF_ROUTE, SOCK_RAW, 0);
1525 if (drv->route < 0)
1526 goto fail;
1527 eloop_register_read_sock(drv->route,
1528 wpa_driver_bsd_event_receive, ctx, drv);
1529
1530 drv->ctx = ctx;
a875087d
JL
1531
1532 if (!GETPARAM(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming)) {
1533 wpa_printf(MSG_DEBUG, "%s: failed to get roaming state: %s",
1534 __func__, strerror(errno));
1535 goto fail;
1536 }
1537 if (!GETPARAM(drv, IEEE80211_IOC_PRIVACY, drv->prev_privacy)) {
1538 wpa_printf(MSG_DEBUG, "%s: failed to get privacy state: %s",
1539 __func__, strerror(errno));
1540 goto fail;
1541 }
1542 if (!GETPARAM(drv, IEEE80211_IOC_WPA, drv->prev_wpa)) {
1543 wpa_printf(MSG_DEBUG, "%s: failed to get wpa state: %s",
1544 __func__, strerror(errno));
1545 goto fail;
1546 }
a875087d 1547
4781064b 1548 if (wpa_driver_bsd_capa(drv))
a875087d 1549 goto fail;
4781064b
JM
1550
1551 drv->opmode = get80211opmode(drv);
a875087d
JL
1552
1553 return drv;
1554fail:
1555 close(drv->sock);
1556fail1:
4781064b 1557 os_free(drv->event_buf);
a875087d
JL
1558 os_free(drv);
1559 return NULL;
1560#undef GETPARAM
1561}
1562
1563static void
1564wpa_driver_bsd_deinit(void *priv)
1565{
4781064b 1566 struct bsd_driver_data *drv = priv;
a875087d 1567
4781064b 1568 wpa_driver_bsd_set_wpa(drv, 0);
a875087d
JL
1569 eloop_unregister_read_sock(drv->route);
1570
1571 /* NB: mark interface down */
4781064b 1572 bsd_ctrl_iface(drv, 0);
a875087d
JL
1573
1574 wpa_driver_bsd_set_wpa_internal(drv, drv->prev_wpa, drv->prev_privacy);
1575 if (set80211param(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming) < 0)
1576 wpa_printf(MSG_DEBUG, "%s: failed to restore roaming state",
1577 __func__);
1578
4781064b
JM
1579 if (drv->sock_xmit != NULL)
1580 l2_packet_deinit(drv->sock_xmit);
a875087d
JL
1581 (void) close(drv->route); /* ioctl socket */
1582 (void) close(drv->sock); /* event socket */
4781064b 1583 os_free(drv->event_buf);
a875087d
JL
1584 os_free(drv);
1585}
1586
4781064b
JM
1587static int
1588wpa_driver_bsd_get_capa(void *priv, struct wpa_driver_capa *capa)
1589{
1590 struct bsd_driver_data *drv = priv;
1591
1592 os_memcpy(capa, &drv->capa, sizeof(*capa));
1593 return 0;
1594}
1595#endif /* HOSTAPD */
1596
a875087d
JL
1597
1598const struct wpa_driver_ops wpa_driver_bsd_ops = {
1599 .name = "bsd",
4781064b
JM
1600 .desc = "BSD 802.11 support",
1601#ifdef HOSTAPD
1602 .hapd_init = bsd_init,
1603 .hapd_deinit = bsd_deinit,
1604 .set_privacy = bsd_set_privacy,
1605 .get_seqnum = bsd_get_seqnum,
1606 .flush = bsd_flush,
1607 .read_sta_data = bsd_read_sta_driver_data,
1608 .sta_disassoc = bsd_sta_disassoc,
1609 .sta_deauth = bsd_sta_deauth,
1610 .sta_set_flags = bsd_set_sta_authorized,
1611 .commit = bsd_commit,
1612#else /* HOSTAPD */
a875087d
JL
1613 .init = wpa_driver_bsd_init,
1614 .deinit = wpa_driver_bsd_deinit,
1615 .get_bssid = wpa_driver_bsd_get_bssid,
1616 .get_ssid = wpa_driver_bsd_get_ssid,
a875087d 1617 .set_countermeasures = wpa_driver_bsd_set_countermeasures,
4781064b
JM
1618 .scan2 = wpa_driver_bsd_scan,
1619 .get_scan_results2 = wpa_driver_bsd_get_scan_results2,
a875087d 1620 .deauthenticate = wpa_driver_bsd_deauthenticate,
a875087d 1621 .associate = wpa_driver_bsd_associate,
4781064b
JM
1622 .get_capa = wpa_driver_bsd_get_capa,
1623#endif /* HOSTAPD */
1624 .set_freq = bsd_set_freq,
1625 .set_key = bsd_set_key,
1626 .set_ieee8021x = bsd_set_ieee8021x,
1627 .hapd_set_ssid = bsd_set_ssid,
1628 .hapd_get_ssid = bsd_get_ssid,
1629 .hapd_send_eapol = bsd_send_eapol,
1630 .set_generic_elem = bsd_set_opt_ie,
a875087d 1631};