Lines Matching +full:mic +full:- +full:pos
2 * wpa_supplicant - TDLS
3 * Copyright (c) 2010-2011, Atheros Communications
56 u8 mic[TDLS_MIC_LEN]; member
77 /* TDLS frame headers as per IEEE Std 802.11z-2010 */
84 static u8 * wpa_add_tdls_timeoutie(u8 *pos, u8 *ie, size_t ie_len, u32 tsecs);
112 u8 kck[16]; /* TPK-KCK */
113 u8 tk[16]; /* TPK-TK; assuming only CCMP will be used */
116 int tk_set; /* TPK-TK configured to the driver */
172 return sm->mlo.links[link_id].bssid; in wpa_tdls_get_link_bssid()
173 return sm->bssid; in wpa_tdls_get_link_bssid()
184 return sm->pairwise_cipher != WPA_CIPHER_NONE; in wpa_tdls_get_privacy()
188 static u8 * wpa_add_ie(u8 *pos, const u8 *ie, size_t ie_len) in wpa_add_ie() argument
190 os_memcpy(pos, ie, ie_len); in wpa_add_ie()
191 return pos + ie_len; in wpa_add_ie()
197 if (wpa_sm_set_key(sm, -1, WPA_ALG_NONE, peer->addr, in wpa_tdls_del_key()
199 wpa_printf(MSG_WARNING, "TDLS: Failed to delete TPK-TK from " in wpa_tdls_del_key()
201 return -1; in wpa_tdls_del_key()
214 if (peer->tk_set) { in wpa_tdls_set_key()
216 * This same TPK-TK has already been configured to the driver in wpa_tdls_set_key()
222 wpa_printf(MSG_INFO, "TDLS: TPK-TK for the peer " MACSTR in wpa_tdls_set_key()
223 " has already been configured to the driver - do not reconfigure", in wpa_tdls_set_key()
224 MAC2STR(peer->addr)); in wpa_tdls_set_key()
225 return -1; in wpa_tdls_set_key()
230 switch (peer->cipher) { in wpa_tdls_set_key()
237 "NONE - do not use pairwise keys"); in wpa_tdls_set_key()
238 return -1; in wpa_tdls_set_key()
241 sm->pairwise_cipher); in wpa_tdls_set_key()
242 return -1; in wpa_tdls_set_key()
246 MAC2STR(peer->addr)); in wpa_tdls_set_key()
247 if (wpa_sm_set_key(sm, -1, alg, peer->addr, 0, 1, rsc, sizeof(rsc), in wpa_tdls_set_key()
248 peer->tpk.tk, key_len, in wpa_tdls_set_key()
252 return -1; in wpa_tdls_set_key()
254 peer->tk_set = 1; in wpa_tdls_set_key()
289 return -1; in wpa_tdls_tpk_send()
298 for (peer = sm->tdls; peer; peer = peer->next) { in wpa_tdls_tpk_send()
299 if (ether_addr_equal(peer->addr, dest)) in wpa_tdls_tpk_send()
312 peer->sm_tmr.count = TPK_M2_RETRY_COUNT; in wpa_tdls_tpk_send()
313 peer->sm_tmr.timer = TPK_M2_TIMEOUT; in wpa_tdls_tpk_send()
315 peer->sm_tmr.count = TPK_M1_RETRY_COUNT; in wpa_tdls_tpk_send()
316 peer->sm_tmr.timer = TPK_M1_TIMEOUT; in wpa_tdls_tpk_send()
320 os_memcpy(peer->sm_tmr.dest, dest, ETH_ALEN); in wpa_tdls_tpk_send()
321 peer->sm_tmr.action_code = action_code; in wpa_tdls_tpk_send()
322 peer->sm_tmr.dialog_token = dialog_token; in wpa_tdls_tpk_send()
323 peer->sm_tmr.status_code = status_code; in wpa_tdls_tpk_send()
324 peer->sm_tmr.peer_capab = peer_capab; in wpa_tdls_tpk_send()
325 peer->sm_tmr.buf_len = msg_len; in wpa_tdls_tpk_send()
326 os_free(peer->sm_tmr.buf); in wpa_tdls_tpk_send()
327 peer->sm_tmr.buf = os_memdup(msg, msg_len); in wpa_tdls_tpk_send()
328 if (peer->sm_tmr.buf == NULL) in wpa_tdls_tpk_send()
329 return -1; in wpa_tdls_tpk_send()
333 eloop_register_timeout(peer->sm_tmr.timer / 1000, in wpa_tdls_tpk_send()
334 (peer->sm_tmr.timer % 1000) * 1000, in wpa_tdls_tpk_send()
345 ret = wpa_tdls_send_teardown(sm, peer->addr, reason_code); in wpa_tdls_do_teardown()
359 if (peer->sm_tmr.count) { in wpa_tdls_tpk_retry_timeout()
360 peer->sm_tmr.count--; in wpa_tdls_tpk_retry_timeout()
364 peer->sm_tmr.action_code); in wpa_tdls_tpk_retry_timeout()
366 if (peer->sm_tmr.buf == NULL) { in wpa_tdls_tpk_retry_timeout()
369 peer->sm_tmr.action_code); in wpa_tdls_tpk_retry_timeout()
376 if (wpa_tdls_send_tpk_msg(sm, peer->sm_tmr.dest, in wpa_tdls_tpk_retry_timeout()
377 peer->sm_tmr.action_code, in wpa_tdls_tpk_retry_timeout()
378 peer->sm_tmr.dialog_token, in wpa_tdls_tpk_retry_timeout()
379 peer->sm_tmr.status_code, in wpa_tdls_tpk_retry_timeout()
380 peer->sm_tmr.peer_capab, in wpa_tdls_tpk_retry_timeout()
381 peer->initiator, in wpa_tdls_tpk_retry_timeout()
382 peer->sm_tmr.buf, in wpa_tdls_tpk_retry_timeout()
383 peer->sm_tmr.buf_len, -1)) { in wpa_tdls_tpk_retry_timeout()
389 eloop_register_timeout(peer->sm_tmr.timer / 1000, in wpa_tdls_tpk_retry_timeout()
390 (peer->sm_tmr.timer % 1000) * 1000, in wpa_tdls_tpk_retry_timeout()
406 if (action_code == peer->sm_tmr.action_code) { in wpa_tdls_tpk_retry_timeout_cancel()
414 os_free(peer->sm_tmr.buf); in wpa_tdls_tpk_retry_timeout_cancel()
415 peer->sm_tmr.buf = NULL; in wpa_tdls_tpk_retry_timeout_cancel()
417 peer->sm_tmr.count = 0; in wpa_tdls_tpk_retry_timeout_cancel()
418 peer->sm_tmr.timer = 0; in wpa_tdls_tpk_retry_timeout_cancel()
419 peer->sm_tmr.buf_len = 0; in wpa_tdls_tpk_retry_timeout_cancel()
420 peer->sm_tmr.action_code = 0xff; in wpa_tdls_tpk_retry_timeout_cancel()
436 /* IEEE Std 802.11-2016 12.7.9.2: in wpa_tdls_generate_tpk()
437 * TPK-Key-Input = Hash(min(SNonce, ANonce) || max(SNonce, ANonce)) in wpa_tdls_generate_tpk()
438 * Hash = SHA-256 for TDLS in wpa_tdls_generate_tpk()
442 if (os_memcmp(peer->inonce, peer->rnonce, WPA_NONCE_LEN) < 0) { in wpa_tdls_generate_tpk()
443 nonce[0] = peer->inonce; in wpa_tdls_generate_tpk()
444 nonce[1] = peer->rnonce; in wpa_tdls_generate_tpk()
446 nonce[0] = peer->rnonce; in wpa_tdls_generate_tpk()
447 nonce[1] = peer->inonce; in wpa_tdls_generate_tpk()
452 wpa_hexdump_key(MSG_DEBUG, "TDLS: TPK-Key-Input", in wpa_tdls_generate_tpk()
456 * TPK = KDF-Hash-Length(TPK-Key-Input, "TDLS PMK", in wpa_tdls_generate_tpk()
460 if (os_memcmp(own_addr, peer->addr, ETH_ALEN) < 0) { in wpa_tdls_generate_tpk()
462 os_memcpy(data + ETH_ALEN, peer->addr, ETH_ALEN); in wpa_tdls_generate_tpk()
464 os_memcpy(data, peer->addr, ETH_ALEN); in wpa_tdls_generate_tpk()
471 (u8 *) &peer->tpk, sizeof(peer->tpk)); in wpa_tdls_generate_tpk()
472 wpa_hexdump_key(MSG_DEBUG, "TDLS: TPK-KCK", in wpa_tdls_generate_tpk()
473 peer->tpk.kck, sizeof(peer->tpk.kck)); in wpa_tdls_generate_tpk()
474 wpa_hexdump_key(MSG_DEBUG, "TDLS: TPK-TK", in wpa_tdls_generate_tpk()
475 peer->tpk.tk, sizeof(peer->tpk.tk)); in wpa_tdls_generate_tpk()
476 peer->tpk_set = 1; in wpa_tdls_generate_tpk()
481 * wpa_tdls_ftie_mic - Calculate TDLS FTIE MIC
482 * @kck: TPK-KCK
489 * @mic: Pointer for writing MIC
491 * Calculate MIC for TDLS frame.
496 const u8 *fte, size_t fte_len, u8 *mic) in wpa_tdls_ftie_mic() argument
498 u8 *buf, *pos; in wpa_tdls_ftie_mic() local
506 wpa_printf(MSG_WARNING, "TDLS: No memory for MIC calculation"); in wpa_tdls_ftie_mic()
507 return -1; in wpa_tdls_ftie_mic()
510 pos = buf; in wpa_tdls_ftie_mic()
513 os_memcpy(pos, _lnkid->init_sta, ETH_ALEN); in wpa_tdls_ftie_mic()
514 pos += ETH_ALEN; in wpa_tdls_ftie_mic()
516 os_memcpy(pos, _lnkid->resp_sta, ETH_ALEN); in wpa_tdls_ftie_mic()
517 pos += ETH_ALEN; in wpa_tdls_ftie_mic()
519 *pos++ = trans_seq; in wpa_tdls_ftie_mic()
521 os_memcpy(pos, lnkid, 2 + lnkid[1]); in wpa_tdls_ftie_mic()
522 pos += 2 + lnkid[1]; in wpa_tdls_ftie_mic()
524 os_memcpy(pos, rsne, rsne_len); in wpa_tdls_ftie_mic()
525 pos += rsne_len; in wpa_tdls_ftie_mic()
527 os_memcpy(pos, timeoutie, 2 + timeoutie[1]); in wpa_tdls_ftie_mic()
528 pos += 2 + timeoutie[1]; in wpa_tdls_ftie_mic()
529 /* 7) FTIE, with the MIC field of the FTIE set to 0 */ in wpa_tdls_ftie_mic()
530 os_memcpy(pos, fte, fte_len); in wpa_tdls_ftie_mic()
531 _ftie = (struct wpa_tdls_ftie *) pos; in wpa_tdls_ftie_mic()
532 os_memset(_ftie->mic, 0, TDLS_MIC_LEN); in wpa_tdls_ftie_mic()
533 pos += fte_len; in wpa_tdls_ftie_mic()
535 wpa_hexdump(MSG_DEBUG, "TDLS: Data for FTIE MIC", buf, pos - buf); in wpa_tdls_ftie_mic()
537 ret = omac1_aes_128(kck, buf, pos - buf, mic); in wpa_tdls_ftie_mic()
539 wpa_hexdump(MSG_DEBUG, "TDLS: FTIE MIC", mic, 16); in wpa_tdls_ftie_mic()
545 * wpa_tdls_key_mic_teardown - Calculate TDLS FTIE MIC for Teardown frame
546 * @kck: TPK-KCK
547 * @trans_seq: Transaction Sequence Number (4 - Teardown)
553 * @mic: Pointer for writing MIC
555 * Calculate MIC for TDLS frame.
559 const u8 *fte, size_t fte_len, u8 *mic) in wpa_tdls_key_mic_teardown() argument
561 u8 *buf, *pos; in wpa_tdls_key_mic_teardown() local
567 return -1; in wpa_tdls_key_mic_teardown()
574 wpa_printf(MSG_WARNING, "TDLS: No memory for MIC calculation"); in wpa_tdls_key_mic_teardown()
575 return -1; in wpa_tdls_key_mic_teardown()
578 pos = buf; in wpa_tdls_key_mic_teardown()
580 os_memcpy(pos, lnkid, 2 + lnkid[1]); in wpa_tdls_key_mic_teardown()
581 pos += 2 + lnkid[1]; in wpa_tdls_key_mic_teardown()
583 WPA_PUT_LE16(pos, rcode); in wpa_tdls_key_mic_teardown()
584 pos += sizeof(rcode); in wpa_tdls_key_mic_teardown()
586 *pos++ = dtoken; in wpa_tdls_key_mic_teardown()
588 *pos++ = trans_seq; in wpa_tdls_key_mic_teardown()
589 /* 7) FTIE, with the MIC field of the FTIE set to 0 */ in wpa_tdls_key_mic_teardown()
590 os_memcpy(pos, fte, fte_len); in wpa_tdls_key_mic_teardown()
591 _ftie = (struct wpa_tdls_ftie *) pos; in wpa_tdls_key_mic_teardown()
592 os_memset(_ftie->mic, 0, TDLS_MIC_LEN); in wpa_tdls_key_mic_teardown()
593 pos += fte_len; in wpa_tdls_key_mic_teardown()
595 wpa_hexdump(MSG_DEBUG, "TDLS: Data for FTIE MIC", buf, pos - buf); in wpa_tdls_key_mic_teardown()
597 ret = omac1_aes_128(kck, buf, pos - buf, mic); in wpa_tdls_key_mic_teardown()
599 wpa_hexdump(MSG_DEBUG, "TDLS: FTIE MIC", mic, 16); in wpa_tdls_key_mic_teardown()
610 u8 mic[16]; in wpa_supplicant_verify_tdls_mic() local
612 if (peer->tpk_set) { in wpa_supplicant_verify_tdls_mic()
613 wpa_tdls_ftie_mic(peer->tpk.kck, trans_seq, lnkid, in wpa_supplicant_verify_tdls_mic()
614 peer->rsnie_p, peer->rsnie_p_len, timeoutie, in wpa_supplicant_verify_tdls_mic()
615 (const u8 *) ftie, fte_len, mic); in wpa_supplicant_verify_tdls_mic()
616 if (os_memcmp_const(mic, ftie->mic, 16) != 0) { in wpa_supplicant_verify_tdls_mic()
617 wpa_printf(MSG_INFO, "TDLS: Invalid MIC in FTIE - " in wpa_supplicant_verify_tdls_mic()
619 wpa_hexdump(MSG_DEBUG, "TDLS: Received MIC", in wpa_supplicant_verify_tdls_mic()
620 ftie->mic, 16); in wpa_supplicant_verify_tdls_mic()
621 wpa_hexdump(MSG_DEBUG, "TDLS: Calculated MIC", in wpa_supplicant_verify_tdls_mic()
622 mic, 16); in wpa_supplicant_verify_tdls_mic()
623 return -1; in wpa_supplicant_verify_tdls_mic()
626 wpa_printf(MSG_WARNING, "TDLS: Could not verify TDLS MIC, " in wpa_supplicant_verify_tdls_mic()
627 "TPK not set - dropping packet"); in wpa_supplicant_verify_tdls_mic()
628 return -1; in wpa_supplicant_verify_tdls_mic()
638 u8 mic[16]; in wpa_supplicant_verify_tdls_mic_teardown() local
640 if (peer->tpk_set) { in wpa_supplicant_verify_tdls_mic_teardown()
641 wpa_tdls_key_mic_teardown(peer->tpk.kck, trans_seq, rcode, in wpa_supplicant_verify_tdls_mic_teardown()
643 fte_len, mic); in wpa_supplicant_verify_tdls_mic_teardown()
644 if (os_memcmp_const(mic, ftie->mic, 16) != 0) { in wpa_supplicant_verify_tdls_mic_teardown()
645 wpa_printf(MSG_INFO, "TDLS: Invalid MIC in Teardown - " in wpa_supplicant_verify_tdls_mic_teardown()
647 return -1; in wpa_supplicant_verify_tdls_mic_teardown()
651 "MIC, TPK not set - dropping packet"); in wpa_supplicant_verify_tdls_mic_teardown()
652 return -1; in wpa_supplicant_verify_tdls_mic_teardown()
665 * the direct link or trying to re-initiate it. The selection of what in wpa_tdls_tpk_timeout()
671 if (peer->initiator) { in wpa_tdls_tpk_timeout()
675 " - try to renew", MAC2STR(peer->addr)); in wpa_tdls_tpk_timeout()
677 os_memcpy(addr, peer->addr, ETH_ALEN); in wpa_tdls_tpk_timeout()
683 " - tear down", MAC2STR(peer->addr)); in wpa_tdls_tpk_timeout()
695 cur = sm->tdls; in wpa_tdls_peer_remove_from_list()
699 cur = cur->next; in wpa_tdls_peer_remove_from_list()
705 MAC2STR(peer->addr)); in wpa_tdls_peer_remove_from_list()
710 prev->next = peer->next; in wpa_tdls_peer_remove_from_list()
712 sm->tdls = peer->next; in wpa_tdls_peer_remove_from_list()
719 MAC2STR(peer->addr)); in wpa_tdls_peer_clear()
722 peer->reconfig_key = 0; in wpa_tdls_peer_clear()
723 peer->initiator = 0; in wpa_tdls_peer_clear()
724 peer->tpk_in_progress = 0; in wpa_tdls_peer_clear()
725 os_free(peer->sm_tmr.buf); in wpa_tdls_peer_clear()
726 peer->sm_tmr.buf = NULL; in wpa_tdls_peer_clear()
727 os_free(peer->ht_capabilities); in wpa_tdls_peer_clear()
728 peer->ht_capabilities = NULL; in wpa_tdls_peer_clear()
729 os_free(peer->vht_capabilities); in wpa_tdls_peer_clear()
730 peer->vht_capabilities = NULL; in wpa_tdls_peer_clear()
731 os_free(peer->he_capabilities); in wpa_tdls_peer_clear()
732 peer->he_capabilities = NULL; in wpa_tdls_peer_clear()
733 os_free(peer->he_6ghz_band_capabilities); in wpa_tdls_peer_clear()
734 peer->he_6ghz_band_capabilities = NULL; in wpa_tdls_peer_clear()
735 os_free(peer->eht_capabilities); in wpa_tdls_peer_clear()
736 peer->eht_capabilities = NULL; in wpa_tdls_peer_clear()
737 os_free(peer->ext_capab); in wpa_tdls_peer_clear()
738 peer->ext_capab = NULL; in wpa_tdls_peer_clear()
739 os_free(peer->supp_channels); in wpa_tdls_peer_clear()
740 peer->supp_channels = NULL; in wpa_tdls_peer_clear()
741 os_free(peer->supp_oper_classes); in wpa_tdls_peer_clear()
742 peer->supp_oper_classes = NULL; in wpa_tdls_peer_clear()
743 peer->rsnie_i_len = peer->rsnie_p_len = 0; in wpa_tdls_peer_clear()
744 peer->cipher = 0; in wpa_tdls_peer_clear()
745 peer->qos_info = 0; in wpa_tdls_peer_clear()
746 peer->wmm_capable = 0; in wpa_tdls_peer_clear()
747 peer->tk_set = peer->tpk_set = peer->tpk_success = 0; in wpa_tdls_peer_clear()
748 peer->chan_switch_enabled = 0; in wpa_tdls_peer_clear()
749 os_memset(&peer->tpk, 0, sizeof(peer->tpk)); in wpa_tdls_peer_clear()
750 os_memset(peer->inonce, 0, WPA_NONCE_LEN); in wpa_tdls_peer_clear()
751 os_memset(peer->rnonce, 0, WPA_NONCE_LEN); in wpa_tdls_peer_clear()
752 peer->mld_link_id = -1; in wpa_tdls_peer_clear()
767 lnkid->ie_type = WLAN_EID_LINK_ID; in wpa_tdls_linkid()
768 lnkid->ie_len = 3 * ETH_ALEN; in wpa_tdls_linkid()
769 os_memcpy(lnkid->bssid, wpa_tdls_get_link_bssid(sm, peer->mld_link_id), in wpa_tdls_linkid()
771 if (peer->initiator) { in wpa_tdls_linkid()
772 os_memcpy(lnkid->init_sta, sm->own_addr, ETH_ALEN); in wpa_tdls_linkid()
773 os_memcpy(lnkid->resp_sta, peer->addr, ETH_ALEN); in wpa_tdls_linkid()
775 os_memcpy(lnkid->init_sta, peer->addr, ETH_ALEN); in wpa_tdls_linkid()
776 os_memcpy(lnkid->resp_sta, sm->own_addr, ETH_ALEN); in wpa_tdls_linkid()
788 u8 *rbuf, *pos; in wpa_tdls_send_teardown() local
791 if (sm->tdls_disabled || !sm->tdls_supported) in wpa_tdls_send_teardown()
792 return -1; in wpa_tdls_send_teardown()
795 for (peer = sm->tdls; peer; peer = peer->next) { in wpa_tdls_send_teardown()
796 if (ether_addr_equal(peer->addr, addr)) in wpa_tdls_send_teardown()
807 if (peer->chan_switch_enabled) { in wpa_tdls_send_teardown()
810 wpa_sm_tdls_disable_channel_switch(sm, peer->addr); in wpa_tdls_send_teardown()
813 dialog_token = peer->dtoken; in wpa_tdls_send_teardown()
819 if (wpa_tdls_get_privacy(sm) && peer->tpk_set && peer->tpk_success) { in wpa_tdls_send_teardown()
820 /* To add FTIE for Teardown request and compute MIC */ in wpa_tdls_send_teardown()
830 return -1; in wpa_tdls_send_teardown()
831 pos = rbuf; in wpa_tdls_send_teardown()
833 if (!wpa_tdls_get_privacy(sm) || !peer->tpk_set || !peer->tpk_success) in wpa_tdls_send_teardown()
836 ftie = (struct wpa_tdls_ftie *) pos; in wpa_tdls_send_teardown()
837 ftie->ie_type = WLAN_EID_FAST_BSS_TRANSITION; in wpa_tdls_send_teardown()
839 os_memcpy(ftie->Anonce, peer->rnonce, WPA_NONCE_LEN); in wpa_tdls_send_teardown()
840 os_memcpy(ftie->Snonce, peer->inonce, WPA_NONCE_LEN); in wpa_tdls_send_teardown()
841 ftie->ie_len = sizeof(struct wpa_tdls_ftie) - 2; in wpa_tdls_send_teardown()
842 pos = (u8 *) (ftie + 1); in wpa_tdls_send_teardown()
845 wpa_printf(MSG_DEBUG, "TDLS: Testing - add extra subelem to " in wpa_tdls_send_teardown()
847 ftie->ie_len += 170; in wpa_tdls_send_teardown()
848 *pos++ = 255; /* FTIE subelem */ in wpa_tdls_send_teardown()
849 *pos++ = 168; /* FTIE subelem length */ in wpa_tdls_send_teardown()
850 pos += 168; in wpa_tdls_send_teardown()
854 (u8 *) ftie, pos - (u8 *) ftie); in wpa_tdls_send_teardown()
856 /* compute MIC before sending */ in wpa_tdls_send_teardown()
858 wpa_tdls_key_mic_teardown(peer->tpk.kck, 4, reason_code, in wpa_tdls_send_teardown()
860 (const u8 *) ftie, 2 + ftie->ie_len, in wpa_tdls_send_teardown()
861 ftie->mic); in wpa_tdls_send_teardown()
869 reason_code, 0, peer->initiator, rbuf, pos - rbuf, in wpa_tdls_send_teardown()
870 -1); in wpa_tdls_send_teardown()
881 if (sm->tdls_disabled || !sm->tdls_supported) in wpa_tdls_teardown_link()
882 return -1; in wpa_tdls_teardown_link()
884 for (peer = sm->tdls; peer; peer = peer->next) { in wpa_tdls_teardown_link()
885 if (ether_addr_equal(peer->addr, addr)) in wpa_tdls_teardown_link()
892 return -1; in wpa_tdls_teardown_link()
895 if (!peer->tpk_success) { in wpa_tdls_teardown_link()
897 " not connected - cannot Teardown link", MAC2STR(addr)); in wpa_tdls_teardown_link()
898 return -1; in wpa_tdls_teardown_link()
908 wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, peer->addr); in wpa_tdls_disable_peer_link()
917 for (peer = sm->tdls; peer; peer = peer->next) { in wpa_tdls_disable_unreachable_link()
918 if (ether_addr_equal(peer->addr, addr)) in wpa_tdls_disable_unreachable_link()
922 if (!peer || !peer->tpk_success) { in wpa_tdls_disable_unreachable_link()
924 " not connected - cannot teardown unreachable link", in wpa_tdls_disable_unreachable_link()
934 if (peer->chan_switch_enabled) in wpa_tdls_disable_unreachable_link()
935 wpa_sm_tdls_disable_channel_switch(sm, peer->addr); in wpa_tdls_disable_unreachable_link()
950 if (sm->tdls_disabled || !sm->tdls_supported) in wpa_tdls_get_link_status()
953 for (peer = sm->tdls; peer; peer = peer->next) { in wpa_tdls_get_link_status()
954 if (ether_addr_equal(peer->addr, addr)) in wpa_tdls_get_link_status()
961 if (!peer->tpk_success) in wpa_tdls_get_link_status()
976 const u8 *pos; in wpa_tdls_recv_teardown() local
980 for (peer = sm->tdls; peer; peer = peer->next) { in wpa_tdls_recv_teardown()
981 if (ether_addr_equal(peer->addr, src_addr)) in wpa_tdls_recv_teardown()
991 pos = buf; in wpa_tdls_recv_teardown()
992 pos += 1 /* pkt_type */ + 1 /* Category */ + 1 /* Action */; in wpa_tdls_recv_teardown()
994 reason_code = WPA_GET_LE16(pos); in wpa_tdls_recv_teardown()
995 pos += 2; in wpa_tdls_recv_teardown()
1000 ielen = len - (pos - buf); /* start of IE in buf */ in wpa_tdls_recv_teardown()
1007 if (wpa_supplicant_parse_ies((const u8 *) pos, ielen, &kde) < 0) in wpa_tdls_recv_teardown()
1009 "TDLS: Failed to parse IEs in Teardown - ignore as an interop workaround"); in wpa_tdls_recv_teardown()
1014 return -1; in wpa_tdls_recv_teardown()
1018 if (!wpa_tdls_get_privacy(sm) || !peer->tpk_set || !peer->tpk_success) in wpa_tdls_recv_teardown()
1023 return -1; in wpa_tdls_recv_teardown()
1028 /* Process MIC check to see if TDLS Teardown is right */ in wpa_tdls_recv_teardown()
1030 peer->dtoken, peer, in wpa_tdls_recv_teardown()
1033 wpa_printf(MSG_DEBUG, "TDLS: MIC failure for TDLS " in wpa_tdls_recv_teardown()
1035 return -1; in wpa_tdls_recv_teardown()
1049 * wpa_tdls_send_error - To send suitable TDLS status response with
1051 * @dst - MAC addr of Peer station
1052 * @tdls_action - TDLS frame type for which error code is sent
1053 * @initiator - was this end the initiator of the connection
1054 * @status - status code mentioning reason
1065 0, initiator, NULL, 0, -1); in wpa_tdls_send_error()
1076 for (peer = sm->tdls; peer; peer = peer->next) { in wpa_tdls_add_peer()
1077 if (ether_addr_equal(peer->addr, addr)) { in wpa_tdls_add_peer()
1080 return peer; /* re-use existing entry */ in wpa_tdls_add_peer()
1091 os_memcpy(peer->addr, addr, ETH_ALEN); in wpa_tdls_add_peer()
1092 peer->mld_link_id = -1; in wpa_tdls_add_peer()
1093 peer->next = sm->tdls; in wpa_tdls_add_peer()
1094 sm->tdls = peer; in wpa_tdls_add_peer()
1107 u8 *rbuf, *pos, *count_pos; in wpa_tdls_send_tpk_m1() local
1114 peer->rsnie_i_len = 0; in wpa_tdls_send_tpk_m1()
1120 * FTIE: ANonce=0, SNonce=initiator nonce MIC=0, DataKDs=(RSNIE_I, in wpa_tdls_send_tpk_m1()
1125 hdr = (struct rsn_ie_hdr *) peer->rsnie_i; in wpa_tdls_send_tpk_m1()
1126 hdr->elem_id = WLAN_EID_RSN; in wpa_tdls_send_tpk_m1()
1127 WPA_PUT_LE16(hdr->version, RSN_VERSION); in wpa_tdls_send_tpk_m1()
1129 pos = (u8 *) (hdr + 1); in wpa_tdls_send_tpk_m1()
1130 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED); in wpa_tdls_send_tpk_m1()
1131 pos += RSN_SELECTOR_LEN; in wpa_tdls_send_tpk_m1()
1132 count_pos = pos; in wpa_tdls_send_tpk_m1()
1133 pos += 2; in wpa_tdls_send_tpk_m1()
1138 * AES-CCMP is the default Encryption preferred for TDLS, so in wpa_tdls_send_tpk_m1()
1145 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP); in wpa_tdls_send_tpk_m1()
1146 pos += RSN_SELECTOR_LEN; in wpa_tdls_send_tpk_m1()
1151 WPA_PUT_LE16(pos, 1); in wpa_tdls_send_tpk_m1()
1152 pos += 2; in wpa_tdls_send_tpk_m1()
1153 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_TPK_HANDSHAKE); in wpa_tdls_send_tpk_m1()
1154 pos += RSN_SELECTOR_LEN; in wpa_tdls_send_tpk_m1()
1165 WPA_PUT_LE16(pos, rsn_capab); in wpa_tdls_send_tpk_m1()
1166 pos += 2; in wpa_tdls_send_tpk_m1()
1170 *pos++ = 0x00; in wpa_tdls_send_tpk_m1()
1171 *pos++ = 0x00; in wpa_tdls_send_tpk_m1()
1175 hdr->len = (pos - peer->rsnie_i) - 2; in wpa_tdls_send_tpk_m1()
1176 peer->rsnie_i_len = pos - peer->rsnie_i; in wpa_tdls_send_tpk_m1()
1178 peer->rsnie_i, peer->rsnie_i_len); in wpa_tdls_send_tpk_m1()
1183 buf_len += peer->rsnie_i_len + sizeof(struct wpa_tdls_ftie) + in wpa_tdls_send_tpk_m1()
1195 return -2; in wpa_tdls_send_tpk_m1()
1197 pos = rbuf; in wpa_tdls_send_tpk_m1()
1203 pos = wpa_add_ie(pos, peer->rsnie_i, peer->rsnie_i_len); in wpa_tdls_send_tpk_m1()
1205 ftie = (struct wpa_tdls_ftie *) pos; in wpa_tdls_send_tpk_m1()
1206 ftie->ie_type = WLAN_EID_FAST_BSS_TRANSITION; in wpa_tdls_send_tpk_m1()
1207 ftie->ie_len = sizeof(struct wpa_tdls_ftie) - 2; in wpa_tdls_send_tpk_m1()
1209 if (os_get_random(peer->inonce, WPA_NONCE_LEN)) { in wpa_tdls_send_tpk_m1()
1210 wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, in wpa_tdls_send_tpk_m1()
1214 return -2; in wpa_tdls_send_tpk_m1()
1216 peer->tk_set = 0; /* A new nonce results in a new TK */ in wpa_tdls_send_tpk_m1()
1218 peer->inonce, WPA_NONCE_LEN); in wpa_tdls_send_tpk_m1()
1219 os_memcpy(ftie->Snonce, peer->inonce, WPA_NONCE_LEN); in wpa_tdls_send_tpk_m1()
1224 pos = (u8 *) (ftie + 1); in wpa_tdls_send_tpk_m1()
1228 wpa_printf(MSG_DEBUG, "TDLS: Testing - add extra subelem to " in wpa_tdls_send_tpk_m1()
1230 ftie->ie_len += 170; in wpa_tdls_send_tpk_m1()
1231 *pos++ = 255; /* FTIE subelem */ in wpa_tdls_send_tpk_m1()
1232 *pos++ = 168; /* FTIE subelem length */ in wpa_tdls_send_tpk_m1()
1233 pos += 168; in wpa_tdls_send_tpk_m1()
1238 peer->lifetime = TPK_LIFETIME; in wpa_tdls_send_tpk_m1()
1241 wpa_printf(MSG_DEBUG, "TDLS: Testing - use short TPK " in wpa_tdls_send_tpk_m1()
1243 peer->lifetime = 301; in wpa_tdls_send_tpk_m1()
1246 wpa_printf(MSG_DEBUG, "TDLS: Testing - use long TPK " in wpa_tdls_send_tpk_m1()
1248 peer->lifetime = 0xffffffff; in wpa_tdls_send_tpk_m1()
1251 pos = wpa_add_tdls_timeoutie(pos, (u8 *) &timeoutie, in wpa_tdls_send_tpk_m1()
1252 sizeof(timeoutie), peer->lifetime); in wpa_tdls_send_tpk_m1()
1253 wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime %u seconds", peer->lifetime); in wpa_tdls_send_tpk_m1()
1259 struct wpa_tdls_lnkid *l = (struct wpa_tdls_lnkid *) pos; in wpa_tdls_send_tpk_m1()
1261 wpa_printf(MSG_DEBUG, "TDLS: Testing - use incorrect BSSID in " in wpa_tdls_send_tpk_m1()
1264 l->bssid[5] ^= 0x01; in wpa_tdls_send_tpk_m1()
1265 pos += sizeof(*l); in wpa_tdls_send_tpk_m1()
1271 MAC2STR(peer->addr)); in wpa_tdls_send_tpk_m1()
1273 status = wpa_tdls_tpk_send(sm, peer->addr, WLAN_TDLS_SETUP_REQUEST, in wpa_tdls_send_tpk_m1()
1274 1, 0, 0, peer->initiator, rbuf, pos - rbuf, in wpa_tdls_send_tpk_m1()
1275 -1); in wpa_tdls_send_tpk_m1()
1287 u8 *rbuf, *pos; in wpa_tdls_send_tpk_m2() local
1298 buf_len += peer->rsnie_i_len + sizeof(struct wpa_tdls_ftie) + in wpa_tdls_send_tpk_m2()
1308 return -1; in wpa_tdls_send_tpk_m2()
1309 pos = rbuf; in wpa_tdls_send_tpk_m2()
1315 pos = wpa_add_ie(pos, peer->rsnie_p, peer->rsnie_p_len); in wpa_tdls_send_tpk_m2()
1317 ftie = (struct wpa_tdls_ftie *) pos; in wpa_tdls_send_tpk_m2()
1318 ftie->ie_type = WLAN_EID_FAST_BSS_TRANSITION; in wpa_tdls_send_tpk_m2()
1319 /* TODO: ftie->mic_control to set 2-RESPONSE */ in wpa_tdls_send_tpk_m2()
1320 os_memcpy(ftie->Anonce, peer->rnonce, WPA_NONCE_LEN); in wpa_tdls_send_tpk_m2()
1321 os_memcpy(ftie->Snonce, peer->inonce, WPA_NONCE_LEN); in wpa_tdls_send_tpk_m2()
1322 ftie->ie_len = sizeof(struct wpa_tdls_ftie) - 2; in wpa_tdls_send_tpk_m2()
1326 pos = (u8 *) (ftie + 1); in wpa_tdls_send_tpk_m2()
1330 wpa_printf(MSG_DEBUG, "TDLS: Testing - add extra subelem to " in wpa_tdls_send_tpk_m2()
1332 ftie->ie_len += 170; in wpa_tdls_send_tpk_m2()
1333 *pos++ = 255; /* FTIE subelem */ in wpa_tdls_send_tpk_m2()
1334 *pos++ = 168; /* FTIE subelem length */ in wpa_tdls_send_tpk_m2()
1335 pos += 168; in wpa_tdls_send_tpk_m2()
1340 lifetime = peer->lifetime; in wpa_tdls_send_tpk_m2()
1343 wpa_printf(MSG_DEBUG, "TDLS: Testing - use wrong TPK " in wpa_tdls_send_tpk_m2()
1348 pos = wpa_add_tdls_timeoutie(pos, (u8 *) &timeoutie, in wpa_tdls_send_tpk_m2()
1353 /* compute MIC before sending */ in wpa_tdls_send_tpk_m2()
1354 wpa_tdls_ftie_mic(peer->tpk.kck, 2, (const u8 *) lnkid, peer->rsnie_p, in wpa_tdls_send_tpk_m2()
1355 peer->rsnie_p_len, (const u8 *) &timeoutie, in wpa_tdls_send_tpk_m2()
1356 (const u8 *) ftie, 2 + ftie->ie_len, ftie->mic); in wpa_tdls_send_tpk_m2()
1359 wpa_printf(MSG_DEBUG, "TDLS: Testing - use wrong MIC"); in wpa_tdls_send_tpk_m2()
1360 ftie->mic[0] ^= 0x01; in wpa_tdls_send_tpk_m2()
1366 dtoken, 0, 0, peer->initiator, rbuf, in wpa_tdls_send_tpk_m2()
1367 pos - rbuf, -1); in wpa_tdls_send_tpk_m2()
1379 u8 *rbuf, *pos; in wpa_tdls_send_tpk_m3() local
1391 buf_len += peer->rsnie_i_len + sizeof(struct wpa_tdls_ftie) + in wpa_tdls_send_tpk_m3()
1401 return -1; in wpa_tdls_send_tpk_m3()
1402 pos = rbuf; in wpa_tdls_send_tpk_m3()
1408 pos = wpa_add_ie(pos, peer->rsnie_p, peer->rsnie_p_len); in wpa_tdls_send_tpk_m3()
1410 ftie = (struct wpa_tdls_ftie *) pos; in wpa_tdls_send_tpk_m3()
1411 ftie->ie_type = WLAN_EID_FAST_BSS_TRANSITION; in wpa_tdls_send_tpk_m3()
1412 /*TODO: ftie->mic_control to set 3-CONFIRM */ in wpa_tdls_send_tpk_m3()
1413 os_memcpy(ftie->Anonce, peer->rnonce, WPA_NONCE_LEN); in wpa_tdls_send_tpk_m3()
1414 os_memcpy(ftie->Snonce, peer->inonce, WPA_NONCE_LEN); in wpa_tdls_send_tpk_m3()
1415 ftie->ie_len = sizeof(struct wpa_tdls_ftie) - 2; in wpa_tdls_send_tpk_m3()
1417 pos = (u8 *) (ftie + 1); in wpa_tdls_send_tpk_m3()
1421 wpa_printf(MSG_DEBUG, "TDLS: Testing - add extra subelem to " in wpa_tdls_send_tpk_m3()
1423 ftie->ie_len += 170; in wpa_tdls_send_tpk_m3()
1424 *pos++ = 255; /* FTIE subelem */ in wpa_tdls_send_tpk_m3()
1425 *pos++ = 168; /* FTIE subelem length */ in wpa_tdls_send_tpk_m3()
1426 pos += 168; in wpa_tdls_send_tpk_m3()
1431 lifetime = peer->lifetime; in wpa_tdls_send_tpk_m3()
1434 wpa_printf(MSG_DEBUG, "TDLS: Testing - use wrong TPK " in wpa_tdls_send_tpk_m3()
1439 pos = wpa_add_tdls_timeoutie(pos, (u8 *) &timeoutie, in wpa_tdls_send_tpk_m3()
1444 /* compute MIC before sending */ in wpa_tdls_send_tpk_m3()
1445 wpa_tdls_ftie_mic(peer->tpk.kck, 3, (const u8 *) lnkid, peer->rsnie_p, in wpa_tdls_send_tpk_m3()
1446 peer->rsnie_p_len, (const u8 *) &timeoutie, in wpa_tdls_send_tpk_m3()
1447 (const u8 *) ftie, 2 + ftie->ie_len, ftie->mic); in wpa_tdls_send_tpk_m3()
1450 wpa_printf(MSG_DEBUG, "TDLS: Testing - use wrong MIC"); in wpa_tdls_send_tpk_m3()
1451 ftie->mic[0] ^= 0x01; in wpa_tdls_send_tpk_m3()
1457 if (peer->he_capabilities) in wpa_tdls_send_tpk_m3()
1459 if (peer->vht_capabilities) in wpa_tdls_send_tpk_m3()
1461 if (peer->ht_capabilities) in wpa_tdls_send_tpk_m3()
1463 if (peer->wmm_capable) in wpa_tdls_send_tpk_m3()
1467 dtoken, 0, peer_capab, peer->initiator, in wpa_tdls_send_tpk_m3()
1468 rbuf, pos - rbuf, -1); in wpa_tdls_send_tpk_m3()
1482 u8 *rbuf, *pos, *count_pos; in wpa_tdls_send_discovery_response() local
1488 "(peer " MACSTR ")", MAC2STR(peer->addr)); in wpa_tdls_send_discovery_response()
1493 hdr = (struct rsn_ie_hdr *) peer->rsnie_i; in wpa_tdls_send_discovery_response()
1494 hdr->elem_id = WLAN_EID_RSN; in wpa_tdls_send_discovery_response()
1495 WPA_PUT_LE16(hdr->version, RSN_VERSION); in wpa_tdls_send_discovery_response()
1496 pos = (u8 *) (hdr + 1); in wpa_tdls_send_discovery_response()
1497 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED); in wpa_tdls_send_discovery_response()
1498 pos += RSN_SELECTOR_LEN; in wpa_tdls_send_discovery_response()
1499 count_pos = pos; in wpa_tdls_send_discovery_response()
1500 pos += 2; in wpa_tdls_send_discovery_response()
1504 * AES-CCMP is the default encryption preferred for TDLS, so in wpa_tdls_send_discovery_response()
1511 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP); in wpa_tdls_send_discovery_response()
1512 pos += RSN_SELECTOR_LEN; in wpa_tdls_send_discovery_response()
1515 WPA_PUT_LE16(pos, 1); in wpa_tdls_send_discovery_response()
1516 pos += 2; in wpa_tdls_send_discovery_response()
1517 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_TPK_HANDSHAKE); in wpa_tdls_send_discovery_response()
1518 pos += RSN_SELECTOR_LEN; in wpa_tdls_send_discovery_response()
1522 WPA_PUT_LE16(pos, rsn_capab); in wpa_tdls_send_discovery_response()
1523 pos += 2; in wpa_tdls_send_discovery_response()
1524 hdr->len = (pos - (u8 *) hdr) - 2; in wpa_tdls_send_discovery_response()
1525 peer->rsnie_i_len = pos - peer->rsnie_i; in wpa_tdls_send_discovery_response()
1528 (u8 *) hdr, hdr->len + 2); in wpa_tdls_send_discovery_response()
1533 buf_len += peer->rsnie_i_len + in wpa_tdls_send_discovery_response()
1539 return -1; in wpa_tdls_send_discovery_response()
1541 pos = rbuf; in wpa_tdls_send_discovery_response()
1546 pos = wpa_add_ie(pos, peer->rsnie_i, peer->rsnie_i_len); in wpa_tdls_send_discovery_response()
1548 peer->lifetime = TPK_LIFETIME; in wpa_tdls_send_discovery_response()
1549 pos = wpa_add_tdls_timeoutie(pos, (u8 *) &timeoutie, in wpa_tdls_send_discovery_response()
1550 sizeof(timeoutie), peer->lifetime); in wpa_tdls_send_discovery_response()
1551 wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime %u seconds", peer->lifetime); in wpa_tdls_send_discovery_response()
1553 status = wpa_tdls_tpk_send(sm, peer->addr, WLAN_TDLS_DISCOVERY_RESPONSE, in wpa_tdls_send_discovery_response()
1554 dialog_token, 0, 0, 0, rbuf, pos - rbuf, in wpa_tdls_send_discovery_response()
1566 *link_id = -1; in wpa_tdls_is_lnkid_bss_valid()
1568 if (!sm->mlo.valid_links) { in wpa_tdls_is_lnkid_bss_valid()
1569 if (!ether_addr_equal(sm->bssid, lnkid->bssid)) in wpa_tdls_is_lnkid_bss_valid()
1574 for_each_link(sm->mlo.valid_links, i) { in wpa_tdls_is_lnkid_bss_valid()
1575 if (ether_addr_equal(lnkid->bssid, in wpa_tdls_is_lnkid_bss_valid()
1576 sm->mlo.links[i].bssid)) { in wpa_tdls_is_lnkid_bss_valid()
1584 MACSTR, MAC2STR(lnkid->bssid)); in wpa_tdls_is_lnkid_bss_valid()
1603 int link_id = -1; in wpa_tdls_process_discovery_request()
1611 return -1; in wpa_tdls_process_discovery_request()
1622 len - (sizeof(struct wpa_tdls_frame) + 1), in wpa_tdls_process_discovery_request()
1625 "TDLS: Failed to parse IEs in Discovery Request - ignore as an interop workaround"); in wpa_tdls_process_discovery_request()
1631 return -1; in wpa_tdls_process_discovery_request()
1639 MACSTR, MAC2STR(lnkid->bssid)); in wpa_tdls_process_discovery_request()
1640 return -1; in wpa_tdls_process_discovery_request()
1645 return -1; in wpa_tdls_process_discovery_request()
1654 if (sm->tdls_disabled || !sm->tdls_supported) in wpa_tdls_send_discovery_request()
1655 return -1; in wpa_tdls_send_discovery_request()
1660 1, 0, 0, 1, NULL, 0, -1); in wpa_tdls_send_discovery_request()
1667 if (!kde->supp_rates) { in copy_supp_rates()
1669 return -1; in copy_supp_rates()
1671 peer->supp_rates_len = merge_byte_arrays( in copy_supp_rates()
1672 peer->supp_rates, sizeof(peer->supp_rates), in copy_supp_rates()
1673 kde->supp_rates + 2, kde->supp_rates_len - 2, in copy_supp_rates()
1674 kde->ext_supp_rates ? kde->ext_supp_rates + 2 : NULL, in copy_supp_rates()
1675 kde->ext_supp_rates ? kde->ext_supp_rates_len - 2 : 0); in copy_supp_rates()
1683 if (!kde->ht_capabilities) { in copy_peer_ht_capab()
1689 if (!peer->ht_capabilities) { in copy_peer_ht_capab()
1690 peer->ht_capabilities = in copy_peer_ht_capab()
1692 if (peer->ht_capabilities == NULL) in copy_peer_ht_capab()
1693 return -1; in copy_peer_ht_capab()
1696 os_memcpy(peer->ht_capabilities, kde->ht_capabilities, in copy_peer_ht_capab()
1699 (u8 *) peer->ht_capabilities, in copy_peer_ht_capab()
1709 if (!kde->vht_capabilities) { in copy_peer_vht_capab()
1715 if (!peer->vht_capabilities) { in copy_peer_vht_capab()
1716 peer->vht_capabilities = in copy_peer_vht_capab()
1718 if (peer->vht_capabilities == NULL) in copy_peer_vht_capab()
1719 return -1; in copy_peer_vht_capab()
1722 os_memcpy(peer->vht_capabilities, kde->vht_capabilities, in copy_peer_vht_capab()
1725 (u8 *) peer->vht_capabilities, in copy_peer_vht_capab()
1735 if (!kde->he_capabilities) { in copy_peer_he_capab()
1740 os_free(peer->he_capabilities); in copy_peer_he_capab()
1741 peer->he_capab_len = 0; in copy_peer_he_capab()
1742 peer->he_capabilities = os_memdup(kde->he_capabilities, in copy_peer_he_capab()
1743 kde->he_capab_len); in copy_peer_he_capab()
1744 if (!peer->he_capabilities) in copy_peer_he_capab()
1745 return -1; in copy_peer_he_capab()
1747 peer->he_capab_len = kde->he_capab_len; in copy_peer_he_capab()
1749 peer->he_capabilities, peer->he_capab_len); in copy_peer_he_capab()
1758 if (!kde->he_6ghz_capabilities) { in copy_peer_he_6ghz_band_capab()
1764 if (!peer->he_6ghz_band_capabilities) { in copy_peer_he_6ghz_band_capab()
1765 peer->he_6ghz_band_capabilities = in copy_peer_he_6ghz_band_capab()
1767 if (peer->he_6ghz_band_capabilities == NULL) in copy_peer_he_6ghz_band_capab()
1768 return -1; in copy_peer_he_6ghz_band_capab()
1771 os_memcpy(peer->he_6ghz_band_capabilities, kde->he_6ghz_capabilities, in copy_peer_he_6ghz_band_capab()
1775 peer->he_6ghz_band_capabilities, in copy_peer_he_6ghz_band_capab()
1785 if (!kde->ext_capab) { in copy_peer_ext_capab()
1791 if (!peer->ext_capab || peer->ext_capab_len < kde->ext_capab_len - 2) { in copy_peer_ext_capab()
1793 os_free(peer->ext_capab); in copy_peer_ext_capab()
1794 peer->ext_capab = os_zalloc(kde->ext_capab_len - 2); in copy_peer_ext_capab()
1795 if (peer->ext_capab == NULL) in copy_peer_ext_capab()
1796 return -1; in copy_peer_ext_capab()
1799 peer->ext_capab_len = kde->ext_capab_len - 2; in copy_peer_ext_capab()
1800 os_memcpy(peer->ext_capab, kde->ext_capab + 2, peer->ext_capab_len); in copy_peer_ext_capab()
1809 if (!kde->eht_capabilities) { in copy_peer_eht_capab()
1814 os_free(peer->eht_capabilities); in copy_peer_eht_capab()
1815 peer->eht_capab_len = 0; in copy_peer_eht_capab()
1816 peer->eht_capabilities = os_memdup(kde->eht_capabilities, in copy_peer_eht_capab()
1817 kde->eht_capab_len); in copy_peer_eht_capab()
1818 if (!peer->eht_capabilities) in copy_peer_eht_capab()
1819 return -1; in copy_peer_eht_capab()
1821 peer->eht_capab_len = kde->eht_capab_len; in copy_peer_eht_capab()
1823 peer->eht_capabilities, peer->eht_capab_len); in copy_peer_eht_capab()
1834 if (!kde->wmm) { in copy_peer_wmm_capab()
1839 if (kde->wmm_len < sizeof(struct wmm_information_element)) { in copy_peer_wmm_capab()
1841 return -1; in copy_peer_wmm_capab()
1844 wmm = (struct wmm_information_element *) kde->wmm; in copy_peer_wmm_capab()
1845 peer->qos_info = wmm->qos_info; in copy_peer_wmm_capab()
1847 peer->wmm_capable = 1; in copy_peer_wmm_capab()
1849 wpa_printf(MSG_DEBUG, "TDLS: Peer WMM QOS Info 0x%x", peer->qos_info); in copy_peer_wmm_capab()
1857 if (!kde->supp_channels) { in copy_peer_supp_channels()
1862 if (!peer->supp_channels || in copy_peer_supp_channels()
1863 peer->supp_channels_len < kde->supp_channels_len) { in copy_peer_supp_channels()
1864 os_free(peer->supp_channels); in copy_peer_supp_channels()
1865 peer->supp_channels = os_zalloc(kde->supp_channels_len); in copy_peer_supp_channels()
1866 if (peer->supp_channels == NULL) in copy_peer_supp_channels()
1867 return -1; in copy_peer_supp_channels()
1870 peer->supp_channels_len = kde->supp_channels_len; in copy_peer_supp_channels()
1872 os_memcpy(peer->supp_channels, kde->supp_channels, in copy_peer_supp_channels()
1873 peer->supp_channels_len); in copy_peer_supp_channels()
1875 (u8 *) peer->supp_channels, peer->supp_channels_len); in copy_peer_supp_channels()
1883 if (!kde->supp_oper_classes) { in copy_peer_supp_oper_classes()
1888 if (!peer->supp_oper_classes || in copy_peer_supp_oper_classes()
1889 peer->supp_oper_classes_len < kde->supp_oper_classes_len) { in copy_peer_supp_oper_classes()
1890 os_free(peer->supp_oper_classes); in copy_peer_supp_oper_classes()
1891 peer->supp_oper_classes = os_zalloc(kde->supp_oper_classes_len); in copy_peer_supp_oper_classes()
1892 if (peer->supp_oper_classes == NULL) in copy_peer_supp_oper_classes()
1893 return -1; in copy_peer_supp_oper_classes()
1896 peer->supp_oper_classes_len = kde->supp_oper_classes_len; in copy_peer_supp_oper_classes()
1897 os_memcpy(peer->supp_oper_classes, kde->supp_oper_classes, in copy_peer_supp_oper_classes()
1898 peer->supp_oper_classes_len); in copy_peer_supp_oper_classes()
1900 (u8 *) peer->supp_oper_classes, in copy_peer_supp_oper_classes()
1901 peer->supp_oper_classes_len); in copy_peer_supp_oper_classes()
1909 return wpa_sm_tdls_peer_addset(sm, peer->addr, add, peer->aid, in wpa_tdls_addset_peer()
1910 peer->capability, in wpa_tdls_addset_peer()
1911 peer->supp_rates, peer->supp_rates_len, in wpa_tdls_addset_peer()
1912 peer->ht_capabilities, in wpa_tdls_addset_peer()
1913 peer->vht_capabilities, in wpa_tdls_addset_peer()
1914 peer->he_capabilities, in wpa_tdls_addset_peer()
1915 peer->he_capab_len, in wpa_tdls_addset_peer()
1916 peer->he_6ghz_band_capabilities, in wpa_tdls_addset_peer()
1917 peer->qos_info, peer->wmm_capable, in wpa_tdls_addset_peer()
1918 peer->ext_capab, peer->ext_capab_len, in wpa_tdls_addset_peer()
1919 peer->supp_channels, in wpa_tdls_addset_peer()
1920 peer->supp_channels_len, in wpa_tdls_addset_peer()
1921 peer->supp_oper_classes, in wpa_tdls_addset_peer()
1922 peer->supp_oper_classes_len, in wpa_tdls_addset_peer()
1923 peer->eht_capabilities, in wpa_tdls_addset_peer()
1924 peer->eht_capab_len, in wpa_tdls_addset_peer()
1925 peer->mld_link_id); in wpa_tdls_addset_peer()
1956 u8 *pos; in wpa_tdls_process_tpk_m1()
1963 int tdls_prohibited = sm->tdls_prohibited; in wpa_tdls_process_tpk_m1()
1965 int link_id = -1; in wpa_tdls_process_tpk_m1()
1968 return -1; in wpa_tdls_process_tpk_m1()
1986 if (peer->tpk_success) { in wpa_tdls_process_tpk_m1()
1988 "direct link is enabled - tear down the " in wpa_tdls_process_tpk_m1()
1990 wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, peer->addr); in wpa_tdls_process_tpk_m1()
1992 } else if (peer->initiator) { in wpa_tdls_process_tpk_m1()
2000 if (os_memcmp(sm->own_addr, src_addr, ETH_ALEN) < 0) { in wpa_tdls_process_tpk_m1()
2004 return -1; in wpa_tdls_process_tpk_m1()
2012 peer->addr); in wpa_tdls_process_tpk_m1()
2019 peer->capability = WPA_GET_LE16(cpos); in wpa_tdls_process_tpk_m1()
2022 ielen = len - (cpos - buf); /* start of IE in buf */ in wpa_tdls_process_tpk_m1()
2031 "TDLS: Failed to parse IEs in TPK M1 - ignore as an interop workaround"); in wpa_tdls_process_tpk_m1()
2044 MACSTR, MAC2STR(lnkid->bssid)); in wpa_tdls_process_tpk_m1()
2049 peer->mld_link_id = link_id; in wpa_tdls_process_tpk_m1()
2050 wpa_printf(MSG_DEBUG, "TDLS: TPK M1 - TPK initiator " MACSTR, in wpa_tdls_process_tpk_m1()
2076 peer->qos_info = kde.qosinfo; in wpa_tdls_process_tpk_m1()
2082 peer->aid = kde.aid; in wpa_tdls_process_tpk_m1()
2090 "TDLS setup - send own request"); in wpa_tdls_process_tpk_m1()
2091 peer->initiator = 1; in wpa_tdls_process_tpk_m1()
2092 wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, in wpa_tdls_process_tpk_m1()
2095 if (wpa_tdls_send_tpk_m1(sm, peer) == -2) { in wpa_tdls_process_tpk_m1()
2103 wpa_printf(MSG_DEBUG, "TDLS: Testing - ignore AP prohibition " in wpa_tdls_process_tpk_m1()
2171 lifetime = WPA_GET_LE32(timeoutie->value); in wpa_tdls_process_tpk_m1()
2182 if (os_memcmp(sm->own_addr, peer->addr, ETH_ALEN) < 0) { in wpa_tdls_process_tpk_m1()
2193 peer->initiator = 0; /* Need to check */ in wpa_tdls_process_tpk_m1()
2194 peer->dtoken = dtoken; in wpa_tdls_process_tpk_m1()
2197 peer->rsnie_i_len = 0; in wpa_tdls_process_tpk_m1()
2198 peer->rsnie_p_len = 0; in wpa_tdls_process_tpk_m1()
2199 peer->cipher = WPA_CIPHER_NONE; in wpa_tdls_process_tpk_m1()
2204 os_memcpy(peer->rsnie_i, kde.rsn_ie, kde.rsn_ie_len); in wpa_tdls_process_tpk_m1()
2205 peer->rsnie_i_len = kde.rsn_ie_len; in wpa_tdls_process_tpk_m1()
2206 peer->cipher = cipher; in wpa_tdls_process_tpk_m1()
2208 if (os_memcmp(peer->inonce, ftie->Snonce, WPA_NONCE_LEN) != 0 || in wpa_tdls_process_tpk_m1()
2209 !tdls_nonce_set(peer->inonce)) { in wpa_tdls_process_tpk_m1()
2218 "TDLS: New TPK M1 INonce - generate new RNonce"); in wpa_tdls_process_tpk_m1()
2219 os_memcpy(peer->inonce, ftie->Snonce, WPA_NONCE_LEN); in wpa_tdls_process_tpk_m1()
2220 if (os_get_random(peer->rnonce, WPA_NONCE_LEN)) { in wpa_tdls_process_tpk_m1()
2221 wpa_msg(sm->ctx->ctx, MSG_WARNING, in wpa_tdls_process_tpk_m1()
2225 peer->tk_set = 0; /* A new nonce results in a new TK */ in wpa_tdls_process_tpk_m1()
2231 rsn_ver = WPA_GET_LE16(hdr->version); in wpa_tdls_process_tpk_m1()
2237 hdr = (struct rsn_ie_hdr *) peer->rsnie_p; in wpa_tdls_process_tpk_m1()
2239 hdr->elem_id = WLAN_EID_RSN; in wpa_tdls_process_tpk_m1()
2240 WPA_PUT_LE16(hdr->version, rsn_ver); in wpa_tdls_process_tpk_m1()
2241 pos = (u8 *) (hdr + 1); in wpa_tdls_process_tpk_m1()
2243 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED); in wpa_tdls_process_tpk_m1()
2244 pos += RSN_SELECTOR_LEN; in wpa_tdls_process_tpk_m1()
2246 WPA_PUT_LE16(pos, 1); in wpa_tdls_process_tpk_m1()
2247 pos += 2; in wpa_tdls_process_tpk_m1()
2249 RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP); in wpa_tdls_process_tpk_m1()
2250 pos += RSN_SELECTOR_LEN; in wpa_tdls_process_tpk_m1()
2252 WPA_PUT_LE16(pos, 1); in wpa_tdls_process_tpk_m1()
2253 pos += 2; in wpa_tdls_process_tpk_m1()
2254 RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_TPK_HANDSHAKE); in wpa_tdls_process_tpk_m1()
2255 pos += RSN_SELECTOR_LEN; in wpa_tdls_process_tpk_m1()
2259 WPA_PUT_LE16(pos, rsn_capab); in wpa_tdls_process_tpk_m1()
2260 pos += 2; in wpa_tdls_process_tpk_m1()
2262 hdr->len = (pos - peer->rsnie_p) - 2; in wpa_tdls_process_tpk_m1()
2263 peer->rsnie_p_len = pos - peer->rsnie_p; in wpa_tdls_process_tpk_m1()
2267 os_memcpy(peer->rsnie_p, peer->rsnie_i, peer->rsnie_i_len); in wpa_tdls_process_tpk_m1()
2268 peer->rsnie_p_len = peer->rsnie_i_len; in wpa_tdls_process_tpk_m1()
2271 peer->rsnie_p, peer->rsnie_p_len); in wpa_tdls_process_tpk_m1()
2273 peer->lifetime = lifetime; in wpa_tdls_process_tpk_m1()
2275 if (peer->mld_link_id >= 0) in wpa_tdls_process_tpk_m1()
2277 peer->mld_link_id); in wpa_tdls_process_tpk_m1()
2278 wpa_tdls_generate_tpk(peer, sm->own_addr, in wpa_tdls_process_tpk_m1()
2279 wpa_tdls_get_link_bssid(sm, peer->mld_link_id)); in wpa_tdls_process_tpk_m1()
2294 peer->tpk_in_progress = 1; in wpa_tdls_process_tpk_m1()
2298 wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, peer->addr); in wpa_tdls_process_tpk_m1()
2304 wpa_printf(MSG_INFO, "TDLS: Testing - Send another TPK M2"); in wpa_tdls_process_tpk_m1()
2316 return -1; in wpa_tdls_process_tpk_m1()
2322 peer->tpk_success = 1; in wpa_tdls_enable_link()
2323 peer->tpk_in_progress = 0; in wpa_tdls_enable_link()
2326 u32 lifetime = peer->lifetime; in wpa_tdls_enable_link()
2331 if (lifetime > 3 && peer->initiator) in wpa_tdls_enable_link()
2332 lifetime -= 3; in wpa_tdls_enable_link()
2338 "TDLS: Testing - disable TPK expiration"); in wpa_tdls_enable_link()
2344 if (peer->reconfig_key && wpa_tdls_set_key(sm, peer) < 0) { in wpa_tdls_enable_link()
2347 return -1; in wpa_tdls_enable_link()
2349 peer->reconfig_key = 0; in wpa_tdls_enable_link()
2351 return wpa_sm_tdls_oper(sm, TDLS_ENABLE_LINK, peer->addr); in wpa_tdls_enable_link()
2369 const u8 *pos; in wpa_tdls_process_tpk_m2() local
2374 for (peer = sm->tdls; peer; peer = peer->next) { in wpa_tdls_process_tpk_m2()
2375 if (ether_addr_equal(peer->addr, src_addr)) in wpa_tdls_process_tpk_m2()
2381 return -1; in wpa_tdls_process_tpk_m2()
2383 if (!peer->initiator) { in wpa_tdls_process_tpk_m2()
2391 return -1; in wpa_tdls_process_tpk_m2()
2394 if (peer->tpk_success) { in wpa_tdls_process_tpk_m2()
2405 return -1; in wpa_tdls_process_tpk_m2()
2408 pos = buf; in wpa_tdls_process_tpk_m2()
2409 pos += 1 /* pkt_type */ + 1 /* Category */ + 1 /* Action */; in wpa_tdls_process_tpk_m2()
2410 status = WPA_GET_LE16(pos); in wpa_tdls_process_tpk_m2()
2411 pos += 2 /* status code */; in wpa_tdls_process_tpk_m2()
2417 return -1; in wpa_tdls_process_tpk_m2()
2423 dtoken = *pos++; /* dialog token */ in wpa_tdls_process_tpk_m2()
2429 return -1; in wpa_tdls_process_tpk_m2()
2433 peer->capability = WPA_GET_LE16(pos); in wpa_tdls_process_tpk_m2()
2434 pos += 2; in wpa_tdls_process_tpk_m2()
2436 ielen = len - (pos - buf); /* start of IE in buf */ in wpa_tdls_process_tpk_m2()
2443 if (wpa_supplicant_parse_ies(pos, ielen, &kde) < 0) in wpa_tdls_process_tpk_m2()
2445 "TDLS: Failed to parse IEs in TPK M2 - ignore as an interop workaround"); in wpa_tdls_process_tpk_m2()
2449 wpa_printf(MSG_DEBUG, "TDLS: Testing - decline response"); in wpa_tdls_process_tpk_m2()
2464 if (!ether_addr_equal(sm->bssid, in wpa_tdls_process_tpk_m2()
2465 wpa_tdls_get_link_bssid(sm, peer->mld_link_id))) { in wpa_tdls_process_tpk_m2()
2494 peer->qos_info = kde.qosinfo; in wpa_tdls_process_tpk_m2()
2500 peer->aid = kde.aid; in wpa_tdls_process_tpk_m2()
2503 peer->rsnie_p_len = 0; in wpa_tdls_process_tpk_m2()
2504 peer->cipher = WPA_CIPHER_NONE; in wpa_tdls_process_tpk_m2()
2530 if (kde.rsn_ie_len != peer->rsnie_i_len || in wpa_tdls_process_tpk_m2()
2531 os_memcmp(peer->rsnie_i, kde.rsn_ie, peer->rsnie_i_len) != 0) { in wpa_tdls_process_tpk_m2()
2535 peer->rsnie_i, peer->rsnie_i_len); in wpa_tdls_process_tpk_m2()
2562 if (os_memcmp(peer->inonce, ftie->Snonce, WPA_NONCE_LEN) != 0) { in wpa_tdls_process_tpk_m2()
2566 return -1; in wpa_tdls_process_tpk_m2()
2570 os_memcpy(peer->rnonce, ftie->Anonce, WPA_NONCE_LEN); in wpa_tdls_process_tpk_m2()
2571 os_memcpy(peer->rsnie_p, kde.rsn_ie, kde.rsn_ie_len); in wpa_tdls_process_tpk_m2()
2572 peer->rsnie_p_len = kde.rsn_ie_len; in wpa_tdls_process_tpk_m2()
2573 peer->cipher = cipher; in wpa_tdls_process_tpk_m2()
2582 lifetime = WPA_GET_LE32(timeoutie->value); in wpa_tdls_process_tpk_m2()
2585 if (lifetime != peer->lifetime) { in wpa_tdls_process_tpk_m2()
2587 "TPK M2 (expected %u)", lifetime, peer->lifetime); in wpa_tdls_process_tpk_m2()
2592 if (peer->mld_link_id >= 0) in wpa_tdls_process_tpk_m2()
2594 peer->mld_link_id); in wpa_tdls_process_tpk_m2()
2595 wpa_tdls_generate_tpk(peer, sm->own_addr, in wpa_tdls_process_tpk_m2()
2596 wpa_tdls_get_link_bssid(sm, peer->mld_link_id)); in wpa_tdls_process_tpk_m2()
2598 /* Process MIC check to see if TPK M2 is right */ in wpa_tdls_process_tpk_m2()
2605 return -1; in wpa_tdls_process_tpk_m2()
2615 peer->reconfig_key = 1; in wpa_tdls_process_tpk_m2()
2619 peer->dtoken = dtoken; in wpa_tdls_process_tpk_m2()
2630 if (!peer->tpk_success) { in wpa_tdls_process_tpk_m2()
2651 return -1; in wpa_tdls_process_tpk_m2()
2665 const u8 *pos; in wpa_tdls_process_tpk_m3() local
2671 for (peer = sm->tdls; peer; peer = peer->next) { in wpa_tdls_process_tpk_m3()
2672 if (ether_addr_equal(peer->addr, src_addr)) in wpa_tdls_process_tpk_m3()
2678 return -1; in wpa_tdls_process_tpk_m3()
2684 pos = buf; in wpa_tdls_process_tpk_m3()
2685 pos += 1 /* pkt_type */ + 1 /* Category */ + 1 /* Action */; in wpa_tdls_process_tpk_m3()
2687 status = WPA_GET_LE16(pos); in wpa_tdls_process_tpk_m3()
2694 pos += 2 /* status code */ + 1 /* dialog token */; in wpa_tdls_process_tpk_m3()
2696 ielen = len - (pos - buf); /* start of IE in buf */ in wpa_tdls_process_tpk_m3()
2700 * explicitly checked below. Some APs piggy-back broken IEs to the end in wpa_tdls_process_tpk_m3()
2704 if (wpa_supplicant_parse_ies((const u8 *) pos, ielen, &kde) < 0) { in wpa_tdls_process_tpk_m3()
2706 "TDLS: Failed to parse KDEs in TPK M3 - ignore as an interop workaround"); in wpa_tdls_process_tpk_m3()
2717 if (!ether_addr_equal(wpa_tdls_get_link_bssid(sm, peer->mld_link_id), in wpa_tdls_process_tpk_m3()
2718 lnkid->bssid)) { in wpa_tdls_process_tpk_m3()
2740 if (kde.rsn_ie_len != peer->rsnie_p_len || in wpa_tdls_process_tpk_m3()
2741 os_memcmp(kde.rsn_ie, peer->rsnie_p, peer->rsnie_p_len) != 0) { in wpa_tdls_process_tpk_m3()
2747 if (os_memcmp(peer->rnonce, ftie->Anonce, WPA_NONCE_LEN) != 0) { in wpa_tdls_process_tpk_m3()
2753 if (os_memcmp(peer->inonce, ftie->Snonce, WPA_NONCE_LEN) != 0) { in wpa_tdls_process_tpk_m3()
2766 lifetime = WPA_GET_LE32(timeoutie->value); in wpa_tdls_process_tpk_m3()
2769 if (lifetime != peer->lifetime) { in wpa_tdls_process_tpk_m3()
2771 "TPK M3 (expected %u)", lifetime, peer->lifetime); in wpa_tdls_process_tpk_m3()
2789 peer->reconfig_key = 1; in wpa_tdls_process_tpk_m3()
2797 if (!peer->tpk_success) { in wpa_tdls_process_tpk_m3()
2812 return -1; in wpa_tdls_process_tpk_m3()
2816 static u8 * wpa_add_tdls_timeoutie(u8 *pos, u8 *ie, size_t ie_len, u32 tsecs) in wpa_add_tdls_timeoutie() argument
2821 lifetime->ie_type = WLAN_EID_TIMEOUT_INTERVAL; in wpa_add_tdls_timeoutie()
2822 lifetime->ie_len = sizeof(struct wpa_tdls_timeoutie) - 2; in wpa_add_tdls_timeoutie()
2823 lifetime->interval_type = WLAN_TIMEOUT_KEY_LIFETIME; in wpa_add_tdls_timeoutie()
2824 WPA_PUT_LE32(lifetime->value, tsecs); in wpa_add_tdls_timeoutie()
2825 os_memcpy(pos, ie, ie_len); in wpa_add_tdls_timeoutie()
2826 return pos + ie_len; in wpa_add_tdls_timeoutie()
2831 * wpa_tdls_start - Initiate TDLS handshake (send TPK Handshake Message 1)
2834 * Returns: 0 on success, or -1 on failure
2842 int tdls_prohibited = sm->tdls_prohibited; in wpa_tdls_start()
2845 if (sm->tdls_disabled || !sm->tdls_supported) in wpa_tdls_start()
2846 return -1; in wpa_tdls_start()
2851 wpa_printf(MSG_DEBUG, "TDLS: Testing - ignore AP prohibition " in wpa_tdls_start()
2858 wpa_printf(MSG_DEBUG, "TDLS: TDLS is prohibited in this BSS - " in wpa_tdls_start()
2860 return -1; in wpa_tdls_start()
2865 return -1; in wpa_tdls_start()
2867 if (peer->tpk_in_progress) { in wpa_tdls_start()
2872 if (sm->mlo.valid_links && !peer->disc_resp_rcvd) { in wpa_tdls_start()
2874 "TDLS: MLO STA connection - defer the setup request since Discovery Resp not yet received"); in wpa_tdls_start()
2875 peer->setup_req_rcvd = true; in wpa_tdls_start()
2878 peer->initiator = 1; in wpa_tdls_start()
2881 if (wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, in wpa_tdls_start()
2883 NULL, 0, NULL, 0, peer->mld_link_id)) { in wpa_tdls_start()
2885 return -1; in wpa_tdls_start()
2888 peer->tpk_in_progress = 1; in wpa_tdls_start()
2892 if (res != -2) in wpa_tdls_start()
2894 return -1; in wpa_tdls_start()
2905 if (sm->tdls_disabled || !sm->tdls_supported) in wpa_tdls_remove()
2908 for (peer = sm->tdls; peer; peer = peer->next) { in wpa_tdls_remove()
2909 if (ether_addr_equal(peer->addr, addr)) in wpa_tdls_remove()
2913 if (peer == NULL || !peer->tpk_success) in wpa_tdls_remove()
2916 if (sm->tdls_external_setup) { in wpa_tdls_remove()
2928 * wpa_supplicant_rx_tdls - Receive TDLS data frame
2941 if (sm->tdls_disabled || !sm->tdls_supported) { in wpa_supplicant_rx_tdls()
2942 wpa_printf(MSG_DEBUG, "TDLS: Discard message - TDLS disabled " in wpa_supplicant_rx_tdls()
2947 if (ether_addr_equal(src_addr, sm->own_addr)) { in wpa_supplicant_rx_tdls()
2959 if (tf->payloadtype != 2 /* TDLS_RFTYPE */ || in wpa_supplicant_rx_tdls()
2960 tf->category != WLAN_ACTION_TDLS) { in wpa_supplicant_rx_tdls()
2961 wpa_printf(MSG_INFO, "TDLS: Invalid frame - payloadtype=%u " in wpa_supplicant_rx_tdls()
2963 tf->payloadtype, tf->category, tf->action); in wpa_supplicant_rx_tdls()
2967 switch (tf->action) { in wpa_supplicant_rx_tdls()
2986 tf->action); in wpa_supplicant_rx_tdls()
2993 * wpa_tdls_init - Initialize driver interface parameters for TDLS
2995 * Returns: 0 on success, -1 on failure
3004 return -1; in wpa_tdls_init()
3006 if (sm->l2_tdls) { in wpa_tdls_init()
3007 l2_packet_deinit(sm->l2_tdls); in wpa_tdls_init()
3008 sm->l2_tdls = NULL; in wpa_tdls_init()
3011 sm->l2_tdls = l2_packet_init(sm->bridge_ifname ? sm->bridge_ifname : in wpa_tdls_init()
3012 sm->ifname, in wpa_tdls_init()
3013 sm->own_addr, in wpa_tdls_init()
3016 if (sm->l2_tdls == NULL) { in wpa_tdls_init()
3019 return -1; in wpa_tdls_init()
3026 if (wpa_sm_tdls_get_capa(sm, &sm->tdls_supported, in wpa_tdls_init()
3027 &sm->tdls_external_setup, in wpa_tdls_init()
3028 &sm->tdls_chan_switch) < 0) { in wpa_tdls_init()
3029 sm->tdls_supported = 1; in wpa_tdls_init()
3030 sm->tdls_external_setup = 0; in wpa_tdls_init()
3034 "driver", sm->tdls_supported ? "" : " not"); in wpa_tdls_init()
3036 sm->tdls_external_setup ? "external" : "internal"); in wpa_tdls_init()
3038 sm->tdls_chan_switch ? "supports" : "does not support"); in wpa_tdls_init()
3050 peer = sm->tdls; in wpa_tdls_teardown_peers()
3055 tmp = peer->next; in wpa_tdls_teardown_peers()
3057 MAC2STR(peer->addr)); in wpa_tdls_teardown_peers()
3058 if (sm->tdls_external_setup) in wpa_tdls_teardown_peers()
3062 wpa_sm_tdls_oper(sm, TDLS_TEARDOWN, peer->addr); in wpa_tdls_teardown_peers()
3073 peer = sm->tdls; in wpa_tdls_remove_peers()
3077 tmp = peer->next; in wpa_tdls_remove_peers()
3078 res = wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, peer->addr); in wpa_tdls_remove_peers()
3080 MAC2STR(peer->addr), res); in wpa_tdls_remove_peers()
3088 * wpa_tdls_deinit - Deinitialize driver interface parameters for TDLS
3098 if (sm->l2_tdls) in wpa_tdls_deinit()
3099 l2_packet_deinit(sm->l2_tdls); in wpa_tdls_deinit()
3100 sm->l2_tdls = NULL; in wpa_tdls_deinit()
3122 /* bit 38 - TDLS Prohibited */ in wpa_tdls_prohibited()
3123 return !!(elems->ext_capab[4] & 0x40); in wpa_tdls_prohibited()
3129 /* bit 39 - TDLS Channel Switch Prohibited */ in wpa_tdls_chan_switch_prohibited()
3130 return !!(elems->ext_capab[4] & 0x80); in wpa_tdls_chan_switch_prohibited()
3138 sm->tdls_prohibited = 0; in wpa_tdls_ap_ies()
3139 sm->tdls_chan_switch_prohibited = 0; in wpa_tdls_ap_ies()
3146 sm->tdls_prohibited = wpa_tdls_prohibited(&elems); in wpa_tdls_ap_ies()
3148 sm->tdls_prohibited ? "prohibited" : "allowed"); in wpa_tdls_ap_ies()
3149 sm->tdls_chan_switch_prohibited = in wpa_tdls_ap_ies()
3152 sm->tdls_chan_switch_prohibited ? "prohibited" : "allowed"); in wpa_tdls_ap_ies()
3165 if (!sm->tdls_prohibited && wpa_tdls_prohibited(&elems)) { in wpa_tdls_assoc_resp_ies()
3168 sm->tdls_prohibited = 1; in wpa_tdls_assoc_resp_ies()
3171 if (!sm->tdls_chan_switch_prohibited && in wpa_tdls_assoc_resp_ies()
3175 sm->tdls_chan_switch_prohibited = 1; in wpa_tdls_assoc_resp_ies()
3183 sm->tdls_disabled = !enabled; in wpa_tdls_enable()
3189 return sm->tdls_external_setup; in wpa_tdls_is_external_setup()
3201 int link_id = -1; in wpa_tdls_process_discovery_response()
3209 return -1; in wpa_tdls_process_discovery_response()
3214 if (ieee802_11_parse_elems(buf + 3, len - 3, &elems, 1) == in wpa_tdls_process_discovery_response()
3218 return -1; in wpa_tdls_process_discovery_response()
3224 return -1; in wpa_tdls_process_discovery_response()
3227 lnkid = (const struct wpa_tdls_lnkid *) (elems.link_id - 2); in wpa_tdls_process_discovery_response()
3232 MACSTR, MAC2STR(lnkid->bssid)); in wpa_tdls_process_discovery_response()
3233 return -1; in wpa_tdls_process_discovery_response()
3239 return -1; in wpa_tdls_process_discovery_response()
3242 peer->mld_link_id = link_id; in wpa_tdls_process_discovery_response()
3244 " , link id: %u", MAC2STR(lnkid->bssid), link_id); in wpa_tdls_process_discovery_response()
3246 peer->disc_resp_rcvd = true; in wpa_tdls_process_discovery_response()
3247 if (peer->setup_req_rcvd) { in wpa_tdls_process_discovery_response()
3248 peer->setup_req_rcvd = false; in wpa_tdls_process_discovery_response()
3264 if (sm->tdls_disabled || !sm->tdls_supported) in wpa_tdls_enable_chan_switch()
3265 return -1; in wpa_tdls_enable_chan_switch()
3267 if (!sm->tdls_chan_switch) { in wpa_tdls_enable_chan_switch()
3270 return -1; in wpa_tdls_enable_chan_switch()
3273 if (sm->tdls_chan_switch_prohibited) { in wpa_tdls_enable_chan_switch()
3275 "TDLS: Channel switching is prohibited in this BSS - reject request to switch channel"); in wpa_tdls_enable_chan_switch()
3276 return -1; in wpa_tdls_enable_chan_switch()
3279 for (peer = sm->tdls; peer; peer = peer->next) { in wpa_tdls_enable_chan_switch()
3280 if (ether_addr_equal(peer->addr, addr)) in wpa_tdls_enable_chan_switch()
3284 if (peer == NULL || !peer->tpk_success) { in wpa_tdls_enable_chan_switch()
3287 return -1; in wpa_tdls_enable_chan_switch()
3290 if (peer->chan_switch_enabled) { in wpa_tdls_enable_chan_switch()
3297 ret = wpa_sm_tdls_enable_channel_switch(sm, peer->addr, in wpa_tdls_enable_chan_switch()
3300 peer->chan_switch_enabled = 1; in wpa_tdls_enable_chan_switch()
3310 if (sm->tdls_disabled || !sm->tdls_supported) in wpa_tdls_disable_chan_switch()
3311 return -1; in wpa_tdls_disable_chan_switch()
3313 for (peer = sm->tdls; peer; peer = peer->next) { in wpa_tdls_disable_chan_switch()
3314 if (ether_addr_equal(peer->addr, addr)) in wpa_tdls_disable_chan_switch()
3318 if (!peer || !peer->chan_switch_enabled) { in wpa_tdls_disable_chan_switch()
3321 return -1; in wpa_tdls_disable_chan_switch()
3325 wpa_sm_tdls_disable_channel_switch(sm, peer->addr); in wpa_tdls_disable_chan_switch()
3327 peer->chan_switch_enabled = 0; in wpa_tdls_disable_chan_switch()