/************************************************************************ * buildNullTemplate * ************************************************************************ DESCRIPTION: This function build a NULL data template to set to the HAL when joining an infrastructure network performs the following: - Build a template & set the template len, the template type is set in the site mgr INPUT: pSiteMgr - Handle to site manager pTemplate - Pointer to the template structure OUTPUT: RETURN: TI_OK ************************************************************************/ TI_STATUS buildNullTemplate(siteMgr_t * pSiteMgr, TSetTemplate * pTemplate) { paramInfo_t param; nullDataTemplate_t *pBuffer = (nullDataTemplate_t *) pTemplate->ptr; siteEntry_t *pPrimarySite = pSiteMgr->pSitesMgmtParams->pPrimarySite; TI_UINT16 fc; os_memoryZero(pSiteMgr->hOs, pBuffer, sizeof(nullDataTemplate_t)); /* * Header First */ /* Set destination address */ MAC_COPY(pBuffer->hdr.DA, pPrimarySite->bssid); /* Set BSSID address */ MAC_COPY(pBuffer->hdr.BSSID, pPrimarySite->bssid); /* Build Source address */ param.paramType = CTRL_DATA_MAC_ADDRESS; ctrlData_getParam(pSiteMgr->hCtrlData, ¶m); MAC_COPY(pBuffer->hdr.SA, param.content.ctrlDataDeviceMacAddress); fc = DOT11_FC_DATA_NULL_FUNCTION; fc |= (TI_TRUE << DOT11_FC_TO_DS_SHIFT); COPY_WLAN_WORD(&pBuffer->hdr.fc, &fc); /* copy with endianess handling. */ pTemplate->len = sizeof(dot11_mgmtHeader_t); return TI_OK; }
TI_STATUS keyParserExternal_remove(struct _keyParser_t *pKeyParser, TI_UINT8 *pKeyData, TI_UINT32 keyDataLen) { TI_STATUS status; OS_802_11_KEY *pKeyDesc; paramInfo_t macParam; encodedKeyMaterial_t encodedKeyMaterial; TI_UINT8 broadcastMacAddr[MAC_ADDR_LEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; TI_UINT8 keyBuffer[MAC_ADDR_LEN+KEY_RSC_LEN+MAX_EXT_KEY_DATA_LENGTH]; if (pKeyData == NULL) { return TI_NOK; } pKeyDesc = (OS_802_11_KEY*)pKeyData; if (pKeyDesc->KeyIndex & EXT_KEY_TRANSMIT_MASK) { /* Bit 31 should always be zero */ return TI_NOK; } if (pKeyDesc->KeyIndex & EXT_KEY_REMAIN_BITS_MASK) { /* Bits 8-29 should always be zero */ return TI_NOK; } encodedKeyMaterial.keyId = pKeyDesc->KeyIndex; encodedKeyMaterial.keyLen = 0; encodedKeyMaterial.pData = (char *) keyBuffer; if (pKeyDesc->KeyIndex & EXT_KEY_PAIRWISE_GROUP_MASK) { /* delete all pairwise keys or for the current BSSID */ if (!MAC_EQUAL(pKeyDesc->BSSID, broadcastMacAddr)) { MAC_COPY (keyBuffer, pKeyDesc->BSSID); } else { macParam.paramType = CTRL_DATA_CURRENT_BSSID_PARAM; status = ctrlData_getParam(pKeyParser->hCtrlData, &macParam); if (status != TI_OK) { return TI_NOK; } MAC_COPY (keyBuffer, macParam.content.ctrlDataCurrentBSSID); } status = pKeyParser->pUcastKey->pKeyDerive->remove(pKeyParser->pUcastKey->pKeyDerive, &encodedKeyMaterial); } else { /* delete all group keys or for the current BSSID */ MAC_COPY (keyBuffer, broadcastMacAddr); status = pKeyParser->pBcastKey->pKeyDerive->remove(pKeyParser->pUcastKey->pKeyDerive, &encodedKeyMaterial); } return status; }
/************************************************************************ * buildPsPollTemplate * ************************************************************************ DESCRIPTION: This function build a ps poll template performs the following: - Build a template & set the template len, the template type is set in the site mgr INPUT: pSiteMgr - Handle to site manager pTemplate - Pointer to the template structure pSsid - Desired SSID OUTPUT: RETURN: TI_OK ************************************************************************/ TI_STATUS buildPsPollTemplate(siteMgr_t * pSiteMgr, TSetTemplate * pTemplate) { paramInfo_t param; TTwdParamInfo tTwdParam; TI_UINT32 size; psPollTemplate_t *pBuffer = (psPollTemplate_t *) pTemplate->ptr; siteEntry_t *pPrimarySite = pSiteMgr->pSitesMgmtParams->pPrimarySite; TI_UINT16 fc; os_memoryZero(pSiteMgr->hOs, pBuffer, sizeof(psPollTemplate_t)); /* * Header First */ /* Set BSSID address */ MAC_COPY(pBuffer->hdr.BSSID, pPrimarySite->bssid); /* Build Source address */ param.paramType = CTRL_DATA_MAC_ADDRESS; ctrlData_getParam(pSiteMgr->hCtrlData, ¶m); MAC_COPY(pBuffer->hdr.TA, param.content.ctrlDataDeviceMacAddress); /* ** Building the Frame Control word (16 bits) ** --------------------------------------------- ** Type = Control ** SubType = Power Save (PS) POLL, */ fc = DOT11_FC_PS_POLL; /* ** setting the Power Management bit in the Frame control field ** to be "Power Save mode" */ fc |= (0x1 << DOT11_FC_PWR_MGMT_SHIFT); COPY_WLAN_WORD(&pBuffer->hdr.fc, &fc); /* copy with endianess handling. */ /* ** Association ID ** ----------------- */ tTwdParam.paramType = TWD_AID_PARAM_ID; TWD_GetParam(pSiteMgr->hTWD, &tTwdParam); /* AID should have its two MSB bit Set to "1" */ pBuffer->hdr.AID = tTwdParam.content.halCtrlAid | 0xC000; size = sizeof(dot11_PsPollFrameHeader_t); pTemplate->len = size; return TI_OK; }
void sendDataPacket (TI_HANDLE hOs) { TI_UINT32 i; TTxCtrlBlk * pPktCtrlBlk; TI_UINT8 * pPktBuf; TEthernetHeader tEthHeader; char SrcBssid[6] = {0x88,0x88,0x88,0x88,0x88,0x88}; char DesBssid[6] = {0x22,0x22,0x22,0x22,0x22,0x22}; /* Allocate a TxCtrlBlk for the Tx packet and save timestamp, length and packet handle */ pPktCtrlBlk = TWD_txCtrlBlk_Alloc (tmp_hTWD); if( NULL == pPktCtrlBlk ) { os_printf("\n sendDataPacket() : pPktCtrlBlk returned as NULL from TWD_txCtrlBlk_Alloc() "); return; } pPktCtrlBlk->tTxDescriptor.startTime = os_timeStampMs (hOs); pPktCtrlBlk->tTxDescriptor.length = (TI_UINT16)packetLength + ETHERNET_HDR_LEN; pPktCtrlBlk->tTxDescriptor.tid = 0; pPktCtrlBlk->tTxPktParams.uPktType = TX_PKT_TYPE_ETHER; /* Allocate buffer with headroom for getting the IP header in a 4-byte aligned address */ pPktBuf = txCtrl_AllocPacketBuffer (tmp_hTxCtrl, pPktCtrlBlk, packetLength + ETHERNET_HDR_LEN + 2); /* Prepare Ethernet header */ tEthHeader.type = HTOWLANS(ETHERTYPE_IP); MAC_COPY (tEthHeader.src, SrcBssid); MAC_COPY (tEthHeader.dst, DesBssid); if( pPktBuf ) { os_memoryCopy (hOs, pPktBuf + 2, &tEthHeader, ETHERNET_HDR_LEN); /* Build BDL */ BUILD_TX_TWO_BUF_PKT_BDL (pPktCtrlBlk, pPktBuf + 2, ETHERNET_HDR_LEN, pPktBuf + 2 + ETHERNET_HDR_LEN, packetLength) /* Fill data buffer with incremented numbers */ for (i = 0; i < packetLength; i++) { *(pPktBuf + 2 + ETHERNET_HDR_LEN + i) = i; } } else {
/** * \fn wlanDrvIf_SetMacAddress * \brief Set STA MAC address * * Called by DrvMain from init process. * Copies STA MAC address to the network interface structure. * * \note * \param hOs - The driver object handle * \param pMacAddr - The STA MAC address * \return TI_OK * \sa wlanDrvIf_LoadFiles */ void wlanDrvIf_SetMacAddress (TI_HANDLE hOs, TI_UINT8 *pMacAddr) { TWlanDrvIfObj *drv = (TWlanDrvIfObj *)hOs; /* Copy STA MAC address to the network interface structure */ MAC_COPY (drv->netdev->dev_addr, pMacAddr); }
TI_STATUS keyDeriveTkip_derive(struct _keyDerive_t * pKeyDerive, encodedKeyMaterial_t * pEncodedKey) { TI_STATUS status; TSecurityKeys key; keyMaterialTkip_t *keyMaterialTkip; if (pEncodedKey == NULL) { return TI_NOK; } key.keyType = KEY_TKIP; key.keyIndex = (TI_UINT8) pEncodedKey->keyId; key.encLen = KEY_DERIVE_TKIP_ENC_LEN; /* Note: Reduce 2 bytes from the size of keyMaterialTkip_t in the following check, because it is added as padding at the end due to the OS_PACKED removal. */ if (pEncodedKey->keyLen < (sizeof(keyMaterialTkip_t) - 2)) { TRACE1(pKeyDerive->hReport, REPORT_SEVERITY_ERROR, "KEY_DERIVE_TKIP: ERROR: wrong key length %d !!!\n", pEncodedKey->keyLen); return TI_NOK; } keyMaterialTkip = (keyMaterialTkip_t *) pEncodedKey->pData; /* Copy encryption key */ os_memoryCopy(pKeyDerive->hOs, (void *)key.encKey, (void *)keyMaterialTkip->encKey, KEY_DERIVE_TKIP_ENC_LEN); if (pEncodedKey->keyId & 0x10000000) { /* Copy MIC RX */ os_memoryCopy(pKeyDerive->hOs, (void *)key.micTxKey, (void *)keyMaterialTkip->micRxKey, KEY_DERIVE_TKIP_MIC_LEN); /* Copy MIC RX */ os_memoryCopy(pKeyDerive->hOs, (void *)key.micRxKey, (void *)keyMaterialTkip->micTxKey, KEY_DERIVE_TKIP_MIC_LEN); } else { /* Copy MIC RX */ os_memoryCopy(pKeyDerive->hOs, (void *)key.micRxKey, (void *)keyMaterialTkip->micRxKey, KEY_DERIVE_TKIP_MIC_LEN); /* Copy MIC RX */ os_memoryCopy(pKeyDerive->hOs, (void *)key.micTxKey, (void *)keyMaterialTkip->micTxKey, KEY_DERIVE_TKIP_MIC_LEN); } /* Copy MAC address key */ MAC_COPY(key.macAddress, keyMaterialTkip->macAddress); /* Copy RSC */ os_memoryCopy(pKeyDerive->hOs, (void *)key.keyRsc, (void *)keyMaterialTkip->keyRSC, KEY_RSC_LEN); status = pKeyDerive->pMainKeys->setKey(pKeyDerive->pMainKeys, &key); if (status == TI_OK) { os_memoryCopy(pKeyDerive->hOs, &pKeyDerive->key, pEncodedKey, sizeof(encodedKeyMaterial_t)); } return status; }
/** * * mainKeySmLogMessage * * \b Description: * * Prints Log messge.\n * Start session timer. * * \b ARGS: * * I - pData - station control block \n * * \b RETURNS: * * TI_OK on success, TI_NOK otherwise. */ TI_STATUS mainKeys_smTimeOut(void* data) { OS_802_11_AUTHENTICATION_REQUEST *request; TI_UINT8 AuthBuf[sizeof(TI_UINT32) + sizeof(OS_802_11_AUTHENTICATION_REQUEST)]; paramInfo_t param; TI_STATUS status; struct _mainKeys_t *pMainKeys = (struct _mainKeys_t *)data; TRACE1(pMainKeys->hReport, REPORT_SEVERITY_INFORMATION, "MAIN_KEY_SM: TRAP: Session Timeout for station , mainKeysTimeoutCounter=%d\n", pMainKeys->mainKeysTimeoutCounter); request = (OS_802_11_AUTHENTICATION_REQUEST *)(AuthBuf + sizeof(TI_UINT32)); request->Length = sizeof(OS_802_11_AUTHENTICATION_REQUEST); param.paramType = CTRL_DATA_CURRENT_BSSID_PARAM; status = ctrlData_getParam(pMainKeys->hCtrlData, ¶m); if (status != TI_OK) { return TI_NOK; } TRACE1(pMainKeys->hReport, REPORT_SEVERITY_INFORMATION, "current station is banned from the roaming candidates list for %d Ms\n", RSN_MAIN_KEYS_SESSION_TIMEOUT); rsn_banSite(pMainKeys->hRsn, param.content.ctrlDataCurrentBSSID, RSN_SITE_BAN_LEVEL_FULL, RSN_MAIN_KEYS_SESSION_TIMEOUT); /* mainKeysTimeoutCounter is a boolean variable, With states: */ /* TI_TRUE - It is a Timeout Association Event */ /* TI_FALSE - It is a Media specific Event */ if (!pMainKeys->mainKeysTimeoutCounter) { /* Fill Media specific indication fields and send to OS/User */ MAC_COPY (request->BSSID, param.content.ctrlDataCurrentBSSID); request->Flags = OS_802_11_REQUEST_REAUTH; *(TI_UINT32*)AuthBuf = os802_11StatusType_Authentication; TRACE1(pMainKeys->hReport, REPORT_SEVERITY_INFORMATION, " %d Ms\n",RSN_MAIN_KEYS_SESSION_TIMEOUT); EvHandlerSendEvent(pMainKeys->hEvHandler, IPC_EVENT_MEDIA_SPECIFIC, (TI_UINT8*)AuthBuf, sizeof(TI_UINT32) + sizeof(OS_802_11_AUTHENTICATION_REQUEST)); tmr_StartTimer (pMainKeys->hSessionTimer, mainKeys_sessionTimeout, (TI_HANDLE)pMainKeys, pMainKeys->keysTimeout, TI_FALSE); pMainKeys->mainKeysTimeoutCounter = TI_TRUE; } else { pMainKeys->mainKeysTimeoutCounter = TI_FALSE; rsn_reportAuthFailure(pMainKeys->hRsn, RSN_AUTH_STATUS_TIMEOUT); conn_reportRsnStatus(pMainKeys->hConn, (mgmtStatus_e)STATUS_SECURITY_FAILURE); } return TI_OK; }
/**************************************************************************** * cmdBld_CfgGroupAddressTable() **************************************************************************** * DESCRIPTION: Sets the Group table according to the given configuration. * * OUTPUT: None * * RETURNS: TI_OK or TI_NOK ****************************************************************************/ TI_STATUS cmdBld_CfgGroupAddressTable (TI_HANDLE hCmdBld, TI_UINT8 uNumGroupAddr, TMacAddr *pGroupAddr, TI_BOOL bEnabled, void *fCb, TI_HANDLE hCb) { TCmdBld *pCmdBld = (TCmdBld *)hCmdBld; TI_UINT32 i; if (uNumGroupAddr > MAX_MULTICAST_GROUP_ADDRS) { TRACE1(pCmdBld->hReport, REPORT_SEVERITY_ERROR, "cmdBld_CfgGroupAddressTable: numGroupAddrs=%d\n", uNumGroupAddr); return PARAM_VALUE_NOT_VALID; } if (NULL == pGroupAddr) { TRACE2(pCmdBld->hReport, REPORT_SEVERITY_ERROR, "cmdBld_CfgGroupAddressTable: numGroupAddrs=%d Group_addr=0x%x !!!\n", uNumGroupAddr, pGroupAddr); return PARAM_VALUE_NOT_VALID; } /* Keeps the parameters in the db */ DB_WLAN(hCmdBld).numGroupAddrs = uNumGroupAddr; DB_WLAN(hCmdBld).isMacAddrFilteringnabled = bEnabled; for (i = 0; i < uNumGroupAddr; i++) { MAC_COPY (DB_WLAN(hCmdBld).aGroupAddr[i], *(pGroupAddr + i)); } return cmdBld_CfgIeGroupAdressTable (hCmdBld, uNumGroupAddr, pGroupAddr, bEnabled, fCb, hCb); }
/** * \fn cmdBld_CfgSetFwHtCapabilities * \brief set the current AP HT Capabilities to the FW. * * \note * \return TI_OK on success or TI_NOK on failure * \sa */ TI_STATUS cmdBld_CfgSetFwHtCapabilities (TI_HANDLE hCmdBld, TI_UINT32 uHtCapabilites, TMacAddr tMacAddress, TI_UINT8 uAmpduMaxLeng, TI_UINT8 uAmpduMinSpac, void *fCb, TI_HANDLE hCb) { CMD_BLD_MARK_INIT_SEQUENCE_CMD_AS_VALID(hCmdBld, __CFG_HT_CAPABILITIES) DB_BSS(hCmdBld).bHtCap = TI_TRUE; DB_BSS(hCmdBld).uHtCapabilites = uHtCapabilites; MAC_COPY ((DB_BSS(hCmdBld).tMacAddress), tMacAddress); DB_BSS(hCmdBld).uAmpduMaxLeng = uAmpduMaxLeng; DB_BSS(hCmdBld).uAmpduMinSpac = uAmpduMinSpac; return cmdBld_CfgIeSetFwHtCapabilities (hCmdBld, uHtCapabilites, tMacAddress, uAmpduMaxLeng, uAmpduMinSpac, fCb, hCb); }
/************************************************************************ * buildQosNullDataTemplate * ************************************************************************ DESCRIPTION: This function build a qos null data template performs the following: - Build a template & set the template len, the template type is set in the site mgr INPUT: pSiteMgr - Handle to site manager pTemplate - Pointer to the template structure pSsid - Desired SSID OUTPUT: RETURN: TI_OK ************************************************************************/ TI_STATUS buildQosNullDataTemplate(siteMgr_t * pSiteMgr, TSetTemplate * pTemplate, TI_UINT8 userPriority) { paramInfo_t param; TI_UINT32 size; QosNullDataTemplate_t *pBuffer = (QosNullDataTemplate_t *) pTemplate->ptr; siteEntry_t *pPrimarySite = pSiteMgr->pSitesMgmtParams->pPrimarySite; TI_UINT16 fc; TI_UINT16 qosControl; os_memoryZero(pSiteMgr->hOs, pBuffer, sizeof(QosNullDataTemplate_t)); /* * Header First */ /* Set destination address */ if (pPrimarySite) { MAC_COPY(pBuffer->hdr.address1, pPrimarySite->bssid); /* Set BSSID address */ MAC_COPY(pBuffer->hdr.address3, pPrimarySite->bssid); } else { TRACE0(pSiteMgr->hReport, REPORT_SEVERITY_INFORMATION, "No Primary site so cannot fill QosNullData template\n"); } /* Build Source address */ param.paramType = CTRL_DATA_MAC_ADDRESS; ctrlData_getParam(pSiteMgr->hCtrlData, ¶m); MAC_COPY(pBuffer->hdr.address2, param.content.ctrlDataDeviceMacAddress); fc = DOT11_FC_DATA_NULL_QOS | (1 << DOT11_FC_TO_DS_SHIFT); COPY_WLAN_WORD(&pBuffer->hdr.fc, &fc); /* copy with endianess handling. */ qosControl = (TI_UINT16) userPriority; qosControl <<= QOS_CONTROL_UP_SHIFT; COPY_WLAN_WORD(&pBuffer->hdr.qosControl, &qosControl); /* copy with endianess handling. */ size = WLAN_QOS_HDR_LEN; pTemplate->len = size; return TI_OK; }
/** * \fn sme_SetDefaults * \brief Set default values to the SME (and the SM and scan result table) * * Set default values to the SME (and the SM and scan result table) * * \param hSme - handle to the SME object * \param pInitParams - values read from registry / ini file * \return None * \sa sme_Create, sme_Init */ void sme_SetDefaults (TI_HANDLE hSme, TSmeModifiedInitParams *pModifiedInitParams, TSmeInitParams *pInitParams) { TSme *pSme = (TSme*)hSme; /* copy init params */ os_memoryCopy (pSme->hOS, &(pSme->tInitParams), pInitParams, sizeof (TSmeInitParams)); /* initialize SME varaibles */ pSme->bRadioOn = pModifiedInitParams->bRadioOn; pSme->eConnectMode = pModifiedInitParams->eConnectMode; if (CONNECT_MODE_AUTO == pSme->eConnectMode) { pSme->hScanResultTable = pSme->hSmeScanResultTable; } else if (CONNECT_MODE_MANUAL == pSme->eConnectMode) { pSme->hScanResultTable = pSme->hScanCncnScanResulTable; } pSme->eBssType = pModifiedInitParams->eDesiredBssType; MAC_COPY (pSme->tBssid, pModifiedInitParams->tDesiredBssid); pSme->tSsid.len = pModifiedInitParams->tDesiredSsid.len; if ( pSme->tSsid.len > MAX_SSID_LEN ) { TRACE2( pSme->hReport, REPORT_SEVERITY_ERROR, "sme_SetDefaults. pSme->tSsid.len=%d exceeds the limit %d\n", pSme->tSsid.len, MAX_SSID_LEN); pSme->tSsid.len = MAX_SSID_LEN; } os_memoryCopy (pSme->hOS, &(pSme->tSsid.str[ 0 ]), &(pModifiedInitParams->tDesiredSsid.str[ 0 ]), pSme->tSsid.len); if (OS_802_11_SSID_JUNK (pSme->tSsid.str, pSme->tSsid.len)) { pSme->eSsidType = SSID_TYPE_INVALID; pSme->bConnectRequired = TI_FALSE; } else if (0 == pSme->tSsid.len) { pSme->eSsidType = SSID_TYPE_ANY; pSme->bConnectRequired = TI_TRUE; } else { pSme->eSsidType = SSID_TYPE_SPECIFIC; pSme->bConnectRequired = TI_TRUE; } pSme->eLastConnectMode = CONNECT_MODE_AUTO; pSme->bAuthSent = TI_FALSE; pSme->bReselect = TI_FALSE; pSme->uScanCount = 0; pSme->bRunning = TI_FALSE; /* Initialize the SME state-machine */ genSM_SetDefaults (pSme->hSmeSm, SME_SM_NUMBER_OF_STATES, SME_SM_NUMBER_OF_EVENTS, (TGenSM_matrix)tSmMatrix, SME_SM_STATE_IDLE, "SME SM", uStateDescription, uEventDescription, __FILE_ID__); /* register scan conecntrator CB */ scanCncn_RegisterScanResultCB (pSme->hScanCncn, SCAN_SCC_DRIVER, sme_ScanResultCB, hSme); }
/**************************************************************************** * cmdBld_CmdIeSetKey() **************************************************************************** * DESCRIPTION: Construct the SetKey command fileds and send it to the mailbox * * INPUTS: * Action - add/remove key * MacAddr - relevant only for mapping keys * KeySize - key size * KeyType - default/mapping/TKIP * KeyId - relevant only for default keys * Key - key data * * OUTPUT: None * * RETURNS: TI_OK or TI_NOK ****************************************************************************/ TI_STATUS cmdBld_CmdIeSetKey (TI_HANDLE hCmdBld, TI_UINT32 action, TI_UINT8 *pMacAddr, TI_UINT32 uKeySize, TI_UINT32 uKeyType, TI_UINT32 uKeyId, TI_UINT8 *pKey, TI_UINT32 uSecuritySeqNumLow, TI_UINT32 uSecuritySeqNumHigh, void *fCb, TI_HANDLE hCb) { TCmdBld *pCmdBld = (TCmdBld *)hCmdBld; SetKey_t AcxCmd_SetKey; SetKey_t *pCmd = &AcxCmd_SetKey; os_memoryZero (pCmdBld->hOs, (void *)pCmd, sizeof(*pCmd)); MAC_COPY (pCmd->addr, pMacAddr); if (uKeySize > MAX_KEY_SIZE) { os_memoryCopy (pCmdBld->hOs, (void *)pCmd->key, (void *)pKey, MAX_KEY_SIZE); } else { os_memoryCopy (pCmdBld->hOs, (void *)pCmd->key, (void *)pKey, uKeySize); } pCmd->action = ENDIAN_HANDLE_WORD((TI_UINT16)action); pCmd->keySize = (TI_UINT8)uKeySize; pCmd->type = (TI_UINT8)uKeyType; pCmd->id = (TI_UINT8)uKeyId; pCmd->ssidProfile = 0; /* * Preserve TKIP/AES security sequence number after recovery. * Note that our STA Tx is currently using only one sequence-counter * for all ACs (unlike the Rx which is separated per AC). */ pCmd->AcSeqNum16[0] = ENDIAN_HANDLE_WORD((TI_UINT16)uSecuritySeqNumLow); pCmd->AcSeqNum16[1] = 0; pCmd->AcSeqNum16[2] = 0; pCmd->AcSeqNum16[3] = 0; pCmd->AcSeqNum32[0] = ENDIAN_HANDLE_LONG(uSecuritySeqNumHigh); pCmd->AcSeqNum32[1] = 0; pCmd->AcSeqNum32[2] = 0; pCmd->AcSeqNum32[3] = 0; TRACE6(pCmdBld->hReport, REPORT_SEVERITY_INFORMATION, "Addr: %02x:%02x:%02x:%02x:%02x:%02x\n", pCmd->addr[0],pCmd->addr[1],pCmd->addr[2],pCmd->addr[3],pCmd->addr[4],pCmd->addr[5]); TRACE7(pCmdBld->hReport, REPORT_SEVERITY_INFORMATION, "Action=%x,keySize=0x%x,type=%x, id=%x, ssidProfile=%x, AcSeqNum16[0]=%x, AcSeqNum32[0]=%x\n", pCmd->action,pCmd->keySize, pCmd->type,pCmd->id,pCmd->ssidProfile,pCmd->AcSeqNum16[0],pCmd->AcSeqNum32[0] ); return cmdQueue_SendCommand (pCmdBld->hCmdQueue, CMD_SET_KEYS, (char *)pCmd, sizeof(*pCmd), fCb, hCb, NULL); }
/** * \fn sme_SelectRsnMatch * \brief Checks if the configured scurity settings match those of a site * * Checks if the configured scurity settings match those of a site * * \param hSme - handle to the SME object * \param pCurrentSite - the site to check * \return TI_TRUE if site matches RSN settings, TI FALSE if it doesn't * \sa sme_Select */ TI_BOOL sme_SelectRsnMatch (TI_HANDLE hSme, TSiteEntry *pCurrentSite) { TSme *pSme = (TSme*)hSme; TRsnData tRsnData; dot11_RSN_t *pRsnIe; TI_UINT8 uRsnIECount=0; TI_UINT8 uCurRsnData[255]; TI_UINT32 uLength = 0; TI_UINT32 uMetric; TRsnSiteParams tRsnSiteParams; tRsnSiteParams.bssType = pCurrentSite->bssType; MAC_COPY(tRsnSiteParams.bssid, pCurrentSite->bssid); tRsnSiteParams.pHTCapabilities = &pCurrentSite->tHtCapabilities; tRsnSiteParams.pHTInfo = &pCurrentSite->tHtInformation; /* copy all RSN IE's */ pRsnIe = pCurrentSite->pRsnIe; while ((uLength < pCurrentSite->rsnIeLen) && (uRsnIECount < MAX_RSN_IE)) { if (uLength + 2 + pRsnIe->hdr[ 1 ] > sizeof (uCurRsnData)) { TRACE4( pSme->hReport, REPORT_SEVERITY_ERROR, "sme_SelectRsnMatch. uRsnIECount=%d, uLength=%d; required copy of %d bytes exceeds the buffer limit %d\n", uRsnIECount, uLength, pRsnIe->hdr[ 1 ] +2, sizeof (uCurRsnData)); handleRunProblem(PROBLEM_BUF_SIZE_VIOLATION); return TI_FALSE; } uCurRsnData[ 0 + uLength ] = pRsnIe->hdr[ 0 ]; uCurRsnData[ 1 + uLength ] = pRsnIe->hdr[ 1 ]; os_memoryCopy (pSme->hOS, &uCurRsnData[ 2 + uLength ], pRsnIe->rsnIeData, pRsnIe->hdr[ 1 ]); uLength += pRsnIe->hdr[ 1 ] + 2; pRsnIe += 1; uRsnIECount++; } /* sanity check - make sure RSN IE's size is not too big */ if (uLength < pCurrentSite->rsnIeLen) { TRACE2(pSme->hReport, REPORT_SEVERITY_ERROR , "sme_SelectRsnMatch, RSN IE is too long: rsnIeLen=%d, MAX_RSN_IE=%d\n", pCurrentSite->rsnIeLen, MAX_RSN_IE); } /* call the RSN to evaluate the site */ tRsnData.pIe = (pCurrentSite->rsnIeLen == 0) ? NULL : uCurRsnData; tRsnData.ieLen = pCurrentSite->rsnIeLen; tRsnData.privacy = pCurrentSite->privacy; if (rsn_evalSite (pSme->hRsn, &tRsnData, &tRsnSiteParams , &uMetric) != TI_OK) { /* no match */ return TI_FALSE; } else { /* match! */ return TI_TRUE; } }
/**************************************************************************** * cmdBld_CmdIeSetKey() **************************************************************************** * DESCRIPTION: Construct the SetKey command fileds and send it to the mailbox * * INPUTS: * Action - add/remove key * MacAddr - relevant only for mapping keys * KeySize - key size * KeyType - default/mapping/TKIP * KeyId - relevant only for default keys * Key - key data * * OUTPUT: None * * RETURNS: TI_OK or TI_NOK ****************************************************************************/ TI_STATUS cmdBld_CmdIeSetKey (TI_HANDLE hCmdBld, TI_UINT32 action, TI_UINT8 *pMacAddr, TI_UINT32 uKeySize, TI_UINT32 uKeyType, TI_UINT32 uKeyId, TI_UINT8 *pKey, TI_UINT32 uSecuritySeqNumLow, TI_UINT32 uSecuritySeqNumHigh, void *fCb, TI_HANDLE hCb) { TCmdBld *pCmdBld = (TCmdBld *)hCmdBld; SetKey_t AcxCmd_SetKey; SetKey_t *pCmd = &AcxCmd_SetKey; os_memoryZero (pCmdBld->hOs, (void *)pCmd, sizeof(*pCmd)); MAC_COPY (pCmd->addr, pMacAddr); if (uKeySize > MAX_KEY_SIZE) { os_memoryCopy (pCmdBld->hOs, (void *)pCmd->key, (void *)pKey, MAX_KEY_SIZE); } else { os_memoryCopy (pCmdBld->hOs, (void *)pCmd->key, (void *)pKey, uKeySize); } pCmd->action = ENDIAN_HANDLE_WORD((TI_UINT16)action); pCmd->keySize = (TI_UINT8)uKeySize; pCmd->type = (TI_UINT8)uKeyType; pCmd->id = (TI_UINT8)uKeyId; pCmd->ssidProfile = 0; /* * Preserve TKIP/AES security sequence number after recovery. * If not in reconfig set to 0 so the FW will ignore it and keep its own number. * Note that our STA Tx is currently using only one sequence-counter * for all ACs (unlike the Rx which is separated per AC). */ if (pCmdBld->bReconfigInProgress == TI_FALSE) { uSecuritySeqNumLow = uSecuritySeqNumHigh = 0; } pCmd->AcSeqNum16[0] = ENDIAN_HANDLE_WORD((TI_UINT16)uSecuritySeqNumLow); pCmd->AcSeqNum16[1] = 0; pCmd->AcSeqNum16[2] = 0; pCmd->AcSeqNum16[3] = 0; pCmd->AcSeqNum32[0] = ENDIAN_HANDLE_LONG(uSecuritySeqNumHigh); pCmd->AcSeqNum32[1] = 0; pCmd->AcSeqNum32[2] = 0; pCmd->AcSeqNum32[3] = 0; return cmdQueue_SendCommand (pCmdBld->hCmdQueue, CMD_SET_KEYS, (char *)pCmd, sizeof(*pCmd), fCb, hCb, NULL); }
/***************************************************************************** * Function name: App_DevicesAllocCreate * Description : This function creates Enet and IMA devices over the Enet * ports created earlier. Also interworking host device is created for * the host generation and termination of the packets. * Input params: None * Output params: None * Return val : None *****************************************************************************/ void App_DevicesAllocCreate (void) { /* Create device on Enet1 */ MAC_COPY (device_enet_cfg.mac_addr, wt_mac_enet1); h_device_enet1 = WP_DeviceCreate (h_port_enet1, WP_PHY (0), WP_DEVICE_ENET, &device_enet_cfg); App_TerminateOnError (h_device_enet1, "WP_DeviceCreate() Enet1"); /* Create device on Enet2 */ device_enet_cfg.loopbackmode = WP_ENET_NORMAL; /* no loop back */ MAC_COPY (device_enet_cfg.mac_addr, wt_mac_enet2); h_device_enet2 = WP_DeviceCreate (h_port_enet2, WP_PHY (0), WP_DEVICE_ENET, &device_enet_cfg); App_TerminateOnError (h_device_enet2, "WP_DeviceCreate() Enet2"); /* Create an IW Host Device */ h_dev_iwhost = WP_DeviceCreate (h_port_iwhost, 0, WP_DEVICE_IW_HOST, NULL); App_TerminateOnError (h_dev_iwhost, "WP_DeviceCreate() IW Host"); }
/** * \fn cmdBld_CfgSetBaInitiator * \brief configure BA session initiator\receiver parameters setting in the FW. * * \note * \return TI_OK on success or TI_NOK on failure * \sa */ TI_STATUS cmdBld_CfgSetBaSession (TI_HANDLE hCmdBld, InfoElement_e eBaType, TI_UINT8 uTid, TI_UINT8 uState, TMacAddr tRa, TI_UINT16 uWinSize, TI_UINT16 uInactivityTimeout, void *fCb, TI_HANDLE hCb) { if (ACX_BA_SESSION_INITIATOR_POLICY == eBaType) { DB_BSS(hCmdBld).bBaInitiator[uTid] = TI_TRUE; DB_BSS(hCmdBld).tBaSessionInitiatorPolicy[uTid].uTid = uTid; DB_BSS(hCmdBld).tBaSessionInitiatorPolicy[uTid].uPolicy = uState; MAC_COPY ((DB_BSS(hCmdBld).tBaSessionInitiatorPolicy[uTid].aMacAddress),tRa); DB_BSS(hCmdBld).tBaSessionInitiatorPolicy[uTid].uWinSize = uWinSize; DB_BSS(hCmdBld).tBaSessionInitiatorPolicy[uTid].uInactivityTimeout = uInactivityTimeout; } else { DB_BSS(hCmdBld).bBaResponder[uTid] = TI_TRUE; DB_BSS(hCmdBld).tBaSessionResponderPolicy[uTid].uTid = uTid; DB_BSS(hCmdBld).tBaSessionResponderPolicy[uTid].uPolicy = uState; MAC_COPY ((DB_BSS(hCmdBld).tBaSessionResponderPolicy[uTid].aMacAddress),tRa); DB_BSS(hCmdBld).tBaSessionResponderPolicy[uTid].uWinSize = uWinSize; DB_BSS(hCmdBld).tBaSessionResponderPolicy[uTid].uInactivityTimeout = uInactivityTimeout; } CMD_BLD_MARK_INIT_SEQUENCE_CMD_AS_VALID(hCmdBld,__CFG_BA_SET_SESSION); return cmdBld_CfgIeSetBaSession (hCmdBld, eBaType, uTid, uState, tRa, uWinSize, uInactivityTimeout, fCb, hCb); }
/************************************************************************ * buildDisconnTemplate * ************************************************************************ DESCRIPTION: This function build a Death/Disassoc template to set to the HAL when joining an infrastructure network performs the following: - Build a template & set the template len, the template type is set in the site mgr INPUT: pSiteMgr - Handle to site manager pTemplate - Pointer to the template structure OUTPUT: RETURN: TI_OK ************************************************************************/ TI_STATUS buildDisconnTemplate(siteMgr_t * pSiteMgr, TSetTemplate * pTemplate) { paramInfo_t param; TI_UINT32 size; disconnTemplate_t *pBuffer = (disconnTemplate_t *) pTemplate->ptr; siteEntry_t *pPrimarySite = pSiteMgr->pSitesMgmtParams->pPrimarySite; TI_UINT16 fc; os_memoryZero(pSiteMgr->hOs, pBuffer, sizeof(disconnTemplate_t)); /* * Header First */ /* Set destination address */ MAC_COPY(pBuffer->hdr.DA, pPrimarySite->bssid); /* Set BSSID address */ MAC_COPY(pBuffer->hdr.BSSID, pPrimarySite->bssid); /* Build Source address */ param.paramType = CTRL_DATA_MAC_ADDRESS; ctrlData_getParam(pSiteMgr->hCtrlData, ¶m); MAC_COPY(pBuffer->hdr.SA, param.content.ctrlDataDeviceMacAddress); fc = DOT11_FC_DISASSOC; /* will be change by firmware to DOT11_FC_DEAUTH if needed */ COPY_WLAN_WORD(&pBuffer->hdr.fc, &fc); /* copy with endianess handling. */ pBuffer->disconnReason = 0; /* filled by firmware */ size = sizeof(disconnTemplate_t); pTemplate->len = size; return TI_OK; }
/*********************************************************************** * txCtrlServ_buildNullFrame *********************************************************************** DESCRIPTION: Build Null frame Function. The function does the following: - Builds Null Data Frame, considering current QoS mode. INPUT: hTxCtrl - Tx Ctrl module handle (the txServ uses the txCtrl object!!). pFrame - A pointer to a buffer where the frame should be stored pLength - A pointer to a placeholder for the frame length ************************************************************************/ TI_STATUS txCtrlServ_buildNullFrame(TI_HANDLE hTxCtrl, TI_UINT8* pFrame, TI_UINT32* pLength) { txCtrl_t *pTxCtrl = (txCtrl_t *)hTxCtrl; EHeaderConvertMode qosMode = pTxCtrl->headerConverMode; dot11_header_t *pHeader; /* Note : there is no body for null frame */ TI_STATUS status; TI_UINT16 fc; pHeader = (dot11_header_t*)(pFrame); if (qosMode == HDR_CONVERT_QOS) { *pLength = WLAN_QOS_HDR_LEN; SET_WLAN_WORD(&pHeader->qosControl, 0); /* We are using user priority 0 (BE) so no need for shift and endianess */ } else { *pLength = WLAN_HDR_LEN; } /* Set the Frame Control with Null Data type, QoS or non-QoS */ if (qosMode == HDR_CONVERT_QOS) fc = DOT11_FC_DATA_NULL_QOS | DOT11_FC_TO_DS; else fc = DOT11_FC_DATA_NULL_FUNCTION | DOT11_FC_TO_DS; COPY_WLAN_WORD(&pHeader->fc, &fc); /* copy with endianess handling. */ /* copy destination mac address */ status = ctrlData_getParamBssid(pTxCtrl->hCtrlData, CTRL_DATA_CURRENT_BSSID_PARAM, pHeader->address3); if (status != TI_OK) { return TI_NOK; } /* copy source mac address */ status = ctrlData_getParamBssid(pTxCtrl->hCtrlData, CTRL_DATA_MAC_ADDRESS, pHeader->address2); if (status != TI_OK) { return TI_NOK; } /* copy BSSID (destination mac address) */ MAC_COPY (pHeader->address1, pHeader->address3); return status; }
TI_STATUS keyDeriveAes_derive(struct _keyDerive_t *pKeyDerive, encodedKeyMaterial_t *pEncodedKey) { TI_STATUS status; TSecurityKeys key; keyMaterialAes_t *keyMaterialAes = NULL; /* Small verification */ if ((pEncodedKey==NULL) || (pKeyDerive == NULL)) { return TI_NOK; } /* Note: Reduce 2 bytes from the size of keyMaterialAes_t in the following check, because it is added as padding at the end due to the OS_PACKED removal. */ if ( pEncodedKey->keyLen < (sizeof(keyMaterialAes_t) - 2) ) { TRACE1(pKeyDerive->hReport, REPORT_SEVERITY_ERROR, "KEY_DERIVE_AES: ERROR: wrong key length %d !!!\n", pEncodedKey->keyLen); return TI_NOK; } keyMaterialAes = (keyMaterialAes_t*)pEncodedKey->pData; /* Fill security key structure */ os_memoryZero(pKeyDerive->hOs, &key, sizeof(TSecurityKeys)); key.keyType = KEY_AES; key.keyIndex = (TI_UINT8)pEncodedKey->keyId; key.encLen = DERIVE_AES_KEY_LEN; os_memoryCopy(pKeyDerive->hOs, (void *)key.encKey, pEncodedKey->pData + MAC_ADDR_LEN+KEY_RSC_LEN, DERIVE_AES_KEY_LEN); /* Copy MAC address key */ MAC_COPY (key.macAddress, keyMaterialAes->macAddress); /* Copy RSC */ os_memoryCopy(pKeyDerive->hOs, (void *)key.keyRsc, (void *)keyMaterialAes->keyRSC, KEY_RSC_LEN); status = pKeyDerive->pMainKeys->setKey(pKeyDerive->pMainKeys, &key); if (status == TI_OK) { os_memoryCopy(pKeyDerive->hOs, &pKeyDerive->key, pEncodedKey, sizeof(encodedKeyMaterial_t)); } return status; }
/** * \fn txDataQ_LinkMacAdd * \brief Set MAC address for the link id. * * \return void * \sa txDataQ_LinkMacAdd */ TI_STATUS txDataQ_LinkMacAdd (TI_HANDLE hTxDataQ, TI_UINT32 uHlid, TMacAddr tMacAddr) { TTxDataQ *pTxDataQ = (TTxDataQ *)hTxDataQ; if (uHlid >= LINK_MAC_TABLE_SIZE) { WLAN_OS_REPORT(("%s: illegal uHlid = %d\n", __FUNCTION__, uHlid)); return TI_NOK; } /* Enter critical section to protect links data */ context_EnterCriticalSection (pTxDataQ->hContext); pTxDataQ->aLinkMac[uHlid].uValid = TI_TRUE; MAC_COPY (pTxDataQ->aLinkMac[uHlid].tMacAddr, tMacAddr); context_LeaveCriticalSection (pTxDataQ->hContext); return TI_OK; }
TI_STATUS keyDeriveWep_remove(struct _keyDerive_t *pKeyDerive, encodedKeyMaterial_t *pEncodedKey) { TI_STATUS status; TSecurityKeys key; os_memoryZero(pKeyDerive->hOs, &key, sizeof(TSecurityKeys)); key.keyType = KEY_WEP; key.keyIndex = (TI_UINT8)pEncodedKey->keyId; key.encLen = (TI_UINT16)pKeyDerive->key.keyLen; MAC_COPY (key.macAddress, pEncodedKey->pData); status = pKeyDerive->pMainKeys->removeKey(pKeyDerive->pMainKeys, &key); if (status == TI_OK) { os_memoryZero(pKeyDerive->hOs, &pKeyDerive->key, sizeof(encodedKeyMaterial_t)); } return status; }
TI_STATUS keyDeriveAes_remove(struct _keyDerive_t *pKeyDerive, encodedKeyMaterial_t *pEncodedKey) { TI_STATUS status; TSecurityKeys key; if ((pEncodedKey==NULL) || (pKeyDerive == NULL)) { return TI_NOK; } os_memoryZero(pKeyDerive->hOs, &key, sizeof(TSecurityKeys)); key.keyType = KEY_AES; key.keyIndex = (TI_UINT8)pEncodedKey->keyId; key.encLen = DERIVE_AES_KEY_LEN; MAC_COPY (key.macAddress, pEncodedKey->pData); status = pKeyDerive->pMainKeys->removeKey(pKeyDerive->pMainKeys, &key); if (status == TI_OK) { os_memoryZero(pKeyDerive->hOs, &pKeyDerive->key, sizeof(encodedKeyMaterial_t)); } return status; }
/*********************************************************************** * txCtrlParams_setBssId *********************************************************************** DESCRIPTION: Update the BSS-ID. ************************************************************************/ void txCtrlParams_setBssId (TI_HANDLE hTxCtrl, TMacAddr *pCurrBssId) { txCtrl_t *pTxCtrl = (txCtrl_t *)hTxCtrl; MAC_COPY (pTxCtrl->currBssId, *pCurrBssId); }
/************************************************************************ * buildArpRspTemplate * ************************************************************************ DESCRIPTION: This function builds an ARP Response template to set to the HAL when joining an infrastructure network. The function's steps: - It builds the template & set the template len. - If QoS is inactive, it discards the QoS Control Field. ** The template type is set in the site mgr. INPUT: pSiteMgr - Handle to site manager. pTemplate - Pointer to the template structure. OUTPUT: RETURN: TI_OK ************************************************************************/ TI_STATUS buildArpRspTemplate(siteMgr_t * pSiteMgr, TSetTemplate * pTemplate, TIpAddr staIp) { siteEntry_t *pPrimarySite = pSiteMgr->pSitesMgmtParams->pPrimarySite; ArpRspTemplate_t *pBuffer = (ArpRspTemplate_t *) pTemplate->ptr; TI_UINT8 *ptr = (TI_UINT8 *) pBuffer; paramInfo_t param; /* To get Site and QoS params */ TI_UINT16 fc; /* Frame Control field in MAC header */ TI_UINT16 macAddrItr; TI_BOOL privacyInvoked; TI_UINT8 encryptionFieldSize, copyPayloadOffset, lenToCopy; /* Reset the buffer */ os_memoryZero(pSiteMgr->hOs, pBuffer, sizeof(ArpRspTemplate_t)); /* Turn on the To_DS bit in the Frame Control field */ fc = (1 << DOT11_FC_TO_DS_SHIFT); /* Set MAC header address fields: ----------------------------- Since To_DS is on and From_DS is off the address meaning is as follows: Address1 - BSSID Address2 - Source Address Address3 - Destination Address Address4 - Not present */ /* - Set BSSID */ if (pPrimarySite) { MAC_COPY(pBuffer->hdr.address1, pPrimarySite->bssid); } else { TRACE0(pSiteMgr->hReport, REPORT_SEVERITY_INFORMATION, "No Primary site so cannot fill QosNullData template.\n"); } /* - Set Source Address */ param.paramType = CTRL_DATA_MAC_ADDRESS; ctrlData_getParam(pSiteMgr->hCtrlData, ¶m); MAC_COPY(pBuffer->hdr.address2, param.content.ctrlDataDeviceMacAddress); /* - Set Destination Address: ARP response should be sent with broadcast DA - Set accordingly */ for (macAddrItr = 0; macAddrItr < MAC_ADDR_LEN; macAddrItr++) { pBuffer->hdr.address3[macAddrItr] = 0xFF; } pBuffer->LLC.DSAP = 0xaa; pBuffer->LLC.SSAP = 0xaa; pBuffer->LLC.Control = 0x03; /* pBuffer->LLC.Control.OUI these 3 bytes are zeroed already */ pBuffer->LLC.Type = WLANTOHS((TI_UINT16) 0x806); pBuffer->hardType = WLANTOHS((TI_UINT16) 1); pBuffer->protType = WLANTOHS((TI_UINT16) 0x800); pBuffer->hardSize = 6; pBuffer->protSize = 4; pBuffer->op = WLANTOHS((TI_UINT16) 2); /*filled as for ARP-RSP, not for RARP_RSP */ MAC_COPY(pBuffer->StaMac, pBuffer->hdr.address2); IP_COPY(pBuffer->StaIp, staIp); pTemplate->len = sizeof(ArpRspTemplate_t); /* Get encryption status */ txCtrlParams_getCurrentEncryptionInfo(pSiteMgr->hTxCtrl, &privacyInvoked, &encryptionFieldSize); /* If no encryption is used, encryptionFieldSize has garbage value */ encryptionFieldSize = privacyInvoked ? encryptionFieldSize : 0; /* Set the subtype field of fc with WEP_BIT */ fc |= (privacyInvoked << DOT11_FC_WEP_SHIFT); /* Get QoS type to check if QoS is active */ param.paramType = QOS_MNGR_ACTIVE_PROTOCOL; qosMngr_getParams(pSiteMgr->hQosMngr, ¶m); if (param.content.qosSiteProtocol == QOS_NONE) { /* QoS is not active */ copyPayloadOffset = sizeof(pBuffer->hdr.qosControl) + AES_AFTER_HEADER_FIELD_SIZE - encryptionFieldSize; /* Set the subtype field of fc with DATA value (non Qos) */ fc |= DOT11_FC_DATA; } else { /* QoS is active */ copyPayloadOffset = AES_AFTER_HEADER_FIELD_SIZE - encryptionFieldSize; /* Set the subtype field of fc with DATA_QOS */ fc |= DOT11_FC_DATA_QOS; } /* Need to copy backward to overwrite security or QoS offset */ if (copyPayloadOffset > 0) { ptr = (TI_UINT8 *) & pBuffer->LLC.DSAP; /* Copy back the actual payload without header & security */ lenToCopy = sizeof(ArpRspTemplate_t) - sizeof(dot11_header_t) - AES_AFTER_HEADER_FIELD_SIZE; os_memoryCopy(pSiteMgr->hOs, ptr - copyPayloadOffset, ptr, lenToCopy); pTemplate->len -= copyPayloadOffset; } COPY_WLAN_WORD(&pBuffer->hdr.fc, &fc); /* copy with endianess handling. */ return TI_OK; }
/************************************************************************ * buildProbeRspTemplate * ************************************************************************ DESCRIPTION: This function build a probe response template to set to the HAL when joining an IBSS network. performs the following: - Build a template & set the template len, the template type is set in the site mgr - The template is built based on the chosen site attributes NOTE: This function is used to build beacon template too. The site manager set the template type (after thos function returns) to beacon or probe response accordingly. INPUT: pSiteMgr - Handle to site manager pTemplate - Pointer to the template structure OUTPUT: RETURN: TI_OK ************************************************************************/ TI_STATUS buildProbeRspTemplate(siteMgr_t * pSiteMgr, TSetTemplate * pTemplate) { paramInfo_t param; TI_UINT8 *pBuf; probeRspTemplate_t *pBuffer = (probeRspTemplate_t *) pTemplate->ptr; siteEntry_t *pPrimarySite = pSiteMgr->pSitesMgmtParams->pPrimarySite; TI_INT32 i, j; TI_UINT32 size; dot11_RATES_t *pDot11Rates; dot11_ERP_t *pdot11Erp; TI_UINT32 len = 0, ofdmIndex = 0; TI_BOOL extRates = TI_FALSE; TI_BOOL useProtection, NonErpPresent, barkerPreambleType; TCountry *pCountry = NULL; TI_UINT8 ratesBuf[DOT11_MAX_SUPPORTED_RATES]; TI_UINT32 supportedRateMask, basicRateMask; TI_UINT16 headerFC = DOT11_FC_PROBE_RESP; os_memoryZero(pSiteMgr->hOs, pBuffer, sizeof(probeRspTemplate_t)); /* * Build WLAN Header: * ================== */ /* Set destination address */ for (i = 0; i < MAC_ADDR_LEN; i++) pBuffer->hdr.DA[i] = 0xFF; /* Set BSSID address */ MAC_COPY(pBuffer->hdr.BSSID, pPrimarySite->bssid); /* Build Source address */ param.paramType = CTRL_DATA_MAC_ADDRESS; ctrlData_getParam(pSiteMgr->hCtrlData, ¶m); MAC_COPY(pBuffer->hdr.SA, param.content.ctrlDataDeviceMacAddress); COPY_WLAN_WORD(&pBuffer->hdr.fc, &headerFC); size = sizeof(dot11_mgmtHeader_t); pBuf = (TI_UINT8 *) pBuffer->timeStamp; /* * Fixed Fields */ /* we skip the timestamp field */ size += TIME_STAMP_LEN; pBuf += TIME_STAMP_LEN; /* Beacon interval */ COPY_WLAN_WORD(pBuf, &pPrimarySite->beaconInterval); size += FIX_FIELD_LEN; pBuf += FIX_FIELD_LEN; /* capabilities */ COPY_WLAN_WORD(pBuf, &pPrimarySite->capabilities); size += FIX_FIELD_LEN; pBuf += FIX_FIELD_LEN; /* * Build Informataion Elements: * ============================ */ /* SSID IE */ /* It looks like it never happens. Anyway decided to check */ if (pPrimarySite->ssid.len > MAX_SSID_LEN) { TRACE2(pSiteMgr->hReport, REPORT_SEVERITY_ERROR, "buildProbeRspTemplate. pPrimarySite->ssid.len=%d exceeds the limit %d\n", pPrimarySite->ssid.len, MAX_SSID_LEN); handleRunProblem(PROBLEM_BUF_SIZE_VIOLATION); return TI_NOK; } ((dot11_SSID_t *) (pBuf))->hdr[0] = DOT11_SSID_ELE_ID; ((dot11_SSID_t *) (pBuf))->hdr[1] = pPrimarySite->ssid.len; os_memoryCopy(pSiteMgr->hOs, pBuf + sizeof(dot11_eleHdr_t), (void *)pPrimarySite->ssid.str, pPrimarySite->ssid.len); size += sizeof(dot11_eleHdr_t) + pPrimarySite->ssid.len; pBuf += sizeof(dot11_eleHdr_t) + pPrimarySite->ssid.len; /* Rates IE */ pDot11Rates = (dot11_RATES_t *) pBuf; if (pPrimarySite->channel == SPECIAL_BG_CHANNEL) { supportedRateMask = rate_GetDrvBitmapForDefaultSupporteSet(); basicRateMask = rate_GetDrvBitmapForDefaultBasicSet(); } else { supportedRateMask = pSiteMgr->pDesiredParams->siteMgrMatchedSuppRateMask; basicRateMask = pSiteMgr->pDesiredParams->siteMgrMatchedBasicRateMask; } rate_DrvBitmapToNetStr(supportedRateMask, basicRateMask, ratesBuf, &len, &ofdmIndex); if (pSiteMgr->siteMgrOperationalMode != DOT11_G_MODE || pSiteMgr->pDesiredParams->siteMgrUseDraftNum == DRAFT_5_AND_EARLIER || ofdmIndex == len) { pDot11Rates->hdr[0] = DOT11_SUPPORTED_RATES_ELE_ID; pDot11Rates->hdr[1] = len; os_memoryCopy(pSiteMgr->hOs, (void *)pDot11Rates->rates, ratesBuf, pDot11Rates->hdr[1]); size += pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t); pBuf += pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t); } else { pDot11Rates->hdr[0] = DOT11_SUPPORTED_RATES_ELE_ID; pDot11Rates->hdr[1] = ofdmIndex; os_memoryCopy(pSiteMgr->hOs, (void *)pDot11Rates->rates, ratesBuf, pDot11Rates->hdr[1]); size += pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t); pBuf += pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t); extRates = TI_TRUE; } /* DS IE */ ((dot11_DS_PARAMS_t *) (pBuf))->hdr[0] = DOT11_DS_PARAMS_ELE_ID; ((dot11_DS_PARAMS_t *) (pBuf))->hdr[1] = DOT11_DS_PARAMS_ELE_LEN; ((dot11_DS_PARAMS_t *) (pBuf))->currChannel = pPrimarySite->channel; size += sizeof(dot11_eleHdr_t) + DOT11_DS_PARAMS_ELE_LEN; pBuf += sizeof(dot11_eleHdr_t) + DOT11_DS_PARAMS_ELE_LEN; /* IBSS IE */ ((dot11_IBSS_PARAMS_t *) (pBuf))->hdr[0] = DOT11_IBSS_PARAMS_ELE_ID; ((dot11_IBSS_PARAMS_t *) (pBuf))->hdr[1] = DOT11_IBSS_PARAMS_ELE_LEN; COPY_WLAN_WORD(&((dot11_IBSS_PARAMS_t *) (pBuf))->atimWindow, &pPrimarySite->atimWindow); size += sizeof(dot11_eleHdr_t) + DOT11_IBSS_PARAMS_ELE_LEN; pBuf += sizeof(dot11_eleHdr_t) + DOT11_IBSS_PARAMS_ELE_LEN; /* Country IE */ param.paramType = REGULATORY_DOMAIN_ENABLED_PARAM; regulatoryDomain_getParam(pSiteMgr->hRegulatoryDomain, ¶m); if (param.content.regulatoryDomainEnabled == TI_TRUE) { /* get country IE */ param.paramType = REGULATORY_DOMAIN_COUNTRY_PARAM; regulatoryDomain_getParam(pSiteMgr->hRegulatoryDomain, ¶m); pCountry = param.content.pCountry; /* Check if a country IE was found */ if (pCountry != NULL) { *pBuf = DOT11_COUNTRY_ELE_ID; pBuf++; size++; *pBuf = (TI_UINT8) (pCountry->len); pBuf++; size++; /* Note: The country structure is not byte-aligned so it is copied as follows to ensure that there are no gaps in the output structure (pBuf). */ os_memoryCopy(pSiteMgr->hOs, pBuf, &pCountry->countryIE.CountryString, DOT11_COUNTRY_STRING_LEN); pBuf += DOT11_COUNTRY_STRING_LEN; size += DOT11_COUNTRY_STRING_LEN; /* Loop on all tripletChannels. Each item has three fields ('i' counts rows and 'j' counts bytes). */ for (i = 0, j = 0; j < (pCountry->len - DOT11_COUNTRY_STRING_LEN); i++, j += 3) { *(pBuf + j) = pCountry->countryIE.tripletChannels[i]. firstChannelNumber; *(pBuf + j + 1) = pCountry->countryIE.tripletChannels[i]. maxTxPowerLevel; *(pBuf + j + 2) = pCountry->countryIE.tripletChannels[i]. numberOfChannels; } pBuf += (pCountry->len - DOT11_COUNTRY_STRING_LEN); size += (pCountry->len - DOT11_COUNTRY_STRING_LEN); } } /*ERP IE */ siteMgr_IsERP_Needed(pSiteMgr, &useProtection, &NonErpPresent, &barkerPreambleType); if (useProtection || NonErpPresent || barkerPreambleType) { pdot11Erp = (dot11_ERP_t *) pBuf; pdot11Erp->hdr[0] = DOT11_ERP_IE_ID; pdot11Erp->hdr[1] = 1; pdot11Erp->ctrl = 0; if (NonErpPresent) pdot11Erp->ctrl |= ERP_IE_NON_ERP_PRESENT_MASK; if (useProtection) pdot11Erp->ctrl |= ERP_IE_USE_PROTECTION_MASK; if (barkerPreambleType) pdot11Erp->ctrl |= ERP_IE_BARKER_PREAMBLE_MODE_MASK; size += pdot11Erp->hdr[1] + sizeof(dot11_eleHdr_t); pBuf += pdot11Erp->hdr[1] + sizeof(dot11_eleHdr_t); } /* Extended supported rates IE */ if (extRates) { pDot11Rates = (dot11_RATES_t *) pBuf; pDot11Rates->hdr[0] = DOT11_EXT_SUPPORTED_RATES_ELE_ID; pDot11Rates->hdr[1] = len - ofdmIndex; os_memoryCopy(pSiteMgr->hOs, (void *)pDot11Rates->rates, &ratesBuf[ofdmIndex], pDot11Rates->hdr[1]); size += pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t); pBuf += pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t); } /* no need to insert RSN information elements */ pTemplate->len = size; TRACE1(pSiteMgr->hReport, REPORT_SEVERITY_INFORMATION, "Probe response template len = %d\n", size); return TI_OK; }
void create_ieee_hdr(struct packet *pkt, uint8_t type, char dsflags, uint16_t duration, struct ether_addr destination, struct ether_addr source, struct ether_addr bssid_or_transm, struct ether_addr recv, uint8_t fragment) { struct ieee_hdr *hdr = (struct ieee_hdr *) pkt->data; //If fragment, do not increase sequence if (!fragment) seqno++; seqno %= 0x1000; if (fragment > 0x0F) { printf("WARNING: Fragment number exceeded maximum of 15, resetting to 0.\n"); fragment = 0; } hdr->type = type; hdr->flags = 0x00; //if (wep) hdr->flags |= 0x40; //If somebody needs WEP, here it is :D switch (dsflags) { case 'a': //Ad Hoc, Beacons: ToDS 0 FromDS 0 Addr: DST, SRC, BSS MAC_COPY(hdr->addr1, destination); MAC_COPY(hdr->addr2, source); MAC_COPY(hdr->addr3, bssid_or_transm); break; case 'f': //From AP to station: ToDS 0 FromDS 1 Addr: DST, BSS, SRC hdr->flags |= 0x02; MAC_COPY(hdr->addr1, destination); MAC_COPY(hdr->addr2, bssid_or_transm); MAC_COPY(hdr->addr3, source); break; case 't': //From station to AP: ToDS 1 FromDS 1 Addr: BSS, SRC, DST hdr->flags |= 0x01; MAC_COPY(hdr->addr1, bssid_or_transm); MAC_COPY(hdr->addr2, source); MAC_COPY(hdr->addr3, destination); break; case 'w': //WDS: ToDS 1 FromDS 1 Addr: RCV, TRN, DST ... SRC hdr->flags |= 0x03; MAC_COPY(hdr->addr1, recv); MAC_COPY(hdr->addr2, bssid_or_transm); MAC_COPY(hdr->addr3, destination); memcpy((pkt->data) + (sizeof(struct ieee_hdr)), source.ether_addr_octet, ETHER_ADDR_LEN); break; default: printf("ERROR: DS Flags invalid, use only a, f, t or w! Frame will have no MAC adresses!\n"); } hdr->duration = htole16(duration); hdr->frag_seq = htole16(fragment | (seqno << 4)); //TODO: Maybe we need to add support for other frame types beside DATA and Beacon. // A good idea would also be QoS Data support pkt->len = sizeof(struct ieee_hdr); if ((hdr->flags & 0x03) == 0x03) pkt->len += 6; //Extra MAC in WDS packets }
TI_STATUS mlmeBuilder_sendFrame(TI_HANDLE hMlme, dot11MgmtSubType_e type, UINT8 *pDataBuff, UINT32 dataLen, UINT8 setWepOpt) { TI_STATUS status; mlme_t *pHandle; mem_MSDU_T *pMsdu; paramInfo_t daParam, saParam; dot11_mgmtFrame_t *pFrame; if (hMlme == NULL) { return NOK; } pHandle = (mlme_t*)hMlme; /* GET NEW MSDU !!! */ status = wlan_memMngrAllocMSDU(pHandle->hMemMgr, &pMsdu, MAX_MANAGEMENT_FRAME_BODY_LEN + configMgr_getPacketHeaderLength(pHandle->hConfigMgr, NULL, TX_DATA_MGMT_MSDU), MLME_MODULE); if (status != OK) return NOK; pFrame = (dot11_mgmtFrame_t*)(pMsdu->firstBDPtr->data + TX_TOTAL_OFFSET_BEFORE_DATA); status = mlmeBuilder_buildFrameCtrl(pHandle, type, (UINT16 *)&pFrame->hdr.fc, setWepOpt); if (status != OK) { wlan_memMngrFreeMSDU(pHandle->hMemMgr, pMsdu->handle); return NOK; } daParam.paramType = CTRL_DATA_CURRENT_BSSID_PARAM; status = ctrlData_getParam(pHandle->hCtrlData, &daParam); if (status != OK) { wlan_memMngrFreeMSDU(pHandle->hMemMgr, pMsdu->handle); return NOK; } /* copy destination mac address */ MAC_COPY(pHandle->hOs, (&pFrame->hdr.DA), (&daParam.content.ctrlDataCurrentBSSID)); saParam.paramType = CTRL_DATA_MAC_ADDRESS; status = ctrlData_getParam(pHandle->hCtrlData, &saParam); if (status != OK) { wlan_memMngrFreeMSDU(pHandle->hMemMgr, pMsdu->handle); return NOK; } /* copy source mac address */ MAC_COPY(pHandle->hOs, (&pFrame->hdr.SA), (&saParam.content.ctrlDataCurrentBSSID)); /* copy BSSID (destination mac address) */ MAC_COPY(pHandle->hOs, (&pFrame->hdr.BSSID), (&daParam.content.ctrlDataCurrentBSSID)); if (pDataBuff != NULL) { os_memoryCopy(pHandle->hOs, (void *)pFrame->body, pDataBuff, dataLen); } /* Update MSDU parameters */ pMsdu->headerLen = sizeof(dot11_mgmtHeader_t); pMsdu->dataLen = sizeof(dot11_mgmtHeader_t) + dataLen; pMsdu->firstBDPtr->dataOffset = TX_TOTAL_OFFSET_BEFORE_DATA; pMsdu->firstBDPtr->length = pMsdu->dataLen + pMsdu->firstBDPtr->dataOffset; /* send the packet to the TX */ pMsdu->qosTag = 0; pMsdu->txFlags |= TX_DATA_MGMT_MSDU; /* * sign the Disassoc packet * A disassociate indication (if occurs) will be provided via TxComplete */ if (type == DIS_ASSOC) pMsdu->txCompleteFlags |= TX_DATA_DISASSOC_SYNC_TRIG; /* sign the De Auth packet * A De Auth indication (if occurs) will be provided via TxComplete */ if (type == DE_AUTH) pMsdu->txCompleteFlags |= TX_DATA_DEAUTH_SYNC_TRIG; status = txData_txSendMsdu(pHandle->hTxData, pMsdu); return status; }
/*********************************************************************** ** acx_rxbuf_to_ether ** ** Uses the contents of a received 802.11 frame to build an ether ** frame. ** ** This function extracts the src and dest address from the 802.11 ** frame to use in the construction of the eth frame. ** ** Based largely on p80211conv.c of the linux-wlan-ng project */ struct sk_buff* acx_rxbuf_to_ether(acx_device_t *adev, rxbuffer_t *rxbuf) { struct wlan_hdr *w_hdr; struct wlan_ethhdr *e_hdr; struct wlan_llc *e_llc; struct wlan_snap *e_snap; struct sk_buff *skb; const u8 *daddr; const u8 *saddr; const u8 *e_payload; int buflen, payload_length; unsigned int payload_offset, mtu; u16 fc; FN_ENTER; /* This looks complex because it must handle possible ** phy header in rxbuff */ w_hdr = acx_get_wlan_hdr(adev, rxbuf); payload_offset = WLAN_HDR_A3_LEN; /* it is relative to w_hdr */ payload_length = RXBUF_BYTES_USED(rxbuf) /* entire rxbuff... */ - ((u8*)w_hdr - (u8*)rxbuf) /* minus space before 802.11 frame */ - WLAN_HDR_A3_LEN; /* minus 802.11 header */ /* setup some vars for convenience */ fc = w_hdr->fc; switch (WF_FC_FROMTODSi & fc) { case 0: daddr = w_hdr->a1; saddr = w_hdr->a2; break; case WF_FC_FROMDSi: daddr = w_hdr->a1; saddr = w_hdr->a3; break; case WF_FC_TODSi: daddr = w_hdr->a3; saddr = w_hdr->a2; break; default: /* WF_FC_FROMTODSi */ payload_offset += (WLAN_HDR_A4_LEN - WLAN_HDR_A3_LEN); payload_length -= (WLAN_HDR_A4_LEN - WLAN_HDR_A3_LEN); daddr = w_hdr->a3; saddr = w_hdr->a4; } if ((WF_FC_ISWEPi & fc) && IS_ACX100(adev)) { /* chop off the IV+ICV WEP header and footer */ log(L_DATA|L_DEBUG, "rx: WEP packet, " "chopping off IV and ICV\n"); payload_offset += WLAN_WEP_IV_LEN; payload_length -= WLAN_WEP_IV_LEN + WLAN_WEP_ICV_LEN; } if (unlikely(payload_length < 0)) { printk("%s: rx frame too short, ignored\n", adev->ndev->name); goto ret_null; } e_hdr = (wlan_ethhdr_t*) ((u8*) w_hdr + payload_offset); e_llc = (wlan_llc_t*) e_hdr; e_snap = (wlan_snap_t*) (e_llc + 1); mtu = adev->ndev->mtu; e_payload = (u8*) (e_snap + 1); log(L_DATA, "rx: payload_offset %d, payload_length %d\n", payload_offset, payload_length); log(L_XFER|L_DATA, "rx: frame info: llc=%02X%02X%02X " "snap.oui=%02X%02X%02X snap.type=%04X\n", e_llc->dsap, e_llc->ssap, e_llc->ctl, e_snap->oui[0], e_snap->oui[1], e_snap->oui[2], ntohs(e_snap->type)); /* Test for the various encodings */ if ((payload_length >= sizeof(wlan_ethhdr_t)) && ((e_llc->dsap != 0xaa) || (e_llc->ssap != 0xaa)) && ( (mac_is_equal(daddr, e_hdr->daddr)) || (mac_is_equal(saddr, e_hdr->saddr)) ) ) { /* 802.3 Encapsulated: */ /* wlan frame body contains complete eth frame (header+body) */ log(L_DEBUG|L_DATA, "rx: 802.3 ENCAP len=%d\n", payload_length); if (unlikely(payload_length > (mtu + ETH_HLEN))) { printk("%s: rx: ENCAP frame too large (%d > %d)\n", adev->ndev->name, payload_length, mtu + ETH_HLEN); goto ret_null; } /* allocate space and setup host buffer */ buflen = payload_length; /* Attempt to align IP header (14 bytes eth header + 2 = 16) */ skb = dev_alloc_skb(buflen + 2); if (unlikely(!skb)) goto no_skb; skb_reserve(skb, 2); skb_put(skb, buflen); /* make room */ /* now copy the data from the 80211 frame */ memcpy(skb->data, e_hdr, payload_length); } else if ( (payload_length >= sizeof(wlan_llc_t)+sizeof(wlan_snap_t)) && llc_is_snap(e_llc) ) { /* wlan frame body contains: AA AA 03 ... (it's a SNAP) */ if ( !oui_is_rfc1042(e_snap) || (proto_is_stt(ieee2host16(e_snap->type)) /* && (ethconv == WLAN_ETHCONV_8021h) */)) { log(L_DEBUG|L_DATA, "rx: SNAP+RFC1042 len=%d\n", payload_length); /* wlan frame body contains: AA AA 03 !(00 00 00) ... -or- */ /* wlan frame body contains: AA AA 03 00 00 00 0x80f3 ... */ /* build eth hdr, type = len, copy AA AA 03... as eth body */ /* it's a SNAP + RFC1042 frame && protocol is in STT */ if (unlikely(payload_length > mtu)) { printk("%s: rx: SNAP frame too large (%d > %d)\n", adev->ndev->name, payload_length, mtu); goto ret_null; } /* allocate space and setup host buffer */ buflen = payload_length + ETH_HLEN; skb = dev_alloc_skb(buflen + 2); if (unlikely(!skb)) goto no_skb; skb_reserve(skb, 2); skb_put(skb, buflen); /* make room */ /* create 802.3 header */ e_hdr = (wlan_ethhdr_t*) skb->data; MAC_COPY(e_hdr->daddr, daddr); MAC_COPY(e_hdr->saddr, saddr); e_hdr->type = htons(payload_length); /* Now copy the data from the 80211 frame. Make room in front for the eth header, and keep the llc and snap from the 802.11 payload */ memcpy(skb->data + ETH_HLEN, e_llc, payload_length); } else { /* wlan frame body contains: AA AA 03 00 00 00 [type] [tail] */ /* build eth hdr, type=[type], copy [tail] as eth body */ log(L_DEBUG|L_DATA, "rx: 802.1h/RFC1042 len=%d\n", payload_length); /* it's an 802.1h frame (an RFC1042 && protocol is not in STT) */ /* build a DIXII + RFC894 */ payload_length -= sizeof(wlan_llc_t) + sizeof(wlan_snap_t); if (unlikely(payload_length > mtu)) { printk("%s: rx: DIXII frame too large (%d > %d)\n", adev->ndev->name, payload_length, mtu); goto ret_null; } /* allocate space and setup host buffer */ buflen = payload_length + ETH_HLEN; skb = dev_alloc_skb(buflen + 2); if (unlikely(!skb)) goto no_skb; skb_reserve(skb, 2); skb_put(skb, buflen); /* make room */ /* create 802.3 header */ e_hdr = (wlan_ethhdr_t *) skb->data; MAC_COPY(e_hdr->daddr, daddr); MAC_COPY(e_hdr->saddr, saddr); e_hdr->type = e_snap->type; /* Now copy the data from the 80211 frame. Make room in front for the eth header, and cut off the llc and snap from the 802.11 payload */ memcpy(skb->data + ETH_HLEN, e_payload, payload_length); } } else { log(L_DEBUG|L_DATA, "rx: NON-ENCAP len=%d\n", payload_length); /* build eth hdr, type=len, copy wlan body as eth body */ /* any NON-ENCAP */ /* it's a generic 80211+LLC or IPX 'Raw 802.3' */ /* build an 802.3 frame */ if (unlikely(payload_length > mtu)) { printk("%s: rx: OTHER frame too large (%d > %d)\n", adev->ndev->name, payload_length, mtu); goto ret_null; } /* allocate space and setup host buffer */ buflen = payload_length + ETH_HLEN; skb = dev_alloc_skb(buflen + 2); if (unlikely(!skb)) goto no_skb; skb_reserve(skb, 2); skb_put(skb, buflen); /* make room */ /* set up the 802.3 header */ e_hdr = (wlan_ethhdr_t *) skb->data; MAC_COPY(e_hdr->daddr, daddr); MAC_COPY(e_hdr->saddr, saddr); e_hdr->type = htons(payload_length); /* now copy the data from the 80211 frame */ memcpy(skb->data + ETH_HLEN, e_llc, payload_length); } skb->dev = adev->ndev; skb->protocol = eth_type_trans(skb, adev->ndev); #ifdef DEBUG_CONVERT if (acx_debug & L_DATA) { int len = RXBUF_BYTES_RCVD(adev, rxbuf); printk("p802.11 frame [%d]: ", len); acx_dump_bytes(w_hdr, len); printk("eth frame [%d]: ", skb->len); acx_dump_bytes(skb->data, skb->len); } #endif FN_EXIT0; return skb; no_skb: printk("%s: rx: no memory for skb (%d bytes)\n", adev->ndev->name, buflen + 2); ret_null: FN_EXIT1((int)NULL); return NULL; }
/*********************************************************************** ** acx_ether_to_txbuf ** ** Uses the contents of the ether frame to build the elements of ** the 802.11 frame. ** ** We don't actually set up the frame header here. That's the ** MAC's job. We're only handling conversion of DIXII or 802.3+LLC ** frames to something that works with 802.11. ** ** Based largely on p80211conv.c of the linux-wlan-ng project */ int acx_ether_to_txbuf(acx_device_t *adev, void *txbuf, const struct sk_buff *skb) { struct wlan_hdr_a3 *w_hdr; struct wlan_ethhdr *e_hdr; struct wlan_llc *e_llc; struct wlan_snap *e_snap; const u8 *a1, *a3; int header_len, payload_len = -1; /* protocol type or data length, depending on whether * DIX or 802.3 ethernet format */ u16 proto; u16 fc; FN_ENTER; if (unlikely(!skb->len)) { log(L_DEBUG, "zero-length skb!\n"); goto end; } w_hdr = (struct wlan_hdr_a3*)txbuf; switch (adev->mode) { case ACX_MODE_MONITOR: /* NB: one day we might want to play with DESC_CTL2_FCS ** Will need to stop doing "- WLAN_FCS_LEN" here then */ if (unlikely(skb->len >= WLAN_A4FR_MAXLEN_WEP_FCS - WLAN_FCS_LEN)) { printk("%s: can't tx oversized frame (%d bytes)\n", adev->ndev->name, skb->len); goto end; } memcpy(w_hdr, skb->data, skb->len); payload_len = skb->len; goto end; } /* step 1: classify ether frame, DIX or 802.3? */ e_hdr = (wlan_ethhdr_t *)skb->data; proto = ntohs(e_hdr->type); if (proto <= 1500) { log(L_DEBUG, "tx: 802.3 len: %d\n", skb->len); /* codes <= 1500 reserved for 802.3 lengths */ /* it's 802.3, pass ether payload unchanged, */ /* trim off ethernet header and copy payload to txdesc */ header_len = WLAN_HDR_A3_LEN; } else { /* it's DIXII, time for some conversion */ /* Create 802.11 packet. Header also contains llc and snap. */ log(L_DEBUG, "tx: DIXII len: %d\n", skb->len); /* size of header is 802.11 header + llc + snap */ header_len = WLAN_HDR_A3_LEN + sizeof(wlan_llc_t) + sizeof(wlan_snap_t); /* llc is located behind the 802.11 header */ e_llc = (wlan_llc_t*)(w_hdr + 1); /* snap is located behind the llc */ e_snap = (wlan_snap_t*)(e_llc + 1); /* setup the LLC header */ store_llc_snap(e_llc); /* setup the SNAP header */ e_snap->type = htons(proto); if (proto_is_stt(proto)) { store_oui_8021h(e_snap); } else { store_oui_rfc1042(e_snap); } } /* trim off ethernet header and copy payload to txbuf */ payload_len = skb->len - sizeof(wlan_ethhdr_t); /* TODO: can we just let acx DMA payload from skb instead? */ memcpy((u8*)txbuf + header_len, skb->data + sizeof(wlan_ethhdr_t), payload_len); payload_len += header_len; /* Set up the 802.11 header */ switch (adev->mode) { case ACX_MODE_0_ADHOC: fc = (WF_FTYPE_DATAi | WF_FSTYPE_DATAONLYi); a1 = e_hdr->daddr; a3 = adev->bssid; break; case ACX_MODE_2_STA: fc = (WF_FTYPE_DATAi | WF_FSTYPE_DATAONLYi | WF_FC_TODSi); a1 = adev->bssid; a3 = e_hdr->daddr; break; case ACX_MODE_3_AP: fc = (WF_FTYPE_DATAi | WF_FSTYPE_DATAONLYi | WF_FC_FROMDSi); a1 = e_hdr->daddr; a3 = e_hdr->saddr; break; default: printk("%s: error - converting eth to wlan in unknown mode\n", adev->ndev->name); payload_len = -1; goto end; } if (adev->wep_enabled) SET_BIT(fc, WF_FC_ISWEPi); w_hdr->fc = fc; w_hdr->dur = 0; MAC_COPY(w_hdr->a1, a1); MAC_COPY(w_hdr->a2, adev->dev_addr); MAC_COPY(w_hdr->a3, a3); w_hdr->seq = 0; #ifdef DEBUG_CONVERT if (acx_debug & L_DATA) { printk("original eth frame [%d]: ", skb->len); acx_dump_bytes(skb->data, skb->len); printk("802.11 frame [%d]: ", payload_len); acx_dump_bytes(w_hdr, payload_len); } #endif end: FN_EXIT1(payload_len); return payload_len; }
/************************************************************************ * buildProbeReqTemplate * ************************************************************************ DESCRIPTION: This function build a probe request template to set to the HAL in the scan process. performs the following: - Build a template & set the template len, the template type is set in the site mgr INPUT: pSiteMgr - Handle to site manager pTemplate - Pointer to the template structure pSsid - Desired SSID OUTPUT: RETURN: TI_OK ************************************************************************/ TI_STATUS buildProbeReqTemplate(siteMgr_t * pSiteMgr, TSetTemplate * pTemplate, TSsid * pSsid, ERadioBand radioBand) { paramInfo_t param; char *pBuf; int i; probeReqTemplate_t *pBuffer = (probeReqTemplate_t *) pTemplate->ptr; TI_UINT32 size; dot11_RATES_t *pDot11Rates; TI_UINT32 len = 0, ofdmIndex = 0; TI_UINT32 suppRatesLen, extSuppRatesLen; TI_UINT8 ratesBuf[DOT11_MAX_SUPPORTED_RATES]; TI_UINT8 WSCOuiIe[DOT11_OUI_LEN] = { 0x00, 0x50, 0xf2, 0x04 }; TI_UINT32 supportedRateMask, basicRateMask; TI_UINT16 fc = DOT11_FC_PROBE_REQ; os_memoryZero(pSiteMgr->hOs, pBuffer, sizeof(probeReqTemplate_t)); /* * Header First */ /* Set destination address */ for (i = 0; i < MAC_ADDR_LEN; i++) pBuffer->hdr.DA[i] = 0xFF; /* Set BSSID address */ for (i = 0; i < MAC_ADDR_LEN; i++) pBuffer->hdr.BSSID[i] = 0xFF; /* Build Source address */ param.paramType = CTRL_DATA_MAC_ADDRESS; ctrlData_getParam(pSiteMgr->hCtrlData, ¶m); MAC_COPY(pBuffer->hdr.SA, param.content.ctrlDataDeviceMacAddress); COPY_WLAN_WORD(&pBuffer->hdr.fc, &fc); /* copy with endianess handling. */ size = sizeof(dot11_mgmtHeader_t); pBuf = (char *)&(pBuffer->infoElements); /* * Informataion elements */ /* SSID */ /* It looks like it never happens. Anyway decided to check */ if (pSsid->len > MAX_SSID_LEN) { TRACE2(pSiteMgr->hReport, REPORT_SEVERITY_ERROR, "buildProbeReqTemplate. pSsid->len=%d exceeds the limit %d\n", pSsid->len, MAX_SSID_LEN); handleRunProblem(PROBLEM_BUF_SIZE_VIOLATION); return TI_NOK; } ((dot11_SSID_t *) (pBuf))->hdr[0] = DOT11_SSID_ELE_ID; ((dot11_SSID_t *) (pBuf))->hdr[1] = pSsid->len; os_memoryCopy(pSiteMgr->hOs, pBuf + sizeof(dot11_eleHdr_t), (void *)pSsid->str, pSsid->len); size += sizeof(dot11_eleHdr_t) + pSsid->len; pBuf += sizeof(dot11_eleHdr_t) + pSsid->len; /* Rates */ pDot11Rates = (dot11_RATES_t *) pBuf; /* * Supported rates in probe request will always use the default rates for BG or A bands, * regardless of the STA desired rates. */ if (radioBand == RADIO_BAND_2_4_GHZ) { /* Basic rates: 1,2,5.5,11 */ basicRateMask = rate_BasicToDrvBitmap((EBasicRateSet) (pSiteMgr->pDesiredParams-> siteMgrRegstryBasicRate [DOT11_G_MODE]), TI_FALSE); /* Extended: 6,9,12,18,24,36,48,54 */ supportedRateMask = rate_SupportedToDrvBitmap((ESupportedRateSet) (pSiteMgr->pDesiredParams-> siteMgrRegstrySuppRate [DOT11_G_MODE]), TI_FALSE); } else if (radioBand == RADIO_BAND_5_0_GHZ) { /* Basic rates: 6,12,24 */ basicRateMask = rate_BasicToDrvBitmap((EBasicRateSet) (pSiteMgr->pDesiredParams-> siteMgrRegstryBasicRate [DOT11_A_MODE]), TI_TRUE); /* Extended: 9,18,24,36,48,54 */ supportedRateMask = rate_SupportedToDrvBitmap((ESupportedRateSet) (pSiteMgr->pDesiredParams-> siteMgrRegstrySuppRate [DOT11_A_MODE]), TI_TRUE); } else { TRACE1(pSiteMgr->hReport, REPORT_SEVERITY_ERROR, "buildProbeReqTemplate, radioBand =%d ???\n", radioBand); /* Use default and pray for the best */ /* Basic rates: 1,2,5.5,11 */ basicRateMask = rate_BasicToDrvBitmap(BASIC_RATE_SET_1_2_5_5_11, TI_FALSE); /* Extended: 6,9,12,18,24,36,48,54 */ supportedRateMask = rate_SupportedToDrvBitmap(SUPPORTED_RATE_SET_UP_TO_54, TI_FALSE); } rate_DrvBitmapToNetStr(supportedRateMask, basicRateMask, ratesBuf, &len, &ofdmIndex); TRACE5(pSiteMgr->hReport, REPORT_SEVERITY_INFORMATION, "buildProbeReqTemplate, supportedRateMask=0x%x, basicRateMask=0x%x, len=%d, ofdmIndex=%d, radioBand =%d\n", supportedRateMask, basicRateMask, len, ofdmIndex, radioBand); /* It looks like it never happens. Anyway decided to check */ if (len > DOT11_MAX_SUPPORTED_RATES) { TRACE2(pSiteMgr->hReport, REPORT_SEVERITY_ERROR, "buildProbeReqTemplate. len=%d exceeds the limit %d\n", len, DOT11_MAX_SUPPORTED_RATES); handleRunProblem(PROBLEM_BUF_SIZE_VIOLATION); return TI_NOK; } if (radioBand == RADIO_BAND_5_0_GHZ || pSiteMgr->pDesiredParams->siteMgrUseDraftNum == DRAFT_5_AND_EARLIER || ofdmIndex == len) { pDot11Rates->hdr[0] = DOT11_SUPPORTED_RATES_ELE_ID; pDot11Rates->hdr[1] = len; os_memoryCopy(pSiteMgr->hOs, (void *)pDot11Rates->rates, ratesBuf, pDot11Rates->hdr[1]); size += pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t); pBuf += pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t); } else { pDot11Rates->hdr[0] = DOT11_SUPPORTED_RATES_ELE_ID; pDot11Rates->hdr[1] = ofdmIndex; os_memoryCopy(pSiteMgr->hOs, (void *)pDot11Rates->rates, ratesBuf, pDot11Rates->hdr[1]); suppRatesLen = pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t); pDot11Rates = (dot11_RATES_t *) (pBuf + suppRatesLen); pDot11Rates->hdr[0] = DOT11_EXT_SUPPORTED_RATES_ELE_ID; pDot11Rates->hdr[1] = len - ofdmIndex; os_memoryCopy(pSiteMgr->hOs, (void *)pDot11Rates->rates, &ratesBuf[ofdmIndex], pDot11Rates->hdr[1]); extSuppRatesLen = pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t); size += suppRatesLen + extSuppRatesLen; pBuf += suppRatesLen + extSuppRatesLen; } /* add HT capabilities IE */ StaCap_GetHtCapabilitiesIe(pSiteMgr->hStaCap, (TI_UINT8 *) pBuf, &len); size += len; pBuf += len; /* WiFi Simple Config */ if (pSiteMgr->includeWSCinProbeReq && (pSiteMgr->siteMgrWSCCurrMode != TIWLN_SIMPLE_CONFIG_OFF)) { ((dot11_WSC_t *) pBuf)->hdr[0] = DOT11_WSC_PARAM_ELE_ID; ((dot11_WSC_t *) pBuf)->hdr[1] = pSiteMgr->uWscIeSize + DOT11_OUI_LEN; pBuf += sizeof(dot11_eleHdr_t); os_memoryCopy(pSiteMgr->hOs, pBuf, &WSCOuiIe, DOT11_OUI_LEN); os_memoryCopy(pSiteMgr->hOs, pBuf + DOT11_OUI_LEN, &pSiteMgr->siteMgrWSCProbeReqParams, pSiteMgr->uWscIeSize); size += sizeof(dot11_eleHdr_t) + pSiteMgr->uWscIeSize + DOT11_OUI_LEN; pBuf += sizeof(dot11_eleHdr_t) + pSiteMgr->uWscIeSize + DOT11_OUI_LEN; } pTemplate->len = size; return TI_OK; }