/*
 * wpa_supplicant - TDLS
 * Copyright (c) 2010-2011, Atheros Communications
 *
 * This software may be distributed under the terms of the BSD license.
 * See README for more details.
 */

#include "utils/includes.h"

#include "utils/common.h"
#include "utils/eloop.h"
#include "utils/os.h"
#include "common/ieee802_11_defs.h"
#include "crypto/sha256.h"
#include "crypto/crypto.h"
#include "crypto/aes_wrap.h"
#include "rsn_supp/wpa.h"
#include "rsn_supp/wpa_ie.h"
#include "rsn_supp/wpa_i.h"
#include "drivers/driver.h"
#include "l2_packet/l2_packet.h"

#ifdef CONFIG_TDLS_TESTING
#define TDLS_TESTING_LONG_FRAME BIT(0)
#define TDLS_TESTING_ALT_RSN_IE BIT(1)
#define TDLS_TESTING_DIFF_BSSID BIT(2)
#define TDLS_TESTING_SHORT_LIFETIME BIT(3)
#define TDLS_TESTING_WRONG_LIFETIME_RESP BIT(4)
#define TDLS_TESTING_WRONG_LIFETIME_CONF BIT(5)
#define TDLS_TESTING_LONG_LIFETIME BIT(6)
#define TDLS_TESTING_CONCURRENT_INIT BIT(7)
#define TDLS_TESTING_NO_TPK_EXPIRATION BIT(8)
#define TDLS_TESTING_DECLINE_RESP BIT(9)
#define TDLS_TESTING_IGNORE_AP_PROHIBIT BIT(10)
unsigned int tdls_testing = 0;
#endif /* CONFIG_TDLS_TESTING */

#define TPK_LIFETIME 43200 /* 12 hours */
#define TPK_RETRY_COUNT 3
#define TPK_TIMEOUT 5000 /* in milliseconds */

#define TDLS_MIC_LEN		16

#define TDLS_TIMEOUT_LEN	4

struct wpa_tdls_ftie {
	u8 ie_type; /* FTIE */
	u8 ie_len;
	u8 mic_ctrl[2];
	u8 mic[TDLS_MIC_LEN];
	u8 Anonce[WPA_NONCE_LEN]; /* Responder Nonce in TDLS */
	u8 Snonce[WPA_NONCE_LEN]; /* Initiator Nonce in TDLS */
	/* followed by optional elements */
} STRUCT_PACKED;

struct wpa_tdls_timeoutie {
	u8 ie_type; /* Timeout IE */
	u8 ie_len;
	u8 interval_type;
	u8 value[TDLS_TIMEOUT_LEN];
} STRUCT_PACKED;

struct wpa_tdls_lnkid {
	u8 ie_type; /* Link Identifier IE */
	u8 ie_len;
	u8 bssid[ETH_ALEN];
	u8 init_sta[ETH_ALEN];
	u8 resp_sta[ETH_ALEN];
} STRUCT_PACKED;

/* TDLS frame headers as per IEEE Std 802.11z-2010 */
struct wpa_tdls_frame {
	u8 payloadtype; /* IEEE80211_TDLS_RFTYPE */
	u8 category; /* Category */
	u8 action; /* Action (enum tdls_frame_type) */
} STRUCT_PACKED;

static u8 * wpa_add_tdls_timeoutie(u8 *pos, u8 *ie, size_t ie_len, u32 tsecs);
static void wpa_tdls_tpk_retry_timeout(void *eloop_ctx, void *timeout_ctx);
static void wpa_tdls_peer_free(struct wpa_sm *sm, struct wpa_tdls_peer *peer);


#define TDLS_MAX_IE_LEN 80
#define IEEE80211_MAX_SUPP_RATES 32

struct wpa_tdls_peer {
	struct wpa_tdls_peer *next;
	int initiator; /* whether this end was initiator for TDLS setup */
	u8 addr[ETH_ALEN]; /* other end MAC address */
	u8 inonce[WPA_NONCE_LEN]; /* Initiator Nonce */
	u8 rnonce[WPA_NONCE_LEN]; /* Responder Nonce */
	u8 rsnie_i[TDLS_MAX_IE_LEN]; /* Initiator RSN IE */
	size_t rsnie_i_len;
	u8 rsnie_p[TDLS_MAX_IE_LEN]; /* Peer RSN IE */
	size_t rsnie_p_len;
	u32 lifetime;
	int cipher; /* Selected cipher (WPA_CIPHER_*) */
	u8 dtoken;

	struct tpk {
		u8 kck[16]; /* TPK-KCK */
		u8 tk[16]; /* TPK-TK; assuming only CCMP will be used */
	} tpk;
	int tpk_set;
	int tpk_success;

	struct tpk_timer {
		u8 dest[ETH_ALEN];
		int count;      /* Retry Count */
		int timer;      /* Timeout in milliseconds */
		u8 action_code; /* TDLS frame type */
		u8 dialog_token;
		u16 status_code;
		int buf_len;    /* length of TPK message for retransmission */
		u8 *buf;        /* buffer for TPK message */
	} sm_tmr;

	u16 capability;

	u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
	size_t supp_rates_len;

	struct ieee80211_ht_capabilities *ht_capabilities;
	struct ieee80211_vht_capabilities *vht_capabilities;

	u8 qos_info;

	u8 *ext_capab;
	size_t ext_capab_len;
};


static int wpa_tdls_get_privacy(struct wpa_sm *sm)
{
	/*
	 * Get info needed from supplicant to check if the current BSS supports
	 * security. Other than OPEN mode, rest are considered secured
	 * WEP/WPA/WPA2 hence TDLS frames are processed for TPK handshake.
	 */
	return sm->pairwise_cipher != WPA_CIPHER_NONE;
}


static u8 * wpa_add_ie(u8 *pos, const u8 *ie, size_t ie_len)
{
	os_memcpy(pos, ie, ie_len);
	return pos + ie_len;
}


