예제 #1
0
VOID    ApcliWpaSendEapolStart(
	IN	PRTMP_ADAPTER	pAd,
	IN  PUCHAR          pBssid,
	IN  PMAC_TABLE_ENTRY pMacEntry,
	IN	PAPCLI_STRUCT pApCliEntry)
{
	IEEE8021X_FRAME		Packet;
	UCHAR               Header802_3[14];
	
	DBGPRINT(RT_DEBUG_TRACE, ("-----> ApCliWpaSendEapolStart\n"));

	NdisZeroMemory(Header802_3,sizeof(UCHAR)*14);

	MAKE_802_3_HEADER(Header802_3, pBssid, &pApCliEntry->CurrentAddress[0], EAPOL);
	
	// Zero message 2 body
	NdisZeroMemory(&Packet, sizeof(Packet));
	Packet.Version = EAPOL_VER;
	Packet.Type    = EAPOLStart;
	Packet.Length  = cpu2be16(0);
	
	// Copy frame to Tx ring
	RTMPToWirelessSta((PRTMP_ADAPTER)pAd, pMacEntry,
					 Header802_3, LENGTH_802_3, (PUCHAR)&Packet, 4, TRUE);

	DBGPRINT(RT_DEBUG_TRACE, ("<----- WpaSendEapolStart\n"));
}
예제 #2
0
/*
	========================================================================
	
	Routine Description:
		Send EAPoL-Start packet to AP.

	Arguments:
		pAd         - NIC Adapter pointer
		
	Return Value:
		None
		
	IRQL = DISPATCH_LEVEL
	
	Note:
		Actions after link up
		1. Change the correct parameters
		2. Send EAPOL - START
		
	========================================================================
*/
VOID    WpaSendEapolStart(
	IN	PRTMP_ADAPTER	pAd,
	IN  PUCHAR          pBssid)
{
	IEEE8021X_FRAME		Packet;
	UCHAR               Header802_3[14];
	
	DBGPRINT(RT_DEBUG_TRACE, ("-----> WpaSendEapolStart\n"));

	NdisZeroMemory(Header802_3,sizeof(UCHAR)*14);

	MAKE_802_3_HEADER(Header802_3, pBssid, &pAd->CurrentAddress[0], EAPOL);
	
	/* Zero message 2 body */
	NdisZeroMemory(&Packet, sizeof(Packet));
	Packet.Version = EAPOL_VER;
	Packet.Type    = EAPOLStart;
	Packet.Length  = cpu2be16(0);
	
	/* Copy frame to Tx ring */
	RTMPToWirelessSta((PRTMP_ADAPTER)pAd, &pAd->MacTab.Content[BSSID_WCID],
					 Header802_3, LENGTH_802_3, (PUCHAR)&Packet, 4, TRUE);

	DBGPRINT(RT_DEBUG_TRACE, ("<----- WpaSendEapolStart\n"));
}
/*
==========================================================================
	Description:

	IRQL = PASSIVE_LEVEL
==========================================================================
*/
NDIS_STATUS
TDLS_ChannelSwitchRspAction(
    IN	PRTMP_ADAPTER	pAd,
    IN	PRT_802_11_TDLS	pTDLS,
    IN	USHORT	ChSwitchTime,
    IN	USHORT	ChSwitchTimeOut,
    IN	UINT16	StatusCode,
    IN	UCHAR	FrameType)
{
    UCHAR	TDLS_ETHERTYPE[] = {0x89, 0x0d};
    UCHAR	Header802_3[14];
    PUCHAR	pOutBuffer = NULL;
    ULONG	FrameLen = 0;
    ULONG	TempLen;
    UCHAR	RemoteFrameType = PROTO_NAME_TDLS;
    NDIS_STATUS	NStatus = NDIS_STATUS_SUCCESS;

    DBGPRINT(RT_DEBUG_WARN, ("TDLS ===> TDLS_ChannelSwitchRspAction\n"));

    MAKE_802_3_HEADER(Header802_3, pTDLS->MacAddr, pAd->CurrentAddress, TDLS_ETHERTYPE);

    // Allocate buffer for transmitting message
    NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);

    if (NStatus	!= NDIS_STATUS_SUCCESS)
    {
        DBGPRINT(RT_DEBUG_ERROR,("ACT - TDLS_ChannelSwitchRspAction() allocate memory failed \n"));
        return NStatus;
    }

    MakeOutgoingFrame(pOutBuffer,			&TempLen,
                      1,				&RemoteFrameType,
                      END_OF_ARGS);

    FrameLen = FrameLen + TempLen;

    TDLS_BuildChannelSwitchResponse(pAd, pOutBuffer, &FrameLen, pTDLS, ChSwitchTime, ChSwitchTimeOut, StatusCode);

    RTMPToWirelessSta(pAd, &pAd->MacTab.Content[pTDLS->MacTabMatchWCID], Header802_3,
                      LENGTH_802_3, pOutBuffer, (UINT)FrameLen, FALSE, FrameType);

    hex_dump("TDLS send channel switch response pack", pOutBuffer, FrameLen);

    MlmeFreeMemory(pAd, pOutBuffer);

    DBGPRINT(RT_DEBUG_WARN, ("TDLS <=== TDLS_ChannelSwitchRspAction\n"));

    return NStatus;
}
예제 #4
0
VOID	WpaMicFailureReportFrame(
	IN  PRTMP_ADAPTER   pAd,
	IN MLME_QUEUE_ELEM *Elem)
{
	PUCHAR              pOutBuffer = NULL;
	UCHAR               Header802_3[14];
	ULONG               FrameLen = 0;
	EAPOL_PACKET        Packet;
	UCHAR               Mic[16];
    BOOLEAN             bUnicast;
        
	DBGPRINT(RT_DEBUG_TRACE, ("WpaMicFailureReportFrame ----->\n"));

    bUnicast = (Elem->Msg[0] == 1 ? TRUE:FALSE);
	pAd->Sequence = ((pAd->Sequence) + 1) & (MAX_SEQ_NUMBER);

	// init 802.3 header and Fill Packet
	MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);	

	NdisZeroMemory(&Packet, sizeof(Packet));
	Packet.ProVer	= EAPOL_VER;
	Packet.ProType	= EAPOLKey;
	
	Packet.KeyDesc.Type = WPA1_KEY_DESC;

    // Request field presented
    Packet.KeyDesc.KeyInfo.Request = 1;
    
	if(pAd->StaCfg.WepStatus  == Ndis802_11Encryption3Enabled)
	{
		Packet.KeyDesc.KeyInfo.KeyDescVer = 2;
	} 
	else	  // TKIP
	{
		Packet.KeyDesc.KeyInfo.KeyDescVer = 1;
	}

    Packet.KeyDesc.KeyInfo.KeyType = (bUnicast ? PAIRWISEKEY : GROUPKEY);

	// KeyMic field presented
	Packet.KeyDesc.KeyInfo.KeyMic  = 1;

    // Error field presented
	Packet.KeyDesc.KeyInfo.Error  = 1;
    
	// Update packet length after decide Key data payload
	SET_UINT16_TO_ARRARY(Packet.Body_Len, LEN_EAPOL_KEY_MSG)

	// Key Replay Count
	NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY);
    inc_byte_array(pAd->StaCfg.ReplayCounter, 8);

	// Convert to little-endian format.
	*((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));


	MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer);  // allocate memory
	if(pOutBuffer == NULL)
	{
		return;
	}
    
	// Prepare EAPOL frame for MIC calculation
	// Be careful, only EAPOL frame is counted for MIC calculation
	MakeOutgoingFrame(pOutBuffer,               &FrameLen,
		              CONV_ARRARY_TO_UINT16(Packet.Body_Len) + 4,   &Packet,
		              END_OF_ARGS);

	// Prepare and Fill MIC value
	NdisZeroMemory(Mic, sizeof(Mic));
	if(pAd->StaCfg.WepStatus  == Ndis802_11Encryption3Enabled)
	{	// AES
        UCHAR digest[20] = {0};
		HMAC_SHA1(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, digest, SHA1_DIGEST_SIZE);
		NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
	} 
	else
	{	// TKIP
		HMAC_MD5(pAd->StaCfg.PTK,  LEN_EAP_MICK, pOutBuffer, FrameLen, Mic, MD5_DIGEST_SIZE);
	}
	NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);

	// copy frame to Tx ring and send MIC failure report frame to authenticator
	RTMPToWirelessSta(pAd, &pAd->MacTab.Content[BSSID_WCID],
					  Header802_3, LENGTH_802_3, 
					  (PUCHAR)&Packet, 
					  CONV_ARRARY_TO_UINT16(Packet.Body_Len) + 4, FALSE);

	MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);

	DBGPRINT(RT_DEBUG_TRACE, ("WpaMicFailureReportFrame <-----\n"));
}
예제 #5
0
VOID	WpaMicFailureReportFrame(
	IN  PRTMP_ADAPTER   pAd,
	IN MLME_QUEUE_ELEM *Elem)
{
	PUCHAR              pOutBuffer = NULL;
	UCHAR               Header802_3[14];
	ULONG               FrameLen = 0;
	UCHAR				*mpool;
	PEAPOL_PACKET       pPacket;
	UCHAR               Mic[16];
    BOOLEAN             bUnicast;
        
	DBGPRINT(RT_DEBUG_TRACE, ("WpaMicFailureReportFrame ----->\n"));

    bUnicast = (Elem->Msg[0] == 1 ? TRUE:FALSE);
	pAd->Sequence = ((pAd->Sequence) + 1) & (MAX_SEQ_NUMBER);

	/* init 802.3 header and Fill Packet */
	MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);	

	/* Allocate memory for output */
	os_alloc_mem(NULL, (PUCHAR *)&mpool, TX_EAPOL_BUFFER);
	if (mpool == NULL)
    {
        DBGPRINT(RT_DEBUG_ERROR, ("!!!%s : no memory!!!\n", __FUNCTION__));
        return;
    }

	pPacket = (PEAPOL_PACKET)mpool;
	NdisZeroMemory(pPacket, TX_EAPOL_BUFFER);
	
	pPacket->ProVer	= EAPOL_VER;
	pPacket->ProType	= EAPOLKey;
	
	pPacket->KeyDesc.Type = WPA1_KEY_DESC;

    /* Request field presented */
    pPacket->KeyDesc.KeyInfo.Request = 1;
    
	if(pAd->StaCfg.WepStatus  == Ndis802_11Encryption3Enabled)
	{
		pPacket->KeyDesc.KeyInfo.KeyDescVer = 2;
	} 
	else	  /* TKIP */
	{
		pPacket->KeyDesc.KeyInfo.KeyDescVer = 1;
	}

    pPacket->KeyDesc.KeyInfo.KeyType = (bUnicast ? PAIRWISEKEY : GROUPKEY);

	/* KeyMic field presented */
	pPacket->KeyDesc.KeyInfo.KeyMic  = 1;

    /* Error field presented */
	pPacket->KeyDesc.KeyInfo.Error  = 1;
    
	/* Update packet length after decide Key data payload */
	SET_UINT16_TO_ARRARY(pPacket->Body_Len, MIN_LEN_OF_EAPOL_KEY_MSG)

	/* Key Replay Count */
	NdisMoveMemory(pPacket->KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY);
    inc_byte_array(pAd->StaCfg.ReplayCounter, 8);

	/* Convert to little-endian format. */
	*((USHORT *)&pPacket->KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&pPacket->KeyDesc.KeyInfo));


	MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer);  /* allocate memory */
	if(pOutBuffer == NULL)
	{
		os_free_mem(NULL, mpool);
		return;
	}
    
	/*
	   Prepare EAPOL frame for MIC calculation
	   Be careful, only EAPOL frame is counted for MIC calculation
	*/
	MakeOutgoingFrame(pOutBuffer,               &FrameLen,
		              CONV_ARRARY_TO_UINT16(pPacket->Body_Len) + 4,   pPacket,
		              END_OF_ARGS);

	/* Prepare and Fill MIC value */
	NdisZeroMemory(Mic, sizeof(Mic));
	if(pAd->StaCfg.WepStatus  == Ndis802_11Encryption3Enabled)
	{	/* AES */
        UCHAR digest[20] = {0};
		RT_HMAC_SHA1(pAd->StaCfg.PTK, LEN_PTK_KCK, pOutBuffer, FrameLen, digest, SHA1_DIGEST_SIZE);
		NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
	} 
	else
	{	/* TKIP */
		RT_HMAC_MD5(pAd->StaCfg.PTK, LEN_PTK_KCK, pOutBuffer, FrameLen, Mic, MD5_DIGEST_SIZE);
	}
	NdisMoveMemory(pPacket->KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);

	/* copy frame to Tx ring and send MIC failure report frame to authenticator */
	RTMPToWirelessSta(pAd, &pAd->MacTab.Content[BSSID_WCID],
					  Header802_3, LENGTH_802_3, 
					  (PUCHAR)pPacket, 
					  CONV_ARRARY_TO_UINT16(pPacket->Body_Len) + 4, FALSE);

	MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);

	os_free_mem(NULL, mpool);

	DBGPRINT(RT_DEBUG_TRACE, ("WpaMicFailureReportFrame <-----\n"));
}
예제 #6
0
/*
========================================================================
Routine Description:
	Send a traffic response frame.

Arguments:
	pAd				- WLAN control block pointer
	pTDLS			- the peer entry

Return Value:
	NDIS_STATUS_SUCCESS
	NDIS_STATUS_FAILURE

Note:
========================================================================
*/
static NDIS_STATUS TDLS_UAPSD_TrafficRspSend(
	IN	PRTMP_ADAPTER				pAd,
	IN	UCHAR						*pPeerMac,
	IN	UCHAR						PeerToken)
{
	MAC_TABLE_ENTRY	*pMacEntry; 
	RT_802_11_TDLS *pTDLS = NULL;
	UCHAR	TDLS_ETHERTYPE[] = {0x89, 0x0d};
	UCHAR	Header802_3[14];
	PUCHAR	pOutBuffer = NULL;
	ULONG	FrameLen = 0;
	ULONG	TempLen;
	INT32	LinkId;
	UCHAR	RemoteFrameType = PROTO_NAME_TDLS;
	NDIS_STATUS	NStatus = NDIS_STATUS_FAILURE;


	DBGPRINT(RT_DEBUG_TRACE, ("====> %s\n", __FUNCTION__));

	/* search TDLS entry */
	LinkId = TDLS_SearchLinkId(pAd, pPeerMac);
	if (TDLS_UAPSD_IS_LINK_INVALID(LinkId))
	{
		DBGPRINT(RT_DEBUG_TRACE,
				("%s: can not find the LinkId!\n", __FUNCTION__));
		TDLS_UAPSD_REBUILD_LINK(pAd, pPeerMac);
		goto LabelExit;
	}

	DBGPRINT(RT_DEBUG_TRACE, ("tdls uapsd> LinkId = %d\n", LinkId));

	pTDLS = TDLS_UAPSD_ENTRY_GET(pAd, LinkId);

	/* sanity check */
	if (TDLS_UAPSD_IS_CONN_NOT_BUILT(pTDLS))
	{
		DBGPRINT(RT_DEBUG_TRACE, ("tdls uapsd> link is not yet built "
				"so we can not send a traffic ind to the peer!!!"));
		goto LabelExit;
	}

	/* init */
	MAKE_802_3_HEADER(Header802_3, pTDLS->MacAddr,
						pAd->CurrentAddress, TDLS_ETHERTYPE);

	/* allocate buffer for transmitting message */
	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
	if (NStatus	!= NDIS_STATUS_SUCCESS)
		goto LabelExit;

	/* build the frame */
	MakeOutgoingFrame(pOutBuffer,		&TempLen,
						1,				&RemoteFrameType,
						END_OF_ARGS);
	FrameLen = FrameLen + TempLen;

	TDLS_UAPSD_TrafficRspBuild(pAd, pOutBuffer, &FrameLen, pTDLS, PeerToken);

	hex_dump("TDLS UAPSD Peer Traffic Response sending packet", pOutBuffer, FrameLen);

	/* need to set the power save mode of the peer to ACTIVE */
	/* we will recover its mode after EOSP frame is received */
	pMacEntry = MacTableLookup(pAd, pTDLS->MacAddr);
	if (pMacEntry == NULL)
		goto LabelExit;

	/* peer can not sleep for a while */
		RTMP_PS_VIRTUAL_WAKEUP_PEER(pMacEntry);

	/* send the frame to the peer without AP's help */
	TDLS_UAPSD_PKT_SEND_TO_PEER(pAd, Header802_3, pOutBuffer, FrameLen, pTDLS);
/*	hex_dump("TDLS traffic response send pack", pOutBuffer, FrameLen); */

	NStatus = NDIS_STATUS_SUCCESS;

	/* free resources */
LabelExit:
	if (pOutBuffer != NULL)
		MlmeFreeMemory(pAd, pOutBuffer);
	return NStatus;
}
예제 #7
0
/*
========================================================================
Routine Description:
	Build the traffic indication frame.

Arguments:
	pAd				- WLAN control block pointer
	pPeerMac		- the peer
	pFrameBuf		- frame
	pHeader802_3	- frame header

Return Value:
	Frame Length

Note:
========================================================================
*/
static ULONG TDLS_UAPSD_TrafficIndBuild(
	IN	PRTMP_ADAPTER				pAd,
	IN	UCHAR						*pPeerMac,
	OUT UCHAR						*pFrameBuf,
	OUT UCHAR						*pHeader802_3)
{
	RT_802_11_TDLS *pTDLS = NULL;
	UCHAR	TDLS_ETHERTYPE[] = {0x89, 0x0d};
	ULONG	FrameLen = 0;
	INT32	LinkId;
	BOOLEAN TimerCancelled;


	DBGPRINT(RT_DEBUG_TRACE, ("====> %s\n", __FUNCTION__));

	/* search TDLS entry */
	LinkId = TDLS_SearchLinkId(pAd, pPeerMac);
	if (TDLS_UAPSD_IS_LINK_INVALID(LinkId))
	{
		DBGPRINT(RT_DEBUG_TRACE,
				("%s: can not find the LinkId!\n", __FUNCTION__));
		TDLS_UAPSD_REBUILD_LINK(pAd, pPeerMac);
		goto LabelExit;
	}

	DBGPRINT(RT_DEBUG_TRACE, ("tdls uapsd> LinkId = %d\n", LinkId));

	pTDLS = TDLS_UAPSD_ENTRY_GET(pAd, LinkId);

	/* sanity check */
	if (TDLS_UAPSD_IS_CONN_NOT_BUILT(pTDLS))
	{
		DBGPRINT(RT_DEBUG_TRACE, ("tdls uapsd> link is not yet built "
				"so we can not send a traffic ind to the peer!!!"));
		goto LabelExit;
	}

	if (pTDLS->FlgIsWaitingUapsdTraRsp == TRUE)
	{
		DBGPRINT(RT_DEBUG_TRACE, ("tdls uapsd> traffic ind was sent before!\n"));
		goto LabelExit; /* has sent it */
	}

	pTDLS->FlgIsWaitingUapsdTraRsp = TRUE;

	/* init packet header */
	MAKE_802_3_HEADER(pHeader802_3, pTDLS->MacAddr,
						pAd->CurrentAddress, TDLS_ETHERTYPE);

	/* build the frame */
	TDLS_UAPSD_TrafficIndPayloadBuild(pAd, pFrameBuf, &FrameLen, pTDLS);

	hex_dump("TDLS UAPSD Peer Traffic Ind sending packet", pFrameBuf, FrameLen);
	/*
		11.2.1.14.1 Peer U-APSD Behavior at the PU buffer STA
		When no corresponding TDLS Peer Traffic Response frame has been
		received within dot11TDLSResponseTimeout after sending a TDLS Peer
		Traffic Indication frame, the STA shall tear down the direct link.

		The default value is 5 seconds.
	*/
	/* set traffic indication timer */
	RTMPCancelTimer(&pTDLS->Timer, &TimerCancelled);
	RTMPSetTimer(&pTDLS->Timer, TDLS_TIMEOUT);

	/* free resources */
LabelExit:
	return FrameLen;
}
예제 #8
0
/*
========================================================================
Routine Description:
	Simulate to send a TDLS Setup request to a peer.

Arguments:
	pAd				- WLAN control block pointer
	Argc			- the number of input parameters
	*pArgv			- input parameters

Return Value:
	None

Note:
	1. Command Format:
		iwpriv ra0 set tdls=51_[PEER MAC]

	11.21.4 TDLS direct-link establishment
	TDLS Setup Request frames, TDLS Setup Response frames, and TDLS Setup
	Confirm frames shall be transmitted through the AP and shall not be
	transmitted to a group address.
========================================================================
*/
static VOID TDLS_UAPSD_CmdSimSetupReqSend(
	IN	PRTMP_ADAPTER				pAd,
	IN	INT32						Argc,
	IN	CHAR						*pArgv)
{
	MLME_QUEUE_ELEM *pElem;
	RT_802_11_TDLS TDLS, *pTDLS = &TDLS;
	UCHAR	TDLS_ETHERTYPE[] = {0x89, 0x0d};
	UCHAR	Header802_3[14];
	PUCHAR	pOutBuffer = NULL;
	ULONG	FrameLen = 0;
	ULONG	TempLen;
	UCHAR	RemoteFrameType = PROTO_NAME_TDLS;
	NDIS_STATUS	NStatus = NDIS_STATUS_SUCCESS;
	UCHAR PeerMac[6];
	UINT32 IdTdls;


	/* get MAC address */
	TDLS_UAPSD_CmdUtilMacGet(&pArgv, PeerMac);

	/* allocate buffer for transmitting message */
	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
	if (NStatus	!= NDIS_STATUS_SUCCESS)	
		return;

	os_alloc_mem(NULL, (UCHAR **)&pElem, sizeof(MLME_QUEUE_ELEM));
	if (pElem == NULL)
	{
		MlmeFreeMemory(pAd, pOutBuffer);
		return;
	}

	/* init link entry */
	NdisZeroMemory(pTDLS, sizeof(RT_802_11_TDLS));
	pTDLS->TimeOut = 0;
	COPY_MAC_ADDR(pTDLS->MacAddr, PeerMac);
	pTDLS->Valid = 1;

	/* search a empty entry */
	for(IdTdls=0; IdTdls<MAX_NUM_OF_TDLS_ENTRY; IdTdls++)
	{
		if (!pAd->StaCfg.TdlsInfo.TDLSEntry[IdTdls].Valid)
		{
			NdisMoveMemory(&pAd->StaCfg.TdlsInfo.TDLSEntry[IdTdls],
							pTDLS, sizeof(RT_802_11_TDLS_UI));
			break;
		}
	}
	if (IdTdls == MAX_NUM_OF_TDLS_ENTRY)
	{
		MlmeFreeMemory(pAd, pOutBuffer);
		os_free_mem(NULL, pElem);
		return;
	}

	/* init request frame */
	MAKE_802_3_HEADER(Header802_3, pTDLS->MacAddr,
						pAd->CurrentAddress, TDLS_ETHERTYPE);

	MakeOutgoingFrame(pOutBuffer,		&TempLen,
						1,				&RemoteFrameType,
						END_OF_ARGS);

	FrameLen = FrameLen + TempLen;
	TDLS_BuildSetupRequest(pAd, pOutBuffer, &FrameLen,
							TDLS_UAPSD_ENTRY_GET(pAd, IdTdls));
	hex_dump("Request=", pOutBuffer, FrameLen);

	TDLS_UAPSD_PKT_SEND_THROUGH_AP(pAd, Header802_3, pOutBuffer, FrameLen);

	/* init response frame */
	FrameLen += LENGTH_802_11 + LENGTH_802_1_H;
	pElem->MsgLen = LENGTH_802_11 + LENGTH_802_1_H + FrameLen;

	/* copy payload type, category, action (3B) */
	memcpy(pElem->Msg + LENGTH_802_11 + LENGTH_802_1_H,
			pOutBuffer, 3);
	/* status code = 0x00 00 (2B) */
	*(USHORT *)(pElem->Msg + LENGTH_802_11 + LENGTH_802_1_H + 3) = 0x00;

	/* copy others */
	memcpy(pElem->Msg + LENGTH_802_11 + LENGTH_802_1_H + 3 + 2,
			pOutBuffer + 3, FrameLen - 3);

	/* handle response frame */
	TDLS_PeerSetupRspAction(pAd, pElem);

	/* free memory */
	MlmeFreeMemory(pAd, pOutBuffer);
	os_free_mem(NULL, pElem);
} /* End of TDLS_UAPSD_CmdSimSetupReqSend */
예제 #9
0
파일: ap_wpa.c 프로젝트: 23171580/ralink
VOID RTMPHandleSTAKey(
    IN PRTMP_ADAPTER    pAd, 
    IN PMAC_TABLE_ENTRY	pEntry,
    IN MLME_QUEUE_ELEM  *Elem) 
{
	extern UCHAR		OUI_WPA2_WEP40[];
	ULONG				FrameLen = 0;
	PUCHAR				pOutBuffer = NULL;
	UCHAR				Header802_3[14];
	UCHAR				*mpool;
	PEAPOL_PACKET		pOutPacket;
	PEAPOL_PACKET		pSTAKey;
	PHEADER_802_11		pHeader;
	UCHAR				Offset = 0;
	ULONG				MICMsgLen;
	UCHAR				DA[MAC_ADDR_LEN];
	UCHAR				Key_Data[512];
	UCHAR				key_length;
	UCHAR				mic[LEN_KEY_DESC_MIC];
	UCHAR				rcv_mic[LEN_KEY_DESC_MIC];
	UCHAR				digest[80];
	UCHAR				temp[64];
	PMAC_TABLE_ENTRY	pDaEntry;

	/*Benson add for big-endian 20081016--> */
	KEY_INFO			peerKeyInfo;
	/*Benson add 20081016 <-- */
	
	DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPHandleSTAKey\n"));

	if (!pEntry)
		return;
	
	if ((pEntry->WpaState != AS_PTKINITDONE))
	{
		DBGPRINT(RT_DEBUG_ERROR, ("Not expect calling STAKey hand shaking here"));
		return;
	}

    pHeader = (PHEADER_802_11) Elem->Msg;

	/* QoS control field (2B) is took off */
/*    if (pHeader->FC.SubType & 0x08) */
/*        Offset += 2; */
    
	pSTAKey = (PEAPOL_PACKET)&Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H + Offset];	
	/*Benson add for big-endian 20081016--> */
	NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo));
	NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pSTAKey->KeyDesc.KeyInfo, sizeof(KEY_INFO));
	*((USHORT *)&peerKeyInfo) = cpu2le16(*((USHORT *)&peerKeyInfo));
	/*Benson add 20081016 <-- */
	
    /* Check Replay Counter */
    if (!RTMPEqualMemory(pSTAKey->KeyDesc.ReplayCounter, pEntry->R_Counter, LEN_KEY_DESC_REPLAY))
    {
        DBGPRINT(RT_DEBUG_ERROR, ("Replay Counter Different in STAKey handshake!! \n"));
        DBGPRINT(RT_DEBUG_ERROR, ("Receive : %d %d %d %d  \n",
				pSTAKey->KeyDesc.ReplayCounter[0],
				pSTAKey->KeyDesc.ReplayCounter[1],
				pSTAKey->KeyDesc.ReplayCounter[2],
				pSTAKey->KeyDesc.ReplayCounter[3]));
        DBGPRINT(RT_DEBUG_ERROR, ("Current : %d %d %d %d  \n",
				pEntry->R_Counter[4],pEntry->R_Counter[5],
				pEntry->R_Counter[6],pEntry->R_Counter[7]));
        return;
    }

    /* Check MIC, if not valid, discard silently */
    NdisMoveMemory(DA, &pSTAKey->KeyDesc.KeyData[6], MAC_ADDR_LEN);

	if (peerKeyInfo.KeyMic && peerKeyInfo.Secure && peerKeyInfo.Request)/*Benson add for big-endian 20081016 --> */
	{
		pEntry->bDlsInit = TRUE;
		DBGPRINT(RT_DEBUG_TRACE, ("STAKey Initiator: %02x:%02x:%02x:%02x:%02x:%02x\n",
					PRINT_MAC(pEntry->Addr)));
	}


    MICMsgLen = pSTAKey->Body_Len[1] | ((pSTAKey->Body_Len[0]<<8) && 0xff00);
    MICMsgLen += LENGTH_EAPOL_H;
    if (MICMsgLen > (Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H))
    {
        DBGPRINT(RT_DEBUG_ERROR, ("Receive wrong format EAPOL packets \n"));
        return;        
    }

	/* This is proprietary DLS protocol, it will be adhered when spec. is finished. */
	NdisZeroMemory(temp, 64);
	NdisZeroMemory(pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK, sizeof(pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK));
	NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32);

	WpaDerivePTK(pAd, temp, temp, pAd->ApCfg.MBSSID[pEntry->apidx].wdev.bssid, temp,
				pEntry->Addr, pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK, LEN_PTK);
	DBGPRINT(RT_DEBUG_TRACE, ("PTK-%x %x %x %x %x %x %x %x \n",
			pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[0],
			pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[1],
			pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[2],
			pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[3],
			pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[4],
			pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[5],
			pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[6],
			pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[7]));


	/* Record the received MIC for check later */
	NdisMoveMemory(rcv_mic, pSTAKey->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
	NdisZeroMemory(pSTAKey->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
    if (pEntry->WepStatus == Ndis802_11TKIPEnable)
    {
        RT_HMAC_MD5(pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK, LEN_PTK_KCK, (PUCHAR)pSTAKey, MICMsgLen, mic, MD5_DIGEST_SIZE);
    }
    else
    {
        RT_HMAC_SHA1(pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK, LEN_PTK_KCK, (PUCHAR)pSTAKey,  MICMsgLen, digest, SHA1_DIGEST_SIZE);
        NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC);
    }

    if (!RTMPEqualMemory(rcv_mic, mic, LEN_KEY_DESC_MIC))
    {
        DBGPRINT(RT_DEBUG_ERROR, ("MIC Different in STAKey handshake!! \n"));
        return;
    }
    else
        DBGPRINT(RT_DEBUG_TRACE, ("MIC VALID in STAKey handshake!! \n"));

	/* Receive init STA's STAKey Message-2, and terminate the handshake */
	/*if (pEntry->bDlsInit && !pSTAKey->KeyDesc.KeyInfo.Request) */
	if (pEntry->bDlsInit && !peerKeyInfo.Request) /*Benson add for big-endian 20081016 --> */
	{
		pEntry->bDlsInit = FALSE;
		DBGPRINT(RT_DEBUG_TRACE, ("Receive init STA's STAKey Message-2, STAKey handshake finished \n"));
		return;
	}

	/* Receive init STA's STAKey Message-2, and terminate the handshake */
	if (RTMPEqualMemory(&pSTAKey->KeyDesc.KeyData[2], OUI_WPA2_WEP40, 3))
	{
		DBGPRINT(RT_DEBUG_WARN, ("Receive a STAKey message which not support currently, just drop it \n"));
		return;
	}
	
    do
    {
    	pDaEntry = MacTableLookup(pAd, DA);
    	if (!pDaEntry)
    		break;

    	if ((pDaEntry->WpaState != AS_PTKINITDONE))
	    {
	        DBGPRINT(RT_DEBUG_ERROR, ("Not expect calling STAKey hand shaking here \n"));
	        break;
	    }
    	
		MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer);  /* allocate memory */
        if(pOutBuffer == NULL)
            break;

        MAKE_802_3_HEADER(Header802_3, pDaEntry->Addr, pAd->ApCfg.MBSSID[pDaEntry->apidx].wdev.bssid, EAPOL);

        /* Increment replay counter by 1 */
        ADD_ONE_To_64BIT_VAR(pDaEntry->R_Counter);

		/* Allocate memory for output */
		os_alloc_mem(NULL, (PUCHAR *)&mpool, TX_EAPOL_BUFFER);
		if (mpool == NULL)
	    {
			MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
	        DBGPRINT(RT_DEBUG_ERROR, ("!!!%s : no memory!!!\n", __FUNCTION__));
	        return;
	    }

		pOutPacket = (PEAPOL_PACKET)mpool;
		NdisZeroMemory(pOutPacket, TX_EAPOL_BUFFER);

        /* 0. init Packet and Fill header */
        pOutPacket->ProVer = EAPOL_VER;
        pOutPacket->ProType = EAPOLKey;
        pOutPacket->Body_Len[1] = 0x5f;
        
        /* 1. Fill replay counter */
/*        NdisMoveMemory(pDaEntry->R_Counter, pAd->ApCfg.R_Counter, sizeof(pDaEntry->R_Counter)); */
        NdisMoveMemory(pOutPacket->KeyDesc.ReplayCounter, pDaEntry->R_Counter, LEN_KEY_DESC_REPLAY);
        
        /* 2. Fill key version, keyinfo, key len */
        pOutPacket->KeyDesc.KeyInfo.KeyDescVer= GROUP_KEY;
        pOutPacket->KeyDesc.KeyInfo.KeyType	= GROUPKEY;
        pOutPacket->KeyDesc.KeyInfo.Install	= 1;
        pOutPacket->KeyDesc.KeyInfo.KeyAck	= 1;
        pOutPacket->KeyDesc.KeyInfo.KeyMic	= 1;
        pOutPacket->KeyDesc.KeyInfo.Secure	= 1;
        pOutPacket->KeyDesc.KeyInfo.EKD_DL	= 1;
		DBGPRINT(RT_DEBUG_TRACE, ("STAKey handshake for peer STA %02x:%02x:%02x:%02x:%02x:%02x\n",
			PRINT_MAC(DA)));
        
        if ((pDaEntry->AuthMode == Ndis802_11AuthModeWPA) || (pDaEntry->AuthMode == Ndis802_11AuthModeWPAPSK))
        {
        	pOutPacket->KeyDesc.Type = WPA1_KEY_DESC;

        	DBGPRINT(RT_DEBUG_TRACE, ("pDaEntry->AuthMode == Ndis802_11AuthModeWPA/WPAPSK\n"));
        }
        else if ((pDaEntry->AuthMode == Ndis802_11AuthModeWPA2) || (pDaEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
        {
        	pOutPacket->KeyDesc.Type = WPA2_KEY_DESC;
        	pOutPacket->KeyDesc.KeyDataLen[1] = 0;

        	DBGPRINT(RT_DEBUG_TRACE, ("pDaEntry->AuthMode == Ndis802_11AuthModeWPA2/WPA2PSK\n"));
        }

        pOutPacket->KeyDesc.KeyLength[1] = LEN_TKIP_TK;
        pOutPacket->KeyDesc.KeyDataLen[1] = LEN_TKIP_TK;
        pOutPacket->KeyDesc.KeyInfo.KeyDescVer = KEY_DESC_TKIP;
        if (pDaEntry->WepStatus == Ndis802_11AESEnable)
        {
            pOutPacket->KeyDesc.KeyLength[1] = LEN_AES_TK;
            pOutPacket->KeyDesc.KeyDataLen[1] = LEN_AES_TK;
            pOutPacket->KeyDesc.KeyInfo.KeyDescVer = KEY_DESC_AES;
        }

		/* Key Data Encapsulation format, use Ralink OUI to distinguish proprietary and standard. */
    	Key_Data[0] = 0xDD;
		Key_Data[1] = 0x00;		/* Length (This field will be filled later) */
    	Key_Data[2] = 0x00;		/* OUI */
    	Key_Data[3] = 0x0C;		/* OUI */
    	Key_Data[4] = 0x43;		/* OUI */
    	Key_Data[5] = 0x02;		/* Data Type (STAKey Key Data Encryption) */

		/* STAKey Data Encapsulation format */
    	Key_Data[6] = 0x00;		/*Reserved */
		Key_Data[7] = 0x00;		/*Reserved */

		/* STAKey MAC address */
		NdisMoveMemory(&Key_Data[8], pEntry->Addr, MAC_ADDR_LEN);		/* initiator MAC address */

		/* STAKey (Handle the difference between TKIP and AES-CCMP) */
		if (pDaEntry->WepStatus == Ndis802_11AESEnable)
        {
        	Key_Data[1] = 0x1E;	/* 4+2+6+16(OUI+Reserved+STAKey_MAC_Addr+STAKey) */
        	NdisMoveMemory(&Key_Data[14], pEntry->PairwiseKey.Key, LEN_AES_TK);
		}
		else
		{
			Key_Data[1] = 0x2E;	/* 4+2+6+32(OUI+Reserved+STAKey_MAC_Addr+STAKey) */
			NdisMoveMemory(&Key_Data[14], pEntry->PairwiseKey.Key, LEN_TK);
			NdisMoveMemory(&Key_Data[14+LEN_TK], pEntry->PairwiseKey.TxMic, LEN_TKIP_MIC);
			NdisMoveMemory(&Key_Data[14+LEN_TK+LEN_TKIP_MIC], pEntry->PairwiseKey.RxMic, LEN_TKIP_MIC);
		}

		key_length = Key_Data[1];
		pOutPacket->Body_Len[1] = key_length + 0x5f;

		/* This is proprietary DLS protocol, it will be adhered when spec. is finished. */
		NdisZeroMemory(temp, 64);
		NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32);
		WpaDerivePTK(pAd, temp, temp, pAd->ApCfg.MBSSID[pEntry->apidx].wdev.bssid, temp, DA, pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK, LEN_PTK);
		
		DBGPRINT(RT_DEBUG_TRACE, ("PTK-0-%x %x %x %x %x %x %x %x \n",
				pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[0],
				pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[1],
				pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[2],
				pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[3],
				pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[4],
				pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[5],
				pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[6],
				pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK[7]));

       	NdisMoveMemory(pOutPacket->KeyDesc.KeyData, Key_Data, key_length);
		NdisZeroMemory(mic, sizeof(mic));

		*(USHORT *)(&pOutPacket->KeyDesc.KeyInfo) = cpu2le16(*(USHORT *)(&pOutPacket->KeyDesc.KeyInfo));

		MakeOutgoingFrame(pOutBuffer,			&FrameLen,
                        pOutPacket->Body_Len[1] + 4,	pOutPacket,
                        END_OF_ARGS);
	    
		/* Calculate MIC */
        if (pDaEntry->WepStatus == Ndis802_11AESEnable)
        {
            RT_HMAC_SHA1(pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK, LEN_PTK_KCK, pOutBuffer, FrameLen, digest, SHA1_DIGEST_SIZE);
            NdisMoveMemory(pOutPacket->KeyDesc.KeyMic, digest, LEN_KEY_DESC_MIC);
	    }
        else
        {
            RT_HMAC_MD5(pAd->ApCfg.MBSSID[pEntry->apidx].DlsPTK, LEN_PTK_KCK, pOutBuffer, FrameLen, mic, MD5_DIGEST_SIZE);
            NdisMoveMemory(pOutPacket->KeyDesc.KeyMic, mic, LEN_KEY_DESC_MIC);
        }

        RTMPToWirelessSta(pAd, pDaEntry, Header802_3, LENGTH_802_3, (PUCHAR)pOutPacket, pOutPacket->Body_Len[1] + 4, FALSE);

        MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
		os_free_mem(NULL, mpool);
    }while(FALSE);
    
    DBGPRINT(RT_DEBUG_TRACE, ("<== RTMPHandleSTAKey: FrameLen=%ld\n", FrameLen));
}
/*
==========================================================================
	Description:

	IRQL = PASSIVE_LEVEL
==========================================================================
*/
NDIS_STATUS
TDLS_ChannelSwitchReqAction(
    IN PRTMP_ADAPTER	pAd,
    IN PMLME_TDLS_CH_SWITCH_STRUCT	pChSwitchReq)
{
    UCHAR	TDLS_ETHERTYPE[] = {0x89, 0x0d};
    UCHAR	Header802_3[14];
    PUCHAR	pOutBuffer = NULL;
    ULONG	FrameLen = 0;
    ULONG	TempLen;
    UCHAR	RemoteFrameType = PROTO_NAME_TDLS;
    NDIS_STATUS	NStatus = NDIS_STATUS_SUCCESS;
    MAC_TABLE_ENTRY       *pEntry = NULL;
    UINT16	SwitchTime = pAd->StaCfg.TdlsInfo.TdlsSwitchTime; //micro seconds
    UINT16	SwitchTimeout = pAd->StaCfg.TdlsInfo.TdlsSwitchTimeout; // micro seconds
    int		LinkId = 0xff;
    PRT_802_11_TDLS	pTDLS = NULL;

    DBGPRINT(RT_DEBUG_WARN, ("====> TDLS_ChannelSwitchReqAction\n"));

    MAKE_802_3_HEADER(Header802_3, pChSwitchReq->PeerMacAddr, pAd->CurrentAddress, TDLS_ETHERTYPE);

    // Allocate buffer for transmitting message
    NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
    if (NStatus	!= NDIS_STATUS_SUCCESS)
        return NStatus;

    MakeOutgoingFrame(pOutBuffer,		&TempLen,
                      1,			&RemoteFrameType,
                      END_OF_ARGS);

    FrameLen = FrameLen + TempLen;

    TDLS_BuildChannelSwitchRequest(pAd, pOutBuffer, &FrameLen, pChSwitchReq->PeerMacAddr,SwitchTime,
                                   SwitchTimeout, pChSwitchReq->TargetChannel, pChSwitchReq->TargetChannelBW);

    pEntry = MacTableLookup(pAd, pChSwitchReq->PeerMacAddr);

    if (pEntry && IS_ENTRY_TDLS(pEntry))
    {
        pTDLS->ChannelSwitchCurrentState = TDLS_CHANNEL_SWITCH_WAIT_RSP;
        if (pChSwitchReq->TargetChannel != pAd->CommonCfg.Channel)
            RTMPToWirelessSta(pAd, pEntry, Header802_3, LENGTH_802_3, pOutBuffer, (UINT)FrameLen, FALSE, RTMP_TDLS_SPECIFIC_EDCA);
        else
            RTMPToWirelessSta(pAd, pEntry, Header802_3, LENGTH_802_3, pOutBuffer, (UINT)FrameLen, FALSE, RTMP_TDLS_SPECIFIC_HCCA);
        pAd->StaCfg.TdlsCurrentChannel = pChSwitchReq->TargetChannel;
        pAd->StaCfg.TdlsCurrentChannelBW = pChSwitchReq->TargetChannelBW;
    }
    else
    {
        DBGPRINT(RT_DEBUG_ERROR, ("Can't find TDLS entry on mac TABLE !!!!\n"));
    }

    hex_dump("TDLS switch channel request send pack", pOutBuffer, FrameLen);

    MlmeFreeMemory(pAd, pOutBuffer);

    DBGPRINT(RT_DEBUG_WARN, ("<==== TDLS_ChannelSwitchReqAction\n"));

    return NStatus;
}