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