/************************************************************************ * 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; }
/*********************************************************************** * txCtrlServ_buildWlanHeader *********************************************************************** DESCRIPTION: Build WLAN header from Ethernet header. 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_buildWlanHeader(TI_HANDLE hTxCtrl, TI_UINT8* pFrame, TI_UINT32* pLength) { txCtrl_t *pTxCtrl = (txCtrl_t *)hTxCtrl; TI_STATUS status; TMacAddr daBssid; TMacAddr saBssid; EQosProtocol qosProt; ScanBssType_e currBssType; TMacAddr currBssId; TI_UINT32 headerLength; TI_UINT16 headerFlags; TI_BOOL currentPrivacyInvokedMode; TI_UINT8 encryptionFieldSize; TTxCtrlBlk tPktCtrlBlk; dot11_header_t *pDot11Header = (dot11_header_t*)(tPktCtrlBlk.aPktHdr); Wlan_LlcHeader_T *pWlanSnapHeader; /* * If QoS is used, add two bytes padding before the header for 4-bytes alignment. * Note that the header length doesn't include it, so the txCtrl detects the pad existence * by checking if the header-length is a multiple of 4. */ qosMngr_getParamsActiveProtocol(pTxCtrl->hQosMngr, &qosProt); if (qosProt == QOS_WME) { headerLength = WLAN_QOS_HDR_LEN; headerFlags = DOT11_FC_DATA_QOS | DOT11_FC_TO_DS; pDot11Header->qosControl = 0; } else { headerLength = WLAN_HDR_LEN; headerFlags = DOT11_FC_DATA | DOT11_FC_TO_DS; } /* * Handle encryption if needed (decision was done at RSN and is provided by TxCtrl): * - Set WEP bit in header. * - Add padding for FW security overhead: 4 bytes for TKIP, 8 for AES. */ txCtrlParams_getCurrentEncryptionInfo (hTxCtrl, ¤tPrivacyInvokedMode, &encryptionFieldSize); if (currentPrivacyInvokedMode) { headerFlags |= DOT11_FC_WEP; headerLength += encryptionFieldSize; } COPY_WLAN_WORD (&pDot11Header->fc, &headerFlags); /* copy with endianess handling. */ /* Get the Destination MAC address */ status = ctrlData_getParamBssid (pTxCtrl->hCtrlData, CTRL_DATA_CURRENT_BSSID_PARAM, daBssid); if (status != TI_OK) { return TI_NOK; } /* Get the Source MAC address */ status = ctrlData_getParamBssid (pTxCtrl->hCtrlData, CTRL_DATA_MAC_ADDRESS, saBssid); if (status != TI_OK) { return TI_NOK; } /* receive BssId and Bss Type from control module */ ctrlData_getCurrBssTypeAndCurrBssId (pTxCtrl->hCtrlData, &currBssId, &currBssType); if (currBssType != BSS_INFRASTRUCTURE) { return TI_NOK; } /* copy BSSID */ MAC_COPY (pDot11Header->address1, currBssId); /* copy source mac address */ MAC_COPY (pDot11Header->address2, saBssid); /* copy destination mac address*/ MAC_COPY (pDot11Header->address3, daBssid); /* Set the SNAP header pointer right after the other header parts handled above. */ pWlanSnapHeader = (Wlan_LlcHeader_T *)&(tPktCtrlBlk.aPktHdr[headerLength]); pWlanSnapHeader->DSAP = SNAP_CHANNEL_ID; pWlanSnapHeader->SSAP = SNAP_CHANNEL_ID; pWlanSnapHeader->Control = LLC_CONTROL_UNNUMBERED_INFORMATION; /* add RFC1042. */ pWlanSnapHeader->OUI[0] = SNAP_OUI_RFC1042_BYTE0; pWlanSnapHeader->OUI[1] = SNAP_OUI_RFC1042_BYTE1; pWlanSnapHeader->OUI[2] = SNAP_OUI_RFC1042_BYTE2; /* set ETH type to IP */ pWlanSnapHeader->Type = HTOWLANS(ETHERTYPE_IP); /* Add the SNAP length to the total header length. */ headerLength += sizeof(Wlan_LlcHeader_T); /* copy WLAN header */ os_memoryCopy (pTxCtrl->hOs, pFrame, tPktCtrlBlk.aPktHdr, headerLength); *pLength = headerLength; return TI_OK; }