static int wpa_tdls_del_key(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
{
	if (wpa_sm_set_key(sm, WPA_ALG_NONE, peer->addr,
			   0, 0, NULL, 0, NULL, 0) < 0) {
		wpa_printf(MSG_WARNING, "TDLS: Failed to delete TPK-TK from "
			   "the driver");
		return -1;
	}

	return 0;
}


static int wpa_tdls_set_key(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
{
	u8 key_len;
	u8 rsc[6];
	enum wpa_alg alg;

	os_memset(rsc, 0, 6);

	switch (peer->cipher) {
	case WPA_CIPHER_CCMP:
		alg = WPA_ALG_CCMP;
		key_len = 16;
		break;
	case WPA_CIPHER_NONE:
		wpa_printf(MSG_DEBUG, "TDLS: Pairwise Cipher Suite: "
			   "NONE - do not use pairwise keys");
		return -1;
	default:
		wpa_printf(MSG_WARNING, "TDLS: Unsupported pairwise cipher %d",
			   sm->pairwise_cipher);
		return -1;
	}

	if (wpa_sm_set_key(sm, alg, peer->addr, -1, 1,
			   rsc, sizeof(rsc), peer->tpk.tk, key_len) < 0) {
		wpa_printf(MSG_WARNING, "TDLS: Failed to set TPK to the "
			   "driver");
		return -1;
	}
	return 0;
}


static int wpa_tdls_send_tpk_msg(struct wpa_sm *sm, const u8 *dst,
				 u8 action_code, u8 dialog_token,
				 u16 status_code, const u8 *buf, size_t len)
{
	return wpa_sm_send_tdls_mgmt(sm, dst, action_code, dialog_token,
				     status_code, buf, len);
}


static int wpa_tdls_tpk_send(struct wpa_sm *sm, const u8 *dest, u8 action_code,
			     u8 dialog_token, u16 status_code,
			     const u8 *msg, size_t msg_len)
{
	struct wpa_tdls_peer *peer;

	wpa_printf(MSG_DEBUG, "TDLS: TPK send dest=" MACSTR " action_code=%u "
		   "dialog_token=%u status_code=%u msg_len=%u",
		   MAC2STR(dest), action_code, dialog_token, status_code,
		   (unsigned int) msg_len);

	if (wpa_tdls_send_tpk_msg(sm, dest, action_code, dialog_token,
				  status_code, msg, msg_len)) {
		wpa_printf(MSG_INFO, "TDLS: Failed to send message "
			   "(action_code=%u)", action_code);
		return -1;
	}

	if (action_code == WLAN_TDLS_SETUP_CONFIRM ||
	    action_code == WLAN_TDLS_TEARDOWN ||
	    action_code == WLAN_TDLS_DISCOVERY_REQUEST ||
	    action_code == WLAN_TDLS_DISCOVERY_RESPONSE)
		return 0; /* No retries */

	for (peer = sm->tdls; peer; peer = peer->next) {
		if (os_memcmp(peer->addr, dest, ETH_ALEN) == 0)
			break;
	}

	if (peer == NULL) {
		wpa_printf(MSG_INFO, "TDLS: No matching entry found for "
			   "retry " MACSTR, MAC2STR(dest));
		return 0;
	}

	eloop_cancel_timeout(wpa_tdls_tpk_retry_timeout, sm, peer);

	peer->sm_tmr.count = TPK_RETRY_COUNT;
	peer->sm_tmr.timer = TPK_TIMEOUT;

	/* Copy message to resend on timeout */
	os_memcpy(peer->sm_tmr.dest, dest, ETH_ALEN);
	peer->sm_tmr.action_code = action_code;
	peer->sm_tmr.dialog_token = dialog_token;
	peer->sm_tmr.status_code = status_code;
	peer->sm_tmr.buf_len = msg_len;
	os_free(peer->sm_tmr.buf);
	peer->sm_tmr.buf = os_malloc(msg_len);
	if (peer->sm_tmr.buf == NULL)
		return -1;
	os_memcpy(peer->sm_tmr.buf, msg, msg_len);

	wpa_printf(MSG_DEBUG, "TDLS: Retry timeout registered "
		   "(action_code=%u)", action_code);
	eloop_register_timeout(peer->sm_tmr.timer / 1000, 0,
			       wpa_tdls_tpk_retry_timeout, sm, peer);
	return 0;
}


static int wpa_tdls_do_teardown(struct wpa_sm *sm, struct wpa_tdls_peer *peer,
				u16 reason_code, int free_peer)
{
	int ret;

	if (sm->tdls_external_setup) {
		ret = wpa_tdls_send_teardown(sm, peer->addr, reason_code);

		/* disable the link after teardown was sent */
		wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, peer->addr);
	} else {
		ret = wpa_sm_tdls_oper(sm, TDLS_TEARDOWN, peer->addr);
	}

	if (sm->tdls_external_setup || free_peer)
		wpa_tdls_peer_free(sm, peer);

	return ret;
}


static void wpa_tdls_tpk_retry_timeout(void *eloop_ctx, void *timeout_ctx)
{

	struct wpa_sm *sm = eloop_ctx;
	struct wpa_tdls_peer *peer = timeout_ctx;

	if (peer->sm_tmr.count) {
		peer->sm_tmr.count--;
		peer->sm_tmr.timer = TPK_TIMEOUT;

		wpa_printf(MSG_INFO, "TDLS: Retrying sending of message "
			   "(action_code=%u)",
			   peer->sm_tmr.action_code);

		if (peer->sm_tmr.buf == NULL) {
			wpa_printf(MSG_INFO, "TDLS: No retry buffer available "
				   "for action_code=%u",
				   peer->sm_tmr.action_code);
			eloop_cancel_timeout(wpa_tdls_tpk_retry_timeout, sm,
					     peer);
			return;
		}

		/* resend TPK Handshake Message to Peer */
		if (wpa_tdls_send_tpk_msg(sm, peer->sm_tmr.dest,
					  peer->sm_tmr.action_code,
					  peer->sm_tmr.dialog_token,
					  peer->sm_tmr.status_code,
					  peer->sm_tmr.buf,
					  peer->sm_tmr.buf_len)) {
			wpa_printf(MSG_INFO, "TDLS: Failed to retry "
				   "transmission");
		}

		eloop_cancel_timeout(wpa_tdls_tpk_retry_timeout, sm, peer);
		eloop_register_timeout(peer->sm_tmr.timer / 1000, 0,
				       wpa_tdls_tpk_retry_timeout, sm, peer);
	} else {
		eloop_cancel_timeout(wpa_tdls_tpk_retry_timeout, sm, peer);

		wpa_printf(MSG_DEBUG, "TDLS: Sending Teardown Request");
		wpa_tdls_do_teardown(sm, peer,
				     WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED, 1);
	}
}


static void wpa_tdls_tpk_retry_timeout_cancel(struct wpa_sm *sm,
					      struct wpa_tdls_peer *peer,
					      u8 action_code)
{
	if (action_code == peer->sm_tmr.action_code) {
		wpa_printf(MSG_DEBUG, "TDLS: Retry timeout cancelled for "
			   "action_code=%u", action_code);

		/* Cancel Timeout registered */
		eloop_cancel_timeout(wpa_tdls_tpk_retry_timeout, sm, peer);

		/* free all resources meant for retry */
		os_free(peer->sm_tmr.buf);
		peer->sm_tmr.buf = NULL;

		peer->sm_tmr.count = 0;
		peer->sm_tmr.timer = 0;
		peer->sm_tmr.buf_len = 0;
		peer->sm_tmr.action_code = 0xff;
	} else {
		wpa_printf(MSG_INFO, "TDLS: Error in cancelling retry timeout "
			   "(Unknown action_code=%u)", action_code);
	}
}


static void wpa_tdls_generate_tpk(struct wpa_tdls_peer *peer,
				  const u8 *own_addr, const u8 *bssid)
{
	u8 key_input[SHA256_MAC_LEN];
	const u8 *nonce[2];
	size_t len[2];
	u8 data[3 * ETH_ALEN];

	/* IEEE Std 802.11z-2010 8.5.9.1:
	 * TPK-Key-Input = SHA-256(min(SNonce, ANonce) || max(SNonce, ANonce))
	 */
	len[0] = WPA_NONCE_LEN;
	len[1] = WPA_NONCE_LEN;
	if (os_memcmp(peer->inonce, peer->rnonce, WPA_NONCE_LEN) < 0) {
		nonce[0] = peer->inonce;
		nonce[1] = peer->rnonce;
	} else {
		nonce[0] = peer->rnonce;
		nonce[1] = peer->inonce;
	}
	wpa_hexdump(MSG_DEBUG, "TDLS: min(Nonce)", nonce[0], WPA_NONCE_LEN);
	wpa_hexdump(MSG_DEBUG, "TDLS: max(Nonce)", nonce[1], WPA_NONCE_LEN);
	sha256_vector(2, nonce, len, key_input);
	wpa_hexdump_key(MSG_DEBUG, "TDLS: TPK-Key-Input",
			key_input, SHA256_MAC_LEN);

	/*
	 * TPK-Key-Data = KDF-N_KEY(TPK-Key-Input, "TDLS PMK",
	 *	min(MAC_I, MAC_R) || max(MAC_I, MAC_R) || BSSID || N_KEY)
	 * TODO: is N_KEY really included in KDF Context and if so, in which
	 * presentation format (little endian 16-bit?) is it used? It gets
	 * added by the KDF anyway..
	 */

	if (os_memcmp(own_addr, peer->addr, ETH_ALEN) < 0) {
		os_memcpy(data, own_addr, ETH_ALEN);
		os_memcpy(data + ETH_ALEN, peer->addr, ETH_ALEN);
	} else {
		os_memcpy(data, peer->addr, ETH_ALEN);
		os_memcpy(data + ETH_ALEN, own_addr, ETH_ALEN);
	}
	os_memcpy(data + 2 * ETH_ALEN, bssid, ETH_ALEN);
	wpa_hexdump(MSG_DEBUG, "TDLS: KDF Context", data, sizeof(data));

	sha256_prf(key_input, SHA256_MAC_LEN, "TDLS PMK", data, sizeof(data),
		   (u8 *) &peer->tpk, sizeof(peer->tpk));
	wpa_hexdump_key(MSG_DEBUG, "TDLS: TPK-KCK",
			peer->tpk.kck, sizeof(peer->tpk.kck));
	wpa_hexdump_key(MSG_DEBUG, "TDLS: TPK-TK",
			peer->tpk.tk, sizeof(peer->tpk.tk));
	peer->tpk_set = 1;
}


/**
 * wpa_tdls_ftie_mic - Calculate TDLS FTIE MIC
 * @kck: TPK-KCK
 * @lnkid: Pointer to the beginning of Link Identifier IE
 * @rsnie: Pointer to the beginning of RSN IE used for handshake
 * @timeoutie: Pointer to the beginning of Timeout IE used for handshake
 * @ftie: Pointer to the beginning of FT IE
 * @mic: Pointer for writing MIC
 *
 * Calculate MIC for TDLS frame.
 */
static int wpa_tdls_ftie_mic(const u8 *kck, u8 trans_seq, const u8 *lnkid,
			     const u8 *rsnie, const u8 *timeoutie,
			     const u8 *ftie, u8 *mic)
{
	u8 *buf, *pos;
	struct wpa_tdls_ftie *_ftie;
	const struct wpa_tdls_lnkid *_lnkid;
	int ret;
	int len = 2 * ETH_ALEN + 1 + 2 + lnkid[1] + 2 + rsnie[1] +
		2 + timeoutie[1] + 2 + ftie[1];
	buf = os_zalloc(len);
	if (!buf) {
		wpa_printf(MSG_WARNING, "TDLS: No memory for MIC calculation");
		return -1;
	}

	pos = buf;
	_lnkid = (const struct wpa_tdls_lnkid *) lnkid;
	/* 1) TDLS initiator STA MAC address */
	os_memcpy(pos, _lnkid->init_sta, ETH_ALEN);
	pos += ETH_ALEN;
	/* 2) TDLS responder STA MAC address */
	os_memcpy(pos, _lnkid->resp_sta, ETH_ALEN);
	pos += ETH_ALEN;
	/* 3) Transaction Sequence number */
	*pos++ = trans_seq;
	/* 4) Link Identifier IE */
	os_memcpy(pos, lnkid, 2 + lnkid[1]);
	pos += 2 + lnkid[1];
	/* 5) RSN IE */
	os_memcpy(pos, rsnie, 2 + rsnie[1]);
	pos += 2 + rsnie[1];
	/* 6) Timeout Interval IE */
	os_memcpy(pos, timeoutie, 2 + timeoutie[1]);
	pos += 2 + timeoutie[1];
	/* 7) FTIE, with the MIC field of the FTIE set to 0 */
	os_memcpy(pos, ftie, 2 + ftie[1]);
	_ftie = (struct wpa_tdls_ftie *) pos;
	os_memset(_ftie->mic, 0, TDLS_MIC_LEN);
	pos += 2 + ftie[1];

	wpa_hexdump(MSG_DEBUG, "TDLS: Data for FTIE MIC", buf, pos - buf);
	wpa_hexdump_key(MSG_DEBUG, "TDLS: KCK", kck, 16);
	ret = omac1_aes_128(kck, buf, pos - buf, mic);
	os_free(buf);
	wpa_hexdump(MSG_DEBUG, "TDLS: FTIE MIC", mic, 16);
	return ret;
}


/**
 * wpa_tdls_key_mic_teardown - Calculate TDLS FTIE MIC for Teardown frame
 * @kck: TPK-KCK
 * @trans_seq: Transaction Sequence Number (4 - Teardown)
 * @rcode: Reason code for Teardown
 * @dtoken: Dialog Token used for that particular link
 * @lnkid: Pointer to the beginning of Link Identifier IE
 * @ftie: Pointer to the beginning of FT IE
 * @mic: Pointer for writing MIC
 *
 * Calculate MIC for TDLS frame.
 */
static int wpa_tdls_key_mic_teardown(const u8 *kck, u8 trans_seq, u16 rcode,
				     u8 dtoken, const u8 *lnkid,
				     const u8 *ftie, u8 *mic)
{
	u8 *buf, *pos;
	struct wpa_tdls_ftie *_ftie;
	int ret;
	int len;

	if (lnkid == NULL)
		return -1;

	len = 2 + lnkid[1] + sizeof(rcode) + sizeof(dtoken) +
		sizeof(trans_seq) + 2 + ftie[1];

	buf = os_zalloc(len);
	if (!buf) {
		wpa_printf(MSG_WARNING, "TDLS: No memory for MIC calculation");
		return -1;
	}

	pos = buf;
	/* 1) Link Identifier IE */
	os_memcpy(pos, lnkid, 2 + lnkid[1]);
	pos += 2 + lnkid[1];
	/* 2) Reason Code */
	WPA_PUT_LE16(pos, rcode);
	pos += sizeof(rcode);
	/* 3) Dialog token */
	*pos++ = dtoken;
	/* 4) Transaction Sequence number */
	*pos++ = trans_seq;
	/* 7) FTIE, with the MIC field of the FTIE set to 0 */
	os_memcpy(pos, ftie, 2 + ftie[1]);
	_ftie = (struct wpa_tdls_ftie *) pos;
	os_memset(_ftie->mic, 0, TDLS_MIC_LEN);
	pos += 2 + ftie[1];

	wpa_hexdump(MSG_DEBUG, "TDLS: Data for FTIE MIC", buf, pos - buf);
	wpa_hexdump_key(MSG_DEBUG, "TDLS: KCK", kck, 16);
	ret = omac1_aes_128(kck, buf, pos - buf, mic);
	os_free(buf);
	wpa_hexdump(MSG_DEBUG, "TDLS: FTIE MIC", mic, 16);
	return ret;
}


static int wpa_supplicant_verify_tdls_mic(u8 trans_seq,
					  struct wpa_tdls_peer *peer,
					  const u8 *lnkid, const u8 *timeoutie,
					  const struct wpa_tdls_ftie *ftie)
{
	u8 mic[16];

	if (peer->tpk_set) {
		wpa_tdls_ftie_mic(peer->tpk.kck, trans_seq, lnkid,
				  peer->rsnie_p, timeoutie, (u8 *) ftie,
				  mic);
		if (os_memcmp(mic, ftie->mic, 16) != 0) {
			wpa_printf(MSG_INFO, "TDLS: Invalid MIC in FTIE - "
				   "dropping packet");
			wpa_hexdump(MSG_DEBUG, "TDLS: Received MIC",
				    ftie->mic, 16);
			wpa_hexdump(MSG_DEBUG, "TDLS: Calculated MIC",
				    mic, 16);
			return -1;
		}
	} else {
		wpa_printf(MSG_WARNING, "TDLS: Could not verify TDLS MIC, "
			   "TPK not set - dropping packet");
		return -1;
	}
	return 0;
}


static int wpa_supplicant_verify_tdls_mic_teardown(
	u8 trans_seq, u16 rcode, u8 dtoken, struct wpa_tdls_peer *peer,
	const u8 *lnkid, const struct wpa_tdls_ftie *ftie)
{
	u8 mic[16];

	if (peer->tpk_set) {
		wpa_tdls_key_mic_teardown(peer->tpk.kck, trans_seq, rcode,
					  dtoken, lnkid, (u8 *) ftie, mic);
		if (os_memcmp(mic, ftie->mic, 16) != 0) {
			wpa_printf(MSG_INFO, "TDLS: Invalid MIC in Teardown - "
				   "dropping packet");
			return -1;
		}
	} else {
		wpa_printf(MSG_INFO, "TDLS: Could not verify TDLS Teardown "
			   "MIC, TPK not set - dropping packet");
		return -1;
	}
	return 0;
}


static void wpa_tdls_tpk_timeout(void *eloop_ctx, void *timeout_ctx)
{
	struct wpa_sm *sm = eloop_ctx;
	struct wpa_tdls_peer *peer = timeout_ctx;

	/*
	 * On TPK lifetime expiration, we have an option of either tearing down
	 * the direct link or trying to re-initiate it. The selection of what
	 * to do is not strictly speaking controlled by our role in the expired
	 * link, but for now, use that to select whether to renew or tear down
	 * the link.
	 */

	if (peer->initiator) {
		wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime expired for " MACSTR
			   " - try to renew", MAC2STR(peer->addr));
		wpa_tdls_start(sm, peer->addr);
	} else {
		wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime expired for " MACSTR
			   " - tear down", MAC2STR(peer->addr));
		wpa_tdls_do_teardown(sm, peer,
				     WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED, 1);
	}
}


