• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/brcm_vendor.h"
19 #include "common/ieee802_11_defs.h"
20 #include "common/ieee802_11_common.h"
21 #include "driver_nl80211.h"
22 
23 static void
24 nl80211_control_port_frame_tx_status(struct wpa_driver_nl80211_data *drv,
25 				     const u8 *frame, size_t len,
26 				     struct nlattr *ack, struct nlattr *cookie);
27 
28 
nl80211_command_to_string(enum nl80211_commands cmd)29 static const char * nl80211_command_to_string(enum nl80211_commands cmd)
30 {
31 #define C2S(x) case x: return #x;
32 	switch (cmd) {
33 	C2S(NL80211_CMD_UNSPEC)
34 	C2S(NL80211_CMD_GET_WIPHY)
35 	C2S(NL80211_CMD_SET_WIPHY)
36 	C2S(NL80211_CMD_NEW_WIPHY)
37 	C2S(NL80211_CMD_DEL_WIPHY)
38 	C2S(NL80211_CMD_GET_INTERFACE)
39 	C2S(NL80211_CMD_SET_INTERFACE)
40 	C2S(NL80211_CMD_NEW_INTERFACE)
41 	C2S(NL80211_CMD_DEL_INTERFACE)
42 	C2S(NL80211_CMD_GET_KEY)
43 	C2S(NL80211_CMD_SET_KEY)
44 	C2S(NL80211_CMD_NEW_KEY)
45 	C2S(NL80211_CMD_DEL_KEY)
46 	C2S(NL80211_CMD_GET_BEACON)
47 	C2S(NL80211_CMD_SET_BEACON)
48 	C2S(NL80211_CMD_START_AP)
49 	C2S(NL80211_CMD_STOP_AP)
50 	C2S(NL80211_CMD_GET_STATION)
51 	C2S(NL80211_CMD_SET_STATION)
52 	C2S(NL80211_CMD_NEW_STATION)
53 	C2S(NL80211_CMD_DEL_STATION)
54 	C2S(NL80211_CMD_GET_MPATH)
55 	C2S(NL80211_CMD_SET_MPATH)
56 	C2S(NL80211_CMD_NEW_MPATH)
57 	C2S(NL80211_CMD_DEL_MPATH)
58 	C2S(NL80211_CMD_SET_BSS)
59 	C2S(NL80211_CMD_SET_REG)
60 	C2S(NL80211_CMD_REQ_SET_REG)
61 	C2S(NL80211_CMD_GET_MESH_CONFIG)
62 	C2S(NL80211_CMD_SET_MESH_CONFIG)
63 	C2S(NL80211_CMD_SET_MGMT_EXTRA_IE)
64 	C2S(NL80211_CMD_GET_REG)
65 	C2S(NL80211_CMD_GET_SCAN)
66 	C2S(NL80211_CMD_TRIGGER_SCAN)
67 	C2S(NL80211_CMD_NEW_SCAN_RESULTS)
68 	C2S(NL80211_CMD_SCAN_ABORTED)
69 	C2S(NL80211_CMD_REG_CHANGE)
70 	C2S(NL80211_CMD_AUTHENTICATE)
71 	C2S(NL80211_CMD_ASSOCIATE)
72 	C2S(NL80211_CMD_DEAUTHENTICATE)
73 	C2S(NL80211_CMD_DISASSOCIATE)
74 	C2S(NL80211_CMD_MICHAEL_MIC_FAILURE)
75 	C2S(NL80211_CMD_REG_BEACON_HINT)
76 	C2S(NL80211_CMD_JOIN_IBSS)
77 	C2S(NL80211_CMD_LEAVE_IBSS)
78 	C2S(NL80211_CMD_TESTMODE)
79 	C2S(NL80211_CMD_CONNECT)
80 	C2S(NL80211_CMD_ROAM)
81 	C2S(NL80211_CMD_DISCONNECT)
82 	C2S(NL80211_CMD_SET_WIPHY_NETNS)
83 	C2S(NL80211_CMD_GET_SURVEY)
84 	C2S(NL80211_CMD_NEW_SURVEY_RESULTS)
85 	C2S(NL80211_CMD_SET_PMKSA)
86 	C2S(NL80211_CMD_DEL_PMKSA)
87 	C2S(NL80211_CMD_FLUSH_PMKSA)
88 	C2S(NL80211_CMD_REMAIN_ON_CHANNEL)
89 	C2S(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL)
90 	C2S(NL80211_CMD_SET_TX_BITRATE_MASK)
91 	C2S(NL80211_CMD_REGISTER_FRAME)
92 	C2S(NL80211_CMD_FRAME)
93 	C2S(NL80211_CMD_FRAME_TX_STATUS)
94 	C2S(NL80211_CMD_SET_POWER_SAVE)
95 	C2S(NL80211_CMD_GET_POWER_SAVE)
96 	C2S(NL80211_CMD_SET_CQM)
97 	C2S(NL80211_CMD_NOTIFY_CQM)
98 	C2S(NL80211_CMD_SET_CHANNEL)
99 	C2S(NL80211_CMD_SET_WDS_PEER)
100 	C2S(NL80211_CMD_FRAME_WAIT_CANCEL)
101 	C2S(NL80211_CMD_JOIN_MESH)
102 	C2S(NL80211_CMD_LEAVE_MESH)
103 	C2S(NL80211_CMD_UNPROT_DEAUTHENTICATE)
104 	C2S(NL80211_CMD_UNPROT_DISASSOCIATE)
105 	C2S(NL80211_CMD_NEW_PEER_CANDIDATE)
106 	C2S(NL80211_CMD_GET_WOWLAN)
107 	C2S(NL80211_CMD_SET_WOWLAN)
108 	C2S(NL80211_CMD_START_SCHED_SCAN)
109 	C2S(NL80211_CMD_STOP_SCHED_SCAN)
110 	C2S(NL80211_CMD_SCHED_SCAN_RESULTS)
111 	C2S(NL80211_CMD_SCHED_SCAN_STOPPED)
112 	C2S(NL80211_CMD_SET_REKEY_OFFLOAD)
113 	C2S(NL80211_CMD_PMKSA_CANDIDATE)
114 	C2S(NL80211_CMD_TDLS_OPER)
115 	C2S(NL80211_CMD_TDLS_MGMT)
116 	C2S(NL80211_CMD_UNEXPECTED_FRAME)
117 	C2S(NL80211_CMD_PROBE_CLIENT)
118 	C2S(NL80211_CMD_REGISTER_BEACONS)
119 	C2S(NL80211_CMD_UNEXPECTED_4ADDR_FRAME)
120 	C2S(NL80211_CMD_SET_NOACK_MAP)
121 	C2S(NL80211_CMD_CH_SWITCH_NOTIFY)
122 	C2S(NL80211_CMD_START_P2P_DEVICE)
123 	C2S(NL80211_CMD_STOP_P2P_DEVICE)
124 	C2S(NL80211_CMD_CONN_FAILED)
125 	C2S(NL80211_CMD_SET_MCAST_RATE)
126 	C2S(NL80211_CMD_SET_MAC_ACL)
127 	C2S(NL80211_CMD_RADAR_DETECT)
128 	C2S(NL80211_CMD_GET_PROTOCOL_FEATURES)
129 	C2S(NL80211_CMD_UPDATE_FT_IES)
130 	C2S(NL80211_CMD_FT_EVENT)
131 	C2S(NL80211_CMD_CRIT_PROTOCOL_START)
132 	C2S(NL80211_CMD_CRIT_PROTOCOL_STOP)
133 	C2S(NL80211_CMD_GET_COALESCE)
134 	C2S(NL80211_CMD_SET_COALESCE)
135 	C2S(NL80211_CMD_CHANNEL_SWITCH)
136 	C2S(NL80211_CMD_VENDOR)
137 	C2S(NL80211_CMD_SET_QOS_MAP)
138 	C2S(NL80211_CMD_ADD_TX_TS)
139 	C2S(NL80211_CMD_DEL_TX_TS)
140 	C2S(NL80211_CMD_GET_MPP)
141 	C2S(NL80211_CMD_JOIN_OCB)
142 	C2S(NL80211_CMD_LEAVE_OCB)
143 	C2S(NL80211_CMD_CH_SWITCH_STARTED_NOTIFY)
144 	C2S(NL80211_CMD_TDLS_CHANNEL_SWITCH)
145 	C2S(NL80211_CMD_TDLS_CANCEL_CHANNEL_SWITCH)
146 	C2S(NL80211_CMD_WIPHY_REG_CHANGE)
147 	C2S(NL80211_CMD_ABORT_SCAN)
148 	C2S(NL80211_CMD_START_NAN)
149 	C2S(NL80211_CMD_STOP_NAN)
150 	C2S(NL80211_CMD_ADD_NAN_FUNCTION)
151 	C2S(NL80211_CMD_DEL_NAN_FUNCTION)
152 	C2S(NL80211_CMD_CHANGE_NAN_CONFIG)
153 	C2S(NL80211_CMD_NAN_MATCH)
154 	C2S(NL80211_CMD_SET_MULTICAST_TO_UNICAST)
155 	C2S(NL80211_CMD_UPDATE_CONNECT_PARAMS)
156 	C2S(NL80211_CMD_SET_PMK)
157 	C2S(NL80211_CMD_DEL_PMK)
158 	C2S(NL80211_CMD_PORT_AUTHORIZED)
159 	C2S(NL80211_CMD_RELOAD_REGDB)
160 	C2S(NL80211_CMD_EXTERNAL_AUTH)
161 	C2S(NL80211_CMD_STA_OPMODE_CHANGED)
162 	C2S(NL80211_CMD_CONTROL_PORT_FRAME)
163 	C2S(NL80211_CMD_GET_FTM_RESPONDER_STATS)
164 	C2S(NL80211_CMD_PEER_MEASUREMENT_START)
165 	C2S(NL80211_CMD_PEER_MEASUREMENT_RESULT)
166 	C2S(NL80211_CMD_PEER_MEASUREMENT_COMPLETE)
167 	C2S(NL80211_CMD_NOTIFY_RADAR)
168 	C2S(NL80211_CMD_UPDATE_OWE_INFO)
169 	C2S(NL80211_CMD_PROBE_MESH_LINK)
170 	C2S(NL80211_CMD_SET_TID_CONFIG)
171 	C2S(NL80211_CMD_UNPROT_BEACON)
172 	C2S(NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS)
173 	C2S(NL80211_CMD_SET_SAR_SPECS)
174 	C2S(NL80211_CMD_OBSS_COLOR_COLLISION)
175 	C2S(NL80211_CMD_COLOR_CHANGE_REQUEST)
176 	C2S(NL80211_CMD_COLOR_CHANGE_STARTED)
177 	C2S(NL80211_CMD_COLOR_CHANGE_ABORTED)
178 	C2S(NL80211_CMD_COLOR_CHANGE_COMPLETED)
179 	C2S(NL80211_CMD_SET_FILS_AAD)
180 	C2S(NL80211_CMD_ASSOC_COMEBACK)
181 	C2S(__NL80211_CMD_AFTER_LAST)
182 	}
183 #undef C2S
184 
185 	return "NL80211_CMD_UNKNOWN";
186 }
187 
188 
mlme_event_auth(struct wpa_driver_nl80211_data * drv,const u8 * frame,size_t len)189 static void mlme_event_auth(struct wpa_driver_nl80211_data *drv,
190 			    const u8 *frame, size_t len)
191 {
192 	const struct ieee80211_mgmt *mgmt;
193 	union wpa_event_data event;
194 
195 	if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME) &&
196 	    drv->force_connect_cmd) {
197 		/*
198 		 * Avoid reporting two association events that would confuse
199 		 * the core code.
200 		 */
201 		wpa_printf(MSG_DEBUG,
202 			   "nl80211: Ignore auth event when using driver SME");
203 		return;
204 	}
205 
206 	wpa_printf(MSG_DEBUG, "nl80211: Authenticate event");
207 	mgmt = (const struct ieee80211_mgmt *) frame;
208 	if (len < 24 + sizeof(mgmt->u.auth)) {
209 		wpa_printf(MSG_DEBUG, "nl80211: Too short association event "
210 			   "frame");
211 		return;
212 	}
213 
214 	os_memcpy(drv->auth_bssid, mgmt->sa, ETH_ALEN);
215 	os_memset(drv->auth_attempt_bssid, 0, ETH_ALEN);
216 	os_memset(&event, 0, sizeof(event));
217 	os_memcpy(event.auth.peer, mgmt->sa, ETH_ALEN);
218 	event.auth.auth_type = le_to_host16(mgmt->u.auth.auth_alg);
219 	event.auth.auth_transaction =
220 		le_to_host16(mgmt->u.auth.auth_transaction);
221 	event.auth.status_code = le_to_host16(mgmt->u.auth.status_code);
222 	if (len > 24 + sizeof(mgmt->u.auth)) {
223 		event.auth.ies = mgmt->u.auth.variable;
224 		event.auth.ies_len = len - 24 - sizeof(mgmt->u.auth);
225 	}
226 
227 	wpa_supplicant_event(drv->ctx, EVENT_AUTH, &event);
228 }
229 
230 
nl80211_parse_wmm_params(struct nlattr * wmm_attr,struct wmm_params * wmm_params)231 static void nl80211_parse_wmm_params(struct nlattr *wmm_attr,
232 				     struct wmm_params *wmm_params)
233 {
234 	struct nlattr *wmm_info[NL80211_STA_WME_MAX + 1];
235 	static struct nla_policy wme_policy[NL80211_STA_WME_MAX + 1] = {
236 		[NL80211_STA_WME_UAPSD_QUEUES] = { .type = NLA_U8 },
237 	};
238 
239 	if (!wmm_attr ||
240 	    nla_parse_nested(wmm_info, NL80211_STA_WME_MAX, wmm_attr,
241 			     wme_policy) ||
242 	    !wmm_info[NL80211_STA_WME_UAPSD_QUEUES])
243 		return;
244 
245 	wmm_params->uapsd_queues =
246 		nla_get_u8(wmm_info[NL80211_STA_WME_UAPSD_QUEUES]);
247 	wmm_params->info_bitmap |= WMM_PARAMS_UAPSD_QUEUES_INFO;
248 }
249 
250 
mlme_event_assoc(struct wpa_driver_nl80211_data * drv,const u8 * frame,size_t len,struct nlattr * wmm,struct nlattr * req_ie)251 static void mlme_event_assoc(struct wpa_driver_nl80211_data *drv,
252 			     const u8 *frame, size_t len, struct nlattr *wmm,
253 			     struct nlattr *req_ie)
254 {
255 	const struct ieee80211_mgmt *mgmt;
256 	union wpa_event_data event;
257 	u16 status;
258 	int ssid_len;
259 
260 	if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME) &&
261 	    drv->force_connect_cmd) {
262 		/*
263 		 * Avoid reporting two association events that would confuse
264 		 * the core code.
265 		 */
266 		wpa_printf(MSG_DEBUG,
267 			   "nl80211: Ignore assoc event when using driver SME");
268 		return;
269 	}
270 
271 	wpa_printf(MSG_DEBUG, "nl80211: Associate event");
272 	mgmt = (const struct ieee80211_mgmt *) frame;
273 	if (len < 24 + sizeof(mgmt->u.assoc_resp)) {
274 		wpa_printf(MSG_DEBUG, "nl80211: Too short association event "
275 			   "frame");
276 		return;
277 	}
278 
279 	status = le_to_host16(mgmt->u.assoc_resp.status_code);
280 	if (status != WLAN_STATUS_SUCCESS) {
281 		os_memset(&event, 0, sizeof(event));
282 		event.assoc_reject.bssid = mgmt->bssid;
283 		if (len > 24 + sizeof(mgmt->u.assoc_resp)) {
284 			event.assoc_reject.resp_ies =
285 				(u8 *) mgmt->u.assoc_resp.variable;
286 			event.assoc_reject.resp_ies_len =
287 				len - 24 - sizeof(mgmt->u.assoc_resp);
288 		}
289 		event.assoc_reject.status_code = status;
290 
291 		wpa_supplicant_event(drv->ctx, EVENT_ASSOC_REJECT, &event);
292 		return;
293 	}
294 
295 	drv->associated = 1;
296 	os_memcpy(drv->bssid, mgmt->sa, ETH_ALEN);
297 	os_memcpy(drv->prev_bssid, mgmt->sa, ETH_ALEN);
298 
299 	os_memset(&event, 0, sizeof(event));
300 	event.assoc_info.resp_frame = frame;
301 	event.assoc_info.resp_frame_len = len;
302 	if (len > 24 + sizeof(mgmt->u.assoc_resp)) {
303 		event.assoc_info.resp_ies = (u8 *) mgmt->u.assoc_resp.variable;
304 		event.assoc_info.resp_ies_len =
305 			len - 24 - sizeof(mgmt->u.assoc_resp);
306 	}
307 
308 	if (req_ie) {
309 		event.assoc_info.req_ies = nla_data(req_ie);
310 		event.assoc_info.req_ies_len = nla_len(req_ie);
311 	}
312 
313 	/* When this association was initiated outside of wpa_supplicant,
314 	 * drv->ssid needs to be set here to satisfy later checking. */
315 	ssid_len = nl80211_get_assoc_ssid(drv, drv->ssid);
316 	if (ssid_len > 0) {
317 		drv->ssid_len = ssid_len;
318 		wpa_printf(MSG_DEBUG,
319 			   "nl80211: Set drv->ssid based on scan res info to '%s'",
320 			   wpa_ssid_txt(drv->ssid, drv->ssid_len));
321 	}
322 
323 	event.assoc_info.freq = drv->assoc_freq;
324 	drv->first_bss->freq = drv->assoc_freq;
325 
326 	nl80211_parse_wmm_params(wmm, &event.assoc_info.wmm_params);
327 
328 	wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event);
329 }
330 
331 
332 #ifdef CONFIG_DRIVER_NL80211_QCA
333 
qca_drv_connect_fail_reason_code_handler(struct nl_msg * msg,void * arg)334 static int qca_drv_connect_fail_reason_code_handler(struct nl_msg *msg,
335 						    void *arg)
336 {
337 	struct nlattr *tb[NL80211_ATTR_MAX + 1];
338 	struct nlattr *tb_sta_info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX + 1];
339 	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
340 	u32 *reason_code = arg;
341 
342 	*reason_code = 0;
343 	nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
344 		  genlmsg_attrlen(gnlh, 0), NULL);
345 
346 	if (!tb[NL80211_ATTR_VENDOR_DATA]) {
347 		wpa_printf(MSG_ERROR, "%s: Vendor data not found", __func__);
348 		return NL_SKIP;
349 	}
350 
351 	nla_parse(tb_sta_info, QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX,
352 		  nla_data(tb[NL80211_ATTR_VENDOR_DATA]),
353 		  nla_len(tb[NL80211_ATTR_VENDOR_DATA]), NULL);
354 
355 	if (!tb_sta_info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_CONNECT_FAIL_REASON_CODE]) {
356 		wpa_printf(MSG_INFO, "%s: Vendor attr not found", __func__);
357 		return NL_SKIP;
358 	}
359 
360 	*reason_code = nla_get_u32(tb_sta_info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_CONNECT_FAIL_REASON_CODE]);
361 
362 	return NL_SKIP;
363 }
364 
365 
366 static enum qca_sta_connect_fail_reason_codes
drv_get_connect_fail_reason_code(struct wpa_driver_nl80211_data * drv)367 drv_get_connect_fail_reason_code(struct wpa_driver_nl80211_data *drv)
368 {
369 	enum qca_sta_connect_fail_reason_codes reason_code;
370 	struct nl_msg *msg;
371 	int ret;
372 
373 	msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR);
374 	if (!msg || nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
375 	    nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
376 			QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO)) {
377 		nlmsg_free(msg);
378 		return 0;
379 	}
380 
381 	ret = send_and_recv_msgs(drv, msg,
382 				 qca_drv_connect_fail_reason_code_handler,
383 				 &reason_code, NULL, NULL);
384 	if (ret)
385 		wpa_printf(MSG_DEBUG,
386 			   "nl80211: Get connect fail reason_code failed: ret=%d (%s)",
387 			   ret, strerror(-ret));
388 
389 	return reason_code;
390 }
391 
392 
393 static enum sta_connect_fail_reason_codes
convert_connect_fail_reason_codes(enum qca_sta_connect_fail_reason_codes reason_code)394 convert_connect_fail_reason_codes(enum qca_sta_connect_fail_reason_codes
395 				  reason_code)
396 {
397 	switch (reason_code) {
398 	case QCA_STA_CONNECT_FAIL_REASON_NO_BSS_FOUND:
399 		return STA_CONNECT_FAIL_REASON_NO_BSS_FOUND;
400 	case QCA_STA_CONNECT_FAIL_REASON_AUTH_TX_FAIL:
401 		return STA_CONNECT_FAIL_REASON_AUTH_TX_FAIL;
402 	case QCA_STA_CONNECT_FAIL_REASON_AUTH_NO_ACK_RECEIVED:
403 		return STA_CONNECT_FAIL_REASON_AUTH_NO_ACK_RECEIVED;
404 	case QCA_STA_CONNECT_FAIL_REASON_AUTH_NO_RESP_RECEIVED:
405 		return STA_CONNECT_FAIL_REASON_AUTH_NO_RESP_RECEIVED;
406 	case QCA_STA_CONNECT_FAIL_REASON_ASSOC_REQ_TX_FAIL:
407 		return STA_CONNECT_FAIL_REASON_ASSOC_REQ_TX_FAIL;
408 	case QCA_STA_CONNECT_FAIL_REASON_ASSOC_NO_ACK_RECEIVED:
409 		return STA_CONNECT_FAIL_REASON_ASSOC_NO_ACK_RECEIVED;
410 	case QCA_STA_CONNECT_FAIL_REASON_ASSOC_NO_RESP_RECEIVED:
411 		return STA_CONNECT_FAIL_REASON_ASSOC_NO_RESP_RECEIVED;
412 	default:
413 		return STA_CONNECT_FAIL_REASON_UNSPECIFIED;
414 	}
415 }
416 
417 #endif /* CONFIG_DRIVER_NL80211_QCA */
418 
419 
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,struct nlattr * fils_erp_next_seq_num,struct nlattr * fils_pmk,struct nlattr * fils_pmkid)420 static void mlme_event_connect(struct wpa_driver_nl80211_data *drv,
421 			       enum nl80211_commands cmd, struct nlattr *status,
422 			       struct nlattr *addr, struct nlattr *req_ie,
423 			       struct nlattr *resp_ie,
424 			       struct nlattr *timed_out,
425 			       struct nlattr *timeout_reason,
426 			       struct nlattr *authorized,
427 			       struct nlattr *key_replay_ctr,
428 			       struct nlattr *ptk_kck,
429 			       struct nlattr *ptk_kek,
430 			       struct nlattr *subnet_status,
431 			       struct nlattr *fils_erp_next_seq_num,
432 			       struct nlattr *fils_pmk,
433 			       struct nlattr *fils_pmkid)
434 {
435 	union wpa_event_data event;
436 	const u8 *ssid = NULL;
437 	u16 status_code;
438 	int ssid_len;
439 
440 	if (drv->capa.flags & WPA_DRIVER_FLAGS_SME) {
441 		/*
442 		 * Avoid reporting two association events that would confuse
443 		 * the core code.
444 		 */
445 		wpa_printf(MSG_DEBUG, "nl80211: Ignore connect event (cmd=%d) "
446 			   "when using userspace SME", cmd);
447 		return;
448 	}
449 
450 	drv->connect_reassoc = 0;
451 
452 	status_code = status ? nla_get_u16(status) : WLAN_STATUS_SUCCESS;
453 
454 	if (cmd == NL80211_CMD_CONNECT) {
455 		wpa_printf(MSG_DEBUG,
456 			   "nl80211: Connect event (status=%u ignore_next_local_disconnect=%d)",
457 			   status_code, drv->ignore_next_local_disconnect);
458 	} else if (cmd == NL80211_CMD_ROAM) {
459 		wpa_printf(MSG_DEBUG, "nl80211: Roam event");
460 	}
461 
462 	os_memset(&event, 0, sizeof(event));
463 	if (cmd == NL80211_CMD_CONNECT && status_code != WLAN_STATUS_SUCCESS) {
464 		if (addr)
465 			event.assoc_reject.bssid = nla_data(addr);
466 		if (drv->ignore_next_local_disconnect) {
467 			drv->ignore_next_local_disconnect = 0;
468 			if (!event.assoc_reject.bssid ||
469 			    (os_memcmp(event.assoc_reject.bssid,
470 				       drv->auth_attempt_bssid,
471 				       ETH_ALEN) != 0)) {
472 				/*
473 				 * Ignore the event that came without a BSSID or
474 				 * for the old connection since this is likely
475 				 * not relevant to the new Connect command.
476 				 */
477 				wpa_printf(MSG_DEBUG,
478 					   "nl80211: Ignore connection failure event triggered during reassociation");
479 				return;
480 			}
481 		}
482 		if (resp_ie) {
483 			event.assoc_reject.resp_ies = nla_data(resp_ie);
484 			event.assoc_reject.resp_ies_len = nla_len(resp_ie);
485 		}
486 		event.assoc_reject.status_code = status_code;
487 		event.assoc_reject.timed_out = timed_out != NULL;
488 		if (timed_out && timeout_reason) {
489 			enum nl80211_timeout_reason reason;
490 
491 			reason = nla_get_u32(timeout_reason);
492 			switch (reason) {
493 			case NL80211_TIMEOUT_SCAN:
494 				event.assoc_reject.timeout_reason = "scan";
495 				break;
496 			case NL80211_TIMEOUT_AUTH:
497 				event.assoc_reject.timeout_reason = "auth";
498 				break;
499 			case NL80211_TIMEOUT_ASSOC:
500 				event.assoc_reject.timeout_reason = "assoc";
501 				break;
502 			default:
503 				break;
504 			}
505 		}
506 		if (fils_erp_next_seq_num)
507 			event.assoc_reject.fils_erp_next_seq_num =
508 				nla_get_u16(fils_erp_next_seq_num);
509 
510 #ifdef CONFIG_DRIVER_NL80211_QCA
511 		if (drv->get_sta_info_vendor_cmd_avail) {
512 			enum qca_sta_connect_fail_reason_codes reason_code;
513 
514 			reason_code = drv_get_connect_fail_reason_code(drv);
515 			event.assoc_reject.reason_code =
516 				convert_connect_fail_reason_codes(reason_code);
517 		}
518 #endif /* CONFIG_DRIVER_NL80211_QCA */
519 
520 		wpa_supplicant_event(drv->ctx, EVENT_ASSOC_REJECT, &event);
521 		return;
522 	}
523 
524 	drv->associated = 1;
525 	if (addr) {
526 		os_memcpy(drv->bssid, nla_data(addr), ETH_ALEN);
527 		os_memcpy(drv->prev_bssid, drv->bssid, ETH_ALEN);
528 	}
529 
530 	if (req_ie) {
531 		event.assoc_info.req_ies = nla_data(req_ie);
532 		event.assoc_info.req_ies_len = nla_len(req_ie);
533 
534 		if (cmd == NL80211_CMD_ROAM) {
535 			ssid = get_ie(event.assoc_info.req_ies,
536 				      event.assoc_info.req_ies_len,
537 				      WLAN_EID_SSID);
538 			if (ssid && ssid[1] > 0 && ssid[1] <= 32) {
539 				drv->ssid_len = ssid[1];
540 				os_memcpy(drv->ssid, ssid + 2, ssid[1]);
541 				wpa_printf(MSG_DEBUG,
542 					   "nl80211: Set drv->ssid based on req_ie to '%s'",
543 					   wpa_ssid_txt(drv->ssid,
544 							drv->ssid_len));
545 			}
546 		}
547 	}
548 	if (resp_ie) {
549 		event.assoc_info.resp_ies = nla_data(resp_ie);
550 		event.assoc_info.resp_ies_len = nla_len(resp_ie);
551 	}
552 
553 	event.assoc_info.freq = nl80211_get_assoc_freq(drv);
554 	drv->first_bss->freq = drv->assoc_freq;
555 
556 	if ((!ssid || ssid[1] == 0 || ssid[1] > 32) &&
557 	    (ssid_len = nl80211_get_assoc_ssid(drv, drv->ssid)) > 0) {
558 		/* When this connection was initiated outside of wpa_supplicant,
559 		 * drv->ssid needs to be set here to satisfy later checking. */
560 		drv->ssid_len = ssid_len;
561 		wpa_printf(MSG_DEBUG,
562 			   "nl80211: Set drv->ssid based on scan res info to '%s'",
563 			   wpa_ssid_txt(drv->ssid, drv->ssid_len));
564 	}
565 
566 	if (authorized && nla_get_u8(authorized)) {
567 		event.assoc_info.authorized = 1;
568 		wpa_printf(MSG_DEBUG, "nl80211: connection authorized");
569 	}
570 	if (key_replay_ctr) {
571 		event.assoc_info.key_replay_ctr = nla_data(key_replay_ctr);
572 		event.assoc_info.key_replay_ctr_len = nla_len(key_replay_ctr);
573 	}
574 	if (ptk_kck) {
575 		event.assoc_info.ptk_kck = nla_data(ptk_kck);
576 		event.assoc_info.ptk_kck_len = nla_len(ptk_kck);
577 	}
578 	if (ptk_kek) {
579 		event.assoc_info.ptk_kek = nla_data(ptk_kek);
580 		event.assoc_info.ptk_kek_len = nla_len(ptk_kek);
581 	}
582 
583 	if (subnet_status) {
584 		/*
585 		 * At least for now, this is only available from
586 		 * QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_SUBNET_STATUS and that
587 		 * attribute has the same values 0, 1, 2 as are used in the
588 		 * variable here, so no mapping between different values are
589 		 * needed.
590 		 */
591 		event.assoc_info.subnet_status = nla_get_u8(subnet_status);
592 	}
593 
594 	if (fils_erp_next_seq_num)
595 		event.assoc_info.fils_erp_next_seq_num =
596 			nla_get_u16(fils_erp_next_seq_num);
597 
598 	if (fils_pmk) {
599 		event.assoc_info.fils_pmk = nla_data(fils_pmk);
600 		event.assoc_info.fils_pmk_len = nla_len(fils_pmk);
601 	}
602 
603 	if (fils_pmkid)
604 		event.assoc_info.fils_pmkid = nla_data(fils_pmkid);
605 
606 	wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event);
607 
608 	/* Avoid a race condition by stopping to ignore any following
609 	 * disconnection events now that the driver has indicated it is
610 	 * connected since that connection could have been triggered by a roam
611 	 * operation that happened in parallel with the disconnection request.
612 	 */
613 	drv->ignore_next_local_disconnect = 0;
614 }
615 
616 
mlme_event_disconnect(struct wpa_driver_nl80211_data * drv,struct nlattr * reason,struct nlattr * addr,struct nlattr * by_ap)617 static void mlme_event_disconnect(struct wpa_driver_nl80211_data *drv,
618 				  struct nlattr *reason, struct nlattr *addr,
619 				  struct nlattr *by_ap)
620 {
621 	union wpa_event_data data;
622 	unsigned int locally_generated = by_ap == NULL;
623 
624 	if (drv->capa.flags & WPA_DRIVER_FLAGS_SME) {
625 		/*
626 		 * Avoid reporting two disassociation events that could
627 		 * confuse the core code.
628 		 */
629 		wpa_printf(MSG_DEBUG, "nl80211: Ignore disconnect "
630 			   "event when using userspace SME");
631 		return;
632 	}
633 
634 	if (drv->ignore_next_local_disconnect) {
635 		drv->ignore_next_local_disconnect = 0;
636 		if (locally_generated) {
637 			wpa_printf(MSG_DEBUG, "nl80211: Ignore disconnect "
638 				   "event triggered during reassociation");
639 			return;
640 		}
641 		wpa_printf(MSG_WARNING, "nl80211: Was expecting local "
642 			   "disconnect but got another disconnect "
643 			   "event first");
644 	}
645 
646 	wpa_printf(MSG_DEBUG, "nl80211: Disconnect event");
647 	nl80211_mark_disconnected(drv);
648 	os_memset(&data, 0, sizeof(data));
649 	if (reason)
650 		data.deauth_info.reason_code = nla_get_u16(reason);
651 	data.deauth_info.locally_generated = by_ap == NULL;
652 	wpa_supplicant_event(drv->ctx, EVENT_DEAUTH, &data);
653 }
654 
655 
calculate_chan_offset(int width,int freq,int cf1,int cf2)656 static int calculate_chan_offset(int width, int freq, int cf1, int cf2)
657 {
658 	int freq1 = 0;
659 
660 	switch (convert2width(width)) {
661 	case CHAN_WIDTH_20_NOHT:
662 	case CHAN_WIDTH_20:
663 		return 0;
664 	case CHAN_WIDTH_40:
665 		freq1 = cf1 - 10;
666 		break;
667 	case CHAN_WIDTH_80:
668 		freq1 = cf1 - 30;
669 		break;
670 	case CHAN_WIDTH_160:
671 		freq1 = cf1 - 70;
672 		break;
673 	case CHAN_WIDTH_80P80:
674 		freq1 = cf1 - 30;
675 		break;
676 	case CHAN_WIDTH_UNKNOWN:
677 	case CHAN_WIDTH_2160:
678 	case CHAN_WIDTH_4320:
679 	case CHAN_WIDTH_6480:
680 	case CHAN_WIDTH_8640:
681 		/* FIXME: implement this */
682 		return 0;
683 	}
684 
685 	return (abs(freq - freq1) / 20) % 2 == 0 ? 1 : -1;
686 }
687 
688 
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,int finished)689 static void mlme_event_ch_switch(struct wpa_driver_nl80211_data *drv,
690 				 struct nlattr *ifindex, struct nlattr *freq,
691 				 struct nlattr *type, struct nlattr *bw,
692 				 struct nlattr *cf1, struct nlattr *cf2,
693 				 int finished)
694 {
695 	struct i802_bss *bss;
696 	union wpa_event_data data;
697 	int ht_enabled = 1;
698 	int chan_offset = 0;
699 	int ifidx;
700 
701 	wpa_printf(MSG_DEBUG, "nl80211: Channel switch%s event",
702 		   finished ? "" : " started");
703 
704 	if (!freq)
705 		return;
706 
707 	ifidx = nla_get_u32(ifindex);
708 	bss = get_bss_ifindex(drv, ifidx);
709 	if (bss == NULL) {
710 		wpa_printf(MSG_WARNING, "nl80211: Unknown ifindex (%d) for channel switch, ignoring",
711 			   ifidx);
712 		return;
713 	}
714 
715 	if (type) {
716 		enum nl80211_channel_type ch_type = nla_get_u32(type);
717 
718 		wpa_printf(MSG_DEBUG, "nl80211: Channel type: %d", ch_type);
719 		switch (ch_type) {
720 		case NL80211_CHAN_NO_HT:
721 			ht_enabled = 0;
722 			break;
723 		case NL80211_CHAN_HT20:
724 			break;
725 		case NL80211_CHAN_HT40PLUS:
726 			chan_offset = 1;
727 			break;
728 		case NL80211_CHAN_HT40MINUS:
729 			chan_offset = -1;
730 			break;
731 		}
732 	} else if (bw && cf1) {
733 		/* This can happen for example with VHT80 ch switch */
734 		chan_offset = calculate_chan_offset(nla_get_u32(bw),
735 						    nla_get_u32(freq),
736 						    nla_get_u32(cf1),
737 						    cf2 ? nla_get_u32(cf2) : 0);
738 		wpa_printf(MSG_DEBUG, "nl80211: Calculated channel offset: %d",
739 			   chan_offset);
740 	} else {
741 		wpa_printf(MSG_WARNING, "nl80211: Unknown secondary channel information - following channel definition calculations may fail");
742 	}
743 
744 	os_memset(&data, 0, sizeof(data));
745 	data.ch_switch.freq = nla_get_u32(freq);
746 	data.ch_switch.ht_enabled = ht_enabled;
747 	data.ch_switch.ch_offset = chan_offset;
748 	if (bw)
749 		data.ch_switch.ch_width = convert2width(nla_get_u32(bw));
750 	if (cf1)
751 		data.ch_switch.cf1 = nla_get_u32(cf1);
752 	if (cf2)
753 		data.ch_switch.cf2 = nla_get_u32(cf2);
754 
755 	if (finished)
756 		bss->freq = data.ch_switch.freq;
757 	drv->assoc_freq = data.ch_switch.freq;
758 
759 	wpa_supplicant_event(bss->ctx, finished ?
760 			     EVENT_CH_SWITCH : EVENT_CH_SWITCH_STARTED, &data);
761 }
762 
763 
mlme_timeout_event(struct wpa_driver_nl80211_data * drv,enum nl80211_commands cmd,struct nlattr * addr)764 static void mlme_timeout_event(struct wpa_driver_nl80211_data *drv,
765 			       enum nl80211_commands cmd, struct nlattr *addr)
766 {
767 	union wpa_event_data event;
768 	enum wpa_event_type ev;
769 
770 	if (nla_len(addr) != ETH_ALEN)
771 		return;
772 
773 	wpa_printf(MSG_DEBUG, "nl80211: MLME event %d; timeout with " MACSTR,
774 		   cmd, MAC2STR((u8 *) nla_data(addr)));
775 
776 	if (cmd == NL80211_CMD_AUTHENTICATE)
777 		ev = EVENT_AUTH_TIMED_OUT;
778 	else if (cmd == NL80211_CMD_ASSOCIATE)
779 		ev = EVENT_ASSOC_TIMED_OUT;
780 	else
781 		return;
782 
783 	os_memset(&event, 0, sizeof(event));
784 	os_memcpy(event.timeout_event.addr, nla_data(addr), ETH_ALEN);
785 	wpa_supplicant_event(drv->ctx, ev, &event);
786 }
787 
788 
mlme_event_mgmt(struct i802_bss * bss,struct nlattr * freq,struct nlattr * sig,const u8 * frame,size_t len)789 static void mlme_event_mgmt(struct i802_bss *bss,
790 			    struct nlattr *freq, struct nlattr *sig,
791 			    const u8 *frame, size_t len)
792 {
793 	struct wpa_driver_nl80211_data *drv = bss->drv;
794 	const struct ieee80211_mgmt *mgmt;
795 	union wpa_event_data event;
796 	u16 fc, stype;
797 	int ssi_signal = 0;
798 	int rx_freq = 0;
799 
800 	wpa_printf(MSG_MSGDUMP, "nl80211: Frame event");
801 	mgmt = (const struct ieee80211_mgmt *) frame;
802 	if (len < 24) {
803 		wpa_printf(MSG_DEBUG, "nl80211: Too short management frame");
804 		return;
805 	}
806 
807 	fc = le_to_host16(mgmt->frame_control);
808 	stype = WLAN_FC_GET_STYPE(fc);
809 
810 	if (sig)
811 		ssi_signal = (s32) nla_get_u32(sig);
812 
813 	os_memset(&event, 0, sizeof(event));
814 	if (freq) {
815 		event.rx_mgmt.freq = nla_get_u32(freq);
816 		rx_freq = drv->last_mgmt_freq = event.rx_mgmt.freq;
817 	}
818 	wpa_printf(MSG_DEBUG,
819 		   "nl80211: RX frame da=" MACSTR " sa=" MACSTR " bssid=" MACSTR
820 		   " freq=%d ssi_signal=%d fc=0x%x seq_ctrl=0x%x stype=%u (%s) len=%u",
821 		   MAC2STR(mgmt->da), MAC2STR(mgmt->sa), MAC2STR(mgmt->bssid),
822 		   rx_freq, ssi_signal, fc,
823 		   le_to_host16(mgmt->seq_ctrl), stype, fc2str(fc),
824 		   (unsigned int) len);
825 	event.rx_mgmt.frame = frame;
826 	event.rx_mgmt.frame_len = len;
827 	event.rx_mgmt.ssi_signal = ssi_signal;
828 	event.rx_mgmt.drv_priv = bss;
829 	wpa_supplicant_event(drv->ctx, EVENT_RX_MGMT, &event);
830 }
831 
832 
mlme_event_mgmt_tx_status(struct wpa_driver_nl80211_data * drv,struct nlattr * cookie,const u8 * frame,size_t len,struct nlattr * ack)833 static void mlme_event_mgmt_tx_status(struct wpa_driver_nl80211_data *drv,
834 				      struct nlattr *cookie, const u8 *frame,
835 				      size_t len, struct nlattr *ack)
836 {
837 	union wpa_event_data event;
838 	const struct ieee80211_hdr *hdr = (const struct ieee80211_hdr *) frame;
839 	u16 fc = le_to_host16(hdr->frame_control);
840 	u64 cookie_val = 0;
841 
842 	if (cookie)
843 		cookie_val = nla_get_u64(cookie);
844 	wpa_printf(MSG_DEBUG,
845 		   "nl80211: Frame TX status event A1=" MACSTR
846 		   " %sstype=%d cookie=0x%llx%s ack=%d",
847 		   MAC2STR(hdr->addr1),
848 		   WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT ? "not-mgmt " : "",
849 		   WLAN_FC_GET_STYPE(fc), (long long unsigned int) cookie_val,
850 		   cookie ? "" : "(N/A)", ack != NULL);
851 
852 	if (cookie_val && cookie_val == drv->eapol_tx_cookie &&
853 	    len >= ETH_HLEN &&
854 	    WPA_GET_BE16(frame + 2 * ETH_ALEN) == ETH_P_PAE) {
855 		wpa_printf(MSG_DEBUG,
856 			   "nl80211: Work around misdelivered control port TX status for EAPOL");
857 		nl80211_control_port_frame_tx_status(drv, frame, len, ack,
858 						     cookie);
859 		return;
860 	}
861 
862 	if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT)
863 		return;
864 
865 	if (!is_ap_interface(drv->nlmode) &&
866 	    WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_ACTION) {
867 		if (!cookie)
868 			return;
869 
870 		wpa_printf(MSG_DEBUG,
871 			   "nl80211: Frame TX status: cookie=0x%llx%s (ack=%d)",
872 			   (long long unsigned int) cookie_val,
873 			   cookie_val == drv->send_frame_cookie ?
874 			   " (match)" : " (unknown)", ack != NULL);
875 		if (cookie_val != drv->send_frame_cookie)
876 			return;
877 	} else if (!is_ap_interface(drv->nlmode) &&
878 		   WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_AUTH) {
879 		wpa_printf(MSG_DEBUG,
880 			   "nl80211: Authentication frame TX status: ack=%d",
881 			   !!ack);
882 	}
883 
884 	os_memset(&event, 0, sizeof(event));
885 	event.tx_status.type = WLAN_FC_GET_TYPE(fc);
886 	event.tx_status.stype = WLAN_FC_GET_STYPE(fc);
887 	event.tx_status.dst = hdr->addr1;
888 	event.tx_status.data = frame;
889 	event.tx_status.data_len = len;
890 	event.tx_status.ack = ack != NULL;
891 	wpa_supplicant_event(drv->ctx, EVENT_TX_STATUS, &event);
892 }
893 
894 
mlme_event_deauth_disassoc(struct wpa_driver_nl80211_data * drv,enum wpa_event_type type,const u8 * frame,size_t len)895 static void mlme_event_deauth_disassoc(struct wpa_driver_nl80211_data *drv,
896 				       enum wpa_event_type type,
897 				       const u8 *frame, size_t len)
898 {
899 	const struct ieee80211_mgmt *mgmt;
900 	union wpa_event_data event;
901 	const u8 *bssid = NULL;
902 	u16 reason_code = 0;
903 
904 	if (type == EVENT_DEAUTH)
905 		wpa_printf(MSG_DEBUG, "nl80211: Deauthenticate event");
906 	else
907 		wpa_printf(MSG_DEBUG, "nl80211: Disassociate event");
908 
909 	mgmt = (const struct ieee80211_mgmt *) frame;
910 	if (len >= 24) {
911 		bssid = mgmt->bssid;
912 
913 		if ((drv->capa.flags & WPA_DRIVER_FLAGS_SME) &&
914 		    !drv->associated &&
915 		    os_memcmp(bssid, drv->auth_bssid, ETH_ALEN) != 0 &&
916 		    os_memcmp(bssid, drv->auth_attempt_bssid, ETH_ALEN) != 0 &&
917 		    os_memcmp(bssid, drv->prev_bssid, ETH_ALEN) == 0) {
918 			/*
919 			 * Avoid issues with some roaming cases where
920 			 * disconnection event for the old AP may show up after
921 			 * we have started connection with the new AP.
922 			 * In case of locally generated event clear
923 			 * ignore_next_local_deauth as well, to avoid next local
924 			 * deauth event be wrongly ignored.
925 			 */
926 			if (!os_memcmp(mgmt->sa, drv->first_bss->addr,
927 				       ETH_ALEN)) {
928 				wpa_printf(MSG_DEBUG,
929 					   "nl80211: Received a locally generated deauth event. Clear ignore_next_local_deauth flag");
930 				drv->ignore_next_local_deauth = 0;
931 			} else {
932 				wpa_printf(MSG_DEBUG,
933 					   "nl80211: Ignore deauth/disassoc event from old AP " MACSTR " when already authenticating with " MACSTR,
934 					   MAC2STR(bssid),
935 					   MAC2STR(drv->auth_attempt_bssid));
936 			}
937 			return;
938 		}
939 
940 		if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME) &&
941 		    drv->connect_reassoc && drv->associated &&
942 		    os_memcmp(bssid, drv->prev_bssid, ETH_ALEN) == 0 &&
943 		    os_memcmp(bssid, drv->auth_attempt_bssid, ETH_ALEN) != 0) {
944 			/*
945 			 * Avoid issues with some roaming cases where
946 			 * disconnection event for the old AP may show up after
947 			 * we have started connection with the new AP.
948 			 */
949 			wpa_printf(MSG_DEBUG,
950 				   "nl80211: Ignore deauth/disassoc event from old AP "
951 				   MACSTR
952 				   " when already connecting with " MACSTR,
953 				   MAC2STR(bssid),
954 				   MAC2STR(drv->auth_attempt_bssid));
955 			return;
956 		}
957 
958 		if (drv->associated != 0 &&
959 		    os_memcmp(bssid, drv->bssid, ETH_ALEN) != 0 &&
960 		    os_memcmp(bssid, drv->auth_bssid, ETH_ALEN) != 0) {
961 			/*
962 			 * We have presumably received this deauth as a
963 			 * response to a clear_state_mismatch() outgoing
964 			 * deauth.  Don't let it take us offline!
965 			 */
966 			wpa_printf(MSG_DEBUG, "nl80211: Deauth received "
967 				   "from Unknown BSSID " MACSTR " -- ignoring",
968 				   MAC2STR(bssid));
969 			return;
970 		}
971 	}
972 
973 	nl80211_mark_disconnected(drv);
974 	os_memset(&event, 0, sizeof(event));
975 
976 	/* Note: Same offset for Reason Code in both frame subtypes */
977 	if (len >= 24 + sizeof(mgmt->u.deauth))
978 		reason_code = le_to_host16(mgmt->u.deauth.reason_code);
979 
980 	if (type == EVENT_DISASSOC) {
981 		event.disassoc_info.locally_generated =
982 			!os_memcmp(mgmt->sa, drv->first_bss->addr, ETH_ALEN);
983 		event.disassoc_info.addr = bssid;
984 		event.disassoc_info.reason_code = reason_code;
985 		if (frame + len > mgmt->u.disassoc.variable) {
986 			event.disassoc_info.ie = mgmt->u.disassoc.variable;
987 			event.disassoc_info.ie_len = frame + len -
988 				mgmt->u.disassoc.variable;
989 		}
990 	} else {
991 		event.deauth_info.locally_generated =
992 			!os_memcmp(mgmt->sa, drv->first_bss->addr, ETH_ALEN);
993 		if (drv->ignore_deauth_event) {
994 			wpa_printf(MSG_DEBUG, "nl80211: Ignore deauth event due to previous forced deauth-during-auth");
995 			drv->ignore_deauth_event = 0;
996 			if (event.deauth_info.locally_generated)
997 				drv->ignore_next_local_deauth = 0;
998 			return;
999 		}
1000 		if (drv->ignore_next_local_deauth) {
1001 			drv->ignore_next_local_deauth = 0;
1002 			if (event.deauth_info.locally_generated) {
1003 				wpa_printf(MSG_DEBUG, "nl80211: Ignore deauth event triggered due to own deauth request");
1004 				return;
1005 			}
1006 			wpa_printf(MSG_WARNING, "nl80211: Was expecting local deauth but got another disconnect event first");
1007 		}
1008 		event.deauth_info.addr = bssid;
1009 		event.deauth_info.reason_code = reason_code;
1010 		if (frame + len > mgmt->u.deauth.variable) {
1011 			event.deauth_info.ie = mgmt->u.deauth.variable;
1012 			event.deauth_info.ie_len = frame + len -
1013 				mgmt->u.deauth.variable;
1014 		}
1015 	}
1016 
1017 	wpa_supplicant_event(drv->ctx, type, &event);
1018 }
1019 
1020 
mlme_event_unprot_disconnect(struct wpa_driver_nl80211_data * drv,enum wpa_event_type type,const u8 * frame,size_t len)1021 static void mlme_event_unprot_disconnect(struct wpa_driver_nl80211_data *drv,
1022 					 enum wpa_event_type type,
1023 					 const u8 *frame, size_t len)
1024 {
1025 	const struct ieee80211_mgmt *mgmt;
1026 	union wpa_event_data event;
1027 	u16 reason_code = 0;
1028 
1029 	if (type == EVENT_UNPROT_DEAUTH)
1030 		wpa_printf(MSG_DEBUG, "nl80211: Unprot Deauthenticate event");
1031 	else
1032 		wpa_printf(MSG_DEBUG, "nl80211: Unprot Disassociate event");
1033 
1034 	if (len < 24)
1035 		return;
1036 
1037 	mgmt = (const struct ieee80211_mgmt *) frame;
1038 
1039 	os_memset(&event, 0, sizeof(event));
1040 	/* Note: Same offset for Reason Code in both frame subtypes */
1041 	if (len >= 24 + sizeof(mgmt->u.deauth))
1042 		reason_code = le_to_host16(mgmt->u.deauth.reason_code);
1043 
1044 	if (type == EVENT_UNPROT_DISASSOC) {
1045 		event.unprot_disassoc.sa = mgmt->sa;
1046 		event.unprot_disassoc.da = mgmt->da;
1047 		event.unprot_disassoc.reason_code = reason_code;
1048 	} else {
1049 		event.unprot_deauth.sa = mgmt->sa;
1050 		event.unprot_deauth.da = mgmt->da;
1051 		event.unprot_deauth.reason_code = reason_code;
1052 	}
1053 
1054 	wpa_supplicant_event(drv->ctx, type, &event);
1055 }
1056 
1057 
mlme_event_unprot_beacon(struct wpa_driver_nl80211_data * drv,const u8 * frame,size_t len)1058 static void mlme_event_unprot_beacon(struct wpa_driver_nl80211_data *drv,
1059 				     const u8 *frame, size_t len)
1060 {
1061 	const struct ieee80211_mgmt *mgmt;
1062 	union wpa_event_data event;
1063 
1064 	if (len < 24)
1065 		return;
1066 
1067 	mgmt = (const struct ieee80211_mgmt *) frame;
1068 
1069 	os_memset(&event, 0, sizeof(event));
1070 	event.unprot_beacon.sa = mgmt->sa;
1071 	wpa_supplicant_event(drv->ctx, EVENT_UNPROT_BEACON, &event);
1072 }
1073 
1074 
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,struct nlattr * req_ie)1075 static void mlme_event(struct i802_bss *bss,
1076 		       enum nl80211_commands cmd, struct nlattr *frame,
1077 		       struct nlattr *addr, struct nlattr *timed_out,
1078 		       struct nlattr *freq, struct nlattr *ack,
1079 		       struct nlattr *cookie, struct nlattr *sig,
1080 		       struct nlattr *wmm, struct nlattr *req_ie)
1081 {
1082 	struct wpa_driver_nl80211_data *drv = bss->drv;
1083 	const u8 *data;
1084 	size_t len;
1085 
1086 	if (timed_out && addr) {
1087 		mlme_timeout_event(drv, cmd, addr);
1088 		return;
1089 	}
1090 
1091 	if (frame == NULL) {
1092 		wpa_printf(MSG_DEBUG,
1093 			   "nl80211: MLME event %d (%s) without frame data",
1094 			   cmd, nl80211_command_to_string(cmd));
1095 		return;
1096 	}
1097 
1098 	data = nla_data(frame);
1099 	len = nla_len(frame);
1100 	if (len < 4 + 2 * ETH_ALEN) {
1101 		wpa_printf(MSG_MSGDUMP, "nl80211: MLME event %d (%s) on %s("
1102 			   MACSTR ") - too short",
1103 			   cmd, nl80211_command_to_string(cmd), bss->ifname,
1104 			   MAC2STR(bss->addr));
1105 		return;
1106 	}
1107 	wpa_printf(MSG_MSGDUMP, "nl80211: MLME event %d (%s) on %s(" MACSTR
1108 		   ") A1=" MACSTR " A2=" MACSTR, cmd,
1109 		   nl80211_command_to_string(cmd), bss->ifname,
1110 		   MAC2STR(bss->addr), MAC2STR(data + 4),
1111 		   MAC2STR(data + 4 + ETH_ALEN));
1112 	if (cmd != NL80211_CMD_FRAME_TX_STATUS && !(data[4] & 0x01) &&
1113 	    os_memcmp(bss->addr, data + 4, ETH_ALEN) != 0 &&
1114 	    (is_zero_ether_addr(bss->rand_addr) ||
1115 	     os_memcmp(bss->rand_addr, data + 4, ETH_ALEN) != 0) &&
1116 	    os_memcmp(bss->addr, data + 4 + ETH_ALEN, ETH_ALEN) != 0) {
1117 		wpa_printf(MSG_MSGDUMP, "nl80211: %s: Ignore MLME frame event "
1118 			   "for foreign address", bss->ifname);
1119 		return;
1120 	}
1121 	wpa_hexdump(MSG_MSGDUMP, "nl80211: MLME event frame",
1122 		    nla_data(frame), nla_len(frame));
1123 
1124 	switch (cmd) {
1125 	case NL80211_CMD_AUTHENTICATE:
1126 		mlme_event_auth(drv, nla_data(frame), nla_len(frame));
1127 		break;
1128 	case NL80211_CMD_ASSOCIATE:
1129 		mlme_event_assoc(drv, nla_data(frame), nla_len(frame), wmm,
1130 				 req_ie);
1131 		break;
1132 	case NL80211_CMD_DEAUTHENTICATE:
1133 		mlme_event_deauth_disassoc(drv, EVENT_DEAUTH,
1134 					   nla_data(frame), nla_len(frame));
1135 		break;
1136 	case NL80211_CMD_DISASSOCIATE:
1137 		mlme_event_deauth_disassoc(drv, EVENT_DISASSOC,
1138 					   nla_data(frame), nla_len(frame));
1139 		break;
1140 	case NL80211_CMD_FRAME:
1141 		mlme_event_mgmt(bss, freq, sig, nla_data(frame),
1142 				nla_len(frame));
1143 		break;
1144 	case NL80211_CMD_FRAME_TX_STATUS:
1145 		mlme_event_mgmt_tx_status(drv, cookie, nla_data(frame),
1146 					  nla_len(frame), ack);
1147 		break;
1148 	case NL80211_CMD_UNPROT_DEAUTHENTICATE:
1149 		mlme_event_unprot_disconnect(drv, EVENT_UNPROT_DEAUTH,
1150 					     nla_data(frame), nla_len(frame));
1151 		break;
1152 	case NL80211_CMD_UNPROT_DISASSOCIATE:
1153 		mlme_event_unprot_disconnect(drv, EVENT_UNPROT_DISASSOC,
1154 					     nla_data(frame), nla_len(frame));
1155 		break;
1156 	case NL80211_CMD_UNPROT_BEACON:
1157 		mlme_event_unprot_beacon(drv, nla_data(frame), nla_len(frame));
1158 		break;
1159 	default:
1160 		break;
1161 	}
1162 }
1163 
1164 
mlme_event_michael_mic_failure(struct i802_bss * bss,struct nlattr * tb[])1165 static void mlme_event_michael_mic_failure(struct i802_bss *bss,
1166 					   struct nlattr *tb[])
1167 {
1168 	union wpa_event_data data;
1169 
1170 	wpa_printf(MSG_DEBUG, "nl80211: MLME event Michael MIC failure");
1171 	os_memset(&data, 0, sizeof(data));
1172 	if (tb[NL80211_ATTR_MAC]) {
1173 		wpa_hexdump(MSG_DEBUG, "nl80211: Source MAC address",
1174 			    nla_data(tb[NL80211_ATTR_MAC]),
1175 			    nla_len(tb[NL80211_ATTR_MAC]));
1176 		data.michael_mic_failure.src = nla_data(tb[NL80211_ATTR_MAC]);
1177 	}
1178 	if (tb[NL80211_ATTR_KEY_SEQ]) {
1179 		wpa_hexdump(MSG_DEBUG, "nl80211: TSC",
1180 			    nla_data(tb[NL80211_ATTR_KEY_SEQ]),
1181 			    nla_len(tb[NL80211_ATTR_KEY_SEQ]));
1182 	}
1183 	if (tb[NL80211_ATTR_KEY_TYPE]) {
1184 		enum nl80211_key_type key_type =
1185 			nla_get_u32(tb[NL80211_ATTR_KEY_TYPE]);
1186 		wpa_printf(MSG_DEBUG, "nl80211: Key Type %d", key_type);
1187 		if (key_type == NL80211_KEYTYPE_PAIRWISE)
1188 			data.michael_mic_failure.unicast = 1;
1189 	} else
1190 		data.michael_mic_failure.unicast = 1;
1191 
1192 	if (tb[NL80211_ATTR_KEY_IDX]) {
1193 		u8 key_id = nla_get_u8(tb[NL80211_ATTR_KEY_IDX]);
1194 		wpa_printf(MSG_DEBUG, "nl80211: Key Id %d", key_id);
1195 	}
1196 
1197 	wpa_supplicant_event(bss->ctx, EVENT_MICHAEL_MIC_FAILURE, &data);
1198 }
1199 
1200 
mlme_event_join_ibss(struct wpa_driver_nl80211_data * drv,struct nlattr * tb[])1201 static void mlme_event_join_ibss(struct wpa_driver_nl80211_data *drv,
1202 				 struct nlattr *tb[])
1203 {
1204 	unsigned int freq;
1205 	union wpa_event_data event;
1206 
1207 	if (tb[NL80211_ATTR_MAC] == NULL) {
1208 		wpa_printf(MSG_DEBUG, "nl80211: No address in IBSS joined "
1209 			   "event");
1210 		return;
1211 	}
1212 	os_memcpy(drv->bssid, nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
1213 
1214 	drv->associated = 1;
1215 	wpa_printf(MSG_DEBUG, "nl80211: IBSS " MACSTR " joined",
1216 		   MAC2STR(drv->bssid));
1217 
1218 	freq = nl80211_get_assoc_freq(drv);
1219 	if (freq) {
1220 		wpa_printf(MSG_DEBUG, "nl80211: IBSS on frequency %u MHz",
1221 			   freq);
1222 		drv->first_bss->freq = freq;
1223 	}
1224 
1225 	os_memset(&event, 0, sizeof(event));
1226 	event.assoc_info.freq = freq;
1227 
1228 	wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event);
1229 }
1230 
1231 
mlme_event_remain_on_channel(struct wpa_driver_nl80211_data * drv,int cancel_event,struct nlattr * tb[])1232 static void mlme_event_remain_on_channel(struct wpa_driver_nl80211_data *drv,
1233 					 int cancel_event, struct nlattr *tb[])
1234 {
1235 	unsigned int freq, chan_type, duration;
1236 	union wpa_event_data data;
1237 	u64 cookie;
1238 
1239 	if (tb[NL80211_ATTR_WIPHY_FREQ])
1240 		freq = nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]);
1241 	else
1242 		freq = 0;
1243 
1244 	if (tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE])
1245 		chan_type = nla_get_u32(tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
1246 	else
1247 		chan_type = 0;
1248 
1249 	if (tb[NL80211_ATTR_DURATION])
1250 		duration = nla_get_u32(tb[NL80211_ATTR_DURATION]);
1251 	else
1252 		duration = 0;
1253 
1254 	if (tb[NL80211_ATTR_COOKIE])
1255 		cookie = nla_get_u64(tb[NL80211_ATTR_COOKIE]);
1256 	else
1257 		cookie = 0;
1258 
1259 	wpa_printf(MSG_DEBUG, "nl80211: Remain-on-channel event (cancel=%d "
1260 		   "freq=%u channel_type=%u duration=%u cookie=0x%llx (%s))",
1261 		   cancel_event, freq, chan_type, duration,
1262 		   (long long unsigned int) cookie,
1263 		   cookie == drv->remain_on_chan_cookie ? "match" : "unknown");
1264 
1265 	if (cookie != drv->remain_on_chan_cookie)
1266 		return; /* not for us */
1267 
1268 	if (cancel_event)
1269 		drv->pending_remain_on_chan = 0;
1270 
1271 	os_memset(&data, 0, sizeof(data));
1272 	data.remain_on_channel.freq = freq;
1273 	data.remain_on_channel.duration = duration;
1274 	wpa_supplicant_event(drv->ctx, cancel_event ?
1275 			     EVENT_CANCEL_REMAIN_ON_CHANNEL :
1276 			     EVENT_REMAIN_ON_CHANNEL, &data);
1277 }
1278 
1279 
mlme_event_ft_event(struct wpa_driver_nl80211_data * drv,struct nlattr * tb[])1280 static void mlme_event_ft_event(struct wpa_driver_nl80211_data *drv,
1281 				struct nlattr *tb[])
1282 {
1283 	union wpa_event_data data;
1284 
1285 	os_memset(&data, 0, sizeof(data));
1286 
1287 	if (tb[NL80211_ATTR_IE]) {
1288 		data.ft_ies.ies = nla_data(tb[NL80211_ATTR_IE]);
1289 		data.ft_ies.ies_len = nla_len(tb[NL80211_ATTR_IE]);
1290 	}
1291 
1292 	if (tb[NL80211_ATTR_IE_RIC]) {
1293 		data.ft_ies.ric_ies = nla_data(tb[NL80211_ATTR_IE_RIC]);
1294 		data.ft_ies.ric_ies_len = nla_len(tb[NL80211_ATTR_IE_RIC]);
1295 	}
1296 
1297 	if (tb[NL80211_ATTR_MAC])
1298 		os_memcpy(data.ft_ies.target_ap,
1299 			  nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
1300 
1301 	wpa_printf(MSG_DEBUG, "nl80211: FT event target_ap " MACSTR,
1302 		   MAC2STR(data.ft_ies.target_ap));
1303 
1304 	wpa_supplicant_event(drv->ctx, EVENT_FT_RESPONSE, &data);
1305 }
1306 
1307 
mlme_event_dh_event(struct wpa_driver_nl80211_data * drv,struct i802_bss * bss,struct nlattr * tb[])1308 static void mlme_event_dh_event(struct wpa_driver_nl80211_data *drv,
1309 				struct i802_bss *bss,
1310 				struct nlattr *tb[])
1311 {
1312 	union wpa_event_data data;
1313 
1314 	if (!is_ap_interface(drv->nlmode))
1315 		return;
1316 	if (!tb[NL80211_ATTR_MAC] || !tb[NL80211_ATTR_IE])
1317 		return;
1318 
1319 	os_memset(&data, 0, sizeof(data));
1320 	data.update_dh.peer = nla_data(tb[NL80211_ATTR_MAC]);
1321 	data.update_dh.ie = nla_data(tb[NL80211_ATTR_IE]);
1322 	data.update_dh.ie_len = nla_len(tb[NL80211_ATTR_IE]);
1323 
1324 	wpa_printf(MSG_DEBUG, "nl80211: DH event - peer " MACSTR,
1325 		   MAC2STR(data.update_dh.peer));
1326 
1327 	wpa_supplicant_event(bss->ctx, EVENT_UPDATE_DH, &data);
1328 }
1329 
1330 
send_scan_event(struct wpa_driver_nl80211_data * drv,int aborted,struct nlattr * tb[],int external_scan)1331 static void send_scan_event(struct wpa_driver_nl80211_data *drv, int aborted,
1332 			    struct nlattr *tb[], int external_scan)
1333 {
1334 	union wpa_event_data event;
1335 	struct nlattr *nl;
1336 	int rem;
1337 	struct scan_info *info;
1338 #define MAX_REPORT_FREQS 100
1339 	int freqs[MAX_REPORT_FREQS];
1340 	int num_freqs = 0;
1341 
1342 	if (!external_scan && drv->scan_for_auth) {
1343 		drv->scan_for_auth = 0;
1344 		wpa_printf(MSG_DEBUG, "nl80211: Scan results for missing "
1345 			   "cfg80211 BSS entry");
1346 		wpa_driver_nl80211_authenticate_retry(drv);
1347 		return;
1348 	}
1349 
1350 	os_memset(&event, 0, sizeof(event));
1351 	info = &event.scan_info;
1352 	info->aborted = aborted;
1353 	info->external_scan = external_scan;
1354 	info->nl_scan_event = 1;
1355 
1356 	if (tb[NL80211_ATTR_SCAN_SSIDS]) {
1357 		nla_for_each_nested(nl, tb[NL80211_ATTR_SCAN_SSIDS], rem) {
1358 			struct wpa_driver_scan_ssid *s =
1359 				&info->ssids[info->num_ssids];
1360 			s->ssid = nla_data(nl);
1361 			s->ssid_len = nla_len(nl);
1362 			wpa_printf(MSG_DEBUG, "nl80211: Scan probed for SSID '%s'",
1363 				   wpa_ssid_txt(s->ssid, s->ssid_len));
1364 			info->num_ssids++;
1365 			if (info->num_ssids == WPAS_MAX_SCAN_SSIDS)
1366 				break;
1367 		}
1368 	}
1369 	if (tb[NL80211_ATTR_SCAN_FREQUENCIES]) {
1370 		char msg[500], *pos, *end;
1371 		int res;
1372 
1373 		pos = msg;
1374 		end = pos + sizeof(msg);
1375 		*pos = '\0';
1376 
1377 		nla_for_each_nested(nl, tb[NL80211_ATTR_SCAN_FREQUENCIES], rem)
1378 		{
1379 			freqs[num_freqs] = nla_get_u32(nl);
1380 			res = os_snprintf(pos, end - pos, " %d",
1381 					  freqs[num_freqs]);
1382 			if (!os_snprintf_error(end - pos, res))
1383 				pos += res;
1384 			num_freqs++;
1385 			if (num_freqs == MAX_REPORT_FREQS - 1)
1386 				break;
1387 		}
1388 		info->freqs = freqs;
1389 		info->num_freqs = num_freqs;
1390 		wpa_printf(MSG_DEBUG, "nl80211: Scan included frequencies:%s",
1391 			   msg);
1392 	}
1393 
1394 	if (tb[NL80211_ATTR_SCAN_START_TIME_TSF] &&
1395 	    tb[NL80211_ATTR_SCAN_START_TIME_TSF_BSSID]) {
1396 		info->scan_start_tsf =
1397 			nla_get_u64(tb[NL80211_ATTR_SCAN_START_TIME_TSF]);
1398 		os_memcpy(info->scan_start_tsf_bssid,
1399 			  nla_data(tb[NL80211_ATTR_SCAN_START_TIME_TSF_BSSID]),
1400 			  ETH_ALEN);
1401 	}
1402 
1403 	wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS, &event);
1404 }
1405 
1406 
nl80211_cqm_event(struct wpa_driver_nl80211_data * drv,struct nlattr * tb[])1407 static void nl80211_cqm_event(struct wpa_driver_nl80211_data *drv,
1408 			      struct nlattr *tb[])
1409 {
1410 	static struct nla_policy cqm_policy[NL80211_ATTR_CQM_MAX + 1] = {
1411 		[NL80211_ATTR_CQM_RSSI_THOLD] = { .type = NLA_U32 },
1412 		[NL80211_ATTR_CQM_RSSI_HYST] = { .type = NLA_U8 },
1413 		[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] = { .type = NLA_U32 },
1414 		[NL80211_ATTR_CQM_PKT_LOSS_EVENT] = { .type = NLA_U32 },
1415 		[NL80211_ATTR_CQM_TXE_RATE] = { .type = NLA_U32 },
1416 		[NL80211_ATTR_CQM_TXE_PKTS] = { .type = NLA_U32 },
1417 		[NL80211_ATTR_CQM_TXE_INTVL] = { .type = NLA_U32 },
1418 		[NL80211_ATTR_CQM_BEACON_LOSS_EVENT] = { .type = NLA_FLAG },
1419 	};
1420 	struct nlattr *cqm[NL80211_ATTR_CQM_MAX + 1];
1421 	enum nl80211_cqm_rssi_threshold_event event;
1422 	union wpa_event_data ed;
1423 	int res;
1424 
1425 	if (tb[NL80211_ATTR_CQM] == NULL ||
1426 	    nla_parse_nested(cqm, NL80211_ATTR_CQM_MAX, tb[NL80211_ATTR_CQM],
1427 			     cqm_policy)) {
1428 		wpa_printf(MSG_DEBUG, "nl80211: Ignore invalid CQM event");
1429 		return;
1430 	}
1431 
1432 	os_memset(&ed, 0, sizeof(ed));
1433 
1434 	if (cqm[NL80211_ATTR_CQM_PKT_LOSS_EVENT]) {
1435 		if (!tb[NL80211_ATTR_MAC])
1436 			return;
1437 		os_memcpy(ed.low_ack.addr, nla_data(tb[NL80211_ATTR_MAC]),
1438 			  ETH_ALEN);
1439 		ed.low_ack.num_packets =
1440 			nla_get_u32(cqm[NL80211_ATTR_CQM_PKT_LOSS_EVENT]);
1441 		wpa_printf(MSG_DEBUG, "nl80211: Packet loss event for " MACSTR
1442 			   " (num_packets %u)",
1443 			   MAC2STR(ed.low_ack.addr), ed.low_ack.num_packets);
1444 		wpa_supplicant_event(drv->ctx, EVENT_STATION_LOW_ACK, &ed);
1445 		return;
1446 	}
1447 
1448 	if (cqm[NL80211_ATTR_CQM_BEACON_LOSS_EVENT]) {
1449 		wpa_printf(MSG_DEBUG, "nl80211: Beacon loss event");
1450 		wpa_supplicant_event(drv->ctx, EVENT_BEACON_LOSS, NULL);
1451 		return;
1452 	}
1453 
1454 	if (cqm[NL80211_ATTR_CQM_TXE_RATE] &&
1455 	    cqm[NL80211_ATTR_CQM_TXE_PKTS] &&
1456 	    cqm[NL80211_ATTR_CQM_TXE_INTVL] &&
1457 	    cqm[NL80211_ATTR_MAC]) {
1458 		wpa_printf(MSG_DEBUG, "nl80211: CQM TXE event for " MACSTR
1459 			   " (rate: %u pkts: %u interval: %u)",
1460 			   MAC2STR((u8 *) nla_data(cqm[NL80211_ATTR_MAC])),
1461 			   nla_get_u32(cqm[NL80211_ATTR_CQM_TXE_RATE]),
1462 			   nla_get_u32(cqm[NL80211_ATTR_CQM_TXE_PKTS]),
1463 			   nla_get_u32(cqm[NL80211_ATTR_CQM_TXE_INTVL]));
1464 		return;
1465 	}
1466 
1467 	if (cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] == NULL) {
1468 		wpa_printf(MSG_DEBUG,
1469 			   "nl80211: Not a CQM RSSI threshold event");
1470 		return;
1471 	}
1472 	event = nla_get_u32(cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT]);
1473 
1474 	if (event == NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH) {
1475 		wpa_printf(MSG_DEBUG, "nl80211: Connection quality monitor "
1476 			   "event: RSSI high");
1477 		ed.signal_change.above_threshold = 1;
1478 	} else if (event == NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW) {
1479 		wpa_printf(MSG_DEBUG, "nl80211: Connection quality monitor "
1480 			   "event: RSSI low");
1481 		ed.signal_change.above_threshold = 0;
1482 	} else {
1483 		wpa_printf(MSG_DEBUG,
1484 			   "nl80211: Unknown CQM RSSI threshold event: %d",
1485 			   event);
1486 		return;
1487 	}
1488 
1489 	/*
1490 	 * nl80211_get_link_signal() and nl80211_get_link_noise() set default
1491 	 * values in case querying the driver fails.
1492 	 */
1493 	res = nl80211_get_link_signal(drv, &ed.signal_change);
1494 	if (res == 0) {
1495 		wpa_printf(MSG_DEBUG, "nl80211: Signal: %d dBm  txrate: %d",
1496 			   ed.signal_change.current_signal,
1497 			   ed.signal_change.current_txrate);
1498 	} else {
1499 		wpa_printf(MSG_DEBUG,
1500 			   "nl80211: Querying the driver for signal info failed");
1501 	}
1502 
1503 	res = nl80211_get_link_noise(drv, &ed.signal_change);
1504 	if (res == 0) {
1505 		wpa_printf(MSG_DEBUG, "nl80211: Noise: %d dBm",
1506 			   ed.signal_change.current_noise);
1507 	} else {
1508 		wpa_printf(MSG_DEBUG,
1509 			   "nl80211: Querying the driver for noise info failed");
1510 	}
1511 
1512 	wpa_supplicant_event(drv->ctx, EVENT_SIGNAL_CHANGE, &ed);
1513 }
1514 
1515 
nl80211_new_peer_candidate(struct wpa_driver_nl80211_data * drv,struct nlattr ** tb)1516 static void nl80211_new_peer_candidate(struct wpa_driver_nl80211_data *drv,
1517 				       struct nlattr **tb)
1518 {
1519 	const u8 *addr;
1520 	union wpa_event_data data;
1521 
1522 	if (drv->nlmode != NL80211_IFTYPE_MESH_POINT ||
1523 	    !tb[NL80211_ATTR_MAC] || !tb[NL80211_ATTR_IE])
1524 		return;
1525 
1526 	addr = nla_data(tb[NL80211_ATTR_MAC]);
1527 	wpa_printf(MSG_DEBUG, "nl80211: New peer candidate " MACSTR,
1528 		   MAC2STR(addr));
1529 
1530 	os_memset(&data, 0, sizeof(data));
1531 	data.mesh_peer.peer = addr;
1532 	data.mesh_peer.ies = nla_data(tb[NL80211_ATTR_IE]);
1533 	data.mesh_peer.ie_len = nla_len(tb[NL80211_ATTR_IE]);
1534 	wpa_supplicant_event(drv->ctx, EVENT_NEW_PEER_CANDIDATE, &data);
1535 }
1536 
1537 
nl80211_new_station_event(struct wpa_driver_nl80211_data * drv,struct i802_bss * bss,struct nlattr ** tb)1538 static void nl80211_new_station_event(struct wpa_driver_nl80211_data *drv,
1539 				      struct i802_bss *bss,
1540 				      struct nlattr **tb)
1541 {
1542 	u8 *addr;
1543 	union wpa_event_data data;
1544 
1545 	if (tb[NL80211_ATTR_MAC] == NULL)
1546 		return;
1547 	addr = nla_data(tb[NL80211_ATTR_MAC]);
1548 	wpa_printf(MSG_DEBUG, "nl80211: New station " MACSTR, MAC2STR(addr));
1549 
1550 	if (is_ap_interface(drv->nlmode) && drv->device_ap_sme) {
1551 		u8 *ies = NULL;
1552 		size_t ies_len = 0;
1553 		if (tb[NL80211_ATTR_IE]) {
1554 			ies = nla_data(tb[NL80211_ATTR_IE]);
1555 			ies_len = nla_len(tb[NL80211_ATTR_IE]);
1556 		}
1557 		wpa_hexdump(MSG_DEBUG, "nl80211: Assoc Req IEs", ies, ies_len);
1558 		drv_event_assoc(bss->ctx, addr, ies, ies_len, 0);
1559 		return;
1560 	}
1561 
1562 	if (drv->nlmode != NL80211_IFTYPE_ADHOC)
1563 		return;
1564 
1565 	os_memset(&data, 0, sizeof(data));
1566 	os_memcpy(data.ibss_rsn_start.peer, addr, ETH_ALEN);
1567 	wpa_supplicant_event(bss->ctx, EVENT_IBSS_RSN_START, &data);
1568 }
1569 
1570 
nl80211_del_station_event(struct wpa_driver_nl80211_data * drv,struct i802_bss * bss,struct nlattr ** tb)1571 static void nl80211_del_station_event(struct wpa_driver_nl80211_data *drv,
1572 				      struct i802_bss *bss,
1573 				      struct nlattr **tb)
1574 {
1575 	u8 *addr;
1576 	union wpa_event_data data;
1577 
1578 	if (tb[NL80211_ATTR_MAC] == NULL)
1579 		return;
1580 	addr = nla_data(tb[NL80211_ATTR_MAC]);
1581 	wpa_printf(MSG_DEBUG, "nl80211: Delete station " MACSTR,
1582 		   MAC2STR(addr));
1583 
1584 	if (is_ap_interface(drv->nlmode) && drv->device_ap_sme) {
1585 		drv_event_disassoc(bss->ctx, addr);
1586 		return;
1587 	}
1588 
1589 	if (drv->nlmode != NL80211_IFTYPE_ADHOC)
1590 		return;
1591 
1592 	os_memset(&data, 0, sizeof(data));
1593 	os_memcpy(data.ibss_peer_lost.peer, addr, ETH_ALEN);
1594 	wpa_supplicant_event(bss->ctx, EVENT_IBSS_PEER_LOST, &data);
1595 }
1596 
1597 
nl80211_rekey_offload_event(struct wpa_driver_nl80211_data * drv,struct nlattr ** tb)1598 static void nl80211_rekey_offload_event(struct wpa_driver_nl80211_data *drv,
1599 					struct nlattr **tb)
1600 {
1601 	struct nlattr *rekey_info[NUM_NL80211_REKEY_DATA];
1602 	static struct nla_policy rekey_policy[NUM_NL80211_REKEY_DATA] = {
1603 		[NL80211_REKEY_DATA_KEK] = {
1604 			.minlen = NL80211_KEK_LEN,
1605 			.maxlen = NL80211_KEK_LEN,
1606 		},
1607 		[NL80211_REKEY_DATA_KCK] = {
1608 			.minlen = NL80211_KCK_LEN,
1609 			.maxlen = NL80211_KCK_LEN,
1610 		},
1611 		[NL80211_REKEY_DATA_REPLAY_CTR] = {
1612 			.minlen = NL80211_REPLAY_CTR_LEN,
1613 			.maxlen = NL80211_REPLAY_CTR_LEN,
1614 		},
1615 	};
1616 	union wpa_event_data data;
1617 
1618 	if (!tb[NL80211_ATTR_MAC] ||
1619 	    !tb[NL80211_ATTR_REKEY_DATA] ||
1620 	    nla_parse_nested(rekey_info, MAX_NL80211_REKEY_DATA,
1621 			     tb[NL80211_ATTR_REKEY_DATA], rekey_policy) ||
1622 	    !rekey_info[NL80211_REKEY_DATA_REPLAY_CTR])
1623 		return;
1624 
1625 	os_memset(&data, 0, sizeof(data));
1626 	data.driver_gtk_rekey.bssid = nla_data(tb[NL80211_ATTR_MAC]);
1627 	wpa_printf(MSG_DEBUG, "nl80211: Rekey offload event for BSSID " MACSTR,
1628 		   MAC2STR(data.driver_gtk_rekey.bssid));
1629 	data.driver_gtk_rekey.replay_ctr =
1630 		nla_data(rekey_info[NL80211_REKEY_DATA_REPLAY_CTR]);
1631 	wpa_hexdump(MSG_DEBUG, "nl80211: Rekey offload - Replay Counter",
1632 		    data.driver_gtk_rekey.replay_ctr, NL80211_REPLAY_CTR_LEN);
1633 	wpa_supplicant_event(drv->ctx, EVENT_DRIVER_GTK_REKEY, &data);
1634 }
1635 
1636 
nl80211_pmksa_candidate_event(struct wpa_driver_nl80211_data * drv,struct nlattr ** tb)1637 static void nl80211_pmksa_candidate_event(struct wpa_driver_nl80211_data *drv,
1638 					  struct nlattr **tb)
1639 {
1640 	struct nlattr *cand[NUM_NL80211_PMKSA_CANDIDATE];
1641 	static struct nla_policy cand_policy[NUM_NL80211_PMKSA_CANDIDATE] = {
1642 		[NL80211_PMKSA_CANDIDATE_INDEX] = { .type = NLA_U32 },
1643 		[NL80211_PMKSA_CANDIDATE_BSSID] = {
1644 			.minlen = ETH_ALEN,
1645 			.maxlen = ETH_ALEN,
1646 		},
1647 		[NL80211_PMKSA_CANDIDATE_PREAUTH] = { .type = NLA_FLAG },
1648 	};
1649 	union wpa_event_data data;
1650 
1651 	wpa_printf(MSG_DEBUG, "nl80211: PMKSA candidate event");
1652 
1653 	if (!tb[NL80211_ATTR_PMKSA_CANDIDATE] ||
1654 	    nla_parse_nested(cand, MAX_NL80211_PMKSA_CANDIDATE,
1655 			     tb[NL80211_ATTR_PMKSA_CANDIDATE], cand_policy) ||
1656 	    !cand[NL80211_PMKSA_CANDIDATE_INDEX] ||
1657 	    !cand[NL80211_PMKSA_CANDIDATE_BSSID])
1658 		return;
1659 
1660 	os_memset(&data, 0, sizeof(data));
1661 	os_memcpy(data.pmkid_candidate.bssid,
1662 		  nla_data(cand[NL80211_PMKSA_CANDIDATE_BSSID]), ETH_ALEN);
1663 	data.pmkid_candidate.index =
1664 		nla_get_u32(cand[NL80211_PMKSA_CANDIDATE_INDEX]);
1665 	data.pmkid_candidate.preauth =
1666 		cand[NL80211_PMKSA_CANDIDATE_PREAUTH] != NULL;
1667 	wpa_supplicant_event(drv->ctx, EVENT_PMKID_CANDIDATE, &data);
1668 }
1669 
1670 
nl80211_client_probe_event(struct wpa_driver_nl80211_data * drv,struct nlattr ** tb)1671 static void nl80211_client_probe_event(struct wpa_driver_nl80211_data *drv,
1672 				       struct nlattr **tb)
1673 {
1674 	union wpa_event_data data;
1675 	const u8 *addr;
1676 	u64 cookie = 0;
1677 
1678 	addr = nla_data(tb[NL80211_ATTR_MAC]);
1679 	if (!addr)
1680 		return;
1681 	if (tb[NL80211_ATTR_COOKIE])
1682 		cookie = nla_get_u64(tb[NL80211_ATTR_COOKIE]);
1683 	wpa_printf(MSG_DEBUG, "nl80211: Probe client event (addr=" MACSTR
1684 		   " ack=%d cookie=%llu)", MAC2STR(addr),
1685 		   tb[NL80211_ATTR_ACK] != NULL,
1686 		   (long long unsigned int) cookie);
1687 	if (!tb[NL80211_ATTR_ACK])
1688 		return;
1689 
1690 	os_memset(&data, 0, sizeof(data));
1691 	os_memcpy(data.client_poll.addr, addr, ETH_ALEN);
1692 	wpa_supplicant_event(drv->ctx, EVENT_DRIVER_CLIENT_POLL_OK, &data);
1693 }
1694 
1695 
nl80211_tdls_oper_event(struct wpa_driver_nl80211_data * drv,struct nlattr ** tb)1696 static void nl80211_tdls_oper_event(struct wpa_driver_nl80211_data *drv,
1697 				    struct nlattr **tb)
1698 {
1699 	union wpa_event_data data;
1700 
1701 	wpa_printf(MSG_DEBUG, "nl80211: TDLS operation event");
1702 
1703 	if (!tb[NL80211_ATTR_MAC] || !tb[NL80211_ATTR_TDLS_OPERATION])
1704 		return;
1705 
1706 	os_memset(&data, 0, sizeof(data));
1707 	os_memcpy(data.tdls.peer, nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
1708 	switch (nla_get_u8(tb[NL80211_ATTR_TDLS_OPERATION])) {
1709 	case NL80211_TDLS_SETUP:
1710 		wpa_printf(MSG_DEBUG, "nl80211: TDLS setup request for peer "
1711 			   MACSTR, MAC2STR(data.tdls.peer));
1712 		data.tdls.oper = TDLS_REQUEST_SETUP;
1713 		break;
1714 	case NL80211_TDLS_TEARDOWN:
1715 		wpa_printf(MSG_DEBUG, "nl80211: TDLS teardown request for peer "
1716 			   MACSTR, MAC2STR(data.tdls.peer));
1717 		data.tdls.oper = TDLS_REQUEST_TEARDOWN;
1718 		break;
1719 	case NL80211_TDLS_DISCOVERY_REQ:
1720 		wpa_printf(MSG_DEBUG,
1721 			   "nl80211: TDLS discovery request for peer " MACSTR,
1722 			   MAC2STR(data.tdls.peer));
1723 		data.tdls.oper = TDLS_REQUEST_DISCOVER;
1724 		break;
1725 	default:
1726 		wpa_printf(MSG_DEBUG, "nl80211: Unsupported TDLS operatione "
1727 			   "event");
1728 		return;
1729 	}
1730 	if (tb[NL80211_ATTR_REASON_CODE]) {
1731 		data.tdls.reason_code =
1732 			nla_get_u16(tb[NL80211_ATTR_REASON_CODE]);
1733 	}
1734 
1735 	wpa_supplicant_event(drv->ctx, EVENT_TDLS, &data);
1736 }
1737 
1738 
nl80211_stop_ap(struct wpa_driver_nl80211_data * drv,struct nlattr ** tb)1739 static void nl80211_stop_ap(struct wpa_driver_nl80211_data *drv,
1740 			    struct nlattr **tb)
1741 {
1742 	wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_UNAVAILABLE, NULL);
1743 }
1744 
1745 
nl80211_connect_failed_event(struct wpa_driver_nl80211_data * drv,struct nlattr ** tb)1746 static void nl80211_connect_failed_event(struct wpa_driver_nl80211_data *drv,
1747 					 struct nlattr **tb)
1748 {
1749 	union wpa_event_data data;
1750 	u32 reason;
1751 
1752 	wpa_printf(MSG_DEBUG, "nl80211: Connect failed event");
1753 
1754 	if (!tb[NL80211_ATTR_MAC] || !tb[NL80211_ATTR_CONN_FAILED_REASON])
1755 		return;
1756 
1757 	os_memset(&data, 0, sizeof(data));
1758 	os_memcpy(data.connect_failed_reason.addr,
1759 		  nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
1760 
1761 	reason = nla_get_u32(tb[NL80211_ATTR_CONN_FAILED_REASON]);
1762 	switch (reason) {
1763 	case NL80211_CONN_FAIL_MAX_CLIENTS:
1764 		wpa_printf(MSG_DEBUG, "nl80211: Max client reached");
1765 		data.connect_failed_reason.code = MAX_CLIENT_REACHED;
1766 		break;
1767 	case NL80211_CONN_FAIL_BLOCKED_CLIENT:
1768 		wpa_printf(MSG_DEBUG, "nl80211: Blocked client " MACSTR
1769 			   " tried to connect",
1770 			   MAC2STR(data.connect_failed_reason.addr));
1771 		data.connect_failed_reason.code = BLOCKED_CLIENT;
1772 		break;
1773 	default:
1774 		wpa_printf(MSG_DEBUG, "nl8021l: Unknown connect failed reason "
1775 			   "%u", reason);
1776 		return;
1777 	}
1778 
1779 	wpa_supplicant_event(drv->ctx, EVENT_CONNECT_FAILED_REASON, &data);
1780 }
1781 
1782 
nl80211_radar_event(struct wpa_driver_nl80211_data * drv,struct nlattr ** tb)1783 static void nl80211_radar_event(struct wpa_driver_nl80211_data *drv,
1784 				struct nlattr **tb)
1785 {
1786 	union wpa_event_data data;
1787 	enum nl80211_radar_event event_type;
1788 
1789 	if (!tb[NL80211_ATTR_WIPHY_FREQ] || !tb[NL80211_ATTR_RADAR_EVENT])
1790 		return;
1791 
1792 	os_memset(&data, 0, sizeof(data));
1793 	data.dfs_event.freq = nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]);
1794 	event_type = nla_get_u32(tb[NL80211_ATTR_RADAR_EVENT]);
1795 
1796 	/* Check HT params */
1797 	if (tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
1798 		data.dfs_event.ht_enabled = 1;
1799 		data.dfs_event.chan_offset = 0;
1800 
1801 		switch (nla_get_u32(tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE])) {
1802 		case NL80211_CHAN_NO_HT:
1803 			data.dfs_event.ht_enabled = 0;
1804 			break;
1805 		case NL80211_CHAN_HT20:
1806 			break;
1807 		case NL80211_CHAN_HT40PLUS:
1808 			data.dfs_event.chan_offset = 1;
1809 			break;
1810 		case NL80211_CHAN_HT40MINUS:
1811 			data.dfs_event.chan_offset = -1;
1812 			break;
1813 		}
1814 	}
1815 
1816 	/* Get VHT params */
1817 	if (tb[NL80211_ATTR_CHANNEL_WIDTH])
1818 		data.dfs_event.chan_width =
1819 			convert2width(nla_get_u32(
1820 					      tb[NL80211_ATTR_CHANNEL_WIDTH]));
1821 	if (tb[NL80211_ATTR_CENTER_FREQ1])
1822 		data.dfs_event.cf1 = nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ1]);
1823 	if (tb[NL80211_ATTR_CENTER_FREQ2])
1824 		data.dfs_event.cf2 = nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ2]);
1825 
1826 	wpa_printf(MSG_DEBUG, "nl80211: DFS event on freq %d MHz, ht: %d, offset: %d, width: %d, cf1: %dMHz, cf2: %dMHz",
1827 		   data.dfs_event.freq, data.dfs_event.ht_enabled,
1828 		   data.dfs_event.chan_offset, data.dfs_event.chan_width,
1829 		   data.dfs_event.cf1, data.dfs_event.cf2);
1830 
1831 	switch (event_type) {
1832 	case NL80211_RADAR_DETECTED:
1833 		wpa_supplicant_event(drv->ctx, EVENT_DFS_RADAR_DETECTED, &data);
1834 		break;
1835 	case NL80211_RADAR_CAC_FINISHED:
1836 		wpa_supplicant_event(drv->ctx, EVENT_DFS_CAC_FINISHED, &data);
1837 		break;
1838 	case NL80211_RADAR_CAC_ABORTED:
1839 		wpa_supplicant_event(drv->ctx, EVENT_DFS_CAC_ABORTED, &data);
1840 		break;
1841 	case NL80211_RADAR_NOP_FINISHED:
1842 		wpa_supplicant_event(drv->ctx, EVENT_DFS_NOP_FINISHED, &data);
1843 		break;
1844 	case NL80211_RADAR_PRE_CAC_EXPIRED:
1845 		wpa_supplicant_event(drv->ctx, EVENT_DFS_PRE_CAC_EXPIRED,
1846 				     &data);
1847 		break;
1848 	case NL80211_RADAR_CAC_STARTED:
1849 		wpa_supplicant_event(drv->ctx, EVENT_DFS_CAC_STARTED, &data);
1850 		break;
1851 	default:
1852 		wpa_printf(MSG_DEBUG, "nl80211: Unknown radar event %d "
1853 			   "received", event_type);
1854 		break;
1855 	}
1856 }
1857 
1858 
nl80211_spurious_frame(struct i802_bss * bss,struct nlattr ** tb,int wds)1859 static void nl80211_spurious_frame(struct i802_bss *bss, struct nlattr **tb,
1860 				   int wds)
1861 {
1862 	struct wpa_driver_nl80211_data *drv = bss->drv;
1863 	union wpa_event_data event;
1864 
1865 	if (!tb[NL80211_ATTR_MAC])
1866 		return;
1867 
1868 	os_memset(&event, 0, sizeof(event));
1869 	event.rx_from_unknown.bssid = bss->addr;
1870 	event.rx_from_unknown.addr = nla_data(tb[NL80211_ATTR_MAC]);
1871 	event.rx_from_unknown.wds = wds;
1872 
1873 	wpa_supplicant_event(drv->ctx, EVENT_RX_FROM_UNKNOWN, &event);
1874 }
1875 
1876 #ifdef CONFIG_DRIVER_NL80211_QCA
1877 
qca_nl80211_avoid_freq(struct wpa_driver_nl80211_data * drv,const u8 * data,size_t len)1878 static void qca_nl80211_avoid_freq(struct wpa_driver_nl80211_data *drv,
1879 				   const u8 *data, size_t len)
1880 {
1881 	u32 i, count;
1882 	union wpa_event_data event;
1883 	struct wpa_freq_range *range = NULL;
1884 	const struct qca_avoid_freq_list *freq_range;
1885 
1886 	freq_range = (const struct qca_avoid_freq_list *) data;
1887 	if (len < sizeof(freq_range->count))
1888 		return;
1889 
1890 	count = freq_range->count;
1891 	if (len < sizeof(freq_range->count) +
1892 	    count * sizeof(struct qca_avoid_freq_range)) {
1893 		wpa_printf(MSG_DEBUG, "nl80211: Ignored too short avoid frequency list (len=%u)",
1894 			   (unsigned int) len);
1895 		return;
1896 	}
1897 
1898 	if (count > 0) {
1899 		range = os_calloc(count, sizeof(struct wpa_freq_range));
1900 		if (range == NULL)
1901 			return;
1902 	}
1903 
1904 	os_memset(&event, 0, sizeof(event));
1905 	for (i = 0; i < count; i++) {
1906 		unsigned int idx = event.freq_range.num;
1907 		range[idx].min = freq_range->range[i].start_freq;
1908 		range[idx].max = freq_range->range[i].end_freq;
1909 		wpa_printf(MSG_DEBUG, "nl80211: Avoid frequency range: %u-%u",
1910 			   range[idx].min, range[idx].max);
1911 		if (range[idx].min > range[idx].max) {
1912 			wpa_printf(MSG_DEBUG, "nl80211: Ignore invalid frequency range");
1913 			continue;
1914 		}
1915 		event.freq_range.num++;
1916 	}
1917 	event.freq_range.range = range;
1918 
1919 	wpa_supplicant_event(drv->ctx, EVENT_AVOID_FREQUENCIES, &event);
1920 
1921 	os_free(range);
1922 }
1923 
1924 
get_qca_hw_mode(u8 hw_mode)1925 static enum hostapd_hw_mode get_qca_hw_mode(u8 hw_mode)
1926 {
1927 	switch (hw_mode) {
1928 	case QCA_ACS_MODE_IEEE80211B:
1929 		return HOSTAPD_MODE_IEEE80211B;
1930 	case QCA_ACS_MODE_IEEE80211G:
1931 		return HOSTAPD_MODE_IEEE80211G;
1932 	case QCA_ACS_MODE_IEEE80211A:
1933 		return HOSTAPD_MODE_IEEE80211A;
1934 	case QCA_ACS_MODE_IEEE80211AD:
1935 		return HOSTAPD_MODE_IEEE80211AD;
1936 	case QCA_ACS_MODE_IEEE80211ANY:
1937 		return HOSTAPD_MODE_IEEE80211ANY;
1938 	default:
1939 		return NUM_HOSTAPD_MODES;
1940 	}
1941 }
1942 
1943 
chan_to_freq(struct wpa_driver_nl80211_data * drv,u8 chan,enum hostapd_hw_mode hw_mode)1944 static unsigned int chan_to_freq(struct wpa_driver_nl80211_data *drv,
1945 				 u8 chan, enum hostapd_hw_mode hw_mode)
1946 {
1947 	if (hw_mode == NUM_HOSTAPD_MODES) {
1948 		/* For drivers that do not report ACS_HW_MODE */
1949 		u16 num_modes, flags;
1950 		struct hostapd_hw_modes *modes;
1951 		u8 dfs_domain;
1952 		int i;
1953 
1954 		modes = nl80211_get_hw_feature_data(drv->first_bss, &num_modes,
1955 						    &flags, &dfs_domain);
1956 		if (!modes) {
1957 			wpa_printf(MSG_DEBUG,
1958 				   "nl80211: Fetching hardware mode failed");
1959 			goto try_2_4_or_5;
1960 		}
1961 		if (num_modes == 1)
1962 			hw_mode = modes[0].mode;
1963 
1964 		for (i = 0; i < num_modes; i++) {
1965 			os_free(modes[i].channels);
1966 			os_free(modes[i].rates);
1967 		}
1968 
1969 		os_free(modes);
1970 	}
1971 
1972 	if (hw_mode == HOSTAPD_MODE_IEEE80211AD) {
1973 		if (chan >= 1 && chan <= 6)
1974 			return 56160 + (2160 * chan);
1975 		return 0;
1976 	}
1977 
1978 try_2_4_or_5:
1979 	if (chan >= 1 && chan <= 13)
1980 		return 2407 + 5 * chan;
1981 	if (chan == 14)
1982 		return 2484;
1983 	if (chan >= 36 && chan <= 177)
1984 		return 5000 + 5 * chan;
1985 
1986 	return 0;
1987 }
1988 
1989 
qca_nl80211_acs_select_ch(struct wpa_driver_nl80211_data * drv,const u8 * data,size_t len)1990 static void qca_nl80211_acs_select_ch(struct wpa_driver_nl80211_data *drv,
1991 				   const u8 *data, size_t len)
1992 {
1993 	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_ACS_MAX + 1];
1994 	union wpa_event_data event;
1995 	u8 chan;
1996 
1997 	wpa_printf(MSG_DEBUG,
1998 		   "nl80211: ACS channel selection vendor event received");
1999 
2000 	if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_ACS_MAX,
2001 		      (struct nlattr *) data, len, NULL) ||
2002 	    (!tb[QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_FREQUENCY] &&
2003 	     !tb[QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL]) ||
2004 	    (!tb[QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_FREQUENCY] &&
2005 	     !tb[QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL]))
2006 		return;
2007 
2008 	os_memset(&event, 0, sizeof(event));
2009 	event.acs_selected_channels.hw_mode = NUM_HOSTAPD_MODES;
2010 
2011 	if (tb[QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE]) {
2012 		u8 hw_mode = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE]);
2013 
2014 		event.acs_selected_channels.hw_mode = get_qca_hw_mode(hw_mode);
2015 		if (event.acs_selected_channels.hw_mode == NUM_HOSTAPD_MODES ||
2016 		    event.acs_selected_channels.hw_mode ==
2017 		    HOSTAPD_MODE_IEEE80211ANY) {
2018 			wpa_printf(MSG_DEBUG,
2019 				   "nl80211: Invalid hw_mode %d in ACS selection event",
2020 				   hw_mode);
2021 			return;
2022 		}
2023 	}
2024 
2025 	if (tb[QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_FREQUENCY]) {
2026 		event.acs_selected_channels.pri_freq = nla_get_u32(
2027 			tb[QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_FREQUENCY]);
2028 	} else {
2029 		chan = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL]);
2030 		event.acs_selected_channels.pri_freq =
2031 			chan_to_freq(drv, chan,
2032 				     event.acs_selected_channels.hw_mode);
2033 	}
2034 
2035 	if (tb[QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_FREQUENCY]) {
2036 		event.acs_selected_channels.sec_freq = nla_get_u32(
2037 			tb[QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_FREQUENCY]);
2038 	} else {
2039 		chan = nla_get_u8(
2040 			tb[QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL]);
2041 		event.acs_selected_channels.sec_freq =
2042 			chan_to_freq(drv, chan,
2043 				     event.acs_selected_channels.hw_mode);
2044 	}
2045 
2046 	if (tb[QCA_WLAN_VENDOR_ATTR_ACS_EDMG_CHANNEL])
2047 		event.acs_selected_channels.edmg_channel =
2048 			nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_EDMG_CHANNEL]);
2049 	if (tb[QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL])
2050 		event.acs_selected_channels.vht_seg0_center_ch =
2051 			nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL]);
2052 	if (tb[QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL])
2053 		event.acs_selected_channels.vht_seg1_center_ch =
2054 			nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL]);
2055 	if (tb[QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH])
2056 		event.acs_selected_channels.ch_width =
2057 			nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH]);
2058 	wpa_printf(MSG_INFO,
2059 		   "nl80211: ACS Results: PFreq: %d SFreq: %d BW: %d VHT0: %d VHT1: %d HW_MODE: %d EDMGCH: %d",
2060 		   event.acs_selected_channels.pri_freq,
2061 		   event.acs_selected_channels.sec_freq,
2062 		   event.acs_selected_channels.ch_width,
2063 		   event.acs_selected_channels.vht_seg0_center_ch,
2064 		   event.acs_selected_channels.vht_seg1_center_ch,
2065 		   event.acs_selected_channels.hw_mode,
2066 		   event.acs_selected_channels.edmg_channel);
2067 
2068 	/* Ignore ACS channel list check for backwards compatibility */
2069 
2070 	wpa_supplicant_event(drv->ctx, EVENT_ACS_CHANNEL_SELECTED, &event);
2071 }
2072 
2073 
qca_nl80211_key_mgmt_auth(struct wpa_driver_nl80211_data * drv,const u8 * data,size_t len)2074 static void qca_nl80211_key_mgmt_auth(struct wpa_driver_nl80211_data *drv,
2075 				      const u8 *data, size_t len)
2076 {
2077 	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_MAX + 1];
2078 	u8 *bssid;
2079 
2080 	wpa_printf(MSG_DEBUG,
2081 		   "nl80211: Key management roam+auth vendor event received");
2082 
2083 	if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_MAX,
2084 		      (struct nlattr *) data, len, NULL) ||
2085 	    !tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_BSSID] ||
2086 	    nla_len(tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_BSSID]) != ETH_ALEN ||
2087 	    !tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_REQ_IE] ||
2088 	    !tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_RESP_IE] ||
2089 	    !tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_AUTHORIZED])
2090 		return;
2091 
2092 	bssid = nla_data(tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_BSSID]);
2093 	wpa_printf(MSG_DEBUG, "  * roam BSSID " MACSTR, MAC2STR(bssid));
2094 
2095 	mlme_event_connect(drv, NL80211_CMD_ROAM, NULL,
2096 			   tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_BSSID],
2097 			   tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_REQ_IE],
2098 			   tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_RESP_IE],
2099 			   NULL, NULL,
2100 			   tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_AUTHORIZED],
2101 			   tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_KEY_REPLAY_CTR],
2102 			   tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KCK],
2103 			   tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KEK],
2104 			   tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_SUBNET_STATUS],
2105 			   tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_FILS_ERP_NEXT_SEQ_NUM],
2106 			   tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PMK],
2107 			   tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PMKID]);
2108 }
2109 
2110 
2111 static void
qca_nl80211_key_mgmt_auth_handler(struct wpa_driver_nl80211_data * drv,const u8 * data,size_t len)2112 qca_nl80211_key_mgmt_auth_handler(struct wpa_driver_nl80211_data *drv,
2113 				  const u8 *data, size_t len)
2114 {
2115 	if (!drv->roam_indication_done) {
2116 		wpa_printf(MSG_DEBUG,
2117 			   "nl80211: Pending roam indication, delay processing roam+auth vendor event");
2118 		os_get_reltime(&drv->pending_roam_ind_time);
2119 
2120 		os_free(drv->pending_roam_data);
2121 		drv->pending_roam_data = os_memdup(data, len);
2122 		if (!drv->pending_roam_data)
2123 			return;
2124 		drv->pending_roam_data_len = len;
2125 		return;
2126 	}
2127 	drv->roam_indication_done = false;
2128 	qca_nl80211_key_mgmt_auth(drv, data, len);
2129 }
2130 
2131 
qca_nl80211_dfs_offload_radar_event(struct wpa_driver_nl80211_data * drv,u32 subcmd,u8 * msg,int length)2132 static void qca_nl80211_dfs_offload_radar_event(
2133 	struct wpa_driver_nl80211_data *drv, u32 subcmd, u8 *msg, int length)
2134 {
2135 	union wpa_event_data data;
2136 	struct nlattr *tb[NL80211_ATTR_MAX + 1];
2137 
2138 	wpa_printf(MSG_DEBUG,
2139 		   "nl80211: DFS offload radar vendor event received");
2140 
2141 	if (nla_parse(tb, NL80211_ATTR_MAX,
2142 		      (struct nlattr *) msg, length, NULL))
2143 		return;
2144 
2145 	if (!tb[NL80211_ATTR_WIPHY_FREQ]) {
2146 		wpa_printf(MSG_INFO,
2147 			   "nl80211: Error parsing WIPHY_FREQ in FS offload radar vendor event");
2148 		return;
2149 	}
2150 
2151 	os_memset(&data, 0, sizeof(data));
2152 	data.dfs_event.freq = nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]);
2153 
2154 	wpa_printf(MSG_DEBUG, "nl80211: DFS event on freq %d MHz",
2155 		   data.dfs_event.freq);
2156 
2157 	/* Check HT params */
2158 	if (tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
2159 		data.dfs_event.ht_enabled = 1;
2160 		data.dfs_event.chan_offset = 0;
2161 
2162 		switch (nla_get_u32(tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE])) {
2163 		case NL80211_CHAN_NO_HT:
2164 			data.dfs_event.ht_enabled = 0;
2165 			break;
2166 		case NL80211_CHAN_HT20:
2167 			break;
2168 		case NL80211_CHAN_HT40PLUS:
2169 			data.dfs_event.chan_offset = 1;
2170 			break;
2171 		case NL80211_CHAN_HT40MINUS:
2172 			data.dfs_event.chan_offset = -1;
2173 			break;
2174 		}
2175 	}
2176 
2177 	/* Get VHT params */
2178 	if (tb[NL80211_ATTR_CHANNEL_WIDTH])
2179 		data.dfs_event.chan_width =
2180 			convert2width(nla_get_u32(
2181 					      tb[NL80211_ATTR_CHANNEL_WIDTH]));
2182 	if (tb[NL80211_ATTR_CENTER_FREQ1])
2183 		data.dfs_event.cf1 = nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ1]);
2184 	if (tb[NL80211_ATTR_CENTER_FREQ2])
2185 		data.dfs_event.cf2 = nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ2]);
2186 
2187 	wpa_printf(MSG_DEBUG, "nl80211: DFS event on freq %d MHz, ht: %d, "
2188 		    "offset: %d, width: %d, cf1: %dMHz, cf2: %dMHz",
2189 		    data.dfs_event.freq, data.dfs_event.ht_enabled,
2190 		    data.dfs_event.chan_offset, data.dfs_event.chan_width,
2191 		    data.dfs_event.cf1, data.dfs_event.cf2);
2192 
2193 	switch (subcmd) {
2194 	case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_RADAR_DETECTED:
2195 		wpa_supplicant_event(drv->ctx, EVENT_DFS_RADAR_DETECTED, &data);
2196 		break;
2197 	case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_STARTED:
2198 		wpa_supplicant_event(drv->ctx, EVENT_DFS_CAC_STARTED, &data);
2199 		break;
2200 	case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_FINISHED:
2201 		wpa_supplicant_event(drv->ctx, EVENT_DFS_CAC_FINISHED, &data);
2202 		break;
2203 	case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_ABORTED:
2204 		wpa_supplicant_event(drv->ctx, EVENT_DFS_CAC_ABORTED, &data);
2205 		break;
2206 	case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_NOP_FINISHED:
2207 		wpa_supplicant_event(drv->ctx, EVENT_DFS_NOP_FINISHED, &data);
2208 		break;
2209 	default:
2210 		wpa_printf(MSG_DEBUG,
2211 			   "nl80211: Unknown DFS offload radar event %d received",
2212 			   subcmd);
2213 		break;
2214 	}
2215 }
2216 
2217 
qca_nl80211_scan_trigger_event(struct wpa_driver_nl80211_data * drv,u8 * data,size_t len)2218 static void qca_nl80211_scan_trigger_event(struct wpa_driver_nl80211_data *drv,
2219 					   u8 *data, size_t len)
2220 {
2221 	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAX + 1];
2222 	u64 cookie = 0;
2223 	union wpa_event_data event;
2224 	struct scan_info *info;
2225 
2226 	if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SCAN_MAX,
2227 		      (struct nlattr *) data, len, NULL) ||
2228 	    !tb[QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE])
2229 		return;
2230 
2231 	cookie = nla_get_u64(tb[QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE]);
2232 	if (cookie != drv->vendor_scan_cookie) {
2233 		/* External scan trigger event, ignore */
2234 		return;
2235 	}
2236 
2237 	/* Cookie match, own scan */
2238 	os_memset(&event, 0, sizeof(event));
2239 	info = &event.scan_info;
2240 	info->external_scan = 0;
2241 	info->nl_scan_event = 0;
2242 
2243 	drv->scan_state = SCAN_STARTED;
2244 	wpa_supplicant_event(drv->ctx, EVENT_SCAN_STARTED, &event);
2245 }
2246 
2247 
send_vendor_scan_event(struct wpa_driver_nl80211_data * drv,int aborted,struct nlattr * tb[],int external_scan)2248 static void send_vendor_scan_event(struct wpa_driver_nl80211_data *drv,
2249 				   int aborted, struct nlattr *tb[],
2250 				   int external_scan)
2251 {
2252 	union wpa_event_data event;
2253 	struct nlattr *nl;
2254 	int rem;
2255 	struct scan_info *info;
2256 	int freqs[MAX_REPORT_FREQS];
2257 	int num_freqs = 0;
2258 
2259 	os_memset(&event, 0, sizeof(event));
2260 	info = &event.scan_info;
2261 	info->aborted = aborted;
2262 	info->external_scan = external_scan;
2263 
2264 	if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS]) {
2265 		nla_for_each_nested(nl,
2266 				    tb[QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS], rem) {
2267 			struct wpa_driver_scan_ssid *s =
2268 				&info->ssids[info->num_ssids];
2269 			s->ssid = nla_data(nl);
2270 			s->ssid_len = nla_len(nl);
2271 			wpa_printf(MSG_DEBUG,
2272 				   "nl80211: Scan probed for SSID '%s'",
2273 				   wpa_ssid_txt(s->ssid, s->ssid_len));
2274 			info->num_ssids++;
2275 			if (info->num_ssids == WPAS_MAX_SCAN_SSIDS)
2276 				break;
2277 		}
2278 	}
2279 
2280 	if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES]) {
2281 		char msg[500], *pos, *end;
2282 		int res;
2283 
2284 		pos = msg;
2285 		end = pos + sizeof(msg);
2286 		*pos = '\0';
2287 
2288 		nla_for_each_nested(nl,
2289 				    tb[QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES],
2290 				    rem) {
2291 			freqs[num_freqs] = nla_get_u32(nl);
2292 			res = os_snprintf(pos, end - pos, " %d",
2293 					  freqs[num_freqs]);
2294 			if (!os_snprintf_error(end - pos, res))
2295 				pos += res;
2296 			num_freqs++;
2297 			if (num_freqs == MAX_REPORT_FREQS - 1)
2298 				break;
2299 		}
2300 
2301 		info->freqs = freqs;
2302 		info->num_freqs = num_freqs;
2303 		wpa_printf(MSG_DEBUG, "nl80211: Scan included frequencies:%s",
2304 			   msg);
2305 	}
2306 	wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS, &event);
2307 }
2308 
2309 
qca_nl80211_scan_done_event(struct wpa_driver_nl80211_data * drv,u8 * data,size_t len)2310 static void qca_nl80211_scan_done_event(struct wpa_driver_nl80211_data *drv,
2311 					u8 *data, size_t len)
2312 {
2313 	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAX + 1];
2314 	u64 cookie = 0;
2315 	enum scan_status status;
2316 	int external_scan;
2317 
2318 	if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SCAN_MAX,
2319 		      (struct nlattr *) data, len, NULL) ||
2320 	    !tb[QCA_WLAN_VENDOR_ATTR_SCAN_STATUS] ||
2321 	    !tb[QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE])
2322 		return;
2323 
2324 	status = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_SCAN_STATUS]);
2325 	if (status >= VENDOR_SCAN_STATUS_MAX)
2326 		return; /* invalid status */
2327 
2328 	cookie = nla_get_u64(tb[QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE]);
2329 	if (cookie != drv->vendor_scan_cookie) {
2330 		/* Event from an external scan, get scan results */
2331 		external_scan = 1;
2332 	} else {
2333 		external_scan = 0;
2334 		if (status == VENDOR_SCAN_STATUS_NEW_RESULTS)
2335 			drv->scan_state = SCAN_COMPLETED;
2336 		else
2337 			drv->scan_state = SCAN_ABORTED;
2338 
2339 		eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv,
2340 				     drv->ctx);
2341 		drv->vendor_scan_cookie = 0;
2342 		drv->last_scan_cmd = 0;
2343 	}
2344 
2345 	send_vendor_scan_event(drv, (status == VENDOR_SCAN_STATUS_ABORTED), tb,
2346 			       external_scan);
2347 }
2348 
2349 
qca_nl80211_p2p_lo_stop_event(struct wpa_driver_nl80211_data * drv,u8 * data,size_t len)2350 static void qca_nl80211_p2p_lo_stop_event(struct wpa_driver_nl80211_data *drv,
2351 					  u8 *data, size_t len)
2352 {
2353 	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_MAX + 1];
2354 	union wpa_event_data event;
2355 
2356 	wpa_printf(MSG_DEBUG,
2357 		   "nl80211: P2P listen offload stop vendor event received");
2358 
2359 	if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_MAX,
2360 		      (struct nlattr *) data, len, NULL) ||
2361 	    !tb[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_STOP_REASON])
2362 		return;
2363 
2364 	os_memset(&event, 0, sizeof(event));
2365 	event.p2p_lo_stop.reason_code =
2366 		nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_STOP_REASON]);
2367 
2368 	wpa_printf(MSG_DEBUG,
2369 		   "nl80211: P2P Listen offload stop reason: %d",
2370 		   event.p2p_lo_stop.reason_code);
2371 	wpa_supplicant_event(drv->ctx, EVENT_P2P_LO_STOP, &event);
2372 }
2373 
2374 #endif /* CONFIG_DRIVER_NL80211_QCA */
2375 
2376 
nl80211_vendor_event_qca(struct wpa_driver_nl80211_data * drv,u32 subcmd,u8 * data,size_t len)2377 static void nl80211_vendor_event_qca(struct wpa_driver_nl80211_data *drv,
2378 				     u32 subcmd, u8 *data, size_t len)
2379 {
2380 	switch (subcmd) {
2381 	case QCA_NL80211_VENDOR_SUBCMD_TEST:
2382 		wpa_hexdump(MSG_DEBUG, "nl80211: QCA test event", data, len);
2383 		break;
2384 #ifdef CONFIG_DRIVER_NL80211_QCA
2385 	case QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY:
2386 		qca_nl80211_avoid_freq(drv, data, len);
2387 		break;
2388 	case QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH:
2389 		qca_nl80211_key_mgmt_auth_handler(drv, data, len);
2390 		break;
2391 	case QCA_NL80211_VENDOR_SUBCMD_DO_ACS:
2392 		qca_nl80211_acs_select_ch(drv, data, len);
2393 		break;
2394 	case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_STARTED:
2395 	case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_FINISHED:
2396 	case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_ABORTED:
2397 	case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_NOP_FINISHED:
2398 	case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_RADAR_DETECTED:
2399 		qca_nl80211_dfs_offload_radar_event(drv, subcmd, data, len);
2400 		break;
2401 	case QCA_NL80211_VENDOR_SUBCMD_TRIGGER_SCAN:
2402 		qca_nl80211_scan_trigger_event(drv, data, len);
2403 		break;
2404 	case QCA_NL80211_VENDOR_SUBCMD_SCAN_DONE:
2405 		qca_nl80211_scan_done_event(drv, data, len);
2406 		break;
2407 	case QCA_NL80211_VENDOR_SUBCMD_P2P_LISTEN_OFFLOAD_STOP:
2408 		qca_nl80211_p2p_lo_stop_event(drv, data, len);
2409 		break;
2410 #endif /* CONFIG_DRIVER_NL80211_QCA */
2411 	default:
2412 		wpa_printf(MSG_DEBUG,
2413 			   "nl80211: Ignore unsupported QCA vendor event %u",
2414 			   subcmd);
2415 		break;
2416 	}
2417 }
2418 
2419 
2420 #if defined(CONFIG_DRIVER_NL80211_BRCM) || defined(CONFIG_DRIVER_NL80211_SYNA)
2421 
brcm_nl80211_acs_select_ch(struct wpa_driver_nl80211_data * drv,const u8 * data,size_t len)2422 static void brcm_nl80211_acs_select_ch(struct wpa_driver_nl80211_data *drv,
2423 				       const u8 *data, size_t len)
2424 {
2425 	struct nlattr *tb[BRCM_VENDOR_ATTR_ACS_LAST + 1];
2426 	union wpa_event_data event;
2427 
2428 	wpa_printf(MSG_DEBUG,
2429 		   "nl80211: BRCM ACS channel selection vendor event received");
2430 
2431 	if (nla_parse(tb, BRCM_VENDOR_ATTR_ACS_LAST, (struct nlattr *) data,
2432 		      len, NULL) ||
2433 	    !tb[BRCM_VENDOR_ATTR_ACS_PRIMARY_FREQ] ||
2434 	    !tb[BRCM_VENDOR_ATTR_ACS_SECONDARY_FREQ])
2435 		return;
2436 
2437 	os_memset(&event, 0, sizeof(event));
2438 	if (tb[BRCM_VENDOR_ATTR_ACS_PRIMARY_FREQ])
2439 		event.acs_selected_channels.pri_freq =
2440 			nla_get_u32(tb[BRCM_VENDOR_ATTR_ACS_PRIMARY_FREQ]);
2441 	if (tb[BRCM_VENDOR_ATTR_ACS_SECONDARY_FREQ])
2442 		event.acs_selected_channels.sec_freq =
2443 			nla_get_u32(tb[BRCM_VENDOR_ATTR_ACS_SECONDARY_FREQ]);
2444 	if (tb[BRCM_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL])
2445 		event.acs_selected_channels.vht_seg0_center_ch =
2446 			nla_get_u8(tb[BRCM_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL]);
2447 	if (tb[BRCM_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL])
2448 		event.acs_selected_channels.vht_seg1_center_ch =
2449 			nla_get_u8(tb[BRCM_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL]);
2450 	if (tb[BRCM_VENDOR_ATTR_ACS_CHWIDTH])
2451 		event.acs_selected_channels.ch_width =
2452 			nla_get_u16(tb[BRCM_VENDOR_ATTR_ACS_CHWIDTH]);
2453 	if (tb[BRCM_VENDOR_ATTR_ACS_HW_MODE]) {
2454 		event.acs_selected_channels.hw_mode = nla_get_u8(tb[BRCM_VENDOR_ATTR_ACS_HW_MODE]);
2455 		if (event.acs_selected_channels.hw_mode == NUM_HOSTAPD_MODES ||
2456 		    event.acs_selected_channels.hw_mode ==
2457 		    HOSTAPD_MODE_IEEE80211ANY) {
2458 			wpa_printf(MSG_DEBUG,
2459 				   "nl80211: Invalid hw_mode %d in ACS selection event",
2460 				   event.acs_selected_channels.hw_mode);
2461 			return;
2462 		}
2463 	}
2464 
2465 	wpa_printf(MSG_DEBUG,
2466 		   "nl80211: ACS Results: PCH: %d SCH: %d BW: %d VHT0: %d VHT1: %d HW_MODE: %d",
2467 		   event.acs_selected_channels.pri_freq,
2468 		   event.acs_selected_channels.sec_freq,
2469 		   event.acs_selected_channels.ch_width,
2470 		   event.acs_selected_channels.vht_seg0_center_ch,
2471 		   event.acs_selected_channels.vht_seg1_center_ch,
2472 		   event.acs_selected_channels.hw_mode);
2473 	wpa_supplicant_event(drv->ctx, EVENT_ACS_CHANNEL_SELECTED, &event);
2474 }
2475 
2476 
nl80211_vendor_event_brcm(struct wpa_driver_nl80211_data * drv,u32 subcmd,u8 * data,size_t len)2477 static void nl80211_vendor_event_brcm(struct wpa_driver_nl80211_data *drv,
2478 				      u32 subcmd, u8 *data, size_t len)
2479 {
2480 	wpa_printf(MSG_DEBUG, "nl80211: Got BRCM vendor event %u", subcmd);
2481 	switch (subcmd) {
2482 	case BRCM_VENDOR_EVENT_PRIV_STR:
2483 	case BRCM_VENDOR_EVENT_HANGED:
2484 		/* Dump the event on to the console */
2485 		wpa_msg(NULL, MSG_INFO, "%s", data);
2486 		break;
2487 	case BRCM_VENDOR_EVENT_ACS:
2488 		brcm_nl80211_acs_select_ch(drv, data, len);
2489 		break;
2490 	default:
2491 		wpa_printf(MSG_DEBUG,
2492 			   "%s: Ignore unsupported BRCM vendor event %u",
2493 			   __func__, subcmd);
2494 		break;
2495 	}
2496 }
2497 
2498 #endif /* CONFIG_DRIVER_NL80211_BRCM || CONFIG_DRIVER_NL80211_SYNA */
2499 
2500 
nl80211_vendor_event(struct wpa_driver_nl80211_data * drv,struct nlattr ** tb)2501 static void nl80211_vendor_event(struct wpa_driver_nl80211_data *drv,
2502 				 struct nlattr **tb)
2503 {
2504 	u32 vendor_id, subcmd, wiphy = 0;
2505 	int wiphy_idx;
2506 	u8 *data = NULL;
2507 	size_t len = 0;
2508 
2509 	if (!tb[NL80211_ATTR_VENDOR_ID] ||
2510 	    !tb[NL80211_ATTR_VENDOR_SUBCMD])
2511 		return;
2512 
2513 	vendor_id = nla_get_u32(tb[NL80211_ATTR_VENDOR_ID]);
2514 	subcmd = nla_get_u32(tb[NL80211_ATTR_VENDOR_SUBCMD]);
2515 
2516 	if (tb[NL80211_ATTR_WIPHY])
2517 		wiphy = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
2518 
2519 	wpa_printf(MSG_DEBUG, "nl80211: Vendor event: wiphy=%u vendor_id=0x%x subcmd=%u",
2520 		   wiphy, vendor_id, subcmd);
2521 
2522 	if (tb[NL80211_ATTR_VENDOR_DATA]) {
2523 		data = nla_data(tb[NL80211_ATTR_VENDOR_DATA]);
2524 		len = nla_len(tb[NL80211_ATTR_VENDOR_DATA]);
2525 		wpa_hexdump(MSG_MSGDUMP, "nl80211: Vendor data", data, len);
2526 	}
2527 
2528 	wiphy_idx = nl80211_get_wiphy_index(drv->first_bss);
2529 	if (wiphy_idx >= 0 && wiphy_idx != (int) wiphy) {
2530 		wpa_printf(MSG_DEBUG, "nl80211: Ignore vendor event for foreign wiphy %u (own: %d)",
2531 			   wiphy, wiphy_idx);
2532 		return;
2533 	}
2534 
2535 #ifdef ANDROID
2536 #ifdef ANDROID_LIB_EVENT
2537        wpa_driver_nl80211_driver_event(drv, vendor_id, subcmd, data, len);
2538 #endif /* ANDROID_LIB_EVENT */
2539 #endif /* ANDROID */
2540 
2541 	switch (vendor_id) {
2542 	case OUI_QCA:
2543 		nl80211_vendor_event_qca(drv, subcmd, data, len);
2544 		break;
2545 #if defined(CONFIG_DRIVER_NL80211_BRCM) || defined(CONFIG_DRIVER_NL80211_SYNA)
2546 	case OUI_BRCM:
2547 		nl80211_vendor_event_brcm(drv, subcmd, data, len);
2548 		break;
2549 #endif /* CONFIG_DRIVER_NL80211_BRCM || CONFIG_DRIVER_NL80211_SYNA */
2550 	default:
2551 		wpa_printf(MSG_DEBUG, "nl80211: Ignore unsupported vendor event");
2552 		break;
2553 	}
2554 }
2555 
2556 
nl80211_reg_change_event(struct wpa_driver_nl80211_data * drv,struct nlattr * tb[])2557 static void nl80211_reg_change_event(struct wpa_driver_nl80211_data *drv,
2558 				     struct nlattr *tb[])
2559 {
2560 	union wpa_event_data data;
2561 	enum nl80211_reg_initiator init;
2562 
2563 	wpa_printf(MSG_DEBUG, "nl80211: Regulatory domain change");
2564 
2565 	if (tb[NL80211_ATTR_REG_INITIATOR] == NULL)
2566 		return;
2567 
2568 	os_memset(&data, 0, sizeof(data));
2569 	init = nla_get_u8(tb[NL80211_ATTR_REG_INITIATOR]);
2570 	wpa_printf(MSG_DEBUG, " * initiator=%d", init);
2571 	switch (init) {
2572 	case NL80211_REGDOM_SET_BY_CORE:
2573 		data.channel_list_changed.initiator = REGDOM_SET_BY_CORE;
2574 		break;
2575 	case NL80211_REGDOM_SET_BY_USER:
2576 		data.channel_list_changed.initiator = REGDOM_SET_BY_USER;
2577 		break;
2578 	case NL80211_REGDOM_SET_BY_DRIVER:
2579 		data.channel_list_changed.initiator = REGDOM_SET_BY_DRIVER;
2580 		break;
2581 	case NL80211_REGDOM_SET_BY_COUNTRY_IE:
2582 		data.channel_list_changed.initiator = REGDOM_SET_BY_COUNTRY_IE;
2583 		break;
2584 	}
2585 
2586 	if (tb[NL80211_ATTR_REG_TYPE]) {
2587 		enum nl80211_reg_type type;
2588 		type = nla_get_u8(tb[NL80211_ATTR_REG_TYPE]);
2589 		wpa_printf(MSG_DEBUG, " * type=%d", type);
2590 		switch (type) {
2591 		case NL80211_REGDOM_TYPE_COUNTRY:
2592 			data.channel_list_changed.type = REGDOM_TYPE_COUNTRY;
2593 			break;
2594 		case NL80211_REGDOM_TYPE_WORLD:
2595 			data.channel_list_changed.type = REGDOM_TYPE_WORLD;
2596 			break;
2597 		case NL80211_REGDOM_TYPE_CUSTOM_WORLD:
2598 			data.channel_list_changed.type =
2599 				REGDOM_TYPE_CUSTOM_WORLD;
2600 			break;
2601 		case NL80211_REGDOM_TYPE_INTERSECTION:
2602 			data.channel_list_changed.type =
2603 				REGDOM_TYPE_INTERSECTION;
2604 			break;
2605 		}
2606 	}
2607 
2608 	if (tb[NL80211_ATTR_REG_ALPHA2]) {
2609 		os_strlcpy(data.channel_list_changed.alpha2,
2610 			   nla_get_string(tb[NL80211_ATTR_REG_ALPHA2]),
2611 			   sizeof(data.channel_list_changed.alpha2));
2612 		wpa_printf(MSG_DEBUG, " * alpha2=%s",
2613 			   data.channel_list_changed.alpha2);
2614 	}
2615 
2616 	wpa_supplicant_event(drv->ctx, EVENT_CHANNEL_LIST_CHANGED, &data);
2617 }
2618 
2619 
nl80211_dump_freq(const char * title,struct nlattr * nl_freq)2620 static void nl80211_dump_freq(const char *title, struct nlattr *nl_freq)
2621 {
2622 	static struct nla_policy freq_policy[NL80211_FREQUENCY_ATTR_MAX + 1] = {
2623 		[NL80211_FREQUENCY_ATTR_FREQ] = { .type = NLA_U32 },
2624 		[NL80211_FREQUENCY_ATTR_DISABLED] = { .type = NLA_FLAG },
2625 		[NL80211_FREQUENCY_ATTR_NO_IR] = { .type = NLA_FLAG },
2626 		[NL80211_FREQUENCY_ATTR_RADAR] = { .type = NLA_FLAG },
2627 		[NL80211_FREQUENCY_ATTR_MAX_TX_POWER] = { .type = NLA_U32 },
2628 	};
2629 	struct nlattr *tb[NL80211_FREQUENCY_ATTR_MAX + 1];
2630 	u32 freq = 0, max_tx_power = 0;
2631 
2632 	nla_parse(tb, NL80211_FREQUENCY_ATTR_MAX,
2633 		  nla_data(nl_freq), nla_len(nl_freq), freq_policy);
2634 
2635 	if (tb[NL80211_FREQUENCY_ATTR_FREQ])
2636 		freq = nla_get_u32(tb[NL80211_FREQUENCY_ATTR_FREQ]);
2637 	if (tb[NL80211_FREQUENCY_ATTR_MAX_TX_POWER])
2638 		max_tx_power =
2639 			nla_get_u32(tb[NL80211_FREQUENCY_ATTR_MAX_TX_POWER]);
2640 
2641 	wpa_printf(MSG_DEBUG,
2642 		   "nl80211: Channel (%s): freq=%u max_tx_power=%u%s%s%s",
2643 		   title, freq, max_tx_power,
2644 		   tb[NL80211_FREQUENCY_ATTR_DISABLED] ? " disabled" : "",
2645 		   tb[NL80211_FREQUENCY_ATTR_NO_IR] ? " no-IR" : "",
2646 		   tb[NL80211_FREQUENCY_ATTR_RADAR] ? " radar" : "");
2647 }
2648 
2649 
nl80211_reg_beacon_hint_event(struct wpa_driver_nl80211_data * drv,struct nlattr * tb[])2650 static void nl80211_reg_beacon_hint_event(struct wpa_driver_nl80211_data *drv,
2651 					   struct nlattr *tb[])
2652 {
2653 	union wpa_event_data data;
2654 
2655 	wpa_printf(MSG_DEBUG, "nl80211: Regulatory beacon hint");
2656 	os_memset(&data, 0, sizeof(data));
2657 	data.channel_list_changed.initiator = REGDOM_BEACON_HINT;
2658 
2659 	if (tb[NL80211_ATTR_FREQ_BEFORE])
2660 		nl80211_dump_freq("before", tb[NL80211_ATTR_FREQ_BEFORE]);
2661 	if (tb[NL80211_ATTR_FREQ_AFTER])
2662 		nl80211_dump_freq("after", tb[NL80211_ATTR_FREQ_AFTER]);
2663 
2664 	wpa_supplicant_event(drv->ctx, EVENT_CHANNEL_LIST_CHANGED, &data);
2665 }
2666 
2667 
nl80211_external_auth(struct wpa_driver_nl80211_data * drv,struct nlattr ** tb)2668 static void nl80211_external_auth(struct wpa_driver_nl80211_data *drv,
2669 				  struct nlattr **tb)
2670 {
2671 	union wpa_event_data event;
2672 	enum nl80211_external_auth_action act;
2673 
2674 	if (!tb[NL80211_ATTR_AKM_SUITES] ||
2675 	    !tb[NL80211_ATTR_EXTERNAL_AUTH_ACTION] ||
2676 	    !tb[NL80211_ATTR_BSSID] ||
2677 	    !tb[NL80211_ATTR_SSID])
2678 		return;
2679 
2680 	os_memset(&event, 0, sizeof(event));
2681 	act = nla_get_u32(tb[NL80211_ATTR_EXTERNAL_AUTH_ACTION]);
2682 	switch (act) {
2683 	case NL80211_EXTERNAL_AUTH_START:
2684 		event.external_auth.action = EXT_AUTH_START;
2685 		break;
2686 	case NL80211_EXTERNAL_AUTH_ABORT:
2687 		event.external_auth.action = EXT_AUTH_ABORT;
2688 		break;
2689 	default:
2690 		return;
2691 	}
2692 
2693 	event.external_auth.key_mgmt_suite =
2694 		nla_get_u32(tb[NL80211_ATTR_AKM_SUITES]);
2695 
2696 	event.external_auth.ssid_len = nla_len(tb[NL80211_ATTR_SSID]);
2697 	if (event.external_auth.ssid_len > SSID_MAX_LEN)
2698 		return;
2699 	event.external_auth.ssid = nla_data(tb[NL80211_ATTR_SSID]);
2700 
2701 	event.external_auth.bssid = nla_data(tb[NL80211_ATTR_BSSID]);
2702 
2703 	wpa_printf(MSG_DEBUG,
2704 		   "nl80211: External auth action: %u, AKM: 0x%x",
2705 		   event.external_auth.action,
2706 		   event.external_auth.key_mgmt_suite);
2707 	wpa_supplicant_event(drv->ctx, EVENT_EXTERNAL_AUTH, &event);
2708 }
2709 
2710 
nl80211_port_authorized(struct wpa_driver_nl80211_data * drv,struct nlattr ** tb)2711 static void nl80211_port_authorized(struct wpa_driver_nl80211_data *drv,
2712 				    struct nlattr **tb)
2713 {
2714 	const u8 *addr;
2715 
2716 	if (!tb[NL80211_ATTR_MAC] ||
2717 	    nla_len(tb[NL80211_ATTR_MAC]) != ETH_ALEN) {
2718 		wpa_printf(MSG_DEBUG,
2719 			   "nl80211: Ignore port authorized event without BSSID");
2720 		return;
2721 	}
2722 
2723 	addr = nla_data(tb[NL80211_ATTR_MAC]);
2724 	if (os_memcmp(addr, drv->bssid, ETH_ALEN) != 0) {
2725 		wpa_printf(MSG_DEBUG,
2726 			   "nl80211: Ignore port authorized event for " MACSTR
2727 			   " (not the currently connected BSSID " MACSTR ")",
2728 			   MAC2STR(addr), MAC2STR(drv->bssid));
2729 		return;
2730 	}
2731 
2732 	wpa_supplicant_event(drv->ctx, EVENT_PORT_AUTHORIZED, NULL);
2733 }
2734 
2735 
nl80211_sta_opmode_change_event(struct wpa_driver_nl80211_data * drv,struct nlattr ** tb)2736 static void nl80211_sta_opmode_change_event(struct wpa_driver_nl80211_data *drv,
2737 					    struct nlattr **tb)
2738 {
2739 	union wpa_event_data ed;
2740 	u8 smps_mode, max_bw;
2741 
2742 	if (!tb[NL80211_ATTR_MAC] ||
2743 	    (!tb[NL80211_ATTR_CHANNEL_WIDTH] &&
2744 	     !tb[NL80211_ATTR_SMPS_MODE] &&
2745 	     !tb[NL80211_ATTR_NSS]))
2746 		return;
2747 
2748 	ed.sta_opmode.smps_mode = SMPS_INVALID;
2749 	ed.sta_opmode.chan_width = CHAN_WIDTH_UNKNOWN;
2750 	ed.sta_opmode.rx_nss = 0xff;
2751 	ed.sta_opmode.addr = nla_data(tb[NL80211_ATTR_MAC]);
2752 
2753 	if (tb[NL80211_ATTR_SMPS_MODE]) {
2754 		smps_mode = nla_get_u8(tb[NL80211_ATTR_SMPS_MODE]);
2755 		switch (smps_mode) {
2756 		case NL80211_SMPS_OFF:
2757 			ed.sta_opmode.smps_mode = SMPS_OFF;
2758 			break;
2759 		case NL80211_SMPS_STATIC:
2760 			ed.sta_opmode.smps_mode = SMPS_STATIC;
2761 			break;
2762 		case NL80211_SMPS_DYNAMIC:
2763 			ed.sta_opmode.smps_mode = SMPS_DYNAMIC;
2764 			break;
2765 		default:
2766 			ed.sta_opmode.smps_mode = SMPS_INVALID;
2767 			break;
2768 		}
2769 	}
2770 
2771 	if (tb[NL80211_ATTR_CHANNEL_WIDTH]) {
2772 		max_bw = nla_get_u32(tb[NL80211_ATTR_CHANNEL_WIDTH]);
2773 		switch (max_bw) {
2774 		case NL80211_CHAN_WIDTH_20_NOHT:
2775 			ed.sta_opmode.chan_width = CHAN_WIDTH_20_NOHT;
2776 			break;
2777 		case NL80211_CHAN_WIDTH_20:
2778 			ed.sta_opmode.chan_width = CHAN_WIDTH_20;
2779 			break;
2780 		case NL80211_CHAN_WIDTH_40:
2781 			ed.sta_opmode.chan_width = CHAN_WIDTH_40;
2782 			break;
2783 		case NL80211_CHAN_WIDTH_80:
2784 			ed.sta_opmode.chan_width = CHAN_WIDTH_80;
2785 			break;
2786 		case NL80211_CHAN_WIDTH_80P80:
2787 			ed.sta_opmode.chan_width = CHAN_WIDTH_80P80;
2788 			break;
2789 		case NL80211_CHAN_WIDTH_160:
2790 			ed.sta_opmode.chan_width = CHAN_WIDTH_160;
2791 			break;
2792 		default:
2793 			ed.sta_opmode.chan_width = CHAN_WIDTH_UNKNOWN;
2794 			break;
2795 
2796 		}
2797 	}
2798 
2799 	if (tb[NL80211_ATTR_NSS])
2800 		ed.sta_opmode.rx_nss = nla_get_u8(tb[NL80211_ATTR_NSS]);
2801 
2802 	wpa_supplicant_event(drv->ctx, EVENT_STATION_OPMODE_CHANGED, &ed);
2803 }
2804 
2805 
nl80211_control_port_frame(struct wpa_driver_nl80211_data * drv,struct nlattr ** tb)2806 static void nl80211_control_port_frame(struct wpa_driver_nl80211_data *drv,
2807 				       struct nlattr **tb)
2808 {
2809 	u8 *src_addr;
2810 	u16 ethertype;
2811 
2812 	if (!tb[NL80211_ATTR_MAC] ||
2813 	    !tb[NL80211_ATTR_FRAME] ||
2814 	    !tb[NL80211_ATTR_CONTROL_PORT_ETHERTYPE])
2815 		return;
2816 
2817 	src_addr = nla_data(tb[NL80211_ATTR_MAC]);
2818 	ethertype = nla_get_u16(tb[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]);
2819 
2820 	switch (ethertype) {
2821 	case ETH_P_RSN_PREAUTH:
2822 		wpa_printf(MSG_INFO, "nl80211: Got pre-auth frame from "
2823 			   MACSTR " over control port unexpectedly",
2824 			   MAC2STR(src_addr));
2825 		break;
2826 	case ETH_P_PAE:
2827 		drv_event_eapol_rx(drv->ctx, src_addr,
2828 				   nla_data(tb[NL80211_ATTR_FRAME]),
2829 				   nla_len(tb[NL80211_ATTR_FRAME]));
2830 		break;
2831 	default:
2832 		wpa_printf(MSG_INFO,
2833 			   "nl80211: Unexpected ethertype 0x%04x from "
2834 			   MACSTR " over control port",
2835 			   ethertype, MAC2STR(src_addr));
2836 		break;
2837 	}
2838 }
2839 
2840 
2841 static void
nl80211_control_port_frame_tx_status(struct wpa_driver_nl80211_data * drv,const u8 * frame,size_t len,struct nlattr * ack,struct nlattr * cookie)2842 nl80211_control_port_frame_tx_status(struct wpa_driver_nl80211_data *drv,
2843 				     const u8 *frame, size_t len,
2844 				     struct nlattr *ack, struct nlattr *cookie)
2845 {
2846 	union wpa_event_data event;
2847 
2848 	if (!cookie || len < ETH_HLEN)
2849 		return;
2850 
2851 	wpa_printf(MSG_DEBUG,
2852 		   "nl80211: Control port TX status (ack=%d), cookie=%llu",
2853 		   ack != NULL, (long long unsigned int) nla_get_u64(cookie));
2854 
2855 	os_memset(&event, 0, sizeof(event));
2856 	event.eapol_tx_status.dst = frame;
2857 	event.eapol_tx_status.data = frame + ETH_HLEN;
2858 	event.eapol_tx_status.data_len = len - ETH_HLEN;
2859 	event.eapol_tx_status.ack = ack != NULL;
2860 	wpa_supplicant_event(drv->ctx, EVENT_EAPOL_TX_STATUS, &event);
2861 }
2862 
2863 
nl80211_frame_wait_cancel(struct wpa_driver_nl80211_data * drv,struct nlattr * cookie_attr)2864 static void nl80211_frame_wait_cancel(struct wpa_driver_nl80211_data *drv,
2865 				      struct nlattr *cookie_attr)
2866 {
2867 	unsigned int i;
2868 	u64 cookie;
2869 	bool match = false;
2870 
2871 	if (!cookie_attr)
2872 		return;
2873 	cookie = nla_get_u64(cookie_attr);
2874 
2875 	for (i = 0; i < drv->num_send_frame_cookies; i++) {
2876 		if (cookie == drv->send_frame_cookies[i]) {
2877 			match = true;
2878 			break;
2879 		}
2880 	}
2881 	wpa_printf(MSG_DEBUG,
2882 		   "nl80211: TX frame wait expired for cookie 0x%llx%s%s",
2883 		   (long long unsigned int) cookie,
2884 		   match ? " (match)" : "",
2885 		   drv->send_frame_cookie == cookie ? " (match-saved)" : "");
2886 	if (drv->send_frame_cookie == cookie)
2887 		drv->send_frame_cookie = (u64) -1;
2888 	if (!match)
2889 		return;
2890 
2891 	if (i < drv->num_send_frame_cookies - 1)
2892 		os_memmove(&drv->send_frame_cookies[i],
2893 			   &drv->send_frame_cookies[i + 1],
2894 			   (drv->num_send_frame_cookies - i - 1) * sizeof(u64));
2895 	drv->num_send_frame_cookies--;
2896 
2897 	wpa_supplicant_event(drv->ctx, EVENT_TX_WAIT_EXPIRE, NULL);
2898 }
2899 
2900 
nl80211_assoc_comeback(struct wpa_driver_nl80211_data * drv,struct nlattr * mac,struct nlattr * timeout)2901 static void nl80211_assoc_comeback(struct wpa_driver_nl80211_data *drv,
2902 				   struct nlattr *mac, struct nlattr *timeout)
2903 {
2904 	if (!mac || !timeout)
2905 		return;
2906 	wpa_printf(MSG_DEBUG, "nl80211: Association comeback requested by "
2907 		   MACSTR " (timeout: %u ms)",
2908 		   MAC2STR((u8 *) nla_data(mac)), nla_get_u32(timeout));
2909 }
2910 
2911 
2912 #ifdef CONFIG_IEEE80211AX
2913 
nl80211_obss_color_collision(struct wpa_driver_nl80211_data * drv,struct nlattr * tb[])2914 static void nl80211_obss_color_collision(struct wpa_driver_nl80211_data *drv,
2915 					 struct nlattr *tb[])
2916 {
2917 	union wpa_event_data data;
2918 
2919 	if (!tb[NL80211_ATTR_OBSS_COLOR_BITMAP])
2920 		return;
2921 
2922 	os_memset(&data, 0, sizeof(data));
2923 	data.bss_color_collision.bitmap =
2924 		nla_get_u64(tb[NL80211_ATTR_OBSS_COLOR_BITMAP]);
2925 
2926 	wpa_printf(MSG_DEBUG, "nl80211: BSS color collision - bitmap %08lx",
2927 		   data.bss_color_collision.bitmap);
2928 	wpa_supplicant_event(drv->ctx, EVENT_BSS_COLOR_COLLISION, &data);
2929 }
2930 
2931 
2932 static void
nl80211_color_change_announcement_started(struct wpa_driver_nl80211_data * drv)2933 nl80211_color_change_announcement_started(struct wpa_driver_nl80211_data *drv)
2934 {
2935 	union wpa_event_data data = {};
2936 
2937 	wpa_printf(MSG_DEBUG, "nl80211: CCA started");
2938 	wpa_supplicant_event(drv->ctx, EVENT_CCA_STARTED_NOTIFY, &data);
2939 }
2940 
2941 
2942 static void
nl80211_color_change_announcement_aborted(struct wpa_driver_nl80211_data * drv)2943 nl80211_color_change_announcement_aborted(struct wpa_driver_nl80211_data *drv)
2944 {
2945 	union wpa_event_data data = {};
2946 
2947 	wpa_printf(MSG_DEBUG, "nl80211: CCA aborted");
2948 	wpa_supplicant_event(drv->ctx, EVENT_CCA_ABORTED_NOTIFY, &data);
2949 }
2950 
2951 
2952 static void
nl80211_color_change_announcement_completed(struct wpa_driver_nl80211_data * drv)2953 nl80211_color_change_announcement_completed(struct wpa_driver_nl80211_data *drv)
2954 {
2955 	union wpa_event_data data = {};
2956 
2957 	wpa_printf(MSG_DEBUG, "nl80211: CCA completed");
2958 	wpa_supplicant_event(drv->ctx, EVENT_CCA_NOTIFY, &data);
2959 }
2960 
2961 #endif /* CONFIG_IEEE80211AX */
2962 
2963 
do_process_drv_event(struct i802_bss * bss,int cmd,struct nlattr ** tb)2964 static void do_process_drv_event(struct i802_bss *bss, int cmd,
2965 				 struct nlattr **tb)
2966 {
2967 	struct wpa_driver_nl80211_data *drv = bss->drv;
2968 	int external_scan_event = 0;
2969 	struct nlattr *frame = tb[NL80211_ATTR_FRAME];
2970 
2971 	wpa_printf(MSG_DEBUG, "nl80211: Drv Event %d (%s) received for %s",
2972 		   cmd, nl80211_command_to_string(cmd), bss->ifname);
2973 
2974 #ifdef CONFIG_DRIVER_NL80211_QCA
2975 	if (cmd == NL80211_CMD_ROAM &&
2976 	    (drv->capa.flags & WPA_DRIVER_FLAGS_KEY_MGMT_OFFLOAD)) {
2977 		if (drv->pending_roam_data) {
2978 			struct os_reltime now, age;
2979 
2980 			os_get_reltime(&now);
2981 			os_reltime_sub(&now, &drv->pending_roam_ind_time, &age);
2982 			if (age.sec == 0 && age.usec < 100000) {
2983 				wpa_printf(MSG_DEBUG,
2984 					   "nl80211: Process pending roam+auth vendor event");
2985 				qca_nl80211_key_mgmt_auth(
2986 					drv, drv->pending_roam_data,
2987 					drv->pending_roam_data_len);
2988 			}
2989 			os_free(drv->pending_roam_data);
2990 			drv->pending_roam_data = NULL;
2991 			return;
2992 		}
2993 		/*
2994 		 * Device will use roam+auth vendor event to indicate
2995 		 * roaming, so ignore the regular roam event.
2996 		 */
2997 		drv->roam_indication_done = true;
2998 		wpa_printf(MSG_DEBUG,
2999 			   "nl80211: Ignore roam event (cmd=%d), device will use vendor event roam+auth",
3000 			   cmd);
3001 		return;
3002 	}
3003 #endif /* CONFIG_DRIVER_NL80211_QCA */
3004 
3005 	if (drv->ap_scan_as_station != NL80211_IFTYPE_UNSPECIFIED &&
3006 	    (cmd == NL80211_CMD_NEW_SCAN_RESULTS ||
3007 	     cmd == NL80211_CMD_SCAN_ABORTED))
3008 		nl80211_restore_ap_mode(bss);
3009 
3010 	switch (cmd) {
3011 	case NL80211_CMD_TRIGGER_SCAN:
3012 		wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Scan trigger");
3013 		drv->scan_state = SCAN_STARTED;
3014 		if (drv->scan_for_auth) {
3015 			/*
3016 			 * Cannot indicate EVENT_SCAN_STARTED here since we skip
3017 			 * EVENT_SCAN_RESULTS in scan_for_auth case and the
3018 			 * upper layer implementation could get confused about
3019 			 * scanning state.
3020 			 */
3021 			wpa_printf(MSG_DEBUG, "nl80211: Do not indicate scan-start event due to internal scan_for_auth");
3022 			break;
3023 		}
3024 		wpa_supplicant_event(drv->ctx, EVENT_SCAN_STARTED, NULL);
3025 		break;
3026 	case NL80211_CMD_START_SCHED_SCAN:
3027 		wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Sched scan started");
3028 		drv->scan_state = SCHED_SCAN_STARTED;
3029 		break;
3030 	case NL80211_CMD_SCHED_SCAN_STOPPED:
3031 		wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Sched scan stopped");
3032 		drv->scan_state = SCHED_SCAN_STOPPED;
3033 		wpa_supplicant_event(drv->ctx, EVENT_SCHED_SCAN_STOPPED, NULL);
3034 		break;
3035 	case NL80211_CMD_NEW_SCAN_RESULTS:
3036 		wpa_dbg(drv->ctx, MSG_DEBUG,
3037 			"nl80211: New scan results available");
3038 		if (drv->last_scan_cmd != NL80211_CMD_VENDOR)
3039 			drv->scan_state = SCAN_COMPLETED;
3040 		drv->scan_complete_events = 1;
3041 		if (drv->last_scan_cmd == NL80211_CMD_TRIGGER_SCAN) {
3042 			eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout,
3043 					     drv, drv->ctx);
3044 			drv->last_scan_cmd = 0;
3045 		} else {
3046 			external_scan_event = 1;
3047 		}
3048 		send_scan_event(drv, 0, tb, external_scan_event);
3049 		break;
3050 	case NL80211_CMD_SCHED_SCAN_RESULTS:
3051 		wpa_dbg(drv->ctx, MSG_DEBUG,
3052 			"nl80211: New sched scan results available");
3053 		drv->scan_state = SCHED_SCAN_RESULTS;
3054 		send_scan_event(drv, 0, tb, 0);
3055 		break;
3056 	case NL80211_CMD_SCAN_ABORTED:
3057 		wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Scan aborted");
3058 		if (drv->last_scan_cmd != NL80211_CMD_VENDOR)
3059 			drv->scan_state = SCAN_ABORTED;
3060 		if (drv->last_scan_cmd == NL80211_CMD_TRIGGER_SCAN) {
3061 			/*
3062 			 * Need to indicate that scan results are available in
3063 			 * order not to make wpa_supplicant stop its scanning.
3064 			 */
3065 			eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout,
3066 					     drv, drv->ctx);
3067 			drv->last_scan_cmd = 0;
3068 		} else {
3069 			external_scan_event = 1;
3070 		}
3071 		send_scan_event(drv, 1, tb, external_scan_event);
3072 		break;
3073 	case NL80211_CMD_AUTHENTICATE:
3074 	case NL80211_CMD_ASSOCIATE:
3075 	case NL80211_CMD_DEAUTHENTICATE:
3076 	case NL80211_CMD_DISASSOCIATE:
3077 	case NL80211_CMD_FRAME_TX_STATUS:
3078 	case NL80211_CMD_UNPROT_DEAUTHENTICATE:
3079 	case NL80211_CMD_UNPROT_DISASSOCIATE:
3080 		mlme_event(bss, cmd, tb[NL80211_ATTR_FRAME],
3081 			   tb[NL80211_ATTR_MAC], tb[NL80211_ATTR_TIMED_OUT],
3082 			   tb[NL80211_ATTR_WIPHY_FREQ], tb[NL80211_ATTR_ACK],
3083 			   tb[NL80211_ATTR_COOKIE],
3084 			   tb[NL80211_ATTR_RX_SIGNAL_DBM],
3085 			   tb[NL80211_ATTR_STA_WME],
3086 			   tb[NL80211_ATTR_REQ_IE]);
3087 		break;
3088 	case NL80211_CMD_CONNECT:
3089 	case NL80211_CMD_ROAM:
3090 		mlme_event_connect(drv, cmd,
3091 				   tb[NL80211_ATTR_STATUS_CODE],
3092 				   tb[NL80211_ATTR_MAC],
3093 				   tb[NL80211_ATTR_REQ_IE],
3094 				   tb[NL80211_ATTR_RESP_IE],
3095 				   tb[NL80211_ATTR_TIMED_OUT],
3096 				   tb[NL80211_ATTR_TIMEOUT_REASON],
3097 				   NULL, NULL, NULL,
3098 				   tb[NL80211_ATTR_FILS_KEK],
3099 				   NULL,
3100 				   tb[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM],
3101 				   tb[NL80211_ATTR_PMK],
3102 				   tb[NL80211_ATTR_PMKID]);
3103 		break;
3104 	case NL80211_CMD_CH_SWITCH_STARTED_NOTIFY:
3105 		mlme_event_ch_switch(drv,
3106 				     tb[NL80211_ATTR_IFINDEX],
3107 				     tb[NL80211_ATTR_WIPHY_FREQ],
3108 				     tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE],
3109 				     tb[NL80211_ATTR_CHANNEL_WIDTH],
3110 				     tb[NL80211_ATTR_CENTER_FREQ1],
3111 				     tb[NL80211_ATTR_CENTER_FREQ2],
3112 				     0);
3113 		break;
3114 	case NL80211_CMD_CH_SWITCH_NOTIFY:
3115 		mlme_event_ch_switch(drv,
3116 				     tb[NL80211_ATTR_IFINDEX],
3117 				     tb[NL80211_ATTR_WIPHY_FREQ],
3118 				     tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE],
3119 				     tb[NL80211_ATTR_CHANNEL_WIDTH],
3120 				     tb[NL80211_ATTR_CENTER_FREQ1],
3121 				     tb[NL80211_ATTR_CENTER_FREQ2],
3122 				     1);
3123 		break;
3124 	case NL80211_CMD_DISCONNECT:
3125 		mlme_event_disconnect(drv, tb[NL80211_ATTR_REASON_CODE],
3126 				      tb[NL80211_ATTR_MAC],
3127 				      tb[NL80211_ATTR_DISCONNECTED_BY_AP]);
3128 		break;
3129 	case NL80211_CMD_MICHAEL_MIC_FAILURE:
3130 		mlme_event_michael_mic_failure(bss, tb);
3131 		break;
3132 	case NL80211_CMD_JOIN_IBSS:
3133 		mlme_event_join_ibss(drv, tb);
3134 		break;
3135 	case NL80211_CMD_REMAIN_ON_CHANNEL:
3136 		mlme_event_remain_on_channel(drv, 0, tb);
3137 		break;
3138 	case NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL:
3139 		mlme_event_remain_on_channel(drv, 1, tb);
3140 		break;
3141 	case NL80211_CMD_NOTIFY_CQM:
3142 		nl80211_cqm_event(drv, tb);
3143 		break;
3144 	case NL80211_CMD_REG_CHANGE:
3145 	case NL80211_CMD_WIPHY_REG_CHANGE:
3146 		nl80211_reg_change_event(drv, tb);
3147 		break;
3148 	case NL80211_CMD_REG_BEACON_HINT:
3149 		nl80211_reg_beacon_hint_event(drv, tb);
3150 		break;
3151 	case NL80211_CMD_NEW_STATION:
3152 		nl80211_new_station_event(drv, bss, tb);
3153 		break;
3154 	case NL80211_CMD_DEL_STATION:
3155 		nl80211_del_station_event(drv, bss, tb);
3156 		break;
3157 	case NL80211_CMD_SET_REKEY_OFFLOAD:
3158 		nl80211_rekey_offload_event(drv, tb);
3159 		break;
3160 	case NL80211_CMD_PMKSA_CANDIDATE:
3161 		nl80211_pmksa_candidate_event(drv, tb);
3162 		break;
3163 	case NL80211_CMD_PROBE_CLIENT:
3164 		nl80211_client_probe_event(drv, tb);
3165 		break;
3166 	case NL80211_CMD_TDLS_OPER:
3167 		nl80211_tdls_oper_event(drv, tb);
3168 		break;
3169 	case NL80211_CMD_CONN_FAILED:
3170 		nl80211_connect_failed_event(drv, tb);
3171 		break;
3172 	case NL80211_CMD_FT_EVENT:
3173 		mlme_event_ft_event(drv, tb);
3174 		break;
3175 	case NL80211_CMD_RADAR_DETECT:
3176 		nl80211_radar_event(drv, tb);
3177 		break;
3178 	case NL80211_CMD_STOP_AP:
3179 		nl80211_stop_ap(drv, tb);
3180 		break;
3181 	case NL80211_CMD_VENDOR:
3182 		nl80211_vendor_event(drv, tb);
3183 		break;
3184 	case NL80211_CMD_NEW_PEER_CANDIDATE:
3185 		nl80211_new_peer_candidate(drv, tb);
3186 		break;
3187 	case NL80211_CMD_PORT_AUTHORIZED:
3188 		nl80211_port_authorized(drv, tb);
3189 		break;
3190 	case NL80211_CMD_STA_OPMODE_CHANGED:
3191 		nl80211_sta_opmode_change_event(drv, tb);
3192 		break;
3193 	case NL80211_CMD_UPDATE_OWE_INFO:
3194 		mlme_event_dh_event(drv, bss, tb);
3195 		break;
3196 	case NL80211_CMD_UNPROT_BEACON:
3197 		if (frame)
3198 			mlme_event_unprot_beacon(drv, nla_data(frame),
3199 						 nla_len(frame));
3200 		break;
3201 	case NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS:
3202 		if (!frame)
3203 			break;
3204 		nl80211_control_port_frame_tx_status(drv,
3205 						     nla_data(frame),
3206 						     nla_len(frame),
3207 						     tb[NL80211_ATTR_ACK],
3208 						     tb[NL80211_ATTR_COOKIE]);
3209 		break;
3210 	case NL80211_CMD_FRAME_WAIT_CANCEL:
3211 		nl80211_frame_wait_cancel(drv, tb[NL80211_ATTR_COOKIE]);
3212 		break;
3213 	case NL80211_CMD_ASSOC_COMEBACK:
3214 		nl80211_assoc_comeback(drv, tb[NL80211_ATTR_MAC],
3215 				       tb[NL80211_ATTR_TIMEOUT]);
3216 		break;
3217 #ifdef CONFIG_IEEE80211AX
3218 	case NL80211_CMD_OBSS_COLOR_COLLISION:
3219 		nl80211_obss_color_collision(drv, tb);
3220 		break;
3221 	case NL80211_CMD_COLOR_CHANGE_STARTED:
3222 		nl80211_color_change_announcement_started(drv);
3223 		break;
3224 	case NL80211_CMD_COLOR_CHANGE_ABORTED:
3225 		nl80211_color_change_announcement_aborted(drv);
3226 		break;
3227 	case NL80211_CMD_COLOR_CHANGE_COMPLETED:
3228 		nl80211_color_change_announcement_completed(drv);
3229 		break;
3230 #endif /* CONFIG_IEEE80211AX */
3231 	default:
3232 		wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Ignored unknown event "
3233 			"(cmd=%d)", cmd);
3234 		break;
3235 	}
3236 }
3237 
3238 
process_global_event(struct nl_msg * msg,void * arg)3239 int process_global_event(struct nl_msg *msg, void *arg)
3240 {
3241 	struct nl80211_global *global = arg;
3242 	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
3243 	struct nlattr *tb[NL80211_ATTR_MAX + 1];
3244 	struct wpa_driver_nl80211_data *drv, *tmp;
3245 	int ifidx = -1, wiphy_idx = -1, wiphy_idx_rx = -1;
3246 	struct i802_bss *bss;
3247 	u64 wdev_id = 0;
3248 	int wdev_id_set = 0;
3249 	int wiphy_idx_set = 0;
3250 
3251 	nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
3252 		  genlmsg_attrlen(gnlh, 0), NULL);
3253 
3254 	if (tb[NL80211_ATTR_IFINDEX])
3255 		ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
3256 	else if (tb[NL80211_ATTR_WDEV]) {
3257 		wdev_id = nla_get_u64(tb[NL80211_ATTR_WDEV]);
3258 		wdev_id_set = 1;
3259 	} else if (tb[NL80211_ATTR_WIPHY]) {
3260 		wiphy_idx_rx = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
3261 		wiphy_idx_set = 1;
3262 	}
3263 
3264 	dl_list_for_each_safe(drv, tmp, &global->interfaces,
3265 			      struct wpa_driver_nl80211_data, list) {
3266 		for (bss = drv->first_bss; bss; bss = bss->next) {
3267 			if (wiphy_idx_set)
3268 				wiphy_idx = nl80211_get_wiphy_index(bss);
3269 			if ((ifidx == -1 && !wiphy_idx_set && !wdev_id_set) ||
3270 			    ifidx == bss->ifindex ||
3271 			    (wiphy_idx_set && wiphy_idx == wiphy_idx_rx) ||
3272 			    (wdev_id_set && bss->wdev_id_set &&
3273 			     wdev_id == bss->wdev_id)) {
3274 				do_process_drv_event(bss, gnlh->cmd, tb);
3275 				return NL_SKIP;
3276 			}
3277 		}
3278 		wpa_printf(MSG_DEBUG,
3279 			   "nl80211: Ignored event %d (%s) for foreign interface (ifindex %d wdev 0x%llx)",
3280 			   gnlh->cmd, nl80211_command_to_string(gnlh->cmd),
3281 			   ifidx, (long long unsigned int) wdev_id);
3282 	}
3283 
3284 	return NL_SKIP;
3285 }
3286 
3287 
process_bss_event(struct nl_msg * msg,void * arg)3288 int process_bss_event(struct nl_msg *msg, void *arg)
3289 {
3290 	struct i802_bss *bss = arg;
3291 	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
3292 	struct nlattr *tb[NL80211_ATTR_MAX + 1];
3293 
3294 	nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
3295 		  genlmsg_attrlen(gnlh, 0), NULL);
3296 
3297 	wpa_printf(MSG_DEBUG, "nl80211: BSS Event %d (%s) received for %s",
3298 		   gnlh->cmd, nl80211_command_to_string(gnlh->cmd),
3299 		   bss->ifname);
3300 
3301 	switch (gnlh->cmd) {
3302 	case NL80211_CMD_FRAME:
3303 	case NL80211_CMD_FRAME_TX_STATUS:
3304 		mlme_event(bss, gnlh->cmd, tb[NL80211_ATTR_FRAME],
3305 			   tb[NL80211_ATTR_MAC], tb[NL80211_ATTR_TIMED_OUT],
3306 			   tb[NL80211_ATTR_WIPHY_FREQ], tb[NL80211_ATTR_ACK],
3307 			   tb[NL80211_ATTR_COOKIE],
3308 			   tb[NL80211_ATTR_RX_SIGNAL_DBM],
3309 			   tb[NL80211_ATTR_STA_WME], NULL);
3310 		break;
3311 	case NL80211_CMD_UNEXPECTED_FRAME:
3312 		nl80211_spurious_frame(bss, tb, 0);
3313 		break;
3314 	case NL80211_CMD_UNEXPECTED_4ADDR_FRAME:
3315 		nl80211_spurious_frame(bss, tb, 1);
3316 		break;
3317 	case NL80211_CMD_EXTERNAL_AUTH:
3318 		nl80211_external_auth(bss->drv, tb);
3319 		break;
3320 	case NL80211_CMD_CONTROL_PORT_FRAME:
3321 		nl80211_control_port_frame(bss->drv, tb);
3322 		break;
3323 	default:
3324 		wpa_printf(MSG_DEBUG, "nl80211: Ignored unknown event "
3325 			   "(cmd=%d)", gnlh->cmd);
3326 		break;
3327 	}
3328 
3329 	return NL_SKIP;
3330 }
3331