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