static void wpa_tdls_peer_free(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
{
	wpa_printf(MSG_DEBUG, "TDLS: Clear state for peer " MACSTR,
		   MAC2STR(peer->addr));
	eloop_cancel_timeout(wpa_tdls_tpk_timeout, sm, peer);
	eloop_cancel_timeout(wpa_tdls_tpk_retry_timeout, sm, peer);
	peer->initiator = 0;
	os_free(peer->sm_tmr.buf);
	peer->sm_tmr.buf = NULL;
	os_free(peer->ht_capabilities);
	peer->ht_capabilities = NULL;
	os_free(peer->vht_capabilities);
	peer->vht_capabilities = NULL;
	os_free(peer->ext_capab);
	peer->ext_capab = NULL;
	peer->rsnie_i_len = peer->rsnie_p_len = 0;
	peer->cipher = 0;
	peer->tpk_set = peer->tpk_success = 0;
	os_memset(&peer->tpk, 0, sizeof(peer->tpk));
	os_memset(peer->inonce, 0, WPA_NONCE_LEN);
	os_memset(peer->rnonce, 0, WPA_NONCE_LEN);
}


static void wpa_tdls_linkid(struct wpa_sm *sm, struct wpa_tdls_peer *peer,
			    struct wpa_tdls_lnkid *lnkid)
{
	lnkid->ie_type = WLAN_EID_LINK_ID;
	lnkid->ie_len = 3 * ETH_ALEN;
	os_memcpy(lnkid->bssid, sm->bssid, ETH_ALEN);
	if (peer->initiator) {
		os_memcpy(lnkid->init_sta, sm->own_addr, ETH_ALEN);
		os_memcpy(lnkid->resp_sta, peer->addr, ETH_ALEN);
	} else {
		os_memcpy(lnkid->init_sta, peer->addr, ETH_ALEN);
		os_memcpy(lnkid->resp_sta, sm->own_addr, ETH_ALEN);
	}
}


int wpa_tdls_send_teardown(struct wpa_sm *sm, const u8 *addr, u16 reason_code)
{
	struct wpa_tdls_peer *peer;
	struct wpa_tdls_ftie *ftie;
	struct wpa_tdls_lnkid lnkid;
	u8 dialog_token;
	u8 *rbuf, *pos;
	int ielen;

	if (sm->tdls_disabled || !sm->tdls_supported)
		return -1;

	/* Find the node and free from the list */
	for (peer = sm->tdls; peer; peer = peer->next) {
		if (os_memcmp(peer->addr, addr, ETH_ALEN) == 0)
			break;
	}

	if (peer == NULL) {
		wpa_printf(MSG_INFO, "TDLS: No matching entry found for "
			   "Teardown " MACSTR, MAC2STR(addr));
		return 0;
	}

	dialog_token = peer->dtoken;

	wpa_printf(MSG_DEBUG, "TDLS: TDLS Teardown for " MACSTR,
		   MAC2STR(addr));

	ielen = 0;
	if (wpa_tdls_get_privacy(sm) && peer->tpk_set && peer->tpk_success) {
		/* To add FTIE for Teardown request and compute MIC */
		ielen += sizeof(*ftie);
#ifdef CONFIG_TDLS_TESTING
		if (tdls_testing & TDLS_TESTING_LONG_FRAME)
			ielen += 170;
#endif /* CONFIG_TDLS_TESTING */
	}

	rbuf = os_zalloc(ielen + 1);
	if (rbuf == NULL)
		return -1;
	pos = rbuf;

	if (!wpa_tdls_get_privacy(sm) || !peer->tpk_set || !peer->tpk_success) {
		if (reason_code != WLAN_REASON_DEAUTH_LEAVING) {
			/* Overwrite the reason code */
			reason_code = WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED;
		}
		goto skip_ies;
	}

	ftie = (struct wpa_tdls_ftie *) pos;
	ftie->ie_type = WLAN_EID_FAST_BSS_TRANSITION;
	/* Using the recent nonce which should be for CONFIRM frame */
	os_memcpy(ftie->Anonce, peer->rnonce, WPA_NONCE_LEN);
	os_memcpy(ftie->Snonce, peer->inonce, WPA_NONCE_LEN);
	ftie->ie_len = sizeof(struct wpa_tdls_ftie) - 2;
	pos = (u8 *) (ftie + 1);
#ifdef CONFIG_TDLS_TESTING
	if (tdls_testing & TDLS_TESTING_LONG_FRAME) {
		wpa_printf(MSG_DEBUG, "TDLS: Testing - add extra subelem to "
			   "FTIE");
		ftie->ie_len += 170;
		*pos++ = 255; /* FTIE subelem */
		*pos++ = 168; /* FTIE subelem length */
		pos += 168;
	}
#endif /* CONFIG_TDLS_TESTING */
	wpa_hexdump(MSG_DEBUG, "TDLS: FTIE for TDLS Teardown handshake",
		    (u8 *) ftie, pos - (u8 *) ftie);

	/* compute MIC before sending */
	wpa_tdls_linkid(sm, peer, &lnkid);
	wpa_tdls_key_mic_teardown(peer->tpk.kck, 4, reason_code,
				  dialog_token, (u8 *) &lnkid, (u8 *) ftie,
				  ftie->mic);

skip_ies:
	/* TODO: register for a Timeout handler, if Teardown is not received at
	 * the other end, then try again another time */

	/* request driver to send Teardown using this FTIE */
	wpa_tdls_tpk_send(sm, addr, WLAN_TDLS_TEARDOWN, 0,
			  reason_code, rbuf, pos - rbuf);
	os_free(rbuf);

	/* clear the Peerkey statemachine */
	wpa_tdls_peer_free(sm, peer);

	return 0;
}


int wpa_tdls_teardown_link(struct wpa_sm *sm, const u8 *addr, u16 reason_code)
{
	struct wpa_tdls_peer *peer;

	if (sm->tdls_disabled || !sm->tdls_supported)
		return -1;

	for (peer = sm->tdls; peer; peer = peer->next) {
		if (os_memcmp(peer->addr, addr, ETH_ALEN) == 0)
			break;
	}

	if (peer == NULL) {
		wpa_printf(MSG_DEBUG, "TDLS: Could not find peer " MACSTR
		   " for link Teardown", MAC2STR(addr));
		return -1;
	}

	if (!peer->tpk_success) {
		wpa_printf(MSG_DEBUG, "TDLS: Peer " MACSTR
		   " not connected - cannot Teardown link", MAC2STR(addr));
		return -1;
	}

	return wpa_tdls_do_teardown(sm, peer, reason_code, 0);
}


void wpa_tdls_disable_link(struct wpa_sm *sm, const u8 *addr)
{
	struct wpa_tdls_peer *peer;

	for (peer = sm->tdls; peer; peer = peer->next) {
		if (os_memcmp(peer->addr, addr, ETH_ALEN) == 0)
			break;
	}

	if (peer) {
		wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, addr);
		wpa_tdls_peer_free(sm, peer);
	}
}


static int wpa_tdls_recv_teardown(struct wpa_sm *sm, const u8 *src_addr,
				  const u8 *buf, size_t len)
{
	struct wpa_tdls_peer *peer = NULL;
	struct wpa_tdls_ftie *ftie;
	struct wpa_tdls_lnkid *lnkid;
	struct wpa_eapol_ie_parse kde;
	u16 reason_code;
	const u8 *pos;
	int ielen;

	/* Find the node and free from the list */
	for (peer = sm->tdls; peer; peer = peer->next) {
		if (os_memcmp(peer->addr, src_addr, ETH_ALEN) == 0)
			break;
	}

	if (peer == NULL) {
		wpa_printf(MSG_INFO, "TDLS: No matching entry found for "
			   "Teardown " MACSTR, MAC2STR(src_addr));
		return 0;
	}

	pos = buf;
	pos += 1 /* pkt_type */ + 1 /* Category */ + 1 /* Action */;

	reason_code = WPA_GET_LE16(pos);
	pos += 2;

	wpa_printf(MSG_DEBUG, "TDLS: TDLS Teardown Request from " MACSTR
		   " (reason code %u)", MAC2STR(src_addr), reason_code);

	ielen = len - (pos - buf); /* start of IE in buf */
	if (wpa_supplicant_parse_ies((const u8 *) pos, ielen, &kde) < 0) {
		wpa_printf(MSG_INFO, "TDLS: Failed to parse IEs in Teardown");
		return -1;
	}

	if (kde.lnkid == NULL || kde.lnkid_len < 3 * ETH_ALEN) {
		wpa_printf(MSG_INFO, "TDLS: No Link Identifier IE in TDLS "
			   "Teardown");
		return -1;
	}
	lnkid = (struct wpa_tdls_lnkid *) kde.lnkid;

	if (!wpa_tdls_get_privacy(sm) || !peer->tpk_set || !peer->tpk_success)
		goto skip_ftie;

	if (kde.ftie == NULL || kde.ftie_len < sizeof(*ftie)) {
		wpa_printf(MSG_INFO, "TDLS: No FTIE in TDLS Teardown");
		return -1;
	}

	ftie = (struct wpa_tdls_ftie *) kde.ftie;

	/* Process MIC check to see if TDLS Teardown is right */
	if (wpa_supplicant_verify_tdls_mic_teardown(4, reason_code,
						    peer->dtoken, peer,
						    (u8 *) lnkid, ftie) < 0) {
		wpa_printf(MSG_DEBUG, "TDLS: MIC failure for TDLS "
			   "Teardown Request from " MACSTR, MAC2STR(src_addr));
		return -1;
	}

skip_ftie:
	/*
	 * Request the driver to disable the direct link and clear associated
	 * keys.
	 */
	wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, src_addr);

	/* clear the Peerkey statemachine */
	wpa_tdls_peer_free(sm, peer);

	return 0;
}


/**
 * wpa_tdls_send_error - To send suitable TDLS status response with
 *	appropriate status code mentioning reason for error/failure.
 * @dst 	- MAC addr of Peer station
 * @tdls_action - TDLS frame type for which error code is sent
 * @status 	- status code mentioning reason
 */

static int wpa_tdls_send_error(struct wpa_sm *sm, const u8 *dst,
			       u8 tdls_action, u8 dialog_token, u16 status)
{
	wpa_printf(MSG_DEBUG, "TDLS: Sending error to " MACSTR
		   " (action=%u status=%u)",
		   MAC2STR(dst), tdls_action, status);
	return wpa_tdls_tpk_send(sm, dst, tdls_action, dialog_token, status,
				 NULL, 0);
}


static struct wpa_tdls_peer *
wpa_tdls_add_peer(struct wpa_sm *sm, const u8 *addr, int *existing)
{
	struct wpa_tdls_peer *peer;

	if (existing)
		*existing = 0;
	for (peer = sm->tdls; peer; peer = peer->next) {
		if (os_memcmp(peer->addr, addr, ETH_ALEN) == 0) {
			if (existing)
				*existing = 1;
			return peer; /* re-use existing entry */
		}
	}

	wpa_printf(MSG_INFO, "TDLS: Creating peer entry for " MACSTR,
		   MAC2STR(addr));

	peer = os_zalloc(sizeof(*peer));
	if (peer == NULL)
		return NULL;

	os_memcpy(peer->addr, addr, ETH_ALEN);
	peer->next = sm->tdls;
	sm->tdls = peer;

	return peer;
}


