assoc.c

来自「Ralink RT61 SoftAP Driver source code. 」· C语言 代码 · 共 796 行 · 第 1/3 页

C
796
字号
	    	{
		    	// Enqueue a EAPOL-start message with the pEntry
		        MlmeEnqueue(pAd, WPA_STATE_MACHINE, MACHINE_TYPE_EAPOLStart, 6, &Addr2);
		    	pEntry->PMKID_CacheIdx = CacheIdx;
		    	DBGPRINT(RT_DEBUG_ERROR, "ASSOC - 1.PMKID matched and start key cache algorithm\n");
	    	}
	    	else
	    	{
	    		pEntry->PMKID_CacheIdx = ENTRY_NOT_FOUND;
		    	DBGPRINT(RT_DEBUG_ERROR, "ASSOC - 1.Recv PMKID=%02x:%02x:%02x:%02x:%02x:%02x\n", *(RSN_IE+22),*(RSN_IE+23),*(RSN_IE+24),*(RSN_IE+25),*(RSN_IE+26),*(RSN_IE+27));
	    	}
#endif
	    }
	}
}

/*
    ==========================================================================
    Description:
        mlme reassoc req handling procedure
    Parameters:
        Elem - 
    Pre:
        -# SSID  (Adapter->PortCfg.ssid[])
        -# BSSID (AP address, Adapter->PortCfg.bssid)
        -# Supported rates (Adapter->PortCfg.supported_rates[])
        -# Supported rates length (Adapter->PortCfg.supported_rates_len)
        -# Tx power (Adapter->PortCfg.tx_power)
    ==========================================================================
 */
