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