static int wpa_tdls_send_tpk_m1(struct wpa_sm *sm,
				struct wpa_tdls_peer *peer)
{
	size_t buf_len;
	struct wpa_tdls_timeoutie timeoutie;
	u16 rsn_capab;
	struct wpa_tdls_ftie *ftie;
	u8 *rbuf, *pos, *count_pos;
	u16 count;
	struct rsn_ie_hdr *hdr;

	if (!wpa_tdls_get_privacy(sm)) {
		wpa_printf(MSG_DEBUG, "TDLS: No security used on the link");
		peer->rsnie_i_len = 0;
		goto skip_rsnie;
	}

	/*
	 * TPK Handshake Message 1:
	 * FTIE: ANonce=0, SNonce=initiator nonce MIC=0, DataKDs=(RSNIE_I,
	 * Timeout Interval IE))
	 */

	/* Filling RSN IE */
	hdr = (struct rsn_ie_hdr *) peer->rsnie_i;
	hdr->elem_id = WLAN_EID_RSN;
	WPA_PUT_LE16(hdr->version, RSN_VERSION);

	pos = (u8 *) (hdr + 1);
	RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED);
	pos += RSN_SELECTOR_LEN;
	count_pos = pos;
	pos += 2;

	count = 0;

	/*
	 * AES-CCMP is the default Encryption preferred for TDLS, so
	 * RSN IE is filled only with CCMP CIPHER
	 * Note: TKIP is not used to encrypt TDLS link.
	 *
	 * Regardless of the cipher used on the AP connection, select CCMP
	 * here.
	 */
	RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
	pos += RSN_SELECTOR_LEN;
	count++;

	WPA_PUT_LE16(count_pos, count);

	WPA_PUT_LE16(pos, 1);
	pos += 2;
	RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_TPK_HANDSHAKE);
	pos += RSN_SELECTOR_LEN;

	rsn_capab = WPA_CAPABILITY_PEERKEY_ENABLED;
	rsn_capab |= RSN_NUM_REPLAY_COUNTERS_16 << 2;
#ifdef CONFIG_TDLS_TESTING
	if (tdls_testing & TDLS_TESTING_ALT_RSN_IE) {
		wpa_printf(MSG_DEBUG, "TDLS: Use alternative RSN IE for "
			   "testing");
		rsn_capab = WPA_CAPABILITY_PEERKEY_ENABLED;
	}
#endif /* CONFIG_TDLS_TESTING */
	WPA_PUT_LE16(pos, rsn_capab);
	pos += 2;
#ifdef CONFIG_TDLS_TESTING
	if (tdls_testing & TDLS_TESTING_ALT_RSN_IE) {
		/* Number of PMKIDs */
		*pos++ = 0x00;
		*pos++ = 0x00;
	}
#endif /* CONFIG_TDLS_TESTING */

	hdr->len = (pos - peer->rsnie_i) - 2;
	peer->rsnie_i_len = pos - peer->rsnie_i;
	wpa_hexdump(MSG_DEBUG, "TDLS: RSN IE for TPK handshake",
		    peer->rsnie_i, peer->rsnie_i_len);

skip_rsnie:
	buf_len = 0;
	if (wpa_tdls_get_privacy(sm))
		buf_len += peer->rsnie_i_len + sizeof(struct wpa_tdls_ftie) +
			sizeof(struct wpa_tdls_timeoutie);
#ifdef CONFIG_TDLS_TESTING
	if (wpa_tdls_get_privacy(sm) &&
	    (tdls_testing & TDLS_TESTING_LONG_FRAME))
		buf_len += 170;
	if (tdls_testing & TDLS_TESTING_DIFF_BSSID)
		buf_len += sizeof(struct wpa_tdls_lnkid);
#endif /* CONFIG_TDLS_TESTING */
	rbuf = os_zalloc(buf_len + 1);
	if (rbuf == NULL) {
		wpa_tdls_peer_free(sm, peer);
		return -1;
	}
	pos = rbuf;

	if (!wpa_tdls_get_privacy(sm))
		goto skip_ies;

	/* Initiator RSN IE */
	pos = wpa_add_ie(pos, peer->rsnie_i, peer->rsnie_i_len);

	ftie = (struct wpa_tdls_ftie *) pos;
	ftie->ie_type = WLAN_EID_FAST_BSS_TRANSITION;
	ftie->ie_len = sizeof(struct wpa_tdls_ftie) - 2;

	if (os_get_random(peer->inonce, WPA_NONCE_LEN)) {
		wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
			"TDLS: Failed to get random data for initiator Nonce");
		os_free(rbuf);
		wpa_tdls_peer_free(sm, peer);
		return -1;
	}
	wpa_hexdump(MSG_DEBUG, "TDLS: Initiator Nonce for TPK handshake",
		    peer->inonce, WPA_NONCE_LEN);
	os_memcpy(ftie->Snonce, peer->inonce, WPA_NONCE_LEN);

	wpa_hexdump(MSG_DEBUG, "TDLS: FTIE for TPK Handshake M1",
		    (u8 *) ftie, sizeof(struct wpa_tdls_ftie));

	pos = (u8 *) (ftie + 1);

#ifdef CONFIG_TDLS_TESTING
	if (tdls_testing & TDLS_TESTING_LONG_FRAME) {
		wpa_printf(MSG_DEBUG, "TDLS: Testing - add extra subelem to "
			   "FTIE");
		ftie->ie_len += 170;
		*pos++ = 255; /* FTIE subelem */
		*pos++ = 168; /* FTIE subelem length */
		pos += 168;
	}
#endif /* CONFIG_TDLS_TESTING */

	/* Lifetime */
	peer->lifetime = TPK_LIFETIME;
#ifdef CONFIG_TDLS_TESTING
	if (tdls_testing & TDLS_TESTING_SHORT_LIFETIME) {
		wpa_printf(MSG_DEBUG, "TDLS: Testing - use short TPK "
			   "lifetime");
		peer->lifetime = 301;
	}
	if (tdls_testing & TDLS_TESTING_LONG_LIFETIME) {
		wpa_printf(MSG_DEBUG, "TDLS: Testing - use long TPK "
			   "lifetime");
		peer->lifetime = 0xffffffff;
	}
#endif /* CONFIG_TDLS_TESTING */
	pos = wpa_add_tdls_timeoutie(pos, (u8 *) &timeoutie,
				     sizeof(timeoutie), peer->lifetime);
	wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime %u seconds", peer->lifetime);

skip_ies:

#ifdef CONFIG_TDLS_TESTING
	if (tdls_testing & TDLS_TESTING_DIFF_BSSID) {
		wpa_printf(MSG_DEBUG, "TDLS: Testing - use incorrect BSSID in "
			   "Link Identifier");
		struct wpa_tdls_lnkid *l = (struct wpa_tdls_lnkid *) pos;
		wpa_tdls_linkid(sm, peer, l);
		l->bssid[5] ^= 0x01;
		pos += sizeof(*l);
	}
#endif /* CONFIG_TDLS_TESTING */

	wpa_printf(MSG_DEBUG, "TDLS: Sending TDLS Setup Request / TPK "
		   "Handshake Message 1 (peer " MACSTR ")",
		   MAC2STR(peer->addr));

	wpa_tdls_tpk_send(sm, peer->addr, WLAN_TDLS_SETUP_REQUEST, 1, 0,
			  rbuf, pos - rbuf);
	os_free(rbuf);

	return 0;
}


static int wpa_tdls_send_tpk_m2(struct wpa_sm *sm,
				const unsigned char *src_addr, u8 dtoken,
				struct wpa_tdls_lnkid *lnkid,
				const struct wpa_tdls_peer *peer)
{
	u8 *rbuf, *pos;
	size_t buf_len;
	u32 lifetime;
	struct wpa_tdls_timeoutie timeoutie;
	struct wpa_tdls_ftie *ftie;

	buf_len = 0;
	if (wpa_tdls_get_privacy(sm)) {
		/* Peer RSN IE, FTIE(Initiator Nonce, Responder Nonce),
		 * Lifetime */
		buf_len += peer->rsnie_i_len + sizeof(struct wpa_tdls_ftie) +
			sizeof(struct wpa_tdls_timeoutie);
#ifdef CONFIG_TDLS_TESTING
		if (tdls_testing & TDLS_TESTING_LONG_FRAME)
			buf_len += 170;
#endif /* CONFIG_TDLS_TESTING */
	}

	rbuf = os_zalloc(buf_len + 1);
	if (rbuf == NULL)
		return -1;
	pos = rbuf;

	if (!wpa_tdls_get_privacy(sm))
		goto skip_ies;

	/* Peer RSN IE */
	pos = wpa_add_ie(pos, peer->rsnie_p, peer->rsnie_p_len);

	ftie = (struct wpa_tdls_ftie *) pos;
	ftie->ie_type = WLAN_EID_FAST_BSS_TRANSITION;
	/* TODO: ftie->mic_control to set 2-RESPONSE */
	os_memcpy(ftie->Anonce, peer->rnonce, WPA_NONCE_LEN);
	os_memcpy(ftie->Snonce, peer->inonce, WPA_NONCE_LEN);
	ftie->ie_len = sizeof(struct wpa_tdls_ftie) - 2;
	wpa_hexdump(MSG_DEBUG, "TDLS: FTIE for TPK M2",
		    (u8 *) ftie, sizeof(*ftie));

	pos = (u8 *) (ftie + 1);

#ifdef CONFIG_TDLS_TESTING
	if (tdls_testing & TDLS_TESTING_LONG_FRAME) {
		wpa_printf(MSG_DEBUG, "TDLS: Testing - add extra subelem to "
			   "FTIE");
		ftie->ie_len += 170;
		*pos++ = 255; /* FTIE subelem */
		*pos++ = 168; /* FTIE subelem length */
		pos += 168;
	}
#endif /* CONFIG_TDLS_TESTING */

	/* Lifetime */
	lifetime = peer->lifetime;
#ifdef CONFIG_TDLS_TESTING
	if (tdls_testing & TDLS_TESTING_WRONG_LIFETIME_RESP) {
		wpa_printf(MSG_DEBUG, "TDLS: Testing - use wrong TPK "
			   "lifetime in response");
		lifetime++;
	}
#endif /* CONFIG_TDLS_TESTING */
	pos = wpa_add_tdls_timeoutie(pos, (u8 *) &timeoutie,
				     sizeof(timeoutie), lifetime);
	wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime %u seconds from initiator",
		   lifetime);

	/* compute MIC before sending */
	wpa_tdls_ftie_mic(peer->tpk.kck, 2, (u8 *) lnkid, peer->rsnie_p,
			  (u8 *) &timeoutie, (u8 *) ftie, ftie->mic);

skip_ies:
	wpa_tdls_tpk_send(sm, src_addr, WLAN_TDLS_SETUP_RESPONSE, dtoken, 0,
			  rbuf, pos - rbuf);
	os_free(rbuf);

	return 0;
}


