Disconnect hostapd from building in base
[dragonfly.git] / contrib / hostapd / src / drivers / driver_nl80211.c
CommitLineData
a875087d 1/*
4781064b
JM
2 * Driver interaction with Linux nl80211/cfg80211
3 * Copyright (c) 2002-2014, 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
a875087d 8 *
4781064b
JM
9 * This software may be distributed under the terms of the BSD license.
10 * See README for more details.
a875087d
JL
11 */
12
13#include "includes.h"
14#include <sys/ioctl.h>
4781064b
JM
15#include <sys/types.h>
16#include <sys/stat.h>
17#include <fcntl.h>
18#include <net/if.h>
a875087d
JL
19#include <netlink/genl/genl.h>
20#include <netlink/genl/family.h>
21#include <netlink/genl/ctrl.h>
4781064b 22#include <linux/rtnetlink.h>
a875087d 23#include <netpacket/packet.h>
4781064b
JM
24#include <linux/filter.h>
25#include <linux/errqueue.h>
26#include "nl80211_copy.h"
a875087d 27
a875087d 28#include "common.h"
a875087d 29#include "eloop.h"
4781064b
JM
30#include "utils/list.h"
31#include "common/qca-vendor.h"
32#include "common/ieee802_11_defs.h"
33#include "common/ieee802_11_common.h"
34#include "l2_packet/l2_packet.h"
35#include "netlink.h"
36#include "linux_ioctl.h"
37#include "radiotap.h"
38#include "radiotap_iter.h"
39#include "rfkill.h"
40#include "driver.h"
41
42#ifndef SO_WIFI_STATUS
43# if defined(__sparc__)
44# define SO_WIFI_STATUS 0x0025
45# elif defined(__parisc__)
46# define SO_WIFI_STATUS 0x4022
47# else
48# define SO_WIFI_STATUS 41
49# endif
50
51# define SCM_WIFI_STATUS SO_WIFI_STATUS
52#endif
53
54#ifndef SO_EE_ORIGIN_TXSTATUS
55#define SO_EE_ORIGIN_TXSTATUS 4
56#endif
57
58#ifndef PACKET_TX_TIMESTAMP
59#define PACKET_TX_TIMESTAMP 16
60#endif
61
62#ifdef ANDROID
63#include "android_drv.h"
64#endif /* ANDROID */
65#ifdef CONFIG_LIBNL20
66/* libnl 2.0 compatibility code */
67#define nl_handle nl_sock
68#define nl80211_handle_alloc nl_socket_alloc_cb
69#define nl80211_handle_destroy nl_socket_free
70#else
71/*
72 * libnl 1.1 has a bug, it tries to allocate socket numbers densely
73 * but when you free a socket again it will mess up its bitmap and
74 * and use the wrong number the next time it needs a socket ID.
75 * Therefore, we wrap the handle alloc/destroy and add our own pid
76 * accounting.
77 */
78static uint32_t port_bitmap[32] = { 0 };
79
80static struct nl_handle *nl80211_handle_alloc(void *cb)
81{
82 struct nl_handle *handle;
83 uint32_t pid = getpid() & 0x3FFFFF;
84 int i;
85
86 handle = nl_handle_alloc_cb(cb);
87
88 for (i = 0; i < 1024; i++) {
89 if (port_bitmap[i / 32] & (1 << (i % 32)))
90 continue;
91 port_bitmap[i / 32] |= 1 << (i % 32);
92 pid += i << 22;
93 break;
94 }
95
96 nl_socket_set_local_port(handle, pid);
97
98 return handle;
99}
100
101static void nl80211_handle_destroy(struct nl_handle *handle)
102{
103 uint32_t port = nl_socket_get_local_port(handle);
104
105 port >>= 22;
106 port_bitmap[port / 32] &= ~(1 << (port % 32));
107
108 nl_handle_destroy(handle);
109}
110#endif /* CONFIG_LIBNL20 */
111
112
113#ifdef ANDROID
114/* system/core/libnl_2 does not include nl_socket_set_nonblocking() */
115static int android_nl_socket_set_nonblocking(struct nl_handle *handle)
116{
117 return fcntl(nl_socket_get_fd(handle), F_SETFL, O_NONBLOCK);
118}
119#undef nl_socket_set_nonblocking
120#define nl_socket_set_nonblocking(h) android_nl_socket_set_nonblocking(h)
121#endif /* ANDROID */
122
123
124static struct nl_handle * nl_create_handle(struct nl_cb *cb, const char *dbg)
125{
126 struct nl_handle *handle;
127
128 handle = nl80211_handle_alloc(cb);
129 if (handle == NULL) {
130 wpa_printf(MSG_ERROR, "nl80211: Failed to allocate netlink "
131 "callbacks (%s)", dbg);
132 return NULL;
133 }
134
135 if (genl_connect(handle)) {
136 wpa_printf(MSG_ERROR, "nl80211: Failed to connect to generic "
137 "netlink (%s)", dbg);
138 nl80211_handle_destroy(handle);
139 return NULL;
140 }
141
142 return handle;
143}
144
145
146static void nl_destroy_handles(struct nl_handle **handle)
147{
148 if (*handle == NULL)
149 return;
150 nl80211_handle_destroy(*handle);
151 *handle = NULL;
152}
153
154
155#if __WORDSIZE == 64
156#define ELOOP_SOCKET_INVALID (intptr_t) 0x8888888888888889ULL
157#else
158#define ELOOP_SOCKET_INVALID (intptr_t) 0x88888889ULL
159#endif
160
161static void nl80211_register_eloop_read(struct nl_handle **handle,
162 eloop_sock_handler handler,
163 void *eloop_data)
164{
165 nl_socket_set_nonblocking(*handle);
166 eloop_register_read_sock(nl_socket_get_fd(*handle), handler,
167 eloop_data, *handle);
168 *handle = (void *) (((intptr_t) *handle) ^ ELOOP_SOCKET_INVALID);
169}
170
171
172static void nl80211_destroy_eloop_handle(struct nl_handle **handle)
173{
174 *handle = (void *) (((intptr_t) *handle) ^ ELOOP_SOCKET_INVALID);
175 eloop_unregister_read_sock(nl_socket_get_fd(*handle));
176 nl_destroy_handles(handle);
177}
178
a875087d
JL
179
180#ifndef IFF_LOWER_UP
181#define IFF_LOWER_UP 0x10000 /* driver signals L1 up */
182#endif
183#ifndef IFF_DORMANT
184#define IFF_DORMANT 0x20000 /* driver signals dormant */
185#endif
186
187#ifndef IF_OPER_DORMANT
188#define IF_OPER_DORMANT 5
189#endif
190#ifndef IF_OPER_UP
191#define IF_OPER_UP 6
192#endif
193
4781064b
JM
194struct nl80211_global {
195 struct dl_list interfaces;
196 int if_add_ifindex;
197 u64 if_add_wdevid;
198 int if_add_wdevid_set;
199 struct netlink_data *netlink;
200 struct nl_cb *nl_cb;
201 struct nl_handle *nl;
202 int nl80211_id;
203 int ioctl_sock; /* socket for ioctl() use */
204
205 struct nl_handle *nl_event;
206};
207
208struct nl80211_wiphy_data {
209 struct dl_list list;
210 struct dl_list bsss;
211 struct dl_list drvs;
212
213 struct nl_handle *nl_beacons;
214 struct nl_cb *nl_cb;
215
216 int wiphy_idx;
217};
218
219static void nl80211_global_deinit(void *priv);
220
221struct i802_bss {
222 struct wpa_driver_nl80211_data *drv;
223 struct i802_bss *next;
224 int ifindex;
225 u64 wdev_id;
226 char ifname[IFNAMSIZ + 1];
227 char brname[IFNAMSIZ];
228 unsigned int beacon_set:1;
229 unsigned int added_if_into_bridge:1;
230 unsigned int added_bridge:1;
231 unsigned int in_deinit:1;
232 unsigned int wdev_id_set:1;
233 unsigned int added_if:1;
234
235 u8 addr[ETH_ALEN];
236
237 int freq;
238 int if_dynamic;
239
240 void *ctx;
241 struct nl_handle *nl_preq, *nl_mgmt;
242 struct nl_cb *nl_cb;
243
244 struct nl80211_wiphy_data *wiphy_data;
245 struct dl_list wiphy_list;
246};
a875087d
JL
247
248struct wpa_driver_nl80211_data {
4781064b
JM
249 struct nl80211_global *global;
250 struct dl_list list;
251 struct dl_list wiphy_list;
252 char phyname[32];
a875087d 253 void *ctx;
a875087d
JL
254 int ifindex;
255 int if_removed;
4781064b
JM
256 int if_disabled;
257 int ignore_if_down_event;
258 struct rfkill_data *rfkill;
a875087d 259 struct wpa_driver_capa capa;
4781064b
JM
260 u8 *extended_capa, *extended_capa_mask;
261 unsigned int extended_capa_len;
a875087d 262 int has_capability;
a875087d
JL
263
264 int operstate;
265
a875087d 266 int scan_complete_events;
4781064b
JM
267 enum scan_states {
268 NO_SCAN, SCAN_REQUESTED, SCAN_STARTED, SCAN_COMPLETED,
269 SCAN_ABORTED, SCHED_SCAN_STARTED, SCHED_SCAN_STOPPED,
270 SCHED_SCAN_RESULTS
271 } scan_state;
a875087d 272
a875087d 273 struct nl_cb *nl_cb;
a875087d 274
4781064b
JM
275 u8 auth_bssid[ETH_ALEN];
276 u8 auth_attempt_bssid[ETH_ALEN];
277 u8 bssid[ETH_ALEN];
278 u8 prev_bssid[ETH_ALEN];
279 int associated;
280 u8 ssid[32];
281 size_t ssid_len;
282 enum nl80211_iftype nlmode;
283 enum nl80211_iftype ap_scan_as_station;
284 unsigned int assoc_freq;
285
286 int monitor_sock;
a875087d 287 int monitor_ifidx;
4781064b
JM
288 int monitor_refcount;
289
290 unsigned int disabled_11b_rates:1;
291 unsigned int pending_remain_on_chan:1;
292 unsigned int in_interface_list:1;
293 unsigned int device_ap_sme:1;
294 unsigned int poll_command_supported:1;
295 unsigned int data_tx_status:1;
296 unsigned int scan_for_auth:1;
297 unsigned int retry_auth:1;
298 unsigned int use_monitor:1;
299 unsigned int ignore_next_local_disconnect:1;
300 unsigned int allow_p2p_device:1;
301 unsigned int hostapd:1;
302 unsigned int start_mode_ap:1;
303 unsigned int start_iface_up:1;
304
305 u64 remain_on_chan_cookie;
306 u64 send_action_cookie;
307
308 unsigned int last_mgmt_freq;
309
310 struct wpa_driver_scan_filter *filter_ssids;
311 size_t num_filter_ssids;
312
313 struct i802_bss *first_bss;
314
315 int eapol_tx_sock;
316
317 int eapol_sock; /* socket for EAPOL frames */
318
319 int default_if_indices[16];
320 int *if_indices;
321 int num_if_indices;
322
323 /* From failed authentication command */
324 int auth_freq;
325 u8 auth_bssid_[ETH_ALEN];
326 u8 auth_ssid[32];
327 size_t auth_ssid_len;
328 int auth_alg;
329 u8 *auth_ie;
330 size_t auth_ie_len;
331 u8 auth_wep_key[4][16];
332 size_t auth_wep_key_len[4];
333 int auth_wep_tx_keyidx;
334 int auth_local_state_change;
335 int auth_p2p;
a875087d
JL
336};
337
338
4781064b 339static void wpa_driver_nl80211_deinit(struct i802_bss *bss);
a875087d
JL
340static void wpa_driver_nl80211_scan_timeout(void *eloop_ctx,
341 void *timeout_ctx);
4781064b
JM
342static int wpa_driver_nl80211_set_mode(struct i802_bss *bss,
343 enum nl80211_iftype nlmode);
344static int
345wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv,
346 const u8 *set_addr, int first);
347static int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data *drv,
348 const u8 *addr, int cmd, u16 reason_code,
349 int local_state_change);
350static void nl80211_remove_monitor_interface(
351 struct wpa_driver_nl80211_data *drv);
352static int nl80211_send_frame_cmd(struct i802_bss *bss,
353 unsigned int freq, unsigned int wait,
354 const u8 *buf, size_t buf_len, u64 *cookie,
355 int no_cck, int no_ack, int offchanok);
356static int nl80211_register_frame(struct i802_bss *bss,
357 struct nl_handle *hl_handle,
358 u16 type, const u8 *match, size_t match_len);
359static int wpa_driver_nl80211_probe_req_report(struct i802_bss *bss,
360 int report);
361#ifdef ANDROID
362static int android_pno_start(struct i802_bss *bss,
363 struct wpa_driver_scan_params *params);
364static int android_pno_stop(struct i802_bss *bss);
365extern int wpa_driver_nl80211_driver_cmd(void *priv, char *cmd, char *buf,
366 size_t buf_len);
367#endif /* ANDROID */
368#ifdef ANDROID_P2P
369int wpa_driver_set_p2p_noa(void *priv, u8 count, int start, int duration);
370int wpa_driver_get_p2p_noa(void *priv, u8 *buf, size_t len);
371int wpa_driver_set_p2p_ps(void *priv, int legacy_ps, int opp_ps, int ctwindow);
372int wpa_driver_set_ap_wps_p2p_ie(void *priv, const struct wpabuf *beacon,
373 const struct wpabuf *proberesp,
374 const struct wpabuf *assocresp);
375#endif /* ANDROID_P2P */
376
377static void add_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx);
378static void del_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx);
379static int have_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx);
380static int wpa_driver_nl80211_if_remove(struct i802_bss *bss,
381 enum wpa_driver_if_type type,
382 const char *ifname);
383
384static int wpa_driver_nl80211_set_freq(struct i802_bss *bss,
385 struct hostapd_freq_params *freq);
386static int nl80211_disable_11b_rates(struct wpa_driver_nl80211_data *drv,
387 int ifindex, int disabled);
388
389static int nl80211_leave_ibss(struct wpa_driver_nl80211_data *drv);
390static int wpa_driver_nl80211_authenticate_retry(
391 struct wpa_driver_nl80211_data *drv);
392
393static int i802_set_iface_flags(struct i802_bss *bss, int up);
394
395
396static const char * nl80211_command_to_string(enum nl80211_commands cmd)
397{
398#define C2S(x) case x: return #x;
399 switch (cmd) {
400 C2S(NL80211_CMD_UNSPEC)
401 C2S(NL80211_CMD_GET_WIPHY)
402 C2S(NL80211_CMD_SET_WIPHY)
403 C2S(NL80211_CMD_NEW_WIPHY)
404 C2S(NL80211_CMD_DEL_WIPHY)
405 C2S(NL80211_CMD_GET_INTERFACE)
406 C2S(NL80211_CMD_SET_INTERFACE)
407 C2S(NL80211_CMD_NEW_INTERFACE)
408 C2S(NL80211_CMD_DEL_INTERFACE)
409 C2S(NL80211_CMD_GET_KEY)
410 C2S(NL80211_CMD_SET_KEY)
411 C2S(NL80211_CMD_NEW_KEY)
412 C2S(NL80211_CMD_DEL_KEY)
413 C2S(NL80211_CMD_GET_BEACON)
414 C2S(NL80211_CMD_SET_BEACON)
415 C2S(NL80211_CMD_START_AP)
416 C2S(NL80211_CMD_STOP_AP)
417 C2S(NL80211_CMD_GET_STATION)
418 C2S(NL80211_CMD_SET_STATION)
419 C2S(NL80211_CMD_NEW_STATION)
420 C2S(NL80211_CMD_DEL_STATION)
421 C2S(NL80211_CMD_GET_MPATH)
422 C2S(NL80211_CMD_SET_MPATH)
423 C2S(NL80211_CMD_NEW_MPATH)
424 C2S(NL80211_CMD_DEL_MPATH)
425 C2S(NL80211_CMD_SET_BSS)
426 C2S(NL80211_CMD_SET_REG)
427 C2S(NL80211_CMD_REQ_SET_REG)
428 C2S(NL80211_CMD_GET_MESH_CONFIG)
429 C2S(NL80211_CMD_SET_MESH_CONFIG)
430 C2S(NL80211_CMD_SET_MGMT_EXTRA_IE)
431 C2S(NL80211_CMD_GET_REG)
432 C2S(NL80211_CMD_GET_SCAN)
433 C2S(NL80211_CMD_TRIGGER_SCAN)
434 C2S(NL80211_CMD_NEW_SCAN_RESULTS)
435 C2S(NL80211_CMD_SCAN_ABORTED)
436 C2S(NL80211_CMD_REG_CHANGE)
437 C2S(NL80211_CMD_AUTHENTICATE)
438 C2S(NL80211_CMD_ASSOCIATE)
439 C2S(NL80211_CMD_DEAUTHENTICATE)
440 C2S(NL80211_CMD_DISASSOCIATE)
441 C2S(NL80211_CMD_MICHAEL_MIC_FAILURE)
442 C2S(NL80211_CMD_REG_BEACON_HINT)
443 C2S(NL80211_CMD_JOIN_IBSS)
444 C2S(NL80211_CMD_LEAVE_IBSS)
445 C2S(NL80211_CMD_TESTMODE)
446 C2S(NL80211_CMD_CONNECT)
447 C2S(NL80211_CMD_ROAM)
448 C2S(NL80211_CMD_DISCONNECT)
449 C2S(NL80211_CMD_SET_WIPHY_NETNS)
450 C2S(NL80211_CMD_GET_SURVEY)
451 C2S(NL80211_CMD_NEW_SURVEY_RESULTS)
452 C2S(NL80211_CMD_SET_PMKSA)
453 C2S(NL80211_CMD_DEL_PMKSA)
454 C2S(NL80211_CMD_FLUSH_PMKSA)
455 C2S(NL80211_CMD_REMAIN_ON_CHANNEL)
456 C2S(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL)
457 C2S(NL80211_CMD_SET_TX_BITRATE_MASK)
458 C2S(NL80211_CMD_REGISTER_FRAME)
459 C2S(NL80211_CMD_FRAME)
460 C2S(NL80211_CMD_FRAME_TX_STATUS)
461 C2S(NL80211_CMD_SET_POWER_SAVE)
462 C2S(NL80211_CMD_GET_POWER_SAVE)
463 C2S(NL80211_CMD_SET_CQM)
464 C2S(NL80211_CMD_NOTIFY_CQM)
465 C2S(NL80211_CMD_SET_CHANNEL)
466 C2S(NL80211_CMD_SET_WDS_PEER)
467 C2S(NL80211_CMD_FRAME_WAIT_CANCEL)
468 C2S(NL80211_CMD_JOIN_MESH)
469 C2S(NL80211_CMD_LEAVE_MESH)
470 C2S(NL80211_CMD_UNPROT_DEAUTHENTICATE)
471 C2S(NL80211_CMD_UNPROT_DISASSOCIATE)
472 C2S(NL80211_CMD_NEW_PEER_CANDIDATE)
473 C2S(NL80211_CMD_GET_WOWLAN)
474 C2S(NL80211_CMD_SET_WOWLAN)
475 C2S(NL80211_CMD_START_SCHED_SCAN)
476 C2S(NL80211_CMD_STOP_SCHED_SCAN)
477 C2S(NL80211_CMD_SCHED_SCAN_RESULTS)
478 C2S(NL80211_CMD_SCHED_SCAN_STOPPED)
479 C2S(NL80211_CMD_SET_REKEY_OFFLOAD)
480 C2S(NL80211_CMD_PMKSA_CANDIDATE)
481 C2S(NL80211_CMD_TDLS_OPER)
482 C2S(NL80211_CMD_TDLS_MGMT)
483 C2S(NL80211_CMD_UNEXPECTED_FRAME)
484 C2S(NL80211_CMD_PROBE_CLIENT)
485 C2S(NL80211_CMD_REGISTER_BEACONS)
486 C2S(NL80211_CMD_UNEXPECTED_4ADDR_FRAME)
487 C2S(NL80211_CMD_SET_NOACK_MAP)
488 C2S(NL80211_CMD_CH_SWITCH_NOTIFY)
489 C2S(NL80211_CMD_START_P2P_DEVICE)
490 C2S(NL80211_CMD_STOP_P2P_DEVICE)
491 C2S(NL80211_CMD_CONN_FAILED)
492 C2S(NL80211_CMD_SET_MCAST_RATE)
493 C2S(NL80211_CMD_SET_MAC_ACL)
494 C2S(NL80211_CMD_RADAR_DETECT)
495 C2S(NL80211_CMD_GET_PROTOCOL_FEATURES)
496 C2S(NL80211_CMD_UPDATE_FT_IES)
497 C2S(NL80211_CMD_FT_EVENT)
498 C2S(NL80211_CMD_CRIT_PROTOCOL_START)
499 C2S(NL80211_CMD_CRIT_PROTOCOL_STOP)
500 C2S(NL80211_CMD_GET_COALESCE)
501 C2S(NL80211_CMD_SET_COALESCE)
502 C2S(NL80211_CMD_CHANNEL_SWITCH)
503 C2S(NL80211_CMD_VENDOR)
504 C2S(NL80211_CMD_SET_QOS_MAP)
505 default:
506 return "NL80211_CMD_UNKNOWN";
507 }
508#undef C2S
509}
510
511
512/* Converts nl80211_chan_width to a common format */
513static enum chan_width convert2width(int width)
514{
515 switch (width) {
516 case NL80211_CHAN_WIDTH_20_NOHT:
517 return CHAN_WIDTH_20_NOHT;
518 case NL80211_CHAN_WIDTH_20:
519 return CHAN_WIDTH_20;
520 case NL80211_CHAN_WIDTH_40:
521 return CHAN_WIDTH_40;
522 case NL80211_CHAN_WIDTH_80:
523 return CHAN_WIDTH_80;
524 case NL80211_CHAN_WIDTH_80P80:
525 return CHAN_WIDTH_80P80;
526 case NL80211_CHAN_WIDTH_160:
527 return CHAN_WIDTH_160;
528 }
529 return CHAN_WIDTH_UNKNOWN;
530}
531
532
533static int is_ap_interface(enum nl80211_iftype nlmode)
534{
535 return (nlmode == NL80211_IFTYPE_AP ||
536 nlmode == NL80211_IFTYPE_P2P_GO);
537}
538
539
540static int is_sta_interface(enum nl80211_iftype nlmode)
541{
542 return (nlmode == NL80211_IFTYPE_STATION ||
543 nlmode == NL80211_IFTYPE_P2P_CLIENT);
544}
545
546
547static int is_p2p_net_interface(enum nl80211_iftype nlmode)
548{
549 return (nlmode == NL80211_IFTYPE_P2P_CLIENT ||
550 nlmode == NL80211_IFTYPE_P2P_GO);
551}
552
553
554static void nl80211_mark_disconnected(struct wpa_driver_nl80211_data *drv)
555{
556 if (drv->associated)
557 os_memcpy(drv->prev_bssid, drv->bssid, ETH_ALEN);
558 drv->associated = 0;
559 os_memset(drv->bssid, 0, ETH_ALEN);
560}
561
562
563struct nl80211_bss_info_arg {
564 struct wpa_driver_nl80211_data *drv;
565 struct wpa_scan_results *res;
566 unsigned int assoc_freq;
567 u8 assoc_bssid[ETH_ALEN];
568};
569
570static int bss_info_handler(struct nl_msg *msg, void *arg);
a875087d
JL
571
572
573/* nl80211 code */
574static int ack_handler(struct nl_msg *msg, void *arg)
575{
576 int *err = arg;
577 *err = 0;
578 return NL_STOP;
579}
580
581static int finish_handler(struct nl_msg *msg, void *arg)
582{
583 int *ret = arg;
584 *ret = 0;
585 return NL_SKIP;
586}
587
588static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err,
589 void *arg)
590{
591 int *ret = arg;
592 *ret = err->error;
593 return NL_SKIP;
594}
595
4781064b
JM
596
597static int no_seq_check(struct nl_msg *msg, void *arg)
598{
599 return NL_OK;
600}
601
602
603static int send_and_recv(struct nl80211_global *global,
604 struct nl_handle *nl_handle, struct nl_msg *msg,
605 int (*valid_handler)(struct nl_msg *, void *),
606 void *valid_data)
a875087d
JL
607{
608 struct nl_cb *cb;
609 int err = -ENOMEM;
610
4781064b 611 cb = nl_cb_clone(global->nl_cb);
a875087d
JL
612 if (!cb)
613 goto out;
614
4781064b 615 err = nl_send_auto_complete(nl_handle, msg);
a875087d
JL
616 if (err < 0)
617 goto out;
618
619 err = 1;
620
621 nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
622 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
623 nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);
624
625 if (valid_handler)
626 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM,
627 valid_handler, valid_data);
628
4781064b
JM
629 while (err > 0) {
630 int res = nl_recvmsgs(nl_handle, cb);
631 if (res) {
632 wpa_printf(MSG_INFO,
633 "nl80211: %s->nl_recvmsgs failed: %d",
634 __func__, res);
635 }
636 }
a875087d
JL
637 out:
638 nl_cb_put(cb);
639 nlmsg_free(msg);
640 return err;
641}
642
643
4781064b
JM
644static int send_and_recv_msgs_global(struct nl80211_global *global,
645 struct nl_msg *msg,
646 int (*valid_handler)(struct nl_msg *, void *),
647 void *valid_data)
648{
649 return send_and_recv(global, global->nl, msg, valid_handler,
650 valid_data);
651}
652
653
654static int send_and_recv_msgs(struct wpa_driver_nl80211_data *drv,
655 struct nl_msg *msg,
656 int (*valid_handler)(struct nl_msg *, void *),
657 void *valid_data)
658{
659 return send_and_recv(drv->global, drv->global->nl, msg,
660 valid_handler, valid_data);
661}
662
663
a875087d
JL
664struct family_data {
665 const char *group;
666 int id;
667};
668
669
4781064b
JM
670static int nl80211_set_iface_id(struct nl_msg *msg, struct i802_bss *bss)
671{
672 if (bss->wdev_id_set)
673 NLA_PUT_U64(msg, NL80211_ATTR_WDEV, bss->wdev_id);
674 else
675 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex);
676 return 0;
677
678nla_put_failure:
679 return -1;
680}
681
682
a875087d
JL
683static int family_handler(struct nl_msg *msg, void *arg)
684{
685 struct family_data *res = arg;
686 struct nlattr *tb[CTRL_ATTR_MAX + 1];
687 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
688 struct nlattr *mcgrp;
689 int i;
690
691 nla_parse(tb, CTRL_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
692 genlmsg_attrlen(gnlh, 0), NULL);
693 if (!tb[CTRL_ATTR_MCAST_GROUPS])
694 return NL_SKIP;
695
696 nla_for_each_nested(mcgrp, tb[CTRL_ATTR_MCAST_GROUPS], i) {
697 struct nlattr *tb2[CTRL_ATTR_MCAST_GRP_MAX + 1];
698 nla_parse(tb2, CTRL_ATTR_MCAST_GRP_MAX, nla_data(mcgrp),
699 nla_len(mcgrp), NULL);
700 if (!tb2[CTRL_ATTR_MCAST_GRP_NAME] ||
701 !tb2[CTRL_ATTR_MCAST_GRP_ID] ||
702 os_strncmp(nla_data(tb2[CTRL_ATTR_MCAST_GRP_NAME]),
703 res->group,
704 nla_len(tb2[CTRL_ATTR_MCAST_GRP_NAME])) != 0)
705 continue;
706 res->id = nla_get_u32(tb2[CTRL_ATTR_MCAST_GRP_ID]);
707 break;
708 };
709
710 return NL_SKIP;
711}
712
713
4781064b 714static int nl_get_multicast_id(struct nl80211_global *global,
a875087d
JL
715 const char *family, const char *group)
716{
717 struct nl_msg *msg;
718 int ret = -1;
719 struct family_data res = { group, -ENOENT };
720
721 msg = nlmsg_alloc();
722 if (!msg)
723 return -ENOMEM;
4781064b 724 genlmsg_put(msg, 0, 0, genl_ctrl_resolve(global->nl, "nlctrl"),
a875087d
JL
725 0, 0, CTRL_CMD_GETFAMILY, 0);
726 NLA_PUT_STRING(msg, CTRL_ATTR_FAMILY_NAME, family);
727
4781064b 728 ret = send_and_recv_msgs_global(global, msg, family_handler, &res);
a875087d
JL
729 msg = NULL;
730 if (ret == 0)
731 ret = res.id;
732
733nla_put_failure:
734 nlmsg_free(msg);
735 return ret;
736}
737
738
4781064b
JM
739static void * nl80211_cmd(struct wpa_driver_nl80211_data *drv,
740 struct nl_msg *msg, int flags, uint8_t cmd)
a875087d 741{
4781064b
JM
742 return genlmsg_put(msg, 0, 0, drv->global->nl80211_id,
743 0, flags, cmd, 0);
a875087d
JL
744}
745
746
4781064b
JM
747struct wiphy_idx_data {
748 int wiphy_idx;
749 enum nl80211_iftype nlmode;
750 u8 *macaddr;
751};
752
753
754static int netdev_info_handler(struct nl_msg *msg, void *arg)
a875087d 755{
4781064b
JM
756 struct nlattr *tb[NL80211_ATTR_MAX + 1];
757 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
758 struct wiphy_idx_data *info = arg;
a875087d 759
4781064b
JM
760 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
761 genlmsg_attrlen(gnlh, 0), NULL);
a875087d 762
4781064b
JM
763 if (tb[NL80211_ATTR_WIPHY])
764 info->wiphy_idx = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
a875087d 765
4781064b
JM
766 if (tb[NL80211_ATTR_IFTYPE])
767 info->nlmode = nla_get_u32(tb[NL80211_ATTR_IFTYPE]);
768
769 if (tb[NL80211_ATTR_MAC] && info->macaddr)
770 os_memcpy(info->macaddr, nla_data(tb[NL80211_ATTR_MAC]),
771 ETH_ALEN);
772
773 return NL_SKIP;
a875087d
JL
774}
775
776
4781064b 777static int nl80211_get_wiphy_index(struct i802_bss *bss)
a875087d 778{
4781064b
JM
779 struct nl_msg *msg;
780 struct wiphy_idx_data data = {
781 .wiphy_idx = -1,
782 .macaddr = NULL,
783 };
a875087d 784
4781064b
JM
785 msg = nlmsg_alloc();
786 if (!msg)
787 return NL80211_IFTYPE_UNSPECIFIED;
a875087d 788
4781064b 789 nl80211_cmd(bss->drv, msg, 0, NL80211_CMD_GET_INTERFACE);
a875087d 790
4781064b
JM
791 if (nl80211_set_iface_id(msg, bss) < 0)
792 goto nla_put_failure;
793
794 if (send_and_recv_msgs(bss->drv, msg, netdev_info_handler, &data) == 0)
795 return data.wiphy_idx;
796 msg = NULL;
797nla_put_failure:
798 nlmsg_free(msg);
799 return -1;
a875087d
JL
800}
801
802
4781064b 803static enum nl80211_iftype nl80211_get_ifmode(struct i802_bss *bss)
a875087d 804{
4781064b
JM
805 struct nl_msg *msg;
806 struct wiphy_idx_data data = {
807 .nlmode = NL80211_IFTYPE_UNSPECIFIED,
808 .macaddr = NULL,
809 };
a875087d 810
4781064b
JM
811 msg = nlmsg_alloc();
812 if (!msg)
813 return -1;
a875087d 814
4781064b 815 nl80211_cmd(bss->drv, msg, 0, NL80211_CMD_GET_INTERFACE);
a875087d 816
4781064b
JM
817 if (nl80211_set_iface_id(msg, bss) < 0)
818 goto nla_put_failure;
819
820 if (send_and_recv_msgs(bss->drv, msg, netdev_info_handler, &data) == 0)
821 return data.nlmode;
822 msg = NULL;
823nla_put_failure:
824 nlmsg_free(msg);
825 return NL80211_IFTYPE_UNSPECIFIED;
a875087d
JL
826}
827
828
4781064b 829static int nl80211_get_macaddr(struct i802_bss *bss)
a875087d 830{
4781064b
JM
831 struct nl_msg *msg;
832 struct wiphy_idx_data data = {
833 .macaddr = bss->addr,
834 };
835
836 msg = nlmsg_alloc();
837 if (!msg)
838 return NL80211_IFTYPE_UNSPECIFIED;
a875087d 839
4781064b
JM
840 nl80211_cmd(bss->drv, msg, 0, NL80211_CMD_GET_INTERFACE);
841 if (nl80211_set_iface_id(msg, bss) < 0)
842 goto nla_put_failure;
a875087d 843
4781064b 844 return send_and_recv_msgs(bss->drv, msg, netdev_info_handler, &data);
a875087d 845
4781064b
JM
846nla_put_failure:
847 nlmsg_free(msg);
848 return NL80211_IFTYPE_UNSPECIFIED;
a875087d
JL
849}
850
851
4781064b
JM
852static int nl80211_register_beacons(struct wpa_driver_nl80211_data *drv,
853 struct nl80211_wiphy_data *w)
a875087d 854{
4781064b
JM
855 struct nl_msg *msg;
856 int ret = -1;
a875087d 857
4781064b
JM
858 msg = nlmsg_alloc();
859 if (!msg)
a875087d
JL
860 return -1;
861
4781064b
JM
862 nl80211_cmd(drv, msg, 0, NL80211_CMD_REGISTER_BEACONS);
863
864 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, w->wiphy_idx);
a875087d 865
4781064b
JM
866 ret = send_and_recv(drv->global, w->nl_beacons, msg, NULL, NULL);
867 msg = NULL;
868 if (ret) {
869 wpa_printf(MSG_DEBUG, "nl80211: Register beacons command "
870 "failed: ret=%d (%s)",
871 ret, strerror(-ret));
872 goto nla_put_failure;
873 }
874 ret = 0;
875nla_put_failure:
876 nlmsg_free(msg);
a875087d
JL
877 return ret;
878}
879
880
4781064b 881static void nl80211_recv_beacons(int sock, void *eloop_ctx, void *handle)
a875087d 882{
4781064b
JM
883 struct nl80211_wiphy_data *w = eloop_ctx;
884 int res;
a875087d 885
4781064b 886 wpa_printf(MSG_EXCESSIVE, "nl80211: Beacon event message available");
a875087d 887
4781064b
JM
888 res = nl_recvmsgs(handle, w->nl_cb);
889 if (res) {
890 wpa_printf(MSG_INFO, "nl80211: %s->nl_recvmsgs failed: %d",
891 __func__, res);
a875087d 892 }
a875087d
JL
893}
894
895
4781064b 896static int process_beacon_event(struct nl_msg *msg, void *arg)
a875087d 897{
4781064b
JM
898 struct nl80211_wiphy_data *w = arg;
899 struct wpa_driver_nl80211_data *drv;
900 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
901 struct nlattr *tb[NL80211_ATTR_MAX + 1];
902 union wpa_event_data event;
a875087d 903
4781064b
JM
904 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
905 genlmsg_attrlen(gnlh, 0), NULL);
a875087d 906
4781064b
JM
907 if (gnlh->cmd != NL80211_CMD_FRAME) {
908 wpa_printf(MSG_DEBUG, "nl80211: Unexpected beacon event? (%d)",
909 gnlh->cmd);
910 return NL_SKIP;
911 }
a875087d 912
4781064b
JM
913 if (!tb[NL80211_ATTR_FRAME])
914 return NL_SKIP;
a875087d 915
4781064b
JM
916 dl_list_for_each(drv, &w->drvs, struct wpa_driver_nl80211_data,
917 wiphy_list) {
918 os_memset(&event, 0, sizeof(event));
919 event.rx_mgmt.frame = nla_data(tb[NL80211_ATTR_FRAME]);
920 event.rx_mgmt.frame_len = nla_len(tb[NL80211_ATTR_FRAME]);
921 wpa_supplicant_event(drv->ctx, EVENT_RX_MGMT, &event);
922 }
a875087d 923
4781064b
JM
924 return NL_SKIP;
925}
a875087d 926
a875087d 927
4781064b
JM
928static struct nl80211_wiphy_data *
929nl80211_get_wiphy_data_ap(struct i802_bss *bss)
930{
931 static DEFINE_DL_LIST(nl80211_wiphys);
932 struct nl80211_wiphy_data *w;
933 int wiphy_idx, found = 0;
934 struct i802_bss *tmp_bss;
a875087d 935
4781064b
JM
936 if (bss->wiphy_data != NULL)
937 return bss->wiphy_data;
a875087d 938
4781064b 939 wiphy_idx = nl80211_get_wiphy_index(bss);
a875087d 940
4781064b
JM
941 dl_list_for_each(w, &nl80211_wiphys, struct nl80211_wiphy_data, list) {
942 if (w->wiphy_idx == wiphy_idx)
943 goto add;
a875087d 944 }
a875087d 945
4781064b
JM
946 /* alloc new one */
947 w = os_zalloc(sizeof(*w));
948 if (w == NULL)
949 return NULL;
950 w->wiphy_idx = wiphy_idx;
951 dl_list_init(&w->bsss);
952 dl_list_init(&w->drvs);
a875087d 953
4781064b
JM
954 w->nl_cb = nl_cb_alloc(NL_CB_DEFAULT);
955 if (!w->nl_cb) {
956 os_free(w);
957 return NULL;
958 }
959 nl_cb_set(w->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL);
960 nl_cb_set(w->nl_cb, NL_CB_VALID, NL_CB_CUSTOM, process_beacon_event,
961 w);
962
963 w->nl_beacons = nl_create_handle(bss->drv->global->nl_cb,
964 "wiphy beacons");
965 if (w->nl_beacons == NULL) {
966 os_free(w);
967 return NULL;
968 }
a875087d 969
4781064b
JM
970 if (nl80211_register_beacons(bss->drv, w)) {
971 nl_destroy_handles(&w->nl_beacons);
972 os_free(w);
973 return NULL;
974 }
a875087d 975
4781064b 976 nl80211_register_eloop_read(&w->nl_beacons, nl80211_recv_beacons, w);
a875087d 977
4781064b 978 dl_list_add(&nl80211_wiphys, &w->list);
a875087d 979
4781064b
JM
980add:
981 /* drv entry for this bss already there? */
982 dl_list_for_each(tmp_bss, &w->bsss, struct i802_bss, wiphy_list) {
983 if (tmp_bss->drv == bss->drv) {
984 found = 1;
985 break;
986 }
987 }
988 /* if not add it */
989 if (!found)
990 dl_list_add(&w->drvs, &bss->drv->wiphy_list);
a875087d 991
4781064b
JM
992 dl_list_add(&w->bsss, &bss->wiphy_list);
993 bss->wiphy_data = w;
994 return w;
a875087d
JL
995}
996
997
4781064b 998static void nl80211_put_wiphy_data_ap(struct i802_bss *bss)
a875087d 999{
4781064b
JM
1000 struct nl80211_wiphy_data *w = bss->wiphy_data;
1001 struct i802_bss *tmp_bss;
1002 int found = 0;
a875087d 1003
4781064b
JM
1004 if (w == NULL)
1005 return;
1006 bss->wiphy_data = NULL;
1007 dl_list_del(&bss->wiphy_list);
a875087d 1008
4781064b
JM
1009 /* still any for this drv present? */
1010 dl_list_for_each(tmp_bss, &w->bsss, struct i802_bss, wiphy_list) {
1011 if (tmp_bss->drv == bss->drv) {
1012 found = 1;
1013 break;
1014 }
1015 }
1016 /* if not remove it */
1017 if (!found)
1018 dl_list_del(&bss->drv->wiphy_list);
a875087d 1019
4781064b
JM
1020 if (!dl_list_empty(&w->bsss))
1021 return;
a875087d 1022
4781064b 1023 nl80211_destroy_eloop_handle(&w->nl_beacons);
a875087d 1024
4781064b
JM
1025 nl_cb_put(w->nl_cb);
1026 dl_list_del(&w->list);
1027 os_free(w);
a875087d
JL
1028}
1029
1030
4781064b 1031static int wpa_driver_nl80211_get_bssid(void *priv, u8 *bssid)
a875087d 1032{
4781064b
JM
1033 struct i802_bss *bss = priv;
1034 struct wpa_driver_nl80211_data *drv = bss->drv;
1035 if (!drv->associated)
a875087d 1036 return -1;
4781064b 1037 os_memcpy(bssid, drv->bssid, ETH_ALEN);
a875087d
JL
1038 return 0;
1039}
1040
1041
4781064b 1042static int wpa_driver_nl80211_get_ssid(void *priv, u8 *ssid)
a875087d 1043{
4781064b
JM
1044 struct i802_bss *bss = priv;
1045 struct wpa_driver_nl80211_data *drv = bss->drv;
1046 if (!drv->associated)
a875087d 1047 return -1;
4781064b
JM
1048 os_memcpy(ssid, drv->ssid, drv->ssid_len);
1049 return drv->ssid_len;
a875087d
JL
1050}
1051
1052
4781064b
JM
1053static void wpa_driver_nl80211_event_newlink(
1054 struct wpa_driver_nl80211_data *drv, char *ifname)
a875087d 1055{
4781064b 1056 union wpa_event_data event;
a875087d 1057
4781064b
JM
1058 if (os_strcmp(drv->first_bss->ifname, ifname) == 0) {
1059 if (if_nametoindex(drv->first_bss->ifname) == 0) {
1060 wpa_printf(MSG_DEBUG, "nl80211: Interface %s does not exist - ignore RTM_NEWLINK",
1061 drv->first_bss->ifname);
1062 return;
1063 }
1064 if (!drv->if_removed)
1065 return;
1066 wpa_printf(MSG_DEBUG, "nl80211: Mark if_removed=0 for %s based on RTM_NEWLINK event",
1067 drv->first_bss->ifname);
1068 drv->if_removed = 0;
a875087d
JL
1069 }
1070
4781064b
JM
1071 os_memset(&event, 0, sizeof(event));
1072 os_strlcpy(event.interface_status.ifname, ifname,
1073 sizeof(event.interface_status.ifname));
1074 event.interface_status.ievent = EVENT_INTERFACE_ADDED;
1075 wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS, &event);
a875087d
JL
1076}
1077
1078
4781064b
JM
1079static void wpa_driver_nl80211_event_dellink(
1080 struct wpa_driver_nl80211_data *drv, char *ifname)
a875087d 1081{
4781064b 1082 union wpa_event_data event;
a875087d 1083
4781064b
JM
1084 if (os_strcmp(drv->first_bss->ifname, ifname) == 0) {
1085 if (drv->if_removed) {
1086 wpa_printf(MSG_DEBUG, "nl80211: if_removed already set - ignore RTM_DELLINK event for %s",
1087 ifname);
a875087d 1088 return;
a875087d 1089 }
4781064b
JM
1090 wpa_printf(MSG_DEBUG, "RTM_DELLINK: Interface '%s' removed - mark if_removed=1",
1091 ifname);
1092 drv->if_removed = 1;
1093 } else {
1094 wpa_printf(MSG_DEBUG, "RTM_DELLINK: Interface '%s' removed",
1095 ifname);
a875087d 1096 }
a875087d
JL
1097
1098 os_memset(&event, 0, sizeof(event));
4781064b
JM
1099 os_strlcpy(event.interface_status.ifname, ifname,
1100 sizeof(event.interface_status.ifname));
1101 event.interface_status.ievent = EVENT_INTERFACE_REMOVED;
1102 wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS, &event);
a875087d
JL
1103}
1104
1105
1106static int wpa_driver_nl80211_own_ifname(struct wpa_driver_nl80211_data *drv,
4781064b 1107 u8 *buf, size_t len)
a875087d 1108{
4781064b 1109 int attrlen, rta_len;
a875087d
JL
1110 struct rtattr *attr;
1111
4781064b
JM
1112 attrlen = len;
1113 attr = (struct rtattr *) buf;
a875087d
JL
1114
1115 rta_len = RTA_ALIGN(sizeof(struct rtattr));
1116 while (RTA_OK(attr, attrlen)) {
1117 if (attr->rta_type == IFLA_IFNAME) {
4781064b
JM
1118 if (os_strcmp(((char *) attr) + rta_len,
1119 drv->first_bss->ifname) == 0)
a875087d
JL
1120 return 1;
1121 else
1122 break;
1123 }
1124 attr = RTA_NEXT(attr, attrlen);
1125 }
1126
1127 return 0;
1128}
1129
1130
1131static int wpa_driver_nl80211_own_ifindex(struct wpa_driver_nl80211_data *drv,
4781064b 1132 int ifindex, u8 *buf, size_t len)
a875087d
JL
1133{
1134 if (drv->ifindex == ifindex)
1135 return 1;
1136
4781064b 1137 if (drv->if_removed && wpa_driver_nl80211_own_ifname(drv, buf, len)) {
a875087d
JL
1138 wpa_printf(MSG_DEBUG, "nl80211: Update ifindex for a removed "
1139 "interface");
4781064b 1140 wpa_driver_nl80211_finish_drv_init(drv, NULL, 0);
a875087d
JL
1141 return 1;
1142 }
1143
1144 return 0;
1145}
1146
1147
4781064b
JM
1148static struct wpa_driver_nl80211_data *
1149nl80211_find_drv(struct nl80211_global *global, int idx, u8 *buf, size_t len)
a875087d 1150{
4781064b
JM
1151 struct wpa_driver_nl80211_data *drv;
1152 dl_list_for_each(drv, &global->interfaces,
1153 struct wpa_driver_nl80211_data, list) {
1154 if (wpa_driver_nl80211_own_ifindex(drv, idx, buf, len) ||
1155 have_ifidx(drv, idx))
1156 return drv;
1157 }
1158 return NULL;
1159}
a875087d 1160
a875087d 1161
4781064b
JM
1162static void wpa_driver_nl80211_event_rtm_newlink(void *ctx,
1163 struct ifinfomsg *ifi,
1164 u8 *buf, size_t len)
1165{
1166 struct nl80211_global *global = ctx;
1167 struct wpa_driver_nl80211_data *drv;
1168 int attrlen;
1169 struct rtattr *attr;
1170 u32 brid = 0;
1171 char namebuf[IFNAMSIZ];
1172 char ifname[IFNAMSIZ + 1];
1173 char extra[100], *pos, *end;
a875087d 1174
4781064b
JM
1175 drv = nl80211_find_drv(global, ifi->ifi_index, buf, len);
1176 if (!drv) {
1177 wpa_printf(MSG_DEBUG, "nl80211: Ignore RTM_NEWLINK event for foreign ifindex %d",
a875087d
JL
1178 ifi->ifi_index);
1179 return;
1180 }
1181
4781064b
JM
1182 extra[0] = '\0';
1183 pos = extra;
1184 end = pos + sizeof(extra);
1185 ifname[0] = '\0';
1186
1187 attrlen = len;
1188 attr = (struct rtattr *) buf;
1189 while (RTA_OK(attr, attrlen)) {
1190 switch (attr->rta_type) {
1191 case IFLA_IFNAME:
1192 if (RTA_PAYLOAD(attr) >= IFNAMSIZ)
1193 break;
1194 os_memcpy(ifname, RTA_DATA(attr), RTA_PAYLOAD(attr));
1195 ifname[RTA_PAYLOAD(attr)] = '\0';
1196 break;
1197 case IFLA_MASTER:
1198 brid = nla_get_u32((struct nlattr *) attr);
1199 pos += os_snprintf(pos, end - pos, " master=%u", brid);
1200 break;
1201 case IFLA_WIRELESS:
1202 pos += os_snprintf(pos, end - pos, " wext");
1203 break;
1204 case IFLA_OPERSTATE:
1205 pos += os_snprintf(pos, end - pos, " operstate=%u",
1206 nla_get_u32((struct nlattr *) attr));
1207 break;
1208 case IFLA_LINKMODE:
1209 pos += os_snprintf(pos, end - pos, " linkmode=%u",
1210 nla_get_u32((struct nlattr *) attr));
1211 break;
1212 }
1213 attr = RTA_NEXT(attr, attrlen);
1214 }
1215 extra[sizeof(extra) - 1] = '\0';
1216
1217 wpa_printf(MSG_DEBUG, "RTM_NEWLINK: ifi_index=%d ifname=%s%s ifi_flags=0x%x (%s%s%s%s)",
1218 ifi->ifi_index, ifname, extra, ifi->ifi_flags,
a875087d
JL
1219 (ifi->ifi_flags & IFF_UP) ? "[UP]" : "",
1220 (ifi->ifi_flags & IFF_RUNNING) ? "[RUNNING]" : "",
1221 (ifi->ifi_flags & IFF_LOWER_UP) ? "[LOWER_UP]" : "",
1222 (ifi->ifi_flags & IFF_DORMANT) ? "[DORMANT]" : "");
4781064b
JM
1223
1224 if (!drv->if_disabled && !(ifi->ifi_flags & IFF_UP)) {
1225 if (if_indextoname(ifi->ifi_index, namebuf) &&
1226 linux_iface_up(drv->global->ioctl_sock,
1227 drv->first_bss->ifname) > 0) {
1228 wpa_printf(MSG_DEBUG, "nl80211: Ignore interface down "
1229 "event since interface %s is up", namebuf);
1230 return;
1231 }
1232 wpa_printf(MSG_DEBUG, "nl80211: Interface down");
1233 if (drv->ignore_if_down_event) {
1234 wpa_printf(MSG_DEBUG, "nl80211: Ignore interface down "
1235 "event generated by mode change");
1236 drv->ignore_if_down_event = 0;
1237 } else {
1238 drv->if_disabled = 1;
1239 wpa_supplicant_event(drv->ctx,
1240 EVENT_INTERFACE_DISABLED, NULL);
1241 }
1242 }
1243
1244 if (drv->if_disabled && (ifi->ifi_flags & IFF_UP)) {
1245 if (if_indextoname(ifi->ifi_index, namebuf) &&
1246 linux_iface_up(drv->global->ioctl_sock,
1247 drv->first_bss->ifname) == 0) {
1248 wpa_printf(MSG_DEBUG, "nl80211: Ignore interface up "
1249 "event since interface %s is down",
1250 namebuf);
1251 } else if (if_nametoindex(drv->first_bss->ifname) == 0) {
1252 wpa_printf(MSG_DEBUG, "nl80211: Ignore interface up "
1253 "event since interface %s does not exist",
1254 drv->first_bss->ifname);
1255 } else if (drv->if_removed) {
1256 wpa_printf(MSG_DEBUG, "nl80211: Ignore interface up "
1257 "event since interface %s is marked "
1258 "removed", drv->first_bss->ifname);
1259 } else {
1260 wpa_printf(MSG_DEBUG, "nl80211: Interface up");
1261 drv->if_disabled = 0;
1262 wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_ENABLED,
1263 NULL);
1264 }
1265 }
1266
a875087d
JL
1267 /*
1268 * Some drivers send the association event before the operup event--in
1269 * this case, lifting operstate in wpa_driver_nl80211_set_operstate()
1270 * fails. This will hit us when wpa_supplicant does not need to do
1271 * IEEE 802.1X authentication
1272 */
1273 if (drv->operstate == 1 &&
1274 (ifi->ifi_flags & (IFF_LOWER_UP | IFF_DORMANT)) == IFF_LOWER_UP &&
4781064b
JM
1275 !(ifi->ifi_flags & IFF_RUNNING)) {
1276 wpa_printf(MSG_DEBUG, "nl80211: Set IF_OPER_UP again based on ifi_flags and expected operstate");
1277 netlink_send_oper_ifla(drv->global->netlink, drv->ifindex,
1278 -1, IF_OPER_UP);
1279 }
a875087d 1280
4781064b
JM
1281 if (ifname[0])
1282 wpa_driver_nl80211_event_newlink(drv, ifname);
1283
1284 if (ifi->ifi_family == AF_BRIDGE && brid) {
1285 /* device has been added to bridge */
1286 if_indextoname(brid, namebuf);
1287 wpa_printf(MSG_DEBUG, "nl80211: Add ifindex %u for bridge %s",
1288 brid, namebuf);
1289 add_ifidx(drv, brid);
1290 }
1291}
1292
1293
1294static void wpa_driver_nl80211_event_rtm_dellink(void *ctx,
1295 struct ifinfomsg *ifi,
1296 u8 *buf, size_t len)
1297{
1298 struct nl80211_global *global = ctx;
1299 struct wpa_driver_nl80211_data *drv;
1300 int attrlen;
1301 struct rtattr *attr;
1302 u32 brid = 0;
1303 char ifname[IFNAMSIZ + 1];
a875087d 1304
4781064b
JM
1305 drv = nl80211_find_drv(global, ifi->ifi_index, buf, len);
1306 if (!drv) {
1307 wpa_printf(MSG_DEBUG, "nl80211: Ignore RTM_DELLINK event for foreign ifindex %d",
1308 ifi->ifi_index);
a875087d 1309 return;
4781064b 1310 }
a875087d 1311
4781064b 1312 ifname[0] = '\0';
a875087d 1313
4781064b
JM
1314 attrlen = len;
1315 attr = (struct rtattr *) buf;
a875087d 1316 while (RTA_OK(attr, attrlen)) {
4781064b
JM
1317 switch (attr->rta_type) {
1318 case IFLA_IFNAME:
1319 if (RTA_PAYLOAD(attr) >= IFNAMSIZ)
1320 break;
1321 os_memcpy(ifname, RTA_DATA(attr), RTA_PAYLOAD(attr));
1322 ifname[RTA_PAYLOAD(attr)] = '\0';
1323 break;
1324 case IFLA_MASTER:
1325 brid = nla_get_u32((struct nlattr *) attr);
1326 break;
a875087d
JL
1327 }
1328 attr = RTA_NEXT(attr, attrlen);
1329 }
4781064b
JM
1330
1331 if (ifname[0])
1332 wpa_driver_nl80211_event_dellink(drv, ifname);
1333
1334 if (ifi->ifi_family == AF_BRIDGE && brid) {
1335 /* device has been removed from bridge */
1336 char namebuf[IFNAMSIZ];
1337 if_indextoname(brid, namebuf);
1338 wpa_printf(MSG_DEBUG, "nl80211: Remove ifindex %u for bridge "
1339 "%s", brid, namebuf);
1340 del_ifidx(drv, brid);
1341 }
a875087d
JL
1342}
1343
1344
4781064b
JM
1345static void mlme_event_auth(struct wpa_driver_nl80211_data *drv,
1346 const u8 *frame, size_t len)
a875087d 1347{
4781064b
JM
1348 const struct ieee80211_mgmt *mgmt;
1349 union wpa_event_data event;
a875087d 1350
4781064b
JM
1351 wpa_printf(MSG_DEBUG, "nl80211: Authenticate event");
1352 mgmt = (const struct ieee80211_mgmt *) frame;
1353 if (len < 24 + sizeof(mgmt->u.auth)) {
1354 wpa_printf(MSG_DEBUG, "nl80211: Too short association event "
1355 "frame");
a875087d 1356 return;
4781064b
JM
1357 }
1358
1359 os_memcpy(drv->auth_bssid, mgmt->sa, ETH_ALEN);
1360 os_memset(drv->auth_attempt_bssid, 0, ETH_ALEN);
1361 os_memset(&event, 0, sizeof(event));
1362 os_memcpy(event.auth.peer, mgmt->sa, ETH_ALEN);
1363 event.auth.auth_type = le_to_host16(mgmt->u.auth.auth_alg);
1364 event.auth.auth_transaction =
1365 le_to_host16(mgmt->u.auth.auth_transaction);
1366 event.auth.status_code = le_to_host16(mgmt->u.auth.status_code);
1367 if (len > 24 + sizeof(mgmt->u.auth)) {
1368 event.auth.ies = mgmt->u.auth.variable;
1369 event.auth.ies_len = len - 24 - sizeof(mgmt->u.auth);
1370 }
a875087d 1371
4781064b
JM
1372 wpa_supplicant_event(drv->ctx, EVENT_AUTH, &event);
1373}
a875087d 1374
a875087d 1375
4781064b
JM
1376static unsigned int nl80211_get_assoc_freq(struct wpa_driver_nl80211_data *drv)
1377{
1378 struct nl_msg *msg;
1379 int ret;
1380 struct nl80211_bss_info_arg arg;
1381
1382 os_memset(&arg, 0, sizeof(arg));
1383 msg = nlmsg_alloc();
1384 if (!msg)
1385 goto nla_put_failure;
a875087d 1386
4781064b
JM
1387 nl80211_cmd(drv, msg, NLM_F_DUMP, NL80211_CMD_GET_SCAN);
1388 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
a875087d 1389
4781064b
JM
1390 arg.drv = drv;
1391 ret = send_and_recv_msgs(drv, msg, bss_info_handler, &arg);
1392 msg = NULL;
1393 if (ret == 0) {
1394 wpa_printf(MSG_DEBUG, "nl80211: Operating frequency for the "
1395 "associated BSS from scan results: %u MHz",
1396 arg.assoc_freq);
1397 if (arg.assoc_freq)
1398 drv->assoc_freq = arg.assoc_freq;
1399 return drv->assoc_freq;
a875087d 1400 }
4781064b
JM
1401 wpa_printf(MSG_DEBUG, "nl80211: Scan result fetch failed: ret=%d "
1402 "(%s)", ret, strerror(-ret));
1403nla_put_failure:
1404 nlmsg_free(msg);
1405 return drv->assoc_freq;
a875087d
JL
1406}
1407
1408
4781064b
JM
1409static void mlme_event_assoc(struct wpa_driver_nl80211_data *drv,
1410 const u8 *frame, size_t len)
a875087d 1411{
4781064b
JM
1412 const struct ieee80211_mgmt *mgmt;
1413 union wpa_event_data event;
1414 u16 status;
a875087d 1415
4781064b
JM
1416 wpa_printf(MSG_DEBUG, "nl80211: Associate event");
1417 mgmt = (const struct ieee80211_mgmt *) frame;
1418 if (len < 24 + sizeof(mgmt->u.assoc_resp)) {
1419 wpa_printf(MSG_DEBUG, "nl80211: Too short association event "
1420 "frame");
a875087d
JL
1421 return;
1422 }
1423
4781064b
JM
1424 status = le_to_host16(mgmt->u.assoc_resp.status_code);
1425 if (status != WLAN_STATUS_SUCCESS) {
1426 os_memset(&event, 0, sizeof(event));
1427 event.assoc_reject.bssid = mgmt->bssid;
1428 if (len > 24 + sizeof(mgmt->u.assoc_resp)) {
1429 event.assoc_reject.resp_ies =
1430 (u8 *) mgmt->u.assoc_resp.variable;
1431 event.assoc_reject.resp_ies_len =
1432 len - 24 - sizeof(mgmt->u.assoc_resp);
a875087d 1433 }
4781064b 1434 event.assoc_reject.status_code = status;
a875087d 1435
4781064b
JM
1436 wpa_supplicant_event(drv->ctx, EVENT_ASSOC_REJECT, &event);
1437 return;
a875087d
JL
1438 }
1439
4781064b
JM
1440 drv->associated = 1;
1441 os_memcpy(drv->bssid, mgmt->sa, ETH_ALEN);
1442 os_memcpy(drv->prev_bssid, mgmt->sa, ETH_ALEN);
a875087d 1443
4781064b
JM
1444 os_memset(&event, 0, sizeof(event));
1445 if (len > 24 + sizeof(mgmt->u.assoc_resp)) {
1446 event.assoc_info.resp_ies = (u8 *) mgmt->u.assoc_resp.variable;
1447 event.assoc_info.resp_ies_len =
1448 len - 24 - sizeof(mgmt->u.assoc_resp);
a875087d 1449 }
a875087d 1450
4781064b 1451 event.assoc_info.freq = drv->assoc_freq;
a875087d 1452
4781064b 1453 wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event);
a875087d
JL
1454}
1455
1456
4781064b
JM
1457static void mlme_event_connect(struct wpa_driver_nl80211_data *drv,
1458 enum nl80211_commands cmd, struct nlattr *status,
1459 struct nlattr *addr, struct nlattr *req_ie,
1460 struct nlattr *resp_ie)
a875087d 1461{
4781064b 1462 union wpa_event_data event;
a875087d 1463
4781064b
JM
1464 if (drv->capa.flags & WPA_DRIVER_FLAGS_SME) {
1465 /*
1466 * Avoid reporting two association events that would confuse
1467 * the core code.
1468 */
1469 wpa_printf(MSG_DEBUG, "nl80211: Ignore connect event (cmd=%d) "
1470 "when using userspace SME", cmd);
1471 return;
1472 }
a875087d 1473
4781064b
JM
1474 if (cmd == NL80211_CMD_CONNECT)
1475 wpa_printf(MSG_DEBUG, "nl80211: Connect event");
1476 else if (cmd == NL80211_CMD_ROAM)
1477 wpa_printf(MSG_DEBUG, "nl80211: Roam event");
1478
1479 os_memset(&event, 0, sizeof(event));
1480 if (cmd == NL80211_CMD_CONNECT &&
1481 nla_get_u16(status) != WLAN_STATUS_SUCCESS) {
1482 if (addr)
1483 event.assoc_reject.bssid = nla_data(addr);
1484 if (resp_ie) {
1485 event.assoc_reject.resp_ies = nla_data(resp_ie);
1486 event.assoc_reject.resp_ies_len = nla_len(resp_ie);
a875087d 1487 }
4781064b
JM
1488 event.assoc_reject.status_code = nla_get_u16(status);
1489 wpa_supplicant_event(drv->ctx, EVENT_ASSOC_REJECT, &event);
1490 return;
a875087d
JL
1491 }
1492
4781064b
JM
1493 drv->associated = 1;
1494 if (addr) {
1495 os_memcpy(drv->bssid, nla_data(addr), ETH_ALEN);
1496 os_memcpy(drv->prev_bssid, drv->bssid, ETH_ALEN);
a875087d
JL
1497 }
1498
4781064b
JM
1499 if (req_ie) {
1500 event.assoc_info.req_ies = nla_data(req_ie);
1501 event.assoc_info.req_ies_len = nla_len(req_ie);
1502 }
1503 if (resp_ie) {
1504 event.assoc_info.resp_ies = nla_data(resp_ie);
1505 event.assoc_info.resp_ies_len = nla_len(resp_ie);
1506 }
1507
1508 event.assoc_info.freq = nl80211_get_assoc_freq(drv);
1509
1510 wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event);
a875087d
JL
1511}
1512
1513
4781064b
JM
1514static void mlme_event_disconnect(struct wpa_driver_nl80211_data *drv,
1515 struct nlattr *reason, struct nlattr *addr,
1516 struct nlattr *by_ap)
a875087d 1517{
4781064b
JM
1518 union wpa_event_data data;
1519 unsigned int locally_generated = by_ap == NULL;
a875087d 1520
4781064b
JM
1521 if (drv->capa.flags & WPA_DRIVER_FLAGS_SME) {
1522 /*
1523 * Avoid reporting two disassociation events that could
1524 * confuse the core code.
1525 */
1526 wpa_printf(MSG_DEBUG, "nl80211: Ignore disconnect "
1527 "event when using userspace SME");
a875087d 1528 return;
4781064b
JM
1529 }
1530
1531 if (drv->ignore_next_local_disconnect) {
1532 drv->ignore_next_local_disconnect = 0;
1533 if (locally_generated) {
1534 wpa_printf(MSG_DEBUG, "nl80211: Ignore disconnect "
1535 "event triggered during reassociation");
1536 return;
1537 }
1538 wpa_printf(MSG_WARNING, "nl80211: Was expecting local "
1539 "disconnect but got another disconnect "
1540 "event first");
1541 }
1542
1543 wpa_printf(MSG_DEBUG, "nl80211: Disconnect event");
1544 nl80211_mark_disconnected(drv);
1545 os_memset(&data, 0, sizeof(data));
1546 if (reason)
1547 data.deauth_info.reason_code = nla_get_u16(reason);
1548 data.deauth_info.locally_generated = by_ap == NULL;
1549 wpa_supplicant_event(drv->ctx, EVENT_DEAUTH, &data);
a875087d
JL
1550}
1551
1552
4781064b 1553static int calculate_chan_offset(int width, int freq, int cf1, int cf2)
a875087d 1554{
4781064b 1555 int freq1 = 0;
a875087d 1556
4781064b
JM
1557 switch (convert2width(width)) {
1558 case CHAN_WIDTH_20_NOHT:
1559 case CHAN_WIDTH_20:
1560 return 0;
1561 case CHAN_WIDTH_40:
1562 freq1 = cf1 - 10;
1563 break;
1564 case CHAN_WIDTH_80:
1565 freq1 = cf1 - 30;
1566 break;
1567 case CHAN_WIDTH_160:
1568 freq1 = cf1 - 70;
1569 break;
1570 case CHAN_WIDTH_UNKNOWN:
1571 case CHAN_WIDTH_80P80:
1572 /* FIXME: implement this */
1573 return 0;
a875087d 1574 }
4781064b
JM
1575
1576 return (abs(freq - freq1) / 20) % 2 == 0 ? 1 : -1;
a875087d
JL
1577}
1578
1579
4781064b
JM
1580static void mlme_event_ch_switch(struct wpa_driver_nl80211_data *drv,
1581 struct nlattr *ifindex, struct nlattr *freq,
1582 struct nlattr *type, struct nlattr *bw,
1583 struct nlattr *cf1, struct nlattr *cf2)
a875087d 1584{
4781064b
JM
1585 struct i802_bss *bss;
1586 union wpa_event_data data;
1587 int ht_enabled = 1;
1588 int chan_offset = 0;
1589 int ifidx;
a875087d 1590
4781064b 1591 wpa_printf(MSG_DEBUG, "nl80211: Channel switch event");
a875087d 1592
4781064b
JM
1593 if (!freq)
1594 return;
a875087d 1595
4781064b
JM
1596 ifidx = nla_get_u32(ifindex);
1597 for (bss = drv->first_bss; bss; bss = bss->next)
1598 if (bss->ifindex == ifidx)
1599 break;
1600
1601 if (bss == NULL) {
1602 wpa_printf(MSG_WARNING, "nl80211: Unknown ifindex (%d) for channel switch, ignoring",
1603 ifidx);
1604 return;
1605 }
1606
1607 if (type) {
1608 switch (nla_get_u32(type)) {
1609 case NL80211_CHAN_NO_HT:
1610 ht_enabled = 0;
1611 break;
1612 case NL80211_CHAN_HT20:
1613 break;
1614 case NL80211_CHAN_HT40PLUS:
1615 chan_offset = 1;
1616 break;
1617 case NL80211_CHAN_HT40MINUS:
1618 chan_offset = -1;
1619 break;
1620 }
1621 } else if (bw && cf1) {
1622 /* This can happen for example with VHT80 ch switch */
1623 chan_offset = calculate_chan_offset(nla_get_u32(bw),
1624 nla_get_u32(freq),
1625 nla_get_u32(cf1),
1626 cf2 ? nla_get_u32(cf2) : 0);
1627 } else {
1628 wpa_printf(MSG_WARNING, "nl80211: Unknown secondary channel information - following channel definition calculations may fail");
1629 }
1630
1631 os_memset(&data, 0, sizeof(data));
1632 data.ch_switch.freq = nla_get_u32(freq);
1633 data.ch_switch.ht_enabled = ht_enabled;
1634 data.ch_switch.ch_offset = chan_offset;
1635 if (bw)
1636 data.ch_switch.ch_width = convert2width(nla_get_u32(bw));
1637 if (cf1)
1638 data.ch_switch.cf1 = nla_get_u32(cf1);
1639 if (cf2)
1640 data.ch_switch.cf2 = nla_get_u32(cf2);
1641
1642 bss->freq = data.ch_switch.freq;
1643
1644 wpa_supplicant_event(drv->ctx, EVENT_CH_SWITCH, &data);
1645}
1646
1647
1648static void mlme_timeout_event(struct wpa_driver_nl80211_data *drv,
1649 enum nl80211_commands cmd, struct nlattr *addr)
1650{
1651 union wpa_event_data event;
1652 enum wpa_event_type ev;
1653
1654 if (nla_len(addr) != ETH_ALEN)
1655 return;
1656
1657 wpa_printf(MSG_DEBUG, "nl80211: MLME event %d; timeout with " MACSTR,
1658 cmd, MAC2STR((u8 *) nla_data(addr)));
1659
1660 if (cmd == NL80211_CMD_AUTHENTICATE)
1661 ev = EVENT_AUTH_TIMED_OUT;
1662 else if (cmd == NL80211_CMD_ASSOCIATE)
1663 ev = EVENT_ASSOC_TIMED_OUT;
1664 else
1665 return;
1666
1667 os_memset(&event, 0, sizeof(event));
1668 os_memcpy(event.timeout_event.addr, nla_data(addr), ETH_ALEN);
1669 wpa_supplicant_event(drv->ctx, ev, &event);
1670}
1671
1672
1673static void mlme_event_mgmt(struct wpa_driver_nl80211_data *drv,
1674 struct nlattr *freq, struct nlattr *sig,
1675 const u8 *frame, size_t len)
1676{
1677 const struct ieee80211_mgmt *mgmt;
1678 union wpa_event_data event;
1679 u16 fc, stype;
1680 int ssi_signal = 0;
1681 int rx_freq = 0;
1682
1683 wpa_printf(MSG_MSGDUMP, "nl80211: Frame event");
1684 mgmt = (const struct ieee80211_mgmt *) frame;
1685 if (len < 24) {
1686 wpa_printf(MSG_DEBUG, "nl80211: Too short management frame");
1687 return;
1688 }
1689
1690 fc = le_to_host16(mgmt->frame_control);
1691 stype = WLAN_FC_GET_STYPE(fc);
1692
1693 if (sig)
1694 ssi_signal = (s32) nla_get_u32(sig);
1695
1696 os_memset(&event, 0, sizeof(event));
1697 if (freq) {
1698 event.rx_mgmt.freq = nla_get_u32(freq);
1699 rx_freq = drv->last_mgmt_freq = event.rx_mgmt.freq;
1700 }
1701 wpa_printf(MSG_DEBUG,
1702 "nl80211: RX frame freq=%d ssi_signal=%d stype=%u len=%u",
1703 rx_freq, ssi_signal, stype, (unsigned int) len);
1704 event.rx_mgmt.frame = frame;
1705 event.rx_mgmt.frame_len = len;
1706 event.rx_mgmt.ssi_signal = ssi_signal;
1707 wpa_supplicant_event(drv->ctx, EVENT_RX_MGMT, &event);
1708}
1709
1710
1711static void mlme_event_mgmt_tx_status(struct wpa_driver_nl80211_data *drv,
1712 struct nlattr *cookie, const u8 *frame,
1713 size_t len, struct nlattr *ack)
1714{
1715 union wpa_event_data event;
1716 const struct ieee80211_hdr *hdr;
1717 u16 fc;
1718
1719 wpa_printf(MSG_DEBUG, "nl80211: Frame TX status event");
1720 if (!is_ap_interface(drv->nlmode)) {
1721 u64 cookie_val;
1722
1723 if (!cookie)
1724 return;
1725
1726 cookie_val = nla_get_u64(cookie);
1727 wpa_printf(MSG_DEBUG, "nl80211: Action TX status:"
1728 " cookie=0%llx%s (ack=%d)",
1729 (long long unsigned int) cookie_val,
1730 cookie_val == drv->send_action_cookie ?
1731 " (match)" : " (unknown)", ack != NULL);
1732 if (cookie_val != drv->send_action_cookie)
1733 return;
1734 }
1735
1736 hdr = (const struct ieee80211_hdr *) frame;
1737 fc = le_to_host16(hdr->frame_control);
1738
1739 os_memset(&event, 0, sizeof(event));
1740 event.tx_status.type = WLAN_FC_GET_TYPE(fc);
1741 event.tx_status.stype = WLAN_FC_GET_STYPE(fc);
1742 event.tx_status.dst = hdr->addr1;
1743 event.tx_status.data = frame;
1744 event.tx_status.data_len = len;
1745 event.tx_status.ack = ack != NULL;
1746 wpa_supplicant_event(drv->ctx, EVENT_TX_STATUS, &event);
1747}
1748
1749
1750static void mlme_event_deauth_disassoc(struct wpa_driver_nl80211_data *drv,
1751 enum wpa_event_type type,
1752 const u8 *frame, size_t len)
1753{
1754 const struct ieee80211_mgmt *mgmt;
1755 union wpa_event_data event;
1756 const u8 *bssid = NULL;
1757 u16 reason_code = 0;
1758
1759 if (type == EVENT_DEAUTH)
1760 wpa_printf(MSG_DEBUG, "nl80211: Deauthenticate event");
1761 else
1762 wpa_printf(MSG_DEBUG, "nl80211: Disassociate event");
1763
1764 mgmt = (const struct ieee80211_mgmt *) frame;
1765 if (len >= 24) {
1766 bssid = mgmt->bssid;
1767
1768 if ((drv->capa.flags & WPA_DRIVER_FLAGS_SME) &&
1769 !drv->associated &&
1770 os_memcmp(bssid, drv->auth_bssid, ETH_ALEN) != 0 &&
1771 os_memcmp(bssid, drv->auth_attempt_bssid, ETH_ALEN) != 0 &&
1772 os_memcmp(bssid, drv->prev_bssid, ETH_ALEN) == 0) {
1773 /*
1774 * Avoid issues with some roaming cases where
1775 * disconnection event for the old AP may show up after
1776 * we have started connection with the new AP.
1777 */
1778 wpa_printf(MSG_DEBUG, "nl80211: Ignore deauth/disassoc event from old AP " MACSTR " when already authenticating with " MACSTR,
1779 MAC2STR(bssid),
1780 MAC2STR(drv->auth_attempt_bssid));
1781 return;
1782 }
1783
1784 if (drv->associated != 0 &&
1785 os_memcmp(bssid, drv->bssid, ETH_ALEN) != 0 &&
1786 os_memcmp(bssid, drv->auth_bssid, ETH_ALEN) != 0) {
1787 /*
1788 * We have presumably received this deauth as a
1789 * response to a clear_state_mismatch() outgoing
1790 * deauth. Don't let it take us offline!
1791 */
1792 wpa_printf(MSG_DEBUG, "nl80211: Deauth received "
1793 "from Unknown BSSID " MACSTR " -- ignoring",
1794 MAC2STR(bssid));
1795 return;
1796 }
1797 }
1798
1799 nl80211_mark_disconnected(drv);
1800 os_memset(&event, 0, sizeof(event));
1801
1802 /* Note: Same offset for Reason Code in both frame subtypes */
1803 if (len >= 24 + sizeof(mgmt->u.deauth))
1804 reason_code = le_to_host16(mgmt->u.deauth.reason_code);
1805
1806 if (type == EVENT_DISASSOC) {
1807 event.disassoc_info.locally_generated =
1808 !os_memcmp(mgmt->sa, drv->first_bss->addr, ETH_ALEN);
1809 event.disassoc_info.addr = bssid;
1810 event.disassoc_info.reason_code = reason_code;
1811 if (frame + len > mgmt->u.disassoc.variable) {
1812 event.disassoc_info.ie = mgmt->u.disassoc.variable;
1813 event.disassoc_info.ie_len = frame + len -
1814 mgmt->u.disassoc.variable;
1815 }
1816 } else {
1817 event.deauth_info.locally_generated =
1818 !os_memcmp(mgmt->sa, drv->first_bss->addr, ETH_ALEN);
1819 event.deauth_info.addr = bssid;
1820 event.deauth_info.reason_code = reason_code;
1821 if (frame + len > mgmt->u.deauth.variable) {
1822 event.deauth_info.ie = mgmt->u.deauth.variable;
1823 event.deauth_info.ie_len = frame + len -
1824 mgmt->u.deauth.variable;
1825 }
1826 }
1827
1828 wpa_supplicant_event(drv->ctx, type, &event);
1829}
1830
1831
1832static void mlme_event_unprot_disconnect(struct wpa_driver_nl80211_data *drv,
1833 enum wpa_event_type type,
1834 const u8 *frame, size_t len)
1835{
1836 const struct ieee80211_mgmt *mgmt;
1837 union wpa_event_data event;
1838 u16 reason_code = 0;
1839
1840 if (type == EVENT_UNPROT_DEAUTH)
1841 wpa_printf(MSG_DEBUG, "nl80211: Unprot Deauthenticate event");
1842 else
1843 wpa_printf(MSG_DEBUG, "nl80211: Unprot Disassociate event");
1844
1845 if (len < 24)
1846 return;
1847
1848 mgmt = (const struct ieee80211_mgmt *) frame;
1849
1850 os_memset(&event, 0, sizeof(event));
1851 /* Note: Same offset for Reason Code in both frame subtypes */
1852 if (len >= 24 + sizeof(mgmt->u.deauth))
1853 reason_code = le_to_host16(mgmt->u.deauth.reason_code);
1854
1855 if (type == EVENT_UNPROT_DISASSOC) {
1856 event.unprot_disassoc.sa = mgmt->sa;
1857 event.unprot_disassoc.da = mgmt->da;
1858 event.unprot_disassoc.reason_code = reason_code;
1859 } else {
1860 event.unprot_deauth.sa = mgmt->sa;
1861 event.unprot_deauth.da = mgmt->da;
1862 event.unprot_deauth.reason_code = reason_code;
1863 }
1864
1865 wpa_supplicant_event(drv->ctx, type, &event);
1866}
1867
1868
1869static void mlme_event(struct i802_bss *bss,
1870 enum nl80211_commands cmd, struct nlattr *frame,
1871 struct nlattr *addr, struct nlattr *timed_out,
1872 struct nlattr *freq, struct nlattr *ack,
1873 struct nlattr *cookie, struct nlattr *sig)
1874{
1875 struct wpa_driver_nl80211_data *drv = bss->drv;
1876 const u8 *data;
1877 size_t len;
1878
1879 if (timed_out && addr) {
1880 mlme_timeout_event(drv, cmd, addr);
1881 return;
1882 }
1883
1884 if (frame == NULL) {
1885 wpa_printf(MSG_DEBUG,
1886 "nl80211: MLME event %d (%s) without frame data",
1887 cmd, nl80211_command_to_string(cmd));
1888 return;
1889 }
1890
1891 data = nla_data(frame);
1892 len = nla_len(frame);
1893 if (len < 4 + 2 * ETH_ALEN) {
1894 wpa_printf(MSG_MSGDUMP, "nl80211: MLME event %d (%s) on %s("
1895 MACSTR ") - too short",
1896 cmd, nl80211_command_to_string(cmd), bss->ifname,
1897 MAC2STR(bss->addr));
1898 return;
1899 }
1900 wpa_printf(MSG_MSGDUMP, "nl80211: MLME event %d (%s) on %s(" MACSTR
1901 ") A1=" MACSTR " A2=" MACSTR, cmd,
1902 nl80211_command_to_string(cmd), bss->ifname,
1903 MAC2STR(bss->addr), MAC2STR(data + 4),
1904 MAC2STR(data + 4 + ETH_ALEN));
1905 if (cmd != NL80211_CMD_FRAME_TX_STATUS && !(data[4] & 0x01) &&
1906 os_memcmp(bss->addr, data + 4, ETH_ALEN) != 0 &&
1907 os_memcmp(bss->addr, data + 4 + ETH_ALEN, ETH_ALEN) != 0) {
1908 wpa_printf(MSG_MSGDUMP, "nl80211: %s: Ignore MLME frame event "
1909 "for foreign address", bss->ifname);
1910 return;
1911 }
1912 wpa_hexdump(MSG_MSGDUMP, "nl80211: MLME event frame",
1913 nla_data(frame), nla_len(frame));
1914
1915 switch (cmd) {
1916 case NL80211_CMD_AUTHENTICATE:
1917 mlme_event_auth(drv, nla_data(frame), nla_len(frame));
1918 break;
1919 case NL80211_CMD_ASSOCIATE:
1920 mlme_event_assoc(drv, nla_data(frame), nla_len(frame));
1921 break;
1922 case NL80211_CMD_DEAUTHENTICATE:
1923 mlme_event_deauth_disassoc(drv, EVENT_DEAUTH,
1924 nla_data(frame), nla_len(frame));
1925 break;
1926 case NL80211_CMD_DISASSOCIATE:
1927 mlme_event_deauth_disassoc(drv, EVENT_DISASSOC,
1928 nla_data(frame), nla_len(frame));
1929 break;
1930 case NL80211_CMD_FRAME:
1931 mlme_event_mgmt(drv, freq, sig, nla_data(frame),
1932 nla_len(frame));
1933 break;
1934 case NL80211_CMD_FRAME_TX_STATUS:
1935 mlme_event_mgmt_tx_status(drv, cookie, nla_data(frame),
1936 nla_len(frame), ack);
1937 break;
1938 case NL80211_CMD_UNPROT_DEAUTHENTICATE:
1939 mlme_event_unprot_disconnect(drv, EVENT_UNPROT_DEAUTH,
1940 nla_data(frame), nla_len(frame));
1941 break;
1942 case NL80211_CMD_UNPROT_DISASSOCIATE:
1943 mlme_event_unprot_disconnect(drv, EVENT_UNPROT_DISASSOC,
1944 nla_data(frame), nla_len(frame));
1945 break;
1946 default:
1947 break;
1948 }
1949}
1950
1951
1952static void mlme_event_michael_mic_failure(struct i802_bss *bss,
1953 struct nlattr *tb[])
1954{
1955 union wpa_event_data data;
1956
1957 wpa_printf(MSG_DEBUG, "nl80211: MLME event Michael MIC failure");
1958 os_memset(&data, 0, sizeof(data));
1959 if (tb[NL80211_ATTR_MAC]) {
1960 wpa_hexdump(MSG_DEBUG, "nl80211: Source MAC address",
1961 nla_data(tb[NL80211_ATTR_MAC]),
1962 nla_len(tb[NL80211_ATTR_MAC]));
1963 data.michael_mic_failure.src = nla_data(tb[NL80211_ATTR_MAC]);
1964 }
1965 if (tb[NL80211_ATTR_KEY_SEQ]) {
1966 wpa_hexdump(MSG_DEBUG, "nl80211: TSC",
1967 nla_data(tb[NL80211_ATTR_KEY_SEQ]),
1968 nla_len(tb[NL80211_ATTR_KEY_SEQ]));
1969 }
1970 if (tb[NL80211_ATTR_KEY_TYPE]) {
1971 enum nl80211_key_type key_type =
1972 nla_get_u32(tb[NL80211_ATTR_KEY_TYPE]);
1973 wpa_printf(MSG_DEBUG, "nl80211: Key Type %d", key_type);
1974 if (key_type == NL80211_KEYTYPE_PAIRWISE)
1975 data.michael_mic_failure.unicast = 1;
1976 } else
1977 data.michael_mic_failure.unicast = 1;
1978
1979 if (tb[NL80211_ATTR_KEY_IDX]) {
1980 u8 key_id = nla_get_u8(tb[NL80211_ATTR_KEY_IDX]);
1981 wpa_printf(MSG_DEBUG, "nl80211: Key Id %d", key_id);
1982 }
1983
1984 wpa_supplicant_event(bss->ctx, EVENT_MICHAEL_MIC_FAILURE, &data);
1985}
1986
1987
1988static void mlme_event_join_ibss(struct wpa_driver_nl80211_data *drv,
1989 struct nlattr *tb[])
1990{
1991 if (tb[NL80211_ATTR_MAC] == NULL) {
1992 wpa_printf(MSG_DEBUG, "nl80211: No address in IBSS joined "
1993 "event");
1994 return;
1995 }
1996 os_memcpy(drv->bssid, nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
1997
1998 drv->associated = 1;
1999 wpa_printf(MSG_DEBUG, "nl80211: IBSS " MACSTR " joined",
2000 MAC2STR(drv->bssid));
2001
2002 wpa_supplicant_event(drv->ctx, EVENT_ASSOC, NULL);
2003}
2004
2005
2006static void mlme_event_remain_on_channel(struct wpa_driver_nl80211_data *drv,
2007 int cancel_event, struct nlattr *tb[])
2008{
2009 unsigned int freq, chan_type, duration;
2010 union wpa_event_data data;
2011 u64 cookie;
2012
2013 if (tb[NL80211_ATTR_WIPHY_FREQ])
2014 freq = nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]);
2015 else
2016 freq = 0;
2017
2018 if (tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE])
2019 chan_type = nla_get_u32(tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
2020 else
2021 chan_type = 0;
2022
2023 if (tb[NL80211_ATTR_DURATION])
2024 duration = nla_get_u32(tb[NL80211_ATTR_DURATION]);
2025 else
2026 duration = 0;
2027
2028 if (tb[NL80211_ATTR_COOKIE])
2029 cookie = nla_get_u64(tb[NL80211_ATTR_COOKIE]);
2030 else
2031 cookie = 0;
2032
2033 wpa_printf(MSG_DEBUG, "nl80211: Remain-on-channel event (cancel=%d "
2034 "freq=%u channel_type=%u duration=%u cookie=0x%llx (%s))",
2035 cancel_event, freq, chan_type, duration,
2036 (long long unsigned int) cookie,
2037 cookie == drv->remain_on_chan_cookie ? "match" : "unknown");
2038
2039 if (cookie != drv->remain_on_chan_cookie)
2040 return; /* not for us */
2041
2042 if (cancel_event)
2043 drv->pending_remain_on_chan = 0;
2044
2045 os_memset(&data, 0, sizeof(data));
2046 data.remain_on_channel.freq = freq;
2047 data.remain_on_channel.duration = duration;
2048 wpa_supplicant_event(drv->ctx, cancel_event ?
2049 EVENT_CANCEL_REMAIN_ON_CHANNEL :
2050 EVENT_REMAIN_ON_CHANNEL, &data);
2051}
2052
2053
2054static void mlme_event_ft_event(struct wpa_driver_nl80211_data *drv,
2055 struct nlattr *tb[])
2056{
2057 union wpa_event_data data;
2058
2059 os_memset(&data, 0, sizeof(data));
2060
2061 if (tb[NL80211_ATTR_IE]) {
2062 data.ft_ies.ies = nla_data(tb[NL80211_ATTR_IE]);
2063 data.ft_ies.ies_len = nla_len(tb[NL80211_ATTR_IE]);
2064 }
2065
2066 if (tb[NL80211_ATTR_IE_RIC]) {
2067 data.ft_ies.ric_ies = nla_data(tb[NL80211_ATTR_IE_RIC]);
2068 data.ft_ies.ric_ies_len = nla_len(tb[NL80211_ATTR_IE_RIC]);
2069 }
2070
2071 if (tb[NL80211_ATTR_MAC])
2072 os_memcpy(data.ft_ies.target_ap,
2073 nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
2074
2075 wpa_printf(MSG_DEBUG, "nl80211: FT event target_ap " MACSTR,
2076 MAC2STR(data.ft_ies.target_ap));
2077
2078 wpa_supplicant_event(drv->ctx, EVENT_FT_RESPONSE, &data);
2079}
2080
2081
2082static void send_scan_event(struct wpa_driver_nl80211_data *drv, int aborted,
2083 struct nlattr *tb[])
2084{
2085 union wpa_event_data event;
2086 struct nlattr *nl;
2087 int rem;
2088 struct scan_info *info;
2089#define MAX_REPORT_FREQS 50
2090 int freqs[MAX_REPORT_FREQS];
2091 int num_freqs = 0;
2092
2093 if (drv->scan_for_auth) {
2094 drv->scan_for_auth = 0;
2095 wpa_printf(MSG_DEBUG, "nl80211: Scan results for missing "
2096 "cfg80211 BSS entry");
2097 wpa_driver_nl80211_authenticate_retry(drv);
2098 return;
2099 }
2100
2101 os_memset(&event, 0, sizeof(event));
2102 info = &event.scan_info;
2103 info->aborted = aborted;
2104
2105 if (tb[NL80211_ATTR_SCAN_SSIDS]) {
2106 nla_for_each_nested(nl, tb[NL80211_ATTR_SCAN_SSIDS], rem) {
2107 struct wpa_driver_scan_ssid *s =
2108 &info->ssids[info->num_ssids];
2109 s->ssid = nla_data(nl);
2110 s->ssid_len = nla_len(nl);
2111 wpa_printf(MSG_DEBUG, "nl80211: Scan probed for SSID '%s'",
2112 wpa_ssid_txt(s->ssid, s->ssid_len));
2113 info->num_ssids++;
2114 if (info->num_ssids == WPAS_MAX_SCAN_SSIDS)
2115 break;
2116 }
2117 }
2118 if (tb[NL80211_ATTR_SCAN_FREQUENCIES]) {
2119 char msg[200], *pos, *end;
2120 int res;
2121
2122 pos = msg;
2123 end = pos + sizeof(msg);
2124 *pos = '\0';
2125
2126 nla_for_each_nested(nl, tb[NL80211_ATTR_SCAN_FREQUENCIES], rem)
2127 {
2128 freqs[num_freqs] = nla_get_u32(nl);
2129 res = os_snprintf(pos, end - pos, " %d",
2130 freqs[num_freqs]);
2131 if (res > 0 && end - pos > res)
2132 pos += res;
2133 num_freqs++;
2134 if (num_freqs == MAX_REPORT_FREQS - 1)
2135 break;
2136 }
2137 info->freqs = freqs;
2138 info->num_freqs = num_freqs;
2139 wpa_printf(MSG_DEBUG, "nl80211: Scan included frequencies:%s",
2140 msg);
2141 }
2142 wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS, &event);
2143}
2144
2145
2146static int get_link_signal(struct nl_msg *msg, void *arg)
2147{
2148 struct nlattr *tb[NL80211_ATTR_MAX + 1];
2149 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
2150 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
2151 static struct nla_policy policy[NL80211_STA_INFO_MAX + 1] = {
2152 [NL80211_STA_INFO_SIGNAL] = { .type = NLA_U8 },
2153 [NL80211_STA_INFO_SIGNAL_AVG] = { .type = NLA_U8 },
2154 };
2155 struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
2156 static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = {
2157 [NL80211_RATE_INFO_BITRATE] = { .type = NLA_U16 },
2158 [NL80211_RATE_INFO_MCS] = { .type = NLA_U8 },
2159 [NL80211_RATE_INFO_40_MHZ_WIDTH] = { .type = NLA_FLAG },
2160 [NL80211_RATE_INFO_SHORT_GI] = { .type = NLA_FLAG },
2161 };
2162 struct wpa_signal_info *sig_change = arg;
2163
2164 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
2165 genlmsg_attrlen(gnlh, 0), NULL);
2166 if (!tb[NL80211_ATTR_STA_INFO] ||
2167 nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,
2168 tb[NL80211_ATTR_STA_INFO], policy))
2169 return NL_SKIP;
2170 if (!sinfo[NL80211_STA_INFO_SIGNAL])
2171 return NL_SKIP;
2172
2173 sig_change->current_signal =
2174 (s8) nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL]);
2175
2176 if (sinfo[NL80211_STA_INFO_SIGNAL_AVG])
2177 sig_change->avg_signal =
2178 (s8) nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL_AVG]);
2179 else
2180 sig_change->avg_signal = 0;
2181
2182 if (sinfo[NL80211_STA_INFO_TX_BITRATE]) {
2183 if (nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX,
2184 sinfo[NL80211_STA_INFO_TX_BITRATE],
2185 rate_policy)) {
2186 sig_change->current_txrate = 0;
2187 } else {
2188 if (rinfo[NL80211_RATE_INFO_BITRATE]) {
2189 sig_change->current_txrate =
2190 nla_get_u16(rinfo[
2191 NL80211_RATE_INFO_BITRATE]) * 100;
2192 }
2193 }
2194 }
2195
2196 return NL_SKIP;
2197}
2198
2199
2200static int nl80211_get_link_signal(struct wpa_driver_nl80211_data *drv,
2201 struct wpa_signal_info *sig)
2202{
2203 struct nl_msg *msg;
2204
2205 sig->current_signal = -9999;
2206 sig->current_txrate = 0;
2207
2208 msg = nlmsg_alloc();
2209 if (!msg)
2210 return -ENOMEM;
2211
2212 nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_STATION);
2213
2214 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
2215 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, drv->bssid);
2216
2217 return send_and_recv_msgs(drv, msg, get_link_signal, sig);
2218 nla_put_failure:
2219 nlmsg_free(msg);
2220 return -ENOBUFS;
2221}
2222
2223
2224static int get_link_noise(struct nl_msg *msg, void *arg)
2225{
2226 struct nlattr *tb[NL80211_ATTR_MAX + 1];
2227 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
2228 struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1];
2229 static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = {
2230 [NL80211_SURVEY_INFO_FREQUENCY] = { .type = NLA_U32 },
2231 [NL80211_SURVEY_INFO_NOISE] = { .type = NLA_U8 },
2232 };
2233 struct wpa_signal_info *sig_change = arg;
2234
2235 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
2236 genlmsg_attrlen(gnlh, 0), NULL);
2237
2238 if (!tb[NL80211_ATTR_SURVEY_INFO]) {
2239 wpa_printf(MSG_DEBUG, "nl80211: survey data missing!");
2240 return NL_SKIP;
2241 }
2242
2243 if (nla_parse_nested(sinfo, NL80211_SURVEY_INFO_MAX,
2244 tb[NL80211_ATTR_SURVEY_INFO],
2245 survey_policy)) {
2246 wpa_printf(MSG_DEBUG, "nl80211: failed to parse nested "
2247 "attributes!");
2248 return NL_SKIP;
2249 }
2250
2251 if (!sinfo[NL80211_SURVEY_INFO_FREQUENCY])
2252 return NL_SKIP;
2253
2254 if (nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]) !=
2255 sig_change->frequency)
2256 return NL_SKIP;
2257
2258 if (!sinfo[NL80211_SURVEY_INFO_NOISE])
2259 return NL_SKIP;
2260
2261 sig_change->current_noise =
2262 (s8) nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
2263
2264 return NL_SKIP;
2265}
2266
2267
2268static int nl80211_get_link_noise(struct wpa_driver_nl80211_data *drv,
2269 struct wpa_signal_info *sig_change)
2270{
2271 struct nl_msg *msg;
2272
2273 sig_change->current_noise = 9999;
2274 sig_change->frequency = drv->assoc_freq;
2275
2276 msg = nlmsg_alloc();
2277 if (!msg)
2278 return -ENOMEM;
2279
2280 nl80211_cmd(drv, msg, NLM_F_DUMP, NL80211_CMD_GET_SURVEY);
2281
2282 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
2283
2284 return send_and_recv_msgs(drv, msg, get_link_noise, sig_change);
2285 nla_put_failure:
2286 nlmsg_free(msg);
2287 return -ENOBUFS;
2288}
2289
2290
2291static int get_noise_for_scan_results(struct nl_msg *msg, void *arg)
2292{
2293 struct nlattr *tb[NL80211_ATTR_MAX + 1];
2294 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
2295 struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1];
2296 static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = {
2297 [NL80211_SURVEY_INFO_FREQUENCY] = { .type = NLA_U32 },
2298 [NL80211_SURVEY_INFO_NOISE] = { .type = NLA_U8 },
2299 };
2300 struct wpa_scan_results *scan_results = arg;
2301 struct wpa_scan_res *scan_res;
2302 size_t i;
2303
2304 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
2305 genlmsg_attrlen(gnlh, 0), NULL);
2306
2307 if (!tb[NL80211_ATTR_SURVEY_INFO]) {
2308 wpa_printf(MSG_DEBUG, "nl80211: Survey data missing");
2309 return NL_SKIP;
2310 }
2311
2312 if (nla_parse_nested(sinfo, NL80211_SURVEY_INFO_MAX,
2313 tb[NL80211_ATTR_SURVEY_INFO],
2314 survey_policy)) {
2315 wpa_printf(MSG_DEBUG, "nl80211: Failed to parse nested "
2316 "attributes");
2317 return NL_SKIP;
2318 }
2319
2320 if (!sinfo[NL80211_SURVEY_INFO_NOISE])
2321 return NL_SKIP;
2322
2323 if (!sinfo[NL80211_SURVEY_INFO_FREQUENCY])
2324 return NL_SKIP;
2325
2326 for (i = 0; i < scan_results->num; ++i) {
2327 scan_res = scan_results->res[i];
2328 if (!scan_res)
2329 continue;
2330 if ((int) nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]) !=
2331 scan_res->freq)
2332 continue;
2333 if (!(scan_res->flags & WPA_SCAN_NOISE_INVALID))
2334 continue;
2335 scan_res->noise = (s8)
2336 nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
2337 scan_res->flags &= ~WPA_SCAN_NOISE_INVALID;
2338 }
2339
2340 return NL_SKIP;
2341}
2342
2343
2344static int nl80211_get_noise_for_scan_results(
2345 struct wpa_driver_nl80211_data *drv,
2346 struct wpa_scan_results *scan_res)
2347{
2348 struct nl_msg *msg;
2349
2350 msg = nlmsg_alloc();
2351 if (!msg)
2352 return -ENOMEM;
2353
2354 nl80211_cmd(drv, msg, NLM_F_DUMP, NL80211_CMD_GET_SURVEY);
2355
2356 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
2357
2358 return send_and_recv_msgs(drv, msg, get_noise_for_scan_results,
2359 scan_res);
2360 nla_put_failure:
2361 nlmsg_free(msg);
2362 return -ENOBUFS;
2363}
2364
2365
2366static void nl80211_cqm_event(struct wpa_driver_nl80211_data *drv,
2367 struct nlattr *tb[])
2368{
2369 static struct nla_policy cqm_policy[NL80211_ATTR_CQM_MAX + 1] = {
2370 [NL80211_ATTR_CQM_RSSI_THOLD] = { .type = NLA_U32 },
2371 [NL80211_ATTR_CQM_RSSI_HYST] = { .type = NLA_U8 },
2372 [NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] = { .type = NLA_U32 },
2373 [NL80211_ATTR_CQM_PKT_LOSS_EVENT] = { .type = NLA_U32 },
2374 };
2375 struct nlattr *cqm[NL80211_ATTR_CQM_MAX + 1];
2376 enum nl80211_cqm_rssi_threshold_event event;
2377 union wpa_event_data ed;
2378 struct wpa_signal_info sig;
2379 int res;
2380
2381 if (tb[NL80211_ATTR_CQM] == NULL ||
2382 nla_parse_nested(cqm, NL80211_ATTR_CQM_MAX, tb[NL80211_ATTR_CQM],
2383 cqm_policy)) {
2384 wpa_printf(MSG_DEBUG, "nl80211: Ignore invalid CQM event");
2385 return;
2386 }
2387
2388 os_memset(&ed, 0, sizeof(ed));
2389
2390 if (cqm[NL80211_ATTR_CQM_PKT_LOSS_EVENT]) {
2391 if (!tb[NL80211_ATTR_MAC])
2392 return;
2393 os_memcpy(ed.low_ack.addr, nla_data(tb[NL80211_ATTR_MAC]),
2394 ETH_ALEN);
2395 wpa_supplicant_event(drv->ctx, EVENT_STATION_LOW_ACK, &ed);
2396 return;
2397 }
2398
2399 if (cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] == NULL)
2400 return;
2401 event = nla_get_u32(cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT]);
2402
2403 if (event == NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH) {
2404 wpa_printf(MSG_DEBUG, "nl80211: Connection quality monitor "
2405 "event: RSSI high");
2406 ed.signal_change.above_threshold = 1;
2407 } else if (event == NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW) {
2408 wpa_printf(MSG_DEBUG, "nl80211: Connection quality monitor "
2409 "event: RSSI low");
2410 ed.signal_change.above_threshold = 0;
2411 } else
2412 return;
2413
2414 res = nl80211_get_link_signal(drv, &sig);
2415 if (res == 0) {
2416 ed.signal_change.current_signal = sig.current_signal;
2417 ed.signal_change.current_txrate = sig.current_txrate;
2418 wpa_printf(MSG_DEBUG, "nl80211: Signal: %d dBm txrate: %d",
2419 sig.current_signal, sig.current_txrate);
2420 }
2421
2422 res = nl80211_get_link_noise(drv, &sig);
2423 if (res == 0) {
2424 ed.signal_change.current_noise = sig.current_noise;
2425 wpa_printf(MSG_DEBUG, "nl80211: Noise: %d dBm",
2426 sig.current_noise);
2427 }
2428
2429 wpa_supplicant_event(drv->ctx, EVENT_SIGNAL_CHANGE, &ed);
2430}
2431
2432
2433static void nl80211_new_station_event(struct wpa_driver_nl80211_data *drv,
2434 struct nlattr **tb)
2435{
2436 u8 *addr;
2437 union wpa_event_data data;
2438
2439 if (tb[NL80211_ATTR_MAC] == NULL)
2440 return;
2441 addr = nla_data(tb[NL80211_ATTR_MAC]);
2442 wpa_printf(MSG_DEBUG, "nl80211: New station " MACSTR, MAC2STR(addr));
2443
2444 if (is_ap_interface(drv->nlmode) && drv->device_ap_sme) {
2445 u8 *ies = NULL;
2446 size_t ies_len = 0;
2447 if (tb[NL80211_ATTR_IE]) {
2448 ies = nla_data(tb[NL80211_ATTR_IE]);
2449 ies_len = nla_len(tb[NL80211_ATTR_IE]);
2450 }
2451 wpa_hexdump(MSG_DEBUG, "nl80211: Assoc Req IEs", ies, ies_len);
2452 drv_event_assoc(drv->ctx, addr, ies, ies_len, 0);
2453 return;
2454 }
2455
2456 if (drv->nlmode != NL80211_IFTYPE_ADHOC)
2457 return;
2458
2459 os_memset(&data, 0, sizeof(data));
2460 os_memcpy(data.ibss_rsn_start.peer, addr, ETH_ALEN);
2461 wpa_supplicant_event(drv->ctx, EVENT_IBSS_RSN_START, &data);
2462}
2463
2464
2465static void nl80211_del_station_event(struct wpa_driver_nl80211_data *drv,
2466 struct nlattr **tb)
2467{
2468 u8 *addr;
2469 union wpa_event_data data;
2470
2471 if (tb[NL80211_ATTR_MAC] == NULL)
2472 return;
2473 addr = nla_data(tb[NL80211_ATTR_MAC]);
2474 wpa_printf(MSG_DEBUG, "nl80211: Delete station " MACSTR,
2475 MAC2STR(addr));
2476
2477 if (is_ap_interface(drv->nlmode) && drv->device_ap_sme) {
2478 drv_event_disassoc(drv->ctx, addr);
2479 return;
2480 }
2481
2482 if (drv->nlmode != NL80211_IFTYPE_ADHOC)
2483 return;
2484
2485 os_memset(&data, 0, sizeof(data));
2486 os_memcpy(data.ibss_peer_lost.peer, addr, ETH_ALEN);
2487 wpa_supplicant_event(drv->ctx, EVENT_IBSS_PEER_LOST, &data);
2488}
2489
2490
2491static void nl80211_rekey_offload_event(struct wpa_driver_nl80211_data *drv,
2492 struct nlattr **tb)
2493{
2494 struct nlattr *rekey_info[NUM_NL80211_REKEY_DATA];
2495 static struct nla_policy rekey_policy[NUM_NL80211_REKEY_DATA] = {
2496 [NL80211_REKEY_DATA_KEK] = {
2497 .minlen = NL80211_KEK_LEN,
2498 .maxlen = NL80211_KEK_LEN,
2499 },
2500 [NL80211_REKEY_DATA_KCK] = {
2501 .minlen = NL80211_KCK_LEN,
2502 .maxlen = NL80211_KCK_LEN,
2503 },
2504 [NL80211_REKEY_DATA_REPLAY_CTR] = {
2505 .minlen = NL80211_REPLAY_CTR_LEN,
2506 .maxlen = NL80211_REPLAY_CTR_LEN,
2507 },
2508 };
2509 union wpa_event_data data;
2510
2511 if (!tb[NL80211_ATTR_MAC])
2512 return;
2513 if (!tb[NL80211_ATTR_REKEY_DATA])
2514 return;
2515 if (nla_parse_nested(rekey_info, MAX_NL80211_REKEY_DATA,
2516 tb[NL80211_ATTR_REKEY_DATA], rekey_policy))
2517 return;
2518 if (!rekey_info[NL80211_REKEY_DATA_REPLAY_CTR])
2519 return;
2520
2521 os_memset(&data, 0, sizeof(data));
2522 data.driver_gtk_rekey.bssid = nla_data(tb[NL80211_ATTR_MAC]);
2523 wpa_printf(MSG_DEBUG, "nl80211: Rekey offload event for BSSID " MACSTR,
2524 MAC2STR(data.driver_gtk_rekey.bssid));
2525 data.driver_gtk_rekey.replay_ctr =
2526 nla_data(rekey_info[NL80211_REKEY_DATA_REPLAY_CTR]);
2527 wpa_hexdump(MSG_DEBUG, "nl80211: Rekey offload - Replay Counter",
2528 data.driver_gtk_rekey.replay_ctr, NL80211_REPLAY_CTR_LEN);
2529 wpa_supplicant_event(drv->ctx, EVENT_DRIVER_GTK_REKEY, &data);
2530}
2531
2532
2533static void nl80211_pmksa_candidate_event(struct wpa_driver_nl80211_data *drv,
2534 struct nlattr **tb)
2535{
2536 struct nlattr *cand[NUM_NL80211_PMKSA_CANDIDATE];
2537 static struct nla_policy cand_policy[NUM_NL80211_PMKSA_CANDIDATE] = {
2538 [NL80211_PMKSA_CANDIDATE_INDEX] = { .type = NLA_U32 },
2539 [NL80211_PMKSA_CANDIDATE_BSSID] = {
2540 .minlen = ETH_ALEN,
2541 .maxlen = ETH_ALEN,
2542 },
2543 [NL80211_PMKSA_CANDIDATE_PREAUTH] = { .type = NLA_FLAG },
2544 };
2545 union wpa_event_data data;
2546
2547 wpa_printf(MSG_DEBUG, "nl80211: PMKSA candidate event");
2548
2549 if (!tb[NL80211_ATTR_PMKSA_CANDIDATE])
2550 return;
2551 if (nla_parse_nested(cand, MAX_NL80211_PMKSA_CANDIDATE,
2552 tb[NL80211_ATTR_PMKSA_CANDIDATE], cand_policy))
2553 return;
2554 if (!cand[NL80211_PMKSA_CANDIDATE_INDEX] ||
2555 !cand[NL80211_PMKSA_CANDIDATE_BSSID])
2556 return;
2557
2558 os_memset(&data, 0, sizeof(data));
2559 os_memcpy(data.pmkid_candidate.bssid,
2560 nla_data(cand[NL80211_PMKSA_CANDIDATE_BSSID]), ETH_ALEN);
2561 data.pmkid_candidate.index =
2562 nla_get_u32(cand[NL80211_PMKSA_CANDIDATE_INDEX]);
2563 data.pmkid_candidate.preauth =
2564 cand[NL80211_PMKSA_CANDIDATE_PREAUTH] != NULL;
2565 wpa_supplicant_event(drv->ctx, EVENT_PMKID_CANDIDATE, &data);
2566}
2567
2568
2569static void nl80211_client_probe_event(struct wpa_driver_nl80211_data *drv,
2570 struct nlattr **tb)
2571{
2572 union wpa_event_data data;
2573
2574 wpa_printf(MSG_DEBUG, "nl80211: Probe client event");
2575
2576 if (!tb[NL80211_ATTR_MAC] || !tb[NL80211_ATTR_ACK])
2577 return;
2578
2579 os_memset(&data, 0, sizeof(data));
2580 os_memcpy(data.client_poll.addr,
2581 nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
2582
2583 wpa_supplicant_event(drv->ctx, EVENT_DRIVER_CLIENT_POLL_OK, &data);
2584}
2585
2586
2587static void nl80211_tdls_oper_event(struct wpa_driver_nl80211_data *drv,
2588 struct nlattr **tb)
2589{
2590 union wpa_event_data data;
2591
2592 wpa_printf(MSG_DEBUG, "nl80211: TDLS operation event");
2593
2594 if (!tb[NL80211_ATTR_MAC] || !tb[NL80211_ATTR_TDLS_OPERATION])
2595 return;
2596
2597 os_memset(&data, 0, sizeof(data));
2598 os_memcpy(data.tdls.peer, nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
2599 switch (nla_get_u8(tb[NL80211_ATTR_TDLS_OPERATION])) {
2600 case NL80211_TDLS_SETUP:
2601 wpa_printf(MSG_DEBUG, "nl80211: TDLS setup request for peer "
2602 MACSTR, MAC2STR(data.tdls.peer));
2603 data.tdls.oper = TDLS_REQUEST_SETUP;
2604 break;
2605 case NL80211_TDLS_TEARDOWN:
2606 wpa_printf(MSG_DEBUG, "nl80211: TDLS teardown request for peer "
2607 MACSTR, MAC2STR(data.tdls.peer));
2608 data.tdls.oper = TDLS_REQUEST_TEARDOWN;
2609 break;
2610 default:
2611 wpa_printf(MSG_DEBUG, "nl80211: Unsupported TDLS operatione "
2612 "event");
2613 return;
2614 }
2615 if (tb[NL80211_ATTR_REASON_CODE]) {
2616 data.tdls.reason_code =
2617 nla_get_u16(tb[NL80211_ATTR_REASON_CODE]);
2618 }
2619
2620 wpa_supplicant_event(drv->ctx, EVENT_TDLS, &data);
2621}
2622
2623
2624static void nl80211_stop_ap(struct wpa_driver_nl80211_data *drv,
2625 struct nlattr **tb)
2626{
2627 wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_UNAVAILABLE, NULL);
2628}
2629
2630
2631static void nl80211_connect_failed_event(struct wpa_driver_nl80211_data *drv,
2632 struct nlattr **tb)
2633{
2634 union wpa_event_data data;
2635 u32 reason;
2636
2637 wpa_printf(MSG_DEBUG, "nl80211: Connect failed event");
2638
2639 if (!tb[NL80211_ATTR_MAC] || !tb[NL80211_ATTR_CONN_FAILED_REASON])
2640 return;
2641
2642 os_memset(&data, 0, sizeof(data));
2643 os_memcpy(data.connect_failed_reason.addr,
2644 nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
2645
2646 reason = nla_get_u32(tb[NL80211_ATTR_CONN_FAILED_REASON]);
2647 switch (reason) {
2648 case NL80211_CONN_FAIL_MAX_CLIENTS:
2649 wpa_printf(MSG_DEBUG, "nl80211: Max client reached");
2650 data.connect_failed_reason.code = MAX_CLIENT_REACHED;
2651 break;
2652 case NL80211_CONN_FAIL_BLOCKED_CLIENT:
2653 wpa_printf(MSG_DEBUG, "nl80211: Blocked client " MACSTR
2654 " tried to connect",
2655 MAC2STR(data.connect_failed_reason.addr));
2656 data.connect_failed_reason.code = BLOCKED_CLIENT;
2657 break;
2658 default:
2659 wpa_printf(MSG_DEBUG, "nl8021l: Unknown connect failed reason "
2660 "%u", reason);
2661 return;
2662 }
2663
2664 wpa_supplicant_event(drv->ctx, EVENT_CONNECT_FAILED_REASON, &data);
2665}
2666
2667
2668static void nl80211_radar_event(struct wpa_driver_nl80211_data *drv,
2669 struct nlattr **tb)
2670{
2671 union wpa_event_data data;
2672 enum nl80211_radar_event event_type;
2673
2674 if (!tb[NL80211_ATTR_WIPHY_FREQ] || !tb[NL80211_ATTR_RADAR_EVENT])
2675 return;
2676
2677 os_memset(&data, 0, sizeof(data));
2678 data.dfs_event.freq = nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]);
2679 event_type = nla_get_u32(tb[NL80211_ATTR_RADAR_EVENT]);
2680
2681 /* Check HT params */
2682 if (tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
2683 data.dfs_event.ht_enabled = 1;
2684 data.dfs_event.chan_offset = 0;
2685
2686 switch (nla_get_u32(tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE])) {
2687 case NL80211_CHAN_NO_HT:
2688 data.dfs_event.ht_enabled = 0;
2689 break;
2690 case NL80211_CHAN_HT20:
2691 break;
2692 case NL80211_CHAN_HT40PLUS:
2693 data.dfs_event.chan_offset = 1;
2694 break;
2695 case NL80211_CHAN_HT40MINUS:
2696 data.dfs_event.chan_offset = -1;
2697 break;
2698 }
2699 }
2700
2701 /* Get VHT params */
2702 if (tb[NL80211_ATTR_CHANNEL_WIDTH])
2703 data.dfs_event.chan_width =
2704 convert2width(nla_get_u32(
2705 tb[NL80211_ATTR_CHANNEL_WIDTH]));
2706 if (tb[NL80211_ATTR_CENTER_FREQ1])
2707 data.dfs_event.cf1 = nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ1]);
2708 if (tb[NL80211_ATTR_CENTER_FREQ2])
2709 data.dfs_event.cf2 = nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ2]);
2710
2711 wpa_printf(MSG_DEBUG, "nl80211: DFS event on freq %d MHz, ht: %d, offset: %d, width: %d, cf1: %dMHz, cf2: %dMHz",
2712 data.dfs_event.freq, data.dfs_event.ht_enabled,
2713 data.dfs_event.chan_offset, data.dfs_event.chan_width,
2714 data.dfs_event.cf1, data.dfs_event.cf2);
2715
2716 switch (event_type) {
2717 case NL80211_RADAR_DETECTED:
2718 wpa_supplicant_event(drv->ctx, EVENT_DFS_RADAR_DETECTED, &data);
2719 break;
2720 case NL80211_RADAR_CAC_FINISHED:
2721 wpa_supplicant_event(drv->ctx, EVENT_DFS_CAC_FINISHED, &data);
2722 break;
2723 case NL80211_RADAR_CAC_ABORTED:
2724 wpa_supplicant_event(drv->ctx, EVENT_DFS_CAC_ABORTED, &data);
2725 break;
2726 case NL80211_RADAR_NOP_FINISHED:
2727 wpa_supplicant_event(drv->ctx, EVENT_DFS_NOP_FINISHED, &data);
2728 break;
2729 default:
2730 wpa_printf(MSG_DEBUG, "nl80211: Unknown radar event %d "
2731 "received", event_type);
2732 break;
2733 }
2734}
2735
2736
2737static void nl80211_spurious_frame(struct i802_bss *bss, struct nlattr **tb,
2738 int wds)
2739{
2740 struct wpa_driver_nl80211_data *drv = bss->drv;
2741 union wpa_event_data event;
2742
2743 if (!tb[NL80211_ATTR_MAC])
2744 return;
2745
2746 os_memset(&event, 0, sizeof(event));
2747 event.rx_from_unknown.bssid = bss->addr;
2748 event.rx_from_unknown.addr = nla_data(tb[NL80211_ATTR_MAC]);
2749 event.rx_from_unknown.wds = wds;
2750
2751 wpa_supplicant_event(drv->ctx, EVENT_RX_FROM_UNKNOWN, &event);
2752}
2753
2754
2755static void qca_nl80211_avoid_freq(struct wpa_driver_nl80211_data *drv,
2756 const u8 *data, size_t len)
2757{
2758 u32 i, count;
2759 union wpa_event_data event;
2760 struct wpa_freq_range *range = NULL;
2761 const struct qca_avoid_freq_list *freq_range;
2762
2763 freq_range = (const struct qca_avoid_freq_list *) data;
2764 if (len < sizeof(freq_range->count))
2765 return;
2766
2767 count = freq_range->count;
2768 if (len < sizeof(freq_range->count) +
2769 count * sizeof(struct qca_avoid_freq_range)) {
2770 wpa_printf(MSG_DEBUG, "nl80211: Ignored too short avoid frequency list (len=%u)",
2771 (unsigned int) len);
2772 return;
2773 }
2774
2775 if (count > 0) {
2776 range = os_calloc(count, sizeof(struct wpa_freq_range));
2777 if (range == NULL)
2778 return;
2779 }
2780
2781 os_memset(&event, 0, sizeof(event));
2782 for (i = 0; i < count; i++) {
2783 unsigned int idx = event.freq_range.num;
2784 range[idx].min = freq_range->range[i].start_freq;
2785 range[idx].max = freq_range->range[i].end_freq;
2786 wpa_printf(MSG_DEBUG, "nl80211: Avoid frequency range: %u-%u",
2787 range[idx].min, range[idx].max);
2788 if (range[idx].min > range[idx].max) {
2789 wpa_printf(MSG_DEBUG, "nl80211: Ignore invalid frequency range");
2790 continue;
2791 }
2792 event.freq_range.num++;
2793 }
2794 event.freq_range.range = range;
2795
2796 wpa_supplicant_event(drv->ctx, EVENT_AVOID_FREQUENCIES, &event);
2797
2798 os_free(range);
2799}
2800
2801
2802static void nl80211_vendor_event_qca(struct wpa_driver_nl80211_data *drv,
2803 u32 subcmd, u8 *data, size_t len)
2804{
2805 switch (subcmd) {
2806 case QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY:
2807 qca_nl80211_avoid_freq(drv, data, len);
2808 break;
2809 default:
2810 wpa_printf(MSG_DEBUG,
2811 "nl80211: Ignore unsupported QCA vendor event %u",
2812 subcmd);
2813 break;
2814 }
2815}
2816
2817
2818static void nl80211_vendor_event(struct wpa_driver_nl80211_data *drv,
2819 struct nlattr **tb)
2820{
2821 u32 vendor_id, subcmd, wiphy = 0;
2822 int wiphy_idx;
2823 u8 *data = NULL;
2824 size_t len = 0;
2825
2826 if (!tb[NL80211_ATTR_VENDOR_ID] ||
2827 !tb[NL80211_ATTR_VENDOR_SUBCMD])
2828 return;
2829
2830 vendor_id = nla_get_u32(tb[NL80211_ATTR_VENDOR_ID]);
2831 subcmd = nla_get_u32(tb[NL80211_ATTR_VENDOR_SUBCMD]);
2832
2833 if (tb[NL80211_ATTR_WIPHY])
2834 wiphy = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
2835
2836 wpa_printf(MSG_DEBUG, "nl80211: Vendor event: wiphy=%u vendor_id=0x%x subcmd=%u",
2837 wiphy, vendor_id, subcmd);
2838
2839 if (tb[NL80211_ATTR_VENDOR_DATA]) {
2840 data = nla_data(tb[NL80211_ATTR_VENDOR_DATA]);
2841 len = nla_len(tb[NL80211_ATTR_VENDOR_DATA]);
2842 wpa_hexdump(MSG_MSGDUMP, "nl80211: Vendor data", data, len);
2843 }
2844
2845 wiphy_idx = nl80211_get_wiphy_index(drv->first_bss);
2846 if (wiphy_idx >= 0 && wiphy_idx != (int) wiphy) {
2847 wpa_printf(MSG_DEBUG, "nl80211: Ignore vendor event for foreign wiphy %u (own: %d)",
2848 wiphy, wiphy_idx);
2849 return;
2850 }
2851
2852 switch (vendor_id) {
2853 case OUI_QCA:
2854 nl80211_vendor_event_qca(drv, subcmd, data, len);
2855 break;
2856 default:
2857 wpa_printf(MSG_DEBUG, "nl80211: Ignore unsupported vendor event");
2858 break;
2859 }
2860}
2861
2862
2863static void do_process_drv_event(struct i802_bss *bss, int cmd,
2864 struct nlattr **tb)
2865{
2866 struct wpa_driver_nl80211_data *drv = bss->drv;
2867 union wpa_event_data data;
2868
2869 wpa_printf(MSG_DEBUG, "nl80211: Drv Event %d (%s) received for %s",
2870 cmd, nl80211_command_to_string(cmd), bss->ifname);
2871
2872 if (drv->ap_scan_as_station != NL80211_IFTYPE_UNSPECIFIED &&
2873 (cmd == NL80211_CMD_NEW_SCAN_RESULTS ||
2874 cmd == NL80211_CMD_SCAN_ABORTED)) {
2875 wpa_driver_nl80211_set_mode(drv->first_bss,
2876 drv->ap_scan_as_station);
2877 drv->ap_scan_as_station = NL80211_IFTYPE_UNSPECIFIED;
2878 }
2879
2880 switch (cmd) {
2881 case NL80211_CMD_TRIGGER_SCAN:
2882 wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Scan trigger");
2883 drv->scan_state = SCAN_STARTED;
2884 wpa_supplicant_event(drv->ctx, EVENT_SCAN_STARTED, NULL);
2885 break;
2886 case NL80211_CMD_START_SCHED_SCAN:
2887 wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Sched scan started");
2888 drv->scan_state = SCHED_SCAN_STARTED;
2889 break;
2890 case NL80211_CMD_SCHED_SCAN_STOPPED:
2891 wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Sched scan stopped");
2892 drv->scan_state = SCHED_SCAN_STOPPED;
2893 wpa_supplicant_event(drv->ctx, EVENT_SCHED_SCAN_STOPPED, NULL);
2894 break;
2895 case NL80211_CMD_NEW_SCAN_RESULTS:
2896 wpa_dbg(drv->ctx, MSG_DEBUG,
2897 "nl80211: New scan results available");
2898 drv->scan_state = SCAN_COMPLETED;
2899 drv->scan_complete_events = 1;
2900 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv,
2901 drv->ctx);
2902 send_scan_event(drv, 0, tb);
2903 break;
2904 case NL80211_CMD_SCHED_SCAN_RESULTS:
2905 wpa_dbg(drv->ctx, MSG_DEBUG,
2906 "nl80211: New sched scan results available");
2907 drv->scan_state = SCHED_SCAN_RESULTS;
2908 send_scan_event(drv, 0, tb);
2909 break;
2910 case NL80211_CMD_SCAN_ABORTED:
2911 wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Scan aborted");
2912 drv->scan_state = SCAN_ABORTED;
2913 /*
2914 * Need to indicate that scan results are available in order
2915 * not to make wpa_supplicant stop its scanning.
2916 */
2917 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv,
2918 drv->ctx);
2919 send_scan_event(drv, 1, tb);
2920 break;
2921 case NL80211_CMD_AUTHENTICATE:
2922 case NL80211_CMD_ASSOCIATE:
2923 case NL80211_CMD_DEAUTHENTICATE:
2924 case NL80211_CMD_DISASSOCIATE:
2925 case NL80211_CMD_FRAME_TX_STATUS:
2926 case NL80211_CMD_UNPROT_DEAUTHENTICATE:
2927 case NL80211_CMD_UNPROT_DISASSOCIATE:
2928 mlme_event(bss, cmd, tb[NL80211_ATTR_FRAME],
2929 tb[NL80211_ATTR_MAC], tb[NL80211_ATTR_TIMED_OUT],
2930 tb[NL80211_ATTR_WIPHY_FREQ], tb[NL80211_ATTR_ACK],
2931 tb[NL80211_ATTR_COOKIE],
2932 tb[NL80211_ATTR_RX_SIGNAL_DBM]);
2933 break;
2934 case NL80211_CMD_CONNECT:
2935 case NL80211_CMD_ROAM:
2936 mlme_event_connect(drv, cmd,
2937 tb[NL80211_ATTR_STATUS_CODE],
2938 tb[NL80211_ATTR_MAC],
2939 tb[NL80211_ATTR_REQ_IE],
2940 tb[NL80211_ATTR_RESP_IE]);
2941 break;
2942 case NL80211_CMD_CH_SWITCH_NOTIFY:
2943 mlme_event_ch_switch(drv,
2944 tb[NL80211_ATTR_IFINDEX],
2945 tb[NL80211_ATTR_WIPHY_FREQ],
2946 tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE],
2947 tb[NL80211_ATTR_CHANNEL_WIDTH],
2948 tb[NL80211_ATTR_CENTER_FREQ1],
2949 tb[NL80211_ATTR_CENTER_FREQ2]);
2950 break;
2951 case NL80211_CMD_DISCONNECT:
2952 mlme_event_disconnect(drv, tb[NL80211_ATTR_REASON_CODE],
2953 tb[NL80211_ATTR_MAC],
2954 tb[NL80211_ATTR_DISCONNECTED_BY_AP]);
2955 break;
2956 case NL80211_CMD_MICHAEL_MIC_FAILURE:
2957 mlme_event_michael_mic_failure(bss, tb);
2958 break;
2959 case NL80211_CMD_JOIN_IBSS:
2960 mlme_event_join_ibss(drv, tb);
2961 break;
2962 case NL80211_CMD_REMAIN_ON_CHANNEL:
2963 mlme_event_remain_on_channel(drv, 0, tb);
2964 break;
2965 case NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL:
2966 mlme_event_remain_on_channel(drv, 1, tb);
2967 break;
2968 case NL80211_CMD_NOTIFY_CQM:
2969 nl80211_cqm_event(drv, tb);
2970 break;
2971 case NL80211_CMD_REG_CHANGE:
2972 wpa_printf(MSG_DEBUG, "nl80211: Regulatory domain change");
2973 if (tb[NL80211_ATTR_REG_INITIATOR] == NULL)
2974 break;
2975 os_memset(&data, 0, sizeof(data));
2976 switch (nla_get_u8(tb[NL80211_ATTR_REG_INITIATOR])) {
2977 case NL80211_REGDOM_SET_BY_CORE:
2978 data.channel_list_changed.initiator =
2979 REGDOM_SET_BY_CORE;
2980 break;
2981 case NL80211_REGDOM_SET_BY_USER:
2982 data.channel_list_changed.initiator =
2983 REGDOM_SET_BY_USER;
2984 break;
2985 case NL80211_REGDOM_SET_BY_DRIVER:
2986 data.channel_list_changed.initiator =
2987 REGDOM_SET_BY_DRIVER;
2988 break;
2989 case NL80211_REGDOM_SET_BY_COUNTRY_IE:
2990 data.channel_list_changed.initiator =
2991 REGDOM_SET_BY_COUNTRY_IE;
2992 break;
2993 default:
2994 wpa_printf(MSG_DEBUG, "nl80211: Unknown reg change initiator %d received",
2995 nla_get_u8(tb[NL80211_ATTR_REG_INITIATOR]));
2996 break;
2997 }
2998 wpa_supplicant_event(drv->ctx, EVENT_CHANNEL_LIST_CHANGED,
2999 &data);
3000 break;
3001 case NL80211_CMD_REG_BEACON_HINT:
3002 wpa_printf(MSG_DEBUG, "nl80211: Regulatory beacon hint");
3003 os_memset(&data, 0, sizeof(data));
3004 data.channel_list_changed.initiator = REGDOM_BEACON_HINT;
3005 wpa_supplicant_event(drv->ctx, EVENT_CHANNEL_LIST_CHANGED,
3006 &data);
3007 break;
3008 case NL80211_CMD_NEW_STATION:
3009 nl80211_new_station_event(drv, tb);
3010 break;
3011 case NL80211_CMD_DEL_STATION:
3012 nl80211_del_station_event(drv, tb);
3013 break;
3014 case NL80211_CMD_SET_REKEY_OFFLOAD:
3015 nl80211_rekey_offload_event(drv, tb);
3016 break;
3017 case NL80211_CMD_PMKSA_CANDIDATE:
3018 nl80211_pmksa_candidate_event(drv, tb);
3019 break;
3020 case NL80211_CMD_PROBE_CLIENT:
3021 nl80211_client_probe_event(drv, tb);
3022 break;
3023 case NL80211_CMD_TDLS_OPER:
3024 nl80211_tdls_oper_event(drv, tb);
3025 break;
3026 case NL80211_CMD_CONN_FAILED:
3027 nl80211_connect_failed_event(drv, tb);
3028 break;
3029 case NL80211_CMD_FT_EVENT:
3030 mlme_event_ft_event(drv, tb);
3031 break;
3032 case NL80211_CMD_RADAR_DETECT:
3033 nl80211_radar_event(drv, tb);
3034 break;
3035 case NL80211_CMD_STOP_AP:
3036 nl80211_stop_ap(drv, tb);
3037 break;
3038 case NL80211_CMD_VENDOR:
3039 nl80211_vendor_event(drv, tb);
3040 break;
3041 default:
3042 wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Ignored unknown event "
3043 "(cmd=%d)", cmd);
3044 break;
3045 }
3046}
3047
3048
3049static int process_drv_event(struct nl_msg *msg, void *arg)
3050{
3051 struct wpa_driver_nl80211_data *drv = arg;
3052 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
3053 struct nlattr *tb[NL80211_ATTR_MAX + 1];
3054 struct i802_bss *bss;
3055 int ifidx = -1;
3056
3057 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
3058 genlmsg_attrlen(gnlh, 0), NULL);
3059
3060 if (tb[NL80211_ATTR_IFINDEX]) {
3061 ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
3062
3063 for (bss = drv->first_bss; bss; bss = bss->next)
3064 if (ifidx == -1 || ifidx == bss->ifindex) {
3065 do_process_drv_event(bss, gnlh->cmd, tb);
3066 return NL_SKIP;
3067 }
3068 wpa_printf(MSG_DEBUG,
3069 "nl80211: Ignored event (cmd=%d) for foreign interface (ifindex %d)",
3070 gnlh->cmd, ifidx);
3071 } else if (tb[NL80211_ATTR_WDEV]) {
3072 u64 wdev_id = nla_get_u64(tb[NL80211_ATTR_WDEV]);
3073 wpa_printf(MSG_DEBUG, "nl80211: Process event on P2P device");
3074 for (bss = drv->first_bss; bss; bss = bss->next) {
3075 if (bss->wdev_id_set && wdev_id == bss->wdev_id) {
3076 do_process_drv_event(bss, gnlh->cmd, tb);
3077 return NL_SKIP;
3078 }
3079 }
3080 wpa_printf(MSG_DEBUG,
3081 "nl80211: Ignored event (cmd=%d) for foreign interface (wdev 0x%llx)",
3082 gnlh->cmd, (long long unsigned int) wdev_id);
3083 }
3084
3085 return NL_SKIP;
3086}
3087
3088
3089static int process_global_event(struct nl_msg *msg, void *arg)
3090{
3091 struct nl80211_global *global = arg;
3092 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
3093 struct nlattr *tb[NL80211_ATTR_MAX + 1];
3094 struct wpa_driver_nl80211_data *drv, *tmp;
3095 int ifidx = -1;
3096 struct i802_bss *bss;
3097 u64 wdev_id = 0;
3098 int wdev_id_set = 0;
3099
3100 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
3101 genlmsg_attrlen(gnlh, 0), NULL);
3102
3103 if (tb[NL80211_ATTR_IFINDEX])
3104 ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
3105 else if (tb[NL80211_ATTR_WDEV]) {
3106 wdev_id = nla_get_u64(tb[NL80211_ATTR_WDEV]);
3107 wdev_id_set = 1;
3108 }
3109
3110 dl_list_for_each_safe(drv, tmp, &global->interfaces,
3111 struct wpa_driver_nl80211_data, list) {
3112 for (bss = drv->first_bss; bss; bss = bss->next) {
3113 if ((ifidx == -1 && !wdev_id_set) ||
3114 ifidx == bss->ifindex ||
3115 (wdev_id_set && bss->wdev_id_set &&
3116 wdev_id == bss->wdev_id)) {
3117 do_process_drv_event(bss, gnlh->cmd, tb);
3118 return NL_SKIP;
3119 }
3120 }
3121 }
3122
3123 return NL_SKIP;
3124}
3125
3126
3127static int process_bss_event(struct nl_msg *msg, void *arg)
3128{
3129 struct i802_bss *bss = arg;
3130 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
3131 struct nlattr *tb[NL80211_ATTR_MAX + 1];
3132
3133 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
3134 genlmsg_attrlen(gnlh, 0), NULL);
3135
3136 wpa_printf(MSG_DEBUG, "nl80211: BSS Event %d (%s) received for %s",
3137 gnlh->cmd, nl80211_command_to_string(gnlh->cmd),
3138 bss->ifname);
3139
3140 switch (gnlh->cmd) {
3141 case NL80211_CMD_FRAME:
3142 case NL80211_CMD_FRAME_TX_STATUS:
3143 mlme_event(bss, gnlh->cmd, tb[NL80211_ATTR_FRAME],
3144 tb[NL80211_ATTR_MAC], tb[NL80211_ATTR_TIMED_OUT],
3145 tb[NL80211_ATTR_WIPHY_FREQ], tb[NL80211_ATTR_ACK],
3146 tb[NL80211_ATTR_COOKIE],
3147 tb[NL80211_ATTR_RX_SIGNAL_DBM]);
3148 break;
3149 case NL80211_CMD_UNEXPECTED_FRAME:
3150 nl80211_spurious_frame(bss, tb, 0);
3151 break;
3152 case NL80211_CMD_UNEXPECTED_4ADDR_FRAME:
3153 nl80211_spurious_frame(bss, tb, 1);
3154 break;
3155 default:
3156 wpa_printf(MSG_DEBUG, "nl80211: Ignored unknown event "
3157 "(cmd=%d)", gnlh->cmd);
3158 break;
3159 }
3160
3161 return NL_SKIP;
3162}
3163
3164
3165static void wpa_driver_nl80211_event_receive(int sock, void *eloop_ctx,
3166 void *handle)
3167{
3168 struct nl_cb *cb = eloop_ctx;
3169 int res;
3170
3171 wpa_printf(MSG_MSGDUMP, "nl80211: Event message available");
3172
3173 res = nl_recvmsgs(handle, cb);
3174 if (res) {
3175 wpa_printf(MSG_INFO, "nl80211: %s->nl_recvmsgs failed: %d",
3176 __func__, res);
3177 }
3178}
3179
3180
3181/**
3182 * wpa_driver_nl80211_set_country - ask nl80211 to set the regulatory domain
3183 * @priv: driver_nl80211 private data
3184 * @alpha2_arg: country to which to switch to
3185 * Returns: 0 on success, -1 on failure
3186 *
3187 * This asks nl80211 to set the regulatory domain for given
3188 * country ISO / IEC alpha2.
3189 */
3190static int wpa_driver_nl80211_set_country(void *priv, const char *alpha2_arg)
3191{
3192 struct i802_bss *bss = priv;
3193 struct wpa_driver_nl80211_data *drv = bss->drv;
3194 char alpha2[3];
3195 struct nl_msg *msg;
3196
3197 msg = nlmsg_alloc();
3198 if (!msg)
3199 return -ENOMEM;
3200
3201 alpha2[0] = alpha2_arg[0];
3202 alpha2[1] = alpha2_arg[1];
3203 alpha2[2] = '\0';
3204
3205 nl80211_cmd(drv, msg, 0, NL80211_CMD_REQ_SET_REG);
3206
3207 NLA_PUT_STRING(msg, NL80211_ATTR_REG_ALPHA2, alpha2);
3208 if (send_and_recv_msgs(drv, msg, NULL, NULL))
3209 return -EINVAL;
3210 return 0;
3211nla_put_failure:
3212 nlmsg_free(msg);
3213 return -EINVAL;
3214}
3215
3216
3217static int nl80211_get_country(struct nl_msg *msg, void *arg)
3218{
3219 char *alpha2 = arg;
3220 struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
3221 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
3222
3223 nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
3224 genlmsg_attrlen(gnlh, 0), NULL);
3225 if (!tb_msg[NL80211_ATTR_REG_ALPHA2]) {
3226 wpa_printf(MSG_DEBUG, "nl80211: No country information available");
3227 return NL_SKIP;
3228 }
3229 os_strlcpy(alpha2, nla_data(tb_msg[NL80211_ATTR_REG_ALPHA2]), 3);
3230 return NL_SKIP;
3231}
3232
3233
3234static int wpa_driver_nl80211_get_country(void *priv, char *alpha2)
3235{
3236 struct i802_bss *bss = priv;
3237 struct wpa_driver_nl80211_data *drv = bss->drv;
3238 struct nl_msg *msg;
3239 int ret;
3240
3241 msg = nlmsg_alloc();
3242 if (!msg)
3243 return -ENOMEM;
3244
3245 nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_REG);
3246 alpha2[0] = '\0';
3247 ret = send_and_recv_msgs(drv, msg, nl80211_get_country, alpha2);
3248 if (!alpha2[0])
3249 ret = -1;
3250
3251 return ret;
3252}
3253
3254
3255static int protocol_feature_handler(struct nl_msg *msg, void *arg)
3256{
3257 u32 *feat = arg;
3258 struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
3259 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
3260
3261 nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
3262 genlmsg_attrlen(gnlh, 0), NULL);
3263
3264 if (tb_msg[NL80211_ATTR_PROTOCOL_FEATURES])
3265 *feat = nla_get_u32(tb_msg[NL80211_ATTR_PROTOCOL_FEATURES]);
3266
3267 return NL_SKIP;
3268}
3269
3270
3271static u32 get_nl80211_protocol_features(struct wpa_driver_nl80211_data *drv)
3272{
3273 u32 feat = 0;
3274 struct nl_msg *msg;
3275
3276 msg = nlmsg_alloc();
3277 if (!msg)
3278 goto nla_put_failure;
3279
3280 nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_PROTOCOL_FEATURES);
3281 if (send_and_recv_msgs(drv, msg, protocol_feature_handler, &feat) == 0)
3282 return feat;
3283
3284 msg = NULL;
3285nla_put_failure:
3286 nlmsg_free(msg);
3287 return 0;
3288}
3289
3290
3291struct wiphy_info_data {
3292 struct wpa_driver_nl80211_data *drv;
3293 struct wpa_driver_capa *capa;
3294
3295 unsigned int num_multichan_concurrent;
3296
3297 unsigned int error:1;
3298 unsigned int device_ap_sme:1;
3299 unsigned int poll_command_supported:1;
3300 unsigned int data_tx_status:1;
3301 unsigned int monitor_supported:1;
3302 unsigned int auth_supported:1;
3303 unsigned int connect_supported:1;
3304 unsigned int p2p_go_supported:1;
3305 unsigned int p2p_client_supported:1;
3306 unsigned int p2p_concurrent:1;
3307 unsigned int channel_switch_supported:1;
3308 unsigned int set_qos_map_supported:1;
3309};
3310
3311
3312static unsigned int probe_resp_offload_support(int supp_protocols)
3313{
3314 unsigned int prot = 0;
3315
3316 if (supp_protocols & NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS)
3317 prot |= WPA_DRIVER_PROBE_RESP_OFFLOAD_WPS;
3318 if (supp_protocols & NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2)
3319 prot |= WPA_DRIVER_PROBE_RESP_OFFLOAD_WPS2;
3320 if (supp_protocols & NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P)
3321 prot |= WPA_DRIVER_PROBE_RESP_OFFLOAD_P2P;
3322 if (supp_protocols & NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U)
3323 prot |= WPA_DRIVER_PROBE_RESP_OFFLOAD_INTERWORKING;
3324
3325 return prot;
3326}
3327
3328
3329static void wiphy_info_supported_iftypes(struct wiphy_info_data *info,
3330 struct nlattr *tb)
3331{
3332 struct nlattr *nl_mode;
3333 int i;
3334
3335 if (tb == NULL)
3336 return;
3337
3338 nla_for_each_nested(nl_mode, tb, i) {
3339 switch (nla_type(nl_mode)) {
3340 case NL80211_IFTYPE_AP:
3341 info->capa->flags |= WPA_DRIVER_FLAGS_AP;
3342 break;
3343 case NL80211_IFTYPE_ADHOC:
3344 info->capa->flags |= WPA_DRIVER_FLAGS_IBSS;
3345 break;
3346 case NL80211_IFTYPE_P2P_DEVICE:
3347 info->capa->flags |=
3348 WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE;
3349 break;
3350 case NL80211_IFTYPE_P2P_GO:
3351 info->p2p_go_supported = 1;
3352 break;
3353 case NL80211_IFTYPE_P2P_CLIENT:
3354 info->p2p_client_supported = 1;
3355 break;
3356 case NL80211_IFTYPE_MONITOR:
3357 info->monitor_supported = 1;
3358 break;
3359 }
3360 }
3361}
3362
3363
3364static int wiphy_info_iface_comb_process(struct wiphy_info_data *info,
3365 struct nlattr *nl_combi)
3366{
3367 struct nlattr *tb_comb[NUM_NL80211_IFACE_COMB];
3368 struct nlattr *tb_limit[NUM_NL80211_IFACE_LIMIT];
3369 struct nlattr *nl_limit, *nl_mode;
3370 int err, rem_limit, rem_mode;
3371 int combination_has_p2p = 0, combination_has_mgd = 0;
3372 static struct nla_policy
3373 iface_combination_policy[NUM_NL80211_IFACE_COMB] = {
3374 [NL80211_IFACE_COMB_LIMITS] = { .type = NLA_NESTED },
3375 [NL80211_IFACE_COMB_MAXNUM] = { .type = NLA_U32 },
3376 [NL80211_IFACE_COMB_STA_AP_BI_MATCH] = { .type = NLA_FLAG },
3377 [NL80211_IFACE_COMB_NUM_CHANNELS] = { .type = NLA_U32 },
3378 [NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS] = { .type = NLA_U32 },
3379 },
3380 iface_limit_policy[NUM_NL80211_IFACE_LIMIT] = {
3381 [NL80211_IFACE_LIMIT_TYPES] = { .type = NLA_NESTED },
3382 [NL80211_IFACE_LIMIT_MAX] = { .type = NLA_U32 },
3383 };
3384
3385 err = nla_parse_nested(tb_comb, MAX_NL80211_IFACE_COMB,
3386 nl_combi, iface_combination_policy);
3387 if (err || !tb_comb[NL80211_IFACE_COMB_LIMITS] ||
3388 !tb_comb[NL80211_IFACE_COMB_MAXNUM] ||
3389 !tb_comb[NL80211_IFACE_COMB_NUM_CHANNELS])
3390 return 0; /* broken combination */
3391
3392 if (tb_comb[NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS])
3393 info->capa->flags |= WPA_DRIVER_FLAGS_RADAR;
3394
3395 nla_for_each_nested(nl_limit, tb_comb[NL80211_IFACE_COMB_LIMITS],
3396 rem_limit) {
3397 err = nla_parse_nested(tb_limit, MAX_NL80211_IFACE_LIMIT,
3398 nl_limit, iface_limit_policy);
3399 if (err || !tb_limit[NL80211_IFACE_LIMIT_TYPES])
3400 return 0; /* broken combination */
3401
3402 nla_for_each_nested(nl_mode,
3403 tb_limit[NL80211_IFACE_LIMIT_TYPES],
3404 rem_mode) {
3405 int ift = nla_type(nl_mode);
3406 if (ift == NL80211_IFTYPE_P2P_GO ||
3407 ift == NL80211_IFTYPE_P2P_CLIENT)
3408 combination_has_p2p = 1;
3409 if (ift == NL80211_IFTYPE_STATION)
3410 combination_has_mgd = 1;
3411 }
3412 if (combination_has_p2p && combination_has_mgd)
3413 break;
3414 }
3415
3416 if (combination_has_p2p && combination_has_mgd) {
3417 info->p2p_concurrent = 1;
3418 info->num_multichan_concurrent =
3419 nla_get_u32(tb_comb[NL80211_IFACE_COMB_NUM_CHANNELS]);
3420 return 1;
3421 }
3422
3423 return 0;
3424}
3425
3426
3427static void wiphy_info_iface_comb(struct wiphy_info_data *info,
3428 struct nlattr *tb)
3429{
3430 struct nlattr *nl_combi;
3431 int rem_combi;
3432
3433 if (tb == NULL)
3434 return;
3435
3436 nla_for_each_nested(nl_combi, tb, rem_combi) {
3437 if (wiphy_info_iface_comb_process(info, nl_combi) > 0)
3438 break;
3439 }
3440}
3441
3442
3443static void wiphy_info_supp_cmds(struct wiphy_info_data *info,
3444 struct nlattr *tb)
3445{
3446 struct nlattr *nl_cmd;
3447 int i;
3448
3449 if (tb == NULL)
3450 return;
3451
3452 nla_for_each_nested(nl_cmd, tb, i) {
3453 switch (nla_get_u32(nl_cmd)) {
3454 case NL80211_CMD_AUTHENTICATE:
3455 info->auth_supported = 1;
3456 break;
3457 case NL80211_CMD_CONNECT:
3458 info->connect_supported = 1;
3459 break;
3460 case NL80211_CMD_START_SCHED_SCAN:
3461 info->capa->sched_scan_supported = 1;
3462 break;
3463 case NL80211_CMD_PROBE_CLIENT:
3464 info->poll_command_supported = 1;
3465 break;
3466 case NL80211_CMD_CHANNEL_SWITCH:
3467 info->channel_switch_supported = 1;
3468 break;
3469 case NL80211_CMD_SET_QOS_MAP:
3470 info->set_qos_map_supported = 1;
3471 break;
3472 }
3473 }
3474}
3475
3476
3477static void wiphy_info_cipher_suites(struct wiphy_info_data *info,
3478 struct nlattr *tb)
3479{
3480 int i, num;
3481 u32 *ciphers;
3482
3483 if (tb == NULL)
3484 return;
3485
3486 num = nla_len(tb) / sizeof(u32);
3487 ciphers = nla_data(tb);
3488 for (i = 0; i < num; i++) {
3489 u32 c = ciphers[i];
3490
3491 wpa_printf(MSG_DEBUG, "nl80211: Supported cipher %02x-%02x-%02x:%d",
3492 c >> 24, (c >> 16) & 0xff,
3493 (c >> 8) & 0xff, c & 0xff);
3494 switch (c) {
3495 case WLAN_CIPHER_SUITE_CCMP_256:
3496 info->capa->enc |= WPA_DRIVER_CAPA_ENC_CCMP_256;
3497 break;
3498 case WLAN_CIPHER_SUITE_GCMP_256:
3499 info->capa->enc |= WPA_DRIVER_CAPA_ENC_GCMP_256;
3500 break;
3501 case WLAN_CIPHER_SUITE_CCMP:
3502 info->capa->enc |= WPA_DRIVER_CAPA_ENC_CCMP;
3503 break;
3504 case WLAN_CIPHER_SUITE_GCMP:
3505 info->capa->enc |= WPA_DRIVER_CAPA_ENC_GCMP;
3506 break;
3507 case WLAN_CIPHER_SUITE_TKIP:
3508 info->capa->enc |= WPA_DRIVER_CAPA_ENC_TKIP;
3509 break;
3510 case WLAN_CIPHER_SUITE_WEP104:
3511 info->capa->enc |= WPA_DRIVER_CAPA_ENC_WEP104;
3512 break;
3513 case WLAN_CIPHER_SUITE_WEP40:
3514 info->capa->enc |= WPA_DRIVER_CAPA_ENC_WEP40;
3515 break;
3516 case WLAN_CIPHER_SUITE_AES_CMAC:
3517 info->capa->enc |= WPA_DRIVER_CAPA_ENC_BIP;
3518 break;
3519 case WLAN_CIPHER_SUITE_BIP_GMAC_128:
3520 info->capa->enc |= WPA_DRIVER_CAPA_ENC_BIP_GMAC_128;
3521 break;
3522 case WLAN_CIPHER_SUITE_BIP_GMAC_256:
3523 info->capa->enc |= WPA_DRIVER_CAPA_ENC_BIP_GMAC_256;
3524 break;
3525 case WLAN_CIPHER_SUITE_BIP_CMAC_256:
3526 info->capa->enc |= WPA_DRIVER_CAPA_ENC_BIP_CMAC_256;
3527 break;
3528 }
3529 }
3530}
3531
3532
3533static void wiphy_info_max_roc(struct wpa_driver_capa *capa,
3534 struct nlattr *tb)
3535{
3536 if (tb)
3537 capa->max_remain_on_chan = nla_get_u32(tb);
3538}
3539
3540
3541static void wiphy_info_tdls(struct wpa_driver_capa *capa, struct nlattr *tdls,
3542 struct nlattr *ext_setup)
3543{
3544 if (tdls == NULL)
3545 return;
3546
3547 wpa_printf(MSG_DEBUG, "nl80211: TDLS supported");
3548 capa->flags |= WPA_DRIVER_FLAGS_TDLS_SUPPORT;
3549
3550 if (ext_setup) {
3551 wpa_printf(MSG_DEBUG, "nl80211: TDLS external setup");
3552 capa->flags |= WPA_DRIVER_FLAGS_TDLS_EXTERNAL_SETUP;
3553 }
3554}
3555
3556
3557static void wiphy_info_feature_flags(struct wiphy_info_data *info,
3558 struct nlattr *tb)
3559{
3560 u32 flags;
3561 struct wpa_driver_capa *capa = info->capa;
3562
3563 if (tb == NULL)
3564 return;
3565
3566 flags = nla_get_u32(tb);
3567
3568 if (flags & NL80211_FEATURE_SK_TX_STATUS)
3569 info->data_tx_status = 1;
3570
3571 if (flags & NL80211_FEATURE_INACTIVITY_TIMER)
3572 capa->flags |= WPA_DRIVER_FLAGS_INACTIVITY_TIMER;
3573
3574 if (flags & NL80211_FEATURE_SAE)
3575 capa->flags |= WPA_DRIVER_FLAGS_SAE;
3576
3577 if (flags & NL80211_FEATURE_NEED_OBSS_SCAN)
3578 capa->flags |= WPA_DRIVER_FLAGS_OBSS_SCAN;
3579}
3580
3581
3582static void wiphy_info_probe_resp_offload(struct wpa_driver_capa *capa,
3583 struct nlattr *tb)
3584{
3585 u32 protocols;
3586
3587 if (tb == NULL)
3588 return;
3589
3590 protocols = nla_get_u32(tb);
3591 wpa_printf(MSG_DEBUG, "nl80211: Supports Probe Response offload in AP "
3592 "mode");
3593 capa->flags |= WPA_DRIVER_FLAGS_PROBE_RESP_OFFLOAD;
3594 capa->probe_resp_offloads = probe_resp_offload_support(protocols);
3595}
3596
3597
3598static int wiphy_info_handler(struct nl_msg *msg, void *arg)
3599{
3600 struct nlattr *tb[NL80211_ATTR_MAX + 1];
3601 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
3602 struct wiphy_info_data *info = arg;
3603 struct wpa_driver_capa *capa = info->capa;
3604 struct wpa_driver_nl80211_data *drv = info->drv;
3605
3606 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
3607 genlmsg_attrlen(gnlh, 0), NULL);
3608
3609 if (tb[NL80211_ATTR_WIPHY_NAME])
3610 os_strlcpy(drv->phyname,
3611 nla_get_string(tb[NL80211_ATTR_WIPHY_NAME]),
3612 sizeof(drv->phyname));
3613 if (tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS])
3614 capa->max_scan_ssids =
3615 nla_get_u8(tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS]);
3616
3617 if (tb[NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS])
3618 capa->max_sched_scan_ssids =
3619 nla_get_u8(tb[NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS]);
3620
3621 if (tb[NL80211_ATTR_MAX_MATCH_SETS])
3622 capa->max_match_sets =
3623 nla_get_u8(tb[NL80211_ATTR_MAX_MATCH_SETS]);
3624
3625 if (tb[NL80211_ATTR_MAC_ACL_MAX])
3626 capa->max_acl_mac_addrs =
3627 nla_get_u8(tb[NL80211_ATTR_MAC_ACL_MAX]);
3628
3629 wiphy_info_supported_iftypes(info, tb[NL80211_ATTR_SUPPORTED_IFTYPES]);
3630 wiphy_info_iface_comb(info, tb[NL80211_ATTR_INTERFACE_COMBINATIONS]);
3631 wiphy_info_supp_cmds(info, tb[NL80211_ATTR_SUPPORTED_COMMANDS]);
3632 wiphy_info_cipher_suites(info, tb[NL80211_ATTR_CIPHER_SUITES]);
3633
3634 if (tb[NL80211_ATTR_OFFCHANNEL_TX_OK]) {
3635 wpa_printf(MSG_DEBUG, "nl80211: Using driver-based "
3636 "off-channel TX");
3637 capa->flags |= WPA_DRIVER_FLAGS_OFFCHANNEL_TX;
3638 }
3639
3640 if (tb[NL80211_ATTR_ROAM_SUPPORT]) {
3641 wpa_printf(MSG_DEBUG, "nl80211: Using driver-based roaming");
3642 capa->flags |= WPA_DRIVER_FLAGS_BSS_SELECTION;
3643 }
3644
3645 wiphy_info_max_roc(capa,
3646 tb[NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION]);
3647
3648 if (tb[NL80211_ATTR_SUPPORT_AP_UAPSD])
3649 capa->flags |= WPA_DRIVER_FLAGS_AP_UAPSD;
3650
3651 wiphy_info_tdls(capa, tb[NL80211_ATTR_TDLS_SUPPORT],
3652 tb[NL80211_ATTR_TDLS_EXTERNAL_SETUP]);
3653
3654 if (tb[NL80211_ATTR_DEVICE_AP_SME])
3655 info->device_ap_sme = 1;
3656
3657 wiphy_info_feature_flags(info, tb[NL80211_ATTR_FEATURE_FLAGS]);
3658 wiphy_info_probe_resp_offload(capa,
3659 tb[NL80211_ATTR_PROBE_RESP_OFFLOAD]);
3660
3661 if (tb[NL80211_ATTR_EXT_CAPA] && tb[NL80211_ATTR_EXT_CAPA_MASK] &&
3662 drv->extended_capa == NULL) {
3663 drv->extended_capa =
3664 os_malloc(nla_len(tb[NL80211_ATTR_EXT_CAPA]));
3665 if (drv->extended_capa) {
3666 os_memcpy(drv->extended_capa,
3667 nla_data(tb[NL80211_ATTR_EXT_CAPA]),
3668 nla_len(tb[NL80211_ATTR_EXT_CAPA]));
3669 drv->extended_capa_len =
3670 nla_len(tb[NL80211