/* ========================================================================== Description: IRQL = PASSIVE_LEVEL ========================================================================== */ VOID TDLS_BuildChannelSwitchResponse( IN PRTMP_ADAPTER pAd, OUT PUCHAR pFrameBuf, OUT PULONG pFrameLen, IN PRT_802_11_TDLS pTDLS, IN USHORT ChSwitchTime, IN USHORT ChSwitchTimeOut, IN UINT16 ReasonCode) { /* fill action code */ TDLS_InsertActField(pAd, (pFrameBuf + *pFrameLen), pFrameLen, CATEGORY_TDLS, TDLS_ACTION_CODE_CHANNEL_SWITCH_RESPONSE); /* fill reason code */ TDLS_InsertReasonCode(pAd, (pFrameBuf + *pFrameLen), pFrameLen, ReasonCode); /* fill link identifier */ if (pTDLS->bInitiator) TDLS_InsertLinkIdentifierIE(pAd, (pFrameBuf + *pFrameLen), pFrameLen, pTDLS->MacAddr, pAd->CurrentAddress); else TDLS_InsertLinkIdentifierIE(pAd, (pFrameBuf + *pFrameLen), pFrameLen, pAd->CurrentAddress, pTDLS->MacAddr); /* Channel Switch Timing */ TDLS_InsertChannelSwitchTimingIE(pAd, (pFrameBuf + *pFrameLen), pFrameLen, ChSwitchTime, ChSwitchTimeOut); }
/* ========================================================================== Description: IRQL = PASSIVE_LEVEL ========================================================================== */ VOID TDLS_BuildTeardown( IN PRTMP_ADAPTER pAd, OUT PUCHAR pFrameBuf, OUT PULONG pFrameLen, IN PRT_802_11_TDLS pTDLS, IN UINT16 ReasonCode) { /* fill action code */ TDLS_InsertActField(pAd, (pFrameBuf + *pFrameLen), pFrameLen, CATEGORY_TDLS, TDLS_ACTION_CODE_TEARDOWN); /* fill reason code */ TDLS_InsertReasonCode(pAd, (pFrameBuf + *pFrameLen), pFrameLen, ReasonCode); /* fill link identifier */ if (pTDLS->bInitiator) TDLS_InsertLinkIdentifierIE(pAd, (pFrameBuf + *pFrameLen), pFrameLen, pTDLS->MacAddr, pAd->CurrentAddress); else TDLS_InsertLinkIdentifierIE(pAd, (pFrameBuf + *pFrameLen), pFrameLen, pAd->CurrentAddress, pTDLS->MacAddr); // FTIE includes if RSNA Enabled if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)) && ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) || (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled))) { UCHAR FTIe[128]; FT_FTIE *ft = NULL; UCHAR content[256]; ULONG c_len = 0; ULONG tmp_len = 0; UCHAR seq = 4; UCHAR mic[16]; UCHAR LinkIdentifier[20]; UINT tmp_aes_len = 0; NdisZeroMemory(LinkIdentifier, 20); LinkIdentifier[0] = IE_TDLS_LINK_IDENTIFIER; LinkIdentifier[1] = 18; NdisMoveMemory(&LinkIdentifier[2], pAd->CommonCfg.Bssid, 6); if (pTDLS->bInitiator) { NdisMoveMemory(&LinkIdentifier[8], pTDLS->MacAddr, 6); NdisMoveMemory(&LinkIdentifier[14], pAd->CurrentAddress, 6); } else { NdisMoveMemory(&LinkIdentifier[8], pAd->CurrentAddress, 6); NdisMoveMemory(&LinkIdentifier[14], pTDLS->MacAddr, 6); } //NdisMoveMemory(&LinkIdentifier[8], pTDLS->MacAddr, 6); //NdisMoveMemory(&LinkIdentifier[14], pAd->CurrentAddress, 6); // FTIE (7.3.2.48) // The contents of FTIE in the TDLS Teardown frame shall be the same as that included // in the TPK Handshake Message3 with the exception of the MIC field. // Construct FTIE (IE + Length + MIC Control + MIC + ANonce + SNonce) // point to the element of IE NdisZeroMemory(FTIe, sizeof(FTIe)); FTIe[0] = IE_FT_FTIE; FTIe[1] = sizeof(FT_FTIE); ft = (PFT_FTIE)&FTIe[2]; NdisMoveMemory(ft->ANonce, pTDLS->ANonce, 32); NdisMoveMemory(ft->SNonce, pTDLS->SNonce, 32); //////////////////////////////////////////////////////////////////////// // The MIC field of FTIE shall be calculated on the concatenation, in the following order, of // 1. Link Identifier (20 bytes) // 2. Reason Code (2 bytes) // 3. Dialog token (1 byte) // 4. Transaction Sequence = 4 (1 byte) // 5. FTIE with the MIC field of FTIE set to zero (84 bytes) /* concatenate Link Identifier, Reason Code, Dialog token, Transaction Sequence */ MakeOutgoingFrame(content, &tmp_len, sizeof(LinkIdentifier), LinkIdentifier, 2, &ReasonCode, 1, &pTDLS->Token, 1, &seq, END_OF_ARGS); c_len += tmp_len; /* concatenate FTIE */ MakeOutgoingFrame(content + c_len, &tmp_len, FTIe[1] + 2, FTIe, END_OF_ARGS); c_len += tmp_len; /* Calculate MIC */ NdisZeroMemory(mic, sizeof(mic)); //AES_128_CMAC(pTDLS->TPK, content, c_len, mic); /* Compute AES-128-CMAC over the concatenation */ tmp_aes_len = AES_KEY128_LENGTH; AES_CMAC(content, c_len, pTDLS->TPK, 16, mic, &tmp_aes_len); /* Fill Mic to ft struct */ NdisMoveMemory(ft->MIC, mic, 16); //////////////////////////////////////////////////////////////////////// // Insert FT_IE to outgoing frame TDLS_InsertFTIE( pAd, (pFrameBuf + *pFrameLen), pFrameLen, FTIe[1], ft->MICCtr, ft->MIC, ft->ANonce, ft->SNonce); } }