static int wpa_tdls_send_tpk_m3(struct wpa_sm *sm,
				const unsigned char *src_addr, u8 dtoken,
				struct wpa_tdls_lnkid *lnkid,
				const struct wpa_tdls_peer *peer)
{
	u8 *rbuf, *pos;
	size_t buf_len;
	struct wpa_tdls_ftie *ftie;
	struct wpa_tdls_timeoutie timeoutie;
	u32 lifetime;

	buf_len = 0;
	if (wpa_tdls_get_privacy(sm)) {
		/* Peer RSN IE, FTIE(Initiator Nonce, Responder Nonce),
		 * Lifetime */
		buf_len += peer->rsnie_i_len + sizeof(struct wpa_tdls_ftie) +
			sizeof(struct wpa_tdls_timeoutie);
#ifdef CONFIG_TDLS_TESTING
		if (tdls_testing & TDLS_TESTING_LONG_FRAME)
			buf_len += 170;
#endif /* CONFIG_TDLS_TESTING */
	}

	rbuf = os_zalloc(buf_len + 1);
	if (rbuf == NULL)
		return -1;
	pos = rbuf;

	if (!wpa_tdls_get_privacy(sm))
		goto skip_ies;

	/* Peer RSN IE */
	pos = wpa_add_ie(pos, peer->rsnie_p, peer->rsnie_p_len);

	ftie = (struct wpa_tdls_ftie *) pos;
	ftie->ie_type = WLAN_EID_FAST_BSS_TRANSITION;
	/*TODO: ftie->mic_control to set 3-CONFIRM */
	os_memcpy(ftie->Anonce, peer->rnonce, WPA_NONCE_LEN);
	os_memcpy(ftie->Snonce, peer->inonce, WPA_NONCE_LEN);
	ftie->ie_len = sizeof(struct wpa_tdls_ftie) - 2;

	pos = (u8 *) (ftie + 1);

#ifdef CONFIG_TDLS_TESTING
	if (tdls_testing & TDLS_TESTING_LONG_FRAME) {
		wpa_printf(MSG_DEBUG, "TDLS: Testing - add extra subelem to "
			   "FTIE");
		ftie->ie_len += 170;
		*pos++ = 255; /* FTIE subelem */
		*pos++ = 168; /* FTIE subelem length */
		pos += 168;
	}
#endif /* CONFIG_TDLS_TESTING */

	/* Lifetime */
	lifetime = peer->lifetime;
#ifdef CONFIG_TDLS_TESTING
	if (tdls_testing & TDLS_TESTING_WRONG_LIFETIME_CONF) {
		wpa_printf(MSG_DEBUG, "TDLS: Testing - use wrong TPK "
			   "lifetime in confirm");
		lifetime++;
	}
#endif /* CONFIG_TDLS_TESTING */
	pos = wpa_add_tdls_timeoutie(pos, (u8 *) &timeoutie,
				     sizeof(timeoutie), lifetime);
	wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime %u seconds",
		   lifetime);

	/* compute MIC before sending */
	wpa_tdls_ftie_mic(peer->tpk.kck, 3, (u8 *) lnkid, peer->rsnie_p,
			  (u8 *) &timeoutie, (u8 *) ftie, ftie->mic);

skip_ies:
	wpa_tdls_tpk_send(sm, src_addr, WLAN_TDLS_SETUP_CONFIRM, dtoken, 0,
			  rbuf, pos - rbuf);
	os_free(rbuf);

	return 0;
}


static int wpa_tdls_send_discovery_response(struct wpa_sm *sm,
					    struct wpa_tdls_peer *peer,
					    u8 dialog_token)
{
	wpa_printf(MSG_DEBUG, "TDLS: Sending TDLS Discovery Response "
		   "(peer " MACSTR ")", MAC2STR(peer->addr));

	return wpa_tdls_tpk_send(sm, peer->addr, WLAN_TDLS_DISCOVERY_RESPONSE,
				 dialog_token, 0, NULL, 0);
}


static int
wpa_tdls_process_discovery_request(struct wpa_sm *sm, const u8 *addr,
				   const u8 *buf, size_t len)
{
	struct wpa_eapol_ie_parse kde;
	const struct wpa_tdls_lnkid *lnkid;
	struct wpa_tdls_peer *peer;
	size_t min_req_len = sizeof(struct wpa_tdls_frame) +
		1 /* dialog token */ + sizeof(struct wpa_tdls_lnkid);
	u8 dialog_token;

	wpa_printf(MSG_DEBUG, "TDLS: Discovery Request from " MACSTR,
		   MAC2STR(addr));

	if (len < min_req_len) {
		wpa_printf(MSG_DEBUG, "TDLS Discovery Request is too short: "
			   "%d", (int) len);
		return -1;
	}

	dialog_token = buf[sizeof(struct wpa_tdls_frame)];

	if (wpa_supplicant_parse_ies(buf + sizeof(struct wpa_tdls_frame) + 1,
				     len - (sizeof(struct wpa_tdls_frame) + 1),
				     &kde) < 0)
		return -1;

	if (!kde.lnkid) {
		wpa_printf(MSG_DEBUG, "TDLS: Link ID not found in Discovery "
			   "Request");
		return -1;
	}

	lnkid = (const struct wpa_tdls_lnkid *) kde.lnkid;

	if (os_memcmp(sm->bssid, lnkid->bssid, ETH_ALEN) != 0) {
		wpa_printf(MSG_DEBUG, "TDLS: Discovery Request from different "
			   " BSS " MACSTR, MAC2STR(lnkid->bssid));
		return -1;
	}

	peer = wpa_tdls_add_peer(sm, addr, NULL);
	if (peer == NULL)
		return -1;

	return wpa_tdls_send_discovery_response(sm, peer, dialog_token);
}


int wpa_tdls_send_discovery_request(struct wpa_sm *sm, const u8 *addr)
{
	if (sm->tdls_disabled || !sm->tdls_supported)
		return -1;

	wpa_printf(MSG_DEBUG, "TDLS: Sending Discovery Request to peer "
		   MACSTR, MAC2STR(addr));
	return wpa_tdls_tpk_send(sm, addr, WLAN_TDLS_DISCOVERY_REQUEST,
				 1, 0, NULL, 0);
}


static int copy_supp_rates(const struct wpa_eapol_ie_parse *kde,
			   struct wpa_tdls_peer *peer)
{
	if (!kde->supp_rates) {
		wpa_printf(MSG_DEBUG, "TDLS: No supported rates received");
		return -1;
	}
	peer->supp_rates_len = merge_byte_arrays(
		peer->supp_rates, sizeof(peer->supp_rates),
		kde->supp_rates + 2, kde->supp_rates_len - 2,
		kde->ext_supp_rates + 2, kde->ext_supp_rates_len - 2);
	return 0;
}


static int copy_peer_ht_capab(const struct wpa_eapol_ie_parse *kde,
			      struct wpa_tdls_peer *peer)
{
	if (!kde->ht_capabilities ||
	    kde->ht_capabilities_len <
	    sizeof(struct ieee80211_ht_capabilities) ) {
		wpa_printf(MSG_DEBUG, "TDLS: No supported ht capabilities "
			   "received");
		return 0;
	}

	if (!peer->ht_capabilities) {
		peer->ht_capabilities =
                        os_zalloc(sizeof(struct ieee80211_ht_capabilities));
		if (peer->ht_capabilities == NULL)
                        return -1;
	}

	os_memcpy(peer->ht_capabilities, kde->ht_capabilities,
                  sizeof(struct ieee80211_ht_capabilities));
	wpa_hexdump(MSG_DEBUG, "TDLS: Peer HT capabilities",
		    (u8 *) peer->ht_capabilities,
		    sizeof(struct ieee80211_ht_capabilities));

	return 0;
}


static int copy_peer_vht_capab(const struct wpa_eapol_ie_parse *kde,
			      struct wpa_tdls_peer *peer)
{
	if (!kde->vht_capabilities ||
	    kde->vht_capabilities_len <
	    sizeof(struct ieee80211_vht_capabilities) ) {
		wpa_printf(MSG_DEBUG, "TDLS: No supported vht capabilities "
			   "received");
		return 0;
	}

	if (!peer->vht_capabilities) {
		peer->vht_capabilities =
                        os_zalloc(sizeof(struct ieee80211_vht_capabilities));
		if (peer->vht_capabilities == NULL)
                        return -1;
	}

	os_memcpy(peer->vht_capabilities, kde->vht_capabilities,
                  sizeof(struct ieee80211_vht_capabilities));
	wpa_hexdump(MSG_DEBUG, "TDLS: Peer VHT capabilities",
		    (u8 *) peer->vht_capabilities,
		    sizeof(struct ieee80211_vht_capabilities));

	return 0;
}


static int copy_peer_ext_capab(const struct wpa_eapol_ie_parse *kde,
			       struct wpa_tdls_peer *peer)
{
	if (!kde->ext_capab) {
		wpa_printf(MSG_DEBUG, "TDLS: No extended capabilities "
			   "received");
		return 0;
	}

	if (!peer->ext_capab || peer->ext_capab_len < kde->ext_capab_len - 2) {
		/* Need to allocate buffer to fit the new information */
		os_free(peer->ext_capab);
		peer->ext_capab = os_zalloc(kde->ext_capab_len - 2);
		if (peer->ext_capab == NULL)
			return -1;
	}

	peer->ext_capab_len = kde->ext_capab_len - 2;
	os_memcpy(peer->ext_capab, kde->ext_capab + 2, peer->ext_capab_len);

	return 0;
}


