]> git.ipfire.org Git - thirdparty/hostap.git/blame - src/drivers/driver_nl80211.c
Remove unused if_update() driver op
[thirdparty/hostap.git] / src / drivers / driver_nl80211.c
CommitLineData
3f5285e8 1/*
c5121837 2 * Driver interaction with Linux nl80211/cfg80211
072ad14c
JM
3 * Copyright (c) 2002-2008, Jouni Malinen <j@w1.fi>
4 * Copyright (c) 2003-2004, Instant802 Networks, Inc.
5 * Copyright (c) 2005-2006, Devicescape Software, Inc.
6 * Copyright (c) 2007, Johannes Berg <johannes@sipsolutions.net>
7 * Copyright (c) 2009, Atheros Communications
3f5285e8
JM
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * Alternatively, this software may be distributed under the terms of BSD
14 * license.
15 *
16 * See README and COPYING for more details.
17 */
18
19#include "includes.h"
20#include <sys/ioctl.h>
21#include <net/if_arp.h>
37b7d082 22#include <net/if.h>
3f5285e8
JM
23#include <netlink/genl/genl.h>
24#include <netlink/genl/family.h>
25#include <netlink/genl/ctrl.h>
7e45830a 26#include "nl80211_copy.h"
625f587b 27
3f5285e8
JM
28#include "common.h"
29#include "driver.h"
30#include "eloop.h"
90973fb2 31#include "common/ieee802_11_defs.h"
3f5285e8 32
c5121837 33#if defined(CONFIG_AP) || defined(HOSTAPD)
0915d02c
JM
34#include <netpacket/packet.h>
35#include <linux/filter.h>
36#include "radiotap.h"
37#include "radiotap_iter.h"
c5121837 38
a8d6ffa4 39#include "../../hostapd/sta_flags.h"
4b9841d3 40#endif /* CONFIG_AP || HOSTAPD */
0915d02c 41
c5121837
JM
42#ifdef CONFIG_LIBNL20
43/* libnl 2.0 compatibility code */
2e8eac2d 44#define nl_handle nl_sock
c5121837
JM
45#define nl_handle_alloc_cb nl_socket_alloc_cb
46#define nl_handle_destroy nl_socket_free
47#endif /* CONFIG_LIBNL20 */
48
c5121837 49
3f5285e8
JM
50#ifndef IFF_LOWER_UP
51#define IFF_LOWER_UP 0x10000 /* driver signals L1 up */
52#endif
53#ifndef IFF_DORMANT
54#define IFF_DORMANT 0x20000 /* driver signals dormant */
55#endif
56
57#ifndef IF_OPER_DORMANT
58#define IF_OPER_DORMANT 5
59#endif
60#ifndef IF_OPER_UP
61#define IF_OPER_UP 6
62#endif
63
c5121837
JM
64struct i802_bss {
65 struct i802_bss *next;
b4fd6fab 66 int ifindex;
c5121837
JM
67 unsigned int beacon_set:1;
68};
3f5285e8
JM
69
70struct wpa_driver_nl80211_data {
71 void *ctx;
d8816397 72 int link_event_sock;
c5121837 73 int ioctl_sock; /* socket for ioctl() use */
3f5285e8
JM
74 char ifname[IFNAMSIZ + 1];
75 int ifindex;
7524cfb1 76 int if_removed;
c2a04078
JM
77 struct wpa_driver_capa capa;
78 int has_capability;
c2a04078 79
3f5285e8
JM
80 int operstate;
81
3f5285e8
JM
82 int scan_complete_events;
83
84 struct nl_handle *nl_handle;
335ce76b 85 struct nl_handle *nl_handle_event;
3f5285e8 86 struct nl_cache *nl_cache;
335ce76b 87 struct nl_cache *nl_cache_event;
3f5285e8
JM
88 struct nl_cb *nl_cb;
89 struct genl_family *nl80211;
1c873584 90
e6b8efeb 91 u8 auth_bssid[ETH_ALEN];
c2a04078
JM
92 u8 bssid[ETH_ALEN];
93 int associated;
fd05d64e
JM
94 u8 ssid[32];
95 size_t ssid_len;
ad1e68e6
JM
96 int nlmode;
97 int ap_scan_as_station;
d2440ba0 98
0915d02c
JM
99 int monitor_sock;
100 int monitor_ifidx;
7da3abe7 101
7da3abe7 102 unsigned int beacon_set:1;
c5121837
JM
103
104#ifdef HOSTAPD
c5121837 105 int eapol_sock; /* socket for EAPOL frames */
c5121837
JM
106
107 int default_if_indices[16];
108 int *if_indices;
109 int num_if_indices;
110
c5121837 111 struct i802_bss bss;
c5121837
JM
112
113 int last_freq;
114 int last_freq_ht;
c5121837 115#endif /* HOSTAPD */
3f5285e8
JM
116};
117
118
119static void wpa_driver_nl80211_scan_timeout(void *eloop_ctx,
120 void *timeout_ctx);
ad1e68e6 121static int wpa_driver_nl80211_set_mode(void *priv, int mode);
362f781e 122static int
7524cfb1 123wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv);
d72aad94
JM
124static int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data *drv,
125 const u8 *addr, int cmd, u16 reason_code);
7524cfb1 126
460456f8
JM
127#if defined(CONFIG_AP) || defined(HOSTAPD)
128static void nl80211_remove_monitor_interface(
129 struct wpa_driver_nl80211_data *drv);
130#endif /* CONFIG_AP || HOSTAPD */
131
0915d02c
JM
132#ifdef CONFIG_AP
133static void nl80211_remove_iface(struct wpa_driver_nl80211_data *drv,
134 int ifidx);
135#endif /* CONFIG_AP */
136
072ad14c 137#ifdef HOSTAPD
2135f224
JM
138static void add_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx);
139static void del_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx);
b4fd6fab
JM
140static struct i802_bss * get_bss(struct wpa_driver_nl80211_data *drv,
141 int ifindex);
bbaf0837
JM
142static void nl80211_remove_iface(struct wpa_driver_nl80211_data *drv,
143 int ifidx);
144static int i802_set_freq(void *priv, struct hostapd_freq_params *freq);
072ad14c
JM
145#endif /* HOSTAPD */
146
3f5285e8 147
6241fcb1
JM
148/* nl80211 code */
149static int ack_handler(struct nl_msg *msg, void *arg)
150{
151 int *err = arg;
152 *err = 0;
153 return NL_STOP;
154}
155
156static int finish_handler(struct nl_msg *msg, void *arg)
157{
8e8df255
JM
158 int *ret = arg;
159 *ret = 0;
6241fcb1
JM
160 return NL_SKIP;
161}
162
163static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err,
164 void *arg)
165{
166 int *ret = arg;
167 *ret = err->error;
168 return NL_SKIP;
169}
170
5b7b85f6
JM
171
172static int no_seq_check(struct nl_msg *msg, void *arg)
173{
174 return NL_OK;
175}
176
177
6241fcb1
JM
178static int send_and_recv_msgs(struct wpa_driver_nl80211_data *drv,
179 struct nl_msg *msg,
180 int (*valid_handler)(struct nl_msg *, void *),
181 void *valid_data)
182{
183 struct nl_cb *cb;
184 int err = -ENOMEM;
185
186 cb = nl_cb_clone(drv->nl_cb);
187 if (!cb)
188 goto out;
189
190 err = nl_send_auto_complete(drv->nl_handle, msg);
191 if (err < 0)
192 goto out;
193
194 err = 1;
195
196 nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
8e8df255 197 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
6241fcb1
JM
198 nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);
199
200 if (valid_handler)
201 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM,
202 valid_handler, valid_data);
203
204 while (err > 0)
205 nl_recvmsgs(drv->nl_handle, cb);
206 out:
207 nl_cb_put(cb);
208 nlmsg_free(msg);
209 return err;
210}
211
212
97865538
JM
213struct family_data {
214 const char *group;
215 int id;
216};
217
218
219static int family_handler(struct nl_msg *msg, void *arg)
220{
221 struct family_data *res = arg;
222 struct nlattr *tb[CTRL_ATTR_MAX + 1];
223 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
224 struct nlattr *mcgrp;
225 int i;
226
227 nla_parse(tb, CTRL_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
228 genlmsg_attrlen(gnlh, 0), NULL);
229 if (!tb[CTRL_ATTR_MCAST_GROUPS])
230 return NL_SKIP;
231
232 nla_for_each_nested(mcgrp, tb[CTRL_ATTR_MCAST_GROUPS], i) {
233 struct nlattr *tb2[CTRL_ATTR_MCAST_GRP_MAX + 1];
234 nla_parse(tb2, CTRL_ATTR_MCAST_GRP_MAX, nla_data(mcgrp),
235 nla_len(mcgrp), NULL);
236 if (!tb2[CTRL_ATTR_MCAST_GRP_NAME] ||
237 !tb2[CTRL_ATTR_MCAST_GRP_ID] ||
238 os_strncmp(nla_data(tb2[CTRL_ATTR_MCAST_GRP_NAME]),
239 res->group,
240 nla_len(tb2[CTRL_ATTR_MCAST_GRP_NAME])) != 0)
241 continue;
242 res->id = nla_get_u32(tb2[CTRL_ATTR_MCAST_GRP_ID]);
243 break;
244 };
245
246 return NL_SKIP;
247}
248
249
250static int nl_get_multicast_id(struct wpa_driver_nl80211_data *drv,
251 const char *family, const char *group)
252{
253 struct nl_msg *msg;
254 int ret = -1;
255 struct family_data res = { group, -ENOENT };
256
257 msg = nlmsg_alloc();
258 if (!msg)
259 return -ENOMEM;
260 genlmsg_put(msg, 0, 0, genl_ctrl_resolve(drv->nl_handle, "nlctrl"),
261 0, 0, CTRL_CMD_GETFAMILY, 0);
262 NLA_PUT_STRING(msg, CTRL_ATTR_FAMILY_NAME, family);
263
264 ret = send_and_recv_msgs(drv, msg, family_handler, &res);
265 msg = NULL;
266 if (ret == 0)
267 ret = res.id;
268
269nla_put_failure:
270 nlmsg_free(msg);
271 return ret;
272}
273
274
41d931ee
JM
275#ifdef HOSTAPD
276static int get_ifhwaddr(struct wpa_driver_nl80211_data *drv,
277 const char *ifname, u8 *addr)
278{
279 struct ifreq ifr;
280
281 os_memset(&ifr, 0, sizeof(ifr));
282 os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
283 if (ioctl(drv->ioctl_sock, SIOCGIFHWADDR, &ifr)) {
284 wpa_printf(MSG_ERROR, "%s: ioctl(SIOCGIFHWADDR): %d (%s)",
285 ifname, errno, strerror(errno));
286 return -1;
287 }
288
289 if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) {
290 wpa_printf(MSG_ERROR, "%s: Invalid HW-addr family 0x%04x",
291 ifname, ifr.ifr_hwaddr.sa_family);
292 return -1;
293 }
294 os_memcpy(addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
295
296 return 0;
297}
298
299
300static int set_ifhwaddr(struct wpa_driver_nl80211_data *drv,
301 const char *ifname, const u8 *addr)
302{
303 struct ifreq ifr;
304
305 os_memset(&ifr, 0, sizeof(ifr));
306 os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
307 os_memcpy(ifr.ifr_hwaddr.sa_data, addr, ETH_ALEN);
308 ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
309
310 if (ioctl(drv->ioctl_sock, SIOCSIFHWADDR, &ifr)) {
311 wpa_printf(MSG_DEBUG, "%s: ioctl(SIOCSIFHWADDR): %d (%s)",
312 ifname, errno, strerror(errno));
313 return -1;
314 }
315
316 return 0;
317}
318#endif /* HOSTAPD */
319
320
3f5285e8
JM
321static int wpa_driver_nl80211_send_oper_ifla(
322 struct wpa_driver_nl80211_data *drv,
323 int linkmode, int operstate)
324{
325 struct {
326 struct nlmsghdr hdr;
327 struct ifinfomsg ifinfo;
328 char opts[16];
329 } req;
330 struct rtattr *rta;
331 static int nl_seq;
332 ssize_t ret;
333
334 os_memset(&req, 0, sizeof(req));
335
336 req.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
337 req.hdr.nlmsg_type = RTM_SETLINK;
338 req.hdr.nlmsg_flags = NLM_F_REQUEST;
339 req.hdr.nlmsg_seq = ++nl_seq;
340 req.hdr.nlmsg_pid = 0;
341
342 req.ifinfo.ifi_family = AF_UNSPEC;
343 req.ifinfo.ifi_type = 0;
344 req.ifinfo.ifi_index = drv->ifindex;
345 req.ifinfo.ifi_flags = 0;
346 req.ifinfo.ifi_change = 0;
347
348 if (linkmode != -1) {
0ae7b086
JM
349 rta = aliasing_hide_typecast(
350 ((char *) &req + NLMSG_ALIGN(req.hdr.nlmsg_len)),
351 struct rtattr);
3f5285e8
JM
352 rta->rta_type = IFLA_LINKMODE;
353 rta->rta_len = RTA_LENGTH(sizeof(char));
354 *((char *) RTA_DATA(rta)) = linkmode;
355 req.hdr.nlmsg_len = NLMSG_ALIGN(req.hdr.nlmsg_len) +
356 RTA_LENGTH(sizeof(char));
357 }
358 if (operstate != -1) {
c1bb3e0a
JM
359 rta = aliasing_hide_typecast(
360 ((char *) &req + NLMSG_ALIGN(req.hdr.nlmsg_len)),
361 struct rtattr);
3f5285e8
JM
362 rta->rta_type = IFLA_OPERSTATE;
363 rta->rta_len = RTA_LENGTH(sizeof(char));
364 *((char *) RTA_DATA(rta)) = operstate;
365 req.hdr.nlmsg_len = NLMSG_ALIGN(req.hdr.nlmsg_len) +
366 RTA_LENGTH(sizeof(char));
367 }
368
7da3abe7 369 wpa_printf(MSG_DEBUG, "nl80211: Operstate: linkmode=%d, operstate=%d",
3f5285e8
JM
370 linkmode, operstate);
371
d8816397 372 ret = send(drv->link_event_sock, &req, req.hdr.nlmsg_len, 0);
3f5285e8 373 if (ret < 0) {
7da3abe7
JM
374 wpa_printf(MSG_DEBUG, "nl80211: Sending operstate IFLA failed:"
375 " %s (assume operstate is not supported)",
3f5285e8
JM
376 strerror(errno));
377 }
378
379 return ret < 0 ? -1 : 0;
380}
381
382
3f5285e8
JM
383static int wpa_driver_nl80211_get_bssid(void *priv, u8 *bssid)
384{
385 struct wpa_driver_nl80211_data *drv = priv;
c2a04078
JM
386 if (!drv->associated)
387 return -1;
388 os_memcpy(bssid, drv->bssid, ETH_ALEN);
389 return 0;
3f5285e8
JM
390}
391
392
3f5285e8
JM
393static int wpa_driver_nl80211_get_ssid(void *priv, u8 *ssid)
394{
395 struct wpa_driver_nl80211_data *drv = priv;
fd05d64e
JM
396 if (!drv->associated)
397 return -1;
398 os_memcpy(ssid, drv->ssid, drv->ssid_len);
399 return drv->ssid_len;
3f5285e8
JM
400}
401
402
c1bb3e0a
JM
403#ifndef HOSTAPD
404
7524cfb1
JM
405static void wpa_driver_nl80211_event_link(struct wpa_driver_nl80211_data *drv,
406 void *ctx, char *buf, size_t len,
407 int del)
3f5285e8
JM
408{
409 union wpa_event_data event;
410
411 os_memset(&event, 0, sizeof(event));
412 if (len > sizeof(event.interface_status.ifname))
413 len = sizeof(event.interface_status.ifname) - 1;
414 os_memcpy(event.interface_status.ifname, buf, len);
415 event.interface_status.ievent = del ? EVENT_INTERFACE_REMOVED :
416 EVENT_INTERFACE_ADDED;
417
418 wpa_printf(MSG_DEBUG, "RTM_%sLINK, IFLA_IFNAME: Interface '%s' %s",
419 del ? "DEL" : "NEW",
420 event.interface_status.ifname,
421 del ? "removed" : "added");
422
7524cfb1
JM
423 if (os_strcmp(drv->ifname, event.interface_status.ifname) == 0) {
424 if (del)
425 drv->if_removed = 1;
426 else
427 drv->if_removed = 0;
428 }
429
3f5285e8
JM
430 wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &event);
431}
432
433
7524cfb1
JM
434static int wpa_driver_nl80211_own_ifname(struct wpa_driver_nl80211_data *drv,
435 struct nlmsghdr *h)
436{
437 struct ifinfomsg *ifi;
438 int attrlen, _nlmsg_len, rta_len;
439 struct rtattr *attr;
440
441 ifi = NLMSG_DATA(h);
442
443 _nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg));
444
445 attrlen = h->nlmsg_len - _nlmsg_len;
446 if (attrlen < 0)
447 return 0;
448
449 attr = (struct rtattr *) (((char *) ifi) + _nlmsg_len);
450
451 rta_len = RTA_ALIGN(sizeof(struct rtattr));
452 while (RTA_OK(attr, attrlen)) {
453 if (attr->rta_type == IFLA_IFNAME) {
454 if (os_strcmp(((char *) attr) + rta_len, drv->ifname)
455 == 0)
456 return 1;
457 else
458 break;
459 }
460 attr = RTA_NEXT(attr, attrlen);
461 }
462
463 return 0;
464}
465
466
467static int wpa_driver_nl80211_own_ifindex(struct wpa_driver_nl80211_data *drv,
468 int ifindex, struct nlmsghdr *h)
469{
470 if (drv->ifindex == ifindex)
471 return 1;
472
473 if (drv->if_removed && wpa_driver_nl80211_own_ifname(drv, h)) {
474 drv->ifindex = if_nametoindex(drv->ifname);
475 wpa_printf(MSG_DEBUG, "nl80211: Update ifindex for a removed "
476 "interface");
477 wpa_driver_nl80211_finish_drv_init(drv);
478 return 1;
479 }
480
481 return 0;
482}
483
484
3f5285e8
JM
485static void wpa_driver_nl80211_event_rtm_newlink(struct wpa_driver_nl80211_data *drv,
486 void *ctx, struct nlmsghdr *h,
487 size_t len)
488{
489 struct ifinfomsg *ifi;
490 int attrlen, _nlmsg_len, rta_len;
491 struct rtattr * attr;
492
493 if (len < sizeof(*ifi))
494 return;
495
496 ifi = NLMSG_DATA(h);
497
7524cfb1 498 if (!wpa_driver_nl80211_own_ifindex(drv, ifi->ifi_index, h)) {
3f5285e8
JM
499 wpa_printf(MSG_DEBUG, "Ignore event for foreign ifindex %d",
500 ifi->ifi_index);
501 return;
502 }
503
504 wpa_printf(MSG_DEBUG, "RTM_NEWLINK: operstate=%d ifi_flags=0x%x "
505 "(%s%s%s%s)",
506 drv->operstate, ifi->ifi_flags,
507 (ifi->ifi_flags & IFF_UP) ? "[UP]" : "",
508 (ifi->ifi_flags & IFF_RUNNING) ? "[RUNNING]" : "",
509 (ifi->ifi_flags & IFF_LOWER_UP) ? "[LOWER_UP]" : "",
510 (ifi->ifi_flags & IFF_DORMANT) ? "[DORMANT]" : "");
511 /*
512 * Some drivers send the association event before the operup event--in
513 * this case, lifting operstate in wpa_driver_nl80211_set_operstate()
514 * fails. This will hit us when wpa_supplicant does not need to do
515 * IEEE 802.1X authentication
516 */
517 if (drv->operstate == 1 &&
518 (ifi->ifi_flags & (IFF_LOWER_UP | IFF_DORMANT)) == IFF_LOWER_UP &&
519 !(ifi->ifi_flags & IFF_RUNNING))
520 wpa_driver_nl80211_send_oper_ifla(drv, -1, IF_OPER_UP);
521
522 _nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg));
523
524 attrlen = h->nlmsg_len - _nlmsg_len;
525 if (attrlen < 0)
526 return;
527
528 attr = (struct rtattr *) (((char *) ifi) + _nlmsg_len);
529
530 rta_len = RTA_ALIGN(sizeof(struct rtattr));
531 while (RTA_OK(attr, attrlen)) {
d8816397 532 if (attr->rta_type == IFLA_IFNAME) {
7524cfb1
JM
533 wpa_driver_nl80211_event_link(
534 drv, ctx,
535 ((char *) attr) + rta_len,
536 attr->rta_len - rta_len, 0);
3f5285e8
JM
537 }
538 attr = RTA_NEXT(attr, attrlen);
539 }
540}
541
542
543static void wpa_driver_nl80211_event_rtm_dellink(struct wpa_driver_nl80211_data *drv,
544 void *ctx, struct nlmsghdr *h,
545 size_t len)
546{
547 struct ifinfomsg *ifi;
548 int attrlen, _nlmsg_len, rta_len;
549 struct rtattr * attr;
550
551 if (len < sizeof(*ifi))
552 return;
553
554 ifi = NLMSG_DATA(h);
555
556 _nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg));
557
558 attrlen = h->nlmsg_len - _nlmsg_len;
559 if (attrlen < 0)
560 return;
561
562 attr = (struct rtattr *) (((char *) ifi) + _nlmsg_len);
563
564 rta_len = RTA_ALIGN(sizeof(struct rtattr));
565 while (RTA_OK(attr, attrlen)) {
566 if (attr->rta_type == IFLA_IFNAME) {
7524cfb1
JM
567 wpa_driver_nl80211_event_link(
568 drv, ctx,
569 ((char *) attr) + rta_len,
570 attr->rta_len - rta_len, 1);
3f5285e8
JM
571 }
572 attr = RTA_NEXT(attr, attrlen);
573 }
574}
575
576
d8816397 577static void wpa_driver_nl80211_event_receive_link(int sock, void *eloop_ctx,
97865538 578 void *sock_ctx)
3f5285e8
JM
579{
580 char buf[8192];
581 int left;
582 struct sockaddr_nl from;
583 socklen_t fromlen;
584 struct nlmsghdr *h;
585 int max_events = 10;
586
587try_again:
588 fromlen = sizeof(from);
589 left = recvfrom(sock, buf, sizeof(buf), MSG_DONTWAIT,
590 (struct sockaddr *) &from, &fromlen);
591 if (left < 0) {
592 if (errno != EINTR && errno != EAGAIN)
593 perror("recvfrom(netlink)");
594 return;
595 }
596
597 h = (struct nlmsghdr *) buf;
598 while (left >= (int) sizeof(*h)) {
599 int len, plen;
600
601 len = h->nlmsg_len;
602 plen = len - sizeof(*h);
603 if (len > left || plen < 0) {
604 wpa_printf(MSG_DEBUG, "Malformed netlink message: "
605 "len=%d left=%d plen=%d",
606 len, left, plen);
607 break;
608 }
609
610 switch (h->nlmsg_type) {
611 case RTM_NEWLINK:
612 wpa_driver_nl80211_event_rtm_newlink(eloop_ctx, sock_ctx,
613 h, plen);
614 break;
615 case RTM_DELLINK:
616 wpa_driver_nl80211_event_rtm_dellink(eloop_ctx, sock_ctx,
617 h, plen);
618 break;
619 }
620
621 len = NLMSG_ALIGN(len);
622 left -= len;
623 h = (struct nlmsghdr *) ((char *) h + len);
624 }
625
626 if (left > 0) {
627 wpa_printf(MSG_DEBUG, "%d extra bytes in the end of netlink "
628 "message", left);
629 }
630
631 if (--max_events > 0) {
632 /*
633 * Try to receive all events in one eloop call in order to
634 * limit race condition on cases where AssocInfo event, Assoc
635 * event, and EAPOL frames are received more or less at the
636 * same time. We want to process the event messages first
637 * before starting EAPOL processing.
638 */
639 goto try_again;
640 }
641}
642
c1bb3e0a
JM
643#endif /* HOSTAPD */
644
3f5285e8 645
c2a04078
JM
646static void mlme_event_auth(struct wpa_driver_nl80211_data *drv,
647 const u8 *frame, size_t len)
648{
649 const struct ieee80211_mgmt *mgmt;
650 union wpa_event_data event;
651
652 mgmt = (const struct ieee80211_mgmt *) frame;
653 if (len < 24 + sizeof(mgmt->u.auth)) {
654 wpa_printf(MSG_DEBUG, "nl80211: Too short association event "
655 "frame");
656 return;
657 }
658
e6b8efeb 659 os_memcpy(drv->auth_bssid, mgmt->sa, ETH_ALEN);
c2a04078
JM
660 os_memset(&event, 0, sizeof(event));
661 os_memcpy(event.auth.peer, mgmt->sa, ETH_ALEN);
662 event.auth.auth_type = le_to_host16(mgmt->u.auth.auth_alg);
663 event.auth.status_code = le_to_host16(mgmt->u.auth.status_code);
664 if (len > 24 + sizeof(mgmt->u.auth)) {
665 event.auth.ies = mgmt->u.auth.variable;
666 event.auth.ies_len = len - 24 - sizeof(mgmt->u.auth);
667 }
668
669 wpa_supplicant_event(drv->ctx, EVENT_AUTH, &event);
670}
671
672
673static void mlme_event_assoc(struct wpa_driver_nl80211_data *drv,
674 const u8 *frame, size_t len)
675{
676 const struct ieee80211_mgmt *mgmt;
677 union wpa_event_data event;
678 u16 status;
679
680 mgmt = (const struct ieee80211_mgmt *) frame;
681 if (len < 24 + sizeof(mgmt->u.assoc_resp)) {
682 wpa_printf(MSG_DEBUG, "nl80211: Too short association event "
683 "frame");
684 return;
685 }
686
687 status = le_to_host16(mgmt->u.assoc_resp.status_code);
688 if (status != WLAN_STATUS_SUCCESS) {
efa46078
JM
689 os_memset(&event, 0, sizeof(event));
690 if (len > 24 + sizeof(mgmt->u.assoc_resp)) {
691 event.assoc_reject.resp_ies =
692 (u8 *) mgmt->u.assoc_resp.variable;
693 event.assoc_reject.resp_ies_len =
694 len - 24 - sizeof(mgmt->u.assoc_resp);
695 }
696 event.assoc_reject.status_code = status;
697
698 wpa_supplicant_event(drv->ctx, EVENT_ASSOC_REJECT, &event);
c2a04078
JM
699 return;
700 }
701
702 drv->associated = 1;
703 os_memcpy(drv->bssid, mgmt->sa, ETH_ALEN);
704
705 os_memset(&event, 0, sizeof(event));
706 if (len > 24 + sizeof(mgmt->u.assoc_resp)) {
707 event.assoc_info.resp_ies = (u8 *) mgmt->u.assoc_resp.variable;
708 event.assoc_info.resp_ies_len =
efa46078 709 len - 24 - sizeof(mgmt->u.assoc_resp);
c2a04078
JM
710 }
711
712 wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event);
713}
714
c1bb3e0a 715
da72a1c1
ZY
716static void mlme_event_connect(struct wpa_driver_nl80211_data *drv,
717 enum nl80211_commands cmd, struct nlattr *status,
718 struct nlattr *addr, struct nlattr *req_ie,
719 struct nlattr *resp_ie)
720{
721 union wpa_event_data event;
722
7da2c527
JM
723 if (drv->capa.flags & WPA_DRIVER_FLAGS_SME) {
724 /*
725 * Avoid reporting two association events that would confuse
726 * the core code.
727 */
728 wpa_printf(MSG_DEBUG, "nl80211: Ignore connect event (cmd=%d) "
729 "when using userspace SME", cmd);
730 return;
731 }
732
da72a1c1
ZY
733 os_memset(&event, 0, sizeof(event));
734 if (cmd == NL80211_CMD_CONNECT &&
735 nla_get_u16(status) != WLAN_STATUS_SUCCESS) {
736 if (resp_ie) {
737 event.assoc_reject.resp_ies = nla_data(resp_ie);
738 event.assoc_reject.resp_ies_len = nla_len(resp_ie);
739 }
740 event.assoc_reject.status_code = nla_get_u16(status);
741 wpa_supplicant_event(drv->ctx, EVENT_ASSOC_REJECT, &event);
742 return;
743 }
744
745 drv->associated = 1;
746 if (addr)
747 os_memcpy(drv->bssid, nla_data(addr), ETH_ALEN);
748
749 if (req_ie) {
750 event.assoc_info.req_ies = nla_data(req_ie);
751 event.assoc_info.req_ies_len = nla_len(req_ie);
752 }
753 if (resp_ie) {
754 event.assoc_info.resp_ies = nla_data(resp_ie);
755 event.assoc_info.resp_ies_len = nla_len(resp_ie);
756 }
757
758 wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event);
759}
c2a04078 760
c1bb3e0a 761
da1fb17c
JM
762static void mlme_timeout_event(struct wpa_driver_nl80211_data *drv,
763 enum nl80211_commands cmd, struct nlattr *addr)
764{
765 union wpa_event_data event;
766 enum wpa_event_type ev;
767
768 if (nla_len(addr) != ETH_ALEN)
769 return;
770
771 wpa_printf(MSG_DEBUG, "nl80211: MLME event %d; timeout with " MACSTR,
772 cmd, MAC2STR((u8 *) nla_data(addr)));
773
774 if (cmd == NL80211_CMD_AUTHENTICATE)
775 ev = EVENT_AUTH_TIMED_OUT;
776 else if (cmd == NL80211_CMD_ASSOCIATE)
777 ev = EVENT_ASSOC_TIMED_OUT;
778 else
779 return;
780
781 os_memset(&event, 0, sizeof(event));
782 os_memcpy(event.timeout_event.addr, nla_data(addr), ETH_ALEN);
783 wpa_supplicant_event(drv->ctx, ev, &event);
784}
785
786
c2a04078 787static void mlme_event(struct wpa_driver_nl80211_data *drv,
da1fb17c
JM
788 enum nl80211_commands cmd, struct nlattr *frame,
789 struct nlattr *addr, struct nlattr *timed_out)
c2a04078 790{
da1fb17c
JM
791 if (timed_out && addr) {
792 mlme_timeout_event(drv, cmd, addr);
793 return;
794 }
795
c2a04078
JM
796 if (frame == NULL) {
797 wpa_printf(MSG_DEBUG, "nl80211: MLME event %d without frame "
798 "data", cmd);
799 return;
800 }
801
802 wpa_printf(MSG_DEBUG, "nl80211: MLME event %d", cmd);
803 wpa_hexdump(MSG_MSGDUMP, "nl80211: MLME event frame",
804 nla_data(frame), nla_len(frame));
805
806 switch (cmd) {
807 case NL80211_CMD_AUTHENTICATE:
808 mlme_event_auth(drv, nla_data(frame), nla_len(frame));
809 break;
810 case NL80211_CMD_ASSOCIATE:
811 mlme_event_assoc(drv, nla_data(frame), nla_len(frame));
812 break;
813 case NL80211_CMD_DEAUTHENTICATE:
814 drv->associated = 0;
815 wpa_supplicant_event(drv->ctx, EVENT_DEAUTH, NULL);
816 break;
817 case NL80211_CMD_DISASSOCIATE:
818 drv->associated = 0;
819 wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL);
820 break;
821 default:
822 break;
823 }
824}
825
826
35583f3f
JM
827static void mlme_event_michael_mic_failure(struct wpa_driver_nl80211_data *drv,
828 struct nlattr *tb[])
829{
830 union wpa_event_data data;
831
832 wpa_printf(MSG_DEBUG, "nl80211: MLME event Michael MIC failure");
833 os_memset(&data, 0, sizeof(data));
834 if (tb[NL80211_ATTR_MAC]) {
835 wpa_hexdump(MSG_DEBUG, "nl80211: Source MAC address",
836 nla_data(tb[NL80211_ATTR_MAC]),
837 nla_len(tb[NL80211_ATTR_MAC]));
ad1e68e6 838 data.michael_mic_failure.src = nla_data(tb[NL80211_ATTR_MAC]);
35583f3f
JM
839 }
840 if (tb[NL80211_ATTR_KEY_SEQ]) {
841 wpa_hexdump(MSG_DEBUG, "nl80211: TSC",
842 nla_data(tb[NL80211_ATTR_KEY_SEQ]),
843 nla_len(tb[NL80211_ATTR_KEY_SEQ]));
844 }
845 if (tb[NL80211_ATTR_KEY_TYPE]) {
846 enum nl80211_key_type key_type =
847 nla_get_u32(tb[NL80211_ATTR_KEY_TYPE]);
848 wpa_printf(MSG_DEBUG, "nl80211: Key Type %d", key_type);
849 if (key_type == NL80211_KEYTYPE_PAIRWISE)
850 data.michael_mic_failure.unicast = 1;
851 } else
852 data.michael_mic_failure.unicast = 1;
853
854 if (tb[NL80211_ATTR_KEY_IDX]) {
855 u8 key_id = nla_get_u8(tb[NL80211_ATTR_KEY_IDX]);
856 wpa_printf(MSG_DEBUG, "nl80211: Key Id %d", key_id);
857 }
858
859 wpa_supplicant_event(drv->ctx, EVENT_MICHAEL_MIC_FAILURE, &data);
860}
861
862
5cc4d64b
JM
863static void mlme_event_join_ibss(struct wpa_driver_nl80211_data *drv,
864 struct nlattr *tb[])
865{
866 if (tb[NL80211_ATTR_MAC] == NULL) {
867 wpa_printf(MSG_DEBUG, "nl80211: No address in IBSS joined "
868 "event");
869 return;
870 }
871 os_memcpy(drv->bssid, nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
872 drv->associated = 1;
873 wpa_printf(MSG_DEBUG, "nl80211: IBSS " MACSTR " joined",
874 MAC2STR(drv->bssid));
875
876 wpa_supplicant_event(drv->ctx, EVENT_ASSOC, NULL);
877}
878
879
97865538
JM
880static int process_event(struct nl_msg *msg, void *arg)
881{
882 struct wpa_driver_nl80211_data *drv = arg;
883 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
884 struct nlattr *tb[NL80211_ATTR_MAX + 1];
885
886 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
887 genlmsg_attrlen(gnlh, 0), NULL);
888
889 if (tb[NL80211_ATTR_IFINDEX]) {
890 int ifindex = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
891 if (ifindex != drv->ifindex) {
892 wpa_printf(MSG_DEBUG, "nl80211: Ignored event (cmd=%d)"
893 " for foreign interface (ifindex %d)",
894 gnlh->cmd, ifindex);
895 return NL_SKIP;
896 }
897 }
898
ad1e68e6
JM
899 if (drv->ap_scan_as_station &&
900 (gnlh->cmd == NL80211_CMD_NEW_SCAN_RESULTS ||
901 gnlh->cmd == NL80211_CMD_SCAN_ABORTED)) {
902 wpa_driver_nl80211_set_mode(drv, IEEE80211_MODE_AP);
903 drv->ap_scan_as_station = 0;
904 }
905
97865538 906 switch (gnlh->cmd) {
d942a79e
JM
907 case NL80211_CMD_TRIGGER_SCAN:
908 wpa_printf(MSG_DEBUG, "nl80211: Scan trigger");
909 break;
97865538
JM
910 case NL80211_CMD_NEW_SCAN_RESULTS:
911 wpa_printf(MSG_DEBUG, "nl80211: New scan results available");
912 drv->scan_complete_events = 1;
913 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv,
914 drv->ctx);
915 wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS, NULL);
916 break;
917 case NL80211_CMD_SCAN_ABORTED:
918 wpa_printf(MSG_DEBUG, "nl80211: Scan aborted");
919 /*
920 * Need to indicate that scan results are available in order
921 * not to make wpa_supplicant stop its scanning.
922 */
923 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv,
924 drv->ctx);
925 wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS, NULL);
926 break;
c2a04078
JM
927 case NL80211_CMD_AUTHENTICATE:
928 case NL80211_CMD_ASSOCIATE:
929 case NL80211_CMD_DEAUTHENTICATE:
930 case NL80211_CMD_DISASSOCIATE:
da1fb17c
JM
931 mlme_event(drv, gnlh->cmd, tb[NL80211_ATTR_FRAME],
932 tb[NL80211_ATTR_MAC], tb[NL80211_ATTR_TIMED_OUT]);
c2a04078 933 break;
da72a1c1
ZY
934 case NL80211_CMD_CONNECT:
935 case NL80211_CMD_ROAM:
936 mlme_event_connect(drv, gnlh->cmd,
937 tb[NL80211_ATTR_STATUS_CODE],
938 tb[NL80211_ATTR_MAC],
939 tb[NL80211_ATTR_REQ_IE],
940 tb[NL80211_ATTR_RESP_IE]);
941 break;
942 case NL80211_CMD_DISCONNECT:
7da2c527
JM
943 if (drv->capa.flags & WPA_DRIVER_FLAGS_SME) {
944 /*
945 * Avoid reporting two disassociation events that could
946 * confuse the core code.
947 */
948 wpa_printf(MSG_DEBUG, "nl80211: Ignore disconnect "
949 "event when using userspace SME");
950 break;
951 }
da72a1c1
ZY
952 drv->associated = 0;
953 wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL);
954 break;
35583f3f
JM
955 case NL80211_CMD_MICHAEL_MIC_FAILURE:
956 mlme_event_michael_mic_failure(drv, tb);
957 break;
5cc4d64b
JM
958 case NL80211_CMD_JOIN_IBSS:
959 mlme_event_join_ibss(drv, tb);
960 break;
97865538 961 default:
c2a04078
JM
962 wpa_printf(MSG_DEBUG, "nl80211: Ignored unknown event "
963 "(cmd=%d)", gnlh->cmd);
97865538
JM
964 break;
965 }
966
967 return NL_SKIP;
968}
969
970
971static void wpa_driver_nl80211_event_receive(int sock, void *eloop_ctx,
972 void *sock_ctx)
973{
974 struct nl_cb *cb;
975 struct wpa_driver_nl80211_data *drv = eloop_ctx;
976
977 wpa_printf(MSG_DEBUG, "nl80211: Event message available");
978
979 cb = nl_cb_clone(drv->nl_cb);
980 if (!cb)
981 return;
982 nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL);
983 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, process_event, drv);
335ce76b 984 nl_recvmsgs(drv->nl_handle_event, cb);
97865538
JM
985 nl_cb_put(cb);
986}
987
988
2135f224
JM
989static int hostapd_set_iface_flags(struct wpa_driver_nl80211_data *drv,
990 const char *ifname, int dev_up)
3f5285e8
JM
991{
992 struct ifreq ifr;
993
2135f224
JM
994 if (drv->ioctl_sock < 0)
995 return -1;
996
3f5285e8
JM
997 os_memset(&ifr, 0, sizeof(ifr));
998 os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
2135f224
JM
999
1000 if (ioctl(drv->ioctl_sock, SIOCGIFFLAGS, &ifr) != 0) {
3f5285e8 1001 perror("ioctl[SIOCGIFFLAGS]");
2135f224
JM
1002 wpa_printf(MSG_DEBUG, "Could not read interface flags (%s)",
1003 ifname);
3f5285e8
JM
1004 return -1;
1005 }
3f5285e8 1006
2135f224
JM
1007 if (dev_up) {
1008 if (ifr.ifr_flags & IFF_UP)
1009 return 0;
1010 ifr.ifr_flags |= IFF_UP;
1011 } else {
1012 if (!(ifr.ifr_flags & IFF_UP))
1013 return 0;
1014 ifr.ifr_flags &= ~IFF_UP;
1015 }
3f5285e8 1016
2135f224
JM
1017 if (ioctl(drv->ioctl_sock, SIOCSIFFLAGS, &ifr) != 0) {
1018 perror("ioctl[SIOCSIFFLAGS]");
3f5285e8
JM
1019 return -1;
1020 }
3f5285e8 1021
2135f224 1022 return 0;
3f5285e8
JM
1023}
1024
1025
6d158490
LR
1026/**
1027 * wpa_driver_nl80211_set_country - ask nl80211 to set the regulatory domain
1028 * @priv: driver_nl80211 private data
1029 * @alpha2_arg: country to which to switch to
1030 * Returns: 0 on success, -1 on failure
1031 *
1032 * This asks nl80211 to set the regulatory domain for given
1033 * country ISO / IEC alpha2.
1034 */
1035static int wpa_driver_nl80211_set_country(void *priv, const char *alpha2_arg)
1036{
1037 struct wpa_driver_nl80211_data *drv = priv;
1038 char alpha2[3];
1039 struct nl_msg *msg;
1040
1041 msg = nlmsg_alloc();
1042 if (!msg)
e785c2ba 1043 return -ENOMEM;
6d158490
LR
1044
1045 alpha2[0] = alpha2_arg[0];
1046 alpha2[1] = alpha2_arg[1];
1047 alpha2[2] = '\0';
1048
1049 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
1050 0, NL80211_CMD_REQ_SET_REG, 0);
1051
1052 NLA_PUT_STRING(msg, NL80211_ATTR_REG_ALPHA2, alpha2);
1053 if (send_and_recv_msgs(drv, msg, NULL, NULL))
1054 return -EINVAL;
1055 return 0;
1056nla_put_failure:
1057 return -EINVAL;
1058}
1059
1060
bbaf0837 1061#ifndef HOSTAPD
80bc75f1
JM
1062struct wiphy_info_data {
1063 int max_scan_ssids;
1581b38b 1064 int ap_supported;
93d11400
ZY
1065 int auth_supported;
1066 int connect_supported;
80bc75f1
JM
1067};
1068
1069
1070static int wiphy_info_handler(struct nl_msg *msg, void *arg)
1071{
1072 struct nlattr *tb[NL80211_ATTR_MAX + 1];
1073 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
1074 struct wiphy_info_data *info = arg;
1075
1076 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
1077 genlmsg_attrlen(gnlh, 0), NULL);
1078
1079 if (tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS])
1080 info->max_scan_ssids =
1081 nla_get_u8(tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS]);
1082
1581b38b
JM
1083 if (tb[NL80211_ATTR_SUPPORTED_IFTYPES]) {
1084 struct nlattr *nl_mode;
1085 int i;
1086 nla_for_each_nested(nl_mode,
1087 tb[NL80211_ATTR_SUPPORTED_IFTYPES], i) {
1088 if (nl_mode->nla_type == NL80211_IFTYPE_AP) {
1089 info->ap_supported = 1;
1090 break;
1091 }
1092 }
1093 }
1094
93d11400
ZY
1095 if (tb[NL80211_ATTR_SUPPORTED_COMMANDS]) {
1096 struct nlattr *nl_cmd;
1097 int i;
1098
1099 nla_for_each_nested(nl_cmd,
1100 tb[NL80211_ATTR_SUPPORTED_COMMANDS], i) {
1101 u32 cmd = nla_get_u32(nl_cmd);
1102 if (cmd == NL80211_CMD_AUTHENTICATE)
1103 info->auth_supported = 1;
1104 else if (cmd == NL80211_CMD_CONNECT)
1105 info->connect_supported = 1;
1106 }
1107 }
1108
80bc75f1
JM
1109 return NL_SKIP;
1110}
1111
1112
1113static int wpa_driver_nl80211_get_info(struct wpa_driver_nl80211_data *drv,
1114 struct wiphy_info_data *info)
1115{
1116 struct nl_msg *msg;
1117
1118 os_memset(info, 0, sizeof(*info));
1119 msg = nlmsg_alloc();
1120 if (!msg)
1121 return -1;
1122
1123 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
1124 0, NL80211_CMD_GET_WIPHY, 0);
1125
1126 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
1127
1128 if (send_and_recv_msgs(drv, msg, wiphy_info_handler, info) == 0)
1129 return 0;
1130 msg = NULL;
1131nla_put_failure:
1132 nlmsg_free(msg);
1133 return -1;
1134}
1135
1136
93d11400 1137static int wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv)
80bc75f1
JM
1138{
1139 struct wiphy_info_data info;
1140 if (wpa_driver_nl80211_get_info(drv, &info))
93d11400 1141 return -1;
80bc75f1 1142 drv->has_capability = 1;
1b2a72e8
JM
1143 /* For now, assume TKIP, CCMP, WPA, WPA2 are supported */
1144 drv->capa.key_mgmt = WPA_DRIVER_CAPA_KEY_MGMT_WPA |
1145 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
1146 WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
1147 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK;
1148 drv->capa.enc = WPA_DRIVER_CAPA_ENC_WEP40 |
1149 WPA_DRIVER_CAPA_ENC_WEP104 |
1150 WPA_DRIVER_CAPA_ENC_TKIP |
1151 WPA_DRIVER_CAPA_ENC_CCMP;
1152
80bc75f1 1153 drv->capa.max_scan_ssids = info.max_scan_ssids;
1581b38b
JM
1154 if (info.ap_supported)
1155 drv->capa.flags |= WPA_DRIVER_FLAGS_AP;
93d11400
ZY
1156
1157 if (info.auth_supported)
1158 drv->capa.flags |= WPA_DRIVER_FLAGS_SME;
1159 else if (!info.connect_supported) {
1160 wpa_printf(MSG_INFO, "nl80211: Driver does not support "
1161 "authentication/association or connect commands");
1162 return -1;
1163 }
1164
0194fedb
JB
1165 drv->capa.flags |= WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC_DONE;
1166
93d11400 1167 return 0;
80bc75f1 1168}
bbaf0837 1169#endif /* HOSTAPD */
80bc75f1
JM
1170
1171
9fff9fdc
JM
1172static int wpa_driver_nl80211_init_nl(struct wpa_driver_nl80211_data *drv,
1173 void *ctx)
3f5285e8 1174{
9fff9fdc 1175 int ret;
3f5285e8 1176
9fff9fdc 1177 /* Initialize generic netlink and nl80211 */
3f5285e8
JM
1178
1179 drv->nl_cb = nl_cb_alloc(NL_CB_DEFAULT);
1180 if (drv->nl_cb == NULL) {
1181 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate netlink "
1182 "callbacks");
1183 goto err1;
1184 }
1185
1186 drv->nl_handle = nl_handle_alloc_cb(drv->nl_cb);
1187 if (drv->nl_handle == NULL) {
1188 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate netlink "
1189 "callbacks");
1190 goto err2;
1191 }
1192
335ce76b
JM
1193 drv->nl_handle_event = nl_handle_alloc_cb(drv->nl_cb);
1194 if (drv->nl_handle_event == NULL) {
1195 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate netlink "
1196 "callbacks (event)");
1197 goto err2b;
1198 }
1199
3f5285e8
JM
1200 if (genl_connect(drv->nl_handle)) {
1201 wpa_printf(MSG_ERROR, "nl80211: Failed to connect to generic "
1202 "netlink");
1203 goto err3;
1204 }
1205
335ce76b
JM
1206 if (genl_connect(drv->nl_handle_event)) {
1207 wpa_printf(MSG_ERROR, "nl80211: Failed to connect to generic "
1208 "netlink (event)");
1209 goto err3;
1210 }
1211
9fff9fdc
JM
1212#ifdef CONFIG_LIBNL20
1213 if (genl_ctrl_alloc_cache(drv->nl_handle, &drv->nl_cache) < 0) {
1214 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate generic "
1215 "netlink cache");
1216 goto err3;
1217 }
335ce76b
JM
1218 if (genl_ctrl_alloc_cache(drv->nl_handle_event, &drv->nl_cache_event) <
1219 0) {
1220 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate generic "
1221 "netlink cache (event)");
1222 goto err3b;
1223 }
9fff9fdc 1224#else /* CONFIG_LIBNL20 */
3f5285e8
JM
1225 drv->nl_cache = genl_ctrl_alloc_cache(drv->nl_handle);
1226 if (drv->nl_cache == NULL) {
1227 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate generic "
1228 "netlink cache");
1229 goto err3;
1230 }
335ce76b
JM
1231 drv->nl_cache_event = genl_ctrl_alloc_cache(drv->nl_handle_event);
1232 if (drv->nl_cache_event == NULL) {
1233 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate generic "
1234 "netlink cache (event)");
1235 goto err3b;
1236 }
9fff9fdc
JM
1237#endif /* CONFIG_LIBNL20 */
1238
3f5285e8
JM
1239 drv->nl80211 = genl_ctrl_search_by_name(drv->nl_cache, "nl80211");
1240 if (drv->nl80211 == NULL) {
1241 wpa_printf(MSG_ERROR, "nl80211: 'nl80211' generic netlink not "
1242 "found");
1243 goto err4;
1244 }
1245
97865538
JM
1246 ret = nl_get_multicast_id(drv, "nl80211", "scan");
1247 if (ret >= 0)
335ce76b 1248 ret = nl_socket_add_membership(drv->nl_handle_event, ret);
97865538
JM
1249 if (ret < 0) {
1250 wpa_printf(MSG_ERROR, "nl80211: Could not add multicast "
1251 "membership for scan events: %d (%s)",
1252 ret, strerror(-ret));
1253 goto err4;
1254 }
c2a04078
JM
1255
1256 ret = nl_get_multicast_id(drv, "nl80211", "mlme");
1257 if (ret >= 0)
335ce76b 1258 ret = nl_socket_add_membership(drv->nl_handle_event, ret);
c2a04078
JM
1259 if (ret < 0) {
1260 wpa_printf(MSG_ERROR, "nl80211: Could not add multicast "
1261 "membership for mlme events: %d (%s)",
1262 ret, strerror(-ret));
1263 goto err4;
1264 }
c2a04078 1265
335ce76b 1266 eloop_register_read_sock(nl_socket_get_fd(drv->nl_handle_event),
97865538
JM
1267 wpa_driver_nl80211_event_receive, drv, ctx);
1268
9fff9fdc
JM
1269 return 0;
1270
1271err4:
335ce76b
JM
1272 nl_cache_free(drv->nl_cache_event);
1273err3b:
9fff9fdc
JM
1274 nl_cache_free(drv->nl_cache);
1275err3:
335ce76b
JM
1276 nl_handle_destroy(drv->nl_handle_event);
1277err2b:
9fff9fdc
JM
1278 nl_handle_destroy(drv->nl_handle);
1279err2:
1280 nl_cb_put(drv->nl_cb);
1281err1:
1282 return -1;
1283}
1284
1285
bbaf0837
JM
1286static int wpa_driver_nl80211_init_link_events(
1287 struct wpa_driver_nl80211_data *drv)
1288{
1289#ifdef HOSTAPD
1290 return 0;
1291#else /* HOSTAPD */
1292 int s;
1293 struct sockaddr_nl local;
1294
1295 s = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
1296 if (s < 0) {
1297 perror("socket(PF_NETLINK,SOCK_RAW,NETLINK_ROUTE)");
7af376e4 1298 return -1;
bbaf0837
JM
1299 }
1300
1301 os_memset(&local, 0, sizeof(local));
1302 local.nl_family = AF_NETLINK;
1303 local.nl_groups = RTMGRP_LINK;
1304 if (bind(s, (struct sockaddr *) &local, sizeof(local)) < 0) {
1305 perror("bind(netlink)");
1306 close(s);
1307 return -1;
1308 }
1309
1310 eloop_register_read_sock(s, wpa_driver_nl80211_event_receive_link, drv,
7af376e4 1311 drv->ctx);
bbaf0837
JM
1312 drv->link_event_sock = s;
1313
1314 return 0;
1315#endif /* HOSTAPD */
1316}
1317
1318
9fff9fdc
JM
1319/**
1320 * wpa_driver_nl80211_init - Initialize nl80211 driver interface
1321 * @ctx: context to be used when calling wpa_supplicant functions,
1322 * e.g., wpa_supplicant_event()
1323 * @ifname: interface name, e.g., wlan0
1324 * Returns: Pointer to private data, %NULL on failure
1325 */
1326static void * wpa_driver_nl80211_init(void *ctx, const char *ifname)
1327{
9fff9fdc
JM
1328 struct wpa_driver_nl80211_data *drv;
1329
1330 drv = os_zalloc(sizeof(*drv));
1331 if (drv == NULL)
1332 return NULL;
1333 drv->ctx = ctx;
1334 os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname));
9fff9fdc
JM
1335 drv->monitor_ifidx = -1;
1336 drv->monitor_sock = -1;
bbaf0837
JM
1337 drv->link_event_sock = -1;
1338 drv->ioctl_sock = -1;
9fff9fdc 1339
bbaf0837
JM
1340 if (wpa_driver_nl80211_init_nl(drv, ctx)) {
1341 os_free(drv);
1342 return NULL;
1343 }
9fff9fdc 1344
3f5285e8
JM
1345 drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
1346 if (drv->ioctl_sock < 0) {
1347 perror("socket(PF_INET,SOCK_DGRAM)");
bbaf0837 1348 goto failed;
3f5285e8
JM
1349 }
1350
bbaf0837
JM
1351 if (wpa_driver_nl80211_init_link_events(drv) ||
1352 wpa_driver_nl80211_finish_drv_init(drv))
1353 goto failed;
7524cfb1
JM
1354
1355 return drv;
1356
bbaf0837
JM
1357failed:
1358 if (drv->link_event_sock >= 0) {
1359 eloop_unregister_read_sock(drv->link_event_sock);
1360 close(drv->link_event_sock);
1361 }
1362 if (drv->ioctl_sock >= 0)
1363 close(drv->ioctl_sock);
1364
7524cfb1 1365 genl_family_put(drv->nl80211);
7524cfb1 1366 nl_cache_free(drv->nl_cache);
7524cfb1 1367 nl_handle_destroy(drv->nl_handle);
7524cfb1 1368 nl_cb_put(drv->nl_cb);
bbaf0837 1369
7524cfb1
JM
1370 os_free(drv);
1371 return NULL;
1372}
1373
1374
362f781e 1375static int
7524cfb1
JM
1376wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv)
1377{
a87c9d96
JM
1378 drv->ifindex = if_nametoindex(drv->ifname);
1379
bbaf0837 1380#ifndef HOSTAPD
ad1e68e6 1381 if (wpa_driver_nl80211_set_mode(drv, IEEE80211_MODE_INFRA) < 0) {
a87c9d96
JM
1382 wpa_printf(MSG_DEBUG, "nl80211: Could not configure driver to "
1383 "use managed mode");
1384 }
1385
2135f224
JM
1386 if (hostapd_set_iface_flags(drv, drv->ifname, 1)) {
1387 wpa_printf(MSG_ERROR, "Could not set interface '%s' "
1388 "UP", drv->ifname);
362f781e
JM
1389 return -1;
1390 }
3f5285e8 1391
93d11400
ZY
1392 if (wpa_driver_nl80211_capa(drv))
1393 return -1;
80bc75f1 1394
3f5285e8 1395 wpa_driver_nl80211_send_oper_ifla(drv, 1, IF_OPER_DORMANT);
bbaf0837 1396#endif /* HOSTAPD */
362f781e
JM
1397
1398 return 0;
3f5285e8
JM
1399}
1400
1401
bbaf0837
JM
1402#ifdef HOSTAPD
1403static void wpa_driver_nl80211_free_bss(struct wpa_driver_nl80211_data *drv)
1404{
1405 struct i802_bss *bss, *prev;
1406 bss = drv->bss.next;
1407 while (bss) {
1408 prev = bss;
1409 bss = bss->next;
1410 os_free(bss);
1411 }
1412}
1413#endif /* HOSTAPD */
1414
1415
8a27af5c
JM
1416#if defined(CONFIG_AP) || defined(HOSTAPD)
1417static int wpa_driver_nl80211_del_beacon(struct wpa_driver_nl80211_data *drv)
1418{
1419 struct nl_msg *msg;
1420
1421 msg = nlmsg_alloc();
1422 if (!msg)
1423 return -ENOMEM;
1424
1425 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
1426 0, NL80211_CMD_DEL_BEACON, 0);
1427 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
1428
1429 return send_and_recv_msgs(drv, msg, NULL, NULL);
1430 nla_put_failure:
1431 return -ENOBUFS;
1432}
1433#endif /* CONFIG_AP || HOSTAPD */
1434
1435
3f5285e8 1436/**
7e5ba1b9
JM
1437 * wpa_driver_nl80211_deinit - Deinitialize nl80211 driver interface
1438 * @priv: Pointer to private nl80211 data from wpa_driver_nl80211_init()
3f5285e8
JM
1439 *
1440 * Shut down driver interface and processing of driver events. Free
1441 * private data buffer if one was allocated in wpa_driver_nl80211_init().
1442 */
7e5ba1b9 1443static void wpa_driver_nl80211_deinit(void *priv)
3f5285e8
JM
1444{
1445 struct wpa_driver_nl80211_data *drv = priv;
3f5285e8 1446
bbaf0837 1447#if defined(CONFIG_AP) || defined(HOSTAPD)
460456f8 1448 nl80211_remove_monitor_interface(drv);
0915d02c
JM
1449 if (drv->monitor_sock >= 0) {
1450 eloop_unregister_read_sock(drv->monitor_sock);
1451 close(drv->monitor_sock);
1452 }
8a27af5c
JM
1453
1454 if (drv->nlmode == NL80211_IFTYPE_AP)
1455 wpa_driver_nl80211_del_beacon(drv);
bbaf0837 1456#endif /* CONFIG_AP || HOSTAPD */
0915d02c 1457
bbaf0837
JM
1458#ifdef HOSTAPD
1459 if (drv->last_freq_ht) {
1460 /* Clear HT flags from the driver */
1461 struct hostapd_freq_params freq;
1462 os_memset(&freq, 0, sizeof(freq));
1463 freq.freq = drv->last_freq;
1464 i802_set_freq(priv, &freq);
1465 }
1466
bbaf0837
JM
1467 if (drv->eapol_sock >= 0) {
1468 eloop_unregister_read_sock(drv->eapol_sock);
1469 close(drv->eapol_sock);
1470 }
1471
1472 if (drv->if_indices != drv->default_if_indices)
1473 os_free(drv->if_indices);
1474
1475 wpa_driver_nl80211_free_bss(drv);
1476#else /* HOSTAPD */
3f5285e8
JM
1477
1478 wpa_driver_nl80211_send_oper_ifla(priv, 0, IF_OPER_UP);
1479
bbaf0837
JM
1480 if (drv->link_event_sock >= 0) {
1481 eloop_unregister_read_sock(drv->link_event_sock);
1482 close(drv->link_event_sock);
1483 }
1484#endif /* HOSTAPD */
3f5285e8 1485
bbaf0837
JM
1486 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);
1487
1488 (void) hostapd_set_iface_flags(drv, drv->ifname, 0);
ad1e68e6 1489 wpa_driver_nl80211_set_mode(drv, IEEE80211_MODE_INFRA);
3f5285e8 1490
bbaf0837
JM
1491 if (drv->ioctl_sock >= 0)
1492 close(drv->ioctl_sock);
3f5285e8 1493
335ce76b 1494 eloop_unregister_read_sock(nl_socket_get_fd(drv->nl_handle_event));
3f5285e8
JM
1495 genl_family_put(drv->nl80211);
1496 nl_cache_free(drv->nl_cache);
335ce76b 1497 nl_cache_free(drv->nl_cache_event);
3f5285e8 1498 nl_handle_destroy(drv->nl_handle);
335ce76b 1499 nl_handle_destroy(drv->nl_handle_event);
3f5285e8
JM
1500 nl_cb_put(drv->nl_cb);
1501
1502 os_free(drv);
1503}
1504
1505
1506/**
1507 * wpa_driver_nl80211_scan_timeout - Scan timeout to report scan completion
ad1e68e6 1508 * @eloop_ctx: Driver private data
3f5285e8
JM
1509 * @timeout_ctx: ctx argument given to wpa_driver_nl80211_init()
1510 *
1511 * This function can be used as registered timeout when starting a scan to
1512 * generate a scan completed event if the driver does not report this.
1513 */
1514static void wpa_driver_nl80211_scan_timeout(void *eloop_ctx, void *timeout_ctx)
1515{
ad1e68e6
JM
1516 struct wpa_driver_nl80211_data *drv = eloop_ctx;
1517 if (drv->ap_scan_as_station) {
1518 wpa_driver_nl80211_set_mode(drv, IEEE80211_MODE_AP);
1519 drv->ap_scan_as_station = 0;
1520 }
3f5285e8
JM
1521 wpa_printf(MSG_DEBUG, "Scan timeout - try to get results");
1522 wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL);
1523}
1524
1525
1526/**
1527 * wpa_driver_nl80211_scan - Request the driver to initiate scan
ad1e68e6 1528 * @priv: Pointer to private driver data from wpa_driver_nl80211_init()
6a1063e0 1529 * @params: Scan parameters
3f5285e8
JM
1530 * Returns: 0 on success, -1 on failure
1531 */
6a1063e0
JM
1532static int wpa_driver_nl80211_scan(void *priv,
1533 struct wpa_driver_scan_params *params)
3f5285e8
JM
1534{
1535 struct wpa_driver_nl80211_data *drv = priv;
3f5285e8 1536 int ret = 0, timeout;
d3a98225 1537 struct nl_msg *msg, *ssids, *freqs;
6a1063e0 1538 size_t i;
3f5285e8 1539
0e75527f
JM
1540 msg = nlmsg_alloc();
1541 ssids = nlmsg_alloc();
d3a98225
JM
1542 freqs = nlmsg_alloc();
1543 if (!msg || !ssids || !freqs) {
0e75527f
JM
1544 nlmsg_free(msg);
1545 nlmsg_free(ssids);
d3a98225 1546 nlmsg_free(freqs);
3f5285e8
JM
1547 return -1;
1548 }
1549
0e75527f
JM
1550 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
1551 NL80211_CMD_TRIGGER_SCAN, 0);
1552
1553 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
3f5285e8 1554
6a1063e0
JM
1555 for (i = 0; i < params->num_ssids; i++) {
1556 NLA_PUT(ssids, i + 1, params->ssids[i].ssid_len,
1557 params->ssids[i].ssid);
3f5285e8 1558 }
6a1063e0
JM
1559 if (params->num_ssids)
1560 nla_put_nested(msg, NL80211_ATTR_SCAN_SSIDS, ssids);
3f5285e8 1561
d173df52
JM
1562 if (params->extra_ies) {
1563 NLA_PUT(msg, NL80211_ATTR_IE, params->extra_ies_len,
1564 params->extra_ies);
1565 }
1566
d3a98225
JM
1567 if (params->freqs) {
1568 for (i = 0; params->freqs[i]; i++)
1569 NLA_PUT_U32(freqs, i + 1, params->freqs[i]);
1570 nla_put_nested(msg, NL80211_ATTR_SCAN_FREQUENCIES, freqs);
1571 }
1572
0e75527f
JM
1573 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
1574 msg = NULL;
1575 if (ret) {
1576 wpa_printf(MSG_DEBUG, "nl80211: Scan trigger failed: ret=%d "
1577 "(%s)", ret, strerror(-ret));
ad1e68e6
JM
1578#ifdef HOSTAPD
1579 if (drv->nlmode == NL80211_IFTYPE_AP) {
1580 /*
1581 * mac80211 does not allow scan requests in AP mode, so
1582 * try to do this in station mode.
1583 */
1584 if (wpa_driver_nl80211_set_mode(drv,
1585 IEEE80211_MODE_INFRA))
1586 goto nla_put_failure;
1587
1588 if (wpa_driver_nl80211_scan(drv, params)) {
1589 wpa_driver_nl80211_set_mode(drv,
1590 IEEE80211_MODE_AP);
1591 goto nla_put_failure;
1592 }
1593
1594 /* Restore AP mode when processing scan results */
1595 drv->ap_scan_as_station = 1;
1596 ret = 0;
1597 } else
1598 goto nla_put_failure;
1599#else /* HOSTAPD */
0e75527f 1600 goto nla_put_failure;
ad1e68e6 1601#endif /* HOSTAPD */
3f5285e8
JM
1602 }
1603
1604 /* Not all drivers generate "scan completed" wireless event, so try to
1605 * read results after a timeout. */
0e75527f 1606 timeout = 10;
3f5285e8
JM
1607 if (drv->scan_complete_events) {
1608 /*
d173df52
JM
1609 * The driver seems to deliver events to notify when scan is
1610 * complete, so use longer timeout to avoid race conditions
1611 * with scanning and following association request.
3f5285e8
JM
1612 */
1613 timeout = 30;
1614 }
1615 wpa_printf(MSG_DEBUG, "Scan requested (ret=%d) - scan timeout %d "
1616 "seconds", ret, timeout);
1617 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);
0e75527f
JM
1618 eloop_register_timeout(timeout, 0, wpa_driver_nl80211_scan_timeout,
1619 drv, drv->ctx);
3f5285e8 1620
0e75527f
JM
1621nla_put_failure:
1622 nlmsg_free(ssids);
1623 nlmsg_free(msg);
d3a98225 1624 nlmsg_free(freqs);
3f5285e8
JM
1625 return ret;
1626}
1627
1628
b3db1e1c 1629static int bss_info_handler(struct nl_msg *msg, void *arg)
3f5285e8 1630{
b3db1e1c
JM
1631 struct nlattr *tb[NL80211_ATTR_MAX + 1];
1632 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
1633 struct nlattr *bss[NL80211_BSS_MAX + 1];
1634 static struct nla_policy bss_policy[NL80211_BSS_MAX + 1] = {
1635 [NL80211_BSS_BSSID] = { .type = NLA_UNSPEC },
1636 [NL80211_BSS_FREQUENCY] = { .type = NLA_U32 },
1637 [NL80211_BSS_TSF] = { .type = NLA_U64 },
1638 [NL80211_BSS_BEACON_INTERVAL] = { .type = NLA_U16 },
1639 [NL80211_BSS_CAPABILITY] = { .type = NLA_U16 },
1640 [NL80211_BSS_INFORMATION_ELEMENTS] = { .type = NLA_UNSPEC },
1641 [NL80211_BSS_SIGNAL_MBM] = { .type = NLA_U32 },
1642 [NL80211_BSS_SIGNAL_UNSPEC] = { .type = NLA_U8 },
e6b8efeb 1643 [NL80211_BSS_STATUS] = { .type = NLA_U32 },
b3ad11bb 1644 [NL80211_BSS_SEEN_MS_AGO] = { .type = NLA_U32 },
b3db1e1c
JM
1645 };
1646 struct wpa_scan_results *res = arg;
3f5285e8
JM
1647 struct wpa_scan_res **tmp;
1648 struct wpa_scan_res *r;
b3db1e1c
JM
1649 const u8 *ie;
1650 size_t ie_len;
3f5285e8 1651
b3db1e1c
JM
1652 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
1653 genlmsg_attrlen(gnlh, 0), NULL);
1654 if (!tb[NL80211_ATTR_BSS])
1655 return NL_SKIP;
1656 if (nla_parse_nested(bss, NL80211_BSS_MAX, tb[NL80211_ATTR_BSS],
1657 bss_policy))
1658 return NL_SKIP;
1659 if (bss[NL80211_BSS_INFORMATION_ELEMENTS]) {
1660 ie = nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS]);
1661 ie_len = nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]);
1662 } else {
1663 ie = NULL;
1664 ie_len = 0;
1665 }
3f5285e8 1666
b3db1e1c 1667 r = os_zalloc(sizeof(*r) + ie_len);
3f5285e8 1668 if (r == NULL)
b3db1e1c
JM
1669 return NL_SKIP;
1670 if (bss[NL80211_BSS_BSSID])
1671 os_memcpy(r->bssid, nla_data(bss[NL80211_BSS_BSSID]),
1672 ETH_ALEN);
1673 if (bss[NL80211_BSS_FREQUENCY])
1674 r->freq = nla_get_u32(bss[NL80211_BSS_FREQUENCY]);
1675 if (bss[NL80211_BSS_BEACON_INTERVAL])
1676 r->beacon_int = nla_get_u16(bss[NL80211_BSS_BEACON_INTERVAL]);
1677 if (bss[NL80211_BSS_CAPABILITY])
1678 r->caps = nla_get_u16(bss[NL80211_BSS_CAPABILITY]);
7c2849d2
JM
1679 r->flags |= WPA_SCAN_NOISE_INVALID;
1680 if (bss[NL80211_BSS_SIGNAL_MBM]) {
b3db1e1c 1681 r->level = nla_get_u32(bss[NL80211_BSS_SIGNAL_MBM]);
7c2849d2
JM
1682 r->level /= 100; /* mBm to dBm */
1683 r->flags |= WPA_SCAN_LEVEL_DBM | WPA_SCAN_QUAL_INVALID;
1684 } else if (bss[NL80211_BSS_SIGNAL_UNSPEC]) {
1685 r->level = nla_get_u8(bss[NL80211_BSS_SIGNAL_UNSPEC]);
1686 r->flags |= WPA_SCAN_LEVEL_INVALID;
1687 } else
1688 r->flags |= WPA_SCAN_LEVEL_INVALID | WPA_SCAN_QUAL_INVALID;
b3db1e1c
JM
1689 if (bss[NL80211_BSS_TSF])
1690 r->tsf = nla_get_u64(bss[NL80211_BSS_TSF]);
b3ad11bb
JM
1691 if (bss[NL80211_BSS_SEEN_MS_AGO])
1692 r->age = nla_get_u32(bss[NL80211_BSS_SEEN_MS_AGO]);
b3db1e1c
JM
1693 r->ie_len = ie_len;
1694 if (ie)
1695 os_memcpy(r + 1, ie, ie_len);
3f5285e8 1696
e6b8efeb
JM
1697 if (bss[NL80211_BSS_STATUS]) {
1698 enum nl80211_bss_status status;
1699 status = nla_get_u32(bss[NL80211_BSS_STATUS]);
1700 switch (status) {
1701 case NL80211_BSS_STATUS_AUTHENTICATED:
1702 r->flags |= WPA_SCAN_AUTHENTICATED;
1703 break;
1704 case NL80211_BSS_STATUS_ASSOCIATED:
1705 r->flags |= WPA_SCAN_ASSOCIATED;
1706 break;
1707 default:
1708 break;
1709 }
1710 }
1711
3f5285e8
JM
1712 tmp = os_realloc(res->res,
1713 (res->num + 1) * sizeof(struct wpa_scan_res *));
1714 if (tmp == NULL) {
1715 os_free(r);
b3db1e1c 1716 return NL_SKIP;
3f5285e8
JM
1717 }
1718 tmp[res->num++] = r;
1719 res->res = tmp;
b3db1e1c
JM
1720
1721 return NL_SKIP;
3f5285e8 1722}
b3db1e1c 1723
3f5285e8 1724
d72aad94
JM
1725static void clear_state_mismatch(struct wpa_driver_nl80211_data *drv,
1726 const u8 *addr)
1727{
1728 if (drv->capa.flags & WPA_DRIVER_FLAGS_SME) {
1729 wpa_printf(MSG_DEBUG, "nl80211: Clear possible state "
1730 "mismatch");
1731 wpa_driver_nl80211_mlme(drv, addr,
1732 NL80211_CMD_DEAUTHENTICATE,
1733 WLAN_REASON_PREV_AUTH_NOT_VALID);
1734 }
1735}
1736
1737
e6b8efeb
JM
1738static void wpa_driver_nl80211_check_bss_status(
1739 struct wpa_driver_nl80211_data *drv, struct wpa_scan_results *res)
1740{
1741 size_t i;
1742
1743 for (i = 0; i < res->num; i++) {
1744 struct wpa_scan_res *r = res->res[i];
1745 if (r->flags & WPA_SCAN_AUTHENTICATED) {
1746 wpa_printf(MSG_DEBUG, "nl80211: Scan results "
1747 "indicates BSS status with " MACSTR
1748 " as authenticated",
1749 MAC2STR(r->bssid));
1750 if (drv->nlmode == NL80211_IFTYPE_STATION &&
1751 os_memcmp(r->bssid, drv->bssid, ETH_ALEN) != 0 &&
1752 os_memcmp(r->bssid, drv->auth_bssid, ETH_ALEN) !=
1753 0) {
1754 wpa_printf(MSG_DEBUG, "nl80211: Unknown BSSID"
1755 " in local state (auth=" MACSTR
1756 " assoc=" MACSTR ")",
1757 MAC2STR(drv->auth_bssid),
1758 MAC2STR(drv->bssid));
1759 }
1760 }
1761
1762 if (r->flags & WPA_SCAN_ASSOCIATED) {
1763 wpa_printf(MSG_DEBUG, "nl80211: Scan results "
1764 "indicate BSS status with " MACSTR
1765 " as associated",
1766 MAC2STR(r->bssid));
1767 if (drv->nlmode == NL80211_IFTYPE_STATION &&
1768 !drv->associated) {
1769 wpa_printf(MSG_DEBUG, "nl80211: Local state "
1770 "(not associated) does not match "
1771 "with BSS state");
d72aad94 1772 clear_state_mismatch(drv, r->bssid);
e6b8efeb
JM
1773 } else if (drv->nlmode == NL80211_IFTYPE_STATION &&
1774 os_memcmp(drv->bssid, r->bssid, ETH_ALEN) !=
1775 0) {
1776 wpa_printf(MSG_DEBUG, "nl80211: Local state "
1777 "(associated with " MACSTR ") does "
1778 "not match with BSS state",
d72aad94
JM
1779 MAC2STR(drv->bssid));
1780 clear_state_mismatch(drv, r->bssid);
1781 clear_state_mismatch(drv, drv->bssid);
e6b8efeb
JM
1782 }
1783 }
1784 }
1785}
1786
1787
3f5285e8
JM
1788/**
1789 * wpa_driver_nl80211_get_scan_results - Fetch the latest scan results
1790 * @priv: Pointer to private wext data from wpa_driver_nl80211_init()
1791 * Returns: Scan results on success, -1 on failure
1792 */
7e5ba1b9
JM
1793static struct wpa_scan_results *
1794wpa_driver_nl80211_get_scan_results(void *priv)
3f5285e8
JM
1795{
1796 struct wpa_driver_nl80211_data *drv = priv;
b3db1e1c 1797 struct nl_msg *msg;
3f5285e8 1798 struct wpa_scan_results *res;
b3db1e1c 1799 int ret;
3f5285e8
JM
1800
1801 res = os_zalloc(sizeof(*res));
b3db1e1c 1802 if (res == NULL)
8e2c104f 1803 return NULL;
b3db1e1c
JM
1804 msg = nlmsg_alloc();
1805 if (!msg)
1806 goto nla_put_failure;
3f5285e8 1807
b3db1e1c
JM
1808 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, NLM_F_DUMP,
1809 NL80211_CMD_GET_SCAN, 0);
1810 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
3f5285e8 1811
b3db1e1c
JM
1812 ret = send_and_recv_msgs(drv, msg, bss_info_handler, res);
1813 msg = NULL;
1814 if (ret == 0) {
1815 wpa_printf(MSG_DEBUG, "Received scan results (%lu BSSes)",
1816 (unsigned long) res->num);
e6b8efeb 1817 wpa_driver_nl80211_check_bss_status(drv, res);
b3db1e1c 1818 return res;
3f5285e8 1819 }
b3db1e1c
JM
1820 wpa_printf(MSG_DEBUG, "nl80211: Scan result fetch failed: ret=%d "
1821 "(%s)", ret, strerror(-ret));
1822nla_put_failure:
1823 nlmsg_free(msg);
1824 wpa_scan_results_free(res);
1825 return NULL;
3f5285e8
JM
1826}
1827
1828
642187d6
JM
1829static int wpa_driver_nl80211_set_key(const char *ifname, void *priv,
1830 wpa_alg alg, const u8 *addr, int key_idx,
1831 int set_tx,
1832 const u8 *seq, size_t seq_len,
1833 const u8 *key, size_t key_len)
3f5285e8 1834{
642187d6
JM
1835 struct wpa_driver_nl80211_data *drv = priv;
1836 int ifindex = if_nametoindex(ifname);
3f5285e8 1837 struct nl_msg *msg;
1ad1cdc2 1838 int ret;
3f5285e8 1839
1ad1cdc2
JM
1840 wpa_printf(MSG_DEBUG, "%s: ifindex=%d alg=%d addr=%p key_idx=%d "
1841 "set_tx=%d seq_len=%lu key_len=%lu",
1842 __func__, ifindex, alg, addr, key_idx, set_tx,
3f5285e8
JM
1843 (unsigned long) seq_len, (unsigned long) key_len);
1844
1845 msg = nlmsg_alloc();
1ad1cdc2
JM
1846 if (!msg)
1847 return -ENOMEM;
3f5285e8
JM
1848
1849 if (alg == WPA_ALG_NONE) {
1ad1cdc2
JM
1850 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
1851 0, NL80211_CMD_DEL_KEY, 0);
3f5285e8 1852 } else {
1ad1cdc2
JM
1853 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
1854 0, NL80211_CMD_NEW_KEY, 0);
3f5285e8 1855 NLA_PUT(msg, NL80211_ATTR_KEY_DATA, key_len, key);
d723bab4
JM
1856 switch (alg) {
1857 case WPA_ALG_WEP:
1858 if (key_len == 5)
1859 NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
1860 WLAN_CIPHER_SUITE_WEP40);
1861 else
1862 NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
1863 WLAN_CIPHER_SUITE_WEP104);
1864 break;
1865 case WPA_ALG_TKIP:
1866 NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
1867 WLAN_CIPHER_SUITE_TKIP);
1868 break;
1869 case WPA_ALG_CCMP:
1870 NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
1871 WLAN_CIPHER_SUITE_CCMP);
1872 break;
1873 case WPA_ALG_IGTK:
1874 NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
1875 WLAN_CIPHER_SUITE_AES_CMAC);
1876 break;
1877 default:
1878 wpa_printf(MSG_ERROR, "%s: Unsupported encryption "
1879 "algorithm %d", __func__, alg);
3f5285e8
JM
1880 nlmsg_free(msg);
1881 return -1;
1882 }
1883 }
1884
849ef835 1885 if (seq && seq_len)
1ad1cdc2
JM
1886 NLA_PUT(msg, NL80211_ATTR_KEY_SEQ, seq_len, seq);
1887
3f5285e8
JM
1888 if (addr && os_memcmp(addr, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) != 0)
1889 {
1890 wpa_printf(MSG_DEBUG, " addr=" MACSTR, MAC2STR(addr));
1891 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
1892 }
1893 NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx);
1ad1cdc2 1894 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
3f5285e8 1895
1ad1cdc2
JM
1896 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
1897 if (ret == -ENOENT && alg == WPA_ALG_NONE)
1898 ret = 0;
1899 if (ret)
1900 wpa_printf(MSG_DEBUG, "nl80211: set_key failed; err=%d %s)",
1901 ret, strerror(-ret));
3f5285e8 1902
1ad1cdc2
JM
1903 /*
1904 * If we failed or don't need to set the default TX key (below),
1905 * we're done here.
1906 */
1907 if (ret || !set_tx || alg == WPA_ALG_NONE)
1908 return ret;
1909#ifdef HOSTAPD /* FIX: is this needed? */
1910 if (addr)
1911 return ret;
1912#endif /* HOSTAPD */
3f5285e8 1913
1ad1cdc2
JM
1914 msg = nlmsg_alloc();
1915 if (!msg)
1916 return -ENOMEM;
3f5285e8 1917
1ad1cdc2
JM
1918 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
1919 0, NL80211_CMD_SET_KEY, 0);
1920 NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx);
1921 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
1922 if (alg == WPA_ALG_IGTK)
1923 NLA_PUT_FLAG(msg, NL80211_ATTR_KEY_DEFAULT_MGMT);
1924 else
1925 NLA_PUT_FLAG(msg, NL80211_ATTR_KEY_DEFAULT);
3f5285e8 1926
1ad1cdc2
JM
1927 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
1928 if (ret == -ENOENT)
1929 ret = 0;
1930 if (ret)
1931 wpa_printf(MSG_DEBUG, "nl80211: set_key default failed; "
1932 "err=%d %s)", ret, strerror(-ret));
1933 return ret;
3f5285e8
JM
1934
1935nla_put_failure:
6241fcb1 1936 return -ENOBUFS;
3f5285e8
JM
1937}
1938
1939
0194fedb
JB
1940static int nl_add_key(struct nl_msg *msg, wpa_alg alg,
1941 int key_idx, int defkey,
1942 const u8 *seq, size_t seq_len,
1943 const u8 *key, size_t key_len)
1944{
1945 struct nlattr *key_attr = nla_nest_start(msg, NL80211_ATTR_KEY);
1946 if (!key_attr)
1947 return -1;
1948
1949 if (defkey && alg == WPA_ALG_IGTK)
1950 NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT_MGMT);
1951 else if (defkey)
1952 NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT);
1953
1954 NLA_PUT_U8(msg, NL80211_KEY_IDX, key_idx);
1955
d723bab4
JM
1956 switch (alg) {
1957 case WPA_ALG_WEP:
1958 if (key_len == 5)
2aa5f847
JM
1959 NLA_PUT_U32(msg, NL80211_KEY_CIPHER,
1960 WLAN_CIPHER_SUITE_WEP40);
d723bab4 1961 else
2aa5f847
JM
1962 NLA_PUT_U32(msg, NL80211_KEY_CIPHER,
1963 WLAN_CIPHER_SUITE_WEP104);
d723bab4
JM
1964 break;
1965 case WPA_ALG_TKIP:
2aa5f847 1966 NLA_PUT_U32(msg, NL80211_KEY_CIPHER, WLAN_CIPHER_SUITE_TKIP);
d723bab4
JM
1967 break;
1968 case WPA_ALG_CCMP:
2aa5f847 1969 NLA_PUT_U32(msg, NL80211_KEY_CIPHER, WLAN_CIPHER_SUITE_CCMP);
d723bab4
JM
1970 break;
1971 case WPA_ALG_IGTK:
2aa5f847
JM
1972 NLA_PUT_U32(msg, NL80211_KEY_CIPHER,
1973 WLAN_CIPHER_SUITE_AES_CMAC);
d723bab4
JM
1974 break;
1975 default:
1976 wpa_printf(MSG_ERROR, "%s: Unsupported encryption "
1977 "algorithm %d", __func__, alg);
0194fedb 1978 return -1;
d723bab4 1979 }
0194fedb
JB
1980
1981 if (seq && seq_len)
1982 NLA_PUT(msg, NL80211_KEY_SEQ, seq_len, seq);
1983
1984 NLA_PUT(msg, NL80211_KEY_DATA, key_len, key);
1985
1986 nla_nest_end(msg, key_attr);
1987
1988 return 0;
1989 nla_put_failure:
1990 return -1;
1991}
1992
c811d5bc 1993
cfaab580
ZY
1994static int nl80211_set_conn_keys(struct wpa_driver_associate_params *params,
1995 struct nl_msg *msg)
1996{
1997 int i, privacy = 0;
1998 struct nlattr *nl_keys, *nl_key;
1999
2000 for (i = 0; i < 4; i++) {
2001 if (!params->wep_key[i])
2002 continue;
2003 privacy = 1;
2004 break;
2005 }
2006 if (!privacy)
2007 return 0;
2008
2009 NLA_PUT_FLAG(msg, NL80211_ATTR_PRIVACY);
2010
2011 nl_keys = nla_nest_start(msg, NL80211_ATTR_KEYS);
2012 if (!nl_keys)
2013 goto nla_put_failure;
2014
2015 for (i = 0; i < 4; i++) {
2016 if (!params->wep_key[i])
2017 continue;
2018
2019 nl_key = nla_nest_start(msg, i);
2020 if (!nl_key)
2021 goto nla_put_failure;
2022
2023 NLA_PUT(msg, NL80211_KEY_DATA, params->wep_key_len[i],
2024 params->wep_key[i]);
2025 if (params->wep_key_len[i] == 5)
2026 NLA_PUT_U32(msg, NL80211_KEY_CIPHER,
2027 WLAN_CIPHER_SUITE_WEP40);
2028 else
2029 NLA_PUT_U32(msg, NL80211_KEY_CIPHER,
2030 WLAN_CIPHER_SUITE_WEP104);
2031
2032 NLA_PUT_U8(msg, NL80211_KEY_IDX, i);
2033
2034 if (i == params->wep_tx_keyidx)
2035 NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT);
2036
2037 nla_nest_end(msg, nl_key);
2038 }
2039 nla_nest_end(msg, nl_keys);
2040
2041 return 0;
2042
2043nla_put_failure:
2044 return -ENOBUFS;
2045}
2046
2047
c2a04078
JM
2048static int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data *drv,
2049 const u8 *addr, int cmd, u16 reason_code)
2050{
2051 int ret = -1;
2052 struct nl_msg *msg;
2053
2054 msg = nlmsg_alloc();
2055 if (!msg)
2056 return -1;
2057
2058 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0, cmd, 0);
2059
2060 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
2061 NLA_PUT_U16(msg, NL80211_ATTR_REASON_CODE, reason_code);
2062 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
2063
2064 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
2065 msg = NULL;
2066 if (ret) {
2067 wpa_printf(MSG_DEBUG, "nl80211: MLME command failed: ret=%d "
2068 "(%s)", ret, strerror(-ret));
2069 goto nla_put_failure;
2070 }
2071 ret = 0;
2072
2073nla_put_failure:
2074 nlmsg_free(msg);
2075 return ret;
2076}
3f5285e8
JM
2077
2078
cfaab580
ZY
2079static int wpa_driver_nl80211_disconnect(struct wpa_driver_nl80211_data *drv,
2080 const u8 *addr, int reason_code)
2081{
2082 wpa_printf(MSG_DEBUG, "%s", __func__);
2083 drv->associated = 0;
2084 return wpa_driver_nl80211_mlme(drv, addr, NL80211_CMD_DISCONNECT,
2085 reason_code);
2086}
2087
2088
3f5285e8 2089static int wpa_driver_nl80211_deauthenticate(void *priv, const u8 *addr,
c2a04078 2090 int reason_code)
3f5285e8
JM
2091{
2092 struct wpa_driver_nl80211_data *drv = priv;
cfaab580
ZY
2093 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME))
2094 return wpa_driver_nl80211_disconnect(drv, addr, reason_code);
c2a04078 2095 wpa_printf(MSG_DEBUG, "%s", __func__);
13405f35 2096 drv->associated = 0;
c2a04078
JM
2097 return wpa_driver_nl80211_mlme(drv, addr, NL80211_CMD_DEAUTHENTICATE,
2098 reason_code);
3f5285e8
JM
2099}
2100
2101
2102static int wpa_driver_nl80211_disassociate(void *priv, const u8 *addr,
c2a04078 2103 int reason_code)
3f5285e8
JM
2104{
2105 struct wpa_driver_nl80211_data *drv = priv;
cfaab580
ZY
2106 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME))
2107 return wpa_driver_nl80211_disconnect(drv, addr, reason_code);
c2a04078 2108 wpa_printf(MSG_DEBUG, "%s", __func__);
13405f35 2109 drv->associated = 0;
c2a04078
JM
2110 return wpa_driver_nl80211_mlme(drv, addr, NL80211_CMD_DISASSOCIATE,
2111 reason_code);
3f5285e8
JM
2112}
2113
2114
c2a04078
JM
2115static int wpa_driver_nl80211_authenticate(
2116 void *priv, struct wpa_driver_auth_params *params)
2117{
2118 struct wpa_driver_nl80211_data *drv = priv;
a0b2f99b 2119 int ret = -1, i;
c2a04078
JM
2120 struct nl_msg *msg;
2121 enum nl80211_auth_type type;
6d6f4bb8 2122 int count = 0;
c2a04078
JM
2123
2124 drv->associated = 0;
e6b8efeb 2125 os_memset(drv->auth_bssid, 0, ETH_ALEN);
c2a04078 2126
4a867032
JM
2127 if (wpa_driver_nl80211_set_mode(drv, IEEE80211_MODE_INFRA) < 0)
2128 return -1;
2129
6d6f4bb8 2130retry:
c2a04078
JM
2131 msg = nlmsg_alloc();
2132 if (!msg)
2133 return -1;
2134
2135 wpa_printf(MSG_DEBUG, "nl80211: Authenticate (ifindex=%d)",
2136 drv->ifindex);
a0b2f99b 2137
0194fedb
JB
2138 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
2139 NL80211_CMD_AUTHENTICATE, 0);
2140
a0b2f99b
JM
2141 for (i = 0; i < 4; i++) {
2142 if (!params->wep_key[i])
2143 continue;
642187d6
JM
2144 wpa_driver_nl80211_set_key(drv->ifname, drv, WPA_ALG_WEP, NULL,
2145 i,
a0b2f99b
JM
2146 i == params->wep_tx_keyidx, NULL, 0,
2147 params->wep_key[i],
2148 params->wep_key_len[i]);
0194fedb
JB
2149 if (params->wep_tx_keyidx != i)
2150 continue;
2151 if (nl_add_key(msg, WPA_ALG_WEP, i, 1, NULL, 0,
2152 params->wep_key[i], params->wep_key_len[i])) {
2153 nlmsg_free(msg);
2154 return -1;
2155 }
a0b2f99b
JM
2156 }
2157
c2a04078
JM
2158 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
2159 if (params->bssid) {
2160 wpa_printf(MSG_DEBUG, " * bssid=" MACSTR,
2161 MAC2STR(params->bssid));
2162 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid);
2163 }
2164 if (params->freq) {
2165 wpa_printf(MSG_DEBUG, " * freq=%d", params->freq);
2166 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq);
2167 }
2168 if (params->ssid) {
2169 wpa_hexdump_ascii(MSG_DEBUG, " * SSID",
2170 params->ssid, params->ssid_len);
2171 NLA_PUT(msg, NL80211_ATTR_SSID, params->ssid_len,
2172 params->ssid);
2173 }
2174 wpa_hexdump(MSG_DEBUG, " * IEs", params->ie, params->ie_len);
2175 if (params->ie)
2176 NLA_PUT(msg, NL80211_ATTR_IE, params->ie_len, params->ie);
2177 /*
2178 * TODO: if multiple auth_alg options enabled, try them one by one if
2179 * the AP rejects authentication due to unknown auth alg
2180 */
2181 if (params->auth_alg & AUTH_ALG_OPEN_SYSTEM)
2182 type = NL80211_AUTHTYPE_OPEN_SYSTEM;
2183 else if (params->auth_alg & AUTH_ALG_SHARED_KEY)
2184 type = NL80211_AUTHTYPE_SHARED_KEY;
2185 else if (params->auth_alg & AUTH_ALG_LEAP)
2186 type = NL80211_AUTHTYPE_NETWORK_EAP;
2187 else if (params->auth_alg & AUTH_ALG_FT)
2188 type = NL80211_AUTHTYPE_FT;
2189 else
2190 goto nla_put_failure;
2191 wpa_printf(MSG_DEBUG, " * Auth Type %d", type);
2192 NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE, type);
2193
2194 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
2195 msg = NULL;
2196 if (ret) {
2197 wpa_printf(MSG_DEBUG, "nl80211: MLME command failed: ret=%d "
2198 "(%s)", ret, strerror(-ret));
6d6f4bb8
JM
2199 count++;
2200 if (ret == -EALREADY && count == 1 && params->bssid) {
2201 /*
2202 * mac80211 does not currently accept new
2203 * authentication if we are already authenticated. As a
2204 * workaround, force deauthentication and try again.
2205 */
2206 wpa_printf(MSG_DEBUG, "nl80211: Retry authentication "
2207 "after forced deauthentication");
2208 wpa_driver_nl80211_deauthenticate(
2209 drv, params->bssid,
2210 WLAN_REASON_PREV_AUTH_NOT_VALID);
2211 nlmsg_free(msg);
2212 goto retry;
2213 }
c2a04078
JM
2214 goto nla_put_failure;
2215 }
2216 ret = 0;
2217 wpa_printf(MSG_DEBUG, "nl80211: Authentication request send "
2218 "successfully");
2219
2220nla_put_failure:
2221 nlmsg_free(msg);
2222 return ret;
2223}
2224
2225
c3965310 2226#if defined(CONFIG_AP) || defined(HOSTAPD)
282d5590
JM
2227
2228struct phy_info_arg {
2229 u16 *num_modes;
2230 struct hostapd_hw_modes *modes;
2231};
2232
2233static int phy_info_handler(struct nl_msg *msg, void *arg)
2234{
2235 struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
2236 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
2237 struct phy_info_arg *phy_info = arg;
2238
2239 struct nlattr *tb_band[NL80211_BAND_ATTR_MAX + 1];
2240
2241 struct nlattr *tb_freq[NL80211_FREQUENCY_ATTR_MAX + 1];
2242 static struct nla_policy freq_policy[NL80211_FREQUENCY_ATTR_MAX + 1] = {
2243 [NL80211_FREQUENCY_ATTR_FREQ] = { .type = NLA_U32 },
2244 [NL80211_FREQUENCY_ATTR_DISABLED] = { .type = NLA_FLAG },
2245 [NL80211_FREQUENCY_ATTR_PASSIVE_SCAN] = { .type = NLA_FLAG },
2246 [NL80211_FREQUENCY_ATTR_NO_IBSS] = { .type = NLA_FLAG },
2247 [NL80211_FREQUENCY_ATTR_RADAR] = { .type = NLA_FLAG },
2248 [NL80211_FREQUENCY_ATTR_MAX_TX_POWER] = { .type = NLA_U32 },
2249 };
2250
2251 struct nlattr *tb_rate[NL80211_BITRATE_ATTR_MAX + 1];
2252 static struct nla_policy rate_policy[NL80211_BITRATE_ATTR_MAX + 1] = {
2253 [NL80211_BITRATE_ATTR_RATE] = { .type = NLA_U32 },
2254 [NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE] = { .type = NLA_FLAG },
2255 };
2256
2257 struct nlattr *nl_band;
2258 struct nlattr *nl_freq;
2259 struct nlattr *nl_rate;
2260 int rem_band, rem_freq, rem_rate;
2261 struct hostapd_hw_modes *mode;
2262 int idx, mode_is_set;
2263
2264 nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
2265 genlmsg_attrlen(gnlh, 0), NULL);
2266
2267 if (!tb_msg[NL80211_ATTR_WIPHY_BANDS])
2268 return NL_SKIP;
2269
2270 nla_for_each_nested(nl_band, tb_msg[NL80211_ATTR_WIPHY_BANDS], rem_band) {
2271 mode = realloc(phy_info->modes, (*phy_info->num_modes + 1) * sizeof(*mode));
2272 if (!mode)
2273 return NL_SKIP;
2274 phy_info->modes = mode;
2275
2276 mode_is_set = 0;
2277
2278 mode = &phy_info->modes[*(phy_info->num_modes)];
2279 memset(mode, 0, sizeof(*mode));
2280 *(phy_info->num_modes) += 1;
2281
2282 nla_parse(tb_band, NL80211_BAND_ATTR_MAX, nla_data(nl_band),
2283 nla_len(nl_band), NULL);
2284
2285 if (tb_band[NL80211_BAND_ATTR_HT_CAPA]) {
2286 mode->ht_capab = nla_get_u16(
2287 tb_band[NL80211_BAND_ATTR_HT_CAPA]);
2288 }
2289
be8eb8ab
JM
2290 if (tb_band[NL80211_BAND_ATTR_HT_AMPDU_FACTOR]) {
2291 mode->a_mpdu_params |= nla_get_u8(
2292 tb_band[NL80211_BAND_ATTR_HT_AMPDU_FACTOR]) &
2293 0x03;
2294 }
2295
2296 if (tb_band[NL80211_BAND_ATTR_HT_AMPDU_DENSITY]) {
2297 mode->a_mpdu_params |= nla_get_u8(
2298 tb_band[NL80211_BAND_ATTR_HT_AMPDU_DENSITY]) <<
2299 2;
2300 }
2301
08eb154d
JM
2302 if (tb_band[NL80211_BAND_ATTR_HT_MCS_SET] &&
2303 nla_len(tb_band[NL80211_BAND_ATTR_HT_MCS_SET])) {
2304 u8 *mcs;
2305 mcs = nla_data(tb_band[NL80211_BAND_ATTR_HT_MCS_SET]);
2306 os_memcpy(mode->mcs_set, mcs, 16);
2307 }
2308
282d5590
JM
2309 nla_for_each_nested(nl_freq, tb_band[NL80211_BAND_ATTR_FREQS], rem_freq) {
2310 nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX, nla_data(nl_freq),
2311 nla_len(nl_freq), freq_policy);
2312 if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ])
2313 continue;
2314 mode->num_channels++;
2315 }
2316
2317 mode->channels = calloc(mode->num_channels, sizeof(struct hostapd_channel_data));
2318 if (!mode->channels)
2319 return NL_SKIP;
2320
2321 idx = 0;
2322
2323 nla_for_each_nested(nl_freq, tb_band[NL80211_BAND_ATTR_FREQS], rem_freq) {
2324 nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX, nla_data(nl_freq),
2325 nla_len(nl_freq), freq_policy);
2326 if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ])
2327 continue;
2328
2329 mode->channels[idx].freq = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_FREQ]);
2330 mode->channels[idx].flag = 0;
2331
2332 if (!mode_is_set) {
2333 /* crude heuristic */
2334 if (mode->channels[idx].freq < 4000)
2335 mode->mode = HOSTAPD_MODE_IEEE80211B;
2336 else
2337 mode->mode = HOSTAPD_MODE_IEEE80211A;
2338 mode_is_set = 1;
2339 }
2340
2341 /* crude heuristic */
2342 if (mode->channels[idx].freq < 4000)
5a0ffb5f 2343 if (mode->channels[idx].freq == 2484)
282d5590
JM
2344 mode->channels[idx].chan = 14;
2345 else
2346 mode->channels[idx].chan = (mode->channels[idx].freq - 2407) / 5;
2347 else
2348 mode->channels[idx].chan = mode->channels[idx].freq/5 - 1000;
2349
2350 if (tb_freq[NL80211_FREQUENCY_ATTR_DISABLED])
2351 mode->channels[idx].flag |=
2352 HOSTAPD_CHAN_DISABLED;
2353 if (tb_freq[NL80211_FREQUENCY_ATTR_PASSIVE_SCAN])
2354 mode->channels[idx].flag |=
2355 HOSTAPD_CHAN_PASSIVE_SCAN;
2356 if (tb_freq[NL80211_FREQUENCY_ATTR_NO_IBSS])
2357 mode->channels[idx].flag |=
2358 HOSTAPD_CHAN_NO_IBSS;
2359 if (tb_freq[NL80211_FREQUENCY_ATTR_RADAR])
2360 mode->channels[idx].flag |=
2361 HOSTAPD_CHAN_RADAR;
2362
2363 if (tb_freq[NL80211_FREQUENCY_ATTR_MAX_TX_POWER] &&
2364 !tb_freq[NL80211_FREQUENCY_ATTR_DISABLED])
2365 mode->channels[idx].max_tx_power =
2366 nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_MAX_TX_POWER]) / 100;
2367
2368 idx++;
2369 }
2370
2371 nla_for_each_nested(nl_rate, tb_band[NL80211_BAND_ATTR_RATES], rem_rate) {
2372 nla_parse(tb_rate, NL80211_BITRATE_ATTR_MAX, nla_data(nl_rate),
2373 nla_len(nl_rate), rate_policy);
2374 if (!tb_rate[NL80211_BITRATE_ATTR_RATE])
2375 continue;
2376 mode->num_rates++;
2377 }
2378
2379 mode->rates = calloc(mode->num_rates, sizeof(struct hostapd_rate_data));
2380 if (!mode->rates)
2381 return NL_SKIP;
2382
2383 idx = 0;
2384
2385 nla_for_each_nested(nl_rate, tb_band[NL80211_BAND_ATTR_RATES], rem_rate) {
2386 nla_parse(tb_rate, NL80211_BITRATE_ATTR_MAX, nla_data(nl_rate),
2387 nla_len(nl_rate), rate_policy);
2388 if (!tb_rate[NL80211_BITRATE_ATTR_RATE])
2389 continue;
2390 mode->rates[idx].rate = nla_get_u32(tb_rate[NL80211_BITRATE_ATTR_RATE]);
2391
2392 /* crude heuristic */
2393 if (mode->mode == HOSTAPD_MODE_IEEE80211B &&
2394 mode->rates[idx].rate > 200)
2395 mode->mode = HOSTAPD_MODE_IEEE80211G;
2396
2397 if (tb_rate[NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE])
2398 mode->rates[idx].flags |= HOSTAPD_RATE_PREAMBLE2;
2399
2400 idx++;
2401 }
2402 }
2403
2404 return NL_SKIP;
2405}
2406
2407static struct hostapd_hw_modes *
2408wpa_driver_nl80211_add_11b(struct hostapd_hw_modes *modes, u16 *num_modes)
2409{
2410 u16 m;
2411 struct hostapd_hw_modes *mode11g = NULL, *nmodes, *mode;
2412 int i, mode11g_idx = -1;
2413
2414 /* If only 802.11g mode is included, use it to construct matching
2415 * 802.11b mode data. */
2416
2417 for (m = 0; m < *num_modes; m++) {
2418 if (modes[m].mode == HOSTAPD_MODE_IEEE80211B)
2419 return modes; /* 802.11b already included */
2420 if (modes[m].mode == HOSTAPD_MODE_IEEE80211G)
2421 mode11g_idx = m;
2422 }
2423
2424 if (mode11g_idx < 0)
2425 return modes; /* 2.4 GHz band not supported at all */
2426
2427 nmodes = os_realloc(modes, (*num_modes + 1) * sizeof(*nmodes));
2428 if (nmodes == NULL)
2429 return modes; /* Could not add 802.11b mode */
2430
2431 mode = &nmodes[*num_modes];
2432 os_memset(mode, 0, sizeof(*mode));
2433 (*num_modes)++;
2434 modes = nmodes;
2435
2436 mode->mode = HOSTAPD_MODE_IEEE80211B;
2437
2438 mode11g = &modes[mode11g_idx];
2439 mode->num_channels = mode11g->num_channels;
2440 mode->channels = os_malloc(mode11g->num_channels *
2441 sizeof(struct hostapd_channel_data));
2442 if (mode->channels == NULL) {
2443 (*num_modes)--;
2444 return modes; /* Could not add 802.11b mode */
2445 }
2446 os_memcpy(mode->channels, mode11g->channels,
2447 mode11g->num_channels * sizeof(struct hostapd_channel_data));
2448
2449 mode->num_rates = 0;
2450 mode->rates = os_malloc(4 * sizeof(struct hostapd_rate_data));
2451 if (mode->rates == NULL) {
2452 os_free(mode->channels);
2453 (*num_modes)--;
2454 return modes; /* Could not add 802.11b mode */
2455 }
2456
2457 for (i = 0; i < mode11g->num_rates; i++) {
2458 if (mode11g->rates[i].rate > 110 ||
2459 mode11g->rates[i].flags &
2460 (HOSTAPD_RATE_ERP | HOSTAPD_RATE_OFDM))
2461 continue;
2462 mode->rates[mode->num_rates] = mode11g->rates[i];
2463 mode->num_rates++;
2464 if (mode->num_rates == 4)
2465 break;
2466 }
2467
2468 if (mode->num_rates == 0) {
2469 os_free(mode->channels);
2470 os_free(mode->rates);
2471 (*num_modes)--;
2472 return modes; /* No 802.11b rates */
2473 }
2474
2475 wpa_printf(MSG_DEBUG, "nl80211: Added 802.11b mode based on 802.11g "
2476 "information");
2477
2478 return modes;
2479}
2480
2481
2482static struct hostapd_hw_modes *
2483wpa_driver_nl80211_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags)
2484{
2485 struct wpa_driver_nl80211_data *drv = priv;
2486 struct nl_msg *msg;
2487 struct phy_info_arg result = {
2488 .num_modes = num_modes,
2489 .modes = NULL,
2490 };
2491
2492 *num_modes = 0;
2493 *flags = 0;
2494
2495 msg = nlmsg_alloc();
2496 if (!msg)
2497 return NULL;
2498
2499 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
2500 0, NL80211_CMD_GET_WIPHY, 0);
2501
2502 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
2503
2504 if (send_and_recv_msgs(drv, msg, phy_info_handler, &result) == 0)
2505 return wpa_driver_nl80211_add_11b(result.modes, num_modes);
2506 nla_put_failure:
2507 return NULL;
2508}
2509
2510
2c2010ac
JM
2511static int wpa_driver_nl80211_send_frame(struct wpa_driver_nl80211_data *drv,
2512 const void *data, size_t len,
2513 int encrypt)
2514{
2515 __u8 rtap_hdr[] = {
2516 0x00, 0x00, /* radiotap version */
2517 0x0e, 0x00, /* radiotap length */
2518 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
2519 IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
2520 0x00, /* padding */
2521 0x00, 0x00, /* RX and TX flags to indicate that */
2522 0x00, 0x00, /* this is the injected frame directly */
2523 };
2524 struct iovec iov[2] = {
2525 {
2526 .iov_base = &rtap_hdr,
2527 .iov_len = sizeof(rtap_hdr),
2528 },
2529 {
2530 .iov_base = (void *) data,
2531 .iov_len = len,
2532 }
2533 };
2534 struct msghdr msg = {
2535 .msg_name = NULL,
2536 .msg_namelen = 0,
2537 .msg_iov = iov,
2538 .msg_iovlen = 2,
2539 .msg_control = NULL,
2540 .msg_controllen = 0,
2541 .msg_flags = 0,
2542 };
2543
2544 if (encrypt)
2545 rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP;
2546
2547 return sendmsg(drv->monitor_sock, &msg, 0);
2548}
2549
2550
2551static int wpa_driver_nl80211_send_mlme(void *priv, const u8 *data,
2552 size_t data_len)
2553{
2554 struct wpa_driver_nl80211_data *drv = priv;
2555 struct ieee80211_mgmt *mgmt;
7a47d567 2556 int encrypt = 1;
2c2010ac
JM
2557 u16 fc;
2558
2559 mgmt = (struct ieee80211_mgmt *) data;
2560 fc = le_to_host16(mgmt->frame_control);
2561
2562 if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
2563 WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_AUTH) {
2564 /*
2565 * Only one of the authentication frame types is encrypted.
2566 * In order for static WEP encryption to work properly (i.e.,
2567 * to not encrypt the frame), we need to tell mac80211 about
2568 * the frames that must not be encrypted.
2569 */
2570 u16 auth_alg = le_to_host16(mgmt->u.auth.auth_alg);
2571 u16 auth_trans = le_to_host16(mgmt->u.auth.auth_transaction);
7a47d567
JB
2572 if (auth_alg != WLAN_AUTH_SHARED_KEY || auth_trans != 3)
2573 encrypt = 0;
2c2010ac
JM
2574 }
2575
7a47d567 2576 return wpa_driver_nl80211_send_frame(drv, data, data_len, encrypt);
2c2010ac
JM
2577}
2578
5d674872
JM
2579#endif /* CONFIG_AP || HOSTAPD */
2580
2c2010ac 2581
5d674872
JM
2582static int wpa_driver_nl80211_set_beacon(const char *ifname, void *priv,
2583 const u8 *head, size_t head_len,
2584 const u8 *tail, size_t tail_len,
2585 int dtim_period, int beacon_int)
d2440ba0
JM
2586{
2587 struct wpa_driver_nl80211_data *drv = priv;
2588 struct nl_msg *msg;
2589 u8 cmd = NL80211_CMD_NEW_BEACON;
2590 int ret;
b4fd6fab 2591 int beacon_set;
5d674872 2592 int ifindex = if_nametoindex(ifname);
b4fd6fab
JM
2593#ifdef HOSTAPD
2594 struct i802_bss *bss;
2595
2596 bss = get_bss(drv, ifindex);
2597 if (bss == NULL)
2598 return -ENOENT;
2599 beacon_set = bss->beacon_set;
2600#else /* HOSTAPD */
2601 beacon_set = drv->beacon_set;
2602#endif /* HOSTAPD */
d2440ba0
JM
2603
2604 msg = nlmsg_alloc();
2605 if (!msg)
2606 return -ENOMEM;
2607
2608 wpa_printf(MSG_DEBUG, "nl80211: Set beacon (beacon_set=%d)",
b4fd6fab
JM
2609 beacon_set);
2610 if (beacon_set)
d2440ba0
JM
2611 cmd = NL80211_CMD_SET_BEACON;
2612
2613 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
2614 0, cmd, 0);
2615 NLA_PUT(msg, NL80211_ATTR_BEACON_HEAD, head_len, head);
2616 NLA_PUT(msg, NL80211_ATTR_BEACON_TAIL, tail_len, tail);
b4fd6fab 2617 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
5d674872 2618 NLA_PUT_U32(msg, NL80211_ATTR_BEACON_INTERVAL, beacon_int);
d2440ba0
JM
2619 NLA_PUT_U32(msg, NL80211_ATTR_DTIM_PERIOD, dtim_period);
2620
2621 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
2622 if (ret) {
2623 wpa_printf(MSG_DEBUG, "nl80211: Beacon set failed: %d (%s)",
2624 ret, strerror(-ret));
b4fd6fab
JM
2625 } else {
2626#ifdef HOSTAPD
2627 bss->beacon_set = 1;
2628#else /* HOSTAPD */
d2440ba0 2629 drv->beacon_set = 1;
b4fd6fab
JM
2630#endif /* HOSTAPD */
2631 }
d2440ba0
JM
2632 return ret;
2633 nla_put_failure:
2634 return -ENOBUFS;
2635}
2636
2637
5d674872 2638#if defined(CONFIG_AP) || defined(HOSTAPD)
d2440ba0 2639
f019981a
JM
2640static int wpa_driver_nl80211_set_freq(struct wpa_driver_nl80211_data *drv,
2641 int freq, int ht_enabled,
2642 int sec_channel_offset)
1581b38b
JM
2643{
2644 struct nl_msg *msg;
d2440ba0 2645 int ret;
1581b38b
JM
2646
2647 msg = nlmsg_alloc();
2648 if (!msg)
2649 return -1;
2650
2651 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
2652 NL80211_CMD_SET_WIPHY, 0);
2653
2654 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
f019981a
JM
2655 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
2656 if (ht_enabled) {
2657 switch (sec_channel_offset) {
2658 case -1:
2659 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
2660 NL80211_CHAN_HT40MINUS);
2661 break;
2662 case 1:
2663 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
2664 NL80211_CHAN_HT40PLUS);
2665 break;
2666 default:
2667 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
2668 NL80211_CHAN_HT20);
2669 break;
2670 }
2671 }
1581b38b 2672
d2440ba0
JM
2673 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
2674 if (ret == 0)
1581b38b 2675 return 0;
f019981a
JM
2676 wpa_printf(MSG_DEBUG, "nl80211: Failed to set channel (freq=%d): "
2677 "%d (%s)", freq, ret, strerror(-ret));
1581b38b
JM
2678nla_put_failure:
2679 return -1;
2680}
2681
0f4e8b4f
JM
2682
2683static int wpa_driver_nl80211_sta_add(const char *ifname, void *priv,
2684 struct hostapd_sta_add_params *params)
2685{
2686 struct wpa_driver_nl80211_data *drv = priv;
2687 struct nl_msg *msg;
2688 int ret = -ENOBUFS;
2689
2690 msg = nlmsg_alloc();
2691 if (!msg)
2692 return -ENOMEM;
2693
2694 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
2695 0, NL80211_CMD_NEW_STATION, 0);
2696
2697 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(ifname));
2698 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->addr);
2699 NLA_PUT_U16(msg, NL80211_ATTR_STA_AID, params->aid);
2700 NLA_PUT(msg, NL80211_ATTR_STA_SUPPORTED_RATES, params->supp_rates_len,
2701 params->supp_rates);
2702 NLA_PUT_U16(msg, NL80211_ATTR_STA_LISTEN_INTERVAL,
2703 params->listen_interval);
0f4e8b4f
JM
2704 if (params->ht_capabilities) {
2705 NLA_PUT(msg, NL80211_ATTR_HT_CAPABILITY,
fc4e2d95
JM
2706 sizeof(*params->ht_capabilities),
2707 params->ht_capabilities);
0f4e8b4f 2708 }
0f4e8b4f
JM
2709
2710 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
2711 if (ret)
2712 wpa_printf(MSG_DEBUG, "nl80211: NL80211_CMD_NEW_STATION "
2713 "result: %d (%s)", ret, strerror(-ret));
2714 if (ret == -EEXIST)
2715 ret = 0;
2716 nla_put_failure:
2717 return ret;
2718}
2719
2720
2721static int wpa_driver_nl80211_sta_remove(void *priv, const u8 *addr)
2722{
2723 struct wpa_driver_nl80211_data *drv = priv;
2724 struct nl_msg *msg;
2725 int ret;
2726
2727 msg = nlmsg_alloc();
2728 if (!msg)
2729 return -ENOMEM;
2730
2731 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
2732 0, NL80211_CMD_DEL_STATION, 0);
2733
2734 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
2735 if_nametoindex(drv->ifname));
2736 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
2737
2738 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
2739 if (ret == -ENOENT)
2740 return 0;
2741 return ret;
2742 nla_put_failure:
2743 return -ENOBUFS;
2744}
2745
1581b38b 2746
0915d02c
JM
2747static void nl80211_remove_iface(struct wpa_driver_nl80211_data *drv,
2748 int ifidx)
2749{
2750 struct nl_msg *msg;
2751
2135f224
JM
2752#ifdef HOSTAPD
2753 /* stop listening for EAPOL on this interface */
2754 del_ifidx(drv, ifidx);
2755#endif /* HOSTAPD */
2756
0915d02c
JM
2757 msg = nlmsg_alloc();
2758 if (!msg)
2759 goto nla_put_failure;
2760
2761 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
2762 0, NL80211_CMD_DEL_INTERFACE, 0);
2763 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifidx);
2764
2765 if (send_and_recv_msgs(drv, msg, NULL, NULL) == 0)
2766 return;
2767 nla_put_failure:
2768 wpa_printf(MSG_ERROR, "Failed to remove interface (ifidx=%d).\n",
2769 ifidx);
2770}
2771
2772
a35187e7
KH
2773static int nl80211_create_iface_once(struct wpa_driver_nl80211_data *drv,
2774 const char *ifname,
2775 enum nl80211_iftype iftype,
2776 const u8 *addr)
0915d02c
JM
2777{
2778 struct nl_msg *msg, *flags = NULL;
2779 int ifidx;
2780 int ret = -ENOBUFS;
2781
2782 msg = nlmsg_alloc();
2783 if (!msg)
2784 return -1;
2785
2786 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
2787 0, NL80211_CMD_NEW_INTERFACE, 0);
2788 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
2789 NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, ifname);
2790 NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, iftype);
2791
2792 if (iftype == NL80211_IFTYPE_MONITOR) {
2793 int err;
2794
2795 flags = nlmsg_alloc();
2796 if (!flags)
2797 goto nla_put_failure;
2798
2799 NLA_PUT_FLAG(flags, NL80211_MNTR_FLAG_COOK_FRAMES);
2800
2801 err = nla_put_nested(msg, NL80211_ATTR_MNTR_FLAGS, flags);
2802
2803 nlmsg_free(flags);
2804
2805 if (err)
2806 goto nla_put_failure;
2807 }
2808
2809 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
2810 if (ret) {
2811 nla_put_failure:
a35187e7
KH
2812 wpa_printf(MSG_ERROR, "Failed to create interface %s: %d (%s)",
2813 ifname, ret, strerror(-ret));
0915d02c
JM
2814 return ret;
2815 }
2816
2817 ifidx = if_nametoindex(ifname);
2818
2819 if (ifidx <= 0)
2820 return -1;
2821
2135f224
JM
2822#ifdef HOSTAPD
2823 /* start listening for EAPOL on this interface */
2824 add_ifidx(drv, ifidx);
2825
41d931ee
JM
2826 if (addr && iftype == NL80211_IFTYPE_AP &&
2827 set_ifhwaddr(drv, ifname, addr)) {
2828 nl80211_remove_iface(drv, ifidx);
2829 return -1;
2135f224
JM
2830 }
2831#endif /* HOSTAPD */
2832
0915d02c
JM
2833 return ifidx;
2834}
a35187e7
KH
2835static int nl80211_create_iface(struct wpa_driver_nl80211_data *drv,
2836 const char *ifname, enum nl80211_iftype iftype,
2837 const u8 *addr)
2838{
2839 int ret;
2840
2841 ret = nl80211_create_iface_once(drv, ifname, iftype, addr);
2842
2843 /* if error occured and interface exists already */
2844 if (ret == -ENFILE && if_nametoindex(ifname)) {
2845 wpa_printf(MSG_INFO, "Try to remove and re-create %s", ifname);
2846
2847 /* Try to remove the interface that was already there. */
2848 nl80211_remove_iface(drv, if_nametoindex(ifname));
2849
2850 /* Try to create the interface again */
2851 ret = nl80211_create_iface_once(drv, ifname, iftype, addr);
2852 }
2853
2854 return ret;
2855}
0915d02c 2856
2135f224
JM
2857#endif /* CONFIG_AP || HOSTAPD */
2858
2859#ifdef CONFIG_AP
0915d02c 2860
0915d02c
JM
2861void ap_tx_status(void *ctx, const u8 *addr,
2862 const u8 *buf, size_t len, int ack);
3a57305f 2863void ap_rx_from_unknown_sta(void *ctx, struct ieee80211_hdr *hdr, size_t len);
0915d02c
JM
2864void ap_mgmt_rx(void *ctx, u8 *buf, size_t len, u16 stype,
2865 struct hostapd_frame_info *fi);
2866void ap_mgmt_tx_cb(void *ctx, u8 *buf, size_t len, u16 stype, int ok);
2867
072ad14c
JM
2868#endif /* CONFIG_AP */
2869
2870#if defined(CONFIG_AP) || defined(HOSTAPD)
0915d02c
JM
2871
2872static void handle_tx_callback(void *ctx, u8 *buf, size_t len, int ok)
2873{
2874 struct ieee80211_hdr *hdr;
2875 u16 fc, type, stype;
2876
2877 hdr = (struct ieee80211_hdr *) buf;
2878 fc = le_to_host16(hdr->frame_control);
2879
2880 type = WLAN_FC_GET_TYPE(fc);
2881 stype = WLAN_FC_GET_STYPE(fc);
2882
2883 switch (type) {
2884 case WLAN_FC_TYPE_MGMT:
2885 wpa_printf(MSG_DEBUG, "MGMT (TX callback) %s",
2886 ok ? "ACK" : "fail");
072ad14c
JM
2887#ifdef HOSTAPD
2888 hostapd_mgmt_tx_cb(ctx, buf, len, stype, ok);
2889#else /* HOSTAPD */
0915d02c 2890 ap_mgmt_tx_cb(ctx, buf, len, stype, ok);
072ad14c 2891#endif /* HOSTAPD */
0915d02c
JM
2892 break;
2893 case WLAN_FC_TYPE_CTRL:
2894 wpa_printf(MSG_DEBUG, "CTRL (TX callback) %s",
2895 ok ? "ACK" : "fail");
2896 break;
2897 case WLAN_FC_TYPE_DATA:
072ad14c
JM
2898#ifdef HOSTAPD
2899 hostapd_tx_status(ctx, hdr->addr1, buf, len, ok);
2900#else /* HOSTAPD */
0915d02c 2901 ap_tx_status(ctx, hdr->addr1, buf, len, ok);
072ad14c 2902#endif /* HOSTAPD */
0915d02c
JM
2903 break;
2904 default:
2905 wpa_printf(MSG_DEBUG, "unknown TX callback frame type %d",
2906 type);
2907 break;
2908 }
2909}
2910
2911
4b9841d3
JM
2912static void from_unknown_sta(struct wpa_driver_nl80211_data *drv,
2913 struct ieee80211_hdr *hdr, size_t len)
0915d02c 2914{
7da3abe7 2915#ifdef HOSTAPD
4b9841d3
JM
2916 hostapd_rx_from_unknown_sta(drv->ctx, hdr, len);
2917#else /* HOSTAPD */
3a57305f 2918 ap_rx_from_unknown_sta(drv->ctx, hdr, len);
7da3abe7 2919#endif /* HOSTAPD */
4b9841d3 2920}
0915d02c 2921
4b9841d3
JM
2922
2923static void handle_frame(struct wpa_driver_nl80211_data *drv,
2924 u8 *buf, size_t len,
2925 struct hostapd_frame_info *hfi)
2926{
2927 struct ieee80211_hdr *hdr;
2928 u16 fc, stype;
0915d02c
JM
2929
2930 hdr = (struct ieee80211_hdr *) buf;
2931 fc = le_to_host16(hdr->frame_control);
0915d02c
JM
2932 stype = WLAN_FC_GET_STYPE(fc);
2933
4b9841d3 2934 switch (WLAN_FC_GET_TYPE(fc)) {
0915d02c
JM
2935 case WLAN_FC_TYPE_MGMT:
2936 if (stype != WLAN_FC_STYPE_BEACON &&
2937 stype != WLAN_FC_STYPE_PROBE_REQ)
2938 wpa_printf(MSG_MSGDUMP, "MGMT");
7da3abe7 2939#ifdef HOSTAPD
4b9841d3 2940 hostapd_mgmt_rx(drv->ctx, buf, len, stype, hfi);
7da3abe7 2941#else /* HOSTAPD */
4b9841d3 2942 ap_mgmt_rx(drv->ctx, buf, len, stype, hfi);
7da3abe7 2943#endif /* HOSTAPD */
0915d02c
JM
2944 break;
2945 case WLAN_FC_TYPE_CTRL:
2946 /* can only get here with PS-Poll frames */
2947 wpa_printf(MSG_DEBUG, "CTRL");
4b9841d3 2948 from_unknown_sta(drv, hdr, len);
0915d02c
JM
2949 break;
2950 case WLAN_FC_TYPE_DATA:
4b9841d3 2951 from_unknown_sta(drv, hdr, len);
0915d02c
JM
2952 break;
2953 }
2954}
2955
2956
2957static void handle_monitor_read(int sock, void *eloop_ctx, void *sock_ctx)
2958{
2959 struct wpa_driver_nl80211_data *drv = eloop_ctx;
2960 int len;
2961 unsigned char buf[3000];
2962 struct ieee80211_radiotap_iterator iter;
2963 int ret;
2964 struct hostapd_frame_info hfi;
4b9841d3 2965 int injected = 0, failed = 0, rxflags = 0;
0915d02c
JM
2966
2967 len = recv(sock, buf, sizeof(buf), 0);
2968 if (len < 0) {
2969 perror("recv");
2970 return;
2971 }
2972
2973 if (ieee80211_radiotap_iterator_init(&iter, (void*)buf, len)) {
2974 printf("received invalid radiotap frame\n");
2975 return;
2976 }
2977
2978 memset(&hfi, 0, sizeof(hfi));
2979
2980 while (1) {
2981 ret = ieee80211_radiotap_iterator_next(&iter);
2982 if (ret == -ENOENT)
2983 break;
2984 if (ret) {
2985 printf("received invalid radiotap frame (%d)\n", ret);
2986 return;
2987 }
2988 switch (iter.this_arg_index) {
2989 case IEEE80211_RADIOTAP_FLAGS:
2990 if (*iter.this_arg & IEEE80211_RADIOTAP_F_FCS)
2991 len -= 4;
2992 break;
2993 case IEEE80211_RADIOTAP_RX_FLAGS:
2994 rxflags = 1;
2995 break;
2996 case IEEE80211_RADIOTAP_TX_FLAGS:
2997 injected = 1;
2998 failed = le_to_host16((*(uint16_t *) iter.this_arg)) &
2999 IEEE80211_RADIOTAP_F_TX_FAIL;
3000 break;
3001 case IEEE80211_RADIOTAP_DATA_RETRIES:
3002 break;
3003 case IEEE80211_RADIOTAP_CHANNEL:
3004 /* TODO convert from freq/flags to channel number
3005 hfi.channel = XXX;
0915d02c
JM
3006 */
3007 break;
3008 case IEEE80211_RADIOTAP_RATE:
3009 hfi.datarate = *iter.this_arg * 5;
3010 break;
3011 case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
3012 hfi.ssi_signal = *iter.this_arg;
3013 break;
3014 }
3015 }
3016
3017 if (rxflags && injected)
3018 return;
3019
3020 if (!injected)
4b9841d3
JM
3021 handle_frame(drv, buf + iter.max_length,
3022 len - iter.max_length, &hfi);
0915d02c 3023 else
4b9841d3
JM
3024 handle_tx_callback(drv->ctx, buf + iter.max_length,
3025 len - iter.max_length, !failed);
0915d02c
JM
3026}
3027
3028
3029/*
3030 * we post-process the filter code later and rewrite
3031 * this to the offset to the last instruction
3032 */
3033#define PASS 0xFF
3034#define FAIL 0xFE
3035
3036static struct sock_filter msock_filter_insns[] = {
3037 /*
3038 * do a little-endian load of the radiotap length field
3039 */
3040 /* load lower byte into A */
3041 BPF_STMT(BPF_LD | BPF_B | BPF_ABS, 2),
3042 /* put it into X (== index register) */
3043 BPF_STMT(BPF_MISC| BPF_TAX, 0),
3044 /* load upper byte into A */
3045 BPF_STMT(BPF_LD | BPF_B | BPF_ABS, 3),
3046 /* left-shift it by 8 */
3047 BPF_STMT(BPF_ALU | BPF_LSH | BPF_K, 8),
3048 /* or with X */
3049 BPF_STMT(BPF_ALU | BPF_OR | BPF_X, 0),
3050 /* put result into X */
3051 BPF_STMT(BPF_MISC| BPF_TAX, 0),
3052
3053 /*
3054 * Allow management frames through, this also gives us those
3055 * management frames that we sent ourselves with status
3056 */
3057 /* load the lower byte of the IEEE 802.11 frame control field */
3058 BPF_STMT(BPF_LD | BPF_B | BPF_IND, 0),
3059 /* mask off frame type and version */
3060 BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0xF),
3061 /* accept frame if it's both 0, fall through otherwise */
3062 BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, PASS, 0),
3063
3064 /*
3065 * TODO: add a bit to radiotap RX flags that indicates
3066 * that the sending station is not associated, then
3067 * add a filter here that filters on our DA and that flag
3068 * to allow us to deauth frames to that bad station.
3069 *
3070 * Not a regression -- we didn't do it before either.
3071 */
3072
3073#if 0
3074 /*
3075 * drop non-data frames, WDS frames
3076 */
3077 /* load the lower byte of the frame control field */
3078 BPF_STMT(BPF_LD | BPF_B | BPF_IND, 0),
3079 /* mask off QoS bit */
3080 BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x0c),
3081 /* drop non-data frames */
3082 BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 8, 0, FAIL),
3083 /* load the upper byte of the frame control field */
3084 BPF_STMT(BPF_LD | BPF_B | BPF_IND, 0),
3085 /* mask off toDS/fromDS */
3086 BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x03),
3087 /* drop WDS frames */
3088 BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 3, FAIL, 0),
3089#endif
3090
3091 /*
3092 * add header length to index
3093 */
3094 /* load the lower byte of the frame control field */
3095 BPF_STMT(BPF_LD | BPF_B | BPF_IND, 0),
3096 /* mask off QoS bit */
3097 BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x80),
3098 /* right shift it by 6 to give 0 or 2 */
3099 BPF_STMT(BPF_ALU | BPF_RSH | BPF_K, 6),
3100 /* add data frame header length */
3101 BPF_STMT(BPF_ALU | BPF_ADD | BPF_K, 24),
3102 /* add index, was start of 802.11 header */
3103 BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0),
3104 /* move to index, now start of LL header */
3105 BPF_STMT(BPF_MISC | BPF_TAX, 0),
3106
3107 /*
3108 * Accept empty data frames, we use those for
3109 * polling activity.
3110 */
3111 BPF_STMT(BPF_LD | BPF_W | BPF_LEN, 0),
3112 BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_X, 0, PASS, 0),
3113
3114 /*
3115 * Accept EAPOL frames
3116 */
3117 BPF_STMT(BPF_LD | BPF_W | BPF_IND, 0),
3118 BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0xAAAA0300, 0, FAIL),
3119 BPF_STMT(BPF_LD | BPF_W | BPF_IND, 4),
3120 BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x0000888E, PASS, FAIL),
3121
3122 /* keep these last two statements or change the code below */
3123 /* return 0 == "DROP" */
3124 BPF_STMT(BPF_RET | BPF_K, 0),
3125 /* return ~0 == "keep all" */
3126 BPF_STMT(BPF_RET | BPF_K, ~0),
3127};
3128
3129static struct sock_fprog msock_filter = {
3130 .len = sizeof(msock_filter_insns)/sizeof(msock_filter_insns[0]),
3131 .filter = msock_filter_insns,
3132};
3133
3134
3135static int add_monitor_filter(int s)
3136{
3137 int idx;
3138
3139 /* rewrite all PASS/FAIL jump offsets */
3140 for (idx = 0; idx < msock_filter.len; idx++) {
3141 struct sock_filter *insn = &msock_filter_insns[idx];
3142
3143 if (BPF_CLASS(insn->code) == BPF_JMP) {
3144 if (insn->code == (BPF_JMP|BPF_JA)) {
3145 if (insn->k == PASS)
3146 insn->k = msock_filter.len - idx - 2;
3147 else if (insn->k == FAIL)
3148 insn->k = msock_filter.len - idx - 3;
3149 }
3150
3151 if (insn->jt == PASS)
3152 insn->jt = msock_filter.len - idx - 2;
3153 else if (insn->jt == FAIL)
3154 insn->jt = msock_filter.len - idx - 3;
3155
3156 if (insn->jf == PASS)
3157 insn->jf = msock_filter.len - idx - 2;
3158 else if (insn->jf == FAIL)
3159 insn->jf = msock_filter.len - idx - 3;
3160 }
3161 }
3162
3163 if (setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER,
3164 &msock_filter, sizeof(msock_filter))) {
3165 perror("SO_ATTACH_FILTER");
3166 return -1;
3167 }
3168
3169 return 0;
3170}
3171
3172
460456f8
JM
3173static void nl80211_remove_monitor_interface(
3174 struct wpa_driver_nl80211_data *drv)
3175{
3176 if (drv->monitor_ifidx >= 0) {
3177 nl80211_remove_iface(drv, drv->monitor_ifidx);
3178 drv->monitor_ifidx = -1;
3179 }
3180}
3181
3182
0915d02c
JM
3183static int
3184nl80211_create_monitor_interface(struct wpa_driver_nl80211_data *drv)
3185{
3186 char buf[IFNAMSIZ];
3187 struct sockaddr_ll ll;
3188 int optval;
3189 socklen_t optlen;
0915d02c
JM
3190
3191 snprintf(buf, IFNAMSIZ, "mon.%s", drv->ifname);
3192 buf[IFNAMSIZ - 1] = '\0';
3193
3194 drv->monitor_ifidx =
2135f224 3195 nl80211_create_iface(drv, buf, NL80211_IFTYPE_MONITOR, NULL);
0915d02c
JM
3196
3197 if (drv->monitor_ifidx < 0)
3198 return -1;
3199
2135f224 3200 if (hostapd_set_iface_flags(drv, buf, 1))
0915d02c 3201 goto error;
0915d02c
JM
3202
3203 memset(&ll, 0, sizeof(ll));
3204 ll.sll_family = AF_PACKET;
3205 ll.sll_ifindex = drv->monitor_ifidx;
3206 drv->monitor_sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
3207 if (drv->monitor_sock < 0) {
3208 perror("socket[PF_PACKET,SOCK_RAW]");
3209 goto error;
3210 }
3211
3212 if (add_monitor_filter(drv->monitor_sock)) {
3213 wpa_printf(MSG_INFO, "Failed to set socket filter for monitor "
3214 "interface; do filtering in user space");
3215 /* This works, but will cost in performance. */
3216 }
3217
2135f224 3218 if (bind(drv->monitor_sock, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
0915d02c
JM
3219 perror("monitor socket bind");
3220 goto error;
3221 }
3222
3223 optlen = sizeof(optval);
3224 optval = 20;
3225 if (setsockopt
3226 (drv->monitor_sock, SOL_SOCKET, SO_PRIORITY, &optval, optlen)) {
3227 perror("Failed to set socket priority");
3228 goto error;
3229 }
3230
3231 if (eloop_register_read_sock(drv->monitor_sock, handle_monitor_read,
3232 drv, NULL)) {
3233 printf("Could not register monitor read socket\n");
3234 goto error;
3235 }
3236
3237 return 0;
3238 error:
460456f8 3239 nl80211_remove_monitor_interface(drv);
0915d02c
JM
3240 return -1;
3241}
3242
db149ac9
JM
3243
3244static const u8 rfc1042_header[6] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
3245
3246static int wpa_driver_nl80211_hapd_send_eapol(
3247 void *priv, const u8 *addr, const u8 *data,
3248 size_t data_len, int encrypt, const u8 *own_addr)
3249{
3250 struct wpa_driver_nl80211_data *drv = priv;
3251 struct ieee80211_hdr *hdr;
3252 size_t len;
3253 u8 *pos;
3254 int res;
3255#if 0 /* FIX */
3256 int qos = sta->flags & WLAN_STA_WME;
3257#else
3258 int qos = 0;
3259#endif
3260
3261 len = sizeof(*hdr) + (qos ? 2 : 0) + sizeof(rfc1042_header) + 2 +
3262 data_len;
3263 hdr = os_zalloc(len);
3264 if (hdr == NULL) {
3265 printf("malloc() failed for i802_send_data(len=%lu)\n",
3266 (unsigned long) len);
3267 return -1;
3268 }
3269
3270 hdr->frame_control =
3271 IEEE80211_FC(WLAN_FC_TYPE_DATA, WLAN_FC_STYPE_DATA);
3272 hdr->frame_control |= host_to_le16(WLAN_FC_FROMDS);
3273 if (encrypt)
3274 hdr->frame_control |= host_to_le16(WLAN_FC_ISWEP);
3275#if 0 /* To be enabled if qos determination is added above */
3276 if (qos) {
3277 hdr->frame_control |=
3278 host_to_le16(WLAN_FC_STYPE_QOS_DATA << 4);
3279 }
3280#endif
3281
3282 memcpy(hdr->IEEE80211_DA_FROMDS, addr, ETH_ALEN);
3283 memcpy(hdr->IEEE80211_BSSID_FROMDS, own_addr, ETH_ALEN);
3284 memcpy(hdr->IEEE80211_SA_FROMDS, own_addr, ETH_ALEN);
3285 pos = (u8 *) (hdr + 1);
3286
3287#if 0 /* To be enabled if qos determination is added above */
3288 if (qos) {
3289 /* add an empty QoS header if needed */
3290 pos[0] = 0;
3291 pos[1] = 0;
3292 pos += 2;
3293 }
3294#endif
3295
3296 memcpy(pos, rfc1042_header, sizeof(rfc1042_header));
3297 pos += sizeof(rfc1042_header);
3298 WPA_PUT_BE16(pos, ETH_P_PAE);
3299 pos += 2;
3300 memcpy(pos, data, data_len);
3301
3302 res = wpa_driver_nl80211_send_frame(drv, (u8 *) hdr, len, encrypt);
3303 if (res < 0) {
3304 wpa_printf(MSG_ERROR, "i802_send_eapol - packet len: %lu - "
3305 "failed: %d (%s)",
3306 (unsigned long) len, errno, strerror(errno));
3307 }
3308 free(hdr);
3309
3310 return res;
3311}
3312
a8d6ffa4 3313
7e76ee9c
JM
3314static u32 sta_flags_nl80211(int flags)
3315{
3316 u32 f = 0;
3317
3318 if (flags & WLAN_STA_AUTHORIZED)
3319 f |= BIT(NL80211_STA_FLAG_AUTHORIZED);
3320 if (flags & WLAN_STA_WMM)
3321 f |= BIT(NL80211_STA_FLAG_WME);
3322 if (flags & WLAN_STA_SHORT_PREAMBLE)
3323 f |= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE);
3324 if (flags & WLAN_STA_MFP)
3325 f |= BIT(NL80211_STA_FLAG_MFP);
3326
3327 return f;
3328}
3329
3330
a8d6ffa4
JM
3331static int wpa_driver_nl80211_sta_set_flags(void *priv, const u8 *addr,
3332 int total_flags, int flags_or,
3333 int flags_and)
3334{
3335 struct wpa_driver_nl80211_data *drv = priv;
3336 struct nl_msg *msg, *flags = NULL;
7e76ee9c 3337 struct nl80211_sta_flag_update upd;
a8d6ffa4
JM
3338
3339 msg = nlmsg_alloc();
3340 if (!msg)
3341 return -ENOMEM;
3342
3343 flags = nlmsg_alloc();
3344 if (!flags) {
3345 nlmsg_free(msg);
3346 return -ENOMEM;
3347 }
3348
3349 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
3350 0, NL80211_CMD_SET_STATION, 0);
3351
3352 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
3353 if_nametoindex(drv->ifname));
3354 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
3355
7e76ee9c
JM
3356 /*
3357 * Backwards compatibility version using NL80211_ATTR_STA_FLAGS. This
3358 * can be removed eventually.
3359 */
a8d6ffa4
JM
3360 if (total_flags & WLAN_STA_AUTHORIZED)
3361 NLA_PUT_FLAG(flags, NL80211_STA_FLAG_AUTHORIZED);
3362
3363 if (total_flags & WLAN_STA_WMM)
3364 NLA_PUT_FLAG(flags, NL80211_STA_FLAG_WME);
3365
3366 if (total_flags & WLAN_STA_SHORT_PREAMBLE)
3367 NLA_PUT_FLAG(flags, NL80211_STA_FLAG_SHORT_PREAMBLE);
3368
3369 if (total_flags & WLAN_STA_MFP)
3370 NLA_PUT_FLAG(flags, NL80211_STA_FLAG_MFP);
3371
3372 if (nla_put_nested(msg, NL80211_ATTR_STA_FLAGS, flags))
3373 goto nla_put_failure;
3374
7e76ee9c
JM
3375 os_memset(&upd, 0, sizeof(upd));
3376 upd.mask = sta_flags_nl80211(flags_or | ~flags_and);
3377 upd.set = sta_flags_nl80211(flags_or);
3378 NLA_PUT(msg, NL80211_ATTR_STA_FLAGS2, sizeof(upd), &upd);
3379
a8d6ffa4
JM
3380 nlmsg_free(flags);
3381
3382 return send_and_recv_msgs(drv, msg, NULL, NULL);
3383 nla_put_failure:
3384 nlmsg_free(flags);
3385 return -ENOBUFS;
3386}
3387
2135f224
JM
3388#endif /* CONFIG_AP || HOSTAPD */
3389
3390#ifdef CONFIG_AP
0915d02c 3391
1581b38b
JM
3392static int wpa_driver_nl80211_ap(struct wpa_driver_nl80211_data *drv,
3393 struct wpa_driver_associate_params *params)
3394{
3395 if (wpa_driver_nl80211_set_mode(drv, params->mode) ||
f019981a 3396 wpa_driver_nl80211_set_freq(drv, params->freq, 0, 0)) {
460456f8 3397 nl80211_remove_monitor_interface(drv);
1581b38b 3398 return -1;
0915d02c 3399 }
1581b38b
JM
3400
3401 /* TODO: setup monitor interface (and add code somewhere to remove this
3402 * when AP mode is stopped; associate with mode != 2 or drv_deinit) */
1581b38b
JM
3403
3404 return 0;
3405}
3406#endif /* CONFIG_AP */
3407
3408
5cc4d64b
JM
3409static int nl80211_leave_ibss(struct wpa_driver_nl80211_data *drv)
3410{
3411 struct nl_msg *msg;
3412 int ret = -1;
3413
3414 msg = nlmsg_alloc();
3415 if (!msg)
3416 return -1;
3417
3418 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
3419 NL80211_CMD_LEAVE_IBSS, 0);
3420 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
3421 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
3422 msg = NULL;
3423 if (ret) {
3424 wpa_printf(MSG_DEBUG, "nl80211: Leave IBSS failed: ret=%d "
3425 "(%s)", ret, strerror(-ret));
3426 goto nla_put_failure;
3427 }
3428
3429 ret = 0;
3430 wpa_printf(MSG_DEBUG, "nl80211: Leave IBSS request sent successfully");
3431
3432nla_put_failure:
3433 nlmsg_free(msg);
3434 return ret;
3435}
3436
3437
3438static int wpa_driver_nl80211_ibss(struct wpa_driver_nl80211_data *drv,
3439 struct wpa_driver_associate_params *params)
3440{
3441 struct nl_msg *msg;
3442 int ret = -1;
3443 int count = 0;
3444
3445 wpa_printf(MSG_DEBUG, "nl80211: Join IBSS (ifindex=%d)", drv->ifindex);
3446
3447 if (wpa_driver_nl80211_set_mode(drv, params->mode)) {
3448 wpa_printf(MSG_INFO, "nl80211: Failed to set interface into "
3449 "IBSS mode");
3450 return -1;
3451 }
3452
3453retry:
3454 msg = nlmsg_alloc();
3455 if (!msg)
3456 return -1;
3457
3458 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
3459 NL80211_CMD_JOIN_IBSS, 0);
3460 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
3461
3462 if (params->ssid == NULL || params->ssid_len > sizeof(drv->ssid))
3463 goto nla_put_failure;
3464
3465 wpa_hexdump_ascii(MSG_DEBUG, " * SSID",
3466 params->ssid, params->ssid_len);
3467 NLA_PUT(msg, NL80211_ATTR_SSID, params->ssid_len,
3468 params->ssid);
3469 os_memcpy(drv->ssid, params->ssid, params->ssid_len);
3470 drv->ssid_len = params->ssid_len;
3471
3472 wpa_printf(MSG_DEBUG, " * freq=%d", params->freq);
3473 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq);
3474
3475 ret = nl80211_set_conn_keys(params, msg);
3476 if (ret)
3477 goto nla_put_failure;
3478
a95795ad
JM
3479 if (params->wpa_ie) {
3480 wpa_hexdump(MSG_DEBUG,
3481 " * Extra IEs for Beacon/Probe Response frames",
3482 params->wpa_ie, params->wpa_ie_len);
3483 NLA_PUT(msg, NL80211_ATTR_IE, params->wpa_ie_len,
3484 params->wpa_ie);
3485 }
3486
5cc4d64b
JM
3487 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
3488 msg = NULL;
3489 if (ret) {
3490 wpa_printf(MSG_DEBUG, "nl80211: Join IBSS failed: ret=%d (%s)",
3491 ret, strerror(-ret));
3492 count++;
3493 if (ret == -EALREADY && count == 1) {
3494 wpa_printf(MSG_DEBUG, "nl80211: Retry IBSS join after "
3495 "forced leave");
3496 nl80211_leave_ibss(drv);
3497 nlmsg_free(msg);
3498 goto retry;
3499 }
3500
3501 goto nla_put_failure;
3502 }
3503 ret = 0;
3504 wpa_printf(MSG_DEBUG, "nl80211: Join IBSS request sent successfully");
3505
3506nla_put_failure:
3507 nlmsg_free(msg);
3508 return ret;
3509}
3510
3511
cfaab580
ZY
3512static int wpa_driver_nl80211_connect(
3513 struct wpa_driver_nl80211_data *drv,
3514 struct wpa_driver_associate_params *params)
3515{
3516 struct nl_msg *msg;
3517 enum nl80211_auth_type type;
3518 int ret = 0;
3519
3520 msg = nlmsg_alloc();
3521 if (!msg)
3522 return -1;
3523
3524 wpa_printf(MSG_DEBUG, "nl80211: Connect (ifindex=%d)", drv->ifindex);
3525 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
3526 NL80211_CMD_CONNECT, 0);
3527
3528 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
3529 if (params->bssid) {
3530 wpa_printf(MSG_DEBUG, " * bssid=" MACSTR,
3531 MAC2STR(params->bssid));
3532 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid);
3533 }
3534 if (params->freq) {
3535 wpa_printf(MSG_DEBUG, " * freq=%d", params->freq);
3536 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq);
3537 }
3538 if (params->ssid) {
3539 wpa_hexdump_ascii(MSG_DEBUG, " * SSID",
3540 params->ssid, params->ssid_len);
3541 NLA_PUT(msg, NL80211_ATTR_SSID, params->ssid_len,
3542 params->ssid);
3543 if (params->ssid_len > sizeof(drv->ssid))
3544 goto nla_put_failure;
3545 os_memcpy(drv->ssid, params->ssid, params->ssid_len);
3546 drv->ssid_len = params->ssid_len;
3547 }
3548 wpa_hexdump(MSG_DEBUG, " * IEs", params->wpa_ie, params->wpa_ie_len);
3549 if (params->wpa_ie)
3550 NLA_PUT(msg, NL80211_ATTR_IE, params->wpa_ie_len,
3551 params->wpa_ie);
3552
3553 if (params->auth_alg & AUTH_ALG_OPEN_SYSTEM)
3554 type = NL80211_AUTHTYPE_OPEN_SYSTEM;
3555 else if (params->auth_alg & AUTH_ALG_SHARED_KEY)
3556 type = NL80211_AUTHTYPE_SHARED_KEY;
3557 else if (params->auth_alg & AUTH_ALG_LEAP)
3558 type = NL80211_AUTHTYPE_NETWORK_EAP;
3559 else if (params->auth_alg & AUTH_ALG_FT)
3560 type = NL80211_AUTHTYPE_FT;
3561 else
3562 goto nla_put_failure;
3563
3564 wpa_printf(MSG_DEBUG, " * Auth Type %d", type);
3565 NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE, type);
3566
3567 if (params->wpa_ie && params->wpa_ie_len) {
3568 enum nl80211_wpa_versions ver;
3569
3570 if (params->wpa_ie[0] == WLAN_EID_RSN)
3571 ver = NL80211_WPA_VERSION_2;
3572 else
3573 ver = NL80211_WPA_VERSION_1;
3574
3575 wpa_printf(MSG_DEBUG, " * WPA Version %d", ver);
3576 NLA_PUT_U32(msg, NL80211_ATTR_WPA_VERSIONS, ver);
3577 }
3578
3579 if (params->pairwise_suite != CIPHER_NONE) {
c1bb3e0a 3580 int cipher;
cfaab580
ZY
3581
3582 switch (params->pairwise_suite) {
3583 case CIPHER_WEP40:
3584 cipher = WLAN_CIPHER_SUITE_WEP40;
3585 break;
3586 case CIPHER_WEP104:
3587 cipher = WLAN_CIPHER_SUITE_WEP104;
3588 break;
3589 case CIPHER_CCMP:
3590 cipher = WLAN_CIPHER_SUITE_CCMP;
3591 break;
3592 case CIPHER_TKIP:
3593 default:
3594 cipher = WLAN_CIPHER_SUITE_TKIP;
3595 break;
3596 }
3597 NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITES_PAIRWISE, cipher);
3598 }
3599
3600 if (params->group_suite != CIPHER_NONE) {
c1bb3e0a 3601 int cipher;
cfaab580
ZY
3602
3603 switch (params->group_suite) {
3604 case CIPHER_WEP40:
3605 cipher = WLAN_CIPHER_SUITE_WEP40;
3606 break;
3607 case CIPHER_WEP104:
3608 cipher = WLAN_CIPHER_SUITE_WEP104;
3609 break;
3610 case CIPHER_CCMP:
3611 cipher = WLAN_CIPHER_SUITE_CCMP;
3612 break;
3613 case CIPHER_TKIP:
3614 default:
3615 cipher = WLAN_CIPHER_SUITE_TKIP;
3616 break;
3617 }
3618 NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP, cipher);
3619 }
3620
3621 if (params->key_mgmt_suite == KEY_MGMT_802_1X ||
3622 params->key_mgmt_suite == KEY_MGMT_PSK) {
3623 int mgmt = WLAN_AKM_SUITE_PSK;
3624
3625 switch (params->key_mgmt_suite) {
3626 case KEY_MGMT_802_1X:
3627 mgmt = WLAN_AKM_SUITE_8021X;
3628 break;
3629 case KEY_MGMT_PSK:
3630 default:
3631 mgmt = WLAN_AKM_SUITE_PSK;
3632 break;
3633 }
3634 NLA_PUT_U32(msg, NL80211_ATTR_AKM_SUITES, mgmt);
3635 }
3636
3637 ret = nl80211_set_conn_keys(params, msg);
3638 if (ret)
3639 goto nla_put_failure;
3640
3641 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
3642 msg = NULL;
3643 if (ret) {
3644 wpa_printf(MSG_DEBUG, "nl80211: MLME connect failed: ret=%d "
3645 "(%s)", ret, strerror(-ret));
3646 goto nla_put_failure;
3647 }
3648 ret = 0;
3649 wpa_printf(MSG_DEBUG, "nl80211: Connect request send successfully");
3650
3651nla_put_failure:
3652 nlmsg_free(msg);
3653 return ret;
3654
3655}
3656
3657
c2a04078
JM
3658static int wpa_driver_nl80211_associate(
3659 void *priv, struct wpa_driver_associate_params *params)
3660{
3661 struct wpa_driver_nl80211_data *drv = priv;
3662 int ret = -1;
3663 struct nl_msg *msg;
3664
1581b38b 3665#ifdef CONFIG_AP
5cc4d64b 3666 if (params->mode == IEEE80211_MODE_AP)
1581b38b
JM
3667 return wpa_driver_nl80211_ap(drv, params);
3668#endif /* CONFIG_AP */
3669
5cc4d64b
JM
3670 if (params->mode == IEEE80211_MODE_IBSS)
3671 return wpa_driver_nl80211_ibss(drv, params);
3672
4a867032
JM
3673 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME)) {
3674 if (wpa_driver_nl80211_set_mode(drv, params->mode) < 0)
3675 return -1;
cfaab580 3676 return wpa_driver_nl80211_connect(drv, params);
4a867032 3677 }
cfaab580 3678
c2a04078
JM
3679 drv->associated = 0;
3680
3681 msg = nlmsg_alloc();
3682 if (!msg)
3683 return -1;
3684
3685 wpa_printf(MSG_DEBUG, "nl80211: Associate (ifindex=%d)",
3686 drv->ifindex);
3687 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
3688 NL80211_CMD_ASSOCIATE, 0);
3689
3690 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
3691 if (params->bssid) {
3692 wpa_printf(MSG_DEBUG, " * bssid=" MACSTR,
3693 MAC2STR(params->bssid));
3694 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid);
3695 }
3696 if (params->freq) {
3697 wpa_printf(MSG_DEBUG, " * freq=%d", params->freq);
3698 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq);
3699 }
3700 if (params->ssid) {
3701 wpa_hexdump_ascii(MSG_DEBUG, " * SSID",
3702 params->ssid, params->ssid_len);
3703 NLA_PUT(msg, NL80211_ATTR_SSID, params->ssid_len,
3704 params->ssid);
fd05d64e
JM
3705 if (params->ssid_len > sizeof(drv->ssid))
3706 goto nla_put_failure;
3707 os_memcpy(drv->ssid, params->ssid, params->ssid_len);
3708 drv->ssid_len = params->ssid_len;
c2a04078
JM
3709 }
3710 wpa_hexdump(MSG_DEBUG, " * IEs", params->wpa_ie, params->wpa_ie_len);
3711 if (params->wpa_ie)
3712 NLA_PUT(msg, NL80211_ATTR_IE, params->wpa_ie_len,
3713 params->wpa_ie);
3714
e572fa33
JM
3715#ifdef CONFIG_IEEE80211W
3716 if (params->mgmt_frame_protection == MGMT_FRAME_PROTECTION_REQUIRED)
3717 NLA_PUT_U32(msg, NL80211_ATTR_USE_MFP, NL80211_MFP_REQUIRED);
3718#endif /* CONFIG_IEEE80211W */
3719
01652550
JM
3720 NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT);
3721
62fa124c
JM
3722 if (params->prev_bssid) {
3723 wpa_printf(MSG_DEBUG, " * prev_bssid=" MACSTR,
3724 MAC2STR(params->prev_bssid));
3725 NLA_PUT(msg, NL80211_ATTR_PREV_BSSID, ETH_ALEN,
3726 params->prev_bssid);
3727 }
3728
c2a04078
JM
3729 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
3730 msg = NULL;
3731 if (ret) {
3732 wpa_printf(MSG_DEBUG, "nl80211: MLME command failed: ret=%d "
3733 "(%s)", ret, strerror(-ret));
3734 goto nla_put_failure;
3735 }
3736 ret = 0;
3737 wpa_printf(MSG_DEBUG, "nl80211: Association request send "
3738 "successfully");
3739
3740nla_put_failure:
3741 nlmsg_free(msg);
3742 return ret;
3743}
3f5285e8
JM
3744
3745
ad1e68e6
JM
3746static int nl80211_set_mode(struct wpa_driver_nl80211_data *drv,
3747 int ifindex, int mode)
3f5285e8 3748{
3f5285e8 3749 struct nl_msg *msg;
ad1e68e6
JM
3750 int ret = -ENOBUFS;
3751
3752 msg = nlmsg_alloc();
3753 if (!msg)
3754 return -ENOMEM;
3755
3756 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
3757 0, NL80211_CMD_SET_INTERFACE, 0);
3758 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
3759 NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, mode);
3760
3761 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
3762 if (!ret)
3763 return 0;
3764nla_put_failure:
3765 wpa_printf(MSG_DEBUG, "nl80211: Failed to set interface %d to mode %d:"
3766 " %d (%s)", ifindex, mode, ret, strerror(-ret));
3767 return ret;
3768}
3769
3770
3771static int wpa_driver_nl80211_set_mode(void *priv, int mode)
3772{
3773 struct wpa_driver_nl80211_data *drv = priv;
3774 int ret = -1;
1581b38b
JM
3775 int nlmode;
3776
3777 switch (mode) {
3778 case 0:
3779 nlmode = NL80211_IFTYPE_STATION;
3780 break;
3781 case 1:
3782 nlmode = NL80211_IFTYPE_ADHOC;
3783 break;
3784 case 2:
3785 nlmode = NL80211_IFTYPE_AP;
3786 break;
3787 default:
3788 return -1;
3789 }
3f5285e8 3790
ad1e68e6
JM
3791 if (nl80211_set_mode(drv, drv->ifindex, nlmode) == 0) {
3792 drv->nlmode = nlmode;
460456f8
JM
3793 ret = 0;
3794 goto done;
ad1e68e6 3795 }
3f5285e8 3796
460456f8
JM
3797 if (nlmode == drv->nlmode) {
3798 ret = 0;
3799 goto done; /* Already in the requested mode */
3800 }
3f5285e8 3801
3f5285e8
JM
3802 /* mac80211 doesn't allow mode changes while the device is up, so
3803 * take the device down, try to set the mode again, and bring the
3804 * device back up.
3805 */
2135f224 3806 if (hostapd_set_iface_flags(drv, drv->ifname, 0) == 0) {
3f5285e8 3807 /* Try to set the mode again while the interface is down */
ad1e68e6 3808 ret = nl80211_set_mode(drv, drv->ifindex, nlmode);
2135f224
JM
3809 if (hostapd_set_iface_flags(drv, drv->ifname, 1))
3810 ret = -1;
3f5285e8
JM
3811 }
3812
ad1e68e6
JM
3813 if (!ret)
3814 drv->nlmode = nlmode;
3815
460456f8
JM
3816done:
3817#if defined(CONFIG_AP) || defined(HOSTAPD)
3818 if (!ret && nlmode == NL80211_IFTYPE_AP) {
3819 /* Setup additional AP mode functionality if needed */
3820 if (drv->monitor_ifidx < 0 &&
3821 nl80211_create_monitor_interface(drv))
3822 return -1;
3823 } else if (!ret && nlmode != NL80211_IFTYPE_AP) {
3824 /* Remove additional AP mode functionality */
3825 nl80211_remove_monitor_interface(drv);
3826 }
3827#endif /* CONFIG_AP || HOSTAPD */
3828
3f5285e8
JM
3829 return ret;
3830}
3831
3832
3f5285e8
JM
3833static int wpa_driver_nl80211_get_capa(void *priv,
3834 struct wpa_driver_capa *capa)
3835{
3836 struct wpa_driver_nl80211_data *drv = priv;
3837 if (!drv->has_capability)
3838 return -1;
3839 os_memcpy(capa, &drv->capa, sizeof(*capa));
3840 return 0;
3841}
3842
3843
3844static int wpa_driver_nl80211_set_operstate(void *priv, int state)
3845{
3846 struct wpa_driver_nl80211_data *drv = priv;
3847
3848 wpa_printf(MSG_DEBUG, "%s: operstate %d->%d (%s)",
3849 __func__, drv->operstate, state, state ? "UP" : "DORMANT");
3850 drv->operstate = state;
3851 return wpa_driver_nl80211_send_oper_ifla(
3852 drv, -1, state ? IF_OPER_UP : IF_OPER_DORMANT);
3853}
3854
01652550
JM
3855
3856static int wpa_driver_nl80211_set_supp_port(void *priv, int authorized)
3857{
3858 struct wpa_driver_nl80211_data *drv = priv;
3859 struct nl_msg *msg;
3860 struct nl80211_sta_flag_update upd;
3861
3862 msg = nlmsg_alloc();
3863 if (!msg)
3864 return -ENOMEM;
3865
3866 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
3867 0, NL80211_CMD_SET_STATION, 0);
3868
3869 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
3870 if_nametoindex(drv->ifname));
3871 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, drv->bssid);
3872
3873 os_memset(&upd, 0, sizeof(upd));
3874 upd.mask = BIT(NL80211_STA_FLAG_AUTHORIZED);
3875 if (authorized)
3876 upd.set = BIT(NL80211_STA_FLAG_AUTHORIZED);
3877 NLA_PUT(msg, NL80211_ATTR_STA_FLAGS2, sizeof(upd), &upd);
3878
3879 return send_and_recv_msgs(drv, msg, NULL, NULL);
3880 nla_put_failure:
3881 return -ENOBUFS;
3882}
3883
3f5285e8 3884
c5121837
JM
3885#ifdef HOSTAPD
3886
c5121837 3887static struct i802_bss * get_bss(struct wpa_driver_nl80211_data *drv,
b4fd6fab 3888 int ifindex)
c5121837
JM
3889{
3890 struct i802_bss *bss = &drv->bss;
3891 while (bss) {
b4fd6fab 3892 if (ifindex == bss->ifindex)
c5121837
JM
3893 return bss;
3894 bss = bss->next;
3895 }
b4fd6fab 3896 wpa_printf(MSG_DEBUG, "nl80211: get_bss(%d) failed", ifindex);
c5121837
JM
3897 return NULL;
3898}
3899
3900
3901static void add_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
3902{
3903 int i;
3904 int *old;
3905
3906 wpa_printf(MSG_DEBUG, "nl80211: Add own interface ifindex %d",
3907 ifidx);
3908 for (i = 0; i < drv->num_if_indices; i++) {
3909 if (drv->if_indices[i] == 0) {
3910 drv->if_indices[i] = ifidx;
3911 return;
3912 }
3913 }
3914
3915 if (drv->if_indices != drv->default_if_indices)
3916 old = drv->if_indices;
3917 else
3918 old = NULL;
3919
3920 drv->if_indices = realloc(old,
3921 sizeof(int) * (drv->num_if_indices + 1));
3922 if (!drv->if_indices) {
3923 if (!old)
3924 drv->if_indices = drv->default_if_indices;
3925 else
3926 drv->if_indices = old;
3927 wpa_printf(MSG_ERROR, "Failed to reallocate memory for "
3928 "interfaces");
3929 wpa_printf(MSG_ERROR, "Ignoring EAPOL on interface %d", ifidx);
3930 return;
3931 }
3932 drv->if_indices[drv->num_if_indices] = ifidx;
3933 drv->num_if_indices++;
3934}
3935
3936
3937static void del_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
3938{
3939 int i;
3940
3941 for (i = 0; i < drv->num_if_indices; i++) {
3942 if (drv->if_indices[i] == ifidx) {
3943 drv->if_indices[i] = 0;
3944 break;
3945 }
3946 }
3947}
3948
3949
3950static int have_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
3951{
3952 int i;
3953
3954 for (i = 0; i < drv->num_if_indices; i++)
3955 if (drv->if_indices[i] == ifidx)
3956 return 1;
3957
3958 return 0;
3959}
3960
3961
c5121837
JM
3962static inline int min_int(int a, int b)
3963{
3964 if (a < b)
3965 return a;
3966 return b;
3967}
3968
3969
3970static int get_key_handler(struct nl_msg *msg, void *arg)
3971{
3972 struct nlattr *tb[NL80211_ATTR_MAX + 1];
3973 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
3974
3975 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
3976 genlmsg_attrlen(gnlh, 0), NULL);
3977
3978 /*
3979 * TODO: validate the key index and mac address!
3980 * Otherwise, there's a race condition as soon as
3981 * the kernel starts sending key notifications.
3982 */
3983
3984 if (tb[NL80211_ATTR_KEY_SEQ])
3985 memcpy(arg, nla_data(tb[NL80211_ATTR_KEY_SEQ]),
3986 min_int(nla_len(tb[NL80211_ATTR_KEY_SEQ]), 6));
3987 return NL_SKIP;
3988}
3989
3990
3991static int i802_get_seqnum(const char *iface, void *priv, const u8 *addr,
3992 int idx, u8 *seq)
3993{
3994 struct wpa_driver_nl80211_data *drv = priv;
3995 struct nl_msg *msg;
3996
3997 msg = nlmsg_alloc();
3998 if (!msg)
3999 return -ENOMEM;
4000
4001 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
4002 0, NL80211_CMD_GET_KEY, 0);
4003
4004 if (addr)
4005 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
4006 NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, idx);
4007 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(iface));
4008
4009 memset(seq, 0, 6);
4010
4011 return send_and_recv_msgs(drv, msg, get_key_handler, seq);
4012 nla_put_failure:
4013 return -ENOBUFS;
4014}
4015
4016
4017static int i802_set_rate_sets(void *priv, int *supp_rates, int *basic_rates,
4018 int mode)
4019{
4020 struct wpa_driver_nl80211_data *drv = priv;
4021 struct nl_msg *msg;
4022 u8 rates[NL80211_MAX_SUPP_RATES];
4023 u8 rates_len = 0;
4024 int i;
4025
4026 msg = nlmsg_alloc();
4027 if (!msg)
4028 return -ENOMEM;
4029
4030 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
4031 NL80211_CMD_SET_BSS, 0);
4032
4033 for (i = 0; i < NL80211_MAX_SUPP_RATES && basic_rates[i] >= 0; i++)
4034 rates[rates_len++] = basic_rates[i] / 5;
4035
4036 NLA_PUT(msg, NL80211_ATTR_BSS_BASIC_RATES, rates_len, rates);
4037
4038 /* TODO: multi-BSS support */
4039 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(drv->ifname));
4040
4041 return send_and_recv_msgs(drv, msg, NULL, NULL);
4042 nla_put_failure:
4043 return -ENOBUFS;
4044}
4045
4046
c5121837
JM
4047/* Set kernel driver on given frequency (MHz) */
4048static int i802_set_freq(void *priv, struct hostapd_freq_params *freq)
4049{
4050 struct wpa_driver_nl80211_data *drv = priv;
f019981a
JM
4051 return wpa_driver_nl80211_set_freq(drv, freq->freq, freq->ht_enabled,
4052 freq->sec_channel_offset);
c5121837
JM
4053}
4054
4055
4056static int i802_set_rts(void *priv, int rts)
4057{
4058 struct wpa_driver_nl80211_data *drv = priv;
ad649451
JM
4059 struct nl_msg *msg;
4060 int ret = -ENOBUFS;
4061 u32 val;
c5121837 4062
ad649451
JM
4063 msg = nlmsg_alloc();
4064 if (!msg)
4065 return -ENOMEM;
c5121837 4066
ad649451
JM
4067 if (rts >= 2347)
4068 val = (u32) -1;
4069 else
4070 val = rts;
c5121837 4071
ad649451
JM
4072 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
4073 0, NL80211_CMD_SET_WIPHY, 0);
4074 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
4075 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, val);
4076
4077 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
4078 if (!ret)
4079 return 0;
4080nla_put_failure:
4081 wpa_printf(MSG_DEBUG, "nl80211: Failed to set RTS threshold %d: "
4082 "%d (%s)", rts, ret, strerror(-ret));
4083 return ret;
c5121837
JM
4084}
4085
4086
4087static int i802_set_frag(void *priv, int frag)
4088{
4089 struct wpa_driver_nl80211_data *drv = priv;
ad649451
JM
4090 struct nl_msg *msg;
4091 int ret = -ENOBUFS;
4092 u32 val;
c5121837 4093
ad649451
JM
4094 msg = nlmsg_alloc();
4095 if (!msg)
4096 return -ENOMEM;
c5121837 4097
ad649451
JM
4098 if (frag >= 2346)
4099 val = (u32) -1;
4100 else
4101 val = frag;
c5121837 4102
ad649451
JM
4103 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
4104 0, NL80211_CMD_SET_WIPHY, 0);
4105 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
4106 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD, val);
4107
4108 ret = send_and_recv_msgs(drv, msg, NULL, NULL);
4109 if (!ret)
4110 return 0;
4111nla_put_failure:
4112 wpa_printf(MSG_DEBUG, "nl80211: Failed to set fragmentation threshold "
4113 "%d: %d (%s)", frag, ret, strerror(-ret));
4114 return ret;
c5121837
JM
4115}
4116
4117
c5121837
JM
4118static int i802_flush(void *priv)
4119{
4120 struct wpa_driver_nl80211_data *drv = priv;
4121 struct nl_msg *msg;
4122
4123 msg = nlmsg_alloc();
4124 if (!msg)
4125 return -1;
4126
4127 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
4128 0, NL80211_CMD_DEL_STATION, 0);
4129
4130 /*
4131 * XXX: FIX! this needs to flush all VLANs too
4132 */
4133 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
4134 if_nametoindex(drv->ifname));
4135
4136 return send_and_recv_msgs(drv, msg, NULL, NULL);
4137 nla_put_failure:
4138 return -ENOBUFS;
4139}
4140
4141
4142static int get_sta_handler(struct nl_msg *msg, void *arg)
4143{
4144 struct nlattr *tb[NL80211_ATTR_MAX + 1];
4145 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
4146 struct hostap_sta_driver_data *data = arg;
4147 struct nlattr *stats[NL80211_STA_INFO_MAX + 1];
4148 static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
4149 [NL80211_STA_INFO_INACTIVE_TIME] = { .type = NLA_U32 },
4150 [NL80211_STA_INFO_RX_BYTES] = { .type = NLA_U32 },
4151 [NL80211_STA_INFO_TX_BYTES] = { .type = NLA_U32 },
4152 [NL80211_STA_INFO_RX_PACKETS] = { .type = NLA_U32 },
4153 [NL80211_STA_INFO_TX_PACKETS] = { .type = NLA_U32 },
4154 };
4155
4156 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
4157 genlmsg_attrlen(gnlh, 0), NULL);
4158
4159 /*
4160 * TODO: validate the interface and mac address!
4161 * Otherwise, there's a race condition as soon as
4162 * the kernel starts sending station notifications.
4163 */
4164
4165 if (!tb[NL80211_ATTR_STA_INFO]) {
4166 wpa_printf(MSG_DEBUG, "sta stats missing!");
4167 return NL_SKIP;
4168 }
4169 if (nla_parse_nested(stats, NL80211_STA_INFO_MAX,
4170 tb[NL80211_ATTR_STA_INFO],
4171 stats_policy)) {
4172 wpa_printf(MSG_DEBUG, "failed to parse nested attributes!");
4173 return NL_SKIP;
4174 }
4175
4176 if (stats[NL80211_STA_INFO_INACTIVE_TIME])
4177 data->inactive_msec =
4178 nla_get_u32(stats[NL80211_STA_INFO_INACTIVE_TIME]);
4179 if (stats[NL80211_STA_INFO_RX_BYTES])
4180 data->rx_bytes = nla_get_u32(stats[NL80211_STA_INFO_RX_BYTES]);
4181 if (stats[NL80211_STA_INFO_TX_BYTES])
4182 data->tx_bytes = nla_get_u32(stats[NL80211_STA_INFO_TX_BYTES]);
4183 if (stats[NL80211_STA_INFO_RX_PACKETS])
4184 data->rx_packets =
4185 nla_get_u32(stats[NL80211_STA_INFO_RX_PACKETS]);
4186 if (stats[NL80211_STA_INFO_TX_PACKETS])
4187 data->tx_packets =
4188 nla_get_u32(stats[NL80211_STA_INFO_TX_PACKETS]);
4189
4190 return NL_SKIP;
4191}
4192
4193static int i802_read_sta_data(void *priv, struct hostap_sta_driver_data *data,
4194 const u8 *addr)
4195{
4196 struct wpa_driver_nl80211_data *drv = priv;
4197 struct nl_msg *msg;
4198
4199 os_memset(data, 0, sizeof(*data));
4200 msg = nlmsg_alloc();
4201 if (!msg)
4202 return -ENOMEM;
4203
4204 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
4205 0, NL80211_CMD_GET_STATION, 0);
4206
4207 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
4208 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(drv->ifname));
4209
4210 return send_and_recv_msgs(drv, msg, get_sta_handler, data);
4211 nla_put_failure:
4212 return -ENOBUFS;
4213}
4214
4215
c5121837
JM
4216static int i802_set_tx_queue_params(void *priv, int queue, int aifs,
4217 int cw_min, int cw_max, int burst_time)
4218{
4219 struct wpa_driver_nl80211_data *drv = priv;
4220 struct nl_msg *msg;
4221 struct nlattr *txq, *params;
4222
4223 msg = nlmsg_alloc();
4224 if (!msg)
4225 return -1;
4226
4227 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
4228 0, NL80211_CMD_SET_WIPHY, 0);
4229
4230 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(drv->ifname));
4231
4232 txq = nla_nest_start(msg, NL80211_ATTR_WIPHY_TXQ_PARAMS);
4233 if (!txq)
4234 goto nla_put_failure;
4235
4236 /* We are only sending parameters for a single TXQ at a time */
4237 params = nla_nest_start(msg, 1);
4238 if (!params)
4239 goto nla_put_failure;
4240
4241 NLA_PUT_U8(msg, NL80211_TXQ_ATTR_QUEUE, queue);
4242 /* Burst time is configured in units of 0.1 msec and TXOP parameter in
4243 * 32 usec, so need to convert the value here. */
4244 NLA_PUT_U16(msg, NL80211_TXQ_ATTR_TXOP, (burst_time * 100 + 16) / 32);
4245 NLA_PUT_U16(msg, NL80211_TXQ_ATTR_CWMIN, cw_min);
4246 NLA_PUT_U16(msg, NL80211_TXQ_ATTR_CWMAX, cw_max);
4247 NLA_PUT_U8(msg, NL80211_TXQ_ATTR_AIFS, aifs);
4248
4249 nla_nest_end(msg, params);
4250
4251 nla_nest_end(msg, txq);
4252
4253 if (send_and_recv_msgs(drv, msg, NULL, NULL) == 0)
4254 return 0;
4255 nla_put_failure:
4256 return -1;
4257}
4258
4259
c5121837
JM
4260static int i802_bss_add(void *priv, const char *ifname, const u8 *bssid)
4261{
4262 struct wpa_driver_nl80211_data *drv = priv;
4263 int ifidx;
4264 struct i802_bss *bss;
4265
4266 bss = os_zalloc(sizeof(*bss));
4267 if (bss == NULL)
4268 return -1;
c5121837
JM
4269
4270 ifidx = nl80211_create_iface(priv, ifname, NL80211_IFTYPE_AP, bssid);
4271 if (ifidx < 0) {
4272 os_free(bss);
4273 return -1;
4274 }
6d550fbe 4275 bss->ifindex = ifidx;
c5121837
JM
4276 if (hostapd_set_iface_flags(priv, ifname, 1)) {
4277 nl80211_remove_iface(priv, ifidx);
4278 os_free(bss);
4279 return -1;
4280 }
4281 bss->next = drv->bss.next;
4282 drv->bss.next = bss;
4283 return 0;
4284}
4285
4286
4287static int i802_bss_remove(void *priv, const char *ifname)
4288{
4289 struct wpa_driver_nl80211_data *drv = priv;
4290 struct i802_bss *bss, *prev;
b4fd6fab
JM
4291 int ifindex = if_nametoindex(ifname);
4292 nl80211_remove_iface(priv, ifindex);
c5121837
JM
4293 prev = &drv->bss;
4294 bss = drv->bss.next;
4295 while (bss) {
b4fd6fab 4296 if (ifindex == bss->ifindex) {
c5121837
JM
4297 prev->next = bss->next;
4298 os_free(bss);
4299 break;
4300 }
4301 prev = bss;
4302 bss = bss->next;
4303 }
4304 return 0;
4305}
4306
4307
c5121837
JM
4308static int i802_set_bss(void *priv, int cts, int preamble, int slot)
4309{
4310 struct wpa_driver_nl80211_data *drv = priv;
4311 struct nl_msg *msg;
4312
4313 msg = nlmsg_alloc();
4314 if (!msg)
4315 return -ENOMEM;
4316
4317 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
4318 NL80211_CMD_SET_BSS, 0);
4319
4320 if (cts >= 0)
4321 NLA_PUT_U8(msg, NL80211_ATTR_BSS_CTS_PROT, cts);
4322 if (preamble >= 0)
4323 NLA_PUT_U8(msg, NL80211_ATTR_BSS_SHORT_PREAMBLE, preamble);
4324 if (slot >= 0)
4325 NLA_PUT_U8(msg, NL80211_ATTR_BSS_SHORT_SLOT_TIME, slot);
4326
4327 /* TODO: multi-BSS support */
4328 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(drv->ifname));
4329
4330 return send_and_recv_msgs(drv, msg, NULL, NULL);
4331 nla_put_failure:
4332 return -ENOBUFS;
4333}
4334
4335
4336static int i802_set_cts_protect(void *priv, int value)
4337{
4338 return i802_set_bss(priv, value, -1, -1);
4339}
4340
4341
4342static int i802_set_preamble(void *priv, int value)
4343{
4344 return i802_set_bss(priv, -1, value, -1);
4345}
4346
4347
4348static int i802_set_short_slot_time(void *priv, int value)
4349{
4350 return i802_set_bss(priv, -1, -1, value);
4351}
4352
4353
4354static enum nl80211_iftype i802_if_type(enum hostapd_driver_if_type type)
4355{
4356 switch (type) {
4357 case HOSTAPD_IF_VLAN:
4358 return NL80211_IFTYPE_AP_VLAN;
c5121837
JM
4359 }
4360 return -1;
4361}
4362
4363
4364static int i802_if_add(const char *iface, void *priv,
4365 enum hostapd_driver_if_type type, char *ifname,
4366 const u8 *addr)
4367{
4368 if (nl80211_create_iface(priv, ifname, i802_if_type(type), addr) < 0)
4369 return -1;
4370 return 0;
4371}
4372
4373
c5121837
JM
4374static int i802_if_remove(void *priv, enum hostapd_driver_if_type type,
4375 const char *ifname, const u8 *addr)
4376{
4377 nl80211_remove_iface(priv, if_nametoindex(ifname));
4378 return 0;
4379}
4380
4381
c5121837
JM
4382static int i802_set_sta_vlan(void *priv, const u8 *addr,
4383 const char *ifname, int vlan_id)
4384{
4385 struct wpa_driver_nl80211_data *drv = priv;
4386 struct nl_msg *msg;
4387
4388 msg = nlmsg_alloc();
4389 if (!msg)
4390 return -ENOMEM;
4391
4392 genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
4393 0, NL80211_CMD_SET_STATION, 0);
4394
4395 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
4396 if_nametoindex(drv->ifname));
4397 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
1c766b09 4398 NLA_PUT_U32(msg, NL80211_ATTR_STA_VLAN,
c5121837
JM
4399 if_nametoindex(ifname));
4400
4401 return send_and_recv_msgs(drv, msg, NULL, NULL);
4402 nla_put_failure:
4403 return -ENOBUFS;
4404}
4405
4406
c5121837
JM
4407static void handle_eapol(int sock, void *eloop_ctx, void *sock_ctx)
4408{
4409 struct wpa_driver_nl80211_data *drv = eloop_ctx;
4410 struct sockaddr_ll lladdr;
4411 unsigned char buf[3000];
4412 int len;
4413 socklen_t fromlen = sizeof(lladdr);
4414
4415 len = recvfrom(sock, buf, sizeof(buf), 0,
4416 (struct sockaddr *)&lladdr, &fromlen);
4417 if (len < 0) {
4418 perror("recv");
4419 return;
4420 }
4421
4422 if (have_ifidx(drv, lladdr.sll_ifindex)) {
4b9841d3
JM
4423 void *ctx;
4424 ctx = hostapd_sta_get_bss(drv->ctx, lladdr.sll_addr);
4425 if (!ctx)
c5121837 4426 return;
4b9841d3 4427 hostapd_eapol_receive(ctx, lladdr.sll_addr, buf, len);
c5121837
JM
4428 }
4429}
4430
4431
c5121837
JM
4432static int i802_get_inact_sec(void *priv, const u8 *addr)
4433{
4434 struct hostap_sta_driver_data data;
4435 int ret;
4436
4437 data.inactive_msec = (unsigned long) -1;
4438 ret = i802_read_sta_data(priv, &data, addr);
4439 if (ret || data.inactive_msec == (unsigned long) -1)
4440 return -1;
4441 return data.inactive_msec / 1000;
4442}
4443
4444
4445static int i802_sta_clear_stats(void *priv, const u8 *addr)
4446{
4447#if 0
4448 /* TODO */
4449#endif
4450 return 0;
4451}
4452
4453
731723a5
JM
4454static int i802_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr,
4455 int reason)
c5121837
JM
4456{
4457 struct wpa_driver_nl80211_data *drv = priv;
4458 struct ieee80211_mgmt mgmt;
4459
4460 memset(&mgmt, 0, sizeof(mgmt));
4461 mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
4462 WLAN_FC_STYPE_DEAUTH);
4463 memcpy(mgmt.da, addr, ETH_ALEN);
731723a5
JM
4464 memcpy(mgmt.sa, own_addr, ETH_ALEN);
4465 memcpy(mgmt.bssid, own_addr, ETH_ALEN);
c5121837 4466 mgmt.u.deauth.reason_code = host_to_le16(reason);
9f324b61
JM
4467 return wpa_driver_nl80211_send_mlme(drv, (u8 *) &mgmt,
4468 IEEE80211_HDRLEN +
4469 sizeof(mgmt.u.deauth));
c5121837
JM
4470}
4471
4472
731723a5
JM
4473static int i802_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr,
4474 int reason)
c5121837
JM
4475{
4476 struct wpa_driver_nl80211_data *drv = priv;
4477 struct ieee80211_mgmt mgmt;
4478
4479 memset(&mgmt, 0, sizeof(mgmt));
4480 mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
4481 WLAN_FC_STYPE_DISASSOC);
4482 memcpy(mgmt.da, addr, ETH_ALEN);
731723a5
JM
4483 memcpy(mgmt.sa, own_addr, ETH_ALEN);
4484 memcpy(mgmt.bssid, own_addr, ETH_ALEN);
c5121837 4485 mgmt.u.disassoc.reason_code = host_to_le16(reason);
9f324b61
JM
4486 return wpa_driver_nl80211_send_mlme(drv, (u8 *) &mgmt,
4487 IEEE80211_HDRLEN +
4488 sizeof(mgmt.u.disassoc));
c5121837
JM
4489}
4490
4491
92f475b4
JM
4492static void *i802_init(struct hostapd_data *hapd,
4493 struct wpa_init_params *params)
c5121837
JM
4494{
4495 struct wpa_driver_nl80211_data *drv;
4496 size_t i;
4497
bbaf0837
JM
4498 drv = wpa_driver_nl80211_init(hapd, params->ifname);
4499 if (drv == NULL)
c5121837 4500 return NULL;
c5121837 4501
b4fd6fab 4502 drv->bss.ifindex = drv->ifindex;
c5121837
JM
4503
4504 drv->num_if_indices = sizeof(drv->default_if_indices) / sizeof(int);
4505 drv->if_indices = drv->default_if_indices;
92f475b4
JM
4506 for (i = 0; i < params->num_bridge; i++) {
4507 if (params->bridge[i])
4508 add_ifidx(drv, if_nametoindex(params->bridge[i]));
c5121837 4509 }
c5121837 4510
ad1e68e6
JM
4511 /* start listening for EAPOL on the default AP interface */
4512 add_ifidx(drv, drv->ifindex);
4513
6980c191
FF
4514 if (hostapd_set_iface_flags(drv, drv->ifname, 0))
4515 goto failed;
ad1e68e6 4516
6980c191 4517 if (params->bssid) {
460456f8
JM
4518 if (set_ifhwaddr(drv, drv->ifname, params->bssid))
4519 goto failed;
4520 }
ad1e68e6 4521
4a867032 4522 if (wpa_driver_nl80211_set_mode(drv, IEEE80211_MODE_AP)) {
ad1e68e6
JM
4523 wpa_printf(MSG_ERROR, "nl80211: Failed to set interface %s "
4524 "into AP mode", drv->ifname);
bbaf0837 4525 goto failed;
ad1e68e6
JM
4526 }
4527
4528 if (hostapd_set_iface_flags(drv, drv->ifname, 1))
bbaf0837 4529 goto failed;
ad1e68e6
JM
4530
4531 drv->eapol_sock = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_PAE));
4532 if (drv->eapol_sock < 0) {
4533 perror("socket(PF_PACKET, SOCK_DGRAM, ETH_P_PAE)");
bbaf0837 4534 goto failed;
ad1e68e6
JM
4535 }
4536
4537 if (eloop_register_read_sock(drv->eapol_sock, handle_eapol, drv, NULL))
4538 {
4539 printf("Could not register read socket for eapol\n");
c5121837 4540 goto failed;
ad1e68e6
JM
4541 }
4542
412036f5 4543 if (get_ifhwaddr(drv, drv->ifname, params->own_addr))
bbaf0837 4544 goto failed;
c5121837 4545
c5121837
JM
4546 return drv;
4547
4548failed:
460456f8 4549 nl80211_remove_monitor_interface(drv);
c5121837
JM
4550 if (drv->ioctl_sock >= 0)
4551 close(drv->ioctl_sock);
c5121837
JM
4552
4553 genl_family_put(drv->nl80211);
4554 nl_cache_free(drv->nl_cache);
4555 nl_handle_destroy(drv->nl_handle);
4556 nl_cb_put(drv->nl_cb);
4557
bbaf0837
JM
4558 os_free(drv);
4559 return NULL;
4560}
c5121837 4561
c5121837 4562
bbaf0837
JM
4563static void i802_deinit(void *priv)
4564{
4565 wpa_driver_nl80211_deinit(priv);
c5121837
JM
4566}
4567
4568#endif /* HOSTAPD */
4569
4570
3f5285e8
JM
4571const struct wpa_driver_ops wpa_driver_nl80211_ops = {
4572 .name = "nl80211",
4573 .desc = "Linux nl80211/cfg80211",
4574 .get_bssid = wpa_driver_nl80211_get_bssid,
4575 .get_ssid = wpa_driver_nl80211_get_ssid,
3f5285e8 4576 .set_key = wpa_driver_nl80211_set_key,
6a1063e0 4577 .scan2 = wpa_driver_nl80211_scan,
3f5285e8
JM
4578 .get_scan_results2 = wpa_driver_nl80211_get_scan_results,
4579 .deauthenticate = wpa_driver_nl80211_deauthenticate,
4580 .disassociate = wpa_driver_nl80211_disassociate,
c2a04078 4581 .authenticate = wpa_driver_nl80211_authenticate,
3f5285e8 4582 .associate = wpa_driver_nl80211_associate,
3f5285e8
JM
4583 .init = wpa_driver_nl80211_init,
4584 .deinit = wpa_driver_nl80211_deinit,
3f5285e8
JM
4585 .get_capa = wpa_driver_nl80211_get_capa,
4586 .set_operstate = wpa_driver_nl80211_set_operstate,
01652550 4587 .set_supp_port = wpa_driver_nl80211_set_supp_port,
6d158490 4588 .set_country = wpa_driver_nl80211_set_country,
d2440ba0 4589 .set_beacon = wpa_driver_nl80211_set_beacon,
c3965310 4590#if defined(CONFIG_AP) || defined(HOSTAPD)
071f8ac4 4591 .send_mlme = wpa_driver_nl80211_send_mlme,
c3965310 4592 .get_hw_feature_data = wpa_driver_nl80211_get_hw_feature_data,
0f4e8b4f
JM
4593 .sta_add = wpa_driver_nl80211_sta_add,
4594 .sta_remove = wpa_driver_nl80211_sta_remove,
db149ac9 4595 .hapd_send_eapol = wpa_driver_nl80211_hapd_send_eapol,
a8d6ffa4 4596 .sta_set_flags = wpa_driver_nl80211_sta_set_flags,
c3965310 4597#endif /* CONFIG_AP || HOSTAPD */
c5121837
JM
4598#ifdef HOSTAPD
4599 .hapd_init = i802_init,
c5121837 4600 .hapd_deinit = i802_deinit,
c5121837
JM
4601 .get_seqnum = i802_get_seqnum,
4602 .flush = i802_flush,
4603 .read_sta_data = i802_read_sta_data,
c5121837
JM
4604 .sta_deauth = i802_sta_deauth,
4605 .sta_disassoc = i802_sta_disassoc,
c5121837
JM
4606 .get_inact_sec = i802_get_inact_sec,
4607 .sta_clear_stats = i802_sta_clear_stats,
4608 .set_freq = i802_set_freq,
4609 .set_rts = i802_set_rts,
4610 .set_frag = i802_set_frag,
c5121837 4611 .set_rate_sets = i802_set_rate_sets,
c5121837
JM
4612 .set_cts_protect = i802_set_cts_protect,
4613 .set_preamble = i802_set_preamble,
4614 .set_short_slot_time = i802_set_short_slot_time,
4615 .set_tx_queue_params = i802_set_tx_queue_params,
4616 .bss_add = i802_bss_add,
4617 .bss_remove = i802_bss_remove,
4618 .if_add = i802_if_add,
c5121837 4619 .if_remove = i802_if_remove,
c5121837 4620 .set_sta_vlan = i802_set_sta_vlan,
c5121837 4621#endif /* HOSTAPD */
3f5285e8 4622};