/* ========================================================================== Description: IRQL = DISPATCH_LEVEL ========================================================================== */ VOID PeerAuthRspAtSeq4Action( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { UCHAR Addr2[MAC_ADDR_LEN]; USHORT Alg, Seq, Status; // CHAR ChlgText[CIPHER_TEXT_LEN]; CHAR *ChlgText = NULL; BOOLEAN TimerCancelled; /* allocate memory */ os_alloc_mem(NULL, (UCHAR **)&ChlgText, CIPHER_TEXT_LEN); if (ChlgText == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: ChlgText Allocate memory fail!!!\n", __FUNCTION__)); return; } if(PeerAuthSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Alg, &Seq, &Status, ChlgText)) { if(MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Addr2) && Seq == 4) { DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Receive AUTH_RSP seq#4 to me\n")); RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &TimerCancelled); if (Status != MLME_SUCCESS) { pAd->StaCfg.AuthFailReason = Status; COPY_MAC_ADDR(pAd->StaCfg.AuthFailSta, Addr2); RTMPSendWirelessEvent(pAd, IW_SHARED_WEP_FAIL, NULL, BSS0, 0); } pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status, 0); } } else { DBGPRINT(RT_DEBUG_TRACE, ("AUTH - PeerAuthRspAtSeq4Action() sanity check fail\n")); } if (ChlgText != NULL) os_free_mem(NULL, ChlgText); }
/* ========================================================================== Description: IRQL = DISPATCH_LEVEL ========================================================================== */ VOID MlmeDeauthReqAction(RTMP_ADAPTER *pAd, MLME_QUEUE_ELEM *Elem) { MLME_DEAUTH_REQ_STRUCT *pInfo; HEADER_802_11 DeauthHdr; PUCHAR pOutBuffer = NULL; NDIS_STATUS NStatus; ULONG FrameLen = 0; USHORT Status; pInfo = (MLME_DEAUTH_REQ_STRUCT *) Elem->Msg; NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */ if (NStatus != NDIS_STATUS_SUCCESS) { DBGPRINT(RT_DEBUG_TRACE, ("AUTH - MlmeDeauthReqAction() allocate memory fail\n")); pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; Status = MLME_FAIL_NO_RESOURCE; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DEAUTH_CONF, 2, &Status, 0); return; } DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Send DE-AUTH request (Reason=%d)...\n", pInfo->Reason)); MgtMacHeaderInit(pAd, &DeauthHdr, SUBTYPE_DEAUTH, 0, pInfo->Addr, pAd->CurrentAddress, pAd->MlmeAux.Bssid); MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof (HEADER_802_11), &DeauthHdr, 2, &pInfo->Reason, END_OF_ARGS); MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); pAd->StaCfg.DeauthReason = pInfo->Reason; COPY_MAC_ADDR(pAd->StaCfg.DeauthSta, pInfo->Addr); pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; Status = MLME_SUCCESS; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DEAUTH_CONF, 2, &Status, 0); /* send wireless event - for deauthentication */ RTMPSendWirelessEvent(pAd, IW_DEAUTH_EVENT_FLAG, NULL, BSS0, 0); }
/* ========================================================================== Description: MLME message sanity check Return: TRUE if all parameters are OK, FALSE otherwise ========================================================================== */ BOOLEAN MlmeAssocReqSanity( IN PRTMP_ADAPTER pAd, IN VOID *Msg, IN ULONG MsgLen, OUT PUCHAR pApAddr, OUT USHORT *pCapabilityInfo, OUT ULONG *pTimeout, OUT USHORT *pListenIntv) { MLME_ASSOC_REQ_STRUCT *pInfo; pInfo = (MLME_ASSOC_REQ_STRUCT *)Msg; *pTimeout = pInfo->Timeout; // timeout COPY_MAC_ADDR(pApAddr, pInfo->Addr); // AP address *pCapabilityInfo = pInfo->CapabilityInfo; // capability info *pListenIntv = pInfo->ListenIntv; return TRUE; }
static VOID P2pSendPassedAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { P2P_GO_FORM_STATE *pCurrState = &(pAd->P2pCfg.GoFormCurrentState); PP2P_CMD_STRUCT pP2pCmd = (PP2P_CMD_STRUCT)Elem->Msg; UCHAR index = pP2pCmd->Idx; DBGPRINT(RT_DEBUG_ERROR, ("%s::\n", __FUNCTION__)); DBGPRINT(RT_DEBUG_ERROR, ("Addr = %02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(pP2pCmd->Addr))); pAd->P2pTable.Client[index].P2pClientState = P2PSTATE_CONNECT_COMMAND; COPY_MAC_ADDR(pAd->P2pCfg.ConnectingMAC, pAd->P2pTable.Client[index].addr); pAd->P2pTable.Client[index].StateCount = 20; pAd->P2pTable.Client[index].bValid = TRUE; P2pConnect(pAd); *pCurrState = P2P_GO_FORM_IDLE; }
static VOID RRM_BcnReortQuery( IN PRTMP_ADAPTER pAd, IN INT ApIdx, IN PRRM_CONFIG pRrmCfg) { INT idx; for (idx = pRrmCfg->QuietCB.CurAid; idx < (pAd->MacTab.Size+1); idx++) { PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[idx]; if (IS_RRM_CAPABLE(pEntry) && IS_RRM_BEACON_MEASURE(pEntry)) { RRM_MLME_BCN_REQ_INFO BcnReq; NdisZeroMemory(&BcnReq, sizeof(RRM_MLME_BCN_REQ_INFO)); COPY_MAC_ADDR(BcnReq.Bssid, BROADCAST_ADDR); BcnReq.pSsid = (PUCHAR)pAd->ApCfg.MBSSID[ApIdx].Ssid; BcnReq.SsidLen = pAd->ApCfg.MBSSID[ApIdx].SsidLen; BcnReq.RegulatoryClass = pAd->CommonCfg.RegulatoryClass[0]; BcnReq.MeasureCh = pRrmCfg->QuietCB.MeasureCh; BcnReq.MeasureMode = RRM_BCN_REQ_MODE_BCNTAB; BcnReq.BcnReqCapFlag.field.ReportCondition = TRUE; BcnReq.MeasureDuration = cpu2le16(pRrmCfg->QuietCB.QuietDuration); if (BcnReq.MeasureCh == 255) BcnReq.BcnReqCapFlag.field.ChannelRep = TRUE; else BcnReq.BcnReqCapFlag.field.ChannelRep = FALSE; RRM_EnqueueBcnReq(pAd, pEntry->Aid, pEntry->apidx, &BcnReq); pRrmCfg->QuietCB.CurAid = idx + 1; break; } } if (idx == (pAd->MacTab.Size + 1)) { pRrmCfg->QuietCB.CurAid = 1; pRrmCfg->QuietCB.MeasureCh = (pRrmCfg->QuietCB.MeasureCh == 255) ? pAd->CommonCfg.Channel : 255; } }
VOID FT_OTA_AuthParmFill( IN PRTMP_ADAPTER pAd, IN OUT MLME_FT_OTA_AUTH_REQ_STRUCT *pFtOtaAuthReq, IN PUCHAR pAddr, IN USHORT Alg, IN PDOT11R_CMN_STRUC pCmmDot11rCfg) { COPY_MAC_ADDR(pFtOtaAuthReq->Addr, pAddr); pFtOtaAuthReq->Alg = Alg; pFtOtaAuthReq->Timeout = (AUTH_TIMEOUT * 2); /* MDIE */ pFtOtaAuthReq->MdIe.FtCapPlc.field.RsrReqCap = 0; pFtOtaAuthReq->MdIe.FtCapPlc.field.FtOverDs = 0; if (pCmmDot11rCfg->bSupportResource && pAd->MlmeAux.MdIeInfo.FtCapPlc.field.RsrReqCap) pFtOtaAuthReq->MdIe.FtCapPlc.field.RsrReqCap = 1; pFtOtaAuthReq->MdIe.FtCapPlc.field.FtOverDs = pAd->MlmeAux.MdIeInfo.FtCapPlc.field.FtOverDs; FT_SET_MDID(pFtOtaAuthReq->MdIe.MdId, pCmmDot11rCfg->MdIeInfo.MdId); }
static INT D_CheckConnectionReq( PRTMP_ADAPTER pAd, PUCHAR pSrcAddr, UINT8 FrameType, PCHAR Rssi, BOOLEAN *bAuthCheck) { PBND_STRG_CLI_TABLE table = P_BND_STRG_TABLE; BNDSTRG_MSG msg; /* Send to daemon */ NdisCopyMemory(msg.Rssi, Rssi, 3); msg.Action= CONNECTION_REQ; msg.Band = table->Band; msg.FrameType = FrameType; msg.bAuthCheck = bAuthCheck ? 1:0; COPY_MAC_ADDR(msg.Addr, pSrcAddr); D_BndStrgSendMsg(pAd, &msg); if (bAuthCheck) { PBND_STRG_CLI_TABLE table = P_BND_STRG_TABLE; PBND_STRG_CLI_ENTRY entry = NULL; if (table->Ops) entry = table->Ops->TableLookup(table, pSrcAddr); if (entry || table->Band == BAND_5G) *bAuthCheck = TRUE; #ifdef BND_STRG_QA else { *bAuthCheck = FALSE; BND_STRG_PRINTQAMSG(table, pSrcAddr, (RED("check 2.4G connection failed. client (%02x:%02x:%02x:%02x:%02x:%02x)" " is not allowed to connect 2.4G.\n"), PRINT_MAC(pSrcAddr))); } #endif } return TRUE; }
/* ========================================================================== Description: ========================================================================== */ VOID MlmeDeauthReqAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { MLME_DEAUTH_REQ_STRUCT *pInfo; HEADER_802_11 DeauthHdr; PUCHAR pOutBuffer = NULL; ULONG FrameLen = 0; USHORT Status; USHORT NStatus; pInfo = (MLME_DEAUTH_REQ_STRUCT *)Elem->Msg; // allocate and send out DeauthReq frame NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory if (NStatus != NDIS_STATUS_SUCCESS) { DBGPRINT(RT_DEBUG_TRACE, "AUTH - MlmeDeauthReqAction() allocate memory fail\n"); pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; Status = MLME_FAIL_NO_RESOURCE; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DEAUTH_CONF, 2, &Status); return; } DBGPRINT(RT_DEBUG_TRACE, "AUTH - Send DE-AUTH request (Reason=%d)...\n", pInfo->Reason); MgtMacHeaderInit(pAd, &DeauthHdr, SUBTYPE_DEAUTH, 0, pInfo->Addr, pAd->MlmeAux.Bssid); MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(HEADER_802_11), &DeauthHdr, 2, &pInfo->Reason, END_OF_ARGS); MiniportMMRequest(pAd, pOutBuffer, FrameLen); pAd->PortCfg.DeauthReason = pInfo->Reason; COPY_MAC_ADDR(pAd->PortCfg.DeauthSta, pInfo->Addr); pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; Status = MLME_SUCCESS; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DEAUTH_CONF, 2, &Status); }
/* ======================================================================== Routine Description: Generate random number by software. Arguments: pAd - pointer to our pAdapter context macAddr - pointer to local MAC address Return Value: Note: 802.1ii-2004 Annex H.5 ======================================================================== */ VOID GenRandom( IN PRTMP_ADAPTER pAd, IN UCHAR *macAddr, OUT UCHAR *random) { INT i, curr; UCHAR local[80], KeyCounter[32]; UCHAR result[80]; ULONG CurrentTime; UCHAR prefix[] = {'I', 'n', 'i', 't', ' ', 'C', 'o', 'u', 'n', 't', 'e', 'r'}; // Zero the related information NdisZeroMemory(result, 80); NdisZeroMemory(local, 80); NdisZeroMemory(KeyCounter, 32); for (i = 0; i < 32; i++) { // copy the local MAC address COPY_MAC_ADDR(local, macAddr); curr = MAC_ADDR_LEN; // concatenate the current time NdisGetSystemUpTime(&CurrentTime); NdisMoveMemory(&local[curr], &CurrentTime, sizeof(CurrentTime)); curr += sizeof(CurrentTime); // concatenate the last result NdisMoveMemory(&local[curr], result, 32); curr += 32; // concatenate a variable NdisMoveMemory(&local[curr], &i, 2); curr += 2; // calculate the result PRF(KeyCounter, 32, prefix,12, local, curr, result, 32); } NdisMoveMemory(random, result, 32); }
/* ========================================================================== Description: APCLI MLME Auth Req timeout state machine procedure ========================================================================== */ static VOID ApCliCtrlAuthReqTimeoutAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { MLME_AUTH_REQ_STRUCT AuthReq; PAPCLI_STRUCT pApCliEntry; USHORT ifIndex = (USHORT)(Elem->Priv); PULONG pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].CtrlCurrState; DBGPRINT(RT_DEBUG_TRACE, ("(%s) Auth Req Timeout.\n", __FUNCTION__)); if (ifIndex >= MAX_APCLI_NUM) return; pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex]; pApCliEntry->AuthReqCnt++; if (pApCliEntry->AuthReqCnt > 5) { *pCurrState = APCLI_CTRL_DISCONNECTED; NdisZeroMemory(pAd->ApCfg.ApCliTab[ifIndex].ApCliMlmeAux.Bssid, MAC_ADDR_LEN); NdisZeroMemory(pAd->ApCfg.ApCliTab[ifIndex].ApCliMlmeAux.Ssid, MAX_LEN_OF_SSID); pApCliEntry->AuthReqCnt = 0; return; } /* stay in same state. */ *pCurrState = APCLI_CTRL_AUTH; /* retry Authentication. */ DBGPRINT(RT_DEBUG_TRACE, ("(%s) Retry Auth Req.\n", __FUNCTION__)); COPY_MAC_ADDR(AuthReq.Addr, pAd->ApCfg.ApCliTab[ifIndex].ApCliMlmeAux.Bssid); AuthReq.Alg = pAd->ApCfg.ApCliTab[ifIndex].ApCliMlmeAux.Alg; /* Ndis802_11AuthModeOpen; */ AuthReq.Timeout = AUTH_TIMEOUT; MlmeEnqueue(pAd, APCLI_AUTH_STATE_MACHINE, APCLI_MT2_MLME_AUTH_REQ, sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq, ifIndex); return; }
BOOLEAN PeerAddBAReqActionSanity( IN PRTMP_ADAPTER pAd, IN VOID *pMsg, IN ULONG MsgLen, OUT PUCHAR pAddr2) { PFRAME_802_11 pFrame = (PFRAME_802_11)pMsg; PFRAME_ADDBA_REQ pAddFrame; pAddFrame = (PFRAME_ADDBA_REQ)(pMsg); if (MsgLen < (sizeof(FRAME_ADDBA_REQ))) { DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Request frame length size = %ld incorrect\n", MsgLen)); return FALSE; } /* we support immediate BA.*/ #ifdef UNALIGNMENT_SUPPORT { BA_PARM tmpBaParm; NdisMoveMemory((PUCHAR)(&tmpBaParm), (PUCHAR)(&pAddFrame->BaParm), sizeof(BA_PARM)); *(USHORT *)(&tmpBaParm) = cpu2le16(*(USHORT *)(&tmpBaParm)); NdisMoveMemory((PUCHAR)(&pAddFrame->BaParm), (PUCHAR)(&tmpBaParm), sizeof(BA_PARM)); } #else *(USHORT *)(&pAddFrame->BaParm) = cpu2le16(*(USHORT *)(&pAddFrame->BaParm)); #endif pAddFrame->TimeOutValue = cpu2le16(pAddFrame->TimeOutValue); pAddFrame->BaStartSeq.word = cpu2le16(pAddFrame->BaStartSeq.word); COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2); if (pAddFrame->BaParm.BAPolicy != IMMED_BA) { DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Request Ba Policy[%d] not support\n", pAddFrame->BaParm.BAPolicy)); DBGPRINT(RT_DEBUG_ERROR,("ADDBA Request. tid=%x, Bufsize=%x, AMSDUSupported=%x \n", pAddFrame->BaParm.TID, pAddFrame->BaParm.BufSize, pAddFrame->BaParm.AMSDUSupported)); return FALSE; } return TRUE; }
/*----------------------------------------------------------------------------*/ VOID kalP2PIndicateConnReq( IN P_GLUE_INFO_T prGlueInfo, IN PUINT_8 pucDevName, IN INT_32 u4NameLength, IN PARAM_MAC_ADDRESS rPeerAddr, IN UINT_8 ucDevType, /* 0: P2P Device / 1: GC / 2: GO */ IN INT_32 i4ConfigMethod, IN INT_32 i4ActiveConfigMethod ) { union iwreq_data evt; UINT_8 aucBuffer[IW_CUSTOM_MAX]; ASSERT(prGlueInfo); /* buffer peer information for later IOC_P2P_GET_REQ_DEVICE_INFO access */ prGlueInfo->prP2PInfo->u4ConnReqNameLength = u4NameLength > 32 ? 32 : u4NameLength; kalMemCopy(prGlueInfo->prP2PInfo->aucConnReqDevName, pucDevName, prGlueInfo->prP2PInfo->u4ConnReqNameLength); COPY_MAC_ADDR(prGlueInfo->prP2PInfo->rConnReqPeerAddr, rPeerAddr); prGlueInfo->prP2PInfo->ucConnReqDevType = ucDevType; prGlueInfo->prP2PInfo->i4ConnReqConfigMethod = i4ConfigMethod; prGlueInfo->prP2PInfo->i4ConnReqActiveConfigMethod = i4ActiveConfigMethod; // prepare event structure memset(&evt, 0, sizeof(evt)); snprintf(aucBuffer, IW_CUSTOM_MAX-1, "P2P_DVC_REQ"); evt.data.length = strlen(aucBuffer); /* indicate in IWEVCUSTOM event */ wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, IWEVCUSTOM, &evt, aucBuffer); return; } /* end of kalP2PIndicateConnReq() */
VOID PeerP2pPresReqAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { MLME_P2P_ACTION_STRUCT P2PActReq; MAC_TABLE_ENTRY *pEntry; PFRAME_P2P_ACTION pFrame; PP2P_NOA_DESC pNoADesc; pFrame = (PFRAME_P2P_ACTION)Elem->Msg; if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE) { DBGPRINT(RT_DEBUG_ERROR, ("PeerP2pPresReqAction. unknown Elem->Wcid = %d \n", Elem->Wcid )); } DBGPRINT(RT_DEBUG_ERROR, ("PeerP2pPresReqAction. Send back to Elem->Wcid = %d \n", Elem->Wcid )); pEntry = &pAd->MacTab.Content[Elem->Wcid]; pNoADesc = (PP2P_NOA_DESC)(&Elem->Msg[11 + sizeof(FRAME_P2P_ACTION)]); pEntry->P2pInfo.NoADesc[0].Count = pNoADesc->Count; pEntry->P2pInfo.NoADesc[0].Duration = *(PULONG)&pNoADesc->Duration[0]; pEntry->P2pInfo.NoADesc[0].Interval = *(PULONG)&pNoADesc->Interval[0]; pEntry->P2pInfo.NoADesc[0].StartTime = *(PULONG)&pNoADesc->StartTime[0]; DBGPRINT(RT_DEBUG_ERROR,(" pP2pEntry->NoADesc[0].Count = %d, \n", pEntry->P2pInfo.NoADesc[0].Count)); DBGPRINT(RT_DEBUG_ERROR,(" pP2pEntry->NoADesc[0].Duration = %d, \n", pEntry->P2pInfo.NoADesc[0].Duration)); DBGPRINT(RT_DEBUG_ERROR,(" pP2pEntry->NoADesc[0].Interval = %d, \n", pEntry->P2pInfo.NoADesc[0].Interval)); DBGPRINT(RT_DEBUG_ERROR,(" pP2pEntry->NoADesc[0].StartTime = %d, \n", pEntry->P2pInfo.NoADesc[0].StartTime)); DBGPRINT(RT_DEBUG_ERROR,("pFrame->Token = %d \n", pFrame->Token)); pEntry->P2pInfo.NoAToken = pFrame->Token; /* pP2pEntry->NoADesc[0].Duration = Elem->Msg; */ NdisZeroMemory(&P2PActReq, sizeof(P2PActReq)); COPY_MAC_ADDR(P2PActReq.Addr, pEntry->Addr); P2PActReq.TabIndex = Elem->Wcid; MlmeEnqueue(pAd, P2P_ACTION_STATE_MACHINE, MT2_MLME_P2P_PRESENCE_RSP, sizeof(MLME_P2P_ACTION_STRUCT), (PVOID)&P2PActReq, 0); MlmeHandler(pAd); }
BOOLEAN BndStrg_IsClientStay( PRTMP_ADAPTER pAd, PMAC_TABLE_ENTRY pEntry) { PBND_STRG_CLI_TABLE table = P_BND_STRG_TABLE; CHAR Rssi = RTMPAvgRssi(pAd, &pEntry->RssiSample); if (table->AlgCtrl.ConditionCheck & fBND_STRG_CND_5G_RSSI && table->Band == BAND_5G && (Rssi < (table->RssiLow - 10/*Test*/))) { BNDSTRG_MSG msg; msg.Action = CLI_DEL; COPY_MAC_ADDR(msg.Addr, pEntry->Addr); /* we don't know the index, daemon should look it up */ msg.TalbeIndex = BND_STRG_MAX_TABLE_SIZE; BND_STRG_DBGPRINT(RT_DEBUG_TRACE, (YLW("%s(): Kick client (%02x:%02x:%02x:%02x:%02x:%02x)") YLW(" due to low Rssi(%d).\n") , __FUNCTION__, PRINT_MAC(pEntry->Addr), Rssi)); RtmpOSWrielessEventSend( pAd->net_dev, RT_WLAN_EVENT_CUSTOM, OID_BNDSTRG_MSG, NULL, (UCHAR *) &msg, sizeof(BNDSTRG_MSG)); table->Ops->TableEntryDel(table, pEntry->Addr, BND_STRG_MAX_TABLE_SIZE); return FALSE; } return TRUE; }
/* ========================================================================== Description: IRQL = DISPATCH_LEVEL ========================================================================== */ VOID FT_OTA_PeerAuthAckAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { UCHAR Addr2[MAC_ADDR_LEN]; USHORT Alg, Seq, Status; BOOLEAN TimerCancelled; if (PeerAuthSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Alg, &Seq, &Status, NULL)) { if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Addr2) && (Alg == AUTH_MODE_FT) && (Seq == 4)) { MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("FT_OTA_AUTH - Receive FT_OTA_AUTH_ACK to me\n")); RTMPCancelTimer(&pAd->MlmeAux.FtOtaAuthTimer, &TimerCancelled); pAd->StaCfg.Dot11RCommInfo.FtRspSuccess = FT_OTA_RESPONSE; if (Status == MLME_SUCCESS) { /* Retrieve Reassociation Deadline */ /* Check RIC-Response */ } else { pAd->StaCfg.AuthFailReason = Status; COPY_MAC_ADDR(pAd->StaCfg.AuthFailSta, Addr2); } pAd->Mlme.FtOtaAuthMachine.CurrState = FT_OTA_AUTH_REQ_IDLE; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status, 0); } } else { MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_TRACE, ("FT_OTA_AUTH - FT_OTA_PeerAuthAckAction() sanity check fail\n")); } }
VOID FT_OTD_ActParmFill( IN PRTMP_ADAPTER pAd, IN OUT MLME_FT_REQ_STRUCT *FtReq, IN PUCHAR pAddr, IN NDIS_802_11_AUTHENTICATION_MODE AuthMode, IN PFT_MDIE_INFO FtMdieInfo, IN PFT_FTIE_INFO FtFtieInfo, IN UCHAR VarIeLen, IN PUCHAR pVarIe) { RTMPZeroMemory(FtReq, sizeof (MLME_FT_REQ_STRUCT)); COPY_MAC_ADDR(FtReq->TargetAddr, pAddr); if (AuthMode >= Ndis802_11AuthModeWPA) FtReq->HaveRSN = 1; FtReq->Timeout = FT_ACT_TIMEOUT; FT_SET_MDID(FtReq->MdIe.MdId, FtMdieInfo->MdId); FtReq->MdIe.FtCapPlc.word = FtMdieInfo->FtCapPlc.word; RTMPMoveMemory(&FtReq->SNonce[0], FtFtieInfo->SNonce, 32); RTMPMoveMemory(&FtReq->R0khId[0], FtFtieInfo->R0khId, FtFtieInfo->R0khIdLen); FtReq->R0khIdLen = FtFtieInfo->R0khIdLen; RTMPMoveMemory(&FtReq->VIe[0], pVarIe, VarIeLen); }
void Cls2errAction(struct rt_rtmp_adapter *pAd, u8 *pAddr) { struct rt_header_802_11 DeauthHdr; u8 *pOutBuffer = NULL; int NStatus; unsigned long FrameLen = 0; u16 Reason = REASON_CLS2ERR; NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); /*Get an unused nonpaged memory */ if (NStatus != NDIS_STATUS_SUCCESS) return; DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Class 2 error, Send DEAUTH frame...\n")); MgtMacHeaderInit(pAd, &DeauthHdr, SUBTYPE_DEAUTH, 0, pAddr, pAd->MlmeAux.Bssid); MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(struct rt_header_802_11), &DeauthHdr, 2, &Reason, END_OF_ARGS); MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); pAd->StaCfg.DeauthReason = Reason; COPY_MAC_ADDR(pAd->StaCfg.DeauthSta, pAddr); }
static VOID CheckParam(PNV_INFO pNvInfo) { extern BOOL_T CheckAuthCode(VOID); extern const UINT8 ZERO_MAC_ADDR[MAC_ADDR_LEN]; #define COPY_MAC_ADDR(Addr1, Addr2) NST_MOVE_MEM((Addr1), (Addr2), MAC_ADDR_LEN) #define MAC_ADDR_IS_GROUP(Addr) (((Addr[0]) & 0x01)) #define TX_GAIN_MAP_TBL_SIZE 0x28//0x26 UINT32 i = 0; // CHECK TX PWR for (i=0; i<MAX_TXPOWER_ARRAY_SIZE*MAX_CH_NUM; i++) if (*((PUINT8)&pNvInfo->MaxTxPwr[0] + i) > (TX_GAIN_MAP_TBL_SIZE-1)) { *((PUINT8)&pNvInfo->MaxTxPwr[0] + i) = *((PUINT8)&DefaultTxPwrIdxTbl[0] + i); } if (i != MAX_TXPOWER_ARRAY_SIZE*MAX_CH_NUM) { DBGPRINT(DEBUG_INFO, "Power of NvInfo is invalid [%d] = 0x%0x \n", i, *((PUINT8)&pNvInfo->MaxTxPwr[0] + i)); NST_MOVE_MEM(pNvInfo->MaxTxPwr, DefaultTxPwrIdxTbl, sizeof(pNvInfo->MaxTxPwr)); } // CHECK MAC ADDR if ((!MAC_ADDR_IS_GROUP(pNvInfo->MacAddr)) && (!NST_EQUAL_MEM(pNvInfo->MacAddr, ZERO_MAC_ADDR, MAC_ADDR_LEN))) COPY_MAC_ADDR(PermanentAddress, pNvInfo->MacAddr); #ifdef CHECK_AUTH_CODE if (CheckAuthCode() == NST_FALSE) { DBGPRINT(DEBUG_TRACE, "Check auth code failed, dead loop\n"); while (1) ; } #endif }
/* ========================================================================== Description: MLME message sanity check Return: TRUE if all parameters are OK, FALSE otherwise IRQL = DISPATCH_LEVEL ========================================================================== */ BOOLEAN PeerAssocRspSanity( IN PRTMP_ADAPTER pAd, IN VOID *pMsg, IN ULONG MsgLen, OUT PUCHAR pAddr2, OUT USHORT *pCapabilityInfo, OUT USHORT *pStatus, OUT USHORT *pAid, OUT UCHAR SupRate[], OUT UCHAR *pSupRateLen, OUT UCHAR ExtRate[], OUT UCHAR *pExtRateLen, OUT HT_CAPABILITY_IE *pHtCapability, OUT ADD_HT_INFO_IE *pAddHtInfo, /* AP might use this additional ht info IE */ OUT UCHAR *pHtCapabilityLen, OUT UCHAR *pAddHtInfoLen, OUT UCHAR *pNewExtChannelOffset, OUT PEDCA_PARM pEdcaParm, OUT EXT_CAP_INFO_ELEMENT *pExtCapInfo, OUT UCHAR *pCkipFlag) { CHAR IeType, *Ptr; PFRAME_802_11 pFrame = (PFRAME_802_11) pMsg; PEID_STRUCT pEid; ULONG Length = 0; *pNewExtChannelOffset = 0xff; *pHtCapabilityLen = 0; *pAddHtInfoLen = 0; COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2); Ptr = (PCHAR) pFrame->Octet; Length += LENGTH_802_11; NdisMoveMemory(pCapabilityInfo, &pFrame->Octet[0], 2); Length += 2; NdisMoveMemory(pStatus, &pFrame->Octet[2], 2); Length += 2; *pCkipFlag = 0; *pExtRateLen = 0; pEdcaParm->bValid = FALSE; if (*pStatus != MLME_SUCCESS) return TRUE; NdisMoveMemory(pAid, &pFrame->Octet[4], 2); Length += 2; /* Aid already swaped byte order in RTMPFrameEndianChange() for big endian platform */ *pAid = (*pAid) & 0x3fff; /* AID is low 14-bit */ /* -- get supported rates from payload and advance the pointer */ IeType = pFrame->Octet[6]; *pSupRateLen = pFrame->Octet[7]; if ((IeType != IE_SUPP_RATES) || (*pSupRateLen > MAX_LEN_OF_SUPPORTED_RATES)) { DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocRspSanity fail - wrong SupportedRates IE\n")); return FALSE; } else NdisMoveMemory(SupRate, &pFrame->Octet[8], *pSupRateLen); Length = Length + 2 + *pSupRateLen; /* many AP implement proprietary IEs in non-standard order, we'd better tolerate mis-ordered IEs to get best compatibility */ pEid = (PEID_STRUCT) & pFrame->Octet[8 + (*pSupRateLen)]; /* get variable fields from payload and advance the pointer */ while ((Length + 2 + pEid->Len) <= MsgLen) { switch (pEid->Eid) { case IE_EXT_SUPP_RATES: if (pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES) { NdisMoveMemory(ExtRate, pEid->Octet, pEid->Len); *pExtRateLen = pEid->Len; } break; case IE_HT_CAP: case IE_HT_CAP2: if (pEid->Len >= SIZE_HT_CAP_IE) { /* Note: allow extension.!! */ NdisMoveMemory(pHtCapability, pEid->Octet, SIZE_HT_CAP_IE); *(USHORT *) (&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *) (&pHtCapability->HtCapInfo)); *(USHORT *) (&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *) (&pHtCapability->ExtHtCapInfo)); *pHtCapabilityLen = SIZE_HT_CAP_IE; } else { DBGPRINT(RT_DEBUG_WARN, ("PeerAssocRspSanity - wrong IE_HT_CAP. \n")); } break; #ifdef DOT11_N_SUPPORT case IE_ADD_HT: case IE_ADD_HT2: if (pEid->Len >= sizeof (ADD_HT_INFO_IE)) { /* This IE allows extension, but we can ignore extra bytes beyond our knowledge , so only copy first sizeof(ADD_HT_INFO_IE) */ NdisMoveMemory(pAddHtInfo, pEid->Octet, sizeof (ADD_HT_INFO_IE)); *(USHORT *) (&pAddHtInfo->AddHtInfo2) = cpu2le16(*(USHORT *) (&pAddHtInfo->AddHtInfo2)); *(USHORT *) (&pAddHtInfo->AddHtInfo3) = cpu2le16(*(USHORT *) (&pAddHtInfo->AddHtInfo3)); *pAddHtInfoLen = SIZE_ADD_HT_INFO_IE; } else { DBGPRINT(RT_DEBUG_WARN, ("PeerAssocRspSanity - wrong IE_ADD_HT. \n")); } break; case IE_SECONDARY_CH_OFFSET: if (pEid->Len == 1) { *pNewExtChannelOffset = pEid->Octet[0]; } else { DBGPRINT(RT_DEBUG_WARN, ("PeerAssocRspSanity - wrong IE_SECONDARY_CH_OFFSET. \n")); } #endif /* DOT11_N_SUPPORT */ break; case IE_VENDOR_SPECIFIC: /* handle WME PARAMTER ELEMENT */ if (NdisEqualMemory(pEid->Octet, WME_PARM_ELEM, 6) && (pEid->Len == 24)) { PUCHAR ptr; int i; /* parsing EDCA parameters */ pEdcaParm->bValid = TRUE; pEdcaParm->bQAck = FALSE; /* pEid->Octet[0] & 0x10; */ pEdcaParm->bQueueRequest = FALSE; /* pEid->Octet[0] & 0x20; */ pEdcaParm->bTxopRequest = FALSE; /* pEid->Octet[0] & 0x40; */ pEdcaParm->EdcaUpdateCount = pEid->Octet[6] & 0x0f; pEdcaParm->bAPSDCapable = (pEid->Octet[6] & 0x80) ? 1 : 0; ptr = (PUCHAR) & pEid->Octet[8]; for (i = 0; i < 4; i++) { UCHAR aci = (*ptr & 0x60) >> 5; /* b5~6 is AC INDEX */ pEdcaParm->bACM[aci] = (((*ptr) & 0x10) == 0x10); /* b5 is ACM */ pEdcaParm->Aifsn[aci] = (*ptr) & 0x0f; /* b0~3 is AIFSN */ pEdcaParm->Cwmin[aci] = *(ptr + 1) & 0x0f; /* b0~4 is Cwmin */ pEdcaParm->Cwmax[aci] = *(ptr + 1) >> 4; /* b5~8 is Cwmax */ pEdcaParm->Txop[aci] = *(ptr + 2) + 256 * (*(ptr + 3)); /* in unit of 32-us */ ptr += 4; /* point to next AC */ } } break; case IE_EXT_CAPABILITY: if (pEid->Len >= sizeof (EXT_CAP_INFO_ELEMENT)) { NdisMoveMemory(pExtCapInfo, &pEid->Octet[0], sizeof (EXT_CAP_INFO_ELEMENT)); DBGPRINT(RT_DEBUG_WARN, ("PeerAssocReqSanity - IE_EXT_CAPABILITY!\n")); } break; default: DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocRspSanity - ignore unrecognized EID = %d\n", pEid->Eid)); break; } Length = Length + 2 + pEid->Len; pEid = (PEID_STRUCT) ((UCHAR *) pEid + 2 + pEid->Len); }
/* ========================================================================== Description: Add and new entry into MAC table ========================================================================== */ BOOLEAN MulticastFilterTableInsertEntry( IN PRTMP_ADAPTER pAd, IN PUCHAR pGrpId, IN PUCHAR pMemberAddr, IN PNET_DEV dev, IN MulticastFilterEntryType type) { UCHAR HashIdx; int i; MULTICAST_FILTER_TABLE_ENTRY *pEntry = NULL, *pCurrEntry, *pPrevEntry; PMEMBER_ENTRY pMemberEntry; PMULTICAST_FILTER_TABLE pMulticastFilterTable = pAd->pMulticastFilterTable; if (pMulticastFilterTable == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s Multicase filter table is not ready.\n", __FUNCTION__)); return FALSE; } /* if FULL, return */ if (pMulticastFilterTable->Size >= MAX_LEN_OF_MULTICAST_FILTER_TABLE) { DBGPRINT(RT_DEBUG_ERROR, ("%s Multicase filter table full. max-entries = %d\n", __FUNCTION__, MAX_LEN_OF_MULTICAST_FILTER_TABLE)); return FALSE; } /* check the rule is in table already or not. */ if ((pEntry = MulticastFilterTableLookup(pMulticastFilterTable, pGrpId, dev))) { /* doesn't indicate member mac address. */ if(pMemberAddr == NULL) { return FALSE; } pMemberEntry = (PMEMBER_ENTRY)pEntry->MemberList.pHead; while (pMemberEntry) { if (MAC_ADDR_EQUAL(pMemberAddr, pMemberEntry->Addr)) { DBGPRINT(RT_DEBUG_ERROR, ("%s: already in Members list.\n", __FUNCTION__)); return FALSE; } pMemberEntry = pMemberEntry->pNext; } } RTMP_SEM_LOCK(&pMulticastFilterTable->MulticastFilterTabLock); do { ULONG Now; /* the multicast entry already exist but doesn't include the member yet. */ if (pEntry != NULL && pMemberAddr != NULL) { InsertIgmpMember(pMulticastFilterTable, &pEntry->MemberList, pMemberAddr); break; } /* allocate one MAC entry */ for (i = 0; i < MAX_LEN_OF_MULTICAST_FILTER_TABLE; i++) { /* pick up the first available vacancy */ pEntry = &pMulticastFilterTable->Content[i]; NdisGetSystemUpTime(&Now); if ((pEntry->Valid == TRUE) && (pEntry->type == MCAT_FILTER_DYNAMIC) && ((Now - pEntry->lastTime) > IGMPMAC_TB_ENTRY_AGEOUT_TIME)) { PMULTICAST_FILTER_TABLE_ENTRY pHashEntry; HashIdx = MULTICAST_ADDR_HASH_INDEX(pEntry->Addr); pHashEntry = pMulticastFilterTable->Hash[HashIdx]; if ((pEntry->net_dev == pHashEntry->net_dev) && MAC_ADDR_EQUAL(pEntry->Addr, pHashEntry->Addr)) { pMulticastFilterTable->Hash[HashIdx] = pHashEntry->pNext; pMulticastFilterTable->Size --; DBGPRINT(RT_DEBUG_TRACE, ("MCastFilterTableDeleteEntry 1 - Total= %d\n", pMulticastFilterTable->Size)); } else { while (pHashEntry->pNext) { pPrevEntry = pHashEntry; pHashEntry = pHashEntry->pNext; if ((pEntry->net_dev == pHashEntry->net_dev) && MAC_ADDR_EQUAL(pEntry->Addr, pHashEntry->Addr)) { pPrevEntry->pNext = pHashEntry->pNext; pMulticastFilterTable->Size --; DBGPRINT(RT_DEBUG_TRACE, ("MCastFilterTableDeleteEntry 2 - Total= %d\n", pMulticastFilterTable->Size)); break; } } } pEntry->Valid = FALSE; DeleteIgmpMemberList(pMulticastFilterTable, &pEntry->MemberList); } if (pEntry->Valid == FALSE) { NdisZeroMemory(pEntry, sizeof(MULTICAST_FILTER_TABLE_ENTRY)); pEntry->Valid = TRUE; COPY_MAC_ADDR(pEntry->Addr, pGrpId); pEntry->net_dev = dev; NdisGetSystemUpTime(&Now); pEntry->lastTime = Now; pEntry->type = type; initList(&pEntry->MemberList); if (pMemberAddr != NULL) InsertIgmpMember(pMulticastFilterTable, &pEntry->MemberList, pMemberAddr); pMulticastFilterTable->Size ++; DBGPRINT(RT_DEBUG_TRACE, ("MulticastFilterTableInsertEntry -IF(%s) allocate entry #%d, Total= %d\n", RTMP_OS_NETDEV_GET_DEVNAME(dev), i, pMulticastFilterTable->Size)); break; } } /* add this MAC entry into HASH table */ if (pEntry) { HashIdx = MULTICAST_ADDR_HASH_INDEX(pGrpId); if (pMulticastFilterTable->Hash[HashIdx] == NULL) { pMulticastFilterTable->Hash[HashIdx] = pEntry; } else { pCurrEntry = pMulticastFilterTable->Hash[HashIdx]; while (pCurrEntry->pNext != NULL) pCurrEntry = pCurrEntry->pNext; pCurrEntry->pNext = pEntry; } } }while(FALSE); RTMP_SEM_UNLOCK(&pMulticastFilterTable->MulticastFilterTabLock); return TRUE; }
int Set_IgmpSn_DelEntry_Proc( IN PRTMP_ADAPTER pAd, IN PSTRING arg) { int i, memberCnt = 0; BOOLEAN bGroupId = 1; PSTRING value; PSTRING thisChar; UCHAR IpAddr[4]; UCHAR Addr[ETH_LENGTH_OF_ADDRESS]; UCHAR GroupId[ETH_LENGTH_OF_ADDRESS]; PUCHAR *pAddr = (PUCHAR *)&Addr; PNET_DEV pDev; POS_COOKIE pObj; UCHAR ifIndex; pObj = (POS_COOKIE) pAd->OS_Cookie; ifIndex = pObj->ioctl_if; pDev = (ifIndex == MAIN_MBSSID) ? (pAd->net_dev) : (pAd->ApCfg.MBSSID[ifIndex].MSSIDDev); while ((thisChar = strsep((char **)&arg, "-")) != NULL) { /* refuse the Member if it's not a MAC address. */ if((bGroupId == 0) && (strlen(thisChar) != 17)) continue; if(strlen(thisChar) == 17) /*Mac address acceptable format 01:02:03:04:05:06 length 17 */ { for (i=0, value = rstrtok(thisChar,":"); value; value = rstrtok(NULL,":")) { if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) ) return FALSE; /*Invalid */ AtoH(value, &Addr[i++], 1); } if(i != 6) return FALSE; /*Invalid */ } else { for (i=0, value = rstrtok(thisChar,"."); value; value = rstrtok(NULL,".")) { if((strlen(value) > 0) && (strlen(value) <= 3)) { int ii; for(ii=0; ii<strlen(value); ii++) if (!isxdigit(*(value + ii))) return FALSE; } else return FALSE; /*Invalid */ IpAddr[i] = (UCHAR)simple_strtol(value, NULL, 10); i++; } if(i != 4) return FALSE; /*Invalid */ ConvertMulticastIP2MAC(IpAddr, (PUCHAR *)&pAddr, ETH_P_IP); } if(bGroupId == 1) COPY_MAC_ADDR(GroupId, Addr); else memberCnt++; if (memberCnt > 0 ) MulticastFilterTableDeleteEntry(pAd, (PUCHAR)GroupId, Addr, pDev); bGroupId = 0; } if(memberCnt == 0) MulticastFilterTableDeleteEntry(pAd, (PUCHAR)GroupId, NULL, pDev); DBGPRINT(RT_DEBUG_TRACE, ("%s (%2X:%2X:%2X:%2X:%2X:%2X)\n", __FUNCTION__, Addr[0], Addr[1], Addr[2], Addr[3], Addr[4], Addr[5])); return TRUE; }
VOID BAOriSessionTearDown( IN OUT PRTMP_ADAPTER pAd, IN UCHAR Wcid, IN UCHAR TID, IN BOOLEAN bPassive, IN BOOLEAN bForceSend) { ULONG Idx = 0; BA_ORI_ENTRY *pBAEntry; BOOLEAN Cancelled; if (Wcid >= MAX_LEN_OF_MAC_TABLE) { return; } // // Locate corresponding BA Originator Entry in BA Table with the (pAddr,TID). // Idx = pAd->MacTab.Content[Wcid].BAOriWcidArray[TID]; if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_ORI_TABLE)) { if (bForceSend == TRUE) { // force send specified TID DelBA MLME_DELBA_REQ_STRUCT DelbaReq; MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG); if (Elem != NULL) { NdisZeroMemory(&DelbaReq, sizeof(DelbaReq)); NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM)); COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr); DelbaReq.Wcid = Wcid; DelbaReq.TID = TID; DelbaReq.Initiator = ORIGINATOR; Elem->MsgLen = sizeof(DelbaReq); NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq)); MlmeDELBAAction(pAd, Elem); kfree(Elem); } else { DBGPRINT(RT_DEBUG_ERROR, ("%s(bForceSend):alloc memory failed!\n", __FUNCTION__)); } } return; } DBGPRINT(RT_DEBUG_TRACE,("%s===>Wcid=%d.TID=%d \n", __FUNCTION__, Wcid, TID)); pBAEntry = &pAd->BATable.BAOriEntry[Idx]; DBGPRINT(RT_DEBUG_TRACE,("\t===>Idx = %ld, Wcid=%d.TID=%d, ORI_BA_Status = %d \n", Idx, Wcid, TID, pBAEntry->ORI_BA_Status)); // // Prepare DelBA action frame and send to the peer. // if ((bPassive == FALSE) && (TID == pBAEntry->TID) && (pBAEntry->ORI_BA_Status == Originator_Done)) { MLME_DELBA_REQ_STRUCT DelbaReq; MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG); if (Elem != NULL) { NdisZeroMemory(&DelbaReq, sizeof(DelbaReq)); NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM)); COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr); DelbaReq.Wcid = Wcid; DelbaReq.TID = pBAEntry->TID; DelbaReq.Initiator = ORIGINATOR; Elem->MsgLen = sizeof(DelbaReq); NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq)); MlmeDELBAAction(pAd, Elem); kfree(Elem); } else { DBGPRINT(RT_DEBUG_ERROR, ("%s():alloc memory failed!\n", __FUNCTION__)); return; } } RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled); BATableFreeOriEntry(pAd, Idx); if (bPassive) { //BAOriSessionSetUp(pAd, &pAd->MacTab.Content[Wcid], TID, 0, 10000, TRUE); } }
VOID BARecSessionTearDown( IN OUT PRTMP_ADAPTER pAd, IN UCHAR Wcid, IN UCHAR TID, IN BOOLEAN bPassive) { ULONG Idx = 0; BA_REC_ENTRY *pBAEntry; if (Wcid >= MAX_LEN_OF_MAC_TABLE) { return; } // // Locate corresponding BA Originator Entry in BA Table with the (pAddr,TID). // Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID]; if (Idx == 0) return; DBGPRINT(RT_DEBUG_TRACE,("%s===>Wcid=%d.TID=%d \n", __FUNCTION__, Wcid, TID)); pBAEntry = &pAd->BATable.BARecEntry[Idx]; DBGPRINT(RT_DEBUG_TRACE,("\t===>Idx = %ld, Wcid=%d.TID=%d, REC_BA_Status = %d \n", Idx, Wcid, TID, pBAEntry->REC_BA_Status)); // // Prepare DelBA action frame and send to the peer. // if ((TID == pBAEntry->TID) && (pBAEntry->REC_BA_Status == Recipient_Accept)) { MLME_DELBA_REQ_STRUCT DelbaReq; BOOLEAN Cancelled; //ULONG offset; //UINT32 VALUE; RTMPCancelTimer(&pBAEntry->RECBATimer, &Cancelled); // // 1. Send DELBA Action Frame // if (bPassive == FALSE) { MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG); if (Elem != NULL) { NdisZeroMemory(&DelbaReq, sizeof(DelbaReq)); NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM)); COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr); DelbaReq.Wcid = Wcid; DelbaReq.TID = TID; DelbaReq.Initiator = RECIPIENT; Elem->MsgLen = sizeof(DelbaReq); NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq)); MlmeDELBAAction(pAd, Elem); kfree(Elem); } else { DBGPRINT(RT_DEBUG_ERROR, ("%s():alloc memory failed!\n", __FUNCTION__)); return; } } // // 2. Free resource of BA session // // flush all pending reordering mpdus ba_refresh_reordering_mpdus(pAd, pBAEntry); NdisAcquireSpinLock(&pAd->BATabLock); // Erase Bitmap flag. pBAEntry->LastIndSeq = RESET_RCV_SEQ; pBAEntry->BAWinSize = 0; // Erase Bitmap flag at software mactable pAd->MacTab.Content[Wcid].RXBAbitmap &= (~(1<<(pBAEntry->TID))); pAd->MacTab.Content[Wcid].BARecWcidArray[TID] = 0; RTMP_DEL_BA_SESSION_FROM_ASIC(pAd, Wcid, TID); NdisReleaseSpinLock(&pAd->BATabLock); } BATableFreeRecEntry(pAd, Idx); }
/* ======================================================================== Routine Description: Close raxx interface. Arguments: *net_dev the raxx interface pointer Return Value: 0 Open OK otherwise Open Fail Note: 1. if open fail, kernel will not call the close function. 2. Free memory for (1) Mlme Memory Handler: MlmeHalt() (2) TX & RX: RTMPFreeTxRxRingMemory() (3) BA Reordering: ba_reordering_resource_release() ======================================================================== */ int MainVirtualIF_close(IN struct net_device *net_dev) { RTMP_ADAPTER *pAd = RTMP_OS_NETDEV_GET_PRIV(net_dev); // Sanity check for pAd if (pAd == NULL) return 0; // close ok netif_carrier_off(pAd->net_dev); netif_stop_queue(pAd->net_dev); #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { BOOLEAN Cancelled; #ifdef QOS_DLS_SUPPORT // send DLS-TEAR_DOWN message, if (pAd->CommonCfg.bDLSCapable) { UCHAR i; // tear down local dls table entry for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++) { if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)) { RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr); pAd->StaCfg.DLSEntry[i].Status = DLS_NONE; pAd->StaCfg.DLSEntry[i].Valid = FALSE; } } // tear down peer dls table entry for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++) { if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)) { RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr); pAd->StaCfg.DLSEntry[i].Status = DLS_NONE; pAd->StaCfg.DLSEntry[i].Valid = FALSE; } } RTMP_MLME_HANDLER(pAd); } #endif // QOS_DLS_SUPPORT // if (INFRA_ON(pAd) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) { MLME_DISASSOC_REQ_STRUCT DisReq; MLME_QUEUE_ELEM *MsgElem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG); if (MsgElem) { COPY_MAC_ADDR(DisReq.Addr, pAd->CommonCfg.Bssid); DisReq.Reason = REASON_DEAUTH_STA_LEAVING; MsgElem->Machine = ASSOC_STATE_MACHINE; MsgElem->MsgType = MT2_MLME_DISASSOC_REQ; MsgElem->MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT); NdisMoveMemory(MsgElem->Msg, &DisReq, sizeof(MLME_DISASSOC_REQ_STRUCT)); // Prevent to connect AP again in STAMlmePeriodicExec pAd->MlmeAux.AutoReconnectSsidLen= 32; NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen); pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC; MlmeDisassocReqAction(pAd, MsgElem); kfree(MsgElem); } RTMPusecDelay(1000); } RTMPCancelTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, &Cancelled); RTMPCancelTimer(&pAd->StaCfg.WpaDisassocAndBlockAssocTimer, &Cancelled); #ifdef WPA_SUPPLICANT_SUPPORT #ifndef NATIVE_WPA_SUPPLICANT_SUPPORT // send wireless event to wpa_supplicant for infroming interface down. RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, RT_INTERFACE_DOWN, NULL, NULL, 0); #endif // NATIVE_WPA_SUPPLICANT_SUPPORT // #endif // WPA_SUPPLICANT_SUPPORT // } #endif // CONFIG_STA_SUPPORT // VIRTUAL_IF_DOWN(pAd); RT_MOD_DEC_USE_COUNT(); return 0; // close ok }
/*----------------------------------------------------------------------------*/ int mtk_cfg80211_add_key ( struct wiphy *wiphy, struct net_device *ndev, u8 key_index, bool pairwise, const u8 *mac_addr, struct key_params *params ) { PARAM_KEY_T rKey; P_GLUE_INFO_T prGlueInfo = NULL; WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; INT_32 i4Rslt = -EINVAL; UINT_32 u4BufLen = 0; UINT_8 tmp1[8]; UINT_8 tmp2[8]; prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ASSERT(prGlueInfo); kalMemZero(&rKey, sizeof(PARAM_KEY_T)); rKey.u4KeyIndex = key_index; if(mac_addr) { COPY_MAC_ADDR(rKey.arBSSID, mac_addr); if ((rKey.arBSSID[0] == 0x00) && (rKey.arBSSID[1] == 0x00) && (rKey.arBSSID[2] == 0x00) && (rKey.arBSSID[3] == 0x00) && (rKey.arBSSID[4] == 0x00) && (rKey.arBSSID[5] == 0x00)) { rKey.arBSSID[0] = 0xff; rKey.arBSSID[1] = 0xff; rKey.arBSSID[2] = 0xff; rKey.arBSSID[3] = 0xff; rKey.arBSSID[4] = 0xff; rKey.arBSSID[5] = 0xff; } if (rKey.arBSSID[0] != 0xFF) { rKey.u4KeyIndex |= BIT(31); if ((rKey.arBSSID[0] != 0x00) || (rKey.arBSSID[1] != 0x00) || (rKey.arBSSID[2] != 0x00) || (rKey.arBSSID[3] != 0x00) || (rKey.arBSSID[4] != 0x00) || (rKey.arBSSID[5] != 0x00)) rKey.u4KeyIndex |= BIT(30); } } else { rKey.arBSSID[0] = 0xff; rKey.arBSSID[1] = 0xff; rKey.arBSSID[2] = 0xff; rKey.arBSSID[3] = 0xff; rKey.arBSSID[4] = 0xff; rKey.arBSSID[5] = 0xff; //rKey.u4KeyIndex |= BIT(31); //Enable BIT 31 will make tx use bc key id, should use pairwise key id 0 } if(params->key) { //rKey.aucKeyMaterial[0] = kalMemAlloc(params->key_len, VIR_MEM_TYPE); kalMemCopy(rKey.aucKeyMaterial, params->key, params->key_len); if (params->key_len == 32) { kalMemCopy(tmp1, ¶ms->key[16], 8); kalMemCopy(tmp2, ¶ms->key[24], 8); kalMemCopy(&rKey.aucKeyMaterial[16], tmp2, 8); kalMemCopy(&rKey.aucKeyMaterial[24], tmp1, 8); } } rKey.u4KeyLength = params->key_len; rKey.u4Length = ((UINT_32)&(((P_P2P_PARAM_KEY_T)0)->aucKeyMaterial)) + rKey.u4KeyLength; rStatus = kalIoctl(prGlueInfo, wlanoidSetAddKey, &rKey, rKey.u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen); if (rStatus == WLAN_STATUS_SUCCESS) i4Rslt = 0; return i4Rslt; }
PMESH_BMPKTSIG_ENTRY BMPktSigTabInsert( IN PRTMP_ADAPTER pAd, IN PUCHAR MeshSA) { INT i; ULONG HashIdx; PMESH_BMPKTSIG_TAB pTab = pAd->MeshTab.pBMPktSigTab; PMESH_BMPKTSIG_ENTRY pEntry = NULL, pCurrEntry; ULONG Now; if(pTab == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: pBMPktSigTab doesn't exist.\n", __FUNCTION__)); return NULL; } pEntry = BMPktSigTabLookUp(pAd, MeshSA); if (pEntry == NULL) { /* if FULL, return */ if (pTab->Size >= MAX_BMPKTSIG_TAB_SIZE) { DBGPRINT(RT_DEBUG_ERROR, ("%s: pBMPktSigTab FULL.\n", __FUNCTION__)); return NULL; } RTMP_SEM_LOCK(&pAd->MeshTab.MeshBMPktTabLock); for (i = 0; i < MAX_BMPKTSIG_TAB_SIZE; i++) { NdisGetSystemUpTime(&Now); pEntry = &pTab->Content[i]; if ((pEntry->Valid == TRUE) && RTMP_TIME_AFTER((unsigned long)Now, (unsigned long)(pEntry->LastRefTime + MESH_BMPKT_RECORD_TIME))) { PMESH_BMPKTSIG_ENTRY pPrevEntry = NULL; ULONG HashIdx = BMPKT_MAC_ADDR_HASH_INDEX(pEntry->MeshSA); PMESH_BMPKTSIG_ENTRY pProbeEntry = pTab->Hash[HashIdx]; /* update Hash list */ do { if (pProbeEntry == pEntry) { if (pPrevEntry == NULL) { pTab->Hash[HashIdx] = pEntry->pNext; } else { pPrevEntry->pNext = pEntry->pNext; } break; } pPrevEntry = pProbeEntry; pProbeEntry = pProbeEntry->pNext; } while (pProbeEntry); NdisZeroMemory(pEntry, sizeof(MESH_BMPKTSIG_ENTRY)); pTab->Size--; continue; } if (pEntry->Valid == FALSE) break; } if (i < MAX_BMPKTSIG_TAB_SIZE) { NdisGetSystemUpTime(&Now); pEntry->LastRefTime = Now; pEntry->Valid = TRUE; COPY_MAC_ADDR(pEntry->MeshSA, MeshSA); pTab->Size++; } else { pEntry = NULL; DBGPRINT(RT_DEBUG_ERROR, ("%s: pBMPktSigTab tab full.\n", __FUNCTION__)); } /* add this Neighbor entry into HASH table */ if (pEntry) { HashIdx = BMPKT_MAC_ADDR_HASH_INDEX(MeshSA); if (pTab->Hash[HashIdx] == NULL) { pTab->Hash[HashIdx] = pEntry; } else { pCurrEntry = pTab->Hash[HashIdx]; while (pCurrEntry->pNext != NULL) pCurrEntry = pCurrEntry->pNext; pCurrEntry->pNext = pEntry; } } RTMP_SEM_UNLOCK(&pAd->MeshTab.MeshBMPktTabLock); } return pEntry; }
/*----------------------------------------------------------------------------*/ __KAL_INLINE__ VOID authComposeAuthFrameHeaderAndFF(IN PUINT_8 pucBuffer, IN UINT_8 aucPeerMACAddress[], IN UINT_8 aucMACAddress[], IN UINT_16 u2AuthAlgNum, IN UINT_16 u2TransactionSeqNum, IN UINT_16 u2StatusCode) { P_WLAN_AUTH_FRAME_T prAuthFrame; UINT_16 u2FrameCtrl; ASSERT(pucBuffer); ASSERT(aucPeerMACAddress); ASSERT(aucMACAddress); prAuthFrame = (P_WLAN_AUTH_FRAME_T) pucBuffer; /* 4 <1> Compose the frame header of the Authentication frame. */ /* Fill the Frame Control field. */ u2FrameCtrl = MAC_FRAME_AUTH; /* If this frame is the third frame in the shared key authentication * sequence, it shall be encrypted. */ if ((u2AuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY) && (u2TransactionSeqNum == AUTH_TRANSACTION_SEQ_3)) { u2FrameCtrl |= MASK_FC_PROTECTED_FRAME; /* HW will also detect this bit for applying encryption */ } /* WLAN_SET_FIELD_16(&prAuthFrame->u2FrameCtrl, u2FrameCtrl); */ prAuthFrame->u2FrameCtrl = u2FrameCtrl; /* NOTE(Kevin): Optimized for ARM */ /* Fill the DA field with Target BSSID. */ COPY_MAC_ADDR(prAuthFrame->aucDestAddr, aucPeerMACAddress); /* Fill the SA field with our MAC Address. */ COPY_MAC_ADDR(prAuthFrame->aucSrcAddr, aucMACAddress); switch (u2TransactionSeqNum) { case AUTH_TRANSACTION_SEQ_1: case AUTH_TRANSACTION_SEQ_3: /* Fill the BSSID field with Target BSSID. */ COPY_MAC_ADDR(prAuthFrame->aucBSSID, aucPeerMACAddress); break; case AUTH_TRANSACTION_SEQ_2: case AUTH_TRANSACTION_SEQ_4: /* Fill the BSSID field with Current BSSID. */ COPY_MAC_ADDR(prAuthFrame->aucBSSID, aucMACAddress); break; default: ASSERT(0); } /* Clear the SEQ/FRAG_NO field. */ prAuthFrame->u2SeqCtrl = 0; /* 4 <2> Compose the frame body's fixed field part of the Authentication frame. */ /* Fill the Authentication Algorithm Number field. */ /* WLAN_SET_FIELD_16(&prAuthFrame->u2AuthAlgNum, u2AuthAlgNum); */ prAuthFrame->u2AuthAlgNum = u2AuthAlgNum; /* NOTE(Kevin): Optimized for ARM */ /* Fill the Authentication Transaction Sequence Number field. */ /* WLAN_SET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, u2TransactionSeqNum); */ prAuthFrame->u2AuthTransSeqNo = u2TransactionSeqNum; /* NOTE(Kevin): Optimized for ARM */ /* Fill the Status Code field. */ /* WLAN_SET_FIELD_16(&prAuthFrame->u2StatusCode, u2StatusCode); */ prAuthFrame->u2StatusCode = u2StatusCode; /* NOTE(Kevin): Optimized for ARM */ return; } /* end of authComposeAuthFrameHeaderAndFF() */
BOOLEAN PktSigCheck( IN PRTMP_ADAPTER pAd, IN PUCHAR pTA, IN PUCHAR pDA, IN PUCHAR pSA, IN UINT32 MeshSeq, IN ULONG FrameType) { BOOLEAN result = FALSE; PMESH_BMPKTSIG_ENTRY pBMPktSigEntry = NULL; do { if ((FrameType == FC_TYPE_MGMT) || (*pDA & 0x01)) { if ((pBMPktSigEntry = BMPktSigTabLookUp(pAd, pSA)) == NULL) { if ((pBMPktSigEntry = BMPktSigTabInsert(pAd, pSA)) == NULL) break; pBMPktSigEntry->MeshSeqBased = MeshSeq; COPY_MAC_ADDR(pBMPktSigEntry->Precursor, pTA); NdisZeroMemory(pBMPktSigEntry->Offset, sizeof(UINT32) * 4); } else { UINT32 DevNum; UINT32 RemainNum; UINT32 SeqDiff; if (MESH_SEQ_AFTER(pBMPktSigEntry->MeshSeqBased, MeshSeq)) break; SeqDiff = MESH_SEQ_SUB(MeshSeq, pBMPktSigEntry->MeshSeqBased); if (SeqDiff == 0) break; if (SeqDiff > 128) { pBMPktSigEntry->MeshSeqBased = MeshSeq; NdisZeroMemory(pBMPktSigEntry->Offset, sizeof(UINT32) * 4); } else { DevNum = (SeqDiff - 1) / 32; RemainNum = (SeqDiff - 1) % 32; if (pBMPktSigEntry->Offset[DevNum] & (1 << RemainNum)) break; else pBMPktSigEntry->Offset[DevNum] |= (1 << RemainNum); } } } #if 0 /* mesh unicast packet doesn't need to check packet signature. */ else { if((pBMPktSigEntry = BMPktSigTabLookUp(pAd, pSA)) == NULL) { if((pBMPktSigEntry = BMPktSigTabInsert(pAd, pSA)) == NULL) break; pBMPktSigEntry->UcaseMeshSeq = MeshSeq; COPY_MAC_ADDR(pBMPktSigEntry->Precursor, pTA); } else { if (MESH_SEQ_AFTER(pBMPktSigEntry->UcaseMeshSeq, MeshSeq)) break; pBMPktSigEntry->UcaseMeshSeq = MeshSeq; } } #endif result = TRUE; } while (FALSE); if ((result == FALSE) && (FrameType == FC_TYPE_DATA) && IS_MULTICAST_MAC_ADDR(pDA) && (pBMPktSigEntry != NULL) && !MAC_ADDR_EQUAL(pBMPktSigEntry->Precursor, pTA)) { MeshMultipathNotice(pAd, pTA, pSA, 1); } return result; }
/*----------------------------------------------------------------------------*/ VOID rlmObssScanDone ( P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr ) { P_MSG_SCN_SCAN_DONE prScanDoneMsg; P_BSS_INFO_T prBssInfo; P_MSDU_INFO_T prMsduInfo; P_ACTION_20_40_COEXIST_FRAME prTxFrame; UINT_16 i, u2PayloadLen; ASSERT(prMsgHdr); prScanDoneMsg = (P_MSG_SCN_SCAN_DONE) prMsgHdr; prBssInfo = &prAdapter->rWifiVar.arBssInfo[prScanDoneMsg->ucNetTypeIndex]; ASSERT(prBssInfo); DBGLOG(RLM, INFO, ("OBSS Scan Done (NetIdx=%d, Mode=%d)\n", prScanDoneMsg->ucNetTypeIndex, prBssInfo->eCurrentOPMode)); cnmMemFree(prAdapter, prMsgHdr); #if CFG_ENABLE_WIFI_DIRECT /* AP mode */ if ((prAdapter->fgIsP2PRegistered) && (IS_NET_ACTIVE(prAdapter, prBssInfo->ucNetTypeIndex)) && (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT)) { return; } #endif /* STA mode */ if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE || !RLM_NET_PARAM_VALID(prBssInfo) || prBssInfo->u2ObssScanInterval == 0) { DBGLOG(RLM, WARN, ("OBSS Scan Done (NetIdx=%d) -- Aborted!!\n", prBssInfo->ucNetTypeIndex)); return; } /* To do: check 2.4G channel list to decide if obss mgmt should be * sent to associated AP. Note: how to handle concurrent network? * To do: invoke rlmObssChnlLevel() to decide if 20/40 BSS coexistence * management frame is needed. */ if ((prBssInfo->auc2G_20mReqChnlList[0] > 0 || prBssInfo->auc2G_NonHtChnlList[0] > 0) && (prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter, MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN)) != NULL) { DBGLOG(RLM, INFO, ("Send 20/40 coexistence mgmt(20mReq=%d, NonHt=%d)\n", prBssInfo->auc2G_20mReqChnlList[0], prBssInfo->auc2G_NonHtChnlList[0])); prTxFrame = (P_ACTION_20_40_COEXIST_FRAME) ((UINT_32)(prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; COPY_MAC_ADDR(prTxFrame->aucDestAddr, prBssInfo->aucBSSID); COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); prTxFrame->ucCategory = CATEGORY_PUBLIC_ACTION; prTxFrame->ucAction = ACTION_PUBLIC_20_40_COEXIST; /* To do: find correct algorithm */ prTxFrame->rBssCoexist.ucId = ELEM_ID_20_40_BSS_COEXISTENCE; prTxFrame->rBssCoexist.ucLength = 1; prTxFrame->rBssCoexist.ucData = (prBssInfo->auc2G_20mReqChnlList[0] > 0) ? BSS_COEXIST_20M_REQ : 0; u2PayloadLen = 2 + 3; if (prBssInfo->auc2G_NonHtChnlList[0] > 0) { ASSERT(prBssInfo->auc2G_NonHtChnlList[0] <= CHNL_LIST_SZ_2G); prTxFrame->rChnlReport.ucId = ELEM_ID_20_40_INTOLERANT_CHNL_REPORT; prTxFrame->rChnlReport.ucLength = prBssInfo->auc2G_NonHtChnlList[0] + 1; prTxFrame->rChnlReport.ucRegulatoryClass = 81; /* 2.4GHz, ch1~13 */ for (i = 0; i < prBssInfo->auc2G_NonHtChnlList[0] && i < CHNL_LIST_SZ_2G; i++) { prTxFrame->rChnlReport.aucChannelList[i] = prBssInfo->auc2G_NonHtChnlList[i+1]; } u2PayloadLen += IE_SIZE(&prTxFrame->rChnlReport); } ASSERT((WLAN_MAC_HEADER_LEN + u2PayloadLen) <= PUBLIC_ACTION_MAX_LEN); /* Clear up channel lists in 2.4G band */ prBssInfo->auc2G_20mReqChnlList[0] = 0; prBssInfo->auc2G_NonHtChnlList[0] = 0; //4 Update information of MSDU_INFO_T prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; /* Management frame */ prMsduInfo->ucStaRecIndex = prBssInfo->prStaRecOfAP->ucIndex; prMsduInfo->ucNetworkType = prBssInfo->ucNetTypeIndex; prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; prMsduInfo->fgIs802_1x = FALSE; prMsduInfo->fgIs802_11 = TRUE; prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); prMsduInfo->pfTxDoneHandler = NULL; prMsduInfo->fgIsBasicRate = FALSE; //4 Enqueue the frame to send this action frame. nicTxEnqueueMsdu(prAdapter, prMsduInfo); } /* end of prMsduInfo != NULL */ if (prBssInfo->u2ObssScanInterval > 0) { DBGLOG(RLM, INFO, ("Set OBSS timer (NetIdx=%d, %d sec)\n", prBssInfo->ucNetTypeIndex, prBssInfo->u2ObssScanInterval)); cnmTimerStartTimer(prAdapter, &prBssInfo->rObssScanTimer, prBssInfo->u2ObssScanInterval * MSEC_PER_SEC); } }
BOOLEAN PeerAssocReqCmmSanity( IN PRTMP_ADAPTER pAd, IN BOOLEAN isReassoc, IN VOID *Msg, IN ULONG MsgLen, OUT PUCHAR pAddr2, OUT USHORT *pCapabilityInfo, OUT USHORT *pListenInterval, OUT PUCHAR pApAddr, OUT UCHAR *pSsidLen, OUT char *Ssid, OUT UCHAR *pRatesLen, OUT UCHAR Rates[], OUT UCHAR *RSN, OUT UCHAR *pRSNLen, OUT BOOLEAN *pbWmmCapable, #ifdef WSC_AP_SUPPORT OUT BOOLEAN *pWscCapable, #endif // WSC_AP_SUPPORT // OUT ULONG *pRalinkIe, OUT EXT_CAP_INFO_ELEMENT *pExtCapInfo, OUT UCHAR *pHtCapabilityLen, OUT HT_CAPABILITY_IE *pHtCapability) { CHAR *Ptr; PFRAME_802_11 Fr = (PFRAME_802_11)Msg; PEID_STRUCT eid_ptr; UCHAR Sanity = 0; UCHAR WPA1_OUI[4] = { 0x00, 0x50, 0xF2, 0x01 }; UCHAR WPA2_OUI[3] = { 0x00, 0x0F, 0xAC }; MAC_TABLE_ENTRY *pEntry = (MAC_TABLE_ENTRY *)NULL; // to prevent caller from using garbage output value *pSsidLen = 0; *pRatesLen = 0; *pRSNLen = 0; *pbWmmCapable = FALSE; *pRalinkIe = 0; *pHtCapabilityLen= 0; COPY_MAC_ADDR(pAddr2, &Fr->Hdr.Addr2); pEntry = MacTableLookup(pAd, pAddr2); if (pEntry == NULL) return FALSE; Ptr = (PCHAR)Fr->Octet; NdisMoveMemory(pCapabilityInfo, &Fr->Octet[0], 2); NdisMoveMemory(pListenInterval, &Fr->Octet[2], 2); if (isReassoc) { NdisMoveMemory(pApAddr, &Fr->Octet[4], 6); eid_ptr = (PEID_STRUCT) &Fr->Octet[10]; } else { eid_ptr = (PEID_STRUCT) &Fr->Octet[4]; } // get variable fields from payload and advance the pointer while (((UCHAR *)eid_ptr + eid_ptr->Len + 1) < ((UCHAR *)Fr + MsgLen)) { switch(eid_ptr->Eid) { case IE_SSID: if (((Sanity&0x1) == 1)) break; if ((eid_ptr->Len <= MAX_LEN_OF_SSID)) { Sanity |= 0x01; NdisMoveMemory(Ssid, eid_ptr->Octet, eid_ptr->Len); *pSsidLen = eid_ptr->Len; DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocReqSanity - SsidLen = %d \n", *pSsidLen)); } else { DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocReqSanity - wrong IE_SSID\n")); return FALSE; } break; case IE_SUPP_RATES: if ((eid_ptr->Len <= MAX_LEN_OF_SUPPORTED_RATES) && (eid_ptr->Len > 0)) { Sanity |= 0x02; NdisMoveMemory(Rates, eid_ptr->Octet, eid_ptr->Len); DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocReqSanity - IE_SUPP_RATES., Len=%d. " "Rates[0]=%x\n", eid_ptr->Len, Rates[0])); DBGPRINT(RT_DEBUG_TRACE, ("Rates[1]=%x %x %x %x %x %x %x\n", Rates[1], Rates[2], Rates[3], Rates[4], Rates[5], Rates[6], Rates[7])); *pRatesLen = eid_ptr->Len; } else { UCHAR RateDefault[8] = \ { 0x82, 0x84, 0x8b, 0x96, 0x12, 0x24, 0x48, 0x6c }; // HT rate not ready yet. return true temporarily. rt2860c //DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocReqSanity - wrong IE_SUPP_RATES\n")); Sanity |= 0x02; *pRatesLen = 8; NdisMoveMemory(Rates, RateDefault, 8); DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocReqSanity - wrong IE_SUPP_RATES., Len=%d\n", eid_ptr->Len)); } break; case IE_EXT_SUPP_RATES: if (eid_ptr->Len + *pRatesLen <= MAX_LEN_OF_SUPPORTED_RATES) { NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, eid_ptr->Len); *pRatesLen = (*pRatesLen) + eid_ptr->Len; } else { NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, MAX_LEN_OF_SUPPORTED_RATES - (*pRatesLen)); *pRatesLen = MAX_LEN_OF_SUPPORTED_RATES; } break; case IE_HT_CAP: if (eid_ptr->Len >= sizeof(HT_CAPABILITY_IE)) { NdisMoveMemory(pHtCapability, eid_ptr->Octet, SIZE_HT_CAP_IE); *(USHORT *)(&pHtCapability->HtCapInfo) = \ cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo)); #ifdef UNALIGNMENT_SUPPORT { EXT_HT_CAP_INFO extHtCapInfo; NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&pHtCapability->ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO)); *(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo)); NdisMoveMemory((PUCHAR)(&pHtCapability->ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO)); } #else *(USHORT *)(&pHtCapability->ExtHtCapInfo) = \ cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo)); #endif // UNALIGNMENT_SUPPORT // *pHtCapabilityLen = SIZE_HT_CAP_IE; Sanity |= 0x10; DBGPRINT(RT_DEBUG_WARN, ("PeerAssocReqSanity - IE_HT_CAP\n")); } else { DBGPRINT(RT_DEBUG_WARN, ("PeerAssocReqSanity - wrong IE_HT_CAP.eid_ptr->Len = %d\n", eid_ptr->Len)); } break; case IE_EXT_CAPABILITY: if (eid_ptr->Len >= sizeof(EXT_CAP_INFO_ELEMENT)) { NdisMoveMemory(pExtCapInfo, eid_ptr->Octet, sizeof(EXT_CAP_INFO_ELEMENT)); DBGPRINT(RT_DEBUG_WARN, ("PeerAssocReqSanity - IE_EXT_CAPABILITY!\n")); } break; case IE_WPA: // same as IE_VENDOR_SPECIFIC case IE_WPA2: #ifdef WSC_AP_SUPPORT if (NdisEqualMemory(eid_ptr->Octet, WPS_OUI, 4)) { #ifdef WSC_V2_SUPPORT if ((pAd->ApCfg.MBSSID[pEntry->apidx].WscControl.WscV2Info.bWpsEnable) || (pAd->ApCfg.MBSSID[pEntry->apidx].WscControl.WscV2Info.bEnableWpsV2 == FALSE)) #endif // WSC_V2_SUPPORT // *pWscCapable = TRUE; break; } #endif // WSC_AP_SUPPORT // /* Handle Atheros and Broadcom draft 11n STAs */ if (NdisEqualMemory(eid_ptr->Octet, BROADCOM_OUI, 3)) { switch (eid_ptr->Octet[3]) { case 0x33: if ((eid_ptr->Len-4) == sizeof(HT_CAPABILITY_IE)) { NdisMoveMemory(pHtCapability, &eid_ptr->Octet[4], SIZE_HT_CAP_IE); *(USHORT *)(&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo)); #ifdef UNALIGNMENT_SUPPORT { EXT_HT_CAP_INFO extHtCapInfo; NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&pHtCapability->ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO)); *(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo)); NdisMoveMemory((PUCHAR)(&pHtCapability->ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO)); } #else *(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo)); #endif // UNALIGNMENT_SUPPORT // *pHtCapabilityLen = SIZE_HT_CAP_IE; } break; default: // ignore other cases break; } } if (NdisEqualMemory(eid_ptr->Octet, RALINK_OUI, 3) && (eid_ptr->Len == 7)) { //*pRalinkIe = eid_ptr->Octet[3]; if (eid_ptr->Octet[3] != 0) *pRalinkIe = eid_ptr->Octet[3]; else *pRalinkIe = 0xf0000000; // Set to non-zero value (can't set bit0-2) to represent this is Ralink Chip. So at linkup, we will set ralinkchip flag. break; } // WMM_IE if (NdisEqualMemory(eid_ptr->Octet, WME_INFO_ELEM, 6) && (eid_ptr->Len == 7)) { *pbWmmCapable = TRUE; #ifdef UAPSD_AP_SUPPORT UAPSD_AssocParse(pAd, pEntry, (UINT8 *)&eid_ptr->Octet[6]); #endif // UAPSD_AP_SUPPORT // break; } if (pAd->ApCfg.MBSSID[pEntry->apidx].AuthMode < Ndis802_11AuthModeWPA) break; /* If this IE did not begins with 00:0x50:0xf2:0x01, it would be proprietary. So we ignore it. */ if (!NdisEqualMemory(eid_ptr->Octet, WPA1_OUI, sizeof(WPA1_OUI)) && !NdisEqualMemory(&eid_ptr->Octet[2], WPA2_OUI, sizeof(WPA2_OUI))) { DBGPRINT(RT_DEBUG_TRACE, ("Not RSN IE, maybe WMM IE!!!\n")); break; } if (/*(eid_ptr->Len <= MAX_LEN_OF_RSNIE) &&*/ (eid_ptr->Len >= MIN_LEN_OF_RSNIE)) { if (!pEntry) return FALSE; hex_dump("Received RSNIE in Assoc-Req", (UCHAR *)eid_ptr, eid_ptr->Len + 2); // Copy whole RSNIE context NdisMoveMemory(RSN, eid_ptr, eid_ptr->Len + 2); *pRSNLen=eid_ptr->Len + 2; } else { *pRSNLen=0; DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocReqSanity - missing IE_WPA(%d)\n",eid_ptr->Len)); return FALSE; } break; #ifdef WAPI_SUPPORT case IE_WAPI: if ((pAd->ApCfg.MBSSID[pEntry->apidx].AuthMode != Ndis802_11AuthModeWAICERT) && (pAd->ApCfg.MBSSID[pEntry->apidx].AuthMode != Ndis802_11AuthModeWAIPSK)) break; // Sanity check the validity of WIE // Todo - AlbertY // Copy whole WAPI-IE context NdisMoveMemory(RSN, eid_ptr, eid_ptr->Len + 2); *pRSNLen=eid_ptr->Len + 2; DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocReqSanity - IE_WAPI(%d)\n",eid_ptr->Len)); break; #endif // WAPI_SUPPORT // default: break; } eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len); } if ((Sanity&0x3) != 0x03) { DBGPRINT(RT_DEBUG_WARN, ("PeerAssocReqSanity - missing mandatory field\n")); return FALSE; } else { DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocReqSanity - success\n")); return TRUE; } }