1 /*
2 * Driver interaction with Linux nl80211/cfg80211 - Event processing
3 * Copyright (c) 2002-2017, Jouni Malinen <j@w1.fi>
4 * Copyright (c) 2007, Johannes Berg <johannes@sipsolutions.net>
5 * Copyright (c) 2009-2010, Atheros Communications
6 *
7 * This software may be distributed under the terms of the BSD license.
8 * See README for more details.
9 */
10
11 #include "includes.h"
12 #include <netlink/genl/genl.h>
13
14 #include "utils/common.h"
15 #include "utils/eloop.h"
16 #include "common/qca-vendor.h"
17 #include "common/qca-vendor-attr.h"
18 #include "common/ieee802_11_defs.h"
19 #include "common/ieee802_11_common.h"
20 #include "driver_nl80211.h"
21
22
nl80211_command_to_string(enum nl80211_commands cmd)23 static const char * nl80211_command_to_string(enum nl80211_commands cmd)
24 {
25 #define C2S(x) case x: return #x;
26 switch (cmd) {
27 C2S(NL80211_CMD_UNSPEC)
28 C2S(NL80211_CMD_GET_WIPHY)
29 C2S(NL80211_CMD_SET_WIPHY)
30 C2S(NL80211_CMD_NEW_WIPHY)
31 C2S(NL80211_CMD_DEL_WIPHY)
32 C2S(NL80211_CMD_GET_INTERFACE)
33 C2S(NL80211_CMD_SET_INTERFACE)
34 C2S(NL80211_CMD_NEW_INTERFACE)
35 C2S(NL80211_CMD_DEL_INTERFACE)
36 C2S(NL80211_CMD_GET_KEY)
37 C2S(NL80211_CMD_SET_KEY)
38 C2S(NL80211_CMD_NEW_KEY)
39 C2S(NL80211_CMD_DEL_KEY)
40 C2S(NL80211_CMD_GET_BEACON)
41 C2S(NL80211_CMD_SET_BEACON)
42 C2S(NL80211_CMD_START_AP)
43 C2S(NL80211_CMD_STOP_AP)
44 C2S(NL80211_CMD_GET_STATION)
45 C2S(NL80211_CMD_SET_STATION)
46 C2S(NL80211_CMD_NEW_STATION)
47 C2S(NL80211_CMD_DEL_STATION)
48 C2S(NL80211_CMD_GET_MPATH)
49 C2S(NL80211_CMD_SET_MPATH)
50 C2S(NL80211_CMD_NEW_MPATH)
51 C2S(NL80211_CMD_DEL_MPATH)
52 C2S(NL80211_CMD_SET_BSS)
53 C2S(NL80211_CMD_SET_REG)
54 C2S(NL80211_CMD_REQ_SET_REG)
55 C2S(NL80211_CMD_GET_MESH_CONFIG)
56 C2S(NL80211_CMD_SET_MESH_CONFIG)
57 C2S(NL80211_CMD_SET_MGMT_EXTRA_IE)
58 C2S(NL80211_CMD_GET_REG)
59 C2S(NL80211_CMD_GET_SCAN)
60 C2S(NL80211_CMD_TRIGGER_SCAN)
61 C2S(NL80211_CMD_NEW_SCAN_RESULTS)
62 C2S(NL80211_CMD_SCAN_ABORTED)
63 C2S(NL80211_CMD_REG_CHANGE)
64 C2S(NL80211_CMD_AUTHENTICATE)
65 C2S(NL80211_CMD_ASSOCIATE)
66 C2S(NL80211_CMD_DEAUTHENTICATE)
67 C2S(NL80211_CMD_DISASSOCIATE)
68 C2S(NL80211_CMD_MICHAEL_MIC_FAILURE)
69 C2S(NL80211_CMD_REG_BEACON_HINT)
70 C2S(NL80211_CMD_JOIN_IBSS)
71 C2S(NL80211_CMD_LEAVE_IBSS)
72 C2S(NL80211_CMD_TESTMODE)
73 C2S(NL80211_CMD_CONNECT)
74 C2S(NL80211_CMD_ROAM)
75 C2S(NL80211_CMD_DISCONNECT)
76 C2S(NL80211_CMD_SET_WIPHY_NETNS)
77 C2S(NL80211_CMD_GET_SURVEY)
78 C2S(NL80211_CMD_NEW_SURVEY_RESULTS)
79 C2S(NL80211_CMD_SET_PMKSA)
80 C2S(NL80211_CMD_DEL_PMKSA)
81 C2S(NL80211_CMD_FLUSH_PMKSA)
82 C2S(NL80211_CMD_REMAIN_ON_CHANNEL)
83 C2S(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL)
84 C2S(NL80211_CMD_SET_TX_BITRATE_MASK)
85 C2S(NL80211_CMD_REGISTER_FRAME)
86 C2S(NL80211_CMD_FRAME)
87 C2S(NL80211_CMD_FRAME_TX_STATUS)
88 C2S(NL80211_CMD_SET_POWER_SAVE)
89 C2S(NL80211_CMD_GET_POWER_SAVE)
90 C2S(NL80211_CMD_SET_CQM)
91 C2S(NL80211_CMD_NOTIFY_CQM)
92 C2S(NL80211_CMD_SET_CHANNEL)
93 C2S(NL80211_CMD_SET_WDS_PEER)
94 C2S(NL80211_CMD_FRAME_WAIT_CANCEL)
95 C2S(NL80211_CMD_JOIN_MESH)
96 C2S(NL80211_CMD_LEAVE_MESH)
97 C2S(NL80211_CMD_UNPROT_DEAUTHENTICATE)
98 C2S(NL80211_CMD_UNPROT_DISASSOCIATE)
99 C2S(NL80211_CMD_NEW_PEER_CANDIDATE)
100 C2S(NL80211_CMD_GET_WOWLAN)
101 C2S(NL80211_CMD_SET_WOWLAN)
102 C2S(NL80211_CMD_START_SCHED_SCAN)
103 C2S(NL80211_CMD_STOP_SCHED_SCAN)
104 C2S(NL80211_CMD_SCHED_SCAN_RESULTS)
105 C2S(NL80211_CMD_SCHED_SCAN_STOPPED)
106 C2S(NL80211_CMD_SET_REKEY_OFFLOAD)
107 C2S(NL80211_CMD_PMKSA_CANDIDATE)
108 C2S(NL80211_CMD_TDLS_OPER)
109 C2S(NL80211_CMD_TDLS_MGMT)
110 C2S(NL80211_CMD_UNEXPECTED_FRAME)
111 C2S(NL80211_CMD_PROBE_CLIENT)
112 C2S(NL80211_CMD_REGISTER_BEACONS)
113 C2S(NL80211_CMD_UNEXPECTED_4ADDR_FRAME)
114 C2S(NL80211_CMD_SET_NOACK_MAP)
115 C2S(NL80211_CMD_CH_SWITCH_NOTIFY)
116 C2S(NL80211_CMD_START_P2P_DEVICE)
117 C2S(NL80211_CMD_STOP_P2P_DEVICE)
118 C2S(NL80211_CMD_CONN_FAILED)
119 C2S(NL80211_CMD_SET_MCAST_RATE)
120 C2S(NL80211_CMD_SET_MAC_ACL)
121 C2S(NL80211_CMD_RADAR_DETECT)
122 C2S(NL80211_CMD_GET_PROTOCOL_FEATURES)
123 C2S(NL80211_CMD_UPDATE_FT_IES)
124 C2S(NL80211_CMD_FT_EVENT)
125 C2S(NL80211_CMD_CRIT_PROTOCOL_START)
126 C2S(NL80211_CMD_CRIT_PROTOCOL_STOP)
127 C2S(NL80211_CMD_GET_COALESCE)
128 C2S(NL80211_CMD_SET_COALESCE)
129 C2S(NL80211_CMD_CHANNEL_SWITCH)
130 C2S(NL80211_CMD_VENDOR)
131 C2S(NL80211_CMD_SET_QOS_MAP)
132 C2S(NL80211_CMD_ADD_TX_TS)
133 C2S(NL80211_CMD_DEL_TX_TS)
134 default:
135 return "NL80211_CMD_UNKNOWN";
136 }
137 #undef C2S
138 }
139
140
mlme_event_auth(struct wpa_driver_nl80211_data * drv,const u8 * frame,size_t len)141 static void mlme_event_auth(struct wpa_driver_nl80211_data *drv,
142 const u8 *frame, size_t len)
143 {
144 const struct ieee80211_mgmt *mgmt;
145 union wpa_event_data event;
146
147 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME) &&
148 drv->force_connect_cmd) {
149 /*
150 * Avoid reporting two association events that would confuse
151 * the core code.
152 */
153 wpa_printf(MSG_DEBUG,
154 "nl80211: Ignore auth event when using driver SME");
155 return;
156 }
157
158 wpa_printf(MSG_DEBUG, "nl80211: Authenticate event");
159 mgmt = (const struct ieee80211_mgmt *) frame;
160 if (len < 24 + sizeof(mgmt->u.auth)) {
161 wpa_printf(MSG_DEBUG, "nl80211: Too short association event "
162 "frame");
163 return;
164 }
165
166 os_memcpy(drv->auth_bssid, mgmt->sa, ETH_ALEN);
167 os_memset(drv->auth_attempt_bssid, 0, ETH_ALEN);
168 os_memset(&event, 0, sizeof(event));
169 os_memcpy(event.auth.peer, mgmt->sa, ETH_ALEN);
170 event.auth.auth_type = le_to_host16(mgmt->u.auth.auth_alg);
171 event.auth.auth_transaction =
172 le_to_host16(mgmt->u.auth.auth_transaction);
173 event.auth.status_code = le_to_host16(mgmt->u.auth.status_code);
174 if (len > 24 + sizeof(mgmt->u.auth)) {
175 event.auth.ies = mgmt->u.auth.variable;
176 event.auth.ies_len = len - 24 - sizeof(mgmt->u.auth);
177 }
178
179 wpa_supplicant_event(drv->ctx, EVENT_AUTH, &event);
180 }
181
182
nl80211_parse_wmm_params(struct nlattr * wmm_attr,struct wmm_params * wmm_params)183 static void nl80211_parse_wmm_params(struct nlattr *wmm_attr,
184 struct wmm_params *wmm_params)
185 {
186 struct nlattr *wmm_info[NL80211_STA_WME_MAX + 1];
187 static struct nla_policy wme_policy[NL80211_STA_WME_MAX + 1] = {
188 [NL80211_STA_WME_UAPSD_QUEUES] = { .type = NLA_U8 },
189 };
190
191 if (!wmm_attr ||
192 nla_parse_nested(wmm_info, NL80211_STA_WME_MAX, wmm_attr,
193 wme_policy) ||
194 !wmm_info[NL80211_STA_WME_UAPSD_QUEUES])
195 return;
196
197 wmm_params->uapsd_queues =
198 nla_get_u8(wmm_info[NL80211_STA_WME_UAPSD_QUEUES]);
199 wmm_params->info_bitmap |= WMM_PARAMS_UAPSD_QUEUES_INFO;
200 }
201
202
mlme_event_assoc(struct wpa_driver_nl80211_data * drv,const u8 * frame,size_t len,struct nlattr * wmm)203 static void mlme_event_assoc(struct wpa_driver_nl80211_data *drv,
204 const u8 *frame, size_t len, struct nlattr *wmm)
205 {
206 const struct ieee80211_mgmt *mgmt;
207 union wpa_event_data event;
208 u16 status;
209 int ssid_len;
210
211 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME) &&
212 drv->force_connect_cmd) {
213 /*
214 * Avoid reporting two association events that would confuse
215 * the core code.
216 */
217 wpa_printf(MSG_DEBUG,
218 "nl80211: Ignore assoc event when using driver SME");
219 return;
220 }
221
222 wpa_printf(MSG_DEBUG, "nl80211: Associate event");
223 mgmt = (const struct ieee80211_mgmt *) frame;
224 if (len < 24 + sizeof(mgmt->u.assoc_resp)) {
225 wpa_printf(MSG_DEBUG, "nl80211: Too short association event "
226 "frame");
227 return;
228 }
229
230 status = le_to_host16(mgmt->u.assoc_resp.status_code);
231 if (status != WLAN_STATUS_SUCCESS) {
232 os_memset(&event, 0, sizeof(event));
233 event.assoc_reject.bssid = mgmt->bssid;
234 if (len > 24 + sizeof(mgmt->u.assoc_resp)) {
235 event.assoc_reject.resp_ies =
236 (u8 *) mgmt->u.assoc_resp.variable;
237 event.assoc_reject.resp_ies_len =
238 len - 24 - sizeof(mgmt->u.assoc_resp);
239 }
240 event.assoc_reject.status_code = status;
241
242 wpa_supplicant_event(drv->ctx, EVENT_ASSOC_REJECT, &event);
243 return;
244 }
245
246 drv->associated = 1;
247 os_memcpy(drv->bssid, mgmt->sa, ETH_ALEN);
248 os_memcpy(drv->prev_bssid, mgmt->sa, ETH_ALEN);
249
250 os_memset(&event, 0, sizeof(event));
251 event.assoc_info.resp_frame = frame;
252 event.assoc_info.resp_frame_len = len;
253 if (len > 24 + sizeof(mgmt->u.assoc_resp)) {
254 event.assoc_info.resp_ies = (u8 *) mgmt->u.assoc_resp.variable;
255 event.assoc_info.resp_ies_len =
256 len - 24 - sizeof(mgmt->u.assoc_resp);
257 }
258
259 event.assoc_info.freq = drv->assoc_freq;
260
261 /* When this association was initiated outside of wpa_supplicant,
262 * drv->ssid needs to be set here to satisfy later checking. */
263 ssid_len = nl80211_get_assoc_ssid(drv, drv->ssid);
264 if (ssid_len > 0) {
265 drv->ssid_len = ssid_len;
266 wpa_printf(MSG_DEBUG,
267 "nl80211: Set drv->ssid based on scan res info to '%s'",
268 wpa_ssid_txt(drv->ssid, drv->ssid_len));
269 }
270
271 nl80211_parse_wmm_params(wmm, &event.assoc_info.wmm_params);
272
273 wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event);
274 }
275
276
mlme_event_connect(struct wpa_driver_nl80211_data * drv,enum nl80211_commands cmd,struct nlattr * status,struct nlattr * addr,struct nlattr * req_ie,struct nlattr * resp_ie,struct nlattr * timed_out,struct nlattr * timeout_reason,struct nlattr * authorized,struct nlattr * key_replay_ctr,struct nlattr * ptk_kck,struct nlattr * ptk_kek,struct nlattr * subnet_status)277 static void mlme_event_connect(struct wpa_driver_nl80211_data *drv,
278 enum nl80211_commands cmd, struct nlattr *status,
279 struct nlattr *addr, struct nlattr *req_ie,
280 struct nlattr *resp_ie,
281 struct nlattr *timed_out,
282 struct nlattr *timeout_reason,
283 struct nlattr *authorized,
284 struct nlattr *key_replay_ctr,
285 struct nlattr *ptk_kck,
286 struct nlattr *ptk_kek,
287 struct nlattr *subnet_status)
288 {
289 union wpa_event_data event;
290 const u8 *ssid = NULL;
291 u16 status_code;
292 int ssid_len;
293
294 if (drv->capa.flags & WPA_DRIVER_FLAGS_SME) {
295 /*
296 * Avoid reporting two association events that would confuse
297 * the core code.
298 */
299 wpa_printf(MSG_DEBUG, "nl80211: Ignore connect event (cmd=%d) "
300 "when using userspace SME", cmd);
301 return;
302 }
303
304 drv->connect_reassoc = 0;
305
306 status_code = status ? nla_get_u16(status) : WLAN_STATUS_SUCCESS;
307
308 if (cmd == NL80211_CMD_CONNECT) {
309 wpa_printf(MSG_DEBUG,
310 "nl80211: Connect event (status=%u ignore_next_local_disconnect=%d)",
311 status_code, drv->ignore_next_local_disconnect);
312 } else if (cmd == NL80211_CMD_ROAM) {
313 wpa_printf(MSG_DEBUG, "nl80211: Roam event");
314 }
315
316 os_memset(&event, 0, sizeof(event));
317 if (cmd == NL80211_CMD_CONNECT && status_code != WLAN_STATUS_SUCCESS) {
318 if (addr)
319 event.assoc_reject.bssid = nla_data(addr);
320 if (drv->ignore_next_local_disconnect) {
321 drv->ignore_next_local_disconnect = 0;
322 if (!event.assoc_reject.bssid ||
323 (os_memcmp(event.assoc_reject.bssid,
324 drv->auth_attempt_bssid,
325 ETH_ALEN) != 0)) {
326 /*
327 * Ignore the event that came without a BSSID or
328 * for the old connection since this is likely
329 * not relevant to the new Connect command.
330 */
331 wpa_printf(MSG_DEBUG,
332 "nl80211: Ignore connection failure event triggered during reassociation");
333 return;
334 }
335 }
336 if (resp_ie) {
337 event.assoc_reject.resp_ies = nla_data(resp_ie);
338 event.assoc_reject.resp_ies_len = nla_len(resp_ie);
339 }
340 event.assoc_reject.status_code = status_code;
341 event.assoc_reject.timed_out = timed_out != NULL;
342 if (timed_out && timeout_reason) {
343 enum nl80211_timeout_reason reason;
344
345 reason = nla_get_u32(timeout_reason);
346 switch (reason) {
347 case NL80211_TIMEOUT_SCAN:
348 event.assoc_reject.timeout_reason = "scan";
349 break;
350 case NL80211_TIMEOUT_AUTH:
351 event.assoc_reject.timeout_reason = "auth";
352 break;
353 case NL80211_TIMEOUT_ASSOC:
354 event.assoc_reject.timeout_reason = "assoc";
355 break;
356 default:
357 break;
358 }
359 }
360 wpa_supplicant_event(drv->ctx, EVENT_ASSOC_REJECT, &event);
361 return;
362 }
363
364 drv->associated = 1;
365 if (addr) {
366 os_memcpy(drv->bssid, nla_data(addr), ETH_ALEN);
367 os_memcpy(drv->prev_bssid, drv->bssid, ETH_ALEN);
368 }
369
370 if (req_ie) {
371 event.assoc_info.req_ies = nla_data(req_ie);
372 event.assoc_info.req_ies_len = nla_len(req_ie);
373
374 if (cmd == NL80211_CMD_ROAM) {
375 ssid = get_ie(event.assoc_info.req_ies,
376 event.assoc_info.req_ies_len,
377 WLAN_EID_SSID);
378 if (ssid && ssid[1] > 0 && ssid[1] <= 32) {
379 drv->ssid_len = ssid[1];
380 os_memcpy(drv->ssid, ssid + 2, ssid[1]);
381 wpa_printf(MSG_DEBUG,
382 "nl80211: Set drv->ssid based on req_ie to '%s'",
383 wpa_ssid_txt(drv->ssid,
384 drv->ssid_len));
385 }
386 }
387 }
388 if (resp_ie) {
389 event.assoc_info.resp_ies = nla_data(resp_ie);
390 event.assoc_info.resp_ies_len = nla_len(resp_ie);
391 }
392
393 event.assoc_info.freq = nl80211_get_assoc_freq(drv);
394
395 if ((!ssid || ssid[1] == 0 || ssid[1] > 32) &&
396 (ssid_len = nl80211_get_assoc_ssid(drv, drv->ssid)) > 0) {
397 /* When this connection was initiated outside of wpa_supplicant,
398 * drv->ssid needs to be set here to satisfy later checking. */
399 drv->ssid_len = ssid_len;
400 wpa_printf(MSG_DEBUG,
401 "nl80211: Set drv->ssid based on scan res info to '%s'",
402 wpa_ssid_txt(drv->ssid, drv->ssid_len));
403 }
404
405 if (authorized && nla_get_u8(authorized)) {
406 event.assoc_info.authorized = 1;
407 wpa_printf(MSG_DEBUG, "nl80211: connection authorized");
408 }
409 if (key_replay_ctr) {
410 event.assoc_info.key_replay_ctr = nla_data(key_replay_ctr);
411 event.assoc_info.key_replay_ctr_len = nla_len(key_replay_ctr);
412 }
413 if (ptk_kck) {
414 event.assoc_info.ptk_kck = nla_data(ptk_kck);
415 event.assoc_info.ptk_kck_len = nla_len(ptk_kck);
416 }
417 if (ptk_kek) {
418 event.assoc_info.ptk_kek = nla_data(ptk_kek);
419 event.assoc_info.ptk_kek_len = nla_len(ptk_kek);
420 }
421
422 if (subnet_status) {
423 /*
424 * At least for now, this is only available from
425 * QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_SUBNET_STATUS and that
426 * attribute has the same values 0, 1, 2 as are used in the
427 * variable here, so no mapping between different values are
428 * needed.
429 */
430 event.assoc_info.subnet_status = nla_get_u8(subnet_status);
431 }
432
433 wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event);
434 }
435
436
mlme_event_disconnect(struct wpa_driver_nl80211_data * drv,struct nlattr * reason,struct nlattr * addr,struct nlattr * by_ap)437 static void mlme_event_disconnect(struct wpa_driver_nl80211_data *drv,
438 struct nlattr *reason, struct nlattr *addr,
439 struct nlattr *by_ap)
440 {
441 union wpa_event_data data;
442 unsigned int locally_generated = by_ap == NULL;
443
444 if (drv->capa.flags & WPA_DRIVER_FLAGS_SME) {
445 /*
446 * Avoid reporting two disassociation events that could
447 * confuse the core code.
448 */
449 wpa_printf(MSG_DEBUG, "nl80211: Ignore disconnect "
450 "event when using userspace SME");
451 return;
452 }
453
454 if (drv->ignore_next_local_disconnect) {
455 drv->ignore_next_local_disconnect = 0;
456 if (locally_generated) {
457 wpa_printf(MSG_DEBUG, "nl80211: Ignore disconnect "
458 "event triggered during reassociation");
459 return;
460 }
461 wpa_printf(MSG_WARNING, "nl80211: Was expecting local "
462 "disconnect but got another disconnect "
463 "event first");
464 }
465
466 wpa_printf(MSG_DEBUG, "nl80211: Disconnect event");
467 nl80211_mark_disconnected(drv);
468 os_memset(&data, 0, sizeof(data));
469 if (reason)
470 data.deauth_info.reason_code = nla_get_u16(reason);
471 data.deauth_info.locally_generated = by_ap == NULL;
472 wpa_supplicant_event(drv->ctx, EVENT_DEAUTH, &data);
473 }
474
475
calculate_chan_offset(int width,int freq,int cf1,int cf2)476 static int calculate_chan_offset(int width, int freq, int cf1, int cf2)
477 {
478 int freq1 = 0;
479
480 switch (convert2width(width)) {
481 case CHAN_WIDTH_20_NOHT:
482 case CHAN_WIDTH_20:
483 return 0;
484 case CHAN_WIDTH_40:
485 freq1 = cf1 - 10;
486 break;
487 case CHAN_WIDTH_80:
488 freq1 = cf1 - 30;
489 break;
490 case CHAN_WIDTH_160:
491 freq1 = cf1 - 70;
492 break;
493 case CHAN_WIDTH_UNKNOWN:
494 case CHAN_WIDTH_80P80:
495 /* FIXME: implement this */
496 return 0;
497 }
498
499 return (abs(freq - freq1) / 20) % 2 == 0 ? 1 : -1;
500 }
501
502
mlme_event_ch_switch(struct wpa_driver_nl80211_data * drv,struct nlattr * ifindex,struct nlattr * freq,struct nlattr * type,struct nlattr * bw,struct nlattr * cf1,struct nlattr * cf2)503 static void mlme_event_ch_switch(struct wpa_driver_nl80211_data *drv,
504 struct nlattr *ifindex, struct nlattr *freq,
505 struct nlattr *type, struct nlattr *bw,
506 struct nlattr *cf1, struct nlattr *cf2)
507 {
508 struct i802_bss *bss;
509 union wpa_event_data data;
510 int ht_enabled = 1;
511 int chan_offset = 0;
512 int ifidx;
513
514 wpa_printf(MSG_DEBUG, "nl80211: Channel switch event");
515
516 if (!freq)
517 return;
518
519 ifidx = nla_get_u32(ifindex);
520 bss = get_bss_ifindex(drv, ifidx);
521 if (bss == NULL) {
522 wpa_printf(MSG_WARNING, "nl80211: Unknown ifindex (%d) for channel switch, ignoring",
523 ifidx);
524 return;
525 }
526
527 if (type) {
528 enum nl80211_channel_type ch_type = nla_get_u32(type);
529
530 wpa_printf(MSG_DEBUG, "nl80211: Channel type: %d", ch_type);
531 switch (ch_type) {
532 case NL80211_CHAN_NO_HT:
533 ht_enabled = 0;
534 break;
535 case NL80211_CHAN_HT20:
536 break;
537 case NL80211_CHAN_HT40PLUS:
538 chan_offset = 1;
539 break;
540 case NL80211_CHAN_HT40MINUS:
541 chan_offset = -1;
542 break;
543 }
544 } else if (bw && cf1) {
545 /* This can happen for example with VHT80 ch switch */
546 chan_offset = calculate_chan_offset(nla_get_u32(bw),
547 nla_get_u32(freq),
548 nla_get_u32(cf1),
549 cf2 ? nla_get_u32(cf2) : 0);
550 } else {
551 wpa_printf(MSG_WARNING, "nl80211: Unknown secondary channel information - following channel definition calculations may fail");
552 }
553
554 os_memset(&data, 0, sizeof(data));
555 data.ch_switch.freq = nla_get_u32(freq);
556 data.ch_switch.ht_enabled = ht_enabled;
557 data.ch_switch.ch_offset = chan_offset;
558 if (bw)
559 data.ch_switch.ch_width = convert2width(nla_get_u32(bw));
560 if (cf1)
561 data.ch_switch.cf1 = nla_get_u32(cf1);
562 if (cf2)
563 data.ch_switch.cf2 = nla_get_u32(cf2);
564
565 bss->freq = data.ch_switch.freq;
566 drv->assoc_freq = data.ch_switch.freq;
567
568 wpa_supplicant_event(bss->ctx, EVENT_CH_SWITCH, &data);
569 }
570
571
mlme_timeout_event(struct wpa_driver_nl80211_data * drv,enum nl80211_commands cmd,struct nlattr * addr)572 static void mlme_timeout_event(struct wpa_driver_nl80211_data *drv,
573 enum nl80211_commands cmd, struct nlattr *addr)
574 {
575 union wpa_event_data event;
576 enum wpa_event_type ev;
577
578 if (nla_len(addr) != ETH_ALEN)
579 return;
580
581 wpa_printf(MSG_DEBUG, "nl80211: MLME event %d; timeout with " MACSTR,
582 cmd, MAC2STR((u8 *) nla_data(addr)));
583
584 if (cmd == NL80211_CMD_AUTHENTICATE)
585 ev = EVENT_AUTH_TIMED_OUT;
586 else if (cmd == NL80211_CMD_ASSOCIATE)
587 ev = EVENT_ASSOC_TIMED_OUT;
588 else
589 return;
590
591 os_memset(&event, 0, sizeof(event));
592 os_memcpy(event.timeout_event.addr, nla_data(addr), ETH_ALEN);
593 wpa_supplicant_event(drv->ctx, ev, &event);
594 }
595
596
mlme_event_mgmt(struct i802_bss * bss,struct nlattr * freq,struct nlattr * sig,const u8 * frame,size_t len)597 static void mlme_event_mgmt(struct i802_bss *bss,
598 struct nlattr *freq, struct nlattr *sig,
599 const u8 *frame, size_t len)
600 {
601 struct wpa_driver_nl80211_data *drv = bss->drv;
602 const struct ieee80211_mgmt *mgmt;
603 union wpa_event_data event;
604 u16 fc, stype;
605 int ssi_signal = 0;
606 int rx_freq = 0;
607
608 wpa_printf(MSG_MSGDUMP, "nl80211: Frame event");
609 mgmt = (const struct ieee80211_mgmt *) frame;
610 if (len < 24) {
611 wpa_printf(MSG_DEBUG, "nl80211: Too short management frame");
612 return;
613 }
614
615 fc = le_to_host16(mgmt->frame_control);
616 stype = WLAN_FC_GET_STYPE(fc);
617
618 if (sig)
619 ssi_signal = (s32) nla_get_u32(sig);
620
621 os_memset(&event, 0, sizeof(event));
622 if (freq) {
623 event.rx_mgmt.freq = nla_get_u32(freq);
624 rx_freq = drv->last_mgmt_freq = event.rx_mgmt.freq;
625 }
626 wpa_printf(MSG_DEBUG,
627 "nl80211: RX frame da=" MACSTR " sa=" MACSTR " bssid=" MACSTR
628 " freq=%d ssi_signal=%d fc=0x%x seq_ctrl=0x%x stype=%u (%s) len=%u",
629 MAC2STR(mgmt->da), MAC2STR(mgmt->sa), MAC2STR(mgmt->bssid),
630 rx_freq, ssi_signal, fc,
631 le_to_host16(mgmt->seq_ctrl), stype, fc2str(fc),
632 (unsigned int) len);
633 event.rx_mgmt.frame = frame;
634 event.rx_mgmt.frame_len = len;
635 event.rx_mgmt.ssi_signal = ssi_signal;
636 event.rx_mgmt.drv_priv = bss;
637 wpa_supplicant_event(drv->ctx, EVENT_RX_MGMT, &event);
638 }
639
640
mlme_event_mgmt_tx_status(struct wpa_driver_nl80211_data * drv,struct nlattr * cookie,const u8 * frame,size_t len,struct nlattr * ack)641 static void mlme_event_mgmt_tx_status(struct wpa_driver_nl80211_data *drv,
642 struct nlattr *cookie, const u8 *frame,
643 size_t len, struct nlattr *ack)
644 {
645 union wpa_event_data event;
646 const struct ieee80211_hdr *hdr;
647 u16 fc;
648
649 wpa_printf(MSG_DEBUG, "nl80211: Frame TX status event");
650 if (!is_ap_interface(drv->nlmode)) {
651 u64 cookie_val;
652
653 if (!cookie)
654 return;
655
656 cookie_val = nla_get_u64(cookie);
657 wpa_printf(MSG_DEBUG, "nl80211: Action TX status:"
658 " cookie=0%llx%s (ack=%d)",
659 (long long unsigned int) cookie_val,
660 cookie_val == drv->send_action_cookie ?
661 " (match)" : " (unknown)", ack != NULL);
662 if (cookie_val != drv->send_action_cookie)
663 return;
664 }
665
666 hdr = (const struct ieee80211_hdr *) frame;
667 fc = le_to_host16(hdr->frame_control);
668
669 os_memset(&event, 0, sizeof(event));
670 event.tx_status.type = WLAN_FC_GET_TYPE(fc);
671 event.tx_status.stype = WLAN_FC_GET_STYPE(fc);
672 event.tx_status.dst = hdr->addr1;
673 event.tx_status.data = frame;
674 event.tx_status.data_len = len;
675 event.tx_status.ack = ack != NULL;
676 wpa_supplicant_event(drv->ctx, EVENT_TX_STATUS, &event);
677 }
678
679
mlme_event_deauth_disassoc(struct wpa_driver_nl80211_data * drv,enum wpa_event_type type,const u8 * frame,size_t len)680 static void mlme_event_deauth_disassoc(struct wpa_driver_nl80211_data *drv,
681 enum wpa_event_type type,
682 const u8 *frame, size_t len)
683 {
684 const struct ieee80211_mgmt *mgmt;
685 union wpa_event_data event;
686 const u8 *bssid = NULL;
687 u16 reason_code = 0;
688
689 if (type == EVENT_DEAUTH)
690 wpa_printf(MSG_DEBUG, "nl80211: Deauthenticate event");
691 else
692 wpa_printf(MSG_DEBUG, "nl80211: Disassociate event");
693
694 mgmt = (const struct ieee80211_mgmt *) frame;
695 if (len >= 24) {
696 bssid = mgmt->bssid;
697
698 if ((drv->capa.flags & WPA_DRIVER_FLAGS_SME) &&
699 !drv->associated &&
700 os_memcmp(bssid, drv->auth_bssid, ETH_ALEN) != 0 &&
701 os_memcmp(bssid, drv->auth_attempt_bssid, ETH_ALEN) != 0 &&
702 os_memcmp(bssid, drv->prev_bssid, ETH_ALEN) == 0) {
703 /*
704 * Avoid issues with some roaming cases where
705 * disconnection event for the old AP may show up after
706 * we have started connection with the new AP.
707 * In case of locally generated event clear
708 * ignore_next_local_deauth as well, to avoid next local
709 * deauth event be wrongly ignored.
710 */
711 if (!os_memcmp(mgmt->sa, drv->first_bss->addr,
712 ETH_ALEN)) {
713 wpa_printf(MSG_DEBUG,
714 "nl80211: Received a locally generated deauth event. Clear ignore_next_local_deauth flag");
715 drv->ignore_next_local_deauth = 0;
716 } else {
717 wpa_printf(MSG_DEBUG,
718 "nl80211: Ignore deauth/disassoc event from old AP " MACSTR " when already authenticating with " MACSTR,
719 MAC2STR(bssid),
720 MAC2STR(drv->auth_attempt_bssid));
721 }
722 return;
723 }
724
725 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME) &&
726 drv->connect_reassoc && drv->associated &&
727 os_memcmp(bssid, drv->prev_bssid, ETH_ALEN) == 0 &&
728 os_memcmp(bssid, drv->auth_attempt_bssid, ETH_ALEN) != 0) {
729 /*
730 * Avoid issues with some roaming cases where
731 * disconnection event for the old AP may show up after
732 * we have started connection with the new AP.
733 */
734 wpa_printf(MSG_DEBUG,
735 "nl80211: Ignore deauth/disassoc event from old AP "
736 MACSTR
737 " when already connecting with " MACSTR,
738 MAC2STR(bssid),
739 MAC2STR(drv->auth_attempt_bssid));
740 return;
741 }
742
743 if (drv->associated != 0 &&
744 os_memcmp(bssid, drv->bssid, ETH_ALEN) != 0 &&
745 os_memcmp(bssid, drv->auth_bssid, ETH_ALEN) != 0) {
746 /*
747 * We have presumably received this deauth as a
748 * response to a clear_state_mismatch() outgoing
749 * deauth. Don't let it take us offline!
750 */
751 wpa_printf(MSG_DEBUG, "nl80211: Deauth received "
752 "from Unknown BSSID " MACSTR " -- ignoring",
753 MAC2STR(bssid));
754 return;
755 }
756 }
757
758 nl80211_mark_disconnected(drv);
759 os_memset(&event, 0, sizeof(event));
760
761 /* Note: Same offset for Reason Code in both frame subtypes */
762 if (len >= 24 + sizeof(mgmt->u.deauth))
763 reason_code = le_to_host16(mgmt->u.deauth.reason_code);
764
765 if (type == EVENT_DISASSOC) {
766 event.disassoc_info.locally_generated =
767 !os_memcmp(mgmt->sa, drv->first_bss->addr, ETH_ALEN);
768 event.disassoc_info.addr = bssid;
769 event.disassoc_info.reason_code = reason_code;
770 if (frame + len > mgmt->u.disassoc.variable) {
771 event.disassoc_info.ie = mgmt->u.disassoc.variable;
772 event.disassoc_info.ie_len = frame + len -
773 mgmt->u.disassoc.variable;
774 }
775 } else {
776 event.deauth_info.locally_generated =
777 !os_memcmp(mgmt->sa, drv->first_bss->addr, ETH_ALEN);
778 if (drv->ignore_deauth_event) {
779 wpa_printf(MSG_DEBUG, "nl80211: Ignore deauth event due to previous forced deauth-during-auth");
780 drv->ignore_deauth_event = 0;
781 if (event.deauth_info.locally_generated)
782 drv->ignore_next_local_deauth = 0;
783 return;
784 }
785 if (drv->ignore_next_local_deauth) {
786 drv->ignore_next_local_deauth = 0;
787 if (event.deauth_info.locally_generated) {
788 wpa_printf(MSG_DEBUG, "nl80211: Ignore deauth event triggered due to own deauth request");
789 return;
790 }
791 wpa_printf(MSG_WARNING, "nl80211: Was expecting local deauth but got another disconnect event first");
792 }
793 event.deauth_info.addr = bssid;
794 event.deauth_info.reason_code = reason_code;
795 if (frame + len > mgmt->u.deauth.variable) {
796 event.deauth_info.ie = mgmt->u.deauth.variable;
797 event.deauth_info.ie_len = frame + len -
798 mgmt->u.deauth.variable;
799 }
800 }
801
802 wpa_supplicant_event(drv->ctx, type, &event);
803 }
804
805
mlme_event_unprot_disconnect(struct wpa_driver_nl80211_data * drv,enum wpa_event_type type,const u8 * frame,size_t len)806 static void mlme_event_unprot_disconnect(struct wpa_driver_nl80211_data *drv,
807 enum wpa_event_type type,
808 const u8 *frame, size_t len)
809 {
810 const struct ieee80211_mgmt *mgmt;
811 union wpa_event_data event;
812 u16 reason_code = 0;
813
814 if (type == EVENT_UNPROT_DEAUTH)
815 wpa_printf(MSG_DEBUG, "nl80211: Unprot Deauthenticate event");
816 else
817 wpa_printf(MSG_DEBUG, "nl80211: Unprot Disassociate event");
818
819 if (len < 24)
820 return;
821
822 mgmt = (const struct ieee80211_mgmt *) frame;
823
824 os_memset(&event, 0, sizeof(event));
825 /* Note: Same offset for Reason Code in both frame subtypes */
826 if (len >= 24 + sizeof(mgmt->u.deauth))
827 reason_code = le_to_host16(mgmt->u.deauth.reason_code);
828
829 if (type == EVENT_UNPROT_DISASSOC) {
830 event.unprot_disassoc.sa = mgmt->sa;
831 event.unprot_disassoc.da = mgmt->da;
832 event.unprot_disassoc.reason_code = reason_code;
833 } else {
834 event.unprot_deauth.sa = mgmt->sa;
835 event.unprot_deauth.da = mgmt->da;
836 event.unprot_deauth.reason_code = reason_code;
837 }
838
839 wpa_supplicant_event(drv->ctx, type, &event);
840 }
841
842
mlme_event(struct i802_bss * bss,enum nl80211_commands cmd,struct nlattr * frame,struct nlattr * addr,struct nlattr * timed_out,struct nlattr * freq,struct nlattr * ack,struct nlattr * cookie,struct nlattr * sig,struct nlattr * wmm)843 static void mlme_event(struct i802_bss *bss,
844 enum nl80211_commands cmd, struct nlattr *frame,
845 struct nlattr *addr, struct nlattr *timed_out,
846 struct nlattr *freq, struct nlattr *ack,
847 struct nlattr *cookie, struct nlattr *sig,
848 struct nlattr *wmm)
849 {
850 struct wpa_driver_nl80211_data *drv = bss->drv;
851 const u8 *data;
852 size_t len;
853
854 if (timed_out && addr) {
855 mlme_timeout_event(drv, cmd, addr);
856 return;
857 }
858
859 if (frame == NULL) {
860 wpa_printf(MSG_DEBUG,
861 "nl80211: MLME event %d (%s) without frame data",
862 cmd, nl80211_command_to_string(cmd));
863 return;
864 }
865
866 data = nla_data(frame);
867 len = nla_len(frame);
868 if (len < 4 + 2 * ETH_ALEN) {
869 wpa_printf(MSG_MSGDUMP, "nl80211: MLME event %d (%s) on %s("
870 MACSTR ") - too short",
871 cmd, nl80211_command_to_string(cmd), bss->ifname,
872 MAC2STR(bss->addr));
873 return;
874 }
875 wpa_printf(MSG_MSGDUMP, "nl80211: MLME event %d (%s) on %s(" MACSTR
876 ") A1=" MACSTR " A2=" MACSTR, cmd,
877 nl80211_command_to_string(cmd), bss->ifname,
878 MAC2STR(bss->addr), MAC2STR(data + 4),
879 MAC2STR(data + 4 + ETH_ALEN));
880 if (cmd != NL80211_CMD_FRAME_TX_STATUS && !(data[4] & 0x01) &&
881 os_memcmp(bss->addr, data + 4, ETH_ALEN) != 0 &&
882 (is_zero_ether_addr(bss->rand_addr) ||
883 os_memcmp(bss->rand_addr, data + 4, ETH_ALEN) != 0) &&
884 os_memcmp(bss->addr, data + 4 + ETH_ALEN, ETH_ALEN) != 0) {
885 wpa_printf(MSG_MSGDUMP, "nl80211: %s: Ignore MLME frame event "
886 "for foreign address", bss->ifname);
887 return;
888 }
889 wpa_hexdump(MSG_MSGDUMP, "nl80211: MLME event frame",
890 nla_data(frame), nla_len(frame));
891
892 switch (cmd) {
893 case NL80211_CMD_AUTHENTICATE:
894 mlme_event_auth(drv, nla_data(frame), nla_len(frame));
895 break;
896 case NL80211_CMD_ASSOCIATE:
897 mlme_event_assoc(drv, nla_data(frame), nla_len(frame), wmm);
898 break;
899 case NL80211_CMD_DEAUTHENTICATE:
900 mlme_event_deauth_disassoc(drv, EVENT_DEAUTH,
901 nla_data(frame), nla_len(frame));
902 break;
903 case NL80211_CMD_DISASSOCIATE:
904 mlme_event_deauth_disassoc(drv, EVENT_DISASSOC,
905 nla_data(frame), nla_len(frame));
906 break;
907 case NL80211_CMD_FRAME:
908 mlme_event_mgmt(bss, freq, sig, nla_data(frame),
909 nla_len(frame));
910 break;
911 case NL80211_CMD_FRAME_TX_STATUS:
912 mlme_event_mgmt_tx_status(drv, cookie, nla_data(frame),
913 nla_len(frame), ack);
914 break;
915 case NL80211_CMD_UNPROT_DEAUTHENTICATE:
916 mlme_event_unprot_disconnect(drv, EVENT_UNPROT_DEAUTH,
917 nla_data(frame), nla_len(frame));
918 break;
919 case NL80211_CMD_UNPROT_DISASSOCIATE:
920 mlme_event_unprot_disconnect(drv, EVENT_UNPROT_DISASSOC,
921 nla_data(frame), nla_len(frame));
922 break;
923 default:
924 break;
925 }
926 }
927
928
mlme_event_michael_mic_failure(struct i802_bss * bss,struct nlattr * tb[])929 static void mlme_event_michael_mic_failure(struct i802_bss *bss,
930 struct nlattr *tb[])
931 {
932 union wpa_event_data data;
933
934 wpa_printf(MSG_DEBUG, "nl80211: MLME event Michael MIC failure");
935 os_memset(&data, 0, sizeof(data));
936 if (tb[NL80211_ATTR_MAC]) {
937 wpa_hexdump(MSG_DEBUG, "nl80211: Source MAC address",
938 nla_data(tb[NL80211_ATTR_MAC]),
939 nla_len(tb[NL80211_ATTR_MAC]));
940 data.michael_mic_failure.src = nla_data(tb[NL80211_ATTR_MAC]);
941 }
942 if (tb[NL80211_ATTR_KEY_SEQ]) {
943 wpa_hexdump(MSG_DEBUG, "nl80211: TSC",
944 nla_data(tb[NL80211_ATTR_KEY_SEQ]),
945 nla_len(tb[NL80211_ATTR_KEY_SEQ]));
946 }
947 if (tb[NL80211_ATTR_KEY_TYPE]) {
948 enum nl80211_key_type key_type =
949 nla_get_u32(tb[NL80211_ATTR_KEY_TYPE]);
950 wpa_printf(MSG_DEBUG, "nl80211: Key Type %d", key_type);
951 if (key_type == NL80211_KEYTYPE_PAIRWISE)
952 data.michael_mic_failure.unicast = 1;
953 } else
954 data.michael_mic_failure.unicast = 1;
955
956 if (tb[NL80211_ATTR_KEY_IDX]) {
957 u8 key_id = nla_get_u8(tb[NL80211_ATTR_KEY_IDX]);
958 wpa_printf(MSG_DEBUG, "nl80211: Key Id %d", key_id);
959 }
960
961 wpa_supplicant_event(bss->ctx, EVENT_MICHAEL_MIC_FAILURE, &data);
962 }
963
964
mlme_event_join_ibss(struct wpa_driver_nl80211_data * drv,struct nlattr * tb[])965 static void mlme_event_join_ibss(struct wpa_driver_nl80211_data *drv,
966 struct nlattr *tb[])
967 {
968 unsigned int freq;
969 union wpa_event_data event;
970
971 if (tb[NL80211_ATTR_MAC] == NULL) {
972 wpa_printf(MSG_DEBUG, "nl80211: No address in IBSS joined "
973 "event");
974 return;
975 }
976 os_memcpy(drv->bssid, nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
977
978 drv->associated = 1;
979 wpa_printf(MSG_DEBUG, "nl80211: IBSS " MACSTR " joined",
980 MAC2STR(drv->bssid));
981
982 freq = nl80211_get_assoc_freq(drv);
983 if (freq) {
984 wpa_printf(MSG_DEBUG, "nl80211: IBSS on frequency %u MHz",
985 freq);
986 drv->first_bss->freq = freq;
987 }
988
989 os_memset(&event, 0, sizeof(event));
990 event.assoc_info.freq = freq;
991
992 wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event);
993 }
994
995
mlme_event_remain_on_channel(struct wpa_driver_nl80211_data * drv,int cancel_event,struct nlattr * tb[])996 static void mlme_event_remain_on_channel(struct wpa_driver_nl80211_data *drv,
997 int cancel_event, struct nlattr *tb[])
998 {
999 unsigned int freq, chan_type, duration;
1000 union wpa_event_data data;
1001 u64 cookie;
1002
1003 if (tb[NL80211_ATTR_WIPHY_FREQ])
1004 freq = nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]);
1005 else
1006 freq = 0;
1007
1008 if (tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE])
1009 chan_type = nla_get_u32(tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
1010 else
1011 chan_type = 0;
1012
1013 if (tb[NL80211_ATTR_DURATION])
1014 duration = nla_get_u32(tb[NL80211_ATTR_DURATION]);
1015 else
1016 duration = 0;
1017
1018 if (tb[NL80211_ATTR_COOKIE])
1019 cookie = nla_get_u64(tb[NL80211_ATTR_COOKIE]);
1020 else
1021 cookie = 0;
1022
1023 wpa_printf(MSG_DEBUG, "nl80211: Remain-on-channel event (cancel=%d "
1024 "freq=%u channel_type=%u duration=%u cookie=0x%llx (%s))",
1025 cancel_event, freq, chan_type, duration,
1026 (long long unsigned int) cookie,
1027 cookie == drv->remain_on_chan_cookie ? "match" : "unknown");
1028
1029 if (cookie != drv->remain_on_chan_cookie)
1030 return; /* not for us */
1031
1032 if (cancel_event)
1033 drv->pending_remain_on_chan = 0;
1034
1035 os_memset(&data, 0, sizeof(data));
1036 data.remain_on_channel.freq = freq;
1037 data.remain_on_channel.duration = duration;
1038 wpa_supplicant_event(drv->ctx, cancel_event ?
1039 EVENT_CANCEL_REMAIN_ON_CHANNEL :
1040 EVENT_REMAIN_ON_CHANNEL, &data);
1041 }
1042
1043
mlme_event_ft_event(struct wpa_driver_nl80211_data * drv,struct nlattr * tb[])1044 static void mlme_event_ft_event(struct wpa_driver_nl80211_data *drv,
1045 struct nlattr *tb[])
1046 {
1047 union wpa_event_data data;
1048
1049 os_memset(&data, 0, sizeof(data));
1050
1051 if (tb[NL80211_ATTR_IE]) {
1052 data.ft_ies.ies = nla_data(tb[NL80211_ATTR_IE]);
1053 data.ft_ies.ies_len = nla_len(tb[NL80211_ATTR_IE]);
1054 }
1055
1056 if (tb[NL80211_ATTR_IE_RIC]) {
1057 data.ft_ies.ric_ies = nla_data(tb[NL80211_ATTR_IE_RIC]);
1058 data.ft_ies.ric_ies_len = nla_len(tb[NL80211_ATTR_IE_RIC]);
1059 }
1060
1061 if (tb[NL80211_ATTR_MAC])
1062 os_memcpy(data.ft_ies.target_ap,
1063 nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
1064
1065 wpa_printf(MSG_DEBUG, "nl80211: FT event target_ap " MACSTR,
1066 MAC2STR(data.ft_ies.target_ap));
1067
1068 wpa_supplicant_event(drv->ctx, EVENT_FT_RESPONSE, &data);
1069 }
1070
1071
send_scan_event(struct wpa_driver_nl80211_data * drv,int aborted,struct nlattr * tb[],int external_scan)1072 static void send_scan_event(struct wpa_driver_nl80211_data *drv, int aborted,
1073 struct nlattr *tb[], int external_scan)
1074 {
1075 union wpa_event_data event;
1076 struct nlattr *nl;
1077 int rem;
1078 struct scan_info *info;
1079 #define MAX_REPORT_FREQS 50
1080 int freqs[MAX_REPORT_FREQS];
1081 int num_freqs = 0;
1082
1083 if (!external_scan && drv->scan_for_auth) {
1084 drv->scan_for_auth = 0;
1085 wpa_printf(MSG_DEBUG, "nl80211: Scan results for missing "
1086 "cfg80211 BSS entry");
1087 wpa_driver_nl80211_authenticate_retry(drv);
1088 return;
1089 }
1090
1091 os_memset(&event, 0, sizeof(event));
1092 info = &event.scan_info;
1093 info->aborted = aborted;
1094 info->external_scan = external_scan;
1095 info->nl_scan_event = 1;
1096
1097 if (tb[NL80211_ATTR_SCAN_SSIDS]) {
1098 nla_for_each_nested(nl, tb[NL80211_ATTR_SCAN_SSIDS], rem) {
1099 struct wpa_driver_scan_ssid *s =
1100 &info->ssids[info->num_ssids];
1101 s->ssid = nla_data(nl);
1102 s->ssid_len = nla_len(nl);
1103 wpa_printf(MSG_DEBUG, "nl80211: Scan probed for SSID '%s'",
1104 wpa_ssid_txt(s->ssid, s->ssid_len));
1105 info->num_ssids++;
1106 if (info->num_ssids == WPAS_MAX_SCAN_SSIDS)
1107 break;
1108 }
1109 }
1110 if (tb[NL80211_ATTR_SCAN_FREQUENCIES]) {
1111 char msg[300], *pos, *end;
1112 int res;
1113
1114 pos = msg;
1115 end = pos + sizeof(msg);
1116 *pos = '\0';
1117
1118 nla_for_each_nested(nl, tb[NL80211_ATTR_SCAN_FREQUENCIES], rem)
1119 {
1120 freqs[num_freqs] = nla_get_u32(nl);
1121 res = os_snprintf(pos, end - pos, " %d",
1122 freqs[num_freqs]);
1123 if (!os_snprintf_error(end - pos, res))
1124 pos += res;
1125 num_freqs++;
1126 if (num_freqs == MAX_REPORT_FREQS - 1)
1127 break;
1128 }
1129 info->freqs = freqs;
1130 info->num_freqs = num_freqs;
1131 wpa_printf(MSG_DEBUG, "nl80211: Scan included frequencies:%s",
1132 msg);
1133 }
1134
1135 if (tb[NL80211_ATTR_SCAN_START_TIME_TSF] &&
1136 tb[NL80211_ATTR_SCAN_START_TIME_TSF_BSSID]) {
1137 info->scan_start_tsf =
1138 nla_get_u64(tb[NL80211_ATTR_SCAN_START_TIME_TSF]);
1139 os_memcpy(info->scan_start_tsf_bssid,
1140 nla_data(tb[NL80211_ATTR_SCAN_START_TIME_TSF_BSSID]),
1141 ETH_ALEN);
1142 }
1143
1144 wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS, &event);
1145 }
1146
1147
nl80211_cqm_event(struct wpa_driver_nl80211_data * drv,struct nlattr * tb[])1148 static void nl80211_cqm_event(struct wpa_driver_nl80211_data *drv,
1149 struct nlattr *tb[])
1150 {
1151 static struct nla_policy cqm_policy[NL80211_ATTR_CQM_MAX + 1] = {
1152 [NL80211_ATTR_CQM_RSSI_THOLD] = { .type = NLA_U32 },
1153 [NL80211_ATTR_CQM_RSSI_HYST] = { .type = NLA_U8 },
1154 [NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] = { .type = NLA_U32 },
1155 [NL80211_ATTR_CQM_PKT_LOSS_EVENT] = { .type = NLA_U32 },
1156 [NL80211_ATTR_CQM_TXE_RATE] = { .type = NLA_U32 },
1157 [NL80211_ATTR_CQM_TXE_PKTS] = { .type = NLA_U32 },
1158 [NL80211_ATTR_CQM_TXE_INTVL] = { .type = NLA_U32 },
1159 [NL80211_ATTR_CQM_BEACON_LOSS_EVENT] = { .type = NLA_FLAG },
1160 };
1161 struct nlattr *cqm[NL80211_ATTR_CQM_MAX + 1];
1162 enum nl80211_cqm_rssi_threshold_event event;
1163 union wpa_event_data ed;
1164 struct wpa_signal_info sig;
1165 int res;
1166
1167 if (tb[NL80211_ATTR_CQM] == NULL ||
1168 nla_parse_nested(cqm, NL80211_ATTR_CQM_MAX, tb[NL80211_ATTR_CQM],
1169 cqm_policy)) {
1170 wpa_printf(MSG_DEBUG, "nl80211: Ignore invalid CQM event");
1171 return;
1172 }
1173
1174 os_memset(&ed, 0, sizeof(ed));
1175
1176 if (cqm[NL80211_ATTR_CQM_PKT_LOSS_EVENT]) {
1177 if (!tb[NL80211_ATTR_MAC])
1178 return;
1179 os_memcpy(ed.low_ack.addr, nla_data(tb[NL80211_ATTR_MAC]),
1180 ETH_ALEN);
1181 ed.low_ack.num_packets =
1182 nla_get_u32(cqm[NL80211_ATTR_CQM_PKT_LOSS_EVENT]);
1183 wpa_printf(MSG_DEBUG, "nl80211: Packet loss event for " MACSTR
1184 " (num_packets %u)",
1185 MAC2STR(ed.low_ack.addr), ed.low_ack.num_packets);
1186 wpa_supplicant_event(drv->ctx, EVENT_STATION_LOW_ACK, &ed);
1187 return;
1188 }
1189
1190 if (cqm[NL80211_ATTR_CQM_BEACON_LOSS_EVENT]) {
1191 wpa_printf(MSG_DEBUG, "nl80211: Beacon loss event");
1192 wpa_supplicant_event(drv->ctx, EVENT_BEACON_LOSS, NULL);
1193 return;
1194 }
1195
1196 if (cqm[NL80211_ATTR_CQM_TXE_RATE] &&
1197 cqm[NL80211_ATTR_CQM_TXE_PKTS] &&
1198 cqm[NL80211_ATTR_CQM_TXE_INTVL] &&
1199 cqm[NL80211_ATTR_MAC]) {
1200 wpa_printf(MSG_DEBUG, "nl80211: CQM TXE event for " MACSTR
1201 " (rate: %u pkts: %u interval: %u)",
1202 MAC2STR((u8 *) nla_data(cqm[NL80211_ATTR_MAC])),
1203 nla_get_u32(cqm[NL80211_ATTR_CQM_TXE_RATE]),
1204 nla_get_u32(cqm[NL80211_ATTR_CQM_TXE_PKTS]),
1205 nla_get_u32(cqm[NL80211_ATTR_CQM_TXE_INTVL]));
1206 return;
1207 }
1208
1209 if (cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] == NULL) {
1210 wpa_printf(MSG_DEBUG,
1211 "nl80211: Not a CQM RSSI threshold event");
1212 return;
1213 }
1214 event = nla_get_u32(cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT]);
1215
1216 if (event == NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH) {
1217 wpa_printf(MSG_DEBUG, "nl80211: Connection quality monitor "
1218 "event: RSSI high");
1219 ed.signal_change.above_threshold = 1;
1220 } else if (event == NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW) {
1221 wpa_printf(MSG_DEBUG, "nl80211: Connection quality monitor "
1222 "event: RSSI low");
1223 ed.signal_change.above_threshold = 0;
1224 } else {
1225 wpa_printf(MSG_DEBUG,
1226 "nl80211: Unknown CQM RSSI threshold event: %d",
1227 event);
1228 return;
1229 }
1230
1231 res = nl80211_get_link_signal(drv, &sig);
1232 if (res == 0) {
1233 ed.signal_change.current_signal = sig.current_signal;
1234 ed.signal_change.current_txrate = sig.current_txrate;
1235 wpa_printf(MSG_DEBUG, "nl80211: Signal: %d dBm txrate: %d",
1236 sig.current_signal, sig.current_txrate);
1237 }
1238
1239 res = nl80211_get_link_noise(drv, &sig);
1240 if (res == 0) {
1241 ed.signal_change.current_noise = sig.current_noise;
1242 wpa_printf(MSG_DEBUG, "nl80211: Noise: %d dBm",
1243 sig.current_noise);
1244 }
1245
1246 wpa_supplicant_event(drv->ctx, EVENT_SIGNAL_CHANGE, &ed);
1247 }
1248
1249
nl80211_new_peer_candidate(struct wpa_driver_nl80211_data * drv,struct nlattr ** tb)1250 static void nl80211_new_peer_candidate(struct wpa_driver_nl80211_data *drv,
1251 struct nlattr **tb)
1252 {
1253 const u8 *addr;
1254 union wpa_event_data data;
1255
1256 if (drv->nlmode != NL80211_IFTYPE_MESH_POINT ||
1257 !tb[NL80211_ATTR_MAC] || !tb[NL80211_ATTR_IE])
1258 return;
1259
1260 addr = nla_data(tb[NL80211_ATTR_MAC]);
1261 wpa_printf(MSG_DEBUG, "nl80211: New peer candidate " MACSTR,
1262 MAC2STR(addr));
1263
1264 os_memset(&data, 0, sizeof(data));
1265 data.mesh_peer.peer = addr;
1266 data.mesh_peer.ies = nla_data(tb[NL80211_ATTR_IE]);
1267 data.mesh_peer.ie_len = nla_len(tb[NL80211_ATTR_IE]);
1268 wpa_supplicant_event(drv->ctx, EVENT_NEW_PEER_CANDIDATE, &data);
1269 }
1270
1271
nl80211_new_station_event(struct wpa_driver_nl80211_data * drv,struct i802_bss * bss,struct nlattr ** tb)1272 static void nl80211_new_station_event(struct wpa_driver_nl80211_data *drv,
1273 struct i802_bss *bss,
1274 struct nlattr **tb)
1275 {
1276 u8 *addr;
1277 union wpa_event_data data;
1278
1279 if (tb[NL80211_ATTR_MAC] == NULL)
1280 return;
1281 addr = nla_data(tb[NL80211_ATTR_MAC]);
1282 wpa_printf(MSG_DEBUG, "nl80211: New station " MACSTR, MAC2STR(addr));
1283
1284 if (is_ap_interface(drv->nlmode) && drv->device_ap_sme) {
1285 u8 *ies = NULL;
1286 size_t ies_len = 0;
1287 if (tb[NL80211_ATTR_IE]) {
1288 ies = nla_data(tb[NL80211_ATTR_IE]);
1289 ies_len = nla_len(tb[NL80211_ATTR_IE]);
1290 }
1291 wpa_hexdump(MSG_DEBUG, "nl80211: Assoc Req IEs", ies, ies_len);
1292 drv_event_assoc(bss->ctx, addr, ies, ies_len, 0);
1293 return;
1294 }
1295
1296 if (drv->nlmode != NL80211_IFTYPE_ADHOC)
1297 return;
1298
1299 os_memset(&data, 0, sizeof(data));
1300 os_memcpy(data.ibss_rsn_start.peer, addr, ETH_ALEN);
1301 wpa_supplicant_event(bss->ctx, EVENT_IBSS_RSN_START, &data);
1302 }
1303
1304
nl80211_del_station_event(struct wpa_driver_nl80211_data * drv,struct i802_bss * bss,struct nlattr ** tb)1305 static void nl80211_del_station_event(struct wpa_driver_nl80211_data *drv,
1306 struct i802_bss *bss,
1307 struct nlattr **tb)
1308 {
1309 u8 *addr;
1310 union wpa_event_data data;
1311
1312 if (tb[NL80211_ATTR_MAC] == NULL)
1313 return;
1314 addr = nla_data(tb[NL80211_ATTR_MAC]);
1315 wpa_printf(MSG_DEBUG, "nl80211: Delete station " MACSTR,
1316 MAC2STR(addr));
1317
1318 if (is_ap_interface(drv->nlmode) && drv->device_ap_sme) {
1319 drv_event_disassoc(bss->ctx, addr);
1320 return;
1321 }
1322
1323 if (drv->nlmode != NL80211_IFTYPE_ADHOC)
1324 return;
1325
1326 os_memset(&data, 0, sizeof(data));
1327 os_memcpy(data.ibss_peer_lost.peer, addr, ETH_ALEN);
1328 wpa_supplicant_event(bss->ctx, EVENT_IBSS_PEER_LOST, &data);
1329 }
1330
1331
nl80211_rekey_offload_event(struct wpa_driver_nl80211_data * drv,struct nlattr ** tb)1332 static void nl80211_rekey_offload_event(struct wpa_driver_nl80211_data *drv,
1333 struct nlattr **tb)
1334 {
1335 struct nlattr *rekey_info[NUM_NL80211_REKEY_DATA];
1336 static struct nla_policy rekey_policy[NUM_NL80211_REKEY_DATA] = {
1337 [NL80211_REKEY_DATA_KEK] = {
1338 .minlen = NL80211_KEK_LEN,
1339 .maxlen = NL80211_KEK_LEN,
1340 },
1341 [NL80211_REKEY_DATA_KCK] = {
1342 .minlen = NL80211_KCK_LEN,
1343 .maxlen = NL80211_KCK_LEN,
1344 },
1345 [NL80211_REKEY_DATA_REPLAY_CTR] = {
1346 .minlen = NL80211_REPLAY_CTR_LEN,
1347 .maxlen = NL80211_REPLAY_CTR_LEN,
1348 },
1349 };
1350 union wpa_event_data data;
1351
1352 if (!tb[NL80211_ATTR_MAC] ||
1353 !tb[NL80211_ATTR_REKEY_DATA] ||
1354 nla_parse_nested(rekey_info, MAX_NL80211_REKEY_DATA,
1355 tb[NL80211_ATTR_REKEY_DATA], rekey_policy) ||
1356 !rekey_info[NL80211_REKEY_DATA_REPLAY_CTR])
1357 return;
1358
1359 os_memset(&data, 0, sizeof(data));
1360 data.driver_gtk_rekey.bssid = nla_data(tb[NL80211_ATTR_MAC]);
1361 wpa_printf(MSG_DEBUG, "nl80211: Rekey offload event for BSSID " MACSTR,
1362 MAC2STR(data.driver_gtk_rekey.bssid));
1363 data.driver_gtk_rekey.replay_ctr =
1364 nla_data(rekey_info[NL80211_REKEY_DATA_REPLAY_CTR]);
1365 wpa_hexdump(MSG_DEBUG, "nl80211: Rekey offload - Replay Counter",
1366 data.driver_gtk_rekey.replay_ctr, NL80211_REPLAY_CTR_LEN);
1367 wpa_supplicant_event(drv->ctx, EVENT_DRIVER_GTK_REKEY, &data);
1368 }
1369
1370
nl80211_pmksa_candidate_event(struct wpa_driver_nl80211_data * drv,struct nlattr ** tb)1371 static void nl80211_pmksa_candidate_event(struct wpa_driver_nl80211_data *drv,
1372 struct nlattr **tb)
1373 {
1374 struct nlattr *cand[NUM_NL80211_PMKSA_CANDIDATE];
1375 static struct nla_policy cand_policy[NUM_NL80211_PMKSA_CANDIDATE] = {
1376 [NL80211_PMKSA_CANDIDATE_INDEX] = { .type = NLA_U32 },
1377 [NL80211_PMKSA_CANDIDATE_BSSID] = {
1378 .minlen = ETH_ALEN,
1379 .maxlen = ETH_ALEN,
1380 },
1381 [NL80211_PMKSA_CANDIDATE_PREAUTH] = { .type = NLA_FLAG },
1382 };
1383 union wpa_event_data data;
1384
1385 wpa_printf(MSG_DEBUG, "nl80211: PMKSA candidate event");
1386
1387 if (!tb[NL80211_ATTR_PMKSA_CANDIDATE] ||
1388 nla_parse_nested(cand, MAX_NL80211_PMKSA_CANDIDATE,
1389 tb[NL80211_ATTR_PMKSA_CANDIDATE], cand_policy) ||
1390 !cand[NL80211_PMKSA_CANDIDATE_INDEX] ||
1391 !cand[NL80211_PMKSA_CANDIDATE_BSSID])
1392 return;
1393
1394 os_memset(&data, 0, sizeof(data));
1395 os_memcpy(data.pmkid_candidate.bssid,
1396 nla_data(cand[NL80211_PMKSA_CANDIDATE_BSSID]), ETH_ALEN);
1397 data.pmkid_candidate.index =
1398 nla_get_u32(cand[NL80211_PMKSA_CANDIDATE_INDEX]);
1399 data.pmkid_candidate.preauth =
1400 cand[NL80211_PMKSA_CANDIDATE_PREAUTH] != NULL;
1401 wpa_supplicant_event(drv->ctx, EVENT_PMKID_CANDIDATE, &data);
1402 }
1403
1404
nl80211_client_probe_event(struct wpa_driver_nl80211_data * drv,struct nlattr ** tb)1405 static void nl80211_client_probe_event(struct wpa_driver_nl80211_data *drv,
1406 struct nlattr **tb)
1407 {
1408 union wpa_event_data data;
1409
1410 wpa_printf(MSG_DEBUG, "nl80211: Probe client event");
1411
1412 if (!tb[NL80211_ATTR_MAC] || !tb[NL80211_ATTR_ACK])
1413 return;
1414
1415 os_memset(&data, 0, sizeof(data));
1416 os_memcpy(data.client_poll.addr,
1417 nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
1418
1419 wpa_supplicant_event(drv->ctx, EVENT_DRIVER_CLIENT_POLL_OK, &data);
1420 }
1421
1422
nl80211_tdls_oper_event(struct wpa_driver_nl80211_data * drv,struct nlattr ** tb)1423 static void nl80211_tdls_oper_event(struct wpa_driver_nl80211_data *drv,
1424 struct nlattr **tb)
1425 {
1426 union wpa_event_data data;
1427
1428 wpa_printf(MSG_DEBUG, "nl80211: TDLS operation event");
1429
1430 if (!tb[NL80211_ATTR_MAC] || !tb[NL80211_ATTR_TDLS_OPERATION])
1431 return;
1432
1433 os_memset(&data, 0, sizeof(data));
1434 os_memcpy(data.tdls.peer, nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
1435 switch (nla_get_u8(tb[NL80211_ATTR_TDLS_OPERATION])) {
1436 case NL80211_TDLS_SETUP:
1437 wpa_printf(MSG_DEBUG, "nl80211: TDLS setup request for peer "
1438 MACSTR, MAC2STR(data.tdls.peer));
1439 data.tdls.oper = TDLS_REQUEST_SETUP;
1440 break;
1441 case NL80211_TDLS_TEARDOWN:
1442 wpa_printf(MSG_DEBUG, "nl80211: TDLS teardown request for peer "
1443 MACSTR, MAC2STR(data.tdls.peer));
1444 data.tdls.oper = TDLS_REQUEST_TEARDOWN;
1445 break;
1446 case NL80211_TDLS_DISCOVERY_REQ:
1447 wpa_printf(MSG_DEBUG,
1448 "nl80211: TDLS discovery request for peer " MACSTR,
1449 MAC2STR(data.tdls.peer));
1450 data.tdls.oper = TDLS_REQUEST_DISCOVER;
1451 break;
1452 default:
1453 wpa_printf(MSG_DEBUG, "nl80211: Unsupported TDLS operatione "
1454 "event");
1455 return;
1456 }
1457 if (tb[NL80211_ATTR_REASON_CODE]) {
1458 data.tdls.reason_code =
1459 nla_get_u16(tb[NL80211_ATTR_REASON_CODE]);
1460 }
1461
1462 wpa_supplicant_event(drv->ctx, EVENT_TDLS, &data);
1463 }
1464
1465
nl80211_stop_ap(struct wpa_driver_nl80211_data * drv,struct nlattr ** tb)1466 static void nl80211_stop_ap(struct wpa_driver_nl80211_data *drv,
1467 struct nlattr **tb)
1468 {
1469 wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_UNAVAILABLE, NULL);
1470 }
1471
1472
nl80211_connect_failed_event(struct wpa_driver_nl80211_data * drv,struct nlattr ** tb)1473 static void nl80211_connect_failed_event(struct wpa_driver_nl80211_data *drv,
1474 struct nlattr **tb)
1475 {
1476 union wpa_event_data data;
1477 u32 reason;
1478
1479 wpa_printf(MSG_DEBUG, "nl80211: Connect failed event");
1480
1481 if (!tb[NL80211_ATTR_MAC] || !tb[NL80211_ATTR_CONN_FAILED_REASON])
1482 return;
1483
1484 os_memset(&data, 0, sizeof(data));
1485 os_memcpy(data.connect_failed_reason.addr,
1486 nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
1487
1488 reason = nla_get_u32(tb[NL80211_ATTR_CONN_FAILED_REASON]);
1489 switch (reason) {
1490 case NL80211_CONN_FAIL_MAX_CLIENTS:
1491 wpa_printf(MSG_DEBUG, "nl80211: Max client reached");
1492 data.connect_failed_reason.code = MAX_CLIENT_REACHED;
1493 break;
1494 case NL80211_CONN_FAIL_BLOCKED_CLIENT:
1495 wpa_printf(MSG_DEBUG, "nl80211: Blocked client " MACSTR
1496 " tried to connect",
1497 MAC2STR(data.connect_failed_reason.addr));
1498 data.connect_failed_reason.code = BLOCKED_CLIENT;
1499 break;
1500 default:
1501 wpa_printf(MSG_DEBUG, "nl8021l: Unknown connect failed reason "
1502 "%u", reason);
1503 return;
1504 }
1505
1506 wpa_supplicant_event(drv->ctx, EVENT_CONNECT_FAILED_REASON, &data);
1507 }
1508
1509
nl80211_radar_event(struct wpa_driver_nl80211_data * drv,struct nlattr ** tb)1510 static void nl80211_radar_event(struct wpa_driver_nl80211_data *drv,
1511 struct nlattr **tb)
1512 {
1513 union wpa_event_data data;
1514 enum nl80211_radar_event event_type;
1515
1516 if (!tb[NL80211_ATTR_WIPHY_FREQ] || !tb[NL80211_ATTR_RADAR_EVENT])
1517 return;
1518
1519 os_memset(&data, 0, sizeof(data));
1520 data.dfs_event.freq = nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]);
1521 event_type = nla_get_u32(tb[NL80211_ATTR_RADAR_EVENT]);
1522
1523 /* Check HT params */
1524 if (tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
1525 data.dfs_event.ht_enabled = 1;
1526 data.dfs_event.chan_offset = 0;
1527
1528 switch (nla_get_u32(tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE])) {
1529 case NL80211_CHAN_NO_HT:
1530 data.dfs_event.ht_enabled = 0;
1531 break;
1532 case NL80211_CHAN_HT20:
1533 break;
1534 case NL80211_CHAN_HT40PLUS:
1535 data.dfs_event.chan_offset = 1;
1536 break;
1537 case NL80211_CHAN_HT40MINUS:
1538 data.dfs_event.chan_offset = -1;
1539 break;
1540 }
1541 }
1542
1543 /* Get VHT params */
1544 if (tb[NL80211_ATTR_CHANNEL_WIDTH])
1545 data.dfs_event.chan_width =
1546 convert2width(nla_get_u32(
1547 tb[NL80211_ATTR_CHANNEL_WIDTH]));
1548 if (tb[NL80211_ATTR_CENTER_FREQ1])
1549 data.dfs_event.cf1 = nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ1]);
1550 if (tb[NL80211_ATTR_CENTER_FREQ2])
1551 data.dfs_event.cf2 = nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ2]);
1552
1553 wpa_printf(MSG_DEBUG, "nl80211: DFS event on freq %d MHz, ht: %d, offset: %d, width: %d, cf1: %dMHz, cf2: %dMHz",
1554 data.dfs_event.freq, data.dfs_event.ht_enabled,
1555 data.dfs_event.chan_offset, data.dfs_event.chan_width,
1556 data.dfs_event.cf1, data.dfs_event.cf2);
1557
1558 switch (event_type) {
1559 case NL80211_RADAR_DETECTED:
1560 wpa_supplicant_event(drv->ctx, EVENT_DFS_RADAR_DETECTED, &data);
1561 break;
1562 case NL80211_RADAR_CAC_FINISHED:
1563 wpa_supplicant_event(drv->ctx, EVENT_DFS_CAC_FINISHED, &data);
1564 break;
1565 case NL80211_RADAR_CAC_ABORTED:
1566 wpa_supplicant_event(drv->ctx, EVENT_DFS_CAC_ABORTED, &data);
1567 break;
1568 case NL80211_RADAR_NOP_FINISHED:
1569 wpa_supplicant_event(drv->ctx, EVENT_DFS_NOP_FINISHED, &data);
1570 break;
1571 default:
1572 wpa_printf(MSG_DEBUG, "nl80211: Unknown radar event %d "
1573 "received", event_type);
1574 break;
1575 }
1576 }
1577
1578
nl80211_spurious_frame(struct i802_bss * bss,struct nlattr ** tb,int wds)1579 static void nl80211_spurious_frame(struct i802_bss *bss, struct nlattr **tb,
1580 int wds)
1581 {
1582 struct wpa_driver_nl80211_data *drv = bss->drv;
1583 union wpa_event_data event;
1584
1585 if (!tb[NL80211_ATTR_MAC])
1586 return;
1587
1588 os_memset(&event, 0, sizeof(event));
1589 event.rx_from_unknown.bssid = bss->addr;
1590 event.rx_from_unknown.addr = nla_data(tb[NL80211_ATTR_MAC]);
1591 event.rx_from_unknown.wds = wds;
1592
1593 wpa_supplicant_event(drv->ctx, EVENT_RX_FROM_UNKNOWN, &event);
1594 }
1595
1596
1597 #ifdef CONFIG_DRIVER_NL80211_QCA
1598
qca_nl80211_avoid_freq(struct wpa_driver_nl80211_data * drv,const u8 * data,size_t len)1599 static void qca_nl80211_avoid_freq(struct wpa_driver_nl80211_data *drv,
1600 const u8 *data, size_t len)
1601 {
1602 u32 i, count;
1603 union wpa_event_data event;
1604 struct wpa_freq_range *range = NULL;
1605 const struct qca_avoid_freq_list *freq_range;
1606
1607 freq_range = (const struct qca_avoid_freq_list *) data;
1608 if (len < sizeof(freq_range->count))
1609 return;
1610
1611 count = freq_range->count;
1612 if (len < sizeof(freq_range->count) +
1613 count * sizeof(struct qca_avoid_freq_range)) {
1614 wpa_printf(MSG_DEBUG, "nl80211: Ignored too short avoid frequency list (len=%u)",
1615 (unsigned int) len);
1616 return;
1617 }
1618
1619 if (count > 0) {
1620 range = os_calloc(count, sizeof(struct wpa_freq_range));
1621 if (range == NULL)
1622 return;
1623 }
1624
1625 os_memset(&event, 0, sizeof(event));
1626 for (i = 0; i < count; i++) {
1627 unsigned int idx = event.freq_range.num;
1628 range[idx].min = freq_range->range[i].start_freq;
1629 range[idx].max = freq_range->range[i].end_freq;
1630 wpa_printf(MSG_DEBUG, "nl80211: Avoid frequency range: %u-%u",
1631 range[idx].min, range[idx].max);
1632 if (range[idx].min > range[idx].max) {
1633 wpa_printf(MSG_DEBUG, "nl80211: Ignore invalid frequency range");
1634 continue;
1635 }
1636 event.freq_range.num++;
1637 }
1638 event.freq_range.range = range;
1639
1640 wpa_supplicant_event(drv->ctx, EVENT_AVOID_FREQUENCIES, &event);
1641
1642 os_free(range);
1643 }
1644
1645
get_qca_hw_mode(u8 hw_mode)1646 static enum hostapd_hw_mode get_qca_hw_mode(u8 hw_mode)
1647 {
1648 switch (hw_mode) {
1649 case QCA_ACS_MODE_IEEE80211B:
1650 return HOSTAPD_MODE_IEEE80211B;
1651 case QCA_ACS_MODE_IEEE80211G:
1652 return HOSTAPD_MODE_IEEE80211G;
1653 case QCA_ACS_MODE_IEEE80211A:
1654 return HOSTAPD_MODE_IEEE80211A;
1655 case QCA_ACS_MODE_IEEE80211AD:
1656 return HOSTAPD_MODE_IEEE80211AD;
1657 case QCA_ACS_MODE_IEEE80211ANY:
1658 return HOSTAPD_MODE_IEEE80211ANY;
1659 default:
1660 return NUM_HOSTAPD_MODES;
1661 }
1662 }
1663
1664
qca_nl80211_acs_select_ch(struct wpa_driver_nl80211_data * drv,const u8 * data,size_t len)1665 static void qca_nl80211_acs_select_ch(struct wpa_driver_nl80211_data *drv,
1666 const u8 *data, size_t len)
1667 {
1668 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_ACS_MAX + 1];
1669 union wpa_event_data event;
1670
1671 wpa_printf(MSG_DEBUG,
1672 "nl80211: ACS channel selection vendor event received");
1673
1674 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_ACS_MAX,
1675 (struct nlattr *) data, len, NULL) ||
1676 !tb[QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL] ||
1677 !tb[QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL])
1678 return;
1679
1680 os_memset(&event, 0, sizeof(event));
1681 event.acs_selected_channels.pri_channel =
1682 nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL]);
1683 event.acs_selected_channels.sec_channel =
1684 nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL]);
1685 if (tb[QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL])
1686 event.acs_selected_channels.vht_seg0_center_ch =
1687 nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL]);
1688 if (tb[QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL])
1689 event.acs_selected_channels.vht_seg1_center_ch =
1690 nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL]);
1691 if (tb[QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH])
1692 event.acs_selected_channels.ch_width =
1693 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH]);
1694 if (tb[QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE]) {
1695 u8 hw_mode = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE]);
1696
1697 event.acs_selected_channels.hw_mode = get_qca_hw_mode(hw_mode);
1698 if (event.acs_selected_channels.hw_mode == NUM_HOSTAPD_MODES ||
1699 event.acs_selected_channels.hw_mode ==
1700 HOSTAPD_MODE_IEEE80211ANY) {
1701 wpa_printf(MSG_DEBUG,
1702 "nl80211: Invalid hw_mode %d in ACS selection event",
1703 hw_mode);
1704 return;
1705 }
1706 }
1707
1708 wpa_printf(MSG_INFO,
1709 "nl80211: ACS Results: PCH: %d SCH: %d BW: %d VHT0: %d VHT1: %d HW_MODE: %d",
1710 event.acs_selected_channels.pri_channel,
1711 event.acs_selected_channels.sec_channel,
1712 event.acs_selected_channels.ch_width,
1713 event.acs_selected_channels.vht_seg0_center_ch,
1714 event.acs_selected_channels.vht_seg1_center_ch,
1715 event.acs_selected_channels.hw_mode);
1716
1717 /* Ignore ACS channel list check for backwards compatibility */
1718
1719 wpa_supplicant_event(drv->ctx, EVENT_ACS_CHANNEL_SELECTED, &event);
1720 }
1721
1722
qca_nl80211_key_mgmt_auth(struct wpa_driver_nl80211_data * drv,const u8 * data,size_t len)1723 static void qca_nl80211_key_mgmt_auth(struct wpa_driver_nl80211_data *drv,
1724 const u8 *data, size_t len)
1725 {
1726 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_MAX + 1];
1727 u8 *bssid;
1728
1729 wpa_printf(MSG_DEBUG,
1730 "nl80211: Key management roam+auth vendor event received");
1731
1732 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_MAX,
1733 (struct nlattr *) data, len, NULL) ||
1734 !tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_BSSID] ||
1735 nla_len(tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_BSSID]) != ETH_ALEN ||
1736 !tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_REQ_IE] ||
1737 !tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_RESP_IE] ||
1738 !tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_AUTHORIZED])
1739 return;
1740
1741 bssid = nla_data(tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_BSSID]);
1742 wpa_printf(MSG_DEBUG, " * roam BSSID " MACSTR, MAC2STR(bssid));
1743
1744 mlme_event_connect(drv, NL80211_CMD_ROAM, NULL,
1745 tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_BSSID],
1746 tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_REQ_IE],
1747 tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_RESP_IE],
1748 NULL, NULL,
1749 tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_AUTHORIZED],
1750 tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_KEY_REPLAY_CTR],
1751 tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KCK],
1752 tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KEK],
1753 tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_SUBNET_STATUS]);
1754 }
1755
1756
qca_nl80211_dfs_offload_radar_event(struct wpa_driver_nl80211_data * drv,u32 subcmd,u8 * msg,int length)1757 static void qca_nl80211_dfs_offload_radar_event(
1758 struct wpa_driver_nl80211_data *drv, u32 subcmd, u8 *msg, int length)
1759 {
1760 union wpa_event_data data;
1761 struct nlattr *tb[NL80211_ATTR_MAX + 1];
1762
1763 wpa_printf(MSG_DEBUG,
1764 "nl80211: DFS offload radar vendor event received");
1765
1766 if (nla_parse(tb, NL80211_ATTR_MAX,
1767 (struct nlattr *) msg, length, NULL))
1768 return;
1769
1770 if (!tb[NL80211_ATTR_WIPHY_FREQ]) {
1771 wpa_printf(MSG_INFO,
1772 "nl80211: Error parsing WIPHY_FREQ in FS offload radar vendor event");
1773 return;
1774 }
1775
1776 os_memset(&data, 0, sizeof(data));
1777 data.dfs_event.freq = nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]);
1778
1779 wpa_printf(MSG_DEBUG, "nl80211: DFS event on freq %d MHz",
1780 data.dfs_event.freq);
1781
1782 /* Check HT params */
1783 if (tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
1784 data.dfs_event.ht_enabled = 1;
1785 data.dfs_event.chan_offset = 0;
1786
1787 switch (nla_get_u32(tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE])) {
1788 case NL80211_CHAN_NO_HT:
1789 data.dfs_event.ht_enabled = 0;
1790 break;
1791 case NL80211_CHAN_HT20:
1792 break;
1793 case NL80211_CHAN_HT40PLUS:
1794 data.dfs_event.chan_offset = 1;
1795 break;
1796 case NL80211_CHAN_HT40MINUS:
1797 data.dfs_event.chan_offset = -1;
1798 break;
1799 }
1800 }
1801
1802 /* Get VHT params */
1803 if (tb[NL80211_ATTR_CHANNEL_WIDTH])
1804 data.dfs_event.chan_width =
1805 convert2width(nla_get_u32(
1806 tb[NL80211_ATTR_CHANNEL_WIDTH]));
1807 if (tb[NL80211_ATTR_CENTER_FREQ1])
1808 data.dfs_event.cf1 = nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ1]);
1809 if (tb[NL80211_ATTR_CENTER_FREQ2])
1810 data.dfs_event.cf2 = nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ2]);
1811
1812 wpa_printf(MSG_DEBUG, "nl80211: DFS event on freq %d MHz, ht: %d, "
1813 "offset: %d, width: %d, cf1: %dMHz, cf2: %dMHz",
1814 data.dfs_event.freq, data.dfs_event.ht_enabled,
1815 data.dfs_event.chan_offset, data.dfs_event.chan_width,
1816 data.dfs_event.cf1, data.dfs_event.cf2);
1817
1818 switch (subcmd) {
1819 case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_RADAR_DETECTED:
1820 wpa_supplicant_event(drv->ctx, EVENT_DFS_RADAR_DETECTED, &data);
1821 break;
1822 case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_STARTED:
1823 wpa_supplicant_event(drv->ctx, EVENT_DFS_CAC_STARTED, &data);
1824 break;
1825 case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_FINISHED:
1826 wpa_supplicant_event(drv->ctx, EVENT_DFS_CAC_FINISHED, &data);
1827 break;
1828 case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_ABORTED:
1829 wpa_supplicant_event(drv->ctx, EVENT_DFS_CAC_ABORTED, &data);
1830 break;
1831 case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_NOP_FINISHED:
1832 wpa_supplicant_event(drv->ctx, EVENT_DFS_NOP_FINISHED, &data);
1833 break;
1834 default:
1835 wpa_printf(MSG_DEBUG,
1836 "nl80211: Unknown DFS offload radar event %d received",
1837 subcmd);
1838 break;
1839 }
1840 }
1841
1842
qca_nl80211_scan_trigger_event(struct wpa_driver_nl80211_data * drv,u8 * data,size_t len)1843 static void qca_nl80211_scan_trigger_event(struct wpa_driver_nl80211_data *drv,
1844 u8 *data, size_t len)
1845 {
1846 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAX + 1];
1847 u64 cookie = 0;
1848 union wpa_event_data event;
1849 struct scan_info *info;
1850
1851 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SCAN_MAX,
1852 (struct nlattr *) data, len, NULL) ||
1853 !tb[QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE])
1854 return;
1855
1856 cookie = nla_get_u64(tb[QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE]);
1857 if (cookie != drv->vendor_scan_cookie) {
1858 /* External scan trigger event, ignore */
1859 return;
1860 }
1861
1862 /* Cookie match, own scan */
1863 os_memset(&event, 0, sizeof(event));
1864 info = &event.scan_info;
1865 info->external_scan = 0;
1866 info->nl_scan_event = 0;
1867
1868 drv->scan_state = SCAN_STARTED;
1869 wpa_supplicant_event(drv->ctx, EVENT_SCAN_STARTED, &event);
1870 }
1871
1872
send_vendor_scan_event(struct wpa_driver_nl80211_data * drv,int aborted,struct nlattr * tb[],int external_scan)1873 static void send_vendor_scan_event(struct wpa_driver_nl80211_data *drv,
1874 int aborted, struct nlattr *tb[],
1875 int external_scan)
1876 {
1877 union wpa_event_data event;
1878 struct nlattr *nl;
1879 int rem;
1880 struct scan_info *info;
1881 int freqs[MAX_REPORT_FREQS];
1882 int num_freqs = 0;
1883
1884 os_memset(&event, 0, sizeof(event));
1885 info = &event.scan_info;
1886 info->aborted = aborted;
1887 info->external_scan = external_scan;
1888
1889 if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS]) {
1890 nla_for_each_nested(nl,
1891 tb[QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS], rem) {
1892 struct wpa_driver_scan_ssid *s =
1893 &info->ssids[info->num_ssids];
1894 s->ssid = nla_data(nl);
1895 s->ssid_len = nla_len(nl);
1896 wpa_printf(MSG_DEBUG,
1897 "nl80211: Scan probed for SSID '%s'",
1898 wpa_ssid_txt(s->ssid, s->ssid_len));
1899 info->num_ssids++;
1900 if (info->num_ssids == WPAS_MAX_SCAN_SSIDS)
1901 break;
1902 }
1903 }
1904
1905 if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES]) {
1906 char msg[300], *pos, *end;
1907 int res;
1908
1909 pos = msg;
1910 end = pos + sizeof(msg);
1911 *pos = '\0';
1912
1913 nla_for_each_nested(nl,
1914 tb[QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES],
1915 rem) {
1916 freqs[num_freqs] = nla_get_u32(nl);
1917 res = os_snprintf(pos, end - pos, " %d",
1918 freqs[num_freqs]);
1919 if (!os_snprintf_error(end - pos, res))
1920 pos += res;
1921 num_freqs++;
1922 if (num_freqs == MAX_REPORT_FREQS - 1)
1923 break;
1924 }
1925
1926 info->freqs = freqs;
1927 info->num_freqs = num_freqs;
1928 wpa_printf(MSG_DEBUG, "nl80211: Scan included frequencies:%s",
1929 msg);
1930 }
1931 wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS, &event);
1932 }
1933
1934
qca_nl80211_scan_done_event(struct wpa_driver_nl80211_data * drv,u8 * data,size_t len)1935 static void qca_nl80211_scan_done_event(struct wpa_driver_nl80211_data *drv,
1936 u8 *data, size_t len)
1937 {
1938 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAX + 1];
1939 u64 cookie = 0;
1940 enum scan_status status;
1941 int external_scan;
1942
1943 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SCAN_MAX,
1944 (struct nlattr *) data, len, NULL) ||
1945 !tb[QCA_WLAN_VENDOR_ATTR_SCAN_STATUS] ||
1946 !tb[QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE])
1947 return;
1948
1949 status = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_SCAN_STATUS]);
1950 if (status >= VENDOR_SCAN_STATUS_MAX)
1951 return; /* invalid status */
1952
1953 cookie = nla_get_u64(tb[QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE]);
1954 if (cookie != drv->vendor_scan_cookie) {
1955 /* Event from an external scan, get scan results */
1956 external_scan = 1;
1957 } else {
1958 external_scan = 0;
1959 if (status == VENDOR_SCAN_STATUS_NEW_RESULTS)
1960 drv->scan_state = SCAN_COMPLETED;
1961 else
1962 drv->scan_state = SCAN_ABORTED;
1963
1964 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv,
1965 drv->ctx);
1966 drv->vendor_scan_cookie = 0;
1967 drv->last_scan_cmd = 0;
1968 }
1969
1970 send_vendor_scan_event(drv, (status == VENDOR_SCAN_STATUS_ABORTED), tb,
1971 external_scan);
1972 }
1973
1974
qca_nl80211_p2p_lo_stop_event(struct wpa_driver_nl80211_data * drv,u8 * data,size_t len)1975 static void qca_nl80211_p2p_lo_stop_event(struct wpa_driver_nl80211_data *drv,
1976 u8 *data, size_t len)
1977 {
1978 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_MAX + 1];
1979 union wpa_event_data event;
1980
1981 wpa_printf(MSG_DEBUG,
1982 "nl80211: P2P listen offload stop vendor event received");
1983
1984 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_MAX,
1985 (struct nlattr *) data, len, NULL) ||
1986 !tb[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_STOP_REASON])
1987 return;
1988
1989 os_memset(&event, 0, sizeof(event));
1990 event.p2p_lo_stop.reason_code =
1991 nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_STOP_REASON]);
1992
1993 wpa_printf(MSG_DEBUG,
1994 "nl80211: P2P Listen offload stop reason: %d",
1995 event.p2p_lo_stop.reason_code);
1996 wpa_supplicant_event(drv->ctx, EVENT_P2P_LO_STOP, &event);
1997 }
1998
1999 #endif /* CONFIG_DRIVER_NL80211_QCA */
2000
2001
nl80211_vendor_event_qca(struct wpa_driver_nl80211_data * drv,u32 subcmd,u8 * data,size_t len)2002 static void nl80211_vendor_event_qca(struct wpa_driver_nl80211_data *drv,
2003 u32 subcmd, u8 *data, size_t len)
2004 {
2005 switch (subcmd) {
2006 case QCA_NL80211_VENDOR_SUBCMD_TEST:
2007 wpa_hexdump(MSG_DEBUG, "nl80211: QCA test event", data, len);
2008 break;
2009 #ifdef CONFIG_DRIVER_NL80211_QCA
2010 case QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY:
2011 qca_nl80211_avoid_freq(drv, data, len);
2012 break;
2013 case QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH:
2014 qca_nl80211_key_mgmt_auth(drv, data, len);
2015 break;
2016 case QCA_NL80211_VENDOR_SUBCMD_DO_ACS:
2017 qca_nl80211_acs_select_ch(drv, data, len);
2018 break;
2019 case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_STARTED:
2020 case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_FINISHED:
2021 case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_ABORTED:
2022 case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_NOP_FINISHED:
2023 case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_RADAR_DETECTED:
2024 qca_nl80211_dfs_offload_radar_event(drv, subcmd, data, len);
2025 break;
2026 case QCA_NL80211_VENDOR_SUBCMD_TRIGGER_SCAN:
2027 qca_nl80211_scan_trigger_event(drv, data, len);
2028 break;
2029 case QCA_NL80211_VENDOR_SUBCMD_SCAN_DONE:
2030 qca_nl80211_scan_done_event(drv, data, len);
2031 break;
2032 case QCA_NL80211_VENDOR_SUBCMD_P2P_LISTEN_OFFLOAD_STOP:
2033 qca_nl80211_p2p_lo_stop_event(drv, data, len);
2034 break;
2035 #endif /* CONFIG_DRIVER_NL80211_QCA */
2036 default:
2037 wpa_printf(MSG_DEBUG,
2038 "nl80211: Ignore unsupported QCA vendor event %u",
2039 subcmd);
2040 break;
2041 }
2042 }
2043
2044
nl80211_vendor_event(struct wpa_driver_nl80211_data * drv,struct nlattr ** tb)2045 static void nl80211_vendor_event(struct wpa_driver_nl80211_data *drv,
2046 struct nlattr **tb)
2047 {
2048 u32 vendor_id, subcmd, wiphy = 0;
2049 int wiphy_idx;
2050 u8 *data = NULL;
2051 size_t len = 0;
2052
2053 if (!tb[NL80211_ATTR_VENDOR_ID] ||
2054 !tb[NL80211_ATTR_VENDOR_SUBCMD])
2055 return;
2056
2057 vendor_id = nla_get_u32(tb[NL80211_ATTR_VENDOR_ID]);
2058 subcmd = nla_get_u32(tb[NL80211_ATTR_VENDOR_SUBCMD]);
2059
2060 if (tb[NL80211_ATTR_WIPHY])
2061 wiphy = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
2062
2063 wpa_printf(MSG_DEBUG, "nl80211: Vendor event: wiphy=%u vendor_id=0x%x subcmd=%u",
2064 wiphy, vendor_id, subcmd);
2065
2066 if (tb[NL80211_ATTR_VENDOR_DATA]) {
2067 data = nla_data(tb[NL80211_ATTR_VENDOR_DATA]);
2068 len = nla_len(tb[NL80211_ATTR_VENDOR_DATA]);
2069 wpa_hexdump(MSG_MSGDUMP, "nl80211: Vendor data", data, len);
2070 }
2071
2072 wiphy_idx = nl80211_get_wiphy_index(drv->first_bss);
2073 if (wiphy_idx >= 0 && wiphy_idx != (int) wiphy) {
2074 wpa_printf(MSG_DEBUG, "nl80211: Ignore vendor event for foreign wiphy %u (own: %d)",
2075 wiphy, wiphy_idx);
2076 return;
2077 }
2078
2079 switch (vendor_id) {
2080 case OUI_QCA:
2081 nl80211_vendor_event_qca(drv, subcmd, data, len);
2082 break;
2083 default:
2084 wpa_printf(MSG_DEBUG, "nl80211: Ignore unsupported vendor event");
2085 break;
2086 }
2087 }
2088
2089
nl80211_reg_change_event(struct wpa_driver_nl80211_data * drv,struct nlattr * tb[])2090 static void nl80211_reg_change_event(struct wpa_driver_nl80211_data *drv,
2091 struct nlattr *tb[])
2092 {
2093 union wpa_event_data data;
2094 enum nl80211_reg_initiator init;
2095
2096 wpa_printf(MSG_DEBUG, "nl80211: Regulatory domain change");
2097
2098 if (tb[NL80211_ATTR_REG_INITIATOR] == NULL)
2099 return;
2100
2101 os_memset(&data, 0, sizeof(data));
2102 init = nla_get_u8(tb[NL80211_ATTR_REG_INITIATOR]);
2103 wpa_printf(MSG_DEBUG, " * initiator=%d", init);
2104 switch (init) {
2105 case NL80211_REGDOM_SET_BY_CORE:
2106 data.channel_list_changed.initiator = REGDOM_SET_BY_CORE;
2107 break;
2108 case NL80211_REGDOM_SET_BY_USER:
2109 data.channel_list_changed.initiator = REGDOM_SET_BY_USER;
2110 break;
2111 case NL80211_REGDOM_SET_BY_DRIVER:
2112 data.channel_list_changed.initiator = REGDOM_SET_BY_DRIVER;
2113 break;
2114 case NL80211_REGDOM_SET_BY_COUNTRY_IE:
2115 data.channel_list_changed.initiator = REGDOM_SET_BY_COUNTRY_IE;
2116 break;
2117 }
2118
2119 if (tb[NL80211_ATTR_REG_TYPE]) {
2120 enum nl80211_reg_type type;
2121 type = nla_get_u8(tb[NL80211_ATTR_REG_TYPE]);
2122 wpa_printf(MSG_DEBUG, " * type=%d", type);
2123 switch (type) {
2124 case NL80211_REGDOM_TYPE_COUNTRY:
2125 data.channel_list_changed.type = REGDOM_TYPE_COUNTRY;
2126 break;
2127 case NL80211_REGDOM_TYPE_WORLD:
2128 data.channel_list_changed.type = REGDOM_TYPE_WORLD;
2129 break;
2130 case NL80211_REGDOM_TYPE_CUSTOM_WORLD:
2131 data.channel_list_changed.type =
2132 REGDOM_TYPE_CUSTOM_WORLD;
2133 break;
2134 case NL80211_REGDOM_TYPE_INTERSECTION:
2135 data.channel_list_changed.type =
2136 REGDOM_TYPE_INTERSECTION;
2137 break;
2138 }
2139 }
2140
2141 if (tb[NL80211_ATTR_REG_ALPHA2]) {
2142 os_strlcpy(data.channel_list_changed.alpha2,
2143 nla_get_string(tb[NL80211_ATTR_REG_ALPHA2]),
2144 sizeof(data.channel_list_changed.alpha2));
2145 wpa_printf(MSG_DEBUG, " * alpha2=%s",
2146 data.channel_list_changed.alpha2);
2147 }
2148
2149 wpa_supplicant_event(drv->ctx, EVENT_CHANNEL_LIST_CHANGED, &data);
2150 }
2151
2152
do_process_drv_event(struct i802_bss * bss,int cmd,struct nlattr ** tb)2153 static void do_process_drv_event(struct i802_bss *bss, int cmd,
2154 struct nlattr **tb)
2155 {
2156 struct wpa_driver_nl80211_data *drv = bss->drv;
2157 union wpa_event_data data;
2158 int external_scan_event = 0;
2159
2160 wpa_printf(MSG_DEBUG, "nl80211: Drv Event %d (%s) received for %s",
2161 cmd, nl80211_command_to_string(cmd), bss->ifname);
2162
2163 if (cmd == NL80211_CMD_ROAM &&
2164 (drv->capa.flags & WPA_DRIVER_FLAGS_KEY_MGMT_OFFLOAD)) {
2165 /*
2166 * Device will use roam+auth vendor event to indicate
2167 * roaming, so ignore the regular roam event.
2168 */
2169 wpa_printf(MSG_DEBUG,
2170 "nl80211: Ignore roam event (cmd=%d), device will use vendor event roam+auth",
2171 cmd);
2172 return;
2173 }
2174
2175 if (drv->ap_scan_as_station != NL80211_IFTYPE_UNSPECIFIED &&
2176 (cmd == NL80211_CMD_NEW_SCAN_RESULTS ||
2177 cmd == NL80211_CMD_SCAN_ABORTED)) {
2178 wpa_driver_nl80211_set_mode(drv->first_bss,
2179 drv->ap_scan_as_station);
2180 drv->ap_scan_as_station = NL80211_IFTYPE_UNSPECIFIED;
2181 }
2182
2183 switch (cmd) {
2184 case NL80211_CMD_TRIGGER_SCAN:
2185 wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Scan trigger");
2186 drv->scan_state = SCAN_STARTED;
2187 if (drv->scan_for_auth) {
2188 /*
2189 * Cannot indicate EVENT_SCAN_STARTED here since we skip
2190 * EVENT_SCAN_RESULTS in scan_for_auth case and the
2191 * upper layer implementation could get confused about
2192 * scanning state.
2193 */
2194 wpa_printf(MSG_DEBUG, "nl80211: Do not indicate scan-start event due to internal scan_for_auth");
2195 break;
2196 }
2197 wpa_supplicant_event(drv->ctx, EVENT_SCAN_STARTED, NULL);
2198 break;
2199 case NL80211_CMD_START_SCHED_SCAN:
2200 wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Sched scan started");
2201 drv->scan_state = SCHED_SCAN_STARTED;
2202 break;
2203 case NL80211_CMD_SCHED_SCAN_STOPPED:
2204 wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Sched scan stopped");
2205 drv->scan_state = SCHED_SCAN_STOPPED;
2206 wpa_supplicant_event(drv->ctx, EVENT_SCHED_SCAN_STOPPED, NULL);
2207 break;
2208 case NL80211_CMD_NEW_SCAN_RESULTS:
2209 wpa_dbg(drv->ctx, MSG_DEBUG,
2210 "nl80211: New scan results available");
2211 if (drv->last_scan_cmd != NL80211_CMD_VENDOR)
2212 drv->scan_state = SCAN_COMPLETED;
2213 drv->scan_complete_events = 1;
2214 if (drv->last_scan_cmd == NL80211_CMD_TRIGGER_SCAN) {
2215 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout,
2216 drv, drv->ctx);
2217 drv->last_scan_cmd = 0;
2218 } else {
2219 external_scan_event = 1;
2220 }
2221 send_scan_event(drv, 0, tb, external_scan_event);
2222 break;
2223 case NL80211_CMD_SCHED_SCAN_RESULTS:
2224 wpa_dbg(drv->ctx, MSG_DEBUG,
2225 "nl80211: New sched scan results available");
2226 drv->scan_state = SCHED_SCAN_RESULTS;
2227 send_scan_event(drv, 0, tb, 0);
2228 break;
2229 case NL80211_CMD_SCAN_ABORTED:
2230 wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Scan aborted");
2231 if (drv->last_scan_cmd != NL80211_CMD_VENDOR)
2232 drv->scan_state = SCAN_ABORTED;
2233 if (drv->last_scan_cmd == NL80211_CMD_TRIGGER_SCAN) {
2234 /*
2235 * Need to indicate that scan results are available in
2236 * order not to make wpa_supplicant stop its scanning.
2237 */
2238 eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout,
2239 drv, drv->ctx);
2240 drv->last_scan_cmd = 0;
2241 } else {
2242 external_scan_event = 1;
2243 }
2244 send_scan_event(drv, 1, tb, external_scan_event);
2245 break;
2246 case NL80211_CMD_AUTHENTICATE:
2247 case NL80211_CMD_ASSOCIATE:
2248 case NL80211_CMD_DEAUTHENTICATE:
2249 case NL80211_CMD_DISASSOCIATE:
2250 case NL80211_CMD_FRAME_TX_STATUS:
2251 case NL80211_CMD_UNPROT_DEAUTHENTICATE:
2252 case NL80211_CMD_UNPROT_DISASSOCIATE:
2253 mlme_event(bss, cmd, tb[NL80211_ATTR_FRAME],
2254 tb[NL80211_ATTR_MAC], tb[NL80211_ATTR_TIMED_OUT],
2255 tb[NL80211_ATTR_WIPHY_FREQ], tb[NL80211_ATTR_ACK],
2256 tb[NL80211_ATTR_COOKIE],
2257 tb[NL80211_ATTR_RX_SIGNAL_DBM],
2258 tb[NL80211_ATTR_STA_WME]);
2259 break;
2260 case NL80211_CMD_CONNECT:
2261 case NL80211_CMD_ROAM:
2262 mlme_event_connect(drv, cmd,
2263 tb[NL80211_ATTR_STATUS_CODE],
2264 tb[NL80211_ATTR_MAC],
2265 tb[NL80211_ATTR_REQ_IE],
2266 tb[NL80211_ATTR_RESP_IE],
2267 tb[NL80211_ATTR_TIMED_OUT],
2268 tb[NL80211_ATTR_TIMEOUT_REASON],
2269 NULL, NULL, NULL, NULL, NULL);
2270 break;
2271 case NL80211_CMD_CH_SWITCH_NOTIFY:
2272 mlme_event_ch_switch(drv,
2273 tb[NL80211_ATTR_IFINDEX],
2274 tb[NL80211_ATTR_WIPHY_FREQ],
2275 tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE],
2276 tb[NL80211_ATTR_CHANNEL_WIDTH],
2277 tb[NL80211_ATTR_CENTER_FREQ1],
2278 tb[NL80211_ATTR_CENTER_FREQ2]);
2279 break;
2280 case NL80211_CMD_DISCONNECT:
2281 mlme_event_disconnect(drv, tb[NL80211_ATTR_REASON_CODE],
2282 tb[NL80211_ATTR_MAC],
2283 tb[NL80211_ATTR_DISCONNECTED_BY_AP]);
2284 break;
2285 case NL80211_CMD_MICHAEL_MIC_FAILURE:
2286 mlme_event_michael_mic_failure(bss, tb);
2287 break;
2288 case NL80211_CMD_JOIN_IBSS:
2289 mlme_event_join_ibss(drv, tb);
2290 break;
2291 case NL80211_CMD_REMAIN_ON_CHANNEL:
2292 mlme_event_remain_on_channel(drv, 0, tb);
2293 break;
2294 case NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL:
2295 mlme_event_remain_on_channel(drv, 1, tb);
2296 break;
2297 case NL80211_CMD_NOTIFY_CQM:
2298 nl80211_cqm_event(drv, tb);
2299 break;
2300 case NL80211_CMD_REG_CHANGE:
2301 nl80211_reg_change_event(drv, tb);
2302 break;
2303 case NL80211_CMD_REG_BEACON_HINT:
2304 wpa_printf(MSG_DEBUG, "nl80211: Regulatory beacon hint");
2305 os_memset(&data, 0, sizeof(data));
2306 data.channel_list_changed.initiator = REGDOM_BEACON_HINT;
2307 wpa_supplicant_event(drv->ctx, EVENT_CHANNEL_LIST_CHANGED,
2308 &data);
2309 break;
2310 case NL80211_CMD_NEW_STATION:
2311 nl80211_new_station_event(drv, bss, tb);
2312 break;
2313 case NL80211_CMD_DEL_STATION:
2314 nl80211_del_station_event(drv, bss, tb);
2315 break;
2316 case NL80211_CMD_SET_REKEY_OFFLOAD:
2317 nl80211_rekey_offload_event(drv, tb);
2318 break;
2319 case NL80211_CMD_PMKSA_CANDIDATE:
2320 nl80211_pmksa_candidate_event(drv, tb);
2321 break;
2322 case NL80211_CMD_PROBE_CLIENT:
2323 nl80211_client_probe_event(drv, tb);
2324 break;
2325 case NL80211_CMD_TDLS_OPER:
2326 nl80211_tdls_oper_event(drv, tb);
2327 break;
2328 case NL80211_CMD_CONN_FAILED:
2329 nl80211_connect_failed_event(drv, tb);
2330 break;
2331 case NL80211_CMD_FT_EVENT:
2332 mlme_event_ft_event(drv, tb);
2333 break;
2334 case NL80211_CMD_RADAR_DETECT:
2335 nl80211_radar_event(drv, tb);
2336 break;
2337 case NL80211_CMD_STOP_AP:
2338 nl80211_stop_ap(drv, tb);
2339 break;
2340 case NL80211_CMD_VENDOR:
2341 nl80211_vendor_event(drv, tb);
2342 break;
2343 case NL80211_CMD_NEW_PEER_CANDIDATE:
2344 nl80211_new_peer_candidate(drv, tb);
2345 break;
2346 default:
2347 wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Ignored unknown event "
2348 "(cmd=%d)", cmd);
2349 break;
2350 }
2351 }
2352
2353
process_global_event(struct nl_msg * msg,void * arg)2354 int process_global_event(struct nl_msg *msg, void *arg)
2355 {
2356 struct nl80211_global *global = arg;
2357 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
2358 struct nlattr *tb[NL80211_ATTR_MAX + 1];
2359 struct wpa_driver_nl80211_data *drv, *tmp;
2360 int ifidx = -1;
2361 struct i802_bss *bss;
2362 u64 wdev_id = 0;
2363 int wdev_id_set = 0;
2364
2365 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
2366 genlmsg_attrlen(gnlh, 0), NULL);
2367
2368 if (tb[NL80211_ATTR_IFINDEX])
2369 ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
2370 else if (tb[NL80211_ATTR_WDEV]) {
2371 wdev_id = nla_get_u64(tb[NL80211_ATTR_WDEV]);
2372 wdev_id_set = 1;
2373 }
2374
2375 dl_list_for_each_safe(drv, tmp, &global->interfaces,
2376 struct wpa_driver_nl80211_data, list) {
2377 for (bss = drv->first_bss; bss; bss = bss->next) {
2378 if ((ifidx == -1 && !wdev_id_set) ||
2379 ifidx == bss->ifindex ||
2380 (wdev_id_set && bss->wdev_id_set &&
2381 wdev_id == bss->wdev_id)) {
2382 do_process_drv_event(bss, gnlh->cmd, tb);
2383 return NL_SKIP;
2384 }
2385 }
2386 wpa_printf(MSG_DEBUG,
2387 "nl80211: Ignored event (cmd=%d) for foreign interface (ifindex %d wdev 0x%llx)",
2388 gnlh->cmd, ifidx, (long long unsigned int) wdev_id);
2389 }
2390
2391 return NL_SKIP;
2392 }
2393
2394
process_bss_event(struct nl_msg * msg,void * arg)2395 int process_bss_event(struct nl_msg *msg, void *arg)
2396 {
2397 struct i802_bss *bss = arg;
2398 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
2399 struct nlattr *tb[NL80211_ATTR_MAX + 1];
2400
2401 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
2402 genlmsg_attrlen(gnlh, 0), NULL);
2403
2404 wpa_printf(MSG_DEBUG, "nl80211: BSS Event %d (%s) received for %s",
2405 gnlh->cmd, nl80211_command_to_string(gnlh->cmd),
2406 bss->ifname);
2407
2408 switch (gnlh->cmd) {
2409 case NL80211_CMD_FRAME:
2410 case NL80211_CMD_FRAME_TX_STATUS:
2411 mlme_event(bss, gnlh->cmd, tb[NL80211_ATTR_FRAME],
2412 tb[NL80211_ATTR_MAC], tb[NL80211_ATTR_TIMED_OUT],
2413 tb[NL80211_ATTR_WIPHY_FREQ], tb[NL80211_ATTR_ACK],
2414 tb[NL80211_ATTR_COOKIE],
2415 tb[NL80211_ATTR_RX_SIGNAL_DBM],
2416 tb[NL80211_ATTR_STA_WME]);
2417 break;
2418 case NL80211_CMD_UNEXPECTED_FRAME:
2419 nl80211_spurious_frame(bss, tb, 0);
2420 break;
2421 case NL80211_CMD_UNEXPECTED_4ADDR_FRAME:
2422 nl80211_spurious_frame(bss, tb, 1);
2423 break;
2424 default:
2425 wpa_printf(MSG_DEBUG, "nl80211: Ignored unknown event "
2426 "(cmd=%d)", gnlh->cmd);
2427 break;
2428 }
2429
2430 return NL_SKIP;
2431 }
2432