VOID PeerReassocReqAction(
    IN PRTMP_ADAPTER pAd, 
    IN MLME_QUEUE_ELEM *Elem) 
{
    UCHAR            ApAddr[MAC_ADDR_LEN], Addr1[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
    HEADER_802_11    ReassocRspHdr;
    UCHAR            RateIe = IE_SUPP_RATES;
    USHORT           CapabilityInfo, ListenInterval;
    USHORT           StatusCode = MLME_SUCCESS;
    USHORT           Aid = 1;
    ULONG            FrameLen = 0;
    PUCHAR           pOutBuffer = NULL;
    CHAR             Ssid[32];
    UCHAR            SsidLen;
    UCHAR            SupportedRatesLen;
    UCHAR            SupportedRates[MAX_LEN_OF_SUPPORTED_RATES];
    UCHAR            MaxSupportedRate = 0;
    INT              i;
    UCHAR            RSNIE_Len;
    UCHAR            RSN_IE[MAX_LEN_OF_RSNIE];
    MAC_TABLE_ENTRY  *pEntry;
    BOOLEAN          bWmmCapable;
    ULONG            RalinkIe;
	BOOLEAN			 bRejectSTA = FALSE;
	PFRAME_802_11    Fr = (PFRAME_802_11)Elem->Msg;

    // frame sanity check
    if (! PeerReassocReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr1, Addr2, &CapabilityInfo, &ListenInterval, ApAddr, &SsidLen, &Ssid[0], &SupportedRatesLen, &SupportedRates[0],RSN_IE, &RSNIE_Len, &bWmmCapable, &RalinkIe))
        return;

    pEntry = MacTableLookup(pAd, Addr2);
    if (!pEntry)
    	return;

	// clear the previous Pairwise key table
    if(pEntry->Aid != 0)
    {
    	NdisZeroMemory(&pEntry->PairwiseKey, sizeof(CIPHER_KEY)); 	
    	AsicRemovePairwiseKeyEntry(pAd, (UCHAR)pEntry->Aid);

		//notify 802.1x-deamon to discard the sta
		RTMPHandleNotify8021xDiscardSta(pAd, pEntry);
    	
    }	

    // for hidden SSID sake, SSID in AssociateRequest should be fully verified
    if ((SsidLen != pAd->PortCfg.MBSSID[pEntry->ApIdx].SsidLen) || (NdisEqualMemory(Ssid, pAd->PortCfg.MBSSID[pEntry->ApIdx].Ssid, SsidLen)==0))
        return;
    
    // ignore request from unwanted STA
    if (! ApCheckAccessControlList(pAd, Addr2, pEntry->ApIdx))
        return;
    
    DBGPRINT(RT_DEBUG_TRACE, "ASSOC - receive RE-ASSOC request from %02x:%02x:%02x:%02x:%02x:%02x\n",
        Addr2[0],Addr2[1],Addr2[2],Addr2[3],Addr2[4],Addr2[5]);
    
	// sta supported rates must support all basic rates
	for (i=0; i<pAd->PortCfg.SupportedRatesLen; i++) {
		int j;
		// the basic rate ap supported 
		if (pAd->PortCfg.SupportedRates[i] & 0x80) {
			bRejectSTA = TRUE;
			for (j=0; j<SupportedRatesLen; j++) {
				if ((SupportedRates[j] & 0x7f) == (pAd->PortCfg.SupportedRates[i] & 0x7f)) {
					bRejectSTA = FALSE;
					break;
				}
			}
			if (bRejectSTA == TRUE)
				break;
		}
	}

    // supported rates array may not be sorted. sort it and find the maximum rate
    for (i=0; i<SupportedRatesLen; i++)
    {
        if (MaxSupportedRate < (SupportedRates[i] & 0x7f))
            MaxSupportedRate = SupportedRates[i] & 0x7f;
    }            
    
	if (bRejectSTA)
		StatusCode = MLME_ASSOC_REJ_DATA_RATE;
	else 
    	// qualify this STA's auth_asoc status in the MAC table, decide StatusCode
    	StatusCode = BuildAssociation(pAd, Addr2, CapabilityInfo, MaxSupportedRate, RSN_IE, &RSNIE_Len, bWmmCapable, RalinkIe, &Aid);

    // reply Re-association Response
    pOutBuffer = kmalloc(MAX_LEN_OF_MLME_BUFFER, MEM_ALLOC_FLAG);
    if(pOutBuffer == NULL)
        return;

    DBGPRINT(RT_DEBUG_TRACE, "ASSOC - Send RE-ASSOC response (Status = %d)...\n", StatusCode);
    Aid |= 0xc000; // 2 most significant bits should be ON
    MgtMacHeaderInit(pAd, &ReassocRspHdr, SUBTYPE_REASSOC_RSP, 0, Addr2, pAd->PortCfg.MBSSID[pEntry->ApIdx].Bssid);

    if ((pAd->PortCfg.PhyMode == PHY_11BG_MIXED) || (pAd->PortCfg.PhyMode == PHY_11G))
    {
        UCHAR SupportedRatesLen = 4;
        UCHAR ExtendedRatesIe = IE_EXT_SUPP_RATES;
        UCHAR ExtendedRatesLen = pAd->PortCfg.SupportedRatesLen - SupportedRatesLen;
        
        MakeOutgoingFrame(pOutBuffer,					&FrameLen,
                          sizeof(HEADER_802_11),		&ReassocRspHdr,
                          2,								&pAd->PortCfg.MBSSID[pEntry->ApIdx].CapabilityInfo ,//use AP's cability 
                          2,								&StatusCode,
                          2,								&Aid,
                          1,								&RateIe,
                          1,								&SupportedRatesLen,
                          SupportedRatesLen,			pAd->PortCfg.SupportedRates,
                          1,								&ExtendedRatesIe,
                          1,								&ExtendedRatesLen,
                          ExtendedRatesLen,				&pAd->PortCfg.SupportedRates[SupportedRatesLen],
                          END_OF_ARGS);
    }
    else	// include A band
    {
        MakeOutgoingFrame(pOutBuffer,                       &FrameLen,
                          sizeof(HEADER_802_11),            &ReassocRspHdr,
                          2,                                &pAd->PortCfg.MBSSID[pEntry->ApIdx].CapabilityInfo ,//use AP's cability 
                          2,                                &StatusCode,
                          2,                                &Aid,
                          1,                                &RateIe,
                          1,                                &pAd->PortCfg.SupportedRatesLen, 
                          pAd->PortCfg.SupportedRatesLen,   pAd->PortCfg.SupportedRates,
                          END_OF_ARGS);
    }
    
#ifdef WMM_SUPPORT
    // add WMM IE here
    if (pAd->PortCfg.MBSSID[pEntry->ApIdx].bWmmCapable && CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE))
    {
        ULONG TmpLen;
        UCHAR WmeParmIe[26] = {IE_VENDOR_SPECIFIC, 24, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0, 0}; 
        WmeParmIe[8] = pAd->PortCfg.BssEdcaParm.EdcaUpdateCount & 0x0f;
        WmeParmIe[8] |= (pAd->PortCfg.bAPSDCapable) ? 0x80 : 0x00;
        for (i=QID_AC_BE; i<=QID_AC_VO; i++)
        {
            WmeParmIe[10+ (i*4)] = (i << 5)                                         +     // b5-6 is ACI
                                   ((UCHAR)pAd->PortCfg.BssEdcaParm.bACM[i] << 4)     +     // b4 is ACM
                                   (pAd->PortCfg.BssEdcaParm.Aifsn[i] & 0x0f);              // b0-3 is AIFSN
            WmeParmIe[11+ (i*4)] = (pAd->PortCfg.BssEdcaParm.Cwmax[i] << 4)           +     // b5-8 is CWMAX
                                   (pAd->PortCfg.BssEdcaParm.Cwmin[i] & 0x0f);              // b0-3 is CWMIN
            WmeParmIe[12+ (i*4)] = (UCHAR)(pAd->PortCfg.BssEdcaParm.Txop[i] & 0xff);        // low byte of TXOP
            WmeParmIe[13+ (i*4)] = (UCHAR)(pAd->PortCfg.BssEdcaParm.Txop[i] >> 8);          // high byte of TXOP
        }

        MakeOutgoingFrame(pOutBuffer+FrameLen,      &TmpLen,
                          26,                       WmeParmIe,
                          END_OF_ARGS);
        FrameLen += TmpLen;
    }
