Line data Source code
1 : /*
2 : * Driver interaction with Linux nl80211/cfg80211
3 : * Copyright (c) 2002-2015, 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-2010, Atheros Communications
8 : *
9 : * This software may be distributed under the terms of the BSD license.
10 : * See README for more details.
11 : */
12 :
13 : #include "includes.h"
14 : #include <sys/types.h>
15 : #include <fcntl.h>
16 : #include <net/if.h>
17 : #include <netlink/genl/genl.h>
18 : #include <netlink/genl/ctrl.h>
19 : #ifdef CONFIG_LIBNL3_ROUTE
20 : #include <netlink/route/neighbour.h>
21 : #endif /* CONFIG_LIBNL3_ROUTE */
22 : #include <linux/rtnetlink.h>
23 : #include <netpacket/packet.h>
24 : #include <linux/errqueue.h>
25 :
26 : #include "common.h"
27 : #include "eloop.h"
28 : #include "common/qca-vendor.h"
29 : #include "common/qca-vendor-attr.h"
30 : #include "common/ieee802_11_defs.h"
31 : #include "common/ieee802_11_common.h"
32 : #include "l2_packet/l2_packet.h"
33 : #include "netlink.h"
34 : #include "linux_defines.h"
35 : #include "linux_ioctl.h"
36 : #include "radiotap.h"
37 : #include "radiotap_iter.h"
38 : #include "rfkill.h"
39 : #include "driver_nl80211.h"
40 :
41 :
42 : #ifndef CONFIG_LIBNL20
43 : /*
44 : * libnl 1.1 has a bug, it tries to allocate socket numbers densely
45 : * but when you free a socket again it will mess up its bitmap and
46 : * and use the wrong number the next time it needs a socket ID.
47 : * Therefore, we wrap the handle alloc/destroy and add our own pid
48 : * accounting.
49 : */
50 : static uint32_t port_bitmap[32] = { 0 };
51 :
52 : static struct nl_handle *nl80211_handle_alloc(void *cb)
53 : {
54 : struct nl_handle *handle;
55 : uint32_t pid = getpid() & 0x3FFFFF;
56 : int i;
57 :
58 : handle = nl_handle_alloc_cb(cb);
59 :
60 : for (i = 0; i < 1024; i++) {
61 : if (port_bitmap[i / 32] & (1 << (i % 32)))
62 : continue;
63 : port_bitmap[i / 32] |= 1 << (i % 32);
64 : pid += i << 22;
65 : break;
66 : }
67 :
68 : nl_socket_set_local_port(handle, pid);
69 :
70 : return handle;
71 : }
72 :
73 : static void nl80211_handle_destroy(struct nl_handle *handle)
74 : {
75 : uint32_t port = nl_socket_get_local_port(handle);
76 :
77 : port >>= 22;
78 : port_bitmap[port / 32] &= ~(1 << (port % 32));
79 :
80 : nl_handle_destroy(handle);
81 : }
82 : #endif /* CONFIG_LIBNL20 */
83 :
84 :
85 : #ifdef ANDROID
86 : /* system/core/libnl_2 does not include nl_socket_set_nonblocking() */
87 : #undef nl_socket_set_nonblocking
88 : #define nl_socket_set_nonblocking(h) android_nl_socket_set_nonblocking(h)
89 :
90 : #define genl_ctrl_resolve android_genl_ctrl_resolve
91 : #endif /* ANDROID */
92 :
93 :
94 4777 : static struct nl_handle * nl_create_handle(struct nl_cb *cb, const char *dbg)
95 : {
96 : struct nl_handle *handle;
97 :
98 4777 : handle = nl80211_handle_alloc(cb);
99 4777 : if (handle == NULL) {
100 0 : wpa_printf(MSG_ERROR, "nl80211: Failed to allocate netlink "
101 : "callbacks (%s)", dbg);
102 0 : return NULL;
103 : }
104 :
105 4777 : if (genl_connect(handle)) {
106 0 : wpa_printf(MSG_ERROR, "nl80211: Failed to connect to generic "
107 : "netlink (%s)", dbg);
108 0 : nl80211_handle_destroy(handle);
109 0 : return NULL;
110 : }
111 :
112 4777 : return handle;
113 : }
114 :
115 :
116 4777 : static void nl_destroy_handles(struct nl_handle **handle)
117 : {
118 4777 : if (*handle == NULL)
119 4777 : return;
120 4777 : nl80211_handle_destroy(*handle);
121 4777 : *handle = NULL;
122 : }
123 :
124 :
125 : #if __WORDSIZE == 64
126 : #define ELOOP_SOCKET_INVALID (intptr_t) 0x8888888888888889ULL
127 : #else
128 : #define ELOOP_SOCKET_INVALID (intptr_t) 0x88888889ULL
129 : #endif
130 :
131 4749 : static void nl80211_register_eloop_read(struct nl_handle **handle,
132 : eloop_sock_handler handler,
133 : void *eloop_data)
134 : {
135 : #ifdef CONFIG_LIBNL20
136 : /*
137 : * libnl uses a pretty small buffer (32 kB that gets converted to 64 kB)
138 : * by default. It is possible to hit that limit in some cases where
139 : * operations are blocked, e.g., with a burst of Deauthentication frames
140 : * to hostapd and STA entry deletion. Try to increase the buffer to make
141 : * this less likely to occur.
142 : */
143 4749 : if (nl_socket_set_buffer_size(*handle, 262144, 0) < 0) {
144 0 : wpa_printf(MSG_DEBUG,
145 : "nl80211: Could not set nl_socket RX buffer size: %s",
146 0 : strerror(errno));
147 : /* continue anyway with the default (smaller) buffer */
148 : }
149 : #endif /* CONFIG_LIBNL20 */
150 :
151 4749 : nl_socket_set_nonblocking(*handle);
152 4749 : eloop_register_read_sock(nl_socket_get_fd(*handle), handler,
153 : eloop_data, *handle);
154 4749 : *handle = (void *) (((intptr_t) *handle) ^ ELOOP_SOCKET_INVALID);
155 4749 : }
156 :
157 :
158 4749 : static void nl80211_destroy_eloop_handle(struct nl_handle **handle)
159 : {
160 4749 : *handle = (void *) (((intptr_t) *handle) ^ ELOOP_SOCKET_INVALID);
161 4749 : eloop_unregister_read_sock(nl_socket_get_fd(*handle));
162 4749 : nl_destroy_handles(handle);
163 4749 : }
164 :
165 :
166 : static void nl80211_global_deinit(void *priv);
167 : static void nl80211_check_global(struct nl80211_global *global);
168 :
169 : static void wpa_driver_nl80211_deinit(struct i802_bss *bss);
170 : static int wpa_driver_nl80211_set_mode_ibss(struct i802_bss *bss,
171 : struct hostapd_freq_params *freq);
172 :
173 : static int
174 : wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv,
175 : const u8 *set_addr, int first,
176 : const char *driver_params);
177 : static int nl80211_send_frame_cmd(struct i802_bss *bss,
178 : unsigned int freq, unsigned int wait,
179 : const u8 *buf, size_t buf_len, u64 *cookie,
180 : int no_cck, int no_ack, int offchanok);
181 : static int wpa_driver_nl80211_probe_req_report(struct i802_bss *bss,
182 : int report);
183 :
184 : static void add_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx);
185 : static void del_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx);
186 : static int have_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx);
187 :
188 : static int nl80211_set_channel(struct i802_bss *bss,
189 : struct hostapd_freq_params *freq, int set_chan);
190 : static int nl80211_disable_11b_rates(struct wpa_driver_nl80211_data *drv,
191 : int ifindex, int disabled);
192 :
193 : static int nl80211_leave_ibss(struct wpa_driver_nl80211_data *drv,
194 : int reset_mode);
195 :
196 : static int i802_set_iface_flags(struct i802_bss *bss, int up);
197 : static int nl80211_set_param(void *priv, const char *param);
198 :
199 :
200 : /* Converts nl80211_chan_width to a common format */
201 121 : enum chan_width convert2width(int width)
202 : {
203 121 : switch (width) {
204 : case NL80211_CHAN_WIDTH_20_NOHT:
205 17 : return CHAN_WIDTH_20_NOHT;
206 : case NL80211_CHAN_WIDTH_20:
207 68 : return CHAN_WIDTH_20;
208 : case NL80211_CHAN_WIDTH_40:
209 24 : return CHAN_WIDTH_40;
210 : case NL80211_CHAN_WIDTH_80:
211 7 : return CHAN_WIDTH_80;
212 : case NL80211_CHAN_WIDTH_80P80:
213 1 : return CHAN_WIDTH_80P80;
214 : case NL80211_CHAN_WIDTH_160:
215 4 : return CHAN_WIDTH_160;
216 : }
217 0 : return CHAN_WIDTH_UNKNOWN;
218 : }
219 :
220 :
221 37707 : int is_ap_interface(enum nl80211_iftype nlmode)
222 : {
223 37707 : return nlmode == NL80211_IFTYPE_AP ||
224 : nlmode == NL80211_IFTYPE_P2P_GO;
225 : }
226 :
227 :
228 12499 : int is_sta_interface(enum nl80211_iftype nlmode)
229 : {
230 12499 : return nlmode == NL80211_IFTYPE_STATION ||
231 : nlmode == NL80211_IFTYPE_P2P_CLIENT;
232 : }
233 :
234 :
235 9059 : static int is_p2p_net_interface(enum nl80211_iftype nlmode)
236 : {
237 9059 : return nlmode == NL80211_IFTYPE_P2P_CLIENT ||
238 : nlmode == NL80211_IFTYPE_P2P_GO;
239 : }
240 :
241 :
242 46 : struct i802_bss * get_bss_ifindex(struct wpa_driver_nl80211_data *drv,
243 : int ifindex)
244 : {
245 : struct i802_bss *bss;
246 :
247 46 : for (bss = drv->first_bss; bss; bss = bss->next) {
248 46 : if (bss->ifindex == ifindex)
249 46 : return bss;
250 : }
251 :
252 0 : return NULL;
253 : }
254 :
255 :
256 6993 : static int is_mesh_interface(enum nl80211_iftype nlmode)
257 : {
258 6993 : return nlmode == NL80211_IFTYPE_MESH_POINT;
259 : }
260 :
261 :
262 9786 : void nl80211_mark_disconnected(struct wpa_driver_nl80211_data *drv)
263 : {
264 9786 : if (drv->associated)
265 2556 : os_memcpy(drv->prev_bssid, drv->bssid, ETH_ALEN);
266 9786 : drv->associated = 0;
267 9786 : os_memset(drv->bssid, 0, ETH_ALEN);
268 9786 : }
269 :
270 :
271 : /* nl80211 code */
272 136900 : static int ack_handler(struct nl_msg *msg, void *arg)
273 : {
274 136900 : int *err = arg;
275 136900 : *err = 0;
276 136900 : return NL_STOP;
277 : }
278 :
279 16192 : static int finish_handler(struct nl_msg *msg, void *arg)
280 : {
281 16192 : int *ret = arg;
282 16192 : *ret = 0;
283 16192 : return NL_SKIP;
284 : }
285 :
286 26928 : static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err,
287 : void *arg)
288 : {
289 26928 : int *ret = arg;
290 26928 : *ret = err->error;
291 26928 : return NL_SKIP;
292 : }
293 :
294 :
295 1034007 : static int no_seq_check(struct nl_msg *msg, void *arg)
296 : {
297 1034007 : return NL_OK;
298 : }
299 :
300 :
301 7435 : static void nl80211_nlmsg_clear(struct nl_msg *msg)
302 : {
303 : /*
304 : * Clear nlmsg data, e.g., to make sure key material is not left in
305 : * heap memory for unnecessarily long time.
306 : */
307 7435 : if (msg) {
308 7435 : struct nlmsghdr *hdr = nlmsg_hdr(msg);
309 7435 : void *data = nlmsg_data(hdr);
310 : /*
311 : * This would use nlmsg_datalen() or the older nlmsg_len() if
312 : * only libnl were to maintain a stable API.. Neither will work
313 : * with all released versions, so just calculate the length
314 : * here.
315 : */
316 7435 : int len = hdr->nlmsg_len - NLMSG_HDRLEN;
317 :
318 7435 : os_memset(data, 0, len);
319 : }
320 7435 : }
321 :
322 :
323 180020 : static int send_and_recv(struct nl80211_global *global,
324 : struct nl_handle *nl_handle, struct nl_msg *msg,
325 : int (*valid_handler)(struct nl_msg *, void *),
326 : void *valid_data)
327 : {
328 : struct nl_cb *cb;
329 180020 : int err = -ENOMEM;
330 :
331 180020 : if (!msg)
332 0 : return -ENOMEM;
333 :
334 180020 : cb = nl_cb_clone(global->nl_cb);
335 180020 : if (!cb)
336 0 : goto out;
337 :
338 180020 : err = nl_send_auto_complete(nl_handle, msg);
339 180020 : if (err < 0)
340 0 : goto out;
341 :
342 180020 : err = 1;
343 :
344 180020 : nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
345 180020 : nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
346 180020 : nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);
347 :
348 180020 : if (valid_handler)
349 67134 : nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM,
350 : valid_handler, valid_data);
351 :
352 587422 : while (err > 0) {
353 227382 : int res = nl_recvmsgs(nl_handle, cb);
354 227382 : if (res < 0) {
355 0 : wpa_printf(MSG_INFO,
356 : "nl80211: %s->nl_recvmsgs failed: %d",
357 : __func__, res);
358 : }
359 : }
360 : out:
361 180020 : nl_cb_put(cb);
362 180020 : if (!valid_handler && valid_data == (void *) -1)
363 7435 : nl80211_nlmsg_clear(msg);
364 180020 : nlmsg_free(msg);
365 180020 : return err;
366 : }
367 :
368 :
369 145266 : int send_and_recv_msgs(struct wpa_driver_nl80211_data *drv,
370 : struct nl_msg *msg,
371 : int (*valid_handler)(struct nl_msg *, void *),
372 : void *valid_data)
373 : {
374 145266 : return send_and_recv(drv->global, drv->global->nl, msg,
375 : valid_handler, valid_data);
376 : }
377 :
378 :
379 : struct family_data {
380 : const char *group;
381 : int id;
382 : };
383 :
384 :
385 5024 : static int family_handler(struct nl_msg *msg, void *arg)
386 : {
387 5024 : struct family_data *res = arg;
388 : struct nlattr *tb[CTRL_ATTR_MAX + 1];
389 5024 : struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
390 : struct nlattr *mcgrp;
391 : int i;
392 :
393 5024 : nla_parse(tb, CTRL_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
394 : genlmsg_attrlen(gnlh, 0), NULL);
395 5024 : if (!tb[CTRL_ATTR_MCAST_GROUPS])
396 0 : return NL_SKIP;
397 :
398 35168 : nla_for_each_nested(mcgrp, tb[CTRL_ATTR_MCAST_GROUPS], i) {
399 : struct nlattr *tb2[CTRL_ATTR_MCAST_GRP_MAX + 1];
400 17584 : nla_parse(tb2, CTRL_ATTR_MCAST_GRP_MAX, nla_data(mcgrp),
401 : nla_len(mcgrp), NULL);
402 35168 : if (!tb2[CTRL_ATTR_MCAST_GRP_NAME] ||
403 35168 : !tb2[CTRL_ATTR_MCAST_GRP_ID] ||
404 17584 : os_strncmp(nla_data(tb2[CTRL_ATTR_MCAST_GRP_NAME]),
405 : res->group,
406 : nla_len(tb2[CTRL_ATTR_MCAST_GRP_NAME])) != 0)
407 12560 : continue;
408 5024 : res->id = nla_get_u32(tb2[CTRL_ATTR_MCAST_GRP_ID]);
409 5024 : break;
410 : };
411 :
412 5024 : return NL_SKIP;
413 : }
414 :
415 :
416 5024 : static int nl_get_multicast_id(struct nl80211_global *global,
417 : const char *family, const char *group)
418 : {
419 : struct nl_msg *msg;
420 : int ret;
421 5024 : struct family_data res = { group, -ENOENT };
422 :
423 5024 : msg = nlmsg_alloc();
424 5024 : if (!msg)
425 0 : return -ENOMEM;
426 5024 : if (!genlmsg_put(msg, 0, 0, genl_ctrl_resolve(global->nl, "nlctrl"),
427 5024 : 0, 0, CTRL_CMD_GETFAMILY, 0) ||
428 5024 : nla_put_string(msg, CTRL_ATTR_FAMILY_NAME, family)) {
429 0 : nlmsg_free(msg);
430 0 : return -1;
431 : }
432 :
433 5024 : ret = send_and_recv(global, global->nl, msg, family_handler, &res);
434 5024 : if (ret == 0)
435 5024 : ret = res.id;
436 5024 : return ret;
437 : }
438 :
439 :
440 174997 : void * nl80211_cmd(struct wpa_driver_nl80211_data *drv,
441 : struct nl_msg *msg, int flags, uint8_t cmd)
442 : {
443 174997 : return genlmsg_put(msg, 0, 0, drv->global->nl80211_id,
444 : 0, flags, cmd, 0);
445 : }
446 :
447 :
448 71952 : static int nl80211_set_iface_id(struct nl_msg *msg, struct i802_bss *bss)
449 : {
450 71952 : if (bss->wdev_id_set)
451 335 : return nla_put_u64(msg, NL80211_ATTR_WDEV, bss->wdev_id);
452 71617 : return nla_put_u32(msg, NL80211_ATTR_IFINDEX, bss->ifindex);
453 : }
454 :
455 :
456 71952 : struct nl_msg * nl80211_cmd_msg(struct i802_bss *bss, int flags, uint8_t cmd)
457 : {
458 : struct nl_msg *msg;
459 :
460 71952 : msg = nlmsg_alloc();
461 71952 : if (!msg)
462 0 : return NULL;
463 :
464 143904 : if (!nl80211_cmd(bss->drv, msg, flags, cmd) ||
465 71952 : nl80211_set_iface_id(msg, bss) < 0) {
466 0 : nlmsg_free(msg);
467 0 : return NULL;
468 : }
469 :
470 71952 : return msg;
471 : }
472 :
473 :
474 : static struct nl_msg *
475 82580 : nl80211_ifindex_msg(struct wpa_driver_nl80211_data *drv, int ifindex,
476 : int flags, uint8_t cmd)
477 : {
478 : struct nl_msg *msg;
479 :
480 82580 : msg = nlmsg_alloc();
481 82580 : if (!msg)
482 0 : return NULL;
483 :
484 165160 : if (!nl80211_cmd(drv, msg, flags, cmd) ||
485 82580 : nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex)) {
486 0 : nlmsg_free(msg);
487 0 : return NULL;
488 : }
489 :
490 82580 : return msg;
491 : }
492 :
493 :
494 15400 : struct nl_msg * nl80211_drv_msg(struct wpa_driver_nl80211_data *drv, int flags,
495 : uint8_t cmd)
496 : {
497 15400 : return nl80211_ifindex_msg(drv, drv->ifindex, flags, cmd);
498 : }
499 :
500 :
501 31498 : struct nl_msg * nl80211_bss_msg(struct i802_bss *bss, int flags, uint8_t cmd)
502 : {
503 31498 : return nl80211_ifindex_msg(bss->drv, bss->ifindex, flags, cmd);
504 : }
505 :
506 :
507 : struct wiphy_idx_data {
508 : int wiphy_idx;
509 : enum nl80211_iftype nlmode;
510 : u8 *macaddr;
511 : };
512 :
513 :
514 7720 : static int netdev_info_handler(struct nl_msg *msg, void *arg)
515 : {
516 : struct nlattr *tb[NL80211_ATTR_MAX + 1];
517 7720 : struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
518 7720 : struct wiphy_idx_data *info = arg;
519 :
520 7720 : nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
521 : genlmsg_attrlen(gnlh, 0), NULL);
522 :
523 7720 : if (tb[NL80211_ATTR_WIPHY])
524 7720 : info->wiphy_idx = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
525 :
526 7720 : if (tb[NL80211_ATTR_IFTYPE])
527 7720 : info->nlmode = nla_get_u32(tb[NL80211_ATTR_IFTYPE]);
528 :
529 7720 : if (tb[NL80211_ATTR_MAC] && info->macaddr)
530 8 : os_memcpy(info->macaddr, nla_data(tb[NL80211_ATTR_MAC]),
531 : ETH_ALEN);
532 :
533 7720 : return NL_SKIP;
534 : }
535 :
536 :
537 2652 : int nl80211_get_wiphy_index(struct i802_bss *bss)
538 : {
539 : struct nl_msg *msg;
540 2652 : struct wiphy_idx_data data = {
541 : .wiphy_idx = -1,
542 : .macaddr = NULL,
543 : };
544 :
545 2652 : if (!(msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_GET_INTERFACE)))
546 0 : return -1;
547 :
548 2652 : if (send_and_recv_msgs(bss->drv, msg, netdev_info_handler, &data) == 0)
549 2652 : return data.wiphy_idx;
550 0 : return -1;
551 : }
552 :
553 :
554 5123 : static enum nl80211_iftype nl80211_get_ifmode(struct i802_bss *bss)
555 : {
556 : struct nl_msg *msg;
557 5123 : struct wiphy_idx_data data = {
558 : .nlmode = NL80211_IFTYPE_UNSPECIFIED,
559 : .macaddr = NULL,
560 : };
561 :
562 5123 : if (!(msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_GET_INTERFACE)))
563 0 : return NL80211_IFTYPE_UNSPECIFIED;
564 :
565 5123 : if (send_and_recv_msgs(bss->drv, msg, netdev_info_handler, &data) == 0)
566 5060 : return data.nlmode;
567 63 : return NL80211_IFTYPE_UNSPECIFIED;
568 : }
569 :
570 :
571 8 : static int nl80211_get_macaddr(struct i802_bss *bss)
572 : {
573 : struct nl_msg *msg;
574 16 : struct wiphy_idx_data data = {
575 8 : .macaddr = bss->addr,
576 : };
577 :
578 8 : if (!(msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_GET_INTERFACE)))
579 0 : return -1;
580 :
581 8 : return send_and_recv_msgs(bss->drv, msg, netdev_info_handler, &data);
582 : }
583 :
584 :
585 1279 : static int nl80211_register_beacons(struct wpa_driver_nl80211_data *drv,
586 : struct nl80211_wiphy_data *w)
587 : {
588 : struct nl_msg *msg;
589 : int ret;
590 :
591 1279 : msg = nlmsg_alloc();
592 1279 : if (!msg)
593 0 : return -1;
594 :
595 2558 : if (!nl80211_cmd(drv, msg, 0, NL80211_CMD_REGISTER_BEACONS) ||
596 1279 : nla_put_u32(msg, NL80211_ATTR_WIPHY, w->wiphy_idx)) {
597 0 : nlmsg_free(msg);
598 0 : return -1;
599 : }
600 :
601 1279 : ret = send_and_recv(drv->global, w->nl_beacons, msg, NULL, NULL);
602 1279 : if (ret) {
603 0 : wpa_printf(MSG_DEBUG, "nl80211: Register beacons command "
604 : "failed: ret=%d (%s)",
605 : ret, strerror(-ret));
606 : }
607 1279 : return ret;
608 : }
609 :
610 :
611 5688 : static void nl80211_recv_beacons(int sock, void *eloop_ctx, void *handle)
612 : {
613 5688 : struct nl80211_wiphy_data *w = eloop_ctx;
614 : int res;
615 :
616 5688 : wpa_printf(MSG_EXCESSIVE, "nl80211: Beacon event message available");
617 :
618 5688 : res = nl_recvmsgs(handle, w->nl_cb);
619 5688 : if (res < 0) {
620 0 : wpa_printf(MSG_INFO, "nl80211: %s->nl_recvmsgs failed: %d",
621 : __func__, res);
622 : }
623 5688 : }
624 :
625 :
626 5684 : static int process_beacon_event(struct nl_msg *msg, void *arg)
627 : {
628 5684 : struct nl80211_wiphy_data *w = arg;
629 : struct wpa_driver_nl80211_data *drv;
630 5684 : struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
631 : struct nlattr *tb[NL80211_ATTR_MAX + 1];
632 : union wpa_event_data event;
633 :
634 5684 : nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
635 : genlmsg_attrlen(gnlh, 0), NULL);
636 :
637 5684 : if (gnlh->cmd != NL80211_CMD_FRAME) {
638 0 : wpa_printf(MSG_DEBUG, "nl80211: Unexpected beacon event? (%d)",
639 0 : gnlh->cmd);
640 0 : return NL_SKIP;
641 : }
642 :
643 5684 : if (!tb[NL80211_ATTR_FRAME])
644 0 : return NL_SKIP;
645 :
646 11368 : dl_list_for_each(drv, &w->drvs, struct wpa_driver_nl80211_data,
647 : wiphy_list) {
648 5684 : os_memset(&event, 0, sizeof(event));
649 5684 : event.rx_mgmt.frame = nla_data(tb[NL80211_ATTR_FRAME]);
650 5684 : event.rx_mgmt.frame_len = nla_len(tb[NL80211_ATTR_FRAME]);
651 5684 : wpa_supplicant_event(drv->ctx, EVENT_RX_MGMT, &event);
652 : }
653 :
654 5684 : return NL_SKIP;
655 : }
656 :
657 :
658 : static struct nl80211_wiphy_data *
659 1444 : nl80211_get_wiphy_data_ap(struct i802_bss *bss)
660 : {
661 : static DEFINE_DL_LIST(nl80211_wiphys);
662 : struct nl80211_wiphy_data *w;
663 1444 : int wiphy_idx, found = 0;
664 : struct i802_bss *tmp_bss;
665 :
666 1444 : if (bss->wiphy_data != NULL)
667 0 : return bss->wiphy_data;
668 :
669 1444 : wiphy_idx = nl80211_get_wiphy_index(bss);
670 :
671 1615 : dl_list_for_each(w, &nl80211_wiphys, struct nl80211_wiphy_data, list) {
672 336 : if (w->wiphy_idx == wiphy_idx)
673 165 : goto add;
674 : }
675 :
676 : /* alloc new one */
677 1279 : w = os_zalloc(sizeof(*w));
678 1279 : if (w == NULL)
679 0 : return NULL;
680 1279 : w->wiphy_idx = wiphy_idx;
681 1279 : dl_list_init(&w->bsss);
682 1279 : dl_list_init(&w->drvs);
683 :
684 1279 : w->nl_cb = nl_cb_alloc(NL_CB_DEFAULT);
685 1279 : if (!w->nl_cb) {
686 0 : os_free(w);
687 0 : return NULL;
688 : }
689 1279 : nl_cb_set(w->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL);
690 1279 : nl_cb_set(w->nl_cb, NL_CB_VALID, NL_CB_CUSTOM, process_beacon_event,
691 : w);
692 :
693 1279 : w->nl_beacons = nl_create_handle(bss->drv->global->nl_cb,
694 : "wiphy beacons");
695 1279 : if (w->nl_beacons == NULL) {
696 0 : os_free(w);
697 0 : return NULL;
698 : }
699 :
700 1279 : if (nl80211_register_beacons(bss->drv, w)) {
701 0 : nl_destroy_handles(&w->nl_beacons);
702 0 : os_free(w);
703 0 : return NULL;
704 : }
705 :
706 1279 : nl80211_register_eloop_read(&w->nl_beacons, nl80211_recv_beacons, w);
707 :
708 1279 : dl_list_add(&nl80211_wiphys, &w->list);
709 :
710 : add:
711 : /* drv entry for this bss already there? */
712 5350 : dl_list_for_each(tmp_bss, &w->bsss, struct i802_bss, wiphy_list) {
713 3947 : if (tmp_bss->drv == bss->drv) {
714 41 : found = 1;
715 41 : break;
716 : }
717 : }
718 : /* if not add it */
719 1444 : if (!found)
720 1403 : dl_list_add(&w->drvs, &bss->drv->wiphy_list);
721 :
722 1444 : dl_list_add(&w->bsss, &bss->wiphy_list);
723 1444 : bss->wiphy_data = w;
724 1444 : return w;
725 : }
726 :
727 :
728 2259 : static void nl80211_put_wiphy_data_ap(struct i802_bss *bss)
729 : {
730 2259 : struct nl80211_wiphy_data *w = bss->wiphy_data;
731 : struct i802_bss *tmp_bss;
732 2259 : int found = 0;
733 :
734 2259 : if (w == NULL)
735 815 : return;
736 1444 : bss->wiphy_data = NULL;
737 1444 : dl_list_del(&bss->wiphy_list);
738 :
739 : /* still any for this drv present? */
740 5350 : dl_list_for_each(tmp_bss, &w->bsss, struct i802_bss, wiphy_list) {
741 3947 : if (tmp_bss->drv == bss->drv) {
742 41 : found = 1;
743 41 : break;
744 : }
745 : }
746 : /* if not remove it */
747 1444 : if (!found)
748 1403 : dl_list_del(&bss->drv->wiphy_list);
749 :
750 1444 : if (!dl_list_empty(&w->bsss))
751 165 : return;
752 :
753 1279 : nl80211_destroy_eloop_handle(&w->nl_beacons);
754 :
755 1279 : nl_cb_put(w->nl_cb);
756 1279 : dl_list_del(&w->list);
757 1279 : os_free(w);
758 : }
759 :
760 :
761 4450 : static int wpa_driver_nl80211_get_bssid(void *priv, u8 *bssid)
762 : {
763 4450 : struct i802_bss *bss = priv;
764 4450 : struct wpa_driver_nl80211_data *drv = bss->drv;
765 4450 : if (!drv->associated)
766 0 : return -1;
767 4450 : os_memcpy(bssid, drv->bssid, ETH_ALEN);
768 4450 : return 0;
769 : }
770 :
771 :
772 1393 : static int wpa_driver_nl80211_get_ssid(void *priv, u8 *ssid)
773 : {
774 1393 : struct i802_bss *bss = priv;
775 1393 : struct wpa_driver_nl80211_data *drv = bss->drv;
776 1393 : if (!drv->associated)
777 1 : return -1;
778 1392 : os_memcpy(ssid, drv->ssid, drv->ssid_len);
779 1392 : return drv->ssid_len;
780 : }
781 :
782 :
783 20807 : static void wpa_driver_nl80211_event_newlink(
784 : struct wpa_driver_nl80211_data *drv, const char *ifname)
785 : {
786 : union wpa_event_data event;
787 :
788 20807 : if (os_strcmp(drv->first_bss->ifname, ifname) == 0) {
789 20521 : if (if_nametoindex(drv->first_bss->ifname) == 0) {
790 22 : wpa_printf(MSG_DEBUG, "nl80211: Interface %s does not exist - ignore RTM_NEWLINK",
791 22 : drv->first_bss->ifname);
792 22 : return;
793 : }
794 20499 : if (!drv->if_removed)
795 20499 : return;
796 0 : wpa_printf(MSG_DEBUG, "nl80211: Mark if_removed=0 for %s based on RTM_NEWLINK event",
797 0 : drv->first_bss->ifname);
798 0 : drv->if_removed = 0;
799 : }
800 :
801 286 : os_memset(&event, 0, sizeof(event));
802 286 : os_strlcpy(event.interface_status.ifname, ifname,
803 : sizeof(event.interface_status.ifname));
804 286 : event.interface_status.ievent = EVENT_INTERFACE_ADDED;
805 286 : wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS, &event);
806 : }
807 :
808 :
809 17 : static void wpa_driver_nl80211_event_dellink(
810 : struct wpa_driver_nl80211_data *drv, const char *ifname)
811 : {
812 : union wpa_event_data event;
813 :
814 17 : if (os_strcmp(drv->first_bss->ifname, ifname) == 0) {
815 16 : if (drv->if_removed) {
816 0 : wpa_printf(MSG_DEBUG, "nl80211: if_removed already set - ignore RTM_DELLINK event for %s",
817 : ifname);
818 17 : return;
819 : }
820 16 : wpa_printf(MSG_DEBUG, "RTM_DELLINK: Interface '%s' removed - mark if_removed=1",
821 : ifname);
822 16 : drv->if_removed = 1;
823 : } else {
824 1 : wpa_printf(MSG_DEBUG, "RTM_DELLINK: Interface '%s' removed",
825 : ifname);
826 : }
827 :
828 17 : os_memset(&event, 0, sizeof(event));
829 17 : os_strlcpy(event.interface_status.ifname, ifname,
830 : sizeof(event.interface_status.ifname));
831 17 : event.interface_status.ievent = EVENT_INTERFACE_REMOVED;
832 17 : wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS, &event);
833 : }
834 :
835 :
836 10 : static int wpa_driver_nl80211_own_ifname(struct wpa_driver_nl80211_data *drv,
837 : u8 *buf, size_t len)
838 : {
839 : int attrlen, rta_len;
840 : struct rtattr *attr;
841 :
842 10 : attrlen = len;
843 10 : attr = (struct rtattr *) buf;
844 :
845 10 : rta_len = RTA_ALIGN(sizeof(struct rtattr));
846 20 : while (RTA_OK(attr, attrlen)) {
847 10 : if (attr->rta_type == IFLA_IFNAME) {
848 10 : if (os_strcmp(((char *) attr) + rta_len,
849 : drv->first_bss->ifname) == 0)
850 0 : return 1;
851 : else
852 10 : break;
853 : }
854 0 : attr = RTA_NEXT(attr, attrlen);
855 : }
856 :
857 10 : return 0;
858 : }
859 :
860 :
861 103111 : static int wpa_driver_nl80211_own_ifindex(struct wpa_driver_nl80211_data *drv,
862 : int ifindex, u8 *buf, size_t len)
863 : {
864 103111 : if (drv->ifindex == ifindex)
865 20883 : return 1;
866 :
867 82228 : if (drv->if_removed && wpa_driver_nl80211_own_ifname(drv, buf, len)) {
868 0 : nl80211_check_global(drv->global);
869 0 : wpa_printf(MSG_DEBUG, "nl80211: Update ifindex for a removed "
870 : "interface");
871 0 : wpa_driver_nl80211_finish_drv_init(drv, NULL, 0, NULL);
872 0 : return 1;
873 : }
874 :
875 82228 : return 0;
876 : }
877 :
878 :
879 : static struct wpa_driver_nl80211_data *
880 114279 : nl80211_find_drv(struct nl80211_global *global, int idx, u8 *buf, size_t len)
881 : {
882 : struct wpa_driver_nl80211_data *drv;
883 196100 : dl_list_for_each(drv, &global->interfaces,
884 : struct wpa_driver_nl80211_data, list) {
885 185339 : if (wpa_driver_nl80211_own_ifindex(drv, idx, buf, len) ||
886 82228 : have_ifidx(drv, idx))
887 21290 : return drv;
888 : }
889 92989 : return NULL;
890 : }
891 :
892 :
893 112913 : static void wpa_driver_nl80211_event_rtm_newlink(void *ctx,
894 : struct ifinfomsg *ifi,
895 : u8 *buf, size_t len)
896 : {
897 112913 : struct nl80211_global *global = ctx;
898 : struct wpa_driver_nl80211_data *drv;
899 : int attrlen;
900 : struct rtattr *attr;
901 112913 : u32 brid = 0;
902 : char namebuf[IFNAMSIZ];
903 : char ifname[IFNAMSIZ + 1];
904 : char extra[100], *pos, *end;
905 :
906 112913 : drv = nl80211_find_drv(global, ifi->ifi_index, buf, len);
907 112913 : if (!drv) {
908 91689 : wpa_printf(MSG_DEBUG, "nl80211: Ignore RTM_NEWLINK event for foreign ifindex %d",
909 : ifi->ifi_index);
910 91689 : return;
911 : }
912 :
913 21224 : extra[0] = '\0';
914 21224 : pos = extra;
915 21224 : end = pos + sizeof(extra);
916 21224 : ifname[0] = '\0';
917 :
918 21224 : attrlen = len;
919 21224 : attr = (struct rtattr *) buf;
920 253977 : while (RTA_OK(attr, attrlen)) {
921 211529 : switch (attr->rta_type) {
922 : case IFLA_IFNAME:
923 21224 : if (RTA_PAYLOAD(attr) >= IFNAMSIZ)
924 0 : break;
925 21224 : os_memcpy(ifname, RTA_DATA(attr), RTA_PAYLOAD(attr));
926 21224 : ifname[RTA_PAYLOAD(attr)] = '\0';
927 21224 : break;
928 : case IFLA_MASTER:
929 321 : brid = nla_get_u32((struct nlattr *) attr);
930 321 : pos += os_snprintf(pos, end - pos, " master=%u", brid);
931 321 : break;
932 : case IFLA_WIRELESS:
933 10525 : pos += os_snprintf(pos, end - pos, " wext");
934 10525 : break;
935 : case IFLA_OPERSTATE:
936 10699 : pos += os_snprintf(pos, end - pos, " operstate=%u",
937 : nla_get_u32((struct nlattr *) attr));
938 10699 : break;
939 : case IFLA_LINKMODE:
940 10496 : pos += os_snprintf(pos, end - pos, " linkmode=%u",
941 : nla_get_u32((struct nlattr *) attr));
942 10496 : break;
943 : }
944 211529 : attr = RTA_NEXT(attr, attrlen);
945 : }
946 21224 : extra[sizeof(extra) - 1] = '\0';
947 :
948 106120 : wpa_printf(MSG_DEBUG, "RTM_NEWLINK: ifi_index=%d ifname=%s%s ifi_family=%d ifi_flags=0x%x (%s%s%s%s)",
949 21224 : ifi->ifi_index, ifname, extra, ifi->ifi_family,
950 : ifi->ifi_flags,
951 21224 : (ifi->ifi_flags & IFF_UP) ? "[UP]" : "",
952 21224 : (ifi->ifi_flags & IFF_RUNNING) ? "[RUNNING]" : "",
953 21224 : (ifi->ifi_flags & IFF_LOWER_UP) ? "[LOWER_UP]" : "",
954 21224 : (ifi->ifi_flags & IFF_DORMANT) ? "[DORMANT]" : "");
955 :
956 21224 : if (!drv->if_disabled && !(ifi->ifi_flags & IFF_UP)) {
957 491 : namebuf[0] = '\0';
958 964 : if (if_indextoname(ifi->ifi_index, namebuf) &&
959 473 : linux_iface_up(drv->global->ioctl_sock, namebuf) > 0) {
960 415 : wpa_printf(MSG_DEBUG, "nl80211: Ignore interface down "
961 : "event since interface %s is up", namebuf);
962 415 : drv->ignore_if_down_event = 0;
963 415 : return;
964 : }
965 76 : wpa_printf(MSG_DEBUG, "nl80211: Interface down (%s/%s)",
966 : namebuf, ifname);
967 76 : if (os_strcmp(drv->first_bss->ifname, ifname) != 0) {
968 47 : wpa_printf(MSG_DEBUG,
969 : "nl80211: Not the main interface (%s) - do not indicate interface down",
970 47 : drv->first_bss->ifname);
971 29 : } else if (drv->ignore_if_down_event) {
972 0 : wpa_printf(MSG_DEBUG, "nl80211: Ignore interface down "
973 : "event generated by mode change");
974 0 : drv->ignore_if_down_event = 0;
975 : } else {
976 29 : drv->if_disabled = 1;
977 29 : wpa_supplicant_event(drv->ctx,
978 : EVENT_INTERFACE_DISABLED, NULL);
979 :
980 : /*
981 : * Try to get drv again, since it may be removed as
982 : * part of the EVENT_INTERFACE_DISABLED handling for
983 : * dynamic interfaces
984 : */
985 29 : drv = nl80211_find_drv(global, ifi->ifi_index,
986 : buf, len);
987 29 : if (!drv)
988 2 : return;
989 : }
990 : }
991 :
992 20807 : if (drv->if_disabled && (ifi->ifi_flags & IFF_UP)) {
993 37 : if (if_indextoname(ifi->ifi_index, namebuf) &&
994 16 : linux_iface_up(drv->global->ioctl_sock, namebuf) == 0) {
995 5 : wpa_printf(MSG_DEBUG, "nl80211: Ignore interface up "
996 : "event since interface %s is down",
997 : namebuf);
998 16 : } else if (if_nametoindex(drv->first_bss->ifname) == 0) {
999 5 : wpa_printf(MSG_DEBUG, "nl80211: Ignore interface up "
1000 : "event since interface %s does not exist",
1001 5 : drv->first_bss->ifname);
1002 11 : } else if (drv->if_removed) {
1003 0 : wpa_printf(MSG_DEBUG, "nl80211: Ignore interface up "
1004 : "event since interface %s is marked "
1005 0 : "removed", drv->first_bss->ifname);
1006 : } else {
1007 : struct i802_bss *bss;
1008 : u8 addr[ETH_ALEN];
1009 :
1010 : /* Re-read MAC address as it may have changed */
1011 11 : bss = get_bss_ifindex(drv, ifi->ifi_index);
1012 22 : if (bss &&
1013 11 : linux_get_ifhwaddr(drv->global->ioctl_sock,
1014 11 : bss->ifname, addr) < 0) {
1015 0 : wpa_printf(MSG_DEBUG,
1016 : "nl80211: %s: failed to re-read MAC address",
1017 0 : bss->ifname);
1018 22 : } else if (bss &&
1019 11 : os_memcmp(addr, bss->addr, ETH_ALEN) != 0) {
1020 26 : wpa_printf(MSG_DEBUG,
1021 : "nl80211: Own MAC address on ifindex %d (%s) changed from "
1022 : MACSTR " to " MACSTR,
1023 2 : ifi->ifi_index, bss->ifname,
1024 12 : MAC2STR(bss->addr),
1025 12 : MAC2STR(addr));
1026 2 : os_memcpy(bss->addr, addr, ETH_ALEN);
1027 : }
1028 :
1029 11 : wpa_printf(MSG_DEBUG, "nl80211: Interface up");
1030 11 : drv->if_disabled = 0;
1031 11 : wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_ENABLED,
1032 : NULL);
1033 : }
1034 : }
1035 :
1036 : /*
1037 : * Some drivers send the association event before the operup event--in
1038 : * this case, lifting operstate in wpa_driver_nl80211_set_operstate()
1039 : * fails. This will hit us when wpa_supplicant does not need to do
1040 : * IEEE 802.1X authentication
1041 : */
1042 26843 : if (drv->operstate == 1 &&
1043 10576 : (ifi->ifi_flags & (IFF_LOWER_UP | IFF_DORMANT)) == IFF_LOWER_UP &&
1044 4540 : !(ifi->ifi_flags & IFF_RUNNING)) {
1045 748 : wpa_printf(MSG_DEBUG, "nl80211: Set IF_OPER_UP again based on ifi_flags and expected operstate");
1046 748 : netlink_send_oper_ifla(drv->global->netlink, drv->ifindex,
1047 : -1, IF_OPER_UP);
1048 : }
1049 :
1050 20807 : if (ifname[0])
1051 20807 : wpa_driver_nl80211_event_newlink(drv, ifname);
1052 :
1053 20807 : if (ifi->ifi_family == AF_BRIDGE && brid) {
1054 : struct i802_bss *bss;
1055 :
1056 : /* device has been added to bridge */
1057 202 : if (!if_indextoname(brid, namebuf)) {
1058 11 : wpa_printf(MSG_DEBUG,
1059 : "nl80211: Could not find bridge ifname for ifindex %u",
1060 : brid);
1061 11 : return;
1062 : }
1063 191 : wpa_printf(MSG_DEBUG, "nl80211: Add ifindex %u for bridge %s",
1064 : brid, namebuf);
1065 191 : add_ifidx(drv, brid);
1066 :
1067 247 : for (bss = drv->first_bss; bss; bss = bss->next) {
1068 191 : if (os_strcmp(ifname, bss->ifname) == 0) {
1069 135 : os_strlcpy(bss->brname, namebuf, IFNAMSIZ);
1070 135 : break;
1071 : }
1072 : }
1073 : }
1074 : }
1075 :
1076 :
1077 1337 : static void wpa_driver_nl80211_event_rtm_dellink(void *ctx,
1078 : struct ifinfomsg *ifi,
1079 : u8 *buf, size_t len)
1080 : {
1081 1337 : struct nl80211_global *global = ctx;
1082 : struct wpa_driver_nl80211_data *drv;
1083 : int attrlen;
1084 : struct rtattr *attr;
1085 1337 : u32 brid = 0;
1086 : char ifname[IFNAMSIZ + 1];
1087 : char extra[100], *pos, *end;
1088 :
1089 1337 : drv = nl80211_find_drv(global, ifi->ifi_index, buf, len);
1090 1337 : if (!drv) {
1091 1298 : wpa_printf(MSG_DEBUG, "nl80211: Ignore RTM_DELLINK event for foreign ifindex %d",
1092 : ifi->ifi_index);
1093 2635 : return;
1094 : }
1095 :
1096 39 : extra[0] = '\0';
1097 39 : pos = extra;
1098 39 : end = pos + sizeof(extra);
1099 39 : ifname[0] = '\0';
1100 :
1101 39 : attrlen = len;
1102 39 : attr = (struct rtattr *) buf;
1103 495 : while (RTA_OK(attr, attrlen)) {
1104 417 : switch (attr->rta_type) {
1105 : case IFLA_IFNAME:
1106 39 : if (RTA_PAYLOAD(attr) >= IFNAMSIZ)
1107 0 : break;
1108 39 : os_memcpy(ifname, RTA_DATA(attr), RTA_PAYLOAD(attr));
1109 39 : ifname[RTA_PAYLOAD(attr)] = '\0';
1110 39 : break;
1111 : case IFLA_MASTER:
1112 22 : brid = nla_get_u32((struct nlattr *) attr);
1113 22 : pos += os_snprintf(pos, end - pos, " master=%u", brid);
1114 22 : break;
1115 : case IFLA_OPERSTATE:
1116 39 : pos += os_snprintf(pos, end - pos, " operstate=%u",
1117 : nla_get_u32((struct nlattr *) attr));
1118 39 : break;
1119 : case IFLA_LINKMODE:
1120 17 : pos += os_snprintf(pos, end - pos, " linkmode=%u",
1121 : nla_get_u32((struct nlattr *) attr));
1122 17 : break;
1123 : }
1124 417 : attr = RTA_NEXT(attr, attrlen);
1125 : }
1126 39 : extra[sizeof(extra) - 1] = '\0';
1127 :
1128 195 : wpa_printf(MSG_DEBUG, "RTM_DELLINK: ifi_index=%d ifname=%s%s ifi_family=%d ifi_flags=0x%x (%s%s%s%s)",
1129 39 : ifi->ifi_index, ifname, extra, ifi->ifi_family,
1130 : ifi->ifi_flags,
1131 39 : (ifi->ifi_flags & IFF_UP) ? "[UP]" : "",
1132 39 : (ifi->ifi_flags & IFF_RUNNING) ? "[RUNNING]" : "",
1133 39 : (ifi->ifi_flags & IFF_LOWER_UP) ? "[LOWER_UP]" : "",
1134 39 : (ifi->ifi_flags & IFF_DORMANT) ? "[DORMANT]" : "");
1135 :
1136 39 : if (ifname[0] && (ifi->ifi_family != AF_BRIDGE || !brid))
1137 17 : wpa_driver_nl80211_event_dellink(drv, ifname);
1138 :
1139 39 : if (ifi->ifi_family == AF_BRIDGE && brid) {
1140 : /* device has been removed from bridge */
1141 : char namebuf[IFNAMSIZ];
1142 :
1143 22 : if (!if_indextoname(brid, namebuf)) {
1144 12 : wpa_printf(MSG_DEBUG,
1145 : "nl80211: Could not find bridge ifname for ifindex %u",
1146 : brid);
1147 : } else {
1148 10 : wpa_printf(MSG_DEBUG,
1149 : "nl80211: Remove ifindex %u for bridge %s",
1150 : brid, namebuf);
1151 : }
1152 22 : del_ifidx(drv, brid);
1153 : }
1154 : }
1155 :
1156 :
1157 59 : unsigned int nl80211_get_assoc_freq(struct wpa_driver_nl80211_data *drv)
1158 : {
1159 : struct nl_msg *msg;
1160 : int ret;
1161 : struct nl80211_bss_info_arg arg;
1162 :
1163 59 : msg = nl80211_drv_msg(drv, NLM_F_DUMP, NL80211_CMD_GET_SCAN);
1164 59 : os_memset(&arg, 0, sizeof(arg));
1165 59 : arg.drv = drv;
1166 59 : ret = send_and_recv_msgs(drv, msg, bss_info_handler, &arg);
1167 59 : if (ret == 0) {
1168 118 : unsigned int freq = drv->nlmode == NL80211_IFTYPE_ADHOC ?
1169 59 : arg.ibss_freq : arg.assoc_freq;
1170 59 : wpa_printf(MSG_DEBUG, "nl80211: Operating frequency for the "
1171 : "associated BSS from scan results: %u MHz", freq);
1172 59 : if (freq)
1173 58 : drv->assoc_freq = freq;
1174 59 : return drv->assoc_freq;
1175 : }
1176 0 : wpa_printf(MSG_DEBUG, "nl80211: Scan result fetch failed: ret=%d "
1177 : "(%s)", ret, strerror(-ret));
1178 0 : return drv->assoc_freq;
1179 : }
1180 :
1181 :
1182 50 : static int get_link_signal(struct nl_msg *msg, void *arg)
1183 : {
1184 : struct nlattr *tb[NL80211_ATTR_MAX + 1];
1185 50 : struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
1186 : struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
1187 : static struct nla_policy policy[NL80211_STA_INFO_MAX + 1] = {
1188 : [NL80211_STA_INFO_SIGNAL] = { .type = NLA_U8 },
1189 : [NL80211_STA_INFO_SIGNAL_AVG] = { .type = NLA_U8 },
1190 : };
1191 : struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
1192 : static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = {
1193 : [NL80211_RATE_INFO_BITRATE] = { .type = NLA_U16 },
1194 : [NL80211_RATE_INFO_MCS] = { .type = NLA_U8 },
1195 : [NL80211_RATE_INFO_40_MHZ_WIDTH] = { .type = NLA_FLAG },
1196 : [NL80211_RATE_INFO_SHORT_GI] = { .type = NLA_FLAG },
1197 : };
1198 50 : struct wpa_signal_info *sig_change = arg;
1199 :
1200 50 : nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
1201 : genlmsg_attrlen(gnlh, 0), NULL);
1202 100 : if (!tb[NL80211_ATTR_STA_INFO] ||
1203 50 : nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,
1204 : tb[NL80211_ATTR_STA_INFO], policy))
1205 0 : return NL_SKIP;
1206 50 : if (!sinfo[NL80211_STA_INFO_SIGNAL])
1207 0 : return NL_SKIP;
1208 :
1209 50 : sig_change->current_signal =
1210 50 : (s8) nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL]);
1211 :
1212 50 : if (sinfo[NL80211_STA_INFO_SIGNAL_AVG])
1213 50 : sig_change->avg_signal =
1214 50 : (s8) nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL_AVG]);
1215 : else
1216 0 : sig_change->avg_signal = 0;
1217 :
1218 50 : if (sinfo[NL80211_STA_INFO_TX_BITRATE]) {
1219 50 : if (nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX,
1220 : sinfo[NL80211_STA_INFO_TX_BITRATE],
1221 : rate_policy)) {
1222 0 : sig_change->current_txrate = 0;
1223 : } else {
1224 50 : if (rinfo[NL80211_RATE_INFO_BITRATE]) {
1225 50 : sig_change->current_txrate =
1226 50 : nla_get_u16(rinfo[
1227 50 : NL80211_RATE_INFO_BITRATE]) * 100;
1228 : }
1229 : }
1230 : }
1231 :
1232 50 : return NL_SKIP;
1233 : }
1234 :
1235 :
1236 50 : int nl80211_get_link_signal(struct wpa_driver_nl80211_data *drv,
1237 : struct wpa_signal_info *sig)
1238 : {
1239 : struct nl_msg *msg;
1240 :
1241 50 : sig->current_signal = -9999;
1242 50 : sig->current_txrate = 0;
1243 :
1244 100 : if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_GET_STATION)) ||
1245 50 : nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, drv->bssid)) {
1246 0 : nlmsg_free(msg);
1247 0 : return -ENOBUFS;
1248 : }
1249 :
1250 50 : return send_and_recv_msgs(drv, msg, get_link_signal, sig);
1251 : }
1252 :
1253 :
1254 50 : static int get_link_noise(struct nl_msg *msg, void *arg)
1255 : {
1256 : struct nlattr *tb[NL80211_ATTR_MAX + 1];
1257 50 : struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
1258 : struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1];
1259 : static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = {
1260 : [NL80211_SURVEY_INFO_FREQUENCY] = { .type = NLA_U32 },
1261 : [NL80211_SURVEY_INFO_NOISE] = { .type = NLA_U8 },
1262 : };
1263 50 : struct wpa_signal_info *sig_change = arg;
1264 :
1265 50 : nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
1266 : genlmsg_attrlen(gnlh, 0), NULL);
1267 :
1268 50 : if (!tb[NL80211_ATTR_SURVEY_INFO]) {
1269 0 : wpa_printf(MSG_DEBUG, "nl80211: survey data missing!");
1270 0 : return NL_SKIP;
1271 : }
1272 :
1273 50 : if (nla_parse_nested(sinfo, NL80211_SURVEY_INFO_MAX,
1274 : tb[NL80211_ATTR_SURVEY_INFO],
1275 : survey_policy)) {
1276 0 : wpa_printf(MSG_DEBUG, "nl80211: failed to parse nested "
1277 : "attributes!");
1278 0 : return NL_SKIP;
1279 : }
1280 :
1281 50 : if (!sinfo[NL80211_SURVEY_INFO_FREQUENCY])
1282 0 : return NL_SKIP;
1283 :
1284 100 : if (nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]) !=
1285 50 : sig_change->frequency)
1286 0 : return NL_SKIP;
1287 :
1288 50 : if (!sinfo[NL80211_SURVEY_INFO_NOISE])
1289 0 : return NL_SKIP;
1290 :
1291 50 : sig_change->current_noise =
1292 50 : (s8) nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
1293 :
1294 50 : return NL_SKIP;
1295 : }
1296 :
1297 :
1298 50 : int nl80211_get_link_noise(struct wpa_driver_nl80211_data *drv,
1299 : struct wpa_signal_info *sig_change)
1300 : {
1301 : struct nl_msg *msg;
1302 :
1303 50 : sig_change->current_noise = 9999;
1304 50 : sig_change->frequency = drv->assoc_freq;
1305 :
1306 50 : msg = nl80211_drv_msg(drv, NLM_F_DUMP, NL80211_CMD_GET_SURVEY);
1307 50 : return send_and_recv_msgs(drv, msg, get_link_noise, sig_change);
1308 : }
1309 :
1310 :
1311 236230 : static void wpa_driver_nl80211_event_receive(int sock, void *eloop_ctx,
1312 : void *handle)
1313 : {
1314 236230 : struct nl_cb *cb = eloop_ctx;
1315 : int res;
1316 :
1317 236230 : wpa_printf(MSG_MSGDUMP, "nl80211: Event message available");
1318 :
1319 236230 : res = nl_recvmsgs(handle, cb);
1320 236230 : if (res < 0) {
1321 0 : wpa_printf(MSG_INFO, "nl80211: %s->nl_recvmsgs failed: %d",
1322 : __func__, res);
1323 : }
1324 236230 : }
1325 :
1326 :
1327 : /**
1328 : * wpa_driver_nl80211_set_country - ask nl80211 to set the regulatory domain
1329 : * @priv: driver_nl80211 private data
1330 : * @alpha2_arg: country to which to switch to
1331 : * Returns: 0 on success, -1 on failure
1332 : *
1333 : * This asks nl80211 to set the regulatory domain for given
1334 : * country ISO / IEC alpha2.
1335 : */
1336 53 : static int wpa_driver_nl80211_set_country(void *priv, const char *alpha2_arg)
1337 : {
1338 53 : struct i802_bss *bss = priv;
1339 53 : struct wpa_driver_nl80211_data *drv = bss->drv;
1340 : char alpha2[3];
1341 : struct nl_msg *msg;
1342 :
1343 53 : msg = nlmsg_alloc();
1344 53 : if (!msg)
1345 0 : return -ENOMEM;
1346 :
1347 53 : alpha2[0] = alpha2_arg[0];
1348 53 : alpha2[1] = alpha2_arg[1];
1349 53 : alpha2[2] = '\0';
1350 :
1351 106 : if (!nl80211_cmd(drv, msg, 0, NL80211_CMD_REQ_SET_REG) ||
1352 53 : nla_put_string(msg, NL80211_ATTR_REG_ALPHA2, alpha2)) {
1353 0 : nlmsg_free(msg);
1354 0 : return -EINVAL;
1355 : }
1356 53 : if (send_and_recv_msgs(drv, msg, NULL, NULL))
1357 0 : return -EINVAL;
1358 53 : return 0;
1359 : }
1360 :
1361 :
1362 46 : static int nl80211_get_country(struct nl_msg *msg, void *arg)
1363 : {
1364 46 : char *alpha2 = arg;
1365 : struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
1366 46 : struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
1367 :
1368 46 : nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
1369 : genlmsg_attrlen(gnlh, 0), NULL);
1370 46 : if (!tb_msg[NL80211_ATTR_REG_ALPHA2]) {
1371 0 : wpa_printf(MSG_DEBUG, "nl80211: No country information available");
1372 0 : return NL_SKIP;
1373 : }
1374 46 : os_strlcpy(alpha2, nla_data(tb_msg[NL80211_ATTR_REG_ALPHA2]), 3);
1375 46 : return NL_SKIP;
1376 : }
1377 :
1378 :
1379 46 : static int wpa_driver_nl80211_get_country(void *priv, char *alpha2)
1380 : {
1381 46 : struct i802_bss *bss = priv;
1382 46 : struct wpa_driver_nl80211_data *drv = bss->drv;
1383 : struct nl_msg *msg;
1384 : int ret;
1385 :
1386 46 : msg = nlmsg_alloc();
1387 46 : if (!msg)
1388 0 : return -ENOMEM;
1389 :
1390 46 : nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_REG);
1391 46 : alpha2[0] = '\0';
1392 46 : ret = send_and_recv_msgs(drv, msg, nl80211_get_country, alpha2);
1393 46 : if (!alpha2[0])
1394 0 : ret = -1;
1395 :
1396 46 : return ret;
1397 : }
1398 :
1399 :
1400 25 : static int wpa_driver_nl80211_init_nl_global(struct nl80211_global *global)
1401 : {
1402 : int ret;
1403 :
1404 25 : global->nl_cb = nl_cb_alloc(NL_CB_DEFAULT);
1405 25 : if (global->nl_cb == NULL) {
1406 0 : wpa_printf(MSG_ERROR, "nl80211: Failed to allocate netlink "
1407 : "callbacks");
1408 0 : return -1;
1409 : }
1410 :
1411 25 : global->nl = nl_create_handle(global->nl_cb, "nl");
1412 25 : if (global->nl == NULL)
1413 0 : goto err;
1414 :
1415 25 : global->nl80211_id = genl_ctrl_resolve(global->nl, "nl80211");
1416 25 : if (global->nl80211_id < 0) {
1417 0 : wpa_printf(MSG_ERROR, "nl80211: 'nl80211' generic netlink not "
1418 : "found");
1419 0 : goto err;
1420 : }
1421 :
1422 25 : global->nl_event = nl_create_handle(global->nl_cb, "event");
1423 25 : if (global->nl_event == NULL)
1424 0 : goto err;
1425 :
1426 25 : ret = nl_get_multicast_id(global, "nl80211", "scan");
1427 25 : if (ret >= 0)
1428 25 : ret = nl_socket_add_membership(global->nl_event, ret);
1429 25 : if (ret < 0) {
1430 0 : wpa_printf(MSG_ERROR, "nl80211: Could not add multicast "
1431 : "membership for scan events: %d (%s)",
1432 : ret, strerror(-ret));
1433 0 : goto err;
1434 : }
1435 :
1436 25 : ret = nl_get_multicast_id(global, "nl80211", "mlme");
1437 25 : if (ret >= 0)
1438 25 : ret = nl_socket_add_membership(global->nl_event, ret);
1439 25 : if (ret < 0) {
1440 0 : wpa_printf(MSG_ERROR, "nl80211: Could not add multicast "
1441 : "membership for mlme events: %d (%s)",
1442 : ret, strerror(-ret));
1443 0 : goto err;
1444 : }
1445 :
1446 25 : ret = nl_get_multicast_id(global, "nl80211", "regulatory");
1447 25 : if (ret >= 0)
1448 25 : ret = nl_socket_add_membership(global->nl_event, ret);
1449 25 : if (ret < 0) {
1450 0 : wpa_printf(MSG_DEBUG, "nl80211: Could not add multicast "
1451 : "membership for regulatory events: %d (%s)",
1452 : ret, strerror(-ret));
1453 : /* Continue without regulatory events */
1454 : }
1455 :
1456 25 : ret = nl_get_multicast_id(global, "nl80211", "vendor");
1457 25 : if (ret >= 0)
1458 25 : ret = nl_socket_add_membership(global->nl_event, ret);
1459 25 : if (ret < 0) {
1460 0 : wpa_printf(MSG_DEBUG, "nl80211: Could not add multicast "
1461 : "membership for vendor events: %d (%s)",
1462 : ret, strerror(-ret));
1463 : /* Continue without vendor events */
1464 : }
1465 :
1466 25 : nl_cb_set(global->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
1467 : no_seq_check, NULL);
1468 25 : nl_cb_set(global->nl_cb, NL_CB_VALID, NL_CB_CUSTOM,
1469 : process_global_event, global);
1470 :
1471 25 : nl80211_register_eloop_read(&global->nl_event,
1472 : wpa_driver_nl80211_event_receive,
1473 25 : global->nl_cb);
1474 :
1475 25 : return 0;
1476 :
1477 : err:
1478 0 : nl_destroy_handles(&global->nl_event);
1479 0 : nl_destroy_handles(&global->nl);
1480 0 : nl_cb_put(global->nl_cb);
1481 0 : global->nl_cb = NULL;
1482 0 : return -1;
1483 : }
1484 :
1485 :
1486 1231 : static void nl80211_check_global(struct nl80211_global *global)
1487 : {
1488 : struct nl_handle *handle;
1489 1231 : const char *groups[] = { "scan", "mlme", "regulatory", "vendor", NULL };
1490 : int ret;
1491 : unsigned int i;
1492 :
1493 : /*
1494 : * Try to re-add memberships to handle case of cfg80211 getting reloaded
1495 : * and all registration having been cleared.
1496 : */
1497 1231 : handle = (void *) (((intptr_t) global->nl_event) ^
1498 : ELOOP_SOCKET_INVALID);
1499 :
1500 6155 : for (i = 0; groups[i]; i++) {
1501 4924 : ret = nl_get_multicast_id(global, "nl80211", groups[i]);
1502 4924 : if (ret >= 0)
1503 4924 : ret = nl_socket_add_membership(handle, ret);
1504 4924 : if (ret < 0) {
1505 0 : wpa_printf(MSG_INFO,
1506 : "nl80211: Could not re-add multicast membership for %s events: %d (%s)",
1507 : groups[i], ret, strerror(-ret));
1508 : }
1509 : }
1510 1231 : }
1511 :
1512 :
1513 27 : static void wpa_driver_nl80211_rfkill_blocked(void *ctx)
1514 : {
1515 27 : wpa_printf(MSG_DEBUG, "nl80211: RFKILL blocked");
1516 : /*
1517 : * This may be for any interface; use ifdown event to disable
1518 : * interface.
1519 : */
1520 27 : }
1521 :
1522 :
1523 26 : static void wpa_driver_nl80211_rfkill_unblocked(void *ctx)
1524 : {
1525 26 : struct wpa_driver_nl80211_data *drv = ctx;
1526 26 : wpa_printf(MSG_DEBUG, "nl80211: RFKILL unblocked");
1527 26 : if (i802_set_iface_flags(drv->first_bss, 1)) {
1528 0 : wpa_printf(MSG_DEBUG, "nl80211: Could not set interface UP "
1529 : "after rfkill unblock");
1530 0 : return;
1531 : }
1532 : /* rtnetlink ifup handler will report interface as enabled */
1533 : }
1534 :
1535 :
1536 9440 : static void wpa_driver_nl80211_handle_eapol_tx_status(int sock,
1537 : void *eloop_ctx,
1538 : void *handle)
1539 : {
1540 9440 : struct wpa_driver_nl80211_data *drv = eloop_ctx;
1541 : u8 data[2048];
1542 : struct msghdr msg;
1543 : struct iovec entry;
1544 : u8 control[512];
1545 : struct cmsghdr *cmsg;
1546 9440 : int res, found_ee = 0, found_wifi = 0, acked = 0;
1547 : union wpa_event_data event;
1548 :
1549 9440 : memset(&msg, 0, sizeof(msg));
1550 9440 : msg.msg_iov = &entry;
1551 9440 : msg.msg_iovlen = 1;
1552 9440 : entry.iov_base = data;
1553 9440 : entry.iov_len = sizeof(data);
1554 9440 : msg.msg_control = &control;
1555 9440 : msg.msg_controllen = sizeof(control);
1556 :
1557 9440 : res = recvmsg(sock, &msg, MSG_ERRQUEUE);
1558 : /* if error or not fitting 802.3 header, return */
1559 9440 : if (res < 14)
1560 0 : return;
1561 :
1562 28320 : for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg))
1563 : {
1564 28320 : if (cmsg->cmsg_level == SOL_SOCKET &&
1565 9440 : cmsg->cmsg_type == SCM_WIFI_STATUS) {
1566 : int *ack;
1567 :
1568 9440 : found_wifi = 1;
1569 9440 : ack = (void *)CMSG_DATA(cmsg);
1570 9440 : acked = *ack;
1571 : }
1572 :
1573 28320 : if (cmsg->cmsg_level == SOL_PACKET &&
1574 9440 : cmsg->cmsg_type == PACKET_TX_TIMESTAMP) {
1575 9440 : struct sock_extended_err *err =
1576 : (struct sock_extended_err *)CMSG_DATA(cmsg);
1577 :
1578 9440 : if (err->ee_origin == SO_EE_ORIGIN_TXSTATUS)
1579 9440 : found_ee = 1;
1580 : }
1581 : }
1582 :
1583 9440 : if (!found_ee || !found_wifi)
1584 0 : return;
1585 :
1586 9440 : memset(&event, 0, sizeof(event));
1587 9440 : event.eapol_tx_status.dst = data;
1588 9440 : event.eapol_tx_status.data = data + 14;
1589 9440 : event.eapol_tx_status.data_len = res - 14;
1590 9440 : event.eapol_tx_status.ack = acked;
1591 9440 : wpa_supplicant_event(drv->ctx, EVENT_EAPOL_TX_STATUS, &event);
1592 : }
1593 :
1594 :
1595 1280 : static int nl80211_init_bss(struct i802_bss *bss)
1596 : {
1597 1280 : bss->nl_cb = nl_cb_alloc(NL_CB_DEFAULT);
1598 1280 : if (!bss->nl_cb)
1599 0 : return -1;
1600 :
1601 1280 : nl_cb_set(bss->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
1602 : no_seq_check, NULL);
1603 1280 : nl_cb_set(bss->nl_cb, NL_CB_VALID, NL_CB_CUSTOM,
1604 : process_bss_event, bss);
1605 :
1606 1280 : return 0;
1607 : }
1608 :
1609 :
1610 1280 : static void nl80211_destroy_bss(struct i802_bss *bss)
1611 : {
1612 1280 : nl_cb_put(bss->nl_cb);
1613 1280 : bss->nl_cb = NULL;
1614 1280 : }
1615 :
1616 :
1617 1246 : static void * wpa_driver_nl80211_drv_init(void *ctx, const char *ifname,
1618 : void *global_priv, int hostapd,
1619 : const u8 *set_addr,
1620 : const char *driver_params)
1621 : {
1622 : struct wpa_driver_nl80211_data *drv;
1623 : struct rfkill_config *rcfg;
1624 : struct i802_bss *bss;
1625 :
1626 1246 : if (global_priv == NULL)
1627 0 : return NULL;
1628 1246 : drv = os_zalloc(sizeof(*drv));
1629 1246 : if (drv == NULL)
1630 4 : return NULL;
1631 1242 : drv->global = global_priv;
1632 1242 : drv->ctx = ctx;
1633 1242 : drv->hostapd = !!hostapd;
1634 1242 : drv->eapol_sock = -1;
1635 :
1636 : /*
1637 : * There is no driver capability flag for this, so assume it is
1638 : * supported and disable this on first attempt to use if the driver
1639 : * rejects the command due to missing support.
1640 : */
1641 1242 : drv->set_rekey_offload = 1;
1642 :
1643 1242 : drv->num_if_indices = sizeof(drv->default_if_indices) / sizeof(int);
1644 1242 : drv->if_indices = drv->default_if_indices;
1645 :
1646 1242 : drv->first_bss = os_zalloc(sizeof(*drv->first_bss));
1647 1242 : if (!drv->first_bss) {
1648 4 : os_free(drv);
1649 4 : return NULL;
1650 : }
1651 1238 : bss = drv->first_bss;
1652 1238 : bss->drv = drv;
1653 1238 : bss->ctx = ctx;
1654 :
1655 1238 : os_strlcpy(bss->ifname, ifname, sizeof(bss->ifname));
1656 1238 : drv->monitor_ifidx = -1;
1657 1238 : drv->monitor_sock = -1;
1658 1238 : drv->eapol_tx_sock = -1;
1659 1238 : drv->ap_scan_as_station = NL80211_IFTYPE_UNSPECIFIED;
1660 :
1661 1238 : if (nl80211_init_bss(bss))
1662 0 : goto failed;
1663 :
1664 1238 : rcfg = os_zalloc(sizeof(*rcfg));
1665 1238 : if (rcfg == NULL)
1666 4 : goto failed;
1667 1234 : rcfg->ctx = drv;
1668 1234 : os_strlcpy(rcfg->ifname, ifname, sizeof(rcfg->ifname));
1669 1234 : rcfg->blocked_cb = wpa_driver_nl80211_rfkill_blocked;
1670 1234 : rcfg->unblocked_cb = wpa_driver_nl80211_rfkill_unblocked;
1671 1234 : drv->rfkill = rfkill_init(rcfg);
1672 1234 : if (drv->rfkill == NULL) {
1673 3 : wpa_printf(MSG_DEBUG, "nl80211: RFKILL status not available");
1674 3 : os_free(rcfg);
1675 : }
1676 :
1677 1234 : if (linux_iface_up(drv->global->ioctl_sock, ifname) > 0)
1678 0 : drv->start_iface_up = 1;
1679 :
1680 1234 : if (wpa_driver_nl80211_finish_drv_init(drv, set_addr, 1, driver_params))
1681 3 : goto failed;
1682 :
1683 1231 : drv->eapol_tx_sock = socket(PF_PACKET, SOCK_DGRAM, 0);
1684 1231 : if (drv->eapol_tx_sock < 0)
1685 0 : goto failed;
1686 :
1687 1231 : if (drv->data_tx_status) {
1688 1231 : int enabled = 1;
1689 :
1690 1231 : if (setsockopt(drv->eapol_tx_sock, SOL_SOCKET, SO_WIFI_STATUS,
1691 : &enabled, sizeof(enabled)) < 0) {
1692 0 : wpa_printf(MSG_DEBUG,
1693 : "nl80211: wifi status sockopt failed\n");
1694 0 : drv->data_tx_status = 0;
1695 0 : if (!drv->use_monitor)
1696 0 : drv->capa.flags &=
1697 : ~WPA_DRIVER_FLAGS_EAPOL_TX_STATUS;
1698 : } else {
1699 1231 : eloop_register_read_sock(drv->eapol_tx_sock,
1700 : wpa_driver_nl80211_handle_eapol_tx_status,
1701 : drv, NULL);
1702 : }
1703 : }
1704 :
1705 1231 : if (drv->global) {
1706 1231 : nl80211_check_global(drv->global);
1707 1231 : dl_list_add(&drv->global->interfaces, &drv->list);
1708 1231 : drv->in_interface_list = 1;
1709 : }
1710 :
1711 1231 : return bss;
1712 :
1713 : failed:
1714 7 : wpa_driver_nl80211_deinit(bss);
1715 7 : return NULL;
1716 : }
1717 :
1718 :
1719 : /**
1720 : * wpa_driver_nl80211_init - Initialize nl80211 driver interface
1721 : * @ctx: context to be used when calling wpa_supplicant functions,
1722 : * e.g., wpa_supplicant_event()
1723 : * @ifname: interface name, e.g., wlan0
1724 : * @global_priv: private driver global data from global_init()
1725 : * Returns: Pointer to private data, %NULL on failure
1726 : */
1727 232 : static void * wpa_driver_nl80211_init(void *ctx, const char *ifname,
1728 : void *global_priv)
1729 : {
1730 232 : return wpa_driver_nl80211_drv_init(ctx, ifname, global_priv, 0, NULL,
1731 : NULL);
1732 : }
1733 :
1734 :
1735 27007 : static int nl80211_register_frame(struct i802_bss *bss,
1736 : struct nl_handle *nl_handle,
1737 : u16 type, const u8 *match, size_t match_len)
1738 : {
1739 27007 : struct wpa_driver_nl80211_data *drv = bss->drv;
1740 : struct nl_msg *msg;
1741 : int ret;
1742 : char buf[30];
1743 :
1744 27007 : buf[0] = '\0';
1745 27007 : wpa_snprintf_hex(buf, sizeof(buf), match, match_len);
1746 27007 : wpa_printf(MSG_DEBUG, "nl80211: Register frame type=0x%x (%s) nl_handle=%p match=%s",
1747 : type, fc2str(type), nl_handle, buf);
1748 :
1749 54014 : if (!(msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_REGISTER_ACTION)) ||
1750 54014 : nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE, type) ||
1751 27007 : nla_put(msg, NL80211_ATTR_FRAME_MATCH, match_len, match)) {
1752 0 : nlmsg_free(msg);
1753 0 : return -1;
1754 : }
1755 :
1756 27007 : ret = send_and_recv(drv->global, nl_handle, msg, NULL, NULL);
1757 27007 : if (ret) {
1758 3 : wpa_printf(MSG_DEBUG, "nl80211: Register frame command "
1759 : "failed (type=%u): ret=%d (%s)",
1760 : type, ret, strerror(-ret));
1761 3 : wpa_hexdump(MSG_DEBUG, "nl80211: Register frame match",
1762 : match, match_len);
1763 : }
1764 27007 : return ret;
1765 : }
1766 :
1767 :
1768 2259 : static int nl80211_alloc_mgmt_handle(struct i802_bss *bss)
1769 : {
1770 2259 : if (bss->nl_mgmt) {
1771 0 : wpa_printf(MSG_DEBUG, "nl80211: Mgmt reporting "
1772 : "already on! (nl_mgmt=%p)", bss->nl_mgmt);
1773 0 : return -1;
1774 : }
1775 :
1776 2259 : bss->nl_mgmt = nl_create_handle(bss->nl_cb, "mgmt");
1777 2259 : if (bss->nl_mgmt == NULL)
1778 0 : return -1;
1779 :
1780 2259 : return 0;
1781 : }
1782 :
1783 :
1784 2259 : static void nl80211_mgmt_handle_register_eloop(struct i802_bss *bss)
1785 : {
1786 2259 : nl80211_register_eloop_read(&bss->nl_mgmt,
1787 : wpa_driver_nl80211_event_receive,
1788 2259 : bss->nl_cb);
1789 2259 : }
1790 :
1791 :
1792 15654 : static int nl80211_register_action_frame(struct i802_bss *bss,
1793 : const u8 *match, size_t match_len)
1794 : {
1795 15654 : u16 type = (WLAN_FC_TYPE_MGMT << 2) | (WLAN_FC_STYPE_ACTION << 4);
1796 15654 : return nl80211_register_frame(bss, bss->nl_mgmt,
1797 : type, match, match_len);
1798 : }
1799 :
1800 :
1801 777 : static int nl80211_mgmt_subscribe_non_ap(struct i802_bss *bss)
1802 : {
1803 777 : struct wpa_driver_nl80211_data *drv = bss->drv;
1804 777 : int ret = 0;
1805 :
1806 777 : if (nl80211_alloc_mgmt_handle(bss))
1807 0 : return -1;
1808 777 : wpa_printf(MSG_DEBUG, "nl80211: Subscribe to mgmt frames with non-AP "
1809 : "handle %p", bss->nl_mgmt);
1810 :
1811 777 : if (drv->nlmode == NL80211_IFTYPE_ADHOC) {
1812 18 : u16 type = (WLAN_FC_TYPE_MGMT << 2) | (WLAN_FC_STYPE_AUTH << 4);
1813 :
1814 : /* register for any AUTH message */
1815 18 : nl80211_register_frame(bss, bss->nl_mgmt, type, NULL, 0);
1816 : }
1817 :
1818 : #ifdef CONFIG_INTERWORKING
1819 : /* QoS Map Configure */
1820 777 : if (nl80211_register_action_frame(bss, (u8 *) "\x01\x04", 2) < 0)
1821 0 : ret = -1;
1822 : #endif /* CONFIG_INTERWORKING */
1823 : #if defined(CONFIG_P2P) || defined(CONFIG_INTERWORKING)
1824 : /* GAS Initial Request */
1825 777 : if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0a", 2) < 0)
1826 0 : ret = -1;
1827 : /* GAS Initial Response */
1828 777 : if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0b", 2) < 0)
1829 0 : ret = -1;
1830 : /* GAS Comeback Request */
1831 777 : if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0c", 2) < 0)
1832 0 : ret = -1;
1833 : /* GAS Comeback Response */
1834 777 : if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0d", 2) < 0)
1835 0 : ret = -1;
1836 : /* Protected GAS Initial Request */
1837 777 : if (nl80211_register_action_frame(bss, (u8 *) "\x09\x0a", 2) < 0)
1838 0 : ret = -1;
1839 : /* Protected GAS Initial Response */
1840 777 : if (nl80211_register_action_frame(bss, (u8 *) "\x09\x0b", 2) < 0)
1841 0 : ret = -1;
1842 : /* Protected GAS Comeback Request */
1843 777 : if (nl80211_register_action_frame(bss, (u8 *) "\x09\x0c", 2) < 0)
1844 0 : ret = -1;
1845 : /* Protected GAS Comeback Response */
1846 777 : if (nl80211_register_action_frame(bss, (u8 *) "\x09\x0d", 2) < 0)
1847 0 : ret = -1;
1848 : #endif /* CONFIG_P2P || CONFIG_INTERWORKING */
1849 : #ifdef CONFIG_P2P
1850 : /* P2P Public Action */
1851 777 : if (nl80211_register_action_frame(bss,
1852 : (u8 *) "\x04\x09\x50\x6f\x9a\x09",
1853 : 6) < 0)
1854 0 : ret = -1;
1855 : /* P2P Action */
1856 777 : if (nl80211_register_action_frame(bss,
1857 : (u8 *) "\x7f\x50\x6f\x9a\x09",
1858 : 5) < 0)
1859 0 : ret = -1;
1860 : #endif /* CONFIG_P2P */
1861 : #ifdef CONFIG_IEEE80211W
1862 : /* SA Query Response */
1863 777 : if (nl80211_register_action_frame(bss, (u8 *) "\x08\x01", 2) < 0)
1864 0 : ret = -1;
1865 : #endif /* CONFIG_IEEE80211W */
1866 : #ifdef CONFIG_TDLS
1867 777 : if ((drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT)) {
1868 : /* TDLS Discovery Response */
1869 777 : if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0e", 2) <
1870 : 0)
1871 0 : ret = -1;
1872 : }
1873 : #endif /* CONFIG_TDLS */
1874 :
1875 : /* FT Action frames */
1876 777 : if (nl80211_register_action_frame(bss, (u8 *) "\x06", 1) < 0)
1877 0 : ret = -1;
1878 : else
1879 777 : drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_FT |
1880 : WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK;
1881 :
1882 : /* WNM - BSS Transition Management Request */
1883 777 : if (nl80211_register_action_frame(bss, (u8 *) "\x0a\x07", 2) < 0)
1884 0 : ret = -1;
1885 : /* WNM-Sleep Mode Response */
1886 777 : if (nl80211_register_action_frame(bss, (u8 *) "\x0a\x11", 2) < 0)
1887 0 : ret = -1;
1888 :
1889 : #ifdef CONFIG_HS20
1890 : /* WNM-Notification */
1891 777 : if (nl80211_register_action_frame(bss, (u8 *) "\x0a\x1a", 2) < 0)
1892 0 : ret = -1;
1893 : #endif /* CONFIG_HS20 */
1894 :
1895 : /* WMM-AC ADDTS Response */
1896 777 : if (nl80211_register_action_frame(bss, (u8 *) "\x11\x01", 2) < 0)
1897 0 : ret = -1;
1898 :
1899 : /* WMM-AC DELTS */
1900 777 : if (nl80211_register_action_frame(bss, (u8 *) "\x11\x02", 2) < 0)
1901 0 : ret = -1;
1902 :
1903 : /* Radio Measurement - Neighbor Report Response */
1904 777 : if (nl80211_register_action_frame(bss, (u8 *) "\x05\x05", 2) < 0)
1905 0 : ret = -1;
1906 :
1907 : /* Radio Measurement - Link Measurement Request */
1908 777 : if ((drv->capa.rrm_flags & WPA_DRIVER_FLAGS_TX_POWER_INSERTION) &&
1909 0 : (nl80211_register_action_frame(bss, (u8 *) "\x05\x02", 2) < 0))
1910 0 : ret = -1;
1911 :
1912 777 : nl80211_mgmt_handle_register_eloop(bss);
1913 :
1914 777 : return ret;
1915 : }
1916 :
1917 :
1918 38 : static int nl80211_mgmt_subscribe_mesh(struct i802_bss *bss)
1919 : {
1920 38 : int ret = 0;
1921 :
1922 38 : if (nl80211_alloc_mgmt_handle(bss))
1923 0 : return -1;
1924 :
1925 38 : wpa_printf(MSG_DEBUG,
1926 : "nl80211: Subscribe to mgmt frames with mesh handle %p",
1927 : bss->nl_mgmt);
1928 :
1929 : /* Auth frames for mesh SAE */
1930 38 : if (nl80211_register_frame(bss, bss->nl_mgmt,
1931 : (WLAN_FC_TYPE_MGMT << 2) |
1932 : (WLAN_FC_STYPE_AUTH << 4),
1933 : NULL, 0) < 0)
1934 0 : ret = -1;
1935 :
1936 : /* Mesh peering open */
1937 38 : if (nl80211_register_action_frame(bss, (u8 *) "\x0f\x01", 2) < 0)
1938 0 : ret = -1;
1939 : /* Mesh peering confirm */
1940 38 : if (nl80211_register_action_frame(bss, (u8 *) "\x0f\x02", 2) < 0)
1941 0 : ret = -1;
1942 : /* Mesh peering close */
1943 38 : if (nl80211_register_action_frame(bss, (u8 *) "\x0f\x03", 2) < 0)
1944 0 : ret = -1;
1945 :
1946 38 : nl80211_mgmt_handle_register_eloop(bss);
1947 :
1948 38 : return ret;
1949 : }
1950 :
1951 :
1952 1444 : static int nl80211_register_spurious_class3(struct i802_bss *bss)
1953 : {
1954 : struct nl_msg *msg;
1955 : int ret;
1956 :
1957 1444 : msg = nl80211_bss_msg(bss, 0, NL80211_CMD_UNEXPECTED_FRAME);
1958 1444 : ret = send_and_recv(bss->drv->global, bss->nl_mgmt, msg, NULL, NULL);
1959 1444 : if (ret) {
1960 0 : wpa_printf(MSG_DEBUG, "nl80211: Register spurious class3 "
1961 : "failed: ret=%d (%s)",
1962 : ret, strerror(-ret));
1963 : }
1964 1444 : return ret;
1965 : }
1966 :
1967 :
1968 1444 : static int nl80211_mgmt_subscribe_ap(struct i802_bss *bss)
1969 : {
1970 : static const int stypes[] = {
1971 : WLAN_FC_STYPE_AUTH,
1972 : WLAN_FC_STYPE_ASSOC_REQ,
1973 : WLAN_FC_STYPE_REASSOC_REQ,
1974 : WLAN_FC_STYPE_DISASSOC,
1975 : WLAN_FC_STYPE_DEAUTH,
1976 : WLAN_FC_STYPE_ACTION,
1977 : WLAN_FC_STYPE_PROBE_REQ,
1978 : /* Beacon doesn't work as mac80211 doesn't currently allow
1979 : * it, but it wouldn't really be the right thing anyway as
1980 : * it isn't per interface ... maybe just dump the scan
1981 : * results periodically for OLBC?
1982 : */
1983 : /* WLAN_FC_STYPE_BEACON, */
1984 : };
1985 : unsigned int i;
1986 :
1987 1444 : if (nl80211_alloc_mgmt_handle(bss))
1988 0 : return -1;
1989 1444 : wpa_printf(MSG_DEBUG, "nl80211: Subscribe to mgmt frames with AP "
1990 : "handle %p", bss->nl_mgmt);
1991 :
1992 11552 : for (i = 0; i < ARRAY_SIZE(stypes); i++) {
1993 10108 : if (nl80211_register_frame(bss, bss->nl_mgmt,
1994 : (WLAN_FC_TYPE_MGMT << 2) |
1995 10108 : (stypes[i] << 4),
1996 : NULL, 0) < 0) {
1997 0 : goto out_err;
1998 : }
1999 : }
2000 :
2001 1444 : if (nl80211_register_spurious_class3(bss))
2002 0 : goto out_err;
2003 :
2004 1444 : if (nl80211_get_wiphy_data_ap(bss) == NULL)
2005 0 : goto out_err;
2006 :
2007 1444 : nl80211_mgmt_handle_register_eloop(bss);
2008 1444 : return 0;
2009 :
2010 : out_err:
2011 0 : nl_destroy_handles(&bss->nl_mgmt);
2012 0 : return -1;
2013 : }
2014 :
2015 :
2016 0 : static int nl80211_mgmt_subscribe_ap_dev_sme(struct i802_bss *bss)
2017 : {
2018 0 : if (nl80211_alloc_mgmt_handle(bss))
2019 0 : return -1;
2020 0 : wpa_printf(MSG_DEBUG, "nl80211: Subscribe to mgmt frames with AP "
2021 : "handle %p (device SME)", bss->nl_mgmt);
2022 :
2023 0 : if (nl80211_register_frame(bss, bss->nl_mgmt,
2024 : (WLAN_FC_TYPE_MGMT << 2) |
2025 : (WLAN_FC_STYPE_ACTION << 4),
2026 : NULL, 0) < 0)
2027 0 : goto out_err;
2028 :
2029 0 : nl80211_mgmt_handle_register_eloop(bss);
2030 0 : return 0;
2031 :
2032 : out_err:
2033 0 : nl_destroy_handles(&bss->nl_mgmt);
2034 0 : return -1;
2035 : }
2036 :
2037 :
2038 4524 : static void nl80211_mgmt_unsubscribe(struct i802_bss *bss, const char *reason)
2039 : {
2040 4524 : if (bss->nl_mgmt == NULL)
2041 6789 : return;
2042 2259 : wpa_printf(MSG_DEBUG, "nl80211: Unsubscribe mgmt frames handle %p "
2043 : "(%s)", bss->nl_mgmt, reason);
2044 2259 : nl80211_destroy_eloop_handle(&bss->nl_mgmt);
2045 :
2046 2259 : nl80211_put_wiphy_data_ap(bss);
2047 : }
2048 :
2049 :
2050 1 : static void wpa_driver_nl80211_send_rfkill(void *eloop_ctx, void *timeout_ctx)
2051 : {
2052 1 : wpa_supplicant_event(timeout_ctx, EVENT_INTERFACE_DISABLED, NULL);
2053 1 : }
2054 :
2055 :
2056 8 : static void nl80211_del_p2pdev(struct i802_bss *bss)
2057 : {
2058 : struct nl_msg *msg;
2059 : int ret;
2060 :
2061 8 : msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_DEL_INTERFACE);
2062 8 : ret = send_and_recv_msgs(bss->drv, msg, NULL, NULL);
2063 :
2064 16 : wpa_printf(MSG_DEBUG, "nl80211: Delete P2P Device %s (0x%llx): %s",
2065 8 : bss->ifname, (long long unsigned int) bss->wdev_id,
2066 : strerror(-ret));
2067 8 : }
2068 :
2069 :
2070 8 : static int nl80211_set_p2pdev(struct i802_bss *bss, int start)
2071 : {
2072 : struct nl_msg *msg;
2073 : int ret;
2074 :
2075 8 : msg = nl80211_cmd_msg(bss, 0, start ? NL80211_CMD_START_P2P_DEVICE :
2076 : NL80211_CMD_STOP_P2P_DEVICE);
2077 8 : ret = send_and_recv_msgs(bss->drv, msg, NULL, NULL);
2078 :
2079 16 : wpa_printf(MSG_DEBUG, "nl80211: %s P2P Device %s (0x%llx): %s",
2080 : start ? "Start" : "Stop",
2081 8 : bss->ifname, (long long unsigned int) bss->wdev_id,
2082 : strerror(-ret));
2083 8 : return ret;
2084 : }
2085 :
2086 :
2087 2560 : static int i802_set_iface_flags(struct i802_bss *bss, int up)
2088 : {
2089 : enum nl80211_iftype nlmode;
2090 :
2091 2560 : nlmode = nl80211_get_ifmode(bss);
2092 2560 : if (nlmode != NL80211_IFTYPE_P2P_DEVICE) {
2093 2552 : return linux_set_iface_flags(bss->drv->global->ioctl_sock,
2094 2552 : bss->ifname, up);
2095 : }
2096 :
2097 : /* P2P Device has start/stop which is equivalent */
2098 8 : return nl80211_set_p2pdev(bss, up);
2099 : }
2100 :
2101 :
2102 : #ifdef CONFIG_TESTING_OPTIONS
2103 1223 : static int qca_vendor_test_cmd_handler(struct nl_msg *msg, void *arg)
2104 : {
2105 : /* struct wpa_driver_nl80211_data *drv = arg; */
2106 : struct nlattr *tb[NL80211_ATTR_MAX + 1];
2107 1223 : struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
2108 :
2109 :
2110 1223 : wpa_printf(MSG_DEBUG,
2111 : "nl80211: QCA vendor test command response received");
2112 :
2113 1223 : nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
2114 : genlmsg_attrlen(gnlh, 0), NULL);
2115 1223 : if (!tb[NL80211_ATTR_VENDOR_DATA]) {
2116 0 : wpa_printf(MSG_DEBUG, "nl80211: No vendor data attribute");
2117 0 : return NL_SKIP;
2118 : }
2119 :
2120 2446 : wpa_hexdump(MSG_DEBUG,
2121 : "nl80211: Received QCA vendor test command response",
2122 1223 : nla_data(tb[NL80211_ATTR_VENDOR_DATA]),
2123 1223 : nla_len(tb[NL80211_ATTR_VENDOR_DATA]));
2124 :
2125 1223 : return NL_SKIP;
2126 : }
2127 : #endif /* CONFIG_TESTING_OPTIONS */
2128 :
2129 :
2130 1223 : static void qca_vendor_test(struct wpa_driver_nl80211_data *drv)
2131 : {
2132 : #ifdef CONFIG_TESTING_OPTIONS
2133 : struct nl_msg *msg;
2134 : struct nlattr *params;
2135 : int ret;
2136 :
2137 2446 : if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
2138 2446 : nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
2139 1223 : nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
2140 1223 : QCA_NL80211_VENDOR_SUBCMD_TEST) ||
2141 1223 : !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
2142 1223 : nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TEST, 123)) {
2143 0 : nlmsg_free(msg);
2144 1223 : return;
2145 : }
2146 1223 : nla_nest_end(msg, params);
2147 :
2148 1223 : ret = send_and_recv_msgs(drv, msg, qca_vendor_test_cmd_handler, drv);
2149 1223 : wpa_printf(MSG_DEBUG,
2150 : "nl80211: QCA vendor test command returned %d (%s)",
2151 : ret, strerror(-ret));
2152 : #endif /* CONFIG_TESTING_OPTIONS */
2153 : }
2154 :
2155 :
2156 : static int
2157 1234 : wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv,
2158 : const u8 *set_addr, int first,
2159 : const char *driver_params)
2160 : {
2161 1234 : struct i802_bss *bss = drv->first_bss;
2162 1234 : int send_rfkill_event = 0;
2163 : enum nl80211_iftype nlmode;
2164 :
2165 1234 : drv->ifindex = if_nametoindex(bss->ifname);
2166 1234 : bss->ifindex = drv->ifindex;
2167 1234 : bss->wdev_id = drv->global->if_add_wdevid;
2168 1234 : bss->wdev_id_set = drv->global->if_add_wdevid_set;
2169 :
2170 1234 : bss->if_dynamic = drv->ifindex == drv->global->if_add_ifindex;
2171 1234 : bss->if_dynamic = bss->if_dynamic || drv->global->if_add_wdevid_set;
2172 1234 : drv->global->if_add_wdevid_set = 0;
2173 :
2174 1234 : if (!bss->if_dynamic && nl80211_get_ifmode(bss) == NL80211_IFTYPE_AP)
2175 178 : bss->static_ap = 1;
2176 :
2177 1234 : if (wpa_driver_nl80211_capa(drv))
2178 3 : return -1;
2179 :
2180 1231 : if (driver_params && nl80211_set_param(bss, driver_params) < 0)
2181 0 : return -1;
2182 :
2183 1231 : wpa_printf(MSG_DEBUG, "nl80211: interface %s in phy %s",
2184 1231 : bss->ifname, drv->phyname);
2185 :
2186 1279 : if (set_addr &&
2187 96 : (linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 0) ||
2188 48 : linux_set_ifhwaddr(drv->global->ioctl_sock, bss->ifname,
2189 : set_addr)))
2190 0 : return -1;
2191 :
2192 1231 : if (first && nl80211_get_ifmode(bss) == NL80211_IFTYPE_AP)
2193 178 : drv->start_mode_ap = 1;
2194 :
2195 1231 : if (drv->hostapd || bss->static_ap)
2196 1002 : nlmode = NL80211_IFTYPE_AP;
2197 229 : else if (bss->if_dynamic)
2198 143 : nlmode = nl80211_get_ifmode(bss);
2199 : else
2200 86 : nlmode = NL80211_IFTYPE_STATION;
2201 :
2202 1231 : if (wpa_driver_nl80211_set_mode(bss, nlmode) < 0) {
2203 0 : wpa_printf(MSG_ERROR, "nl80211: Could not configure driver mode");
2204 0 : return -1;
2205 : }
2206 :
2207 1231 : if (nlmode == NL80211_IFTYPE_P2P_DEVICE)
2208 8 : nl80211_get_macaddr(bss);
2209 :
2210 1231 : if (!rfkill_is_blocked(drv->rfkill)) {
2211 1229 : int ret = i802_set_iface_flags(bss, 1);
2212 1229 : if (ret) {
2213 0 : wpa_printf(MSG_ERROR, "nl80211: Could not set "
2214 0 : "interface '%s' UP", bss->ifname);
2215 0 : return ret;
2216 : }
2217 1229 : if (nlmode == NL80211_IFTYPE_P2P_DEVICE)
2218 8 : return ret;
2219 : } else {
2220 2 : wpa_printf(MSG_DEBUG, "nl80211: Could not yet enable "
2221 2 : "interface '%s' due to rfkill", bss->ifname);
2222 2 : if (nlmode == NL80211_IFTYPE_P2P_DEVICE)
2223 0 : return 0;
2224 2 : drv->if_disabled = 1;
2225 2 : send_rfkill_event = 1;
2226 : }
2227 :
2228 1223 : if (!drv->hostapd)
2229 221 : netlink_send_oper_ifla(drv->global->netlink, drv->ifindex,
2230 : 1, IF_OPER_DORMANT);
2231 :
2232 1223 : if (linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname,
2233 1223 : bss->addr))
2234 0 : return -1;
2235 1223 : os_memcpy(drv->perm_addr, bss->addr, ETH_ALEN);
2236 :
2237 1223 : if (send_rfkill_event) {
2238 2 : eloop_register_timeout(0, 0, wpa_driver_nl80211_send_rfkill,
2239 : drv, drv->ctx);
2240 : }
2241 :
2242 1223 : if (drv->vendor_cmd_test_avail)
2243 1223 : qca_vendor_test(drv);
2244 :
2245 1223 : return 0;
2246 : }
2247 :
2248 :
2249 1415 : static int wpa_driver_nl80211_del_beacon(struct wpa_driver_nl80211_data *drv)
2250 : {
2251 : struct nl_msg *msg;
2252 :
2253 1415 : wpa_printf(MSG_DEBUG, "nl80211: Remove beacon (ifindex=%d)",
2254 : drv->ifindex);
2255 1415 : msg = nl80211_drv_msg(drv, 0, NL80211_CMD_DEL_BEACON);
2256 1415 : return send_and_recv_msgs(drv, msg, NULL, NULL);
2257 : }
2258 :
2259 :
2260 : /**
2261 : * wpa_driver_nl80211_deinit - Deinitialize nl80211 driver interface
2262 : * @bss: Pointer to private nl80211 data from wpa_driver_nl80211_init()
2263 : *
2264 : * Shut down driver interface and processing of driver events. Free
2265 : * private data buffer if one was allocated in wpa_driver_nl80211_init().
2266 : */
2267 1238 : static void wpa_driver_nl80211_deinit(struct i802_bss *bss)
2268 : {
2269 1238 : struct wpa_driver_nl80211_data *drv = bss->drv;
2270 :
2271 2476 : wpa_printf(MSG_INFO, "nl80211: deinit ifname=%s disabled_11b_rates=%d",
2272 2476 : bss->ifname, drv->disabled_11b_rates);
2273 :
2274 1238 : bss->in_deinit = 1;
2275 1238 : if (drv->data_tx_status)
2276 1231 : eloop_unregister_read_sock(drv->eapol_tx_sock);
2277 1238 : if (drv->eapol_tx_sock >= 0)
2278 1231 : close(drv->eapol_tx_sock);
2279 :
2280 1238 : if (bss->nl_preq)
2281 0 : wpa_driver_nl80211_probe_req_report(bss, 0);
2282 1238 : if (bss->added_if_into_bridge) {
2283 15 : if (linux_br_del_if(drv->global->ioctl_sock, bss->brname,
2284 15 : bss->ifname) < 0)
2285 28 : wpa_printf(MSG_INFO, "nl80211: Failed to remove "
2286 : "interface %s from bridge %s: %s",
2287 28 : bss->ifname, bss->brname, strerror(errno));
2288 15 : if (drv->rtnl_sk)
2289 15 : nl80211_handle_destroy(drv->rtnl_sk);
2290 : }
2291 1238 : if (bss->added_bridge) {
2292 10 : if (linux_set_iface_flags(drv->global->ioctl_sock, bss->brname,
2293 : 0) < 0)
2294 9 : wpa_printf(MSG_INFO,
2295 : "nl80211: Could not set bridge %s down",
2296 9 : bss->brname);
2297 10 : if (linux_br_del(drv->global->ioctl_sock, bss->brname) < 0)
2298 18 : wpa_printf(MSG_INFO, "nl80211: Failed to remove "
2299 : "bridge %s: %s",
2300 18 : bss->brname, strerror(errno));
2301 : }
2302 :
2303 1238 : nl80211_remove_monitor_interface(drv);
2304 :
2305 1238 : if (is_ap_interface(drv->nlmode))
2306 1103 : wpa_driver_nl80211_del_beacon(drv);
2307 :
2308 1238 : if (drv->eapol_sock >= 0) {
2309 1002 : eloop_unregister_read_sock(drv->eapol_sock);
2310 1002 : close(drv->eapol_sock);
2311 : }
2312 :
2313 1238 : if (drv->if_indices != drv->default_if_indices)
2314 1 : os_free(drv->if_indices);
2315 :
2316 1238 : if (drv->disabled_11b_rates)
2317 101 : nl80211_disable_11b_rates(drv, drv->ifindex, 0);
2318 :
2319 1238 : netlink_send_oper_ifla(drv->global->netlink, drv->ifindex, 0,
2320 : IF_OPER_UP);
2321 1238 : eloop_cancel_timeout(wpa_driver_nl80211_send_rfkill, drv, drv->ctx);
2322 1238 : rfkill_deinit(drv->rfkill);
2323 :
2324 1238 : eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);
2325 :
2326 1238 : if (!drv->start_iface_up)
2327 1238 : (void) i802_set_iface_flags(bss, 0);
2328 :
2329 1238 : if (drv->addr_changed) {
2330 3 : if (linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname,
2331 : 0) < 0) {
2332 0 : wpa_printf(MSG_DEBUG,
2333 : "nl80211: Could not set interface down to restore permanent MAC address");
2334 : }
2335 3 : if (linux_set_ifhwaddr(drv->global->ioctl_sock, bss->ifname,
2336 3 : drv->perm_addr) < 0) {
2337 0 : wpa_printf(MSG_DEBUG,
2338 : "nl80211: Could not restore permanent MAC address");
2339 : }
2340 : }
2341 :
2342 1238 : if (drv->nlmode != NL80211_IFTYPE_P2P_DEVICE) {
2343 1230 : if (!drv->hostapd || !drv->start_mode_ap)
2344 1052 : wpa_driver_nl80211_set_mode(bss,
2345 : NL80211_IFTYPE_STATION);
2346 1230 : nl80211_mgmt_unsubscribe(bss, "deinit");
2347 : } else {
2348 8 : nl80211_mgmt_unsubscribe(bss, "deinit");
2349 8 : nl80211_del_p2pdev(bss);
2350 : }
2351 :
2352 1238 : nl80211_destroy_bss(drv->first_bss);
2353 :
2354 1238 : os_free(drv->filter_ssids);
2355 :
2356 1238 : os_free(drv->auth_ie);
2357 :
2358 1238 : if (drv->in_interface_list)
2359 1231 : dl_list_del(&drv->list);
2360 :
2361 1238 : os_free(drv->extended_capa);
2362 1238 : os_free(drv->extended_capa_mask);
2363 1238 : os_free(drv->first_bss);
2364 1238 : os_free(drv);
2365 1238 : }
2366 :
2367 :
2368 7402 : static u32 wpa_alg_to_cipher_suite(enum wpa_alg alg, size_t key_len)
2369 : {
2370 7402 : switch (alg) {
2371 : case WPA_ALG_WEP:
2372 106 : if (key_len == 5)
2373 46 : return WLAN_CIPHER_SUITE_WEP40;
2374 60 : return WLAN_CIPHER_SUITE_WEP104;
2375 : case WPA_ALG_TKIP:
2376 173 : return WLAN_CIPHER_SUITE_TKIP;
2377 : case WPA_ALG_CCMP:
2378 6756 : return WLAN_CIPHER_SUITE_CCMP;
2379 : case WPA_ALG_GCMP:
2380 13 : return WLAN_CIPHER_SUITE_GCMP;
2381 : case WPA_ALG_CCMP_256:
2382 5 : return WLAN_CIPHER_SUITE_CCMP_256;
2383 : case WPA_ALG_GCMP_256:
2384 13 : return WLAN_CIPHER_SUITE_GCMP_256;
2385 : case WPA_ALG_IGTK:
2386 309 : return WLAN_CIPHER_SUITE_AES_CMAC;
2387 : case WPA_ALG_BIP_GMAC_128:
2388 7 : return WLAN_CIPHER_SUITE_BIP_GMAC_128;
2389 : case WPA_ALG_BIP_GMAC_256:
2390 7 : return WLAN_CIPHER_SUITE_BIP_GMAC_256;
2391 : case WPA_ALG_BIP_CMAC_256:
2392 3 : return WLAN_CIPHER_SUITE_BIP_CMAC_256;
2393 : case WPA_ALG_SMS4:
2394 0 : return WLAN_CIPHER_SUITE_SMS4;
2395 : case WPA_ALG_KRK:
2396 0 : return WLAN_CIPHER_SUITE_KRK;
2397 : case WPA_ALG_NONE:
2398 : case WPA_ALG_PMK:
2399 8 : wpa_printf(MSG_ERROR, "nl80211: Unexpected encryption algorithm %d",
2400 : alg);
2401 8 : return 0;
2402 : }
2403 :
2404 2 : wpa_printf(MSG_ERROR, "nl80211: Unsupported encryption algorithm %d",
2405 : alg);
2406 2 : return 0;
2407 : }
2408 :
2409 :
2410 6744 : static u32 wpa_cipher_to_cipher_suite(unsigned int cipher)
2411 : {
2412 6744 : switch (cipher) {
2413 : case WPA_CIPHER_CCMP_256:
2414 3 : return WLAN_CIPHER_SUITE_CCMP_256;
2415 : case WPA_CIPHER_GCMP_256:
2416 8 : return WLAN_CIPHER_SUITE_GCMP_256;
2417 : case WPA_CIPHER_CCMP:
2418 6043 : return WLAN_CIPHER_SUITE_CCMP;
2419 : case WPA_CIPHER_GCMP:
2420 8 : return WLAN_CIPHER_SUITE_GCMP;
2421 : case WPA_CIPHER_TKIP:
2422 174 : return WLAN_CIPHER_SUITE_TKIP;
2423 : case WPA_CIPHER_WEP104:
2424 32 : return WLAN_CIPHER_SUITE_WEP104;
2425 : case WPA_CIPHER_WEP40:
2426 49 : return WLAN_CIPHER_SUITE_WEP40;
2427 : case WPA_CIPHER_GTK_NOT_USED:
2428 0 : return WLAN_CIPHER_SUITE_NO_GROUP_ADDR;
2429 : }
2430 :
2431 427 : return 0;
2432 : }
2433 :
2434 :
2435 2878 : static int wpa_cipher_to_cipher_suites(unsigned int ciphers, u32 suites[],
2436 : int max_suites)
2437 : {
2438 2878 : int num_suites = 0;
2439 :
2440 2878 : if (num_suites < max_suites && ciphers & WPA_CIPHER_CCMP_256)
2441 1 : suites[num_suites++] = WLAN_CIPHER_SUITE_CCMP_256;
2442 2878 : if (num_suites < max_suites && ciphers & WPA_CIPHER_GCMP_256)
2443 2 : suites[num_suites++] = WLAN_CIPHER_SUITE_GCMP_256;
2444 2878 : if (num_suites < max_suites && ciphers & WPA_CIPHER_CCMP)
2445 2362 : suites[num_suites++] = WLAN_CIPHER_SUITE_CCMP;
2446 2878 : if (num_suites < max_suites && ciphers & WPA_CIPHER_GCMP)
2447 2 : suites[num_suites++] = WLAN_CIPHER_SUITE_GCMP;
2448 2878 : if (num_suites < max_suites && ciphers & WPA_CIPHER_TKIP)
2449 114 : suites[num_suites++] = WLAN_CIPHER_SUITE_TKIP;
2450 2878 : if (num_suites < max_suites && ciphers & WPA_CIPHER_WEP104)
2451 16 : suites[num_suites++] = WLAN_CIPHER_SUITE_WEP104;
2452 2878 : if (num_suites < max_suites && ciphers & WPA_CIPHER_WEP40)
2453 27 : suites[num_suites++] = WLAN_CIPHER_SUITE_WEP40;
2454 :
2455 2878 : return num_suites;
2456 : }
2457 :
2458 :
2459 3 : static int issue_key_mgmt_set_key(struct wpa_driver_nl80211_data *drv,
2460 : const u8 *key, size_t key_len)
2461 : {
2462 : struct nl_msg *msg;
2463 : int ret;
2464 :
2465 3 : if (!(drv->capa.flags & WPA_DRIVER_FLAGS_KEY_MGMT_OFFLOAD))
2466 3 : return 0;
2467 :
2468 0 : if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
2469 0 : nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
2470 0 : nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
2471 0 : QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_SET_KEY) ||
2472 0 : nla_put(msg, NL80211_ATTR_VENDOR_DATA, key_len, key)) {
2473 0 : nl80211_nlmsg_clear(msg);
2474 0 : nlmsg_free(msg);
2475 0 : return -1;
2476 : }
2477 0 : ret = send_and_recv_msgs(drv, msg, NULL, (void *) -1);
2478 0 : if (ret) {
2479 0 : wpa_printf(MSG_DEBUG,
2480 : "nl80211: Key management set key failed: ret=%d (%s)",
2481 : ret, strerror(-ret));
2482 : }
2483 :
2484 0 : return ret;
2485 : }
2486 :
2487 :
2488 29081 : static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss,
2489 : enum wpa_alg alg, const u8 *addr,
2490 : int key_idx, int set_tx,
2491 : const u8 *seq, size_t seq_len,
2492 : const u8 *key, size_t key_len)
2493 : {
2494 29081 : struct wpa_driver_nl80211_data *drv = bss->drv;
2495 : int ifindex;
2496 : struct nl_msg *msg;
2497 : int ret;
2498 29081 : int tdls = 0;
2499 :
2500 : /* Ignore for P2P Device */
2501 29081 : if (drv->nlmode == NL80211_IFTYPE_P2P_DEVICE)
2502 48 : return 0;
2503 :
2504 29033 : ifindex = if_nametoindex(ifname);
2505 29033 : wpa_printf(MSG_DEBUG, "%s: ifindex=%d (%s) alg=%d addr=%p key_idx=%d "
2506 : "set_tx=%d seq_len=%lu key_len=%lu",
2507 : __func__, ifindex, ifname, alg, addr, key_idx, set_tx,
2508 : (unsigned long) seq_len, (unsigned long) key_len);
2509 : #ifdef CONFIG_TDLS
2510 12414 : if (key_idx == -1) {
2511 74 : key_idx = 0;
2512 74 : tdls = 1;
2513 : }
2514 : #endif /* CONFIG_TDLS */
2515 :
2516 29041 : if (alg == WPA_ALG_PMK &&
2517 8 : (drv->capa.flags & WPA_DRIVER_FLAGS_KEY_MGMT_OFFLOAD)) {
2518 0 : wpa_printf(MSG_DEBUG, "%s: calling issue_key_mgmt_set_key",
2519 : __func__);
2520 0 : ret = issue_key_mgmt_set_key(drv, key, key_len);
2521 0 : return ret;
2522 : }
2523 :
2524 29033 : if (alg == WPA_ALG_NONE) {
2525 21654 : msg = nl80211_ifindex_msg(drv, ifindex, 0, NL80211_CMD_DEL_KEY);
2526 21654 : if (!msg)
2527 0 : return -ENOBUFS;
2528 : } else {
2529 7379 : msg = nl80211_ifindex_msg(drv, ifindex, 0, NL80211_CMD_NEW_KEY);
2530 14758 : if (!msg ||
2531 14758 : nla_put(msg, NL80211_ATTR_KEY_DATA, key_len, key) ||
2532 7379 : nla_put_u32(msg, NL80211_ATTR_KEY_CIPHER,
2533 : wpa_alg_to_cipher_suite(alg, key_len)))
2534 : goto fail;
2535 7379 : wpa_hexdump_key(MSG_DEBUG, "nl80211: KEY_DATA", key, key_len);
2536 : }
2537 :
2538 29033 : if (seq && seq_len) {
2539 3573 : if (nla_put(msg, NL80211_ATTR_KEY_SEQ, seq_len, seq))
2540 0 : goto fail;
2541 3573 : wpa_hexdump(MSG_DEBUG, "nl80211: KEY_SEQ", seq, seq_len);
2542 : }
2543 :
2544 29033 : if (addr && !is_broadcast_ether_addr(addr)) {
2545 14799 : wpa_printf(MSG_DEBUG, " addr=" MACSTR, MAC2STR(addr));
2546 14799 : if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
2547 0 : goto fail;
2548 :
2549 29598 : if (alg != WPA_ALG_WEP && key_idx && !set_tx) {
2550 28 : wpa_printf(MSG_DEBUG, " RSN IBSS RX GTK");
2551 28 : if (nla_put_u32(msg, NL80211_ATTR_KEY_TYPE,
2552 : NL80211_KEYTYPE_GROUP))
2553 0 : goto fail;
2554 : }
2555 14234 : } else if (addr && is_broadcast_ether_addr(addr)) {
2556 : struct nlattr *types;
2557 :
2558 3582 : wpa_printf(MSG_DEBUG, " broadcast key");
2559 :
2560 3582 : types = nla_nest_start(msg, NL80211_ATTR_KEY_DEFAULT_TYPES);
2561 7164 : if (!types ||
2562 3582 : nla_put_flag(msg, NL80211_KEY_DEFAULT_TYPE_MULTICAST))
2563 : goto fail;
2564 3582 : nla_nest_end(msg, types);
2565 : }
2566 29033 : if (nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_idx))
2567 0 : goto fail;
2568 :
2569 29033 : ret = send_and_recv_msgs(drv, msg, NULL, key ? (void *) -1 : NULL);
2570 29033 : if ((ret == -ENOENT || ret == -ENOLINK) && alg == WPA_ALG_NONE)
2571 20275 : ret = 0;
2572 29033 : if (ret)
2573 349 : wpa_printf(MSG_DEBUG, "nl80211: set_key failed; err=%d %s)",
2574 : ret, strerror(-ret));
2575 :
2576 : /*
2577 : * If we failed or don't need to set the default TX key (below),
2578 : * we're done here.
2579 : */
2580 29033 : if (ret || !set_tx || alg == WPA_ALG_NONE || tdls)
2581 23664 : return ret;
2582 9098 : if (is_ap_interface(drv->nlmode) && addr &&
2583 3729 : !is_broadcast_ether_addr(addr))
2584 1765 : return ret;
2585 :
2586 3604 : msg = nl80211_ifindex_msg(drv, ifindex, 0, NL80211_CMD_SET_KEY);
2587 7208 : if (!msg ||
2588 7208 : nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_idx) ||
2589 3874 : nla_put_flag(msg, (alg == WPA_ALG_IGTK ||
2590 3340 : alg == WPA_ALG_BIP_GMAC_128 ||
2591 3336 : alg == WPA_ALG_BIP_GMAC_256 ||
2592 : alg == WPA_ALG_BIP_CMAC_256) ?
2593 : NL80211_ATTR_KEY_DEFAULT_MGMT :
2594 : NL80211_ATTR_KEY_DEFAULT))
2595 : goto fail;
2596 5580 : if (addr && is_broadcast_ether_addr(addr)) {
2597 : struct nlattr *types;
2598 :
2599 1976 : types = nla_nest_start(msg, NL80211_ATTR_KEY_DEFAULT_TYPES);
2600 3952 : if (!types ||
2601 1976 : nla_put_flag(msg, NL80211_KEY_DEFAULT_TYPE_MULTICAST))
2602 : goto fail;
2603 1976 : nla_nest_end(msg, types);
2604 1628 : } else if (addr) {
2605 : struct nlattr *types;
2606 :
2607 1564 : types = nla_nest_start(msg, NL80211_ATTR_KEY_DEFAULT_TYPES);
2608 3128 : if (!types ||
2609 1564 : nla_put_flag(msg, NL80211_KEY_DEFAULT_TYPE_UNICAST))
2610 : goto fail;
2611 1564 : nla_nest_end(msg, types);
2612 : }
2613 :
2614 3604 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
2615 3604 : if (ret == -ENOENT)
2616 0 : ret = 0;
2617 3604 : if (ret)
2618 0 : wpa_printf(MSG_DEBUG, "nl80211: set_key default failed; "
2619 : "err=%d %s)", ret, strerror(-ret));
2620 3604 : return ret;
2621 :
2622 : fail:
2623 0 : nl80211_nlmsg_clear(msg);
2624 0 : nlmsg_free(msg);
2625 0 : return -ENOBUFS;
2626 : }
2627 :
2628 :
2629 23 : static int nl_add_key(struct nl_msg *msg, enum wpa_alg alg,
2630 : int key_idx, int defkey,
2631 : const u8 *seq, size_t seq_len,
2632 : const u8 *key, size_t key_len)
2633 : {
2634 23 : struct nlattr *key_attr = nla_nest_start(msg, NL80211_ATTR_KEY);
2635 23 : if (!key_attr)
2636 0 : return -1;
2637 :
2638 23 : if (defkey && alg == WPA_ALG_IGTK) {
2639 0 : if (nla_put_flag(msg, NL80211_KEY_DEFAULT_MGMT))
2640 0 : return -1;
2641 23 : } else if (defkey) {
2642 23 : if (nla_put_flag(msg, NL80211_KEY_DEFAULT))
2643 0 : return -1;
2644 : }
2645 :
2646 46 : if (nla_put_u8(msg, NL80211_KEY_IDX, key_idx) ||
2647 23 : nla_put_u32(msg, NL80211_KEY_CIPHER,
2648 23 : wpa_alg_to_cipher_suite(alg, key_len)) ||
2649 0 : (seq && seq_len &&
2650 23 : nla_put(msg, NL80211_KEY_SEQ, seq_len, seq)) ||
2651 23 : nla_put(msg, NL80211_KEY_DATA, key_len, key))
2652 0 : return -1;
2653 :
2654 23 : nla_nest_end(msg, key_attr);
2655 :
2656 23 : return 0;
2657 : }
2658 :
2659 :
2660 46 : static int nl80211_set_conn_keys(struct wpa_driver_associate_params *params,
2661 : struct nl_msg *msg)
2662 : {
2663 46 : int i, privacy = 0;
2664 : struct nlattr *nl_keys, *nl_key;
2665 :
2666 420 : for (i = 0; i < 4; i++) {
2667 169 : if (!params->wep_key[i])
2668 164 : continue;
2669 5 : privacy = 1;
2670 5 : break;
2671 : }
2672 46 : if (params->wps == WPS_MODE_PRIVACY)
2673 1 : privacy = 1;
2674 92 : if (params->pairwise_suite &&
2675 46 : params->pairwise_suite != WPA_CIPHER_NONE)
2676 26 : privacy = 1;
2677 :
2678 46 : if (!privacy)
2679 19 : return 0;
2680 :
2681 27 : if (nla_put_flag(msg, NL80211_ATTR_PRIVACY))
2682 0 : return -ENOBUFS;
2683 :
2684 27 : nl_keys = nla_nest_start(msg, NL80211_ATTR_KEYS);
2685 27 : if (!nl_keys)
2686 0 : return -ENOBUFS;
2687 :
2688 135 : for (i = 0; i < 4; i++) {
2689 108 : if (!params->wep_key[i])
2690 103 : continue;
2691 :
2692 5 : nl_key = nla_nest_start(msg, i);
2693 10 : if (!nl_key ||
2694 5 : nla_put(msg, NL80211_KEY_DATA, params->wep_key_len[i],
2695 10 : params->wep_key[i]) ||
2696 5 : nla_put_u32(msg, NL80211_KEY_CIPHER,
2697 5 : params->wep_key_len[i] == 5 ?
2698 : WLAN_CIPHER_SUITE_WEP40 :
2699 5 : WLAN_CIPHER_SUITE_WEP104) ||
2700 10 : nla_put_u8(msg, NL80211_KEY_IDX, i) ||
2701 10 : (i == params->wep_tx_keyidx &&
2702 5 : nla_put_flag(msg, NL80211_KEY_DEFAULT)))
2703 0 : return -ENOBUFS;
2704 :
2705 5 : nla_nest_end(msg, nl_key);
2706 : }
2707 27 : nla_nest_end(msg, nl_keys);
2708 :
2709 27 : return 0;
2710 : }
2711 :
2712 :
2713 2277 : int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data *drv,
2714 : const u8 *addr, int cmd, u16 reason_code,
2715 : int local_state_change)
2716 : {
2717 : int ret;
2718 : struct nl_msg *msg;
2719 :
2720 4554 : if (!(msg = nl80211_drv_msg(drv, 0, cmd)) ||
2721 4554 : nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason_code) ||
2722 2258 : (addr && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) ||
2723 0 : (local_state_change &&
2724 0 : nla_put_flag(msg, NL80211_ATTR_LOCAL_STATE_CHANGE))) {
2725 0 : nlmsg_free(msg);
2726 0 : return -1;
2727 : }
2728 :
2729 2277 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
2730 2277 : if (ret) {
2731 296 : wpa_dbg(drv->ctx, MSG_DEBUG,
2732 : "nl80211: MLME command failed: reason=%u ret=%d (%s)",
2733 : reason_code, ret, strerror(-ret));
2734 : }
2735 2277 : return ret;
2736 : }
2737 :
2738 :
2739 19 : static int wpa_driver_nl80211_disconnect(struct wpa_driver_nl80211_data *drv,
2740 : int reason_code)
2741 : {
2742 : int ret;
2743 :
2744 19 : wpa_printf(MSG_DEBUG, "%s(reason_code=%d)", __func__, reason_code);
2745 19 : nl80211_mark_disconnected(drv);
2746 : /* Disconnect command doesn't need BSSID - it uses cached value */
2747 19 : ret = wpa_driver_nl80211_mlme(drv, NULL, NL80211_CMD_DISCONNECT,
2748 : reason_code, 0);
2749 : /*
2750 : * For locally generated disconnect, supplicant already generates a
2751 : * DEAUTH event, so ignore the event from NL80211.
2752 : */
2753 19 : drv->ignore_next_local_disconnect = ret == 0;
2754 :
2755 19 : return ret;
2756 : }
2757 :
2758 :
2759 2293 : static int wpa_driver_nl80211_deauthenticate(struct i802_bss *bss,
2760 : const u8 *addr, int reason_code)
2761 : {
2762 2293 : struct wpa_driver_nl80211_data *drv = bss->drv;
2763 : int ret;
2764 :
2765 2293 : if (drv->nlmode == NL80211_IFTYPE_ADHOC) {
2766 18 : nl80211_mark_disconnected(drv);
2767 18 : return nl80211_leave_ibss(drv, 1);
2768 : }
2769 2275 : if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME))
2770 17 : return wpa_driver_nl80211_disconnect(drv, reason_code);
2771 13548 : wpa_printf(MSG_DEBUG, "%s(addr=" MACSTR " reason_code=%d)",
2772 13548 : __func__, MAC2STR(addr), reason_code);
2773 2258 : nl80211_mark_disconnected(drv);
2774 2258 : ret = wpa_driver_nl80211_mlme(drv, addr, NL80211_CMD_DEAUTHENTICATE,
2775 : reason_code, 0);
2776 : /*
2777 : * For locally generated deauthenticate, supplicant already generates a
2778 : * DEAUTH event, so ignore the event from NL80211.
2779 : */
2780 2258 : drv->ignore_next_local_deauth = ret == 0;
2781 2258 : return ret;
2782 : }
2783 :
2784 :
2785 5 : static void nl80211_copy_auth_params(struct wpa_driver_nl80211_data *drv,
2786 : struct wpa_driver_auth_params *params)
2787 : {
2788 : int i;
2789 :
2790 5 : drv->auth_freq = params->freq;
2791 5 : drv->auth_alg = params->auth_alg;
2792 5 : drv->auth_wep_tx_keyidx = params->wep_tx_keyidx;
2793 5 : drv->auth_local_state_change = params->local_state_change;
2794 5 : drv->auth_p2p = params->p2p;
2795 :
2796 5 : if (params->bssid)
2797 5 : os_memcpy(drv->auth_bssid_, params->bssid, ETH_ALEN);
2798 : else
2799 0 : os_memset(drv->auth_bssid_, 0, ETH_ALEN);
2800 :
2801 5 : if (params->ssid) {
2802 5 : os_memcpy(drv->auth_ssid, params->ssid, params->ssid_len);
2803 5 : drv->auth_ssid_len = params->ssid_len;
2804 : } else
2805 0 : drv->auth_ssid_len = 0;
2806 :
2807 :
2808 5 : os_free(drv->auth_ie);
2809 5 : drv->auth_ie = NULL;
2810 5 : drv->auth_ie_len = 0;
2811 5 : if (params->ie) {
2812 0 : drv->auth_ie = os_malloc(params->ie_len);
2813 0 : if (drv->auth_ie) {
2814 0 : os_memcpy(drv->auth_ie, params->ie, params->ie_len);
2815 0 : drv->auth_ie_len = params->ie_len;
2816 : }
2817 : }
2818 :
2819 25 : for (i = 0; i < 4; i++) {
2820 21 : if (params->wep_key[i] && params->wep_key_len[i] &&
2821 1 : params->wep_key_len[i] <= 16) {
2822 1 : os_memcpy(drv->auth_wep_key[i], params->wep_key[i],
2823 : params->wep_key_len[i]);
2824 1 : drv->auth_wep_key_len[i] = params->wep_key_len[i];
2825 : } else
2826 19 : drv->auth_wep_key_len[i] = 0;
2827 : }
2828 5 : }
2829 :
2830 :
2831 5596 : static void nl80211_unmask_11b_rates(struct i802_bss *bss)
2832 : {
2833 5596 : struct wpa_driver_nl80211_data *drv = bss->drv;
2834 :
2835 5596 : if (is_p2p_net_interface(drv->nlmode) || !drv->disabled_11b_rates)
2836 11191 : return;
2837 :
2838 : /*
2839 : * Looks like we failed to unmask 11b rates previously. This could
2840 : * happen, e.g., if the interface was down at the point in time when a
2841 : * P2P group was terminated.
2842 : */
2843 1 : wpa_printf(MSG_DEBUG,
2844 : "nl80211: Interface %s mode is for non-P2P, but 11b rates were disabled - re-enable them",
2845 1 : bss->ifname);
2846 1 : nl80211_disable_11b_rates(drv, drv->ifindex, 0);
2847 : }
2848 :
2849 :
2850 2718 : static int wpa_driver_nl80211_authenticate(
2851 : struct i802_bss *bss, struct wpa_driver_auth_params *params)
2852 : {
2853 2718 : struct wpa_driver_nl80211_data *drv = bss->drv;
2854 2718 : int ret = -1, i;
2855 : struct nl_msg *msg;
2856 : enum nl80211_auth_type type;
2857 : enum nl80211_iftype nlmode;
2858 2718 : int count = 0;
2859 : int is_retry;
2860 :
2861 2718 : nl80211_unmask_11b_rates(bss);
2862 :
2863 2718 : is_retry = drv->retry_auth;
2864 2718 : drv->retry_auth = 0;
2865 2718 : drv->ignore_deauth_event = 0;
2866 :
2867 2718 : nl80211_mark_disconnected(drv);
2868 2718 : os_memset(drv->auth_bssid, 0, ETH_ALEN);
2869 2718 : if (params->bssid)
2870 2718 : os_memcpy(drv->auth_attempt_bssid, params->bssid, ETH_ALEN);
2871 : else
2872 0 : os_memset(drv->auth_attempt_bssid, 0, ETH_ALEN);
2873 : /* FIX: IBSS mode */
2874 2718 : nlmode = params->p2p ?
2875 : NL80211_IFTYPE_P2P_CLIENT : NL80211_IFTYPE_STATION;
2876 2889 : if (drv->nlmode != nlmode &&
2877 171 : wpa_driver_nl80211_set_mode(bss, nlmode) < 0)
2878 0 : return -1;
2879 :
2880 : retry:
2881 2762 : wpa_printf(MSG_DEBUG, "nl80211: Authenticate (ifindex=%d)",
2882 : drv->ifindex);
2883 :
2884 2762 : msg = nl80211_drv_msg(drv, 0, NL80211_CMD_AUTHENTICATE);
2885 2762 : if (!msg)
2886 0 : goto fail;
2887 :
2888 13810 : for (i = 0; i < 4; i++) {
2889 11048 : if (!params->wep_key[i])
2890 11019 : continue;
2891 58 : wpa_driver_nl80211_set_key(bss->ifname, bss, WPA_ALG_WEP,
2892 : NULL, i,
2893 29 : i == params->wep_tx_keyidx, NULL, 0,
2894 : params->wep_key[i],
2895 : params->wep_key_len[i]);
2896 29 : if (params->wep_tx_keyidx != i)
2897 6 : continue;
2898 23 : if (nl_add_key(msg, WPA_ALG_WEP, i, 1, NULL, 0,
2899 : params->wep_key[i], params->wep_key_len[i]))
2900 0 : goto fail;
2901 : }
2902 :
2903 2762 : if (params->bssid) {
2904 16572 : wpa_printf(MSG_DEBUG, " * bssid=" MACSTR,
2905 16572 : MAC2STR(params->bssid));
2906 2762 : if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid))
2907 0 : goto fail;
2908 : }
2909 2762 : if (params->freq) {
2910 2762 : wpa_printf(MSG_DEBUG, " * freq=%d", params->freq);
2911 2762 : if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq))
2912 0 : goto fail;
2913 : }
2914 2762 : if (params->ssid) {
2915 5524 : wpa_hexdump_ascii(MSG_DEBUG, " * SSID",
2916 2762 : params->ssid, params->ssid_len);
2917 2762 : if (nla_put(msg, NL80211_ATTR_SSID, params->ssid_len,
2918 2762 : params->ssid))
2919 0 : goto fail;
2920 : }
2921 2762 : wpa_hexdump(MSG_DEBUG, " * IEs", params->ie, params->ie_len);
2922 2875 : if (params->ie &&
2923 113 : nla_put(msg, NL80211_ATTR_IE, params->ie_len, params->ie))
2924 0 : goto fail;
2925 2762 : if (params->sae_data) {
2926 62 : wpa_hexdump(MSG_DEBUG, " * SAE data", params->sae_data,
2927 : params->sae_data_len);
2928 62 : if (nla_put(msg, NL80211_ATTR_SAE_DATA, params->sae_data_len,
2929 62 : params->sae_data))
2930 0 : goto fail;
2931 : }
2932 2762 : if (params->auth_alg & WPA_AUTH_ALG_OPEN)
2933 2351 : type = NL80211_AUTHTYPE_OPEN_SYSTEM;
2934 411 : else if (params->auth_alg & WPA_AUTH_ALG_SHARED)
2935 12 : type = NL80211_AUTHTYPE_SHARED_KEY;
2936 399 : else if (params->auth_alg & WPA_AUTH_ALG_LEAP)
2937 3 : type = NL80211_AUTHTYPE_NETWORK_EAP;
2938 396 : else if (params->auth_alg & WPA_AUTH_ALG_FT)
2939 334 : type = NL80211_AUTHTYPE_FT;
2940 62 : else if (params->auth_alg & WPA_AUTH_ALG_SAE)
2941 62 : type = NL80211_AUTHTYPE_SAE;
2942 : else
2943 0 : goto fail;
2944 2762 : wpa_printf(MSG_DEBUG, " * Auth Type %d", type);
2945 2762 : if (nla_put_u32(msg, NL80211_ATTR_AUTH_TYPE, type))
2946 0 : goto fail;
2947 2762 : if (params->local_state_change) {
2948 221 : wpa_printf(MSG_DEBUG, " * Local state change only");
2949 221 : if (nla_put_flag(msg, NL80211_ATTR_LOCAL_STATE_CHANGE))
2950 0 : goto fail;
2951 : }
2952 :
2953 2762 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
2954 2762 : msg = NULL;
2955 2762 : if (ret) {
2956 51 : wpa_dbg(drv->ctx, MSG_DEBUG,
2957 : "nl80211: MLME command failed (auth): ret=%d (%s)",
2958 : ret, strerror(-ret));
2959 51 : count++;
2960 95 : if (ret == -EALREADY && count == 1 && params->bssid &&
2961 44 : !params->local_state_change) {
2962 : /*
2963 : * mac80211 does not currently accept new
2964 : * authentication if we are already authenticated. As a
2965 : * workaround, force deauthentication and try again.
2966 : */
2967 44 : wpa_printf(MSG_DEBUG, "nl80211: Retry authentication "
2968 : "after forced deauthentication");
2969 44 : drv->ignore_deauth_event = 1;
2970 44 : wpa_driver_nl80211_deauthenticate(
2971 : bss, params->bssid,
2972 : WLAN_REASON_PREV_AUTH_NOT_VALID);
2973 44 : nlmsg_free(msg);
2974 44 : goto retry;
2975 : }
2976 :
2977 12 : if (ret == -ENOENT && params->freq && !is_retry) {
2978 : /*
2979 : * cfg80211 has likely expired the BSS entry even
2980 : * though it was previously available in our internal
2981 : * BSS table. To recover quickly, start a single
2982 : * channel scan on the specified channel.
2983 : */
2984 : struct wpa_driver_scan_params scan;
2985 : int freqs[2];
2986 :
2987 5 : os_memset(&scan, 0, sizeof(scan));
2988 5 : scan.num_ssids = 1;
2989 5 : if (params->ssid) {
2990 5 : scan.ssids[0].ssid = params->ssid;
2991 5 : scan.ssids[0].ssid_len = params->ssid_len;
2992 : }
2993 5 : freqs[0] = params->freq;
2994 5 : freqs[1] = 0;
2995 5 : scan.freqs = freqs;
2996 5 : wpa_printf(MSG_DEBUG, "nl80211: Trigger single "
2997 : "channel scan to refresh cfg80211 BSS "
2998 : "entry");
2999 5 : ret = wpa_driver_nl80211_scan(bss, &scan);
3000 5 : if (ret == 0) {
3001 5 : nl80211_copy_auth_params(drv, params);
3002 5 : drv->scan_for_auth = 1;
3003 : }
3004 2 : } else if (is_retry) {
3005 : /*
3006 : * Need to indicate this with an event since the return
3007 : * value from the retry is not delivered to core code.
3008 : */
3009 : union wpa_event_data event;
3010 2 : wpa_printf(MSG_DEBUG, "nl80211: Authentication retry "
3011 : "failed");
3012 2 : os_memset(&event, 0, sizeof(event));
3013 2 : os_memcpy(event.timeout_event.addr, drv->auth_bssid_,
3014 : ETH_ALEN);
3015 2 : wpa_supplicant_event(drv->ctx, EVENT_AUTH_TIMED_OUT,
3016 : &event);
3017 : }
3018 : } else {
3019 2711 : wpa_printf(MSG_DEBUG,
3020 : "nl80211: Authentication request send successfully");
3021 : }
3022 :
3023 : fail:
3024 2718 : nlmsg_free(msg);
3025 2718 : return ret;
3026 : }
3027 :
3028 :
3029 5 : int wpa_driver_nl80211_authenticate_retry(struct wpa_driver_nl80211_data *drv)
3030 : {
3031 : struct wpa_driver_auth_params params;
3032 5 : struct i802_bss *bss = drv->first_bss;
3033 : int i;
3034 :
3035 5 : wpa_printf(MSG_DEBUG, "nl80211: Try to authenticate again");
3036 :
3037 5 : os_memset(¶ms, 0, sizeof(params));
3038 5 : params.freq = drv->auth_freq;
3039 5 : params.auth_alg = drv->auth_alg;
3040 5 : params.wep_tx_keyidx = drv->auth_wep_tx_keyidx;
3041 5 : params.local_state_change = drv->auth_local_state_change;
3042 5 : params.p2p = drv->auth_p2p;
3043 :
3044 5 : if (!is_zero_ether_addr(drv->auth_bssid_))
3045 5 : params.bssid = drv->auth_bssid_;
3046 :
3047 5 : if (drv->auth_ssid_len) {
3048 5 : params.ssid = drv->auth_ssid;
3049 5 : params.ssid_len = drv->auth_ssid_len;
3050 : }
3051 :
3052 5 : params.ie = drv->auth_ie;
3053 5 : params.ie_len = drv->auth_ie_len;
3054 :
3055 25 : for (i = 0; i < 4; i++) {
3056 20 : if (drv->auth_wep_key_len[i]) {
3057 1 : params.wep_key[i] = drv->auth_wep_key[i];
3058 1 : params.wep_key_len[i] = drv->auth_wep_key_len[i];
3059 : }
3060 : }
3061 :
3062 5 : drv->retry_auth = 1;
3063 5 : return wpa_driver_nl80211_authenticate(bss, ¶ms);
3064 : }
3065 :
3066 :
3067 11657 : static int wpa_driver_nl80211_send_frame(struct i802_bss *bss,
3068 : const void *data, size_t len,
3069 : int encrypt, int noack,
3070 : unsigned int freq, int no_cck,
3071 : int offchanok, unsigned int wait_time)
3072 : {
3073 11657 : struct wpa_driver_nl80211_data *drv = bss->drv;
3074 : u64 cookie;
3075 : int res;
3076 :
3077 11657 : if (freq == 0 && drv->nlmode == NL80211_IFTYPE_ADHOC) {
3078 22 : freq = nl80211_get_assoc_freq(drv);
3079 22 : wpa_printf(MSG_DEBUG,
3080 : "nl80211: send_frame - Use assoc_freq=%u for IBSS",
3081 : freq);
3082 : }
3083 11657 : if (freq == 0) {
3084 11296 : wpa_printf(MSG_DEBUG, "nl80211: send_frame - Use bss->freq=%u",
3085 : bss->freq);
3086 11296 : freq = bss->freq;
3087 : }
3088 :
3089 11657 : if (drv->use_monitor) {
3090 102 : wpa_printf(MSG_DEBUG, "nl80211: send_frame(freq=%u bss->freq=%u) -> send_monitor",
3091 : freq, bss->freq);
3092 102 : return nl80211_send_monitor(drv, data, len, encrypt, noack);
3093 : }
3094 :
3095 11555 : wpa_printf(MSG_DEBUG, "nl80211: send_frame -> send_frame_cmd");
3096 11555 : res = nl80211_send_frame_cmd(bss, freq, wait_time, data, len,
3097 : &cookie, no_cck, noack, offchanok);
3098 11555 : if (res == 0 && !noack) {
3099 : const struct ieee80211_mgmt *mgmt;
3100 : u16 fc;
3101 :
3102 8508 : mgmt = (const struct ieee80211_mgmt *) data;
3103 8508 : fc = le_to_host16(mgmt->frame_control);
3104 17016 : if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
3105 8508 : WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_ACTION) {
3106 1500 : wpa_printf(MSG_MSGDUMP,
3107 : "nl80211: Update send_action_cookie from 0x%llx to 0x%llx",
3108 : (long long unsigned int)
3109 750 : drv->send_action_cookie,
3110 : (long long unsigned int) cookie);
3111 750 : drv->send_action_cookie = cookie;
3112 : }
3113 : }
3114 :
3115 11555 : return res;
3116 : }
3117 :
3118 :
3119 12257 : static int wpa_driver_nl80211_send_mlme(struct i802_bss *bss, const u8 *data,
3120 : size_t data_len, int noack,
3121 : unsigned int freq, int no_cck,
3122 : int offchanok,
3123 : unsigned int wait_time)
3124 : {
3125 12257 : struct wpa_driver_nl80211_data *drv = bss->drv;
3126 : struct ieee80211_mgmt *mgmt;
3127 12257 : int encrypt = 1;
3128 : u16 fc;
3129 :
3130 12257 : mgmt = (struct ieee80211_mgmt *) data;
3131 12257 : fc = le_to_host16(mgmt->frame_control);
3132 85799 : wpa_printf(MSG_DEBUG, "nl80211: send_mlme - da= " MACSTR
3133 : " noack=%d freq=%u no_cck=%d offchanok=%d wait_time=%u fc=0x%x (%s) nlmode=%d",
3134 73542 : MAC2STR(mgmt->da), noack, freq, no_cck, offchanok, wait_time,
3135 12257 : fc, fc2str(fc), drv->nlmode);
3136 :
3137 23817 : if ((is_sta_interface(drv->nlmode) ||
3138 12262 : drv->nlmode == NL80211_IFTYPE_P2P_DEVICE) &&
3139 1404 : WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
3140 702 : WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_PROBE_RESP) {
3141 : /*
3142 : * The use of last_mgmt_freq is a bit of a hack,
3143 : * but it works due to the single-threaded nature
3144 : * of wpa_supplicant.
3145 : */
3146 672 : if (freq == 0) {
3147 672 : wpa_printf(MSG_DEBUG, "nl80211: Use last_mgmt_freq=%d",
3148 : drv->last_mgmt_freq);
3149 672 : freq = drv->last_mgmt_freq;
3150 : }
3151 672 : return nl80211_send_frame_cmd(bss, freq, 0,
3152 : data, data_len, NULL, 1, noack,
3153 : 1);
3154 : }
3155 :
3156 11585 : if (drv->device_ap_sme && is_ap_interface(drv->nlmode)) {
3157 0 : if (freq == 0) {
3158 0 : wpa_printf(MSG_DEBUG, "nl80211: Use bss->freq=%d",
3159 : bss->freq);
3160 0 : freq = bss->freq;
3161 : }
3162 0 : return nl80211_send_frame_cmd(bss, freq,
3163 0 : (int) freq == bss->freq ? 0 :
3164 : wait_time,
3165 : data, data_len,
3166 : &drv->send_action_cookie,
3167 : no_cck, noack, offchanok);
3168 : }
3169 :
3170 23170 : if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
3171 11585 : WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_AUTH) {
3172 : /*
3173 : * Only one of the authentication frame types is encrypted.
3174 : * In order for static WEP encryption to work properly (i.e.,
3175 : * to not encrypt the frame), we need to tell mac80211 about
3176 : * the frames that must not be encrypted.
3177 : */
3178 2991 : u16 auth_alg = le_to_host16(mgmt->u.auth.auth_alg);
3179 2991 : u16 auth_trans = le_to_host16(mgmt->u.auth.auth_transaction);
3180 2991 : if (auth_alg != WLAN_AUTH_SHARED_KEY || auth_trans != 3)
3181 2991 : encrypt = 0;
3182 : }
3183 :
3184 11585 : wpa_printf(MSG_DEBUG, "nl80211: send_mlme -> send_frame");
3185 11585 : return wpa_driver_nl80211_send_frame(bss, data, data_len, encrypt,
3186 : noack, freq, no_cck, offchanok,
3187 : wait_time);
3188 : }
3189 :
3190 :
3191 2902 : static int nl80211_put_basic_rates(struct nl_msg *msg, const int *basic_rates)
3192 : {
3193 : u8 rates[NL80211_MAX_SUPP_RATES];
3194 2902 : u8 rates_len = 0;
3195 : int i;
3196 :
3197 2902 : if (!basic_rates)
3198 0 : return 0;
3199 :
3200 13040 : for (i = 0; i < NL80211_MAX_SUPP_RATES && basic_rates[i] >= 0; i++)
3201 10138 : rates[rates_len++] = basic_rates[i] / 5;
3202 :
3203 2902 : return nla_put(msg, NL80211_ATTR_BSS_BASIC_RATES, rates_len, rates);
3204 : }
3205 :
3206 :
3207 2869 : static int nl80211_set_bss(struct i802_bss *bss, int cts, int preamble,
3208 : int slot, int ht_opmode, int ap_isolate,
3209 : const int *basic_rates)
3210 : {
3211 2869 : struct wpa_driver_nl80211_data *drv = bss->drv;
3212 : struct nl_msg *msg;
3213 :
3214 2869 : if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_SET_BSS)) ||
3215 2869 : (cts >= 0 &&
3216 5738 : nla_put_u8(msg, NL80211_ATTR_BSS_CTS_PROT, cts)) ||
3217 2869 : (preamble >= 0 &&
3218 5738 : nla_put_u8(msg, NL80211_ATTR_BSS_SHORT_PREAMBLE, preamble)) ||
3219 2765 : (slot >= 0 &&
3220 5634 : nla_put_u8(msg, NL80211_ATTR_BSS_SHORT_SLOT_TIME, slot)) ||
3221 2775 : (ht_opmode >= 0 &&
3222 5644 : nla_put_u16(msg, NL80211_ATTR_BSS_HT_OPMODE, ht_opmode)) ||
3223 2869 : (ap_isolate >= 0 &&
3224 5738 : nla_put_u8(msg, NL80211_ATTR_AP_ISOLATE, ap_isolate)) ||
3225 2869 : nl80211_put_basic_rates(msg, basic_rates)) {
3226 0 : nlmsg_free(msg);
3227 0 : return -ENOBUFS;
3228 : }
3229 :
3230 2869 : return send_and_recv_msgs(drv, msg, NULL, NULL);
3231 : }
3232 :
3233 :
3234 0 : static int wpa_driver_nl80211_set_acl(void *priv,
3235 : struct hostapd_acl_params *params)
3236 : {
3237 0 : struct i802_bss *bss = priv;
3238 0 : struct wpa_driver_nl80211_data *drv = bss->drv;
3239 : struct nl_msg *msg;
3240 : struct nlattr *acl;
3241 : unsigned int i;
3242 : int ret;
3243 :
3244 0 : if (!(drv->capa.max_acl_mac_addrs))
3245 0 : return -ENOTSUP;
3246 :
3247 0 : if (params->num_mac_acl > drv->capa.max_acl_mac_addrs)
3248 0 : return -ENOTSUP;
3249 :
3250 0 : wpa_printf(MSG_DEBUG, "nl80211: Set %s ACL (num_mac_acl=%u)",
3251 0 : params->acl_policy ? "Accept" : "Deny", params->num_mac_acl);
3252 :
3253 0 : if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_SET_MAC_ACL)) ||
3254 0 : nla_put_u32(msg, NL80211_ATTR_ACL_POLICY, params->acl_policy ?
3255 : NL80211_ACL_POLICY_DENY_UNLESS_LISTED :
3256 0 : NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED) ||
3257 : (acl = nla_nest_start(msg, NL80211_ATTR_MAC_ADDRS)) == NULL) {
3258 0 : nlmsg_free(msg);
3259 0 : return -ENOMEM;
3260 : }
3261 :
3262 0 : for (i = 0; i < params->num_mac_acl; i++) {
3263 0 : if (nla_put(msg, i + 1, ETH_ALEN, params->mac_acl[i].addr)) {
3264 0 : nlmsg_free(msg);
3265 0 : return -ENOMEM;
3266 : }
3267 : }
3268 :
3269 0 : nla_nest_end(msg, acl);
3270 :
3271 0 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
3272 0 : if (ret) {
3273 0 : wpa_printf(MSG_DEBUG, "nl80211: Failed to set MAC ACL: %d (%s)",
3274 : ret, strerror(-ret));
3275 : }
3276 :
3277 0 : return ret;
3278 : }
3279 :
3280 :
3281 2930 : static int nl80211_put_beacon_int(struct nl_msg *msg, int beacon_int)
3282 : {
3283 2930 : if (beacon_int > 0) {
3284 2887 : wpa_printf(MSG_DEBUG, " * beacon_int=%d", beacon_int);
3285 2887 : return nla_put_u32(msg, NL80211_ATTR_BEACON_INTERVAL,
3286 : beacon_int);
3287 : }
3288 :
3289 43 : return 0;
3290 : }
3291 :
3292 :
3293 2878 : static int wpa_driver_nl80211_set_ap(void *priv,
3294 : struct wpa_driver_ap_params *params)
3295 : {
3296 2878 : struct i802_bss *bss = priv;
3297 2878 : struct wpa_driver_nl80211_data *drv = bss->drv;
3298 : struct nl_msg *msg;
3299 2878 : u8 cmd = NL80211_CMD_NEW_BEACON;
3300 : int ret;
3301 : int beacon_set;
3302 : int num_suites;
3303 : int smps_mode;
3304 : u32 suites[10], suite;
3305 : u32 ver;
3306 :
3307 2878 : beacon_set = params->reenable ? 0 : bss->beacon_set;
3308 :
3309 2878 : wpa_printf(MSG_DEBUG, "nl80211: Set beacon (beacon_set=%d)",
3310 : beacon_set);
3311 2878 : if (beacon_set)
3312 1532 : cmd = NL80211_CMD_SET_BEACON;
3313 :
3314 5756 : wpa_hexdump(MSG_DEBUG, "nl80211: Beacon head",
3315 2878 : params->head, params->head_len);
3316 5756 : wpa_hexdump(MSG_DEBUG, "nl80211: Beacon tail",
3317 2878 : params->tail, params->tail_len);
3318 2878 : wpa_printf(MSG_DEBUG, "nl80211: ifindex=%d", bss->ifindex);
3319 2878 : wpa_printf(MSG_DEBUG, "nl80211: beacon_int=%d", params->beacon_int);
3320 2878 : wpa_printf(MSG_DEBUG, "nl80211: dtim_period=%d", params->dtim_period);
3321 5756 : wpa_hexdump_ascii(MSG_DEBUG, "nl80211: ssid",
3322 2878 : params->ssid, params->ssid_len);
3323 5756 : if (!(msg = nl80211_bss_msg(bss, 0, cmd)) ||
3324 2878 : nla_put(msg, NL80211_ATTR_BEACON_HEAD, params->head_len,
3325 5756 : params->head) ||
3326 2878 : nla_put(msg, NL80211_ATTR_BEACON_TAIL, params->tail_len,
3327 5756 : params->tail) ||
3328 5756 : nl80211_put_beacon_int(msg, params->beacon_int) ||
3329 5756 : nla_put_u32(msg, NL80211_ATTR_DTIM_PERIOD, params->dtim_period) ||
3330 2878 : nla_put(msg, NL80211_ATTR_SSID, params->ssid_len, params->ssid))
3331 : goto fail;
3332 2878 : if (params->proberesp && params->proberesp_len) {
3333 0 : wpa_hexdump(MSG_DEBUG, "nl80211: proberesp (offload)",
3334 0 : params->proberesp, params->proberesp_len);
3335 0 : if (nla_put(msg, NL80211_ATTR_PROBE_RESP, params->proberesp_len,
3336 0 : params->proberesp))
3337 0 : goto fail;
3338 : }
3339 2878 : switch (params->hide_ssid) {
3340 : case NO_SSID_HIDING:
3341 2869 : wpa_printf(MSG_DEBUG, "nl80211: hidden SSID not in use");
3342 2869 : if (nla_put_u32(msg, NL80211_ATTR_HIDDEN_SSID,
3343 : NL80211_HIDDEN_SSID_NOT_IN_USE))
3344 0 : goto fail;
3345 2869 : break;
3346 : case HIDDEN_SSID_ZERO_LEN:
3347 8 : wpa_printf(MSG_DEBUG, "nl80211: hidden SSID zero len");
3348 8 : if (nla_put_u32(msg, NL80211_ATTR_HIDDEN_SSID,
3349 : NL80211_HIDDEN_SSID_ZERO_LEN))
3350 0 : goto fail;
3351 8 : break;
3352 : case HIDDEN_SSID_ZERO_CONTENTS:
3353 1 : wpa_printf(MSG_DEBUG, "nl80211: hidden SSID zero contents");
3354 1 : if (nla_put_u32(msg, NL80211_ATTR_HIDDEN_SSID,
3355 : NL80211_HIDDEN_SSID_ZERO_CONTENTS))
3356 0 : goto fail;
3357 1 : break;
3358 : }
3359 2878 : wpa_printf(MSG_DEBUG, "nl80211: privacy=%d", params->privacy);
3360 5319 : if (params->privacy &&
3361 2441 : nla_put_flag(msg, NL80211_ATTR_PRIVACY))
3362 0 : goto fail;
3363 2878 : wpa_printf(MSG_DEBUG, "nl80211: auth_algs=0x%x", params->auth_algs);
3364 2878 : if ((params->auth_algs & (WPA_AUTH_ALG_OPEN | WPA_AUTH_ALG_SHARED)) ==
3365 : (WPA_AUTH_ALG_OPEN | WPA_AUTH_ALG_SHARED)) {
3366 : /* Leave out the attribute */
3367 1570 : } else if (params->auth_algs & WPA_AUTH_ALG_SHARED) {
3368 22 : if (nla_put_u32(msg, NL80211_ATTR_AUTH_TYPE,
3369 : NL80211_AUTHTYPE_SHARED_KEY))
3370 0 : goto fail;
3371 : } else {
3372 1548 : if (nla_put_u32(msg, NL80211_ATTR_AUTH_TYPE,
3373 : NL80211_AUTHTYPE_OPEN_SYSTEM))
3374 0 : goto fail;
3375 : }
3376 :
3377 2878 : wpa_printf(MSG_DEBUG, "nl80211: wpa_version=0x%x", params->wpa_version);
3378 2878 : ver = 0;
3379 2878 : if (params->wpa_version & WPA_PROTO_WPA)
3380 99 : ver |= NL80211_WPA_VERSION_1;
3381 2878 : if (params->wpa_version & WPA_PROTO_RSN)
3382 2366 : ver |= NL80211_WPA_VERSION_2;
3383 5275 : if (ver &&
3384 2397 : nla_put_u32(msg, NL80211_ATTR_WPA_VERSIONS, ver))
3385 0 : goto fail;
3386 :
3387 2878 : wpa_printf(MSG_DEBUG, "nl80211: key_mgmt_suites=0x%x",
3388 : params->key_mgmt_suites);
3389 2878 : num_suites = 0;
3390 2878 : if (params->key_mgmt_suites & WPA_KEY_MGMT_IEEE8021X)
3391 399 : suites[num_suites++] = WLAN_AKM_SUITE_8021X;
3392 2878 : if (params->key_mgmt_suites & WPA_KEY_MGMT_PSK)
3393 1962 : suites[num_suites++] = WLAN_AKM_SUITE_PSK;
3394 5219 : if (num_suites &&
3395 2341 : nla_put(msg, NL80211_ATTR_AKM_SUITES, num_suites * sizeof(u32),
3396 : suites))
3397 0 : goto fail;
3398 :
3399 2886 : if (params->key_mgmt_suites & WPA_KEY_MGMT_IEEE8021X_NO_WPA &&
3400 13 : params->pairwise_ciphers & (WPA_CIPHER_WEP104 | WPA_CIPHER_WEP40) &&
3401 5 : nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT))
3402 0 : goto fail;
3403 :
3404 2878 : wpa_printf(MSG_DEBUG, "nl80211: pairwise_ciphers=0x%x",
3405 : params->pairwise_ciphers);
3406 2878 : num_suites = wpa_cipher_to_cipher_suites(params->pairwise_ciphers,
3407 : suites, ARRAY_SIZE(suites));
3408 5329 : if (num_suites &&
3409 2451 : nla_put(msg, NL80211_ATTR_CIPHER_SUITES_PAIRWISE,
3410 : num_suites * sizeof(u32), suites))
3411 0 : goto fail;
3412 :
3413 2878 : wpa_printf(MSG_DEBUG, "nl80211: group_cipher=0x%x",
3414 : params->group_cipher);
3415 2878 : suite = wpa_cipher_to_cipher_suite(params->group_cipher);
3416 5329 : if (suite &&
3417 2451 : nla_put_u32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP, suite))
3418 0 : goto fail;
3419 :
3420 2878 : switch (params->smps_mode) {
3421 : case HT_CAP_INFO_SMPS_DYNAMIC:
3422 1 : wpa_printf(MSG_DEBUG, "nl80211: SMPS mode - dynamic");
3423 1 : smps_mode = NL80211_SMPS_DYNAMIC;
3424 1 : break;
3425 : case HT_CAP_INFO_SMPS_STATIC:
3426 1 : wpa_printf(MSG_DEBUG, "nl80211: SMPS mode - static");
3427 1 : smps_mode = NL80211_SMPS_STATIC;
3428 1 : break;
3429 : default:
3430 : /* invalid - fallback to smps off */
3431 : case HT_CAP_INFO_SMPS_DISABLED:
3432 2876 : wpa_printf(MSG_DEBUG, "nl80211: SMPS mode - off");
3433 2876 : smps_mode = NL80211_SMPS_OFF;
3434 2876 : break;
3435 : }
3436 2878 : if (nla_put_u32(msg, NL80211_ATTR_SMPS_MODE, smps_mode))
3437 0 : goto fail;
3438 :
3439 2878 : if (params->beacon_ies) {
3440 2878 : wpa_hexdump_buf(MSG_DEBUG, "nl80211: beacon_ies",
3441 : params->beacon_ies);
3442 5756 : if (nla_put(msg, NL80211_ATTR_IE,
3443 2878 : wpabuf_len(params->beacon_ies),
3444 : wpabuf_head(params->beacon_ies)))
3445 0 : goto fail;
3446 : }
3447 2878 : if (params->proberesp_ies) {
3448 2878 : wpa_hexdump_buf(MSG_DEBUG, "nl80211: proberesp_ies",
3449 : params->proberesp_ies);
3450 5756 : if (nla_put(msg, NL80211_ATTR_IE_PROBE_RESP,
3451 2878 : wpabuf_len(params->proberesp_ies),
3452 : wpabuf_head(params->proberesp_ies)))
3453 0 : goto fail;
3454 : }
3455 2878 : if (params->assocresp_ies) {
3456 2878 : wpa_hexdump_buf(MSG_DEBUG, "nl80211: assocresp_ies",
3457 : params->assocresp_ies);
3458 5756 : if (nla_put(msg, NL80211_ATTR_IE_ASSOC_RESP,
3459 2878 : wpabuf_len(params->assocresp_ies),
3460 : wpabuf_head(params->assocresp_ies)))
3461 0 : goto fail;
3462 : }
3463 :
3464 2878 : if (drv->capa.flags & WPA_DRIVER_FLAGS_INACTIVITY_TIMER) {
3465 0 : wpa_printf(MSG_DEBUG, "nl80211: ap_max_inactivity=%d",
3466 : params->ap_max_inactivity);
3467 0 : if (nla_put_u16(msg, NL80211_ATTR_INACTIVITY_TIMEOUT,
3468 0 : params->ap_max_inactivity))
3469 0 : goto fail;
3470 : }
3471 :
3472 : #ifdef CONFIG_P2P
3473 1528 : if (params->p2p_go_ctwindow > 0) {
3474 0 : if (drv->p2p_go_ctwindow_supported) {
3475 0 : wpa_printf(MSG_DEBUG, "nl80211: P2P GO ctwindow=%d",
3476 0 : params->p2p_go_ctwindow);
3477 0 : if (nla_put_u8(msg, NL80211_ATTR_P2P_CTWINDOW,
3478 0 : params->p2p_go_ctwindow))
3479 0 : goto fail;
3480 : } else {
3481 0 : wpa_printf(MSG_INFO,
3482 : "nl80211: Driver does not support CTWindow configuration - ignore this parameter");
3483 : }
3484 : }
3485 : #endif /* CONFIG_P2P */
3486 :
3487 2878 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
3488 2878 : if (ret) {
3489 9 : wpa_printf(MSG_DEBUG, "nl80211: Beacon set failed: %d (%s)",
3490 : ret, strerror(-ret));
3491 : } else {
3492 2869 : bss->beacon_set = 1;
3493 2869 : nl80211_set_bss(bss, params->cts_protect, params->preamble,
3494 : params->short_slot_time, params->ht_opmode,
3495 2869 : params->isolate, params->basic_rates);
3496 4401 : if (beacon_set && params->freq &&
3497 1532 : params->freq->bandwidth != bss->bandwidth) {
3498 16 : wpa_printf(MSG_DEBUG,
3499 : "nl80211: Update BSS %s bandwidth: %d -> %d",
3500 8 : bss->ifname, bss->bandwidth,
3501 8 : params->freq->bandwidth);
3502 8 : ret = nl80211_set_channel(bss, params->freq, 1);
3503 16 : if (ret) {
3504 0 : wpa_printf(MSG_DEBUG,
3505 : "nl80211: Frequency set failed: %d (%s)",
3506 : ret, strerror(-ret));
3507 : } else {
3508 8 : wpa_printf(MSG_DEBUG,
3509 : "nl80211: Frequency set succeeded for ht2040 coex");
3510 8 : bss->bandwidth = params->freq->bandwidth;
3511 : }
3512 2861 : } else if (!beacon_set) {
3513 : /*
3514 : * cfg80211 updates the driver on frequence change in AP
3515 : * mode only at the point when beaconing is started, so
3516 : * set the initial value here.
3517 : */
3518 1337 : bss->bandwidth = params->freq->bandwidth;
3519 : }
3520 : }
3521 2878 : return ret;
3522 : fail:
3523 0 : nlmsg_free(msg);
3524 0 : return -ENOBUFS;
3525 : }
3526 :
3527 :
3528 1710 : static int nl80211_put_freq_params(struct nl_msg *msg,
3529 : const struct hostapd_freq_params *freq)
3530 : {
3531 1710 : wpa_printf(MSG_DEBUG, " * freq=%d", freq->freq);
3532 1710 : if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq->freq))
3533 0 : return -ENOBUFS;
3534 :
3535 1710 : wpa_printf(MSG_DEBUG, " * vht_enabled=%d", freq->vht_enabled);
3536 1710 : wpa_printf(MSG_DEBUG, " * ht_enabled=%d", freq->ht_enabled);
3537 :
3538 1710 : if (freq->vht_enabled) {
3539 : enum nl80211_chan_width cw;
3540 :
3541 29 : wpa_printf(MSG_DEBUG, " * bandwidth=%d", freq->bandwidth);
3542 29 : switch (freq->bandwidth) {
3543 : case 20:
3544 12 : cw = NL80211_CHAN_WIDTH_20;
3545 12 : break;
3546 : case 40:
3547 2 : cw = NL80211_CHAN_WIDTH_40;
3548 2 : break;
3549 : case 80:
3550 10 : if (freq->center_freq2)
3551 2 : cw = NL80211_CHAN_WIDTH_80P80;
3552 : else
3553 8 : cw = NL80211_CHAN_WIDTH_80;
3554 10 : break;
3555 : case 160:
3556 4 : cw = NL80211_CHAN_WIDTH_160;
3557 4 : break;
3558 : default:
3559 1 : return -EINVAL;
3560 : }
3561 :
3562 28 : wpa_printf(MSG_DEBUG, " * channel_width=%d", cw);
3563 28 : wpa_printf(MSG_DEBUG, " * center_freq1=%d",
3564 : freq->center_freq1);
3565 28 : wpa_printf(MSG_DEBUG, " * center_freq2=%d",
3566 : freq->center_freq2);
3567 56 : if (nla_put_u32(msg, NL80211_ATTR_CHANNEL_WIDTH, cw) ||
3568 28 : nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ1,
3569 56 : freq->center_freq1) ||
3570 30 : (freq->center_freq2 &&
3571 2 : nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ2,
3572 2 : freq->center_freq2)))
3573 0 : return -ENOBUFS;
3574 1681 : } else if (freq->ht_enabled) {
3575 : enum nl80211_channel_type ct;
3576 :
3577 1335 : wpa_printf(MSG_DEBUG, " * sec_channel_offset=%d",
3578 : freq->sec_channel_offset);
3579 1335 : switch (freq->sec_channel_offset) {
3580 : case -1:
3581 14 : ct = NL80211_CHAN_HT40MINUS;
3582 14 : break;
3583 : case 1:
3584 30 : ct = NL80211_CHAN_HT40PLUS;
3585 30 : break;
3586 : default:
3587 1291 : ct = NL80211_CHAN_HT20;
3588 1291 : break;
3589 : }
3590 :
3591 1335 : wpa_printf(MSG_DEBUG, " * channel_type=%d", ct);
3592 1335 : if (nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, ct))
3593 0 : return -ENOBUFS;
3594 : }
3595 1709 : return 0;
3596 : }
3597 :
3598 :
3599 1621 : static int nl80211_set_channel(struct i802_bss *bss,
3600 : struct hostapd_freq_params *freq, int set_chan)
3601 : {
3602 1621 : struct wpa_driver_nl80211_data *drv = bss->drv;
3603 : struct nl_msg *msg;
3604 : int ret;
3605 :
3606 1621 : wpa_printf(MSG_DEBUG,
3607 : "nl80211: Set freq %d (ht_enabled=%d, vht_enabled=%d, bandwidth=%d MHz, cf1=%d MHz, cf2=%d MHz)",
3608 : freq->freq, freq->ht_enabled, freq->vht_enabled,
3609 : freq->bandwidth, freq->center_freq1, freq->center_freq2);
3610 :
3611 1621 : msg = nl80211_drv_msg(drv, 0, set_chan ? NL80211_CMD_SET_CHANNEL :
3612 : NL80211_CMD_SET_WIPHY);
3613 1621 : if (!msg || nl80211_put_freq_params(msg, freq) < 0) {
3614 0 : nlmsg_free(msg);
3615 0 : return -1;
3616 : }
3617 :
3618 1621 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
3619 1621 : if (ret == 0) {
3620 1620 : bss->freq = freq->freq;
3621 1620 : return 0;
3622 : }
3623 1 : wpa_printf(MSG_DEBUG, "nl80211: Failed to set channel (freq=%d): "
3624 : "%d (%s)", freq->freq, ret, strerror(-ret));
3625 1 : return -1;
3626 : }
3627 :
3628 :
3629 19348 : static u32 sta_flags_nl80211(int flags)
3630 : {
3631 19348 : u32 f = 0;
3632 :
3633 19348 : if (flags & WPA_STA_AUTHORIZED)
3634 7462 : f |= BIT(NL80211_STA_FLAG_AUTHORIZED);
3635 19348 : if (flags & WPA_STA_WMM)
3636 7776 : f |= BIT(NL80211_STA_FLAG_WME);
3637 19348 : if (flags & WPA_STA_SHORT_PREAMBLE)
3638 7571 : f |= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE);
3639 19348 : if (flags & WPA_STA_MFP)
3640 2667 : f |= BIT(NL80211_STA_FLAG_MFP);
3641 19348 : if (flags & WPA_STA_TDLS_PEER)
3642 107 : f |= BIT(NL80211_STA_FLAG_TDLS_PEER);
3643 19348 : if (flags & WPA_STA_AUTHENTICATED)
3644 100 : f |= BIT(NL80211_STA_FLAG_AUTHENTICATED);
3645 :
3646 19348 : return f;
3647 : }
3648 :
3649 :
3650 : #ifdef CONFIG_MESH
3651 211 : static u32 sta_plink_state_nl80211(enum mesh_plink_state state)
3652 : {
3653 211 : switch (state) {
3654 : case PLINK_LISTEN:
3655 55 : return NL80211_PLINK_LISTEN;
3656 : case PLINK_OPEN_SENT:
3657 43 : return NL80211_PLINK_OPN_SNT;
3658 : case PLINK_OPEN_RCVD:
3659 31 : return NL80211_PLINK_OPN_RCVD;
3660 : case PLINK_CNF_RCVD:
3661 0 : return NL80211_PLINK_CNF_RCVD;
3662 : case PLINK_ESTAB:
3663 26 : return NL80211_PLINK_ESTAB;
3664 : case PLINK_HOLDING:
3665 54 : return NL80211_PLINK_HOLDING;
3666 : case PLINK_BLOCKED:
3667 2 : return NL80211_PLINK_BLOCKED;
3668 : default:
3669 0 : wpa_printf(MSG_ERROR, "nl80211: Invalid mesh plink state %d",
3670 : state);
3671 : }
3672 0 : return -1;
3673 : }
3674 : #endif /* CONFIG_MESH */
3675 :
3676 :
3677 2879 : static int wpa_driver_nl80211_sta_add(void *priv,
3678 : struct hostapd_sta_add_params *params)
3679 : {
3680 2879 : struct i802_bss *bss = priv;
3681 2879 : struct wpa_driver_nl80211_data *drv = bss->drv;
3682 : struct nl_msg *msg;
3683 : struct nl80211_sta_flag_update upd;
3684 2879 : int ret = -ENOBUFS;
3685 :
3686 2986 : if ((params->flags & WPA_STA_TDLS_PEER) &&
3687 107 : !(drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT))
3688 0 : return -EOPNOTSUPP;
3689 :
3690 20153 : wpa_printf(MSG_DEBUG, "nl80211: %s STA " MACSTR,
3691 20153 : params->set ? "Set" : "Add", MAC2STR(params->addr));
3692 2879 : msg = nl80211_bss_msg(bss, 0, params->set ? NL80211_CMD_SET_STATION :
3693 : NL80211_CMD_NEW_STATION);
3694 2879 : if (!msg || nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, params->addr))
3695 : goto fail;
3696 :
3697 2879 : if (!params->set || (params->flags & WPA_STA_TDLS_PEER)) {
3698 5430 : wpa_hexdump(MSG_DEBUG, " * supported rates",
3699 2715 : params->supp_rates, params->supp_rates_len);
3700 2715 : wpa_printf(MSG_DEBUG, " * capability=0x%x",
3701 2715 : params->capability);
3702 2715 : if (nla_put(msg, NL80211_ATTR_STA_SUPPORTED_RATES,
3703 5430 : params->supp_rates_len, params->supp_rates) ||
3704 2715 : nla_put_u16(msg, NL80211_ATTR_STA_CAPABILITY,
3705 2715 : params->capability))
3706 : goto fail;
3707 :
3708 2715 : if (params->ht_capabilities) {
3709 2634 : wpa_hexdump(MSG_DEBUG, " * ht_capabilities",
3710 2634 : (u8 *) params->ht_capabilities,
3711 : sizeof(*params->ht_capabilities));
3712 2634 : if (nla_put(msg, NL80211_ATTR_HT_CAPABILITY,
3713 : sizeof(*params->ht_capabilities),
3714 2634 : params->ht_capabilities))
3715 0 : goto fail;
3716 : }
3717 :
3718 2715 : if (params->vht_capabilities) {
3719 90 : wpa_hexdump(MSG_DEBUG, " * vht_capabilities",
3720 90 : (u8 *) params->vht_capabilities,
3721 : sizeof(*params->vht_capabilities));
3722 90 : if (nla_put(msg, NL80211_ATTR_VHT_CAPABILITY,
3723 : sizeof(*params->vht_capabilities),
3724 90 : params->vht_capabilities))
3725 0 : goto fail;
3726 : }
3727 :
3728 2715 : if (params->ext_capab) {
3729 152 : wpa_hexdump(MSG_DEBUG, " * ext_capab",
3730 76 : params->ext_capab, params->ext_capab_len);
3731 76 : if (nla_put(msg, NL80211_ATTR_STA_EXT_CAPABILITY,
3732 76 : params->ext_capab_len, params->ext_capab))
3733 0 : goto fail;
3734 : }
3735 : }
3736 2879 : if (!params->set) {
3737 2666 : if (params->aid) {
3738 2580 : wpa_printf(MSG_DEBUG, " * aid=%u", params->aid);
3739 2580 : if (nla_put_u16(msg, NL80211_ATTR_STA_AID, params->aid))
3740 0 : goto fail;
3741 : } else {
3742 : /*
3743 : * cfg80211 validates that AID is non-zero, so we have
3744 : * to make this a non-zero value for the TDLS case where
3745 : * a dummy STA entry is used for now.
3746 : */
3747 86 : wpa_printf(MSG_DEBUG, " * aid=1 (TDLS workaround)");
3748 86 : if (nla_put_u16(msg, NL80211_ATTR_STA_AID, 1))
3749 0 : goto fail;
3750 : }
3751 2666 : wpa_printf(MSG_DEBUG, " * listen_interval=%u",
3752 2666 : params->listen_interval);
3753 2666 : if (nla_put_u16(msg, NL80211_ATTR_STA_LISTEN_INTERVAL,
3754 2666 : params->listen_interval))
3755 0 : goto fail;
3756 213 : } else if (params->aid && (params->flags & WPA_STA_TDLS_PEER)) {
3757 48 : wpa_printf(MSG_DEBUG, " * peer_aid=%u", params->aid);
3758 48 : if (nla_put_u16(msg, NL80211_ATTR_PEER_AID, params->aid))
3759 0 : goto fail;
3760 : }
3761 :
3762 2879 : if (params->vht_opmode_enabled) {
3763 0 : wpa_printf(MSG_DEBUG, " * opmode=%u", params->vht_opmode);
3764 0 : if (nla_put_u8(msg, NL80211_ATTR_OPMODE_NOTIF,
3765 0 : params->vht_opmode))
3766 0 : goto fail;
3767 : }
3768 :
3769 2879 : if (params->supp_channels) {
3770 152 : wpa_hexdump(MSG_DEBUG, " * supported channels",
3771 76 : params->supp_channels, params->supp_channels_len);
3772 76 : if (nla_put(msg, NL80211_ATTR_STA_SUPPORTED_CHANNELS,
3773 76 : params->supp_channels_len, params->supp_channels))
3774 0 : goto fail;
3775 : }
3776 :
3777 2879 : if (params->supp_oper_classes) {
3778 0 : wpa_hexdump(MSG_DEBUG, " * supported operating classes",
3779 0 : params->supp_oper_classes,
3780 : params->supp_oper_classes_len);
3781 0 : if (nla_put(msg, NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES,
3782 0 : params->supp_oper_classes_len,
3783 0 : params->supp_oper_classes))
3784 0 : goto fail;
3785 : }
3786 :
3787 2879 : os_memset(&upd, 0, sizeof(upd));
3788 2879 : upd.set = sta_flags_nl80211(params->flags);
3789 2879 : upd.mask = upd.set | sta_flags_nl80211(params->flags_mask);
3790 2879 : wpa_printf(MSG_DEBUG, " * flags set=0x%x mask=0x%x",
3791 : upd.set, upd.mask);
3792 2879 : if (nla_put(msg, NL80211_ATTR_STA_FLAGS2, sizeof(upd), &upd))
3793 0 : goto fail;
3794 :
3795 : #ifdef CONFIG_MESH
3796 943 : if (params->plink_state &&
3797 211 : nla_put_u8(msg, NL80211_ATTR_STA_PLINK_STATE,
3798 211 : sta_plink_state_nl80211(params->plink_state)))
3799 0 : goto fail;
3800 : #endif /* CONFIG_MESH */
3801 :
3802 2879 : if (params->flags & WPA_STA_WMM) {
3803 2677 : struct nlattr *wme = nla_nest_start(msg, NL80211_ATTR_STA_WME);
3804 :
3805 2677 : wpa_printf(MSG_DEBUG, " * qosinfo=0x%x", params->qosinfo);
3806 5354 : if (!wme ||
3807 2677 : nla_put_u8(msg, NL80211_STA_WME_UAPSD_QUEUES,
3808 5354 : params->qosinfo & WMM_QOSINFO_STA_AC_MASK) ||
3809 2677 : nla_put_u8(msg, NL80211_STA_WME_MAX_SP,
3810 2677 : (params->qosinfo >> WMM_QOSINFO_STA_SP_SHIFT) &
3811 : WMM_QOSINFO_STA_SP_MASK))
3812 : goto fail;
3813 2677 : nla_nest_end(msg, wme);
3814 : }
3815 :
3816 2879 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
3817 2879 : msg = NULL;
3818 2879 : if (ret)
3819 26 : wpa_printf(MSG_DEBUG, "nl80211: NL80211_CMD_%s_STATION "
3820 13 : "result: %d (%s)", params->set ? "SET" : "NEW", ret,
3821 : strerror(-ret));
3822 2879 : if (ret == -EEXIST)
3823 13 : ret = 0;
3824 : fail:
3825 2879 : nlmsg_free(msg);
3826 2879 : return ret;
3827 : }
3828 :
3829 :
3830 45 : static void rtnl_neigh_delete_fdb_entry(struct i802_bss *bss, const u8 *addr)
3831 : {
3832 : #ifdef CONFIG_LIBNL3_ROUTE
3833 45 : struct wpa_driver_nl80211_data *drv = bss->drv;
3834 : struct rtnl_neigh *rn;
3835 : struct nl_addr *nl_addr;
3836 : int err;
3837 :
3838 45 : rn = rtnl_neigh_alloc();
3839 45 : if (!rn)
3840 0 : return;
3841 :
3842 45 : rtnl_neigh_set_family(rn, AF_BRIDGE);
3843 45 : rtnl_neigh_set_ifindex(rn, bss->ifindex);
3844 45 : nl_addr = nl_addr_build(AF_BRIDGE, (void *) addr, ETH_ALEN);
3845 45 : if (!nl_addr) {
3846 0 : rtnl_neigh_put(rn);
3847 0 : return;
3848 : }
3849 45 : rtnl_neigh_set_lladdr(rn, nl_addr);
3850 :
3851 45 : err = rtnl_neigh_delete(drv->rtnl_sk, rn, 0);
3852 45 : if (err < 0) {
3853 196 : wpa_printf(MSG_DEBUG, "nl80211: bridge FDB entry delete for "
3854 168 : MACSTR " ifindex=%d failed: %s", MAC2STR(addr),
3855 : bss->ifindex, nl_geterror(err));
3856 : } else {
3857 102 : wpa_printf(MSG_DEBUG, "nl80211: deleted bridge FDB entry for "
3858 102 : MACSTR, MAC2STR(addr));
3859 : }
3860 :
3861 45 : nl_addr_put(nl_addr);
3862 45 : rtnl_neigh_put(rn);
3863 : #endif /* CONFIG_LIBNL3_ROUTE */
3864 0 : }
3865 :
3866 :
3867 4744 : static int wpa_driver_nl80211_sta_remove(struct i802_bss *bss, const u8 *addr,
3868 : int deauth, u16 reason_code)
3869 : {
3870 4744 : struct wpa_driver_nl80211_data *drv = bss->drv;
3871 : struct nl_msg *msg;
3872 : int ret;
3873 :
3874 9488 : if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_DEL_STATION)) ||
3875 9488 : nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
3876 0 : (deauth == 0 &&
3877 0 : nla_put_u8(msg, NL80211_ATTR_MGMT_SUBTYPE,
3878 4744 : WLAN_FC_STYPE_DISASSOC)) ||
3879 0 : (deauth == 1 &&
3880 0 : nla_put_u8(msg, NL80211_ATTR_MGMT_SUBTYPE,
3881 4744 : WLAN_FC_STYPE_DEAUTH)) ||
3882 0 : (reason_code &&
3883 0 : nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason_code))) {
3884 0 : nlmsg_free(msg);
3885 0 : return -ENOBUFS;
3886 : }
3887 :
3888 4744 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
3889 37952 : wpa_printf(MSG_DEBUG, "nl80211: sta_remove -> DEL_STATION %s " MACSTR
3890 : " --> %d (%s)",
3891 33208 : bss->ifname, MAC2STR(addr), ret, strerror(-ret));
3892 :
3893 4744 : if (drv->rtnl_sk)
3894 45 : rtnl_neigh_delete_fdb_entry(bss, addr);
3895 :
3896 4744 : if (ret == -ENOENT)
3897 2332 : return 0;
3898 2412 : return ret;
3899 : }
3900 :
3901 :
3902 198 : void nl80211_remove_iface(struct wpa_driver_nl80211_data *drv, int ifidx)
3903 : {
3904 : struct nl_msg *msg;
3905 : struct wpa_driver_nl80211_data *drv2;
3906 :
3907 198 : wpa_printf(MSG_DEBUG, "nl80211: Remove interface ifindex=%d", ifidx);
3908 :
3909 : /* stop listening for EAPOL on this interface */
3910 2424 : dl_list_for_each(drv2, &drv->global->interfaces,
3911 : struct wpa_driver_nl80211_data, list)
3912 2226 : del_ifidx(drv2, ifidx);
3913 :
3914 198 : msg = nl80211_ifindex_msg(drv, ifidx, 0, NL80211_CMD_DEL_INTERFACE);
3915 198 : if (send_and_recv_msgs(drv, msg, NULL, NULL) == 0)
3916 396 : return;
3917 0 : wpa_printf(MSG_ERROR, "Failed to remove interface (ifidx=%d)", ifidx);
3918 : }
3919 :
3920 :
3921 3555 : static const char * nl80211_iftype_str(enum nl80211_iftype mode)
3922 : {
3923 3555 : switch (mode) {
3924 : case NL80211_IFTYPE_ADHOC:
3925 18 : return "ADHOC";
3926 : case NL80211_IFTYPE_STATION:
3927 1631 : return "STATION";
3928 : case NL80211_IFTYPE_AP:
3929 1058 : return "AP";
3930 : case NL80211_IFTYPE_AP_VLAN:
3931 14 : return "AP_VLAN";
3932 : case NL80211_IFTYPE_WDS:
3933 0 : return "WDS";
3934 : case NL80211_IFTYPE_MONITOR:
3935 7 : return "MONITOR";
3936 : case NL80211_IFTYPE_MESH_POINT:
3937 72 : return "MESH_POINT";
3938 : case NL80211_IFTYPE_P2P_CLIENT:
3939 246 : return "P2P_CLIENT";
3940 : case NL80211_IFTYPE_P2P_GO:
3941 493 : return "P2P_GO";
3942 : case NL80211_IFTYPE_P2P_DEVICE:
3943 16 : return "P2P_DEVICE";
3944 : default:
3945 0 : return "unknown";
3946 : }
3947 : }
3948 :
3949 :
3950 214 : static int nl80211_create_iface_once(struct wpa_driver_nl80211_data *drv,
3951 : const char *ifname,
3952 : enum nl80211_iftype iftype,
3953 : const u8 *addr, int wds,
3954 : int (*handler)(struct nl_msg *, void *),
3955 : void *arg)
3956 : {
3957 : struct nl_msg *msg;
3958 : int ifidx;
3959 214 : int ret = -ENOBUFS;
3960 :
3961 214 : wpa_printf(MSG_DEBUG, "nl80211: Create interface iftype %d (%s)",
3962 : iftype, nl80211_iftype_str(iftype));
3963 :
3964 214 : msg = nl80211_cmd_msg(drv->first_bss, 0, NL80211_CMD_NEW_INTERFACE);
3965 428 : if (!msg ||
3966 428 : nla_put_string(msg, NL80211_ATTR_IFNAME, ifname) ||
3967 214 : nla_put_u32(msg, NL80211_ATTR_IFTYPE, iftype))
3968 : goto fail;
3969 :
3970 214 : if (iftype == NL80211_IFTYPE_MONITOR) {
3971 : struct nlattr *flags;
3972 :
3973 7 : flags = nla_nest_start(msg, NL80211_ATTR_MNTR_FLAGS);
3974 14 : if (!flags ||
3975 7 : nla_put_flag(msg, NL80211_MNTR_FLAG_COOK_FRAMES))
3976 : goto fail;
3977 :
3978 7 : nla_nest_end(msg, flags);
3979 207 : } else if (wds) {
3980 1 : if (nla_put_u8(msg, NL80211_ATTR_4ADDR, wds))
3981 0 : goto fail;
3982 : }
3983 :
3984 : /*
3985 : * Tell cfg80211 that the interface belongs to the socket that created
3986 : * it, and the interface should be deleted when the socket is closed.
3987 : */
3988 214 : if (nla_put_flag(msg, NL80211_ATTR_IFACE_SOCKET_OWNER))
3989 0 : goto fail;
3990 :
3991 214 : ret = send_and_recv_msgs(drv, msg, handler, arg);
3992 214 : msg = NULL;
3993 214 : if (ret) {
3994 : fail:
3995 2 : nlmsg_free(msg);
3996 2 : wpa_printf(MSG_ERROR, "Failed to create interface %s: %d (%s)",
3997 : ifname, ret, strerror(-ret));
3998 2 : return ret;
3999 : }
4000 :
4001 212 : if (iftype == NL80211_IFTYPE_P2P_DEVICE)
4002 8 : return 0;
4003 :
4004 204 : ifidx = if_nametoindex(ifname);
4005 204 : wpa_printf(MSG_DEBUG, "nl80211: New interface %s created: ifindex=%d",
4006 : ifname, ifidx);
4007 :
4008 204 : if (ifidx <= 0)
4009 0 : return -1;
4010 :
4011 : /*
4012 : * Some virtual interfaces need to process EAPOL packets and events on
4013 : * the parent interface. This is used mainly with hostapd.
4014 : */
4015 204 : if (drv->hostapd ||
4016 147 : iftype == NL80211_IFTYPE_AP_VLAN ||
4017 147 : iftype == NL80211_IFTYPE_WDS ||
4018 : iftype == NL80211_IFTYPE_MONITOR) {
4019 : /* start listening for EAPOL on this interface */
4020 62 : add_ifidx(drv, ifidx);
4021 : }
4022 :
4023 259 : if (addr && iftype != NL80211_IFTYPE_MONITOR &&
4024 55 : linux_set_ifhwaddr(drv->global->ioctl_sock, ifname, addr)) {
4025 0 : nl80211_remove_iface(drv, ifidx);
4026 0 : return -1;
4027 : }
4028 :
4029 204 : return ifidx;
4030 : }
4031 :
4032 :
4033 213 : int nl80211_create_iface(struct wpa_driver_nl80211_data *drv,
4034 : const char *ifname, enum nl80211_iftype iftype,
4035 : const u8 *addr, int wds,
4036 : int (*handler)(struct nl_msg *, void *),
4037 : void *arg, int use_existing)
4038 : {
4039 : int ret;
4040 :
4041 213 : ret = nl80211_create_iface_once(drv, ifname, iftype, addr, wds, handler,
4042 : arg);
4043 :
4044 : /* if error occurred and interface exists already */
4045 213 : if (ret == -ENFILE && if_nametoindex(ifname)) {
4046 2 : if (use_existing) {
4047 1 : wpa_printf(MSG_DEBUG, "nl80211: Continue using existing interface %s",
4048 : ifname);
4049 2 : if (addr && iftype != NL80211_IFTYPE_MONITOR &&
4050 1 : linux_set_ifhwaddr(drv->global->ioctl_sock, ifname,
4051 0 : addr) < 0 &&
4052 0 : (linux_set_iface_flags(drv->global->ioctl_sock,
4053 0 : ifname, 0) < 0 ||
4054 0 : linux_set_ifhwaddr(drv->global->ioctl_sock, ifname,
4055 0 : addr) < 0 ||
4056 0 : linux_set_iface_flags(drv->global->ioctl_sock,
4057 : ifname, 1) < 0))
4058 0 : return -1;
4059 1 : return -ENFILE;
4060 : }
4061 1 : wpa_printf(MSG_INFO, "Try to remove and re-create %s", ifname);
4062 :
4063 : /* Try to remove the interface that was already there. */
4064 1 : nl80211_remove_iface(drv, if_nametoindex(ifname));
4065 :
4066 : /* Try to create the interface again */
4067 1 : ret = nl80211_create_iface_once(drv, ifname, iftype, addr,
4068 : wds, handler, arg);
4069 : }
4070 :
4071 212 : if (ret >= 0 && is_p2p_net_interface(iftype)) {
4072 138 : wpa_printf(MSG_DEBUG,
4073 : "nl80211: Interface %s created for P2P - disable 11b rates",
4074 : ifname);
4075 138 : nl80211_disable_11b_rates(drv, ret, 1);
4076 : }
4077 :
4078 212 : return ret;
4079 : }
4080 :
4081 :
4082 1452 : static int nl80211_setup_ap(struct i802_bss *bss)
4083 : {
4084 1452 : struct wpa_driver_nl80211_data *drv = bss->drv;
4085 :
4086 4356 : wpa_printf(MSG_DEBUG, "nl80211: Setup AP(%s) - device_ap_sme=%d use_monitor=%d",
4087 4356 : bss->ifname, drv->device_ap_sme, drv->use_monitor);
4088 :
4089 : /*
4090 : * Disable Probe Request reporting unless we need it in this way for
4091 : * devices that include the AP SME, in the other case (unless using
4092 : * monitor iface) we'll get it through the nl_mgmt socket instead.
4093 : */
4094 1452 : if (!drv->device_ap_sme)
4095 1452 : wpa_driver_nl80211_probe_req_report(bss, 0);
4096 :
4097 1452 : if (!drv->device_ap_sme && !drv->use_monitor)
4098 1444 : if (nl80211_mgmt_subscribe_ap(bss))
4099 0 : return -1;
4100 :
4101 1452 : if (drv->device_ap_sme && !drv->use_monitor)
4102 0 : if (nl80211_mgmt_subscribe_ap_dev_sme(bss))
4103 0 : return -1;
4104 :
4105 1460 : if (!drv->device_ap_sme && drv->use_monitor &&
4106 8 : nl80211_create_monitor_interface(drv) &&
4107 0 : !drv->device_ap_sme)
4108 0 : return -1;
4109 :
4110 1452 : if (drv->device_ap_sme &&
4111 0 : wpa_driver_nl80211_probe_req_report(bss, 1) < 0) {
4112 0 : wpa_printf(MSG_DEBUG, "nl80211: Failed to enable "
4113 : "Probe Request frame reporting in AP mode");
4114 : /* Try to survive without this */
4115 : }
4116 :
4117 1452 : return 0;
4118 : }
4119 :
4120 :
4121 1176 : static void nl80211_teardown_ap(struct i802_bss *bss)
4122 : {
4123 1176 : struct wpa_driver_nl80211_data *drv = bss->drv;
4124 :
4125 3528 : wpa_printf(MSG_DEBUG, "nl80211: Teardown AP(%s) - device_ap_sme=%d use_monitor=%d",
4126 3528 : bss->ifname, drv->device_ap_sme, drv->use_monitor);
4127 1176 : if (drv->device_ap_sme) {
4128 0 : wpa_driver_nl80211_probe_req_report(bss, 0);
4129 0 : if (!drv->use_monitor)
4130 0 : nl80211_mgmt_unsubscribe(bss, "AP teardown (dev SME)");
4131 1176 : } else if (drv->use_monitor)
4132 7 : nl80211_remove_monitor_interface(drv);
4133 : else
4134 1169 : nl80211_mgmt_unsubscribe(bss, "AP teardown");
4135 :
4136 1176 : bss->beacon_set = 0;
4137 1176 : }
4138 :
4139 :
4140 9440 : static int nl80211_send_eapol_data(struct i802_bss *bss,
4141 : const u8 *addr, const u8 *data,
4142 : size_t data_len)
4143 : {
4144 : struct sockaddr_ll ll;
4145 : int ret;
4146 :
4147 9440 : if (bss->drv->eapol_tx_sock < 0) {
4148 0 : wpa_printf(MSG_DEBUG, "nl80211: No socket to send EAPOL");
4149 0 : return -1;
4150 : }
4151 :
4152 9440 : os_memset(&ll, 0, sizeof(ll));
4153 9440 : ll.sll_family = AF_PACKET;
4154 9440 : ll.sll_ifindex = bss->ifindex;
4155 9440 : ll.sll_protocol = htons(ETH_P_PAE);
4156 9440 : ll.sll_halen = ETH_ALEN;
4157 9440 : os_memcpy(ll.sll_addr, addr, ETH_ALEN);
4158 9440 : ret = sendto(bss->drv->eapol_tx_sock, data, data_len, 0,
4159 : (struct sockaddr *) &ll, sizeof(ll));
4160 9440 : if (ret < 0)
4161 0 : wpa_printf(MSG_ERROR, "nl80211: EAPOL TX: %s",
4162 0 : strerror(errno));
4163 :
4164 9440 : return ret;
4165 : }
4166 :
4167 :
4168 : static const u8 rfc1042_header[6] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
4169 :
4170 9452 : static int wpa_driver_nl80211_hapd_send_eapol(
4171 : void *priv, const u8 *addr, const u8 *data,
4172 : size_t data_len, int encrypt, const u8 *own_addr, u32 flags)
4173 : {
4174 9452 : struct i802_bss *bss = priv;
4175 9452 : struct wpa_driver_nl80211_data *drv = bss->drv;
4176 : struct ieee80211_hdr *hdr;
4177 : size_t len;
4178 : u8 *pos;
4179 : int res;
4180 9452 : int qos = flags & WPA_STA_WMM;
4181 :
4182 9452 : if (drv->device_ap_sme || !drv->use_monitor)
4183 9440 : return nl80211_send_eapol_data(bss, addr, data, data_len);
4184 :
4185 12 : len = sizeof(*hdr) + (qos ? 2 : 0) + sizeof(rfc1042_header) + 2 +
4186 : data_len;
4187 12 : hdr = os_zalloc(len);
4188 12 : if (hdr == NULL) {
4189 0 : wpa_printf(MSG_INFO, "nl80211: Failed to allocate EAPOL buffer(len=%lu)",
4190 : (unsigned long) len);
4191 0 : return -1;
4192 : }
4193 :
4194 12 : hdr->frame_control =
4195 : IEEE80211_FC(WLAN_FC_TYPE_DATA, WLAN_FC_STYPE_DATA);
4196 12 : hdr->frame_control |= host_to_le16(WLAN_FC_FROMDS);
4197 12 : if (encrypt)
4198 0 : hdr->frame_control |= host_to_le16(WLAN_FC_ISWEP);
4199 12 : if (qos) {
4200 12 : hdr->frame_control |=
4201 : host_to_le16(WLAN_FC_STYPE_QOS_DATA << 4);
4202 : }
4203 :
4204 12 : memcpy(hdr->IEEE80211_DA_FROMDS, addr, ETH_ALEN);
4205 12 : memcpy(hdr->IEEE80211_BSSID_FROMDS, own_addr, ETH_ALEN);
4206 12 : memcpy(hdr->IEEE80211_SA_FROMDS, own_addr, ETH_ALEN);
4207 12 : pos = (u8 *) (hdr + 1);
4208 :
4209 12 : if (qos) {
4210 : /* Set highest priority in QoS header */
4211 12 : pos[0] = 7;
4212 12 : pos[1] = 0;
4213 12 : pos += 2;
4214 : }
4215 :
4216 12 : memcpy(pos, rfc1042_header, sizeof(rfc1042_header));
4217 12 : pos += sizeof(rfc1042_header);
4218 12 : WPA_PUT_BE16(pos, ETH_P_PAE);
4219 12 : pos += 2;
4220 12 : memcpy(pos, data, data_len);
4221 :
4222 12 : res = wpa_driver_nl80211_send_frame(bss, (u8 *) hdr, len, encrypt, 0,
4223 : 0, 0, 0, 0);
4224 12 : if (res < 0) {
4225 0 : wpa_printf(MSG_ERROR, "i802_send_eapol - packet len: %lu - "
4226 : "failed: %d (%s)",
4227 0 : (unsigned long) len, errno, strerror(errno));
4228 : }
4229 12 : os_free(hdr);
4230 :
4231 12 : return res;
4232 : }
4233 :
4234 :
4235 6795 : static int wpa_driver_nl80211_sta_set_flags(void *priv, const u8 *addr,
4236 : int total_flags,
4237 : int flags_or, int flags_and)
4238 : {
4239 6795 : struct i802_bss *bss = priv;
4240 : struct nl_msg *msg;
4241 : struct nlattr *flags;
4242 : struct nl80211_sta_flag_update upd;
4243 :
4244 54360 : wpa_printf(MSG_DEBUG, "nl80211: Set STA flags - ifname=%s addr=" MACSTR
4245 : " total_flags=0x%x flags_or=0x%x flags_and=0x%x authorized=%d",
4246 47565 : bss->ifname, MAC2STR(addr), total_flags, flags_or, flags_and,
4247 6795 : !!(total_flags & WPA_STA_AUTHORIZED));
4248 :
4249 13590 : if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_SET_STATION)) ||
4250 6795 : nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
4251 : goto fail;
4252 :
4253 : /*
4254 : * Backwards compatibility version using NL80211_ATTR_STA_FLAGS. This
4255 : * can be removed eventually.
4256 : */
4257 6795 : flags = nla_nest_start(msg, NL80211_ATTR_STA_FLAGS);
4258 13590 : if (!flags ||
4259 8725 : ((total_flags & WPA_STA_AUTHORIZED) &&
4260 8725 : nla_put_flag(msg, NL80211_STA_FLAG_AUTHORIZED)) ||
4261 13545 : ((total_flags & WPA_STA_WMM) &&
4262 13545 : nla_put_flag(msg, NL80211_STA_FLAG_WME)) ||
4263 13480 : ((total_flags & WPA_STA_SHORT_PREAMBLE) &&
4264 13480 : nla_put_flag(msg, NL80211_STA_FLAG_SHORT_PREAMBLE)) ||
4265 6946 : ((total_flags & WPA_STA_MFP) &&
4266 6946 : nla_put_flag(msg, NL80211_STA_FLAG_MFP)) ||
4267 6795 : ((total_flags & WPA_STA_TDLS_PEER) &&
4268 0 : nla_put_flag(msg, NL80211_STA_FLAG_TDLS_PEER)))
4269 : goto fail;
4270 :
4271 6795 : nla_nest_end(msg, flags);
4272 :
4273 6795 : os_memset(&upd, 0, sizeof(upd));
4274 6795 : upd.mask = sta_flags_nl80211(flags_or | ~flags_and);
4275 6795 : upd.set = sta_flags_nl80211(flags_or);
4276 6795 : if (nla_put(msg, NL80211_ATTR_STA_FLAGS2, sizeof(upd), &upd))
4277 0 : goto fail;
4278 :
4279 6795 : return send_and_recv_msgs(bss->drv, msg, NULL, NULL);
4280 : fail:
4281 0 : nlmsg_free(msg);
4282 0 : return -ENOBUFS;
4283 : }
4284 :
4285 :
4286 312 : static int wpa_driver_nl80211_ap(struct wpa_driver_nl80211_data *drv,
4287 : struct wpa_driver_associate_params *params)
4288 : {
4289 : enum nl80211_iftype nlmode, old_mode;
4290 :
4291 312 : if (params->p2p) {
4292 298 : wpa_printf(MSG_DEBUG, "nl80211: Setup AP operations for P2P "
4293 : "group (GO)");
4294 298 : nlmode = NL80211_IFTYPE_P2P_GO;
4295 : } else
4296 14 : nlmode = NL80211_IFTYPE_AP;
4297 :
4298 312 : old_mode = drv->nlmode;
4299 312 : if (wpa_driver_nl80211_set_mode(drv->first_bss, nlmode)) {
4300 0 : nl80211_remove_monitor_interface(drv);
4301 0 : return -1;
4302 : }
4303 :
4304 623 : if (params->freq.freq &&
4305 311 : nl80211_set_channel(drv->first_bss, ¶ms->freq, 0)) {
4306 1 : if (old_mode != nlmode)
4307 1 : wpa_driver_nl80211_set_mode(drv->first_bss, old_mode);
4308 1 : nl80211_remove_monitor_interface(drv);
4309 1 : return -1;
4310 : }
4311 :
4312 311 : return 0;
4313 : }
4314 :
4315 :
4316 19 : static int nl80211_leave_ibss(struct wpa_driver_nl80211_data *drv,
4317 : int reset_mode)
4318 : {
4319 : struct nl_msg *msg;
4320 : int ret;
4321 :
4322 19 : msg = nl80211_drv_msg(drv, 0, NL80211_CMD_LEAVE_IBSS);
4323 19 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
4324 19 : if (ret) {
4325 1 : wpa_printf(MSG_DEBUG, "nl80211: Leave IBSS failed: ret=%d "
4326 : "(%s)", ret, strerror(-ret));
4327 : } else {
4328 18 : wpa_printf(MSG_DEBUG,
4329 : "nl80211: Leave IBSS request sent successfully");
4330 : }
4331 :
4332 37 : if (reset_mode &&
4333 18 : wpa_driver_nl80211_set_mode(drv->first_bss,
4334 : NL80211_IFTYPE_STATION)) {
4335 0 : wpa_printf(MSG_INFO, "nl80211: Failed to set interface into "
4336 : "station mode");
4337 : }
4338 :
4339 19 : return ret;
4340 : }
4341 :
4342 :
4343 2569 : static int nl80211_ht_vht_overrides(struct nl_msg *msg,
4344 : struct wpa_driver_associate_params *params)
4345 : {
4346 2569 : if (params->disable_ht && nla_put_flag(msg, NL80211_ATTR_DISABLE_HT))
4347 0 : return -1;
4348 :
4349 2569 : if (params->htcaps && params->htcaps_mask) {
4350 2569 : int sz = sizeof(struct ieee80211_ht_capabilities);
4351 2569 : wpa_hexdump(MSG_DEBUG, " * htcaps", params->htcaps, sz);
4352 5138 : wpa_hexdump(MSG_DEBUG, " * htcaps_mask",
4353 2569 : params->htcaps_mask, sz);
4354 2569 : if (nla_put(msg, NL80211_ATTR_HT_CAPABILITY, sz,
4355 5138 : params->htcaps) ||
4356 2569 : nla_put(msg, NL80211_ATTR_HT_CAPABILITY_MASK, sz,
4357 2569 : params->htcaps_mask))
4358 0 : return -1;
4359 : }
4360 :
4361 : #ifdef CONFIG_VHT_OVERRIDES
4362 2569 : if (params->disable_vht) {
4363 1 : wpa_printf(MSG_DEBUG, " * VHT disabled");
4364 1 : if (nla_put_flag(msg, NL80211_ATTR_DISABLE_VHT))
4365 0 : return -1;
4366 : }
4367 :
4368 2569 : if (params->vhtcaps && params->vhtcaps_mask) {
4369 2569 : int sz = sizeof(struct ieee80211_vht_capabilities);
4370 2569 : wpa_hexdump(MSG_DEBUG, " * vhtcaps", params->vhtcaps, sz);
4371 5138 : wpa_hexdump(MSG_DEBUG, " * vhtcaps_mask",
4372 2569 : params->vhtcaps_mask, sz);
4373 2569 : if (nla_put(msg, NL80211_ATTR_VHT_CAPABILITY, sz,
4374 5138 : params->vhtcaps) ||
4375 2569 : nla_put(msg, NL80211_ATTR_VHT_CAPABILITY_MASK, sz,
4376 2569 : params->vhtcaps_mask))
4377 0 : return -1;
4378 : }
4379 : #endif /* CONFIG_VHT_OVERRIDES */
4380 :
4381 2569 : return 0;
4382 : }
4383 :
4384 :
4385 18 : static int wpa_driver_nl80211_ibss(struct wpa_driver_nl80211_data *drv,
4386 : struct wpa_driver_associate_params *params)
4387 : {
4388 : struct nl_msg *msg;
4389 18 : int ret = -1;
4390 18 : int count = 0;
4391 :
4392 18 : wpa_printf(MSG_DEBUG, "nl80211: Join IBSS (ifindex=%d)", drv->ifindex);
4393 :
4394 18 : if (wpa_driver_nl80211_set_mode_ibss(drv->first_bss, ¶ms->freq)) {
4395 0 : wpa_printf(MSG_INFO, "nl80211: Failed to set interface into "
4396 : "IBSS mode");
4397 0 : return -1;
4398 : }
4399 :
4400 : retry:
4401 38 : if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_JOIN_IBSS)) ||
4402 38 : params->ssid == NULL || params->ssid_len > sizeof(drv->ssid))
4403 : goto fail;
4404 :
4405 38 : wpa_hexdump_ascii(MSG_DEBUG, " * SSID",
4406 19 : params->ssid, params->ssid_len);
4407 19 : if (nla_put(msg, NL80211_ATTR_SSID, params->ssid_len, params->ssid))
4408 0 : goto fail;
4409 19 : os_memcpy(drv->ssid, params->ssid, params->ssid_len);
4410 19 : drv->ssid_len = params->ssid_len;
4411 :
4412 38 : if (nl80211_put_freq_params(msg, ¶ms->freq) < 0 ||
4413 19 : nl80211_put_beacon_int(msg, params->beacon_int))
4414 : goto fail;
4415 :
4416 19 : ret = nl80211_set_conn_keys(params, msg);
4417 19 : if (ret)
4418 0 : goto fail;
4419 :
4420 19 : if (params->bssid && params->fixed_bssid) {
4421 24 : wpa_printf(MSG_DEBUG, " * BSSID=" MACSTR,
4422 24 : MAC2STR(params->bssid));
4423 4 : if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid))
4424 0 : goto fail;
4425 : }
4426 :
4427 19 : if (params->fixed_freq) {
4428 0 : wpa_printf(MSG_DEBUG, " * fixed_freq");
4429 0 : if (nla_put_flag(msg, NL80211_ATTR_FREQ_FIXED))
4430 0 : goto fail;
4431 : }
4432 :
4433 38 : if (params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X ||
4434 32 : params->key_mgmt_suite == WPA_KEY_MGMT_PSK ||
4435 26 : params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SHA256 ||
4436 13 : params->key_mgmt_suite == WPA_KEY_MGMT_PSK_SHA256) {
4437 6 : wpa_printf(MSG_DEBUG, " * control port");
4438 6 : if (nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT))
4439 0 : goto fail;
4440 : }
4441 :
4442 19 : if (params->wpa_ie) {
4443 38 : wpa_hexdump(MSG_DEBUG,
4444 : " * Extra IEs for Beacon/Probe Response frames",
4445 19 : params->wpa_ie, params->wpa_ie_len);
4446 19 : if (nla_put(msg, NL80211_ATTR_IE, params->wpa_ie_len,
4447 19 : params->wpa_ie))
4448 0 : goto fail;
4449 : }
4450 :
4451 19 : if (nl80211_ht_vht_overrides(msg, params) < 0)
4452 0 : return -1;
4453 :
4454 19 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
4455 19 : msg = NULL;
4456 19 : if (ret) {
4457 1 : wpa_printf(MSG_DEBUG, "nl80211: Join IBSS failed: ret=%d (%s)",
4458 : ret, strerror(-ret));
4459 1 : count++;
4460 1 : if (ret == -EALREADY && count == 1) {
4461 1 : wpa_printf(MSG_DEBUG, "nl80211: Retry IBSS join after "
4462 : "forced leave");
4463 1 : nl80211_leave_ibss(drv, 0);
4464 1 : nlmsg_free(msg);
4465 1 : goto retry;
4466 : }
4467 : } else {
4468 18 : wpa_printf(MSG_DEBUG,
4469 : "nl80211: Join IBSS request sent successfully");
4470 : }
4471 :
4472 : fail:
4473 18 : nlmsg_free(msg);
4474 18 : return ret;
4475 : }
4476 :
4477 :
4478 2550 : static int nl80211_connect_common(struct wpa_driver_nl80211_data *drv,
4479 : struct wpa_driver_associate_params *params,
4480 : struct nl_msg *msg)
4481 : {
4482 2550 : if (params->bssid) {
4483 15258 : wpa_printf(MSG_DEBUG, " * bssid=" MACSTR,
4484 15258 : MAC2STR(params->bssid));
4485 2543 : if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid))
4486 0 : return -1;
4487 : }
4488 :
4489 2550 : if (params->bssid_hint) {
4490 126 : wpa_printf(MSG_DEBUG, " * bssid_hint=" MACSTR,
4491 126 : MAC2STR(params->bssid_hint));
4492 21 : if (nla_put(msg, NL80211_ATTR_MAC_HINT, ETH_ALEN,
4493 21 : params->bssid_hint))
4494 0 : return -1;
4495 : }
4496 :
4497 2550 : if (params->freq.freq) {
4498 2543 : wpa_printf(MSG_DEBUG, " * freq=%d", params->freq.freq);
4499 2543 : if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ,
4500 2543 : params->freq.freq))
4501 0 : return -1;
4502 2543 : drv->assoc_freq = params->freq.freq;
4503 : } else
4504 7 : drv->assoc_freq = 0;
4505 :
4506 2550 : if (params->freq_hint) {
4507 21 : wpa_printf(MSG_DEBUG, " * freq_hint=%d", params->freq_hint);
4508 21 : if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ_HINT,
4509 21 : params->freq_hint))
4510 0 : return -1;
4511 : }
4512 :
4513 2550 : if (params->bg_scan_period >= 0) {
4514 3 : wpa_printf(MSG_DEBUG, " * bg scan period=%d",
4515 : params->bg_scan_period);
4516 3 : if (nla_put_u16(msg, NL80211_ATTR_BG_SCAN_PERIOD,
4517 3 : params->bg_scan_period))
4518 0 : return -1;
4519 : }
4520 :
4521 2550 : if (params->ssid) {
4522 5100 : wpa_hexdump_ascii(MSG_DEBUG, " * SSID",
4523 2550 : params->ssid, params->ssid_len);
4524 2550 : if (nla_put(msg, NL80211_ATTR_SSID, params->ssid_len,
4525 2550 : params->ssid))
4526 0 : return -1;
4527 2550 : if (params->ssid_len > sizeof(drv->ssid))
4528 0 : return -1;
4529 2550 : os_memcpy(drv->ssid, params->ssid, params->ssid_len);
4530 2550 : drv->ssid_len = params->ssid_len;
4531 : }
4532 :
4533 2550 : wpa_hexdump(MSG_DEBUG, " * IEs", params->wpa_ie, params->wpa_ie_len);
4534 5100 : if (params->wpa_ie &&
4535 2550 : nla_put(msg, NL80211_ATTR_IE, params->wpa_ie_len, params->wpa_ie))
4536 0 : return -1;
4537 :
4538 2550 : if (params->wpa_proto) {
4539 2422 : enum nl80211_wpa_versions ver = 0;
4540 :
4541 2422 : if (params->wpa_proto & WPA_PROTO_WPA)
4542 23 : ver |= NL80211_WPA_VERSION_1;
4543 2422 : if (params->wpa_proto & WPA_PROTO_RSN)
4544 2397 : ver |= NL80211_WPA_VERSION_2;
4545 :
4546 2422 : wpa_printf(MSG_DEBUG, " * WPA Versions 0x%x", ver);
4547 2422 : if (nla_put_u32(msg, NL80211_ATTR_WPA_VERSIONS, ver))
4548 0 : return -1;
4549 : }
4550 :
4551 2550 : if (params->pairwise_suite != WPA_CIPHER_NONE) {
4552 1934 : u32 cipher = wpa_cipher_to_cipher_suite(params->pairwise_suite);
4553 1934 : wpa_printf(MSG_DEBUG, " * pairwise=0x%x", cipher);
4554 1934 : if (nla_put_u32(msg, NL80211_ATTR_CIPHER_SUITES_PAIRWISE,
4555 : cipher))
4556 0 : return -1;
4557 : }
4558 :
4559 2552 : if (params->group_suite == WPA_CIPHER_GTK_NOT_USED &&
4560 2 : !(drv->capa.enc & WPA_DRIVER_CAPA_ENC_GTK_NOT_USED)) {
4561 : /*
4562 : * This is likely to work even though many drivers do not
4563 : * advertise support for operations without GTK.
4564 : */
4565 2 : wpa_printf(MSG_DEBUG, " * skip group cipher configuration for GTK_NOT_USED due to missing driver support advertisement");
4566 2548 : } else if (params->group_suite != WPA_CIPHER_NONE) {
4567 1932 : u32 cipher = wpa_cipher_to_cipher_suite(params->group_suite);
4568 1932 : wpa_printf(MSG_DEBUG, " * group=0x%x", cipher);
4569 1932 : if (nla_put_u32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP, cipher))
4570 0 : return -1;
4571 : }
4572 :
4573 4111 : if (params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X ||
4574 2498 : params->key_mgmt_suite == WPA_KEY_MGMT_PSK ||
4575 1866 : params->key_mgmt_suite == WPA_KEY_MGMT_FT_IEEE8021X ||
4576 1627 : params->key_mgmt_suite == WPA_KEY_MGMT_FT_PSK ||
4577 1396 : params->key_mgmt_suite == WPA_KEY_MGMT_CCKM ||
4578 1394 : params->key_mgmt_suite == WPA_KEY_MGMT_OSEN ||
4579 1388 : params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SHA256 ||
4580 1364 : params->key_mgmt_suite == WPA_KEY_MGMT_PSK_SHA256 ||
4581 1342 : params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SUITE_B ||
4582 670 : params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) {
4583 1882 : int mgmt = WLAN_AKM_SUITE_PSK;
4584 :
4585 1882 : switch (params->key_mgmt_suite) {
4586 : case WPA_KEY_MGMT_CCKM:
4587 0 : mgmt = WLAN_AKM_SUITE_CCKM;
4588 0 : break;
4589 : case WPA_KEY_MGMT_IEEE8021X:
4590 989 : mgmt = WLAN_AKM_SUITE_8021X;
4591 989 : break;
4592 : case WPA_KEY_MGMT_FT_IEEE8021X:
4593 8 : mgmt = WLAN_AKM_SUITE_FT_8021X;
4594 8 : break;
4595 : case WPA_KEY_MGMT_FT_PSK:
4596 231 : mgmt = WLAN_AKM_SUITE_FT_PSK;
4597 231 : break;
4598 : case WPA_KEY_MGMT_IEEE8021X_SHA256:
4599 4 : mgmt = WLAN_AKM_SUITE_8021X_SHA256;
4600 4 : break;
4601 : case WPA_KEY_MGMT_PSK_SHA256:
4602 20 : mgmt = WLAN_AKM_SUITE_PSK_SHA256;
4603 20 : break;
4604 : case WPA_KEY_MGMT_OSEN:
4605 2 : mgmt = WLAN_AKM_SUITE_OSEN;
4606 2 : break;
4607 : case WPA_KEY_MGMT_IEEE8021X_SUITE_B:
4608 2 : mgmt = WLAN_AKM_SUITE_8021X_SUITE_B;
4609 2 : break;
4610 : case WPA_KEY_MGMT_IEEE8021X_SUITE_B_192:
4611 2 : mgmt = WLAN_AKM_SUITE_8021X_SUITE_B_192;
4612 2 : break;
4613 : case WPA_KEY_MGMT_PSK:
4614 : default:
4615 624 : mgmt = WLAN_AKM_SUITE_PSK;
4616 624 : break;
4617 : }
4618 1882 : wpa_printf(MSG_DEBUG, " * akm=0x%x", mgmt);
4619 1882 : if (nla_put_u32(msg, NL80211_ATTR_AKM_SUITES, mgmt))
4620 0 : return -1;
4621 : }
4622 :
4623 2550 : if (nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT))
4624 0 : return -1;
4625 :
4626 2597 : if (params->mgmt_frame_protection == MGMT_FRAME_PROTECTION_REQUIRED &&
4627 47 : nla_put_u32(msg, NL80211_ATTR_USE_MFP, NL80211_MFP_REQUIRED))
4628 0 : return -1;
4629 :
4630 2550 : if (params->rrm_used) {
4631 1 : u32 drv_rrm_flags = drv->capa.rrm_flags;
4632 1 : if (!(drv_rrm_flags &
4633 1 : WPA_DRIVER_FLAGS_DS_PARAM_SET_IE_IN_PROBES) ||
4634 2 : !(drv_rrm_flags & WPA_DRIVER_FLAGS_QUIET) ||
4635 1 : nla_put_flag(msg, NL80211_ATTR_USE_RRM))
4636 0 : return -1;
4637 : }
4638 :
4639 2550 : if (nl80211_ht_vht_overrides(msg, params) < 0)
4640 0 : return -1;
4641 :
4642 2550 : if (params->p2p)
4643 366 : wpa_printf(MSG_DEBUG, " * P2P group");
4644 :
4645 2550 : return 0;
4646 : }
4647 :
4648 :
4649 27 : static int wpa_driver_nl80211_try_connect(
4650 : struct wpa_driver_nl80211_data *drv,
4651 : struct wpa_driver_associate_params *params)
4652 : {
4653 : struct nl_msg *msg;
4654 : enum nl80211_auth_type type;
4655 : int ret;
4656 : int algs;
4657 :
4658 30 : if (params->req_key_mgmt_offload && params->psk &&
4659 3 : (params->key_mgmt_suite == WPA_KEY_MGMT_PSK ||
4660 0 : params->key_mgmt_suite == WPA_KEY_MGMT_PSK_SHA256 ||
4661 0 : params->key_mgmt_suite == WPA_KEY_MGMT_FT_PSK)) {
4662 3 : wpa_printf(MSG_DEBUG, "nl80211: Key management set PSK");
4663 3 : ret = issue_key_mgmt_set_key(drv, params->psk, 32);
4664 3 : if (ret)
4665 0 : return ret;
4666 : }
4667 :
4668 27 : wpa_printf(MSG_DEBUG, "nl80211: Connect (ifindex=%d)", drv->ifindex);
4669 27 : msg = nl80211_drv_msg(drv, 0, NL80211_CMD_CONNECT);
4670 27 : if (!msg)
4671 0 : return -1;
4672 :
4673 27 : ret = nl80211_connect_common(drv, params, msg);
4674 27 : if (ret)
4675 0 : goto fail;
4676 :
4677 27 : algs = 0;
4678 27 : if (params->auth_alg & WPA_AUTH_ALG_OPEN)
4679 26 : algs++;
4680 27 : if (params->auth_alg & WPA_AUTH_ALG_SHARED)
4681 2 : algs++;
4682 27 : if (params->auth_alg & WPA_AUTH_ALG_LEAP)
4683 0 : algs++;
4684 27 : if (algs > 1) {
4685 1 : wpa_printf(MSG_DEBUG, " * Leave out Auth Type for automatic "
4686 : "selection");
4687 1 : goto skip_auth_type;
4688 : }
4689 :
4690 26 : if (params->auth_alg & WPA_AUTH_ALG_OPEN)
4691 25 : type = NL80211_AUTHTYPE_OPEN_SYSTEM;
4692 1 : else if (params->auth_alg & WPA_AUTH_ALG_SHARED)
4693 1 : type = NL80211_AUTHTYPE_SHARED_KEY;
4694 0 : else if (params->auth_alg & WPA_AUTH_ALG_LEAP)
4695 0 : type = NL80211_AUTHTYPE_NETWORK_EAP;
4696 0 : else if (params->auth_alg & WPA_AUTH_ALG_FT)
4697 0 : type = NL80211_AUTHTYPE_FT;
4698 : else
4699 0 : goto fail;
4700 :
4701 26 : wpa_printf(MSG_DEBUG, " * Auth Type %d", type);
4702 26 : if (nla_put_u32(msg, NL80211_ATTR_AUTH_TYPE, type))
4703 0 : goto fail;
4704 :
4705 : skip_auth_type:
4706 27 : ret = nl80211_set_conn_keys(params, msg);
4707 27 : if (ret)
4708 0 : goto fail;
4709 :
4710 27 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
4711 27 : msg = NULL;
4712 27 : if (ret) {
4713 2 : wpa_printf(MSG_DEBUG, "nl80211: MLME connect failed: ret=%d "
4714 : "(%s)", ret, strerror(-ret));
4715 : } else {
4716 25 : wpa_printf(MSG_DEBUG,
4717 : "nl80211: Connect request send successfully");
4718 : }
4719 :
4720 : fail:
4721 27 : nlmsg_free(msg);
4722 27 : return ret;
4723 :
4724 : }
4725 :
4726 :
4727 25 : static int wpa_driver_nl80211_connect(
4728 : struct wpa_driver_nl80211_data *drv,
4729 : struct wpa_driver_associate_params *params)
4730 : {
4731 : int ret;
4732 :
4733 : /* Store the connection attempted bssid for future use */
4734 25 : if (params->bssid)
4735 18 : os_memcpy(drv->auth_attempt_bssid, params->bssid, ETH_ALEN);
4736 : else
4737 7 : os_memset(drv->auth_attempt_bssid, 0, ETH_ALEN);
4738 :
4739 25 : ret = wpa_driver_nl80211_try_connect(drv, params);
4740 25 : if (ret == -EALREADY) {
4741 : /*
4742 : * cfg80211 does not currently accept new connections if
4743 : * we are already connected. As a workaround, force
4744 : * disconnection and try again.
4745 : */
4746 2 : wpa_printf(MSG_DEBUG, "nl80211: Explicitly "
4747 : "disconnecting before reassociation "
4748 : "attempt");
4749 2 : if (wpa_driver_nl80211_disconnect(
4750 : drv, WLAN_REASON_PREV_AUTH_NOT_VALID))
4751 0 : return -1;
4752 2 : ret = wpa_driver_nl80211_try_connect(drv, params);
4753 : }
4754 25 : return ret;
4755 : }
4756 :
4757 :
4758 2878 : static int wpa_driver_nl80211_associate(
4759 : void *priv, struct wpa_driver_associate_params *params)
4760 : {
4761 2878 : struct i802_bss *bss = priv;
4762 2878 : struct wpa_driver_nl80211_data *drv = bss->drv;
4763 2878 : int ret = -1;
4764 : struct nl_msg *msg;
4765 :
4766 2878 : nl80211_unmask_11b_rates(bss);
4767 :
4768 2878 : if (params->mode == IEEE80211_MODE_AP)
4769 312 : return wpa_driver_nl80211_ap(drv, params);
4770 :
4771 2566 : if (params->mode == IEEE80211_MODE_IBSS)
4772 18 : return wpa_driver_nl80211_ibss(drv, params);
4773 :
4774 2548 : if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME)) {
4775 25 : enum nl80211_iftype nlmode = params->p2p ?
4776 : NL80211_IFTYPE_P2P_CLIENT : NL80211_IFTYPE_STATION;
4777 :
4778 25 : if (wpa_driver_nl80211_set_mode(priv, nlmode) < 0)
4779 0 : return -1;
4780 25 : return wpa_driver_nl80211_connect(drv, params);
4781 : }
4782 :
4783 2523 : nl80211_mark_disconnected(drv);
4784 :
4785 2523 : wpa_printf(MSG_DEBUG, "nl80211: Associate (ifindex=%d)",
4786 : drv->ifindex);
4787 2523 : msg = nl80211_drv_msg(drv, 0, NL80211_CMD_ASSOCIATE);
4788 2523 : if (!msg)
4789 0 : return -1;
4790 :
4791 2523 : ret = nl80211_connect_common(drv, params, msg);
4792 2523 : if (ret)
4793 0 : goto fail;
4794 :
4795 2523 : if (params->prev_bssid) {
4796 1824 : wpa_printf(MSG_DEBUG, " * prev_bssid=" MACSTR,
4797 1824 : MAC2STR(params->prev_bssid));
4798 304 : if (nla_put(msg, NL80211_ATTR_PREV_BSSID, ETH_ALEN,
4799 304 : params->prev_bssid))
4800 0 : goto fail;
4801 : }
4802 :
4803 2523 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
4804 2523 : msg = NULL;
4805 2523 : if (ret) {
4806 0 : wpa_dbg(drv->ctx, MSG_DEBUG,
4807 : "nl80211: MLME command failed (assoc): ret=%d (%s)",
4808 : ret, strerror(-ret));
4809 0 : nl80211_dump_scan(drv);
4810 : } else {
4811 2523 : wpa_printf(MSG_DEBUG,
4812 : "nl80211: Association request send successfully");
4813 : }
4814 :
4815 : fail:
4816 2523 : nlmsg_free(msg);
4817 2523 : return ret;
4818 : }
4819 :
4820 :
4821 3341 : static int nl80211_set_mode(struct wpa_driver_nl80211_data *drv,
4822 : int ifindex, enum nl80211_iftype mode)
4823 : {
4824 : struct nl_msg *msg;
4825 3341 : int ret = -ENOBUFS;
4826 :
4827 3341 : wpa_printf(MSG_DEBUG, "nl80211: Set mode ifindex %d iftype %d (%s)",
4828 : ifindex, mode, nl80211_iftype_str(mode));
4829 :
4830 3341 : msg = nl80211_cmd_msg(drv->first_bss, 0, NL80211_CMD_SET_INTERFACE);
4831 3341 : if (!msg || nla_put_u32(msg, NL80211_ATTR_IFTYPE, mode))
4832 : goto fail;
4833 :
4834 3341 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
4835 3341 : msg = NULL;
4836 3341 : if (!ret)
4837 3243 : return 0;
4838 : fail:
4839 98 : nlmsg_free(msg);
4840 98 : wpa_printf(MSG_DEBUG, "nl80211: Failed to set interface %d to mode %d:"
4841 : " %d (%s)", ifindex, mode, ret, strerror(-ret));
4842 98 : return ret;
4843 : }
4844 :
4845 :
4846 3277 : static int wpa_driver_nl80211_set_mode_impl(
4847 : struct i802_bss *bss,
4848 : enum nl80211_iftype nlmode,
4849 : struct hostapd_freq_params *desired_freq_params)
4850 : {
4851 3277 : struct wpa_driver_nl80211_data *drv = bss->drv;
4852 3277 : int ret = -1;
4853 : int i;
4854 3277 : int was_ap = is_ap_interface(drv->nlmode);
4855 : int res;
4856 : int mode_switch_res;
4857 :
4858 3277 : mode_switch_res = nl80211_set_mode(drv, drv->ifindex, nlmode);
4859 3277 : if (mode_switch_res && nlmode == nl80211_get_ifmode(bss))
4860 8 : mode_switch_res = 0;
4861 :
4862 3277 : if (mode_switch_res == 0) {
4863 3187 : drv->nlmode = nlmode;
4864 3187 : ret = 0;
4865 3187 : goto done;
4866 : }
4867 :
4868 90 : if (mode_switch_res == -ENODEV)
4869 26 : return -1;
4870 :
4871 64 : if (nlmode == drv->nlmode) {
4872 0 : wpa_printf(MSG_DEBUG, "nl80211: Interface already in "
4873 : "requested mode - ignore error");
4874 0 : ret = 0;
4875 0 : goto done; /* Already in the requested mode */
4876 : }
4877 :
4878 : /* mac80211 doesn't allow mode changes while the device is up, so
4879 : * take the device down, try to set the mode again, and bring the
4880 : * device back up.
4881 : */
4882 64 : wpa_printf(MSG_DEBUG, "nl80211: Try mode change after setting "
4883 : "interface down");
4884 64 : for (i = 0; i < 10; i++) {
4885 64 : res = i802_set_iface_flags(bss, 0);
4886 64 : if (res == -EACCES || res == -ENODEV)
4887 : break;
4888 64 : if (res != 0) {
4889 0 : wpa_printf(MSG_DEBUG, "nl80211: Failed to set "
4890 : "interface down");
4891 0 : os_sleep(0, 100000);
4892 0 : continue;
4893 : }
4894 :
4895 : /*
4896 : * Setting the mode will fail for some drivers if the phy is
4897 : * on a frequency that the mode is disallowed in.
4898 : */
4899 64 : if (desired_freq_params) {
4900 0 : res = nl80211_set_channel(bss, desired_freq_params, 0);
4901 0 : if (res) {
4902 0 : wpa_printf(MSG_DEBUG,
4903 : "nl80211: Failed to set frequency on interface");
4904 : }
4905 : }
4906 :
4907 : /* Try to set the mode again while the interface is down */
4908 64 : mode_switch_res = nl80211_set_mode(drv, drv->ifindex, nlmode);
4909 64 : if (mode_switch_res == -EBUSY) {
4910 0 : wpa_printf(MSG_DEBUG,
4911 : "nl80211: Delaying mode set while interface going down");
4912 0 : os_sleep(0, 100000);
4913 0 : continue;
4914 : }
4915 64 : ret = mode_switch_res;
4916 64 : break;
4917 : }
4918 :
4919 64 : if (!ret) {
4920 64 : wpa_printf(MSG_DEBUG, "nl80211: Mode change succeeded while "
4921 : "interface is down");
4922 64 : drv->nlmode = nlmode;
4923 64 : drv->ignore_if_down_event = 1;
4924 : }
4925 :
4926 : /* Bring the interface back up */
4927 64 : res = linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 1);
4928 64 : if (res != 0) {
4929 0 : wpa_printf(MSG_DEBUG,
4930 : "nl80211: Failed to set interface up after switching mode");
4931 0 : ret = -1;
4932 : }
4933 :
4934 : done:
4935 3251 : if (ret) {
4936 0 : wpa_printf(MSG_DEBUG, "nl80211: Interface mode change to %d "
4937 0 : "from %d failed", nlmode, drv->nlmode);
4938 0 : return ret;
4939 : }
4940 :
4941 3251 : if (is_p2p_net_interface(nlmode)) {
4942 600 : wpa_printf(MSG_DEBUG,
4943 : "nl80211: Interface %s mode change to P2P - disable 11b rates",
4944 600 : bss->ifname);
4945 600 : nl80211_disable_11b_rates(drv, drv->ifindex, 1);
4946 2651 : } else if (drv->disabled_11b_rates) {
4947 370 : wpa_printf(MSG_DEBUG,
4948 : "nl80211: Interface %s mode changed to non-P2P - re-enable 11b rates",
4949 370 : bss->ifname);
4950 370 : nl80211_disable_11b_rates(drv, drv->ifindex, 0);
4951 : }
4952 :
4953 3251 : if (is_ap_interface(nlmode)) {
4954 1410 : nl80211_mgmt_unsubscribe(bss, "start AP");
4955 : /* Setup additional AP mode functionality if needed */
4956 1410 : if (nl80211_setup_ap(bss))
4957 0 : return -1;
4958 1841 : } else if (was_ap) {
4959 : /* Remove additional AP mode functionality */
4960 1134 : nl80211_teardown_ap(bss);
4961 : } else {
4962 707 : nl80211_mgmt_unsubscribe(bss, "mode change");
4963 : }
4964 :
4965 3289 : if (is_mesh_interface(nlmode) &&
4966 38 : nl80211_mgmt_subscribe_mesh(bss))
4967 0 : return -1;
4968 :
4969 4066 : if (!bss->in_deinit && !is_ap_interface(nlmode) &&
4970 1592 : !is_mesh_interface(nlmode) &&
4971 777 : nl80211_mgmt_subscribe_non_ap(bss) < 0)
4972 0 : wpa_printf(MSG_DEBUG, "nl80211: Failed to register Action "
4973 : "frame processing - ignore for now");
4974 :
4975 3251 : return 0;
4976 : }
4977 :
4978 :
4979 3259 : int wpa_driver_nl80211_set_mode(struct i802_bss *bss,
4980 : enum nl80211_iftype nlmode)
4981 : {
4982 3259 : return wpa_driver_nl80211_set_mode_impl(bss, nlmode, NULL);
4983 : }
4984 :
4985 :
4986 18 : static int wpa_driver_nl80211_set_mode_ibss(struct i802_bss *bss,
4987 : struct hostapd_freq_params *freq)
4988 : {
4989 18 : return wpa_driver_nl80211_set_mode_impl(bss, NL80211_IFTYPE_ADHOC,
4990 : freq);
4991 : }
4992 :
4993 :
4994 1746 : static int wpa_driver_nl80211_get_capa(void *priv,
4995 : struct wpa_driver_capa *capa)
4996 : {
4997 1746 : struct i802_bss *bss = priv;
4998 1746 : struct wpa_driver_nl80211_data *drv = bss->drv;
4999 :
5000 1746 : if (!drv->has_capability)
5001 0 : return -1;
5002 1746 : os_memcpy(capa, &drv->capa, sizeof(*capa));
5003 1746 : if (drv->extended_capa && drv->extended_capa_mask) {
5004 1746 : capa->extended_capa = drv->extended_capa;
5005 1746 : capa->extended_capa_mask = drv->extended_capa_mask;
5006 1746 : capa->extended_capa_len = drv->extended_capa_len;
5007 : }
5008 :
5009 1746 : return 0;
5010 : }
5011 :
5012 :
5013 14329 : static int wpa_driver_nl80211_set_operstate(void *priv, int state)
5014 : {
5015 14329 : struct i802_bss *bss = priv;
5016 14329 : struct wpa_driver_nl80211_data *drv = bss->drv;
5017 :
5018 28658 : wpa_printf(MSG_DEBUG, "nl80211: Set %s operstate %d->%d (%s)",
5019 14329 : bss->ifname, drv->operstate, state,
5020 : state ? "UP" : "DORMANT");
5021 14329 : drv->operstate = state;
5022 14329 : return netlink_send_oper_ifla(drv->global->netlink, drv->ifindex, -1,
5023 : state ? IF_OPER_UP : IF_OPER_DORMANT);
5024 : }
5025 :
5026 :
5027 5185 : static int wpa_driver_nl80211_set_supp_port(void *priv, int authorized)
5028 : {
5029 5185 : struct i802_bss *bss = priv;
5030 5185 : struct wpa_driver_nl80211_data *drv = bss->drv;
5031 : struct nl_msg *msg;
5032 : struct nl80211_sta_flag_update upd;
5033 : int ret;
5034 :
5035 5185 : if (!drv->associated && is_zero_ether_addr(drv->bssid) && !authorized) {
5036 2475 : wpa_printf(MSG_DEBUG, "nl80211: Skip set_supp_port(unauthorized) while not associated");
5037 2475 : return 0;
5038 : }
5039 :
5040 16260 : wpa_printf(MSG_DEBUG, "nl80211: Set supplicant port %sauthorized for "
5041 16260 : MACSTR, authorized ? "" : "un", MAC2STR(drv->bssid));
5042 :
5043 2710 : os_memset(&upd, 0, sizeof(upd));
5044 2710 : upd.mask = BIT(NL80211_STA_FLAG_AUTHORIZED);
5045 2710 : if (authorized)
5046 1834 : upd.set = BIT(NL80211_STA_FLAG_AUTHORIZED);
5047 :
5048 5420 : if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_SET_STATION)) ||
5049 5420 : nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, drv->bssid) ||
5050 2710 : nla_put(msg, NL80211_ATTR_STA_FLAGS2, sizeof(upd), &upd)) {
5051 0 : nlmsg_free(msg);
5052 0 : return -ENOBUFS;
5053 : }
5054 :
5055 2710 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5056 2710 : if (!ret)
5057 2683 : return 0;
5058 27 : wpa_printf(MSG_DEBUG, "nl80211: Failed to set STA flag: %d (%s)",
5059 : ret, strerror(-ret));
5060 27 : return ret;
5061 : }
5062 :
5063 :
5064 : /* Set kernel driver on given frequency (MHz) */
5065 1302 : static int i802_set_freq(void *priv, struct hostapd_freq_params *freq)
5066 : {
5067 1302 : struct i802_bss *bss = priv;
5068 1302 : return nl80211_set_channel(bss, freq, 0);
5069 : }
5070 :
5071 :
5072 1637 : static inline int min_int(int a, int b)
5073 : {
5074 1637 : if (a < b)
5075 0 : return a;
5076 1637 : return b;
5077 : }
5078 :
5079 :
5080 1637 : static int get_key_handler(struct nl_msg *msg, void *arg)
5081 : {
5082 : struct nlattr *tb[NL80211_ATTR_MAX + 1];
5083 1637 : struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
5084 :
5085 1637 : nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
5086 : genlmsg_attrlen(gnlh, 0), NULL);
5087 :
5088 : /*
5089 : * TODO: validate the key index and mac address!
5090 : * Otherwise, there's a race condition as soon as
5091 : * the kernel starts sending key notifications.
5092 : */
5093 :
5094 1637 : if (tb[NL80211_ATTR_KEY_SEQ])
5095 1637 : memcpy(arg, nla_data(tb[NL80211_ATTR_KEY_SEQ]),
5096 1637 : min_int(nla_len(tb[NL80211_ATTR_KEY_SEQ]), 6));
5097 1637 : return NL_SKIP;
5098 : }
5099 :
5100 :
5101 1637 : static int i802_get_seqnum(const char *iface, void *priv, const u8 *addr,
5102 : int idx, u8 *seq)
5103 : {
5104 1637 : struct i802_bss *bss = priv;
5105 1637 : struct wpa_driver_nl80211_data *drv = bss->drv;
5106 : struct nl_msg *msg;
5107 :
5108 1637 : msg = nl80211_ifindex_msg(drv, if_nametoindex(iface), 0,
5109 : NL80211_CMD_GET_KEY);
5110 1637 : if (!msg ||
5111 1637 : (addr && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) ||
5112 1637 : nla_put_u8(msg, NL80211_ATTR_KEY_IDX, idx)) {
5113 0 : nlmsg_free(msg);
5114 0 : return -ENOBUFS;
5115 : }
5116 :
5117 1637 : memset(seq, 0, 6);
5118 :
5119 1637 : return send_and_recv_msgs(drv, msg, get_key_handler, seq);
5120 : }
5121 :
5122 :
5123 1 : static int i802_set_rts(void *priv, int rts)
5124 : {
5125 1 : struct i802_bss *bss = priv;
5126 1 : struct wpa_driver_nl80211_data *drv = bss->drv;
5127 : struct nl_msg *msg;
5128 : int ret;
5129 : u32 val;
5130 :
5131 1 : if (rts >= 2347)
5132 0 : val = (u32) -1;
5133 : else
5134 1 : val = rts;
5135 :
5136 2 : if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_SET_WIPHY)) ||
5137 1 : nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, val)) {
5138 0 : nlmsg_free(msg);
5139 0 : return -ENOBUFS;
5140 : }
5141 :
5142 1 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5143 1 : if (!ret)
5144 1 : return 0;
5145 0 : wpa_printf(MSG_DEBUG, "nl80211: Failed to set RTS threshold %d: "
5146 : "%d (%s)", rts, ret, strerror(-ret));
5147 0 : return ret;
5148 : }
5149 :
5150 :
5151 3 : static int i802_set_frag(void *priv, int frag)
5152 : {
5153 3 : struct i802_bss *bss = priv;
5154 3 : struct wpa_driver_nl80211_data *drv = bss->drv;
5155 : struct nl_msg *msg;
5156 : int ret;
5157 : u32 val;
5158 :
5159 3 : if (frag >= 2346)
5160 0 : val = (u32) -1;
5161 : else
5162 3 : val = frag;
5163 :
5164 6 : if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_SET_WIPHY)) ||
5165 3 : nla_put_u32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD, val)) {
5166 0 : nlmsg_free(msg);
5167 0 : return -ENOBUFS;
5168 : }
5169 :
5170 3 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5171 3 : if (!ret)
5172 3 : return 0;
5173 0 : wpa_printf(MSG_DEBUG, "nl80211: Failed to set fragmentation threshold "
5174 : "%d: %d (%s)", frag, ret, strerror(-ret));
5175 0 : return ret;
5176 : }
5177 :
5178 :
5179 1165 : static int i802_flush(void *priv)
5180 : {
5181 1165 : struct i802_bss *bss = priv;
5182 : struct nl_msg *msg;
5183 : int res;
5184 :
5185 1165 : wpa_printf(MSG_DEBUG, "nl80211: flush -> DEL_STATION %s (all)",
5186 1165 : bss->ifname);
5187 :
5188 : /*
5189 : * XXX: FIX! this needs to flush all VLANs too
5190 : */
5191 1165 : msg = nl80211_bss_msg(bss, 0, NL80211_CMD_DEL_STATION);
5192 1165 : res = send_and_recv_msgs(bss->drv, msg, NULL, NULL);
5193 1165 : if (res) {
5194 32 : wpa_printf(MSG_DEBUG, "nl80211: Station flush failed: ret=%d "
5195 : "(%s)", res, strerror(-res));
5196 : }
5197 1165 : return res;
5198 : }
5199 :
5200 :
5201 303 : static int get_sta_handler(struct nl_msg *msg, void *arg)
5202 : {
5203 : struct nlattr *tb[NL80211_ATTR_MAX + 1];
5204 303 : struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
5205 303 : struct hostap_sta_driver_data *data = arg;
5206 : struct nlattr *stats[NL80211_STA_INFO_MAX + 1];
5207 : static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
5208 : [NL80211_STA_INFO_INACTIVE_TIME] = { .type = NLA_U32 },
5209 : [NL80211_STA_INFO_RX_BYTES] = { .type = NLA_U32 },
5210 : [NL80211_STA_INFO_TX_BYTES] = { .type = NLA_U32 },
5211 : [NL80211_STA_INFO_RX_PACKETS] = { .type = NLA_U32 },
5212 : [NL80211_STA_INFO_TX_PACKETS] = { .type = NLA_U32 },
5213 : [NL80211_STA_INFO_TX_FAILED] = { .type = NLA_U32 },
5214 : };
5215 :
5216 303 : nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
5217 : genlmsg_attrlen(gnlh, 0), NULL);
5218 :
5219 : /*
5220 : * TODO: validate the interface and mac address!
5221 : * Otherwise, there's a race condition as soon as
5222 : * the kernel starts sending station notifications.
5223 : */
5224 :
5225 303 : if (!tb[NL80211_ATTR_STA_INFO]) {
5226 0 : wpa_printf(MSG_DEBUG, "sta stats missing!");
5227 0 : return NL_SKIP;
5228 : }
5229 303 : if (nla_parse_nested(stats, NL80211_STA_INFO_MAX,
5230 : tb[NL80211_ATTR_STA_INFO],
5231 : stats_policy)) {
5232 0 : wpa_printf(MSG_DEBUG, "failed to parse nested attributes!");
5233 0 : return NL_SKIP;
5234 : }
5235 :
5236 303 : if (stats[NL80211_STA_INFO_INACTIVE_TIME])
5237 303 : data->inactive_msec =
5238 303 : nla_get_u32(stats[NL80211_STA_INFO_INACTIVE_TIME]);
5239 303 : if (stats[NL80211_STA_INFO_RX_BYTES])
5240 303 : data->rx_bytes = nla_get_u32(stats[NL80211_STA_INFO_RX_BYTES]);
5241 303 : if (stats[NL80211_STA_INFO_TX_BYTES])
5242 303 : data->tx_bytes = nla_get_u32(stats[NL80211_STA_INFO_TX_BYTES]);
5243 303 : if (stats[NL80211_STA_INFO_RX_PACKETS])
5244 303 : data->rx_packets =
5245 303 : nla_get_u32(stats[NL80211_STA_INFO_RX_PACKETS]);
5246 303 : if (stats[NL80211_STA_INFO_TX_PACKETS])
5247 303 : data->tx_packets =
5248 303 : nla_get_u32(stats[NL80211_STA_INFO_TX_PACKETS]);
5249 303 : if (stats[NL80211_STA_INFO_TX_FAILED])
5250 303 : data->tx_retry_failed =
5251 303 : nla_get_u32(stats[NL80211_STA_INFO_TX_FAILED]);
5252 :
5253 303 : return NL_SKIP;
5254 : }
5255 :
5256 304 : static int i802_read_sta_data(struct i802_bss *bss,
5257 : struct hostap_sta_driver_data *data,
5258 : const u8 *addr)
5259 : {
5260 : struct nl_msg *msg;
5261 :
5262 304 : os_memset(data, 0, sizeof(*data));
5263 :
5264 608 : if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_GET_STATION)) ||
5265 304 : nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) {
5266 0 : nlmsg_free(msg);
5267 0 : return -ENOBUFS;
5268 : }
5269 :
5270 304 : return send_and_recv_msgs(bss->drv, msg, get_sta_handler, data);
5271 : }
5272 :
5273 :
5274 4064 : static int i802_set_tx_queue_params(void *priv, int queue, int aifs,
5275 : int cw_min, int cw_max, int burst_time)
5276 : {
5277 4064 : struct i802_bss *bss = priv;
5278 4064 : struct wpa_driver_nl80211_data *drv = bss->drv;
5279 : struct nl_msg *msg;
5280 : struct nlattr *txq, *params;
5281 :
5282 4064 : msg = nl80211_bss_msg(bss, 0, NL80211_CMD_SET_WIPHY);
5283 4064 : if (!msg)
5284 0 : return -1;
5285 :
5286 4064 : txq = nla_nest_start(msg, NL80211_ATTR_WIPHY_TXQ_PARAMS);
5287 4064 : if (!txq)
5288 0 : goto fail;
5289 :
5290 : /* We are only sending parameters for a single TXQ at a time */
5291 4064 : params = nla_nest_start(msg, 1);
5292 4064 : if (!params)
5293 0 : goto fail;
5294 :
5295 4064 : switch (queue) {
5296 : case 0:
5297 1016 : if (nla_put_u8(msg, NL80211_TXQ_ATTR_QUEUE, NL80211_TXQ_Q_VO))
5298 0 : goto fail;
5299 1016 : break;
5300 : case 1:
5301 1016 : if (nla_put_u8(msg, NL80211_TXQ_ATTR_QUEUE, NL80211_TXQ_Q_VI))
5302 0 : goto fail;
5303 1016 : break;
5304 : case 2:
5305 1016 : if (nla_put_u8(msg, NL80211_TXQ_ATTR_QUEUE, NL80211_TXQ_Q_BE))
5306 0 : goto fail;
5307 1016 : break;
5308 : case 3:
5309 1016 : if (nla_put_u8(msg, NL80211_TXQ_ATTR_QUEUE, NL80211_TXQ_Q_BK))
5310 0 : goto fail;
5311 1016 : break;
5312 : }
5313 : /* Burst time is configured in units of 0.1 msec and TXOP parameter in
5314 : * 32 usec, so need to convert the value here. */
5315 4064 : if (nla_put_u16(msg, NL80211_TXQ_ATTR_TXOP,
5316 8128 : (burst_time * 100 + 16) / 32) ||
5317 8128 : nla_put_u16(msg, NL80211_TXQ_ATTR_CWMIN, cw_min) ||
5318 8128 : nla_put_u16(msg, NL80211_TXQ_ATTR_CWMAX, cw_max) ||
5319 4064 : nla_put_u8(msg, NL80211_TXQ_ATTR_AIFS, aifs))
5320 : goto fail;
5321 :
5322 4064 : nla_nest_end(msg, params);
5323 :
5324 4064 : nla_nest_end(msg, txq);
5325 :
5326 4064 : if (send_and_recv_msgs(drv, msg, NULL, NULL) == 0)
5327 3928 : return 0;
5328 136 : msg = NULL;
5329 : fail:
5330 136 : nlmsg_free(msg);
5331 136 : return -1;
5332 : }
5333 :
5334 :
5335 16 : static int i802_set_sta_vlan(struct i802_bss *bss, const u8 *addr,
5336 : const char *ifname, int vlan_id)
5337 : {
5338 16 : struct wpa_driver_nl80211_data *drv = bss->drv;
5339 : struct nl_msg *msg;
5340 : int ret;
5341 :
5342 144 : wpa_printf(MSG_DEBUG, "nl80211: %s[%d]: set_sta_vlan(" MACSTR
5343 : ", ifname=%s[%d], vlan_id=%d)",
5344 32 : bss->ifname, if_nametoindex(bss->ifname),
5345 96 : MAC2STR(addr), ifname, if_nametoindex(ifname), vlan_id);
5346 32 : if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_SET_STATION)) ||
5347 32 : nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
5348 16 : nla_put_u32(msg, NL80211_ATTR_STA_VLAN, if_nametoindex(ifname))) {
5349 0 : nlmsg_free(msg);
5350 0 : return -ENOBUFS;
5351 : }
5352 :
5353 16 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5354 16 : if (ret < 0) {
5355 0 : wpa_printf(MSG_ERROR, "nl80211: NL80211_ATTR_STA_VLAN (addr="
5356 : MACSTR " ifname=%s vlan_id=%d) failed: %d (%s)",
5357 0 : MAC2STR(addr), ifname, vlan_id, ret,
5358 : strerror(-ret));
5359 : }
5360 16 : return ret;
5361 : }
5362 :
5363 :
5364 7 : static int i802_get_inact_sec(void *priv, const u8 *addr)
5365 : {
5366 : struct hostap_sta_driver_data data;
5367 : int ret;
5368 :
5369 7 : data.inactive_msec = (unsigned long) -1;
5370 7 : ret = i802_read_sta_data(priv, &data, addr);
5371 7 : if (ret == -ENOENT)
5372 0 : return -ENOENT;
5373 7 : if (ret || data.inactive_msec == (unsigned long) -1)
5374 0 : return -1;
5375 7 : return data.inactive_msec / 1000;
5376 : }
5377 :
5378 :
5379 1474 : static int i802_sta_clear_stats(void *priv, const u8 *addr)
5380 : {
5381 : #if 0
5382 : /* TODO */
5383 : #endif
5384 1474 : return 0;
5385 : }
5386 :
5387 :
5388 2922 : static int i802_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr,
5389 : int reason)
5390 : {
5391 2922 : struct i802_bss *bss = priv;
5392 2922 : struct wpa_driver_nl80211_data *drv = bss->drv;
5393 : struct ieee80211_mgmt mgmt;
5394 :
5395 2922 : if (is_mesh_interface(drv->nlmode))
5396 38 : return -1;
5397 :
5398 2884 : if (drv->device_ap_sme)
5399 0 : return wpa_driver_nl80211_sta_remove(bss, addr, 1, reason);
5400 :
5401 2884 : memset(&mgmt, 0, sizeof(mgmt));
5402 2884 : mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
5403 : WLAN_FC_STYPE_DEAUTH);
5404 2884 : memcpy(mgmt.da, addr, ETH_ALEN);
5405 2884 : memcpy(mgmt.sa, own_addr, ETH_ALEN);
5406 2884 : memcpy(mgmt.bssid, own_addr, ETH_ALEN);
5407 2884 : mgmt.u.deauth.reason_code = host_to_le16(reason);
5408 2884 : return wpa_driver_nl80211_send_mlme(bss, (u8 *) &mgmt,
5409 : IEEE80211_HDRLEN +
5410 : sizeof(mgmt.u.deauth), 0, 0, 0, 0,
5411 : 0);
5412 : }
5413 :
5414 :
5415 5 : static int i802_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr,
5416 : int reason)
5417 : {
5418 5 : struct i802_bss *bss = priv;
5419 5 : struct wpa_driver_nl80211_data *drv = bss->drv;
5420 : struct ieee80211_mgmt mgmt;
5421 :
5422 5 : if (is_mesh_interface(drv->nlmode))
5423 0 : return -1;
5424 :
5425 5 : if (drv->device_ap_sme)
5426 0 : return wpa_driver_nl80211_sta_remove(bss, addr, 0, reason);
5427 :
5428 5 : memset(&mgmt, 0, sizeof(mgmt));
5429 5 : mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
5430 : WLAN_FC_STYPE_DISASSOC);
5431 5 : memcpy(mgmt.da, addr, ETH_ALEN);
5432 5 : memcpy(mgmt.sa, own_addr, ETH_ALEN);
5433 5 : memcpy(mgmt.bssid, own_addr, ETH_ALEN);
5434 5 : mgmt.u.disassoc.reason_code = host_to_le16(reason);
5435 5 : return wpa_driver_nl80211_send_mlme(bss, (u8 *) &mgmt,
5436 : IEEE80211_HDRLEN +
5437 : sizeof(mgmt.u.disassoc), 0, 0, 0, 0,
5438 : 0);
5439 : }
5440 :
5441 :
5442 3350 : static void dump_ifidx(struct wpa_driver_nl80211_data *drv)
5443 : {
5444 : char buf[200], *pos, *end;
5445 : int i, res;
5446 :
5447 3350 : pos = buf;
5448 3350 : end = pos + sizeof(buf);
5449 :
5450 56967 : for (i = 0; i < drv->num_if_indices; i++) {
5451 53617 : if (!drv->if_indices[i])
5452 52012 : continue;
5453 1605 : res = os_snprintf(pos, end - pos, " %d", drv->if_indices[i]);
5454 1605 : if (os_snprintf_error(end - pos, res))
5455 0 : break;
5456 1605 : pos += res;
5457 : }
5458 3350 : *pos = '\0';
5459 :
5460 3350 : wpa_printf(MSG_DEBUG, "nl80211: if_indices[%d]:%s",
5461 : drv->num_if_indices, buf);
5462 3350 : }
5463 :
5464 :
5465 1326 : static void add_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
5466 : {
5467 : int i;
5468 : int *old;
5469 :
5470 1326 : wpa_printf(MSG_DEBUG, "nl80211: Add own interface ifindex %d",
5471 : ifidx);
5472 1326 : if (have_ifidx(drv, ifidx)) {
5473 225 : wpa_printf(MSG_DEBUG, "nl80211: ifindex %d already in the list",
5474 : ifidx);
5475 225 : return;
5476 : }
5477 1357 : for (i = 0; i < drv->num_if_indices; i++) {
5478 1356 : if (drv->if_indices[i] == 0) {
5479 1100 : drv->if_indices[i] = ifidx;
5480 1100 : dump_ifidx(drv);
5481 1100 : return;
5482 : }
5483 : }
5484 :
5485 1 : if (drv->if_indices != drv->default_if_indices)
5486 0 : old = drv->if_indices;
5487 : else
5488 1 : old = NULL;
5489 :
5490 1 : drv->if_indices = os_realloc_array(old, drv->num_if_indices + 1,
5491 : sizeof(int));
5492 1 : if (!drv->if_indices) {
5493 0 : if (!old)
5494 0 : drv->if_indices = drv->default_if_indices;
5495 : else
5496 0 : drv->if_indices = old;
5497 0 : wpa_printf(MSG_ERROR, "Failed to reallocate memory for "
5498 : "interfaces");
5499 0 : wpa_printf(MSG_ERROR, "Ignoring EAPOL on interface %d", ifidx);
5500 0 : return;
5501 1 : } else if (!old)
5502 1 : os_memcpy(drv->if_indices, drv->default_if_indices,
5503 : sizeof(drv->default_if_indices));
5504 1 : drv->if_indices[drv->num_if_indices] = ifidx;
5505 1 : drv->num_if_indices++;
5506 1 : dump_ifidx(drv);
5507 : }
5508 :
5509 :
5510 2249 : static void del_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
5511 : {
5512 : int i;
5513 :
5514 37086 : for (i = 0; i < drv->num_if_indices; i++) {
5515 34922 : if (drv->if_indices[i] == ifidx) {
5516 85 : drv->if_indices[i] = 0;
5517 85 : break;
5518 : }
5519 : }
5520 2249 : dump_ifidx(drv);
5521 2249 : }
5522 :
5523 :
5524 99726 : static int have_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
5525 : {
5526 : int i;
5527 :
5528 1578484 : for (i = 0; i < drv->num_if_indices; i++)
5529 1486165 : if (drv->if_indices[i] == ifidx)
5530 7407 : return 1;
5531 :
5532 92319 : return 0;
5533 : }
5534 :
5535 :
5536 2 : static int i802_set_wds_sta(void *priv, const u8 *addr, int aid, int val,
5537 : const char *bridge_ifname, char *ifname_wds)
5538 : {
5539 2 : struct i802_bss *bss = priv;
5540 2 : struct wpa_driver_nl80211_data *drv = bss->drv;
5541 : char name[IFNAMSIZ + 1];
5542 :
5543 2 : os_snprintf(name, sizeof(name), "%s.sta%d", bss->ifname, aid);
5544 2 : if (ifname_wds)
5545 1 : os_strlcpy(ifname_wds, name, IFNAMSIZ + 1);
5546 :
5547 12 : wpa_printf(MSG_DEBUG, "nl80211: Set WDS STA addr=" MACSTR
5548 12 : " aid=%d val=%d name=%s", MAC2STR(addr), aid, val, name);
5549 2 : if (val) {
5550 1 : if (!if_nametoindex(name)) {
5551 1 : if (nl80211_create_iface(drv, name,
5552 : NL80211_IFTYPE_AP_VLAN,
5553 1 : bss->addr, 1, NULL, NULL, 0) <
5554 : 0)
5555 0 : return -1;
5556 2 : if (bridge_ifname &&
5557 1 : linux_br_add_if(drv->global->ioctl_sock,
5558 : bridge_ifname, name) < 0)
5559 0 : return -1;
5560 : }
5561 1 : if (linux_set_iface_flags(drv->global->ioctl_sock, name, 1)) {
5562 0 : wpa_printf(MSG_ERROR, "nl80211: Failed to set WDS STA "
5563 : "interface %s up", name);
5564 : }
5565 1 : return i802_set_sta_vlan(priv, addr, name, 0);
5566 : } else {
5567 1 : if (bridge_ifname)
5568 1 : linux_br_del_if(drv->global->ioctl_sock, bridge_ifname,
5569 : name);
5570 :
5571 1 : i802_set_sta_vlan(priv, addr, bss->ifname, 0);
5572 1 : nl80211_remove_iface(drv, if_nametoindex(name));
5573 1 : return 0;
5574 : }
5575 : }
5576 :
5577 :
5578 16172 : static void handle_eapol(int sock, void *eloop_ctx, void *sock_ctx)
5579 : {
5580 16172 : struct wpa_driver_nl80211_data *drv = eloop_ctx;
5581 : struct sockaddr_ll lladdr;
5582 : unsigned char buf[3000];
5583 : int len;
5584 16172 : socklen_t fromlen = sizeof(lladdr);
5585 :
5586 16172 : len = recvfrom(sock, buf, sizeof(buf), 0,
5587 : (struct sockaddr *)&lladdr, &fromlen);
5588 16172 : if (len < 0) {
5589 0 : wpa_printf(MSG_ERROR, "nl80211: EAPOL recv failed: %s",
5590 0 : strerror(errno));
5591 16172 : return;
5592 : }
5593 :
5594 16172 : if (have_ifidx(drv, lladdr.sll_ifindex))
5595 6775 : drv_event_eapol_rx(drv->ctx, lladdr.sll_addr, buf, len);
5596 : }
5597 :
5598 :
5599 15 : static int i802_check_bridge(struct wpa_driver_nl80211_data *drv,
5600 : struct i802_bss *bss,
5601 : const char *brname, const char *ifname)
5602 : {
5603 : int br_ifindex;
5604 : char in_br[IFNAMSIZ];
5605 :
5606 15 : os_strlcpy(bss->brname, brname, IFNAMSIZ);
5607 15 : br_ifindex = if_nametoindex(brname);
5608 15 : if (br_ifindex == 0) {
5609 : /*
5610 : * Bridge was configured, but the bridge device does
5611 : * not exist. Try to add it now.
5612 : */
5613 10 : if (linux_br_add(drv->global->ioctl_sock, brname) < 0) {
5614 0 : wpa_printf(MSG_ERROR, "nl80211: Failed to add the "
5615 : "bridge interface %s: %s",
5616 0 : brname, strerror(errno));
5617 0 : return -1;
5618 : }
5619 10 : bss->added_bridge = 1;
5620 10 : br_ifindex = if_nametoindex(brname);
5621 10 : add_ifidx(drv, br_ifindex);
5622 : }
5623 15 : bss->br_ifindex = br_ifindex;
5624 :
5625 15 : if (linux_br_get(in_br, ifname) == 0) {
5626 1 : if (os_strcmp(in_br, brname) == 0)
5627 0 : return 0; /* already in the bridge */
5628 :
5629 1 : wpa_printf(MSG_DEBUG, "nl80211: Removing interface %s from "
5630 : "bridge %s", ifname, in_br);
5631 1 : if (linux_br_del_if(drv->global->ioctl_sock, in_br, ifname) <
5632 : 0) {
5633 0 : wpa_printf(MSG_ERROR, "nl80211: Failed to "
5634 : "remove interface %s from bridge "
5635 : "%s: %s",
5636 0 : ifname, brname, strerror(errno));
5637 0 : return -1;
5638 : }
5639 : }
5640 :
5641 15 : wpa_printf(MSG_DEBUG, "nl80211: Adding interface %s into bridge %s",
5642 : ifname, brname);
5643 15 : if (linux_br_add_if(drv->global->ioctl_sock, brname, ifname) < 0) {
5644 0 : wpa_printf(MSG_ERROR, "nl80211: Failed to add interface %s "
5645 : "into bridge %s: %s",
5646 0 : ifname, brname, strerror(errno));
5647 0 : return -1;
5648 : }
5649 15 : bss->added_if_into_bridge = 1;
5650 :
5651 15 : return 0;
5652 : }
5653 :
5654 :
5655 1014 : static void *i802_init(struct hostapd_data *hapd,
5656 : struct wpa_init_params *params)
5657 : {
5658 : struct wpa_driver_nl80211_data *drv;
5659 : struct i802_bss *bss;
5660 : size_t i;
5661 : char brname[IFNAMSIZ];
5662 : int ifindex, br_ifindex;
5663 1014 : int br_added = 0;
5664 :
5665 1014 : bss = wpa_driver_nl80211_drv_init(hapd, params->ifname,
5666 : params->global_priv, 1,
5667 : params->bssid, params->driver_params);
5668 1014 : if (bss == NULL)
5669 12 : return NULL;
5670 :
5671 1002 : drv = bss->drv;
5672 :
5673 1002 : if (linux_br_get(brname, params->ifname) == 0) {
5674 2 : wpa_printf(MSG_DEBUG, "nl80211: Interface %s is in bridge %s",
5675 : params->ifname, brname);
5676 2 : br_ifindex = if_nametoindex(brname);
5677 2 : os_strlcpy(bss->brname, brname, IFNAMSIZ);
5678 : } else {
5679 1000 : brname[0] = '\0';
5680 1000 : br_ifindex = 0;
5681 : }
5682 1002 : bss->br_ifindex = br_ifindex;
5683 :
5684 2011 : for (i = 0; i < params->num_bridge; i++) {
5685 1009 : if (params->bridge[i]) {
5686 15 : ifindex = if_nametoindex(params->bridge[i]);
5687 15 : if (ifindex)
5688 5 : add_ifidx(drv, ifindex);
5689 15 : if (ifindex == br_ifindex)
5690 9 : br_added = 1;
5691 : }
5692 : }
5693 :
5694 : /* start listening for EAPOL on the default AP interface */
5695 1002 : add_ifidx(drv, drv->ifindex);
5696 :
5697 1002 : if (params->num_bridge && params->bridge[0]) {
5698 15 : if (i802_check_bridge(drv, bss, params->bridge[0],
5699 : params->ifname) < 0)
5700 0 : goto failed;
5701 15 : if (os_strcmp(params->bridge[0], brname) != 0)
5702 15 : br_added = 1;
5703 : }
5704 :
5705 1003 : if (!br_added && br_ifindex &&
5706 2 : (params->num_bridge == 0 || !params->bridge[0]))
5707 1 : add_ifidx(drv, br_ifindex);
5708 :
5709 : #ifdef CONFIG_LIBNL3_ROUTE
5710 1002 : if (bss->added_if_into_bridge) {
5711 15 : drv->rtnl_sk = nl_socket_alloc();
5712 15 : if (drv->rtnl_sk == NULL) {
5713 0 : wpa_printf(MSG_ERROR, "nl80211: Failed to allocate nl_sock");
5714 0 : goto failed;
5715 : }
5716 :
5717 15 : if (nl_connect(drv->rtnl_sk, NETLINK_ROUTE)) {
5718 0 : wpa_printf(MSG_ERROR, "nl80211: Failed to connect nl_sock to NETLINK_ROUTE: %s",
5719 0 : strerror(errno));
5720 0 : goto failed;
5721 : }
5722 : }
5723 : #endif /* CONFIG_LIBNL3_ROUTE */
5724 :
5725 1002 : drv->eapol_sock = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_PAE));
5726 1002 : if (drv->eapol_sock < 0) {
5727 0 : wpa_printf(MSG_ERROR, "nl80211: socket(PF_PACKET, SOCK_DGRAM, ETH_P_PAE) failed: %s",
5728 0 : strerror(errno));
5729 0 : goto failed;
5730 : }
5731 :
5732 1002 : if (eloop_register_read_sock(drv->eapol_sock, handle_eapol, drv, NULL))
5733 : {
5734 1 : wpa_printf(MSG_INFO, "nl80211: Could not register read socket for eapol");
5735 1 : goto failed;
5736 : }
5737 :
5738 1001 : if (linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname,
5739 : params->own_addr))
5740 0 : goto failed;
5741 1001 : os_memcpy(drv->perm_addr, params->own_addr, ETH_ALEN);
5742 :
5743 1001 : memcpy(bss->addr, params->own_addr, ETH_ALEN);
5744 :
5745 1001 : return bss;
5746 :
5747 : failed:
5748 1 : wpa_driver_nl80211_deinit(bss);
5749 1 : return NULL;
5750 : }
5751 :
5752 :
5753 1001 : static void i802_deinit(void *priv)
5754 : {
5755 1001 : struct i802_bss *bss = priv;
5756 1001 : wpa_driver_nl80211_deinit(bss);
5757 1001 : }
5758 :
5759 :
5760 205 : static enum nl80211_iftype wpa_driver_nl80211_if_type(
5761 : enum wpa_driver_if_type type)
5762 : {
5763 205 : switch (type) {
5764 : case WPA_IF_STATION:
5765 0 : return NL80211_IFTYPE_STATION;
5766 : case WPA_IF_P2P_CLIENT:
5767 : case WPA_IF_P2P_GROUP:
5768 40 : return NL80211_IFTYPE_P2P_CLIENT;
5769 : case WPA_IF_AP_VLAN:
5770 13 : return NL80211_IFTYPE_AP_VLAN;
5771 : case WPA_IF_AP_BSS:
5772 42 : return NL80211_IFTYPE_AP;
5773 : case WPA_IF_P2P_GO:
5774 98 : return NL80211_IFTYPE_P2P_GO;
5775 : case WPA_IF_P2P_DEVICE:
5776 8 : return NL80211_IFTYPE_P2P_DEVICE;
5777 : case WPA_IF_MESH:
5778 4 : return NL80211_IFTYPE_MESH_POINT;
5779 : }
5780 0 : return -1;
5781 : }
5782 :
5783 :
5784 : #if defined(CONFIG_P2P) || defined(CONFIG_MESH)
5785 :
5786 2286 : static int nl80211_addr_in_use(struct nl80211_global *global, const u8 *addr)
5787 : {
5788 : struct wpa_driver_nl80211_data *drv;
5789 49991 : dl_list_for_each(drv, &global->interfaces,
5790 : struct wpa_driver_nl80211_data, list) {
5791 49850 : if (os_memcmp(addr, drv->first_bss->addr, ETH_ALEN) == 0)
5792 2145 : return 1;
5793 : }
5794 141 : return 0;
5795 : }
5796 :
5797 :
5798 72 : static int nl80211_vif_addr(struct wpa_driver_nl80211_data *drv, u8 *new_addr)
5799 : {
5800 : unsigned int idx;
5801 :
5802 72 : if (!drv->global)
5803 0 : return -1;
5804 :
5805 72 : os_memcpy(new_addr, drv->first_bss->addr, ETH_ALEN);
5806 2145 : for (idx = 0; idx < 64; idx++) {
5807 2144 : new_addr[0] = drv->first_bss->addr[0] | 0x02;
5808 2144 : new_addr[0] ^= idx << 2;
5809 2144 : if (!nl80211_addr_in_use(drv->global, new_addr))
5810 71 : break;
5811 : }
5812 72 : if (idx == 64)
5813 1 : return -1;
5814 :
5815 426 : wpa_printf(MSG_DEBUG, "nl80211: Assigned new virtual interface address "
5816 426 : MACSTR, MAC2STR(new_addr));
5817 :
5818 71 : return 0;
5819 : }
5820 :
5821 : #endif /* CONFIG_P2P || CONFIG_MESH */
5822 :
5823 :
5824 : struct wdev_info {
5825 : u64 wdev_id;
5826 : int wdev_id_set;
5827 : u8 macaddr[ETH_ALEN];
5828 : };
5829 :
5830 8 : static int nl80211_wdev_handler(struct nl_msg *msg, void *arg)
5831 : {
5832 8 : struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
5833 : struct nlattr *tb[NL80211_ATTR_MAX + 1];
5834 8 : struct wdev_info *wi = arg;
5835 :
5836 8 : nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
5837 : genlmsg_attrlen(gnlh, 0), NULL);
5838 8 : if (tb[NL80211_ATTR_WDEV]) {
5839 8 : wi->wdev_id = nla_get_u64(tb[NL80211_ATTR_WDEV]);
5840 8 : wi->wdev_id_set = 1;
5841 : }
5842 :
5843 8 : if (tb[NL80211_ATTR_MAC])
5844 8 : os_memcpy(wi->macaddr, nla_data(tb[NL80211_ATTR_MAC]),
5845 : ETH_ALEN);
5846 :
5847 8 : return NL_SKIP;
5848 : }
5849 :
5850 :
5851 205 : static int wpa_driver_nl80211_if_add(void *priv, enum wpa_driver_if_type type,
5852 : const char *ifname, const u8 *addr,
5853 : void *bss_ctx, void **drv_priv,
5854 : char *force_ifname, u8 *if_addr,
5855 : const char *bridge, int use_existing)
5856 : {
5857 : enum nl80211_iftype nlmode;
5858 205 : struct i802_bss *bss = priv;
5859 205 : struct wpa_driver_nl80211_data *drv = bss->drv;
5860 : int ifidx;
5861 205 : int added = 1;
5862 :
5863 205 : if (addr)
5864 55 : os_memcpy(if_addr, addr, ETH_ALEN);
5865 205 : nlmode = wpa_driver_nl80211_if_type(type);
5866 205 : if (nlmode == NL80211_IFTYPE_P2P_DEVICE) {
5867 : struct wdev_info p2pdev_info;
5868 :
5869 8 : os_memset(&p2pdev_info, 0, sizeof(p2pdev_info));
5870 8 : ifidx = nl80211_create_iface(drv, ifname, nlmode, addr,
5871 : 0, nl80211_wdev_handler,
5872 : &p2pdev_info, use_existing);
5873 8 : if (!p2pdev_info.wdev_id_set || ifidx != 0) {
5874 0 : wpa_printf(MSG_ERROR, "nl80211: Failed to create a P2P Device interface %s",
5875 : ifname);
5876 0 : return -1;
5877 : }
5878 :
5879 8 : drv->global->if_add_wdevid = p2pdev_info.wdev_id;
5880 8 : drv->global->if_add_wdevid_set = p2pdev_info.wdev_id_set;
5881 8 : if (!is_zero_ether_addr(p2pdev_info.macaddr))
5882 8 : os_memcpy(if_addr, p2pdev_info.macaddr, ETH_ALEN);
5883 8 : wpa_printf(MSG_DEBUG, "nl80211: New P2P Device interface %s (0x%llx) created",
5884 : ifname,
5885 8 : (long long unsigned int) p2pdev_info.wdev_id);
5886 : } else {
5887 197 : ifidx = nl80211_create_iface(drv, ifname, nlmode, addr,
5888 : 0, NULL, NULL, use_existing);
5889 197 : if (use_existing && ifidx == -ENFILE) {
5890 1 : added = 0;
5891 1 : ifidx = if_nametoindex(ifname);
5892 196 : } else if (ifidx < 0) {
5893 0 : return -1;
5894 : }
5895 : }
5896 :
5897 205 : if (!addr) {
5898 150 : if (drv->nlmode == NL80211_IFTYPE_P2P_DEVICE)
5899 7 : os_memcpy(if_addr, bss->addr, ETH_ALEN);
5900 143 : else if (linux_get_ifhwaddr(drv->global->ioctl_sock,
5901 143 : bss->ifname, if_addr) < 0) {
5902 0 : if (added)
5903 0 : nl80211_remove_iface(drv, ifidx);
5904 0 : return -1;
5905 : }
5906 : }
5907 :
5908 : #if defined(CONFIG_P2P) || defined(CONFIG_MESH)
5909 150 : if (!addr &&
5910 136 : (type == WPA_IF_P2P_CLIENT || type == WPA_IF_P2P_GROUP ||
5911 12 : type == WPA_IF_P2P_GO || type == WPA_IF_MESH)) {
5912 : /* Enforce unique P2P Interface Address */
5913 : u8 new_addr[ETH_ALEN];
5914 :
5915 142 : if (linux_get_ifhwaddr(drv->global->ioctl_sock, ifname,
5916 : new_addr) < 0) {
5917 0 : if (added)
5918 0 : nl80211_remove_iface(drv, ifidx);
5919 1 : return -1;
5920 : }
5921 142 : if (nl80211_addr_in_use(drv->global, new_addr)) {
5922 72 : wpa_printf(MSG_DEBUG, "nl80211: Allocate new address "
5923 : "for %s interface", type == WPA_IF_MESH ?
5924 : "mesh" : "P2P group");
5925 72 : if (nl80211_vif_addr(drv, new_addr) < 0) {
5926 1 : if (added)
5927 1 : nl80211_remove_iface(drv, ifidx);
5928 1 : return -1;
5929 : }
5930 71 : if (linux_set_ifhwaddr(drv->global->ioctl_sock, ifname,
5931 : new_addr) < 0) {
5932 0 : if (added)
5933 0 : nl80211_remove_iface(drv, ifidx);
5934 0 : return -1;
5935 : }
5936 : }
5937 141 : os_memcpy(if_addr, new_addr, ETH_ALEN);
5938 : }
5939 : #endif /* CONFIG_P2P || CONFIG_MESH */
5940 :
5941 204 : if (type == WPA_IF_AP_BSS) {
5942 42 : struct i802_bss *new_bss = os_zalloc(sizeof(*new_bss));
5943 42 : if (new_bss == NULL) {
5944 0 : if (added)
5945 0 : nl80211_remove_iface(drv, ifidx);
5946 0 : return -1;
5947 : }
5948 :
5949 42 : if (bridge &&
5950 0 : i802_check_bridge(drv, new_bss, bridge, ifname) < 0) {
5951 0 : wpa_printf(MSG_ERROR, "nl80211: Failed to add the new "
5952 : "interface %s to a bridge %s",
5953 : ifname, bridge);
5954 0 : if (added)
5955 0 : nl80211_remove_iface(drv, ifidx);
5956 0 : os_free(new_bss);
5957 0 : return -1;
5958 : }
5959 :
5960 42 : if (linux_set_iface_flags(drv->global->ioctl_sock, ifname, 1))
5961 : {
5962 0 : if (added)
5963 0 : nl80211_remove_iface(drv, ifidx);
5964 0 : os_free(new_bss);
5965 0 : return -1;
5966 : }
5967 42 : os_strlcpy(new_bss->ifname, ifname, IFNAMSIZ);
5968 42 : os_memcpy(new_bss->addr, if_addr, ETH_ALEN);
5969 42 : new_bss->ifindex = ifidx;
5970 42 : new_bss->drv = drv;
5971 42 : new_bss->next = drv->first_bss->next;
5972 42 : new_bss->freq = drv->first_bss->freq;
5973 42 : new_bss->ctx = bss_ctx;
5974 42 : new_bss->added_if = added;
5975 42 : drv->first_bss->next = new_bss;
5976 42 : if (drv_priv)
5977 42 : *drv_priv = new_bss;
5978 42 : nl80211_init_bss(new_bss);
5979 :
5980 : /* Subscribe management frames for this WPA_IF_AP_BSS */
5981 42 : if (nl80211_setup_ap(new_bss))
5982 0 : return -1;
5983 : }
5984 :
5985 204 : if (drv->global)
5986 204 : drv->global->if_add_ifindex = ifidx;
5987 :
5988 : /*
5989 : * Some virtual interfaces need to process EAPOL packets and events on
5990 : * the parent interface. This is used mainly with hostapd.
5991 : */
5992 400 : if (ifidx > 0 &&
5993 337 : (drv->hostapd ||
5994 141 : nlmode == NL80211_IFTYPE_AP_VLAN ||
5995 141 : nlmode == NL80211_IFTYPE_WDS ||
5996 : nlmode == NL80211_IFTYPE_MONITOR))
5997 55 : add_ifidx(drv, ifidx);
5998 :
5999 204 : return 0;
6000 : }
6001 :
6002 :
6003 194 : static int wpa_driver_nl80211_if_remove(struct i802_bss *bss,
6004 : enum wpa_driver_if_type type,
6005 : const char *ifname)
6006 : {
6007 194 : struct wpa_driver_nl80211_data *drv = bss->drv;
6008 194 : int ifindex = if_nametoindex(ifname);
6009 :
6010 194 : wpa_printf(MSG_DEBUG, "nl80211: %s(type=%d ifname=%s) ifindex=%d added_if=%d",
6011 194 : __func__, type, ifname, ifindex, bss->added_if);
6012 194 : if (ifindex > 0 && (bss->added_if || bss->ifindex != ifindex))
6013 188 : nl80211_remove_iface(drv, ifindex);
6014 6 : else if (ifindex > 0 && !bss->added_if) {
6015 : struct wpa_driver_nl80211_data *drv2;
6016 2 : dl_list_for_each(drv2, &drv->global->interfaces,
6017 : struct wpa_driver_nl80211_data, list)
6018 1 : del_ifidx(drv2, ifindex);
6019 : }
6020 :
6021 194 : if (type != WPA_IF_AP_BSS)
6022 152 : return 0;
6023 :
6024 42 : if (bss->added_if_into_bridge) {
6025 0 : if (linux_br_del_if(drv->global->ioctl_sock, bss->brname,
6026 0 : bss->ifname) < 0)
6027 0 : wpa_printf(MSG_INFO, "nl80211: Failed to remove "
6028 : "interface %s from bridge %s: %s",
6029 0 : bss->ifname, bss->brname, strerror(errno));
6030 : }
6031 42 : if (bss->added_bridge) {
6032 0 : if (linux_br_del(drv->global->ioctl_sock, bss->brname) < 0)
6033 0 : wpa_printf(MSG_INFO, "nl80211: Failed to remove "
6034 : "bridge %s: %s",
6035 0 : bss->brname, strerror(errno));
6036 : }
6037 :
6038 42 : if (bss != drv->first_bss) {
6039 : struct i802_bss *tbss;
6040 :
6041 42 : wpa_printf(MSG_DEBUG, "nl80211: Not the first BSS - remove it");
6042 165 : for (tbss = drv->first_bss; tbss; tbss = tbss->next) {
6043 165 : if (tbss->next == bss) {
6044 42 : tbss->next = bss->next;
6045 : /* Unsubscribe management frames */
6046 42 : nl80211_teardown_ap(bss);
6047 42 : nl80211_destroy_bss(bss);
6048 42 : if (!bss->added_if)
6049 1 : i802_set_iface_flags(bss, 0);
6050 42 : os_free(bss);
6051 42 : bss = NULL;
6052 42 : break;
6053 : }
6054 : }
6055 42 : if (bss)
6056 0 : wpa_printf(MSG_INFO, "nl80211: %s - could not find "
6057 : "BSS %p in the list", __func__, bss);
6058 : } else {
6059 0 : wpa_printf(MSG_DEBUG, "nl80211: First BSS - reassign context");
6060 0 : nl80211_teardown_ap(bss);
6061 0 : if (!bss->added_if && !drv->first_bss->next)
6062 0 : wpa_driver_nl80211_del_beacon(drv);
6063 0 : nl80211_destroy_bss(bss);
6064 0 : if (!bss->added_if)
6065 0 : i802_set_iface_flags(bss, 0);
6066 0 : if (drv->first_bss->next) {
6067 0 : drv->first_bss = drv->first_bss->next;
6068 0 : drv->ctx = drv->first_bss->ctx;
6069 0 : os_free(bss);
6070 : } else {
6071 0 : wpa_printf(MSG_DEBUG, "nl80211: No second BSS to reassign context to");
6072 : }
6073 : }
6074 :
6075 42 : return 0;
6076 : }
6077 :
6078 :
6079 12016 : static int cookie_handler(struct nl_msg *msg, void *arg)
6080 : {
6081 : struct nlattr *tb[NL80211_ATTR_MAX + 1];
6082 12016 : struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
6083 12016 : u64 *cookie = arg;
6084 12016 : nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
6085 : genlmsg_attrlen(gnlh, 0), NULL);
6086 12016 : if (tb[NL80211_ATTR_COOKIE])
6087 12016 : *cookie = nla_get_u64(tb[NL80211_ATTR_COOKIE]);
6088 12016 : return NL_SKIP;
6089 : }
6090 :
6091 :
6092 14136 : static int nl80211_send_frame_cmd(struct i802_bss *bss,
6093 : unsigned int freq, unsigned int wait,
6094 : const u8 *buf, size_t buf_len,
6095 : u64 *cookie_out, int no_cck, int no_ack,
6096 : int offchanok)
6097 : {
6098 14136 : struct wpa_driver_nl80211_data *drv = bss->drv;
6099 : struct nl_msg *msg;
6100 : u64 cookie;
6101 14136 : int ret = -1;
6102 :
6103 14136 : wpa_printf(MSG_MSGDUMP, "nl80211: CMD_FRAME freq=%u wait=%u no_cck=%d "
6104 : "no_ack=%d offchanok=%d",
6105 : freq, wait, no_cck, no_ack, offchanok);
6106 14136 : wpa_hexdump(MSG_MSGDUMP, "CMD_FRAME", buf, buf_len);
6107 :
6108 14136 : if (!(msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_FRAME)) ||
6109 14120 : (freq && nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq)) ||
6110 1658 : (wait && nla_put_u32(msg, NL80211_ATTR_DURATION, wait)) ||
6111 2920 : (offchanok && ((drv->capa.flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX) ||
6112 2920 : drv->test_use_roc_tx) &&
6113 17056 : nla_put_flag(msg, NL80211_ATTR_OFFCHANNEL_TX_OK)) ||
6114 1936 : (no_cck && nla_put_flag(msg, NL80211_ATTR_TX_NO_CCK_RATE)) ||
6115 16768 : (no_ack && nla_put_flag(msg, NL80211_ATTR_DONT_WAIT_FOR_ACK)) ||
6116 14136 : nla_put(msg, NL80211_ATTR_FRAME, buf_len, buf))
6117 : goto fail;
6118 :
6119 14136 : cookie = 0;
6120 14136 : ret = send_and_recv_msgs(drv, msg, cookie_handler, &cookie);
6121 14136 : msg = NULL;
6122 14136 : if (ret) {
6123 1091 : wpa_printf(MSG_DEBUG, "nl80211: Frame command failed: ret=%d "
6124 : "(%s) (freq=%u wait=%u)", ret, strerror(-ret),
6125 : freq, wait);
6126 : } else {
6127 13045 : wpa_printf(MSG_MSGDUMP, "nl80211: Frame TX command accepted%s; "
6128 : "cookie 0x%llx", no_ack ? " (no ACK)" : "",
6129 : (long long unsigned int) cookie);
6130 :
6131 13045 : if (cookie_out)
6132 12373 : *cookie_out = no_ack ? (u64) -1 : cookie;
6133 : }
6134 :
6135 : fail:
6136 14136 : nlmsg_free(msg);
6137 14136 : return ret;
6138 : }
6139 :
6140 :
6141 2248 : static int wpa_driver_nl80211_send_action(struct i802_bss *bss,
6142 : unsigned int freq,
6143 : unsigned int wait_time,
6144 : const u8 *dst, const u8 *src,
6145 : const u8 *bssid,
6146 : const u8 *data, size_t data_len,
6147 : int no_cck)
6148 : {
6149 2248 : struct wpa_driver_nl80211_data *drv = bss->drv;
6150 2248 : int ret = -1;
6151 : u8 *buf;
6152 : struct ieee80211_hdr *hdr;
6153 :
6154 2248 : wpa_printf(MSG_DEBUG, "nl80211: Send Action frame (ifindex=%d, "
6155 : "freq=%u MHz wait=%d ms no_cck=%d)",
6156 : drv->ifindex, freq, wait_time, no_cck);
6157 :
6158 2248 : buf = os_zalloc(24 + data_len);
6159 2248 : if (buf == NULL)
6160 0 : return ret;
6161 2248 : os_memcpy(buf + 24, data, data_len);
6162 2248 : hdr = (struct ieee80211_hdr *) buf;
6163 2248 : hdr->frame_control =
6164 : IEEE80211_FC(WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_ACTION);
6165 2248 : os_memcpy(hdr->addr1, dst, ETH_ALEN);
6166 2248 : os_memcpy(hdr->addr2, src, ETH_ALEN);
6167 2248 : os_memcpy(hdr->addr3, bssid, ETH_ALEN);
6168 :
6169 2587 : if (is_ap_interface(drv->nlmode) &&
6170 678 : (!(drv->capa.flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX) ||
6171 347 : (int) freq == bss->freq || drv->device_ap_sme ||
6172 4 : !drv->use_monitor))
6173 339 : ret = wpa_driver_nl80211_send_mlme(bss, buf, 24 + data_len,
6174 : 0, freq, no_cck, 1,
6175 : wait_time);
6176 : else
6177 1909 : ret = nl80211_send_frame_cmd(bss, freq, wait_time, buf,
6178 : 24 + data_len,
6179 : &drv->send_action_cookie,
6180 : no_cck, 0, 1);
6181 :
6182 2248 : os_free(buf);
6183 2248 : return ret;
6184 : }
6185 :
6186 :
6187 1061 : static void wpa_driver_nl80211_send_action_cancel_wait(void *priv)
6188 : {
6189 1061 : struct i802_bss *bss = priv;
6190 1061 : struct wpa_driver_nl80211_data *drv = bss->drv;
6191 : struct nl_msg *msg;
6192 : int ret;
6193 :
6194 1061 : wpa_printf(MSG_DEBUG, "nl80211: Cancel TX frame wait: cookie=0x%llx",
6195 1061 : (long long unsigned int) drv->send_action_cookie);
6196 2122 : if (!(msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_FRAME_WAIT_CANCEL)) ||
6197 1061 : nla_put_u64(msg, NL80211_ATTR_COOKIE, drv->send_action_cookie)) {
6198 0 : nlmsg_free(msg);
6199 1061 : return;
6200 : }
6201 :
6202 1061 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
6203 1061 : if (ret)
6204 120 : wpa_printf(MSG_DEBUG, "nl80211: wait cancel failed: ret=%d "
6205 : "(%s)", ret, strerror(-ret));
6206 : }
6207 :
6208 :
6209 1599 : static int wpa_driver_nl80211_remain_on_channel(void *priv, unsigned int freq,
6210 : unsigned int duration)
6211 : {
6212 1599 : struct i802_bss *bss = priv;
6213 1599 : struct wpa_driver_nl80211_data *drv = bss->drv;
6214 : struct nl_msg *msg;
6215 : int ret;
6216 : u64 cookie;
6217 :
6218 3198 : if (!(msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_REMAIN_ON_CHANNEL)) ||
6219 3198 : nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq) ||
6220 1599 : nla_put_u32(msg, NL80211_ATTR_DURATION, duration)) {
6221 0 : nlmsg_free(msg);
6222 0 : return -1;
6223 : }
6224 :
6225 1599 : cookie = 0;
6226 1599 : ret = send_and_recv_msgs(drv, msg, cookie_handler, &cookie);
6227 1599 : if (ret == 0) {
6228 1599 : wpa_printf(MSG_DEBUG, "nl80211: Remain-on-channel cookie "
6229 : "0x%llx for freq=%u MHz duration=%u",
6230 : (long long unsigned int) cookie, freq, duration);
6231 1599 : drv->remain_on_chan_cookie = cookie;
6232 1599 : drv->pending_remain_on_chan = 1;
6233 1599 : return 0;
6234 : }
6235 0 : wpa_printf(MSG_DEBUG, "nl80211: Failed to request remain-on-channel "
6236 : "(freq=%d duration=%u): %d (%s)",
6237 : freq, duration, ret, strerror(-ret));
6238 0 : return -1;
6239 : }
6240 :
6241 :
6242 750 : static int wpa_driver_nl80211_cancel_remain_on_channel(void *priv)
6243 : {
6244 750 : struct i802_bss *bss = priv;
6245 750 : struct wpa_driver_nl80211_data *drv = bss->drv;
6246 : struct nl_msg *msg;
6247 : int ret;
6248 :
6249 750 : if (!drv->pending_remain_on_chan) {
6250 0 : wpa_printf(MSG_DEBUG, "nl80211: No pending remain-on-channel "
6251 : "to cancel");
6252 0 : return -1;
6253 : }
6254 :
6255 750 : wpa_printf(MSG_DEBUG, "nl80211: Cancel remain-on-channel with cookie "
6256 : "0x%llx",
6257 750 : (long long unsigned int) drv->remain_on_chan_cookie);
6258 :
6259 750 : msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL);
6260 1500 : if (!msg ||
6261 750 : nla_put_u64(msg, NL80211_ATTR_COOKIE, drv->remain_on_chan_cookie)) {
6262 0 : nlmsg_free(msg);
6263 0 : return -1;
6264 : }
6265 :
6266 750 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
6267 750 : if (ret == 0)
6268 748 : return 0;
6269 2 : wpa_printf(MSG_DEBUG, "nl80211: Failed to cancel remain-on-channel: "
6270 : "%d (%s)", ret, strerror(-ret));
6271 2 : return -1;
6272 : }
6273 :
6274 :
6275 15326 : static int wpa_driver_nl80211_probe_req_report(struct i802_bss *bss, int report)
6276 : {
6277 15326 : struct wpa_driver_nl80211_data *drv = bss->drv;
6278 :
6279 15326 : if (!report) {
6280 13726 : if (bss->nl_preq && drv->device_ap_sme &&
6281 0 : is_ap_interface(drv->nlmode) && !bss->in_deinit &&
6282 0 : !bss->static_ap) {
6283 : /*
6284 : * Do not disable Probe Request reporting that was
6285 : * enabled in nl80211_setup_ap().
6286 : */
6287 0 : wpa_printf(MSG_DEBUG, "nl80211: Skip disabling of "
6288 : "Probe Request reporting nl_preq=%p while "
6289 : "in AP mode", bss->nl_preq);
6290 13726 : } else if (bss->nl_preq) {
6291 1186 : wpa_printf(MSG_DEBUG, "nl80211: Disable Probe Request "
6292 : "reporting nl_preq=%p", bss->nl_preq);
6293 1186 : nl80211_destroy_eloop_handle(&bss->nl_preq);
6294 : }
6295 13726 : return 0;
6296 : }
6297 :
6298 1600 : if (bss->nl_preq) {
6299 411 : wpa_printf(MSG_DEBUG, "nl80211: Probe Request reporting "
6300 : "already on! nl_preq=%p", bss->nl_preq);
6301 411 : return 0;
6302 : }
6303 :
6304 1189 : bss->nl_preq = nl_create_handle(drv->global->nl_cb, "preq");
6305 1189 : if (bss->nl_preq == NULL)
6306 0 : return -1;
6307 1189 : wpa_printf(MSG_DEBUG, "nl80211: Enable Probe Request "
6308 : "reporting nl_preq=%p", bss->nl_preq);
6309 :
6310 1189 : if (nl80211_register_frame(bss, bss->nl_preq,
6311 : (WLAN_FC_TYPE_MGMT << 2) |
6312 : (WLAN_FC_STYPE_PROBE_REQ << 4),
6313 : NULL, 0) < 0)
6314 3 : goto out_err;
6315 :
6316 1186 : nl80211_register_eloop_read(&bss->nl_preq,
6317 : wpa_driver_nl80211_event_receive,
6318 1186 : bss->nl_cb);
6319 :
6320 1186 : return 0;
6321 :
6322 : out_err:
6323 3 : nl_destroy_handles(&bss->nl_preq);
6324 3 : return -1;
6325 : }
6326 :
6327 :
6328 1210 : static int nl80211_disable_11b_rates(struct wpa_driver_nl80211_data *drv,
6329 : int ifindex, int disabled)
6330 : {
6331 : struct nl_msg *msg;
6332 : struct nlattr *bands, *band;
6333 : int ret;
6334 :
6335 1210 : wpa_printf(MSG_DEBUG,
6336 : "nl80211: NL80211_CMD_SET_TX_BITRATE_MASK (ifindex=%d %s)",
6337 : ifindex, disabled ? "NL80211_TXRATE_LEGACY=OFDM-only" :
6338 : "no NL80211_TXRATE_LEGACY constraint");
6339 :
6340 1210 : msg = nl80211_ifindex_msg(drv, ifindex, 0,
6341 : NL80211_CMD_SET_TX_BITRATE_MASK);
6342 1210 : if (!msg)
6343 0 : return -1;
6344 :
6345 1210 : bands = nla_nest_start(msg, NL80211_ATTR_TX_RATES);
6346 1210 : if (!bands)
6347 0 : goto fail;
6348 :
6349 : /*
6350 : * Disable 2 GHz rates 1, 2, 5.5, 11 Mbps by masking out everything
6351 : * else apart from 6, 9, 12, 18, 24, 36, 48, 54 Mbps from non-MCS
6352 : * rates. All 5 GHz rates are left enabled.
6353 : */
6354 1210 : band = nla_nest_start(msg, NL80211_BAND_2GHZ);
6355 1210 : if (!band ||
6356 738 : (disabled && nla_put(msg, NL80211_TXRATE_LEGACY, 8,
6357 : "\x0c\x12\x18\x24\x30\x48\x60\x6c")))
6358 : goto fail;
6359 1210 : nla_nest_end(msg, band);
6360 :
6361 1210 : nla_nest_end(msg, bands);
6362 :
6363 1210 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
6364 1210 : if (ret) {
6365 276 : wpa_printf(MSG_DEBUG, "nl80211: Set TX rates failed: ret=%d "
6366 : "(%s)", ret, strerror(-ret));
6367 : } else
6368 934 : drv->disabled_11b_rates = disabled;
6369 :
6370 1210 : return ret;
6371 :
6372 : fail:
6373 0 : nlmsg_free(msg);
6374 0 : return -1;
6375 : }
6376 :
6377 :
6378 311 : static int wpa_driver_nl80211_deinit_ap(void *priv)
6379 : {
6380 311 : struct i802_bss *bss = priv;
6381 311 : struct wpa_driver_nl80211_data *drv = bss->drv;
6382 311 : if (!is_ap_interface(drv->nlmode))
6383 0 : return -1;
6384 311 : wpa_driver_nl80211_del_beacon(drv);
6385 311 : bss->beacon_set = 0;
6386 :
6387 : /*
6388 : * If the P2P GO interface was dynamically added, then it is
6389 : * possible that the interface change to station is not possible.
6390 : */
6391 311 : if (drv->nlmode == NL80211_IFTYPE_P2P_GO && bss->if_dynamic)
6392 101 : return 0;
6393 :
6394 210 : return wpa_driver_nl80211_set_mode(priv, NL80211_IFTYPE_STATION);
6395 : }
6396 :
6397 :
6398 1 : static int wpa_driver_nl80211_stop_ap(void *priv)
6399 : {
6400 1 : struct i802_bss *bss = priv;
6401 1 : struct wpa_driver_nl80211_data *drv = bss->drv;
6402 1 : if (!is_ap_interface(drv->nlmode))
6403 0 : return -1;
6404 1 : wpa_driver_nl80211_del_beacon(drv);
6405 1 : bss->beacon_set = 0;
6406 1 : return 0;
6407 : }
6408 :
6409 :
6410 172 : static int wpa_driver_nl80211_deinit_p2p_cli(void *priv)
6411 : {
6412 172 : struct i802_bss *bss = priv;
6413 172 : struct wpa_driver_nl80211_data *drv = bss->drv;
6414 172 : if (drv->nlmode != NL80211_IFTYPE_P2P_CLIENT)
6415 1 : return -1;
6416 :
6417 : /*
6418 : * If the P2P Client interface was dynamically added, then it is
6419 : * possible that the interface change to station is not possible.
6420 : */
6421 171 : if (bss->if_dynamic)
6422 0 : return 0;
6423 :
6424 171 : return wpa_driver_nl80211_set_mode(priv, NL80211_IFTYPE_STATION);
6425 : }
6426 :
6427 :
6428 2 : static void wpa_driver_nl80211_resume(void *priv)
6429 : {
6430 2 : struct i802_bss *bss = priv;
6431 :
6432 2 : if (i802_set_iface_flags(bss, 1))
6433 0 : wpa_printf(MSG_DEBUG, "nl80211: Failed to set interface up on resume event");
6434 2 : }
6435 :
6436 :
6437 10 : static int nl80211_signal_monitor(void *priv, int threshold, int hysteresis)
6438 : {
6439 10 : struct i802_bss *bss = priv;
6440 10 : struct wpa_driver_nl80211_data *drv = bss->drv;
6441 : struct nl_msg *msg;
6442 : struct nlattr *cqm;
6443 :
6444 10 : wpa_printf(MSG_DEBUG, "nl80211: Signal monitor threshold=%d "
6445 : "hysteresis=%d", threshold, hysteresis);
6446 :
6447 10 : if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_SET_CQM)) ||
6448 10 : !(cqm = nla_nest_start(msg, NL80211_ATTR_CQM)) ||
6449 20 : nla_put_u32(msg, NL80211_ATTR_CQM_RSSI_THOLD, threshold) ||
6450 10 : nla_put_u32(msg, NL80211_ATTR_CQM_RSSI_HYST, hysteresis)) {
6451 0 : nlmsg_free(msg);
6452 0 : return -1;
6453 : }
6454 10 : nla_nest_end(msg, cqm);
6455 :
6456 10 : return send_and_recv_msgs(drv, msg, NULL, NULL);
6457 : }
6458 :
6459 :
6460 45 : static int get_channel_width(struct nl_msg *msg, void *arg)
6461 : {
6462 : struct nlattr *tb[NL80211_ATTR_MAX + 1];
6463 45 : struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
6464 45 : struct wpa_signal_info *sig_change = arg;
6465 :
6466 45 : nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
6467 : genlmsg_attrlen(gnlh, 0), NULL);
6468 :
6469 45 : sig_change->center_frq1 = -1;
6470 45 : sig_change->center_frq2 = -1;
6471 45 : sig_change->chanwidth = CHAN_WIDTH_UNKNOWN;
6472 :
6473 45 : if (tb[NL80211_ATTR_CHANNEL_WIDTH]) {
6474 45 : sig_change->chanwidth = convert2width(
6475 45 : nla_get_u32(tb[NL80211_ATTR_CHANNEL_WIDTH]));
6476 45 : if (tb[NL80211_ATTR_CENTER_FREQ1])
6477 45 : sig_change->center_frq1 =
6478 45 : nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ1]);
6479 45 : if (tb[NL80211_ATTR_CENTER_FREQ2])
6480 1 : sig_change->center_frq2 =
6481 1 : nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ2]);
6482 : }
6483 :
6484 45 : return NL_SKIP;
6485 : }
6486 :
6487 :
6488 45 : static int nl80211_get_channel_width(struct wpa_driver_nl80211_data *drv,
6489 : struct wpa_signal_info *sig)
6490 : {
6491 : struct nl_msg *msg;
6492 :
6493 45 : msg = nl80211_drv_msg(drv, 0, NL80211_CMD_GET_INTERFACE);
6494 45 : return send_and_recv_msgs(drv, msg, get_channel_width, sig);
6495 : }
6496 :
6497 :
6498 45 : static int nl80211_signal_poll(void *priv, struct wpa_signal_info *si)
6499 : {
6500 45 : struct i802_bss *bss = priv;
6501 45 : struct wpa_driver_nl80211_data *drv = bss->drv;
6502 : int res;
6503 :
6504 45 : os_memset(si, 0, sizeof(*si));
6505 45 : res = nl80211_get_link_signal(drv, si);
6506 45 : if (res != 0)
6507 0 : return res;
6508 :
6509 45 : res = nl80211_get_channel_width(drv, si);
6510 45 : if (res != 0)
6511 0 : return res;
6512 :
6513 45 : return nl80211_get_link_noise(drv, si);
6514 : }
6515 :
6516 :
6517 0 : static int wpa_driver_nl80211_shared_freq(void *priv)
6518 : {
6519 0 : struct i802_bss *bss = priv;
6520 0 : struct wpa_driver_nl80211_data *drv = bss->drv;
6521 : struct wpa_driver_nl80211_data *driver;
6522 0 : int freq = 0;
6523 :
6524 : /*
6525 : * If the same PHY is in connected state with some other interface,
6526 : * then retrieve the assoc freq.
6527 : */
6528 0 : wpa_printf(MSG_DEBUG, "nl80211: Get shared freq for PHY %s",
6529 0 : drv->phyname);
6530 :
6531 0 : dl_list_for_each(driver, &drv->global->interfaces,
6532 : struct wpa_driver_nl80211_data, list) {
6533 0 : if (drv == driver ||
6534 0 : os_strcmp(drv->phyname, driver->phyname) != 0 ||
6535 0 : !driver->associated)
6536 0 : continue;
6537 :
6538 0 : wpa_printf(MSG_DEBUG, "nl80211: Found a match for PHY %s - %s "
6539 : MACSTR,
6540 0 : driver->phyname, driver->first_bss->ifname,
6541 0 : MAC2STR(driver->first_bss->addr));
6542 0 : if (is_ap_interface(driver->nlmode))
6543 0 : freq = driver->first_bss->freq;
6544 : else
6545 0 : freq = nl80211_get_assoc_freq(driver);
6546 0 : wpa_printf(MSG_DEBUG, "nl80211: Shared freq for PHY %s: %d",
6547 0 : drv->phyname, freq);
6548 : }
6549 :
6550 0 : if (!freq)
6551 0 : wpa_printf(MSG_DEBUG, "nl80211: No shared interface for "
6552 0 : "PHY (%s) in associated state", drv->phyname);
6553 :
6554 0 : return freq;
6555 : }
6556 :
6557 :
6558 60 : static int nl80211_send_frame(void *priv, const u8 *data, size_t data_len,
6559 : int encrypt)
6560 : {
6561 60 : struct i802_bss *bss = priv;
6562 60 : return wpa_driver_nl80211_send_frame(bss, data, data_len, encrypt, 0,
6563 : 0, 0, 0, 0);
6564 : }
6565 :
6566 :
6567 231 : static int nl80211_set_param(void *priv, const char *param)
6568 : {
6569 231 : wpa_printf(MSG_DEBUG, "nl80211: driver param='%s'", param);
6570 231 : if (param == NULL)
6571 204 : return 0;
6572 :
6573 : #ifdef CONFIG_P2P
6574 25 : if (os_strstr(param, "use_p2p_group_interface=1")) {
6575 0 : struct i802_bss *bss = priv;
6576 0 : struct wpa_driver_nl80211_data *drv = bss->drv;
6577 :
6578 0 : wpa_printf(MSG_DEBUG, "nl80211: Use separate P2P group "
6579 : "interface");
6580 0 : drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_CONCURRENT;
6581 0 : drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_MGMT_AND_NON_P2P;
6582 : }
6583 : #endif /* CONFIG_P2P */
6584 :
6585 27 : if (os_strstr(param, "use_monitor=1")) {
6586 7 : struct i802_bss *bss = priv;
6587 7 : struct wpa_driver_nl80211_data *drv = bss->drv;
6588 7 : drv->use_monitor = 1;
6589 : }
6590 :
6591 27 : if (os_strstr(param, "force_connect_cmd=1")) {
6592 15 : struct i802_bss *bss = priv;
6593 15 : struct wpa_driver_nl80211_data *drv = bss->drv;
6594 15 : drv->capa.flags &= ~WPA_DRIVER_FLAGS_SME;
6595 15 : drv->force_connect_cmd = 1;
6596 : }
6597 :
6598 27 : if (os_strstr(param, "no_offchannel_tx=1")) {
6599 5 : struct i802_bss *bss = priv;
6600 5 : struct wpa_driver_nl80211_data *drv = bss->drv;
6601 5 : drv->capa.flags &= ~WPA_DRIVER_FLAGS_OFFCHANNEL_TX;
6602 5 : drv->test_use_roc_tx = 1;
6603 : }
6604 :
6605 27 : return 0;
6606 : }
6607 :
6608 :
6609 25 : static void * nl80211_global_init(void)
6610 : {
6611 : struct nl80211_global *global;
6612 : struct netlink_config *cfg;
6613 :
6614 25 : global = os_zalloc(sizeof(*global));
6615 25 : if (global == NULL)
6616 0 : return NULL;
6617 25 : global->ioctl_sock = -1;
6618 25 : dl_list_init(&global->interfaces);
6619 25 : global->if_add_ifindex = -1;
6620 :
6621 25 : cfg = os_zalloc(sizeof(*cfg));
6622 25 : if (cfg == NULL)
6623 0 : goto err;
6624 :
6625 25 : cfg->ctx = global;
6626 25 : cfg->newlink_cb = wpa_driver_nl80211_event_rtm_newlink;
6627 25 : cfg->dellink_cb = wpa_driver_nl80211_event_rtm_dellink;
6628 25 : global->netlink = netlink_init(cfg);
6629 25 : if (global->netlink == NULL) {
6630 0 : os_free(cfg);
6631 0 : goto err;
6632 : }
6633 :
6634 25 : if (wpa_driver_nl80211_init_nl_global(global) < 0)
6635 0 : goto err;
6636 :
6637 25 : global->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
6638 25 : if (global->ioctl_sock < 0) {
6639 0 : wpa_printf(MSG_ERROR, "nl80211: socket(PF_INET,SOCK_DGRAM) failed: %s",
6640 0 : strerror(errno));
6641 0 : goto err;
6642 : }
6643 :
6644 25 : return global;
6645 :
6646 : err:
6647 0 : nl80211_global_deinit(global);
6648 0 : return NULL;
6649 : }
6650 :
6651 :
6652 25 : static void nl80211_global_deinit(void *priv)
6653 : {
6654 25 : struct nl80211_global *global = priv;
6655 25 : if (global == NULL)
6656 25 : return;
6657 25 : if (!dl_list_empty(&global->interfaces)) {
6658 0 : wpa_printf(MSG_ERROR, "nl80211: %u interface(s) remain at "
6659 : "nl80211_global_deinit",
6660 : dl_list_len(&global->interfaces));
6661 : }
6662 :
6663 25 : if (global->netlink)
6664 25 : netlink_deinit(global->netlink);
6665 :
6666 25 : nl_destroy_handles(&global->nl);
6667 :
6668 25 : if (global->nl_event)
6669 25 : nl80211_destroy_eloop_handle(&global->nl_event);
6670 :
6671 25 : nl_cb_put(global->nl_cb);
6672 :
6673 25 : if (global->ioctl_sock >= 0)
6674 25 : close(global->ioctl_sock);
6675 :
6676 25 : os_free(global);
6677 : }
6678 :
6679 :
6680 1549 : static const char * nl80211_get_radio_name(void *priv)
6681 : {
6682 1549 : struct i802_bss *bss = priv;
6683 1549 : struct wpa_driver_nl80211_data *drv = bss->drv;
6684 1549 : return drv->phyname;
6685 : }
6686 :
6687 :
6688 1534 : static int nl80211_pmkid(struct i802_bss *bss, int cmd, const u8 *bssid,
6689 : const u8 *pmkid)
6690 : {
6691 : struct nl_msg *msg;
6692 :
6693 1534 : if (!(msg = nl80211_bss_msg(bss, 0, cmd)) ||
6694 1306 : (pmkid && nla_put(msg, NL80211_ATTR_PMKID, 16, pmkid)) ||
6695 1306 : (bssid && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))) {
6696 0 : nlmsg_free(msg);
6697 0 : return -ENOBUFS;
6698 : }
6699 :
6700 1534 : return send_and_recv_msgs(bss->drv, msg, NULL, NULL);
6701 : }
6702 :
6703 :
6704 653 : static int nl80211_add_pmkid(void *priv, const u8 *bssid, const u8 *pmkid)
6705 : {
6706 653 : struct i802_bss *bss = priv;
6707 653 : wpa_printf(MSG_DEBUG, "nl80211: Add PMKID for " MACSTR, MAC2STR(bssid));
6708 653 : return nl80211_pmkid(bss, NL80211_CMD_SET_PMKSA, bssid, pmkid);
6709 : }
6710 :
6711 :
6712 653 : static int nl80211_remove_pmkid(void *priv, const u8 *bssid, const u8 *pmkid)
6713 : {
6714 653 : struct i802_bss *bss = priv;
6715 3918 : wpa_printf(MSG_DEBUG, "nl80211: Delete PMKID for " MACSTR,
6716 3918 : MAC2STR(bssid));
6717 653 : return nl80211_pmkid(bss, NL80211_CMD_DEL_PMKSA, bssid, pmkid);
6718 : }
6719 :
6720 :
6721 228 : static int nl80211_flush_pmkid(void *priv)
6722 : {
6723 228 : struct i802_bss *bss = priv;
6724 228 : wpa_printf(MSG_DEBUG, "nl80211: Flush PMKIDs");
6725 228 : return nl80211_pmkid(bss, NL80211_CMD_FLUSH_PMKSA, NULL, NULL);
6726 : }
6727 :
6728 :
6729 45 : static void clean_survey_results(struct survey_results *survey_results)
6730 : {
6731 : struct freq_survey *survey, *tmp;
6732 :
6733 45 : if (dl_list_empty(&survey_results->survey_list))
6734 85 : return;
6735 :
6736 10 : dl_list_for_each_safe(survey, tmp, &survey_results->survey_list,
6737 : struct freq_survey, list) {
6738 5 : dl_list_del(&survey->list);
6739 5 : os_free(survey);
6740 : }
6741 : }
6742 :
6743 :
6744 45 : static void add_survey(struct nlattr **sinfo, u32 ifidx,
6745 : struct dl_list *survey_list)
6746 : {
6747 : struct freq_survey *survey;
6748 :
6749 45 : survey = os_zalloc(sizeof(struct freq_survey));
6750 45 : if (!survey)
6751 45 : return;
6752 :
6753 45 : survey->ifidx = ifidx;
6754 45 : survey->freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]);
6755 45 : survey->filled = 0;
6756 :
6757 45 : if (sinfo[NL80211_SURVEY_INFO_NOISE]) {
6758 45 : survey->nf = (int8_t)
6759 45 : nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
6760 45 : survey->filled |= SURVEY_HAS_NF;
6761 : }
6762 :
6763 45 : if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME]) {
6764 0 : survey->channel_time =
6765 0 : nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME]);
6766 0 : survey->filled |= SURVEY_HAS_CHAN_TIME;
6767 : }
6768 :
6769 45 : if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY]) {
6770 0 : survey->channel_time_busy =
6771 0 : nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY]);
6772 0 : survey->filled |= SURVEY_HAS_CHAN_TIME_BUSY;
6773 : }
6774 :
6775 45 : if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_RX]) {
6776 0 : survey->channel_time_rx =
6777 0 : nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_RX]);
6778 0 : survey->filled |= SURVEY_HAS_CHAN_TIME_RX;
6779 : }
6780 :
6781 45 : if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_TX]) {
6782 0 : survey->channel_time_tx =
6783 0 : nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_TX]);
6784 0 : survey->filled |= SURVEY_HAS_CHAN_TIME_TX;
6785 : }
6786 :
6787 90 : wpa_printf(MSG_DEBUG, "nl80211: Freq survey dump event (freq=%d MHz noise=%d channel_time=%ld busy_time=%ld tx_time=%ld rx_time=%ld filled=%04x)",
6788 : survey->freq,
6789 45 : survey->nf,
6790 : (unsigned long int) survey->channel_time,
6791 : (unsigned long int) survey->channel_time_busy,
6792 : (unsigned long int) survey->channel_time_tx,
6793 : (unsigned long int) survey->channel_time_rx,
6794 : survey->filled);
6795 :
6796 45 : dl_list_add_tail(survey_list, &survey->list);
6797 : }
6798 :
6799 :
6800 45 : static int check_survey_ok(struct nlattr **sinfo, u32 surveyed_freq,
6801 : unsigned int freq_filter)
6802 : {
6803 45 : if (!freq_filter)
6804 40 : return 1;
6805 :
6806 5 : return freq_filter == surveyed_freq;
6807 : }
6808 :
6809 :
6810 45 : static int survey_handler(struct nl_msg *msg, void *arg)
6811 : {
6812 : struct nlattr *tb[NL80211_ATTR_MAX + 1];
6813 45 : struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
6814 : struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1];
6815 : struct survey_results *survey_results;
6816 45 : u32 surveyed_freq = 0;
6817 : u32 ifidx;
6818 :
6819 : static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = {
6820 : [NL80211_SURVEY_INFO_FREQUENCY] = { .type = NLA_U32 },
6821 : [NL80211_SURVEY_INFO_NOISE] = { .type = NLA_U8 },
6822 : };
6823 :
6824 45 : survey_results = (struct survey_results *) arg;
6825 :
6826 45 : nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
6827 : genlmsg_attrlen(gnlh, 0), NULL);
6828 :
6829 45 : if (!tb[NL80211_ATTR_IFINDEX])
6830 0 : return NL_SKIP;
6831 :
6832 45 : ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
6833 :
6834 45 : if (!tb[NL80211_ATTR_SURVEY_INFO])
6835 0 : return NL_SKIP;
6836 :
6837 45 : if (nla_parse_nested(sinfo, NL80211_SURVEY_INFO_MAX,
6838 : tb[NL80211_ATTR_SURVEY_INFO],
6839 : survey_policy))
6840 0 : return NL_SKIP;
6841 :
6842 45 : if (!sinfo[NL80211_SURVEY_INFO_FREQUENCY]) {
6843 0 : wpa_printf(MSG_ERROR, "nl80211: Invalid survey data");
6844 0 : return NL_SKIP;
6845 : }
6846 :
6847 45 : surveyed_freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]);
6848 :
6849 45 : if (!check_survey_ok(sinfo, surveyed_freq,
6850 : survey_results->freq_filter))
6851 0 : return NL_SKIP;
6852 :
6853 50 : if (survey_results->freq_filter &&
6854 5 : survey_results->freq_filter != surveyed_freq) {
6855 0 : wpa_printf(MSG_EXCESSIVE, "nl80211: Ignoring survey data for freq %d MHz",
6856 : surveyed_freq);
6857 0 : return NL_SKIP;
6858 : }
6859 :
6860 45 : add_survey(sinfo, ifidx, &survey_results->survey_list);
6861 :
6862 45 : return NL_SKIP;
6863 : }
6864 :
6865 :
6866 45 : static int wpa_driver_nl80211_get_survey(void *priv, unsigned int freq)
6867 : {
6868 45 : struct i802_bss *bss = priv;
6869 45 : struct wpa_driver_nl80211_data *drv = bss->drv;
6870 : struct nl_msg *msg;
6871 : int err;
6872 : union wpa_event_data data;
6873 : struct survey_results *survey_results;
6874 :
6875 45 : os_memset(&data, 0, sizeof(data));
6876 45 : survey_results = &data.survey_results;
6877 :
6878 45 : dl_list_init(&survey_results->survey_list);
6879 :
6880 45 : msg = nl80211_drv_msg(drv, NLM_F_DUMP, NL80211_CMD_GET_SURVEY);
6881 45 : if (!msg)
6882 0 : return -ENOBUFS;
6883 :
6884 45 : if (freq)
6885 5 : data.survey_results.freq_filter = freq;
6886 :
6887 : do {
6888 45 : wpa_printf(MSG_DEBUG, "nl80211: Fetch survey data");
6889 45 : err = send_and_recv_msgs(drv, msg, survey_handler,
6890 : survey_results);
6891 45 : } while (err > 0);
6892 :
6893 45 : if (err)
6894 0 : wpa_printf(MSG_ERROR, "nl80211: Failed to process survey data");
6895 : else
6896 45 : wpa_supplicant_event(drv->ctx, EVENT_SURVEY, &data);
6897 :
6898 45 : clean_survey_results(survey_results);
6899 45 : return err;
6900 : }
6901 :
6902 :
6903 1336 : static void nl80211_set_rekey_info(void *priv, const u8 *kek, size_t kek_len,
6904 : const u8 *kck, size_t kck_len,
6905 : const u8 *replay_ctr)
6906 : {
6907 1336 : struct i802_bss *bss = priv;
6908 1336 : struct wpa_driver_nl80211_data *drv = bss->drv;
6909 : struct nlattr *replay_nested;
6910 : struct nl_msg *msg;
6911 : int ret;
6912 :
6913 1336 : if (!drv->set_rekey_offload)
6914 1278 : return;
6915 :
6916 58 : wpa_printf(MSG_DEBUG, "nl80211: Set rekey offload");
6917 58 : if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_SET_REKEY_OFFLOAD)) ||
6918 58 : !(replay_nested = nla_nest_start(msg, NL80211_ATTR_REKEY_DATA)) ||
6919 116 : nla_put(msg, NL80211_REKEY_DATA_KEK, kek_len, kek) ||
6920 116 : nla_put(msg, NL80211_REKEY_DATA_KCK, kck_len, kck) ||
6921 58 : nla_put(msg, NL80211_REKEY_DATA_REPLAY_CTR, NL80211_REPLAY_CTR_LEN,
6922 : replay_ctr)) {
6923 0 : nl80211_nlmsg_clear(msg);
6924 0 : nlmsg_free(msg);
6925 0 : return;
6926 : }
6927 :
6928 58 : nla_nest_end(msg, replay_nested);
6929 :
6930 58 : ret = send_and_recv_msgs(drv, msg, NULL, (void *) -1);
6931 58 : if (ret == -EOPNOTSUPP) {
6932 58 : wpa_printf(MSG_DEBUG,
6933 : "nl80211: Driver does not support rekey offload");
6934 58 : drv->set_rekey_offload = 0;
6935 : }
6936 : }
6937 :
6938 :
6939 0 : static void nl80211_send_null_frame(struct i802_bss *bss, const u8 *own_addr,
6940 : const u8 *addr, int qos)
6941 : {
6942 : /* send data frame to poll STA and check whether
6943 : * this frame is ACKed */
6944 : struct {
6945 : struct ieee80211_hdr hdr;
6946 : u16 qos_ctl;
6947 : } STRUCT_PACKED nulldata;
6948 : size_t size;
6949 :
6950 : /* Send data frame to poll STA and check whether this frame is ACKed */
6951 :
6952 0 : os_memset(&nulldata, 0, sizeof(nulldata));
6953 :
6954 0 : if (qos) {
6955 0 : nulldata.hdr.frame_control =
6956 : IEEE80211_FC(WLAN_FC_TYPE_DATA,
6957 : WLAN_FC_STYPE_QOS_NULL);
6958 0 : size = sizeof(nulldata);
6959 : } else {
6960 0 : nulldata.hdr.frame_control =
6961 : IEEE80211_FC(WLAN_FC_TYPE_DATA,
6962 : WLAN_FC_STYPE_NULLFUNC);
6963 0 : size = sizeof(struct ieee80211_hdr);
6964 : }
6965 :
6966 0 : nulldata.hdr.frame_control |= host_to_le16(WLAN_FC_FROMDS);
6967 0 : os_memcpy(nulldata.hdr.IEEE80211_DA_FROMDS, addr, ETH_ALEN);
6968 0 : os_memcpy(nulldata.hdr.IEEE80211_BSSID_FROMDS, own_addr, ETH_ALEN);
6969 0 : os_memcpy(nulldata.hdr.IEEE80211_SA_FROMDS, own_addr, ETH_ALEN);
6970 :
6971 0 : if (wpa_driver_nl80211_send_mlme(bss, (u8 *) &nulldata, size, 0, 0, 0,
6972 : 0, 0) < 0)
6973 0 : wpa_printf(MSG_DEBUG, "nl80211_send_null_frame: Failed to "
6974 : "send poll frame");
6975 0 : }
6976 :
6977 2 : static void nl80211_poll_client(void *priv, const u8 *own_addr, const u8 *addr,
6978 : int qos)
6979 : {
6980 2 : struct i802_bss *bss = priv;
6981 2 : struct wpa_driver_nl80211_data *drv = bss->drv;
6982 : struct nl_msg *msg;
6983 : int ret;
6984 :
6985 2 : if (!drv->poll_command_supported) {
6986 0 : nl80211_send_null_frame(bss, own_addr, addr, qos);
6987 0 : return;
6988 : }
6989 :
6990 4 : if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_PROBE_CLIENT)) ||
6991 2 : nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) {
6992 0 : nlmsg_free(msg);
6993 0 : return;
6994 : }
6995 :
6996 2 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
6997 2 : if (ret < 0) {
6998 0 : wpa_printf(MSG_DEBUG, "nl80211: Client probe request for "
6999 : MACSTR " failed: ret=%d (%s)",
7000 0 : MAC2STR(addr), ret, strerror(-ret));
7001 : }
7002 : }
7003 :
7004 :
7005 3 : static int nl80211_set_power_save(struct i802_bss *bss, int enabled)
7006 : {
7007 : struct nl_msg *msg;
7008 :
7009 6 : if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_SET_POWER_SAVE)) ||
7010 3 : nla_put_u32(msg, NL80211_ATTR_PS_STATE,
7011 : enabled ? NL80211_PS_ENABLED : NL80211_PS_DISABLED)) {
7012 0 : nlmsg_free(msg);
7013 0 : return -ENOBUFS;
7014 : }
7015 3 : return send_and_recv_msgs(bss->drv, msg, NULL, NULL);
7016 : }
7017 :
7018 :
7019 8 : static int nl80211_set_p2p_powersave(void *priv, int legacy_ps, int opp_ps,
7020 : int ctwindow)
7021 : {
7022 8 : struct i802_bss *bss = priv;
7023 :
7024 8 : wpa_printf(MSG_DEBUG, "nl80211: set_p2p_powersave (legacy_ps=%d "
7025 : "opp_ps=%d ctwindow=%d)", legacy_ps, opp_ps, ctwindow);
7026 :
7027 8 : if (opp_ps != -1 || ctwindow != -1) {
7028 : #ifdef ANDROID_P2P
7029 : wpa_driver_set_p2p_ps(priv, legacy_ps, opp_ps, ctwindow);
7030 : #else /* ANDROID_P2P */
7031 2 : return -1; /* Not yet supported */
7032 : #endif /* ANDROID_P2P */
7033 : }
7034 :
7035 6 : if (legacy_ps == -1)
7036 1 : return 0;
7037 5 : if (legacy_ps != 0 && legacy_ps != 1)
7038 2 : return -1; /* Not yet supported */
7039 :
7040 3 : return nl80211_set_power_save(bss, legacy_ps);
7041 : }
7042 :
7043 :
7044 13 : static int nl80211_start_radar_detection(void *priv,
7045 : struct hostapd_freq_params *freq)
7046 : {
7047 13 : struct i802_bss *bss = priv;
7048 13 : struct wpa_driver_nl80211_data *drv = bss->drv;
7049 : struct nl_msg *msg;
7050 : int ret;
7051 :
7052 13 : wpa_printf(MSG_DEBUG, "nl80211: Start radar detection (CAC) %d MHz (ht_enabled=%d, vht_enabled=%d, bandwidth=%d MHz, cf1=%d MHz, cf2=%d MHz)",
7053 : freq->freq, freq->ht_enabled, freq->vht_enabled,
7054 : freq->bandwidth, freq->center_freq1, freq->center_freq2);
7055 :
7056 13 : if (!(drv->capa.flags & WPA_DRIVER_FLAGS_RADAR)) {
7057 0 : wpa_printf(MSG_DEBUG, "nl80211: Driver does not support radar "
7058 : "detection");
7059 0 : return -1;
7060 : }
7061 :
7062 26 : if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_RADAR_DETECT)) ||
7063 13 : nl80211_put_freq_params(msg, freq) < 0) {
7064 0 : nlmsg_free(msg);
7065 0 : return -1;
7066 : }
7067 :
7068 13 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
7069 13 : if (ret == 0)
7070 12 : return 0;
7071 1 : wpa_printf(MSG_DEBUG, "nl80211: Failed to start radar detection: "
7072 : "%d (%s)", ret, strerror(-ret));
7073 1 : return -1;
7074 : }
7075 :
7076 : #ifdef CONFIG_TDLS
7077 :
7078 128 : static int nl80211_send_tdls_mgmt(void *priv, const u8 *dst, u8 action_code,
7079 : u8 dialog_token, u16 status_code,
7080 : u32 peer_capab, int initiator, const u8 *buf,
7081 : size_t len)
7082 : {
7083 128 : struct i802_bss *bss = priv;
7084 128 : struct wpa_driver_nl80211_data *drv = bss->drv;
7085 : struct nl_msg *msg;
7086 :
7087 128 : if (!(drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT))
7088 0 : return -EOPNOTSUPP;
7089 :
7090 128 : if (!dst)
7091 0 : return -EINVAL;
7092 :
7093 256 : if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_TDLS_MGMT)) ||
7094 256 : nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, dst) ||
7095 256 : nla_put_u8(msg, NL80211_ATTR_TDLS_ACTION, action_code) ||
7096 256 : nla_put_u8(msg, NL80211_ATTR_TDLS_DIALOG_TOKEN, dialog_token) ||
7097 128 : nla_put_u16(msg, NL80211_ATTR_STATUS_CODE, status_code))
7098 : goto fail;
7099 128 : if (peer_capab) {
7100 : /*
7101 : * The internal enum tdls_peer_capability definition is
7102 : * currently identical with the nl80211 enum
7103 : * nl80211_tdls_peer_capability, so no conversion is needed
7104 : * here.
7105 : */
7106 25 : if (nla_put_u32(msg, NL80211_ATTR_TDLS_PEER_CAPABILITY,
7107 : peer_capab))
7108 0 : goto fail;
7109 : }
7110 211 : if ((initiator &&
7111 211 : nla_put_flag(msg, NL80211_ATTR_TDLS_INITIATOR)) ||
7112 128 : nla_put(msg, NL80211_ATTR_IE, len, buf))
7113 : goto fail;
7114 :
7115 128 : return send_and_recv_msgs(drv, msg, NULL, NULL);
7116 :
7117 : fail:
7118 0 : nlmsg_free(msg);
7119 0 : return -ENOBUFS;
7120 : }
7121 :
7122 :
7123 3451 : static int nl80211_tdls_oper(void *priv, enum tdls_oper oper, const u8 *peer)
7124 : {
7125 3451 : struct i802_bss *bss = priv;
7126 3451 : struct wpa_driver_nl80211_data *drv = bss->drv;
7127 : struct nl_msg *msg;
7128 : enum nl80211_tdls_operation nl80211_oper;
7129 :
7130 3451 : if (!(drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT))
7131 0 : return -EOPNOTSUPP;
7132 :
7133 3451 : switch (oper) {
7134 : case TDLS_DISCOVERY_REQ:
7135 0 : nl80211_oper = NL80211_TDLS_DISCOVERY_REQ;
7136 0 : break;
7137 : case TDLS_SETUP:
7138 0 : nl80211_oper = NL80211_TDLS_SETUP;
7139 0 : break;
7140 : case TDLS_TEARDOWN:
7141 0 : nl80211_oper = NL80211_TDLS_TEARDOWN;
7142 0 : break;
7143 : case TDLS_ENABLE_LINK:
7144 49 : nl80211_oper = NL80211_TDLS_ENABLE_LINK;
7145 49 : break;
7146 : case TDLS_DISABLE_LINK:
7147 59 : nl80211_oper = NL80211_TDLS_DISABLE_LINK;
7148 59 : break;
7149 : case TDLS_ENABLE:
7150 3342 : return 0;
7151 : case TDLS_DISABLE:
7152 1 : return 0;
7153 : default:
7154 0 : return -EINVAL;
7155 : }
7156 :
7157 216 : if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_TDLS_OPER)) ||
7158 216 : nla_put_u8(msg, NL80211_ATTR_TDLS_OPERATION, nl80211_oper) ||
7159 108 : nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, peer)) {
7160 0 : nlmsg_free(msg);
7161 0 : return -ENOBUFS;
7162 : }
7163 :
7164 108 : return send_and_recv_msgs(drv, msg, NULL, NULL);
7165 : }
7166 :
7167 :
7168 : static int
7169 1 : nl80211_tdls_enable_channel_switch(void *priv, const u8 *addr, u8 oper_class,
7170 : const struct hostapd_freq_params *params)
7171 : {
7172 1 : struct i802_bss *bss = priv;
7173 1 : struct wpa_driver_nl80211_data *drv = bss->drv;
7174 : struct nl_msg *msg;
7175 1 : int ret = -ENOBUFS;
7176 :
7177 2 : if (!(drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT) ||
7178 1 : !(drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_CHANNEL_SWITCH))
7179 0 : return -EOPNOTSUPP;
7180 :
7181 7 : wpa_printf(MSG_DEBUG, "nl80211: Enable TDLS channel switch " MACSTR
7182 : " oper_class=%u freq=%u",
7183 6 : MAC2STR(addr), oper_class, params->freq);
7184 1 : msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_TDLS_CHANNEL_SWITCH);
7185 2 : if (!msg ||
7186 2 : nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
7187 2 : nla_put_u8(msg, NL80211_ATTR_OPER_CLASS, oper_class) ||
7188 : (ret = nl80211_put_freq_params(msg, params))) {
7189 0 : nlmsg_free(msg);
7190 0 : wpa_printf(MSG_DEBUG, "nl80211: Could not build TDLS chan switch");
7191 0 : return ret;
7192 : }
7193 :
7194 1 : return send_and_recv_msgs(drv, msg, NULL, NULL);
7195 : }
7196 :
7197 :
7198 : static int
7199 1 : nl80211_tdls_disable_channel_switch(void *priv, const u8 *addr)
7200 : {
7201 1 : struct i802_bss *bss = priv;
7202 1 : struct wpa_driver_nl80211_data *drv = bss->drv;
7203 : struct nl_msg *msg;
7204 :
7205 2 : if (!(drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT) ||
7206 1 : !(drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_CHANNEL_SWITCH))
7207 0 : return -EOPNOTSUPP;
7208 :
7209 6 : wpa_printf(MSG_DEBUG, "nl80211: Disable TDLS channel switch " MACSTR,
7210 6 : MAC2STR(addr));
7211 1 : msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_TDLS_CANCEL_CHANNEL_SWITCH);
7212 2 : if (!msg ||
7213 1 : nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) {
7214 0 : nlmsg_free(msg);
7215 0 : wpa_printf(MSG_DEBUG,
7216 : "nl80211: Could not build TDLS cancel chan switch");
7217 0 : return -ENOBUFS;
7218 : }
7219 :
7220 1 : return send_and_recv_msgs(drv, msg, NULL, NULL);
7221 : }
7222 :
7223 : #endif /* CONFIG TDLS */
7224 :
7225 :
7226 29052 : static int driver_nl80211_set_key(const char *ifname, void *priv,
7227 : enum wpa_alg alg, const u8 *addr,
7228 : int key_idx, int set_tx,
7229 : const u8 *seq, size_t seq_len,
7230 : const u8 *key, size_t key_len)
7231 : {
7232 29052 : struct i802_bss *bss = priv;
7233 29052 : return wpa_driver_nl80211_set_key(ifname, bss, alg, addr, key_idx,
7234 : set_tx, seq, seq_len, key, key_len);
7235 : }
7236 :
7237 :
7238 2940 : static int driver_nl80211_scan2(void *priv,
7239 : struct wpa_driver_scan_params *params)
7240 : {
7241 2940 : struct i802_bss *bss = priv;
7242 2940 : return wpa_driver_nl80211_scan(bss, params);
7243 : }
7244 :
7245 :
7246 2249 : static int driver_nl80211_deauthenticate(void *priv, const u8 *addr,
7247 : int reason_code)
7248 : {
7249 2249 : struct i802_bss *bss = priv;
7250 2249 : return wpa_driver_nl80211_deauthenticate(bss, addr, reason_code);
7251 : }
7252 :
7253 :
7254 2713 : static int driver_nl80211_authenticate(void *priv,
7255 : struct wpa_driver_auth_params *params)
7256 : {
7257 2713 : struct i802_bss *bss = priv;
7258 2713 : return wpa_driver_nl80211_authenticate(bss, params);
7259 : }
7260 :
7261 :
7262 229 : static void driver_nl80211_deinit(void *priv)
7263 : {
7264 229 : struct i802_bss *bss = priv;
7265 229 : wpa_driver_nl80211_deinit(bss);
7266 229 : }
7267 :
7268 :
7269 194 : static int driver_nl80211_if_remove(void *priv, enum wpa_driver_if_type type,
7270 : const char *ifname)
7271 : {
7272 194 : struct i802_bss *bss = priv;
7273 194 : return wpa_driver_nl80211_if_remove(bss, type, ifname);
7274 : }
7275 :
7276 :
7277 9029 : static int driver_nl80211_send_mlme(void *priv, const u8 *data,
7278 : size_t data_len, int noack)
7279 : {
7280 9029 : struct i802_bss *bss = priv;
7281 9029 : return wpa_driver_nl80211_send_mlme(bss, data, data_len, noack,
7282 : 0, 0, 0, 0);
7283 : }
7284 :
7285 :
7286 4744 : static int driver_nl80211_sta_remove(void *priv, const u8 *addr)
7287 : {
7288 4744 : struct i802_bss *bss = priv;
7289 4744 : return wpa_driver_nl80211_sta_remove(bss, addr, -1, 0);
7290 : }
7291 :
7292 :
7293 14 : static int driver_nl80211_set_sta_vlan(void *priv, const u8 *addr,
7294 : const char *ifname, int vlan_id)
7295 : {
7296 14 : struct i802_bss *bss = priv;
7297 14 : return i802_set_sta_vlan(bss, addr, ifname, vlan_id);
7298 : }
7299 :
7300 :
7301 297 : static int driver_nl80211_read_sta_data(void *priv,
7302 : struct hostap_sta_driver_data *data,
7303 : const u8 *addr)
7304 : {
7305 297 : struct i802_bss *bss = priv;
7306 297 : return i802_read_sta_data(bss, data, addr);
7307 : }
7308 :
7309 :
7310 2248 : static int driver_nl80211_send_action(void *priv, unsigned int freq,
7311 : unsigned int wait_time,
7312 : const u8 *dst, const u8 *src,
7313 : const u8 *bssid,
7314 : const u8 *data, size_t data_len,
7315 : int no_cck)
7316 : {
7317 2248 : struct i802_bss *bss = priv;
7318 2248 : return wpa_driver_nl80211_send_action(bss, freq, wait_time, dst, src,
7319 : bssid, data, data_len, no_cck);
7320 : }
7321 :
7322 :
7323 13874 : static int driver_nl80211_probe_req_report(void *priv, int report)
7324 : {
7325 13874 : struct i802_bss *bss = priv;
7326 13874 : return wpa_driver_nl80211_probe_req_report(bss, report);
7327 : }
7328 :
7329 :
7330 0 : static int wpa_driver_nl80211_update_ft_ies(void *priv, const u8 *md,
7331 : const u8 *ies, size_t ies_len)
7332 : {
7333 : int ret;
7334 : struct nl_msg *msg;
7335 0 : struct i802_bss *bss = priv;
7336 0 : struct wpa_driver_nl80211_data *drv = bss->drv;
7337 0 : u16 mdid = WPA_GET_LE16(md);
7338 :
7339 0 : wpa_printf(MSG_DEBUG, "nl80211: Updating FT IEs");
7340 0 : if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_UPDATE_FT_IES)) ||
7341 0 : nla_put(msg, NL80211_ATTR_IE, ies_len, ies) ||
7342 0 : nla_put_u16(msg, NL80211_ATTR_MDID, mdid)) {
7343 0 : nlmsg_free(msg);
7344 0 : return -ENOBUFS;
7345 : }
7346 :
7347 0 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
7348 0 : if (ret) {
7349 0 : wpa_printf(MSG_DEBUG, "nl80211: update_ft_ies failed "
7350 : "err=%d (%s)", ret, strerror(-ret));
7351 : }
7352 :
7353 0 : return ret;
7354 : }
7355 :
7356 :
7357 250 : const u8 * wpa_driver_nl80211_get_macaddr(void *priv)
7358 : {
7359 250 : struct i802_bss *bss = priv;
7360 250 : struct wpa_driver_nl80211_data *drv = bss->drv;
7361 :
7362 250 : if (drv->nlmode != NL80211_IFTYPE_P2P_DEVICE)
7363 242 : return NULL;
7364 :
7365 8 : return bss->addr;
7366 : }
7367 :
7368 :
7369 4252 : static const char * scan_state_str(enum scan_states scan_state)
7370 : {
7371 4252 : switch (scan_state) {
7372 : case NO_SCAN:
7373 85 : return "NO_SCAN";
7374 : case SCAN_REQUESTED:
7375 2 : return "SCAN_REQUESTED";
7376 : case SCAN_STARTED:
7377 22 : return "SCAN_STARTED";
7378 : case SCAN_COMPLETED:
7379 4130 : return "SCAN_COMPLETED";
7380 : case SCAN_ABORTED:
7381 13 : return "SCAN_ABORTED";
7382 : case SCHED_SCAN_STARTED:
7383 0 : return "SCHED_SCAN_STARTED";
7384 : case SCHED_SCAN_STOPPED:
7385 0 : return "SCHED_SCAN_STOPPED";
7386 : case SCHED_SCAN_RESULTS:
7387 0 : return "SCHED_SCAN_RESULTS";
7388 : }
7389 :
7390 0 : return "??";
7391 : }
7392 :
7393 :
7394 4252 : static int wpa_driver_nl80211_status(void *priv, char *buf, size_t buflen)
7395 : {
7396 4252 : struct i802_bss *bss = priv;
7397 4252 : struct wpa_driver_nl80211_data *drv = bss->drv;
7398 : int res;
7399 : char *pos, *end;
7400 :
7401 4252 : pos = buf;
7402 4252 : end = buf + buflen;
7403 :
7404 51024 : res = os_snprintf(pos, end - pos,
7405 : "ifindex=%d\n"
7406 : "ifname=%s\n"
7407 : "brname=%s\n"
7408 : "addr=" MACSTR "\n"
7409 : "freq=%d\n"
7410 : "%s%s%s%s%s",
7411 : bss->ifindex,
7412 4252 : bss->ifname,
7413 4252 : bss->brname,
7414 25512 : MAC2STR(bss->addr),
7415 : bss->freq,
7416 4252 : bss->beacon_set ? "beacon_set=1\n" : "",
7417 4252 : bss->added_if_into_bridge ?
7418 : "added_if_into_bridge=1\n" : "",
7419 4252 : bss->added_bridge ? "added_bridge=1\n" : "",
7420 4252 : bss->in_deinit ? "in_deinit=1\n" : "",
7421 4252 : bss->if_dynamic ? "if_dynamic=1\n" : "");
7422 4252 : if (os_snprintf_error(end - pos, res))
7423 0 : return pos - buf;
7424 4252 : pos += res;
7425 :
7426 4252 : if (bss->wdev_id_set) {
7427 1 : res = os_snprintf(pos, end - pos, "wdev_id=%llu\n",
7428 1 : (unsigned long long) bss->wdev_id);
7429 1 : if (os_snprintf_error(end - pos, res))
7430 0 : return pos - buf;
7431 1 : pos += res;
7432 : }
7433 :
7434 187088 : res = os_snprintf(pos, end - pos,
7435 : "phyname=%s\n"
7436 : "perm_addr=" MACSTR "\n"
7437 : "drv_ifindex=%d\n"
7438 : "operstate=%d\n"
7439 : "scan_state=%s\n"
7440 : "auth_bssid=" MACSTR "\n"
7441 : "auth_attempt_bssid=" MACSTR "\n"
7442 : "bssid=" MACSTR "\n"
7443 : "prev_bssid=" MACSTR "\n"
7444 : "associated=%d\n"
7445 : "assoc_freq=%u\n"
7446 : "monitor_sock=%d\n"
7447 : "monitor_ifidx=%d\n"
7448 : "monitor_refcount=%d\n"
7449 : "last_mgmt_freq=%u\n"
7450 : "eapol_tx_sock=%d\n"
7451 : "%s%s%s%s%s%s%s%s%s%s%s%s%s",
7452 4252 : drv->phyname,
7453 25512 : MAC2STR(drv->perm_addr),
7454 : drv->ifindex,
7455 : drv->operstate,
7456 : scan_state_str(drv->scan_state),
7457 25512 : MAC2STR(drv->auth_bssid),
7458 25512 : MAC2STR(drv->auth_attempt_bssid),
7459 25512 : MAC2STR(drv->bssid),
7460 25512 : MAC2STR(drv->prev_bssid),
7461 : drv->associated,
7462 : drv->assoc_freq,
7463 : drv->monitor_sock,
7464 : drv->monitor_ifidx,
7465 : drv->monitor_refcount,
7466 : drv->last_mgmt_freq,
7467 : drv->eapol_tx_sock,
7468 4252 : drv->ignore_if_down_event ?
7469 : "ignore_if_down_event=1\n" : "",
7470 4252 : drv->scan_complete_events ?
7471 : "scan_complete_events=1\n" : "",
7472 4252 : drv->disabled_11b_rates ?
7473 : "disabled_11b_rates=1\n" : "",
7474 4252 : drv->pending_remain_on_chan ?
7475 : "pending_remain_on_chan=1\n" : "",
7476 4252 : drv->in_interface_list ? "in_interface_list=1\n" : "",
7477 4252 : drv->device_ap_sme ? "device_ap_sme=1\n" : "",
7478 4252 : drv->poll_command_supported ?
7479 : "poll_command_supported=1\n" : "",
7480 4252 : drv->data_tx_status ? "data_tx_status=1\n" : "",
7481 4252 : drv->scan_for_auth ? "scan_for_auth=1\n" : "",
7482 4252 : drv->retry_auth ? "retry_auth=1\n" : "",
7483 4252 : drv->use_monitor ? "use_monitor=1\n" : "",
7484 4252 : drv->ignore_next_local_disconnect ?
7485 : "ignore_next_local_disconnect=1\n" : "",
7486 4252 : drv->ignore_next_local_deauth ?
7487 : "ignore_next_local_deauth=1\n" : "");
7488 4252 : if (os_snprintf_error(end - pos, res))
7489 0 : return pos - buf;
7490 4252 : pos += res;
7491 :
7492 4252 : if (drv->has_capability) {
7493 12756 : res = os_snprintf(pos, end - pos,
7494 : "capa.key_mgmt=0x%x\n"
7495 : "capa.enc=0x%x\n"
7496 : "capa.auth=0x%x\n"
7497 : "capa.flags=0x%llx\n"
7498 : "capa.rrm_flags=0x%x\n"
7499 : "capa.max_scan_ssids=%d\n"
7500 : "capa.max_sched_scan_ssids=%d\n"
7501 : "capa.sched_scan_supported=%d\n"
7502 : "capa.max_match_sets=%d\n"
7503 : "capa.max_remain_on_chan=%u\n"
7504 : "capa.max_stations=%u\n"
7505 : "capa.probe_resp_offloads=0x%x\n"
7506 : "capa.max_acl_mac_addrs=%u\n"
7507 : "capa.num_multichan_concurrent=%u\n"
7508 : "capa.mac_addr_rand_sched_scan_supported=%d\n"
7509 : "capa.mac_addr_rand_scan_supported=%d\n",
7510 : drv->capa.key_mgmt,
7511 : drv->capa.enc,
7512 : drv->capa.auth,
7513 4252 : (unsigned long long) drv->capa.flags,
7514 : drv->capa.rrm_flags,
7515 : drv->capa.max_scan_ssids,
7516 : drv->capa.max_sched_scan_ssids,
7517 : drv->capa.sched_scan_supported,
7518 : drv->capa.max_match_sets,
7519 : drv->capa.max_remain_on_chan,
7520 : drv->capa.max_stations,
7521 : drv->capa.probe_resp_offloads,
7522 : drv->capa.max_acl_mac_addrs,
7523 : drv->capa.num_multichan_concurrent,
7524 4252 : drv->capa.mac_addr_rand_sched_scan_supported,
7525 4252 : drv->capa.mac_addr_rand_scan_supported);
7526 4252 : if (os_snprintf_error(end - pos, res))
7527 0 : return pos - buf;
7528 4252 : pos += res;
7529 : }
7530 :
7531 4252 : return pos - buf;
7532 : }
7533 :
7534 :
7535 44 : static int set_beacon_data(struct nl_msg *msg, struct beacon_data *settings)
7536 : {
7537 88 : if ((settings->head &&
7538 44 : nla_put(msg, NL80211_ATTR_BEACON_HEAD,
7539 88 : settings->head_len, settings->head)) ||
7540 88 : (settings->tail &&
7541 44 : nla_put(msg, NL80211_ATTR_BEACON_TAIL,
7542 88 : settings->tail_len, settings->tail)) ||
7543 88 : (settings->beacon_ies &&
7544 44 : nla_put(msg, NL80211_ATTR_IE,
7545 88 : settings->beacon_ies_len, settings->beacon_ies)) ||
7546 88 : (settings->proberesp_ies &&
7547 44 : nla_put(msg, NL80211_ATTR_IE_PROBE_RESP,
7548 88 : settings->proberesp_ies_len, settings->proberesp_ies)) ||
7549 88 : (settings->assocresp_ies &&
7550 44 : nla_put(msg, NL80211_ATTR_IE_ASSOC_RESP,
7551 88 : settings->assocresp_ies_len, settings->assocresp_ies)) ||
7552 44 : (settings->probe_resp &&
7553 0 : nla_put(msg, NL80211_ATTR_PROBE_RESP,
7554 0 : settings->probe_resp_len, settings->probe_resp)))
7555 0 : return -ENOBUFS;
7556 :
7557 44 : return 0;
7558 : }
7559 :
7560 :
7561 23 : static int nl80211_switch_channel(void *priv, struct csa_settings *settings)
7562 : {
7563 : struct nl_msg *msg;
7564 23 : struct i802_bss *bss = priv;
7565 23 : struct wpa_driver_nl80211_data *drv = bss->drv;
7566 : struct nlattr *beacon_csa;
7567 23 : int ret = -ENOBUFS;
7568 :
7569 69 : wpa_printf(MSG_DEBUG, "nl80211: Channel switch request (cs_count=%u block_tx=%u freq=%d width=%d cf1=%d cf2=%d)",
7570 46 : settings->cs_count, settings->block_tx,
7571 : settings->freq_params.freq, settings->freq_params.bandwidth,
7572 : settings->freq_params.center_freq1,
7573 : settings->freq_params.center_freq2);
7574 :
7575 23 : if (!(drv->capa.flags & WPA_DRIVER_FLAGS_AP_CSA)) {
7576 0 : wpa_printf(MSG_DEBUG, "nl80211: Driver does not support channel switch command");
7577 0 : return -EOPNOTSUPP;
7578 : }
7579 :
7580 24 : if ((drv->nlmode != NL80211_IFTYPE_AP) &&
7581 1 : (drv->nlmode != NL80211_IFTYPE_P2P_GO))
7582 0 : return -EOPNOTSUPP;
7583 :
7584 : /* check settings validity */
7585 46 : if (!settings->beacon_csa.tail ||
7586 46 : ((settings->beacon_csa.tail_len <=
7587 46 : settings->counter_offset_beacon) ||
7588 23 : (settings->beacon_csa.tail[settings->counter_offset_beacon] !=
7589 23 : settings->cs_count)))
7590 0 : return -EINVAL;
7591 :
7592 23 : if (settings->beacon_csa.probe_resp &&
7593 0 : ((settings->beacon_csa.probe_resp_len <=
7594 0 : settings->counter_offset_presp) ||
7595 0 : (settings->beacon_csa.probe_resp[settings->counter_offset_presp] !=
7596 0 : settings->cs_count)))
7597 0 : return -EINVAL;
7598 :
7599 46 : if (!(msg = nl80211_bss_msg(bss, 0, NL80211_CMD_CHANNEL_SWITCH)) ||
7600 23 : nla_put_u32(msg, NL80211_ATTR_CH_SWITCH_COUNT,
7601 46 : settings->cs_count) ||
7602 45 : (ret = nl80211_put_freq_params(msg, &settings->freq_params)) ||
7603 25 : (settings->block_tx &&
7604 3 : nla_put_flag(msg, NL80211_ATTR_CH_SWITCH_BLOCK_TX)))
7605 : goto error;
7606 :
7607 : /* beacon_after params */
7608 22 : ret = set_beacon_data(msg, &settings->beacon_after);
7609 22 : if (ret)
7610 0 : goto error;
7611 :
7612 : /* beacon_csa params */
7613 22 : beacon_csa = nla_nest_start(msg, NL80211_ATTR_CSA_IES);
7614 22 : if (!beacon_csa)
7615 0 : goto fail;
7616 :
7617 22 : ret = set_beacon_data(msg, &settings->beacon_csa);
7618 22 : if (ret)
7619 0 : goto error;
7620 :
7621 22 : if (nla_put_u16(msg, NL80211_ATTR_CSA_C_OFF_BEACON,
7622 44 : settings->counter_offset_beacon) ||
7623 22 : (settings->beacon_csa.probe_resp &&
7624 0 : nla_put_u16(msg, NL80211_ATTR_CSA_C_OFF_PRESP,
7625 0 : settings->counter_offset_presp)))
7626 : goto fail;
7627 :
7628 22 : nla_nest_end(msg, beacon_csa);
7629 22 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
7630 22 : if (ret) {
7631 1 : wpa_printf(MSG_DEBUG, "nl80211: switch_channel failed err=%d (%s)",
7632 : ret, strerror(-ret));
7633 : }
7634 22 : return ret;
7635 :
7636 : fail:
7637 0 : ret = -ENOBUFS;
7638 : error:
7639 1 : nlmsg_free(msg);
7640 1 : wpa_printf(MSG_DEBUG, "nl80211: Could not build channel switch request");
7641 1 : return ret;
7642 : }
7643 :
7644 :
7645 0 : static int nl80211_add_ts(void *priv, u8 tsid, const u8 *addr,
7646 : u8 user_priority, u16 admitted_time)
7647 : {
7648 0 : struct i802_bss *bss = priv;
7649 0 : struct wpa_driver_nl80211_data *drv = bss->drv;
7650 : struct nl_msg *msg;
7651 : int ret;
7652 :
7653 0 : wpa_printf(MSG_DEBUG,
7654 : "nl80211: add_ts request: tsid=%u admitted_time=%u up=%d",
7655 : tsid, admitted_time, user_priority);
7656 :
7657 0 : if (!is_sta_interface(drv->nlmode))
7658 0 : return -ENOTSUP;
7659 :
7660 0 : msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_ADD_TX_TS);
7661 0 : if (!msg ||
7662 0 : nla_put_u8(msg, NL80211_ATTR_TSID, tsid) ||
7663 0 : nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
7664 0 : nla_put_u8(msg, NL80211_ATTR_USER_PRIO, user_priority) ||
7665 0 : nla_put_u16(msg, NL80211_ATTR_ADMITTED_TIME, admitted_time)) {
7666 0 : nlmsg_free(msg);
7667 0 : return -ENOBUFS;
7668 : }
7669 :
7670 0 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
7671 0 : if (ret)
7672 0 : wpa_printf(MSG_DEBUG, "nl80211: add_ts failed err=%d (%s)",
7673 : ret, strerror(-ret));
7674 0 : return ret;
7675 : }
7676 :
7677 :
7678 0 : static int nl80211_del_ts(void *priv, u8 tsid, const u8 *addr)
7679 : {
7680 0 : struct i802_bss *bss = priv;
7681 0 : struct wpa_driver_nl80211_data *drv = bss->drv;
7682 : struct nl_msg *msg;
7683 : int ret;
7684 :
7685 0 : wpa_printf(MSG_DEBUG, "nl80211: del_ts request: tsid=%u", tsid);
7686 :
7687 0 : if (!is_sta_interface(drv->nlmode))
7688 0 : return -ENOTSUP;
7689 :
7690 0 : if (!(msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_DEL_TX_TS)) ||
7691 0 : nla_put_u8(msg, NL80211_ATTR_TSID, tsid) ||
7692 0 : nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) {
7693 0 : nlmsg_free(msg);
7694 0 : return -ENOBUFS;
7695 : }
7696 :
7697 0 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
7698 0 : if (ret)
7699 0 : wpa_printf(MSG_DEBUG, "nl80211: del_ts failed err=%d (%s)",
7700 : ret, strerror(-ret));
7701 0 : return ret;
7702 : }
7703 :
7704 :
7705 : #ifdef CONFIG_TESTING_OPTIONS
7706 2 : static int cmd_reply_handler(struct nl_msg *msg, void *arg)
7707 : {
7708 2 : struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
7709 2 : struct wpabuf *buf = arg;
7710 :
7711 2 : if (!buf)
7712 0 : return NL_SKIP;
7713 :
7714 2 : if ((size_t) genlmsg_attrlen(gnlh, 0) > wpabuf_tailroom(buf)) {
7715 0 : wpa_printf(MSG_INFO, "nl80211: insufficient buffer space for reply");
7716 0 : return NL_SKIP;
7717 : }
7718 :
7719 2 : wpabuf_put_data(buf, genlmsg_attrdata(gnlh, 0),
7720 2 : genlmsg_attrlen(gnlh, 0));
7721 :
7722 2 : return NL_SKIP;
7723 : }
7724 : #endif /* CONFIG_TESTING_OPTIONS */
7725 :
7726 :
7727 0 : static int vendor_reply_handler(struct nl_msg *msg, void *arg)
7728 : {
7729 : struct nlattr *tb[NL80211_ATTR_MAX + 1];
7730 : struct nlattr *nl_vendor_reply, *nl;
7731 0 : struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
7732 0 : struct wpabuf *buf = arg;
7733 : int rem;
7734 :
7735 0 : if (!buf)
7736 0 : return NL_SKIP;
7737 :
7738 0 : nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
7739 : genlmsg_attrlen(gnlh, 0), NULL);
7740 0 : nl_vendor_reply = tb[NL80211_ATTR_VENDOR_DATA];
7741 :
7742 0 : if (!nl_vendor_reply)
7743 0 : return NL_SKIP;
7744 :
7745 0 : if ((size_t) nla_len(nl_vendor_reply) > wpabuf_tailroom(buf)) {
7746 0 : wpa_printf(MSG_INFO, "nl80211: Vendor command: insufficient buffer space for reply");
7747 0 : return NL_SKIP;
7748 : }
7749 :
7750 0 : nla_for_each_nested(nl, nl_vendor_reply, rem) {
7751 0 : wpabuf_put_data(buf, nla_data(nl), nla_len(nl));
7752 : }
7753 :
7754 0 : return NL_SKIP;
7755 : }
7756 :
7757 :
7758 5 : static int nl80211_vendor_cmd(void *priv, unsigned int vendor_id,
7759 : unsigned int subcmd, const u8 *data,
7760 : size_t data_len, struct wpabuf *buf)
7761 : {
7762 5 : struct i802_bss *bss = priv;
7763 5 : struct wpa_driver_nl80211_data *drv = bss->drv;
7764 : struct nl_msg *msg;
7765 : int ret;
7766 :
7767 : #ifdef CONFIG_TESTING_OPTIONS
7768 5 : if (vendor_id == 0xffffffff) {
7769 5 : msg = nlmsg_alloc();
7770 5 : if (!msg)
7771 0 : return -ENOMEM;
7772 :
7773 5 : nl80211_cmd(drv, msg, 0, subcmd);
7774 5 : if (nlmsg_append(msg, (void *) data, data_len, NLMSG_ALIGNTO) <
7775 : 0)
7776 0 : goto fail;
7777 5 : ret = send_and_recv_msgs(drv, msg, cmd_reply_handler, buf);
7778 5 : if (ret)
7779 0 : wpa_printf(MSG_DEBUG, "nl80211: command failed err=%d",
7780 : ret);
7781 5 : return ret;
7782 : }
7783 : #endif /* CONFIG_TESTING_OPTIONS */
7784 :
7785 0 : if (!(msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_VENDOR)) ||
7786 0 : nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, vendor_id) ||
7787 0 : nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, subcmd) ||
7788 0 : (data &&
7789 0 : nla_put(msg, NL80211_ATTR_VENDOR_DATA, data_len, data)))
7790 : goto fail;
7791 :
7792 0 : ret = send_and_recv_msgs(drv, msg, vendor_reply_handler, buf);
7793 0 : if (ret)
7794 0 : wpa_printf(MSG_DEBUG, "nl80211: vendor command failed err=%d",
7795 : ret);
7796 0 : return ret;
7797 :
7798 : fail:
7799 0 : nlmsg_free(msg);
7800 0 : return -ENOBUFS;
7801 : }
7802 :
7803 :
7804 5 : static int nl80211_set_qos_map(void *priv, const u8 *qos_map_set,
7805 : u8 qos_map_set_len)
7806 : {
7807 5 : struct i802_bss *bss = priv;
7808 5 : struct wpa_driver_nl80211_data *drv = bss->drv;
7809 : struct nl_msg *msg;
7810 : int ret;
7811 :
7812 5 : wpa_hexdump(MSG_DEBUG, "nl80211: Setting QoS Map",
7813 : qos_map_set, qos_map_set_len);
7814 :
7815 10 : if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_SET_QOS_MAP)) ||
7816 5 : nla_put(msg, NL80211_ATTR_QOS_MAP, qos_map_set_len, qos_map_set)) {
7817 0 : nlmsg_free(msg);
7818 0 : return -ENOBUFS;
7819 : }
7820 :
7821 5 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
7822 5 : if (ret)
7823 0 : wpa_printf(MSG_DEBUG, "nl80211: Setting QoS Map failed");
7824 :
7825 5 : return ret;
7826 : }
7827 :
7828 :
7829 0 : static int nl80211_set_wowlan(void *priv,
7830 : const struct wowlan_triggers *triggers)
7831 : {
7832 0 : struct i802_bss *bss = priv;
7833 0 : struct wpa_driver_nl80211_data *drv = bss->drv;
7834 : struct nl_msg *msg;
7835 : struct nlattr *wowlan_triggers;
7836 : int ret;
7837 :
7838 0 : wpa_printf(MSG_DEBUG, "nl80211: Setting wowlan");
7839 :
7840 0 : if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_SET_WOWLAN)) ||
7841 : !(wowlan_triggers = nla_nest_start(msg,
7842 0 : NL80211_ATTR_WOWLAN_TRIGGERS)) ||
7843 0 : (triggers->any &&
7844 0 : nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) ||
7845 0 : (triggers->disconnect &&
7846 0 : nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) ||
7847 0 : (triggers->magic_pkt &&
7848 0 : nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) ||
7849 0 : (triggers->gtk_rekey_failure &&
7850 0 : nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) ||
7851 0 : (triggers->eap_identity_req &&
7852 0 : nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) ||
7853 0 : (triggers->four_way_handshake &&
7854 0 : nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) ||
7855 0 : (triggers->rfkill_release &&
7856 0 : nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE))) {
7857 0 : nlmsg_free(msg);
7858 0 : return -ENOBUFS;
7859 : }
7860 :
7861 0 : nla_nest_end(msg, wowlan_triggers);
7862 :
7863 0 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
7864 0 : if (ret)
7865 0 : wpa_printf(MSG_DEBUG, "nl80211: Setting wowlan failed");
7866 :
7867 0 : return ret;
7868 : }
7869 :
7870 :
7871 3 : static int nl80211_roaming(void *priv, int allowed, const u8 *bssid)
7872 : {
7873 3 : struct i802_bss *bss = priv;
7874 3 : struct wpa_driver_nl80211_data *drv = bss->drv;
7875 : struct nl_msg *msg;
7876 : struct nlattr *params;
7877 :
7878 3 : wpa_printf(MSG_DEBUG, "nl80211: Roaming policy: allowed=%d", allowed);
7879 :
7880 3 : if (!drv->roaming_vendor_cmd_avail) {
7881 3 : wpa_printf(MSG_DEBUG,
7882 : "nl80211: Ignore roaming policy change since driver does not provide command for setting it");
7883 3 : return -1;
7884 : }
7885 :
7886 0 : if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
7887 0 : nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7888 0 : nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7889 0 : QCA_NL80211_VENDOR_SUBCMD_ROAMING) ||
7890 0 : !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7891 0 : nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY,
7892 : allowed ? QCA_ROAMING_ALLOWED_WITHIN_ESS :
7893 0 : QCA_ROAMING_NOT_ALLOWED) ||
7894 0 : (bssid &&
7895 0 : nla_put(msg, QCA_WLAN_VENDOR_ATTR_MAC_ADDR, ETH_ALEN, bssid))) {
7896 0 : nlmsg_free(msg);
7897 0 : return -1;
7898 : }
7899 0 : nla_nest_end(msg, params);
7900 :
7901 0 : return send_and_recv_msgs(drv, msg, NULL, NULL);
7902 : }
7903 :
7904 :
7905 11 : static int nl80211_set_mac_addr(void *priv, const u8 *addr)
7906 : {
7907 11 : struct i802_bss *bss = priv;
7908 11 : struct wpa_driver_nl80211_data *drv = bss->drv;
7909 11 : int new_addr = addr != NULL;
7910 :
7911 11 : if (!addr)
7912 2 : addr = drv->perm_addr;
7913 :
7914 11 : if (linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 0) < 0)
7915 0 : return -1;
7916 :
7917 11 : if (linux_set_ifhwaddr(drv->global->ioctl_sock, bss->ifname, addr) < 0)
7918 : {
7919 0 : wpa_printf(MSG_DEBUG,
7920 : "nl80211: failed to set_mac_addr for %s to " MACSTR,
7921 0 : bss->ifname, MAC2STR(addr));
7922 0 : if (linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname,
7923 : 1) < 0) {
7924 0 : wpa_printf(MSG_DEBUG,
7925 : "nl80211: Could not restore interface UP after failed set_mac_addr");
7926 : }
7927 0 : return -1;
7928 : }
7929 :
7930 77 : wpa_printf(MSG_DEBUG, "nl80211: set_mac_addr for %s to " MACSTR,
7931 77 : bss->ifname, MAC2STR(addr));
7932 11 : drv->addr_changed = new_addr;
7933 11 : os_memcpy(bss->addr, addr, ETH_ALEN);
7934 :
7935 11 : if (linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 1) < 0)
7936 : {
7937 0 : wpa_printf(MSG_DEBUG,
7938 : "nl80211: Could not restore interface UP after set_mac_addr");
7939 : }
7940 :
7941 11 : return 0;
7942 : }
7943 :
7944 :
7945 : #ifdef CONFIG_MESH
7946 :
7947 34 : static int wpa_driver_nl80211_init_mesh(void *priv)
7948 : {
7949 34 : if (wpa_driver_nl80211_set_mode(priv, NL80211_IFTYPE_MESH_POINT)) {
7950 0 : wpa_printf(MSG_INFO,
7951 : "nl80211: Failed to set interface into mesh mode");
7952 0 : return -1;
7953 : }
7954 34 : return 0;
7955 : }
7956 :
7957 :
7958 33 : static int nl80211_put_mesh_id(struct nl_msg *msg, const u8 *mesh_id,
7959 : size_t mesh_id_len)
7960 : {
7961 33 : if (mesh_id) {
7962 33 : wpa_hexdump_ascii(MSG_DEBUG, " * Mesh ID (SSID)",
7963 : mesh_id, mesh_id_len);
7964 33 : return nla_put(msg, NL80211_ATTR_MESH_ID, mesh_id_len, mesh_id);
7965 : }
7966 :
7967 0 : return 0;
7968 : }
7969 :
7970 :
7971 33 : static int nl80211_join_mesh(struct i802_bss *bss,
7972 : struct wpa_driver_mesh_join_params *params)
7973 : {
7974 33 : struct wpa_driver_nl80211_data *drv = bss->drv;
7975 : struct nl_msg *msg;
7976 : struct nlattr *container;
7977 33 : int ret = -1;
7978 :
7979 33 : wpa_printf(MSG_DEBUG, "nl80211: mesh join (ifindex=%d)", drv->ifindex);
7980 33 : msg = nl80211_drv_msg(drv, 0, NL80211_CMD_JOIN_MESH);
7981 66 : if (!msg ||
7982 66 : nl80211_put_freq_params(msg, ¶ms->freq) ||
7983 66 : nl80211_put_basic_rates(msg, params->basic_rates) ||
7984 66 : nl80211_put_mesh_id(msg, params->meshid, params->meshid_len) ||
7985 33 : nl80211_put_beacon_int(msg, params->beacon_int))
7986 : goto fail;
7987 :
7988 33 : wpa_printf(MSG_DEBUG, " * flags=%08X", params->flags);
7989 :
7990 33 : container = nla_nest_start(msg, NL80211_ATTR_MESH_SETUP);
7991 33 : if (!container)
7992 0 : goto fail;
7993 :
7994 33 : if (params->ies) {
7995 12 : wpa_hexdump(MSG_DEBUG, " * IEs", params->ies, params->ie_len);
7996 12 : if (nla_put(msg, NL80211_MESH_SETUP_IE, params->ie_len,
7997 12 : params->ies))
7998 0 : goto fail;
7999 : }
8000 : /* WPA_DRIVER_MESH_FLAG_OPEN_AUTH is treated as default by nl80211 */
8001 33 : if (params->flags & WPA_DRIVER_MESH_FLAG_SAE_AUTH) {
8002 24 : if (nla_put_u8(msg, NL80211_MESH_SETUP_AUTH_PROTOCOL, 0x1) ||
8003 12 : nla_put_flag(msg, NL80211_MESH_SETUP_USERSPACE_AUTH))
8004 : goto fail;
8005 : }
8006 45 : if ((params->flags & WPA_DRIVER_MESH_FLAG_AMPE) &&
8007 12 : nla_put_flag(msg, NL80211_MESH_SETUP_USERSPACE_AMPE))
8008 0 : goto fail;
8009 66 : if ((params->flags & WPA_DRIVER_MESH_FLAG_USER_MPM) &&
8010 33 : nla_put_flag(msg, NL80211_MESH_SETUP_USERSPACE_MPM))
8011 0 : goto fail;
8012 33 : nla_nest_end(msg, container);
8013 :
8014 33 : container = nla_nest_start(msg, NL80211_ATTR_MESH_CONFIG);
8015 33 : if (!container)
8016 0 : goto fail;
8017 :
8018 66 : if (!(params->conf.flags & WPA_DRIVER_MESH_CONF_FLAG_AUTO_PLINKS) &&
8019 33 : nla_put_u32(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS, 0))
8020 0 : goto fail;
8021 33 : if ((params->conf.flags & WPA_DRIVER_MESH_FLAG_DRIVER_MPM) &&
8022 0 : nla_put_u16(msg, NL80211_MESHCONF_MAX_PEER_LINKS,
8023 0 : params->max_peer_links))
8024 0 : goto fail;
8025 :
8026 : /*
8027 : * Set NL80211_MESHCONF_PLINK_TIMEOUT even if user mpm is used because
8028 : * the timer could disconnect stations even in that case.
8029 : */
8030 33 : if (nla_put_u32(msg, NL80211_MESHCONF_PLINK_TIMEOUT,
8031 33 : params->conf.peer_link_timeout)) {
8032 0 : wpa_printf(MSG_ERROR, "nl80211: Failed to set PLINK_TIMEOUT");
8033 0 : goto fail;
8034 : }
8035 :
8036 33 : nla_nest_end(msg, container);
8037 :
8038 33 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
8039 33 : msg = NULL;
8040 33 : if (ret) {
8041 0 : wpa_printf(MSG_DEBUG, "nl80211: mesh join failed: ret=%d (%s)",
8042 : ret, strerror(-ret));
8043 0 : goto fail;
8044 : }
8045 33 : ret = 0;
8046 33 : bss->freq = params->freq.freq;
8047 33 : wpa_printf(MSG_DEBUG, "nl80211: mesh join request send successfully");
8048 :
8049 : fail:
8050 33 : nlmsg_free(msg);
8051 33 : return ret;
8052 : }
8053 :
8054 :
8055 : static int
8056 33 : wpa_driver_nl80211_join_mesh(void *priv,
8057 : struct wpa_driver_mesh_join_params *params)
8058 : {
8059 33 : struct i802_bss *bss = priv;
8060 : int ret, timeout;
8061 :
8062 33 : timeout = params->conf.peer_link_timeout;
8063 :
8064 : /* Disable kernel inactivity timer */
8065 33 : if (params->flags & WPA_DRIVER_MESH_FLAG_USER_MPM)
8066 33 : params->conf.peer_link_timeout = 0;
8067 :
8068 33 : ret = nl80211_join_mesh(bss, params);
8069 33 : if (ret == -EINVAL && params->conf.peer_link_timeout == 0) {
8070 0 : wpa_printf(MSG_DEBUG,
8071 : "nl80211: Mesh join retry for peer_link_timeout");
8072 : /*
8073 : * Old kernel does not support setting
8074 : * NL80211_MESHCONF_PLINK_TIMEOUT to zero, so set 60 seconds
8075 : * into future from peer_link_timeout.
8076 : */
8077 0 : params->conf.peer_link_timeout = timeout + 60;
8078 0 : ret = nl80211_join_mesh(priv, params);
8079 : }
8080 :
8081 33 : params->conf.peer_link_timeout = timeout;
8082 33 : return ret;
8083 : }
8084 :
8085 :
8086 34 : static int wpa_driver_nl80211_leave_mesh(void *priv)
8087 : {
8088 34 : struct i802_bss *bss = priv;
8089 34 : struct wpa_driver_nl80211_data *drv = bss->drv;
8090 : struct nl_msg *msg;
8091 : int ret;
8092 :
8093 34 : wpa_printf(MSG_DEBUG, "nl80211: mesh leave (ifindex=%d)", drv->ifindex);
8094 34 : msg = nl80211_drv_msg(drv, 0, NL80211_CMD_LEAVE_MESH);
8095 34 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
8096 34 : if (ret) {
8097 1 : wpa_printf(MSG_DEBUG, "nl80211: mesh leave failed: ret=%d (%s)",
8098 : ret, strerror(-ret));
8099 : } else {
8100 33 : wpa_printf(MSG_DEBUG,
8101 : "nl80211: mesh leave request send successfully");
8102 : }
8103 :
8104 34 : if (wpa_driver_nl80211_set_mode(drv->first_bss,
8105 : NL80211_IFTYPE_STATION)) {
8106 0 : wpa_printf(MSG_INFO,
8107 : "nl80211: Failed to set interface into station mode");
8108 : }
8109 34 : return ret;
8110 : }
8111 :
8112 : #endif /* CONFIG_MESH */
8113 :
8114 :
8115 17 : static int wpa_driver_br_add_ip_neigh(void *priv, u8 version,
8116 : const u8 *ipaddr, int prefixlen,
8117 : const u8 *addr)
8118 : {
8119 : #ifdef CONFIG_LIBNL3_ROUTE
8120 17 : struct i802_bss *bss = priv;
8121 17 : struct wpa_driver_nl80211_data *drv = bss->drv;
8122 : struct rtnl_neigh *rn;
8123 17 : struct nl_addr *nl_ipaddr = NULL;
8124 17 : struct nl_addr *nl_lladdr = NULL;
8125 : int family, addrsize;
8126 : int res;
8127 :
8128 17 : if (!ipaddr || prefixlen == 0 || !addr)
8129 0 : return -EINVAL;
8130 :
8131 17 : if (bss->br_ifindex == 0) {
8132 0 : wpa_printf(MSG_DEBUG,
8133 : "nl80211: bridge must be set before adding an ip neigh to it");
8134 0 : return -1;
8135 : }
8136 :
8137 17 : if (!drv->rtnl_sk) {
8138 0 : wpa_printf(MSG_DEBUG,
8139 : "nl80211: nl_sock for NETLINK_ROUTE is not initialized");
8140 0 : return -1;
8141 : }
8142 :
8143 17 : if (version == 4) {
8144 6 : family = AF_INET;
8145 6 : addrsize = 4;
8146 11 : } else if (version == 6) {
8147 11 : family = AF_INET6;
8148 11 : addrsize = 16;
8149 : } else {
8150 0 : return -EINVAL;
8151 : }
8152 :
8153 17 : rn = rtnl_neigh_alloc();
8154 17 : if (rn == NULL)
8155 0 : return -ENOMEM;
8156 :
8157 : /* set the destination ip address for neigh */
8158 17 : nl_ipaddr = nl_addr_build(family, (void *) ipaddr, addrsize);
8159 17 : if (nl_ipaddr == NULL) {
8160 0 : wpa_printf(MSG_DEBUG, "nl80211: nl_ipaddr build failed");
8161 0 : res = -ENOMEM;
8162 0 : goto errout;
8163 : }
8164 17 : nl_addr_set_prefixlen(nl_ipaddr, prefixlen);
8165 17 : res = rtnl_neigh_set_dst(rn, nl_ipaddr);
8166 17 : if (res) {
8167 0 : wpa_printf(MSG_DEBUG,
8168 : "nl80211: neigh set destination addr failed");
8169 0 : goto errout;
8170 : }
8171 :
8172 : /* set the corresponding lladdr for neigh */
8173 17 : nl_lladdr = nl_addr_build(AF_BRIDGE, (u8 *) addr, ETH_ALEN);
8174 17 : if (nl_lladdr == NULL) {
8175 0 : wpa_printf(MSG_DEBUG, "nl80211: neigh set lladdr failed");
8176 0 : res = -ENOMEM;
8177 0 : goto errout;
8178 : }
8179 17 : rtnl_neigh_set_lladdr(rn, nl_lladdr);
8180 :
8181 17 : rtnl_neigh_set_ifindex(rn, bss->br_ifindex);
8182 17 : rtnl_neigh_set_state(rn, NUD_PERMANENT);
8183 :
8184 17 : res = rtnl_neigh_add(drv->rtnl_sk, rn, NLM_F_CREATE);
8185 17 : if (res) {
8186 0 : wpa_printf(MSG_DEBUG,
8187 : "nl80211: Adding bridge ip neigh failed: %s",
8188 0 : strerror(errno));
8189 : }
8190 : errout:
8191 17 : if (nl_lladdr)
8192 17 : nl_addr_put(nl_lladdr);
8193 17 : if (nl_ipaddr)
8194 17 : nl_addr_put(nl_ipaddr);
8195 17 : if (rn)
8196 17 : rtnl_neigh_put(rn);
8197 17 : return res;
8198 : #else /* CONFIG_LIBNL3_ROUTE */
8199 0 : return -1;
8200 : #endif /* CONFIG_LIBNL3_ROUTE */
8201 : }
8202 :
8203 :
8204 28 : static int wpa_driver_br_delete_ip_neigh(void *priv, u8 version,
8205 : const u8 *ipaddr)
8206 : {
8207 : #ifdef CONFIG_LIBNL3_ROUTE
8208 28 : struct i802_bss *bss = priv;
8209 28 : struct wpa_driver_nl80211_data *drv = bss->drv;
8210 : struct rtnl_neigh *rn;
8211 : struct nl_addr *nl_ipaddr;
8212 : int family, addrsize;
8213 : int res;
8214 :
8215 28 : if (!ipaddr)
8216 0 : return -EINVAL;
8217 :
8218 28 : if (version == 4) {
8219 6 : family = AF_INET;
8220 6 : addrsize = 4;
8221 22 : } else if (version == 6) {
8222 22 : family = AF_INET6;
8223 22 : addrsize = 16;
8224 : } else {
8225 0 : return -EINVAL;
8226 : }
8227 :
8228 28 : if (bss->br_ifindex == 0) {
8229 0 : wpa_printf(MSG_DEBUG,
8230 : "nl80211: bridge must be set to delete an ip neigh");
8231 0 : return -1;
8232 : }
8233 :
8234 28 : if (!drv->rtnl_sk) {
8235 0 : wpa_printf(MSG_DEBUG,
8236 : "nl80211: nl_sock for NETLINK_ROUTE is not initialized");
8237 0 : return -1;
8238 : }
8239 :
8240 28 : rn = rtnl_neigh_alloc();
8241 28 : if (rn == NULL)
8242 0 : return -ENOMEM;
8243 :
8244 : /* set the destination ip address for neigh */
8245 28 : nl_ipaddr = nl_addr_build(family, (void *) ipaddr, addrsize);
8246 28 : if (nl_ipaddr == NULL) {
8247 0 : wpa_printf(MSG_DEBUG, "nl80211: nl_ipaddr build failed");
8248 0 : res = -ENOMEM;
8249 0 : goto errout;
8250 : }
8251 28 : res = rtnl_neigh_set_dst(rn, nl_ipaddr);
8252 28 : if (res) {
8253 0 : wpa_printf(MSG_DEBUG,
8254 : "nl80211: neigh set destination addr failed");
8255 0 : goto errout;
8256 : }
8257 :
8258 28 : rtnl_neigh_set_ifindex(rn, bss->br_ifindex);
8259 :
8260 28 : res = rtnl_neigh_delete(drv->rtnl_sk, rn, 0);
8261 28 : if (res) {
8262 11 : wpa_printf(MSG_DEBUG,
8263 : "nl80211: Deleting bridge ip neigh failed: %s",
8264 11 : strerror(errno));
8265 : }
8266 : errout:
8267 28 : if (nl_ipaddr)
8268 28 : nl_addr_put(nl_ipaddr);
8269 28 : if (rn)
8270 28 : rtnl_neigh_put(rn);
8271 28 : return res;
8272 : #else /* CONFIG_LIBNL3_ROUTE */
8273 0 : return -1;
8274 : #endif /* CONFIG_LIBNL3_ROUTE */
8275 : }
8276 :
8277 :
8278 2988 : static int linux_write_system_file(const char *path, unsigned int val)
8279 : {
8280 : char buf[50];
8281 : int fd, len;
8282 :
8283 2988 : len = os_snprintf(buf, sizeof(buf), "%u\n", val);
8284 2988 : if (os_snprintf_error(sizeof(buf), len))
8285 0 : return -1;
8286 :
8287 2988 : fd = open(path, O_WRONLY);
8288 2988 : if (fd < 0)
8289 2970 : return -1;
8290 :
8291 18 : if (write(fd, buf, len) < 0) {
8292 0 : wpa_printf(MSG_DEBUG,
8293 : "nl80211: Failed to write Linux system file: %s with the value of %d",
8294 : path, val);
8295 0 : close(fd);
8296 0 : return -1;
8297 : }
8298 18 : close(fd);
8299 :
8300 18 : return 0;
8301 : }
8302 :
8303 :
8304 1992 : static const char * drv_br_port_attr_str(enum drv_br_port_attr attr)
8305 : {
8306 1992 : switch (attr) {
8307 : case DRV_BR_PORT_ATTR_PROXYARP:
8308 996 : return "proxyarp_wifi";
8309 : case DRV_BR_PORT_ATTR_HAIRPIN_MODE:
8310 996 : return "hairpin_mode";
8311 : }
8312 :
8313 0 : return NULL;
8314 : }
8315 :
8316 :
8317 1992 : static int wpa_driver_br_port_set_attr(void *priv, enum drv_br_port_attr attr,
8318 : unsigned int val)
8319 : {
8320 1992 : struct i802_bss *bss = priv;
8321 : char path[128];
8322 : const char *attr_txt;
8323 :
8324 1992 : attr_txt = drv_br_port_attr_str(attr);
8325 1992 : if (attr_txt == NULL)
8326 0 : return -EINVAL;
8327 :
8328 1992 : os_snprintf(path, sizeof(path), "/sys/class/net/%s/brport/%s",
8329 1992 : bss->ifname, attr_txt);
8330 :
8331 1992 : if (linux_write_system_file(path, val))
8332 1980 : return -1;
8333 :
8334 12 : return 0;
8335 : }
8336 :
8337 :
8338 996 : static const char * drv_br_net_param_str(enum drv_br_net_param param)
8339 : {
8340 996 : switch (param) {
8341 : case DRV_BR_NET_PARAM_GARP_ACCEPT:
8342 996 : return "arp_accept";
8343 : }
8344 :
8345 0 : return NULL;
8346 : }
8347 :
8348 :
8349 996 : static int wpa_driver_br_set_net_param(void *priv, enum drv_br_net_param param,
8350 : unsigned int val)
8351 : {
8352 996 : struct i802_bss *bss = priv;
8353 : char path[128];
8354 : const char *param_txt;
8355 996 : int ip_version = 4;
8356 :
8357 996 : param_txt = drv_br_net_param_str(param);
8358 996 : if (param_txt == NULL)
8359 0 : return -EINVAL;
8360 :
8361 996 : switch (param) {
8362 : case DRV_BR_NET_PARAM_GARP_ACCEPT:
8363 996 : ip_version = 4;
8364 996 : break;
8365 : default:
8366 0 : return -EINVAL;
8367 : }
8368 :
8369 996 : os_snprintf(path, sizeof(path), "/proc/sys/net/ipv%d/conf/%s/%s",
8370 996 : ip_version, bss->brname, param_txt);
8371 :
8372 996 : if (linux_write_system_file(path, val))
8373 990 : return -1;
8374 :
8375 6 : return 0;
8376 : }
8377 :
8378 :
8379 0 : static int hw_mode_to_qca_acs(enum hostapd_hw_mode hw_mode)
8380 : {
8381 0 : switch (hw_mode) {
8382 : case HOSTAPD_MODE_IEEE80211B:
8383 0 : return QCA_ACS_MODE_IEEE80211B;
8384 : case HOSTAPD_MODE_IEEE80211G:
8385 0 : return QCA_ACS_MODE_IEEE80211G;
8386 : case HOSTAPD_MODE_IEEE80211A:
8387 0 : return QCA_ACS_MODE_IEEE80211A;
8388 : case HOSTAPD_MODE_IEEE80211AD:
8389 0 : return QCA_ACS_MODE_IEEE80211AD;
8390 : default:
8391 0 : return -1;
8392 : }
8393 : }
8394 :
8395 :
8396 0 : static int wpa_driver_do_acs(void *priv, struct drv_acs_params *params)
8397 : {
8398 0 : struct i802_bss *bss = priv;
8399 0 : struct wpa_driver_nl80211_data *drv = bss->drv;
8400 : struct nl_msg *msg;
8401 : struct nlattr *data;
8402 : int ret;
8403 : int mode;
8404 :
8405 0 : mode = hw_mode_to_qca_acs(params->hw_mode);
8406 0 : if (mode < 0)
8407 0 : return -1;
8408 :
8409 0 : if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
8410 0 : nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8411 0 : nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8412 0 : QCA_NL80211_VENDOR_SUBCMD_DO_ACS) ||
8413 0 : !(data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8414 0 : nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE, mode) ||
8415 0 : (params->ht_enabled &&
8416 0 : nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_ACS_HT_ENABLED)) ||
8417 0 : (params->ht40_enabled &&
8418 0 : nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_ACS_HT40_ENABLED))) {
8419 0 : nlmsg_free(msg);
8420 0 : return -ENOBUFS;
8421 : }
8422 0 : nla_nest_end(msg, data);
8423 :
8424 0 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
8425 0 : if (ret) {
8426 0 : wpa_printf(MSG_DEBUG,
8427 : "nl80211: Failed to invoke driver ACS function: %s",
8428 0 : strerror(errno));
8429 : }
8430 0 : return ret;
8431 : }
8432 :
8433 :
8434 : const struct wpa_driver_ops wpa_driver_nl80211_ops = {
8435 : .name = "nl80211",
8436 : .desc = "Linux nl80211/cfg80211",
8437 : .get_bssid = wpa_driver_nl80211_get_bssid,
8438 : .get_ssid = wpa_driver_nl80211_get_ssid,
8439 : .set_key = driver_nl80211_set_key,
8440 : .scan2 = driver_nl80211_scan2,
8441 : .sched_scan = wpa_driver_nl80211_sched_scan,
8442 : .stop_sched_scan = wpa_driver_nl80211_stop_sched_scan,
8443 : .get_scan_results2 = wpa_driver_nl80211_get_scan_results,
8444 : .deauthenticate = driver_nl80211_deauthenticate,
8445 : .authenticate = driver_nl80211_authenticate,
8446 : .associate = wpa_driver_nl80211_associate,
8447 : .global_init = nl80211_global_init,
8448 : .global_deinit = nl80211_global_deinit,
8449 : .init2 = wpa_driver_nl80211_init,
8450 : .deinit = driver_nl80211_deinit,
8451 : .get_capa = wpa_driver_nl80211_get_capa,
8452 : .set_operstate = wpa_driver_nl80211_set_operstate,
8453 : .set_supp_port = wpa_driver_nl80211_set_supp_port,
8454 : .set_country = wpa_driver_nl80211_set_country,
8455 : .get_country = wpa_driver_nl80211_get_country,
8456 : .set_ap = wpa_driver_nl80211_set_ap,
8457 : .set_acl = wpa_driver_nl80211_set_acl,
8458 : .if_add = wpa_driver_nl80211_if_add,
8459 : .if_remove = driver_nl80211_if_remove,
8460 : .send_mlme = driver_nl80211_send_mlme,
8461 : .get_hw_feature_data = nl80211_get_hw_feature_data,
8462 : .sta_add = wpa_driver_nl80211_sta_add,
8463 : .sta_remove = driver_nl80211_sta_remove,
8464 : .hapd_send_eapol = wpa_driver_nl80211_hapd_send_eapol,
8465 : .sta_set_flags = wpa_driver_nl80211_sta_set_flags,
8466 : .hapd_init = i802_init,
8467 : .hapd_deinit = i802_deinit,
8468 : .set_wds_sta = i802_set_wds_sta,
8469 : .get_seqnum = i802_get_seqnum,
8470 : .flush = i802_flush,
8471 : .get_inact_sec = i802_get_inact_sec,
8472 : .sta_clear_stats = i802_sta_clear_stats,
8473 : .set_rts = i802_set_rts,
8474 : .set_frag = i802_set_frag,
8475 : .set_tx_queue_params = i802_set_tx_queue_params,
8476 : .set_sta_vlan = driver_nl80211_set_sta_vlan,
8477 : .sta_deauth = i802_sta_deauth,
8478 : .sta_disassoc = i802_sta_disassoc,
8479 : .read_sta_data = driver_nl80211_read_sta_data,
8480 : .set_freq = i802_set_freq,
8481 : .send_action = driver_nl80211_send_action,
8482 : .send_action_cancel_wait = wpa_driver_nl80211_send_action_cancel_wait,
8483 : .remain_on_channel = wpa_driver_nl80211_remain_on_channel,
8484 : .cancel_remain_on_channel =
8485 : wpa_driver_nl80211_cancel_remain_on_channel,
8486 : .probe_req_report = driver_nl80211_probe_req_report,
8487 : .deinit_ap = wpa_driver_nl80211_deinit_ap,
8488 : .deinit_p2p_cli = wpa_driver_nl80211_deinit_p2p_cli,
8489 : .resume = wpa_driver_nl80211_resume,
8490 : .signal_monitor = nl80211_signal_monitor,
8491 : .signal_poll = nl80211_signal_poll,
8492 : .send_frame = nl80211_send_frame,
8493 : .shared_freq = wpa_driver_nl80211_shared_freq,
8494 : .set_param = nl80211_set_param,
8495 : .get_radio_name = nl80211_get_radio_name,
8496 : .add_pmkid = nl80211_add_pmkid,
8497 : .remove_pmkid = nl80211_remove_pmkid,
8498 : .flush_pmkid = nl80211_flush_pmkid,
8499 : .set_rekey_info = nl80211_set_rekey_info,
8500 : .poll_client = nl80211_poll_client,
8501 : .set_p2p_powersave = nl80211_set_p2p_powersave,
8502 : .start_dfs_cac = nl80211_start_radar_detection,
8503 : .stop_ap = wpa_driver_nl80211_stop_ap,
8504 : #ifdef CONFIG_TDLS
8505 : .send_tdls_mgmt = nl80211_send_tdls_mgmt,
8506 : .tdls_oper = nl80211_tdls_oper,
8507 : .tdls_enable_channel_switch = nl80211_tdls_enable_channel_switch,
8508 : .tdls_disable_channel_switch = nl80211_tdls_disable_channel_switch,
8509 : #endif /* CONFIG_TDLS */
8510 : .update_ft_ies = wpa_driver_nl80211_update_ft_ies,
8511 : .get_mac_addr = wpa_driver_nl80211_get_macaddr,
8512 : .get_survey = wpa_driver_nl80211_get_survey,
8513 : .status = wpa_driver_nl80211_status,
8514 : .switch_channel = nl80211_switch_channel,
8515 : #ifdef ANDROID_P2P
8516 : .set_noa = wpa_driver_set_p2p_noa,
8517 : .get_noa = wpa_driver_get_p2p_noa,
8518 : .set_ap_wps_ie = wpa_driver_set_ap_wps_p2p_ie,
8519 : #endif /* ANDROID_P2P */
8520 : #ifdef ANDROID
8521 : .driver_cmd = wpa_driver_nl80211_driver_cmd,
8522 : #endif /* ANDROID */
8523 : .vendor_cmd = nl80211_vendor_cmd,
8524 : .set_qos_map = nl80211_set_qos_map,
8525 : .set_wowlan = nl80211_set_wowlan,
8526 : .roaming = nl80211_roaming,
8527 : .set_mac_addr = nl80211_set_mac_addr,
8528 : #ifdef CONFIG_MESH
8529 : .init_mesh = wpa_driver_nl80211_init_mesh,
8530 : .join_mesh = wpa_driver_nl80211_join_mesh,
8531 : .leave_mesh = wpa_driver_nl80211_leave_mesh,
8532 : #endif /* CONFIG_MESH */
8533 : .br_add_ip_neigh = wpa_driver_br_add_ip_neigh,
8534 : .br_delete_ip_neigh = wpa_driver_br_delete_ip_neigh,
8535 : .br_port_set_attr = wpa_driver_br_port_set_attr,
8536 : .br_set_net_param = wpa_driver_br_set_net_param,
8537 : .add_tx_ts = nl80211_add_ts,
8538 : .del_tx_ts = nl80211_del_ts,
8539 : .do_acs = wpa_driver_do_acs,
8540 : };
|