static int wpa_tdls_process_tpk_m1(struct wpa_sm *sm, const u8 *src_addr,
				   const u8 *buf, size_t len)
{
	struct wpa_tdls_peer *peer;
	struct wpa_eapol_ie_parse kde;
	struct wpa_ie_data ie;
	int cipher;
	const u8 *cpos;
	struct wpa_tdls_ftie *ftie = NULL;
	struct wpa_tdls_timeoutie *timeoutie;
	struct wpa_tdls_lnkid *lnkid;
	u32 lifetime = 0;
#if 0
	struct rsn_ie_hdr *hdr;
	u8 *pos;
	u16 rsn_capab;
	u16 rsn_ver;
#endif
	u8 dtoken;
	u16 ielen;
	u16 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
	int tdls_prohibited = sm->tdls_prohibited;
	int existing_peer = 0;

	if (len < 3 + 3)
		return -1;

	cpos = buf;
	cpos += 1 /* pkt_type */ + 1 /* Category */ + 1 /* Action */;

	/* driver had already verified the frame format */
	dtoken = *cpos++; /* dialog token */

	wpa_printf(MSG_INFO, "TDLS: Dialog Token in TPK M1 %d", dtoken);

	peer = wpa_tdls_add_peer(sm, src_addr, &existing_peer);
	if (peer == NULL)
		goto error;

	/* capability information */
	peer->capability = WPA_GET_LE16(cpos);
	cpos += 2;

	ielen = len - (cpos - buf); /* start of IE in buf */
	if (wpa_supplicant_parse_ies(cpos, ielen, &kde) < 0) {
		wpa_printf(MSG_INFO, "TDLS: Failed to parse IEs in TPK M1");
		goto error;
	}

	if (kde.lnkid == NULL || kde.lnkid_len < 3 * ETH_ALEN) {
		wpa_printf(MSG_INFO, "TDLS: No valid Link Identifier IE in "
			   "TPK M1");
		goto error;
	}
	wpa_hexdump(MSG_DEBUG, "TDLS: Link ID Received from TPK M1",
		    kde.lnkid, kde.lnkid_len);
	lnkid = (struct wpa_tdls_lnkid *) kde.lnkid;
	if (os_memcmp(sm->bssid, lnkid->bssid, ETH_ALEN) != 0) {
		wpa_printf(MSG_INFO, "TDLS: TPK M1 from diff BSS");
		status = WLAN_STATUS_NOT_IN_SAME_BSS;
		goto error;
	}

	wpa_printf(MSG_DEBUG, "TDLS: TPK M1 - TPK initiator " MACSTR,
		   MAC2STR(src_addr));

	if (copy_supp_rates(&kde, peer) < 0)
		goto error;

	if (copy_peer_ht_capab(&kde, peer) < 0)
		goto error;

	if (copy_peer_vht_capab(&kde, peer) < 0)
		goto error;

	if (copy_peer_ext_capab(&kde, peer) < 0)
		goto error;

	peer->qos_info = kde.qosinfo;

#ifdef CONFIG_TDLS_TESTING
	if (tdls_testing & TDLS_TESTING_CONCURRENT_INIT) {
		peer = wpa_tdls_add_peer(sm, src_addr, NULL);
		if (peer == NULL)
			goto error;
		wpa_printf(MSG_DEBUG, "TDLS: Testing concurrent initiation of "
			   "TDLS setup - send own request");
		peer->initiator = 1;
		wpa_tdls_send_tpk_m1(sm, peer);
	}

	if ((tdls_testing & TDLS_TESTING_IGNORE_AP_PROHIBIT) &&
	    tdls_prohibited) {
		wpa_printf(MSG_DEBUG, "TDLS: Testing - ignore AP prohibition "
			   "on TDLS");
		tdls_prohibited = 0;
	}
#endif /* CONFIG_TDLS_TESTING */

	if (tdls_prohibited) {
		wpa_printf(MSG_INFO, "TDLS: TDLS prohibited in this BSS");
		status = WLAN_STATUS_REQUEST_DECLINED;
		goto error;
	}

	if (!wpa_tdls_get_privacy(sm)) {
		if (kde.rsn_ie) {
			wpa_printf(MSG_INFO, "TDLS: RSN IE in TPK M1 while "
				   "security is disabled");
			status = WLAN_STATUS_SECURITY_DISABLED;
			goto error;
		}
		goto skip_rsn;
	}

	if (kde.ftie == NULL || kde.ftie_len < sizeof(*ftie) ||
	    kde.rsn_ie == NULL) {
		wpa_printf(MSG_INFO, "TDLS: No FTIE or RSN IE in TPK M1");
		status = WLAN_STATUS_INVALID_PARAMETERS;
		goto error;
	}

	if (kde.rsn_ie_len > TDLS_MAX_IE_LEN) {
		wpa_printf(MSG_INFO, "TDLS: Too long Initiator RSN IE in "
			   "TPK M1");
		status = WLAN_STATUS_INVALID_RSNIE;
		goto error;
	}

	if (wpa_parse_wpa_ie_rsn(kde.rsn_ie, kde.rsn_ie_len, &ie) < 0) {
		wpa_printf(MSG_INFO, "TDLS: Failed to parse RSN IE in TPK M1");
		status = WLAN_STATUS_INVALID_RSNIE;
		goto error;
	}

	cipher = ie.pairwise_cipher;
	if (cipher & WPA_CIPHER_CCMP) {
		wpa_printf(MSG_DEBUG, "TDLS: Using CCMP for direct link");
		cipher = WPA_CIPHER_CCMP;
	} else {
		wpa_printf(MSG_INFO, "TDLS: No acceptable cipher in TPK M1");
		status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
		goto error;
	}

	if ((ie.capabilities &
	     (WPA_CAPABILITY_NO_PAIRWISE | WPA_CAPABILITY_PEERKEY_ENABLED)) !=
	    WPA_CAPABILITY_PEERKEY_ENABLED) {
		wpa_printf(MSG_INFO, "TDLS: Invalid RSN Capabilities in "
			   "TPK M1");
		status = WLAN_STATUS_INVALID_RSN_IE_CAPAB;
		goto error;
	}

	/* Lifetime */
	if (kde.key_lifetime == NULL) {
		wpa_printf(MSG_INFO, "TDLS: No Key Lifetime IE in TPK M1");
		status = WLAN_STATUS_UNACCEPTABLE_LIFETIME;
		goto error;
	}
	timeoutie = (struct wpa_tdls_timeoutie *) kde.key_lifetime;
	lifetime = WPA_GET_LE32(timeoutie->value);
	wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime %u seconds", lifetime);
	if (lifetime < 300) {
		wpa_printf(MSG_INFO, "TDLS: Too short TPK lifetime");
		status = WLAN_STATUS_UNACCEPTABLE_LIFETIME;
		goto error;
	}

skip_rsn:
	/* If found, use existing entry instead of adding a new one;
	 * how to handle the case where both ends initiate at the
	 * same time? */
	if (existing_peer) {
		if (peer->tpk_success) {
			wpa_printf(MSG_DEBUG, "TDLS: TDLS Setup Request while "
				   "direct link is enabled - tear down the "
				   "old link first");
#if 0
			/* TODO: Disabling the link would be more proper
			 * operation here, but it seems to trigger a race with
			 * some drivers handling the new request frame. */
			wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, src_addr);
#else
			if (sm->tdls_external_setup)
				wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK,
						 src_addr);
			else
				wpa_tdls_del_key(sm, peer);
#endif
			wpa_tdls_peer_free(sm, peer);
		}

		/*
		 * An entry is already present, so check if we already sent a
		 * TDLS Setup Request. If so, compare MAC addresses and let the
		 * STA with the lower MAC address continue as the initiator.
		 * The other negotiation is terminated.
		 */
		if (peer->initiator) {
			if (os_memcmp(sm->own_addr, src_addr, ETH_ALEN) < 0) {
				wpa_printf(MSG_DEBUG, "TDLS: Discard request "
					   "from peer with higher address "
					   MACSTR, MAC2STR(src_addr));
				return -1;
			} else {
				wpa_printf(MSG_DEBUG, "TDLS: Accept request "
					   "from peer with lower address "
					   MACSTR " (terminate previously "
					   "initiated negotiation",
					   MAC2STR(src_addr));
				wpa_tdls_disable_link(sm, peer->addr);
			}
		}
	}

#ifdef CONFIG_TDLS_TESTING
	if (tdls_testing & TDLS_TESTING_CONCURRENT_INIT) {
		if (os_memcmp(sm->own_addr, peer->addr, ETH_ALEN) < 0) {
			/*
			 * The request frame from us is going to win, so do not
			 * replace information based on this request frame from
			 * the peer.
			 */
			goto skip_rsn_check;
		}
	}
#endif /* CONFIG_TDLS_TESTING */

	peer->initiator = 0; /* Need to check */
	peer->dtoken = dtoken;

	if (!wpa_tdls_get_privacy(sm)) {
		peer->rsnie_i_len = 0;
		peer->rsnie_p_len = 0;
		peer->cipher = WPA_CIPHER_NONE;
		goto skip_rsn_check;
	}

	ftie = (struct wpa_tdls_ftie *) kde.ftie;
	os_memcpy(peer->inonce, ftie->Snonce, WPA_NONCE_LEN);
	os_memcpy(peer->rsnie_i, kde.rsn_ie, kde.rsn_ie_len);
	peer->rsnie_i_len = kde.rsn_ie_len;
	peer->cipher = cipher;

	if (os_get_random(peer->rnonce, WPA_NONCE_LEN)) {
		wpa_msg(sm->ctx->ctx, MSG_WARNING,
			"TDLS: Failed to get random data for responder nonce");
		wpa_tdls_peer_free(sm, peer);
		goto error;
	}

#if 0
	/* get version info from RSNIE received from Peer */
	hdr = (struct rsn_ie_hdr *) kde.rsn_ie;
	rsn_ver = WPA_GET_LE16(hdr->version);

	/* use min(peer's version, out version) */
	if (rsn_ver > RSN_VERSION)
		rsn_ver = RSN_VERSION;

	hdr = (struct rsn_ie_hdr *) peer->rsnie_p;

	hdr->elem_id = WLAN_EID_RSN;
	WPA_PUT_LE16(hdr->version, rsn_ver);
	pos = (u8 *) (hdr + 1);

	RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED);
	pos += RSN_SELECTOR_LEN;
	/* Include only the selected cipher in pairwise cipher suite */
	WPA_PUT_LE16(pos, 1);
	pos += 2;
	if (cipher == WPA_CIPHER_CCMP)
		RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP);
	pos += RSN_SELECTOR_LEN;

	WPA_PUT_LE16(pos, 1);
	pos += 2;
	RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_TPK_HANDSHAKE);
	pos += RSN_SELECTOR_LEN;

	rsn_capab = WPA_CAPABILITY_PEERKEY_ENABLED;
	rsn_capab |= RSN_NUM_REPLAY_COUNTERS_16 << 2;
	WPA_PUT_LE16(pos, rsn_capab);
	pos += 2;

	hdr->len = (pos - peer->rsnie_p) - 2;
	peer->rsnie_p_len = pos - peer->rsnie_p;
#endif

	/* temp fix: validation of RSNIE later */
	os_memcpy(peer->rsnie_p, peer->rsnie_i, peer->rsnie_i_len);
	peer->rsnie_p_len = peer->rsnie_i_len;

	wpa_hexdump(MSG_DEBUG, "TDLS: RSN IE for TPK handshake",
		    peer->rsnie_p, peer->rsnie_p_len);

	peer->lifetime = lifetime;

	wpa_tdls_generate_tpk(peer, sm->own_addr, sm->bssid);

skip_rsn_check:
	/* add the peer to the driver as a "setup in progress" peer */
	wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, NULL, 0, NULL, NULL, 0,
				NULL, 0);

	wpa_printf(MSG_DEBUG, "TDLS: Sending TDLS Setup Response / TPK M2");
	if (wpa_tdls_send_tpk_m2(sm, src_addr, dtoken, lnkid, peer) < 0) {
		wpa_tdls_disable_link(sm, peer->addr);
		goto error;
	}

	return 0;

error:
	wpa_tdls_send_error(sm, src_addr, WLAN_TDLS_SETUP_RESPONSE, dtoken,
			    status);
	return -1;
}


static void wpa_tdls_enable_link(struct wpa_sm *sm, struct wpa_tdls_peer *peer)
{
	peer->tpk_success = 1;
	eloop_cancel_timeout(wpa_tdls_tpk_timeout, sm, peer);
	if (wpa_tdls_get_privacy(sm)) {
		u32 lifetime = peer->lifetime;
		/*
		 * Start the initiator process a bit earlier to avoid race
		 * condition with the responder sending teardown request.
		 */
		if (lifetime > 3 && peer->initiator)
			lifetime -= 3;
		eloop_register_timeout(lifetime, 0, wpa_tdls_tpk_timeout,
				       sm, peer);
#ifdef CONFIG_TDLS_TESTING
	if (tdls_testing & TDLS_TESTING_NO_TPK_EXPIRATION) {
		wpa_printf(MSG_DEBUG, "TDLS: Testing - disable TPK "
			   "expiration");
		eloop_cancel_timeout(wpa_tdls_tpk_timeout, sm, peer);
	}
#endif /* CONFIG_TDLS_TESTING */
	}

	/* add supported rates, capabilities, and qos_info to the TDLS peer */
	wpa_sm_tdls_peer_addset(sm, peer->addr, 0, peer->capability,
				peer->supp_rates, peer->supp_rates_len,
				peer->ht_capabilities, peer->vht_capabilities,
				peer->qos_info, peer->ext_capab,
				peer->ext_capab_len);

	wpa_sm_tdls_oper(sm, TDLS_ENABLE_LINK, peer->addr);
}


static int wpa_tdls_process_tpk_m2(struct wpa_sm *sm, const u8 *src_addr,
				   const u8 *buf, size_t len)
{
	struct wpa_tdls_peer *peer;
	struct wpa_eapol_ie_parse kde;
	struct wpa_ie_data ie;
	int cipher;
	struct wpa_tdls_ftie *ftie;
	struct wpa_tdls_timeoutie *timeoutie;
	struct wpa_tdls_lnkid *lnkid;
	u32 lifetime;
	u8 dtoken;
	int ielen;
	u16 status;
	const u8 *pos;

	wpa_printf(MSG_DEBUG, "TDLS: Received TDLS Setup Response / TPK M2 "
		   "(Peer " MACSTR ")", MAC2STR(src_addr));
	for (peer = sm->tdls; peer; peer = peer->next) {
		if (os_memcmp(peer->addr, src_addr, ETH_ALEN) == 0)
			break;
	}
	if (peer == NULL) {
		wpa_printf(MSG_INFO, "TDLS: No matching peer found for "
			   "TPK M2: " MACSTR, MAC2STR(src_addr));
		return -1;
	}
	wpa_tdls_tpk_retry_timeout_cancel(sm, peer, WLAN_TDLS_SETUP_REQUEST);

	if (len < 3 + 2 + 1)
		return -1;
	pos = buf;
	pos += 1 /* pkt_type */ + 1 /* Category */ + 1 /* Action */;
	status = WPA_GET_LE16(pos);
	pos += 2 /* status code */;

	if (status != WLAN_STATUS_SUCCESS) {
		wpa_printf(MSG_INFO, "TDLS: Status code in TPK M2: %u",
			   status);
		if (sm->tdls_external_setup)
			wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, src_addr);
		return -1;
	}

	status = WLAN_STATUS_UNSPECIFIED_FAILURE;

	/* TODO: need to verify dialog token matches here or in kernel */
	dtoken = *pos++; /* dialog token */

	wpa_printf(MSG_DEBUG, "TDLS: Dialog Token in TPK M2 %d", dtoken);

	if (len < 3 + 2 + 1 + 2)
		return -1;

	/* capability information */
	peer->capability = WPA_GET_LE16(pos);
	pos += 2;

	ielen = len - (pos - buf); /* start of IE in buf */
	if (wpa_supplicant_parse_ies(pos, ielen, &kde) < 0) {
		wpa_printf(MSG_INFO, "TDLS: Failed to parse IEs in TPK M2");
		goto error;
	}

