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