#endif /* WMM_SUPPORT */
    
#ifdef AGGREGATION_SUPPORT
    // add Ralink-specific IE here - Byte0.b0=1 for aggregation
    if (pAd->PortCfg.bAggregationCapable)
    {
	        ULONG TmpLen;
	        UCHAR RalinkSpecificIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x01, 0x00, 0x00, 0x00}; 
	        MakeOutgoingFrame(pOutBuffer+FrameLen,       &TmpLen,
	                          9,                         RalinkSpecificIe,
	                          END_OF_ARGS);
	        FrameLen += TmpLen;
    }
#endif /* AGGREGATION_SUPPORT */
    
    MiniportMMRequest(pAd, pOutBuffer, FrameLen);
    kfree(pOutBuffer);

	// enqueue a EAPOL_START message to trigger WPA state machine doing the authentication
    if (StatusCode == MLME_SUCCESS)
	{
#ifdef RTL865X_FAST_PATH
		rtl865x_extDev_addHost(pEntry->Addr, CONFIG_8139CP_VID, pAd->PortCfg.MBSSID[pEntry->ApIdx].mylinkid);
#endif

		pAd->RTSignal.Sig = SIG_REASSOCIATION;
		pAd->RTSignal.Sequence = Fr->Hdr.Sequence;
		NdisMoveMemory(pAd->RTSignal.MacAddr, pEntry->Addr, MAC_ADDR_LEN);
		NdisMoveMemory(pAd->RTSignal.CurrAPAddr, ApAddr, MAC_ADDR_LEN);
		SendSingalToDaemon(pAd, SIGUSR2);
		
	    if ((pEntry->AuthMode == Ndis802_11AuthModeWPAPSK) || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
	    {
	        // Enqueue a EAPOL-start message with the pEntry
	        MlmeEnqueue(pAd, WPA_STATE_MACHINE, MACHINE_TYPE_EAPOLStart, 6, &Addr2);
	    }
	    else if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) && (RSNIE_Len == 38))
	    {// Key cache
	    	INT	CacheIdx;
	    	
	    	if (((CacheIdx = RTMPSearchPMKIDCache(pAd, pEntry->ApIdx, pEntry->Addr)) != -1) && (RTMPEqualMemory((RSN_IE + 22), &pAd->PortCfg.MBSSID[pEntry->ApIdx].PMKIDCache.BSSIDInfo[CacheIdx].PMKID, LEN_PMKID)))
	    	{
		    	// Enqueue a EAPOL-start message with the pEntry
		        MlmeEnqueue(pAd, WPA_STATE_MACHINE, MACHINE_TYPE_EAPOLStart, 6, &Addr2);
		    	pEntry->PMKID_CacheIdx = CacheIdx;
		    	DBGPRINT(RT_DEBUG_ERROR, "ASSOC - 2.PMKID matched and start key cache algorithm\n");
	    	}
	    	else
	    	{
	    		pEntry->PMKID_CacheIdx = ENTRY_NOT_FOUND;
		    	DBGPRINT(RT_DEBUG_ERROR, "ASSOC - 2.Recv PMKID=%02x:%02x:%02x:%02x:%02x:%02x\n", *(RSN_IE+22),*(RSN_IE+23),*(RSN_IE+24),*(RSN_IE+25),*(RSN_IE+26),*(RSN_IE+27));
	    	}
	    }
	}
}

/*
    ==========================================================================
    Description:
        left part of IEEE 802.11/1999 p.374 
    Parameters:
        Elem - MLME message containing the received frame
    ==========================================================================
 */
VOID PeerDisassocReqAction(
    IN PRTMP_ADAPTER pAd, 
    IN MLME_QUEUE_ELEM *Elem) 
{
    UCHAR           Addr2[MAC_ADDR_LEN];
    USHORT          Reason;
    MAC_TABLE_ENTRY *pEntry;

    if (! PeerDisassocReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Reason)) 
        return;
    
    pEntry = MacTableLookup(pAd, Addr2);
    if (pEntry)
    {
		//notify 802.1x-deamon to discard the sta
		RTMPHandleNotify8021xDiscardSta(pAd, pEntry);
		
        ApLogEvent(pAd, Addr2, EVENT_DISASSOCIATED, pEntry->ApIdx);
        MacTableDeleteEntry(pAd, Addr2);
#ifdef RTL865X_FAST_PATH
		rtl865x_extDev_removeHost(pEntry->Addr, CONFIG_8139CP_VID); 

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?