#ifdef CONFIG_TDLS_TESTING
	if (tdls_testing & TDLS_TESTING_DECLINE_RESP) {
		wpa_printf(MSG_DEBUG, "TDLS: Testing - decline response");
		status = WLAN_STATUS_REQUEST_DECLINED;
		goto error;
	}
#endif /* CONFIG_TDLS_TESTING */

	if (kde.lnkid == NULL || kde.lnkid_len < 3 * ETH_ALEN) {
		wpa_printf(MSG_INFO, "TDLS: No valid Link Identifier IE in "
			   "TPK M2");
		goto error;
	}
	wpa_hexdump(MSG_DEBUG, "TDLS: Link ID Received from TPK M2",
		    kde.lnkid, kde.lnkid_len);
	lnkid = (struct wpa_tdls_lnkid *) kde.lnkid;

	if (os_memcmp(sm->bssid, lnkid->bssid, ETH_ALEN) != 0) {
		wpa_printf(MSG_INFO, "TDLS: TPK M2 from different BSS");
		status = WLAN_STATUS_NOT_IN_SAME_BSS;
		goto error;
	}

	if (copy_supp_rates(&kde, peer) < 0)
		goto error;

	if (copy_peer_ht_capab(&kde, peer) < 0)
		goto error;

	if (copy_peer_vht_capab(&kde, peer) < 0)
		goto error;

	if (copy_peer_ext_capab(&kde, peer) < 0)
		goto error;

	peer->qos_info = kde.qosinfo;

	if (!wpa_tdls_get_privacy(sm)) {
		peer->rsnie_p_len = 0;
		peer->cipher = WPA_CIPHER_NONE;
		goto skip_rsn;
	}

	if (kde.ftie == NULL || kde.ftie_len < sizeof(*ftie) ||
	    kde.rsn_ie == NULL) {
		wpa_printf(MSG_INFO, "TDLS: No FTIE or RSN IE in TPK M2");
		status = WLAN_STATUS_INVALID_PARAMETERS;
		goto error;
	}
	wpa_hexdump(MSG_DEBUG, "TDLS: RSN IE Received from TPK M2",
		    kde.rsn_ie, kde.rsn_ie_len);

	/*
	 * FIX: bitwise comparison of RSN IE is not the correct way of
	 * validation this. It can be different, but certain fields must
	 * match. Since we list only a single pairwise cipher in TPK M1, the
	 * memcmp is likely to work in most cases, though.
	 */
	if (kde.rsn_ie_len != peer->rsnie_i_len ||
	    os_memcmp(peer->rsnie_i, kde.rsn_ie, peer->rsnie_i_len) != 0) {
		wpa_printf(MSG_INFO, "TDLS: RSN IE in TPK M2 does "
			   "not match with RSN IE used in TPK M1");
		wpa_hexdump(MSG_DEBUG, "TDLS: RSN IE Sent in TPK M1",
			    peer->rsnie_i, peer->rsnie_i_len);
		wpa_hexdump(MSG_DEBUG, "TDLS: RSN IE Received from TPK M2",
			    kde.rsn_ie, kde.rsn_ie_len);
		status = WLAN_STATUS_INVALID_RSNIE;
		goto error;
	}

	if (wpa_parse_wpa_ie_rsn(kde.rsn_ie, kde.rsn_ie_len, &ie) < 0) {
		wpa_printf(MSG_INFO, "TDLS: Failed to parse RSN IE in TPK M2");
		status = WLAN_STATUS_INVALID_RSNIE;
		goto error;
	}

	cipher = ie.pairwise_cipher;
	if (cipher == WPA_CIPHER_CCMP) {
		wpa_printf(MSG_DEBUG, "TDLS: Using CCMP for direct link");
		cipher = WPA_CIPHER_CCMP;
	} else {
		wpa_printf(MSG_INFO, "TDLS: No acceptable cipher in TPK M2");
		status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
		goto error;
	}

	wpa_hexdump(MSG_DEBUG, "TDLS: FTIE Received from TPK M2",
		    kde.ftie, sizeof(*ftie));
	ftie = (struct wpa_tdls_ftie *) kde.ftie;

	if (!os_memcmp(peer->inonce, ftie->Snonce, WPA_NONCE_LEN) == 0) {
		wpa_printf(MSG_INFO, "TDLS: FTIE SNonce in TPK M2 does "
			   "not match with FTIE SNonce used in TPK M1");
		/* Silently discard the frame */
		return -1;
	}

	/* Responder Nonce and RSN IE */
	os_memcpy(peer->rnonce, ftie->Anonce, WPA_NONCE_LEN);
	os_memcpy(peer->rsnie_p, kde.rsn_ie, kde.rsn_ie_len);
	peer->rsnie_p_len = kde.rsn_ie_len;
	peer->cipher = cipher;

	/* Lifetime */
	if (kde.key_lifetime == NULL) {
		wpa_printf(MSG_INFO, "TDLS: No Key Lifetime IE in TPK M2");
		status = WLAN_STATUS_UNACCEPTABLE_LIFETIME;
		goto error;
	}
	timeoutie = (struct wpa_tdls_timeoutie *) kde.key_lifetime;
	lifetime = WPA_GET_LE32(timeoutie->value);
	wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime %u seconds in TPK M2",
		   lifetime);
	if (lifetime != peer->lifetime) {
		wpa_printf(MSG_INFO, "TDLS: Unexpected TPK lifetime %u in "
			   "TPK M2 (expected %u)", lifetime, peer->lifetime);
		status = WLAN_STATUS_UNACCEPTABLE_LIFETIME;
		goto error;
	}

	wpa_tdls_generate_tpk(peer, sm->own_addr, sm->bssid);

	/* Process MIC check to see if TPK M2 is right */
	if (wpa_supplicant_verify_tdls_mic(2, peer, (u8 *) lnkid,
					   (u8 *) timeoutie, ftie) < 0) {
		/* Discard the frame */
		wpa_tdls_del_key(sm, peer);
		wpa_tdls_peer_free(sm, peer);
		if (sm->tdls_external_setup)
			wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, src_addr);
		return -1;
	}

	wpa_tdls_set_key(sm, peer);

skip_rsn:
	peer->dtoken = dtoken;

	wpa_printf(MSG_DEBUG, "TDLS: Sending TDLS Setup Confirm / "
		   "TPK Handshake Message 3");
	wpa_tdls_send_tpk_m3(sm, src_addr, dtoken, lnkid, peer);

	wpa_tdls_enable_link(sm, peer);

	return 0;

error:
	wpa_tdls_send_error(sm, src_addr, WLAN_TDLS_SETUP_CONFIRM, dtoken,
			    status);
	if (sm->tdls_external_setup)
		wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, src_addr);
	return -1;
}


static int wpa_tdls_process_tpk_m3(struct wpa_sm *sm, const u8 *src_addr,
				   const u8 *buf, size_t len)
{
	struct wpa_tdls_peer *peer;
	struct wpa_eapol_ie_parse kde;
	struct wpa_tdls_ftie *ftie;
	struct wpa_tdls_timeoutie *timeoutie;
	struct wpa_tdls_lnkid *lnkid;
	int ielen;
	u16 status;
	const u8 *pos;
	u32 lifetime;

	wpa_printf(MSG_DEBUG, "TDLS: Received TDLS Setup Confirm / TPK M3 "
		   "(Peer " MACSTR ")", MAC2STR(src_addr));
	for (peer = sm->tdls; peer; peer = peer->next) {
		if (os_memcmp(peer->addr, src_addr, ETH_ALEN) == 0)
			break;
	}
	if (peer == NULL) {
		wpa_printf(MSG_INFO, "TDLS: No matching peer found for "
			   "TPK M3: " MACSTR, MAC2STR(src_addr));
		return -1;
	}
	wpa_tdls_tpk_retry_timeout_cancel(sm, peer, WLAN_TDLS_SETUP_RESPONSE);

	if (len < 3 + 3)
		return -1;
	pos = buf;
	pos += 1 /* pkt_type */ + 1 /* Category */ + 1 /* Action */;

	status = WPA_GET_LE16(pos);

	if (status != 0) {
		wpa_printf(MSG_INFO, "TDLS: Status code in TPK M3: %u",
			   status);
		if (sm->tdls_external_setup)
			wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, src_addr);
		return -1;
	}
	pos += 2 /* status code */ + 1 /* dialog token */;

	ielen = len - (pos - buf); /* start of IE in buf */
	if (wpa_supplicant_parse_ies((const u8 *) pos, ielen, &kde) < 0) {
		wpa_printf(MSG_INFO, "TDLS: Failed to parse KDEs in TPK M3");
		return -1;
	}

	if (kde.lnkid == NULL || kde.lnkid_len < 3 * ETH_ALEN) {
		wpa_printf(MSG_INFO, "TDLS: No Link Identifier IE in TPK M3");
		return -1;
	}
	wpa_hexdump(MSG_DEBUG, "TDLS: Link ID Received from TPK M3",
		    (u8 *) kde.lnkid, kde.lnkid_len);
	lnkid = (struct wpa_tdls_lnkid *) kde.lnkid;

	if (os_memcmp(sm->bssid, lnkid->bssid, ETH_ALEN) != 0) {
		wpa_printf(MSG_INFO, "TDLS: TPK M3 from diff BSS");
		return -1;
	}

	if (!wpa_tdls_get_privacy(sm))
		goto skip_rsn;

	if (kde.ftie == NULL || kde.ftie_len < sizeof(*ftie)) {
		wpa_printf(MSG_INFO, "TDLS: No FTIE in TPK M3");
		return -1;
	}
	wpa_hexdump(MSG_DEBUG, "TDLS: FTIE Received from TPK M3",
		    kde.ftie, sizeof(*ftie));
	ftie = (struct wpa_tdls_ftie *) kde.ftie;

	if (kde.rsn_ie == NULL) {
		wpa_printf(MSG_INFO, "TDLS: No RSN IE in TPK M3");
		return -1;
	}
	wpa_hexdump(MSG_DEBUG, "TDLS: RSN IE Received from TPK M3",
		    kde.rsn_ie, kde.rsn_ie_len);
	if (kde.rsn_ie_len != peer->rsnie_p_len ||
	    os_memcmp(kde.rsn_ie, peer->rsnie_p, peer->rsnie_p_len) != 0) {
		wpa_printf(MSG_INFO, "TDLS: RSN IE in TPK M3 does not match "
			   "with the one sent in TPK M2");
		return -1;
	}

	if (!os_memcmp(peer->rnonce, ftie->Anonce, WPA_NONCE_LEN) == 0) {
		wpa_printf(MSG_INFO, "TDLS: FTIE ANonce in TPK M3 does "
			   "not match with FTIE ANonce used in TPK M2");
		return -1;
	}

	if (!os_memcmp(peer->inonce, ftie->Snonce, WPA_NONCE_LEN) == 0) {
		wpa_printf(MSG_INFO, "TDLS: FTIE SNonce in TPK M3 does not "
			   "match with FTIE SNonce used in TPK M1");
		return -1;
	}

	if (kde.key_lifetime == NULL) {
		wpa_printf(MSG_INFO, "TDLS: No Key Lifetime IE in TPK M3");
		return -1;
	}
	timeoutie = (struct wpa_tdls_timeoutie *) kde.key_lifetime;
	wpa_hexdump(MSG_DEBUG, "TDLS: Timeout IE Received from TPK M3",
		    (u8 *) timeoutie, sizeof(*timeoutie));
	lifetime = WPA_GET_LE32(timeoutie->value);
	wpa_printf(MSG_DEBUG, "TDLS: TPK lifetime %u seconds in TPK M3",
		   lifetime);
	if (lifetime != peer->lifetime) {
		wpa_printf(MSG_INFO, "TDLS: Unexpected TPK lifetime %u in "
			   "TPK M3 (expected %u)", lifetime, peer->lifetime);
		if (sm->tdls_external_setup)
			wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, src_addr);
		return -1;
	}

	if (wpa_supplicant_verify_tdls_mic(3, peer, (u8 *) lnkid,
					   (u8 *) timeoutie, ftie) < 0) {
		wpa_tdls_del_key(sm, peer);
		wpa_tdls_peer_free(sm, peer);
		return -1;
	}

	if (wpa_tdls_set_key(sm, peer) < 0)
		return -1;

