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