Line data Source code
1 : /*
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
8 : *
9 : * This software may be distributed under the terms of the BSD license.
10 : * See README for more details.
11 : */
12 :
13 : #include "includes.h"
14 : #include <sys/ioctl.h>
15 : #include <sys/types.h>
16 : #include <sys/stat.h>
17 : #include <fcntl.h>
18 : #include <net/if.h>
19 : #include <netlink/genl/genl.h>
20 : #include <netlink/genl/family.h>
21 : #include <netlink/genl/ctrl.h>
22 : #include <linux/rtnetlink.h>
23 : #include <netpacket/packet.h>
24 : #include <linux/filter.h>
25 : #include <linux/errqueue.h>
26 : #include "nl80211_copy.h"
27 :
28 : #include "common.h"
29 : #include "eloop.h"
30 : #include "utils/list.h"
31 : #include "common/qca-vendor.h"
32 : #include "common/qca-vendor-attr.h"
33 : #include "common/ieee802_11_defs.h"
34 : #include "common/ieee802_11_common.h"
35 : #include "l2_packet/l2_packet.h"
36 : #include "netlink.h"
37 : #include "linux_ioctl.h"
38 : #include "radiotap.h"
39 : #include "radiotap_iter.h"
40 : #include "rfkill.h"
41 : #include "driver.h"
42 :
43 : #ifndef SO_WIFI_STATUS
44 : # if defined(__sparc__)
45 : # define SO_WIFI_STATUS 0x0025
46 : # elif defined(__parisc__)
47 : # define SO_WIFI_STATUS 0x4022
48 : # else
49 : # define SO_WIFI_STATUS 41
50 : # endif
51 :
52 : # define SCM_WIFI_STATUS SO_WIFI_STATUS
53 : #endif
54 :
55 : #ifndef SO_EE_ORIGIN_TXSTATUS
56 : #define SO_EE_ORIGIN_TXSTATUS 4
57 : #endif
58 :
59 : #ifndef PACKET_TX_TIMESTAMP
60 : #define PACKET_TX_TIMESTAMP 16
61 : #endif
62 :
63 : #ifdef ANDROID
64 : #include "android_drv.h"
65 : #endif /* ANDROID */
66 : #ifdef CONFIG_LIBNL20
67 : /* libnl 2.0 compatibility code */
68 : #define nl_handle nl_sock
69 : #define nl80211_handle_alloc nl_socket_alloc_cb
70 : #define nl80211_handle_destroy nl_socket_free
71 : #else
72 : /*
73 : * libnl 1.1 has a bug, it tries to allocate socket numbers densely
74 : * but when you free a socket again it will mess up its bitmap and
75 : * and use the wrong number the next time it needs a socket ID.
76 : * Therefore, we wrap the handle alloc/destroy and add our own pid
77 : * accounting.
78 : */
79 : static uint32_t port_bitmap[32] = { 0 };
80 :
81 : static struct nl_handle *nl80211_handle_alloc(void *cb)
82 : {
83 : struct nl_handle *handle;
84 : uint32_t pid = getpid() & 0x3FFFFF;
85 : int i;
86 :
87 : handle = nl_handle_alloc_cb(cb);
88 :
89 : for (i = 0; i < 1024; i++) {
90 : if (port_bitmap[i / 32] & (1 << (i % 32)))
91 : continue;
92 : port_bitmap[i / 32] |= 1 << (i % 32);
93 : pid += i << 22;
94 : break;
95 : }
96 :
97 : nl_socket_set_local_port(handle, pid);
98 :
99 : return handle;
100 : }
101 :
102 : static void nl80211_handle_destroy(struct nl_handle *handle)
103 : {
104 : uint32_t port = nl_socket_get_local_port(handle);
105 :
106 : port >>= 22;
107 : port_bitmap[port / 32] &= ~(1 << (port % 32));
108 :
109 : nl_handle_destroy(handle);
110 : }
111 : #endif /* CONFIG_LIBNL20 */
112 :
113 :
114 : #ifdef ANDROID
115 : /* system/core/libnl_2 does not include nl_socket_set_nonblocking() */
116 : static int android_nl_socket_set_nonblocking(struct nl_handle *handle)
117 : {
118 : return fcntl(nl_socket_get_fd(handle), F_SETFL, O_NONBLOCK);
119 : }
120 : #undef nl_socket_set_nonblocking
121 : #define nl_socket_set_nonblocking(h) android_nl_socket_set_nonblocking(h)
122 : #endif /* ANDROID */
123 :
124 :
125 2592 : static struct nl_handle * nl_create_handle(struct nl_cb *cb, const char *dbg)
126 : {
127 : struct nl_handle *handle;
128 :
129 2592 : handle = nl80211_handle_alloc(cb);
130 2592 : if (handle == NULL) {
131 0 : wpa_printf(MSG_ERROR, "nl80211: Failed to allocate netlink "
132 : "callbacks (%s)", dbg);
133 0 : return NULL;
134 : }
135 :
136 2592 : if (genl_connect(handle)) {
137 0 : wpa_printf(MSG_ERROR, "nl80211: Failed to connect to generic "
138 : "netlink (%s)", dbg);
139 0 : nl80211_handle_destroy(handle);
140 0 : return NULL;
141 : }
142 :
143 2592 : return handle;
144 : }
145 :
146 :
147 2592 : static void nl_destroy_handles(struct nl_handle **handle)
148 : {
149 2592 : if (*handle == NULL)
150 2592 : return;
151 2592 : nl80211_handle_destroy(*handle);
152 2592 : *handle = NULL;
153 : }
154 :
155 :
156 : #if __WORDSIZE == 64
157 : #define ELOOP_SOCKET_INVALID (intptr_t) 0x8888888888888889ULL
158 : #else
159 : #define ELOOP_SOCKET_INVALID (intptr_t) 0x88888889ULL
160 : #endif
161 :
162 2586 : static void nl80211_register_eloop_read(struct nl_handle **handle,
163 : eloop_sock_handler handler,
164 : void *eloop_data)
165 : {
166 2586 : nl_socket_set_nonblocking(*handle);
167 2586 : eloop_register_read_sock(nl_socket_get_fd(*handle), handler,
168 : eloop_data, *handle);
169 2586 : *handle = (void *) (((intptr_t) *handle) ^ ELOOP_SOCKET_INVALID);
170 2586 : }
171 :
172 :
173 2586 : static void nl80211_destroy_eloop_handle(struct nl_handle **handle)
174 : {
175 2586 : *handle = (void *) (((intptr_t) *handle) ^ ELOOP_SOCKET_INVALID);
176 2586 : eloop_unregister_read_sock(nl_socket_get_fd(*handle));
177 2586 : nl_destroy_handles(handle);
178 2586 : }
179 :
180 :
181 : #ifndef IFF_LOWER_UP
182 : #define IFF_LOWER_UP 0x10000 /* driver signals L1 up */
183 : #endif
184 : #ifndef IFF_DORMANT
185 : #define IFF_DORMANT 0x20000 /* driver signals dormant */
186 : #endif
187 :
188 : #ifndef IF_OPER_DORMANT
189 : #define IF_OPER_DORMANT 5
190 : #endif
191 : #ifndef IF_OPER_UP
192 : #define IF_OPER_UP 6
193 : #endif
194 :
195 : struct nl80211_global {
196 : struct dl_list interfaces;
197 : int if_add_ifindex;
198 : u64 if_add_wdevid;
199 : int if_add_wdevid_set;
200 : struct netlink_data *netlink;
201 : struct nl_cb *nl_cb;
202 : struct nl_handle *nl;
203 : int nl80211_id;
204 : int ioctl_sock; /* socket for ioctl() use */
205 :
206 : struct nl_handle *nl_event;
207 : };
208 :
209 : struct nl80211_wiphy_data {
210 : struct dl_list list;
211 : struct dl_list bsss;
212 : struct dl_list drvs;
213 :
214 : struct nl_handle *nl_beacons;
215 : struct nl_cb *nl_cb;
216 :
217 : int wiphy_idx;
218 : };
219 :
220 : static void nl80211_global_deinit(void *priv);
221 :
222 : struct i802_bss {
223 : struct wpa_driver_nl80211_data *drv;
224 : struct i802_bss *next;
225 : int ifindex;
226 : u64 wdev_id;
227 : char ifname[IFNAMSIZ + 1];
228 : char brname[IFNAMSIZ];
229 : unsigned int beacon_set:1;
230 : unsigned int added_if_into_bridge:1;
231 : unsigned int added_bridge:1;
232 : unsigned int in_deinit:1;
233 : unsigned int wdev_id_set:1;
234 : unsigned int added_if:1;
235 :
236 : u8 addr[ETH_ALEN];
237 :
238 : int freq;
239 : int bandwidth;
240 : int if_dynamic;
241 :
242 : void *ctx;
243 : struct nl_handle *nl_preq, *nl_mgmt;
244 : struct nl_cb *nl_cb;
245 :
246 : struct nl80211_wiphy_data *wiphy_data;
247 : struct dl_list wiphy_list;
248 : };
249 :
250 : struct wpa_driver_nl80211_data {
251 : struct nl80211_global *global;
252 : struct dl_list list;
253 : struct dl_list wiphy_list;
254 : char phyname[32];
255 : void *ctx;
256 : int ifindex;
257 : int if_removed;
258 : int if_disabled;
259 : int ignore_if_down_event;
260 : struct rfkill_data *rfkill;
261 : struct wpa_driver_capa capa;
262 : u8 *extended_capa, *extended_capa_mask;
263 : unsigned int extended_capa_len;
264 : int has_capability;
265 :
266 : int operstate;
267 :
268 : int scan_complete_events;
269 : enum scan_states {
270 : NO_SCAN, SCAN_REQUESTED, SCAN_STARTED, SCAN_COMPLETED,
271 : SCAN_ABORTED, SCHED_SCAN_STARTED, SCHED_SCAN_STOPPED,
272 : SCHED_SCAN_RESULTS
273 : } scan_state;
274 :
275 : struct nl_cb *nl_cb;
276 :
277 : u8 auth_bssid[ETH_ALEN];
278 : u8 auth_attempt_bssid[ETH_ALEN];
279 : u8 bssid[ETH_ALEN];
280 : u8 prev_bssid[ETH_ALEN];
281 : int associated;
282 : u8 ssid[32];
283 : size_t ssid_len;
284 : enum nl80211_iftype nlmode;
285 : enum nl80211_iftype ap_scan_as_station;
286 : unsigned int assoc_freq;
287 :
288 : int monitor_sock;
289 : int monitor_ifidx;
290 : int monitor_refcount;
291 :
292 : unsigned int disabled_11b_rates:1;
293 : unsigned int pending_remain_on_chan:1;
294 : unsigned int in_interface_list:1;
295 : unsigned int device_ap_sme:1;
296 : unsigned int poll_command_supported:1;
297 : unsigned int data_tx_status:1;
298 : unsigned int scan_for_auth:1;
299 : unsigned int retry_auth:1;
300 : unsigned int use_monitor:1;
301 : unsigned int ignore_next_local_disconnect:1;
302 : unsigned int ignore_next_local_deauth:1;
303 : unsigned int allow_p2p_device:1;
304 : unsigned int hostapd:1;
305 : unsigned int start_mode_ap:1;
306 : unsigned int start_iface_up:1;
307 : unsigned int test_use_roc_tx:1;
308 : unsigned int ignore_deauth_event:1;
309 : unsigned int dfs_vendor_cmd_avail:1;
310 :
311 : u64 remain_on_chan_cookie;
312 : u64 send_action_cookie;
313 :
314 : unsigned int last_mgmt_freq;
315 :
316 : struct wpa_driver_scan_filter *filter_ssids;
317 : size_t num_filter_ssids;
318 :
319 : struct i802_bss *first_bss;
320 :
321 : int eapol_tx_sock;
322 :
323 : int eapol_sock; /* socket for EAPOL frames */
324 :
325 : int default_if_indices[16];
326 : int *if_indices;
327 : int num_if_indices;
328 :
329 : /* From failed authentication command */
330 : int auth_freq;
331 : u8 auth_bssid_[ETH_ALEN];
332 : u8 auth_ssid[32];
333 : size_t auth_ssid_len;
334 : int auth_alg;
335 : u8 *auth_ie;
336 : size_t auth_ie_len;
337 : u8 auth_wep_key[4][16];
338 : size_t auth_wep_key_len[4];
339 : int auth_wep_tx_keyidx;
340 : int auth_local_state_change;
341 : int auth_p2p;
342 : };
343 :
344 :
345 : static void wpa_driver_nl80211_deinit(struct i802_bss *bss);
346 : static void wpa_driver_nl80211_scan_timeout(void *eloop_ctx,
347 : void *timeout_ctx);
348 : static int wpa_driver_nl80211_set_mode(struct i802_bss *bss,
349 : enum nl80211_iftype nlmode);
350 : static int
351 : wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv,
352 : const u8 *set_addr, int first);
353 : static int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data *drv,
354 : const u8 *addr, int cmd, u16 reason_code,
355 : int local_state_change);
356 : static void nl80211_remove_monitor_interface(
357 : struct wpa_driver_nl80211_data *drv);
358 : static int nl80211_send_frame_cmd(struct i802_bss *bss,
359 : unsigned int freq, unsigned int wait,
360 : const u8 *buf, size_t buf_len, u64 *cookie,
361 : int no_cck, int no_ack, int offchanok);
362 : static int nl80211_register_frame(struct i802_bss *bss,
363 : struct nl_handle *hl_handle,
364 : u16 type, const u8 *match, size_t match_len);
365 : static int wpa_driver_nl80211_probe_req_report(struct i802_bss *bss,
366 : int report);
367 : #ifdef ANDROID
368 : static int android_pno_start(struct i802_bss *bss,
369 : struct wpa_driver_scan_params *params);
370 : static int android_pno_stop(struct i802_bss *bss);
371 : extern int wpa_driver_nl80211_driver_cmd(void *priv, char *cmd, char *buf,
372 : size_t buf_len);
373 : #endif /* ANDROID */
374 : #ifdef ANDROID_P2P
375 : #ifdef ANDROID_P2P_STUB
376 : int wpa_driver_set_p2p_noa(void *priv, u8 count, int start, int duration) {
377 : return 0;
378 : }
379 : int wpa_driver_get_p2p_noa(void *priv, u8 *buf, size_t len) {
380 : return 0;
381 : }
382 : int wpa_driver_set_p2p_ps(void *priv, int legacy_ps, int opp_ps, int ctwindow) {
383 : return -1;
384 : }
385 : int wpa_driver_set_ap_wps_p2p_ie(void *priv, const struct wpabuf *beacon,
386 : const struct wpabuf *proberesp,
387 : const struct wpabuf *assocresp) {
388 : return 0;
389 : }
390 : #else /* ANDROID_P2P_STUB */
391 : int wpa_driver_set_p2p_noa(void *priv, u8 count, int start, int duration);
392 : int wpa_driver_get_p2p_noa(void *priv, u8 *buf, size_t len);
393 : int wpa_driver_set_p2p_ps(void *priv, int legacy_ps, int opp_ps, int ctwindow);
394 : int wpa_driver_set_ap_wps_p2p_ie(void *priv, const struct wpabuf *beacon,
395 : const struct wpabuf *proberesp,
396 : const struct wpabuf *assocresp);
397 : #endif /* ANDROID_P2P_STUB */
398 : #endif /* ANDROID_P2P */
399 :
400 : static void add_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx);
401 : static void del_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx);
402 : static int have_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx);
403 : static int wpa_driver_nl80211_if_remove(struct i802_bss *bss,
404 : enum wpa_driver_if_type type,
405 : const char *ifname);
406 :
407 : static int nl80211_set_channel(struct i802_bss *bss,
408 : struct hostapd_freq_params *freq, int set_chan);
409 : static int nl80211_disable_11b_rates(struct wpa_driver_nl80211_data *drv,
410 : int ifindex, int disabled);
411 :
412 : static int nl80211_leave_ibss(struct wpa_driver_nl80211_data *drv);
413 : static int wpa_driver_nl80211_authenticate_retry(
414 : struct wpa_driver_nl80211_data *drv);
415 :
416 : static int i802_set_iface_flags(struct i802_bss *bss, int up);
417 :
418 :
419 43327 : static const char * nl80211_command_to_string(enum nl80211_commands cmd)
420 : {
421 : #define C2S(x) case x: return #x;
422 43327 : switch (cmd) {
423 0 : C2S(NL80211_CMD_UNSPEC)
424 0 : C2S(NL80211_CMD_GET_WIPHY)
425 0 : C2S(NL80211_CMD_SET_WIPHY)
426 0 : C2S(NL80211_CMD_NEW_WIPHY)
427 0 : C2S(NL80211_CMD_DEL_WIPHY)
428 0 : C2S(NL80211_CMD_GET_INTERFACE)
429 0 : C2S(NL80211_CMD_SET_INTERFACE)
430 0 : C2S(NL80211_CMD_NEW_INTERFACE)
431 0 : C2S(NL80211_CMD_DEL_INTERFACE)
432 0 : C2S(NL80211_CMD_GET_KEY)
433 0 : C2S(NL80211_CMD_SET_KEY)
434 0 : C2S(NL80211_CMD_NEW_KEY)
435 0 : C2S(NL80211_CMD_DEL_KEY)
436 0 : C2S(NL80211_CMD_GET_BEACON)
437 0 : C2S(NL80211_CMD_SET_BEACON)
438 0 : C2S(NL80211_CMD_START_AP)
439 1 : C2S(NL80211_CMD_STOP_AP)
440 0 : C2S(NL80211_CMD_GET_STATION)
441 0 : C2S(NL80211_CMD_SET_STATION)
442 2167 : C2S(NL80211_CMD_NEW_STATION)
443 2101 : C2S(NL80211_CMD_DEL_STATION)
444 0 : C2S(NL80211_CMD_GET_MPATH)
445 0 : C2S(NL80211_CMD_SET_MPATH)
446 0 : C2S(NL80211_CMD_NEW_MPATH)
447 0 : C2S(NL80211_CMD_DEL_MPATH)
448 0 : C2S(NL80211_CMD_SET_BSS)
449 0 : C2S(NL80211_CMD_SET_REG)
450 0 : C2S(NL80211_CMD_REQ_SET_REG)
451 0 : C2S(NL80211_CMD_GET_MESH_CONFIG)
452 0 : C2S(NL80211_CMD_SET_MESH_CONFIG)
453 0 : C2S(NL80211_CMD_SET_MGMT_EXTRA_IE)
454 0 : C2S(NL80211_CMD_GET_REG)
455 0 : C2S(NL80211_CMD_GET_SCAN)
456 1911 : C2S(NL80211_CMD_TRIGGER_SCAN)
457 1904 : C2S(NL80211_CMD_NEW_SCAN_RESULTS)
458 1 : C2S(NL80211_CMD_SCAN_ABORTED)
459 3249 : C2S(NL80211_CMD_REG_CHANGE)
460 2141 : C2S(NL80211_CMD_AUTHENTICATE)
461 2056 : C2S(NL80211_CMD_ASSOCIATE)
462 1998 : C2S(NL80211_CMD_DEAUTHENTICATE)
463 8 : C2S(NL80211_CMD_DISASSOCIATE)
464 4 : C2S(NL80211_CMD_MICHAEL_MIC_FAILURE)
465 0 : C2S(NL80211_CMD_REG_BEACON_HINT)
466 15 : C2S(NL80211_CMD_JOIN_IBSS)
467 0 : C2S(NL80211_CMD_LEAVE_IBSS)
468 0 : C2S(NL80211_CMD_TESTMODE)
469 1027 : C2S(NL80211_CMD_CONNECT)
470 0 : C2S(NL80211_CMD_ROAM)
471 997 : C2S(NL80211_CMD_DISCONNECT)
472 0 : C2S(NL80211_CMD_SET_WIPHY_NETNS)
473 0 : C2S(NL80211_CMD_GET_SURVEY)
474 0 : C2S(NL80211_CMD_NEW_SURVEY_RESULTS)
475 0 : C2S(NL80211_CMD_SET_PMKSA)
476 0 : C2S(NL80211_CMD_DEL_PMKSA)
477 0 : C2S(NL80211_CMD_FLUSH_PMKSA)
478 1095 : C2S(NL80211_CMD_REMAIN_ON_CHANNEL)
479 1093 : C2S(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL)
480 0 : C2S(NL80211_CMD_SET_TX_BITRATE_MASK)
481 0 : C2S(NL80211_CMD_REGISTER_FRAME)
482 12842 : C2S(NL80211_CMD_FRAME)
483 8698 : C2S(NL80211_CMD_FRAME_TX_STATUS)
484 0 : C2S(NL80211_CMD_SET_POWER_SAVE)
485 0 : C2S(NL80211_CMD_GET_POWER_SAVE)
486 0 : C2S(NL80211_CMD_SET_CQM)
487 5 : C2S(NL80211_CMD_NOTIFY_CQM)
488 0 : C2S(NL80211_CMD_SET_CHANNEL)
489 0 : C2S(NL80211_CMD_SET_WDS_PEER)
490 0 : C2S(NL80211_CMD_FRAME_WAIT_CANCEL)
491 0 : C2S(NL80211_CMD_JOIN_MESH)
492 0 : C2S(NL80211_CMD_LEAVE_MESH)
493 6 : C2S(NL80211_CMD_UNPROT_DEAUTHENTICATE)
494 4 : C2S(NL80211_CMD_UNPROT_DISASSOCIATE)
495 0 : C2S(NL80211_CMD_NEW_PEER_CANDIDATE)
496 0 : C2S(NL80211_CMD_GET_WOWLAN)
497 0 : C2S(NL80211_CMD_SET_WOWLAN)
498 0 : C2S(NL80211_CMD_START_SCHED_SCAN)
499 0 : C2S(NL80211_CMD_STOP_SCHED_SCAN)
500 0 : C2S(NL80211_CMD_SCHED_SCAN_RESULTS)
501 0 : C2S(NL80211_CMD_SCHED_SCAN_STOPPED)
502 0 : C2S(NL80211_CMD_SET_REKEY_OFFLOAD)
503 0 : C2S(NL80211_CMD_PMKSA_CANDIDATE)
504 0 : C2S(NL80211_CMD_TDLS_OPER)
505 0 : C2S(NL80211_CMD_TDLS_MGMT)
506 1 : C2S(NL80211_CMD_UNEXPECTED_FRAME)
507 2 : C2S(NL80211_CMD_PROBE_CLIENT)
508 0 : C2S(NL80211_CMD_REGISTER_BEACONS)
509 1 : C2S(NL80211_CMD_UNEXPECTED_4ADDR_FRAME)
510 0 : C2S(NL80211_CMD_SET_NOACK_MAP)
511 0 : C2S(NL80211_CMD_CH_SWITCH_NOTIFY)
512 0 : C2S(NL80211_CMD_START_P2P_DEVICE)
513 0 : C2S(NL80211_CMD_STOP_P2P_DEVICE)
514 0 : C2S(NL80211_CMD_CONN_FAILED)
515 0 : C2S(NL80211_CMD_SET_MCAST_RATE)
516 0 : C2S(NL80211_CMD_SET_MAC_ACL)
517 0 : C2S(NL80211_CMD_RADAR_DETECT)
518 0 : C2S(NL80211_CMD_GET_PROTOCOL_FEATURES)
519 0 : C2S(NL80211_CMD_UPDATE_FT_IES)
520 0 : C2S(NL80211_CMD_FT_EVENT)
521 0 : C2S(NL80211_CMD_CRIT_PROTOCOL_START)
522 0 : C2S(NL80211_CMD_CRIT_PROTOCOL_STOP)
523 0 : C2S(NL80211_CMD_GET_COALESCE)
524 0 : C2S(NL80211_CMD_SET_COALESCE)
525 0 : C2S(NL80211_CMD_CHANNEL_SWITCH)
526 0 : C2S(NL80211_CMD_VENDOR)
527 0 : C2S(NL80211_CMD_SET_QOS_MAP)
528 : default:
529 0 : return "NL80211_CMD_UNKNOWN";
530 : }
531 : #undef C2S
532 : }
533 :
534 :
535 : /* Converts nl80211_chan_width to a common format */
536 5 : static enum chan_width convert2width(int width)
537 : {
538 5 : switch (width) {
539 : case NL80211_CHAN_WIDTH_20_NOHT:
540 0 : return CHAN_WIDTH_20_NOHT;
541 : case NL80211_CHAN_WIDTH_20:
542 5 : return CHAN_WIDTH_20;
543 : case NL80211_CHAN_WIDTH_40:
544 0 : return CHAN_WIDTH_40;
545 : case NL80211_CHAN_WIDTH_80:
546 0 : return CHAN_WIDTH_80;
547 : case NL80211_CHAN_WIDTH_80P80:
548 0 : return CHAN_WIDTH_80P80;
549 : case NL80211_CHAN_WIDTH_160:
550 0 : return CHAN_WIDTH_160;
551 : }
552 0 : return CHAN_WIDTH_UNKNOWN;
553 : }
554 :
555 :
556 17726 : static int is_ap_interface(enum nl80211_iftype nlmode)
557 : {
558 17726 : return nlmode == NL80211_IFTYPE_AP ||
559 : nlmode == NL80211_IFTYPE_P2P_GO;
560 : }
561 :
562 :
563 6356 : static int is_sta_interface(enum nl80211_iftype nlmode)
564 : {
565 6356 : return nlmode == NL80211_IFTYPE_STATION ||
566 : nlmode == NL80211_IFTYPE_P2P_CLIENT;
567 : }
568 :
569 :
570 1799 : static int is_p2p_net_interface(enum nl80211_iftype nlmode)
571 : {
572 1799 : return nlmode == NL80211_IFTYPE_P2P_CLIENT ||
573 : nlmode == NL80211_IFTYPE_P2P_GO;
574 : }
575 :
576 :
577 4029 : static void nl80211_mark_disconnected(struct wpa_driver_nl80211_data *drv)
578 : {
579 4029 : if (drv->associated)
580 1033 : os_memcpy(drv->prev_bssid, drv->bssid, ETH_ALEN);
581 4029 : drv->associated = 0;
582 4029 : os_memset(drv->bssid, 0, ETH_ALEN);
583 4029 : }
584 :
585 :
586 : struct nl80211_bss_info_arg {
587 : struct wpa_driver_nl80211_data *drv;
588 : struct wpa_scan_results *res;
589 : unsigned int assoc_freq;
590 : unsigned int ibss_freq;
591 : u8 assoc_bssid[ETH_ALEN];
592 : };
593 :
594 : static int bss_info_handler(struct nl_msg *msg, void *arg);
595 :
596 :
597 : /* nl80211 code */
598 60699 : static int ack_handler(struct nl_msg *msg, void *arg)
599 : {
600 60699 : int *err = arg;
601 60699 : *err = 0;
602 60699 : return NL_STOP;
603 : }
604 :
605 7910 : static int finish_handler(struct nl_msg *msg, void *arg)
606 : {
607 7910 : int *ret = arg;
608 7910 : *ret = 0;
609 7910 : return NL_SKIP;
610 : }
611 :
612 11816 : static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err,
613 : void *arg)
614 : {
615 11816 : int *ret = arg;
616 11816 : *ret = err->error;
617 11816 : return NL_SKIP;
618 : }
619 :
620 :
621 431457 : static int no_seq_check(struct nl_msg *msg, void *arg)
622 : {
623 431457 : return NL_OK;
624 : }
625 :
626 :
627 80425 : static int send_and_recv(struct nl80211_global *global,
628 : struct nl_handle *nl_handle, struct nl_msg *msg,
629 : int (*valid_handler)(struct nl_msg *, void *),
630 : void *valid_data)
631 : {
632 : struct nl_cb *cb;
633 80425 : int err = -ENOMEM;
634 :
635 80425 : cb = nl_cb_clone(global->nl_cb);
636 80425 : if (!cb)
637 0 : goto out;
638 :
639 80425 : err = nl_send_auto_complete(nl_handle, msg);
640 80425 : if (err < 0)
641 0 : goto out;
642 :
643 80425 : err = 1;
644 :
645 80425 : nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
646 80425 : nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
647 80425 : nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);
648 :
649 80425 : if (valid_handler)
650 27164 : nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM,
651 : valid_handler, valid_data);
652 :
653 258232 : while (err > 0) {
654 97382 : int res = nl_recvmsgs(nl_handle, cb);
655 97382 : if (res) {
656 0 : wpa_printf(MSG_INFO,
657 : "nl80211: %s->nl_recvmsgs failed: %d",
658 : __func__, res);
659 : }
660 : }
661 : out:
662 80425 : nl_cb_put(cb);
663 80425 : nlmsg_free(msg);
664 80425 : return err;
665 : }
666 :
667 :
668 20 : static int send_and_recv_msgs_global(struct nl80211_global *global,
669 : struct nl_msg *msg,
670 : int (*valid_handler)(struct nl_msg *, void *),
671 : void *valid_data)
672 : {
673 20 : return send_and_recv(global, global->nl, msg, valid_handler,
674 : valid_data);
675 : }
676 :
677 :
678 66185 : static int send_and_recv_msgs(struct wpa_driver_nl80211_data *drv,
679 : struct nl_msg *msg,
680 : int (*valid_handler)(struct nl_msg *, void *),
681 : void *valid_data)
682 : {
683 66185 : return send_and_recv(drv->global, drv->global->nl, msg,
684 : valid_handler, valid_data);
685 : }
686 :
687 :
688 : struct family_data {
689 : const char *group;
690 : int id;
691 : };
692 :
693 :
694 32446 : static int nl80211_set_iface_id(struct nl_msg *msg, struct i802_bss *bss)
695 : {
696 32446 : if (bss->wdev_id_set)
697 0 : NLA_PUT_U64(msg, NL80211_ATTR_WDEV, bss->wdev_id);
698 : else
699 32446 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex);
700 32446 : return 0;
701 :
702 : nla_put_failure:
703 0 : return -1;
704 : }
705 :
706 :
707 20 : static int family_handler(struct nl_msg *msg, void *arg)
708 : {
709 20 : struct family_data *res = arg;
710 : struct nlattr *tb[CTRL_ATTR_MAX + 1];
711 20 : struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
712 : struct nlattr *mcgrp;
713 : int i;
714 :
715 20 : nla_parse(tb, CTRL_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
716 : genlmsg_attrlen(gnlh, 0), NULL);
717 20 : if (!tb[CTRL_ATTR_MCAST_GROUPS])
718 0 : return NL_SKIP;
719 :
720 140 : nla_for_each_nested(mcgrp, tb[CTRL_ATTR_MCAST_GROUPS], i) {
721 : struct nlattr *tb2[CTRL_ATTR_MCAST_GRP_MAX + 1];
722 70 : nla_parse(tb2, CTRL_ATTR_MCAST_GRP_MAX, nla_data(mcgrp),
723 : nla_len(mcgrp), NULL);
724 140 : if (!tb2[CTRL_ATTR_MCAST_GRP_NAME] ||
725 140 : !tb2[CTRL_ATTR_MCAST_GRP_ID] ||
726 70 : os_strncmp(nla_data(tb2[CTRL_ATTR_MCAST_GRP_NAME]),
727 : res->group,
728 : nla_len(tb2[CTRL_ATTR_MCAST_GRP_NAME])) != 0)
729 50 : continue;
730 20 : res->id = nla_get_u32(tb2[CTRL_ATTR_MCAST_GRP_ID]);
731 20 : break;
732 : };
733 :
734 20 : return NL_SKIP;
735 : }
736 :
737 :
738 20 : static int nl_get_multicast_id(struct nl80211_global *global,
739 : const char *family, const char *group)
740 : {
741 : struct nl_msg *msg;
742 20 : int ret = -1;
743 20 : struct family_data res = { group, -ENOENT };
744 :
745 20 : msg = nlmsg_alloc();
746 20 : if (!msg)
747 0 : return -ENOMEM;
748 20 : genlmsg_put(msg, 0, 0, genl_ctrl_resolve(global->nl, "nlctrl"),
749 : 0, 0, CTRL_CMD_GETFAMILY, 0);
750 20 : NLA_PUT_STRING(msg, CTRL_ATTR_FAMILY_NAME, family);
751 :
752 20 : ret = send_and_recv_msgs_global(global, msg, family_handler, &res);
753 20 : msg = NULL;
754 20 : if (ret == 0)
755 20 : ret = res.id;
756 :
757 : nla_put_failure:
758 20 : nlmsg_free(msg);
759 20 : return ret;
760 : }
761 :
762 :
763 80405 : static void * nl80211_cmd(struct wpa_driver_nl80211_data *drv,
764 : struct nl_msg *msg, int flags, uint8_t cmd)
765 : {
766 80405 : return genlmsg_put(msg, 0, 0, drv->global->nl80211_id,
767 : 0, flags, cmd, 0);
768 : }
769 :
770 :
771 : struct wiphy_idx_data {
772 : int wiphy_idx;
773 : enum nl80211_iftype nlmode;
774 : u8 *macaddr;
775 : };
776 :
777 :
778 2601 : static int netdev_info_handler(struct nl_msg *msg, void *arg)
779 : {
780 : struct nlattr *tb[NL80211_ATTR_MAX + 1];
781 2601 : struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
782 2601 : struct wiphy_idx_data *info = arg;
783 :
784 2601 : nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
785 : genlmsg_attrlen(gnlh, 0), NULL);
786 :
787 2601 : if (tb[NL80211_ATTR_WIPHY])
788 2601 : info->wiphy_idx = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
789 :
790 2601 : if (tb[NL80211_ATTR_IFTYPE])
791 2601 : info->nlmode = nla_get_u32(tb[NL80211_ATTR_IFTYPE]);
792 :
793 2601 : if (tb[NL80211_ATTR_MAC] && info->macaddr)
794 0 : os_memcpy(info->macaddr, nla_data(tb[NL80211_ATTR_MAC]),
795 : ETH_ALEN);
796 :
797 2601 : return NL_SKIP;
798 : }
799 :
800 :
801 707 : static int nl80211_get_wiphy_index(struct i802_bss *bss)
802 : {
803 : struct nl_msg *msg;
804 707 : struct wiphy_idx_data data = {
805 : .wiphy_idx = -1,
806 : .macaddr = NULL,
807 : };
808 :
809 707 : msg = nlmsg_alloc();
810 707 : if (!msg)
811 0 : return NL80211_IFTYPE_UNSPECIFIED;
812 :
813 707 : nl80211_cmd(bss->drv, msg, 0, NL80211_CMD_GET_INTERFACE);
814 :
815 707 : if (nl80211_set_iface_id(msg, bss) < 0)
816 0 : goto nla_put_failure;
817 :
818 707 : if (send_and_recv_msgs(bss->drv, msg, netdev_info_handler, &data) == 0)
819 707 : return data.wiphy_idx;
820 0 : msg = NULL;
821 : nla_put_failure:
822 0 : nlmsg_free(msg);
823 0 : return -1;
824 : }
825 :
826 :
827 1898 : static enum nl80211_iftype nl80211_get_ifmode(struct i802_bss *bss)
828 : {
829 : struct nl_msg *msg;
830 1898 : struct wiphy_idx_data data = {
831 : .nlmode = NL80211_IFTYPE_UNSPECIFIED,
832 : .macaddr = NULL,
833 : };
834 :
835 1898 : msg = nlmsg_alloc();
836 1898 : if (!msg)
837 0 : return -1;
838 :
839 1898 : nl80211_cmd(bss->drv, msg, 0, NL80211_CMD_GET_INTERFACE);
840 :
841 1898 : if (nl80211_set_iface_id(msg, bss) < 0)
842 0 : goto nla_put_failure;
843 :
844 1898 : if (send_and_recv_msgs(bss->drv, msg, netdev_info_handler, &data) == 0)
845 1894 : return data.nlmode;
846 4 : msg = NULL;
847 : nla_put_failure:
848 4 : nlmsg_free(msg);
849 4 : return NL80211_IFTYPE_UNSPECIFIED;
850 : }
851 :
852 :
853 0 : static int nl80211_get_macaddr(struct i802_bss *bss)
854 : {
855 : struct nl_msg *msg;
856 0 : struct wiphy_idx_data data = {
857 0 : .macaddr = bss->addr,
858 : };
859 :
860 0 : msg = nlmsg_alloc();
861 0 : if (!msg)
862 0 : return NL80211_IFTYPE_UNSPECIFIED;
863 :
864 0 : nl80211_cmd(bss->drv, msg, 0, NL80211_CMD_GET_INTERFACE);
865 0 : if (nl80211_set_iface_id(msg, bss) < 0)
866 0 : goto nla_put_failure;
867 :
868 0 : return send_and_recv_msgs(bss->drv, msg, netdev_info_handler, &data);
869 :
870 : nla_put_failure:
871 0 : nlmsg_free(msg);
872 0 : return NL80211_IFTYPE_UNSPECIFIED;
873 : }
874 :
875 :
876 690 : static int nl80211_register_beacons(struct wpa_driver_nl80211_data *drv,
877 : struct nl80211_wiphy_data *w)
878 : {
879 : struct nl_msg *msg;
880 690 : int ret = -1;
881 :
882 690 : msg = nlmsg_alloc();
883 690 : if (!msg)
884 0 : return -1;
885 :
886 690 : nl80211_cmd(drv, msg, 0, NL80211_CMD_REGISTER_BEACONS);
887 :
888 690 : NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, w->wiphy_idx);
889 :
890 690 : ret = send_and_recv(drv->global, w->nl_beacons, msg, NULL, NULL);
891 690 : msg = NULL;
892 690 : if (ret) {
893 0 : wpa_printf(MSG_DEBUG, "nl80211: Register beacons command "
894 : "failed: ret=%d (%s)",
895 : ret, strerror(-ret));
896 0 : goto nla_put_failure;
897 : }
898 690 : ret = 0;
899 : nla_put_failure:
900 690 : nlmsg_free(msg);
901 690 : return ret;
902 : }
903 :
904 :
905 1869 : static void nl80211_recv_beacons(int sock, void *eloop_ctx, void *handle)
906 : {
907 1869 : struct nl80211_wiphy_data *w = eloop_ctx;
908 : int res;
909 :
910 1869 : wpa_printf(MSG_EXCESSIVE, "nl80211: Beacon event message available");
911 :
912 1869 : res = nl_recvmsgs(handle, w->nl_cb);
913 1869 : if (res) {
914 0 : wpa_printf(MSG_INFO, "nl80211: %s->nl_recvmsgs failed: %d",
915 : __func__, res);
916 : }
917 1869 : }
918 :
919 :
920 1868 : static int process_beacon_event(struct nl_msg *msg, void *arg)
921 : {
922 1868 : struct nl80211_wiphy_data *w = arg;
923 : struct wpa_driver_nl80211_data *drv;
924 1868 : struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
925 : struct nlattr *tb[NL80211_ATTR_MAX + 1];
926 : union wpa_event_data event;
927 :
928 1868 : nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
929 : genlmsg_attrlen(gnlh, 0), NULL);
930 :
931 1868 : if (gnlh->cmd != NL80211_CMD_FRAME) {
932 0 : wpa_printf(MSG_DEBUG, "nl80211: Unexpected beacon event? (%d)",
933 0 : gnlh->cmd);
934 0 : return NL_SKIP;
935 : }
936 :
937 1868 : if (!tb[NL80211_ATTR_FRAME])
938 0 : return NL_SKIP;
939 :
940 3736 : dl_list_for_each(drv, &w->drvs, struct wpa_driver_nl80211_data,
941 : wiphy_list) {
942 1868 : os_memset(&event, 0, sizeof(event));
943 1868 : event.rx_mgmt.frame = nla_data(tb[NL80211_ATTR_FRAME]);
944 1868 : event.rx_mgmt.frame_len = nla_len(tb[NL80211_ATTR_FRAME]);
945 1868 : wpa_supplicant_event(drv->ctx, EVENT_RX_MGMT, &event);
946 : }
947 :
948 1868 : return NL_SKIP;
949 : }
950 :
951 :
952 : static struct nl80211_wiphy_data *
953 707 : nl80211_get_wiphy_data_ap(struct i802_bss *bss)
954 : {
955 : static DEFINE_DL_LIST(nl80211_wiphys);
956 : struct nl80211_wiphy_data *w;
957 707 : int wiphy_idx, found = 0;
958 : struct i802_bss *tmp_bss;
959 :
960 707 : if (bss->wiphy_data != NULL)
961 0 : return bss->wiphy_data;
962 :
963 707 : wiphy_idx = nl80211_get_wiphy_index(bss);
964 :
965 775 : dl_list_for_each(w, &nl80211_wiphys, struct nl80211_wiphy_data, list) {
966 85 : if (w->wiphy_idx == wiphy_idx)
967 17 : goto add;
968 : }
969 :
970 : /* alloc new one */
971 690 : w = os_zalloc(sizeof(*w));
972 690 : if (w == NULL)
973 0 : return NULL;
974 690 : w->wiphy_idx = wiphy_idx;
975 690 : dl_list_init(&w->bsss);
976 690 : dl_list_init(&w->drvs);
977 :
978 690 : w->nl_cb = nl_cb_alloc(NL_CB_DEFAULT);
979 690 : if (!w->nl_cb) {
980 0 : os_free(w);
981 0 : return NULL;
982 : }
983 690 : nl_cb_set(w->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL);
984 690 : nl_cb_set(w->nl_cb, NL_CB_VALID, NL_CB_CUSTOM, process_beacon_event,
985 : w);
986 :
987 690 : w->nl_beacons = nl_create_handle(bss->drv->global->nl_cb,
988 : "wiphy beacons");
989 690 : if (w->nl_beacons == NULL) {
990 0 : os_free(w);
991 0 : return NULL;
992 : }
993 :
994 690 : if (nl80211_register_beacons(bss->drv, w)) {
995 0 : nl_destroy_handles(&w->nl_beacons);
996 0 : os_free(w);
997 0 : return NULL;
998 : }
999 :
1000 690 : nl80211_register_eloop_read(&w->nl_beacons, nl80211_recv_beacons, w);
1001 :
1002 690 : dl_list_add(&nl80211_wiphys, &w->list);
1003 :
1004 : add:
1005 : /* drv entry for this bss already there? */
1006 707 : dl_list_for_each(tmp_bss, &w->bsss, struct i802_bss, wiphy_list) {
1007 17 : if (tmp_bss->drv == bss->drv) {
1008 17 : found = 1;
1009 17 : break;
1010 : }
1011 : }
1012 : /* if not add it */
1013 707 : if (!found)
1014 690 : dl_list_add(&w->drvs, &bss->drv->wiphy_list);
1015 :
1016 707 : dl_list_add(&w->bsss, &bss->wiphy_list);
1017 707 : bss->wiphy_data = w;
1018 707 : return w;
1019 : }
1020 :
1021 :
1022 1124 : static void nl80211_put_wiphy_data_ap(struct i802_bss *bss)
1023 : {
1024 1124 : struct nl80211_wiphy_data *w = bss->wiphy_data;
1025 : struct i802_bss *tmp_bss;
1026 1124 : int found = 0;
1027 :
1028 1124 : if (w == NULL)
1029 417 : return;
1030 707 : bss->wiphy_data = NULL;
1031 707 : dl_list_del(&bss->wiphy_list);
1032 :
1033 : /* still any for this drv present? */
1034 707 : dl_list_for_each(tmp_bss, &w->bsss, struct i802_bss, wiphy_list) {
1035 17 : if (tmp_bss->drv == bss->drv) {
1036 17 : found = 1;
1037 17 : break;
1038 : }
1039 : }
1040 : /* if not remove it */
1041 707 : if (!found)
1042 690 : dl_list_del(&bss->drv->wiphy_list);
1043 :
1044 707 : if (!dl_list_empty(&w->bsss))
1045 17 : return;
1046 :
1047 690 : nl80211_destroy_eloop_handle(&w->nl_beacons);
1048 :
1049 690 : nl_cb_put(w->nl_cb);
1050 690 : dl_list_del(&w->list);
1051 690 : os_free(w);
1052 : }
1053 :
1054 :
1055 1793 : static int wpa_driver_nl80211_get_bssid(void *priv, u8 *bssid)
1056 : {
1057 1793 : struct i802_bss *bss = priv;
1058 1793 : struct wpa_driver_nl80211_data *drv = bss->drv;
1059 1793 : if (!drv->associated)
1060 3 : return -1;
1061 1790 : os_memcpy(bssid, drv->bssid, ETH_ALEN);
1062 1790 : return 0;
1063 : }
1064 :
1065 :
1066 664 : static int wpa_driver_nl80211_get_ssid(void *priv, u8 *ssid)
1067 : {
1068 664 : struct i802_bss *bss = priv;
1069 664 : struct wpa_driver_nl80211_data *drv = bss->drv;
1070 664 : if (!drv->associated)
1071 1 : return -1;
1072 663 : os_memcpy(ssid, drv->ssid, drv->ssid_len);
1073 663 : return drv->ssid_len;
1074 : }
1075 :
1076 :
1077 4791 : static void wpa_driver_nl80211_event_newlink(
1078 : struct wpa_driver_nl80211_data *drv, char *ifname)
1079 : {
1080 : union wpa_event_data event;
1081 :
1082 4791 : if (os_strcmp(drv->first_bss->ifname, ifname) == 0) {
1083 4640 : if (if_nametoindex(drv->first_bss->ifname) == 0) {
1084 0 : wpa_printf(MSG_DEBUG, "nl80211: Interface %s does not exist - ignore RTM_NEWLINK",
1085 0 : drv->first_bss->ifname);
1086 0 : return;
1087 : }
1088 4640 : if (!drv->if_removed)
1089 4636 : return;
1090 4 : wpa_printf(MSG_DEBUG, "nl80211: Mark if_removed=0 for %s based on RTM_NEWLINK event",
1091 4 : drv->first_bss->ifname);
1092 4 : drv->if_removed = 0;
1093 : }
1094 :
1095 155 : os_memset(&event, 0, sizeof(event));
1096 155 : os_strlcpy(event.interface_status.ifname, ifname,
1097 : sizeof(event.interface_status.ifname));
1098 155 : event.interface_status.ievent = EVENT_INTERFACE_ADDED;
1099 155 : wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS, &event);
1100 : }
1101 :
1102 :
1103 5 : static void wpa_driver_nl80211_event_dellink(
1104 : struct wpa_driver_nl80211_data *drv, char *ifname)
1105 : {
1106 : union wpa_event_data event;
1107 :
1108 5 : if (os_strcmp(drv->first_bss->ifname, ifname) == 0) {
1109 4 : if (drv->if_removed) {
1110 0 : wpa_printf(MSG_DEBUG, "nl80211: if_removed already set - ignore RTM_DELLINK event for %s",
1111 : ifname);
1112 5 : return;
1113 : }
1114 4 : wpa_printf(MSG_DEBUG, "RTM_DELLINK: Interface '%s' removed - mark if_removed=1",
1115 : ifname);
1116 4 : drv->if_removed = 1;
1117 : } else {
1118 1 : wpa_printf(MSG_DEBUG, "RTM_DELLINK: Interface '%s' removed",
1119 : ifname);
1120 : }
1121 :
1122 5 : os_memset(&event, 0, sizeof(event));
1123 5 : os_strlcpy(event.interface_status.ifname, ifname,
1124 : sizeof(event.interface_status.ifname));
1125 5 : event.interface_status.ievent = EVENT_INTERFACE_REMOVED;
1126 5 : wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS, &event);
1127 : }
1128 :
1129 :
1130 0 : static int wpa_driver_nl80211_own_ifname(struct wpa_driver_nl80211_data *drv,
1131 : u8 *buf, size_t len)
1132 : {
1133 : int attrlen, rta_len;
1134 : struct rtattr *attr;
1135 :
1136 0 : attrlen = len;
1137 0 : attr = (struct rtattr *) buf;
1138 :
1139 0 : rta_len = RTA_ALIGN(sizeof(struct rtattr));
1140 0 : while (RTA_OK(attr, attrlen)) {
1141 0 : if (attr->rta_type == IFLA_IFNAME) {
1142 0 : if (os_strcmp(((char *) attr) + rta_len,
1143 : drv->first_bss->ifname) == 0)
1144 0 : return 1;
1145 : else
1146 0 : break;
1147 : }
1148 0 : attr = RTA_NEXT(attr, attrlen);
1149 : }
1150 :
1151 0 : return 0;
1152 : }
1153 :
1154 :
1155 22244 : static int wpa_driver_nl80211_own_ifindex(struct wpa_driver_nl80211_data *drv,
1156 : int ifindex, u8 *buf, size_t len)
1157 : {
1158 22244 : if (drv->ifindex == ifindex)
1159 4662 : return 1;
1160 :
1161 17582 : if (drv->if_removed && wpa_driver_nl80211_own_ifname(drv, buf, len)) {
1162 0 : wpa_printf(MSG_DEBUG, "nl80211: Update ifindex for a removed "
1163 : "interface");
1164 0 : wpa_driver_nl80211_finish_drv_init(drv, NULL, 0);
1165 0 : return 1;
1166 : }
1167 :
1168 17582 : return 0;
1169 : }
1170 :
1171 :
1172 : static struct wpa_driver_nl80211_data *
1173 29499 : nl80211_find_drv(struct nl80211_global *global, int idx, u8 *buf, size_t len)
1174 : {
1175 : struct wpa_driver_nl80211_data *drv;
1176 46829 : dl_list_for_each(drv, &global->interfaces,
1177 : struct wpa_driver_nl80211_data, list) {
1178 39826 : if (wpa_driver_nl80211_own_ifindex(drv, idx, buf, len) ||
1179 17582 : have_ifidx(drv, idx))
1180 4914 : return drv;
1181 : }
1182 24585 : return NULL;
1183 : }
1184 :
1185 :
1186 28998 : static void wpa_driver_nl80211_event_rtm_newlink(void *ctx,
1187 : struct ifinfomsg *ifi,
1188 : u8 *buf, size_t len)
1189 : {
1190 28998 : struct nl80211_global *global = ctx;
1191 : struct wpa_driver_nl80211_data *drv;
1192 : int attrlen;
1193 : struct rtattr *attr;
1194 28998 : u32 brid = 0;
1195 : char namebuf[IFNAMSIZ];
1196 : char ifname[IFNAMSIZ + 1];
1197 : char extra[100], *pos, *end;
1198 :
1199 28998 : drv = nl80211_find_drv(global, ifi->ifi_index, buf, len);
1200 28998 : if (!drv) {
1201 24090 : wpa_printf(MSG_DEBUG, "nl80211: Ignore RTM_NEWLINK event for foreign ifindex %d",
1202 : ifi->ifi_index);
1203 24090 : return;
1204 : }
1205 :
1206 4908 : extra[0] = '\0';
1207 4908 : pos = extra;
1208 4908 : end = pos + sizeof(extra);
1209 4908 : ifname[0] = '\0';
1210 :
1211 4908 : attrlen = len;
1212 4908 : attr = (struct rtattr *) buf;
1213 97359 : while (RTA_OK(attr, attrlen)) {
1214 87543 : switch (attr->rta_type) {
1215 : case IFLA_IFNAME:
1216 4908 : if (RTA_PAYLOAD(attr) >= IFNAMSIZ)
1217 0 : break;
1218 4908 : os_memcpy(ifname, RTA_DATA(attr), RTA_PAYLOAD(attr));
1219 4908 : ifname[RTA_PAYLOAD(attr)] = '\0';
1220 4908 : break;
1221 : case IFLA_MASTER:
1222 100 : brid = nla_get_u32((struct nlattr *) attr);
1223 100 : pos += os_snprintf(pos, end - pos, " master=%u", brid);
1224 100 : break;
1225 : case IFLA_WIRELESS:
1226 0 : pos += os_snprintf(pos, end - pos, " wext");
1227 0 : break;
1228 : case IFLA_OPERSTATE:
1229 4908 : pos += os_snprintf(pos, end - pos, " operstate=%u",
1230 : nla_get_u32((struct nlattr *) attr));
1231 4908 : break;
1232 : case IFLA_LINKMODE:
1233 4834 : pos += os_snprintf(pos, end - pos, " linkmode=%u",
1234 : nla_get_u32((struct nlattr *) attr));
1235 4834 : break;
1236 : }
1237 87543 : attr = RTA_NEXT(attr, attrlen);
1238 : }
1239 4908 : extra[sizeof(extra) - 1] = '\0';
1240 :
1241 19632 : wpa_printf(MSG_DEBUG, "RTM_NEWLINK: ifi_index=%d ifname=%s%s ifi_flags=0x%x (%s%s%s%s)",
1242 : ifi->ifi_index, ifname, extra, ifi->ifi_flags,
1243 4908 : (ifi->ifi_flags & IFF_UP) ? "[UP]" : "",
1244 4908 : (ifi->ifi_flags & IFF_RUNNING) ? "[RUNNING]" : "",
1245 4908 : (ifi->ifi_flags & IFF_LOWER_UP) ? "[LOWER_UP]" : "",
1246 4908 : (ifi->ifi_flags & IFF_DORMANT) ? "[DORMANT]" : "");
1247 :
1248 4908 : if (!drv->if_disabled && !(ifi->ifi_flags & IFF_UP)) {
1249 236 : if (if_indextoname(ifi->ifi_index, namebuf) &&
1250 118 : linux_iface_up(drv->global->ioctl_sock,
1251 118 : drv->first_bss->ifname) > 0) {
1252 117 : wpa_printf(MSG_DEBUG, "nl80211: Ignore interface down "
1253 : "event since interface %s is up", namebuf);
1254 117 : return;
1255 : }
1256 1 : wpa_printf(MSG_DEBUG, "nl80211: Interface down");
1257 1 : if (drv->ignore_if_down_event) {
1258 0 : wpa_printf(MSG_DEBUG, "nl80211: Ignore interface down "
1259 : "event generated by mode change");
1260 0 : drv->ignore_if_down_event = 0;
1261 : } else {
1262 1 : drv->if_disabled = 1;
1263 1 : wpa_supplicant_event(drv->ctx,
1264 : EVENT_INTERFACE_DISABLED, NULL);
1265 :
1266 : /*
1267 : * Try to get drv again, since it may be removed as
1268 : * part of the EVENT_INTERFACE_DISABLED handling for
1269 : * dynamic interfaces
1270 : */
1271 1 : drv = nl80211_find_drv(global, ifi->ifi_index,
1272 : buf, len);
1273 1 : if (!drv)
1274 0 : return;
1275 : }
1276 : }
1277 :
1278 4791 : if (drv->if_disabled && (ifi->ifi_flags & IFF_UP)) {
1279 2 : if (if_indextoname(ifi->ifi_index, namebuf) &&
1280 1 : linux_iface_up(drv->global->ioctl_sock,
1281 1 : drv->first_bss->ifname) == 0) {
1282 0 : wpa_printf(MSG_DEBUG, "nl80211: Ignore interface up "
1283 : "event since interface %s is down",
1284 : namebuf);
1285 1 : } else if (if_nametoindex(drv->first_bss->ifname) == 0) {
1286 0 : wpa_printf(MSG_DEBUG, "nl80211: Ignore interface up "
1287 : "event since interface %s does not exist",
1288 0 : drv->first_bss->ifname);
1289 1 : } else if (drv->if_removed) {
1290 0 : wpa_printf(MSG_DEBUG, "nl80211: Ignore interface up "
1291 : "event since interface %s is marked "
1292 0 : "removed", drv->first_bss->ifname);
1293 : } else {
1294 1 : wpa_printf(MSG_DEBUG, "nl80211: Interface up");
1295 1 : drv->if_disabled = 0;
1296 1 : wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_ENABLED,
1297 : NULL);
1298 : }
1299 : }
1300 :
1301 : /*
1302 : * Some drivers send the association event before the operup event--in
1303 : * this case, lifting operstate in wpa_driver_nl80211_set_operstate()
1304 : * fails. This will hit us when wpa_supplicant does not need to do
1305 : * IEEE 802.1X authentication
1306 : */
1307 7250 : if (drv->operstate == 1 &&
1308 4305 : (ifi->ifi_flags & (IFF_LOWER_UP | IFF_DORMANT)) == IFF_LOWER_UP &&
1309 1846 : !(ifi->ifi_flags & IFF_RUNNING)) {
1310 178 : wpa_printf(MSG_DEBUG, "nl80211: Set IF_OPER_UP again based on ifi_flags and expected operstate");
1311 178 : netlink_send_oper_ifla(drv->global->netlink, drv->ifindex,
1312 : -1, IF_OPER_UP);
1313 : }
1314 :
1315 4791 : if (ifname[0])
1316 4791 : wpa_driver_nl80211_event_newlink(drv, ifname);
1317 :
1318 4791 : if (ifi->ifi_family == AF_BRIDGE && brid) {
1319 : /* device has been added to bridge */
1320 73 : if_indextoname(brid, namebuf);
1321 73 : wpa_printf(MSG_DEBUG, "nl80211: Add ifindex %u for bridge %s",
1322 : brid, namebuf);
1323 73 : add_ifidx(drv, brid);
1324 : }
1325 : }
1326 :
1327 :
1328 500 : static void wpa_driver_nl80211_event_rtm_dellink(void *ctx,
1329 : struct ifinfomsg *ifi,
1330 : u8 *buf, size_t len)
1331 : {
1332 500 : struct nl80211_global *global = ctx;
1333 : struct wpa_driver_nl80211_data *drv;
1334 : int attrlen;
1335 : struct rtattr *attr;
1336 500 : u32 brid = 0;
1337 : char ifname[IFNAMSIZ + 1];
1338 :
1339 500 : drv = nl80211_find_drv(global, ifi->ifi_index, buf, len);
1340 500 : if (!drv) {
1341 495 : wpa_printf(MSG_DEBUG, "nl80211: Ignore RTM_DELLINK event for foreign ifindex %d",
1342 : ifi->ifi_index);
1343 995 : return;
1344 : }
1345 :
1346 5 : ifname[0] = '\0';
1347 :
1348 5 : attrlen = len;
1349 5 : attr = (struct rtattr *) buf;
1350 35 : while (RTA_OK(attr, attrlen)) {
1351 25 : switch (attr->rta_type) {
1352 : case IFLA_IFNAME:
1353 5 : if (RTA_PAYLOAD(attr) >= IFNAMSIZ)
1354 0 : break;
1355 5 : os_memcpy(ifname, RTA_DATA(attr), RTA_PAYLOAD(attr));
1356 5 : ifname[RTA_PAYLOAD(attr)] = '\0';
1357 5 : break;
1358 : case IFLA_MASTER:
1359 5 : brid = nla_get_u32((struct nlattr *) attr);
1360 5 : break;
1361 : }
1362 25 : attr = RTA_NEXT(attr, attrlen);
1363 : }
1364 :
1365 5 : if (ifname[0])
1366 5 : wpa_driver_nl80211_event_dellink(drv, ifname);
1367 :
1368 5 : if (ifi->ifi_family == AF_BRIDGE && brid) {
1369 : /* device has been removed from bridge */
1370 : char namebuf[IFNAMSIZ];
1371 5 : if_indextoname(brid, namebuf);
1372 5 : wpa_printf(MSG_DEBUG, "nl80211: Remove ifindex %u for bridge "
1373 : "%s", brid, namebuf);
1374 5 : del_ifidx(drv, brid);
1375 : }
1376 : }
1377 :
1378 :
1379 1068 : static void mlme_event_auth(struct wpa_driver_nl80211_data *drv,
1380 : const u8 *frame, size_t len)
1381 : {
1382 : const struct ieee80211_mgmt *mgmt;
1383 : union wpa_event_data event;
1384 :
1385 1068 : wpa_printf(MSG_DEBUG, "nl80211: Authenticate event");
1386 1068 : mgmt = (const struct ieee80211_mgmt *) frame;
1387 1068 : if (len < 24 + sizeof(mgmt->u.auth)) {
1388 0 : wpa_printf(MSG_DEBUG, "nl80211: Too short association event "
1389 : "frame");
1390 1068 : return;
1391 : }
1392 :
1393 1068 : os_memcpy(drv->auth_bssid, mgmt->sa, ETH_ALEN);
1394 1068 : os_memset(drv->auth_attempt_bssid, 0, ETH_ALEN);
1395 1068 : os_memset(&event, 0, sizeof(event));
1396 1068 : os_memcpy(event.auth.peer, mgmt->sa, ETH_ALEN);
1397 1068 : event.auth.auth_type = le_to_host16(mgmt->u.auth.auth_alg);
1398 1068 : event.auth.auth_transaction =
1399 1068 : le_to_host16(mgmt->u.auth.auth_transaction);
1400 1068 : event.auth.status_code = le_to_host16(mgmt->u.auth.status_code);
1401 1068 : if (len > 24 + sizeof(mgmt->u.auth)) {
1402 57 : event.auth.ies = mgmt->u.auth.variable;
1403 57 : event.auth.ies_len = len - 24 - sizeof(mgmt->u.auth);
1404 : }
1405 :
1406 1068 : wpa_supplicant_event(drv->ctx, EVENT_AUTH, &event);
1407 : }
1408 :
1409 :
1410 48 : static unsigned int nl80211_get_assoc_freq(struct wpa_driver_nl80211_data *drv)
1411 : {
1412 : struct nl_msg *msg;
1413 : int ret;
1414 : struct nl80211_bss_info_arg arg;
1415 :
1416 48 : os_memset(&arg, 0, sizeof(arg));
1417 48 : msg = nlmsg_alloc();
1418 48 : if (!msg)
1419 0 : goto nla_put_failure;
1420 :
1421 48 : nl80211_cmd(drv, msg, NLM_F_DUMP, NL80211_CMD_GET_SCAN);
1422 48 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
1423 :
1424 48 : arg.drv = drv;
1425 48 : ret = send_and_recv_msgs(drv, msg, bss_info_handler, &arg);
1426 48 : msg = NULL;
1427 48 : if (ret == 0) {
1428 96 : unsigned int freq = drv->nlmode == NL80211_IFTYPE_ADHOC ?
1429 48 : arg.ibss_freq : arg.assoc_freq;
1430 48 : wpa_printf(MSG_DEBUG, "nl80211: Operating frequency for the "
1431 : "associated BSS from scan results: %u MHz", freq);
1432 48 : if (freq)
1433 48 : drv->assoc_freq = freq;
1434 48 : return drv->assoc_freq;
1435 : }
1436 0 : wpa_printf(MSG_DEBUG, "nl80211: Scan result fetch failed: ret=%d "
1437 : "(%s)", ret, strerror(-ret));
1438 : nla_put_failure:
1439 0 : nlmsg_free(msg);
1440 0 : return drv->assoc_freq;
1441 : }
1442 :
1443 :
1444 1027 : static void mlme_event_assoc(struct wpa_driver_nl80211_data *drv,
1445 : const u8 *frame, size_t len)
1446 : {
1447 : const struct ieee80211_mgmt *mgmt;
1448 : union wpa_event_data event;
1449 : u16 status;
1450 :
1451 1027 : wpa_printf(MSG_DEBUG, "nl80211: Associate event");
1452 1027 : mgmt = (const struct ieee80211_mgmt *) frame;
1453 1027 : if (len < 24 + sizeof(mgmt->u.assoc_resp)) {
1454 0 : wpa_printf(MSG_DEBUG, "nl80211: Too short association event "
1455 : "frame");
1456 0 : return;
1457 : }
1458 :
1459 1027 : status = le_to_host16(mgmt->u.assoc_resp.status_code);
1460 1027 : if (status != WLAN_STATUS_SUCCESS) {
1461 7 : os_memset(&event, 0, sizeof(event));
1462 7 : event.assoc_reject.bssid = mgmt->bssid;
1463 7 : if (len > 24 + sizeof(mgmt->u.assoc_resp)) {
1464 7 : event.assoc_reject.resp_ies =
1465 7 : (u8 *) mgmt->u.assoc_resp.variable;
1466 7 : event.assoc_reject.resp_ies_len =
1467 7 : len - 24 - sizeof(mgmt->u.assoc_resp);
1468 : }
1469 7 : event.assoc_reject.status_code = status;
1470 :
1471 7 : wpa_supplicant_event(drv->ctx, EVENT_ASSOC_REJECT, &event);
1472 7 : return;
1473 : }
1474 :
1475 1020 : drv->associated = 1;
1476 1020 : os_memcpy(drv->bssid, mgmt->sa, ETH_ALEN);
1477 1020 : os_memcpy(drv->prev_bssid, mgmt->sa, ETH_ALEN);
1478 :
1479 1020 : os_memset(&event, 0, sizeof(event));
1480 1020 : if (len > 24 + sizeof(mgmt->u.assoc_resp)) {
1481 1020 : event.assoc_info.resp_ies = (u8 *) mgmt->u.assoc_resp.variable;
1482 1020 : event.assoc_info.resp_ies_len =
1483 1020 : len - 24 - sizeof(mgmt->u.assoc_resp);
1484 : }
1485 :
1486 1020 : event.assoc_info.freq = drv->assoc_freq;
1487 :
1488 1020 : wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event);
1489 : }
1490 :
1491 :
1492 1027 : static void mlme_event_connect(struct wpa_driver_nl80211_data *drv,
1493 : enum nl80211_commands cmd, struct nlattr *status,
1494 : struct nlattr *addr, struct nlattr *req_ie,
1495 : struct nlattr *resp_ie)
1496 : {
1497 : union wpa_event_data event;
1498 :
1499 1027 : if (drv->capa.flags & WPA_DRIVER_FLAGS_SME) {
1500 : /*
1501 : * Avoid reporting two association events that would confuse
1502 : * the core code.
1503 : */
1504 1016 : wpa_printf(MSG_DEBUG, "nl80211: Ignore connect event (cmd=%d) "
1505 : "when using userspace SME", cmd);
1506 1016 : return;
1507 : }
1508 :
1509 11 : if (cmd == NL80211_CMD_CONNECT)
1510 11 : wpa_printf(MSG_DEBUG, "nl80211: Connect event");
1511 0 : else if (cmd == NL80211_CMD_ROAM)
1512 0 : wpa_printf(MSG_DEBUG, "nl80211: Roam event");
1513 :
1514 11 : os_memset(&event, 0, sizeof(event));
1515 22 : if (cmd == NL80211_CMD_CONNECT &&
1516 11 : nla_get_u16(status) != WLAN_STATUS_SUCCESS) {
1517 0 : if (addr)
1518 0 : event.assoc_reject.bssid = nla_data(addr);
1519 0 : if (resp_ie) {
1520 0 : event.assoc_reject.resp_ies = nla_data(resp_ie);
1521 0 : event.assoc_reject.resp_ies_len = nla_len(resp_ie);
1522 : }
1523 0 : event.assoc_reject.status_code = nla_get_u16(status);
1524 0 : wpa_supplicant_event(drv->ctx, EVENT_ASSOC_REJECT, &event);
1525 0 : return;
1526 : }
1527 :
1528 11 : drv->associated = 1;
1529 11 : if (addr) {
1530 11 : os_memcpy(drv->bssid, nla_data(addr), ETH_ALEN);
1531 11 : os_memcpy(drv->prev_bssid, drv->bssid, ETH_ALEN);
1532 : }
1533 :
1534 11 : if (req_ie) {
1535 0 : event.assoc_info.req_ies = nla_data(req_ie);
1536 0 : event.assoc_info.req_ies_len = nla_len(req_ie);
1537 : }
1538 11 : if (resp_ie) {
1539 11 : event.assoc_info.resp_ies = nla_data(resp_ie);
1540 11 : event.assoc_info.resp_ies_len = nla_len(resp_ie);
1541 : }
1542 :
1543 11 : event.assoc_info.freq = nl80211_get_assoc_freq(drv);
1544 :
1545 11 : wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event);
1546 : }
1547 :
1548 :
1549 997 : static void mlme_event_disconnect(struct wpa_driver_nl80211_data *drv,
1550 : struct nlattr *reason, struct nlattr *addr,
1551 : struct nlattr *by_ap)
1552 : {
1553 : union wpa_event_data data;
1554 997 : unsigned int locally_generated = by_ap == NULL;
1555 :
1556 997 : if (drv->capa.flags & WPA_DRIVER_FLAGS_SME) {
1557 : /*
1558 : * Avoid reporting two disassociation events that could
1559 : * confuse the core code.
1560 : */
1561 990 : wpa_printf(MSG_DEBUG, "nl80211: Ignore disconnect "
1562 : "event when using userspace SME");
1563 990 : return;
1564 : }
1565 :
1566 7 : if (drv->ignore_next_local_disconnect) {
1567 7 : drv->ignore_next_local_disconnect = 0;
1568 7 : if (locally_generated) {
1569 7 : wpa_printf(MSG_DEBUG, "nl80211: Ignore disconnect "
1570 : "event triggered during reassociation");
1571 7 : return;
1572 : }
1573 0 : wpa_printf(MSG_WARNING, "nl80211: Was expecting local "
1574 : "disconnect but got another disconnect "
1575 : "event first");
1576 : }
1577 :
1578 0 : wpa_printf(MSG_DEBUG, "nl80211: Disconnect event");
1579 0 : nl80211_mark_disconnected(drv);
1580 0 : os_memset(&data, 0, sizeof(data));
1581 0 : if (reason)
1582 0 : data.deauth_info.reason_code = nla_get_u16(reason);
1583 0 : data.deauth_info.locally_generated = by_ap == NULL;
1584 0 : wpa_supplicant_event(drv->ctx, EVENT_DEAUTH, &data);
1585 : }
1586 :
1587 :
1588 0 : static int calculate_chan_offset(int width, int freq, int cf1, int cf2)
1589 : {
1590 0 : int freq1 = 0;
1591 :
1592 0 : switch (convert2width(width)) {
1593 : case CHAN_WIDTH_20_NOHT:
1594 : case CHAN_WIDTH_20:
1595 0 : return 0;
1596 : case CHAN_WIDTH_40:
1597 0 : freq1 = cf1 - 10;
1598 0 : break;
1599 : case CHAN_WIDTH_80:
1600 0 : freq1 = cf1 - 30;
1601 0 : break;
1602 : case CHAN_WIDTH_160:
1603 0 : freq1 = cf1 - 70;
1604 0 : break;
1605 : case CHAN_WIDTH_UNKNOWN:
1606 : case CHAN_WIDTH_80P80:
1607 : /* FIXME: implement this */
1608 0 : return 0;
1609 : }
1610 :
1611 0 : return (abs(freq - freq1) / 20) % 2 == 0 ? 1 : -1;
1612 : }
1613 :
1614 :
1615 0 : static void mlme_event_ch_switch(struct wpa_driver_nl80211_data *drv,
1616 : struct nlattr *ifindex, struct nlattr *freq,
1617 : struct nlattr *type, struct nlattr *bw,
1618 : struct nlattr *cf1, struct nlattr *cf2)
1619 : {
1620 : struct i802_bss *bss;
1621 : union wpa_event_data data;
1622 0 : int ht_enabled = 1;
1623 0 : int chan_offset = 0;
1624 : int ifidx;
1625 :
1626 0 : wpa_printf(MSG_DEBUG, "nl80211: Channel switch event");
1627 :
1628 0 : if (!freq)
1629 0 : return;
1630 :
1631 0 : ifidx = nla_get_u32(ifindex);
1632 0 : for (bss = drv->first_bss; bss; bss = bss->next)
1633 0 : if (bss->ifindex == ifidx)
1634 0 : break;
1635 :
1636 0 : if (bss == NULL) {
1637 0 : wpa_printf(MSG_WARNING, "nl80211: Unknown ifindex (%d) for channel switch, ignoring",
1638 : ifidx);
1639 0 : return;
1640 : }
1641 :
1642 0 : if (type) {
1643 0 : switch (nla_get_u32(type)) {
1644 : case NL80211_CHAN_NO_HT:
1645 0 : ht_enabled = 0;
1646 0 : break;
1647 : case NL80211_CHAN_HT20:
1648 0 : break;
1649 : case NL80211_CHAN_HT40PLUS:
1650 0 : chan_offset = 1;
1651 0 : break;
1652 : case NL80211_CHAN_HT40MINUS:
1653 0 : chan_offset = -1;
1654 0 : break;
1655 : }
1656 0 : } else if (bw && cf1) {
1657 : /* This can happen for example with VHT80 ch switch */
1658 0 : chan_offset = calculate_chan_offset(nla_get_u32(bw),
1659 0 : nla_get_u32(freq),
1660 0 : nla_get_u32(cf1),
1661 0 : cf2 ? nla_get_u32(cf2) : 0);
1662 : } else {
1663 0 : wpa_printf(MSG_WARNING, "nl80211: Unknown secondary channel information - following channel definition calculations may fail");
1664 : }
1665 :
1666 0 : os_memset(&data, 0, sizeof(data));
1667 0 : data.ch_switch.freq = nla_get_u32(freq);
1668 0 : data.ch_switch.ht_enabled = ht_enabled;
1669 0 : data.ch_switch.ch_offset = chan_offset;
1670 0 : if (bw)
1671 0 : data.ch_switch.ch_width = convert2width(nla_get_u32(bw));
1672 0 : if (cf1)
1673 0 : data.ch_switch.cf1 = nla_get_u32(cf1);
1674 0 : if (cf2)
1675 0 : data.ch_switch.cf2 = nla_get_u32(cf2);
1676 :
1677 0 : bss->freq = data.ch_switch.freq;
1678 :
1679 0 : wpa_supplicant_event(drv->ctx, EVENT_CH_SWITCH, &data);
1680 : }
1681 :
1682 :
1683 7 : static void mlme_timeout_event(struct wpa_driver_nl80211_data *drv,
1684 : enum nl80211_commands cmd, struct nlattr *addr)
1685 : {
1686 : union wpa_event_data event;
1687 : enum wpa_event_type ev;
1688 :
1689 7 : if (nla_len(addr) != ETH_ALEN)
1690 0 : return;
1691 :
1692 42 : wpa_printf(MSG_DEBUG, "nl80211: MLME event %d; timeout with " MACSTR,
1693 42 : cmd, MAC2STR((u8 *) nla_data(addr)));
1694 :
1695 7 : if (cmd == NL80211_CMD_AUTHENTICATE)
1696 5 : ev = EVENT_AUTH_TIMED_OUT;
1697 2 : else if (cmd == NL80211_CMD_ASSOCIATE)
1698 2 : ev = EVENT_ASSOC_TIMED_OUT;
1699 : else
1700 0 : return;
1701 :
1702 7 : os_memset(&event, 0, sizeof(event));
1703 7 : os_memcpy(event.timeout_event.addr, nla_data(addr), ETH_ALEN);
1704 7 : wpa_supplicant_event(drv->ctx, ev, &event);
1705 : }
1706 :
1707 :
1708 6420 : static void mlme_event_mgmt(struct i802_bss *bss,
1709 : struct nlattr *freq, struct nlattr *sig,
1710 : const u8 *frame, size_t len)
1711 : {
1712 6420 : struct wpa_driver_nl80211_data *drv = bss->drv;
1713 : const struct ieee80211_mgmt *mgmt;
1714 : union wpa_event_data event;
1715 : u16 fc, stype;
1716 6420 : int ssi_signal = 0;
1717 6420 : int rx_freq = 0;
1718 :
1719 6420 : wpa_printf(MSG_MSGDUMP, "nl80211: Frame event");
1720 6420 : mgmt = (const struct ieee80211_mgmt *) frame;
1721 6420 : if (len < 24) {
1722 0 : wpa_printf(MSG_DEBUG, "nl80211: Too short management frame");
1723 6420 : return;
1724 : }
1725 :
1726 6420 : fc = le_to_host16(mgmt->frame_control);
1727 6420 : stype = WLAN_FC_GET_STYPE(fc);
1728 :
1729 6420 : if (sig)
1730 6420 : ssi_signal = (s32) nla_get_u32(sig);
1731 :
1732 6420 : os_memset(&event, 0, sizeof(event));
1733 6420 : if (freq) {
1734 6420 : event.rx_mgmt.freq = nla_get_u32(freq);
1735 6420 : rx_freq = drv->last_mgmt_freq = event.rx_mgmt.freq;
1736 : }
1737 6420 : wpa_printf(MSG_DEBUG,
1738 : "nl80211: RX frame freq=%d ssi_signal=%d stype=%u len=%u",
1739 : rx_freq, ssi_signal, stype, (unsigned int) len);
1740 6420 : event.rx_mgmt.frame = frame;
1741 6420 : event.rx_mgmt.frame_len = len;
1742 6420 : event.rx_mgmt.ssi_signal = ssi_signal;
1743 6420 : event.rx_mgmt.drv_priv = bss;
1744 6420 : wpa_supplicant_event(drv->ctx, EVENT_RX_MGMT, &event);
1745 : }
1746 :
1747 :
1748 4349 : static void mlme_event_mgmt_tx_status(struct wpa_driver_nl80211_data *drv,
1749 : struct nlattr *cookie, const u8 *frame,
1750 : size_t len, struct nlattr *ack)
1751 : {
1752 : union wpa_event_data event;
1753 : const struct ieee80211_hdr *hdr;
1754 : u16 fc;
1755 :
1756 4349 : wpa_printf(MSG_DEBUG, "nl80211: Frame TX status event");
1757 4349 : if (!is_ap_interface(drv->nlmode)) {
1758 : u64 cookie_val;
1759 :
1760 1178 : if (!cookie)
1761 132 : return;
1762 :
1763 1178 : cookie_val = nla_get_u64(cookie);
1764 2356 : wpa_printf(MSG_DEBUG, "nl80211: Action TX status:"
1765 : " cookie=0%llx%s (ack=%d)",
1766 : (long long unsigned int) cookie_val,
1767 1178 : cookie_val == drv->send_action_cookie ?
1768 : " (match)" : " (unknown)", ack != NULL);
1769 1178 : if (cookie_val != drv->send_action_cookie)
1770 132 : return;
1771 : }
1772 :
1773 4217 : hdr = (const struct ieee80211_hdr *) frame;
1774 4217 : fc = le_to_host16(hdr->frame_control);
1775 :
1776 4217 : os_memset(&event, 0, sizeof(event));
1777 4217 : event.tx_status.type = WLAN_FC_GET_TYPE(fc);
1778 4217 : event.tx_status.stype = WLAN_FC_GET_STYPE(fc);
1779 4217 : event.tx_status.dst = hdr->addr1;
1780 4217 : event.tx_status.data = frame;
1781 4217 : event.tx_status.data_len = len;
1782 4217 : event.tx_status.ack = ack != NULL;
1783 4217 : wpa_supplicant_event(drv->ctx, EVENT_TX_STATUS, &event);
1784 : }
1785 :
1786 :
1787 1003 : static void mlme_event_deauth_disassoc(struct wpa_driver_nl80211_data *drv,
1788 : enum wpa_event_type type,
1789 : const u8 *frame, size_t len)
1790 : {
1791 : const struct ieee80211_mgmt *mgmt;
1792 : union wpa_event_data event;
1793 1003 : const u8 *bssid = NULL;
1794 1003 : u16 reason_code = 0;
1795 :
1796 1003 : if (type == EVENT_DEAUTH)
1797 999 : wpa_printf(MSG_DEBUG, "nl80211: Deauthenticate event");
1798 : else
1799 4 : wpa_printf(MSG_DEBUG, "nl80211: Disassociate event");
1800 :
1801 1003 : mgmt = (const struct ieee80211_mgmt *) frame;
1802 1003 : if (len >= 24) {
1803 1003 : bssid = mgmt->bssid;
1804 :
1805 1999 : if ((drv->capa.flags & WPA_DRIVER_FLAGS_SME) &&
1806 1851 : !drv->associated &&
1807 905 : os_memcmp(bssid, drv->auth_bssid, ETH_ALEN) != 0 &&
1808 86 : os_memcmp(bssid, drv->auth_attempt_bssid, ETH_ALEN) != 0 &&
1809 36 : os_memcmp(bssid, drv->prev_bssid, ETH_ALEN) == 0) {
1810 : /*
1811 : * Avoid issues with some roaming cases where
1812 : * disconnection event for the old AP may show up after
1813 : * we have started connection with the new AP.
1814 : */
1815 432 : wpa_printf(MSG_DEBUG, "nl80211: Ignore deauth/disassoc event from old AP " MACSTR " when already authenticating with " MACSTR,
1816 216 : MAC2STR(bssid),
1817 216 : MAC2STR(drv->auth_attempt_bssid));
1818 36 : return;
1819 : }
1820 :
1821 1108 : if (drv->associated != 0 &&
1822 141 : os_memcmp(bssid, drv->bssid, ETH_ALEN) != 0 &&
1823 0 : os_memcmp(bssid, drv->auth_bssid, ETH_ALEN) != 0) {
1824 : /*
1825 : * We have presumably received this deauth as a
1826 : * response to a clear_state_mismatch() outgoing
1827 : * deauth. Don't let it take us offline!
1828 : */
1829 0 : wpa_printf(MSG_DEBUG, "nl80211: Deauth received "
1830 : "from Unknown BSSID " MACSTR " -- ignoring",
1831 0 : MAC2STR(bssid));
1832 0 : return;
1833 : }
1834 : }
1835 :
1836 967 : nl80211_mark_disconnected(drv);
1837 967 : os_memset(&event, 0, sizeof(event));
1838 :
1839 : /* Note: Same offset for Reason Code in both frame subtypes */
1840 967 : if (len >= 24 + sizeof(mgmt->u.deauth))
1841 967 : reason_code = le_to_host16(mgmt->u.deauth.reason_code);
1842 :
1843 967 : if (type == EVENT_DISASSOC) {
1844 4 : event.disassoc_info.locally_generated =
1845 4 : !os_memcmp(mgmt->sa, drv->first_bss->addr, ETH_ALEN);
1846 4 : event.disassoc_info.addr = bssid;
1847 4 : event.disassoc_info.reason_code = reason_code;
1848 4 : if (frame + len > mgmt->u.disassoc.variable) {
1849 1 : event.disassoc_info.ie = mgmt->u.disassoc.variable;
1850 1 : event.disassoc_info.ie_len = frame + len -
1851 : mgmt->u.disassoc.variable;
1852 : }
1853 : } else {
1854 963 : if (drv->ignore_deauth_event) {
1855 3 : wpa_printf(MSG_DEBUG, "nl80211: Ignore deauth event due to previous forced deauth-during-auth");
1856 3 : drv->ignore_deauth_event = 0;
1857 3 : return;
1858 : }
1859 960 : event.deauth_info.locally_generated =
1860 960 : !os_memcmp(mgmt->sa, drv->first_bss->addr, ETH_ALEN);
1861 960 : if (drv->ignore_next_local_deauth) {
1862 798 : drv->ignore_next_local_deauth = 0;
1863 798 : if (event.deauth_info.locally_generated) {
1864 798 : wpa_printf(MSG_DEBUG, "nl80211: Ignore deauth event triggered due to own deauth request");
1865 798 : return;
1866 : }
1867 0 : wpa_printf(MSG_WARNING, "nl80211: Was expecting local deauth but got another disconnect event first");
1868 : }
1869 162 : event.deauth_info.addr = bssid;
1870 162 : event.deauth_info.reason_code = reason_code;
1871 162 : if (frame + len > mgmt->u.deauth.variable) {
1872 1 : event.deauth_info.ie = mgmt->u.deauth.variable;
1873 1 : event.deauth_info.ie_len = frame + len -
1874 : mgmt->u.deauth.variable;
1875 : }
1876 : }
1877 :
1878 166 : wpa_supplicant_event(drv->ctx, type, &event);
1879 : }
1880 :
1881 :
1882 5 : static void mlme_event_unprot_disconnect(struct wpa_driver_nl80211_data *drv,
1883 : enum wpa_event_type type,
1884 : const u8 *frame, size_t len)
1885 : {
1886 : const struct ieee80211_mgmt *mgmt;
1887 : union wpa_event_data event;
1888 5 : u16 reason_code = 0;
1889 :
1890 5 : if (type == EVENT_UNPROT_DEAUTH)
1891 3 : wpa_printf(MSG_DEBUG, "nl80211: Unprot Deauthenticate event");
1892 : else
1893 2 : wpa_printf(MSG_DEBUG, "nl80211: Unprot Disassociate event");
1894 :
1895 5 : if (len < 24)
1896 5 : return;
1897 :
1898 5 : mgmt = (const struct ieee80211_mgmt *) frame;
1899 :
1900 5 : os_memset(&event, 0, sizeof(event));
1901 : /* Note: Same offset for Reason Code in both frame subtypes */
1902 5 : if (len >= 24 + sizeof(mgmt->u.deauth))
1903 5 : reason_code = le_to_host16(mgmt->u.deauth.reason_code);
1904 :
1905 5 : if (type == EVENT_UNPROT_DISASSOC) {
1906 2 : event.unprot_disassoc.sa = mgmt->sa;
1907 2 : event.unprot_disassoc.da = mgmt->da;
1908 2 : event.unprot_disassoc.reason_code = reason_code;
1909 : } else {
1910 3 : event.unprot_deauth.sa = mgmt->sa;
1911 3 : event.unprot_deauth.da = mgmt->da;
1912 3 : event.unprot_deauth.reason_code = reason_code;
1913 : }
1914 :
1915 5 : wpa_supplicant_event(drv->ctx, type, &event);
1916 : }
1917 :
1918 :
1919 13880 : static void mlme_event(struct i802_bss *bss,
1920 : enum nl80211_commands cmd, struct nlattr *frame,
1921 : struct nlattr *addr, struct nlattr *timed_out,
1922 : struct nlattr *freq, struct nlattr *ack,
1923 : struct nlattr *cookie, struct nlattr *sig)
1924 : {
1925 13880 : struct wpa_driver_nl80211_data *drv = bss->drv;
1926 : const u8 *data;
1927 : size_t len;
1928 :
1929 13880 : if (timed_out && addr) {
1930 7 : mlme_timeout_event(drv, cmd, addr);
1931 7 : return;
1932 : }
1933 :
1934 13873 : if (frame == NULL) {
1935 0 : wpa_printf(MSG_DEBUG,
1936 : "nl80211: MLME event %d (%s) without frame data",
1937 : cmd, nl80211_command_to_string(cmd));
1938 0 : return;
1939 : }
1940 :
1941 13873 : data = nla_data(frame);
1942 13873 : len = nla_len(frame);
1943 13873 : if (len < 4 + 2 * ETH_ALEN) {
1944 0 : wpa_printf(MSG_MSGDUMP, "nl80211: MLME event %d (%s) on %s("
1945 : MACSTR ") - too short",
1946 0 : cmd, nl80211_command_to_string(cmd), bss->ifname,
1947 0 : MAC2STR(bss->addr));
1948 0 : return;
1949 : }
1950 263587 : wpa_printf(MSG_MSGDUMP, "nl80211: MLME event %d (%s) on %s(" MACSTR
1951 : ") A1=" MACSTR " A2=" MACSTR, cmd,
1952 13873 : nl80211_command_to_string(cmd), bss->ifname,
1953 166476 : MAC2STR(bss->addr), MAC2STR(data + 4),
1954 83238 : MAC2STR(data + 4 + ETH_ALEN));
1955 21357 : if (cmd != NL80211_CMD_FRAME_TX_STATUS && !(data[4] & 0x01) &&
1956 8331 : os_memcmp(bss->addr, data + 4, ETH_ALEN) != 0 &&
1957 847 : os_memcmp(bss->addr, data + 4 + ETH_ALEN, ETH_ALEN) != 0) {
1958 1 : wpa_printf(MSG_MSGDUMP, "nl80211: %s: Ignore MLME frame event "
1959 1 : "for foreign address", bss->ifname);
1960 1 : return;
1961 : }
1962 27744 : wpa_hexdump(MSG_MSGDUMP, "nl80211: MLME event frame",
1963 27744 : nla_data(frame), nla_len(frame));
1964 :
1965 13872 : switch (cmd) {
1966 : case NL80211_CMD_AUTHENTICATE:
1967 1068 : mlme_event_auth(drv, nla_data(frame), nla_len(frame));
1968 1068 : break;
1969 : case NL80211_CMD_ASSOCIATE:
1970 1027 : mlme_event_assoc(drv, nla_data(frame), nla_len(frame));
1971 1027 : break;
1972 : case NL80211_CMD_DEAUTHENTICATE:
1973 1998 : mlme_event_deauth_disassoc(drv, EVENT_DEAUTH,
1974 1998 : nla_data(frame), nla_len(frame));
1975 999 : break;
1976 : case NL80211_CMD_DISASSOCIATE:
1977 8 : mlme_event_deauth_disassoc(drv, EVENT_DISASSOC,
1978 8 : nla_data(frame), nla_len(frame));
1979 4 : break;
1980 : case NL80211_CMD_FRAME:
1981 6420 : mlme_event_mgmt(bss, freq, sig, nla_data(frame),
1982 6420 : nla_len(frame));
1983 6420 : break;
1984 : case NL80211_CMD_FRAME_TX_STATUS:
1985 4349 : mlme_event_mgmt_tx_status(drv, cookie, nla_data(frame),
1986 4349 : nla_len(frame), ack);
1987 4349 : break;
1988 : case NL80211_CMD_UNPROT_DEAUTHENTICATE:
1989 6 : mlme_event_unprot_disconnect(drv, EVENT_UNPROT_DEAUTH,
1990 6 : nla_data(frame), nla_len(frame));
1991 3 : break;
1992 : case NL80211_CMD_UNPROT_DISASSOCIATE:
1993 4 : mlme_event_unprot_disconnect(drv, EVENT_UNPROT_DISASSOC,
1994 4 : nla_data(frame), nla_len(frame));
1995 2 : break;
1996 : default:
1997 0 : break;
1998 : }
1999 : }
2000 :
2001 :
2002 4 : static void mlme_event_michael_mic_failure(struct i802_bss *bss,
2003 : struct nlattr *tb[])
2004 : {
2005 : union wpa_event_data data;
2006 :
2007 4 : wpa_printf(MSG_DEBUG, "nl80211: MLME event Michael MIC failure");
2008 4 : os_memset(&data, 0, sizeof(data));
2009 4 : if (tb[NL80211_ATTR_MAC]) {
2010 8 : wpa_hexdump(MSG_DEBUG, "nl80211: Source MAC address",
2011 4 : nla_data(tb[NL80211_ATTR_MAC]),
2012 4 : nla_len(tb[NL80211_ATTR_MAC]));
2013 4 : data.michael_mic_failure.src = nla_data(tb[NL80211_ATTR_MAC]);
2014 : }
2015 4 : if (tb[NL80211_ATTR_KEY_SEQ]) {
2016 0 : wpa_hexdump(MSG_DEBUG, "nl80211: TSC",
2017 0 : nla_data(tb[NL80211_ATTR_KEY_SEQ]),
2018 0 : nla_len(tb[NL80211_ATTR_KEY_SEQ]));
2019 : }
2020 4 : if (tb[NL80211_ATTR_KEY_TYPE]) {
2021 4 : enum nl80211_key_type key_type =
2022 4 : nla_get_u32(tb[NL80211_ATTR_KEY_TYPE]);
2023 4 : wpa_printf(MSG_DEBUG, "nl80211: Key Type %d", key_type);
2024 4 : if (key_type == NL80211_KEYTYPE_PAIRWISE)
2025 3 : data.michael_mic_failure.unicast = 1;
2026 : } else
2027 0 : data.michael_mic_failure.unicast = 1;
2028 :
2029 4 : if (tb[NL80211_ATTR_KEY_IDX]) {
2030 4 : u8 key_id = nla_get_u8(tb[NL80211_ATTR_KEY_IDX]);
2031 4 : wpa_printf(MSG_DEBUG, "nl80211: Key Id %d", key_id);
2032 : }
2033 :
2034 4 : wpa_supplicant_event(bss->ctx, EVENT_MICHAEL_MIC_FAILURE, &data);
2035 4 : }
2036 :
2037 :
2038 15 : static void mlme_event_join_ibss(struct wpa_driver_nl80211_data *drv,
2039 : struct nlattr *tb[])
2040 : {
2041 : unsigned int freq;
2042 :
2043 15 : if (tb[NL80211_ATTR_MAC] == NULL) {
2044 0 : wpa_printf(MSG_DEBUG, "nl80211: No address in IBSS joined "
2045 : "event");
2046 15 : return;
2047 : }
2048 15 : os_memcpy(drv->bssid, nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
2049 :
2050 15 : drv->associated = 1;
2051 90 : wpa_printf(MSG_DEBUG, "nl80211: IBSS " MACSTR " joined",
2052 90 : MAC2STR(drv->bssid));
2053 :
2054 15 : freq = nl80211_get_assoc_freq(drv);
2055 15 : if (freq) {
2056 15 : wpa_printf(MSG_DEBUG, "nl80211: IBSS on frequency %u MHz",
2057 : freq);
2058 15 : drv->first_bss->freq = freq;
2059 : }
2060 :
2061 15 : wpa_supplicant_event(drv->ctx, EVENT_ASSOC, NULL);
2062 : }
2063 :
2064 :
2065 2188 : static void mlme_event_remain_on_channel(struct wpa_driver_nl80211_data *drv,
2066 : int cancel_event, struct nlattr *tb[])
2067 : {
2068 : unsigned int freq, chan_type, duration;
2069 : union wpa_event_data data;
2070 : u64 cookie;
2071 :
2072 2188 : if (tb[NL80211_ATTR_WIPHY_FREQ])
2073 2188 : freq = nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]);
2074 : else
2075 0 : freq = 0;
2076 :
2077 2188 : if (tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE])
2078 2188 : chan_type = nla_get_u32(tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
2079 : else
2080 0 : chan_type = 0;
2081 :
2082 2188 : if (tb[NL80211_ATTR_DURATION])
2083 1095 : duration = nla_get_u32(tb[NL80211_ATTR_DURATION]);
2084 : else
2085 1093 : duration = 0;
2086 :
2087 2188 : if (tb[NL80211_ATTR_COOKIE])
2088 2188 : cookie = nla_get_u64(tb[NL80211_ATTR_COOKIE]);
2089 : else
2090 0 : cookie = 0;
2091 :
2092 2188 : wpa_printf(MSG_DEBUG, "nl80211: Remain-on-channel event (cancel=%d "
2093 : "freq=%u channel_type=%u duration=%u cookie=0x%llx (%s))",
2094 : cancel_event, freq, chan_type, duration,
2095 : (long long unsigned int) cookie,
2096 2188 : cookie == drv->remain_on_chan_cookie ? "match" : "unknown");
2097 :
2098 2188 : if (cookie != drv->remain_on_chan_cookie)
2099 2219 : return; /* not for us */
2100 :
2101 2157 : if (cancel_event)
2102 1064 : drv->pending_remain_on_chan = 0;
2103 :
2104 2157 : os_memset(&data, 0, sizeof(data));
2105 2157 : data.remain_on_channel.freq = freq;
2106 2157 : data.remain_on_channel.duration = duration;
2107 2157 : wpa_supplicant_event(drv->ctx, cancel_event ?
2108 : EVENT_CANCEL_REMAIN_ON_CHANNEL :
2109 : EVENT_REMAIN_ON_CHANNEL, &data);
2110 : }
2111 :
2112 :
2113 0 : static void mlme_event_ft_event(struct wpa_driver_nl80211_data *drv,
2114 : struct nlattr *tb[])
2115 : {
2116 : union wpa_event_data data;
2117 :
2118 0 : os_memset(&data, 0, sizeof(data));
2119 :
2120 0 : if (tb[NL80211_ATTR_IE]) {
2121 0 : data.ft_ies.ies = nla_data(tb[NL80211_ATTR_IE]);
2122 0 : data.ft_ies.ies_len = nla_len(tb[NL80211_ATTR_IE]);
2123 : }
2124 :
2125 0 : if (tb[NL80211_ATTR_IE_RIC]) {
2126 0 : data.ft_ies.ric_ies = nla_data(tb[NL80211_ATTR_IE_RIC]);
2127 0 : data.ft_ies.ric_ies_len = nla_len(tb[NL80211_ATTR_IE_RIC]);
2128 : }
2129 :
2130 0 : if (tb[NL80211_ATTR_MAC])
2131 0 : os_memcpy(data.ft_ies.target_ap,
2132 : nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
2133 :
2134 0 : wpa_printf(MSG_DEBUG, "nl80211: FT event target_ap " MACSTR,
2135 0 : MAC2STR(data.ft_ies.target_ap));
2136 :
2137 0 : wpa_supplicant_event(drv->ctx, EVENT_FT_RESPONSE, &data);
2138 0 : }
2139 :
2140 :
2141 1905 : static void send_scan_event(struct wpa_driver_nl80211_data *drv, int aborted,
2142 : struct nlattr *tb[])
2143 : {
2144 : union wpa_event_data event;
2145 : struct nlattr *nl;
2146 : int rem;
2147 : struct scan_info *info;
2148 : #define MAX_REPORT_FREQS 50
2149 : int freqs[MAX_REPORT_FREQS];
2150 1905 : int num_freqs = 0;
2151 :
2152 1905 : if (drv->scan_for_auth) {
2153 0 : drv->scan_for_auth = 0;
2154 0 : wpa_printf(MSG_DEBUG, "nl80211: Scan results for missing "
2155 : "cfg80211 BSS entry");
2156 0 : wpa_driver_nl80211_authenticate_retry(drv);
2157 1905 : return;
2158 : }
2159 :
2160 1905 : os_memset(&event, 0, sizeof(event));
2161 1905 : info = &event.scan_info;
2162 1905 : info->aborted = aborted;
2163 :
2164 1905 : if (tb[NL80211_ATTR_SCAN_SSIDS]) {
2165 3742 : nla_for_each_nested(nl, tb[NL80211_ATTR_SCAN_SSIDS], rem) {
2166 1837 : struct wpa_driver_scan_ssid *s =
2167 1837 : &info->ssids[info->num_ssids];
2168 1837 : s->ssid = nla_data(nl);
2169 1837 : s->ssid_len = nla_len(nl);
2170 1837 : wpa_printf(MSG_DEBUG, "nl80211: Scan probed for SSID '%s'",
2171 : wpa_ssid_txt(s->ssid, s->ssid_len));
2172 1837 : info->num_ssids++;
2173 1837 : if (info->num_ssids == WPAS_MAX_SCAN_SSIDS)
2174 0 : break;
2175 : }
2176 : }
2177 1905 : if (tb[NL80211_ATTR_SCAN_FREQUENCIES]) {
2178 : char msg[200], *pos, *end;
2179 : int res;
2180 :
2181 1905 : pos = msg;
2182 1905 : end = pos + sizeof(msg);
2183 1905 : *pos = '\0';
2184 :
2185 10778 : nla_for_each_nested(nl, tb[NL80211_ATTR_SCAN_FREQUENCIES], rem)
2186 : {
2187 8873 : freqs[num_freqs] = nla_get_u32(nl);
2188 8873 : res = os_snprintf(pos, end - pos, " %d",
2189 : freqs[num_freqs]);
2190 8873 : if (res > 0 && end - pos > res)
2191 8873 : pos += res;
2192 8873 : num_freqs++;
2193 8873 : if (num_freqs == MAX_REPORT_FREQS - 1)
2194 0 : break;
2195 : }
2196 1905 : info->freqs = freqs;
2197 1905 : info->num_freqs = num_freqs;
2198 1905 : wpa_printf(MSG_DEBUG, "nl80211: Scan included frequencies:%s",
2199 : msg);
2200 : }
2201 1905 : wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS, &event);
2202 : }
2203 :
2204 :
2205 9 : static int get_link_signal(struct nl_msg *msg, void *arg)
2206 : {
2207 : struct nlattr *tb[NL80211_ATTR_MAX + 1];
2208 9 : struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
2209 : struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
2210 : static struct nla_policy policy[NL80211_STA_INFO_MAX + 1] = {
2211 : [NL80211_STA_INFO_SIGNAL] = { .type = NLA_U8 },
2212 : [NL80211_STA_INFO_SIGNAL_AVG] = { .type = NLA_U8 },
2213 : };
2214 : struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
2215 : static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = {
2216 : [NL80211_RATE_INFO_BITRATE] = { .type = NLA_U16 },
2217 : [NL80211_RATE_INFO_MCS] = { .type = NLA_U8 },
2218 : [NL80211_RATE_INFO_40_MHZ_WIDTH] = { .type = NLA_FLAG },
2219 : [NL80211_RATE_INFO_SHORT_GI] = { .type = NLA_FLAG },
2220 : };
2221 9 : struct wpa_signal_info *sig_change = arg;
2222 :
2223 9 : nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
2224 : genlmsg_attrlen(gnlh, 0), NULL);
2225 18 : if (!tb[NL80211_ATTR_STA_INFO] ||
2226 9 : nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,
2227 : tb[NL80211_ATTR_STA_INFO], policy))
2228 0 : return NL_SKIP;
2229 9 : if (!sinfo[NL80211_STA_INFO_SIGNAL])
2230 0 : return NL_SKIP;
2231 :
2232 9 : sig_change->current_signal =
2233 9 : (s8) nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL]);
2234 :
2235 9 : if (sinfo[NL80211_STA_INFO_SIGNAL_AVG])
2236 9 : sig_change->avg_signal =
2237 9 : (s8) nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL_AVG]);
2238 : else
2239 0 : sig_change->avg_signal = 0;
2240 :
2241 9 : if (sinfo[NL80211_STA_INFO_TX_BITRATE]) {
2242 9 : if (nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX,
2243 : sinfo[NL80211_STA_INFO_TX_BITRATE],
2244 : rate_policy)) {
2245 0 : sig_change->current_txrate = 0;
2246 : } else {
2247 9 : if (rinfo[NL80211_RATE_INFO_BITRATE]) {
2248 9 : sig_change->current_txrate =
2249 9 : nla_get_u16(rinfo[
2250 9 : NL80211_RATE_INFO_BITRATE]) * 100;
2251 : }
2252 : }
2253 : }
2254 :
2255 9 : return NL_SKIP;
2256 : }
2257 :
2258 :
2259 9 : static int nl80211_get_link_signal(struct wpa_driver_nl80211_data *drv,
2260 : struct wpa_signal_info *sig)
2261 : {
2262 : struct nl_msg *msg;
2263 :
2264 9 : sig->current_signal = -9999;
2265 9 : sig->current_txrate = 0;
2266 :
2267 9 : msg = nlmsg_alloc();
2268 9 : if (!msg)
2269 0 : return -ENOMEM;
2270 :
2271 9 : nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_STATION);
2272 :
2273 9 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
2274 9 : NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, drv->bssid);
2275 :
2276 9 : return send_and_recv_msgs(drv, msg, get_link_signal, sig);
2277 : nla_put_failure:
2278 0 : nlmsg_free(msg);
2279 0 : return -ENOBUFS;
2280 : }
2281 :
2282 :
2283 9 : static int get_link_noise(struct nl_msg *msg, void *arg)
2284 : {
2285 : struct nlattr *tb[NL80211_ATTR_MAX + 1];
2286 9 : struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
2287 : struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1];
2288 : static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = {
2289 : [NL80211_SURVEY_INFO_FREQUENCY] = { .type = NLA_U32 },
2290 : [NL80211_SURVEY_INFO_NOISE] = { .type = NLA_U8 },
2291 : };
2292 9 : struct wpa_signal_info *sig_change = arg;
2293 :
2294 9 : nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
2295 : genlmsg_attrlen(gnlh, 0), NULL);
2296 :
2297 9 : if (!tb[NL80211_ATTR_SURVEY_INFO]) {
2298 0 : wpa_printf(MSG_DEBUG, "nl80211: survey data missing!");
2299 0 : return NL_SKIP;
2300 : }
2301 :
2302 9 : if (nla_parse_nested(sinfo, NL80211_SURVEY_INFO_MAX,
2303 : tb[NL80211_ATTR_SURVEY_INFO],
2304 : survey_policy)) {
2305 0 : wpa_printf(MSG_DEBUG, "nl80211: failed to parse nested "
2306 : "attributes!");
2307 0 : return NL_SKIP;
2308 : }
2309 :
2310 9 : if (!sinfo[NL80211_SURVEY_INFO_FREQUENCY])
2311 0 : return NL_SKIP;
2312 :
2313 18 : if (nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]) !=
2314 9 : sig_change->frequency)
2315 0 : return NL_SKIP;
2316 :
2317 9 : if (!sinfo[NL80211_SURVEY_INFO_NOISE])
2318 0 : return NL_SKIP;
2319 :
2320 9 : sig_change->current_noise =
2321 9 : (s8) nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
2322 :
2323 9 : return NL_SKIP;
2324 : }
2325 :
2326 :
2327 9 : static int nl80211_get_link_noise(struct wpa_driver_nl80211_data *drv,
2328 : struct wpa_signal_info *sig_change)
2329 : {
2330 : struct nl_msg *msg;
2331 :
2332 9 : sig_change->current_noise = 9999;
2333 9 : sig_change->frequency = drv->assoc_freq;
2334 :
2335 9 : msg = nlmsg_alloc();
2336 9 : if (!msg)
2337 0 : return -ENOMEM;
2338 :
2339 9 : nl80211_cmd(drv, msg, NLM_F_DUMP, NL80211_CMD_GET_SURVEY);
2340 :
2341 9 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
2342 :
2343 9 : return send_and_recv_msgs(drv, msg, get_link_noise, sig_change);
2344 : nla_put_failure:
2345 0 : nlmsg_free(msg);
2346 0 : return -ENOBUFS;
2347 : }
2348 :
2349 :
2350 1879 : static int get_noise_for_scan_results(struct nl_msg *msg, void *arg)
2351 : {
2352 : struct nlattr *tb[NL80211_ATTR_MAX + 1];
2353 1879 : struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
2354 : struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1];
2355 : static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = {
2356 : [NL80211_SURVEY_INFO_FREQUENCY] = { .type = NLA_U32 },
2357 : [NL80211_SURVEY_INFO_NOISE] = { .type = NLA_U8 },
2358 : };
2359 1879 : struct wpa_scan_results *scan_results = arg;
2360 : struct wpa_scan_res *scan_res;
2361 : size_t i;
2362 :
2363 1879 : nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
2364 : genlmsg_attrlen(gnlh, 0), NULL);
2365 :
2366 1879 : if (!tb[NL80211_ATTR_SURVEY_INFO]) {
2367 0 : wpa_printf(MSG_DEBUG, "nl80211: Survey data missing");
2368 0 : return NL_SKIP;
2369 : }
2370 :
2371 1879 : if (nla_parse_nested(sinfo, NL80211_SURVEY_INFO_MAX,
2372 : tb[NL80211_ATTR_SURVEY_INFO],
2373 : survey_policy)) {
2374 0 : wpa_printf(MSG_DEBUG, "nl80211: Failed to parse nested "
2375 : "attributes");
2376 0 : return NL_SKIP;
2377 : }
2378 :
2379 1879 : if (!sinfo[NL80211_SURVEY_INFO_NOISE])
2380 0 : return NL_SKIP;
2381 :
2382 1879 : if (!sinfo[NL80211_SURVEY_INFO_FREQUENCY])
2383 0 : return NL_SKIP;
2384 :
2385 4664 : for (i = 0; i < scan_results->num; ++i) {
2386 2785 : scan_res = scan_results->res[i];
2387 2785 : if (!scan_res)
2388 0 : continue;
2389 5570 : if ((int) nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]) !=
2390 2785 : scan_res->freq)
2391 824 : continue;
2392 1961 : if (!(scan_res->flags & WPA_SCAN_NOISE_INVALID))
2393 0 : continue;
2394 1961 : scan_res->noise = (s8)
2395 1961 : nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
2396 1961 : scan_res->flags &= ~WPA_SCAN_NOISE_INVALID;
2397 : }
2398 :
2399 1879 : return NL_SKIP;
2400 : }
2401 :
2402 :
2403 1879 : static int nl80211_get_noise_for_scan_results(
2404 : struct wpa_driver_nl80211_data *drv,
2405 : struct wpa_scan_results *scan_res)
2406 : {
2407 : struct nl_msg *msg;
2408 :
2409 1879 : msg = nlmsg_alloc();
2410 1879 : if (!msg)
2411 0 : return -ENOMEM;
2412 :
2413 1879 : nl80211_cmd(drv, msg, NLM_F_DUMP, NL80211_CMD_GET_SURVEY);
2414 :
2415 1879 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
2416 :
2417 1879 : return send_and_recv_msgs(drv, msg, get_noise_for_scan_results,
2418 : scan_res);
2419 : nla_put_failure:
2420 0 : nlmsg_free(msg);
2421 0 : return -ENOBUFS;
2422 : }
2423 :
2424 :
2425 5 : static void nl80211_cqm_event(struct wpa_driver_nl80211_data *drv,
2426 : struct nlattr *tb[])
2427 : {
2428 : static struct nla_policy cqm_policy[NL80211_ATTR_CQM_MAX + 1] = {
2429 : [NL80211_ATTR_CQM_RSSI_THOLD] = { .type = NLA_U32 },
2430 : [NL80211_ATTR_CQM_RSSI_HYST] = { .type = NLA_U8 },
2431 : [NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] = { .type = NLA_U32 },
2432 : [NL80211_ATTR_CQM_PKT_LOSS_EVENT] = { .type = NLA_U32 },
2433 : };
2434 : struct nlattr *cqm[NL80211_ATTR_CQM_MAX + 1];
2435 : enum nl80211_cqm_rssi_threshold_event event;
2436 : union wpa_event_data ed;
2437 : struct wpa_signal_info sig;
2438 : int res;
2439 :
2440 10 : if (tb[NL80211_ATTR_CQM] == NULL ||
2441 5 : nla_parse_nested(cqm, NL80211_ATTR_CQM_MAX, tb[NL80211_ATTR_CQM],
2442 : cqm_policy)) {
2443 0 : wpa_printf(MSG_DEBUG, "nl80211: Ignore invalid CQM event");
2444 0 : return;
2445 : }
2446 :
2447 5 : os_memset(&ed, 0, sizeof(ed));
2448 :
2449 5 : if (cqm[NL80211_ATTR_CQM_PKT_LOSS_EVENT]) {
2450 0 : if (!tb[NL80211_ATTR_MAC])
2451 0 : return;
2452 0 : os_memcpy(ed.low_ack.addr, nla_data(tb[NL80211_ATTR_MAC]),
2453 : ETH_ALEN);
2454 0 : wpa_supplicant_event(drv->ctx, EVENT_STATION_LOW_ACK, &ed);
2455 0 : return;
2456 : }
2457 :
2458 5 : if (cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] == NULL)
2459 0 : return;
2460 5 : event = nla_get_u32(cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT]);
2461 :
2462 5 : if (event == NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH) {
2463 2 : wpa_printf(MSG_DEBUG, "nl80211: Connection quality monitor "
2464 : "event: RSSI high");
2465 2 : ed.signal_change.above_threshold = 1;
2466 3 : } else if (event == NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW) {
2467 2 : wpa_printf(MSG_DEBUG, "nl80211: Connection quality monitor "
2468 : "event: RSSI low");
2469 2 : ed.signal_change.above_threshold = 0;
2470 : } else
2471 1 : return;
2472 :
2473 4 : res = nl80211_get_link_signal(drv, &sig);
2474 4 : if (res == 0) {
2475 4 : ed.signal_change.current_signal = sig.current_signal;
2476 4 : ed.signal_change.current_txrate = sig.current_txrate;
2477 4 : wpa_printf(MSG_DEBUG, "nl80211: Signal: %d dBm txrate: %d",
2478 : sig.current_signal, sig.current_txrate);
2479 : }
2480 :
2481 4 : res = nl80211_get_link_noise(drv, &sig);
2482 4 : if (res == 0) {
2483 4 : ed.signal_change.current_noise = sig.current_noise;
2484 4 : wpa_printf(MSG_DEBUG, "nl80211: Noise: %d dBm",
2485 : sig.current_noise);
2486 : }
2487 :
2488 4 : wpa_supplicant_event(drv->ctx, EVENT_SIGNAL_CHANGE, &ed);
2489 : }
2490 :
2491 :
2492 2167 : static void nl80211_new_station_event(struct wpa_driver_nl80211_data *drv,
2493 : struct nlattr **tb)
2494 : {
2495 : u8 *addr;
2496 : union wpa_event_data data;
2497 :
2498 2167 : if (tb[NL80211_ATTR_MAC] == NULL)
2499 2149 : return;
2500 2167 : addr = nla_data(tb[NL80211_ATTR_MAC]);
2501 2167 : wpa_printf(MSG_DEBUG, "nl80211: New station " MACSTR, MAC2STR(addr));
2502 :
2503 2167 : if (is_ap_interface(drv->nlmode) && drv->device_ap_sme) {
2504 0 : u8 *ies = NULL;
2505 0 : size_t ies_len = 0;
2506 0 : if (tb[NL80211_ATTR_IE]) {
2507 0 : ies = nla_data(tb[NL80211_ATTR_IE]);
2508 0 : ies_len = nla_len(tb[NL80211_ATTR_IE]);
2509 : }
2510 0 : wpa_hexdump(MSG_DEBUG, "nl80211: Assoc Req IEs", ies, ies_len);
2511 0 : drv_event_assoc(drv->ctx, addr, ies, ies_len, 0);
2512 0 : return;
2513 : }
2514 :
2515 2167 : if (drv->nlmode != NL80211_IFTYPE_ADHOC)
2516 2149 : return;
2517 :
2518 18 : os_memset(&data, 0, sizeof(data));
2519 18 : os_memcpy(data.ibss_rsn_start.peer, addr, ETH_ALEN);
2520 18 : wpa_supplicant_event(drv->ctx, EVENT_IBSS_RSN_START, &data);
2521 : }
2522 :
2523 :
2524 2101 : static void nl80211_del_station_event(struct wpa_driver_nl80211_data *drv,
2525 : struct nlattr **tb)
2526 : {
2527 : u8 *addr;
2528 : union wpa_event_data data;
2529 :
2530 2101 : if (tb[NL80211_ATTR_MAC] == NULL)
2531 2099 : return;
2532 2101 : addr = nla_data(tb[NL80211_ATTR_MAC]);
2533 12606 : wpa_printf(MSG_DEBUG, "nl80211: Delete station " MACSTR,
2534 12606 : MAC2STR(addr));
2535 :
2536 2101 : if (is_ap_interface(drv->nlmode) && drv->device_ap_sme) {
2537 0 : drv_event_disassoc(drv->ctx, addr);
2538 0 : return;
2539 : }
2540 :
2541 2101 : if (drv->nlmode != NL80211_IFTYPE_ADHOC)
2542 2099 : return;
2543 :
2544 2 : os_memset(&data, 0, sizeof(data));
2545 2 : os_memcpy(data.ibss_peer_lost.peer, addr, ETH_ALEN);
2546 2 : wpa_supplicant_event(drv->ctx, EVENT_IBSS_PEER_LOST, &data);
2547 : }
2548 :
2549 :
2550 0 : static void nl80211_rekey_offload_event(struct wpa_driver_nl80211_data *drv,
2551 : struct nlattr **tb)
2552 : {
2553 : struct nlattr *rekey_info[NUM_NL80211_REKEY_DATA];
2554 : static struct nla_policy rekey_policy[NUM_NL80211_REKEY_DATA] = {
2555 : [NL80211_REKEY_DATA_KEK] = {
2556 : .minlen = NL80211_KEK_LEN,
2557 : .maxlen = NL80211_KEK_LEN,
2558 : },
2559 : [NL80211_REKEY_DATA_KCK] = {
2560 : .minlen = NL80211_KCK_LEN,
2561 : .maxlen = NL80211_KCK_LEN,
2562 : },
2563 : [NL80211_REKEY_DATA_REPLAY_CTR] = {
2564 : .minlen = NL80211_REPLAY_CTR_LEN,
2565 : .maxlen = NL80211_REPLAY_CTR_LEN,
2566 : },
2567 : };
2568 : union wpa_event_data data;
2569 :
2570 0 : if (!tb[NL80211_ATTR_MAC])
2571 0 : return;
2572 0 : if (!tb[NL80211_ATTR_REKEY_DATA])
2573 0 : return;
2574 0 : if (nla_parse_nested(rekey_info, MAX_NL80211_REKEY_DATA,
2575 0 : tb[NL80211_ATTR_REKEY_DATA], rekey_policy))
2576 0 : return;
2577 0 : if (!rekey_info[NL80211_REKEY_DATA_REPLAY_CTR])
2578 0 : return;
2579 :
2580 0 : os_memset(&data, 0, sizeof(data));
2581 0 : data.driver_gtk_rekey.bssid = nla_data(tb[NL80211_ATTR_MAC]);
2582 0 : wpa_printf(MSG_DEBUG, "nl80211: Rekey offload event for BSSID " MACSTR,
2583 0 : MAC2STR(data.driver_gtk_rekey.bssid));
2584 0 : data.driver_gtk_rekey.replay_ctr =
2585 0 : nla_data(rekey_info[NL80211_REKEY_DATA_REPLAY_CTR]);
2586 0 : wpa_hexdump(MSG_DEBUG, "nl80211: Rekey offload - Replay Counter",
2587 0 : data.driver_gtk_rekey.replay_ctr, NL80211_REPLAY_CTR_LEN);
2588 0 : wpa_supplicant_event(drv->ctx, EVENT_DRIVER_GTK_REKEY, &data);
2589 : }
2590 :
2591 :
2592 0 : static void nl80211_pmksa_candidate_event(struct wpa_driver_nl80211_data *drv,
2593 : struct nlattr **tb)
2594 : {
2595 : struct nlattr *cand[NUM_NL80211_PMKSA_CANDIDATE];
2596 : static struct nla_policy cand_policy[NUM_NL80211_PMKSA_CANDIDATE] = {
2597 : [NL80211_PMKSA_CANDIDATE_INDEX] = { .type = NLA_U32 },
2598 : [NL80211_PMKSA_CANDIDATE_BSSID] = {
2599 : .minlen = ETH_ALEN,
2600 : .maxlen = ETH_ALEN,
2601 : },
2602 : [NL80211_PMKSA_CANDIDATE_PREAUTH] = { .type = NLA_FLAG },
2603 : };
2604 : union wpa_event_data data;
2605 :
2606 0 : wpa_printf(MSG_DEBUG, "nl80211: PMKSA candidate event");
2607 :
2608 0 : if (!tb[NL80211_ATTR_PMKSA_CANDIDATE])
2609 0 : return;
2610 0 : if (nla_parse_nested(cand, MAX_NL80211_PMKSA_CANDIDATE,
2611 0 : tb[NL80211_ATTR_PMKSA_CANDIDATE], cand_policy))
2612 0 : return;
2613 0 : if (!cand[NL80211_PMKSA_CANDIDATE_INDEX] ||
2614 0 : !cand[NL80211_PMKSA_CANDIDATE_BSSID])
2615 0 : return;
2616 :
2617 0 : os_memset(&data, 0, sizeof(data));
2618 0 : os_memcpy(data.pmkid_candidate.bssid,
2619 : nla_data(cand[NL80211_PMKSA_CANDIDATE_BSSID]), ETH_ALEN);
2620 0 : data.pmkid_candidate.index =
2621 0 : nla_get_u32(cand[NL80211_PMKSA_CANDIDATE_INDEX]);
2622 0 : data.pmkid_candidate.preauth =
2623 0 : cand[NL80211_PMKSA_CANDIDATE_PREAUTH] != NULL;
2624 0 : wpa_supplicant_event(drv->ctx, EVENT_PMKID_CANDIDATE, &data);
2625 : }
2626 :
2627 :
2628 2 : static void nl80211_client_probe_event(struct wpa_driver_nl80211_data *drv,
2629 : struct nlattr **tb)
2630 : {
2631 : union wpa_event_data data;
2632 :
2633 2 : wpa_printf(MSG_DEBUG, "nl80211: Probe client event");
2634 :
2635 2 : if (!tb[NL80211_ATTR_MAC] || !tb[NL80211_ATTR_ACK])
2636 4 : return;
2637 :
2638 0 : os_memset(&data, 0, sizeof(data));
2639 0 : os_memcpy(data.client_poll.addr,
2640 : nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
2641 :
2642 0 : wpa_supplicant_event(drv->ctx, EVENT_DRIVER_CLIENT_POLL_OK, &data);
2643 : }
2644 :
2645 :
2646 0 : static void nl80211_tdls_oper_event(struct wpa_driver_nl80211_data *drv,
2647 : struct nlattr **tb)
2648 : {
2649 : union wpa_event_data data;
2650 :
2651 0 : wpa_printf(MSG_DEBUG, "nl80211: TDLS operation event");
2652 :
2653 0 : if (!tb[NL80211_ATTR_MAC] || !tb[NL80211_ATTR_TDLS_OPERATION])
2654 0 : return;
2655 :
2656 0 : os_memset(&data, 0, sizeof(data));
2657 0 : os_memcpy(data.tdls.peer, nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
2658 0 : switch (nla_get_u8(tb[NL80211_ATTR_TDLS_OPERATION])) {
2659 : case NL80211_TDLS_SETUP:
2660 0 : wpa_printf(MSG_DEBUG, "nl80211: TDLS setup request for peer "
2661 0 : MACSTR, MAC2STR(data.tdls.peer));
2662 0 : data.tdls.oper = TDLS_REQUEST_SETUP;
2663 0 : break;
2664 : case NL80211_TDLS_TEARDOWN:
2665 0 : wpa_printf(MSG_DEBUG, "nl80211: TDLS teardown request for peer "
2666 0 : MACSTR, MAC2STR(data.tdls.peer));
2667 0 : data.tdls.oper = TDLS_REQUEST_TEARDOWN;
2668 0 : break;
2669 : default:
2670 0 : wpa_printf(MSG_DEBUG, "nl80211: Unsupported TDLS operatione "
2671 : "event");
2672 0 : return;
2673 : }
2674 0 : if (tb[NL80211_ATTR_REASON_CODE]) {
2675 0 : data.tdls.reason_code =
2676 0 : nla_get_u16(tb[NL80211_ATTR_REASON_CODE]);
2677 : }
2678 :
2679 0 : wpa_supplicant_event(drv->ctx, EVENT_TDLS, &data);
2680 : }
2681 :
2682 :
2683 1 : static void nl80211_stop_ap(struct wpa_driver_nl80211_data *drv,
2684 : struct nlattr **tb)
2685 : {
2686 1 : wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_UNAVAILABLE, NULL);
2687 1 : }
2688 :
2689 :
2690 0 : static void nl80211_connect_failed_event(struct wpa_driver_nl80211_data *drv,
2691 : struct nlattr **tb)
2692 : {
2693 : union wpa_event_data data;
2694 : u32 reason;
2695 :
2696 0 : wpa_printf(MSG_DEBUG, "nl80211: Connect failed event");
2697 :
2698 0 : if (!tb[NL80211_ATTR_MAC] || !tb[NL80211_ATTR_CONN_FAILED_REASON])
2699 0 : return;
2700 :
2701 0 : os_memset(&data, 0, sizeof(data));
2702 0 : os_memcpy(data.connect_failed_reason.addr,
2703 : nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
2704 :
2705 0 : reason = nla_get_u32(tb[NL80211_ATTR_CONN_FAILED_REASON]);
2706 0 : switch (reason) {
2707 : case NL80211_CONN_FAIL_MAX_CLIENTS:
2708 0 : wpa_printf(MSG_DEBUG, "nl80211: Max client reached");
2709 0 : data.connect_failed_reason.code = MAX_CLIENT_REACHED;
2710 0 : break;
2711 : case NL80211_CONN_FAIL_BLOCKED_CLIENT:
2712 0 : wpa_printf(MSG_DEBUG, "nl80211: Blocked client " MACSTR
2713 : " tried to connect",
2714 0 : MAC2STR(data.connect_failed_reason.addr));
2715 0 : data.connect_failed_reason.code = BLOCKED_CLIENT;
2716 0 : break;
2717 : default:
2718 0 : wpa_printf(MSG_DEBUG, "nl8021l: Unknown connect failed reason "
2719 : "%u", reason);
2720 0 : return;
2721 : }
2722 :
2723 0 : wpa_supplicant_event(drv->ctx, EVENT_CONNECT_FAILED_REASON, &data);
2724 : }
2725 :
2726 :
2727 0 : static void nl80211_radar_event(struct wpa_driver_nl80211_data *drv,
2728 : struct nlattr **tb)
2729 : {
2730 : union wpa_event_data data;
2731 : enum nl80211_radar_event event_type;
2732 :
2733 0 : if (!tb[NL80211_ATTR_WIPHY_FREQ] || !tb[NL80211_ATTR_RADAR_EVENT])
2734 0 : return;
2735 :
2736 0 : os_memset(&data, 0, sizeof(data));
2737 0 : data.dfs_event.freq = nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]);
2738 0 : event_type = nla_get_u32(tb[NL80211_ATTR_RADAR_EVENT]);
2739 :
2740 : /* Check HT params */
2741 0 : if (tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
2742 0 : data.dfs_event.ht_enabled = 1;
2743 0 : data.dfs_event.chan_offset = 0;
2744 :
2745 0 : switch (nla_get_u32(tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE])) {
2746 : case NL80211_CHAN_NO_HT:
2747 0 : data.dfs_event.ht_enabled = 0;
2748 0 : break;
2749 : case NL80211_CHAN_HT20:
2750 0 : break;
2751 : case NL80211_CHAN_HT40PLUS:
2752 0 : data.dfs_event.chan_offset = 1;
2753 0 : break;
2754 : case NL80211_CHAN_HT40MINUS:
2755 0 : data.dfs_event.chan_offset = -1;
2756 0 : break;
2757 : }
2758 : }
2759 :
2760 : /* Get VHT params */
2761 0 : if (tb[NL80211_ATTR_CHANNEL_WIDTH])
2762 0 : data.dfs_event.chan_width =
2763 0 : convert2width(nla_get_u32(
2764 0 : tb[NL80211_ATTR_CHANNEL_WIDTH]));
2765 0 : if (tb[NL80211_ATTR_CENTER_FREQ1])
2766 0 : data.dfs_event.cf1 = nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ1]);
2767 0 : if (tb[NL80211_ATTR_CENTER_FREQ2])
2768 0 : data.dfs_event.cf2 = nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ2]);
2769 :
2770 0 : wpa_printf(MSG_DEBUG, "nl80211: DFS event on freq %d MHz, ht: %d, offset: %d, width: %d, cf1: %dMHz, cf2: %dMHz",
2771 : data.dfs_event.freq, data.dfs_event.ht_enabled,
2772 0 : data.dfs_event.chan_offset, data.dfs_event.chan_width,
2773 : data.dfs_event.cf1, data.dfs_event.cf2);
2774 :
2775 0 : switch (event_type) {
2776 : case NL80211_RADAR_DETECTED:
2777 0 : wpa_supplicant_event(drv->ctx, EVENT_DFS_RADAR_DETECTED, &data);
2778 0 : break;
2779 : case NL80211_RADAR_CAC_FINISHED:
2780 0 : wpa_supplicant_event(drv->ctx, EVENT_DFS_CAC_FINISHED, &data);
2781 0 : break;
2782 : case NL80211_RADAR_CAC_ABORTED:
2783 0 : wpa_supplicant_event(drv->ctx, EVENT_DFS_CAC_ABORTED, &data);
2784 0 : break;
2785 : case NL80211_RADAR_NOP_FINISHED:
2786 0 : wpa_supplicant_event(drv->ctx, EVENT_DFS_NOP_FINISHED, &data);
2787 0 : break;
2788 : default:
2789 0 : wpa_printf(MSG_DEBUG, "nl80211: Unknown radar event %d "
2790 : "received", event_type);
2791 0 : break;
2792 : }
2793 : }
2794 :
2795 :
2796 2 : static void nl80211_spurious_frame(struct i802_bss *bss, struct nlattr **tb,
2797 : int wds)
2798 : {
2799 2 : struct wpa_driver_nl80211_data *drv = bss->drv;
2800 : union wpa_event_data event;
2801 :
2802 2 : if (!tb[NL80211_ATTR_MAC])
2803 2 : return;
2804 :
2805 2 : os_memset(&event, 0, sizeof(event));
2806 2 : event.rx_from_unknown.bssid = bss->addr;
2807 2 : event.rx_from_unknown.addr = nla_data(tb[NL80211_ATTR_MAC]);
2808 2 : event.rx_from_unknown.wds = wds;
2809 :
2810 2 : wpa_supplicant_event(drv->ctx, EVENT_RX_FROM_UNKNOWN, &event);
2811 : }
2812 :
2813 :
2814 0 : static void qca_nl80211_avoid_freq(struct wpa_driver_nl80211_data *drv,
2815 : const u8 *data, size_t len)
2816 : {
2817 : u32 i, count;
2818 : union wpa_event_data event;
2819 0 : struct wpa_freq_range *range = NULL;
2820 : const struct qca_avoid_freq_list *freq_range;
2821 :
2822 0 : freq_range = (const struct qca_avoid_freq_list *) data;
2823 0 : if (len < sizeof(freq_range->count))
2824 0 : return;
2825 :
2826 0 : count = freq_range->count;
2827 0 : if (len < sizeof(freq_range->count) +
2828 0 : count * sizeof(struct qca_avoid_freq_range)) {
2829 0 : wpa_printf(MSG_DEBUG, "nl80211: Ignored too short avoid frequency list (len=%u)",
2830 : (unsigned int) len);
2831 0 : return;
2832 : }
2833 :
2834 0 : if (count > 0) {
2835 0 : range = os_calloc(count, sizeof(struct wpa_freq_range));
2836 0 : if (range == NULL)
2837 0 : return;
2838 : }
2839 :
2840 0 : os_memset(&event, 0, sizeof(event));
2841 0 : for (i = 0; i < count; i++) {
2842 0 : unsigned int idx = event.freq_range.num;
2843 0 : range[idx].min = freq_range->range[i].start_freq;
2844 0 : range[idx].max = freq_range->range[i].end_freq;
2845 0 : wpa_printf(MSG_DEBUG, "nl80211: Avoid frequency range: %u-%u",
2846 0 : range[idx].min, range[idx].max);
2847 0 : if (range[idx].min > range[idx].max) {
2848 0 : wpa_printf(MSG_DEBUG, "nl80211: Ignore invalid frequency range");
2849 0 : continue;
2850 : }
2851 0 : event.freq_range.num++;
2852 : }
2853 0 : event.freq_range.range = range;
2854 :
2855 0 : wpa_supplicant_event(drv->ctx, EVENT_AVOID_FREQUENCIES, &event);
2856 :
2857 0 : os_free(range);
2858 : }
2859 :
2860 :
2861 0 : static void nl80211_vendor_event_qca(struct wpa_driver_nl80211_data *drv,
2862 : u32 subcmd, u8 *data, size_t len)
2863 : {
2864 0 : switch (subcmd) {
2865 : case QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY:
2866 0 : qca_nl80211_avoid_freq(drv, data, len);
2867 0 : break;
2868 : default:
2869 0 : wpa_printf(MSG_DEBUG,
2870 : "nl80211: Ignore unsupported QCA vendor event %u",
2871 : subcmd);
2872 0 : break;
2873 : }
2874 0 : }
2875 :
2876 :
2877 0 : static void nl80211_vendor_event(struct wpa_driver_nl80211_data *drv,
2878 : struct nlattr **tb)
2879 : {
2880 0 : u32 vendor_id, subcmd, wiphy = 0;
2881 : int wiphy_idx;
2882 0 : u8 *data = NULL;
2883 0 : size_t len = 0;
2884 :
2885 0 : if (!tb[NL80211_ATTR_VENDOR_ID] ||
2886 0 : !tb[NL80211_ATTR_VENDOR_SUBCMD])
2887 0 : return;
2888 :
2889 0 : vendor_id = nla_get_u32(tb[NL80211_ATTR_VENDOR_ID]);
2890 0 : subcmd = nla_get_u32(tb[NL80211_ATTR_VENDOR_SUBCMD]);
2891 :
2892 0 : if (tb[NL80211_ATTR_WIPHY])
2893 0 : wiphy = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
2894 :
2895 0 : wpa_printf(MSG_DEBUG, "nl80211: Vendor event: wiphy=%u vendor_id=0x%x subcmd=%u",
2896 : wiphy, vendor_id, subcmd);
2897 :
2898 0 : if (tb[NL80211_ATTR_VENDOR_DATA]) {
2899 0 : data = nla_data(tb[NL80211_ATTR_VENDOR_DATA]);
2900 0 : len = nla_len(tb[NL80211_ATTR_VENDOR_DATA]);
2901 0 : wpa_hexdump(MSG_MSGDUMP, "nl80211: Vendor data", data, len);
2902 : }
2903 :
2904 0 : wiphy_idx = nl80211_get_wiphy_index(drv->first_bss);
2905 0 : if (wiphy_idx >= 0 && wiphy_idx != (int) wiphy) {
2906 0 : wpa_printf(MSG_DEBUG, "nl80211: Ignore vendor event for foreign wiphy %u (own: %d)",
2907 : wiphy, wiphy_idx);
2908 0 : return;
2909 : }
2910 :
2911 0 : switch (vendor_id) {
2912 : case OUI_QCA:
2913 0 : nl80211_vendor_event_qca(drv, subcmd, data, len);
2914 0 : break;
2915 : default:
2916 0 : wpa_printf(MSG_DEBUG, "nl80211: Ignore unsupported vendor event");
2917 0 : break;
2918 : }
2919 : }
2920 :
2921 :
2922 3249 : static void nl80211_reg_change_event(struct wpa_driver_nl80211_data *drv,
2923 : struct nlattr *tb[])
2924 : {
2925 : union wpa_event_data data;
2926 : enum nl80211_reg_initiator init;
2927 :
2928 3249 : wpa_printf(MSG_DEBUG, "nl80211: Regulatory domain change");
2929 :
2930 3249 : if (tb[NL80211_ATTR_REG_INITIATOR] == NULL)
2931 3249 : return;
2932 :
2933 3249 : os_memset(&data, 0, sizeof(data));
2934 3249 : init = nla_get_u8(tb[NL80211_ATTR_REG_INITIATOR]);
2935 3249 : wpa_printf(MSG_DEBUG, " * initiator=%d", init);
2936 3249 : switch (init) {
2937 : case NL80211_REGDOM_SET_BY_CORE:
2938 3093 : data.channel_list_changed.initiator = REGDOM_SET_BY_CORE;
2939 3093 : break;
2940 : case NL80211_REGDOM_SET_BY_USER:
2941 148 : data.channel_list_changed.initiator = REGDOM_SET_BY_USER;
2942 148 : break;
2943 : case NL80211_REGDOM_SET_BY_DRIVER:
2944 0 : data.channel_list_changed.initiator = REGDOM_SET_BY_DRIVER;
2945 0 : break;
2946 : case NL80211_REGDOM_SET_BY_COUNTRY_IE:
2947 8 : data.channel_list_changed.initiator = REGDOM_SET_BY_COUNTRY_IE;
2948 8 : break;
2949 : }
2950 :
2951 3249 : if (tb[NL80211_ATTR_REG_TYPE]) {
2952 : enum nl80211_reg_type type;
2953 3249 : type = nla_get_u8(tb[NL80211_ATTR_REG_TYPE]);
2954 3249 : wpa_printf(MSG_DEBUG, " * type=%d", type);
2955 3249 : switch (type) {
2956 : case NL80211_REGDOM_TYPE_COUNTRY:
2957 156 : data.channel_list_changed.type = REGDOM_TYPE_COUNTRY;
2958 156 : break;
2959 : case NL80211_REGDOM_TYPE_WORLD:
2960 3093 : data.channel_list_changed.type = REGDOM_TYPE_WORLD;
2961 3093 : break;
2962 : case NL80211_REGDOM_TYPE_CUSTOM_WORLD:
2963 0 : data.channel_list_changed.type =
2964 : REGDOM_TYPE_CUSTOM_WORLD;
2965 0 : break;
2966 : case NL80211_REGDOM_TYPE_INTERSECTION:
2967 0 : data.channel_list_changed.type =
2968 : REGDOM_TYPE_INTERSECTION;
2969 0 : break;
2970 : }
2971 : }
2972 :
2973 3249 : if (tb[NL80211_ATTR_REG_ALPHA2]) {
2974 156 : os_strlcpy(data.channel_list_changed.alpha2,
2975 156 : nla_get_string(tb[NL80211_ATTR_REG_ALPHA2]),
2976 : sizeof(data.channel_list_changed.alpha2));
2977 156 : wpa_printf(MSG_DEBUG, " * alpha2=%s",
2978 : data.channel_list_changed.alpha2);
2979 : }
2980 :
2981 3249 : wpa_supplicant_event(drv->ctx, EVENT_CHANNEL_LIST_CHANGED, &data);
2982 : }
2983 :
2984 :
2985 23031 : static void do_process_drv_event(struct i802_bss *bss, int cmd,
2986 : struct nlattr **tb)
2987 : {
2988 23031 : struct wpa_driver_nl80211_data *drv = bss->drv;
2989 : union wpa_event_data data;
2990 :
2991 23031 : wpa_printf(MSG_DEBUG, "nl80211: Drv Event %d (%s) received for %s",
2992 23031 : cmd, nl80211_command_to_string(cmd), bss->ifname);
2993 :
2994 23031 : if (drv->ap_scan_as_station != NL80211_IFTYPE_UNSPECIFIED &&
2995 0 : (cmd == NL80211_CMD_NEW_SCAN_RESULTS ||
2996 : cmd == NL80211_CMD_SCAN_ABORTED)) {
2997 0 : wpa_driver_nl80211_set_mode(drv->first_bss,
2998 : drv->ap_scan_as_station);
2999 0 : drv->ap_scan_as_station = NL80211_IFTYPE_UNSPECIFIED;
3000 : }
3001 :
3002 23031 : switch (cmd) {
3003 : case NL80211_CMD_TRIGGER_SCAN:
3004 1911 : wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Scan trigger");
3005 1911 : drv->scan_state = SCAN_STARTED;
3006 1911 : if (drv->scan_for_auth) {
3007 : /*
3008 : * Cannot indicate EVENT_SCAN_STARTED here since we skip
3009 : * EVENT_SCAN_RESULTS in scan_for_auth case and the
3010 : * upper layer implementation could get confused about
3011 : * scanning state.
3012 : */
3013 0 : wpa_printf(MSG_DEBUG, "nl80211: Do not indicate scan-start event due to internal scan_for_auth");
3014 0 : break;
3015 : }
3016 1911 : wpa_supplicant_event(drv->ctx, EVENT_SCAN_STARTED, NULL);
3017 1911 : break;
3018 : case NL80211_CMD_START_SCHED_SCAN:
3019 0 : wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Sched scan started");
3020 0 : drv->scan_state = SCHED_SCAN_STARTED;
3021 0 : break;
3022 : case NL80211_CMD_SCHED_SCAN_STOPPED:
3023 0 : wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Sched scan stopped");
3024 0 : drv->scan_state = SCHED_SCAN_STOPPED;
3025 0 : wpa_supplicant_event(drv->ctx, EVENT_SCHED_SCAN_STOPPED, NULL);
3026 0 : break;
3027 : case NL80211_CMD_NEW_SCAN_RESULTS:
3028 1904 : wpa_dbg(drv->ctx, MSG_DEBUG,
3029 : "nl80211: New scan results available");
3030 1904 : drv->scan_state = SCAN_COMPLETED;
3031 1904 : drv->scan_complete_events = 1;
3032 1904 : eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv,
3033 : drv->ctx);
3034 1904 : send_scan_event(drv, 0, tb);
3035 1904 : break;
3036 : case NL80211_CMD_SCHED_SCAN_RESULTS:
3037 0 : wpa_dbg(drv->ctx, MSG_DEBUG,
3038 : "nl80211: New sched scan results available");
3039 0 : drv->scan_state = SCHED_SCAN_RESULTS;
3040 0 : send_scan_event(drv, 0, tb);
3041 0 : break;
3042 : case NL80211_CMD_SCAN_ABORTED:
3043 1 : wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Scan aborted");
3044 1 : drv->scan_state = SCAN_ABORTED;
3045 : /*
3046 : * Need to indicate that scan results are available in order
3047 : * not to make wpa_supplicant stop its scanning.
3048 : */
3049 1 : eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv,
3050 : drv->ctx);
3051 1 : send_scan_event(drv, 1, tb);
3052 1 : break;
3053 : case NL80211_CMD_AUTHENTICATE:
3054 : case NL80211_CMD_ASSOCIATE:
3055 : case NL80211_CMD_DEAUTHENTICATE:
3056 : case NL80211_CMD_DISASSOCIATE:
3057 : case NL80211_CMD_FRAME_TX_STATUS:
3058 : case NL80211_CMD_UNPROT_DEAUTHENTICATE:
3059 : case NL80211_CMD_UNPROT_DISASSOCIATE:
3060 44754 : mlme_event(bss, cmd, tb[NL80211_ATTR_FRAME],
3061 14918 : tb[NL80211_ATTR_MAC], tb[NL80211_ATTR_TIMED_OUT],
3062 14918 : tb[NL80211_ATTR_WIPHY_FREQ], tb[NL80211_ATTR_ACK],
3063 7459 : tb[NL80211_ATTR_COOKIE],
3064 7459 : tb[NL80211_ATTR_RX_SIGNAL_DBM]);
3065 7459 : break;
3066 : case NL80211_CMD_CONNECT:
3067 : case NL80211_CMD_ROAM:
3068 4108 : mlme_event_connect(drv, cmd,
3069 1027 : tb[NL80211_ATTR_STATUS_CODE],
3070 1027 : tb[NL80211_ATTR_MAC],
3071 1027 : tb[NL80211_ATTR_REQ_IE],
3072 1027 : tb[NL80211_ATTR_RESP_IE]);
3073 1027 : break;
3074 : case NL80211_CMD_CH_SWITCH_NOTIFY:
3075 0 : mlme_event_ch_switch(drv,
3076 0 : tb[NL80211_ATTR_IFINDEX],
3077 0 : tb[NL80211_ATTR_WIPHY_FREQ],
3078 0 : tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE],
3079 0 : tb[NL80211_ATTR_CHANNEL_WIDTH],
3080 0 : tb[NL80211_ATTR_CENTER_FREQ1],
3081 0 : tb[NL80211_ATTR_CENTER_FREQ2]);
3082 0 : break;
3083 : case NL80211_CMD_DISCONNECT:
3084 1994 : mlme_event_disconnect(drv, tb[NL80211_ATTR_REASON_CODE],
3085 997 : tb[NL80211_ATTR_MAC],
3086 997 : tb[NL80211_ATTR_DISCONNECTED_BY_AP]);
3087 997 : break;
3088 : case NL80211_CMD_MICHAEL_MIC_FAILURE:
3089 4 : mlme_event_michael_mic_failure(bss, tb);
3090 4 : break;
3091 : case NL80211_CMD_JOIN_IBSS:
3092 15 : mlme_event_join_ibss(drv, tb);
3093 15 : break;
3094 : case NL80211_CMD_REMAIN_ON_CHANNEL:
3095 1095 : mlme_event_remain_on_channel(drv, 0, tb);
3096 1095 : break;
3097 : case NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL:
3098 1093 : mlme_event_remain_on_channel(drv, 1, tb);
3099 1093 : break;
3100 : case NL80211_CMD_NOTIFY_CQM:
3101 5 : nl80211_cqm_event(drv, tb);
3102 5 : break;
3103 : case NL80211_CMD_REG_CHANGE:
3104 3249 : nl80211_reg_change_event(drv, tb);
3105 3249 : break;
3106 : case NL80211_CMD_REG_BEACON_HINT:
3107 0 : wpa_printf(MSG_DEBUG, "nl80211: Regulatory beacon hint");
3108 0 : os_memset(&data, 0, sizeof(data));
3109 0 : data.channel_list_changed.initiator = REGDOM_BEACON_HINT;
3110 0 : wpa_supplicant_event(drv->ctx, EVENT_CHANNEL_LIST_CHANGED,
3111 : &data);
3112 0 : break;
3113 : case NL80211_CMD_NEW_STATION:
3114 2167 : nl80211_new_station_event(drv, tb);
3115 2167 : break;
3116 : case NL80211_CMD_DEL_STATION:
3117 2101 : nl80211_del_station_event(drv, tb);
3118 2101 : break;
3119 : case NL80211_CMD_SET_REKEY_OFFLOAD:
3120 0 : nl80211_rekey_offload_event(drv, tb);
3121 0 : break;
3122 : case NL80211_CMD_PMKSA_CANDIDATE:
3123 0 : nl80211_pmksa_candidate_event(drv, tb);
3124 0 : break;
3125 : case NL80211_CMD_PROBE_CLIENT:
3126 2 : nl80211_client_probe_event(drv, tb);
3127 2 : break;
3128 : case NL80211_CMD_TDLS_OPER:
3129 0 : nl80211_tdls_oper_event(drv, tb);
3130 0 : break;
3131 : case NL80211_CMD_CONN_FAILED:
3132 0 : nl80211_connect_failed_event(drv, tb);
3133 0 : break;
3134 : case NL80211_CMD_FT_EVENT:
3135 0 : mlme_event_ft_event(drv, tb);
3136 0 : break;
3137 : case NL80211_CMD_RADAR_DETECT:
3138 0 : nl80211_radar_event(drv, tb);
3139 0 : break;
3140 : case NL80211_CMD_STOP_AP:
3141 1 : nl80211_stop_ap(drv, tb);
3142 1 : break;
3143 : case NL80211_CMD_VENDOR:
3144 0 : nl80211_vendor_event(drv, tb);
3145 0 : break;
3146 : default:
3147 0 : wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Ignored unknown event "
3148 : "(cmd=%d)", cmd);
3149 0 : break;
3150 : }
3151 23031 : }
3152 :
3153 :
3154 0 : static int process_drv_event(struct nl_msg *msg, void *arg)
3155 : {
3156 0 : struct wpa_driver_nl80211_data *drv = arg;
3157 0 : struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
3158 : struct nlattr *tb[NL80211_ATTR_MAX + 1];
3159 : struct i802_bss *bss;
3160 0 : int ifidx = -1;
3161 :
3162 0 : nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
3163 : genlmsg_attrlen(gnlh, 0), NULL);
3164 :
3165 0 : if (tb[NL80211_ATTR_IFINDEX]) {
3166 0 : ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
3167 :
3168 0 : for (bss = drv->first_bss; bss; bss = bss->next)
3169 0 : if (ifidx == -1 || ifidx == bss->ifindex) {
3170 0 : do_process_drv_event(bss, gnlh->cmd, tb);
3171 0 : return NL_SKIP;
3172 : }
3173 0 : wpa_printf(MSG_DEBUG,
3174 : "nl80211: Ignored event (cmd=%d) for foreign interface (ifindex %d)",
3175 0 : gnlh->cmd, ifidx);
3176 0 : } else if (tb[NL80211_ATTR_WDEV]) {
3177 0 : u64 wdev_id = nla_get_u64(tb[NL80211_ATTR_WDEV]);
3178 0 : wpa_printf(MSG_DEBUG, "nl80211: Process event on P2P device");
3179 0 : for (bss = drv->first_bss; bss; bss = bss->next) {
3180 0 : if (bss->wdev_id_set && wdev_id == bss->wdev_id) {
3181 0 : do_process_drv_event(bss, gnlh->cmd, tb);
3182 0 : return NL_SKIP;
3183 : }
3184 : }
3185 0 : wpa_printf(MSG_DEBUG,
3186 : "nl80211: Ignored event (cmd=%d) for foreign interface (wdev 0x%llx)",
3187 0 : gnlh->cmd, (long long unsigned int) wdev_id);
3188 : }
3189 :
3190 0 : return NL_SKIP;
3191 : }
3192 :
3193 :
3194 106034 : static int process_global_event(struct nl_msg *msg, void *arg)
3195 : {
3196 106034 : struct nl80211_global *global = arg;
3197 106034 : struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
3198 : struct nlattr *tb[NL80211_ATTR_MAX + 1];
3199 : struct wpa_driver_nl80211_data *drv, *tmp;
3200 106034 : int ifidx = -1;
3201 : struct i802_bss *bss;
3202 106034 : u64 wdev_id = 0;
3203 106034 : int wdev_id_set = 0;
3204 :
3205 106034 : nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
3206 : genlmsg_attrlen(gnlh, 0), NULL);
3207 :
3208 106034 : if (tb[NL80211_ATTR_IFINDEX])
3209 101642 : ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
3210 4392 : else if (tb[NL80211_ATTR_WDEV]) {
3211 0 : wdev_id = nla_get_u64(tb[NL80211_ATTR_WDEV]);
3212 0 : wdev_id_set = 1;
3213 : }
3214 :
3215 163060 : dl_list_for_each_safe(drv, tmp, &global->interfaces,
3216 : struct wpa_driver_nl80211_data, list) {
3217 137912 : for (bss = drv->first_bss; bss; bss = bss->next) {
3218 158522 : if ((ifidx == -1 && !wdev_id_set) ||
3219 135491 : ifidx == bss->ifindex ||
3220 0 : (wdev_id_set && bss->wdev_id_set &&
3221 0 : wdev_id == bss->wdev_id)) {
3222 23031 : do_process_drv_event(bss, gnlh->cmd, tb);
3223 23031 : return NL_SKIP;
3224 : }
3225 : }
3226 : }
3227 :
3228 83003 : return NL_SKIP;
3229 : }
3230 :
3231 :
3232 6423 : static int process_bss_event(struct nl_msg *msg, void *arg)
3233 : {
3234 6423 : struct i802_bss *bss = arg;
3235 6423 : struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
3236 : struct nlattr *tb[NL80211_ATTR_MAX + 1];
3237 :
3238 6423 : nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
3239 : genlmsg_attrlen(gnlh, 0), NULL);
3240 :
3241 12846 : wpa_printf(MSG_DEBUG, "nl80211: BSS Event %d (%s) received for %s",
3242 12846 : gnlh->cmd, nl80211_command_to_string(gnlh->cmd),
3243 6423 : bss->ifname);
3244 :
3245 6423 : switch (gnlh->cmd) {
3246 : case NL80211_CMD_FRAME:
3247 : case NL80211_CMD_FRAME_TX_STATUS:
3248 6421 : mlme_event(bss, gnlh->cmd, tb[NL80211_ATTR_FRAME],
3249 : tb[NL80211_ATTR_MAC], tb[NL80211_ATTR_TIMED_OUT],
3250 : tb[NL80211_ATTR_WIPHY_FREQ], tb[NL80211_ATTR_ACK],
3251 : tb[NL80211_ATTR_COOKIE],
3252 : tb[NL80211_ATTR_RX_SIGNAL_DBM]);
3253 6421 : break;
3254 : case NL80211_CMD_UNEXPECTED_FRAME:
3255 1 : nl80211_spurious_frame(bss, tb, 0);
3256 1 : break;
3257 : case NL80211_CMD_UNEXPECTED_4ADDR_FRAME:
3258 1 : nl80211_spurious_frame(bss, tb, 1);
3259 1 : break;
3260 : default:
3261 0 : wpa_printf(MSG_DEBUG, "nl80211: Ignored unknown event "
3262 0 : "(cmd=%d)", gnlh->cmd);
3263 0 : break;
3264 : }
3265 :
3266 6423 : return NL_SKIP;
3267 : }
3268 :
3269 :
3270 112390 : static void wpa_driver_nl80211_event_receive(int sock, void *eloop_ctx,
3271 : void *handle)
3272 : {
3273 112390 : struct nl_cb *cb = eloop_ctx;
3274 : int res;
3275 :
3276 112390 : wpa_printf(MSG_MSGDUMP, "nl80211: Event message available");
3277 :
3278 112390 : res = nl_recvmsgs(handle, cb);
3279 112390 : if (res) {
3280 0 : wpa_printf(MSG_INFO, "nl80211: %s->nl_recvmsgs failed: %d",
3281 : __func__, res);
3282 : }
3283 112390 : }
3284 :
3285 :
3286 : /**
3287 : * wpa_driver_nl80211_set_country - ask nl80211 to set the regulatory domain
3288 : * @priv: driver_nl80211 private data
3289 : * @alpha2_arg: country to which to switch to
3290 : * Returns: 0 on success, -1 on failure
3291 : *
3292 : * This asks nl80211 to set the regulatory domain for given
3293 : * country ISO / IEC alpha2.
3294 : */
3295 21 : static int wpa_driver_nl80211_set_country(void *priv, const char *alpha2_arg)
3296 : {
3297 21 : struct i802_bss *bss = priv;
3298 21 : struct wpa_driver_nl80211_data *drv = bss->drv;
3299 : char alpha2[3];
3300 : struct nl_msg *msg;
3301 :
3302 21 : msg = nlmsg_alloc();
3303 21 : if (!msg)
3304 0 : return -ENOMEM;
3305 :
3306 21 : alpha2[0] = alpha2_arg[0];
3307 21 : alpha2[1] = alpha2_arg[1];
3308 21 : alpha2[2] = '\0';
3309 :
3310 21 : nl80211_cmd(drv, msg, 0, NL80211_CMD_REQ_SET_REG);
3311 :
3312 21 : NLA_PUT_STRING(msg, NL80211_ATTR_REG_ALPHA2, alpha2);
3313 21 : if (send_and_recv_msgs(drv, msg, NULL, NULL))
3314 0 : return -EINVAL;
3315 21 : return 0;
3316 : nla_put_failure:
3317 0 : nlmsg_free(msg);
3318 0 : return -EINVAL;
3319 : }
3320 :
3321 :
3322 19 : static int nl80211_get_country(struct nl_msg *msg, void *arg)
3323 : {
3324 19 : char *alpha2 = arg;
3325 : struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
3326 19 : struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
3327 :
3328 19 : nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
3329 : genlmsg_attrlen(gnlh, 0), NULL);
3330 19 : if (!tb_msg[NL80211_ATTR_REG_ALPHA2]) {
3331 0 : wpa_printf(MSG_DEBUG, "nl80211: No country information available");
3332 0 : return NL_SKIP;
3333 : }
3334 19 : os_strlcpy(alpha2, nla_data(tb_msg[NL80211_ATTR_REG_ALPHA2]), 3);
3335 19 : return NL_SKIP;
3336 : }
3337 :
3338 :
3339 19 : static int wpa_driver_nl80211_get_country(void *priv, char *alpha2)
3340 : {
3341 19 : struct i802_bss *bss = priv;
3342 19 : struct wpa_driver_nl80211_data *drv = bss->drv;
3343 : struct nl_msg *msg;
3344 : int ret;
3345 :
3346 19 : msg = nlmsg_alloc();
3347 19 : if (!msg)
3348 0 : return -ENOMEM;
3349 :
3350 19 : nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_REG);
3351 19 : alpha2[0] = '\0';
3352 19 : ret = send_and_recv_msgs(drv, msg, nl80211_get_country, alpha2);
3353 19 : if (!alpha2[0])
3354 0 : ret = -1;
3355 :
3356 19 : return ret;
3357 : }
3358 :
3359 :
3360 4060 : static int protocol_feature_handler(struct nl_msg *msg, void *arg)
3361 : {
3362 4060 : u32 *feat = arg;
3363 : struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
3364 4060 : struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
3365 :
3366 4060 : nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
3367 : genlmsg_attrlen(gnlh, 0), NULL);
3368 :
3369 4060 : if (tb_msg[NL80211_ATTR_PROTOCOL_FEATURES])
3370 4060 : *feat = nla_get_u32(tb_msg[NL80211_ATTR_PROTOCOL_FEATURES]);
3371 :
3372 4060 : return NL_SKIP;
3373 : }
3374 :
3375 :
3376 4060 : static u32 get_nl80211_protocol_features(struct wpa_driver_nl80211_data *drv)
3377 : {
3378 4060 : u32 feat = 0;
3379 : struct nl_msg *msg;
3380 :
3381 4060 : msg = nlmsg_alloc();
3382 4060 : if (!msg)
3383 0 : goto nla_put_failure;
3384 :
3385 4060 : nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_PROTOCOL_FEATURES);
3386 4060 : if (send_and_recv_msgs(drv, msg, protocol_feature_handler, &feat) == 0)
3387 4060 : return feat;
3388 :
3389 0 : msg = NULL;
3390 : nla_put_failure:
3391 0 : nlmsg_free(msg);
3392 0 : return 0;
3393 : }
3394 :
3395 :
3396 : struct wiphy_info_data {
3397 : struct wpa_driver_nl80211_data *drv;
3398 : struct wpa_driver_capa *capa;
3399 :
3400 : unsigned int num_multichan_concurrent;
3401 :
3402 : unsigned int error:1;
3403 : unsigned int device_ap_sme:1;
3404 : unsigned int poll_command_supported:1;
3405 : unsigned int data_tx_status:1;
3406 : unsigned int monitor_supported:1;
3407 : unsigned int auth_supported:1;
3408 : unsigned int connect_supported:1;
3409 : unsigned int p2p_go_supported:1;
3410 : unsigned int p2p_client_supported:1;
3411 : unsigned int p2p_concurrent:1;
3412 : unsigned int channel_switch_supported:1;
3413 : unsigned int set_qos_map_supported:1;
3414 : };
3415 :
3416 :
3417 0 : static unsigned int probe_resp_offload_support(int supp_protocols)
3418 : {
3419 0 : unsigned int prot = 0;
3420 :
3421 0 : if (supp_protocols & NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS)
3422 0 : prot |= WPA_DRIVER_PROBE_RESP_OFFLOAD_WPS;
3423 0 : if (supp_protocols & NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2)
3424 0 : prot |= WPA_DRIVER_PROBE_RESP_OFFLOAD_WPS2;
3425 0 : if (supp_protocols & NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P)
3426 0 : prot |= WPA_DRIVER_PROBE_RESP_OFFLOAD_P2P;
3427 0 : if (supp_protocols & NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U)
3428 0 : prot |= WPA_DRIVER_PROBE_RESP_OFFLOAD_INTERWORKING;
3429 :
3430 0 : return prot;
3431 : }
3432 :
3433 :
3434 32807 : static void wiphy_info_supported_iftypes(struct wiphy_info_data *info,
3435 : struct nlattr *tb)
3436 : {
3437 : struct nlattr *nl_mode;
3438 : int i;
3439 :
3440 32807 : if (tb == NULL)
3441 64995 : return;
3442 :
3443 5571 : nla_for_each_nested(nl_mode, tb, i) {
3444 4952 : switch (nla_type(nl_mode)) {
3445 : case NL80211_IFTYPE_AP:
3446 619 : info->capa->flags |= WPA_DRIVER_FLAGS_AP;
3447 619 : break;
3448 : case NL80211_IFTYPE_ADHOC:
3449 619 : info->capa->flags |= WPA_DRIVER_FLAGS_IBSS;
3450 619 : break;
3451 : case NL80211_IFTYPE_P2P_DEVICE:
3452 619 : info->capa->flags |=
3453 : WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE;
3454 619 : break;
3455 : case NL80211_IFTYPE_P2P_GO:
3456 619 : info->p2p_go_supported = 1;
3457 619 : break;
3458 : case NL80211_IFTYPE_P2P_CLIENT:
3459 619 : info->p2p_client_supported = 1;
3460 619 : break;
3461 : case NL80211_IFTYPE_MONITOR:
3462 619 : info->monitor_supported = 1;
3463 619 : break;
3464 : }
3465 : }
3466 : }
3467 :
3468 :
3469 1238 : static int wiphy_info_iface_comb_process(struct wiphy_info_data *info,
3470 : struct nlattr *nl_combi)
3471 : {
3472 : struct nlattr *tb_comb[NUM_NL80211_IFACE_COMB];
3473 : struct nlattr *tb_limit[NUM_NL80211_IFACE_LIMIT];
3474 : struct nlattr *nl_limit, *nl_mode;
3475 : int err, rem_limit, rem_mode;
3476 1238 : int combination_has_p2p = 0, combination_has_mgd = 0;
3477 : static struct nla_policy
3478 : iface_combination_policy[NUM_NL80211_IFACE_COMB] = {
3479 : [NL80211_IFACE_COMB_LIMITS] = { .type = NLA_NESTED },
3480 : [NL80211_IFACE_COMB_MAXNUM] = { .type = NLA_U32 },
3481 : [NL80211_IFACE_COMB_STA_AP_BI_MATCH] = { .type = NLA_FLAG },
3482 : [NL80211_IFACE_COMB_NUM_CHANNELS] = { .type = NLA_U32 },
3483 : [NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS] = { .type = NLA_U32 },
3484 : },
3485 : iface_limit_policy[NUM_NL80211_IFACE_LIMIT] = {
3486 : [NL80211_IFACE_LIMIT_TYPES] = { .type = NLA_NESTED },
3487 : [NL80211_IFACE_LIMIT_MAX] = { .type = NLA_U32 },
3488 : };
3489 :
3490 1238 : err = nla_parse_nested(tb_comb, MAX_NL80211_IFACE_COMB,
3491 : nl_combi, iface_combination_policy);
3492 2476 : if (err || !tb_comb[NL80211_IFACE_COMB_LIMITS] ||
3493 2476 : !tb_comb[NL80211_IFACE_COMB_MAXNUM] ||
3494 1238 : !tb_comb[NL80211_IFACE_COMB_NUM_CHANNELS])
3495 0 : return 0; /* broken combination */
3496 :
3497 1238 : if (tb_comb[NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS])
3498 1238 : info->capa->flags |= WPA_DRIVER_FLAGS_RADAR;
3499 :
3500 2476 : nla_for_each_nested(nl_limit, tb_comb[NL80211_IFACE_COMB_LIMITS],
3501 : rem_limit) {
3502 1857 : err = nla_parse_nested(tb_limit, MAX_NL80211_IFACE_LIMIT,
3503 : nl_limit, iface_limit_policy);
3504 1857 : if (err || !tb_limit[NL80211_IFACE_LIMIT_TYPES])
3505 0 : return 0; /* broken combination */
3506 :
3507 5571 : nla_for_each_nested(nl_mode,
3508 : tb_limit[NL80211_IFACE_LIMIT_TYPES],
3509 : rem_mode) {
3510 3714 : int ift = nla_type(nl_mode);
3511 3714 : if (ift == NL80211_IFTYPE_P2P_GO ||
3512 : ift == NL80211_IFTYPE_P2P_CLIENT)
3513 1238 : combination_has_p2p = 1;
3514 3714 : if (ift == NL80211_IFTYPE_STATION)
3515 619 : combination_has_mgd = 1;
3516 : }
3517 1857 : if (combination_has_p2p && combination_has_mgd)
3518 619 : break;
3519 : }
3520 :
3521 1238 : if (combination_has_p2p && combination_has_mgd) {
3522 619 : unsigned int num_channels =
3523 619 : nla_get_u32(tb_comb[NL80211_IFACE_COMB_NUM_CHANNELS]);
3524 :
3525 619 : info->p2p_concurrent = 1;
3526 619 : if (info->num_multichan_concurrent < num_channels)
3527 619 : info->num_multichan_concurrent = num_channels;
3528 : }
3529 :
3530 1238 : return 0;
3531 : }
3532 :
3533 :
3534 32807 : static void wiphy_info_iface_comb(struct wiphy_info_data *info,
3535 : struct nlattr *tb)
3536 : {
3537 : struct nlattr *nl_combi;
3538 : int rem_combi;
3539 :
3540 32807 : if (tb == NULL)
3541 64995 : return;
3542 :
3543 1857 : nla_for_each_nested(nl_combi, tb, rem_combi) {
3544 1238 : if (wiphy_info_iface_comb_process(info, nl_combi) > 0)
3545 0 : break;
3546 : }
3547 : }
3548 :
3549 :
3550 32807 : static void wiphy_info_supp_cmds(struct wiphy_info_data *info,
3551 : struct nlattr *tb)
3552 : {
3553 : struct nlattr *nl_cmd;
3554 : int i;
3555 :
3556 32807 : if (tb == NULL)
3557 64995 : return;
3558 :
3559 17951 : nla_for_each_nested(nl_cmd, tb, i) {
3560 17332 : switch (nla_get_u32(nl_cmd)) {
3561 : case NL80211_CMD_AUTHENTICATE:
3562 619 : info->auth_supported = 1;
3563 619 : break;
3564 : case NL80211_CMD_CONNECT:
3565 619 : info->connect_supported = 1;
3566 619 : break;
3567 : case NL80211_CMD_START_SCHED_SCAN:
3568 0 : info->capa->sched_scan_supported = 1;
3569 0 : break;
3570 : case NL80211_CMD_PROBE_CLIENT:
3571 619 : info->poll_command_supported = 1;
3572 619 : break;
3573 : case NL80211_CMD_CHANNEL_SWITCH:
3574 0 : info->channel_switch_supported = 1;
3575 0 : break;
3576 : case NL80211_CMD_SET_QOS_MAP:
3577 619 : info->set_qos_map_supported = 1;
3578 619 : break;
3579 : }
3580 : }
3581 : }
3582 :
3583 :
3584 32807 : static void wiphy_info_cipher_suites(struct wiphy_info_data *info,
3585 : struct nlattr *tb)
3586 : {
3587 : int i, num;
3588 : u32 *ciphers;
3589 :
3590 32807 : if (tb == NULL)
3591 64995 : return;
3592 :
3593 619 : num = nla_len(tb) / sizeof(u32);
3594 619 : ciphers = nla_data(tb);
3595 3714 : for (i = 0; i < num; i++) {
3596 3095 : u32 c = ciphers[i];
3597 :
3598 9285 : wpa_printf(MSG_DEBUG, "nl80211: Supported cipher %02x-%02x-%02x:%d",
3599 3095 : c >> 24, (c >> 16) & 0xff,
3600 3095 : (c >> 8) & 0xff, c & 0xff);
3601 3095 : switch (c) {
3602 : case WLAN_CIPHER_SUITE_CCMP_256:
3603 0 : info->capa->enc |= WPA_DRIVER_CAPA_ENC_CCMP_256;
3604 0 : break;
3605 : case WLAN_CIPHER_SUITE_GCMP_256:
3606 0 : info->capa->enc |= WPA_DRIVER_CAPA_ENC_GCMP_256;
3607 0 : break;
3608 : case WLAN_CIPHER_SUITE_CCMP:
3609 619 : info->capa->enc |= WPA_DRIVER_CAPA_ENC_CCMP;
3610 619 : break;
3611 : case WLAN_CIPHER_SUITE_GCMP:
3612 0 : info->capa->enc |= WPA_DRIVER_CAPA_ENC_GCMP;
3613 0 : break;
3614 : case WLAN_CIPHER_SUITE_TKIP:
3615 619 : info->capa->enc |= WPA_DRIVER_CAPA_ENC_TKIP;
3616 619 : break;
3617 : case WLAN_CIPHER_SUITE_WEP104:
3618 619 : info->capa->enc |= WPA_DRIVER_CAPA_ENC_WEP104;
3619 619 : break;
3620 : case WLAN_CIPHER_SUITE_WEP40:
3621 619 : info->capa->enc |= WPA_DRIVER_CAPA_ENC_WEP40;
3622 619 : break;
3623 : case WLAN_CIPHER_SUITE_AES_CMAC:
3624 619 : info->capa->enc |= WPA_DRIVER_CAPA_ENC_BIP;
3625 619 : break;
3626 : case WLAN_CIPHER_SUITE_BIP_GMAC_128:
3627 0 : info->capa->enc |= WPA_DRIVER_CAPA_ENC_BIP_GMAC_128;
3628 0 : break;
3629 : case WLAN_CIPHER_SUITE_BIP_GMAC_256:
3630 0 : info->capa->enc |= WPA_DRIVER_CAPA_ENC_BIP_GMAC_256;
3631 0 : break;
3632 : case WLAN_CIPHER_SUITE_BIP_CMAC_256:
3633 0 : info->capa->enc |= WPA_DRIVER_CAPA_ENC_BIP_CMAC_256;
3634 0 : break;
3635 : case WLAN_CIPHER_SUITE_NO_GROUP_ADDR:
3636 0 : info->capa->enc |= WPA_DRIVER_CAPA_ENC_GTK_NOT_USED;
3637 0 : break;
3638 : }
3639 : }
3640 : }
3641 :
3642 :
3643 32807 : static void wiphy_info_max_roc(struct wpa_driver_capa *capa,
3644 : struct nlattr *tb)
3645 : {
3646 32807 : if (tb)
3647 619 : capa->max_remain_on_chan = nla_get_u32(tb);
3648 32807 : }
3649 :
3650 :
3651 32807 : static void wiphy_info_tdls(struct wpa_driver_capa *capa, struct nlattr *tdls,
3652 : struct nlattr *ext_setup)
3653 : {
3654 32807 : if (tdls == NULL)
3655 64995 : return;
3656 :
3657 619 : wpa_printf(MSG_DEBUG, "nl80211: TDLS supported");
3658 619 : capa->flags |= WPA_DRIVER_FLAGS_TDLS_SUPPORT;
3659 :
3660 619 : if (ext_setup) {
3661 619 : wpa_printf(MSG_DEBUG, "nl80211: TDLS external setup");
3662 619 : capa->flags |= WPA_DRIVER_FLAGS_TDLS_EXTERNAL_SETUP;
3663 : }
3664 : }
3665 :
3666 :
3667 32807 : static void wiphy_info_feature_flags(struct wiphy_info_data *info,
3668 : struct nlattr *tb)
3669 : {
3670 : u32 flags;
3671 32807 : struct wpa_driver_capa *capa = info->capa;
3672 :
3673 32807 : if (tb == NULL)
3674 64995 : return;
3675 :
3676 619 : flags = nla_get_u32(tb);
3677 :
3678 619 : if (flags & NL80211_FEATURE_SK_TX_STATUS)
3679 619 : info->data_tx_status = 1;
3680 :
3681 619 : if (flags & NL80211_FEATURE_INACTIVITY_TIMER)
3682 0 : capa->flags |= WPA_DRIVER_FLAGS_INACTIVITY_TIMER;
3683 :
3684 619 : if (flags & NL80211_FEATURE_SAE)
3685 619 : capa->flags |= WPA_DRIVER_FLAGS_SAE;
3686 :
3687 619 : if (flags & NL80211_FEATURE_NEED_OBSS_SCAN)
3688 0 : capa->flags |= WPA_DRIVER_FLAGS_OBSS_SCAN;
3689 :
3690 619 : if (flags & NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE)
3691 619 : capa->flags |= WPA_DRIVER_FLAGS_HT_2040_COEX;
3692 : }
3693 :
3694 :
3695 32807 : static void wiphy_info_probe_resp_offload(struct wpa_driver_capa *capa,
3696 : struct nlattr *tb)
3697 : {
3698 : u32 protocols;
3699 :
3700 32807 : if (tb == NULL)
3701 65614 : return;
3702 :
3703 0 : protocols = nla_get_u32(tb);
3704 0 : wpa_printf(MSG_DEBUG, "nl80211: Supports Probe Response offload in AP "
3705 : "mode");
3706 0 : capa->flags |= WPA_DRIVER_FLAGS_PROBE_RESP_OFFLOAD;
3707 0 : capa->probe_resp_offloads = probe_resp_offload_support(protocols);
3708 : }
3709 :
3710 :
3711 32807 : static void wiphy_info_wowlan_triggers(struct wpa_driver_capa *capa,
3712 : struct nlattr *tb)
3713 : {
3714 : struct nlattr *triggers[MAX_NL80211_WOWLAN_TRIG + 1];
3715 :
3716 32807 : if (tb == NULL)
3717 65614 : return;
3718 :
3719 0 : if (nla_parse_nested(triggers, MAX_NL80211_WOWLAN_TRIG,
3720 : tb, NULL))
3721 0 : return;
3722 :
3723 0 : if (triggers[NL80211_WOWLAN_TRIG_ANY])
3724 0 : capa->wowlan_triggers.any = 1;
3725 0 : if (triggers[NL80211_WOWLAN_TRIG_DISCONNECT])
3726 0 : capa->wowlan_triggers.disconnect = 1;
3727 0 : if (triggers[NL80211_WOWLAN_TRIG_MAGIC_PKT])
3728 0 : capa->wowlan_triggers.magic_pkt = 1;
3729 0 : if (triggers[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE])
3730 0 : capa->wowlan_triggers.gtk_rekey_failure = 1;
3731 0 : if (triggers[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST])
3732 0 : capa->wowlan_triggers.eap_identity_req = 1;
3733 0 : if (triggers[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE])
3734 0 : capa->wowlan_triggers.four_way_handshake = 1;
3735 0 : if (triggers[NL80211_WOWLAN_TRIG_RFKILL_RELEASE])
3736 0 : capa->wowlan_triggers.rfkill_release = 1;
3737 : }
3738 :
3739 :
3740 32807 : static int wiphy_info_handler(struct nl_msg *msg, void *arg)
3741 : {
3742 : struct nlattr *tb[NL80211_ATTR_MAX + 1];
3743 32807 : struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
3744 32807 : struct wiphy_info_data *info = arg;
3745 32807 : struct wpa_driver_capa *capa = info->capa;
3746 32807 : struct wpa_driver_nl80211_data *drv = info->drv;
3747 :
3748 32807 : nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
3749 : genlmsg_attrlen(gnlh, 0), NULL);
3750 :
3751 32807 : if (tb[NL80211_ATTR_WIPHY_NAME])
3752 32807 : os_strlcpy(drv->phyname,
3753 32807 : nla_get_string(tb[NL80211_ATTR_WIPHY_NAME]),
3754 : sizeof(drv->phyname));
3755 32807 : if (tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS])
3756 619 : capa->max_scan_ssids =
3757 619 : nla_get_u8(tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS]);
3758 :
3759 32807 : if (tb[NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS])
3760 619 : capa->max_sched_scan_ssids =
3761 619 : nla_get_u8(tb[NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS]);
3762 :
3763 32807 : if (tb[NL80211_ATTR_MAX_MATCH_SETS])
3764 619 : capa->max_match_sets =
3765 619 : nla_get_u8(tb[NL80211_ATTR_MAX_MATCH_SETS]);
3766 :
3767 32807 : if (tb[NL80211_ATTR_MAC_ACL_MAX])
3768 0 : capa->max_acl_mac_addrs =
3769 0 : nla_get_u8(tb[NL80211_ATTR_MAC_ACL_MAX]);
3770 :
3771 32807 : wiphy_info_supported_iftypes(info, tb[NL80211_ATTR_SUPPORTED_IFTYPES]);
3772 32807 : wiphy_info_iface_comb(info, tb[NL80211_ATTR_INTERFACE_COMBINATIONS]);
3773 32807 : wiphy_info_supp_cmds(info, tb[NL80211_ATTR_SUPPORTED_COMMANDS]);
3774 32807 : wiphy_info_cipher_suites(info, tb[NL80211_ATTR_CIPHER_SUITES]);
3775 :
3776 32807 : if (tb[NL80211_ATTR_OFFCHANNEL_TX_OK]) {
3777 619 : wpa_printf(MSG_DEBUG, "nl80211: Using driver-based "
3778 : "off-channel TX");
3779 619 : capa->flags |= WPA_DRIVER_FLAGS_OFFCHANNEL_TX;
3780 : }
3781 :
3782 32807 : if (tb[NL80211_ATTR_ROAM_SUPPORT]) {
3783 0 : wpa_printf(MSG_DEBUG, "nl80211: Using driver-based roaming");
3784 0 : capa->flags |= WPA_DRIVER_FLAGS_BSS_SELECTION;
3785 : }
3786 :
3787 32807 : wiphy_info_max_roc(capa,
3788 : tb[NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION]);
3789 :
3790 32807 : if (tb[NL80211_ATTR_SUPPORT_AP_UAPSD])
3791 619 : capa->flags |= WPA_DRIVER_FLAGS_AP_UAPSD;
3792 :
3793 32807 : wiphy_info_tdls(capa, tb[NL80211_ATTR_TDLS_SUPPORT],
3794 : tb[NL80211_ATTR_TDLS_EXTERNAL_SETUP]);
3795 :
3796 32807 : if (tb[NL80211_ATTR_DEVICE_AP_SME])
3797 0 : info->device_ap_sme = 1;
3798 :
3799 32807 : wiphy_info_feature_flags(info, tb[NL80211_ATTR_FEATURE_FLAGS]);
3800 32807 : wiphy_info_probe_resp_offload(capa,
3801 : tb[NL80211_ATTR_PROBE_RESP_OFFLOAD]);
3802 :
3803 33426 : if (tb[NL80211_ATTR_EXT_CAPA] && tb[NL80211_ATTR_EXT_CAPA_MASK] &&
3804 619 : drv->extended_capa == NULL) {
3805 619 : drv->extended_capa =
3806 619 : os_malloc(nla_len(tb[NL80211_ATTR_EXT_CAPA]));
3807 619 : if (drv->extended_capa) {
3808 619 : os_memcpy(drv->extended_capa,
3809 : nla_data(tb[NL80211_ATTR_EXT_CAPA]),
3810 : nla_len(tb[NL80211_ATTR_EXT_CAPA]));
3811 619 : drv->extended_capa_len =
3812 619 : nla_len(tb[NL80211_ATTR_EXT_CAPA]);
3813 : }
3814 619 : drv->extended_capa_mask =
3815 619 : os_malloc(nla_len(tb[NL80211_ATTR_EXT_CAPA]));
3816 619 : if (drv->extended_capa_mask) {
3817 619 : os_memcpy(drv->extended_capa_mask,
3818 : nla_data(tb[NL80211_ATTR_EXT_CAPA]),
3819 : nla_len(tb[NL80211_ATTR_EXT_CAPA]));
3820 : } else {
3821 0 : os_free(drv->extended_capa);
3822 0 : drv->extended_capa = NULL;
3823 0 : drv->extended_capa_len = 0;
3824 : }
3825 : }
3826 :
3827 32807 : if (tb[NL80211_ATTR_VENDOR_DATA]) {
3828 : struct nlattr *nl;
3829 : int rem;
3830 :
3831 0 : nla_for_each_nested(nl, tb[NL80211_ATTR_VENDOR_DATA], rem) {
3832 : struct nl80211_vendor_cmd_info *vinfo;
3833 0 : if (nla_len(nl) != sizeof(*vinfo)) {
3834 0 : wpa_printf(MSG_DEBUG, "nl80211: Unexpected vendor data info");
3835 0 : continue;
3836 : }
3837 0 : vinfo = nla_data(nl);
3838 0 : if (vinfo->subcmd ==
3839 : QCA_NL80211_VENDOR_SUBCMD_DFS_CAPABILITY)
3840 0 : drv->dfs_vendor_cmd_avail = 1;
3841 :
3842 0 : wpa_printf(MSG_DEBUG, "nl80211: Supported vendor command: vendor_id=0x%x subcmd=%u",
3843 : vinfo->vendor_id, vinfo->subcmd);
3844 : }
3845 : }
3846 :
3847 32807 : if (tb[NL80211_ATTR_VENDOR_EVENTS]) {
3848 : struct nlattr *nl;
3849 : int rem;
3850 :
3851 0 : nla_for_each_nested(nl, tb[NL80211_ATTR_VENDOR_EVENTS], rem) {
3852 : struct nl80211_vendor_cmd_info *vinfo;
3853 0 : if (nla_len(nl) != sizeof(*vinfo)) {
3854 0 : wpa_printf(MSG_DEBUG, "nl80211: Unexpected vendor data info");
3855 0 : continue;
3856 : }
3857 0 : vinfo = nla_data(nl);
3858 0 : wpa_printf(MSG_DEBUG, "nl80211: Supported vendor event: vendor_id=0x%x subcmd=%u",
3859 : vinfo->vendor_id, vinfo->subcmd);
3860 : }
3861 : }
3862 :
3863 32807 : wiphy_info_wowlan_triggers(capa,
3864 : tb[NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED]);
3865 :
3866 32807 : if (tb[NL80211_ATTR_MAX_AP_ASSOC_STA])
3867 0 : capa->max_stations =
3868 0 : nla_get_u32(tb[NL80211_ATTR_MAX_AP_ASSOC_STA]);
3869 :
3870 32807 : return NL_SKIP;
3871 : }
3872 :
3873 :
3874 621 : static int wpa_driver_nl80211_get_info(struct wpa_driver_nl80211_data *drv,
3875 : struct wiphy_info_data *info)
3876 : {
3877 : u32 feat;
3878 : struct nl_msg *msg;
3879 :
3880 621 : os_memset(info, 0, sizeof(*info));
3881 621 : info->capa = &drv->capa;
3882 621 : info->drv = drv;
3883 :
3884 621 : msg = nlmsg_alloc();
3885 621 : if (!msg)
3886 0 : return -1;
3887 :
3888 621 : feat = get_nl80211_protocol_features(drv);
3889 621 : if (feat & NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP)
3890 621 : nl80211_cmd(drv, msg, NLM_F_DUMP, NL80211_CMD_GET_WIPHY);
3891 : else
3892 0 : nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_WIPHY);
3893 :
3894 621 : NLA_PUT_FLAG(msg, NL80211_ATTR_SPLIT_WIPHY_DUMP);
3895 621 : if (nl80211_set_iface_id(msg, drv->first_bss) < 0)
3896 0 : goto nla_put_failure;
3897 :
3898 621 : if (send_and_recv_msgs(drv, msg, wiphy_info_handler, info))
3899 0 : return -1;
3900 :
3901 621 : if (info->auth_supported)
3902 619 : drv->capa.flags |= WPA_DRIVER_FLAGS_SME;
3903 2 : else if (!info->connect_supported) {
3904 2 : wpa_printf(MSG_INFO, "nl80211: Driver does not support "
3905 : "authentication/association or connect commands");
3906 2 : info->error = 1;
3907 : }
3908 :
3909 621 : if (info->p2p_go_supported && info->p2p_client_supported)
3910 619 : drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_CAPABLE;
3911 621 : if (info->p2p_concurrent) {
3912 619 : wpa_printf(MSG_DEBUG, "nl80211: Use separate P2P group "
3913 : "interface (driver advertised support)");
3914 619 : drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_CONCURRENT;
3915 619 : drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_MGMT_AND_NON_P2P;
3916 : }
3917 621 : if (info->num_multichan_concurrent > 1) {
3918 0 : wpa_printf(MSG_DEBUG, "nl80211: Enable multi-channel "
3919 : "concurrent (driver advertised support)");
3920 0 : drv->capa.num_multichan_concurrent =
3921 0 : info->num_multichan_concurrent;
3922 : }
3923 :
3924 : /* default to 5000 since early versions of mac80211 don't set it */
3925 621 : if (!drv->capa.max_remain_on_chan)
3926 2 : drv->capa.max_remain_on_chan = 5000;
3927 :
3928 621 : if (info->channel_switch_supported)
3929 0 : drv->capa.flags |= WPA_DRIVER_FLAGS_AP_CSA;
3930 :
3931 621 : return 0;
3932 : nla_put_failure:
3933 0 : nlmsg_free(msg);
3934 0 : return -1;
3935 : }
3936 :
3937 :
3938 621 : static int wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv)
3939 : {
3940 : struct wiphy_info_data info;
3941 621 : if (wpa_driver_nl80211_get_info(drv, &info))
3942 0 : return -1;
3943 :
3944 621 : if (info.error)
3945 2 : return -1;
3946 :
3947 619 : drv->has_capability = 1;
3948 619 : drv->capa.key_mgmt = WPA_DRIVER_CAPA_KEY_MGMT_WPA |
3949 : WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
3950 : WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
3951 : WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK;
3952 619 : drv->capa.auth = WPA_DRIVER_AUTH_OPEN |
3953 : WPA_DRIVER_AUTH_SHARED |
3954 : WPA_DRIVER_AUTH_LEAP;
3955 :
3956 619 : drv->capa.flags |= WPA_DRIVER_FLAGS_SANE_ERROR_CODES;
3957 619 : drv->capa.flags |= WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC_DONE;
3958 619 : drv->capa.flags |= WPA_DRIVER_FLAGS_EAPOL_TX_STATUS;
3959 :
3960 : /*
3961 : * As all cfg80211 drivers must support cases where the AP interface is
3962 : * removed without the knowledge of wpa_supplicant/hostapd, e.g., in
3963 : * case that the user space daemon has crashed, they must be able to
3964 : * cleanup all stations and key entries in the AP tear down flow. Thus,
3965 : * this flag can/should always be set for cfg80211 drivers.
3966 : */
3967 619 : drv->capa.flags |= WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT;
3968 :
3969 619 : if (!info.device_ap_sme) {
3970 619 : drv->capa.flags |= WPA_DRIVER_FLAGS_DEAUTH_TX_STATUS;
3971 :
3972 : /*
3973 : * No AP SME is currently assumed to also indicate no AP MLME
3974 : * in the driver/firmware.
3975 : */
3976 619 : drv->capa.flags |= WPA_DRIVER_FLAGS_AP_MLME;
3977 : }
3978 :
3979 619 : drv->device_ap_sme = info.device_ap_sme;
3980 619 : drv->poll_command_supported = info.poll_command_supported;
3981 619 : drv->data_tx_status = info.data_tx_status;
3982 619 : if (info.set_qos_map_supported)
3983 619 : drv->capa.flags |= WPA_DRIVER_FLAGS_QOS_MAPPING;
3984 :
3985 : /*
3986 : * If poll command and tx status are supported, mac80211 is new enough
3987 : * to have everything we need to not need monitor interfaces.
3988 : */
3989 619 : drv->use_monitor = !info.poll_command_supported || !info.data_tx_status;
3990 :
3991 619 : if (drv->device_ap_sme && drv->use_monitor) {
3992 : /*
3993 : * Non-mac80211 drivers may not support monitor interface.
3994 : * Make sure we do not get stuck with incorrect capability here
3995 : * by explicitly testing this.
3996 : */
3997 0 : if (!info.monitor_supported) {
3998 0 : wpa_printf(MSG_DEBUG, "nl80211: Disable use_monitor "
3999 : "with device_ap_sme since no monitor mode "
4000 : "support detected");
4001 0 : drv->use_monitor = 0;
4002 : }
4003 : }
4004 :
4005 : /*
4006 : * If we aren't going to use monitor interfaces, but the
4007 : * driver doesn't support data TX status, we won't get TX
4008 : * status for EAPOL frames.
4009 : */
4010 619 : if (!drv->use_monitor && !info.data_tx_status)
4011 0 : drv->capa.flags &= ~WPA_DRIVER_FLAGS_EAPOL_TX_STATUS;
4012 :
4013 619 : return 0;
4014 : }
4015 :
4016 :
4017 : #ifdef ANDROID
4018 : static int android_genl_ctrl_resolve(struct nl_handle *handle,
4019 : const char *name)
4020 : {
4021 : /*
4022 : * Android ICS has very minimal genl_ctrl_resolve() implementation, so
4023 : * need to work around that.
4024 : */
4025 : struct nl_cache *cache = NULL;
4026 : struct genl_family *nl80211 = NULL;
4027 : int id = -1;
4028 :
4029 : if (genl_ctrl_alloc_cache(handle, &cache) < 0) {
4030 : wpa_printf(MSG_ERROR, "nl80211: Failed to allocate generic "
4031 : "netlink cache");
4032 : goto fail;
4033 : }
4034 :
4035 : nl80211 = genl_ctrl_search_by_name(cache, name);
4036 : if (nl80211 == NULL)
4037 : goto fail;
4038 :
4039 : id = genl_family_get_id(nl80211);
4040 :
4041 : fail:
4042 : if (nl80211)
4043 : genl_family_put(nl80211);
4044 : if (cache)
4045 : nl_cache_free(cache);
4046 :
4047 : return id;
4048 : }
4049 : #define genl_ctrl_resolve android_genl_ctrl_resolve
4050 : #endif /* ANDROID */
4051 :
4052 :
4053 5 : static int wpa_driver_nl80211_init_nl_global(struct nl80211_global *global)
4054 : {
4055 : int ret;
4056 :
4057 5 : global->nl_cb = nl_cb_alloc(NL_CB_DEFAULT);
4058 5 : if (global->nl_cb == NULL) {
4059 0 : wpa_printf(MSG_ERROR, "nl80211: Failed to allocate netlink "
4060 : "callbacks");
4061 0 : return -1;
4062 : }
4063 :
4064 5 : global->nl = nl_create_handle(global->nl_cb, "nl");
4065 5 : if (global->nl == NULL)
4066 0 : goto err;
4067 :
4068 5 : global->nl80211_id = genl_ctrl_resolve(global->nl, "nl80211");
4069 5 : if (global->nl80211_id < 0) {
4070 0 : wpa_printf(MSG_ERROR, "nl80211: 'nl80211' generic netlink not "
4071 : "found");
4072 0 : goto err;
4073 : }
4074 :
4075 5 : global->nl_event = nl_create_handle(global->nl_cb, "event");
4076 5 : if (global->nl_event == NULL)
4077 0 : goto err;
4078 :
4079 5 : ret = nl_get_multicast_id(global, "nl80211", "scan");
4080 5 : if (ret >= 0)
4081 5 : ret = nl_socket_add_membership(global->nl_event, ret);
4082 5 : if (ret < 0) {
4083 0 : wpa_printf(MSG_ERROR, "nl80211: Could not add multicast "
4084 : "membership for scan events: %d (%s)",
4085 : ret, strerror(-ret));
4086 0 : goto err;
4087 : }
4088 :
4089 5 : ret = nl_get_multicast_id(global, "nl80211", "mlme");
4090 5 : if (ret >= 0)
4091 5 : ret = nl_socket_add_membership(global->nl_event, ret);
4092 5 : if (ret < 0) {
4093 0 : wpa_printf(MSG_ERROR, "nl80211: Could not add multicast "
4094 : "membership for mlme events: %d (%s)",
4095 : ret, strerror(-ret));
4096 0 : goto err;
4097 : }
4098 :
4099 5 : ret = nl_get_multicast_id(global, "nl80211", "regulatory");
4100 5 : if (ret >= 0)
4101 5 : ret = nl_socket_add_membership(global->nl_event, ret);
4102 5 : if (ret < 0) {
4103 0 : wpa_printf(MSG_DEBUG, "nl80211: Could not add multicast "
4104 : "membership for regulatory events: %d (%s)",
4105 : ret, strerror(-ret));
4106 : /* Continue without regulatory events */
4107 : }
4108 :
4109 5 : ret = nl_get_multicast_id(global, "nl80211", "vendor");
4110 5 : if (ret >= 0)
4111 5 : ret = nl_socket_add_membership(global->nl_event, ret);
4112 5 : if (ret < 0) {
4113 0 : wpa_printf(MSG_DEBUG, "nl80211: Could not add multicast "
4114 : "membership for vendor events: %d (%s)",
4115 : ret, strerror(-ret));
4116 : /* Continue without vendor events */
4117 : }
4118 :
4119 5 : nl_cb_set(global->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
4120 : no_seq_check, NULL);
4121 5 : nl_cb_set(global->nl_cb, NL_CB_VALID, NL_CB_CUSTOM,
4122 : process_global_event, global);
4123 :
4124 5 : nl80211_register_eloop_read(&global->nl_event,
4125 : wpa_driver_nl80211_event_receive,
4126 5 : global->nl_cb);
4127 :
4128 5 : return 0;
4129 :
4130 : err:
4131 0 : nl_destroy_handles(&global->nl_event);
4132 0 : nl_destroy_handles(&global->nl);
4133 0 : nl_cb_put(global->nl_cb);
4134 0 : global->nl_cb = NULL;
4135 0 : return -1;
4136 : }
4137 :
4138 :
4139 621 : static int wpa_driver_nl80211_init_nl(struct wpa_driver_nl80211_data *drv)
4140 : {
4141 621 : drv->nl_cb = nl_cb_alloc(NL_CB_DEFAULT);
4142 621 : if (!drv->nl_cb) {
4143 0 : wpa_printf(MSG_ERROR, "nl80211: Failed to alloc cb struct");
4144 0 : return -1;
4145 : }
4146 :
4147 621 : nl_cb_set(drv->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
4148 : no_seq_check, NULL);
4149 621 : nl_cb_set(drv->nl_cb, NL_CB_VALID, NL_CB_CUSTOM,
4150 : process_drv_event, drv);
4151 :
4152 621 : return 0;
4153 : }
4154 :
4155 :
4156 0 : static void wpa_driver_nl80211_rfkill_blocked(void *ctx)
4157 : {
4158 0 : wpa_printf(MSG_DEBUG, "nl80211: RFKILL blocked");
4159 : /*
4160 : * This may be for any interface; use ifdown event to disable
4161 : * interface.
4162 : */
4163 0 : }
4164 :
4165 :
4166 0 : static void wpa_driver_nl80211_rfkill_unblocked(void *ctx)
4167 : {
4168 0 : struct wpa_driver_nl80211_data *drv = ctx;
4169 0 : wpa_printf(MSG_DEBUG, "nl80211: RFKILL unblocked");
4170 0 : if (i802_set_iface_flags(drv->first_bss, 1)) {
4171 0 : wpa_printf(MSG_DEBUG, "nl80211: Could not set interface UP "
4172 : "after rfkill unblock");
4173 0 : return;
4174 : }
4175 : /* rtnetlink ifup handler will report interface as enabled */
4176 : }
4177 :
4178 :
4179 4761 : static void wpa_driver_nl80211_handle_eapol_tx_status(int sock,
4180 : void *eloop_ctx,
4181 : void *handle)
4182 : {
4183 4761 : struct wpa_driver_nl80211_data *drv = eloop_ctx;
4184 : u8 data[2048];
4185 : struct msghdr msg;
4186 : struct iovec entry;
4187 : u8 control[512];
4188 : struct cmsghdr *cmsg;
4189 4761 : int res, found_ee = 0, found_wifi = 0, acked = 0;
4190 : union wpa_event_data event;
4191 :
4192 4761 : memset(&msg, 0, sizeof(msg));
4193 4761 : msg.msg_iov = &entry;
4194 4761 : msg.msg_iovlen = 1;
4195 4761 : entry.iov_base = data;
4196 4761 : entry.iov_len = sizeof(data);
4197 4761 : msg.msg_control = &control;
4198 4761 : msg.msg_controllen = sizeof(control);
4199 :
4200 4761 : res = recvmsg(sock, &msg, MSG_ERRQUEUE);
4201 : /* if error or not fitting 802.3 header, return */
4202 4761 : if (res < 14)
4203 0 : return;
4204 :
4205 14283 : for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg))
4206 : {
4207 14283 : if (cmsg->cmsg_level == SOL_SOCKET &&
4208 4761 : cmsg->cmsg_type == SCM_WIFI_STATUS) {
4209 : int *ack;
4210 :
4211 4761 : found_wifi = 1;
4212 4761 : ack = (void *)CMSG_DATA(cmsg);
4213 4761 : acked = *ack;
4214 : }
4215 :
4216 14283 : if (cmsg->cmsg_level == SOL_PACKET &&
4217 4761 : cmsg->cmsg_type == PACKET_TX_TIMESTAMP) {
4218 4761 : struct sock_extended_err *err =
4219 : (struct sock_extended_err *)CMSG_DATA(cmsg);
4220 :
4221 4761 : if (err->ee_origin == SO_EE_ORIGIN_TXSTATUS)
4222 4761 : found_ee = 1;
4223 : }
4224 : }
4225 :
4226 4761 : if (!found_ee || !found_wifi)
4227 0 : return;
4228 :
4229 4761 : memset(&event, 0, sizeof(event));
4230 4761 : event.eapol_tx_status.dst = data;
4231 4761 : event.eapol_tx_status.data = data + 14;
4232 4761 : event.eapol_tx_status.data_len = res - 14;
4233 4761 : event.eapol_tx_status.ack = acked;
4234 4761 : wpa_supplicant_event(drv->ctx, EVENT_EAPOL_TX_STATUS, &event);
4235 : }
4236 :
4237 :
4238 638 : static int nl80211_init_bss(struct i802_bss *bss)
4239 : {
4240 638 : bss->nl_cb = nl_cb_alloc(NL_CB_DEFAULT);
4241 638 : if (!bss->nl_cb)
4242 0 : return -1;
4243 :
4244 638 : nl_cb_set(bss->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
4245 : no_seq_check, NULL);
4246 638 : nl_cb_set(bss->nl_cb, NL_CB_VALID, NL_CB_CUSTOM,
4247 : process_bss_event, bss);
4248 :
4249 638 : return 0;
4250 : }
4251 :
4252 :
4253 638 : static void nl80211_destroy_bss(struct i802_bss *bss)
4254 : {
4255 638 : nl_cb_put(bss->nl_cb);
4256 638 : bss->nl_cb = NULL;
4257 638 : }
4258 :
4259 :
4260 621 : static void * wpa_driver_nl80211_drv_init(void *ctx, const char *ifname,
4261 : void *global_priv, int hostapd,
4262 : const u8 *set_addr)
4263 : {
4264 : struct wpa_driver_nl80211_data *drv;
4265 : struct rfkill_config *rcfg;
4266 : struct i802_bss *bss;
4267 :
4268 621 : if (global_priv == NULL)
4269 0 : return NULL;
4270 621 : drv = os_zalloc(sizeof(*drv));
4271 621 : if (drv == NULL)
4272 0 : return NULL;
4273 621 : drv->global = global_priv;
4274 621 : drv->ctx = ctx;
4275 621 : drv->hostapd = !!hostapd;
4276 621 : drv->eapol_sock = -1;
4277 621 : drv->num_if_indices = sizeof(drv->default_if_indices) / sizeof(int);
4278 621 : drv->if_indices = drv->default_if_indices;
4279 :
4280 621 : drv->first_bss = os_zalloc(sizeof(*drv->first_bss));
4281 621 : if (!drv->first_bss) {
4282 0 : os_free(drv);
4283 0 : return NULL;
4284 : }
4285 621 : bss = drv->first_bss;
4286 621 : bss->drv = drv;
4287 621 : bss->ctx = ctx;
4288 :
4289 621 : os_strlcpy(bss->ifname, ifname, sizeof(bss->ifname));
4290 621 : drv->monitor_ifidx = -1;
4291 621 : drv->monitor_sock = -1;
4292 621 : drv->eapol_tx_sock = -1;
4293 621 : drv->ap_scan_as_station = NL80211_IFTYPE_UNSPECIFIED;
4294 :
4295 621 : if (wpa_driver_nl80211_init_nl(drv)) {
4296 0 : os_free(drv);
4297 0 : return NULL;
4298 : }
4299 :
4300 621 : if (nl80211_init_bss(bss))
4301 0 : goto failed;
4302 :
4303 621 : rcfg = os_zalloc(sizeof(*rcfg));
4304 621 : if (rcfg == NULL)
4305 0 : goto failed;
4306 621 : rcfg->ctx = drv;
4307 621 : os_strlcpy(rcfg->ifname, ifname, sizeof(rcfg->ifname));
4308 621 : rcfg->blocked_cb = wpa_driver_nl80211_rfkill_blocked;
4309 621 : rcfg->unblocked_cb = wpa_driver_nl80211_rfkill_unblocked;
4310 621 : drv->rfkill = rfkill_init(rcfg);
4311 621 : if (drv->rfkill == NULL) {
4312 0 : wpa_printf(MSG_DEBUG, "nl80211: RFKILL status not available");
4313 0 : os_free(rcfg);
4314 : }
4315 :
4316 621 : if (linux_iface_up(drv->global->ioctl_sock, ifname) > 0)
4317 0 : drv->start_iface_up = 1;
4318 :
4319 621 : if (wpa_driver_nl80211_finish_drv_init(drv, set_addr, 1))
4320 2 : goto failed;
4321 :
4322 619 : drv->eapol_tx_sock = socket(PF_PACKET, SOCK_DGRAM, 0);
4323 619 : if (drv->eapol_tx_sock < 0)
4324 0 : goto failed;
4325 :
4326 619 : if (drv->data_tx_status) {
4327 619 : int enabled = 1;
4328 :
4329 619 : if (setsockopt(drv->eapol_tx_sock, SOL_SOCKET, SO_WIFI_STATUS,
4330 : &enabled, sizeof(enabled)) < 0) {
4331 0 : wpa_printf(MSG_DEBUG,
4332 : "nl80211: wifi status sockopt failed\n");
4333 0 : drv->data_tx_status = 0;
4334 0 : if (!drv->use_monitor)
4335 0 : drv->capa.flags &=
4336 : ~WPA_DRIVER_FLAGS_EAPOL_TX_STATUS;
4337 : } else {
4338 619 : eloop_register_read_sock(drv->eapol_tx_sock,
4339 : wpa_driver_nl80211_handle_eapol_tx_status,
4340 : drv, NULL);
4341 : }
4342 : }
4343 :
4344 619 : if (drv->global) {
4345 619 : dl_list_add(&drv->global->interfaces, &drv->list);
4346 619 : drv->in_interface_list = 1;
4347 : }
4348 :
4349 619 : return bss;
4350 :
4351 : failed:
4352 2 : wpa_driver_nl80211_deinit(bss);
4353 2 : return NULL;
4354 : }
4355 :
4356 :
4357 : /**
4358 : * wpa_driver_nl80211_init - Initialize nl80211 driver interface
4359 : * @ctx: context to be used when calling wpa_supplicant functions,
4360 : * e.g., wpa_supplicant_event()
4361 : * @ifname: interface name, e.g., wlan0
4362 : * @global_priv: private driver global data from global_init()
4363 : * Returns: Pointer to private data, %NULL on failure
4364 : */
4365 71 : static void * wpa_driver_nl80211_init(void *ctx, const char *ifname,
4366 : void *global_priv)
4367 : {
4368 71 : return wpa_driver_nl80211_drv_init(ctx, ifname, global_priv, 0, NULL);
4369 : }
4370 :
4371 :
4372 12823 : static int nl80211_register_frame(struct i802_bss *bss,
4373 : struct nl_handle *nl_handle,
4374 : u16 type, const u8 *match, size_t match_len)
4375 : {
4376 12823 : struct wpa_driver_nl80211_data *drv = bss->drv;
4377 : struct nl_msg *msg;
4378 12823 : int ret = -1;
4379 : char buf[30];
4380 :
4381 12823 : msg = nlmsg_alloc();
4382 12823 : if (!msg)
4383 0 : return -1;
4384 :
4385 12823 : buf[0] = '\0';
4386 12823 : wpa_snprintf_hex(buf, sizeof(buf), match, match_len);
4387 12823 : wpa_printf(MSG_DEBUG, "nl80211: Register frame type=0x%x nl_handle=%p match=%s",
4388 : type, nl_handle, buf);
4389 :
4390 12823 : nl80211_cmd(drv, msg, 0, NL80211_CMD_REGISTER_ACTION);
4391 :
4392 12823 : if (nl80211_set_iface_id(msg, bss) < 0)
4393 0 : goto nla_put_failure;
4394 :
4395 12823 : NLA_PUT_U16(msg, NL80211_ATTR_FRAME_TYPE, type);
4396 12823 : NLA_PUT(msg, NL80211_ATTR_FRAME_MATCH, match_len, match);
4397 :
4398 12823 : ret = send_and_recv(drv->global, nl_handle, msg, NULL, NULL);
4399 12823 : msg = NULL;
4400 12823 : if (ret) {
4401 1 : wpa_printf(MSG_DEBUG, "nl80211: Register frame command "
4402 : "failed (type=%u): ret=%d (%s)",
4403 : type, ret, strerror(-ret));
4404 1 : wpa_hexdump(MSG_DEBUG, "nl80211: Register frame match",
4405 : match, match_len);
4406 1 : goto nla_put_failure;
4407 : }
4408 12822 : ret = 0;
4409 : nla_put_failure:
4410 12823 : nlmsg_free(msg);
4411 12823 : return ret;
4412 : }
4413 :
4414 :
4415 1124 : static int nl80211_alloc_mgmt_handle(struct i802_bss *bss)
4416 : {
4417 1124 : struct wpa_driver_nl80211_data *drv = bss->drv;
4418 :
4419 1124 : if (bss->nl_mgmt) {
4420 0 : wpa_printf(MSG_DEBUG, "nl80211: Mgmt reporting "
4421 : "already on! (nl_mgmt=%p)", bss->nl_mgmt);
4422 0 : return -1;
4423 : }
4424 :
4425 1124 : bss->nl_mgmt = nl_create_handle(drv->nl_cb, "mgmt");
4426 1124 : if (bss->nl_mgmt == NULL)
4427 0 : return -1;
4428 :
4429 1124 : return 0;
4430 : }
4431 :
4432 :
4433 1124 : static void nl80211_mgmt_handle_register_eloop(struct i802_bss *bss)
4434 : {
4435 1124 : nl80211_register_eloop_read(&bss->nl_mgmt,
4436 : wpa_driver_nl80211_event_receive,
4437 1124 : bss->nl_cb);
4438 1124 : }
4439 :
4440 :
4441 7089 : static int nl80211_register_action_frame(struct i802_bss *bss,
4442 : const u8 *match, size_t match_len)
4443 : {
4444 7089 : u16 type = (WLAN_FC_TYPE_MGMT << 2) | (WLAN_FC_STYPE_ACTION << 4);
4445 7089 : return nl80211_register_frame(bss, bss->nl_mgmt,
4446 : type, match, match_len);
4447 : }
4448 :
4449 :
4450 417 : static int nl80211_mgmt_subscribe_non_ap(struct i802_bss *bss)
4451 : {
4452 417 : struct wpa_driver_nl80211_data *drv = bss->drv;
4453 417 : int ret = 0;
4454 :
4455 417 : if (nl80211_alloc_mgmt_handle(bss))
4456 0 : return -1;
4457 417 : wpa_printf(MSG_DEBUG, "nl80211: Subscribe to mgmt frames with non-AP "
4458 : "handle %p", bss->nl_mgmt);
4459 :
4460 417 : if (drv->nlmode == NL80211_IFTYPE_ADHOC) {
4461 17 : u16 type = (WLAN_FC_TYPE_MGMT << 2) | (WLAN_FC_STYPE_AUTH << 4);
4462 :
4463 : /* register for any AUTH message */
4464 17 : nl80211_register_frame(bss, bss->nl_mgmt, type, NULL, 0);
4465 : }
4466 :
4467 : #ifdef CONFIG_INTERWORKING
4468 : /* QoS Map Configure */
4469 417 : if (nl80211_register_action_frame(bss, (u8 *) "\x01\x04", 2) < 0)
4470 0 : ret = -1;
4471 : #endif /* CONFIG_INTERWORKING */
4472 : #if defined(CONFIG_P2P) || defined(CONFIG_INTERWORKING)
4473 : /* GAS Initial Request */
4474 417 : if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0a", 2) < 0)
4475 0 : ret = -1;
4476 : /* GAS Initial Response */
4477 417 : if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0b", 2) < 0)
4478 0 : ret = -1;
4479 : /* GAS Comeback Request */
4480 417 : if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0c", 2) < 0)
4481 0 : ret = -1;
4482 : /* GAS Comeback Response */
4483 417 : if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0d", 2) < 0)
4484 0 : ret = -1;
4485 : /* Protected GAS Initial Request */
4486 417 : if (nl80211_register_action_frame(bss, (u8 *) "\x09\x0a", 2) < 0)
4487 0 : ret = -1;
4488 : /* Protected GAS Initial Response */
4489 417 : if (nl80211_register_action_frame(bss, (u8 *) "\x09\x0b", 2) < 0)
4490 0 : ret = -1;
4491 : /* Protected GAS Comeback Request */
4492 417 : if (nl80211_register_action_frame(bss, (u8 *) "\x09\x0c", 2) < 0)
4493 0 : ret = -1;
4494 : /* Protected GAS Comeback Response */
4495 417 : if (nl80211_register_action_frame(bss, (u8 *) "\x09\x0d", 2) < 0)
4496 0 : ret = -1;
4497 : #endif /* CONFIG_P2P || CONFIG_INTERWORKING */
4498 : #ifdef CONFIG_P2P
4499 : /* P2P Public Action */
4500 417 : if (nl80211_register_action_frame(bss,
4501 : (u8 *) "\x04\x09\x50\x6f\x9a\x09",
4502 : 6) < 0)
4503 0 : ret = -1;
4504 : /* P2P Action */
4505 417 : if (nl80211_register_action_frame(bss,
4506 : (u8 *) "\x7f\x50\x6f\x9a\x09",
4507 : 5) < 0)
4508 0 : ret = -1;
4509 : #endif /* CONFIG_P2P */
4510 : #ifdef CONFIG_IEEE80211W
4511 : /* SA Query Response */
4512 417 : if (nl80211_register_action_frame(bss, (u8 *) "\x08\x01", 2) < 0)
4513 0 : ret = -1;
4514 : #endif /* CONFIG_IEEE80211W */
4515 : #ifdef CONFIG_TDLS
4516 417 : if ((drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT)) {
4517 : /* TDLS Discovery Response */
4518 417 : if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0e", 2) <
4519 : 0)
4520 0 : ret = -1;
4521 : }
4522 : #endif /* CONFIG_TDLS */
4523 :
4524 : /* FT Action frames */
4525 417 : if (nl80211_register_action_frame(bss, (u8 *) "\x06", 1) < 0)
4526 0 : ret = -1;
4527 : else
4528 417 : drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_FT |
4529 : WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK;
4530 :
4531 : /* WNM - BSS Transition Management Request */
4532 417 : if (nl80211_register_action_frame(bss, (u8 *) "\x0a\x07", 2) < 0)
4533 0 : ret = -1;
4534 : /* WNM-Sleep Mode Response */
4535 417 : if (nl80211_register_action_frame(bss, (u8 *) "\x0a\x11", 2) < 0)
4536 0 : ret = -1;
4537 :
4538 : #ifdef CONFIG_HS20
4539 : /* WNM-Notification */
4540 417 : if (nl80211_register_action_frame(bss, (u8 *) "\x0a\x1a", 2) < 0)
4541 0 : return -1;
4542 : #endif /* CONFIG_HS20 */
4543 :
4544 417 : nl80211_mgmt_handle_register_eloop(bss);
4545 :
4546 417 : return ret;
4547 : }
4548 :
4549 :
4550 707 : static int nl80211_register_spurious_class3(struct i802_bss *bss)
4551 : {
4552 707 : struct wpa_driver_nl80211_data *drv = bss->drv;
4553 : struct nl_msg *msg;
4554 707 : int ret = -1;
4555 :
4556 707 : msg = nlmsg_alloc();
4557 707 : if (!msg)
4558 0 : return -1;
4559 :
4560 707 : nl80211_cmd(drv, msg, 0, NL80211_CMD_UNEXPECTED_FRAME);
4561 :
4562 707 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex);
4563 :
4564 707 : ret = send_and_recv(drv->global, bss->nl_mgmt, msg, NULL, NULL);
4565 707 : msg = NULL;
4566 707 : if (ret) {
4567 0 : wpa_printf(MSG_DEBUG, "nl80211: Register spurious class3 "
4568 : "failed: ret=%d (%s)",
4569 : ret, strerror(-ret));
4570 0 : goto nla_put_failure;
4571 : }
4572 707 : ret = 0;
4573 : nla_put_failure:
4574 707 : nlmsg_free(msg);
4575 707 : return ret;
4576 : }
4577 :
4578 :
4579 707 : static int nl80211_mgmt_subscribe_ap(struct i802_bss *bss)
4580 : {
4581 : static const int stypes[] = {
4582 : WLAN_FC_STYPE_AUTH,
4583 : WLAN_FC_STYPE_ASSOC_REQ,
4584 : WLAN_FC_STYPE_REASSOC_REQ,
4585 : WLAN_FC_STYPE_DISASSOC,
4586 : WLAN_FC_STYPE_DEAUTH,
4587 : WLAN_FC_STYPE_ACTION,
4588 : WLAN_FC_STYPE_PROBE_REQ,
4589 : /* Beacon doesn't work as mac80211 doesn't currently allow
4590 : * it, but it wouldn't really be the right thing anyway as
4591 : * it isn't per interface ... maybe just dump the scan
4592 : * results periodically for OLBC?
4593 : */
4594 : /* WLAN_FC_STYPE_BEACON, */
4595 : };
4596 : unsigned int i;
4597 :
4598 707 : if (nl80211_alloc_mgmt_handle(bss))
4599 0 : return -1;
4600 707 : wpa_printf(MSG_DEBUG, "nl80211: Subscribe to mgmt frames with AP "
4601 : "handle %p", bss->nl_mgmt);
4602 :
4603 5656 : for (i = 0; i < ARRAY_SIZE(stypes); i++) {
4604 4949 : if (nl80211_register_frame(bss, bss->nl_mgmt,
4605 : (WLAN_FC_TYPE_MGMT << 2) |
4606 4949 : (stypes[i] << 4),
4607 : NULL, 0) < 0) {
4608 0 : goto out_err;
4609 : }
4610 : }
4611 :
4612 707 : if (nl80211_register_spurious_class3(bss))
4613 0 : goto out_err;
4614 :
4615 707 : if (nl80211_get_wiphy_data_ap(bss) == NULL)
4616 0 : goto out_err;
4617 :
4618 707 : nl80211_mgmt_handle_register_eloop(bss);
4619 707 : return 0;
4620 :
4621 : out_err:
4622 0 : nl_destroy_handles(&bss->nl_mgmt);
4623 0 : return -1;
4624 : }
4625 :
4626 :
4627 0 : static int nl80211_mgmt_subscribe_ap_dev_sme(struct i802_bss *bss)
4628 : {
4629 0 : if (nl80211_alloc_mgmt_handle(bss))
4630 0 : return -1;
4631 0 : wpa_printf(MSG_DEBUG, "nl80211: Subscribe to mgmt frames with AP "
4632 : "handle %p (device SME)", bss->nl_mgmt);
4633 :
4634 0 : if (nl80211_register_frame(bss, bss->nl_mgmt,
4635 : (WLAN_FC_TYPE_MGMT << 2) |
4636 : (WLAN_FC_STYPE_ACTION << 4),
4637 : NULL, 0) < 0)
4638 0 : goto out_err;
4639 :
4640 0 : nl80211_mgmt_handle_register_eloop(bss);
4641 0 : return 0;
4642 :
4643 : out_err:
4644 0 : nl_destroy_handles(&bss->nl_mgmt);
4645 0 : return -1;
4646 : }
4647 :
4648 :
4649 2364 : static void nl80211_mgmt_unsubscribe(struct i802_bss *bss, const char *reason)
4650 : {
4651 2364 : if (bss->nl_mgmt == NULL)
4652 3604 : return;
4653 1124 : wpa_printf(MSG_DEBUG, "nl80211: Unsubscribe mgmt frames handle %p "
4654 : "(%s)", bss->nl_mgmt, reason);
4655 1124 : nl80211_destroy_eloop_handle(&bss->nl_mgmt);
4656 :
4657 1124 : nl80211_put_wiphy_data_ap(bss);
4658 : }
4659 :
4660 :
4661 0 : static void wpa_driver_nl80211_send_rfkill(void *eloop_ctx, void *timeout_ctx)
4662 : {
4663 0 : wpa_supplicant_event(timeout_ctx, EVENT_INTERFACE_DISABLED, NULL);
4664 0 : }
4665 :
4666 :
4667 0 : static void nl80211_del_p2pdev(struct i802_bss *bss)
4668 : {
4669 0 : struct wpa_driver_nl80211_data *drv = bss->drv;
4670 : struct nl_msg *msg;
4671 : int ret;
4672 :
4673 0 : msg = nlmsg_alloc();
4674 0 : if (!msg)
4675 0 : return;
4676 :
4677 0 : nl80211_cmd(drv, msg, 0, NL80211_CMD_DEL_INTERFACE);
4678 0 : NLA_PUT_U64(msg, NL80211_ATTR_WDEV, bss->wdev_id);
4679 :
4680 0 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
4681 0 : msg = NULL;
4682 :
4683 0 : wpa_printf(MSG_DEBUG, "nl80211: Delete P2P Device %s (0x%llx): %s",
4684 0 : bss->ifname, (long long unsigned int) bss->wdev_id,
4685 : strerror(-ret));
4686 :
4687 : nla_put_failure:
4688 0 : nlmsg_free(msg);
4689 : }
4690 :
4691 :
4692 0 : static int nl80211_set_p2pdev(struct i802_bss *bss, int start)
4693 : {
4694 0 : struct wpa_driver_nl80211_data *drv = bss->drv;
4695 : struct nl_msg *msg;
4696 0 : int ret = -1;
4697 :
4698 0 : msg = nlmsg_alloc();
4699 0 : if (!msg)
4700 0 : return -1;
4701 :
4702 0 : if (start)
4703 0 : nl80211_cmd(drv, msg, 0, NL80211_CMD_START_P2P_DEVICE);
4704 : else
4705 0 : nl80211_cmd(drv, msg, 0, NL80211_CMD_STOP_P2P_DEVICE);
4706 :
4707 0 : NLA_PUT_U64(msg, NL80211_ATTR_WDEV, bss->wdev_id);
4708 :
4709 0 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
4710 0 : msg = NULL;
4711 :
4712 0 : wpa_printf(MSG_DEBUG, "nl80211: %s P2P Device %s (0x%llx): %s",
4713 : start ? "Start" : "Stop",
4714 0 : bss->ifname, (long long unsigned int) bss->wdev_id,
4715 : strerror(-ret));
4716 :
4717 : nla_put_failure:
4718 0 : nlmsg_free(msg);
4719 0 : return ret;
4720 : }
4721 :
4722 :
4723 1242 : static int i802_set_iface_flags(struct i802_bss *bss, int up)
4724 : {
4725 : enum nl80211_iftype nlmode;
4726 :
4727 1242 : nlmode = nl80211_get_ifmode(bss);
4728 1242 : if (nlmode != NL80211_IFTYPE_P2P_DEVICE) {
4729 1242 : return linux_set_iface_flags(bss->drv->global->ioctl_sock,
4730 1242 : bss->ifname, up);
4731 : }
4732 :
4733 : /* P2P Device has start/stop which is equivalent */
4734 0 : return nl80211_set_p2pdev(bss, up);
4735 : }
4736 :
4737 :
4738 : static int
4739 621 : wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv,
4740 : const u8 *set_addr, int first)
4741 : {
4742 621 : struct i802_bss *bss = drv->first_bss;
4743 621 : int send_rfkill_event = 0;
4744 : enum nl80211_iftype nlmode;
4745 :
4746 621 : drv->ifindex = if_nametoindex(bss->ifname);
4747 621 : bss->ifindex = drv->ifindex;
4748 621 : bss->wdev_id = drv->global->if_add_wdevid;
4749 621 : bss->wdev_id_set = drv->global->if_add_wdevid_set;
4750 :
4751 621 : bss->if_dynamic = drv->ifindex == drv->global->if_add_ifindex;
4752 621 : bss->if_dynamic = bss->if_dynamic || drv->global->if_add_wdevid_set;
4753 621 : drv->global->if_add_wdevid_set = 0;
4754 :
4755 621 : if (wpa_driver_nl80211_capa(drv))
4756 2 : return -1;
4757 :
4758 619 : wpa_printf(MSG_DEBUG, "nl80211: interface %s in phy %s",
4759 619 : bss->ifname, drv->phyname);
4760 :
4761 625 : if (set_addr &&
4762 12 : (linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 0) ||
4763 6 : linux_set_ifhwaddr(drv->global->ioctl_sock, bss->ifname,
4764 : set_addr)))
4765 0 : return -1;
4766 :
4767 619 : if (first && nl80211_get_ifmode(bss) == NL80211_IFTYPE_AP)
4768 0 : drv->start_mode_ap = 1;
4769 :
4770 619 : if (drv->hostapd)
4771 550 : nlmode = NL80211_IFTYPE_AP;
4772 69 : else if (bss->if_dynamic)
4773 35 : nlmode = nl80211_get_ifmode(bss);
4774 : else
4775 34 : nlmode = NL80211_IFTYPE_STATION;
4776 :
4777 619 : if (wpa_driver_nl80211_set_mode(bss, nlmode) < 0) {
4778 0 : wpa_printf(MSG_ERROR, "nl80211: Could not configure driver mode");
4779 0 : return -1;
4780 : }
4781 :
4782 619 : if (nlmode == NL80211_IFTYPE_P2P_DEVICE)
4783 0 : nl80211_get_macaddr(bss);
4784 :
4785 619 : if (!rfkill_is_blocked(drv->rfkill)) {
4786 619 : int ret = i802_set_iface_flags(bss, 1);
4787 619 : if (ret) {
4788 0 : wpa_printf(MSG_ERROR, "nl80211: Could not set "
4789 0 : "interface '%s' UP", bss->ifname);
4790 0 : return ret;
4791 : }
4792 619 : if (nlmode == NL80211_IFTYPE_P2P_DEVICE)
4793 0 : return ret;
4794 : } else {
4795 0 : wpa_printf(MSG_DEBUG, "nl80211: Could not yet enable "
4796 0 : "interface '%s' due to rfkill", bss->ifname);
4797 0 : if (nlmode == NL80211_IFTYPE_P2P_DEVICE)
4798 0 : return 0;
4799 0 : drv->if_disabled = 1;
4800 0 : send_rfkill_event = 1;
4801 : }
4802 :
4803 619 : if (!drv->hostapd)
4804 69 : netlink_send_oper_ifla(drv->global->netlink, drv->ifindex,
4805 : 1, IF_OPER_DORMANT);
4806 :
4807 619 : if (linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname,
4808 619 : bss->addr))
4809 0 : return -1;
4810 :
4811 619 : if (send_rfkill_event) {
4812 0 : eloop_register_timeout(0, 0, wpa_driver_nl80211_send_rfkill,
4813 : drv, drv->ctx);
4814 : }
4815 :
4816 619 : return 0;
4817 : }
4818 :
4819 :
4820 692 : static int wpa_driver_nl80211_del_beacon(struct wpa_driver_nl80211_data *drv)
4821 : {
4822 : struct nl_msg *msg;
4823 :
4824 692 : msg = nlmsg_alloc();
4825 692 : if (!msg)
4826 0 : return -ENOMEM;
4827 :
4828 692 : wpa_printf(MSG_DEBUG, "nl80211: Remove beacon (ifindex=%d)",
4829 : drv->ifindex);
4830 692 : nl80211_cmd(drv, msg, 0, NL80211_CMD_DEL_BEACON);
4831 692 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
4832 :
4833 692 : return send_and_recv_msgs(drv, msg, NULL, NULL);
4834 : nla_put_failure:
4835 0 : nlmsg_free(msg);
4836 0 : return -ENOBUFS;
4837 : }
4838 :
4839 :
4840 : /**
4841 : * wpa_driver_nl80211_deinit - Deinitialize nl80211 driver interface
4842 : * @bss: Pointer to private nl80211 data from wpa_driver_nl80211_init()
4843 : *
4844 : * Shut down driver interface and processing of driver events. Free
4845 : * private data buffer if one was allocated in wpa_driver_nl80211_init().
4846 : */
4847 621 : static void wpa_driver_nl80211_deinit(struct i802_bss *bss)
4848 : {
4849 621 : struct wpa_driver_nl80211_data *drv = bss->drv;
4850 :
4851 621 : bss->in_deinit = 1;
4852 621 : if (drv->data_tx_status)
4853 619 : eloop_unregister_read_sock(drv->eapol_tx_sock);
4854 621 : if (drv->eapol_tx_sock >= 0)
4855 619 : close(drv->eapol_tx_sock);
4856 :
4857 621 : if (bss->nl_preq)
4858 0 : wpa_driver_nl80211_probe_req_report(bss, 0);
4859 621 : if (bss->added_if_into_bridge) {
4860 4 : if (linux_br_del_if(drv->global->ioctl_sock, bss->brname,
4861 4 : bss->ifname) < 0)
4862 8 : wpa_printf(MSG_INFO, "nl80211: Failed to remove "
4863 : "interface %s from bridge %s: %s",
4864 8 : bss->ifname, bss->brname, strerror(errno));
4865 : }
4866 621 : if (bss->added_bridge) {
4867 2 : if (linux_br_del(drv->global->ioctl_sock, bss->brname) < 0)
4868 4 : wpa_printf(MSG_INFO, "nl80211: Failed to remove "
4869 : "bridge %s: %s",
4870 4 : bss->brname, strerror(errno));
4871 : }
4872 :
4873 621 : nl80211_remove_monitor_interface(drv);
4874 :
4875 621 : if (is_ap_interface(drv->nlmode))
4876 566 : wpa_driver_nl80211_del_beacon(drv);
4877 :
4878 621 : if (drv->eapol_sock >= 0) {
4879 550 : eloop_unregister_read_sock(drv->eapol_sock);
4880 550 : close(drv->eapol_sock);
4881 : }
4882 :
4883 621 : if (drv->if_indices != drv->default_if_indices)
4884 0 : os_free(drv->if_indices);
4885 :
4886 621 : if (drv->disabled_11b_rates)
4887 17 : nl80211_disable_11b_rates(drv, drv->ifindex, 0);
4888 :
4889 621 : netlink_send_oper_ifla(drv->global->netlink, drv->ifindex, 0,
4890 : IF_OPER_UP);
4891 621 : eloop_cancel_timeout(wpa_driver_nl80211_send_rfkill, drv, drv->ctx);
4892 621 : rfkill_deinit(drv->rfkill);
4893 :
4894 621 : eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);
4895 :
4896 621 : if (!drv->start_iface_up)
4897 621 : (void) i802_set_iface_flags(bss, 0);
4898 621 : if (drv->nlmode != NL80211_IFTYPE_P2P_DEVICE) {
4899 621 : if (!drv->hostapd || !drv->start_mode_ap)
4900 621 : wpa_driver_nl80211_set_mode(bss,
4901 : NL80211_IFTYPE_STATION);
4902 621 : nl80211_mgmt_unsubscribe(bss, "deinit");
4903 : } else {
4904 0 : nl80211_mgmt_unsubscribe(bss, "deinit");
4905 0 : nl80211_del_p2pdev(bss);
4906 : }
4907 621 : nl_cb_put(drv->nl_cb);
4908 :
4909 621 : nl80211_destroy_bss(drv->first_bss);
4910 :
4911 621 : os_free(drv->filter_ssids);
4912 :
4913 621 : os_free(drv->auth_ie);
4914 :
4915 621 : if (drv->in_interface_list)
4916 619 : dl_list_del(&drv->list);
4917 :
4918 621 : os_free(drv->extended_capa);
4919 621 : os_free(drv->extended_capa_mask);
4920 621 : os_free(drv->first_bss);
4921 621 : os_free(drv);
4922 621 : }
4923 :
4924 :
4925 : /**
4926 : * wpa_driver_nl80211_scan_timeout - Scan timeout to report scan completion
4927 : * @eloop_ctx: Driver private data
4928 : * @timeout_ctx: ctx argument given to wpa_driver_nl80211_init()
4929 : *
4930 : * This function can be used as registered timeout when starting a scan to
4931 : * generate a scan completed event if the driver does not report this.
4932 : */
4933 0 : static void wpa_driver_nl80211_scan_timeout(void *eloop_ctx, void *timeout_ctx)
4934 : {
4935 0 : struct wpa_driver_nl80211_data *drv = eloop_ctx;
4936 0 : if (drv->ap_scan_as_station != NL80211_IFTYPE_UNSPECIFIED) {
4937 0 : wpa_driver_nl80211_set_mode(drv->first_bss,
4938 : drv->ap_scan_as_station);
4939 0 : drv->ap_scan_as_station = NL80211_IFTYPE_UNSPECIFIED;
4940 : }
4941 0 : wpa_printf(MSG_DEBUG, "Scan timeout - try to get results");
4942 0 : wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL);
4943 0 : }
4944 :
4945 :
4946 : static struct nl_msg *
4947 1913 : nl80211_scan_common(struct wpa_driver_nl80211_data *drv, u8 cmd,
4948 : struct wpa_driver_scan_params *params, u64 *wdev_id)
4949 : {
4950 : struct nl_msg *msg;
4951 : size_t i;
4952 :
4953 1913 : msg = nlmsg_alloc();
4954 1913 : if (!msg)
4955 0 : return NULL;
4956 :
4957 1913 : nl80211_cmd(drv, msg, 0, cmd);
4958 :
4959 1913 : if (!wdev_id)
4960 1913 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
4961 : else
4962 0 : NLA_PUT_U64(msg, NL80211_ATTR_WDEV, *wdev_id);
4963 :
4964 1913 : if (params->num_ssids) {
4965 : struct nlattr *ssids;
4966 :
4967 1836 : ssids = nla_nest_start(msg, NL80211_ATTR_SCAN_SSIDS);
4968 1836 : if (ssids == NULL)
4969 0 : goto fail;
4970 3676 : for (i = 0; i < params->num_ssids; i++) {
4971 3680 : wpa_hexdump_ascii(MSG_MSGDUMP, "nl80211: Scan SSID",
4972 1840 : params->ssids[i].ssid,
4973 : params->ssids[i].ssid_len);
4974 1840 : if (nla_put(msg, i + 1, params->ssids[i].ssid_len,
4975 1840 : params->ssids[i].ssid) < 0)
4976 0 : goto fail;
4977 : }
4978 1836 : nla_nest_end(msg, ssids);
4979 : }
4980 :
4981 1913 : if (params->extra_ies) {
4982 3672 : wpa_hexdump(MSG_MSGDUMP, "nl80211: Scan extra IEs",
4983 1836 : params->extra_ies, params->extra_ies_len);
4984 1836 : if (nla_put(msg, NL80211_ATTR_IE, params->extra_ies_len,
4985 1836 : params->extra_ies) < 0)
4986 0 : goto fail;
4987 : }
4988 :
4989 1913 : if (params->freqs) {
4990 : struct nlattr *freqs;
4991 1674 : freqs = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES);
4992 1674 : if (freqs == NULL)
4993 0 : goto fail;
4994 5147 : for (i = 0; params->freqs[i]; i++) {
4995 3473 : wpa_printf(MSG_MSGDUMP, "nl80211: Scan frequency %u "
4996 3473 : "MHz", params->freqs[i]);
4997 3473 : if (nla_put_u32(msg, i + 1, params->freqs[i]) < 0)
4998 0 : goto fail;
4999 : }
5000 1674 : nla_nest_end(msg, freqs);
5001 : }
5002 :
5003 1913 : os_free(drv->filter_ssids);
5004 1913 : drv->filter_ssids = params->filter_ssids;
5005 1913 : params->filter_ssids = NULL;
5006 1913 : drv->num_filter_ssids = params->num_filter_ssids;
5007 :
5008 1913 : if (params->only_new_results) {
5009 738 : wpa_printf(MSG_DEBUG, "nl80211: Add NL80211_SCAN_FLAG_FLUSH");
5010 738 : NLA_PUT_U32(msg, NL80211_ATTR_SCAN_FLAGS,
5011 : NL80211_SCAN_FLAG_FLUSH);
5012 : }
5013 :
5014 1913 : return msg;
5015 :
5016 : fail:
5017 : nla_put_failure:
5018 0 : nlmsg_free(msg);
5019 0 : return NULL;
5020 : }
5021 :
5022 :
5023 : /**
5024 : * wpa_driver_nl80211_scan - Request the driver to initiate scan
5025 : * @bss: Pointer to private driver data from wpa_driver_nl80211_init()
5026 : * @params: Scan parameters
5027 : * Returns: 0 on success, -1 on failure
5028 : */
5029 1913 : static int wpa_driver_nl80211_scan(struct i802_bss *bss,
5030 : struct wpa_driver_scan_params *params)
5031 : {
5032 1913 : struct wpa_driver_nl80211_data *drv = bss->drv;
5033 1913 : int ret = -1, timeout;
5034 1913 : struct nl_msg *msg = NULL;
5035 :
5036 1913 : wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: scan request");
5037 1913 : drv->scan_for_auth = 0;
5038 :
5039 1913 : msg = nl80211_scan_common(drv, NL80211_CMD_TRIGGER_SCAN, params,
5040 1913 : bss->wdev_id_set ? &bss->wdev_id : NULL);
5041 1913 : if (!msg)
5042 0 : return -1;
5043 :
5044 1913 : if (params->p2p_probe) {
5045 : struct nlattr *rates;
5046 :
5047 816 : wpa_printf(MSG_DEBUG, "nl80211: P2P probe - mask SuppRates");
5048 :
5049 816 : rates = nla_nest_start(msg, NL80211_ATTR_SCAN_SUPP_RATES);
5050 816 : if (rates == NULL)
5051 0 : goto nla_put_failure;
5052 :
5053 : /*
5054 : * Remove 2.4 GHz rates 1, 2, 5.5, 11 Mbps from supported rates
5055 : * by masking out everything else apart from the OFDM rates 6,
5056 : * 9, 12, 18, 24, 36, 48, 54 Mbps from non-MCS rates. All 5 GHz
5057 : * rates are left enabled.
5058 : */
5059 816 : NLA_PUT(msg, NL80211_BAND_2GHZ, 8,
5060 : "\x0c\x12\x18\x24\x30\x48\x60\x6c");
5061 816 : nla_nest_end(msg, rates);
5062 :
5063 816 : NLA_PUT_FLAG(msg, NL80211_ATTR_TX_NO_CCK_RATE);
5064 : }
5065 :
5066 1913 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5067 1913 : msg = NULL;
5068 1913 : if (ret) {
5069 5 : wpa_printf(MSG_DEBUG, "nl80211: Scan trigger failed: ret=%d "
5070 : "(%s)", ret, strerror(-ret));
5071 5 : if (drv->hostapd && is_ap_interface(drv->nlmode)) {
5072 0 : enum nl80211_iftype old_mode = drv->nlmode;
5073 :
5074 : /*
5075 : * mac80211 does not allow scan requests in AP mode, so
5076 : * try to do this in station mode.
5077 : */
5078 0 : if (wpa_driver_nl80211_set_mode(
5079 : bss, NL80211_IFTYPE_STATION))
5080 0 : goto nla_put_failure;
5081 :
5082 0 : if (wpa_driver_nl80211_scan(bss, params)) {
5083 0 : wpa_driver_nl80211_set_mode(bss, drv->nlmode);
5084 0 : goto nla_put_failure;
5085 : }
5086 :
5087 : /* Restore AP mode when processing scan results */
5088 0 : drv->ap_scan_as_station = old_mode;
5089 0 : ret = 0;
5090 : } else
5091 : goto nla_put_failure;
5092 : }
5093 :
5094 1908 : drv->scan_state = SCAN_REQUESTED;
5095 : /* Not all drivers generate "scan completed" wireless event, so try to
5096 : * read results after a timeout. */
5097 1908 : timeout = 10;
5098 1908 : if (drv->scan_complete_events) {
5099 : /*
5100 : * The driver seems to deliver events to notify when scan is
5101 : * complete, so use longer timeout to avoid race conditions
5102 : * with scanning and following association request.
5103 : */
5104 1831 : timeout = 30;
5105 : }
5106 1908 : wpa_printf(MSG_DEBUG, "Scan requested (ret=%d) - scan timeout %d "
5107 : "seconds", ret, timeout);
5108 1908 : eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);
5109 1908 : eloop_register_timeout(timeout, 0, wpa_driver_nl80211_scan_timeout,
5110 : drv, drv->ctx);
5111 :
5112 : nla_put_failure:
5113 1913 : nlmsg_free(msg);
5114 1913 : return ret;
5115 : }
5116 :
5117 :
5118 : /**
5119 : * wpa_driver_nl80211_sched_scan - Initiate a scheduled scan
5120 : * @priv: Pointer to private driver data from wpa_driver_nl80211_init()
5121 : * @params: Scan parameters
5122 : * @interval: Interval between scan cycles in milliseconds
5123 : * Returns: 0 on success, -1 on failure or if not supported
5124 : */
5125 0 : static int wpa_driver_nl80211_sched_scan(void *priv,
5126 : struct wpa_driver_scan_params *params,
5127 : u32 interval)
5128 : {
5129 0 : struct i802_bss *bss = priv;
5130 0 : struct wpa_driver_nl80211_data *drv = bss->drv;
5131 0 : int ret = -1;
5132 : struct nl_msg *msg;
5133 : size_t i;
5134 :
5135 0 : wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: sched_scan request");
5136 :
5137 : #ifdef ANDROID
5138 : if (!drv->capa.sched_scan_supported)
5139 : return android_pno_start(bss, params);
5140 : #endif /* ANDROID */
5141 :
5142 0 : msg = nl80211_scan_common(drv, NL80211_CMD_START_SCHED_SCAN, params,
5143 0 : bss->wdev_id_set ? &bss->wdev_id : NULL);
5144 0 : if (!msg)
5145 0 : goto nla_put_failure;
5146 :
5147 0 : NLA_PUT_U32(msg, NL80211_ATTR_SCHED_SCAN_INTERVAL, interval);
5148 :
5149 0 : if ((drv->num_filter_ssids &&
5150 0 : (int) drv->num_filter_ssids <= drv->capa.max_match_sets) ||
5151 0 : params->filter_rssi) {
5152 : struct nlattr *match_sets;
5153 0 : match_sets = nla_nest_start(msg, NL80211_ATTR_SCHED_SCAN_MATCH);
5154 0 : if (match_sets == NULL)
5155 0 : goto nla_put_failure;
5156 :
5157 0 : for (i = 0; i < drv->num_filter_ssids; i++) {
5158 : struct nlattr *match_set_ssid;
5159 0 : wpa_hexdump_ascii(MSG_MSGDUMP,
5160 : "nl80211: Sched scan filter SSID",
5161 0 : drv->filter_ssids[i].ssid,
5162 0 : drv->filter_ssids[i].ssid_len);
5163 :
5164 0 : match_set_ssid = nla_nest_start(msg, i + 1);
5165 0 : if (match_set_ssid == NULL)
5166 0 : goto nla_put_failure;
5167 0 : NLA_PUT(msg, NL80211_ATTR_SCHED_SCAN_MATCH_SSID,
5168 : drv->filter_ssids[i].ssid_len,
5169 : drv->filter_ssids[i].ssid);
5170 0 : if (params->filter_rssi)
5171 0 : NLA_PUT_U32(msg,
5172 : NL80211_SCHED_SCAN_MATCH_ATTR_RSSI,
5173 : params->filter_rssi);
5174 :
5175 0 : nla_nest_end(msg, match_set_ssid);
5176 : }
5177 :
5178 : /*
5179 : * Due to backward compatibility code, newer kernels treat this
5180 : * matchset (with only an RSSI filter) as the default for all
5181 : * other matchsets, unless it's the only one, in which case the
5182 : * matchset will actually allow all SSIDs above the RSSI.
5183 : */
5184 0 : if (params->filter_rssi) {
5185 : struct nlattr *match_set_rssi;
5186 0 : match_set_rssi = nla_nest_start(msg, 0);
5187 0 : if (match_set_rssi == NULL)
5188 0 : goto nla_put_failure;
5189 0 : NLA_PUT_U32(msg, NL80211_SCHED_SCAN_MATCH_ATTR_RSSI,
5190 : params->filter_rssi);
5191 0 : wpa_printf(MSG_MSGDUMP,
5192 : "nl80211: Sched scan RSSI filter %d dBm",
5193 : params->filter_rssi);
5194 0 : nla_nest_end(msg, match_set_rssi);
5195 : }
5196 :
5197 0 : nla_nest_end(msg, match_sets);
5198 : }
5199 :
5200 0 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5201 :
5202 : /* TODO: if we get an error here, we should fall back to normal scan */
5203 :
5204 0 : msg = NULL;
5205 0 : if (ret) {
5206 0 : wpa_printf(MSG_DEBUG, "nl80211: Sched scan start failed: "
5207 : "ret=%d (%s)", ret, strerror(-ret));
5208 0 : goto nla_put_failure;
5209 : }
5210 :
5211 0 : wpa_printf(MSG_DEBUG, "nl80211: Sched scan requested (ret=%d) - "
5212 : "scan interval %d msec", ret, interval);
5213 :
5214 : nla_put_failure:
5215 0 : nlmsg_free(msg);
5216 0 : return ret;
5217 : }
5218 :
5219 :
5220 : /**
5221 : * wpa_driver_nl80211_stop_sched_scan - Stop a scheduled scan
5222 : * @priv: Pointer to private driver data from wpa_driver_nl80211_init()
5223 : * Returns: 0 on success, -1 on failure or if not supported
5224 : */
5225 0 : static int wpa_driver_nl80211_stop_sched_scan(void *priv)
5226 : {
5227 0 : struct i802_bss *bss = priv;
5228 0 : struct wpa_driver_nl80211_data *drv = bss->drv;
5229 0 : int ret = 0;
5230 : struct nl_msg *msg;
5231 :
5232 : #ifdef ANDROID
5233 : if (!drv->capa.sched_scan_supported)
5234 : return android_pno_stop(bss);
5235 : #endif /* ANDROID */
5236 :
5237 0 : msg = nlmsg_alloc();
5238 0 : if (!msg)
5239 0 : return -1;
5240 :
5241 0 : nl80211_cmd(drv, msg, 0, NL80211_CMD_STOP_SCHED_SCAN);
5242 :
5243 0 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
5244 :
5245 0 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5246 0 : msg = NULL;
5247 0 : if (ret) {
5248 0 : wpa_printf(MSG_DEBUG, "nl80211: Sched scan stop failed: "
5249 : "ret=%d (%s)", ret, strerror(-ret));
5250 0 : goto nla_put_failure;
5251 : }
5252 :
5253 0 : wpa_printf(MSG_DEBUG, "nl80211: Sched scan stop sent (ret=%d)", ret);
5254 :
5255 : nla_put_failure:
5256 0 : nlmsg_free(msg);
5257 0 : return ret;
5258 : }
5259 :
5260 :
5261 798 : static const u8 * nl80211_get_ie(const u8 *ies, size_t ies_len, u8 ie)
5262 : {
5263 : const u8 *end, *pos;
5264 :
5265 798 : if (ies == NULL)
5266 0 : return NULL;
5267 :
5268 798 : pos = ies;
5269 798 : end = ies + ies_len;
5270 :
5271 1596 : while (pos + 1 < end) {
5272 798 : if (pos + 2 + pos[1] > end)
5273 0 : break;
5274 798 : if (pos[0] == ie)
5275 798 : return pos;
5276 0 : pos += 2 + pos[1];
5277 : }
5278 :
5279 0 : return NULL;
5280 : }
5281 :
5282 :
5283 2792 : static int nl80211_scan_filtered(struct wpa_driver_nl80211_data *drv,
5284 : const u8 *ie, size_t ie_len)
5285 : {
5286 : const u8 *ssid;
5287 : size_t i;
5288 :
5289 2792 : if (drv->filter_ssids == NULL)
5290 2790 : return 0;
5291 :
5292 2 : ssid = nl80211_get_ie(ie, ie_len, WLAN_EID_SSID);
5293 2 : if (ssid == NULL)
5294 0 : return 1;
5295 :
5296 3 : for (i = 0; i < drv->num_filter_ssids; i++) {
5297 3 : if (ssid[1] == drv->filter_ssids[i].ssid_len &&
5298 1 : os_memcmp(ssid + 2, drv->filter_ssids[i].ssid, ssid[1]) ==
5299 : 0)
5300 1 : return 0;
5301 : }
5302 :
5303 1 : return 1;
5304 : }
5305 :
5306 :
5307 2864 : static int bss_info_handler(struct nl_msg *msg, void *arg)
5308 : {
5309 : struct nlattr *tb[NL80211_ATTR_MAX + 1];
5310 2864 : struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
5311 : struct nlattr *bss[NL80211_BSS_MAX + 1];
5312 : static struct nla_policy bss_policy[NL80211_BSS_MAX + 1] = {
5313 : [NL80211_BSS_BSSID] = { .type = NLA_UNSPEC },
5314 : [NL80211_BSS_FREQUENCY] = { .type = NLA_U32 },
5315 : [NL80211_BSS_TSF] = { .type = NLA_U64 },
5316 : [NL80211_BSS_BEACON_INTERVAL] = { .type = NLA_U16 },
5317 : [NL80211_BSS_CAPABILITY] = { .type = NLA_U16 },
5318 : [NL80211_BSS_INFORMATION_ELEMENTS] = { .type = NLA_UNSPEC },
5319 : [NL80211_BSS_SIGNAL_MBM] = { .type = NLA_U32 },
5320 : [NL80211_BSS_SIGNAL_UNSPEC] = { .type = NLA_U8 },
5321 : [NL80211_BSS_STATUS] = { .type = NLA_U32 },
5322 : [NL80211_BSS_SEEN_MS_AGO] = { .type = NLA_U32 },
5323 : [NL80211_BSS_BEACON_IES] = { .type = NLA_UNSPEC },
5324 : };
5325 2864 : struct nl80211_bss_info_arg *_arg = arg;
5326 2864 : struct wpa_scan_results *res = _arg->res;
5327 : struct wpa_scan_res **tmp;
5328 : struct wpa_scan_res *r;
5329 : const u8 *ie, *beacon_ie;
5330 : size_t ie_len, beacon_ie_len;
5331 : u8 *pos;
5332 : size_t i;
5333 :
5334 2864 : nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
5335 : genlmsg_attrlen(gnlh, 0), NULL);
5336 2864 : if (!tb[NL80211_ATTR_BSS])
5337 0 : return NL_SKIP;
5338 2864 : if (nla_parse_nested(bss, NL80211_BSS_MAX, tb[NL80211_ATTR_BSS],
5339 : bss_policy))
5340 0 : return NL_SKIP;
5341 2864 : if (bss[NL80211_BSS_STATUS]) {
5342 : enum nl80211_bss_status status;
5343 124 : status = nla_get_u32(bss[NL80211_BSS_STATUS]);
5344 207 : if (status == NL80211_BSS_STATUS_ASSOCIATED &&
5345 83 : bss[NL80211_BSS_FREQUENCY]) {
5346 83 : _arg->assoc_freq =
5347 83 : nla_get_u32(bss[NL80211_BSS_FREQUENCY]);
5348 83 : wpa_printf(MSG_DEBUG, "nl80211: Associated on %u MHz",
5349 : _arg->assoc_freq);
5350 : }
5351 165 : if (status == NL80211_BSS_STATUS_IBSS_JOINED &&
5352 41 : bss[NL80211_BSS_FREQUENCY]) {
5353 41 : _arg->ibss_freq =
5354 41 : nla_get_u32(bss[NL80211_BSS_FREQUENCY]);
5355 41 : wpa_printf(MSG_DEBUG, "nl80211: IBSS-joined on %u MHz",
5356 : _arg->ibss_freq);
5357 : }
5358 207 : if (status == NL80211_BSS_STATUS_ASSOCIATED &&
5359 83 : bss[NL80211_BSS_BSSID]) {
5360 83 : os_memcpy(_arg->assoc_bssid,
5361 : nla_data(bss[NL80211_BSS_BSSID]), ETH_ALEN);
5362 498 : wpa_printf(MSG_DEBUG, "nl80211: Associated with "
5363 498 : MACSTR, MAC2STR(_arg->assoc_bssid));
5364 : }
5365 : }
5366 2864 : if (!res)
5367 72 : return NL_SKIP;
5368 2792 : if (bss[NL80211_BSS_INFORMATION_ELEMENTS]) {
5369 2792 : ie = nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS]);
5370 2792 : ie_len = nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]);
5371 : } else {
5372 0 : ie = NULL;
5373 0 : ie_len = 0;
5374 : }
5375 2792 : if (bss[NL80211_BSS_BEACON_IES]) {
5376 1747 : beacon_ie = nla_data(bss[NL80211_BSS_BEACON_IES]);
5377 1747 : beacon_ie_len = nla_len(bss[NL80211_BSS_BEACON_IES]);
5378 : } else {
5379 1045 : beacon_ie = NULL;
5380 1045 : beacon_ie_len = 0;
5381 : }
5382 :
5383 2792 : if (nl80211_scan_filtered(_arg->drv, ie ? ie : beacon_ie,
5384 : ie ? ie_len : beacon_ie_len))
5385 1 : return NL_SKIP;
5386 :
5387 2791 : r = os_zalloc(sizeof(*r) + ie_len + beacon_ie_len);
5388 2791 : if (r == NULL)
5389 0 : return NL_SKIP;
5390 2791 : if (bss[NL80211_BSS_BSSID])
5391 2791 : os_memcpy(r->bssid, nla_data(bss[NL80211_BSS_BSSID]),
5392 : ETH_ALEN);
5393 2791 : if (bss[NL80211_BSS_FREQUENCY])
5394 2791 : r->freq = nla_get_u32(bss[NL80211_BSS_FREQUENCY]);
5395 2791 : if (bss[NL80211_BSS_BEACON_INTERVAL])
5396 2791 : r->beacon_int = nla_get_u16(bss[NL80211_BSS_BEACON_INTERVAL]);
5397 2791 : if (bss[NL80211_BSS_CAPABILITY])
5398 2791 : r->caps = nla_get_u16(bss[NL80211_BSS_CAPABILITY]);
5399 2791 : r->flags |= WPA_SCAN_NOISE_INVALID;
5400 2791 : if (bss[NL80211_BSS_SIGNAL_MBM]) {
5401 2791 : r->level = nla_get_u32(bss[NL80211_BSS_SIGNAL_MBM]);
5402 2791 : r->level /= 100; /* mBm to dBm */
5403 2791 : r->flags |= WPA_SCAN_LEVEL_DBM | WPA_SCAN_QUAL_INVALID;
5404 0 : } else if (bss[NL80211_BSS_SIGNAL_UNSPEC]) {
5405 0 : r->level = nla_get_u8(bss[NL80211_BSS_SIGNAL_UNSPEC]);
5406 0 : r->flags |= WPA_SCAN_QUAL_INVALID;
5407 : } else
5408 0 : r->flags |= WPA_SCAN_LEVEL_INVALID | WPA_SCAN_QUAL_INVALID;
5409 2791 : if (bss[NL80211_BSS_TSF])
5410 2791 : r->tsf = nla_get_u64(bss[NL80211_BSS_TSF]);
5411 2791 : if (bss[NL80211_BSS_SEEN_MS_AGO])
5412 2791 : r->age = nla_get_u32(bss[NL80211_BSS_SEEN_MS_AGO]);
5413 2791 : r->ie_len = ie_len;
5414 2791 : pos = (u8 *) (r + 1);
5415 2791 : if (ie) {
5416 2791 : os_memcpy(pos, ie, ie_len);
5417 2791 : pos += ie_len;
5418 : }
5419 2791 : r->beacon_ie_len = beacon_ie_len;
5420 2791 : if (beacon_ie)
5421 1747 : os_memcpy(pos, beacon_ie, beacon_ie_len);
5422 :
5423 2791 : if (bss[NL80211_BSS_STATUS]) {
5424 : enum nl80211_bss_status status;
5425 76 : status = nla_get_u32(bss[NL80211_BSS_STATUS]);
5426 76 : switch (status) {
5427 : case NL80211_BSS_STATUS_AUTHENTICATED:
5428 0 : r->flags |= WPA_SCAN_AUTHENTICATED;
5429 0 : break;
5430 : case NL80211_BSS_STATUS_ASSOCIATED:
5431 72 : r->flags |= WPA_SCAN_ASSOCIATED;
5432 72 : break;
5433 : default:
5434 4 : break;
5435 : }
5436 : }
5437 :
5438 : /*
5439 : * cfg80211 maintains separate BSS table entries for APs if the same
5440 : * BSSID,SSID pair is seen on multiple channels. wpa_supplicant does
5441 : * not use frequency as a separate key in the BSS table, so filter out
5442 : * duplicated entries. Prefer associated BSS entry in such a case in
5443 : * order to get the correct frequency into the BSS table. Similarly,
5444 : * prefer newer entries over older.
5445 : */
5446 4078 : for (i = 0; i < res->num; i++) {
5447 : const u8 *s1, *s2;
5448 1293 : if (os_memcmp(res->res[i]->bssid, r->bssid, ETH_ALEN) != 0)
5449 895 : continue;
5450 :
5451 398 : s1 = nl80211_get_ie((u8 *) (res->res[i] + 1),
5452 398 : res->res[i]->ie_len, WLAN_EID_SSID);
5453 398 : s2 = nl80211_get_ie((u8 *) (r + 1), r->ie_len, WLAN_EID_SSID);
5454 512 : if (s1 == NULL || s2 == NULL || s1[1] != s2[1] ||
5455 114 : os_memcmp(s1, s2, 2 + s1[1]) != 0)
5456 392 : continue;
5457 :
5458 : /* Same BSSID,SSID was already included in scan results */
5459 36 : wpa_printf(MSG_DEBUG, "nl80211: Remove duplicated scan result "
5460 36 : "for " MACSTR, MAC2STR(r->bssid));
5461 :
5462 6 : if (((r->flags & WPA_SCAN_ASSOCIATED) &&
5463 6 : !(res->res[i]->flags & WPA_SCAN_ASSOCIATED)) ||
5464 6 : r->age < res->res[i]->age) {
5465 6 : os_free(res->res[i]);
5466 6 : res->res[i] = r;
5467 : } else
5468 0 : os_free(r);
5469 6 : return NL_SKIP;
5470 : }
5471 :
5472 2785 : tmp = os_realloc_array(res->res, res->num + 1,
5473 : sizeof(struct wpa_scan_res *));
5474 2785 : if (tmp == NULL) {
5475 0 : os_free(r);
5476 0 : return NL_SKIP;
5477 : }
5478 2785 : tmp[res->num++] = r;
5479 2785 : res->res = tmp;
5480 :
5481 2785 : return NL_SKIP;
5482 : }
5483 :
5484 :
5485 0 : static void clear_state_mismatch(struct wpa_driver_nl80211_data *drv,
5486 : const u8 *addr)
5487 : {
5488 0 : if (drv->capa.flags & WPA_DRIVER_FLAGS_SME) {
5489 0 : wpa_printf(MSG_DEBUG, "nl80211: Clear possible state "
5490 0 : "mismatch (" MACSTR ")", MAC2STR(addr));
5491 0 : wpa_driver_nl80211_mlme(drv, addr,
5492 : NL80211_CMD_DEAUTHENTICATE,
5493 : WLAN_REASON_PREV_AUTH_NOT_VALID, 1);
5494 : }
5495 0 : }
5496 :
5497 :
5498 1879 : static void wpa_driver_nl80211_check_bss_status(
5499 : struct wpa_driver_nl80211_data *drv, struct wpa_scan_results *res)
5500 : {
5501 : size_t i;
5502 :
5503 4664 : for (i = 0; i < res->num; i++) {
5504 2785 : struct wpa_scan_res *r = res->res[i];
5505 2785 : if (r->flags & WPA_SCAN_AUTHENTICATED) {
5506 0 : wpa_printf(MSG_DEBUG, "nl80211: Scan results "
5507 : "indicates BSS status with " MACSTR
5508 : " as authenticated",
5509 0 : MAC2STR(r->bssid));
5510 0 : if (is_sta_interface(drv->nlmode) &&
5511 0 : os_memcmp(r->bssid, drv->bssid, ETH_ALEN) != 0 &&
5512 0 : os_memcmp(r->bssid, drv->auth_bssid, ETH_ALEN) !=
5513 : 0) {
5514 0 : wpa_printf(MSG_DEBUG, "nl80211: Unknown BSSID"
5515 : " in local state (auth=" MACSTR
5516 : " assoc=" MACSTR ")",
5517 0 : MAC2STR(drv->auth_bssid),
5518 0 : MAC2STR(drv->bssid));
5519 0 : clear_state_mismatch(drv, r->bssid);
5520 : }
5521 : }
5522 :
5523 2785 : if (r->flags & WPA_SCAN_ASSOCIATED) {
5524 432 : wpa_printf(MSG_DEBUG, "nl80211: Scan results "
5525 : "indicate BSS status with " MACSTR
5526 : " as associated",
5527 432 : MAC2STR(r->bssid));
5528 144 : if (is_sta_interface(drv->nlmode) &&
5529 72 : !drv->associated) {
5530 0 : wpa_printf(MSG_DEBUG, "nl80211: Local state "
5531 : "(not associated) does not match "
5532 : "with BSS state");
5533 0 : clear_state_mismatch(drv, r->bssid);
5534 144 : } else if (is_sta_interface(drv->nlmode) &&
5535 72 : os_memcmp(drv->bssid, r->bssid, ETH_ALEN) !=
5536 : 0) {
5537 0 : wpa_printf(MSG_DEBUG, "nl80211: Local state "
5538 : "(associated with " MACSTR ") does "
5539 : "not match with BSS state",
5540 0 : MAC2STR(drv->bssid));
5541 0 : clear_state_mismatch(drv, r->bssid);
5542 0 : clear_state_mismatch(drv, drv->bssid);
5543 : }
5544 : }
5545 : }
5546 1879 : }
5547 :
5548 :
5549 : static struct wpa_scan_results *
5550 1879 : nl80211_get_scan_results(struct wpa_driver_nl80211_data *drv)
5551 : {
5552 : struct nl_msg *msg;
5553 : struct wpa_scan_results *res;
5554 : int ret;
5555 : struct nl80211_bss_info_arg arg;
5556 :
5557 1879 : res = os_zalloc(sizeof(*res));
5558 1879 : if (res == NULL)
5559 0 : return NULL;
5560 1879 : msg = nlmsg_alloc();
5561 1879 : if (!msg)
5562 0 : goto nla_put_failure;
5563 :
5564 1879 : nl80211_cmd(drv, msg, NLM_F_DUMP, NL80211_CMD_GET_SCAN);
5565 1879 : if (nl80211_set_iface_id(msg, drv->first_bss) < 0)
5566 0 : goto nla_put_failure;
5567 :
5568 1879 : arg.drv = drv;
5569 1879 : arg.res = res;
5570 1879 : ret = send_and_recv_msgs(drv, msg, bss_info_handler, &arg);
5571 1879 : msg = NULL;
5572 1879 : if (ret == 0) {
5573 1879 : wpa_printf(MSG_DEBUG, "nl80211: Received scan results (%lu "
5574 : "BSSes)", (unsigned long) res->num);
5575 1879 : nl80211_get_noise_for_scan_results(drv, res);
5576 1879 : return res;
5577 : }
5578 0 : wpa_printf(MSG_DEBUG, "nl80211: Scan result fetch failed: ret=%d "
5579 : "(%s)", ret, strerror(-ret));
5580 : nla_put_failure:
5581 0 : nlmsg_free(msg);
5582 0 : wpa_scan_results_free(res);
5583 0 : return NULL;
5584 : }
5585 :
5586 :
5587 : /**
5588 : * wpa_driver_nl80211_get_scan_results - Fetch the latest scan results
5589 : * @priv: Pointer to private wext data from wpa_driver_nl80211_init()
5590 : * Returns: Scan results on success, -1 on failure
5591 : */
5592 : static struct wpa_scan_results *
5593 1879 : wpa_driver_nl80211_get_scan_results(void *priv)
5594 : {
5595 1879 : struct i802_bss *bss = priv;
5596 1879 : struct wpa_driver_nl80211_data *drv = bss->drv;
5597 : struct wpa_scan_results *res;
5598 :
5599 1879 : res = nl80211_get_scan_results(drv);
5600 1879 : if (res)
5601 1879 : wpa_driver_nl80211_check_bss_status(drv, res);
5602 1879 : return res;
5603 : }
5604 :
5605 :
5606 0 : static void nl80211_dump_scan(struct wpa_driver_nl80211_data *drv)
5607 : {
5608 : struct wpa_scan_results *res;
5609 : size_t i;
5610 :
5611 0 : res = nl80211_get_scan_results(drv);
5612 0 : if (res == NULL) {
5613 0 : wpa_printf(MSG_DEBUG, "nl80211: Failed to get scan results");
5614 0 : return;
5615 : }
5616 :
5617 0 : wpa_printf(MSG_DEBUG, "nl80211: Scan result dump");
5618 0 : for (i = 0; i < res->num; i++) {
5619 0 : struct wpa_scan_res *r = res->res[i];
5620 0 : wpa_printf(MSG_DEBUG, "nl80211: %d/%d " MACSTR "%s%s",
5621 0 : (int) i, (int) res->num, MAC2STR(r->bssid),
5622 0 : r->flags & WPA_SCAN_AUTHENTICATED ? " [auth]" : "",
5623 0 : r->flags & WPA_SCAN_ASSOCIATED ? " [assoc]" : "");
5624 : }
5625 :
5626 0 : wpa_scan_results_free(res);
5627 : }
5628 :
5629 :
5630 3286 : static u32 wpa_alg_to_cipher_suite(enum wpa_alg alg, size_t key_len)
5631 : {
5632 3286 : switch (alg) {
5633 : case WPA_ALG_WEP:
5634 47 : if (key_len == 5)
5635 23 : return WLAN_CIPHER_SUITE_WEP40;
5636 24 : return WLAN_CIPHER_SUITE_WEP104;
5637 : case WPA_ALG_TKIP:
5638 130 : return WLAN_CIPHER_SUITE_TKIP;
5639 : case WPA_ALG_CCMP:
5640 2867 : return WLAN_CIPHER_SUITE_CCMP;
5641 : case WPA_ALG_GCMP:
5642 0 : return WLAN_CIPHER_SUITE_GCMP;
5643 : case WPA_ALG_CCMP_256:
5644 0 : return WLAN_CIPHER_SUITE_CCMP_256;
5645 : case WPA_ALG_GCMP_256:
5646 0 : return WLAN_CIPHER_SUITE_GCMP_256;
5647 : case WPA_ALG_IGTK:
5648 240 : return WLAN_CIPHER_SUITE_AES_CMAC;
5649 : case WPA_ALG_BIP_GMAC_128:
5650 0 : return WLAN_CIPHER_SUITE_BIP_GMAC_128;
5651 : case WPA_ALG_BIP_GMAC_256:
5652 0 : return WLAN_CIPHER_SUITE_BIP_GMAC_256;
5653 : case WPA_ALG_BIP_CMAC_256:
5654 0 : return WLAN_CIPHER_SUITE_BIP_CMAC_256;
5655 : case WPA_ALG_SMS4:
5656 0 : return WLAN_CIPHER_SUITE_SMS4;
5657 : case WPA_ALG_KRK:
5658 0 : return WLAN_CIPHER_SUITE_KRK;
5659 : case WPA_ALG_NONE:
5660 : case WPA_ALG_PMK:
5661 0 : wpa_printf(MSG_ERROR, "nl80211: Unexpected encryption algorithm %d",
5662 : alg);
5663 0 : return 0;
5664 : }
5665 :
5666 2 : wpa_printf(MSG_ERROR, "nl80211: Unsupported encryption algorithm %d",
5667 : alg);
5668 2 : return 0;
5669 : }
5670 :
5671 :
5672 2954 : static u32 wpa_cipher_to_cipher_suite(unsigned int cipher)
5673 : {
5674 2954 : switch (cipher) {
5675 : case WPA_CIPHER_CCMP_256:
5676 0 : return WLAN_CIPHER_SUITE_CCMP_256;
5677 : case WPA_CIPHER_GCMP_256:
5678 0 : return WLAN_CIPHER_SUITE_GCMP_256;
5679 : case WPA_CIPHER_CCMP:
5680 2590 : return WLAN_CIPHER_SUITE_CCMP;
5681 : case WPA_CIPHER_GCMP:
5682 0 : return WLAN_CIPHER_SUITE_GCMP;
5683 : case WPA_CIPHER_TKIP:
5684 127 : return WLAN_CIPHER_SUITE_TKIP;
5685 : case WPA_CIPHER_WEP104:
5686 9 : return WLAN_CIPHER_SUITE_WEP104;
5687 : case WPA_CIPHER_WEP40:
5688 22 : return WLAN_CIPHER_SUITE_WEP40;
5689 : case WPA_CIPHER_GTK_NOT_USED:
5690 0 : return WLAN_CIPHER_SUITE_NO_GROUP_ADDR;
5691 : }
5692 :
5693 206 : return 0;
5694 : }
5695 :
5696 :
5697 1648 : static int wpa_cipher_to_cipher_suites(unsigned int ciphers, u32 suites[],
5698 : int max_suites)
5699 : {
5700 1648 : int num_suites = 0;
5701 :
5702 1648 : if (num_suites < max_suites && ciphers & WPA_CIPHER_CCMP_256)
5703 0 : suites[num_suites++] = WLAN_CIPHER_SUITE_CCMP_256;
5704 1648 : if (num_suites < max_suites && ciphers & WPA_CIPHER_GCMP_256)
5705 0 : suites[num_suites++] = WLAN_CIPHER_SUITE_GCMP_256;
5706 1648 : if (num_suites < max_suites && ciphers & WPA_CIPHER_CCMP)
5707 1405 : suites[num_suites++] = WLAN_CIPHER_SUITE_CCMP;
5708 1648 : if (num_suites < max_suites && ciphers & WPA_CIPHER_GCMP)
5709 0 : suites[num_suites++] = WLAN_CIPHER_SUITE_GCMP;
5710 1648 : if (num_suites < max_suites && ciphers & WPA_CIPHER_TKIP)
5711 53 : suites[num_suites++] = WLAN_CIPHER_SUITE_TKIP;
5712 1648 : if (num_suites < max_suites && ciphers & WPA_CIPHER_WEP104)
5713 5 : suites[num_suites++] = WLAN_CIPHER_SUITE_WEP104;
5714 1648 : if (num_suites < max_suites && ciphers & WPA_CIPHER_WEP40)
5715 10 : suites[num_suites++] = WLAN_CIPHER_SUITE_WEP40;
5716 :
5717 1648 : return num_suites;
5718 : }
5719 :
5720 :
5721 12144 : static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss,
5722 : enum wpa_alg alg, const u8 *addr,
5723 : int key_idx, int set_tx,
5724 : const u8 *seq, size_t seq_len,
5725 : const u8 *key, size_t key_len)
5726 : {
5727 12144 : struct wpa_driver_nl80211_data *drv = bss->drv;
5728 : int ifindex;
5729 : struct nl_msg *msg;
5730 : int ret;
5731 12144 : int tdls = 0;
5732 :
5733 : /* Ignore for P2P Device */
5734 12144 : if (drv->nlmode == NL80211_IFTYPE_P2P_DEVICE)
5735 0 : return 0;
5736 :
5737 12144 : ifindex = if_nametoindex(ifname);
5738 12144 : wpa_printf(MSG_DEBUG, "%s: ifindex=%d (%s) alg=%d addr=%p key_idx=%d "
5739 : "set_tx=%d seq_len=%lu key_len=%lu",
5740 : __func__, ifindex, ifname, alg, addr, key_idx, set_tx,
5741 : (unsigned long) seq_len, (unsigned long) key_len);
5742 : #ifdef CONFIG_TDLS
5743 5194 : if (key_idx == -1) {
5744 70 : key_idx = 0;
5745 70 : tdls = 1;
5746 : }
5747 : #endif /* CONFIG_TDLS */
5748 :
5749 12144 : msg = nlmsg_alloc();
5750 12144 : if (!msg)
5751 0 : return -ENOMEM;
5752 :
5753 12144 : if (alg == WPA_ALG_NONE) {
5754 8871 : nl80211_cmd(drv, msg, 0, NL80211_CMD_DEL_KEY);
5755 : } else {
5756 3273 : nl80211_cmd(drv, msg, 0, NL80211_CMD_NEW_KEY);
5757 3273 : NLA_PUT(msg, NL80211_ATTR_KEY_DATA, key_len, key);
5758 3273 : wpa_hexdump_key(MSG_DEBUG, "nl80211: KEY_DATA", key, key_len);
5759 3273 : NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER,
5760 : wpa_alg_to_cipher_suite(alg, key_len));
5761 : }
5762 :
5763 12144 : if (seq && seq_len) {
5764 1457 : NLA_PUT(msg, NL80211_ATTR_KEY_SEQ, seq_len, seq);
5765 1457 : wpa_hexdump(MSG_DEBUG, "nl80211: KEY_SEQ", seq, seq_len);
5766 : }
5767 :
5768 12144 : if (addr && !is_broadcast_ether_addr(addr)) {
5769 5467 : wpa_printf(MSG_DEBUG, " addr=" MACSTR, MAC2STR(addr));
5770 5467 : NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
5771 :
5772 10934 : if (alg != WPA_ALG_WEP && key_idx && !set_tx) {
5773 10 : wpa_printf(MSG_DEBUG, " RSN IBSS RX GTK");
5774 10 : NLA_PUT_U32(msg, NL80211_ATTR_KEY_TYPE,
5775 : NL80211_KEYTYPE_GROUP);
5776 : }
5777 6677 : } else if (addr && is_broadcast_ether_addr(addr)) {
5778 : struct nlattr *types;
5779 :
5780 1822 : wpa_printf(MSG_DEBUG, " broadcast key");
5781 :
5782 1822 : types = nla_nest_start(msg, NL80211_ATTR_KEY_DEFAULT_TYPES);
5783 1822 : if (!types)
5784 0 : goto nla_put_failure;
5785 1822 : NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT_TYPE_MULTICAST);
5786 1822 : nla_nest_end(msg, types);
5787 : }
5788 12144 : NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx);
5789 12144 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
5790 :
5791 12144 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5792 12144 : if ((ret == -ENOENT || ret == -ENOLINK) && alg == WPA_ALG_NONE)
5793 8369 : ret = 0;
5794 12144 : if (ret)
5795 99 : wpa_printf(MSG_DEBUG, "nl80211: set_key failed; err=%d %s)",
5796 : ret, strerror(-ret));
5797 :
5798 : /*
5799 : * If we failed or don't need to set the default TX key (below),
5800 : * we're done here.
5801 : */
5802 12144 : if (ret || !set_tx || alg == WPA_ALG_NONE || tdls)
5803 9680 : return ret;
5804 4253 : if (is_ap_interface(drv->nlmode) && addr &&
5805 1789 : !is_broadcast_ether_addr(addr))
5806 649 : return ret;
5807 :
5808 1815 : msg = nlmsg_alloc();
5809 1815 : if (!msg)
5810 0 : return -ENOMEM;
5811 :
5812 1815 : nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_KEY);
5813 1815 : NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx);
5814 1815 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
5815 1815 : if (alg == WPA_ALG_IGTK)
5816 207 : NLA_PUT_FLAG(msg, NL80211_ATTR_KEY_DEFAULT_MGMT);
5817 : else
5818 1608 : NLA_PUT_FLAG(msg, NL80211_ATTR_KEY_DEFAULT);
5819 2965 : if (addr && is_broadcast_ether_addr(addr)) {
5820 : struct nlattr *types;
5821 :
5822 1150 : types = nla_nest_start(msg, NL80211_ATTR_KEY_DEFAULT_TYPES);
5823 1150 : if (!types)
5824 0 : goto nla_put_failure;
5825 1150 : NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT_TYPE_MULTICAST);
5826 1150 : nla_nest_end(msg, types);
5827 665 : } else if (addr) {
5828 : struct nlattr *types;
5829 :
5830 649 : types = nla_nest_start(msg, NL80211_ATTR_KEY_DEFAULT_TYPES);
5831 649 : if (!types)
5832 0 : goto nla_put_failure;
5833 649 : NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT_TYPE_UNICAST);
5834 649 : nla_nest_end(msg, types);
5835 : }
5836 :
5837 1815 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5838 1815 : if (ret == -ENOENT)
5839 0 : ret = 0;
5840 1815 : if (ret)
5841 0 : wpa_printf(MSG_DEBUG, "nl80211: set_key default failed; "
5842 : "err=%d %s)", ret, strerror(-ret));
5843 1815 : return ret;
5844 :
5845 : nla_put_failure:
5846 0 : nlmsg_free(msg);
5847 0 : return -ENOBUFS;
5848 : }
5849 :
5850 :
5851 13 : static int nl_add_key(struct nl_msg *msg, enum wpa_alg alg,
5852 : int key_idx, int defkey,
5853 : const u8 *seq, size_t seq_len,
5854 : const u8 *key, size_t key_len)
5855 : {
5856 13 : struct nlattr *key_attr = nla_nest_start(msg, NL80211_ATTR_KEY);
5857 13 : if (!key_attr)
5858 0 : return -1;
5859 :
5860 13 : if (defkey && alg == WPA_ALG_IGTK)
5861 0 : NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT_MGMT);
5862 13 : else if (defkey)
5863 13 : NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT);
5864 :
5865 13 : NLA_PUT_U8(msg, NL80211_KEY_IDX, key_idx);
5866 :
5867 13 : NLA_PUT_U32(msg, NL80211_KEY_CIPHER,
5868 : wpa_alg_to_cipher_suite(alg, key_len));
5869 :
5870 13 : if (seq && seq_len)
5871 0 : NLA_PUT(msg, NL80211_KEY_SEQ, seq_len, seq);
5872 :
5873 13 : NLA_PUT(msg, NL80211_KEY_DATA, key_len, key);
5874 :
5875 13 : nla_nest_end(msg, key_attr);
5876 :
5877 13 : return 0;
5878 : nla_put_failure:
5879 0 : return -1;
5880 : }
5881 :
5882 :
5883 32 : static int nl80211_set_conn_keys(struct wpa_driver_associate_params *params,
5884 : struct nl_msg *msg)
5885 : {
5886 32 : int i, privacy = 0;
5887 : struct nlattr *nl_keys, *nl_key;
5888 :
5889 320 : for (i = 0; i < 4; i++) {
5890 128 : if (!params->wep_key[i])
5891 128 : continue;
5892 0 : privacy = 1;
5893 0 : break;
5894 : }
5895 32 : if (params->wps == WPS_MODE_PRIVACY)
5896 1 : privacy = 1;
5897 64 : if (params->pairwise_suite &&
5898 32 : params->pairwise_suite != WPA_CIPHER_NONE)
5899 24 : privacy = 1;
5900 :
5901 32 : if (!privacy)
5902 7 : return 0;
5903 :
5904 25 : NLA_PUT_FLAG(msg, NL80211_ATTR_PRIVACY);
5905 :
5906 25 : nl_keys = nla_nest_start(msg, NL80211_ATTR_KEYS);
5907 25 : if (!nl_keys)
5908 0 : goto nla_put_failure;
5909 :
5910 125 : for (i = 0; i < 4; i++) {
5911 100 : if (!params->wep_key[i])
5912 100 : continue;
5913 :
5914 0 : nl_key = nla_nest_start(msg, i);
5915 0 : if (!nl_key)
5916 0 : goto nla_put_failure;
5917 :
5918 0 : NLA_PUT(msg, NL80211_KEY_DATA, params->wep_key_len[i],
5919 : params->wep_key[i]);
5920 0 : if (params->wep_key_len[i] == 5)
5921 0 : NLA_PUT_U32(msg, NL80211_KEY_CIPHER,
5922 : WLAN_CIPHER_SUITE_WEP40);
5923 : else
5924 0 : NLA_PUT_U32(msg, NL80211_KEY_CIPHER,
5925 : WLAN_CIPHER_SUITE_WEP104);
5926 :
5927 0 : NLA_PUT_U8(msg, NL80211_KEY_IDX, i);
5928 :
5929 0 : if (i == params->wep_tx_keyidx)
5930 0 : NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT);
5931 :
5932 0 : nla_nest_end(msg, nl_key);
5933 : }
5934 25 : nla_nest_end(msg, nl_keys);
5935 :
5936 25 : return 0;
5937 :
5938 : nla_put_failure:
5939 0 : return -ENOBUFS;
5940 : }
5941 :
5942 :
5943 955 : static int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data *drv,
5944 : const u8 *addr, int cmd, u16 reason_code,
5945 : int local_state_change)
5946 : {
5947 955 : int ret = -1;
5948 : struct nl_msg *msg;
5949 :
5950 955 : msg = nlmsg_alloc();
5951 955 : if (!msg)
5952 0 : return -1;
5953 :
5954 955 : nl80211_cmd(drv, msg, 0, cmd);
5955 :
5956 955 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
5957 955 : NLA_PUT_U16(msg, NL80211_ATTR_REASON_CODE, reason_code);
5958 955 : if (addr)
5959 944 : NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
5960 955 : if (local_state_change)
5961 0 : NLA_PUT_FLAG(msg, NL80211_ATTR_LOCAL_STATE_CHANGE);
5962 :
5963 955 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
5964 955 : msg = NULL;
5965 955 : if (ret) {
5966 130 : wpa_dbg(drv->ctx, MSG_DEBUG,
5967 : "nl80211: MLME command failed: reason=%u ret=%d (%s)",
5968 : reason_code, ret, strerror(-ret));
5969 130 : goto nla_put_failure;
5970 : }
5971 825 : ret = 0;
5972 :
5973 : nla_put_failure:
5974 955 : nlmsg_free(msg);
5975 955 : return ret;
5976 : }
5977 :
5978 :
5979 11 : static int wpa_driver_nl80211_disconnect(struct wpa_driver_nl80211_data *drv,
5980 : int reason_code)
5981 : {
5982 : int ret;
5983 :
5984 11 : wpa_printf(MSG_DEBUG, "%s(reason_code=%d)", __func__, reason_code);
5985 11 : nl80211_mark_disconnected(drv);
5986 : /* Disconnect command doesn't need BSSID - it uses cached value */
5987 11 : ret = wpa_driver_nl80211_mlme(drv, NULL, NL80211_CMD_DISCONNECT,
5988 : reason_code, 0);
5989 : /*
5990 : * For locally generated disconnect, supplicant already generates a
5991 : * DEAUTH event, so ignore the event from NL80211.
5992 : */
5993 11 : drv->ignore_next_local_disconnect = ret == 0;
5994 :
5995 11 : return ret;
5996 : }
5997 :
5998 :
5999 966 : static int wpa_driver_nl80211_deauthenticate(struct i802_bss *bss,
6000 : const u8 *addr, int reason_code)
6001 : {
6002 966 : struct wpa_driver_nl80211_data *drv = bss->drv;
6003 : int ret;
6004 :
6005 966 : if (drv->nlmode == NL80211_IFTYPE_ADHOC) {
6006 13 : nl80211_mark_disconnected(drv);
6007 13 : return nl80211_leave_ibss(drv);
6008 : }
6009 953 : if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME))
6010 9 : return wpa_driver_nl80211_disconnect(drv, reason_code);
6011 5664 : wpa_printf(MSG_DEBUG, "%s(addr=" MACSTR " reason_code=%d)",
6012 5664 : __func__, MAC2STR(addr), reason_code);
6013 944 : nl80211_mark_disconnected(drv);
6014 944 : ret = wpa_driver_nl80211_mlme(drv, addr, NL80211_CMD_DEAUTHENTICATE,
6015 : reason_code, 0);
6016 : /*
6017 : * For locally generated deauthenticate, supplicant already generates a
6018 : * DEAUTH event, so ignore the event from NL80211.
6019 : */
6020 944 : drv->ignore_next_local_deauth = ret == 0;
6021 944 : return ret;
6022 : }
6023 :
6024 :
6025 0 : static void nl80211_copy_auth_params(struct wpa_driver_nl80211_data *drv,
6026 : struct wpa_driver_auth_params *params)
6027 : {
6028 : int i;
6029 :
6030 0 : drv->auth_freq = params->freq;
6031 0 : drv->auth_alg = params->auth_alg;
6032 0 : drv->auth_wep_tx_keyidx = params->wep_tx_keyidx;
6033 0 : drv->auth_local_state_change = params->local_state_change;
6034 0 : drv->auth_p2p = params->p2p;
6035 :
6036 0 : if (params->bssid)
6037 0 : os_memcpy(drv->auth_bssid_, params->bssid, ETH_ALEN);
6038 : else
6039 0 : os_memset(drv->auth_bssid_, 0, ETH_ALEN);
6040 :
6041 0 : if (params->ssid) {
6042 0 : os_memcpy(drv->auth_ssid, params->ssid, params->ssid_len);
6043 0 : drv->auth_ssid_len = params->ssid_len;
6044 : } else
6045 0 : drv->auth_ssid_len = 0;
6046 :
6047 :
6048 0 : os_free(drv->auth_ie);
6049 0 : drv->auth_ie = NULL;
6050 0 : drv->auth_ie_len = 0;
6051 0 : if (params->ie) {
6052 0 : drv->auth_ie = os_malloc(params->ie_len);
6053 0 : if (drv->auth_ie) {
6054 0 : os_memcpy(drv->auth_ie, params->ie, params->ie_len);
6055 0 : drv->auth_ie_len = params->ie_len;
6056 : }
6057 : }
6058 :
6059 0 : for (i = 0; i < 4; i++) {
6060 0 : if (params->wep_key[i] && params->wep_key_len[i] &&
6061 0 : params->wep_key_len[i] <= 16) {
6062 0 : os_memcpy(drv->auth_wep_key[i], params->wep_key[i],
6063 : params->wep_key_len[i]);
6064 0 : drv->auth_wep_key_len[i] = params->wep_key_len[i];
6065 : } else
6066 0 : drv->auth_wep_key_len[i] = 0;
6067 : }
6068 0 : }
6069 :
6070 :
6071 1079 : static int wpa_driver_nl80211_authenticate(
6072 : struct i802_bss *bss, struct wpa_driver_auth_params *params)
6073 : {
6074 1079 : struct wpa_driver_nl80211_data *drv = bss->drv;
6075 1079 : int ret = -1, i;
6076 : struct nl_msg *msg;
6077 : enum nl80211_auth_type type;
6078 : enum nl80211_iftype nlmode;
6079 1079 : int count = 0;
6080 : int is_retry;
6081 :
6082 1079 : is_retry = drv->retry_auth;
6083 1079 : drv->retry_auth = 0;
6084 1079 : drv->ignore_deauth_event = 0;
6085 :
6086 1079 : nl80211_mark_disconnected(drv);
6087 1079 : os_memset(drv->auth_bssid, 0, ETH_ALEN);
6088 1079 : if (params->bssid)
6089 1079 : os_memcpy(drv->auth_attempt_bssid, params->bssid, ETH_ALEN);
6090 : else
6091 0 : os_memset(drv->auth_attempt_bssid, 0, ETH_ALEN);
6092 : /* FIX: IBSS mode */
6093 1079 : nlmode = params->p2p ?
6094 : NL80211_IFTYPE_P2P_CLIENT : NL80211_IFTYPE_STATION;
6095 1184 : if (drv->nlmode != nlmode &&
6096 105 : wpa_driver_nl80211_set_mode(bss, nlmode) < 0)
6097 0 : return -1;
6098 :
6099 : retry:
6100 1082 : msg = nlmsg_alloc();
6101 1082 : if (!msg)
6102 0 : return -1;
6103 :
6104 1082 : wpa_printf(MSG_DEBUG, "nl80211: Authenticate (ifindex=%d)",
6105 : drv->ifindex);
6106 :
6107 1082 : nl80211_cmd(drv, msg, 0, NL80211_CMD_AUTHENTICATE);
6108 :
6109 5410 : for (i = 0; i < 4; i++) {
6110 4328 : if (!params->wep_key[i])
6111 4315 : continue;
6112 26 : wpa_driver_nl80211_set_key(bss->ifname, bss, WPA_ALG_WEP,
6113 : NULL, i,
6114 13 : i == params->wep_tx_keyidx, NULL, 0,
6115 : params->wep_key[i],
6116 : params->wep_key_len[i]);
6117 13 : if (params->wep_tx_keyidx != i)
6118 0 : continue;
6119 13 : if (nl_add_key(msg, WPA_ALG_WEP, i, 1, NULL, 0,
6120 : params->wep_key[i], params->wep_key_len[i])) {
6121 0 : nlmsg_free(msg);
6122 0 : return -1;
6123 : }
6124 : }
6125 :
6126 1082 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
6127 1082 : if (params->bssid) {
6128 6492 : wpa_printf(MSG_DEBUG, " * bssid=" MACSTR,
6129 6492 : MAC2STR(params->bssid));
6130 1082 : NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid);
6131 : }
6132 1082 : if (params->freq) {
6133 1082 : wpa_printf(MSG_DEBUG, " * freq=%d", params->freq);
6134 1082 : NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq);
6135 : }
6136 1082 : if (params->ssid) {
6137 2164 : wpa_hexdump_ascii(MSG_DEBUG, " * SSID",
6138 1082 : params->ssid, params->ssid_len);
6139 1082 : NLA_PUT(msg, NL80211_ATTR_SSID, params->ssid_len,
6140 : params->ssid);
6141 : }
6142 1082 : wpa_hexdump(MSG_DEBUG, " * IEs", params->ie, params->ie_len);
6143 1082 : if (params->ie)
6144 12 : NLA_PUT(msg, NL80211_ATTR_IE, params->ie_len, params->ie);
6145 1082 : if (params->sae_data) {
6146 48 : wpa_hexdump(MSG_DEBUG, " * SAE data", params->sae_data,
6147 : params->sae_data_len);
6148 48 : NLA_PUT(msg, NL80211_ATTR_SAE_DATA, params->sae_data_len,
6149 : params->sae_data);
6150 : }
6151 1082 : if (params->auth_alg & WPA_AUTH_ALG_OPEN)
6152 996 : type = NL80211_AUTHTYPE_OPEN_SYSTEM;
6153 86 : else if (params->auth_alg & WPA_AUTH_ALG_SHARED)
6154 3 : type = NL80211_AUTHTYPE_SHARED_KEY;
6155 83 : else if (params->auth_alg & WPA_AUTH_ALG_LEAP)
6156 3 : type = NL80211_AUTHTYPE_NETWORK_EAP;
6157 80 : else if (params->auth_alg & WPA_AUTH_ALG_FT)
6158 32 : type = NL80211_AUTHTYPE_FT;
6159 48 : else if (params->auth_alg & WPA_AUTH_ALG_SAE)
6160 48 : type = NL80211_AUTHTYPE_SAE;
6161 : else
6162 0 : goto nla_put_failure;
6163 1082 : wpa_printf(MSG_DEBUG, " * Auth Type %d", type);
6164 1082 : NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE, type);
6165 1082 : if (params->local_state_change) {
6166 20 : wpa_printf(MSG_DEBUG, " * Local state change only");
6167 20 : NLA_PUT_FLAG(msg, NL80211_ATTR_LOCAL_STATE_CHANGE);
6168 : }
6169 :
6170 1082 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
6171 1082 : msg = NULL;
6172 1082 : if (ret) {
6173 3 : wpa_dbg(drv->ctx, MSG_DEBUG,
6174 : "nl80211: MLME command failed (auth): ret=%d (%s)",
6175 : ret, strerror(-ret));
6176 3 : count++;
6177 6 : if (ret == -EALREADY && count == 1 && params->bssid &&
6178 3 : !params->local_state_change) {
6179 : /*
6180 : * mac80211 does not currently accept new
6181 : * authentication if we are already authenticated. As a
6182 : * workaround, force deauthentication and try again.
6183 : */
6184 3 : wpa_printf(MSG_DEBUG, "nl80211: Retry authentication "
6185 : "after forced deauthentication");
6186 3 : drv->ignore_deauth_event = 1;
6187 3 : wpa_driver_nl80211_deauthenticate(
6188 : bss, params->bssid,
6189 : WLAN_REASON_PREV_AUTH_NOT_VALID);
6190 3 : nlmsg_free(msg);
6191 3 : goto retry;
6192 : }
6193 :
6194 0 : if (ret == -ENOENT && params->freq && !is_retry) {
6195 : /*
6196 : * cfg80211 has likely expired the BSS entry even
6197 : * though it was previously available in our internal
6198 : * BSS table. To recover quickly, start a single
6199 : * channel scan on the specified channel.
6200 : */
6201 : struct wpa_driver_scan_params scan;
6202 : int freqs[2];
6203 :
6204 0 : os_memset(&scan, 0, sizeof(scan));
6205 0 : scan.num_ssids = 1;
6206 0 : if (params->ssid) {
6207 0 : scan.ssids[0].ssid = params->ssid;
6208 0 : scan.ssids[0].ssid_len = params->ssid_len;
6209 : }
6210 0 : freqs[0] = params->freq;
6211 0 : freqs[1] = 0;
6212 0 : scan.freqs = freqs;
6213 0 : wpa_printf(MSG_DEBUG, "nl80211: Trigger single "
6214 : "channel scan to refresh cfg80211 BSS "
6215 : "entry");
6216 0 : ret = wpa_driver_nl80211_scan(bss, &scan);
6217 0 : if (ret == 0) {
6218 0 : nl80211_copy_auth_params(drv, params);
6219 0 : drv->scan_for_auth = 1;
6220 : }
6221 0 : } else if (is_retry) {
6222 : /*
6223 : * Need to indicate this with an event since the return
6224 : * value from the retry is not delivered to core code.
6225 : */
6226 : union wpa_event_data event;
6227 0 : wpa_printf(MSG_DEBUG, "nl80211: Authentication retry "
6228 : "failed");
6229 0 : os_memset(&event, 0, sizeof(event));
6230 0 : os_memcpy(event.timeout_event.addr, drv->auth_bssid_,
6231 : ETH_ALEN);
6232 0 : wpa_supplicant_event(drv->ctx, EVENT_AUTH_TIMED_OUT,
6233 : &event);
6234 : }
6235 :
6236 0 : goto nla_put_failure;
6237 : }
6238 1079 : ret = 0;
6239 1079 : wpa_printf(MSG_DEBUG, "nl80211: Authentication request send "
6240 : "successfully");
6241 :
6242 : nla_put_failure:
6243 1079 : nlmsg_free(msg);
6244 1079 : return ret;
6245 : }
6246 :
6247 :
6248 0 : static int wpa_driver_nl80211_authenticate_retry(
6249 : struct wpa_driver_nl80211_data *drv)
6250 : {
6251 : struct wpa_driver_auth_params params;
6252 0 : struct i802_bss *bss = drv->first_bss;
6253 : int i;
6254 :
6255 0 : wpa_printf(MSG_DEBUG, "nl80211: Try to authenticate again");
6256 :
6257 0 : os_memset(¶ms, 0, sizeof(params));
6258 0 : params.freq = drv->auth_freq;
6259 0 : params.auth_alg = drv->auth_alg;
6260 0 : params.wep_tx_keyidx = drv->auth_wep_tx_keyidx;
6261 0 : params.local_state_change = drv->auth_local_state_change;
6262 0 : params.p2p = drv->auth_p2p;
6263 :
6264 0 : if (!is_zero_ether_addr(drv->auth_bssid_))
6265 0 : params.bssid = drv->auth_bssid_;
6266 :
6267 0 : if (drv->auth_ssid_len) {
6268 0 : params.ssid = drv->auth_ssid;
6269 0 : params.ssid_len = drv->auth_ssid_len;
6270 : }
6271 :
6272 0 : params.ie = drv->auth_ie;
6273 0 : params.ie_len = drv->auth_ie_len;
6274 :
6275 0 : for (i = 0; i < 4; i++) {
6276 0 : if (drv->auth_wep_key_len[i]) {
6277 0 : params.wep_key[i] = drv->auth_wep_key[i];
6278 0 : params.wep_key_len[i] = drv->auth_wep_key_len[i];
6279 : }
6280 : }
6281 :
6282 0 : drv->retry_auth = 1;
6283 0 : return wpa_driver_nl80211_authenticate(bss, ¶ms);
6284 : }
6285 :
6286 :
6287 : struct phy_info_arg {
6288 : u16 *num_modes;
6289 : struct hostapd_hw_modes *modes;
6290 : int last_mode, last_chan_idx;
6291 : };
6292 :
6293 144438 : static void phy_info_ht_capa(struct hostapd_hw_modes *mode, struct nlattr *capa,
6294 : struct nlattr *ampdu_factor,
6295 : struct nlattr *ampdu_density,
6296 : struct nlattr *mcs_set)
6297 : {
6298 144438 : if (capa)
6299 6878 : mode->ht_capab = nla_get_u16(capa);
6300 :
6301 144438 : if (ampdu_factor)
6302 6878 : mode->a_mpdu_params |= nla_get_u8(ampdu_factor) & 0x03;
6303 :
6304 144438 : if (ampdu_density)
6305 6878 : mode->a_mpdu_params |= nla_get_u8(ampdu_density) << 2;
6306 :
6307 144438 : if (mcs_set && nla_len(mcs_set) >= 16) {
6308 : u8 *mcs;
6309 6878 : mcs = nla_data(mcs_set);
6310 6878 : os_memcpy(mode->mcs_set, mcs, 16);
6311 : }
6312 144438 : }
6313 :
6314 :
6315 144438 : static void phy_info_vht_capa(struct hostapd_hw_modes *mode,
6316 : struct nlattr *capa,
6317 : struct nlattr *mcs_set)
6318 : {
6319 144438 : if (capa)
6320 6878 : mode->vht_capab = nla_get_u32(capa);
6321 :
6322 144438 : if (mcs_set && nla_len(mcs_set) >= 8) {
6323 : u8 *mcs;
6324 6878 : mcs = nla_data(mcs_set);
6325 6878 : os_memcpy(mode->vht_mcs_set, mcs, 8);
6326 : }
6327 144438 : }
6328 :
6329 :
6330 130682 : static void phy_info_freq(struct hostapd_hw_modes *mode,
6331 : struct hostapd_channel_data *chan,
6332 : struct nlattr *tb_freq[])
6333 : {
6334 : u8 channel;
6335 130682 : chan->freq = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_FREQ]);
6336 130682 : chan->flag = 0;
6337 130682 : chan->dfs_cac_ms = 0;
6338 130682 : if (ieee80211_freq_to_chan(chan->freq, &channel) != NUM_HOSTAPD_MODES)
6339 130682 : chan->chan = channel;
6340 :
6341 130682 : if (tb_freq[NL80211_FREQUENCY_ATTR_DISABLED])
6342 50750 : chan->flag |= HOSTAPD_CHAN_DISABLED;
6343 130682 : if (tb_freq[NL80211_FREQUENCY_ATTR_NO_IR])
6344 37522 : chan->flag |= HOSTAPD_CHAN_PASSIVE_SCAN | HOSTAPD_CHAN_NO_IBSS;
6345 130682 : if (tb_freq[NL80211_FREQUENCY_ATTR_RADAR])
6346 51557 : chan->flag |= HOSTAPD_CHAN_RADAR;
6347 :
6348 130682 : if (tb_freq[NL80211_FREQUENCY_ATTR_DFS_STATE]) {
6349 51557 : enum nl80211_dfs_state state =
6350 51557 : nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_DFS_STATE]);
6351 :
6352 51557 : switch (state) {
6353 : case NL80211_DFS_USABLE:
6354 51557 : chan->flag |= HOSTAPD_CHAN_DFS_USABLE;
6355 51557 : break;
6356 : case NL80211_DFS_AVAILABLE:
6357 0 : chan->flag |= HOSTAPD_CHAN_DFS_AVAILABLE;
6358 0 : break;
6359 : case NL80211_DFS_UNAVAILABLE:
6360 0 : chan->flag |= HOSTAPD_CHAN_DFS_UNAVAILABLE;
6361 0 : break;
6362 : }
6363 : }
6364 :
6365 130682 : if (tb_freq[NL80211_FREQUENCY_ATTR_DFS_CAC_TIME]) {
6366 51557 : chan->dfs_cac_ms = nla_get_u32(
6367 51557 : tb_freq[NL80211_FREQUENCY_ATTR_DFS_CAC_TIME]);
6368 : }
6369 130682 : }
6370 :
6371 :
6372 144438 : static int phy_info_freqs(struct phy_info_arg *phy_info,
6373 : struct hostapd_hw_modes *mode, struct nlattr *tb)
6374 : {
6375 : static struct nla_policy freq_policy[NL80211_FREQUENCY_ATTR_MAX + 1] = {
6376 : [NL80211_FREQUENCY_ATTR_FREQ] = { .type = NLA_U32 },
6377 : [NL80211_FREQUENCY_ATTR_DISABLED] = { .type = NLA_FLAG },
6378 : [NL80211_FREQUENCY_ATTR_NO_IR] = { .type = NLA_FLAG },
6379 : [NL80211_FREQUENCY_ATTR_RADAR] = { .type = NLA_FLAG },
6380 : [NL80211_FREQUENCY_ATTR_MAX_TX_POWER] = { .type = NLA_U32 },
6381 : [NL80211_FREQUENCY_ATTR_DFS_STATE] = { .type = NLA_U32 },
6382 : };
6383 144438 : int new_channels = 0;
6384 : struct hostapd_channel_data *channel;
6385 : struct nlattr *tb_freq[NL80211_FREQUENCY_ATTR_MAX + 1];
6386 : struct nlattr *nl_freq;
6387 : int rem_freq, idx;
6388 :
6389 144438 : if (tb == NULL)
6390 6878 : return NL_OK;
6391 :
6392 268242 : nla_for_each_nested(nl_freq, tb, rem_freq) {
6393 261364 : nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX,
6394 130682 : nla_data(nl_freq), nla_len(nl_freq), freq_policy);
6395 130682 : if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ])
6396 0 : continue;
6397 130682 : new_channels++;
6398 : }
6399 :
6400 137560 : channel = os_realloc_array(mode->channels,
6401 137560 : mode->num_channels + new_channels,
6402 : sizeof(struct hostapd_channel_data));
6403 137560 : if (!channel)
6404 0 : return NL_SKIP;
6405 :
6406 137560 : mode->channels = channel;
6407 137560 : mode->num_channels += new_channels;
6408 :
6409 137560 : idx = phy_info->last_chan_idx;
6410 :
6411 268242 : nla_for_each_nested(nl_freq, tb, rem_freq) {
6412 261364 : nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX,
6413 130682 : nla_data(nl_freq), nla_len(nl_freq), freq_policy);
6414 130682 : if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ])
6415 0 : continue;
6416 130682 : phy_info_freq(mode, &mode->channels[idx], tb_freq);
6417 130682 : idx++;
6418 : }
6419 137560 : phy_info->last_chan_idx = idx;
6420 :
6421 137560 : return NL_OK;
6422 : }
6423 :
6424 :
6425 144438 : static int phy_info_rates(struct hostapd_hw_modes *mode, struct nlattr *tb)
6426 : {
6427 : static struct nla_policy rate_policy[NL80211_BITRATE_ATTR_MAX + 1] = {
6428 : [NL80211_BITRATE_ATTR_RATE] = { .type = NLA_U32 },
6429 : [NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE] =
6430 : { .type = NLA_FLAG },
6431 : };
6432 : struct nlattr *tb_rate[NL80211_BITRATE_ATTR_MAX + 1];
6433 : struct nlattr *nl_rate;
6434 : int rem_rate, idx;
6435 :
6436 144438 : if (tb == NULL)
6437 137560 : return NL_OK;
6438 :
6439 75658 : nla_for_each_nested(nl_rate, tb, rem_rate) {
6440 137560 : nla_parse(tb_rate, NL80211_BITRATE_ATTR_MAX,
6441 68780 : nla_data(nl_rate), nla_len(nl_rate),
6442 : rate_policy);
6443 68780 : if (!tb_rate[NL80211_BITRATE_ATTR_RATE])
6444 0 : continue;
6445 68780 : mode->num_rates++;
6446 : }
6447 :
6448 6878 : mode->rates = os_calloc(mode->num_rates, sizeof(int));
6449 6878 : if (!mode->rates)
6450 0 : return NL_SKIP;
6451 :
6452 6878 : idx = 0;
6453 :
6454 75658 : nla_for_each_nested(nl_rate, tb, rem_rate) {
6455 137560 : nla_parse(tb_rate, NL80211_BITRATE_ATTR_MAX,
6456 68780 : nla_data(nl_rate), nla_len(nl_rate),
6457 : rate_policy);
6458 68780 : if (!tb_rate[NL80211_BITRATE_ATTR_RATE])
6459 0 : continue;
6460 68780 : mode->rates[idx] = nla_get_u32(
6461 : tb_rate[NL80211_BITRATE_ATTR_RATE]);
6462 68780 : idx++;
6463 : }
6464 :
6465 6878 : return NL_OK;
6466 : }
6467 :
6468 :
6469 144438 : static int phy_info_band(struct phy_info_arg *phy_info, struct nlattr *nl_band)
6470 : {
6471 : struct nlattr *tb_band[NL80211_BAND_ATTR_MAX + 1];
6472 : struct hostapd_hw_modes *mode;
6473 : int ret;
6474 :
6475 144438 : if (phy_info->last_mode != nl_band->nla_type) {
6476 6878 : mode = os_realloc_array(phy_info->modes,
6477 6878 : *phy_info->num_modes + 1,
6478 : sizeof(*mode));
6479 6878 : if (!mode)
6480 0 : return NL_SKIP;
6481 6878 : phy_info->modes = mode;
6482 :
6483 6878 : mode = &phy_info->modes[*(phy_info->num_modes)];
6484 6878 : os_memset(mode, 0, sizeof(*mode));
6485 6878 : mode->mode = NUM_HOSTAPD_MODES;
6486 6878 : mode->flags = HOSTAPD_MODE_FLAG_HT_INFO_KNOWN |
6487 : HOSTAPD_MODE_FLAG_VHT_INFO_KNOWN;
6488 :
6489 : /*
6490 : * Unsupported VHT MCS stream is defined as value 3, so the VHT
6491 : * MCS RX/TX map must be initialized with 0xffff to mark all 8
6492 : * possible streams as unsupported. This will be overridden if
6493 : * driver advertises VHT support.
6494 : */
6495 6878 : mode->vht_mcs_set[0] = 0xff;
6496 6878 : mode->vht_mcs_set[1] = 0xff;
6497 6878 : mode->vht_mcs_set[4] = 0xff;
6498 6878 : mode->vht_mcs_set[5] = 0xff;
6499 :
6500 6878 : *(phy_info->num_modes) += 1;
6501 6878 : phy_info->last_mode = nl_band->nla_type;
6502 6878 : phy_info->last_chan_idx = 0;
6503 : } else
6504 137560 : mode = &phy_info->modes[*(phy_info->num_modes) - 1];
6505 :
6506 144438 : nla_parse(tb_band, NL80211_BAND_ATTR_MAX, nla_data(nl_band),
6507 : nla_len(nl_band), NULL);
6508 :
6509 144438 : phy_info_ht_capa(mode, tb_band[NL80211_BAND_ATTR_HT_CAPA],
6510 : tb_band[NL80211_BAND_ATTR_HT_AMPDU_FACTOR],
6511 : tb_band[NL80211_BAND_ATTR_HT_AMPDU_DENSITY],
6512 : tb_band[NL80211_BAND_ATTR_HT_MCS_SET]);
6513 144438 : phy_info_vht_capa(mode, tb_band[NL80211_BAND_ATTR_VHT_CAPA],
6514 : tb_band[NL80211_BAND_ATTR_VHT_MCS_SET]);
6515 144438 : ret = phy_info_freqs(phy_info, mode, tb_band[NL80211_BAND_ATTR_FREQS]);
6516 144438 : if (ret != NL_OK)
6517 0 : return ret;
6518 144438 : ret = phy_info_rates(mode, tb_band[NL80211_BAND_ATTR_RATES]);
6519 144438 : if (ret != NL_OK)
6520 0 : return ret;
6521 :
6522 144438 : return NL_OK;
6523 : }
6524 :
6525 :
6526 182267 : static int phy_info_handler(struct nl_msg *msg, void *arg)
6527 : {
6528 : struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
6529 182267 : struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
6530 182267 : struct phy_info_arg *phy_info = arg;
6531 : struct nlattr *nl_band;
6532 : int rem_band;
6533 :
6534 182267 : nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
6535 : genlmsg_attrlen(gnlh, 0), NULL);
6536 :
6537 182267 : if (!tb_msg[NL80211_ATTR_WIPHY_BANDS])
6538 34390 : return NL_SKIP;
6539 :
6540 292315 : nla_for_each_nested(nl_band, tb_msg[NL80211_ATTR_WIPHY_BANDS], rem_band)
6541 : {
6542 144438 : int res = phy_info_band(phy_info, nl_band);
6543 144438 : if (res != NL_OK)
6544 0 : return res;
6545 : }
6546 :
6547 147877 : return NL_SKIP;
6548 : }
6549 :
6550 :
6551 : static struct hostapd_hw_modes *
6552 3439 : wpa_driver_nl80211_postprocess_modes(struct hostapd_hw_modes *modes,
6553 : u16 *num_modes)
6554 : {
6555 : u16 m;
6556 3439 : struct hostapd_hw_modes *mode11g = NULL, *nmodes, *mode;
6557 3439 : int i, mode11g_idx = -1;
6558 :
6559 : /* heuristic to set up modes */
6560 10317 : for (m = 0; m < *num_modes; m++) {
6561 6878 : if (!modes[m].num_channels)
6562 0 : continue;
6563 6878 : if (modes[m].channels[0].freq < 4000) {
6564 3439 : modes[m].mode = HOSTAPD_MODE_IEEE80211B;
6565 30951 : for (i = 0; i < modes[m].num_rates; i++) {
6566 30951 : if (modes[m].rates[i] > 200) {
6567 3439 : modes[m].mode = HOSTAPD_MODE_IEEE80211G;
6568 3439 : break;
6569 : }
6570 : }
6571 3439 : } else if (modes[m].channels[0].freq > 50000)
6572 0 : modes[m].mode = HOSTAPD_MODE_IEEE80211AD;
6573 : else
6574 3439 : modes[m].mode = HOSTAPD_MODE_IEEE80211A;
6575 : }
6576 :
6577 : /* If only 802.11g mode is included, use it to construct matching
6578 : * 802.11b mode data. */
6579 :
6580 10317 : for (m = 0; m < *num_modes; m++) {
6581 6878 : if (modes[m].mode == HOSTAPD_MODE_IEEE80211B)
6582 0 : return modes; /* 802.11b already included */
6583 6878 : if (modes[m].mode == HOSTAPD_MODE_IEEE80211G)
6584 3439 : mode11g_idx = m;
6585 : }
6586 :
6587 3439 : if (mode11g_idx < 0)
6588 0 : return modes; /* 2.4 GHz band not supported at all */
6589 :
6590 3439 : nmodes = os_realloc_array(modes, *num_modes + 1, sizeof(*nmodes));
6591 3439 : if (nmodes == NULL)
6592 0 : return modes; /* Could not add 802.11b mode */
6593 :
6594 3439 : mode = &nmodes[*num_modes];
6595 3439 : os_memset(mode, 0, sizeof(*mode));
6596 3439 : (*num_modes)++;
6597 3439 : modes = nmodes;
6598 :
6599 3439 : mode->mode = HOSTAPD_MODE_IEEE80211B;
6600 :
6601 3439 : mode11g = &modes[mode11g_idx];
6602 3439 : mode->num_channels = mode11g->num_channels;
6603 3439 : mode->channels = os_malloc(mode11g->num_channels *
6604 : sizeof(struct hostapd_channel_data));
6605 3439 : if (mode->channels == NULL) {
6606 0 : (*num_modes)--;
6607 0 : return modes; /* Could not add 802.11b mode */
6608 : }
6609 3439 : os_memcpy(mode->channels, mode11g->channels,
6610 : mode11g->num_channels * sizeof(struct hostapd_channel_data));
6611 :
6612 3439 : mode->num_rates = 0;
6613 3439 : mode->rates = os_malloc(4 * sizeof(int));
6614 3439 : if (mode->rates == NULL) {
6615 0 : os_free(mode->channels);
6616 0 : (*num_modes)--;
6617 0 : return modes; /* Could not add 802.11b mode */
6618 : }
6619 :
6620 13756 : for (i = 0; i < mode11g->num_rates; i++) {
6621 20634 : if (mode11g->rates[i] != 10 && mode11g->rates[i] != 20 &&
6622 10317 : mode11g->rates[i] != 55 && mode11g->rates[i] != 110)
6623 0 : continue;
6624 13756 : mode->rates[mode->num_rates] = mode11g->rates[i];
6625 13756 : mode->num_rates++;
6626 13756 : if (mode->num_rates == 4)
6627 3439 : break;
6628 : }
6629 :
6630 3439 : if (mode->num_rates == 0) {
6631 0 : os_free(mode->channels);
6632 0 : os_free(mode->rates);
6633 0 : (*num_modes)--;
6634 0 : return modes; /* No 802.11b rates */
6635 : }
6636 :
6637 3439 : wpa_printf(MSG_DEBUG, "nl80211: Added 802.11b mode based on 802.11g "
6638 : "information");
6639 :
6640 3439 : return modes;
6641 : }
6642 :
6643 :
6644 34424 : static void nl80211_set_ht40_mode(struct hostapd_hw_modes *mode, int start,
6645 : int end)
6646 : {
6647 : int c;
6648 :
6649 688480 : for (c = 0; c < mode->num_channels; c++) {
6650 654056 : struct hostapd_channel_data *chan = &mode->channels[c];
6651 654056 : if (chan->freq - 10 >= start && chan->freq + 10 <= end)
6652 76582 : chan->flag |= HOSTAPD_CHAN_HT40;
6653 : }
6654 34424 : }
6655 :
6656 :
6657 41020 : static void nl80211_set_ht40_mode_sec(struct hostapd_hw_modes *mode, int start,
6658 : int end)
6659 : {
6660 : int c;
6661 :
6662 820400 : for (c = 0; c < mode->num_channels; c++) {
6663 779380 : struct hostapd_channel_data *chan = &mode->channels[c];
6664 779380 : if (!(chan->flag & HOSTAPD_CHAN_HT40))
6665 323120 : continue;
6666 456260 : if (chan->freq - 30 >= start && chan->freq - 10 <= end)
6667 55956 : chan->flag |= HOSTAPD_CHAN_HT40MINUS;
6668 456260 : if (chan->freq + 10 >= start && chan->freq + 30 <= end)
6669 55956 : chan->flag |= HOSTAPD_CHAN_HT40PLUS;
6670 : }
6671 41020 : }
6672 :
6673 :
6674 20510 : static void nl80211_reg_rule_max_eirp(u32 start, u32 end, u32 max_eirp,
6675 : struct phy_info_arg *results)
6676 : {
6677 : u16 m;
6678 :
6679 61530 : for (m = 0; m < *results->num_modes; m++) {
6680 : int c;
6681 41020 : struct hostapd_hw_modes *mode = &results->modes[m];
6682 :
6683 820400 : for (c = 0; c < mode->num_channels; c++) {
6684 779380 : struct hostapd_channel_data *chan = &mode->channels[c];
6685 1185784 : if ((u32) chan->freq - 10 >= start &&
6686 406404 : (u32) chan->freq + 10 <= end)
6687 79880 : chan->max_tx_power = max_eirp;
6688 : }
6689 : }
6690 20510 : }
6691 :
6692 :
6693 17212 : static void nl80211_reg_rule_ht40(u32 start, u32 end,
6694 : struct phy_info_arg *results)
6695 : {
6696 : u16 m;
6697 :
6698 51636 : for (m = 0; m < *results->num_modes; m++) {
6699 34424 : if (!(results->modes[m].ht_capab &
6700 : HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
6701 0 : continue;
6702 34424 : nl80211_set_ht40_mode(&results->modes[m], start, end);
6703 : }
6704 17212 : }
6705 :
6706 :
6707 20510 : static void nl80211_reg_rule_sec(struct nlattr *tb[],
6708 : struct phy_info_arg *results)
6709 : {
6710 : u32 start, end, max_bw;
6711 : u16 m;
6712 :
6713 41020 : if (tb[NL80211_ATTR_FREQ_RANGE_START] == NULL ||
6714 41020 : tb[NL80211_ATTR_FREQ_RANGE_END] == NULL ||
6715 20510 : tb[NL80211_ATTR_FREQ_RANGE_MAX_BW] == NULL)
6716 0 : return;
6717 :
6718 20510 : start = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]) / 1000;
6719 20510 : end = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]) / 1000;
6720 20510 : max_bw = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]) / 1000;
6721 :
6722 20510 : if (max_bw < 20)
6723 0 : return;
6724 :
6725 61530 : for (m = 0; m < *results->num_modes; m++) {
6726 41020 : if (!(results->modes[m].ht_capab &
6727 : HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
6728 0 : continue;
6729 41020 : nl80211_set_ht40_mode_sec(&results->modes[m], start, end);
6730 : }
6731 : }
6732 :
6733 :
6734 20908 : static void nl80211_set_vht_mode(struct hostapd_hw_modes *mode, int start,
6735 : int end)
6736 : {
6737 : int c;
6738 :
6739 418160 : for (c = 0; c < mode->num_channels; c++) {
6740 397252 : struct hostapd_channel_data *chan = &mode->channels[c];
6741 397252 : if (chan->freq - 10 >= start && chan->freq + 70 <= end)
6742 10947 : chan->flag |= HOSTAPD_CHAN_VHT_10_70;
6743 :
6744 397252 : if (chan->freq - 30 >= start && chan->freq + 50 <= end)
6745 10955 : chan->flag |= HOSTAPD_CHAN_VHT_30_50;
6746 :
6747 397252 : if (chan->freq - 50 >= start && chan->freq + 30 <= end)
6748 10955 : chan->flag |= HOSTAPD_CHAN_VHT_50_30;
6749 :
6750 397252 : if (chan->freq - 70 >= start && chan->freq + 10 <= end)
6751 10947 : chan->flag |= HOSTAPD_CHAN_VHT_70_10;
6752 : }
6753 20908 : }
6754 :
6755 :
6756 20510 : static void nl80211_reg_rule_vht(struct nlattr *tb[],
6757 : struct phy_info_arg *results)
6758 : {
6759 : u32 start, end, max_bw;
6760 : u16 m;
6761 :
6762 41020 : if (tb[NL80211_ATTR_FREQ_RANGE_START] == NULL ||
6763 41020 : tb[NL80211_ATTR_FREQ_RANGE_END] == NULL ||
6764 20510 : tb[NL80211_ATTR_FREQ_RANGE_MAX_BW] == NULL)
6765 0 : return;
6766 :
6767 20510 : start = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]) / 1000;
6768 20510 : end = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]) / 1000;
6769 20510 : max_bw = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]) / 1000;
6770 :
6771 20510 : if (max_bw < 80)
6772 10056 : return;
6773 :
6774 31362 : for (m = 0; m < *results->num_modes; m++) {
6775 20908 : if (!(results->modes[m].ht_capab &
6776 : HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
6777 0 : continue;
6778 : /* TODO: use a real VHT support indication */
6779 20908 : if (!results->modes[m].vht_capab)
6780 0 : continue;
6781 :
6782 20908 : nl80211_set_vht_mode(&results->modes[m], start, end);
6783 : }
6784 : }
6785 :
6786 :
6787 0 : static const char * dfs_domain_name(enum nl80211_dfs_regions region)
6788 : {
6789 0 : switch (region) {
6790 : case NL80211_DFS_UNSET:
6791 0 : return "DFS-UNSET";
6792 : case NL80211_DFS_FCC:
6793 0 : return "DFS-FCC";
6794 : case NL80211_DFS_ETSI:
6795 0 : return "DFS-ETSI";
6796 : case NL80211_DFS_JP:
6797 0 : return "DFS-JP";
6798 : default:
6799 0 : return "DFS-invalid";
6800 : }
6801 : }
6802 :
6803 :
6804 3439 : static int nl80211_get_reg(struct nl_msg *msg, void *arg)
6805 : {
6806 3439 : struct phy_info_arg *results = arg;
6807 : struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
6808 3439 : struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
6809 : struct nlattr *nl_rule;
6810 : struct nlattr *tb_rule[NL80211_FREQUENCY_ATTR_MAX + 1];
6811 : int rem_rule;
6812 : static struct nla_policy reg_policy[NL80211_FREQUENCY_ATTR_MAX + 1] = {
6813 : [NL80211_ATTR_REG_RULE_FLAGS] = { .type = NLA_U32 },
6814 : [NL80211_ATTR_FREQ_RANGE_START] = { .type = NLA_U32 },
6815 : [NL80211_ATTR_FREQ_RANGE_END] = { .type = NLA_U32 },
6816 : [NL80211_ATTR_FREQ_RANGE_MAX_BW] = { .type = NLA_U32 },
6817 : [NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN] = { .type = NLA_U32 },
6818 : [NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 },
6819 : };
6820 :
6821 3439 : nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
6822 : genlmsg_attrlen(gnlh, 0), NULL);
6823 6878 : if (!tb_msg[NL80211_ATTR_REG_ALPHA2] ||
6824 3439 : !tb_msg[NL80211_ATTR_REG_RULES]) {
6825 0 : wpa_printf(MSG_DEBUG, "nl80211: No regulatory information "
6826 : "available");
6827 0 : return NL_SKIP;
6828 : }
6829 :
6830 3439 : if (tb_msg[NL80211_ATTR_DFS_REGION]) {
6831 : enum nl80211_dfs_regions dfs_domain;
6832 0 : dfs_domain = nla_get_u8(tb_msg[NL80211_ATTR_DFS_REGION]);
6833 0 : wpa_printf(MSG_DEBUG, "nl80211: Regulatory information - country=%s (%s)",
6834 0 : (char *) nla_data(tb_msg[NL80211_ATTR_REG_ALPHA2]),
6835 : dfs_domain_name(dfs_domain));
6836 : } else {
6837 3439 : wpa_printf(MSG_DEBUG, "nl80211: Regulatory information - country=%s",
6838 3439 : (char *) nla_data(tb_msg[NL80211_ATTR_REG_ALPHA2]));
6839 : }
6840 :
6841 23949 : nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule)
6842 : {
6843 20510 : u32 start, end, max_eirp = 0, max_bw = 0, flags = 0;
6844 41020 : nla_parse(tb_rule, NL80211_FREQUENCY_ATTR_MAX,
6845 20510 : nla_data(nl_rule), nla_len(nl_rule), reg_policy);
6846 41020 : if (tb_rule[NL80211_ATTR_FREQ_RANGE_START] == NULL ||
6847 20510 : tb_rule[NL80211_ATTR_FREQ_RANGE_END] == NULL)
6848 0 : continue;
6849 20510 : start = nla_get_u32(tb_rule[NL80211_ATTR_FREQ_RANGE_START]) / 1000;
6850 20510 : end = nla_get_u32(tb_rule[NL80211_ATTR_FREQ_RANGE_END]) / 1000;
6851 20510 : if (tb_rule[NL80211_ATTR_POWER_RULE_MAX_EIRP])
6852 20510 : max_eirp = nla_get_u32(tb_rule[NL80211_ATTR_POWER_RULE_MAX_EIRP]) / 100;
6853 20510 : if (tb_rule[NL80211_ATTR_FREQ_RANGE_MAX_BW])
6854 20510 : max_bw = nla_get_u32(tb_rule[NL80211_ATTR_FREQ_RANGE_MAX_BW]) / 1000;
6855 20510 : if (tb_rule[NL80211_ATTR_REG_RULE_FLAGS])
6856 20510 : flags = nla_get_u32(tb_rule[NL80211_ATTR_REG_RULE_FLAGS]);
6857 :
6858 164080 : wpa_printf(MSG_DEBUG, "nl80211: %u-%u @ %u MHz %u mBm%s%s%s%s%s%s%s%s",
6859 : start, end, max_bw, max_eirp,
6860 20510 : flags & NL80211_RRF_NO_OFDM ? " (no OFDM)" : "",
6861 20510 : flags & NL80211_RRF_NO_CCK ? " (no CCK)" : "",
6862 20510 : flags & NL80211_RRF_NO_INDOOR ? " (no indoor)" : "",
6863 20510 : flags & NL80211_RRF_NO_OUTDOOR ? " (no outdoor)" :
6864 : "",
6865 20510 : flags & NL80211_RRF_DFS ? " (DFS)" : "",
6866 20510 : flags & NL80211_RRF_PTP_ONLY ? " (PTP only)" : "",
6867 20510 : flags & NL80211_RRF_PTMP_ONLY ? " (PTMP only)" : "",
6868 20510 : flags & NL80211_RRF_NO_IR ? " (no IR)" : "");
6869 20510 : if (max_bw >= 40)
6870 17212 : nl80211_reg_rule_ht40(start, end, results);
6871 20510 : if (tb_rule[NL80211_ATTR_POWER_RULE_MAX_EIRP])
6872 20510 : nl80211_reg_rule_max_eirp(start, end, max_eirp,
6873 : results);
6874 : }
6875 :
6876 23949 : nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule)
6877 : {
6878 41020 : nla_parse(tb_rule, NL80211_FREQUENCY_ATTR_MAX,
6879 20510 : nla_data(nl_rule), nla_len(nl_rule), reg_policy);
6880 20510 : nl80211_reg_rule_sec(tb_rule, results);
6881 : }
6882 :
6883 23949 : nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule)
6884 : {
6885 41020 : nla_parse(tb_rule, NL80211_FREQUENCY_ATTR_MAX,
6886 20510 : nla_data(nl_rule), nla_len(nl_rule), reg_policy);
6887 20510 : nl80211_reg_rule_vht(tb_rule, results);
6888 : }
6889 :
6890 3439 : return NL_SKIP;
6891 : }
6892 :
6893 :
6894 3439 : static int nl80211_set_regulatory_flags(struct wpa_driver_nl80211_data *drv,
6895 : struct phy_info_arg *results)
6896 : {
6897 : struct nl_msg *msg;
6898 :
6899 3439 : msg = nlmsg_alloc();
6900 3439 : if (!msg)
6901 0 : return -ENOMEM;
6902 :
6903 3439 : nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_REG);
6904 3439 : return send_and_recv_msgs(drv, msg, nl80211_get_reg, results);
6905 : }
6906 :
6907 :
6908 : static struct hostapd_hw_modes *
6909 3439 : wpa_driver_nl80211_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags)
6910 : {
6911 : u32 feat;
6912 3439 : struct i802_bss *bss = priv;
6913 3439 : struct wpa_driver_nl80211_data *drv = bss->drv;
6914 : struct nl_msg *msg;
6915 3439 : struct phy_info_arg result = {
6916 : .num_modes = num_modes,
6917 : .modes = NULL,
6918 : .last_mode = -1,
6919 : };
6920 :
6921 3439 : *num_modes = 0;
6922 3439 : *flags = 0;
6923 :
6924 3439 : msg = nlmsg_alloc();
6925 3439 : if (!msg)
6926 0 : return NULL;
6927 :
6928 3439 : feat = get_nl80211_protocol_features(drv);
6929 3439 : if (feat & NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP)
6930 3439 : nl80211_cmd(drv, msg, NLM_F_DUMP, NL80211_CMD_GET_WIPHY);
6931 : else
6932 0 : nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_WIPHY);
6933 :
6934 3439 : NLA_PUT_FLAG(msg, NL80211_ATTR_SPLIT_WIPHY_DUMP);
6935 3439 : if (nl80211_set_iface_id(msg, bss) < 0)
6936 0 : goto nla_put_failure;
6937 :
6938 3439 : if (send_and_recv_msgs(drv, msg, phy_info_handler, &result) == 0) {
6939 3439 : nl80211_set_regulatory_flags(drv, &result);
6940 3439 : return wpa_driver_nl80211_postprocess_modes(result.modes,
6941 : num_modes);
6942 : }
6943 0 : msg = NULL;
6944 : nla_put_failure:
6945 0 : nlmsg_free(msg);
6946 0 : return NULL;
6947 : }
6948 :
6949 :
6950 24 : static int wpa_driver_nl80211_send_mntr(struct wpa_driver_nl80211_data *drv,
6951 : const void *data, size_t len,
6952 : int encrypt, int noack)
6953 : {
6954 24 : __u8 rtap_hdr[] = {
6955 : 0x00, 0x00, /* radiotap version */
6956 : 0x0e, 0x00, /* radiotap length */
6957 : 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
6958 : IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
6959 : 0x00, /* padding */
6960 : 0x00, 0x00, /* RX and TX flags to indicate that */
6961 : 0x00, 0x00, /* this is the injected frame directly */
6962 : };
6963 24 : struct iovec iov[2] = {
6964 : {
6965 : .iov_base = &rtap_hdr,
6966 : .iov_len = sizeof(rtap_hdr),
6967 : },
6968 : {
6969 : .iov_base = (void *) data,
6970 : .iov_len = len,
6971 : }
6972 : };
6973 24 : struct msghdr msg = {
6974 : .msg_name = NULL,
6975 : .msg_namelen = 0,
6976 : .msg_iov = iov,
6977 : .msg_iovlen = 2,
6978 : .msg_control = NULL,
6979 : .msg_controllen = 0,
6980 : .msg_flags = 0,
6981 : };
6982 : int res;
6983 24 : u16 txflags = 0;
6984 :
6985 24 : if (encrypt)
6986 13 : rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP;
6987 :
6988 24 : if (drv->monitor_sock < 0) {
6989 0 : wpa_printf(MSG_DEBUG, "nl80211: No monitor socket available "
6990 : "for %s", __func__);
6991 0 : return -1;
6992 : }
6993 :
6994 24 : if (noack)
6995 3 : txflags |= IEEE80211_RADIOTAP_F_TX_NOACK;
6996 24 : WPA_PUT_LE16(&rtap_hdr[12], txflags);
6997 :
6998 24 : res = sendmsg(drv->monitor_sock, &msg, 0);
6999 24 : if (res < 0) {
7000 0 : wpa_printf(MSG_INFO, "nl80211: sendmsg: %s", strerror(errno));
7001 0 : return -1;
7002 : }
7003 24 : return 0;
7004 : }
7005 :
7006 :
7007 5797 : static int wpa_driver_nl80211_send_frame(struct i802_bss *bss,
7008 : const void *data, size_t len,
7009 : int encrypt, int noack,
7010 : unsigned int freq, int no_cck,
7011 : int offchanok, unsigned int wait_time)
7012 : {
7013 5797 : struct wpa_driver_nl80211_data *drv = bss->drv;
7014 : u64 cookie;
7015 : int res;
7016 :
7017 5797 : if (freq == 0 && drv->nlmode == NL80211_IFTYPE_ADHOC) {
7018 22 : freq = nl80211_get_assoc_freq(drv);
7019 22 : wpa_printf(MSG_DEBUG,
7020 : "nl80211: send_frame - Use assoc_freq=%u for IBSS",
7021 : freq);
7022 : }
7023 5797 : if (freq == 0) {
7024 5495 : wpa_printf(MSG_DEBUG, "nl80211: send_frame - Use bss->freq=%u",
7025 : bss->freq);
7026 5495 : freq = bss->freq;
7027 : }
7028 :
7029 5797 : if (drv->use_monitor) {
7030 24 : wpa_printf(MSG_DEBUG, "nl80211: send_frame(freq=%u bss->freq=%u) -> send_mntr",
7031 : freq, bss->freq);
7032 24 : return wpa_driver_nl80211_send_mntr(drv, data, len,
7033 : encrypt, noack);
7034 : }
7035 :
7036 5773 : wpa_printf(MSG_DEBUG, "nl80211: send_frame -> send_frame_cmd");
7037 5773 : res = nl80211_send_frame_cmd(bss, freq, wait_time, data, len,
7038 : &cookie, no_cck, noack, offchanok);
7039 5773 : if (res == 0 && !noack) {
7040 : const struct ieee80211_mgmt *mgmt;
7041 : u16 fc;
7042 :
7043 3856 : mgmt = (const struct ieee80211_mgmt *) data;
7044 3856 : fc = le_to_host16(mgmt->frame_control);
7045 7712 : if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
7046 3856 : WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_ACTION) {
7047 1104 : wpa_printf(MSG_MSGDUMP,
7048 : "nl80211: Update send_action_cookie from 0x%llx to 0x%llx",
7049 : (long long unsigned int)
7050 552 : drv->send_action_cookie,
7051 : (long long unsigned int) cookie);
7052 552 : drv->send_action_cookie = cookie;
7053 : }
7054 : }
7055 :
7056 5773 : return res;
7057 : }
7058 :
7059 :
7060 6212 : static int wpa_driver_nl80211_send_mlme(struct i802_bss *bss, const u8 *data,
7061 : size_t data_len, int noack,
7062 : unsigned int freq, int no_cck,
7063 : int offchanok,
7064 : unsigned int wait_time)
7065 : {
7066 6212 : struct wpa_driver_nl80211_data *drv = bss->drv;
7067 : struct ieee80211_mgmt *mgmt;
7068 6212 : int encrypt = 1;
7069 : u16 fc;
7070 :
7071 6212 : mgmt = (struct ieee80211_mgmt *) data;
7072 6212 : fc = le_to_host16(mgmt->frame_control);
7073 6212 : wpa_printf(MSG_DEBUG, "nl80211: send_mlme - noack=%d freq=%u no_cck=%d offchanok=%d wait_time=%u fc=0x%x nlmode=%d",
7074 6212 : noack, freq, no_cck, offchanok, wait_time, fc, drv->nlmode);
7075 :
7076 11979 : if ((is_sta_interface(drv->nlmode) ||
7077 6212 : drv->nlmode == NL80211_IFTYPE_P2P_DEVICE) &&
7078 890 : WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
7079 445 : WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_PROBE_RESP) {
7080 : /*
7081 : * The use of last_mgmt_freq is a bit of a hack,
7082 : * but it works due to the single-threaded nature
7083 : * of wpa_supplicant.
7084 : */
7085 445 : if (freq == 0) {
7086 445 : wpa_printf(MSG_DEBUG, "nl80211: Use last_mgmt_freq=%d",
7087 : drv->last_mgmt_freq);
7088 445 : freq = drv->last_mgmt_freq;
7089 : }
7090 445 : return nl80211_send_frame_cmd(bss, freq, 0,
7091 : data, data_len, NULL, 1, noack,
7092 : 1);
7093 : }
7094 :
7095 5767 : if (drv->device_ap_sme && is_ap_interface(drv->nlmode)) {
7096 0 : if (freq == 0) {
7097 0 : wpa_printf(MSG_DEBUG, "nl80211: Use bss->freq=%d",
7098 : bss->freq);
7099 0 : freq = bss->freq;
7100 : }
7101 0 : return nl80211_send_frame_cmd(bss, freq,
7102 0 : (int) freq == bss->freq ? 0 :
7103 : wait_time,
7104 : data, data_len,
7105 : &drv->send_action_cookie,
7106 : no_cck, noack, offchanok);
7107 : }
7108 :
7109 11534 : if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
7110 5767 : WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_AUTH) {
7111 : /*
7112 : * Only one of the authentication frame types is encrypted.
7113 : * In order for static WEP encryption to work properly (i.e.,
7114 : * to not encrypt the frame), we need to tell mac80211 about
7115 : * the frames that must not be encrypted.
7116 : */
7117 1070 : u16 auth_alg = le_to_host16(mgmt->u.auth.auth_alg);
7118 1070 : u16 auth_trans = le_to_host16(mgmt->u.auth.auth_transaction);
7119 1070 : if (auth_alg != WLAN_AUTH_SHARED_KEY || auth_trans != 3)
7120 1070 : encrypt = 0;
7121 : }
7122 :
7123 5767 : wpa_printf(MSG_DEBUG, "nl80211: send_mlme -> send_frame");
7124 5767 : return wpa_driver_nl80211_send_frame(bss, data, data_len, encrypt,
7125 : noack, freq, no_cck, offchanok,
7126 : wait_time);
7127 : }
7128 :
7129 :
7130 1648 : static int nl80211_set_bss(struct i802_bss *bss, int cts, int preamble,
7131 : int slot, int ht_opmode, int ap_isolate,
7132 : int *basic_rates)
7133 : {
7134 1648 : struct wpa_driver_nl80211_data *drv = bss->drv;
7135 : struct nl_msg *msg;
7136 :
7137 1648 : msg = nlmsg_alloc();
7138 1648 : if (!msg)
7139 0 : return -ENOMEM;
7140 :
7141 1648 : nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_BSS);
7142 :
7143 1648 : if (cts >= 0)
7144 1648 : NLA_PUT_U8(msg, NL80211_ATTR_BSS_CTS_PROT, cts);
7145 1648 : if (preamble >= 0)
7146 1648 : NLA_PUT_U8(msg, NL80211_ATTR_BSS_SHORT_PREAMBLE, preamble);
7147 1648 : if (slot >= 0)
7148 1594 : NLA_PUT_U8(msg, NL80211_ATTR_BSS_SHORT_SLOT_TIME, slot);
7149 1648 : if (ht_opmode >= 0)
7150 1606 : NLA_PUT_U16(msg, NL80211_ATTR_BSS_HT_OPMODE, ht_opmode);
7151 1648 : if (ap_isolate >= 0)
7152 1648 : NLA_PUT_U8(msg, NL80211_ATTR_AP_ISOLATE, ap_isolate);
7153 :
7154 1648 : if (basic_rates) {
7155 : u8 rates[NL80211_MAX_SUPP_RATES];
7156 1648 : u8 rates_len = 0;
7157 : int i;
7158 :
7159 9000 : for (i = 0; i < NL80211_MAX_SUPP_RATES && basic_rates[i] >= 0;
7160 5704 : i++)
7161 5704 : rates[rates_len++] = basic_rates[i] / 5;
7162 :
7163 1648 : NLA_PUT(msg, NL80211_ATTR_BSS_BASIC_RATES, rates_len, rates);
7164 : }
7165 :
7166 1648 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(bss->ifname));
7167 :
7168 1648 : return send_and_recv_msgs(drv, msg, NULL, NULL);
7169 : nla_put_failure:
7170 0 : nlmsg_free(msg);
7171 0 : return -ENOBUFS;
7172 : }
7173 :
7174 :
7175 0 : static int wpa_driver_nl80211_set_acl(void *priv,
7176 : struct hostapd_acl_params *params)
7177 : {
7178 0 : struct i802_bss *bss = priv;
7179 0 : struct wpa_driver_nl80211_data *drv = bss->drv;
7180 : struct nl_msg *msg;
7181 : struct nlattr *acl;
7182 : unsigned int i;
7183 0 : int ret = 0;
7184 :
7185 0 : if (!(drv->capa.max_acl_mac_addrs))
7186 0 : return -ENOTSUP;
7187 :
7188 0 : if (params->num_mac_acl > drv->capa.max_acl_mac_addrs)
7189 0 : return -ENOTSUP;
7190 :
7191 0 : msg = nlmsg_alloc();
7192 0 : if (!msg)
7193 0 : return -ENOMEM;
7194 :
7195 0 : wpa_printf(MSG_DEBUG, "nl80211: Set %s ACL (num_mac_acl=%u)",
7196 0 : params->acl_policy ? "Accept" : "Deny", params->num_mac_acl);
7197 :
7198 0 : nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_MAC_ACL);
7199 :
7200 0 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
7201 :
7202 0 : NLA_PUT_U32(msg, NL80211_ATTR_ACL_POLICY, params->acl_policy ?
7203 : NL80211_ACL_POLICY_DENY_UNLESS_LISTED :
7204 : NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED);
7205 :
7206 0 : acl = nla_nest_start(msg, NL80211_ATTR_MAC_ADDRS);
7207 0 : if (acl == NULL)
7208 0 : goto nla_put_failure;
7209 :
7210 0 : for (i = 0; i < params->num_mac_acl; i++)
7211 0 : NLA_PUT(msg, i + 1, ETH_ALEN, params->mac_acl[i].addr);
7212 :
7213 0 : nla_nest_end(msg, acl);
7214 :
7215 0 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
7216 0 : msg = NULL;
7217 0 : if (ret) {
7218 0 : wpa_printf(MSG_DEBUG, "nl80211: Failed to set MAC ACL: %d (%s)",
7219 : ret, strerror(-ret));
7220 : }
7221 :
7222 : nla_put_failure:
7223 0 : nlmsg_free(msg);
7224 :
7225 0 : return ret;
7226 : }
7227 :
7228 :
7229 1648 : static int wpa_driver_nl80211_set_ap(void *priv,
7230 : struct wpa_driver_ap_params *params)
7231 : {
7232 1648 : struct i802_bss *bss = priv;
7233 1648 : struct wpa_driver_nl80211_data *drv = bss->drv;
7234 : struct nl_msg *msg;
7235 1648 : u8 cmd = NL80211_CMD_NEW_BEACON;
7236 : int ret;
7237 : int beacon_set;
7238 1648 : int ifindex = if_nametoindex(bss->ifname);
7239 : int num_suites;
7240 : u32 suites[10], suite;
7241 : u32 ver;
7242 :
7243 1648 : beacon_set = bss->beacon_set;
7244 :
7245 1648 : msg = nlmsg_alloc();
7246 1648 : if (!msg)
7247 0 : return -ENOMEM;
7248 :
7249 1648 : wpa_printf(MSG_DEBUG, "nl80211: Set beacon (beacon_set=%d)",
7250 : beacon_set);
7251 1648 : if (beacon_set)
7252 972 : cmd = NL80211_CMD_SET_BEACON;
7253 :
7254 1648 : nl80211_cmd(drv, msg, 0, cmd);
7255 3296 : wpa_hexdump(MSG_DEBUG, "nl80211: Beacon head",
7256 1648 : params->head, params->head_len);
7257 1648 : NLA_PUT(msg, NL80211_ATTR_BEACON_HEAD, params->head_len, params->head);
7258 3296 : wpa_hexdump(MSG_DEBUG, "nl80211: Beacon tail",
7259 1648 : params->tail, params->tail_len);
7260 1648 : NLA_PUT(msg, NL80211_ATTR_BEACON_TAIL, params->tail_len, params->tail);
7261 1648 : wpa_printf(MSG_DEBUG, "nl80211: ifindex=%d", ifindex);
7262 1648 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
7263 1648 : wpa_printf(MSG_DEBUG, "nl80211: beacon_int=%d", params->beacon_int);
7264 1648 : NLA_PUT_U32(msg, NL80211_ATTR_BEACON_INTERVAL, params->beacon_int);
7265 1648 : wpa_printf(MSG_DEBUG, "nl80211: dtim_period=%d", params->dtim_period);
7266 1648 : NLA_PUT_U32(msg, NL80211_ATTR_DTIM_PERIOD, params->dtim_period);
7267 3296 : wpa_hexdump_ascii(MSG_DEBUG, "nl80211: ssid",
7268 1648 : params->ssid, params->ssid_len);
7269 1648 : NLA_PUT(msg, NL80211_ATTR_SSID, params->ssid_len,
7270 : params->ssid);
7271 1648 : if (params->proberesp && params->proberesp_len) {
7272 0 : wpa_hexdump(MSG_DEBUG, "nl80211: proberesp (offload)",
7273 0 : params->proberesp, params->proberesp_len);
7274 0 : NLA_PUT(msg, NL80211_ATTR_PROBE_RESP, params->proberesp_len,
7275 : params->proberesp);
7276 : }
7277 1648 : switch (params->hide_ssid) {
7278 : case NO_SSID_HIDING:
7279 1645 : wpa_printf(MSG_DEBUG, "nl80211: hidden SSID not in use");
7280 1645 : NLA_PUT_U32(msg, NL80211_ATTR_HIDDEN_SSID,
7281 : NL80211_HIDDEN_SSID_NOT_IN_USE);
7282 1645 : break;
7283 : case HIDDEN_SSID_ZERO_LEN:
7284 2 : wpa_printf(MSG_DEBUG, "nl80211: hidden SSID zero len");
7285 2 : NLA_PUT_U32(msg, NL80211_ATTR_HIDDEN_SSID,
7286 : NL80211_HIDDEN_SSID_ZERO_LEN);
7287 2 : break;
7288 : case HIDDEN_SSID_ZERO_CONTENTS:
7289 1 : wpa_printf(MSG_DEBUG, "nl80211: hidden SSID zero contents");
7290 1 : NLA_PUT_U32(msg, NL80211_ATTR_HIDDEN_SSID,
7291 : NL80211_HIDDEN_SSID_ZERO_CONTENTS);
7292 1 : break;
7293 : }
7294 1648 : wpa_printf(MSG_DEBUG, "nl80211: privacy=%d", params->privacy);
7295 1648 : if (params->privacy)
7296 1440 : NLA_PUT_FLAG(msg, NL80211_ATTR_PRIVACY);
7297 1648 : wpa_printf(MSG_DEBUG, "nl80211: auth_algs=0x%x", params->auth_algs);
7298 1648 : if ((params->auth_algs & (WPA_AUTH_ALG_OPEN | WPA_AUTH_ALG_SHARED)) ==
7299 : (WPA_AUTH_ALG_OPEN | WPA_AUTH_ALG_SHARED)) {
7300 : /* Leave out the attribute */
7301 916 : } else if (params->auth_algs & WPA_AUTH_ALG_SHARED)
7302 3 : NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE,
7303 : NL80211_AUTHTYPE_SHARED_KEY);
7304 : else
7305 913 : NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE,
7306 : NL80211_AUTHTYPE_OPEN_SYSTEM);
7307 :
7308 1648 : wpa_printf(MSG_DEBUG, "nl80211: wpa_version=0x%x", params->wpa_version);
7309 1648 : ver = 0;
7310 1648 : if (params->wpa_version & WPA_PROTO_WPA)
7311 77 : ver |= NL80211_WPA_VERSION_1;
7312 1648 : if (params->wpa_version & WPA_PROTO_RSN)
7313 1405 : ver |= NL80211_WPA_VERSION_2;
7314 1648 : if (ver)
7315 1424 : NLA_PUT_U32(msg, NL80211_ATTR_WPA_VERSIONS, ver);
7316 :
7317 1648 : wpa_printf(MSG_DEBUG, "nl80211: key_mgmt_suites=0x%x",
7318 : params->key_mgmt_suites);
7319 1648 : num_suites = 0;
7320 1648 : if (params->key_mgmt_suites & WPA_KEY_MGMT_IEEE8021X)
7321 222 : suites[num_suites++] = WLAN_AKM_SUITE_8021X;
7322 1648 : if (params->key_mgmt_suites & WPA_KEY_MGMT_PSK)
7323 1390 : suites[num_suites++] = WLAN_AKM_SUITE_PSK;
7324 1648 : if (num_suites) {
7325 1600 : NLA_PUT(msg, NL80211_ATTR_AKM_SUITES,
7326 : num_suites * sizeof(u32), suites);
7327 : }
7328 :
7329 1870 : if (params->key_mgmt_suites & WPA_KEY_MGMT_IEEE8021X &&
7330 222 : params->pairwise_ciphers & (WPA_CIPHER_WEP104 | WPA_CIPHER_WEP40))
7331 0 : NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT);
7332 :
7333 1648 : wpa_printf(MSG_DEBUG, "nl80211: pairwise_ciphers=0x%x",
7334 : params->pairwise_ciphers);
7335 1648 : num_suites = wpa_cipher_to_cipher_suites(params->pairwise_ciphers,
7336 : suites, ARRAY_SIZE(suites));
7337 1648 : if (num_suites) {
7338 1426 : NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES_PAIRWISE,
7339 : num_suites * sizeof(u32), suites);
7340 : }
7341 :
7342 1648 : wpa_printf(MSG_DEBUG, "nl80211: group_cipher=0x%x",
7343 : params->group_cipher);
7344 1648 : suite = wpa_cipher_to_cipher_suite(params->group_cipher);
7345 1648 : if (suite)
7346 1442 : NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP, suite);
7347 :
7348 1648 : if (params->beacon_ies) {
7349 1648 : wpa_hexdump_buf(MSG_DEBUG, "nl80211: beacon_ies",
7350 : params->beacon_ies);
7351 1648 : NLA_PUT(msg, NL80211_ATTR_IE, wpabuf_len(params->beacon_ies),
7352 : wpabuf_head(params->beacon_ies));
7353 : }
7354 1648 : if (params->proberesp_ies) {
7355 1648 : wpa_hexdump_buf(MSG_DEBUG, "nl80211: proberesp_ies",
7356 : params->proberesp_ies);
7357 1648 : NLA_PUT(msg, NL80211_ATTR_IE_PROBE_RESP,
7358 : wpabuf_len(params->proberesp_ies),
7359 : wpabuf_head(params->proberesp_ies));
7360 : }
7361 1648 : if (params->assocresp_ies) {
7362 1648 : wpa_hexdump_buf(MSG_DEBUG, "nl80211: assocresp_ies",
7363 : params->assocresp_ies);
7364 1648 : NLA_PUT(msg, NL80211_ATTR_IE_ASSOC_RESP,
7365 : wpabuf_len(params->assocresp_ies),
7366 : wpabuf_head(params->assocresp_ies));
7367 : }
7368 :
7369 1648 : if (drv->capa.flags & WPA_DRIVER_FLAGS_INACTIVITY_TIMER) {
7370 0 : wpa_printf(MSG_DEBUG, "nl80211: ap_max_inactivity=%d",
7371 : params->ap_max_inactivity);
7372 0 : NLA_PUT_U16(msg, NL80211_ATTR_INACTIVITY_TIMEOUT,
7373 : params->ap_max_inactivity);
7374 : }
7375 :
7376 1648 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
7377 1648 : if (ret) {
7378 0 : wpa_printf(MSG_DEBUG, "nl80211: Beacon set failed: %d (%s)",
7379 : ret, strerror(-ret));
7380 : } else {
7381 1648 : bss->beacon_set = 1;
7382 1648 : nl80211_set_bss(bss, params->cts_protect, params->preamble,
7383 : params->short_slot_time, params->ht_opmode,
7384 : params->isolate, params->basic_rates);
7385 2620 : if (beacon_set && params->freq &&
7386 972 : params->freq->bandwidth != bss->bandwidth) {
7387 12 : wpa_printf(MSG_DEBUG,
7388 : "nl80211: Update BSS %s bandwidth: %d -> %d",
7389 6 : bss->ifname, bss->bandwidth,
7390 6 : params->freq->bandwidth);
7391 6 : ret = nl80211_set_channel(bss, params->freq, 1);
7392 12 : if (ret) {
7393 0 : wpa_printf(MSG_DEBUG,
7394 : "nl80211: Frequency set failed: %d (%s)",
7395 : ret, strerror(-ret));
7396 : } else {
7397 6 : wpa_printf(MSG_DEBUG,
7398 : "nl80211: Frequency set succeeded for ht2040 coex");
7399 6 : bss->bandwidth = params->freq->bandwidth;
7400 : }
7401 1642 : } else if (!beacon_set) {
7402 : /*
7403 : * cfg80211 updates the driver on frequence change in AP
7404 : * mode only at the point when beaconing is started, so
7405 : * set the initial value here.
7406 : */
7407 676 : bss->bandwidth = params->freq->bandwidth;
7408 : }
7409 : }
7410 1648 : return ret;
7411 : nla_put_failure:
7412 0 : nlmsg_free(msg);
7413 0 : return -ENOBUFS;
7414 : }
7415 :
7416 :
7417 796 : static int nl80211_put_freq_params(struct nl_msg *msg,
7418 : struct hostapd_freq_params *freq)
7419 : {
7420 796 : NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq->freq);
7421 796 : if (freq->vht_enabled) {
7422 11 : switch (freq->bandwidth) {
7423 : case 20:
7424 9 : NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH,
7425 : NL80211_CHAN_WIDTH_20);
7426 9 : break;
7427 : case 40:
7428 0 : NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH,
7429 : NL80211_CHAN_WIDTH_40);
7430 0 : break;
7431 : case 80:
7432 2 : if (freq->center_freq2)
7433 0 : NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH,
7434 : NL80211_CHAN_WIDTH_80P80);
7435 : else
7436 2 : NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH,
7437 : NL80211_CHAN_WIDTH_80);
7438 2 : break;
7439 : case 160:
7440 0 : NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH,
7441 : NL80211_CHAN_WIDTH_160);
7442 0 : break;
7443 : default:
7444 0 : return -EINVAL;
7445 : }
7446 11 : NLA_PUT_U32(msg, NL80211_ATTR_CENTER_FREQ1, freq->center_freq1);
7447 11 : if (freq->center_freq2)
7448 0 : NLA_PUT_U32(msg, NL80211_ATTR_CENTER_FREQ2,
7449 : freq->center_freq2);
7450 785 : } else if (freq->ht_enabled) {
7451 653 : switch (freq->sec_channel_offset) {
7452 : case -1:
7453 11 : NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
7454 : NL80211_CHAN_HT40MINUS);
7455 11 : break;
7456 : case 1:
7457 12 : NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
7458 : NL80211_CHAN_HT40PLUS);
7459 12 : break;
7460 : default:
7461 630 : NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
7462 : NL80211_CHAN_HT20);
7463 630 : break;
7464 : }
7465 : }
7466 796 : return 0;
7467 :
7468 : nla_put_failure:
7469 0 : return -ENOBUFS;
7470 : }
7471 :
7472 :
7473 796 : static int nl80211_set_channel(struct i802_bss *bss,
7474 : struct hostapd_freq_params *freq, int set_chan)
7475 : {
7476 796 : struct wpa_driver_nl80211_data *drv = bss->drv;
7477 : struct nl_msg *msg;
7478 : int ret;
7479 :
7480 796 : wpa_printf(MSG_DEBUG,
7481 : "nl80211: Set freq %d (ht_enabled=%d, vht_enabled=%d, bandwidth=%d MHz, cf1=%d MHz, cf2=%d MHz)",
7482 : freq->freq, freq->ht_enabled, freq->vht_enabled,
7483 : freq->bandwidth, freq->center_freq1, freq->center_freq2);
7484 796 : msg = nlmsg_alloc();
7485 796 : if (!msg)
7486 0 : return -1;
7487 :
7488 796 : nl80211_cmd(drv, msg, 0, set_chan ? NL80211_CMD_SET_CHANNEL :
7489 : NL80211_CMD_SET_WIPHY);
7490 :
7491 796 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
7492 796 : if (nl80211_put_freq_params(msg, freq) < 0)
7493 0 : goto nla_put_failure;
7494 :
7495 796 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
7496 796 : msg = NULL;
7497 796 : if (ret == 0) {
7498 795 : bss->freq = freq->freq;
7499 795 : return 0;
7500 : }
7501 1 : wpa_printf(MSG_DEBUG, "nl80211: Failed to set channel (freq=%d): "
7502 : "%d (%s)", freq->freq, ret, strerror(-ret));
7503 : nla_put_failure:
7504 1 : nlmsg_free(msg);
7505 1 : return -1;
7506 : }
7507 :
7508 :
7509 7027 : static u32 sta_flags_nl80211(int flags)
7510 : {
7511 7027 : u32 f = 0;
7512 :
7513 7027 : if (flags & WPA_STA_AUTHORIZED)
7514 3277 : f |= BIT(NL80211_STA_FLAG_AUTHORIZED);
7515 7027 : if (flags & WPA_STA_WMM)
7516 3052 : f |= BIT(NL80211_STA_FLAG_WME);
7517 7027 : if (flags & WPA_STA_SHORT_PREAMBLE)
7518 3024 : f |= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE);
7519 7027 : if (flags & WPA_STA_MFP)
7520 1084 : f |= BIT(NL80211_STA_FLAG_MFP);
7521 7027 : if (flags & WPA_STA_TDLS_PEER)
7522 87 : f |= BIT(NL80211_STA_FLAG_TDLS_PEER);
7523 :
7524 7027 : return f;
7525 : }
7526 :
7527 :
7528 1107 : static int wpa_driver_nl80211_sta_add(void *priv,
7529 : struct hostapd_sta_add_params *params)
7530 : {
7531 1107 : struct i802_bss *bss = priv;
7532 1107 : struct wpa_driver_nl80211_data *drv = bss->drv;
7533 : struct nl_msg *msg;
7534 : struct nl80211_sta_flag_update upd;
7535 1107 : int ret = -ENOBUFS;
7536 :
7537 1194 : if ((params->flags & WPA_STA_TDLS_PEER) &&
7538 87 : !(drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT))
7539 0 : return -EOPNOTSUPP;
7540 :
7541 1107 : msg = nlmsg_alloc();
7542 1107 : if (!msg)
7543 0 : return -ENOMEM;
7544 :
7545 7749 : wpa_printf(MSG_DEBUG, "nl80211: %s STA " MACSTR,
7546 7749 : params->set ? "Set" : "Add", MAC2STR(params->addr));
7547 1107 : nl80211_cmd(drv, msg, 0, params->set ? NL80211_CMD_SET_STATION :
7548 : NL80211_CMD_NEW_STATION);
7549 :
7550 1107 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(bss->ifname));
7551 1107 : NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->addr);
7552 1107 : NLA_PUT(msg, NL80211_ATTR_STA_SUPPORTED_RATES, params->supp_rates_len,
7553 : params->supp_rates);
7554 1107 : wpa_hexdump(MSG_DEBUG, " * supported rates", params->supp_rates,
7555 : params->supp_rates_len);
7556 1107 : if (!params->set) {
7557 1068 : if (params->aid) {
7558 1020 : wpa_printf(MSG_DEBUG, " * aid=%u", params->aid);
7559 1020 : NLA_PUT_U16(msg, NL80211_ATTR_STA_AID, params->aid);
7560 : } else {
7561 : /*
7562 : * cfg80211 validates that AID is non-zero, so we have
7563 : * to make this a non-zero value for the TDLS case where
7564 : * a dummy STA entry is used for now.
7565 : */
7566 48 : wpa_printf(MSG_DEBUG, " * aid=1 (TDLS workaround)");
7567 48 : NLA_PUT_U16(msg, NL80211_ATTR_STA_AID, 1);
7568 : }
7569 1068 : wpa_printf(MSG_DEBUG, " * listen_interval=%u",
7570 1068 : params->listen_interval);
7571 1068 : NLA_PUT_U16(msg, NL80211_ATTR_STA_LISTEN_INTERVAL,
7572 : params->listen_interval);
7573 39 : } else if (params->aid && (params->flags & WPA_STA_TDLS_PEER)) {
7574 0 : wpa_printf(MSG_DEBUG, " * peer_aid=%u", params->aid);
7575 0 : NLA_PUT_U16(msg, NL80211_ATTR_PEER_AID, params->aid);
7576 : }
7577 1107 : if (params->ht_capabilities) {
7578 998 : wpa_hexdump(MSG_DEBUG, " * ht_capabilities",
7579 998 : (u8 *) params->ht_capabilities,
7580 : sizeof(*params->ht_capabilities));
7581 998 : NLA_PUT(msg, NL80211_ATTR_HT_CAPABILITY,
7582 : sizeof(*params->ht_capabilities),
7583 : params->ht_capabilities);
7584 : }
7585 :
7586 1107 : if (params->vht_capabilities) {
7587 3 : wpa_hexdump(MSG_DEBUG, " * vht_capabilities",
7588 3 : (u8 *) params->vht_capabilities,
7589 : sizeof(*params->vht_capabilities));
7590 3 : NLA_PUT(msg, NL80211_ATTR_VHT_CAPABILITY,
7591 : sizeof(*params->vht_capabilities),
7592 : params->vht_capabilities);
7593 : }
7594 :
7595 1107 : if (params->vht_opmode_enabled) {
7596 0 : wpa_printf(MSG_DEBUG, " * opmode=%u", params->vht_opmode);
7597 0 : NLA_PUT_U8(msg, NL80211_ATTR_OPMODE_NOTIF,
7598 : params->vht_opmode);
7599 : }
7600 :
7601 1107 : wpa_printf(MSG_DEBUG, " * capability=0x%x", params->capability);
7602 1107 : NLA_PUT_U16(msg, NL80211_ATTR_STA_CAPABILITY, params->capability);
7603 :
7604 1107 : if (params->ext_capab) {
7605 78 : wpa_hexdump(MSG_DEBUG, " * ext_capab",
7606 39 : params->ext_capab, params->ext_capab_len);
7607 39 : NLA_PUT(msg, NL80211_ATTR_STA_EXT_CAPABILITY,
7608 : params->ext_capab_len, params->ext_capab);
7609 : }
7610 :
7611 1107 : if (params->supp_channels) {
7612 0 : wpa_hexdump(MSG_DEBUG, " * supported channels",
7613 0 : params->supp_channels, params->supp_channels_len);
7614 0 : NLA_PUT(msg, NL80211_ATTR_STA_SUPPORTED_CHANNELS,
7615 : params->supp_channels_len, params->supp_channels);
7616 : }
7617 :
7618 1107 : if (params->supp_oper_classes) {
7619 0 : wpa_hexdump(MSG_DEBUG, " * supported operating classes",
7620 0 : params->supp_oper_classes,
7621 : params->supp_oper_classes_len);
7622 0 : NLA_PUT(msg, NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES,
7623 : params->supp_oper_classes_len,
7624 : params->supp_oper_classes);
7625 : }
7626 :
7627 1107 : os_memset(&upd, 0, sizeof(upd));
7628 1107 : upd.mask = sta_flags_nl80211(params->flags);
7629 1107 : upd.set = upd.mask;
7630 1107 : wpa_printf(MSG_DEBUG, " * flags set=0x%x mask=0x%x",
7631 : upd.set, upd.mask);
7632 1107 : NLA_PUT(msg, NL80211_ATTR_STA_FLAGS2, sizeof(upd), &upd);
7633 :
7634 1107 : if (params->flags & WPA_STA_WMM) {
7635 1016 : struct nlattr *wme = nla_nest_start(msg, NL80211_ATTR_STA_WME);
7636 :
7637 1016 : if (!wme)
7638 0 : goto nla_put_failure;
7639 :
7640 1016 : wpa_printf(MSG_DEBUG, " * qosinfo=0x%x", params->qosinfo);
7641 1016 : NLA_PUT_U8(msg, NL80211_STA_WME_UAPSD_QUEUES,
7642 : params->qosinfo & WMM_QOSINFO_STA_AC_MASK);
7643 1016 : NLA_PUT_U8(msg, NL80211_STA_WME_MAX_SP,
7644 : (params->qosinfo >> WMM_QOSINFO_STA_SP_SHIFT) &
7645 : WMM_QOSINFO_STA_SP_MASK);
7646 1016 : nla_nest_end(msg, wme);
7647 : }
7648 :
7649 1107 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
7650 1107 : msg = NULL;
7651 1107 : if (ret)
7652 0 : wpa_printf(MSG_DEBUG, "nl80211: NL80211_CMD_%s_STATION "
7653 0 : "result: %d (%s)", params->set ? "SET" : "NEW", ret,
7654 : strerror(-ret));
7655 1107 : if (ret == -EEXIST)
7656 0 : ret = 0;
7657 : nla_put_failure:
7658 1107 : nlmsg_free(msg);
7659 1107 : return ret;
7660 : }
7661 :
7662 :
7663 1915 : static int wpa_driver_nl80211_sta_remove(struct i802_bss *bss, const u8 *addr)
7664 : {
7665 1915 : struct wpa_driver_nl80211_data *drv = bss->drv;
7666 : struct nl_msg *msg;
7667 : int ret;
7668 :
7669 1915 : msg = nlmsg_alloc();
7670 1915 : if (!msg)
7671 0 : return -ENOMEM;
7672 :
7673 1915 : nl80211_cmd(drv, msg, 0, NL80211_CMD_DEL_STATION);
7674 :
7675 1915 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
7676 : if_nametoindex(bss->ifname));
7677 1915 : NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
7678 :
7679 1915 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
7680 15320 : wpa_printf(MSG_DEBUG, "nl80211: sta_remove -> DEL_STATION %s " MACSTR
7681 : " --> %d (%s)",
7682 13405 : bss->ifname, MAC2STR(addr), ret, strerror(-ret));
7683 1915 : if (ret == -ENOENT)
7684 1004 : return 0;
7685 911 : return ret;
7686 : nla_put_failure:
7687 0 : nlmsg_free(msg);
7688 0 : return -ENOBUFS;
7689 : }
7690 :
7691 :
7692 70 : static void nl80211_remove_iface(struct wpa_driver_nl80211_data *drv,
7693 : int ifidx)
7694 : {
7695 : struct nl_msg *msg;
7696 : struct wpa_driver_nl80211_data *drv2;
7697 :
7698 70 : wpa_printf(MSG_DEBUG, "nl80211: Remove interface ifindex=%d", ifidx);
7699 :
7700 : /* stop listening for EAPOL on this interface */
7701 140 : dl_list_for_each(drv2, &drv->global->interfaces,
7702 : struct wpa_driver_nl80211_data, list)
7703 70 : del_ifidx(drv2, ifidx);
7704 :
7705 70 : msg = nlmsg_alloc();
7706 70 : if (!msg)
7707 0 : goto nla_put_failure;
7708 :
7709 70 : nl80211_cmd(drv, msg, 0, NL80211_CMD_DEL_INTERFACE);
7710 70 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifidx);
7711 :
7712 70 : if (send_and_recv_msgs(drv, msg, NULL, NULL) == 0)
7713 140 : return;
7714 0 : msg = NULL;
7715 : nla_put_failure:
7716 0 : nlmsg_free(msg);
7717 0 : wpa_printf(MSG_ERROR, "Failed to remove interface (ifidx=%d)", ifidx);
7718 : }
7719 :
7720 :
7721 1802 : static const char * nl80211_iftype_str(enum nl80211_iftype mode)
7722 : {
7723 1802 : switch (mode) {
7724 : case NL80211_IFTYPE_ADHOC:
7725 17 : return "ADHOC";
7726 : case NL80211_IFTYPE_STATION:
7727 895 : return "STATION";
7728 : case NL80211_IFTYPE_AP:
7729 576 : return "AP";
7730 : case NL80211_IFTYPE_AP_VLAN:
7731 12 : return "AP_VLAN";
7732 : case NL80211_IFTYPE_WDS:
7733 0 : return "WDS";
7734 : case NL80211_IFTYPE_MONITOR:
7735 3 : return "MONITOR";
7736 : case NL80211_IFTYPE_MESH_POINT:
7737 0 : return "MESH_POINT";
7738 : case NL80211_IFTYPE_P2P_CLIENT:
7739 148 : return "P2P_CLIENT";
7740 : case NL80211_IFTYPE_P2P_GO:
7741 151 : return "P2P_GO";
7742 : case NL80211_IFTYPE_P2P_DEVICE:
7743 0 : return "P2P_DEVICE";
7744 : default:
7745 0 : return "unknown";
7746 : }
7747 : }
7748 :
7749 :
7750 71 : static int nl80211_create_iface_once(struct wpa_driver_nl80211_data *drv,
7751 : const char *ifname,
7752 : enum nl80211_iftype iftype,
7753 : const u8 *addr, int wds,
7754 : int (*handler)(struct nl_msg *, void *),
7755 : void *arg)
7756 : {
7757 : struct nl_msg *msg;
7758 : int ifidx;
7759 71 : int ret = -ENOBUFS;
7760 :
7761 71 : wpa_printf(MSG_DEBUG, "nl80211: Create interface iftype %d (%s)",
7762 : iftype, nl80211_iftype_str(iftype));
7763 :
7764 71 : msg = nlmsg_alloc();
7765 71 : if (!msg)
7766 0 : return -1;
7767 :
7768 71 : nl80211_cmd(drv, msg, 0, NL80211_CMD_NEW_INTERFACE);
7769 71 : if (nl80211_set_iface_id(msg, drv->first_bss) < 0)
7770 0 : goto nla_put_failure;
7771 71 : NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, ifname);
7772 71 : NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, iftype);
7773 :
7774 71 : if (iftype == NL80211_IFTYPE_MONITOR) {
7775 : struct nlattr *flags;
7776 :
7777 3 : flags = nla_nest_start(msg, NL80211_ATTR_MNTR_FLAGS);
7778 3 : if (!flags)
7779 0 : goto nla_put_failure;
7780 :
7781 3 : NLA_PUT_FLAG(msg, NL80211_MNTR_FLAG_COOK_FRAMES);
7782 :
7783 3 : nla_nest_end(msg, flags);
7784 68 : } else if (wds) {
7785 1 : NLA_PUT_U8(msg, NL80211_ATTR_4ADDR, wds);
7786 : }
7787 :
7788 : /*
7789 : * Tell cfg80211 that the interface belongs to the socket that created
7790 : * it, and the interface should be deleted when the socket is closed.
7791 : */
7792 71 : NLA_PUT_FLAG(msg, NL80211_ATTR_IFACE_SOCKET_OWNER);
7793 :
7794 71 : ret = send_and_recv_msgs(drv, msg, handler, arg);
7795 71 : msg = NULL;
7796 71 : if (ret) {
7797 : nla_put_failure:
7798 1 : nlmsg_free(msg);
7799 1 : wpa_printf(MSG_ERROR, "Failed to create interface %s: %d (%s)",
7800 : ifname, ret, strerror(-ret));
7801 1 : return ret;
7802 : }
7803 :
7804 70 : if (iftype == NL80211_IFTYPE_P2P_DEVICE)
7805 0 : return 0;
7806 :
7807 70 : ifidx = if_nametoindex(ifname);
7808 70 : wpa_printf(MSG_DEBUG, "nl80211: New interface %s created: ifindex=%d",
7809 : ifname, ifidx);
7810 :
7811 70 : if (ifidx <= 0)
7812 0 : return -1;
7813 :
7814 : /*
7815 : * Some virtual interfaces need to process EAPOL packets and events on
7816 : * the parent interface. This is used mainly with hostapd.
7817 : */
7818 70 : if (drv->hostapd ||
7819 41 : iftype == NL80211_IFTYPE_AP_VLAN ||
7820 41 : iftype == NL80211_IFTYPE_WDS ||
7821 : iftype == NL80211_IFTYPE_MONITOR) {
7822 : /* start listening for EAPOL on this interface */
7823 32 : add_ifidx(drv, ifidx);
7824 : }
7825 :
7826 99 : if (addr && iftype != NL80211_IFTYPE_MONITOR &&
7827 29 : linux_set_ifhwaddr(drv->global->ioctl_sock, ifname, addr)) {
7828 0 : nl80211_remove_iface(drv, ifidx);
7829 0 : return -1;
7830 : }
7831 :
7832 70 : return ifidx;
7833 : }
7834 :
7835 :
7836 70 : static int nl80211_create_iface(struct wpa_driver_nl80211_data *drv,
7837 : const char *ifname, enum nl80211_iftype iftype,
7838 : const u8 *addr, int wds,
7839 : int (*handler)(struct nl_msg *, void *),
7840 : void *arg, int use_existing)
7841 : {
7842 : int ret;
7843 :
7844 70 : ret = nl80211_create_iface_once(drv, ifname, iftype, addr, wds, handler,
7845 : arg);
7846 :
7847 : /* if error occurred and interface exists already */
7848 70 : if (ret == -ENFILE && if_nametoindex(ifname)) {
7849 1 : if (use_existing) {
7850 0 : wpa_printf(MSG_DEBUG, "nl80211: Continue using existing interface %s",
7851 : ifname);
7852 0 : if (addr && iftype != NL80211_IFTYPE_MONITOR &&
7853 0 : linux_set_ifhwaddr(drv->global->ioctl_sock, ifname,
7854 0 : addr) < 0 &&
7855 0 : (linux_set_iface_flags(drv->global->ioctl_sock,
7856 0 : ifname, 0) < 0 ||
7857 0 : linux_set_ifhwaddr(drv->global->ioctl_sock, ifname,
7858 0 : addr) < 0 ||
7859 0 : linux_set_iface_flags(drv->global->ioctl_sock,
7860 : ifname, 1) < 0))
7861 0 : return -1;
7862 0 : return -ENFILE;
7863 : }
7864 1 : wpa_printf(MSG_INFO, "Try to remove and re-create %s", ifname);
7865 :
7866 : /* Try to remove the interface that was already there. */
7867 1 : nl80211_remove_iface(drv, if_nametoindex(ifname));
7868 :
7869 : /* Try to create the interface again */
7870 1 : ret = nl80211_create_iface_once(drv, ifname, iftype, addr,
7871 : wds, handler, arg);
7872 : }
7873 :
7874 70 : if (ret >= 0 && is_p2p_net_interface(iftype))
7875 38 : nl80211_disable_11b_rates(drv, ret, 1);
7876 :
7877 70 : return ret;
7878 : }
7879 :
7880 :
7881 18 : static void handle_tx_callback(void *ctx, u8 *buf, size_t len, int ok)
7882 : {
7883 : struct ieee80211_hdr *hdr;
7884 : u16 fc;
7885 : union wpa_event_data event;
7886 :
7887 18 : hdr = (struct ieee80211_hdr *) buf;
7888 18 : fc = le_to_host16(hdr->frame_control);
7889 :
7890 18 : os_memset(&event, 0, sizeof(event));
7891 18 : event.tx_status.type = WLAN_FC_GET_TYPE(fc);
7892 18 : event.tx_status.stype = WLAN_FC_GET_STYPE(fc);
7893 18 : event.tx_status.dst = hdr->addr1;
7894 18 : event.tx_status.data = buf;
7895 18 : event.tx_status.data_len = len;
7896 18 : event.tx_status.ack = ok;
7897 18 : wpa_supplicant_event(ctx, EVENT_TX_STATUS, &event);
7898 18 : }
7899 :
7900 :
7901 0 : static void from_unknown_sta(struct wpa_driver_nl80211_data *drv,
7902 : u8 *buf, size_t len)
7903 : {
7904 0 : struct ieee80211_hdr *hdr = (void *)buf;
7905 : u16 fc;
7906 : union wpa_event_data event;
7907 :
7908 0 : if (len < sizeof(*hdr))
7909 0 : return;
7910 :
7911 0 : fc = le_to_host16(hdr->frame_control);
7912 :
7913 0 : os_memset(&event, 0, sizeof(event));
7914 0 : event.rx_from_unknown.bssid = get_hdr_bssid(hdr, len);
7915 0 : event.rx_from_unknown.addr = hdr->addr2;
7916 0 : event.rx_from_unknown.wds = (fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) ==
7917 : (WLAN_FC_FROMDS | WLAN_FC_TODS);
7918 0 : wpa_supplicant_event(drv->ctx, EVENT_RX_FROM_UNKNOWN, &event);
7919 : }
7920 :
7921 :
7922 13 : static void handle_frame(struct wpa_driver_nl80211_data *drv,
7923 : u8 *buf, size_t len, int datarate, int ssi_signal)
7924 : {
7925 : struct ieee80211_hdr *hdr;
7926 : u16 fc;
7927 : union wpa_event_data event;
7928 :
7929 13 : hdr = (struct ieee80211_hdr *) buf;
7930 13 : fc = le_to_host16(hdr->frame_control);
7931 :
7932 13 : switch (WLAN_FC_GET_TYPE(fc)) {
7933 : case WLAN_FC_TYPE_MGMT:
7934 13 : os_memset(&event, 0, sizeof(event));
7935 13 : event.rx_mgmt.frame = buf;
7936 13 : event.rx_mgmt.frame_len = len;
7937 13 : event.rx_mgmt.datarate = datarate;
7938 13 : event.rx_mgmt.ssi_signal = ssi_signal;
7939 13 : wpa_supplicant_event(drv->ctx, EVENT_RX_MGMT, &event);
7940 13 : break;
7941 : case WLAN_FC_TYPE_CTRL:
7942 : /* can only get here with PS-Poll frames */
7943 0 : wpa_printf(MSG_DEBUG, "CTRL");
7944 0 : from_unknown_sta(drv, buf, len);
7945 0 : break;
7946 : case WLAN_FC_TYPE_DATA:
7947 0 : from_unknown_sta(drv, buf, len);
7948 0 : break;
7949 : }
7950 13 : }
7951 :
7952 :
7953 31 : static void handle_monitor_read(int sock, void *eloop_ctx, void *sock_ctx)
7954 : {
7955 31 : struct wpa_driver_nl80211_data *drv = eloop_ctx;
7956 : int len;
7957 : unsigned char buf[3000];
7958 : struct ieee80211_radiotap_iterator iter;
7959 : int ret;
7960 31 : int datarate = 0, ssi_signal = 0;
7961 31 : int injected = 0, failed = 0, rxflags = 0;
7962 :
7963 31 : len = recv(sock, buf, sizeof(buf), 0);
7964 31 : if (len < 0) {
7965 0 : wpa_printf(MSG_ERROR, "nl80211: Monitor socket recv failed: %s",
7966 0 : strerror(errno));
7967 0 : return;
7968 : }
7969 :
7970 31 : if (ieee80211_radiotap_iterator_init(&iter, (void *) buf, len, NULL)) {
7971 0 : wpa_printf(MSG_INFO, "nl80211: received invalid radiotap frame");
7972 0 : return;
7973 : }
7974 :
7975 : while (1) {
7976 176 : ret = ieee80211_radiotap_iterator_next(&iter);
7977 176 : if (ret == -ENOENT)
7978 31 : break;
7979 145 : if (ret) {
7980 0 : wpa_printf(MSG_INFO, "nl80211: received invalid radiotap frame (%d)",
7981 : ret);
7982 0 : return;
7983 : }
7984 145 : switch (iter.this_arg_index) {
7985 : case IEEE80211_RADIOTAP_FLAGS:
7986 13 : if (*iter.this_arg & IEEE80211_RADIOTAP_F_FCS)
7987 0 : len -= 4;
7988 13 : break;
7989 : case IEEE80211_RADIOTAP_RX_FLAGS:
7990 13 : rxflags = 1;
7991 13 : break;
7992 : case IEEE80211_RADIOTAP_TX_FLAGS:
7993 18 : injected = 1;
7994 18 : failed = le_to_host16((*(uint16_t *) iter.this_arg)) &
7995 : IEEE80211_RADIOTAP_F_TX_FAIL;
7996 18 : break;
7997 : case IEEE80211_RADIOTAP_DATA_RETRIES:
7998 18 : break;
7999 : case IEEE80211_RADIOTAP_CHANNEL:
8000 : /* TODO: convert from freq/flags to channel number */
8001 13 : break;
8002 : case IEEE80211_RADIOTAP_RATE:
8003 27 : datarate = *iter.this_arg * 5;
8004 27 : break;
8005 : case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
8006 13 : ssi_signal = (s8) *iter.this_arg;
8007 13 : break;
8008 : }
8009 145 : }
8010 :
8011 31 : if (rxflags && injected)
8012 0 : return;
8013 :
8014 31 : if (!injected)
8015 13 : handle_frame(drv, buf + iter._max_length,
8016 13 : len - iter._max_length, datarate, ssi_signal);
8017 : else
8018 36 : handle_tx_callback(drv->ctx, buf + iter._max_length,
8019 18 : len - iter._max_length, !failed);
8020 : }
8021 :
8022 :
8023 : /*
8024 : * we post-process the filter code later and rewrite
8025 : * this to the offset to the last instruction
8026 : */
8027 : #define PASS 0xFF
8028 : #define FAIL 0xFE
8029 :
8030 : static struct sock_filter msock_filter_insns[] = {
8031 : /*
8032 : * do a little-endian load of the radiotap length field
8033 : */
8034 : /* load lower byte into A */
8035 : BPF_STMT(BPF_LD | BPF_B | BPF_ABS, 2),
8036 : /* put it into X (== index register) */
8037 : BPF_STMT(BPF_MISC| BPF_TAX, 0),
8038 : /* load upper byte into A */
8039 : BPF_STMT(BPF_LD | BPF_B | BPF_ABS, 3),
8040 : /* left-shift it by 8 */
8041 : BPF_STMT(BPF_ALU | BPF_LSH | BPF_K, 8),
8042 : /* or with X */
8043 : BPF_STMT(BPF_ALU | BPF_OR | BPF_X, 0),
8044 : /* put result into X */
8045 : BPF_STMT(BPF_MISC| BPF_TAX, 0),
8046 :
8047 : /*
8048 : * Allow management frames through, this also gives us those
8049 : * management frames that we sent ourselves with status
8050 : */
8051 : /* load the lower byte of the IEEE 802.11 frame control field */
8052 : BPF_STMT(BPF_LD | BPF_B | BPF_IND, 0),
8053 : /* mask off frame type and version */
8054 : BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0xF),
8055 : /* accept frame if it's both 0, fall through otherwise */
8056 : BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, PASS, 0),
8057 :
8058 : /*
8059 : * TODO: add a bit to radiotap RX flags that indicates
8060 : * that the sending station is not associated, then
8061 : * add a filter here that filters on our DA and that flag
8062 : * to allow us to deauth frames to that bad station.
8063 : *
8064 : * For now allow all To DS data frames through.
8065 : */
8066 : /* load the IEEE 802.11 frame control field */
8067 : BPF_STMT(BPF_LD | BPF_H | BPF_IND, 0),
8068 : /* mask off frame type, version and DS status */
8069 : BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x0F03),
8070 : /* accept frame if version 0, type 2 and To DS, fall through otherwise
8071 : */
8072 : BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x0801, PASS, 0),
8073 :
8074 : #if 0
8075 : /*
8076 : * drop non-data frames
8077 : */
8078 : /* load the lower byte of the frame control field */
8079 : BPF_STMT(BPF_LD | BPF_B | BPF_IND, 0),
8080 : /* mask off QoS bit */
8081 : BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x0c),
8082 : /* drop non-data frames */
8083 : BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 8, 0, FAIL),
8084 : #endif
8085 : /* load the upper byte of the frame control field */
8086 : BPF_STMT(BPF_LD | BPF_B | BPF_IND, 1),
8087 : /* mask off toDS/fromDS */
8088 : BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x03),
8089 : /* accept WDS frames */
8090 : BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 3, PASS, 0),
8091 :
8092 : /*
8093 : * add header length to index
8094 : */
8095 : /* load the lower byte of the frame control field */
8096 : BPF_STMT(BPF_LD | BPF_B | BPF_IND, 0),
8097 : /* mask off QoS bit */
8098 : BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x80),
8099 : /* right shift it by 6 to give 0 or 2 */
8100 : BPF_STMT(BPF_ALU | BPF_RSH | BPF_K, 6),
8101 : /* add data frame header length */
8102 : BPF_STMT(BPF_ALU | BPF_ADD | BPF_K, 24),
8103 : /* add index, was start of 802.11 header */
8104 : BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0),
8105 : /* move to index, now start of LL header */
8106 : BPF_STMT(BPF_MISC | BPF_TAX, 0),
8107 :
8108 : /*
8109 : * Accept empty data frames, we use those for
8110 : * polling activity.
8111 : */
8112 : BPF_STMT(BPF_LD | BPF_W | BPF_LEN, 0),
8113 : BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_X, 0, PASS, 0),
8114 :
8115 : /*
8116 : * Accept EAPOL frames
8117 : */
8118 : BPF_STMT(BPF_LD | BPF_W | BPF_IND, 0),
8119 : BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0xAAAA0300, 0, FAIL),
8120 : BPF_STMT(BPF_LD | BPF_W | BPF_IND, 4),
8121 : BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x0000888E, PASS, FAIL),
8122 :
8123 : /* keep these last two statements or change the code below */
8124 : /* return 0 == "DROP" */
8125 : BPF_STMT(BPF_RET | BPF_K, 0),
8126 : /* return ~0 == "keep all" */
8127 : BPF_STMT(BPF_RET | BPF_K, ~0),
8128 : };
8129 :
8130 : static struct sock_fprog msock_filter = {
8131 : .len = ARRAY_SIZE(msock_filter_insns),
8132 : .filter = msock_filter_insns,
8133 : };
8134 :
8135 :
8136 3 : static int add_monitor_filter(int s)
8137 : {
8138 : int idx;
8139 :
8140 : /* rewrite all PASS/FAIL jump offsets */
8141 90 : for (idx = 0; idx < msock_filter.len; idx++) {
8142 87 : struct sock_filter *insn = &msock_filter_insns[idx];
8143 :
8144 87 : if (BPF_CLASS(insn->code) == BPF_JMP) {
8145 18 : if (insn->code == (BPF_JMP|BPF_JA)) {
8146 0 : if (insn->k == PASS)
8147 0 : insn->k = msock_filter.len - idx - 2;
8148 0 : else if (insn->k == FAIL)
8149 0 : insn->k = msock_filter.len - idx - 3;
8150 : }
8151 :
8152 18 : if (insn->jt == PASS)
8153 5 : insn->jt = msock_filter.len - idx - 2;
8154 13 : else if (insn->jt == FAIL)
8155 0 : insn->jt = msock_filter.len - idx - 3;
8156 :
8157 18 : if (insn->jf == PASS)
8158 0 : insn->jf = msock_filter.len - idx - 2;
8159 18 : else if (insn->jf == FAIL)
8160 2 : insn->jf = msock_filter.len - idx - 3;
8161 : }
8162 : }
8163 :
8164 3 : if (setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER,
8165 : &msock_filter, sizeof(msock_filter))) {
8166 0 : wpa_printf(MSG_ERROR, "nl80211: setsockopt(SO_ATTACH_FILTER) failed: %s",
8167 0 : strerror(errno));
8168 0 : return -1;
8169 : }
8170 :
8171 3 : return 0;
8172 : }
8173 :
8174 :
8175 625 : static void nl80211_remove_monitor_interface(
8176 : struct wpa_driver_nl80211_data *drv)
8177 : {
8178 625 : if (drv->monitor_refcount > 0)
8179 3 : drv->monitor_refcount--;
8180 625 : wpa_printf(MSG_DEBUG, "nl80211: Remove monitor interface: refcount=%d",
8181 : drv->monitor_refcount);
8182 625 : if (drv->monitor_refcount > 0)
8183 625 : return;
8184 :
8185 625 : if (drv->monitor_ifidx >= 0) {
8186 3 : nl80211_remove_iface(drv, drv->monitor_ifidx);
8187 3 : drv->monitor_ifidx = -1;
8188 : }
8189 625 : if (drv->monitor_sock >= 0) {
8190 3 : eloop_unregister_read_sock(drv->monitor_sock);
8191 3 : close(drv->monitor_sock);
8192 3 : drv->monitor_sock = -1;
8193 : }
8194 : }
8195 :
8196 :
8197 : static int
8198 3 : nl80211_create_monitor_interface(struct wpa_driver_nl80211_data *drv)
8199 : {
8200 : char buf[IFNAMSIZ];
8201 : struct sockaddr_ll ll;
8202 : int optval;
8203 : socklen_t optlen;
8204 :
8205 3 : if (drv->monitor_ifidx >= 0) {
8206 0 : drv->monitor_refcount++;
8207 0 : wpa_printf(MSG_DEBUG, "nl80211: Re-use existing monitor interface: refcount=%d",
8208 : drv->monitor_refcount);
8209 0 : return 0;
8210 : }
8211 :
8212 3 : if (os_strncmp(drv->first_bss->ifname, "p2p-", 4) == 0) {
8213 : /*
8214 : * P2P interface name is of the format p2p-%s-%d. For monitor
8215 : * interface name corresponding to P2P GO, replace "p2p-" with
8216 : * "mon-" to retain the same interface name length and to
8217 : * indicate that it is a monitor interface.
8218 : */
8219 0 : snprintf(buf, IFNAMSIZ, "mon-%s", drv->first_bss->ifname + 4);
8220 : } else {
8221 : /* Non-P2P interface with AP functionality. */
8222 3 : snprintf(buf, IFNAMSIZ, "mon.%s", drv->first_bss->ifname);
8223 : }
8224 :
8225 3 : buf[IFNAMSIZ - 1] = '\0';
8226 :
8227 3 : drv->monitor_ifidx =
8228 3 : nl80211_create_iface(drv, buf, NL80211_IFTYPE_MONITOR, NULL,
8229 : 0, NULL, NULL, 0);
8230 :
8231 3 : if (drv->monitor_ifidx == -EOPNOTSUPP) {
8232 : /*
8233 : * This is backward compatibility for a few versions of
8234 : * the kernel only that didn't advertise the right
8235 : * attributes for the only driver that then supported
8236 : * AP mode w/o monitor -- ath6kl.
8237 : */
8238 0 : wpa_printf(MSG_DEBUG, "nl80211: Driver does not support "
8239 : "monitor interface type - try to run without it");
8240 0 : drv->device_ap_sme = 1;
8241 : }
8242 :
8243 3 : if (drv->monitor_ifidx < 0)
8244 0 : return -1;
8245 :
8246 3 : if (linux_set_iface_flags(drv->global->ioctl_sock, buf, 1))
8247 0 : goto error;
8248 :
8249 3 : memset(&ll, 0, sizeof(ll));
8250 3 : ll.sll_family = AF_PACKET;
8251 3 : ll.sll_ifindex = drv->monitor_ifidx;
8252 3 : drv->monitor_sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
8253 3 : if (drv->monitor_sock < 0) {
8254 0 : wpa_printf(MSG_ERROR, "nl80211: socket[PF_PACKET,SOCK_RAW] failed: %s",
8255 0 : strerror(errno));
8256 0 : goto error;
8257 : }
8258 :
8259 3 : if (add_monitor_filter(drv->monitor_sock)) {
8260 0 : wpa_printf(MSG_INFO, "Failed to set socket filter for monitor "
8261 : "interface; do filtering in user space");
8262 : /* This works, but will cost in performance. */
8263 : }
8264 :
8265 3 : if (bind(drv->monitor_sock, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
8266 0 : wpa_printf(MSG_ERROR, "nl80211: monitor socket bind failed: %s",
8267 0 : strerror(errno));
8268 0 : goto error;
8269 : }
8270 :
8271 3 : optlen = sizeof(optval);
8272 3 : optval = 20;
8273 3 : if (setsockopt
8274 3 : (drv->monitor_sock, SOL_SOCKET, SO_PRIORITY, &optval, optlen)) {
8275 0 : wpa_printf(MSG_ERROR, "nl80211: Failed to set socket priority: %s",
8276 0 : strerror(errno));
8277 0 : goto error;
8278 : }
8279 :
8280 3 : if (eloop_register_read_sock(drv->monitor_sock, handle_monitor_read,
8281 : drv, NULL)) {
8282 0 : wpa_printf(MSG_INFO, "nl80211: Could not register monitor read socket");
8283 0 : goto error;
8284 : }
8285 :
8286 3 : drv->monitor_refcount++;
8287 3 : return 0;
8288 : error:
8289 0 : nl80211_remove_monitor_interface(drv);
8290 0 : return -1;
8291 : }
8292 :
8293 :
8294 710 : static int nl80211_setup_ap(struct i802_bss *bss)
8295 : {
8296 710 : struct wpa_driver_nl80211_data *drv = bss->drv;
8297 :
8298 2130 : wpa_printf(MSG_DEBUG, "nl80211: Setup AP(%s) - device_ap_sme=%d use_monitor=%d",
8299 2130 : bss->ifname, drv->device_ap_sme, drv->use_monitor);
8300 :
8301 : /*
8302 : * Disable Probe Request reporting unless we need it in this way for
8303 : * devices that include the AP SME, in the other case (unless using
8304 : * monitor iface) we'll get it through the nl_mgmt socket instead.
8305 : */
8306 710 : if (!drv->device_ap_sme)
8307 710 : wpa_driver_nl80211_probe_req_report(bss, 0);
8308 :
8309 710 : if (!drv->device_ap_sme && !drv->use_monitor)
8310 707 : if (nl80211_mgmt_subscribe_ap(bss))
8311 0 : return -1;
8312 :
8313 710 : if (drv->device_ap_sme && !drv->use_monitor)
8314 0 : if (nl80211_mgmt_subscribe_ap_dev_sme(bss))
8315 0 : return -1;
8316 :
8317 713 : if (!drv->device_ap_sme && drv->use_monitor &&
8318 3 : nl80211_create_monitor_interface(drv) &&
8319 0 : !drv->device_ap_sme)
8320 0 : return -1;
8321 :
8322 710 : if (drv->device_ap_sme &&
8323 0 : wpa_driver_nl80211_probe_req_report(bss, 1) < 0) {
8324 0 : wpa_printf(MSG_DEBUG, "nl80211: Failed to enable "
8325 : "Probe Request frame reporting in AP mode");
8326 : /* Try to survive without this */
8327 : }
8328 :
8329 710 : return 0;
8330 : }
8331 :
8332 :
8333 694 : static void nl80211_teardown_ap(struct i802_bss *bss)
8334 : {
8335 694 : struct wpa_driver_nl80211_data *drv = bss->drv;
8336 :
8337 2082 : wpa_printf(MSG_DEBUG, "nl80211: Teardown AP(%s) - device_ap_sme=%d use_monitor=%d",
8338 2082 : bss->ifname, drv->device_ap_sme, drv->use_monitor);
8339 694 : if (drv->device_ap_sme) {
8340 0 : wpa_driver_nl80211_probe_req_report(bss, 0);
8341 0 : if (!drv->use_monitor)
8342 0 : nl80211_mgmt_unsubscribe(bss, "AP teardown (dev SME)");
8343 694 : } else if (drv->use_monitor)
8344 3 : nl80211_remove_monitor_interface(drv);
8345 : else
8346 691 : nl80211_mgmt_unsubscribe(bss, "AP teardown");
8347 :
8348 694 : bss->beacon_set = 0;
8349 694 : }
8350 :
8351 :
8352 4761 : static int nl80211_send_eapol_data(struct i802_bss *bss,
8353 : const u8 *addr, const u8 *data,
8354 : size_t data_len)
8355 : {
8356 : struct sockaddr_ll ll;
8357 : int ret;
8358 :
8359 4761 : if (bss->drv->eapol_tx_sock < 0) {
8360 0 : wpa_printf(MSG_DEBUG, "nl80211: No socket to send EAPOL");
8361 0 : return -1;
8362 : }
8363 :
8364 4761 : os_memset(&ll, 0, sizeof(ll));
8365 4761 : ll.sll_family = AF_PACKET;
8366 4761 : ll.sll_ifindex = bss->ifindex;
8367 4761 : ll.sll_protocol = htons(ETH_P_PAE);
8368 4761 : ll.sll_halen = ETH_ALEN;
8369 4761 : os_memcpy(ll.sll_addr, addr, ETH_ALEN);
8370 4761 : ret = sendto(bss->drv->eapol_tx_sock, data, data_len, 0,
8371 : (struct sockaddr *) &ll, sizeof(ll));
8372 4761 : if (ret < 0)
8373 0 : wpa_printf(MSG_ERROR, "nl80211: EAPOL TX: %s",
8374 0 : strerror(errno));
8375 :
8376 4761 : return ret;
8377 : }
8378 :
8379 :
8380 : static const u8 rfc1042_header[6] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
8381 :
8382 4765 : static int wpa_driver_nl80211_hapd_send_eapol(
8383 : void *priv, const u8 *addr, const u8 *data,
8384 : size_t data_len, int encrypt, const u8 *own_addr, u32 flags)
8385 : {
8386 4765 : struct i802_bss *bss = priv;
8387 4765 : struct wpa_driver_nl80211_data *drv = bss->drv;
8388 : struct ieee80211_hdr *hdr;
8389 : size_t len;
8390 : u8 *pos;
8391 : int res;
8392 4765 : int qos = flags & WPA_STA_WMM;
8393 :
8394 4765 : if (drv->device_ap_sme || !drv->use_monitor)
8395 4761 : return nl80211_send_eapol_data(bss, addr, data, data_len);
8396 :
8397 4 : len = sizeof(*hdr) + (qos ? 2 : 0) + sizeof(rfc1042_header) + 2 +
8398 : data_len;
8399 4 : hdr = os_zalloc(len);
8400 4 : if (hdr == NULL) {
8401 0 : wpa_printf(MSG_INFO, "nl80211: Failed to allocate EAPOL buffer(len=%lu)",
8402 : (unsigned long) len);
8403 0 : return -1;
8404 : }
8405 :
8406 4 : hdr->frame_control =
8407 : IEEE80211_FC(WLAN_FC_TYPE_DATA, WLAN_FC_STYPE_DATA);
8408 4 : hdr->frame_control |= host_to_le16(WLAN_FC_FROMDS);
8409 4 : if (encrypt)
8410 0 : hdr->frame_control |= host_to_le16(WLAN_FC_ISWEP);
8411 4 : if (qos) {
8412 4 : hdr->frame_control |=
8413 : host_to_le16(WLAN_FC_STYPE_QOS_DATA << 4);
8414 : }
8415 :
8416 4 : memcpy(hdr->IEEE80211_DA_FROMDS, addr, ETH_ALEN);
8417 4 : memcpy(hdr->IEEE80211_BSSID_FROMDS, own_addr, ETH_ALEN);
8418 4 : memcpy(hdr->IEEE80211_SA_FROMDS, own_addr, ETH_ALEN);
8419 4 : pos = (u8 *) (hdr + 1);
8420 :
8421 4 : if (qos) {
8422 : /* Set highest priority in QoS header */
8423 4 : pos[0] = 7;
8424 4 : pos[1] = 0;
8425 4 : pos += 2;
8426 : }
8427 :
8428 4 : memcpy(pos, rfc1042_header, sizeof(rfc1042_header));
8429 4 : pos += sizeof(rfc1042_header);
8430 4 : WPA_PUT_BE16(pos, ETH_P_PAE);
8431 4 : pos += 2;
8432 4 : memcpy(pos, data, data_len);
8433 :
8434 4 : res = wpa_driver_nl80211_send_frame(bss, (u8 *) hdr, len, encrypt, 0,
8435 : 0, 0, 0, 0);
8436 4 : if (res < 0) {
8437 0 : wpa_printf(MSG_ERROR, "i802_send_eapol - packet len: %lu - "
8438 : "failed: %d (%s)",
8439 0 : (unsigned long) len, errno, strerror(errno));
8440 : }
8441 4 : os_free(hdr);
8442 :
8443 4 : return res;
8444 : }
8445 :
8446 :
8447 2960 : static int wpa_driver_nl80211_sta_set_flags(void *priv, const u8 *addr,
8448 : int total_flags,
8449 : int flags_or, int flags_and)
8450 : {
8451 2960 : struct i802_bss *bss = priv;
8452 2960 : struct wpa_driver_nl80211_data *drv = bss->drv;
8453 : struct nl_msg *msg;
8454 : struct nlattr *flags;
8455 : struct nl80211_sta_flag_update upd;
8456 :
8457 2960 : msg = nlmsg_alloc();
8458 2960 : if (!msg)
8459 0 : return -ENOMEM;
8460 :
8461 2960 : nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_STATION);
8462 :
8463 2960 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
8464 : if_nametoindex(bss->ifname));
8465 2960 : NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
8466 :
8467 : /*
8468 : * Backwards compatibility version using NL80211_ATTR_STA_FLAGS. This
8469 : * can be removed eventually.
8470 : */
8471 2960 : flags = nla_nest_start(msg, NL80211_ATTR_STA_FLAGS);
8472 2960 : if (!flags)
8473 0 : goto nla_put_failure;
8474 2960 : if (total_flags & WPA_STA_AUTHORIZED)
8475 840 : NLA_PUT_FLAG(msg, NL80211_STA_FLAG_AUTHORIZED);
8476 :
8477 2960 : if (total_flags & WPA_STA_WMM)
8478 2922 : NLA_PUT_FLAG(msg, NL80211_STA_FLAG_WME);
8479 :
8480 2960 : if (total_flags & WPA_STA_SHORT_PREAMBLE)
8481 2893 : NLA_PUT_FLAG(msg, NL80211_STA_FLAG_SHORT_PREAMBLE);
8482 :
8483 2960 : if (total_flags & WPA_STA_MFP)
8484 102 : NLA_PUT_FLAG(msg, NL80211_STA_FLAG_MFP);
8485 :
8486 2960 : if (total_flags & WPA_STA_TDLS_PEER)
8487 0 : NLA_PUT_FLAG(msg, NL80211_STA_FLAG_TDLS_PEER);
8488 :
8489 2960 : nla_nest_end(msg, flags);
8490 :
8491 2960 : os_memset(&upd, 0, sizeof(upd));
8492 2960 : upd.mask = sta_flags_nl80211(flags_or | ~flags_and);
8493 2960 : upd.set = sta_flags_nl80211(flags_or);
8494 2960 : NLA_PUT(msg, NL80211_ATTR_STA_FLAGS2, sizeof(upd), &upd);
8495 :
8496 2960 : return send_and_recv_msgs(drv, msg, NULL, NULL);
8497 : nla_put_failure:
8498 0 : nlmsg_free(msg);
8499 0 : return -ENOBUFS;
8500 : }
8501 :
8502 :
8503 127 : static int wpa_driver_nl80211_ap(struct wpa_driver_nl80211_data *drv,
8504 : struct wpa_driver_associate_params *params)
8505 : {
8506 : enum nl80211_iftype nlmode, old_mode;
8507 254 : struct hostapd_freq_params freq = {
8508 127 : .freq = params->freq,
8509 : };
8510 :
8511 127 : if (params->p2p) {
8512 118 : wpa_printf(MSG_DEBUG, "nl80211: Setup AP operations for P2P "
8513 : "group (GO)");
8514 118 : nlmode = NL80211_IFTYPE_P2P_GO;
8515 : } else
8516 9 : nlmode = NL80211_IFTYPE_AP;
8517 :
8518 127 : old_mode = drv->nlmode;
8519 127 : if (wpa_driver_nl80211_set_mode(drv->first_bss, nlmode)) {
8520 0 : nl80211_remove_monitor_interface(drv);
8521 0 : return -1;
8522 : }
8523 :
8524 127 : if (nl80211_set_channel(drv->first_bss, &freq, 0)) {
8525 1 : if (old_mode != nlmode)
8526 1 : wpa_driver_nl80211_set_mode(drv->first_bss, old_mode);
8527 1 : nl80211_remove_monitor_interface(drv);
8528 1 : return -1;
8529 : }
8530 :
8531 126 : return 0;
8532 : }
8533 :
8534 :
8535 15 : static int nl80211_leave_ibss(struct wpa_driver_nl80211_data *drv)
8536 : {
8537 : struct nl_msg *msg;
8538 15 : int ret = -1;
8539 :
8540 15 : msg = nlmsg_alloc();
8541 15 : if (!msg)
8542 0 : return -1;
8543 :
8544 15 : nl80211_cmd(drv, msg, 0, NL80211_CMD_LEAVE_IBSS);
8545 15 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
8546 15 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
8547 15 : msg = NULL;
8548 15 : if (ret) {
8549 0 : wpa_printf(MSG_DEBUG, "nl80211: Leave IBSS failed: ret=%d "
8550 : "(%s)", ret, strerror(-ret));
8551 0 : goto nla_put_failure;
8552 : }
8553 :
8554 15 : ret = 0;
8555 15 : wpa_printf(MSG_DEBUG, "nl80211: Leave IBSS request sent successfully");
8556 :
8557 : nla_put_failure:
8558 15 : if (wpa_driver_nl80211_set_mode(drv->first_bss,
8559 : NL80211_IFTYPE_STATION)) {
8560 0 : wpa_printf(MSG_INFO, "nl80211: Failed to set interface into "
8561 : "station mode");
8562 : }
8563 :
8564 15 : nlmsg_free(msg);
8565 15 : return ret;
8566 : }
8567 :
8568 :
8569 17 : static int wpa_driver_nl80211_ibss(struct wpa_driver_nl80211_data *drv,
8570 : struct wpa_driver_associate_params *params)
8571 : {
8572 : struct nl_msg *msg;
8573 17 : int ret = -1;
8574 17 : int count = 0;
8575 :
8576 17 : wpa_printf(MSG_DEBUG, "nl80211: Join IBSS (ifindex=%d)", drv->ifindex);
8577 :
8578 17 : if (wpa_driver_nl80211_set_mode(drv->first_bss,
8579 : NL80211_IFTYPE_ADHOC)) {
8580 0 : wpa_printf(MSG_INFO, "nl80211: Failed to set interface into "
8581 : "IBSS mode");
8582 0 : return -1;
8583 : }
8584 :
8585 : retry:
8586 19 : msg = nlmsg_alloc();
8587 19 : if (!msg)
8588 0 : return -1;
8589 :
8590 19 : nl80211_cmd(drv, msg, 0, NL80211_CMD_JOIN_IBSS);
8591 19 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
8592 :
8593 19 : if (params->ssid == NULL || params->ssid_len > sizeof(drv->ssid))
8594 : goto nla_put_failure;
8595 :
8596 38 : wpa_hexdump_ascii(MSG_DEBUG, " * SSID",
8597 19 : params->ssid, params->ssid_len);
8598 19 : NLA_PUT(msg, NL80211_ATTR_SSID, params->ssid_len,
8599 : params->ssid);
8600 19 : os_memcpy(drv->ssid, params->ssid, params->ssid_len);
8601 19 : drv->ssid_len = params->ssid_len;
8602 :
8603 19 : wpa_printf(MSG_DEBUG, " * freq=%d", params->freq);
8604 19 : NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq);
8605 :
8606 19 : if (params->beacon_int > 0) {
8607 4 : wpa_printf(MSG_DEBUG, " * beacon_int=%d", params->beacon_int);
8608 4 : NLA_PUT_U32(msg, NL80211_ATTR_BEACON_INTERVAL,
8609 : params->beacon_int);
8610 : }
8611 :
8612 19 : ret = nl80211_set_conn_keys(params, msg);
8613 19 : if (ret)
8614 0 : goto nla_put_failure;
8615 :
8616 19 : if (params->bssid && params->fixed_bssid) {
8617 12 : wpa_printf(MSG_DEBUG, " * BSSID=" MACSTR,
8618 12 : MAC2STR(params->bssid));
8619 2 : NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid);
8620 : }
8621 :
8622 38 : if (params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X ||
8623 28 : params->key_mgmt_suite == WPA_KEY_MGMT_PSK ||
8624 18 : params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SHA256 ||
8625 9 : params->key_mgmt_suite == WPA_KEY_MGMT_PSK_SHA256) {
8626 10 : wpa_printf(MSG_DEBUG, " * control port");
8627 10 : NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT);
8628 : }
8629 :
8630 19 : if (params->wpa_ie) {
8631 38 : wpa_hexdump(MSG_DEBUG,
8632 : " * Extra IEs for Beacon/Probe Response frames",
8633 19 : params->wpa_ie, params->wpa_ie_len);
8634 19 : NLA_PUT(msg, NL80211_ATTR_IE, params->wpa_ie_len,
8635 : params->wpa_ie);
8636 : }
8637 :
8638 19 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
8639 19 : msg = NULL;
8640 19 : if (ret) {
8641 4 : wpa_printf(MSG_DEBUG, "nl80211: Join IBSS failed: ret=%d (%s)",
8642 : ret, strerror(-ret));
8643 4 : count++;
8644 4 : if (ret == -EALREADY && count == 1) {
8645 2 : wpa_printf(MSG_DEBUG, "nl80211: Retry IBSS join after "
8646 : "forced leave");
8647 2 : nl80211_leave_ibss(drv);
8648 2 : nlmsg_free(msg);
8649 2 : goto retry;
8650 : }
8651 :
8652 2 : goto nla_put_failure;
8653 : }
8654 15 : ret = 0;
8655 15 : wpa_printf(MSG_DEBUG, "nl80211: Join IBSS request sent successfully");
8656 :
8657 : nla_put_failure:
8658 17 : nlmsg_free(msg);
8659 17 : return ret;
8660 : }
8661 :
8662 :
8663 1028 : static int nl80211_connect_common(struct wpa_driver_nl80211_data *drv,
8664 : struct wpa_driver_associate_params *params,
8665 : struct nl_msg *msg)
8666 : {
8667 1028 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
8668 :
8669 1028 : if (params->bssid) {
8670 6168 : wpa_printf(MSG_DEBUG, " * bssid=" MACSTR,
8671 6168 : MAC2STR(params->bssid));
8672 1028 : NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid);
8673 : }
8674 :
8675 1028 : if (params->bssid_hint) {
8676 78 : wpa_printf(MSG_DEBUG, " * bssid_hint=" MACSTR,
8677 78 : MAC2STR(params->bssid_hint));
8678 13 : NLA_PUT(msg, NL80211_ATTR_MAC_HINT, ETH_ALEN,
8679 : params->bssid_hint);
8680 : }
8681 :
8682 1028 : if (params->freq) {
8683 1028 : wpa_printf(MSG_DEBUG, " * freq=%d", params->freq);
8684 1028 : NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq);
8685 1028 : drv->assoc_freq = params->freq;
8686 : } else
8687 0 : drv->assoc_freq = 0;
8688 :
8689 1028 : if (params->freq_hint) {
8690 13 : wpa_printf(MSG_DEBUG, " * freq_hint=%d", params->freq_hint);
8691 13 : NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ_HINT,
8692 : params->freq_hint);
8693 : }
8694 :
8695 1028 : if (params->bg_scan_period >= 0) {
8696 0 : wpa_printf(MSG_DEBUG, " * bg scan period=%d",
8697 : params->bg_scan_period);
8698 0 : NLA_PUT_U16(msg, NL80211_ATTR_BG_SCAN_PERIOD,
8699 : params->bg_scan_period);
8700 : }
8701 :
8702 1028 : if (params->ssid) {
8703 2056 : wpa_hexdump_ascii(MSG_DEBUG, " * SSID",
8704 1028 : params->ssid, params->ssid_len);
8705 1028 : NLA_PUT(msg, NL80211_ATTR_SSID, params->ssid_len,
8706 : params->ssid);
8707 1028 : if (params->ssid_len > sizeof(drv->ssid))
8708 0 : goto nla_put_failure;
8709 1028 : os_memcpy(drv->ssid, params->ssid, params->ssid_len);
8710 1028 : drv->ssid_len = params->ssid_len;
8711 : }
8712 :
8713 1028 : wpa_hexdump(MSG_DEBUG, " * IEs", params->wpa_ie, params->wpa_ie_len);
8714 1028 : if (params->wpa_ie)
8715 1028 : NLA_PUT(msg, NL80211_ATTR_IE, params->wpa_ie_len,
8716 : params->wpa_ie);
8717 :
8718 1028 : if (params->wpa_proto) {
8719 988 : enum nl80211_wpa_versions ver = 0;
8720 :
8721 988 : if (params->wpa_proto & WPA_PROTO_WPA)
8722 23 : ver |= NL80211_WPA_VERSION_1;
8723 988 : if (params->wpa_proto & WPA_PROTO_RSN)
8724 963 : ver |= NL80211_WPA_VERSION_2;
8725 :
8726 988 : wpa_printf(MSG_DEBUG, " * WPA Versions 0x%x", ver);
8727 988 : NLA_PUT_U32(msg, NL80211_ATTR_WPA_VERSIONS, ver);
8728 : }
8729 :
8730 1028 : if (params->pairwise_suite != WPA_CIPHER_NONE) {
8731 654 : u32 cipher = wpa_cipher_to_cipher_suite(params->pairwise_suite);
8732 654 : wpa_printf(MSG_DEBUG, " * pairwise=0x%x", cipher);
8733 654 : NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITES_PAIRWISE, cipher);
8734 : }
8735 :
8736 1030 : if (params->group_suite == WPA_CIPHER_GTK_NOT_USED &&
8737 2 : !(drv->capa.enc & WPA_DRIVER_CAPA_ENC_GTK_NOT_USED)) {
8738 : /*
8739 : * This is likely to work even though many drivers do not
8740 : * advertise support for operations without GTK.
8741 : */
8742 2 : wpa_printf(MSG_DEBUG, " * skip group cipher configuration for GTK_NOT_USED due to missing driver support advertisement");
8743 1026 : } else if (params->group_suite != WPA_CIPHER_NONE) {
8744 652 : u32 cipher = wpa_cipher_to_cipher_suite(params->group_suite);
8745 652 : wpa_printf(MSG_DEBUG, " * group=0x%x", cipher);
8746 652 : NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP, cipher);
8747 : }
8748 :
8749 1771 : if (params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X ||
8750 1194 : params->key_mgmt_suite == WPA_KEY_MGMT_PSK ||
8751 895 : params->key_mgmt_suite == WPA_KEY_MGMT_FT_IEEE8021X ||
8752 865 : params->key_mgmt_suite == WPA_KEY_MGMT_FT_PSK ||
8753 842 : params->key_mgmt_suite == WPA_KEY_MGMT_CCKM ||
8754 840 : params->key_mgmt_suite == WPA_KEY_MGMT_OSEN ||
8755 835 : params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SHA256 ||
8756 416 : params->key_mgmt_suite == WPA_KEY_MGMT_PSK_SHA256) {
8757 622 : int mgmt = WLAN_AKM_SUITE_PSK;
8758 :
8759 622 : switch (params->key_mgmt_suite) {
8760 : case WPA_KEY_MGMT_CCKM:
8761 0 : mgmt = WLAN_AKM_SUITE_CCKM;
8762 0 : break;
8763 : case WPA_KEY_MGMT_IEEE8021X:
8764 285 : mgmt = WLAN_AKM_SUITE_8021X;
8765 285 : break;
8766 : case WPA_KEY_MGMT_FT_IEEE8021X:
8767 7 : mgmt = WLAN_AKM_SUITE_FT_8021X;
8768 7 : break;
8769 : case WPA_KEY_MGMT_FT_PSK:
8770 23 : mgmt = WLAN_AKM_SUITE_FT_PSK;
8771 23 : break;
8772 : case WPA_KEY_MGMT_IEEE8021X_SHA256:
8773 3 : mgmt = WLAN_AKM_SUITE_8021X_SHA256;
8774 3 : break;
8775 : case WPA_KEY_MGMT_PSK_SHA256:
8776 10 : mgmt = WLAN_AKM_SUITE_PSK_SHA256;
8777 10 : break;
8778 : case WPA_KEY_MGMT_OSEN:
8779 2 : mgmt = WLAN_AKM_SUITE_OSEN;
8780 2 : break;
8781 : case WPA_KEY_MGMT_PSK:
8782 : default:
8783 292 : mgmt = WLAN_AKM_SUITE_PSK;
8784 292 : break;
8785 : }
8786 622 : wpa_printf(MSG_DEBUG, " * akm=0x%x", mgmt);
8787 622 : NLA_PUT_U32(msg, NL80211_ATTR_AKM_SUITES, mgmt);
8788 : }
8789 :
8790 1028 : NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT);
8791 :
8792 1028 : if (params->mgmt_frame_protection == MGMT_FRAME_PROTECTION_REQUIRED)
8793 32 : NLA_PUT_U32(msg, NL80211_ATTR_USE_MFP, NL80211_MFP_REQUIRED);
8794 :
8795 1028 : if (params->disable_ht)
8796 3 : NLA_PUT_FLAG(msg, NL80211_ATTR_DISABLE_HT);
8797 :
8798 1028 : if (params->htcaps && params->htcaps_mask) {
8799 1028 : int sz = sizeof(struct ieee80211_ht_capabilities);
8800 1028 : wpa_hexdump(MSG_DEBUG, " * htcaps", params->htcaps, sz);
8801 1028 : NLA_PUT(msg, NL80211_ATTR_HT_CAPABILITY, sz, params->htcaps);
8802 2056 : wpa_hexdump(MSG_DEBUG, " * htcaps_mask",
8803 1028 : params->htcaps_mask, sz);
8804 1028 : NLA_PUT(msg, NL80211_ATTR_HT_CAPABILITY_MASK, sz,
8805 : params->htcaps_mask);
8806 : }
8807 :
8808 : #ifdef CONFIG_VHT_OVERRIDES
8809 1028 : if (params->disable_vht) {
8810 1 : wpa_printf(MSG_DEBUG, " * VHT disabled");
8811 1 : NLA_PUT_FLAG(msg, NL80211_ATTR_DISABLE_VHT);
8812 : }
8813 :
8814 1028 : if (params->vhtcaps && params->vhtcaps_mask) {
8815 1028 : int sz = sizeof(struct ieee80211_vht_capabilities);
8816 1028 : wpa_hexdump(MSG_DEBUG, " * vhtcaps", params->vhtcaps, sz);
8817 1028 : NLA_PUT(msg, NL80211_ATTR_VHT_CAPABILITY, sz, params->vhtcaps);
8818 2056 : wpa_hexdump(MSG_DEBUG, " * vhtcaps_mask",
8819 1028 : params->vhtcaps_mask, sz);
8820 1028 : NLA_PUT(msg, NL80211_ATTR_VHT_CAPABILITY_MASK, sz,
8821 : params->vhtcaps_mask);
8822 : }
8823 : #endif /* CONFIG_VHT_OVERRIDES */
8824 :
8825 1028 : if (params->p2p)
8826 227 : wpa_printf(MSG_DEBUG, " * P2P group");
8827 :
8828 1028 : return 0;
8829 : nla_put_failure:
8830 0 : return -1;
8831 : }
8832 :
8833 :
8834 13 : static int wpa_driver_nl80211_try_connect(
8835 : struct wpa_driver_nl80211_data *drv,
8836 : struct wpa_driver_associate_params *params)
8837 : {
8838 : struct nl_msg *msg;
8839 : enum nl80211_auth_type type;
8840 : int ret;
8841 : int algs;
8842 :
8843 13 : msg = nlmsg_alloc();
8844 13 : if (!msg)
8845 0 : return -1;
8846 :
8847 13 : wpa_printf(MSG_DEBUG, "nl80211: Connect (ifindex=%d)", drv->ifindex);
8848 13 : nl80211_cmd(drv, msg, 0, NL80211_CMD_CONNECT);
8849 :
8850 13 : ret = nl80211_connect_common(drv, params, msg);
8851 13 : if (ret)
8852 0 : goto nla_put_failure;
8853 :
8854 13 : algs = 0;
8855 13 : if (params->auth_alg & WPA_AUTH_ALG_OPEN)
8856 13 : algs++;
8857 13 : if (params->auth_alg & WPA_AUTH_ALG_SHARED)
8858 0 : algs++;
8859 13 : if (params->auth_alg & WPA_AUTH_ALG_LEAP)
8860 0 : algs++;
8861 13 : if (algs > 1) {
8862 0 : wpa_printf(MSG_DEBUG, " * Leave out Auth Type for automatic "
8863 : "selection");
8864 0 : goto skip_auth_type;
8865 : }
8866 :
8867 13 : if (params->auth_alg & WPA_AUTH_ALG_OPEN)
8868 13 : type = NL80211_AUTHTYPE_OPEN_SYSTEM;
8869 0 : else if (params->auth_alg & WPA_AUTH_ALG_SHARED)
8870 0 : type = NL80211_AUTHTYPE_SHARED_KEY;
8871 0 : else if (params->auth_alg & WPA_AUTH_ALG_LEAP)
8872 0 : type = NL80211_AUTHTYPE_NETWORK_EAP;
8873 0 : else if (params->auth_alg & WPA_AUTH_ALG_FT)
8874 0 : type = NL80211_AUTHTYPE_FT;
8875 : else
8876 0 : goto nla_put_failure;
8877 :
8878 13 : wpa_printf(MSG_DEBUG, " * Auth Type %d", type);
8879 13 : NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE, type);
8880 :
8881 : skip_auth_type:
8882 13 : ret = nl80211_set_conn_keys(params, msg);
8883 13 : if (ret)
8884 0 : goto nla_put_failure;
8885 :
8886 13 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
8887 13 : msg = NULL;
8888 13 : if (ret) {
8889 2 : wpa_printf(MSG_DEBUG, "nl80211: MLME connect failed: ret=%d "
8890 : "(%s)", ret, strerror(-ret));
8891 2 : goto nla_put_failure;
8892 : }
8893 11 : ret = 0;
8894 11 : wpa_printf(MSG_DEBUG, "nl80211: Connect request send successfully");
8895 :
8896 : nla_put_failure:
8897 13 : nlmsg_free(msg);
8898 13 : return ret;
8899 :
8900 : }
8901 :
8902 :
8903 11 : static int wpa_driver_nl80211_connect(
8904 : struct wpa_driver_nl80211_data *drv,
8905 : struct wpa_driver_associate_params *params)
8906 : {
8907 11 : int ret = wpa_driver_nl80211_try_connect(drv, params);
8908 11 : if (ret == -EALREADY) {
8909 : /*
8910 : * cfg80211 does not currently accept new connections if
8911 : * we are already connected. As a workaround, force
8912 : * disconnection and try again.
8913 : */
8914 2 : wpa_printf(MSG_DEBUG, "nl80211: Explicitly "
8915 : "disconnecting before reassociation "
8916 : "attempt");
8917 2 : if (wpa_driver_nl80211_disconnect(
8918 : drv, WLAN_REASON_PREV_AUTH_NOT_VALID))
8919 0 : return -1;
8920 2 : ret = wpa_driver_nl80211_try_connect(drv, params);
8921 : }
8922 11 : return ret;
8923 : }
8924 :
8925 :
8926 1170 : static int wpa_driver_nl80211_associate(
8927 : void *priv, struct wpa_driver_associate_params *params)
8928 : {
8929 1170 : struct i802_bss *bss = priv;
8930 1170 : struct wpa_driver_nl80211_data *drv = bss->drv;
8931 : int ret;
8932 : struct nl_msg *msg;
8933 :
8934 1170 : if (params->mode == IEEE80211_MODE_AP)
8935 127 : return wpa_driver_nl80211_ap(drv, params);
8936 :
8937 1043 : if (params->mode == IEEE80211_MODE_IBSS)
8938 17 : return wpa_driver_nl80211_ibss(drv, params);
8939 :
8940 1026 : if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME)) {
8941 11 : enum nl80211_iftype nlmode = params->p2p ?
8942 : NL80211_IFTYPE_P2P_CLIENT : NL80211_IFTYPE_STATION;
8943 :
8944 11 : if (wpa_driver_nl80211_set_mode(priv, nlmode) < 0)
8945 0 : return -1;
8946 11 : return wpa_driver_nl80211_connect(drv, params);
8947 : }
8948 :
8949 1015 : nl80211_mark_disconnected(drv);
8950 :
8951 1015 : msg = nlmsg_alloc();
8952 1015 : if (!msg)
8953 0 : return -1;
8954 :
8955 1015 : wpa_printf(MSG_DEBUG, "nl80211: Associate (ifindex=%d)",
8956 : drv->ifindex);
8957 1015 : nl80211_cmd(drv, msg, 0, NL80211_CMD_ASSOCIATE);
8958 :
8959 1015 : ret = nl80211_connect_common(drv, params, msg);
8960 1015 : if (ret)
8961 0 : goto nla_put_failure;
8962 :
8963 1015 : if (params->prev_bssid) {
8964 204 : wpa_printf(MSG_DEBUG, " * prev_bssid=" MACSTR,
8965 204 : MAC2STR(params->prev_bssid));
8966 34 : NLA_PUT(msg, NL80211_ATTR_PREV_BSSID, ETH_ALEN,
8967 : params->prev_bssid);
8968 : }
8969 :
8970 1015 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
8971 1015 : msg = NULL;
8972 1015 : if (ret) {
8973 0 : wpa_dbg(drv->ctx, MSG_DEBUG,
8974 : "nl80211: MLME command failed (assoc): ret=%d (%s)",
8975 : ret, strerror(-ret));
8976 0 : nl80211_dump_scan(drv);
8977 0 : goto nla_put_failure;
8978 : }
8979 1015 : ret = 0;
8980 1015 : wpa_printf(MSG_DEBUG, "nl80211: Association request send "
8981 : "successfully");
8982 :
8983 : nla_put_failure:
8984 1015 : nlmsg_free(msg);
8985 1015 : return ret;
8986 : }
8987 :
8988 :
8989 1731 : static int nl80211_set_mode(struct wpa_driver_nl80211_data *drv,
8990 : int ifindex, enum nl80211_iftype mode)
8991 : {
8992 : struct nl_msg *msg;
8993 1731 : int ret = -ENOBUFS;
8994 :
8995 1731 : wpa_printf(MSG_DEBUG, "nl80211: Set mode ifindex %d iftype %d (%s)",
8996 : ifindex, mode, nl80211_iftype_str(mode));
8997 :
8998 1731 : msg = nlmsg_alloc();
8999 1731 : if (!msg)
9000 0 : return -ENOMEM;
9001 :
9002 1731 : nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_INTERFACE);
9003 1731 : if (nl80211_set_iface_id(msg, drv->first_bss) < 0)
9004 0 : goto nla_put_failure;
9005 1731 : NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, mode);
9006 :
9007 1731 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
9008 1731 : msg = NULL;
9009 1731 : if (!ret)
9010 1729 : return 0;
9011 : nla_put_failure:
9012 2 : nlmsg_free(msg);
9013 2 : wpa_printf(MSG_DEBUG, "nl80211: Failed to set interface %d to mode %d:"
9014 : " %d (%s)", ifindex, mode, ret, strerror(-ret));
9015 2 : return ret;
9016 : }
9017 :
9018 :
9019 1731 : static int wpa_driver_nl80211_set_mode(struct i802_bss *bss,
9020 : enum nl80211_iftype nlmode)
9021 : {
9022 1731 : struct wpa_driver_nl80211_data *drv = bss->drv;
9023 1731 : int ret = -1;
9024 : int i;
9025 1731 : int was_ap = is_ap_interface(drv->nlmode);
9026 : int res;
9027 :
9028 1731 : res = nl80211_set_mode(drv, drv->ifindex, nlmode);
9029 1731 : if (res && nlmode == nl80211_get_ifmode(bss))
9030 0 : res = 0;
9031 :
9032 1731 : if (res == 0) {
9033 1729 : drv->nlmode = nlmode;
9034 1729 : ret = 0;
9035 1729 : goto done;
9036 : }
9037 :
9038 2 : if (res == -ENODEV)
9039 2 : return -1;
9040 :
9041 0 : if (nlmode == drv->nlmode) {
9042 0 : wpa_printf(MSG_DEBUG, "nl80211: Interface already in "
9043 : "requested mode - ignore error");
9044 0 : ret = 0;
9045 0 : goto done; /* Already in the requested mode */
9046 : }
9047 :
9048 : /* mac80211 doesn't allow mode changes while the device is up, so
9049 : * take the device down, try to set the mode again, and bring the
9050 : * device back up.
9051 : */
9052 0 : wpa_printf(MSG_DEBUG, "nl80211: Try mode change after setting "
9053 : "interface down");
9054 0 : for (i = 0; i < 10; i++) {
9055 0 : res = i802_set_iface_flags(bss, 0);
9056 0 : if (res == -EACCES || res == -ENODEV)
9057 : break;
9058 0 : if (res == 0) {
9059 : /* Try to set the mode again while the interface is
9060 : * down */
9061 0 : ret = nl80211_set_mode(drv, drv->ifindex, nlmode);
9062 0 : if (ret == -EACCES)
9063 0 : break;
9064 0 : res = i802_set_iface_flags(bss, 1);
9065 0 : if (res && !ret)
9066 0 : ret = -1;
9067 0 : else if (ret != -EBUSY)
9068 0 : break;
9069 : } else
9070 0 : wpa_printf(MSG_DEBUG, "nl80211: Failed to set "
9071 : "interface down");
9072 0 : os_sleep(0, 100000);
9073 : }
9074 :
9075 0 : if (!ret) {
9076 0 : wpa_printf(MSG_DEBUG, "nl80211: Mode change succeeded while "
9077 : "interface is down");
9078 0 : drv->nlmode = nlmode;
9079 0 : drv->ignore_if_down_event = 1;
9080 : }
9081 :
9082 : done:
9083 1729 : if (ret) {
9084 0 : wpa_printf(MSG_DEBUG, "nl80211: Interface mode change to %d "
9085 0 : "from %d failed", nlmode, drv->nlmode);
9086 0 : return ret;
9087 : }
9088 :
9089 1729 : if (is_p2p_net_interface(nlmode))
9090 260 : nl80211_disable_11b_rates(drv, drv->ifindex, 1);
9091 1469 : else if (drv->disabled_11b_rates)
9092 208 : nl80211_disable_11b_rates(drv, drv->ifindex, 0);
9093 :
9094 1729 : if (is_ap_interface(nlmode)) {
9095 693 : nl80211_mgmt_unsubscribe(bss, "start AP");
9096 : /* Setup additional AP mode functionality if needed */
9097 693 : if (nl80211_setup_ap(bss))
9098 0 : return -1;
9099 1036 : } else if (was_ap) {
9100 : /* Remove additional AP mode functionality */
9101 677 : nl80211_teardown_ap(bss);
9102 : } else {
9103 359 : nl80211_mgmt_unsubscribe(bss, "mode change");
9104 : }
9105 :
9106 2146 : if (!bss->in_deinit && !is_ap_interface(nlmode) &&
9107 417 : nl80211_mgmt_subscribe_non_ap(bss) < 0)
9108 0 : wpa_printf(MSG_DEBUG, "nl80211: Failed to register Action "
9109 : "frame processing - ignore for now");
9110 :
9111 1729 : return 0;
9112 : }
9113 :
9114 :
9115 0 : static int dfs_info_handler(struct nl_msg *msg, void *arg)
9116 : {
9117 : struct nlattr *tb[NL80211_ATTR_MAX + 1];
9118 0 : struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
9119 0 : int *dfs_capability_ptr = arg;
9120 :
9121 0 : nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
9122 : genlmsg_attrlen(gnlh, 0), NULL);
9123 :
9124 0 : if (tb[NL80211_ATTR_VENDOR_DATA]) {
9125 0 : struct nlattr *nl_vend = tb[NL80211_ATTR_VENDOR_DATA];
9126 : struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_MAX + 1];
9127 :
9128 0 : nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_MAX,
9129 0 : nla_data(nl_vend), nla_len(nl_vend), NULL);
9130 :
9131 0 : if (tb_vendor[QCA_WLAN_VENDOR_ATTR_DFS]) {
9132 : u32 val;
9133 0 : val = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_DFS]);
9134 0 : wpa_printf(MSG_DEBUG, "nl80211: DFS offload capability: %u",
9135 : val);
9136 0 : *dfs_capability_ptr = val;
9137 : }
9138 : }
9139 :
9140 0 : return NL_SKIP;
9141 : }
9142 :
9143 :
9144 884 : static int wpa_driver_nl80211_get_capa(void *priv,
9145 : struct wpa_driver_capa *capa)
9146 : {
9147 884 : struct i802_bss *bss = priv;
9148 884 : struct wpa_driver_nl80211_data *drv = bss->drv;
9149 : struct nl_msg *msg;
9150 884 : int dfs_capability = 0;
9151 884 : int ret = 0;
9152 :
9153 884 : if (!drv->has_capability)
9154 0 : return -1;
9155 884 : os_memcpy(capa, &drv->capa, sizeof(*capa));
9156 884 : if (drv->extended_capa && drv->extended_capa_mask) {
9157 884 : capa->extended_capa = drv->extended_capa;
9158 884 : capa->extended_capa_mask = drv->extended_capa_mask;
9159 884 : capa->extended_capa_len = drv->extended_capa_len;
9160 : }
9161 :
9162 1768 : if ((capa->flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) &&
9163 884 : !drv->allow_p2p_device) {
9164 884 : wpa_printf(MSG_DEBUG, "nl80211: Do not indicate P2P_DEVICE support (p2p_device=1 driver param not specified)");
9165 884 : capa->flags &= ~WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE;
9166 : }
9167 :
9168 884 : if (drv->dfs_vendor_cmd_avail == 1) {
9169 0 : msg = nlmsg_alloc();
9170 0 : if (!msg)
9171 0 : return -ENOMEM;
9172 :
9173 0 : nl80211_cmd(drv, msg, 0, NL80211_CMD_VENDOR);
9174 :
9175 0 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
9176 0 : NLA_PUT_U32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA);
9177 0 : NLA_PUT_U32(msg, NL80211_ATTR_VENDOR_SUBCMD,
9178 : QCA_NL80211_VENDOR_SUBCMD_DFS_CAPABILITY);
9179 :
9180 0 : ret = send_and_recv_msgs(drv, msg, dfs_info_handler,
9181 : &dfs_capability);
9182 0 : if (!ret) {
9183 0 : if (dfs_capability)
9184 0 : capa->flags |= WPA_DRIVER_FLAGS_DFS_OFFLOAD;
9185 : }
9186 : }
9187 :
9188 884 : return ret;
9189 :
9190 : nla_put_failure:
9191 0 : nlmsg_free(msg);
9192 0 : return -ENOBUFS;
9193 : }
9194 :
9195 :
9196 6165 : static int wpa_driver_nl80211_set_operstate(void *priv, int state)
9197 : {
9198 6165 : struct i802_bss *bss = priv;
9199 6165 : struct wpa_driver_nl80211_data *drv = bss->drv;
9200 :
9201 12330 : wpa_printf(MSG_DEBUG, "nl80211: Set %s operstate %d->%d (%s)",
9202 6165 : bss->ifname, drv->operstate, state,
9203 : state ? "UP" : "DORMANT");
9204 6165 : drv->operstate = state;
9205 6165 : return netlink_send_oper_ifla(drv->global->netlink, drv->ifindex, -1,
9206 : state ? IF_OPER_UP : IF_OPER_DORMANT);
9207 : }
9208 :
9209 :
9210 2151 : static int wpa_driver_nl80211_set_supp_port(void *priv, int authorized)
9211 : {
9212 2151 : struct i802_bss *bss = priv;
9213 2151 : struct wpa_driver_nl80211_data *drv = bss->drv;
9214 : struct nl_msg *msg;
9215 : struct nl80211_sta_flag_update upd;
9216 2151 : int ret = -ENOBUFS;
9217 :
9218 2151 : if (!drv->associated && is_zero_ether_addr(drv->bssid) && !authorized) {
9219 1067 : wpa_printf(MSG_DEBUG, "nl80211: Skip set_supp_port(unauthorized) while not associated");
9220 1067 : return 0;
9221 : }
9222 :
9223 6504 : wpa_printf(MSG_DEBUG, "nl80211: Set supplicant port %sauthorized for "
9224 6504 : MACSTR, authorized ? "" : "un", MAC2STR(drv->bssid));
9225 :
9226 1084 : msg = nlmsg_alloc();
9227 1084 : if (!msg)
9228 0 : return -ENOMEM;
9229 :
9230 1084 : nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_STATION);
9231 :
9232 1084 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
9233 : if_nametoindex(bss->ifname));
9234 1084 : NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, drv->bssid);
9235 :
9236 1084 : os_memset(&upd, 0, sizeof(upd));
9237 1084 : upd.mask = BIT(NL80211_STA_FLAG_AUTHORIZED);
9238 1084 : if (authorized)
9239 776 : upd.set = BIT(NL80211_STA_FLAG_AUTHORIZED);
9240 1084 : NLA_PUT(msg, NL80211_ATTR_STA_FLAGS2, sizeof(upd), &upd);
9241 :
9242 1084 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
9243 1084 : msg = NULL;
9244 1084 : if (!ret)
9245 1067 : return 0;
9246 : nla_put_failure:
9247 17 : nlmsg_free(msg);
9248 17 : wpa_printf(MSG_DEBUG, "nl80211: Failed to set STA flag: %d (%s)",
9249 : ret, strerror(-ret));
9250 17 : return ret;
9251 : }
9252 :
9253 :
9254 : /* Set kernel driver on given frequency (MHz) */
9255 663 : static int i802_set_freq(void *priv, struct hostapd_freq_params *freq)
9256 : {
9257 663 : struct i802_bss *bss = priv;
9258 663 : return nl80211_set_channel(bss, freq, 0);
9259 : }
9260 :
9261 :
9262 688 : static inline int min_int(int a, int b)
9263 : {
9264 688 : if (a < b)
9265 0 : return a;
9266 688 : return b;
9267 : }
9268 :
9269 :
9270 688 : static int get_key_handler(struct nl_msg *msg, void *arg)
9271 : {
9272 : struct nlattr *tb[NL80211_ATTR_MAX + 1];
9273 688 : struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
9274 :
9275 688 : nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
9276 : genlmsg_attrlen(gnlh, 0), NULL);
9277 :
9278 : /*
9279 : * TODO: validate the key index and mac address!
9280 : * Otherwise, there's a race condition as soon as
9281 : * the kernel starts sending key notifications.
9282 : */
9283 :
9284 688 : if (tb[NL80211_ATTR_KEY_SEQ])
9285 688 : memcpy(arg, nla_data(tb[NL80211_ATTR_KEY_SEQ]),
9286 688 : min_int(nla_len(tb[NL80211_ATTR_KEY_SEQ]), 6));
9287 688 : return NL_SKIP;
9288 : }
9289 :
9290 :
9291 688 : static int i802_get_seqnum(const char *iface, void *priv, const u8 *addr,
9292 : int idx, u8 *seq)
9293 : {
9294 688 : struct i802_bss *bss = priv;
9295 688 : struct wpa_driver_nl80211_data *drv = bss->drv;
9296 : struct nl_msg *msg;
9297 :
9298 688 : msg = nlmsg_alloc();
9299 688 : if (!msg)
9300 0 : return -ENOMEM;
9301 :
9302 688 : nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_KEY);
9303 :
9304 688 : if (addr)
9305 0 : NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
9306 688 : NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, idx);
9307 688 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(iface));
9308 :
9309 688 : memset(seq, 0, 6);
9310 :
9311 688 : return send_and_recv_msgs(drv, msg, get_key_handler, seq);
9312 : nla_put_failure:
9313 0 : nlmsg_free(msg);
9314 0 : return -ENOBUFS;
9315 : }
9316 :
9317 :
9318 1 : static int i802_set_rts(void *priv, int rts)
9319 : {
9320 1 : struct i802_bss *bss = priv;
9321 1 : struct wpa_driver_nl80211_data *drv = bss->drv;
9322 : struct nl_msg *msg;
9323 1 : int ret = -ENOBUFS;
9324 : u32 val;
9325 :
9326 1 : msg = nlmsg_alloc();
9327 1 : if (!msg)
9328 0 : return -ENOMEM;
9329 :
9330 1 : if (rts >= 2347)
9331 0 : val = (u32) -1;
9332 : else
9333 1 : val = rts;
9334 :
9335 1 : nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_WIPHY);
9336 1 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
9337 1 : NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, val);
9338 :
9339 1 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
9340 1 : msg = NULL;
9341 1 : if (!ret)
9342 1 : return 0;
9343 : nla_put_failure:
9344 0 : nlmsg_free(msg);
9345 0 : wpa_printf(MSG_DEBUG, "nl80211: Failed to set RTS threshold %d: "
9346 : "%d (%s)", rts, ret, strerror(-ret));
9347 0 : return ret;
9348 : }
9349 :
9350 :
9351 3 : static int i802_set_frag(void *priv, int frag)
9352 : {
9353 3 : struct i802_bss *bss = priv;
9354 3 : struct wpa_driver_nl80211_data *drv = bss->drv;
9355 : struct nl_msg *msg;
9356 3 : int ret = -ENOBUFS;
9357 : u32 val;
9358 :
9359 3 : msg = nlmsg_alloc();
9360 3 : if (!msg)
9361 0 : return -ENOMEM;
9362 :
9363 3 : if (frag >= 2346)
9364 0 : val = (u32) -1;
9365 : else
9366 3 : val = frag;
9367 :
9368 3 : nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_WIPHY);
9369 3 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
9370 3 : NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD, val);
9371 :
9372 3 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
9373 3 : msg = NULL;
9374 3 : if (!ret)
9375 3 : return 0;
9376 : nla_put_failure:
9377 0 : nlmsg_free(msg);
9378 0 : wpa_printf(MSG_DEBUG, "nl80211: Failed to set fragmentation threshold "
9379 : "%d: %d (%s)", frag, ret, strerror(-ret));
9380 0 : return ret;
9381 : }
9382 :
9383 :
9384 712 : static int i802_flush(void *priv)
9385 : {
9386 712 : struct i802_bss *bss = priv;
9387 712 : struct wpa_driver_nl80211_data *drv = bss->drv;
9388 : struct nl_msg *msg;
9389 : int res;
9390 :
9391 712 : msg = nlmsg_alloc();
9392 712 : if (!msg)
9393 0 : return -1;
9394 :
9395 712 : wpa_printf(MSG_DEBUG, "nl80211: flush -> DEL_STATION %s (all)",
9396 712 : bss->ifname);
9397 712 : nl80211_cmd(drv, msg, 0, NL80211_CMD_DEL_STATION);
9398 :
9399 : /*
9400 : * XXX: FIX! this needs to flush all VLANs too
9401 : */
9402 712 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
9403 : if_nametoindex(bss->ifname));
9404 :
9405 712 : res = send_and_recv_msgs(drv, msg, NULL, NULL);
9406 712 : if (res) {
9407 0 : wpa_printf(MSG_DEBUG, "nl80211: Station flush failed: ret=%d "
9408 : "(%s)", res, strerror(-res));
9409 : }
9410 712 : return res;
9411 : nla_put_failure:
9412 0 : nlmsg_free(msg);
9413 0 : return -ENOBUFS;
9414 : }
9415 :
9416 :
9417 46 : static int get_sta_handler(struct nl_msg *msg, void *arg)
9418 : {
9419 : struct nlattr *tb[NL80211_ATTR_MAX + 1];
9420 46 : struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
9421 46 : struct hostap_sta_driver_data *data = arg;
9422 : struct nlattr *stats[NL80211_STA_INFO_MAX + 1];
9423 : static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
9424 : [NL80211_STA_INFO_INACTIVE_TIME] = { .type = NLA_U32 },
9425 : [NL80211_STA_INFO_RX_BYTES] = { .type = NLA_U32 },
9426 : [NL80211_STA_INFO_TX_BYTES] = { .type = NLA_U32 },
9427 : [NL80211_STA_INFO_RX_PACKETS] = { .type = NLA_U32 },
9428 : [NL80211_STA_INFO_TX_PACKETS] = { .type = NLA_U32 },
9429 : [NL80211_STA_INFO_TX_FAILED] = { .type = NLA_U32 },
9430 : };
9431 :
9432 46 : nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
9433 : genlmsg_attrlen(gnlh, 0), NULL);
9434 :
9435 : /*
9436 : * TODO: validate the interface and mac address!
9437 : * Otherwise, there's a race condition as soon as
9438 : * the kernel starts sending station notifications.
9439 : */
9440 :
9441 46 : if (!tb[NL80211_ATTR_STA_INFO]) {
9442 0 : wpa_printf(MSG_DEBUG, "sta stats missing!");
9443 0 : return NL_SKIP;
9444 : }
9445 46 : if (nla_parse_nested(stats, NL80211_STA_INFO_MAX,
9446 : tb[NL80211_ATTR_STA_INFO],
9447 : stats_policy)) {
9448 0 : wpa_printf(MSG_DEBUG, "failed to parse nested attributes!");
9449 0 : return NL_SKIP;
9450 : }
9451 :
9452 46 : if (stats[NL80211_STA_INFO_INACTIVE_TIME])
9453 46 : data->inactive_msec =
9454 46 : nla_get_u32(stats[NL80211_STA_INFO_INACTIVE_TIME]);
9455 46 : if (stats[NL80211_STA_INFO_RX_BYTES])
9456 46 : data->rx_bytes = nla_get_u32(stats[NL80211_STA_INFO_RX_BYTES]);
9457 46 : if (stats[NL80211_STA_INFO_TX_BYTES])
9458 46 : data->tx_bytes = nla_get_u32(stats[NL80211_STA_INFO_TX_BYTES]);
9459 46 : if (stats[NL80211_STA_INFO_RX_PACKETS])
9460 46 : data->rx_packets =
9461 46 : nla_get_u32(stats[NL80211_STA_INFO_RX_PACKETS]);
9462 46 : if (stats[NL80211_STA_INFO_TX_PACKETS])
9463 46 : data->tx_packets =
9464 46 : nla_get_u32(stats[NL80211_STA_INFO_TX_PACKETS]);
9465 46 : if (stats[NL80211_STA_INFO_TX_FAILED])
9466 46 : data->tx_retry_failed =
9467 46 : nla_get_u32(stats[NL80211_STA_INFO_TX_FAILED]);
9468 :
9469 46 : return NL_SKIP;
9470 : }
9471 :
9472 47 : static int i802_read_sta_data(struct i802_bss *bss,
9473 : struct hostap_sta_driver_data *data,
9474 : const u8 *addr)
9475 : {
9476 47 : struct wpa_driver_nl80211_data *drv = bss->drv;
9477 : struct nl_msg *msg;
9478 :
9479 47 : os_memset(data, 0, sizeof(*data));
9480 47 : msg = nlmsg_alloc();
9481 47 : if (!msg)
9482 0 : return -ENOMEM;
9483 :
9484 47 : nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_STATION);
9485 :
9486 47 : NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
9487 47 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(bss->ifname));
9488 :
9489 47 : return send_and_recv_msgs(drv, msg, get_sta_handler, data);
9490 : nla_put_failure:
9491 0 : nlmsg_free(msg);
9492 0 : return -ENOBUFS;
9493 : }
9494 :
9495 :
9496 2636 : static int i802_set_tx_queue_params(void *priv, int queue, int aifs,
9497 : int cw_min, int cw_max, int burst_time)
9498 : {
9499 2636 : struct i802_bss *bss = priv;
9500 2636 : struct wpa_driver_nl80211_data *drv = bss->drv;
9501 : struct nl_msg *msg;
9502 : struct nlattr *txq, *params;
9503 :
9504 2636 : msg = nlmsg_alloc();
9505 2636 : if (!msg)
9506 0 : return -1;
9507 :
9508 2636 : nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_WIPHY);
9509 :
9510 2636 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(bss->ifname));
9511 :
9512 2636 : txq = nla_nest_start(msg, NL80211_ATTR_WIPHY_TXQ_PARAMS);
9513 2636 : if (!txq)
9514 0 : goto nla_put_failure;
9515 :
9516 : /* We are only sending parameters for a single TXQ at a time */
9517 2636 : params = nla_nest_start(msg, 1);
9518 2636 : if (!params)
9519 0 : goto nla_put_failure;
9520 :
9521 2636 : switch (queue) {
9522 : case 0:
9523 659 : NLA_PUT_U8(msg, NL80211_TXQ_ATTR_QUEUE, NL80211_TXQ_Q_VO);
9524 659 : break;
9525 : case 1:
9526 659 : NLA_PUT_U8(msg, NL80211_TXQ_ATTR_QUEUE, NL80211_TXQ_Q_VI);
9527 659 : break;
9528 : case 2:
9529 659 : NLA_PUT_U8(msg, NL80211_TXQ_ATTR_QUEUE, NL80211_TXQ_Q_BE);
9530 659 : break;
9531 : case 3:
9532 659 : NLA_PUT_U8(msg, NL80211_TXQ_ATTR_QUEUE, NL80211_TXQ_Q_BK);
9533 659 : break;
9534 : }
9535 : /* Burst time is configured in units of 0.1 msec and TXOP parameter in
9536 : * 32 usec, so need to convert the value here. */
9537 2636 : NLA_PUT_U16(msg, NL80211_TXQ_ATTR_TXOP, (burst_time * 100 + 16) / 32);
9538 2636 : NLA_PUT_U16(msg, NL80211_TXQ_ATTR_CWMIN, cw_min);
9539 2636 : NLA_PUT_U16(msg, NL80211_TXQ_ATTR_CWMAX, cw_max);
9540 2636 : NLA_PUT_U8(msg, NL80211_TXQ_ATTR_AIFS, aifs);
9541 :
9542 2636 : nla_nest_end(msg, params);
9543 :
9544 2636 : nla_nest_end(msg, txq);
9545 :
9546 2636 : if (send_and_recv_msgs(drv, msg, NULL, NULL) == 0)
9547 2636 : return 0;
9548 0 : msg = NULL;
9549 : nla_put_failure:
9550 0 : nlmsg_free(msg);
9551 0 : return -1;
9552 : }
9553 :
9554 :
9555 14 : static int i802_set_sta_vlan(struct i802_bss *bss, const u8 *addr,
9556 : const char *ifname, int vlan_id)
9557 : {
9558 14 : struct wpa_driver_nl80211_data *drv = bss->drv;
9559 : struct nl_msg *msg;
9560 14 : int ret = -ENOBUFS;
9561 :
9562 14 : msg = nlmsg_alloc();
9563 14 : if (!msg)
9564 0 : return -ENOMEM;
9565 :
9566 126 : wpa_printf(MSG_DEBUG, "nl80211: %s[%d]: set_sta_vlan(" MACSTR
9567 : ", ifname=%s[%d], vlan_id=%d)",
9568 28 : bss->ifname, if_nametoindex(bss->ifname),
9569 84 : MAC2STR(addr), ifname, if_nametoindex(ifname), vlan_id);
9570 14 : nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_STATION);
9571 :
9572 14 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
9573 : if_nametoindex(bss->ifname));
9574 14 : NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
9575 14 : NLA_PUT_U32(msg, NL80211_ATTR_STA_VLAN,
9576 : if_nametoindex(ifname));
9577 :
9578 14 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
9579 14 : msg = NULL;
9580 14 : if (ret < 0) {
9581 0 : wpa_printf(MSG_ERROR, "nl80211: NL80211_ATTR_STA_VLAN (addr="
9582 : MACSTR " ifname=%s vlan_id=%d) failed: %d (%s)",
9583 0 : MAC2STR(addr), ifname, vlan_id, ret,
9584 : strerror(-ret));
9585 : }
9586 : nla_put_failure:
9587 14 : nlmsg_free(msg);
9588 14 : return ret;
9589 : }
9590 :
9591 :
9592 6 : static int i802_get_inact_sec(void *priv, const u8 *addr)
9593 : {
9594 : struct hostap_sta_driver_data data;
9595 : int ret;
9596 :
9597 6 : data.inactive_msec = (unsigned long) -1;
9598 6 : ret = i802_read_sta_data(priv, &data, addr);
9599 6 : if (ret || data.inactive_msec == (unsigned long) -1)
9600 0 : return -1;
9601 6 : return data.inactive_msec / 1000;
9602 : }
9603 :
9604 :
9605 672 : static int i802_sta_clear_stats(void *priv, const u8 *addr)
9606 : {
9607 : #if 0
9608 : /* TODO */
9609 : #endif
9610 672 : return 0;
9611 : }
9612 :
9613 :
9614 1663 : static int i802_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr,
9615 : int reason)
9616 : {
9617 1663 : struct i802_bss *bss = priv;
9618 1663 : struct wpa_driver_nl80211_data *drv = bss->drv;
9619 : struct ieee80211_mgmt mgmt;
9620 :
9621 1663 : if (drv->device_ap_sme)
9622 0 : return wpa_driver_nl80211_sta_remove(bss, addr);
9623 :
9624 1663 : memset(&mgmt, 0, sizeof(mgmt));
9625 1663 : mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
9626 : WLAN_FC_STYPE_DEAUTH);
9627 1663 : memcpy(mgmt.da, addr, ETH_ALEN);
9628 1663 : memcpy(mgmt.sa, own_addr, ETH_ALEN);
9629 1663 : memcpy(mgmt.bssid, own_addr, ETH_ALEN);
9630 1663 : mgmt.u.deauth.reason_code = host_to_le16(reason);
9631 1663 : return wpa_driver_nl80211_send_mlme(bss, (u8 *) &mgmt,
9632 : IEEE80211_HDRLEN +
9633 : sizeof(mgmt.u.deauth), 0, 0, 0, 0,
9634 : 0);
9635 : }
9636 :
9637 :
9638 4 : static int i802_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr,
9639 : int reason)
9640 : {
9641 4 : struct i802_bss *bss = priv;
9642 4 : struct wpa_driver_nl80211_data *drv = bss->drv;
9643 : struct ieee80211_mgmt mgmt;
9644 :
9645 4 : if (drv->device_ap_sme)
9646 0 : return wpa_driver_nl80211_sta_remove(bss, addr);
9647 :
9648 4 : memset(&mgmt, 0, sizeof(mgmt));
9649 4 : mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
9650 : WLAN_FC_STYPE_DISASSOC);
9651 4 : memcpy(mgmt.da, addr, ETH_ALEN);
9652 4 : memcpy(mgmt.sa, own_addr, ETH_ALEN);
9653 4 : memcpy(mgmt.bssid, own_addr, ETH_ALEN);
9654 4 : mgmt.u.disassoc.reason_code = host_to_le16(reason);
9655 4 : return wpa_driver_nl80211_send_mlme(bss, (u8 *) &mgmt,
9656 : IEEE80211_HDRLEN +
9657 : sizeof(mgmt.u.disassoc), 0, 0, 0, 0,
9658 : 0);
9659 : }
9660 :
9661 :
9662 711 : static void dump_ifidx(struct wpa_driver_nl80211_data *drv)
9663 : {
9664 : char buf[200], *pos, *end;
9665 : int i, res;
9666 :
9667 711 : pos = buf;
9668 711 : end = pos + sizeof(buf);
9669 :
9670 12087 : for (i = 0; i < drv->num_if_indices; i++) {
9671 11376 : if (!drv->if_indices[i])
9672 10584 : continue;
9673 792 : res = os_snprintf(pos, end - pos, " %d", drv->if_indices[i]);
9674 792 : if (res < 0 || res >= end - pos)
9675 : break;
9676 792 : pos += res;
9677 : }
9678 711 : *pos = '\0';
9679 :
9680 711 : wpa_printf(MSG_DEBUG, "nl80211: if_indices[%d]:%s",
9681 : drv->num_if_indices, buf);
9682 711 : }
9683 :
9684 :
9685 725 : static void add_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
9686 : {
9687 : int i;
9688 : int *old;
9689 :
9690 725 : wpa_printf(MSG_DEBUG, "nl80211: Add own interface ifindex %d",
9691 : ifidx);
9692 725 : if (have_ifidx(drv, ifidx)) {
9693 89 : wpa_printf(MSG_DEBUG, "nl80211: ifindex %d already in the list",
9694 : ifidx);
9695 89 : return;
9696 : }
9697 721 : for (i = 0; i < drv->num_if_indices; i++) {
9698 721 : if (drv->if_indices[i] == 0) {
9699 636 : drv->if_indices[i] = ifidx;
9700 636 : dump_ifidx(drv);
9701 636 : return;
9702 : }
9703 : }
9704 :
9705 0 : if (drv->if_indices != drv->default_if_indices)
9706 0 : old = drv->if_indices;
9707 : else
9708 0 : old = NULL;
9709 :
9710 0 : drv->if_indices = os_realloc_array(old, drv->num_if_indices + 1,
9711 : sizeof(int));
9712 0 : if (!drv->if_indices) {
9713 0 : if (!old)
9714 0 : drv->if_indices = drv->default_if_indices;
9715 : else
9716 0 : drv->if_indices = old;
9717 0 : wpa_printf(MSG_ERROR, "Failed to reallocate memory for "
9718 : "interfaces");
9719 0 : wpa_printf(MSG_ERROR, "Ignoring EAPOL on interface %d", ifidx);
9720 0 : return;
9721 0 : } else if (!old)
9722 0 : os_memcpy(drv->if_indices, drv->default_if_indices,
9723 : sizeof(drv->default_if_indices));
9724 0 : drv->if_indices[drv->num_if_indices] = ifidx;
9725 0 : drv->num_if_indices++;
9726 0 : dump_ifidx(drv);
9727 : }
9728 :
9729 :
9730 75 : static void del_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
9731 : {
9732 : int i;
9733 :
9734 142 : for (i = 0; i < drv->num_if_indices; i++) {
9735 141 : if (drv->if_indices[i] == ifidx) {
9736 74 : drv->if_indices[i] = 0;
9737 74 : break;
9738 : }
9739 : }
9740 75 : dump_ifidx(drv);
9741 75 : }
9742 :
9743 :
9744 26304 : static int have_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
9745 : {
9746 : int i;
9747 :
9748 388128 : for (i = 0; i < drv->num_if_indices; i++)
9749 365549 : if (drv->if_indices[i] == ifidx)
9750 3725 : return 1;
9751 :
9752 22579 : return 0;
9753 : }
9754 :
9755 :
9756 2 : static int i802_set_wds_sta(void *priv, const u8 *addr, int aid, int val,
9757 : const char *bridge_ifname, char *ifname_wds)
9758 : {
9759 2 : struct i802_bss *bss = priv;
9760 2 : struct wpa_driver_nl80211_data *drv = bss->drv;
9761 : char name[IFNAMSIZ + 1];
9762 :
9763 2 : os_snprintf(name, sizeof(name), "%s.sta%d", bss->ifname, aid);
9764 2 : if (ifname_wds)
9765 1 : os_strlcpy(ifname_wds, name, IFNAMSIZ + 1);
9766 :
9767 12 : wpa_printf(MSG_DEBUG, "nl80211: Set WDS STA addr=" MACSTR
9768 12 : " aid=%d val=%d name=%s", MAC2STR(addr), aid, val, name);
9769 2 : if (val) {
9770 1 : if (!if_nametoindex(name)) {
9771 1 : if (nl80211_create_iface(drv, name,
9772 : NL80211_IFTYPE_AP_VLAN,
9773 1 : bss->addr, 1, NULL, NULL, 0) <
9774 : 0)
9775 0 : return -1;
9776 2 : if (bridge_ifname &&
9777 1 : linux_br_add_if(drv->global->ioctl_sock,
9778 : bridge_ifname, name) < 0)
9779 0 : return -1;
9780 : }
9781 1 : if (linux_set_iface_flags(drv->global->ioctl_sock, name, 1)) {
9782 0 : wpa_printf(MSG_ERROR, "nl80211: Failed to set WDS STA "
9783 : "interface %s up", name);
9784 : }
9785 1 : return i802_set_sta_vlan(priv, addr, name, 0);
9786 : } else {
9787 1 : if (bridge_ifname)
9788 1 : linux_br_del_if(drv->global->ioctl_sock, bridge_ifname,
9789 : name);
9790 :
9791 1 : i802_set_sta_vlan(priv, addr, bss->ifname, 0);
9792 1 : nl80211_remove_iface(drv, if_nametoindex(name));
9793 1 : return 0;
9794 : }
9795 : }
9796 :
9797 :
9798 7997 : static void handle_eapol(int sock, void *eloop_ctx, void *sock_ctx)
9799 : {
9800 7997 : struct wpa_driver_nl80211_data *drv = eloop_ctx;
9801 : struct sockaddr_ll lladdr;
9802 : unsigned char buf[3000];
9803 : int len;
9804 7997 : socklen_t fromlen = sizeof(lladdr);
9805 :
9806 7997 : len = recvfrom(sock, buf, sizeof(buf), 0,
9807 : (struct sockaddr *)&lladdr, &fromlen);
9808 7997 : if (len < 0) {
9809 0 : wpa_printf(MSG_ERROR, "nl80211: EAPOL recv failed: %s",
9810 0 : strerror(errno));
9811 7997 : return;
9812 : }
9813 :
9814 7997 : if (have_ifidx(drv, lladdr.sll_ifindex))
9815 3384 : drv_event_eapol_rx(drv->ctx, lladdr.sll_addr, buf, len);
9816 : }
9817 :
9818 :
9819 4 : static int i802_check_bridge(struct wpa_driver_nl80211_data *drv,
9820 : struct i802_bss *bss,
9821 : const char *brname, const char *ifname)
9822 : {
9823 : int ifindex;
9824 : char in_br[IFNAMSIZ];
9825 :
9826 4 : os_strlcpy(bss->brname, brname, IFNAMSIZ);
9827 4 : ifindex = if_nametoindex(brname);
9828 4 : if (ifindex == 0) {
9829 : /*
9830 : * Bridge was configured, but the bridge device does
9831 : * not exist. Try to add it now.
9832 : */
9833 2 : if (linux_br_add(drv->global->ioctl_sock, brname) < 0) {
9834 0 : wpa_printf(MSG_ERROR, "nl80211: Failed to add the "
9835 : "bridge interface %s: %s",
9836 0 : brname, strerror(errno));
9837 0 : return -1;
9838 : }
9839 2 : bss->added_bridge = 1;
9840 2 : add_ifidx(drv, if_nametoindex(brname));
9841 : }
9842 :
9843 4 : if (linux_br_get(in_br, ifname) == 0) {
9844 0 : if (os_strcmp(in_br, brname) == 0)
9845 0 : return 0; /* already in the bridge */
9846 :
9847 0 : wpa_printf(MSG_DEBUG, "nl80211: Removing interface %s from "
9848 : "bridge %s", ifname, in_br);
9849 0 : if (linux_br_del_if(drv->global->ioctl_sock, in_br, ifname) <
9850 : 0) {
9851 0 : wpa_printf(MSG_ERROR, "nl80211: Failed to "
9852 : "remove interface %s from bridge "
9853 : "%s: %s",
9854 0 : ifname, brname, strerror(errno));
9855 0 : return -1;
9856 : }
9857 : }
9858 :
9859 4 : wpa_printf(MSG_DEBUG, "nl80211: Adding interface %s into bridge %s",
9860 : ifname, brname);
9861 4 : if (linux_br_add_if(drv->global->ioctl_sock, brname, ifname) < 0) {
9862 0 : wpa_printf(MSG_ERROR, "nl80211: Failed to add interface %s "
9863 : "into bridge %s: %s",
9864 0 : ifname, brname, strerror(errno));
9865 0 : return -1;
9866 : }
9867 4 : bss->added_if_into_bridge = 1;
9868 :
9869 4 : return 0;
9870 : }
9871 :
9872 :
9873 550 : static void *i802_init(struct hostapd_data *hapd,
9874 : struct wpa_init_params *params)
9875 : {
9876 : struct wpa_driver_nl80211_data *drv;
9877 : struct i802_bss *bss;
9878 : size_t i;
9879 : char brname[IFNAMSIZ];
9880 : int ifindex, br_ifindex;
9881 550 : int br_added = 0;
9882 :
9883 550 : bss = wpa_driver_nl80211_drv_init(hapd, params->ifname,
9884 : params->global_priv, 1,
9885 : params->bssid);
9886 550 : if (bss == NULL)
9887 0 : return NULL;
9888 :
9889 550 : drv = bss->drv;
9890 :
9891 550 : if (linux_br_get(brname, params->ifname) == 0) {
9892 0 : wpa_printf(MSG_DEBUG, "nl80211: Interface %s is in bridge %s",
9893 : params->ifname, brname);
9894 0 : br_ifindex = if_nametoindex(brname);
9895 : } else {
9896 550 : brname[0] = '\0';
9897 550 : br_ifindex = 0;
9898 : }
9899 :
9900 1106 : for (i = 0; i < params->num_bridge; i++) {
9901 556 : if (params->bridge[i]) {
9902 4 : ifindex = if_nametoindex(params->bridge[i]);
9903 4 : if (ifindex)
9904 2 : add_ifidx(drv, ifindex);
9905 4 : if (ifindex == br_ifindex)
9906 2 : br_added = 1;
9907 : }
9908 : }
9909 550 : if (!br_added && br_ifindex &&
9910 0 : (params->num_bridge == 0 || !params->bridge[0]))
9911 0 : add_ifidx(drv, br_ifindex);
9912 :
9913 : /* start listening for EAPOL on the default AP interface */
9914 550 : add_ifidx(drv, drv->ifindex);
9915 :
9916 554 : if (params->num_bridge && params->bridge[0] &&
9917 4 : i802_check_bridge(drv, bss, params->bridge[0], params->ifname) < 0)
9918 0 : goto failed;
9919 :
9920 550 : drv->eapol_sock = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_PAE));
9921 550 : if (drv->eapol_sock < 0) {
9922 0 : wpa_printf(MSG_ERROR, "nl80211: socket(PF_PACKET, SOCK_DGRAM, ETH_P_PAE) failed: %s",
9923 0 : strerror(errno));
9924 0 : goto failed;
9925 : }
9926 :
9927 550 : if (eloop_register_read_sock(drv->eapol_sock, handle_eapol, drv, NULL))
9928 : {
9929 0 : wpa_printf(MSG_INFO, "nl80211: Could not register read socket for eapol");
9930 0 : goto failed;
9931 : }
9932 :
9933 550 : if (linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname,
9934 : params->own_addr))
9935 0 : goto failed;
9936 :
9937 550 : memcpy(bss->addr, params->own_addr, ETH_ALEN);
9938 :
9939 550 : return bss;
9940 :
9941 : failed:
9942 0 : wpa_driver_nl80211_deinit(bss);
9943 0 : return NULL;
9944 : }
9945 :
9946 :
9947 550 : static void i802_deinit(void *priv)
9948 : {
9949 550 : struct i802_bss *bss = priv;
9950 550 : wpa_driver_nl80211_deinit(bss);
9951 550 : }
9952 :
9953 :
9954 66 : static enum nl80211_iftype wpa_driver_nl80211_if_type(
9955 : enum wpa_driver_if_type type)
9956 : {
9957 66 : switch (type) {
9958 : case WPA_IF_STATION:
9959 0 : return NL80211_IFTYPE_STATION;
9960 : case WPA_IF_P2P_CLIENT:
9961 : case WPA_IF_P2P_GROUP:
9962 22 : return NL80211_IFTYPE_P2P_CLIENT;
9963 : case WPA_IF_AP_VLAN:
9964 11 : return NL80211_IFTYPE_AP_VLAN;
9965 : case WPA_IF_AP_BSS:
9966 17 : return NL80211_IFTYPE_AP;
9967 : case WPA_IF_P2P_GO:
9968 16 : return NL80211_IFTYPE_P2P_GO;
9969 : case WPA_IF_P2P_DEVICE:
9970 0 : return NL80211_IFTYPE_P2P_DEVICE;
9971 : }
9972 0 : return -1;
9973 : }
9974 :
9975 :
9976 : #ifdef CONFIG_P2P
9977 :
9978 38 : static int nl80211_addr_in_use(struct nl80211_global *global, const u8 *addr)
9979 : {
9980 : struct wpa_driver_nl80211_data *drv;
9981 76 : dl_list_for_each(drv, &global->interfaces,
9982 : struct wpa_driver_nl80211_data, list) {
9983 38 : if (os_memcmp(addr, drv->first_bss->addr, ETH_ALEN) == 0)
9984 0 : return 1;
9985 : }
9986 38 : return 0;
9987 : }
9988 :
9989 :
9990 0 : static int nl80211_p2p_interface_addr(struct wpa_driver_nl80211_data *drv,
9991 : u8 *new_addr)
9992 : {
9993 : unsigned int idx;
9994 :
9995 0 : if (!drv->global)
9996 0 : return -1;
9997 :
9998 0 : os_memcpy(new_addr, drv->first_bss->addr, ETH_ALEN);
9999 0 : for (idx = 0; idx < 64; idx++) {
10000 0 : new_addr[0] = drv->first_bss->addr[0] | 0x02;
10001 0 : new_addr[0] ^= idx << 2;
10002 0 : if (!nl80211_addr_in_use(drv->global, new_addr))
10003 0 : break;
10004 : }
10005 0 : if (idx == 64)
10006 0 : return -1;
10007 :
10008 0 : wpa_printf(MSG_DEBUG, "nl80211: Assigned new P2P Interface Address "
10009 0 : MACSTR, MAC2STR(new_addr));
10010 :
10011 0 : return 0;
10012 : }
10013 :
10014 : #endif /* CONFIG_P2P */
10015 :
10016 :
10017 : struct wdev_info {
10018 : u64 wdev_id;
10019 : int wdev_id_set;
10020 : u8 macaddr[ETH_ALEN];
10021 : };
10022 :
10023 0 : static int nl80211_wdev_handler(struct nl_msg *msg, void *arg)
10024 : {
10025 0 : struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
10026 : struct nlattr *tb[NL80211_ATTR_MAX + 1];
10027 0 : struct wdev_info *wi = arg;
10028 :
10029 0 : nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
10030 : genlmsg_attrlen(gnlh, 0), NULL);
10031 0 : if (tb[NL80211_ATTR_WDEV]) {
10032 0 : wi->wdev_id = nla_get_u64(tb[NL80211_ATTR_WDEV]);
10033 0 : wi->wdev_id_set = 1;
10034 : }
10035 :
10036 0 : if (tb[NL80211_ATTR_MAC])
10037 0 : os_memcpy(wi->macaddr, nla_data(tb[NL80211_ATTR_MAC]),
10038 : ETH_ALEN);
10039 :
10040 0 : return NL_SKIP;
10041 : }
10042 :
10043 :
10044 66 : static int wpa_driver_nl80211_if_add(void *priv, enum wpa_driver_if_type type,
10045 : const char *ifname, const u8 *addr,
10046 : void *bss_ctx, void **drv_priv,
10047 : char *force_ifname, u8 *if_addr,
10048 : const char *bridge, int use_existing)
10049 : {
10050 : enum nl80211_iftype nlmode;
10051 66 : struct i802_bss *bss = priv;
10052 66 : struct wpa_driver_nl80211_data *drv = bss->drv;
10053 : int ifidx;
10054 66 : int added = 1;
10055 :
10056 66 : if (addr)
10057 28 : os_memcpy(if_addr, addr, ETH_ALEN);
10058 66 : nlmode = wpa_driver_nl80211_if_type(type);
10059 66 : if (nlmode == NL80211_IFTYPE_P2P_DEVICE) {
10060 : struct wdev_info p2pdev_info;
10061 :
10062 0 : os_memset(&p2pdev_info, 0, sizeof(p2pdev_info));
10063 0 : ifidx = nl80211_create_iface(drv, ifname, nlmode, addr,
10064 : 0, nl80211_wdev_handler,
10065 : &p2pdev_info, use_existing);
10066 0 : if (!p2pdev_info.wdev_id_set || ifidx != 0) {
10067 0 : wpa_printf(MSG_ERROR, "nl80211: Failed to create a P2P Device interface %s",
10068 : ifname);
10069 0 : return -1;
10070 : }
10071 :
10072 0 : drv->global->if_add_wdevid = p2pdev_info.wdev_id;
10073 0 : drv->global->if_add_wdevid_set = p2pdev_info.wdev_id_set;
10074 0 : if (!is_zero_ether_addr(p2pdev_info.macaddr))
10075 0 : os_memcpy(if_addr, p2pdev_info.macaddr, ETH_ALEN);
10076 0 : wpa_printf(MSG_DEBUG, "nl80211: New P2P Device interface %s (0x%llx) created",
10077 : ifname,
10078 0 : (long long unsigned int) p2pdev_info.wdev_id);
10079 : } else {
10080 66 : ifidx = nl80211_create_iface(drv, ifname, nlmode, addr,
10081 : 0, NULL, NULL, use_existing);
10082 66 : if (use_existing && ifidx == -ENFILE) {
10083 0 : added = 0;
10084 0 : ifidx = if_nametoindex(ifname);
10085 66 : } else if (ifidx < 0) {
10086 0 : return -1;
10087 : }
10088 : }
10089 :
10090 66 : if (!addr) {
10091 38 : if (drv->nlmode == NL80211_IFTYPE_P2P_DEVICE)
10092 0 : os_memcpy(if_addr, bss->addr, ETH_ALEN);
10093 38 : else if (linux_get_ifhwaddr(drv->global->ioctl_sock,
10094 38 : bss->ifname, if_addr) < 0) {
10095 0 : if (added)
10096 0 : nl80211_remove_iface(drv, ifidx);
10097 0 : return -1;
10098 : }
10099 : }
10100 :
10101 : #ifdef CONFIG_P2P
10102 38 : if (!addr &&
10103 32 : (type == WPA_IF_P2P_CLIENT || type == WPA_IF_P2P_GROUP ||
10104 : type == WPA_IF_P2P_GO)) {
10105 : /* Enforce unique P2P Interface Address */
10106 : u8 new_addr[ETH_ALEN];
10107 :
10108 38 : if (linux_get_ifhwaddr(drv->global->ioctl_sock, ifname,
10109 : new_addr) < 0) {
10110 0 : nl80211_remove_iface(drv, ifidx);
10111 0 : return -1;
10112 : }
10113 38 : if (nl80211_addr_in_use(drv->global, new_addr)) {
10114 0 : wpa_printf(MSG_DEBUG, "nl80211: Allocate new address "
10115 : "for P2P group interface");
10116 0 : if (nl80211_p2p_interface_addr(drv, new_addr) < 0) {
10117 0 : nl80211_remove_iface(drv, ifidx);
10118 0 : return -1;
10119 : }
10120 0 : if (linux_set_ifhwaddr(drv->global->ioctl_sock, ifname,
10121 : new_addr) < 0) {
10122 0 : nl80211_remove_iface(drv, ifidx);
10123 0 : return -1;
10124 : }
10125 : }
10126 38 : os_memcpy(if_addr, new_addr, ETH_ALEN);
10127 : }
10128 : #endif /* CONFIG_P2P */
10129 :
10130 66 : if (type == WPA_IF_AP_BSS) {
10131 17 : struct i802_bss *new_bss = os_zalloc(sizeof(*new_bss));
10132 17 : if (new_bss == NULL) {
10133 0 : if (added)
10134 0 : nl80211_remove_iface(drv, ifidx);
10135 0 : return -1;
10136 : }
10137 :
10138 17 : if (bridge &&
10139 0 : i802_check_bridge(drv, new_bss, bridge, ifname) < 0) {
10140 0 : wpa_printf(MSG_ERROR, "nl80211: Failed to add the new "
10141 : "interface %s to a bridge %s",
10142 : ifname, bridge);
10143 0 : if (added)
10144 0 : nl80211_remove_iface(drv, ifidx);
10145 0 : os_free(new_bss);
10146 0 : return -1;
10147 : }
10148 :
10149 17 : if (linux_set_iface_flags(drv->global->ioctl_sock, ifname, 1))
10150 : {
10151 0 : nl80211_remove_iface(drv, ifidx);
10152 0 : os_free(new_bss);
10153 0 : return -1;
10154 : }
10155 17 : os_strlcpy(new_bss->ifname, ifname, IFNAMSIZ);
10156 17 : os_memcpy(new_bss->addr, if_addr, ETH_ALEN);
10157 17 : new_bss->ifindex = ifidx;
10158 17 : new_bss->drv = drv;
10159 17 : new_bss->next = drv->first_bss->next;
10160 17 : new_bss->freq = drv->first_bss->freq;
10161 17 : new_bss->ctx = bss_ctx;
10162 17 : new_bss->added_if = added;
10163 17 : drv->first_bss->next = new_bss;
10164 17 : if (drv_priv)
10165 17 : *drv_priv = new_bss;
10166 17 : nl80211_init_bss(new_bss);
10167 :
10168 : /* Subscribe management frames for this WPA_IF_AP_BSS */
10169 17 : if (nl80211_setup_ap(new_bss))
10170 0 : return -1;
10171 : }
10172 :
10173 66 : if (drv->global)
10174 66 : drv->global->if_add_ifindex = ifidx;
10175 :
10176 66 : if (ifidx > 0)
10177 66 : add_ifidx(drv, ifidx);
10178 :
10179 66 : return 0;
10180 : }
10181 :
10182 :
10183 65 : static int wpa_driver_nl80211_if_remove(struct i802_bss *bss,
10184 : enum wpa_driver_if_type type,
10185 : const char *ifname)
10186 : {
10187 65 : struct wpa_driver_nl80211_data *drv = bss->drv;
10188 65 : int ifindex = if_nametoindex(ifname);
10189 :
10190 65 : wpa_printf(MSG_DEBUG, "nl80211: %s(type=%d ifname=%s) ifindex=%d added_if=%d",
10191 65 : __func__, type, ifname, ifindex, bss->added_if);
10192 65 : if (ifindex > 0 && (bss->added_if || bss->ifindex != ifindex))
10193 65 : nl80211_remove_iface(drv, ifindex);
10194 0 : else if (ifindex > 0 && !bss->added_if) {
10195 : struct wpa_driver_nl80211_data *drv2;
10196 0 : dl_list_for_each(drv2, &drv->global->interfaces,
10197 : struct wpa_driver_nl80211_data, list)
10198 0 : del_ifidx(drv2, ifindex);
10199 : }
10200 :
10201 65 : if (type != WPA_IF_AP_BSS)
10202 48 : return 0;
10203 :
10204 17 : if (bss->added_if_into_bridge) {
10205 0 : if (linux_br_del_if(drv->global->ioctl_sock, bss->brname,
10206 0 : bss->ifname) < 0)
10207 0 : wpa_printf(MSG_INFO, "nl80211: Failed to remove "
10208 : "interface %s from bridge %s: %s",
10209 0 : bss->ifname, bss->brname, strerror(errno));
10210 : }
10211 17 : if (bss->added_bridge) {
10212 0 : if (linux_br_del(drv->global->ioctl_sock, bss->brname) < 0)
10213 0 : wpa_printf(MSG_INFO, "nl80211: Failed to remove "
10214 : "bridge %s: %s",
10215 0 : bss->brname, strerror(errno));
10216 : }
10217 :
10218 17 : if (bss != drv->first_bss) {
10219 : struct i802_bss *tbss;
10220 :
10221 17 : wpa_printf(MSG_DEBUG, "nl80211: Not the first BSS - remove it");
10222 20 : for (tbss = drv->first_bss; tbss; tbss = tbss->next) {
10223 20 : if (tbss->next == bss) {
10224 17 : tbss->next = bss->next;
10225 : /* Unsubscribe management frames */
10226 17 : nl80211_teardown_ap(bss);
10227 17 : nl80211_destroy_bss(bss);
10228 17 : if (!bss->added_if)
10229 0 : i802_set_iface_flags(bss, 0);
10230 17 : os_free(bss);
10231 17 : bss = NULL;
10232 17 : break;
10233 : }
10234 : }
10235 17 : if (bss)
10236 0 : wpa_printf(MSG_INFO, "nl80211: %s - could not find "
10237 : "BSS %p in the list", __func__, bss);
10238 : } else {
10239 0 : wpa_printf(MSG_DEBUG, "nl80211: First BSS - reassign context");
10240 0 : nl80211_teardown_ap(bss);
10241 0 : if (!bss->added_if && !drv->first_bss->next)
10242 0 : wpa_driver_nl80211_del_beacon(drv);
10243 0 : nl80211_destroy_bss(bss);
10244 0 : if (!bss->added_if)
10245 0 : i802_set_iface_flags(bss, 0);
10246 0 : if (drv->first_bss->next) {
10247 0 : drv->first_bss = drv->first_bss->next;
10248 0 : drv->ctx = drv->first_bss->ctx;
10249 0 : os_free(bss);
10250 : } else {
10251 0 : wpa_printf(MSG_DEBUG, "nl80211: No second BSS to reassign context to");
10252 : }
10253 : }
10254 :
10255 17 : return 0;
10256 : }
10257 :
10258 :
10259 5999 : static int cookie_handler(struct nl_msg *msg, void *arg)
10260 : {
10261 : struct nlattr *tb[NL80211_ATTR_MAX + 1];
10262 5999 : struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
10263 5999 : u64 *cookie = arg;
10264 5999 : nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
10265 : genlmsg_attrlen(gnlh, 0), NULL);
10266 5999 : if (tb[NL80211_ATTR_COOKIE])
10267 5999 : *cookie = nla_get_u64(tb[NL80211_ATTR_COOKIE]);
10268 5999 : return NL_SKIP;
10269 : }
10270 :
10271 :
10272 7266 : static int nl80211_send_frame_cmd(struct i802_bss *bss,
10273 : unsigned int freq, unsigned int wait,
10274 : const u8 *buf, size_t buf_len,
10275 : u64 *cookie_out, int no_cck, int no_ack,
10276 : int offchanok)
10277 : {
10278 7266 : struct wpa_driver_nl80211_data *drv = bss->drv;
10279 : struct nl_msg *msg;
10280 : u64 cookie;
10281 7266 : int ret = -1;
10282 :
10283 7266 : msg = nlmsg_alloc();
10284 7266 : if (!msg)
10285 0 : return -1;
10286 :
10287 7266 : wpa_printf(MSG_MSGDUMP, "nl80211: CMD_FRAME freq=%u wait=%u no_cck=%d "
10288 : "no_ack=%d offchanok=%d",
10289 : freq, wait, no_cck, no_ack, offchanok);
10290 7266 : wpa_hexdump(MSG_MSGDUMP, "CMD_FRAME", buf, buf_len);
10291 7266 : nl80211_cmd(drv, msg, 0, NL80211_CMD_FRAME);
10292 :
10293 7266 : if (nl80211_set_iface_id(msg, bss) < 0)
10294 0 : goto nla_put_failure;
10295 7266 : if (freq)
10296 7251 : NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
10297 7266 : if (wait)
10298 1035 : NLA_PUT_U32(msg, NL80211_ATTR_DURATION, wait);
10299 7266 : if (offchanok && ((drv->capa.flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX) ||
10300 : drv->test_use_roc_tx))
10301 1773 : NLA_PUT_FLAG(msg, NL80211_ATTR_OFFCHANNEL_TX_OK);
10302 7266 : if (no_cck)
10303 1113 : NLA_PUT_FLAG(msg, NL80211_ATTR_TX_NO_CCK_RATE);
10304 7266 : if (no_ack)
10305 1672 : NLA_PUT_FLAG(msg, NL80211_ATTR_DONT_WAIT_FOR_ACK);
10306 :
10307 7266 : NLA_PUT(msg, NL80211_ATTR_FRAME, buf_len, buf);
10308 :
10309 7266 : cookie = 0;
10310 7266 : ret = send_and_recv_msgs(drv, msg, cookie_handler, &cookie);
10311 7266 : msg = NULL;
10312 7266 : if (ret) {
10313 693 : wpa_printf(MSG_DEBUG, "nl80211: Frame command failed: ret=%d "
10314 : "(%s) (freq=%u wait=%u)", ret, strerror(-ret),
10315 : freq, wait);
10316 693 : goto nla_put_failure;
10317 : }
10318 6573 : wpa_printf(MSG_MSGDUMP, "nl80211: Frame TX command accepted%s; "
10319 : "cookie 0x%llx", no_ack ? " (no ACK)" : "",
10320 : (long long unsigned int) cookie);
10321 :
10322 6573 : if (cookie_out)
10323 6128 : *cookie_out = no_ack ? (u64) -1 : cookie;
10324 :
10325 : nla_put_failure:
10326 7266 : nlmsg_free(msg);
10327 7266 : return ret;
10328 : }
10329 :
10330 :
10331 1328 : static int wpa_driver_nl80211_send_action(struct i802_bss *bss,
10332 : unsigned int freq,
10333 : unsigned int wait_time,
10334 : const u8 *dst, const u8 *src,
10335 : const u8 *bssid,
10336 : const u8 *data, size_t data_len,
10337 : int no_cck)
10338 : {
10339 1328 : struct wpa_driver_nl80211_data *drv = bss->drv;
10340 1328 : int ret = -1;
10341 : u8 *buf;
10342 : struct ieee80211_hdr *hdr;
10343 :
10344 1328 : wpa_printf(MSG_DEBUG, "nl80211: Send Action frame (ifindex=%d, "
10345 : "freq=%u MHz wait=%d ms no_cck=%d)",
10346 : drv->ifindex, freq, wait_time, no_cck);
10347 :
10348 1328 : buf = os_zalloc(24 + data_len);
10349 1328 : if (buf == NULL)
10350 0 : return ret;
10351 1328 : os_memcpy(buf + 24, data, data_len);
10352 1328 : hdr = (struct ieee80211_hdr *) buf;
10353 1328 : hdr->frame_control =
10354 : IEEE80211_FC(WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_ACTION);
10355 1328 : os_memcpy(hdr->addr1, dst, ETH_ALEN);
10356 1328 : os_memcpy(hdr->addr2, src, ETH_ALEN);
10357 1328 : os_memcpy(hdr->addr3, bssid, ETH_ALEN);
10358 :
10359 1608 : if (is_ap_interface(drv->nlmode) &&
10360 560 : (!(drv->capa.flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX) ||
10361 288 : (int) freq == bss->freq || drv->device_ap_sme ||
10362 4 : !drv->use_monitor))
10363 280 : ret = wpa_driver_nl80211_send_mlme(bss, buf, 24 + data_len,
10364 : 0, freq, no_cck, 1,
10365 : wait_time);
10366 : else
10367 1048 : ret = nl80211_send_frame_cmd(bss, freq, wait_time, buf,
10368 : 24 + data_len,
10369 : &drv->send_action_cookie,
10370 : no_cck, 0, 1);
10371 :
10372 1328 : os_free(buf);
10373 1328 : return ret;
10374 : }
10375 :
10376 :
10377 553 : static void wpa_driver_nl80211_send_action_cancel_wait(void *priv)
10378 : {
10379 553 : struct i802_bss *bss = priv;
10380 553 : struct wpa_driver_nl80211_data *drv = bss->drv;
10381 : struct nl_msg *msg;
10382 : int ret;
10383 :
10384 553 : msg = nlmsg_alloc();
10385 553 : if (!msg)
10386 553 : return;
10387 :
10388 553 : wpa_printf(MSG_DEBUG, "nl80211: Cancel TX frame wait: cookie=0x%llx",
10389 553 : (long long unsigned int) drv->send_action_cookie);
10390 553 : nl80211_cmd(drv, msg, 0, NL80211_CMD_FRAME_WAIT_CANCEL);
10391 :
10392 553 : if (nl80211_set_iface_id(msg, bss) < 0)
10393 0 : goto nla_put_failure;
10394 553 : NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, drv->send_action_cookie);
10395 :
10396 553 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
10397 553 : msg = NULL;
10398 553 : if (ret)
10399 74 : wpa_printf(MSG_DEBUG, "nl80211: wait cancel failed: ret=%d "
10400 : "(%s)", ret, strerror(-ret));
10401 :
10402 : nla_put_failure:
10403 553 : nlmsg_free(msg);
10404 : }
10405 :
10406 :
10407 1095 : static int wpa_driver_nl80211_remain_on_channel(void *priv, unsigned int freq,
10408 : unsigned int duration)
10409 : {
10410 1095 : struct i802_bss *bss = priv;
10411 1095 : struct wpa_driver_nl80211_data *drv = bss->drv;
10412 : struct nl_msg *msg;
10413 : int ret;
10414 : u64 cookie;
10415 :
10416 1095 : msg = nlmsg_alloc();
10417 1095 : if (!msg)
10418 0 : return -1;
10419 :
10420 1095 : nl80211_cmd(drv, msg, 0, NL80211_CMD_REMAIN_ON_CHANNEL);
10421 :
10422 1095 : if (nl80211_set_iface_id(msg, bss) < 0)
10423 0 : goto nla_put_failure;
10424 :
10425 1095 : NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
10426 1095 : NLA_PUT_U32(msg, NL80211_ATTR_DURATION, duration);
10427 :
10428 1095 : cookie = 0;
10429 1095 : ret = send_and_recv_msgs(drv, msg, cookie_handler, &cookie);
10430 1095 : msg = NULL;
10431 1095 : if (ret == 0) {
10432 1095 : wpa_printf(MSG_DEBUG, "nl80211: Remain-on-channel cookie "
10433 : "0x%llx for freq=%u MHz duration=%u",
10434 : (long long unsigned int) cookie, freq, duration);
10435 1095 : drv->remain_on_chan_cookie = cookie;
10436 1095 : drv->pending_remain_on_chan = 1;
10437 1095 : return 0;
10438 : }
10439 0 : wpa_printf(MSG_DEBUG, "nl80211: Failed to request remain-on-channel "
10440 : "(freq=%d duration=%u): %d (%s)",
10441 : freq, duration, ret, strerror(-ret));
10442 : nla_put_failure:
10443 0 : nlmsg_free(msg);
10444 0 : return -1;
10445 : }
10446 :
10447 :
10448 363 : static int wpa_driver_nl80211_cancel_remain_on_channel(void *priv)
10449 : {
10450 363 : struct i802_bss *bss = priv;
10451 363 : struct wpa_driver_nl80211_data *drv = bss->drv;
10452 : struct nl_msg *msg;
10453 : int ret;
10454 :
10455 363 : if (!drv->pending_remain_on_chan) {
10456 0 : wpa_printf(MSG_DEBUG, "nl80211: No pending remain-on-channel "
10457 : "to cancel");
10458 0 : return -1;
10459 : }
10460 :
10461 363 : wpa_printf(MSG_DEBUG, "nl80211: Cancel remain-on-channel with cookie "
10462 : "0x%llx",
10463 363 : (long long unsigned int) drv->remain_on_chan_cookie);
10464 :
10465 363 : msg = nlmsg_alloc();
10466 363 : if (!msg)
10467 0 : return -1;
10468 :
10469 363 : nl80211_cmd(drv, msg, 0, NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL);
10470 :
10471 363 : if (nl80211_set_iface_id(msg, bss) < 0)
10472 0 : goto nla_put_failure;
10473 :
10474 363 : NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, drv->remain_on_chan_cookie);
10475 :
10476 363 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
10477 363 : msg = NULL;
10478 363 : if (ret == 0)
10479 361 : return 0;
10480 2 : wpa_printf(MSG_DEBUG, "nl80211: Failed to cancel remain-on-channel: "
10481 : "%d (%s)", ret, strerror(-ret));
10482 : nla_put_failure:
10483 2 : nlmsg_free(msg);
10484 2 : return -1;
10485 : }
10486 :
10487 :
10488 8743 : static int wpa_driver_nl80211_probe_req_report(struct i802_bss *bss, int report)
10489 : {
10490 8743 : struct wpa_driver_nl80211_data *drv = bss->drv;
10491 :
10492 8743 : if (!report) {
10493 7649 : if (bss->nl_preq && drv->device_ap_sme &&
10494 0 : is_ap_interface(drv->nlmode)) {
10495 : /*
10496 : * Do not disable Probe Request reporting that was
10497 : * enabled in nl80211_setup_ap().
10498 : */
10499 0 : wpa_printf(MSG_DEBUG, "nl80211: Skip disabling of "
10500 : "Probe Request reporting nl_preq=%p while "
10501 : "in AP mode", bss->nl_preq);
10502 7649 : } else if (bss->nl_preq) {
10503 767 : wpa_printf(MSG_DEBUG, "nl80211: Disable Probe Request "
10504 : "reporting nl_preq=%p", bss->nl_preq);
10505 767 : nl80211_destroy_eloop_handle(&bss->nl_preq);
10506 : }
10507 7649 : return 0;
10508 : }
10509 :
10510 1094 : if (bss->nl_preq) {
10511 326 : wpa_printf(MSG_DEBUG, "nl80211: Probe Request reporting "
10512 : "already on! nl_preq=%p", bss->nl_preq);
10513 326 : return 0;
10514 : }
10515 :
10516 768 : bss->nl_preq = nl_create_handle(drv->global->nl_cb, "preq");
10517 768 : if (bss->nl_preq == NULL)
10518 0 : return -1;
10519 768 : wpa_printf(MSG_DEBUG, "nl80211: Enable Probe Request "
10520 : "reporting nl_preq=%p", bss->nl_preq);
10521 :
10522 768 : if (nl80211_register_frame(bss, bss->nl_preq,
10523 : (WLAN_FC_TYPE_MGMT << 2) |
10524 : (WLAN_FC_STYPE_PROBE_REQ << 4),
10525 : NULL, 0) < 0)
10526 1 : goto out_err;
10527 :
10528 767 : nl80211_register_eloop_read(&bss->nl_preq,
10529 : wpa_driver_nl80211_event_receive,
10530 767 : bss->nl_cb);
10531 :
10532 767 : return 0;
10533 :
10534 : out_err:
10535 1 : nl_destroy_handles(&bss->nl_preq);
10536 1 : return -1;
10537 : }
10538 :
10539 :
10540 523 : static int nl80211_disable_11b_rates(struct wpa_driver_nl80211_data *drv,
10541 : int ifindex, int disabled)
10542 : {
10543 : struct nl_msg *msg;
10544 : struct nlattr *bands, *band;
10545 : int ret;
10546 :
10547 523 : msg = nlmsg_alloc();
10548 523 : if (!msg)
10549 0 : return -1;
10550 :
10551 523 : nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_TX_BITRATE_MASK);
10552 523 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
10553 :
10554 523 : bands = nla_nest_start(msg, NL80211_ATTR_TX_RATES);
10555 523 : if (!bands)
10556 0 : goto nla_put_failure;
10557 :
10558 : /*
10559 : * Disable 2 GHz rates 1, 2, 5.5, 11 Mbps by masking out everything
10560 : * else apart from 6, 9, 12, 18, 24, 36, 48, 54 Mbps from non-MCS
10561 : * rates. All 5 GHz rates are left enabled.
10562 : */
10563 523 : band = nla_nest_start(msg, NL80211_BAND_2GHZ);
10564 523 : if (!band)
10565 0 : goto nla_put_failure;
10566 523 : if (disabled) {
10567 298 : NLA_PUT(msg, NL80211_TXRATE_LEGACY, 8,
10568 : "\x0c\x12\x18\x24\x30\x48\x60\x6c");
10569 : }
10570 523 : nla_nest_end(msg, band);
10571 :
10572 523 : nla_nest_end(msg, bands);
10573 :
10574 523 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
10575 523 : msg = NULL;
10576 523 : if (ret) {
10577 75 : wpa_printf(MSG_DEBUG, "nl80211: Set TX rates failed: ret=%d "
10578 : "(%s)", ret, strerror(-ret));
10579 : } else
10580 448 : drv->disabled_11b_rates = disabled;
10581 :
10582 523 : return ret;
10583 :
10584 : nla_put_failure:
10585 0 : nlmsg_free(msg);
10586 0 : return -1;
10587 : }
10588 :
10589 :
10590 126 : static int wpa_driver_nl80211_deinit_ap(void *priv)
10591 : {
10592 126 : struct i802_bss *bss = priv;
10593 126 : struct wpa_driver_nl80211_data *drv = bss->drv;
10594 126 : if (!is_ap_interface(drv->nlmode))
10595 0 : return -1;
10596 126 : wpa_driver_nl80211_del_beacon(drv);
10597 :
10598 : /*
10599 : * If the P2P GO interface was dynamically added, then it is
10600 : * possible that the interface change to station is not possible.
10601 : */
10602 126 : if (drv->nlmode == NL80211_IFTYPE_P2P_GO && bss->if_dynamic)
10603 16 : return 0;
10604 :
10605 110 : return wpa_driver_nl80211_set_mode(priv, NL80211_IFTYPE_STATION);
10606 : }
10607 :
10608 :
10609 0 : static int wpa_driver_nl80211_stop_ap(void *priv)
10610 : {
10611 0 : struct i802_bss *bss = priv;
10612 0 : struct wpa_driver_nl80211_data *drv = bss->drv;
10613 0 : if (!is_ap_interface(drv->nlmode))
10614 0 : return -1;
10615 0 : wpa_driver_nl80211_del_beacon(drv);
10616 0 : bss->beacon_set = 0;
10617 0 : return 0;
10618 : }
10619 :
10620 :
10621 106 : static int wpa_driver_nl80211_deinit_p2p_cli(void *priv)
10622 : {
10623 106 : struct i802_bss *bss = priv;
10624 106 : struct wpa_driver_nl80211_data *drv = bss->drv;
10625 106 : if (drv->nlmode != NL80211_IFTYPE_P2P_CLIENT)
10626 1 : return -1;
10627 :
10628 : /*
10629 : * If the P2P Client interface was dynamically added, then it is
10630 : * possible that the interface change to station is not possible.
10631 : */
10632 105 : if (bss->if_dynamic)
10633 0 : return 0;
10634 :
10635 105 : return wpa_driver_nl80211_set_mode(priv, NL80211_IFTYPE_STATION);
10636 : }
10637 :
10638 :
10639 2 : static void wpa_driver_nl80211_resume(void *priv)
10640 : {
10641 2 : struct i802_bss *bss = priv;
10642 :
10643 2 : if (i802_set_iface_flags(bss, 1))
10644 0 : wpa_printf(MSG_DEBUG, "nl80211: Failed to set interface up on resume event");
10645 2 : }
10646 :
10647 :
10648 13 : static int nl80211_send_ft_action(void *priv, u8 action, const u8 *target_ap,
10649 : const u8 *ies, size_t ies_len)
10650 : {
10651 13 : struct i802_bss *bss = priv;
10652 13 : struct wpa_driver_nl80211_data *drv = bss->drv;
10653 : int ret;
10654 : u8 *data, *pos;
10655 : size_t data_len;
10656 13 : const u8 *own_addr = bss->addr;
10657 :
10658 13 : if (action != 1) {
10659 0 : wpa_printf(MSG_ERROR, "nl80211: Unsupported send_ft_action "
10660 : "action %d", action);
10661 0 : return -1;
10662 : }
10663 :
10664 : /*
10665 : * Action frame payload:
10666 : * Category[1] = 6 (Fast BSS Transition)
10667 : * Action[1] = 1 (Fast BSS Transition Request)
10668 : * STA Address
10669 : * Target AP Address
10670 : * FT IEs
10671 : */
10672 :
10673 13 : data_len = 2 + 2 * ETH_ALEN + ies_len;
10674 13 : data = os_malloc(data_len);
10675 13 : if (data == NULL)
10676 0 : return -1;
10677 13 : pos = data;
10678 13 : *pos++ = 0x06; /* FT Action category */
10679 13 : *pos++ = action;
10680 13 : os_memcpy(pos, own_addr, ETH_ALEN);
10681 13 : pos += ETH_ALEN;
10682 13 : os_memcpy(pos, target_ap, ETH_ALEN);
10683 13 : pos += ETH_ALEN;
10684 13 : os_memcpy(pos, ies, ies_len);
10685 :
10686 13 : ret = wpa_driver_nl80211_send_action(bss, drv->assoc_freq, 0,
10687 13 : drv->bssid, own_addr, drv->bssid,
10688 : data, data_len, 0);
10689 13 : os_free(data);
10690 :
10691 13 : return ret;
10692 : }
10693 :
10694 :
10695 8 : static int nl80211_signal_monitor(void *priv, int threshold, int hysteresis)
10696 : {
10697 8 : struct i802_bss *bss = priv;
10698 8 : struct wpa_driver_nl80211_data *drv = bss->drv;
10699 : struct nl_msg *msg;
10700 : struct nlattr *cqm;
10701 8 : int ret = -1;
10702 :
10703 8 : wpa_printf(MSG_DEBUG, "nl80211: Signal monitor threshold=%d "
10704 : "hysteresis=%d", threshold, hysteresis);
10705 :
10706 8 : msg = nlmsg_alloc();
10707 8 : if (!msg)
10708 0 : return -1;
10709 :
10710 8 : nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_CQM);
10711 :
10712 8 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex);
10713 :
10714 8 : cqm = nla_nest_start(msg, NL80211_ATTR_CQM);
10715 8 : if (cqm == NULL)
10716 0 : goto nla_put_failure;
10717 :
10718 8 : NLA_PUT_U32(msg, NL80211_ATTR_CQM_RSSI_THOLD, threshold);
10719 8 : NLA_PUT_U32(msg, NL80211_ATTR_CQM_RSSI_HYST, hysteresis);
10720 8 : nla_nest_end(msg, cqm);
10721 :
10722 8 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
10723 8 : msg = NULL;
10724 :
10725 : nla_put_failure:
10726 8 : nlmsg_free(msg);
10727 8 : return ret;
10728 : }
10729 :
10730 :
10731 5 : static int get_channel_width(struct nl_msg *msg, void *arg)
10732 : {
10733 : struct nlattr *tb[NL80211_ATTR_MAX + 1];
10734 5 : struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
10735 5 : struct wpa_signal_info *sig_change = arg;
10736 :
10737 5 : nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
10738 : genlmsg_attrlen(gnlh, 0), NULL);
10739 :
10740 5 : sig_change->center_frq1 = -1;
10741 5 : sig_change->center_frq2 = -1;
10742 5 : sig_change->chanwidth = CHAN_WIDTH_UNKNOWN;
10743 :
10744 5 : if (tb[NL80211_ATTR_CHANNEL_WIDTH]) {
10745 5 : sig_change->chanwidth = convert2width(
10746 5 : nla_get_u32(tb[NL80211_ATTR_CHANNEL_WIDTH]));
10747 5 : if (tb[NL80211_ATTR_CENTER_FREQ1])
10748 5 : sig_change->center_frq1 =
10749 5 : nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ1]);
10750 5 : if (tb[NL80211_ATTR_CENTER_FREQ2])
10751 0 : sig_change->center_frq2 =
10752 0 : nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ2]);
10753 : }
10754 :
10755 5 : return NL_SKIP;
10756 : }
10757 :
10758 :
10759 5 : static int nl80211_get_channel_width(struct wpa_driver_nl80211_data *drv,
10760 : struct wpa_signal_info *sig)
10761 : {
10762 : struct nl_msg *msg;
10763 :
10764 5 : msg = nlmsg_alloc();
10765 5 : if (!msg)
10766 0 : return -ENOMEM;
10767 :
10768 5 : nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_INTERFACE);
10769 5 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
10770 :
10771 5 : return send_and_recv_msgs(drv, msg, get_channel_width, sig);
10772 :
10773 : nla_put_failure:
10774 0 : nlmsg_free(msg);
10775 0 : return -ENOBUFS;
10776 : }
10777 :
10778 :
10779 5 : static int nl80211_signal_poll(void *priv, struct wpa_signal_info *si)
10780 : {
10781 5 : struct i802_bss *bss = priv;
10782 5 : struct wpa_driver_nl80211_data *drv = bss->drv;
10783 : int res;
10784 :
10785 5 : os_memset(si, 0, sizeof(*si));
10786 5 : res = nl80211_get_link_signal(drv, si);
10787 5 : if (res != 0)
10788 0 : return res;
10789 :
10790 5 : res = nl80211_get_channel_width(drv, si);
10791 5 : if (res != 0)
10792 0 : return res;
10793 :
10794 5 : return nl80211_get_link_noise(drv, si);
10795 : }
10796 :
10797 :
10798 0 : static int wpa_driver_nl80211_shared_freq(void *priv)
10799 : {
10800 0 : struct i802_bss *bss = priv;
10801 0 : struct wpa_driver_nl80211_data *drv = bss->drv;
10802 : struct wpa_driver_nl80211_data *driver;
10803 0 : int freq = 0;
10804 :
10805 : /*
10806 : * If the same PHY is in connected state with some other interface,
10807 : * then retrieve the assoc freq.
10808 : */
10809 0 : wpa_printf(MSG_DEBUG, "nl80211: Get shared freq for PHY %s",
10810 0 : drv->phyname);
10811 :
10812 0 : dl_list_for_each(driver, &drv->global->interfaces,
10813 : struct wpa_driver_nl80211_data, list) {
10814 0 : if (drv == driver ||
10815 0 : os_strcmp(drv->phyname, driver->phyname) != 0 ||
10816 0 : !driver->associated)
10817 0 : continue;
10818 :
10819 0 : wpa_printf(MSG_DEBUG, "nl80211: Found a match for PHY %s - %s "
10820 : MACSTR,
10821 0 : driver->phyname, driver->first_bss->ifname,
10822 0 : MAC2STR(driver->first_bss->addr));
10823 0 : if (is_ap_interface(driver->nlmode))
10824 0 : freq = driver->first_bss->freq;
10825 : else
10826 0 : freq = nl80211_get_assoc_freq(driver);
10827 0 : wpa_printf(MSG_DEBUG, "nl80211: Shared freq for PHY %s: %d",
10828 0 : drv->phyname, freq);
10829 : }
10830 :
10831 0 : if (!freq)
10832 0 : wpa_printf(MSG_DEBUG, "nl80211: No shared interface for "
10833 0 : "PHY (%s) in associated state", drv->phyname);
10834 :
10835 0 : return freq;
10836 : }
10837 :
10838 :
10839 26 : static int nl80211_send_frame(void *priv, const u8 *data, size_t data_len,
10840 : int encrypt)
10841 : {
10842 26 : struct i802_bss *bss = priv;
10843 26 : return wpa_driver_nl80211_send_frame(bss, data, data_len, encrypt, 0,
10844 : 0, 0, 0, 0);
10845 : }
10846 :
10847 :
10848 69 : static int nl80211_set_param(void *priv, const char *param)
10849 : {
10850 69 : wpa_printf(MSG_DEBUG, "nl80211: driver param='%s'", param);
10851 69 : if (param == NULL)
10852 53 : return 0;
10853 :
10854 : #ifdef CONFIG_P2P
10855 16 : if (os_strstr(param, "use_p2p_group_interface=1")) {
10856 0 : struct i802_bss *bss = priv;
10857 0 : struct wpa_driver_nl80211_data *drv = bss->drv;
10858 :
10859 0 : wpa_printf(MSG_DEBUG, "nl80211: Use separate P2P group "
10860 : "interface");
10861 0 : drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_CONCURRENT;
10862 0 : drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_MGMT_AND_NON_P2P;
10863 : }
10864 :
10865 16 : if (os_strstr(param, "p2p_device=1")) {
10866 0 : struct i802_bss *bss = priv;
10867 0 : struct wpa_driver_nl80211_data *drv = bss->drv;
10868 0 : drv->allow_p2p_device = 1;
10869 : }
10870 : #endif /* CONFIG_P2P */
10871 :
10872 16 : if (os_strstr(param, "use_monitor=1")) {
10873 3 : struct i802_bss *bss = priv;
10874 3 : struct wpa_driver_nl80211_data *drv = bss->drv;
10875 3 : drv->use_monitor = 1;
10876 : }
10877 :
10878 16 : if (os_strstr(param, "force_connect_cmd=1")) {
10879 8 : struct i802_bss *bss = priv;
10880 8 : struct wpa_driver_nl80211_data *drv = bss->drv;
10881 8 : drv->capa.flags &= ~WPA_DRIVER_FLAGS_SME;
10882 : }
10883 :
10884 16 : if (os_strstr(param, "no_offchannel_tx=1")) {
10885 5 : struct i802_bss *bss = priv;
10886 5 : struct wpa_driver_nl80211_data *drv = bss->drv;
10887 5 : drv->capa.flags &= ~WPA_DRIVER_FLAGS_OFFCHANNEL_TX;
10888 5 : drv->test_use_roc_tx = 1;
10889 : }
10890 :
10891 16 : return 0;
10892 : }
10893 :
10894 :
10895 5 : static void * nl80211_global_init(void)
10896 : {
10897 : struct nl80211_global *global;
10898 : struct netlink_config *cfg;
10899 :
10900 5 : global = os_zalloc(sizeof(*global));
10901 5 : if (global == NULL)
10902 0 : return NULL;
10903 5 : global->ioctl_sock = -1;
10904 5 : dl_list_init(&global->interfaces);
10905 5 : global->if_add_ifindex = -1;
10906 :
10907 5 : cfg = os_zalloc(sizeof(*cfg));
10908 5 : if (cfg == NULL)
10909 0 : goto err;
10910 :
10911 5 : cfg->ctx = global;
10912 5 : cfg->newlink_cb = wpa_driver_nl80211_event_rtm_newlink;
10913 5 : cfg->dellink_cb = wpa_driver_nl80211_event_rtm_dellink;
10914 5 : global->netlink = netlink_init(cfg);
10915 5 : if (global->netlink == NULL) {
10916 0 : os_free(cfg);
10917 0 : goto err;
10918 : }
10919 :
10920 5 : if (wpa_driver_nl80211_init_nl_global(global) < 0)
10921 0 : goto err;
10922 :
10923 5 : global->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
10924 5 : if (global->ioctl_sock < 0) {
10925 0 : wpa_printf(MSG_ERROR, "nl80211: socket(PF_INET,SOCK_DGRAM) failed: %s",
10926 0 : strerror(errno));
10927 0 : goto err;
10928 : }
10929 :
10930 5 : return global;
10931 :
10932 : err:
10933 0 : nl80211_global_deinit(global);
10934 0 : return NULL;
10935 : }
10936 :
10937 :
10938 5 : static void nl80211_global_deinit(void *priv)
10939 : {
10940 5 : struct nl80211_global *global = priv;
10941 5 : if (global == NULL)
10942 5 : return;
10943 5 : if (!dl_list_empty(&global->interfaces)) {
10944 0 : wpa_printf(MSG_ERROR, "nl80211: %u interface(s) remain at "
10945 : "nl80211_global_deinit",
10946 : dl_list_len(&global->interfaces));
10947 : }
10948 :
10949 5 : if (global->netlink)
10950 5 : netlink_deinit(global->netlink);
10951 :
10952 5 : nl_destroy_handles(&global->nl);
10953 :
10954 5 : if (global->nl_event)
10955 5 : nl80211_destroy_eloop_handle(&global->nl_event);
10956 :
10957 5 : nl_cb_put(global->nl_cb);
10958 :
10959 5 : if (global->ioctl_sock >= 0)
10960 5 : close(global->ioctl_sock);
10961 :
10962 5 : os_free(global);
10963 : }
10964 :
10965 :
10966 2220 : static const char * nl80211_get_radio_name(void *priv)
10967 : {
10968 2220 : struct i802_bss *bss = priv;
10969 2220 : struct wpa_driver_nl80211_data *drv = bss->drv;
10970 2220 : return drv->phyname;
10971 : }
10972 :
10973 :
10974 617 : static int nl80211_pmkid(struct i802_bss *bss, int cmd, const u8 *bssid,
10975 : const u8 *pmkid)
10976 : {
10977 : struct nl_msg *msg;
10978 :
10979 617 : msg = nlmsg_alloc();
10980 617 : if (!msg)
10981 0 : return -ENOMEM;
10982 :
10983 617 : nl80211_cmd(bss->drv, msg, 0, cmd);
10984 :
10985 617 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(bss->ifname));
10986 617 : if (pmkid)
10987 548 : NLA_PUT(msg, NL80211_ATTR_PMKID, 16, pmkid);
10988 617 : if (bssid)
10989 548 : NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid);
10990 :
10991 617 : return send_and_recv_msgs(bss->drv, msg, NULL, NULL);
10992 : nla_put_failure:
10993 0 : nlmsg_free(msg);
10994 0 : return -ENOBUFS;
10995 : }
10996 :
10997 :
10998 274 : static int nl80211_add_pmkid(void *priv, const u8 *bssid, const u8 *pmkid)
10999 : {
11000 274 : struct i802_bss *bss = priv;
11001 274 : wpa_printf(MSG_DEBUG, "nl80211: Add PMKID for " MACSTR, MAC2STR(bssid));
11002 274 : return nl80211_pmkid(bss, NL80211_CMD_SET_PMKSA, bssid, pmkid);
11003 : }
11004 :
11005 :
11006 274 : static int nl80211_remove_pmkid(void *priv, const u8 *bssid, const u8 *pmkid)
11007 : {
11008 274 : struct i802_bss *bss = priv;
11009 1644 : wpa_printf(MSG_DEBUG, "nl80211: Delete PMKID for " MACSTR,
11010 1644 : MAC2STR(bssid));
11011 274 : return nl80211_pmkid(bss, NL80211_CMD_DEL_PMKSA, bssid, pmkid);
11012 : }
11013 :
11014 :
11015 69 : static int nl80211_flush_pmkid(void *priv)
11016 : {
11017 69 : struct i802_bss *bss = priv;
11018 69 : wpa_printf(MSG_DEBUG, "nl80211: Flush PMKIDs");
11019 69 : return nl80211_pmkid(bss, NL80211_CMD_FLUSH_PMKSA, NULL, NULL);
11020 : }
11021 :
11022 :
11023 35 : static void clean_survey_results(struct survey_results *survey_results)
11024 : {
11025 : struct freq_survey *survey, *tmp;
11026 :
11027 35 : if (dl_list_empty(&survey_results->survey_list))
11028 55 : return;
11029 :
11030 30 : dl_list_for_each_safe(survey, tmp, &survey_results->survey_list,
11031 : struct freq_survey, list) {
11032 15 : dl_list_del(&survey->list);
11033 15 : os_free(survey);
11034 : }
11035 : }
11036 :
11037 :
11038 35 : static void add_survey(struct nlattr **sinfo, u32 ifidx,
11039 : struct dl_list *survey_list)
11040 : {
11041 : struct freq_survey *survey;
11042 :
11043 35 : survey = os_zalloc(sizeof(struct freq_survey));
11044 35 : if (!survey)
11045 35 : return;
11046 :
11047 35 : survey->ifidx = ifidx;
11048 35 : survey->freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]);
11049 35 : survey->filled = 0;
11050 :
11051 35 : if (sinfo[NL80211_SURVEY_INFO_NOISE]) {
11052 35 : survey->nf = (int8_t)
11053 35 : nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
11054 35 : survey->filled |= SURVEY_HAS_NF;
11055 : }
11056 :
11057 35 : if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME]) {
11058 0 : survey->channel_time =
11059 0 : nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME]);
11060 0 : survey->filled |= SURVEY_HAS_CHAN_TIME;
11061 : }
11062 :
11063 35 : if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY]) {
11064 0 : survey->channel_time_busy =
11065 0 : nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY]);
11066 0 : survey->filled |= SURVEY_HAS_CHAN_TIME_BUSY;
11067 : }
11068 :
11069 35 : if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_RX]) {
11070 0 : survey->channel_time_rx =
11071 0 : nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_RX]);
11072 0 : survey->filled |= SURVEY_HAS_CHAN_TIME_RX;
11073 : }
11074 :
11075 35 : if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_TX]) {
11076 0 : survey->channel_time_tx =
11077 0 : nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_TX]);
11078 0 : survey->filled |= SURVEY_HAS_CHAN_TIME_TX;
11079 : }
11080 :
11081 70 : wpa_printf(MSG_DEBUG, "nl80211: Freq survey dump event (freq=%d MHz noise=%d channel_time=%ld busy_time=%ld tx_time=%ld rx_time=%ld filled=%04x)",
11082 : survey->freq,
11083 35 : survey->nf,
11084 : (unsigned long int) survey->channel_time,
11085 : (unsigned long int) survey->channel_time_busy,
11086 : (unsigned long int) survey->channel_time_tx,
11087 : (unsigned long int) survey->channel_time_rx,
11088 : survey->filled);
11089 :
11090 35 : dl_list_add_tail(survey_list, &survey->list);
11091 : }
11092 :
11093 :
11094 35 : static int check_survey_ok(struct nlattr **sinfo, u32 surveyed_freq,
11095 : unsigned int freq_filter)
11096 : {
11097 35 : if (!freq_filter)
11098 35 : return 1;
11099 :
11100 0 : return freq_filter == surveyed_freq;
11101 : }
11102 :
11103 :
11104 35 : static int survey_handler(struct nl_msg *msg, void *arg)
11105 : {
11106 : struct nlattr *tb[NL80211_ATTR_MAX + 1];
11107 35 : struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
11108 : struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1];
11109 : struct survey_results *survey_results;
11110 35 : u32 surveyed_freq = 0;
11111 : u32 ifidx;
11112 :
11113 : static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = {
11114 : [NL80211_SURVEY_INFO_FREQUENCY] = { .type = NLA_U32 },
11115 : [NL80211_SURVEY_INFO_NOISE] = { .type = NLA_U8 },
11116 : };
11117 :
11118 35 : survey_results = (struct survey_results *) arg;
11119 :
11120 35 : nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
11121 : genlmsg_attrlen(gnlh, 0), NULL);
11122 :
11123 35 : if (!tb[NL80211_ATTR_IFINDEX])
11124 0 : return NL_SKIP;
11125 :
11126 35 : ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
11127 :
11128 35 : if (!tb[NL80211_ATTR_SURVEY_INFO])
11129 0 : return NL_SKIP;
11130 :
11131 35 : if (nla_parse_nested(sinfo, NL80211_SURVEY_INFO_MAX,
11132 : tb[NL80211_ATTR_SURVEY_INFO],
11133 : survey_policy))
11134 0 : return NL_SKIP;
11135 :
11136 35 : if (!sinfo[NL80211_SURVEY_INFO_FREQUENCY]) {
11137 0 : wpa_printf(MSG_ERROR, "nl80211: Invalid survey data");
11138 0 : return NL_SKIP;
11139 : }
11140 :
11141 35 : surveyed_freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]);
11142 :
11143 35 : if (!check_survey_ok(sinfo, surveyed_freq,
11144 : survey_results->freq_filter))
11145 0 : return NL_SKIP;
11146 :
11147 35 : if (survey_results->freq_filter &&
11148 0 : survey_results->freq_filter != surveyed_freq) {
11149 0 : wpa_printf(MSG_EXCESSIVE, "nl80211: Ignoring survey data for freq %d MHz",
11150 : surveyed_freq);
11151 0 : return NL_SKIP;
11152 : }
11153 :
11154 35 : add_survey(sinfo, ifidx, &survey_results->survey_list);
11155 :
11156 35 : return NL_SKIP;
11157 : }
11158 :
11159 :
11160 35 : static int wpa_driver_nl80211_get_survey(void *priv, unsigned int freq)
11161 : {
11162 35 : struct i802_bss *bss = priv;
11163 35 : struct wpa_driver_nl80211_data *drv = bss->drv;
11164 : struct nl_msg *msg;
11165 35 : int err = -ENOBUFS;
11166 : union wpa_event_data data;
11167 : struct survey_results *survey_results;
11168 :
11169 35 : os_memset(&data, 0, sizeof(data));
11170 35 : survey_results = &data.survey_results;
11171 :
11172 35 : dl_list_init(&survey_results->survey_list);
11173 :
11174 35 : msg = nlmsg_alloc();
11175 35 : if (!msg)
11176 0 : goto nla_put_failure;
11177 :
11178 35 : nl80211_cmd(drv, msg, NLM_F_DUMP, NL80211_CMD_GET_SURVEY);
11179 :
11180 35 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
11181 :
11182 35 : if (freq)
11183 0 : data.survey_results.freq_filter = freq;
11184 :
11185 : do {
11186 35 : wpa_printf(MSG_DEBUG, "nl80211: Fetch survey data");
11187 35 : err = send_and_recv_msgs(drv, msg, survey_handler,
11188 : survey_results);
11189 35 : } while (err > 0);
11190 :
11191 35 : if (err) {
11192 0 : wpa_printf(MSG_ERROR, "nl80211: Failed to process survey data");
11193 0 : goto out_clean;
11194 : }
11195 :
11196 35 : wpa_supplicant_event(drv->ctx, EVENT_SURVEY, &data);
11197 :
11198 : out_clean:
11199 35 : clean_survey_results(survey_results);
11200 : nla_put_failure:
11201 35 : return err;
11202 : }
11203 :
11204 :
11205 618 : static void nl80211_set_rekey_info(void *priv, const u8 *kek, const u8 *kck,
11206 : const u8 *replay_ctr)
11207 : {
11208 618 : struct i802_bss *bss = priv;
11209 618 : struct wpa_driver_nl80211_data *drv = bss->drv;
11210 : struct nlattr *replay_nested;
11211 : struct nl_msg *msg;
11212 :
11213 618 : msg = nlmsg_alloc();
11214 618 : if (!msg)
11215 0 : return;
11216 :
11217 618 : nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_REKEY_OFFLOAD);
11218 :
11219 618 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex);
11220 :
11221 618 : replay_nested = nla_nest_start(msg, NL80211_ATTR_REKEY_DATA);
11222 618 : if (!replay_nested)
11223 0 : goto nla_put_failure;
11224 :
11225 618 : NLA_PUT(msg, NL80211_REKEY_DATA_KEK, NL80211_KEK_LEN, kek);
11226 618 : NLA_PUT(msg, NL80211_REKEY_DATA_KCK, NL80211_KCK_LEN, kck);
11227 618 : NLA_PUT(msg, NL80211_REKEY_DATA_REPLAY_CTR, NL80211_REPLAY_CTR_LEN,
11228 : replay_ctr);
11229 :
11230 618 : nla_nest_end(msg, replay_nested);
11231 :
11232 618 : send_and_recv_msgs(drv, msg, NULL, NULL);
11233 618 : return;
11234 : nla_put_failure:
11235 0 : nlmsg_free(msg);
11236 : }
11237 :
11238 :
11239 0 : static void nl80211_send_null_frame(struct i802_bss *bss, const u8 *own_addr,
11240 : const u8 *addr, int qos)
11241 : {
11242 : /* send data frame to poll STA and check whether
11243 : * this frame is ACKed */
11244 : struct {
11245 : struct ieee80211_hdr hdr;
11246 : u16 qos_ctl;
11247 : } STRUCT_PACKED nulldata;
11248 : size_t size;
11249 :
11250 : /* Send data frame to poll STA and check whether this frame is ACKed */
11251 :
11252 0 : os_memset(&nulldata, 0, sizeof(nulldata));
11253 :
11254 0 : if (qos) {
11255 0 : nulldata.hdr.frame_control =
11256 : IEEE80211_FC(WLAN_FC_TYPE_DATA,
11257 : WLAN_FC_STYPE_QOS_NULL);
11258 0 : size = sizeof(nulldata);
11259 : } else {
11260 0 : nulldata.hdr.frame_control =
11261 : IEEE80211_FC(WLAN_FC_TYPE_DATA,
11262 : WLAN_FC_STYPE_NULLFUNC);
11263 0 : size = sizeof(struct ieee80211_hdr);
11264 : }
11265 :
11266 0 : nulldata.hdr.frame_control |= host_to_le16(WLAN_FC_FROMDS);
11267 0 : os_memcpy(nulldata.hdr.IEEE80211_DA_FROMDS, addr, ETH_ALEN);
11268 0 : os_memcpy(nulldata.hdr.IEEE80211_BSSID_FROMDS, own_addr, ETH_ALEN);
11269 0 : os_memcpy(nulldata.hdr.IEEE80211_SA_FROMDS, own_addr, ETH_ALEN);
11270 :
11271 0 : if (wpa_driver_nl80211_send_mlme(bss, (u8 *) &nulldata, size, 0, 0, 0,
11272 : 0, 0) < 0)
11273 0 : wpa_printf(MSG_DEBUG, "nl80211_send_null_frame: Failed to "
11274 : "send poll frame");
11275 0 : }
11276 :
11277 1 : static void nl80211_poll_client(void *priv, const u8 *own_addr, const u8 *addr,
11278 : int qos)
11279 : {
11280 1 : struct i802_bss *bss = priv;
11281 1 : struct wpa_driver_nl80211_data *drv = bss->drv;
11282 : struct nl_msg *msg;
11283 :
11284 1 : if (!drv->poll_command_supported) {
11285 0 : nl80211_send_null_frame(bss, own_addr, addr, qos);
11286 0 : return;
11287 : }
11288 :
11289 1 : msg = nlmsg_alloc();
11290 1 : if (!msg)
11291 0 : return;
11292 :
11293 1 : nl80211_cmd(drv, msg, 0, NL80211_CMD_PROBE_CLIENT);
11294 :
11295 1 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex);
11296 1 : NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
11297 :
11298 1 : send_and_recv_msgs(drv, msg, NULL, NULL);
11299 1 : return;
11300 : nla_put_failure:
11301 0 : nlmsg_free(msg);
11302 : }
11303 :
11304 :
11305 0 : static int nl80211_set_power_save(struct i802_bss *bss, int enabled)
11306 : {
11307 : struct nl_msg *msg;
11308 :
11309 0 : msg = nlmsg_alloc();
11310 0 : if (!msg)
11311 0 : return -ENOMEM;
11312 :
11313 0 : nl80211_cmd(bss->drv, msg, 0, NL80211_CMD_SET_POWER_SAVE);
11314 0 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, bss->ifindex);
11315 0 : NLA_PUT_U32(msg, NL80211_ATTR_PS_STATE,
11316 : enabled ? NL80211_PS_ENABLED : NL80211_PS_DISABLED);
11317 0 : return send_and_recv_msgs(bss->drv, msg, NULL, NULL);
11318 : nla_put_failure:
11319 0 : nlmsg_free(msg);
11320 0 : return -ENOBUFS;
11321 : }
11322 :
11323 :
11324 0 : static int nl80211_set_p2p_powersave(void *priv, int legacy_ps, int opp_ps,
11325 : int ctwindow)
11326 : {
11327 0 : struct i802_bss *bss = priv;
11328 :
11329 0 : wpa_printf(MSG_DEBUG, "nl80211: set_p2p_powersave (legacy_ps=%d "
11330 : "opp_ps=%d ctwindow=%d)", legacy_ps, opp_ps, ctwindow);
11331 :
11332 0 : if (opp_ps != -1 || ctwindow != -1) {
11333 : #ifdef ANDROID_P2P
11334 : wpa_driver_set_p2p_ps(priv, legacy_ps, opp_ps, ctwindow);
11335 : #else /* ANDROID_P2P */
11336 0 : return -1; /* Not yet supported */
11337 : #endif /* ANDROID_P2P */
11338 : }
11339 :
11340 0 : if (legacy_ps == -1)
11341 0 : return 0;
11342 0 : if (legacy_ps != 0 && legacy_ps != 1)
11343 0 : return -1; /* Not yet supported */
11344 :
11345 0 : return nl80211_set_power_save(bss, legacy_ps);
11346 : }
11347 :
11348 :
11349 1 : static int nl80211_start_radar_detection(void *priv,
11350 : struct hostapd_freq_params *freq)
11351 : {
11352 1 : struct i802_bss *bss = priv;
11353 1 : struct wpa_driver_nl80211_data *drv = bss->drv;
11354 : struct nl_msg *msg;
11355 : int ret;
11356 :
11357 1 : wpa_printf(MSG_DEBUG, "nl80211: Start radar detection (CAC) %d MHz (ht_enabled=%d, vht_enabled=%d, bandwidth=%d MHz, cf1=%d MHz, cf2=%d MHz)",
11358 : freq->freq, freq->ht_enabled, freq->vht_enabled,
11359 : freq->bandwidth, freq->center_freq1, freq->center_freq2);
11360 :
11361 1 : if (!(drv->capa.flags & WPA_DRIVER_FLAGS_RADAR)) {
11362 0 : wpa_printf(MSG_DEBUG, "nl80211: Driver does not support radar "
11363 : "detection");
11364 0 : return -1;
11365 : }
11366 :
11367 1 : msg = nlmsg_alloc();
11368 1 : if (!msg)
11369 0 : return -1;
11370 :
11371 1 : nl80211_cmd(bss->drv, msg, 0, NL80211_CMD_RADAR_DETECT);
11372 1 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
11373 1 : NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq->freq);
11374 :
11375 1 : if (freq->vht_enabled) {
11376 0 : switch (freq->bandwidth) {
11377 : case 20:
11378 0 : NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH,
11379 : NL80211_CHAN_WIDTH_20);
11380 0 : break;
11381 : case 40:
11382 0 : NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH,
11383 : NL80211_CHAN_WIDTH_40);
11384 0 : break;
11385 : case 80:
11386 0 : if (freq->center_freq2)
11387 0 : NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH,
11388 : NL80211_CHAN_WIDTH_80P80);
11389 : else
11390 0 : NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH,
11391 : NL80211_CHAN_WIDTH_80);
11392 0 : break;
11393 : case 160:
11394 0 : NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH,
11395 : NL80211_CHAN_WIDTH_160);
11396 0 : break;
11397 : default:
11398 0 : return -1;
11399 : }
11400 0 : NLA_PUT_U32(msg, NL80211_ATTR_CENTER_FREQ1, freq->center_freq1);
11401 0 : if (freq->center_freq2)
11402 0 : NLA_PUT_U32(msg, NL80211_ATTR_CENTER_FREQ2,
11403 : freq->center_freq2);
11404 1 : } else if (freq->ht_enabled) {
11405 1 : switch (freq->sec_channel_offset) {
11406 : case -1:
11407 0 : NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
11408 : NL80211_CHAN_HT40MINUS);
11409 0 : break;
11410 : case 1:
11411 0 : NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
11412 : NL80211_CHAN_HT40PLUS);
11413 0 : break;
11414 : default:
11415 1 : NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
11416 : NL80211_CHAN_HT20);
11417 1 : break;
11418 : }
11419 : }
11420 :
11421 1 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
11422 1 : if (ret == 0)
11423 0 : return 0;
11424 1 : wpa_printf(MSG_DEBUG, "nl80211: Failed to start radar detection: "
11425 : "%d (%s)", ret, strerror(-ret));
11426 : nla_put_failure:
11427 1 : return -1;
11428 : }
11429 :
11430 : #ifdef CONFIG_TDLS
11431 :
11432 127 : static int nl80211_send_tdls_mgmt(void *priv, const u8 *dst, u8 action_code,
11433 : u8 dialog_token, u16 status_code,
11434 : u32 peer_capab, const u8 *buf, size_t len)
11435 : {
11436 127 : struct i802_bss *bss = priv;
11437 127 : struct wpa_driver_nl80211_data *drv = bss->drv;
11438 : struct nl_msg *msg;
11439 :
11440 127 : if (!(drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT))
11441 0 : return -EOPNOTSUPP;
11442 :
11443 127 : if (!dst)
11444 0 : return -EINVAL;
11445 :
11446 127 : msg = nlmsg_alloc();
11447 127 : if (!msg)
11448 0 : return -ENOMEM;
11449 :
11450 127 : nl80211_cmd(drv, msg, 0, NL80211_CMD_TDLS_MGMT);
11451 127 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
11452 127 : NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, dst);
11453 127 : NLA_PUT_U8(msg, NL80211_ATTR_TDLS_ACTION, action_code);
11454 127 : NLA_PUT_U8(msg, NL80211_ATTR_TDLS_DIALOG_TOKEN, dialog_token);
11455 127 : NLA_PUT_U16(msg, NL80211_ATTR_STATUS_CODE, status_code);
11456 127 : if (peer_capab) {
11457 : /*
11458 : * The internal enum tdls_peer_capability definition is
11459 : * currently identical with the nl80211 enum
11460 : * nl80211_tdls_peer_capability, so no conversion is needed
11461 : * here.
11462 : */
11463 0 : NLA_PUT_U32(msg, NL80211_ATTR_TDLS_PEER_CAPABILITY, peer_capab);
11464 : }
11465 127 : NLA_PUT(msg, NL80211_ATTR_IE, len, buf);
11466 :
11467 127 : return send_and_recv_msgs(drv, msg, NULL, NULL);
11468 :
11469 : nla_put_failure:
11470 0 : nlmsg_free(msg);
11471 0 : return -ENOBUFS;
11472 : }
11473 :
11474 :
11475 2050 : static int nl80211_tdls_oper(void *priv, enum tdls_oper oper, const u8 *peer)
11476 : {
11477 2050 : struct i802_bss *bss = priv;
11478 2050 : struct wpa_driver_nl80211_data *drv = bss->drv;
11479 : struct nl_msg *msg;
11480 : enum nl80211_tdls_operation nl80211_oper;
11481 :
11482 2050 : if (!(drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT))
11483 0 : return -EOPNOTSUPP;
11484 :
11485 2050 : switch (oper) {
11486 : case TDLS_DISCOVERY_REQ:
11487 0 : nl80211_oper = NL80211_TDLS_DISCOVERY_REQ;
11488 0 : break;
11489 : case TDLS_SETUP:
11490 0 : nl80211_oper = NL80211_TDLS_SETUP;
11491 0 : break;
11492 : case TDLS_TEARDOWN:
11493 0 : nl80211_oper = NL80211_TDLS_TEARDOWN;
11494 0 : break;
11495 : case TDLS_ENABLE_LINK:
11496 39 : nl80211_oper = NL80211_TDLS_ENABLE_LINK;
11497 39 : break;
11498 : case TDLS_DISABLE_LINK:
11499 106 : nl80211_oper = NL80211_TDLS_DISABLE_LINK;
11500 106 : break;
11501 : case TDLS_ENABLE:
11502 1904 : return 0;
11503 : case TDLS_DISABLE:
11504 1 : return 0;
11505 : default:
11506 0 : return -EINVAL;
11507 : }
11508 :
11509 145 : msg = nlmsg_alloc();
11510 145 : if (!msg)
11511 0 : return -ENOMEM;
11512 :
11513 145 : nl80211_cmd(drv, msg, 0, NL80211_CMD_TDLS_OPER);
11514 145 : NLA_PUT_U8(msg, NL80211_ATTR_TDLS_OPERATION, nl80211_oper);
11515 145 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
11516 145 : NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, peer);
11517 :
11518 145 : return send_and_recv_msgs(drv, msg, NULL, NULL);
11519 :
11520 : nla_put_failure:
11521 0 : nlmsg_free(msg);
11522 0 : return -ENOBUFS;
11523 : }
11524 :
11525 : #endif /* CONFIG TDLS */
11526 :
11527 :
11528 : #ifdef ANDROID
11529 :
11530 : typedef struct android_wifi_priv_cmd {
11531 : char *buf;
11532 : int used_len;
11533 : int total_len;
11534 : } android_wifi_priv_cmd;
11535 :
11536 : static int drv_errors = 0;
11537 :
11538 : static void wpa_driver_send_hang_msg(struct wpa_driver_nl80211_data *drv)
11539 : {
11540 : drv_errors++;
11541 : if (drv_errors > DRV_NUMBER_SEQUENTIAL_ERRORS) {
11542 : drv_errors = 0;
11543 : wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
11544 : }
11545 : }
11546 :
11547 :
11548 : static int android_priv_cmd(struct i802_bss *bss, const char *cmd)
11549 : {
11550 : struct wpa_driver_nl80211_data *drv = bss->drv;
11551 : struct ifreq ifr;
11552 : android_wifi_priv_cmd priv_cmd;
11553 : char buf[MAX_DRV_CMD_SIZE];
11554 : int ret;
11555 :
11556 : os_memset(&ifr, 0, sizeof(ifr));
11557 : os_memset(&priv_cmd, 0, sizeof(priv_cmd));
11558 : os_strlcpy(ifr.ifr_name, bss->ifname, IFNAMSIZ);
11559 :
11560 : os_memset(buf, 0, sizeof(buf));
11561 : os_strlcpy(buf, cmd, sizeof(buf));
11562 :
11563 : priv_cmd.buf = buf;
11564 : priv_cmd.used_len = sizeof(buf);
11565 : priv_cmd.total_len = sizeof(buf);
11566 : ifr.ifr_data = &priv_cmd;
11567 :
11568 : ret = ioctl(drv->global->ioctl_sock, SIOCDEVPRIVATE + 1, &ifr);
11569 : if (ret < 0) {
11570 : wpa_printf(MSG_ERROR, "%s: failed to issue private commands",
11571 : __func__);
11572 : wpa_driver_send_hang_msg(drv);
11573 : return ret;
11574 : }
11575 :
11576 : drv_errors = 0;
11577 : return 0;
11578 : }
11579 :
11580 :
11581 : static int android_pno_start(struct i802_bss *bss,
11582 : struct wpa_driver_scan_params *params)
11583 : {
11584 : struct wpa_driver_nl80211_data *drv = bss->drv;
11585 : struct ifreq ifr;
11586 : android_wifi_priv_cmd priv_cmd;
11587 : int ret = 0, i = 0, bp;
11588 : char buf[WEXT_PNO_MAX_COMMAND_SIZE];
11589 :
11590 : bp = WEXT_PNOSETUP_HEADER_SIZE;
11591 : os_memcpy(buf, WEXT_PNOSETUP_HEADER, bp);
11592 : buf[bp++] = WEXT_PNO_TLV_PREFIX;
11593 : buf[bp++] = WEXT_PNO_TLV_VERSION;
11594 : buf[bp++] = WEXT_PNO_TLV_SUBVERSION;
11595 : buf[bp++] = WEXT_PNO_TLV_RESERVED;
11596 :
11597 : while (i < WEXT_PNO_AMOUNT && (size_t) i < params->num_ssids) {
11598 : /* Check that there is enough space needed for 1 more SSID, the
11599 : * other sections and null termination */
11600 : if ((bp + WEXT_PNO_SSID_HEADER_SIZE + MAX_SSID_LEN +
11601 : WEXT_PNO_NONSSID_SECTIONS_SIZE + 1) >= (int) sizeof(buf))
11602 : break;
11603 : wpa_hexdump_ascii(MSG_DEBUG, "For PNO Scan",
11604 : params->ssids[i].ssid,
11605 : params->ssids[i].ssid_len);
11606 : buf[bp++] = WEXT_PNO_SSID_SECTION;
11607 : buf[bp++] = params->ssids[i].ssid_len;
11608 : os_memcpy(&buf[bp], params->ssids[i].ssid,
11609 : params->ssids[i].ssid_len);
11610 : bp += params->ssids[i].ssid_len;
11611 : i++;
11612 : }
11613 :
11614 : buf[bp++] = WEXT_PNO_SCAN_INTERVAL_SECTION;
11615 : os_snprintf(&buf[bp], WEXT_PNO_SCAN_INTERVAL_LENGTH + 1, "%x",
11616 : WEXT_PNO_SCAN_INTERVAL);
11617 : bp += WEXT_PNO_SCAN_INTERVAL_LENGTH;
11618 :
11619 : buf[bp++] = WEXT_PNO_REPEAT_SECTION;
11620 : os_snprintf(&buf[bp], WEXT_PNO_REPEAT_LENGTH + 1, "%x",
11621 : WEXT_PNO_REPEAT);
11622 : bp += WEXT_PNO_REPEAT_LENGTH;
11623 :
11624 : buf[bp++] = WEXT_PNO_MAX_REPEAT_SECTION;
11625 : os_snprintf(&buf[bp], WEXT_PNO_MAX_REPEAT_LENGTH + 1, "%x",
11626 : WEXT_PNO_MAX_REPEAT);
11627 : bp += WEXT_PNO_MAX_REPEAT_LENGTH + 1;
11628 :
11629 : memset(&ifr, 0, sizeof(ifr));
11630 : memset(&priv_cmd, 0, sizeof(priv_cmd));
11631 : os_strlcpy(ifr.ifr_name, bss->ifname, IFNAMSIZ);
11632 :
11633 : priv_cmd.buf = buf;
11634 : priv_cmd.used_len = bp;
11635 : priv_cmd.total_len = bp;
11636 : ifr.ifr_data = &priv_cmd;
11637 :
11638 : ret = ioctl(drv->global->ioctl_sock, SIOCDEVPRIVATE + 1, &ifr);
11639 :
11640 : if (ret < 0) {
11641 : wpa_printf(MSG_ERROR, "ioctl[SIOCSIWPRIV] (pnosetup): %d",
11642 : ret);
11643 : wpa_driver_send_hang_msg(drv);
11644 : return ret;
11645 : }
11646 :
11647 : drv_errors = 0;
11648 :
11649 : return android_priv_cmd(bss, "PNOFORCE 1");
11650 : }
11651 :
11652 :
11653 : static int android_pno_stop(struct i802_bss *bss)
11654 : {
11655 : return android_priv_cmd(bss, "PNOFORCE 0");
11656 : }
11657 :
11658 : #endif /* ANDROID */
11659 :
11660 :
11661 12131 : static int driver_nl80211_set_key(const char *ifname, void *priv,
11662 : enum wpa_alg alg, const u8 *addr,
11663 : int key_idx, int set_tx,
11664 : const u8 *seq, size_t seq_len,
11665 : const u8 *key, size_t key_len)
11666 : {
11667 12131 : struct i802_bss *bss = priv;
11668 12131 : return wpa_driver_nl80211_set_key(ifname, bss, alg, addr, key_idx,
11669 : set_tx, seq, seq_len, key, key_len);
11670 : }
11671 :
11672 :
11673 1913 : static int driver_nl80211_scan2(void *priv,
11674 : struct wpa_driver_scan_params *params)
11675 : {
11676 1913 : struct i802_bss *bss = priv;
11677 1913 : return wpa_driver_nl80211_scan(bss, params);
11678 : }
11679 :
11680 :
11681 963 : static int driver_nl80211_deauthenticate(void *priv, const u8 *addr,
11682 : int reason_code)
11683 : {
11684 963 : struct i802_bss *bss = priv;
11685 963 : return wpa_driver_nl80211_deauthenticate(bss, addr, reason_code);
11686 : }
11687 :
11688 :
11689 1079 : static int driver_nl80211_authenticate(void *priv,
11690 : struct wpa_driver_auth_params *params)
11691 : {
11692 1079 : struct i802_bss *bss = priv;
11693 1079 : return wpa_driver_nl80211_authenticate(bss, params);
11694 : }
11695 :
11696 :
11697 69 : static void driver_nl80211_deinit(void *priv)
11698 : {
11699 69 : struct i802_bss *bss = priv;
11700 69 : wpa_driver_nl80211_deinit(bss);
11701 69 : }
11702 :
11703 :
11704 65 : static int driver_nl80211_if_remove(void *priv, enum wpa_driver_if_type type,
11705 : const char *ifname)
11706 : {
11707 65 : struct i802_bss *bss = priv;
11708 65 : return wpa_driver_nl80211_if_remove(bss, type, ifname);
11709 : }
11710 :
11711 :
11712 4265 : static int driver_nl80211_send_mlme(void *priv, const u8 *data,
11713 : size_t data_len, int noack)
11714 : {
11715 4265 : struct i802_bss *bss = priv;
11716 4265 : return wpa_driver_nl80211_send_mlme(bss, data, data_len, noack,
11717 : 0, 0, 0, 0);
11718 : }
11719 :
11720 :
11721 1915 : static int driver_nl80211_sta_remove(void *priv, const u8 *addr)
11722 : {
11723 1915 : struct i802_bss *bss = priv;
11724 1915 : return wpa_driver_nl80211_sta_remove(bss, addr);
11725 : }
11726 :
11727 :
11728 12 : static int driver_nl80211_set_sta_vlan(void *priv, const u8 *addr,
11729 : const char *ifname, int vlan_id)
11730 : {
11731 12 : struct i802_bss *bss = priv;
11732 12 : return i802_set_sta_vlan(bss, addr, ifname, vlan_id);
11733 : }
11734 :
11735 :
11736 41 : static int driver_nl80211_read_sta_data(void *priv,
11737 : struct hostap_sta_driver_data *data,
11738 : const u8 *addr)
11739 : {
11740 41 : struct i802_bss *bss = priv;
11741 41 : return i802_read_sta_data(bss, data, addr);
11742 : }
11743 :
11744 :
11745 1315 : static int driver_nl80211_send_action(void *priv, unsigned int freq,
11746 : unsigned int wait_time,
11747 : const u8 *dst, const u8 *src,
11748 : const u8 *bssid,
11749 : const u8 *data, size_t data_len,
11750 : int no_cck)
11751 : {
11752 1315 : struct i802_bss *bss = priv;
11753 1315 : return wpa_driver_nl80211_send_action(bss, freq, wait_time, dst, src,
11754 : bssid, data, data_len, no_cck);
11755 : }
11756 :
11757 :
11758 8033 : static int driver_nl80211_probe_req_report(void *priv, int report)
11759 : {
11760 8033 : struct i802_bss *bss = priv;
11761 8033 : return wpa_driver_nl80211_probe_req_report(bss, report);
11762 : }
11763 :
11764 :
11765 0 : static int wpa_driver_nl80211_update_ft_ies(void *priv, const u8 *md,
11766 : const u8 *ies, size_t ies_len)
11767 : {
11768 : int ret;
11769 : struct nl_msg *msg;
11770 0 : struct i802_bss *bss = priv;
11771 0 : struct wpa_driver_nl80211_data *drv = bss->drv;
11772 0 : u16 mdid = WPA_GET_LE16(md);
11773 :
11774 0 : msg = nlmsg_alloc();
11775 0 : if (!msg)
11776 0 : return -ENOMEM;
11777 :
11778 0 : wpa_printf(MSG_DEBUG, "nl80211: Updating FT IEs");
11779 0 : nl80211_cmd(drv, msg, 0, NL80211_CMD_UPDATE_FT_IES);
11780 0 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
11781 0 : NLA_PUT(msg, NL80211_ATTR_IE, ies_len, ies);
11782 0 : NLA_PUT_U16(msg, NL80211_ATTR_MDID, mdid);
11783 :
11784 0 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
11785 0 : if (ret) {
11786 0 : wpa_printf(MSG_DEBUG, "nl80211: update_ft_ies failed "
11787 : "err=%d (%s)", ret, strerror(-ret));
11788 : }
11789 :
11790 0 : return ret;
11791 :
11792 : nla_put_failure:
11793 0 : nlmsg_free(msg);
11794 0 : return -ENOBUFS;
11795 : }
11796 :
11797 :
11798 72 : const u8 * wpa_driver_nl80211_get_macaddr(void *priv)
11799 : {
11800 72 : struct i802_bss *bss = priv;
11801 72 : struct wpa_driver_nl80211_data *drv = bss->drv;
11802 :
11803 72 : if (drv->nlmode != NL80211_IFTYPE_P2P_DEVICE)
11804 72 : return NULL;
11805 :
11806 0 : return bss->addr;
11807 : }
11808 :
11809 :
11810 1908 : static const char * scan_state_str(enum scan_states scan_state)
11811 : {
11812 1908 : switch (scan_state) {
11813 : case NO_SCAN:
11814 23 : return "NO_SCAN";
11815 : case SCAN_REQUESTED:
11816 0 : return "SCAN_REQUESTED";
11817 : case SCAN_STARTED:
11818 10 : return "SCAN_STARTED";
11819 : case SCAN_COMPLETED:
11820 1874 : return "SCAN_COMPLETED";
11821 : case SCAN_ABORTED:
11822 1 : return "SCAN_ABORTED";
11823 : case SCHED_SCAN_STARTED:
11824 0 : return "SCHED_SCAN_STARTED";
11825 : case SCHED_SCAN_STOPPED:
11826 0 : return "SCHED_SCAN_STOPPED";
11827 : case SCHED_SCAN_RESULTS:
11828 0 : return "SCHED_SCAN_RESULTS";
11829 : }
11830 :
11831 0 : return "??";
11832 : }
11833 :
11834 :
11835 1908 : static int wpa_driver_nl80211_status(void *priv, char *buf, size_t buflen)
11836 : {
11837 1908 : struct i802_bss *bss = priv;
11838 1908 : struct wpa_driver_nl80211_data *drv = bss->drv;
11839 : int res;
11840 : char *pos, *end;
11841 :
11842 1908 : pos = buf;
11843 1908 : end = buf + buflen;
11844 :
11845 22896 : res = os_snprintf(pos, end - pos,
11846 : "ifindex=%d\n"
11847 : "ifname=%s\n"
11848 : "brname=%s\n"
11849 : "addr=" MACSTR "\n"
11850 : "freq=%d\n"
11851 : "%s%s%s%s%s",
11852 : bss->ifindex,
11853 1908 : bss->ifname,
11854 1908 : bss->brname,
11855 11448 : MAC2STR(bss->addr),
11856 : bss->freq,
11857 1908 : bss->beacon_set ? "beacon_set=1\n" : "",
11858 1908 : bss->added_if_into_bridge ?
11859 : "added_if_into_bridge=1\n" : "",
11860 1908 : bss->added_bridge ? "added_bridge=1\n" : "",
11861 1908 : bss->in_deinit ? "in_deinit=1\n" : "",
11862 1908 : bss->if_dynamic ? "if_dynamic=1\n" : "");
11863 1908 : if (res < 0 || res >= end - pos)
11864 0 : return pos - buf;
11865 1908 : pos += res;
11866 :
11867 1908 : if (bss->wdev_id_set) {
11868 0 : res = os_snprintf(pos, end - pos, "wdev_id=%llu\n",
11869 0 : (unsigned long long) bss->wdev_id);
11870 0 : if (res < 0 || res >= end - pos)
11871 0 : return pos - buf;
11872 0 : pos += res;
11873 : }
11874 :
11875 74412 : res = os_snprintf(pos, end - pos,
11876 : "phyname=%s\n"
11877 : "drv_ifindex=%d\n"
11878 : "operstate=%d\n"
11879 : "scan_state=%s\n"
11880 : "auth_bssid=" MACSTR "\n"
11881 : "auth_attempt_bssid=" MACSTR "\n"
11882 : "bssid=" MACSTR "\n"
11883 : "prev_bssid=" MACSTR "\n"
11884 : "associated=%d\n"
11885 : "assoc_freq=%u\n"
11886 : "monitor_sock=%d\n"
11887 : "monitor_ifidx=%d\n"
11888 : "monitor_refcount=%d\n"
11889 : "last_mgmt_freq=%u\n"
11890 : "eapol_tx_sock=%d\n"
11891 : "%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
11892 1908 : drv->phyname,
11893 : drv->ifindex,
11894 : drv->operstate,
11895 : scan_state_str(drv->scan_state),
11896 11448 : MAC2STR(drv->auth_bssid),
11897 11448 : MAC2STR(drv->auth_attempt_bssid),
11898 11448 : MAC2STR(drv->bssid),
11899 11448 : MAC2STR(drv->prev_bssid),
11900 : drv->associated,
11901 : drv->assoc_freq,
11902 : drv->monitor_sock,
11903 : drv->monitor_ifidx,
11904 : drv->monitor_refcount,
11905 : drv->last_mgmt_freq,
11906 : drv->eapol_tx_sock,
11907 1908 : drv->ignore_if_down_event ?
11908 : "ignore_if_down_event=1\n" : "",
11909 1908 : drv->scan_complete_events ?
11910 : "scan_complete_events=1\n" : "",
11911 1908 : drv->disabled_11b_rates ?
11912 : "disabled_11b_rates=1\n" : "",
11913 1908 : drv->pending_remain_on_chan ?
11914 : "pending_remain_on_chan=1\n" : "",
11915 1908 : drv->in_interface_list ? "in_interface_list=1\n" : "",
11916 1908 : drv->device_ap_sme ? "device_ap_sme=1\n" : "",
11917 1908 : drv->poll_command_supported ?
11918 : "poll_command_supported=1\n" : "",
11919 1908 : drv->data_tx_status ? "data_tx_status=1\n" : "",
11920 1908 : drv->scan_for_auth ? "scan_for_auth=1\n" : "",
11921 1908 : drv->retry_auth ? "retry_auth=1\n" : "",
11922 1908 : drv->use_monitor ? "use_monitor=1\n" : "",
11923 1908 : drv->ignore_next_local_disconnect ?
11924 : "ignore_next_local_disconnect=1\n" : "",
11925 1908 : drv->ignore_next_local_deauth ?
11926 : "ignore_next_local_deauth=1\n" : "",
11927 1908 : drv->allow_p2p_device ? "allow_p2p_device=1\n" : "");
11928 1908 : if (res < 0 || res >= end - pos)
11929 0 : return pos - buf;
11930 1908 : pos += res;
11931 :
11932 1908 : if (drv->has_capability) {
11933 1908 : res = os_snprintf(pos, end - pos,
11934 : "capa.key_mgmt=0x%x\n"
11935 : "capa.enc=0x%x\n"
11936 : "capa.auth=0x%x\n"
11937 : "capa.flags=0x%x\n"
11938 : "capa.max_scan_ssids=%d\n"
11939 : "capa.max_sched_scan_ssids=%d\n"
11940 : "capa.sched_scan_supported=%d\n"
11941 : "capa.max_match_sets=%d\n"
11942 : "capa.max_remain_on_chan=%u\n"
11943 : "capa.max_stations=%u\n"
11944 : "capa.probe_resp_offloads=0x%x\n"
11945 : "capa.max_acl_mac_addrs=%u\n"
11946 : "capa.num_multichan_concurrent=%u\n",
11947 : drv->capa.key_mgmt,
11948 : drv->capa.enc,
11949 : drv->capa.auth,
11950 : drv->capa.flags,
11951 : drv->capa.max_scan_ssids,
11952 : drv->capa.max_sched_scan_ssids,
11953 : drv->capa.sched_scan_supported,
11954 : drv->capa.max_match_sets,
11955 : drv->capa.max_remain_on_chan,
11956 : drv->capa.max_stations,
11957 : drv->capa.probe_resp_offloads,
11958 : drv->capa.max_acl_mac_addrs,
11959 : drv->capa.num_multichan_concurrent);
11960 1908 : if (res < 0 || res >= end - pos)
11961 0 : return pos - buf;
11962 1908 : pos += res;
11963 : }
11964 :
11965 1908 : return pos - buf;
11966 : }
11967 :
11968 :
11969 0 : static int set_beacon_data(struct nl_msg *msg, struct beacon_data *settings)
11970 : {
11971 0 : if (settings->head)
11972 0 : NLA_PUT(msg, NL80211_ATTR_BEACON_HEAD,
11973 : settings->head_len, settings->head);
11974 :
11975 0 : if (settings->tail)
11976 0 : NLA_PUT(msg, NL80211_ATTR_BEACON_TAIL,
11977 : settings->tail_len, settings->tail);
11978 :
11979 0 : if (settings->beacon_ies)
11980 0 : NLA_PUT(msg, NL80211_ATTR_IE,
11981 : settings->beacon_ies_len, settings->beacon_ies);
11982 :
11983 0 : if (settings->proberesp_ies)
11984 0 : NLA_PUT(msg, NL80211_ATTR_IE_PROBE_RESP,
11985 : settings->proberesp_ies_len, settings->proberesp_ies);
11986 :
11987 0 : if (settings->assocresp_ies)
11988 0 : NLA_PUT(msg,
11989 : NL80211_ATTR_IE_ASSOC_RESP,
11990 : settings->assocresp_ies_len, settings->assocresp_ies);
11991 :
11992 0 : if (settings->probe_resp)
11993 0 : NLA_PUT(msg, NL80211_ATTR_PROBE_RESP,
11994 : settings->probe_resp_len, settings->probe_resp);
11995 :
11996 0 : return 0;
11997 :
11998 : nla_put_failure:
11999 0 : return -ENOBUFS;
12000 : }
12001 :
12002 :
12003 2 : static int nl80211_switch_channel(void *priv, struct csa_settings *settings)
12004 : {
12005 : struct nl_msg *msg;
12006 2 : struct i802_bss *bss = priv;
12007 2 : struct wpa_driver_nl80211_data *drv = bss->drv;
12008 : struct nlattr *beacon_csa;
12009 2 : int ret = -ENOBUFS;
12010 :
12011 6 : wpa_printf(MSG_DEBUG, "nl80211: Channel switch request (cs_count=%u block_tx=%u freq=%d width=%d cf1=%d cf2=%d)",
12012 4 : settings->cs_count, settings->block_tx,
12013 : settings->freq_params.freq, settings->freq_params.bandwidth,
12014 : settings->freq_params.center_freq1,
12015 : settings->freq_params.center_freq2);
12016 :
12017 2 : if (!(drv->capa.flags & WPA_DRIVER_FLAGS_AP_CSA)) {
12018 2 : wpa_printf(MSG_DEBUG, "nl80211: Driver does not support channel switch command");
12019 2 : return -EOPNOTSUPP;
12020 : }
12021 :
12022 0 : if ((drv->nlmode != NL80211_IFTYPE_AP) &&
12023 0 : (drv->nlmode != NL80211_IFTYPE_P2P_GO))
12024 0 : return -EOPNOTSUPP;
12025 :
12026 : /* check settings validity */
12027 0 : if (!settings->beacon_csa.tail ||
12028 0 : ((settings->beacon_csa.tail_len <=
12029 0 : settings->counter_offset_beacon) ||
12030 0 : (settings->beacon_csa.tail[settings->counter_offset_beacon] !=
12031 0 : settings->cs_count)))
12032 0 : return -EINVAL;
12033 :
12034 0 : if (settings->beacon_csa.probe_resp &&
12035 0 : ((settings->beacon_csa.probe_resp_len <=
12036 0 : settings->counter_offset_presp) ||
12037 0 : (settings->beacon_csa.probe_resp[settings->counter_offset_presp] !=
12038 0 : settings->cs_count)))
12039 0 : return -EINVAL;
12040 :
12041 0 : msg = nlmsg_alloc();
12042 0 : if (!msg)
12043 0 : return -ENOMEM;
12044 :
12045 0 : nl80211_cmd(drv, msg, 0, NL80211_CMD_CHANNEL_SWITCH);
12046 0 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
12047 0 : NLA_PUT_U32(msg, NL80211_ATTR_CH_SWITCH_COUNT, settings->cs_count);
12048 0 : ret = nl80211_put_freq_params(msg, &settings->freq_params);
12049 0 : if (ret)
12050 0 : goto error;
12051 :
12052 0 : if (settings->block_tx)
12053 0 : NLA_PUT_FLAG(msg, NL80211_ATTR_CH_SWITCH_BLOCK_TX);
12054 :
12055 : /* beacon_after params */
12056 0 : ret = set_beacon_data(msg, &settings->beacon_after);
12057 0 : if (ret)
12058 0 : goto error;
12059 :
12060 : /* beacon_csa params */
12061 0 : beacon_csa = nla_nest_start(msg, NL80211_ATTR_CSA_IES);
12062 0 : if (!beacon_csa)
12063 0 : goto nla_put_failure;
12064 :
12065 0 : ret = set_beacon_data(msg, &settings->beacon_csa);
12066 0 : if (ret)
12067 0 : goto error;
12068 :
12069 0 : NLA_PUT_U16(msg, NL80211_ATTR_CSA_C_OFF_BEACON,
12070 : settings->counter_offset_beacon);
12071 :
12072 0 : if (settings->beacon_csa.probe_resp)
12073 0 : NLA_PUT_U16(msg, NL80211_ATTR_CSA_C_OFF_PRESP,
12074 : settings->counter_offset_presp);
12075 :
12076 0 : nla_nest_end(msg, beacon_csa);
12077 0 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
12078 0 : if (ret) {
12079 0 : wpa_printf(MSG_DEBUG, "nl80211: switch_channel failed err=%d (%s)",
12080 : ret, strerror(-ret));
12081 : }
12082 0 : return ret;
12083 :
12084 : nla_put_failure:
12085 0 : ret = -ENOBUFS;
12086 : error:
12087 0 : nlmsg_free(msg);
12088 0 : wpa_printf(MSG_DEBUG, "nl80211: Could not build channel switch request");
12089 0 : return ret;
12090 : }
12091 :
12092 :
12093 : #ifdef CONFIG_TESTING_OPTIONS
12094 0 : static int cmd_reply_handler(struct nl_msg *msg, void *arg)
12095 : {
12096 0 : struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
12097 0 : struct wpabuf *buf = arg;
12098 :
12099 0 : if (!buf)
12100 0 : return NL_SKIP;
12101 :
12102 0 : if ((size_t) genlmsg_attrlen(gnlh, 0) > wpabuf_tailroom(buf)) {
12103 0 : wpa_printf(MSG_INFO, "nl80211: insufficient buffer space for reply");
12104 0 : return NL_SKIP;
12105 : }
12106 :
12107 0 : wpabuf_put_data(buf, genlmsg_attrdata(gnlh, 0),
12108 0 : genlmsg_attrlen(gnlh, 0));
12109 :
12110 0 : return NL_SKIP;
12111 : }
12112 : #endif /* CONFIG_TESTING_OPTIONS */
12113 :
12114 :
12115 0 : static int vendor_reply_handler(struct nl_msg *msg, void *arg)
12116 : {
12117 : struct nlattr *tb[NL80211_ATTR_MAX + 1];
12118 : struct nlattr *nl_vendor_reply, *nl;
12119 0 : struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
12120 0 : struct wpabuf *buf = arg;
12121 : int rem;
12122 :
12123 0 : if (!buf)
12124 0 : return NL_SKIP;
12125 :
12126 0 : nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
12127 : genlmsg_attrlen(gnlh, 0), NULL);
12128 0 : nl_vendor_reply = tb[NL80211_ATTR_VENDOR_DATA];
12129 :
12130 0 : if (!nl_vendor_reply)
12131 0 : return NL_SKIP;
12132 :
12133 0 : if ((size_t) nla_len(nl_vendor_reply) > wpabuf_tailroom(buf)) {
12134 0 : wpa_printf(MSG_INFO, "nl80211: Vendor command: insufficient buffer space for reply");
12135 0 : return NL_SKIP;
12136 : }
12137 :
12138 0 : nla_for_each_nested(nl, nl_vendor_reply, rem) {
12139 0 : wpabuf_put_data(buf, nla_data(nl), nla_len(nl));
12140 : }
12141 :
12142 0 : return NL_SKIP;
12143 : }
12144 :
12145 :
12146 1 : static int nl80211_vendor_cmd(void *priv, unsigned int vendor_id,
12147 : unsigned int subcmd, const u8 *data,
12148 : size_t data_len, struct wpabuf *buf)
12149 : {
12150 1 : struct i802_bss *bss = priv;
12151 1 : struct wpa_driver_nl80211_data *drv = bss->drv;
12152 : struct nl_msg *msg;
12153 : int ret;
12154 :
12155 1 : msg = nlmsg_alloc();
12156 1 : if (!msg)
12157 0 : return -ENOMEM;
12158 :
12159 : #ifdef CONFIG_TESTING_OPTIONS
12160 1 : if (vendor_id == 0xffffffff) {
12161 1 : nl80211_cmd(drv, msg, 0, subcmd);
12162 1 : if (nlmsg_append(msg, (void *) data, data_len, NLMSG_ALIGNTO) <
12163 : 0)
12164 0 : goto nla_put_failure;
12165 1 : ret = send_and_recv_msgs(drv, msg, cmd_reply_handler, buf);
12166 1 : if (ret)
12167 0 : wpa_printf(MSG_DEBUG, "nl80211: command failed err=%d",
12168 : ret);
12169 1 : return ret;
12170 : }
12171 : #endif /* CONFIG_TESTING_OPTIONS */
12172 :
12173 0 : nl80211_cmd(drv, msg, 0, NL80211_CMD_VENDOR);
12174 0 : if (nl80211_set_iface_id(msg, bss) < 0)
12175 0 : goto nla_put_failure;
12176 0 : NLA_PUT_U32(msg, NL80211_ATTR_VENDOR_ID, vendor_id);
12177 0 : NLA_PUT_U32(msg, NL80211_ATTR_VENDOR_SUBCMD, subcmd);
12178 0 : if (data)
12179 0 : NLA_PUT(msg, NL80211_ATTR_VENDOR_DATA, data_len, data);
12180 :
12181 0 : ret = send_and_recv_msgs(drv, msg, vendor_reply_handler, buf);
12182 0 : if (ret)
12183 0 : wpa_printf(MSG_DEBUG, "nl80211: vendor command failed err=%d",
12184 : ret);
12185 0 : return ret;
12186 :
12187 : nla_put_failure:
12188 0 : nlmsg_free(msg);
12189 0 : return -ENOBUFS;
12190 : }
12191 :
12192 :
12193 5 : static int nl80211_set_qos_map(void *priv, const u8 *qos_map_set,
12194 : u8 qos_map_set_len)
12195 : {
12196 5 : struct i802_bss *bss = priv;
12197 5 : struct wpa_driver_nl80211_data *drv = bss->drv;
12198 : struct nl_msg *msg;
12199 : int ret;
12200 :
12201 5 : msg = nlmsg_alloc();
12202 5 : if (!msg)
12203 0 : return -ENOMEM;
12204 :
12205 5 : wpa_hexdump(MSG_DEBUG, "nl80211: Setting QoS Map",
12206 : qos_map_set, qos_map_set_len);
12207 :
12208 5 : nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_QOS_MAP);
12209 5 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
12210 5 : NLA_PUT(msg, NL80211_ATTR_QOS_MAP, qos_map_set_len, qos_map_set);
12211 :
12212 5 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
12213 5 : if (ret)
12214 0 : wpa_printf(MSG_DEBUG, "nl80211: Setting QoS Map failed");
12215 :
12216 5 : return ret;
12217 :
12218 : nla_put_failure:
12219 0 : nlmsg_free(msg);
12220 0 : return -ENOBUFS;
12221 : }
12222 :
12223 :
12224 0 : static int nl80211_set_wowlan(void *priv,
12225 : const struct wowlan_triggers *triggers)
12226 : {
12227 0 : struct i802_bss *bss = priv;
12228 0 : struct wpa_driver_nl80211_data *drv = bss->drv;
12229 : struct nl_msg *msg;
12230 : struct nlattr *wowlan_triggers;
12231 : int ret;
12232 :
12233 0 : msg = nlmsg_alloc();
12234 0 : if (!msg)
12235 0 : return -ENOMEM;
12236 :
12237 0 : wpa_printf(MSG_DEBUG, "nl80211: Setting wowlan");
12238 :
12239 0 : nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_WOWLAN);
12240 0 : NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
12241 :
12242 0 : wowlan_triggers = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS);
12243 0 : if (!wowlan_triggers)
12244 0 : goto nla_put_failure;
12245 :
12246 0 : if (triggers->any)
12247 0 : NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_ANY);
12248 0 : if (triggers->disconnect)
12249 0 : NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_DISCONNECT);
12250 0 : if (triggers->magic_pkt)
12251 0 : NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT);
12252 0 : if (triggers->gtk_rekey_failure)
12253 0 : NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE);
12254 0 : if (triggers->eap_identity_req)
12255 0 : NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST);
12256 0 : if (triggers->four_way_handshake)
12257 0 : NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE);
12258 0 : if (triggers->rfkill_release)
12259 0 : NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE);
12260 :
12261 0 : nla_nest_end(msg, wowlan_triggers);
12262 :
12263 0 : ret = send_and_recv_msgs(drv, msg, NULL, NULL);
12264 0 : if (ret)
12265 0 : wpa_printf(MSG_DEBUG, "nl80211: Setting wowlan failed");
12266 :
12267 0 : return ret;
12268 :
12269 : nla_put_failure:
12270 0 : nlmsg_free(msg);
12271 0 : return -ENOBUFS;
12272 : }
12273 :
12274 :
12275 : const struct wpa_driver_ops wpa_driver_nl80211_ops = {
12276 : .name = "nl80211",
12277 : .desc = "Linux nl80211/cfg80211",
12278 : .get_bssid = wpa_driver_nl80211_get_bssid,
12279 : .get_ssid = wpa_driver_nl80211_get_ssid,
12280 : .set_key = driver_nl80211_set_key,
12281 : .scan2 = driver_nl80211_scan2,
12282 : .sched_scan = wpa_driver_nl80211_sched_scan,
12283 : .stop_sched_scan = wpa_driver_nl80211_stop_sched_scan,
12284 : .get_scan_results2 = wpa_driver_nl80211_get_scan_results,
12285 : .deauthenticate = driver_nl80211_deauthenticate,
12286 : .authenticate = driver_nl80211_authenticate,
12287 : .associate = wpa_driver_nl80211_associate,
12288 : .global_init = nl80211_global_init,
12289 : .global_deinit = nl80211_global_deinit,
12290 : .init2 = wpa_driver_nl80211_init,
12291 : .deinit = driver_nl80211_deinit,
12292 : .get_capa = wpa_driver_nl80211_get_capa,
12293 : .set_operstate = wpa_driver_nl80211_set_operstate,
12294 : .set_supp_port = wpa_driver_nl80211_set_supp_port,
12295 : .set_country = wpa_driver_nl80211_set_country,
12296 : .get_country = wpa_driver_nl80211_get_country,
12297 : .set_ap = wpa_driver_nl80211_set_ap,
12298 : .set_acl = wpa_driver_nl80211_set_acl,
12299 : .if_add = wpa_driver_nl80211_if_add,
12300 : .if_remove = driver_nl80211_if_remove,
12301 : .send_mlme = driver_nl80211_send_mlme,
12302 : .get_hw_feature_data = wpa_driver_nl80211_get_hw_feature_data,
12303 : .sta_add = wpa_driver_nl80211_sta_add,
12304 : .sta_remove = driver_nl80211_sta_remove,
12305 : .hapd_send_eapol = wpa_driver_nl80211_hapd_send_eapol,
12306 : .sta_set_flags = wpa_driver_nl80211_sta_set_flags,
12307 : .hapd_init = i802_init,
12308 : .hapd_deinit = i802_deinit,
12309 : .set_wds_sta = i802_set_wds_sta,
12310 : .get_seqnum = i802_get_seqnum,
12311 : .flush = i802_flush,
12312 : .get_inact_sec = i802_get_inact_sec,
12313 : .sta_clear_stats = i802_sta_clear_stats,
12314 : .set_rts = i802_set_rts,
12315 : .set_frag = i802_set_frag,
12316 : .set_tx_queue_params = i802_set_tx_queue_params,
12317 : .set_sta_vlan = driver_nl80211_set_sta_vlan,
12318 : .sta_deauth = i802_sta_deauth,
12319 : .sta_disassoc = i802_sta_disassoc,
12320 : .read_sta_data = driver_nl80211_read_sta_data,
12321 : .set_freq = i802_set_freq,
12322 : .send_action = driver_nl80211_send_action,
12323 : .send_action_cancel_wait = wpa_driver_nl80211_send_action_cancel_wait,
12324 : .remain_on_channel = wpa_driver_nl80211_remain_on_channel,
12325 : .cancel_remain_on_channel =
12326 : wpa_driver_nl80211_cancel_remain_on_channel,
12327 : .probe_req_report = driver_nl80211_probe_req_report,
12328 : .deinit_ap = wpa_driver_nl80211_deinit_ap,
12329 : .deinit_p2p_cli = wpa_driver_nl80211_deinit_p2p_cli,
12330 : .resume = wpa_driver_nl80211_resume,
12331 : .send_ft_action = nl80211_send_ft_action,
12332 : .signal_monitor = nl80211_signal_monitor,
12333 : .signal_poll = nl80211_signal_poll,
12334 : .send_frame = nl80211_send_frame,
12335 : .shared_freq = wpa_driver_nl80211_shared_freq,
12336 : .set_param = nl80211_set_param,
12337 : .get_radio_name = nl80211_get_radio_name,
12338 : .add_pmkid = nl80211_add_pmkid,
12339 : .remove_pmkid = nl80211_remove_pmkid,
12340 : .flush_pmkid = nl80211_flush_pmkid,
12341 : .set_rekey_info = nl80211_set_rekey_info,
12342 : .poll_client = nl80211_poll_client,
12343 : .set_p2p_powersave = nl80211_set_p2p_powersave,
12344 : .start_dfs_cac = nl80211_start_radar_detection,
12345 : .stop_ap = wpa_driver_nl80211_stop_ap,
12346 : #ifdef CONFIG_TDLS
12347 : .send_tdls_mgmt = nl80211_send_tdls_mgmt,
12348 : .tdls_oper = nl80211_tdls_oper,
12349 : #endif /* CONFIG_TDLS */
12350 : .update_ft_ies = wpa_driver_nl80211_update_ft_ies,
12351 : .get_mac_addr = wpa_driver_nl80211_get_macaddr,
12352 : .get_survey = wpa_driver_nl80211_get_survey,
12353 : .status = wpa_driver_nl80211_status,
12354 : .switch_channel = nl80211_switch_channel,
12355 : #ifdef ANDROID_P2P
12356 : .set_noa = wpa_driver_set_p2p_noa,
12357 : .get_noa = wpa_driver_get_p2p_noa,
12358 : .set_ap_wps_ie = wpa_driver_set_ap_wps_p2p_ie,
12359 : #endif /* ANDROID_P2P */
12360 : #ifdef ANDROID
12361 : .driver_cmd = wpa_driver_nl80211_driver_cmd,
12362 : #endif /* ANDROID */
12363 : .vendor_cmd = nl80211_vendor_cmd,
12364 : .set_qos_map = nl80211_set_qos_map,
12365 : .set_wowlan = nl80211_set_wowlan,
12366 : };
|