skip_rsn:
	wpa_tdls_enable_link(sm, peer);

	return 0;
}


static u8 * wpa_add_tdls_timeoutie(u8 *pos, u8 *ie, size_t ie_len, u32 tsecs)
{
	struct wpa_tdls_timeoutie *lifetime = (struct wpa_tdls_timeoutie *) ie;

	os_memset(lifetime, 0, ie_len);
	lifetime->ie_type = WLAN_EID_TIMEOUT_INTERVAL;
	lifetime->ie_len = sizeof(struct wpa_tdls_timeoutie) - 2;
	lifetime->interval_type = WLAN_TIMEOUT_KEY_LIFETIME;
	WPA_PUT_LE32(lifetime->value, tsecs);
	os_memcpy(pos, ie, ie_len);
	return pos + ie_len;
}


/**
 * wpa_tdls_start - Initiate TDLS handshake (send TPK Handshake Message 1)
 * @sm: Pointer to WPA state machine data from wpa_sm_init()
 * @peer: MAC address of the peer STA
 * Returns: 0 on success, or -1 on failure
 *
 * Send TPK Handshake Message 1 info to driver to start TDLS
 * handshake with the peer.
 */
int wpa_tdls_start(struct wpa_sm *sm, const u8 *addr)
{
	struct wpa_tdls_peer *peer;
	int tdls_prohibited = sm->tdls_prohibited;

	if (sm->tdls_disabled || !sm->tdls_supported)
		return -1;

#ifdef CONFIG_TDLS_TESTING
	if ((tdls_testing & TDLS_TESTING_IGNORE_AP_PROHIBIT) &&
	    tdls_prohibited) {
		wpa_printf(MSG_DEBUG, "TDLS: Testing - ignore AP prohibition "
			   "on TDLS");
		tdls_prohibited = 0;
	}
#endif /* CONFIG_TDLS_TESTING */

	if (tdls_prohibited) {
		wpa_printf(MSG_DEBUG, "TDLS: TDLS is prohibited in this BSS - "
			   "reject request to start setup");
		return -1;
	}

	peer = wpa_tdls_add_peer(sm, addr, NULL);
	if (peer == NULL)
		return -1;

	peer->initiator = 1;

	/* add the peer to the driver as a "setup in progress" peer */
	wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, NULL, 0, NULL, NULL, 0,
				NULL, 0);

	if (wpa_tdls_send_tpk_m1(sm, peer) < 0) {
		wpa_tdls_disable_link(sm, peer->addr);
		return -1;
	}

	return 0;
}


void wpa_tdls_remove(struct wpa_sm *sm, const u8 *addr)
{
	struct wpa_tdls_peer *peer;

	if (sm->tdls_disabled || !sm->tdls_supported)
		return;

	for (peer = sm->tdls; peer; peer = peer->next) {
		if (os_memcmp(peer->addr, addr, ETH_ALEN) == 0)
			break;
	}

	if (peer == NULL || !peer->tpk_success)
		return;

	if (sm->tdls_external_setup) {
		/*
		 * Disable previous link to allow renegotiation to be completed
		 * on AP path.
		 */
		wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, peer->addr);
	}
}


/**
 * wpa_supplicant_rx_tdls - Receive TDLS data frame
 *
 * This function is called to receive TDLS (ethertype = 0x890d) data frames.
 */
static void wpa_supplicant_rx_tdls(void *ctx, const u8 *src_addr,
				   const u8 *buf, size_t len)
{
	struct wpa_sm *sm = ctx;
	struct wpa_tdls_frame *tf;

	wpa_hexdump(MSG_DEBUG, "TDLS: Received Data frame encapsulation",
		    buf, len);

	if (sm->tdls_disabled || !sm->tdls_supported) {
		wpa_printf(MSG_DEBUG, "TDLS: Discard message - TDLS disabled "
			   "or unsupported by driver");
		return;
	}

	if (os_memcmp(src_addr, sm->own_addr, ETH_ALEN) == 0) {
		wpa_printf(MSG_DEBUG, "TDLS: Discard copy of own message");
		return;
	}

	if (len < sizeof(*tf)) {
		wpa_printf(MSG_INFO, "TDLS: Drop too short frame");
		return;
	}

	/* Check to make sure its a valid encapsulated TDLS frame */
	tf = (struct wpa_tdls_frame *) buf;
	if (tf->payloadtype != 2 /* TDLS_RFTYPE */ ||
	    tf->category != WLAN_ACTION_TDLS) {
		wpa_printf(MSG_INFO, "TDLS: Invalid frame - payloadtype=%u "
			   "category=%u action=%u",
			   tf->payloadtype, tf->category, tf->action);
		return;
	}

	switch (tf->action) {
	case WLAN_TDLS_SETUP_REQUEST:
		wpa_tdls_process_tpk_m1(sm, src_addr, buf, len);
		break;
	case WLAN_TDLS_SETUP_RESPONSE:
		wpa_tdls_process_tpk_m2(sm, src_addr, buf, len);
		break;
	case WLAN_TDLS_SETUP_CONFIRM:
		wpa_tdls_process_tpk_m3(sm, src_addr, buf, len);
		break;
	case WLAN_TDLS_TEARDOWN:
		wpa_tdls_recv_teardown(sm, src_addr, buf, len);
		break;
	case WLAN_TDLS_DISCOVERY_REQUEST:
		wpa_tdls_process_discovery_request(sm, src_addr, buf, len);
		break;
	default:
		/* Kernel code will process remaining frames */
		wpa_printf(MSG_DEBUG, "TDLS: Ignore TDLS frame action code %u",
			   tf->action);
		break;
	}
}


/**
 * wpa_tdls_init - Initialize driver interface parameters for TDLS
 * @wpa_s: Pointer to wpa_supplicant data
 * Returns: 0 on success, -1 on failure
 *
 * This function is called to initialize driver interface parameters for TDLS.
 * wpa_drv_init() must have been called before this function to initialize the
 * driver interface.
 */
int wpa_tdls_init(struct wpa_sm *sm)
{
	if (sm == NULL)
		return -1;

	sm->l2_tdls = l2_packet_init(sm->bridge_ifname ? sm->bridge_ifname :
				     sm->ifname,
				     sm->own_addr,
				     ETH_P_80211_ENCAP, wpa_supplicant_rx_tdls,
				     sm, 0);
	if (sm->l2_tdls == NULL) {
		wpa_printf(MSG_ERROR, "TDLS: Failed to open l2_packet "
			   "connection");
		return -1;
	}

	/*
	 * Drivers that support TDLS but don't implement the get_capa callback
	 * are assumed to perform everything internally
	 */
	if (wpa_sm_tdls_get_capa(sm, &sm->tdls_supported,
				 &sm->tdls_external_setup) < 0) {
		sm->tdls_supported = 1;
		sm->tdls_external_setup = 0;
	}

	wpa_printf(MSG_DEBUG, "TDLS: TDLS operation%s supported by "
		   "driver", sm->tdls_supported ? "" : " not");
	wpa_printf(MSG_DEBUG, "TDLS: Driver uses %s link setup",
		   sm->tdls_external_setup ? "external" : "internal");

	return 0;
}


void wpa_tdls_teardown_peers(struct wpa_sm *sm)
{
	struct wpa_tdls_peer *peer;

	peer = sm->tdls;

	wpa_printf(MSG_DEBUG, "TDLS: Tear down peers");

	while (peer) {
		wpa_printf(MSG_DEBUG, "TDLS: Tear down peer " MACSTR,
			   MAC2STR(peer->addr));
		if (sm->tdls_external_setup)
			wpa_tdls_send_teardown(sm, peer->addr,
					       WLAN_REASON_DEAUTH_LEAVING);
		else
			wpa_sm_tdls_oper(sm, TDLS_TEARDOWN, peer->addr);

		peer = peer->next;
	}
}


static void wpa_tdls_remove_peers(struct wpa_sm *sm)
{
	struct wpa_tdls_peer *peer, *tmp;

	peer = sm->tdls;
	sm->tdls = NULL;

	while (peer) {
		int res;
		tmp = peer->next;
		res = wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, peer->addr);
		wpa_printf(MSG_DEBUG, "TDLS: Remove peer " MACSTR " (res=%d)",
			   MAC2STR(peer->addr), res);
		wpa_tdls_peer_free(sm, peer);
		os_free(peer);
		peer = tmp;
	}
}


/**
 * wpa_tdls_deinit - Deinitialize driver interface parameters for TDLS
 *
 * This function is called to recover driver interface parameters for TDLS
 * and frees resources allocated for it.
 */
void wpa_tdls_deinit(struct wpa_sm *sm)
{
	if (sm == NULL)
		return;

	if (sm->l2_tdls)
		l2_packet_deinit(sm->l2_tdls);
	sm->l2_tdls = NULL;

	wpa_tdls_remove_peers(sm);
}


void wpa_tdls_assoc(struct wpa_sm *sm)
{
	wpa_printf(MSG_DEBUG, "TDLS: Remove peers on association");
	wpa_tdls_remove_peers(sm);
}


void wpa_tdls_disassoc(struct wpa_sm *sm)
{
	wpa_printf(MSG_DEBUG, "TDLS: Remove peers on disassociation");
	wpa_tdls_remove_peers(sm);
}


static int wpa_tdls_prohibited(const u8 *ies, size_t len)
{
	struct wpa_eapol_ie_parse elems;

	if (ies == NULL)
		return 0;

	if (wpa_supplicant_parse_ies(ies, len, &elems) < 0)
		return 0;

	if (elems.ext_capab == NULL || elems.ext_capab_len < 2 + 5)
		return 0;

	 /* bit 38 - TDLS Prohibited */
	return !!(elems.ext_capab[2 + 4] & 0x40);
}


void wpa_tdls_ap_ies(struct wpa_sm *sm, const u8 *ies, size_t len)
{
	sm->tdls_prohibited = wpa_tdls_prohibited(ies, len);
	wpa_printf(MSG_DEBUG, "TDLS: TDLS is %s in the target BSS",
		   sm->tdls_prohibited ? "prohibited" : "allowed");
}


void wpa_tdls_assoc_resp_ies(struct wpa_sm *sm, const u8 *ies, size_t len)
{
	if (!sm->tdls_prohibited && wpa_tdls_prohibited(ies, len)) {
		wpa_printf(MSG_DEBUG, "TDLS: TDLS prohibited based on "
			   "(Re)Association Response IEs");
		sm->tdls_prohibited = 1;
	}
}


void wpa_tdls_enable(struct wpa_sm *sm, int enabled)
{
	wpa_printf(MSG_DEBUG, "TDLS: %s", enabled ? "enabled" : "disabled");
	sm->tdls_disabled = !enabled;
}


int wpa_tdls_is_external_setup(struct wpa_sm *sm)
{
	return sm->tdls_external_setup;
}
