| /** @file parser.c |
| * |
| * @brief This file defines function for 802.11 Management Frames Parsing |
| * |
| * Copyright (C) 2014, Marvell International Ltd. |
| * |
| * This software file (the "File") is distributed by Marvell International |
| * Ltd. under the terms of the GNU General Public License Version 2, June 1991 |
| * (the "License"). You may use, redistribute and/or modify this File in |
| * accordance with the terms and conditions of the License, a copy of which |
| * is available by writing to the Free Software Foundation, Inc., |
| * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the |
| * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. |
| * |
| * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE |
| * ARE EXPRESSLY DISCLAIMED. The License provides additional details about |
| * this warranty disclaimer. |
| */ |
| |
| /****************************************************** |
| Change log: |
| 03/07/2014: Initial version |
| ******************************************************/ |
| /***************************************************************************** |
| * |
| * File: parser.c |
| * |
| * |
| * |
| * Author(s): Rajesh Bhagwat |
| * Date: 2005-02-04 |
| * Description: 802.11 Management Frames Parsing |
| * |
| ******************************************************************************/ |
| #include "wltypes.h" |
| #include "wl_mib.h" |
| #include "IEEE_types.h" |
| #include "parser.h" |
| #include "parser_rom.h" |
| |
| #include "hostsa_ext_def.h" |
| #include "authenticator.h" |
| |
| VendorSpecificIEType_e |
| IsEpigramHTElement(void *priv, uint8 *pBuffer) |
| { |
| phostsa_private psapriv = (phostsa_private)priv; |
| hostsa_util_fns *util_fns = &psapriv->util_fns; |
| VendorSpecificIEType_e retVal = VendSpecIE_Other; |
| const uint8 szMatchingCapElement[] = { 0x00, 0x90, 0x4c, 0x33 }; |
| const uint8 szMatchingInfoElement[] = { 0x00, 0x90, 0x4c, 0x34 }; |
| |
| if (!memcmp(util_fns, pBuffer, |
| szMatchingInfoElement, sizeof(szMatchingInfoElement))) { |
| retVal = VendSpecIE_HT_Info; |
| } else if (!memcmp(util_fns, pBuffer, |
| szMatchingCapElement, |
| sizeof(szMatchingCapElement))) { |
| retVal = VendSpecIE_HT_Cap; |
| } |
| |
| return retVal; |
| } |
| |
| VendorSpecificIEType_e |
| IsWPSElement(void *priv, UINT8 *pBuffer) |
| { |
| phostsa_private psapriv = (phostsa_private)priv; |
| hostsa_util_fns *util_fns = &psapriv->util_fns; |
| VendorSpecificIEType_e retVal = VendSpecIE_Other; |
| const UINT8 szMatchingInfoElement[] = { 0x00, 0x50, 0xf2, 0x04 }; |
| |
| if (!memcmp(util_fns, pBuffer, |
| szMatchingInfoElement, sizeof(szMatchingInfoElement))) { |
| retVal = VendSpecIE_WPS; |
| } |
| |
| return retVal; |
| } |
| |
| VendorSpecificIEType_e |
| IsSsIdLElement(void *priv, UINT8 *pBuffer) |
| { |
| phostsa_private psapriv = (phostsa_private)priv; |
| hostsa_util_fns *util_fns = &psapriv->util_fns; |
| VendorSpecificIEType_e retVal = VendSpecIE_Other; |
| const UINT8 szMatchingInfoElement[] = { 0x00, 0x50, 0xf2, 0x05, 0x00 }; |
| |
| if (!memcmp(util_fns, pBuffer, |
| szMatchingInfoElement, sizeof(szMatchingInfoElement))) { |
| retVal = VendSpecIE_SsIdL; |
| } |
| |
| return retVal; |
| } |
| |
| int |
| ieBufValidate(UINT8 *pIe, int bufLen) |
| { |
| while (bufLen) { |
| UINT8 ieLen = *(pIe + 1); |
| if (bufLen < (ieLen + 2)) { |
| return MLME_FAILURE; |
| } |
| bufLen -= ieLen + 2; |
| pIe += ieLen + 2; |
| } |
| |
| return MLME_SUCCESS; |
| } |
| |
| int |
| GetIEPointers(void *priv, UINT8 *pIe, int bufLen, IEPointers_t *pIePointers) |
| { |
| phostsa_private psapriv = (phostsa_private)priv; |
| hostsa_util_fns *util_fns = &psapriv->util_fns; |
| memset(util_fns, pIePointers, 0x00, sizeof(IEPointers_t)); |
| |
| while (bufLen) { |
| if (bufLen < (*(pIe + 1) + 2)) { |
| break; |
| } |
| |
| /* Handle IEs not processed by ROM functions. */ |
| switch (*pIe) { |
| case ELEM_ID_RSN: |
| pIePointers->pRsn = (IEEEtypes_RSNElement_t *)pIe; |
| break; |
| case ELEM_ID_WAPI: |
| pIePointers->pWapi = (IEEEtypes_WAPIElement_t *)pIe; |
| break; |
| |
| /* Add element not handled by ROM_parser_getIEPtr or ** |
| override element processing in ROM_parser_getIEPtr |
| ** here. */ |
| case ELEM_ID_VENDOR_SPECIFIC: |
| default: |
| if (ROM_parser_getIEPtr(priv, pIe, pIePointers) == |
| FALSE) { |
| if ((*pIe) == ELEM_ID_VENDOR_SPECIFIC) { |
| if (IsWPSElement(priv, (pIe + 2))) { |
| pIePointers->pWps = |
| (IEEEtypes_WPSElement_t |
| *)pIe; |
| } |
| } |
| // Add your code to process vendor specific |
| // elements not |
| // processed by above ROM_paser_getAssocIEPtr |
| // function. |
| } |
| break; |
| } |
| bufLen -= *(pIe + 1) + 2; |
| pIe += *(pIe + 1) + 2; |
| } |
| return bufLen; |
| } |
| |
| BOOLEAN |
| parser_getAssocIEs(void *priv, UINT8 *pIe, |
| int bufLen, AssocIePointers_t *pIePointers) |
| { |
| phostsa_private psapriv = (phostsa_private)priv; |
| hostsa_util_fns *util_fns = &psapriv->util_fns; |
| BOOLEAN ieParseSuccessful = TRUE; |
| |
| memset(util_fns, pIePointers, 0x00, sizeof(AssocIePointers_t)); |
| |
| while (bufLen) { |
| UINT8 ieType = *pIe; |
| UINT8 ieLen = *(pIe + 1); |
| |
| if (bufLen < (ieLen + 2)) { |
| ieParseSuccessful = FALSE; |
| break; |
| } |
| |
| switch (ieType) { |
| // add code for elements not handled in ROM function. |
| case ELEM_ID_AP_CHANNEL_REPORT: |
| pIePointers->pApChanRpt = |
| (IEEEtypes_ApChanRptElement_t *)pIe; |
| break; |
| #ifdef TDLS |
| case ELEM_ID_SUPPORTED_REGCLASS: |
| pIePointers->pSuppRegClass = |
| (IEEEtypes_SupportedRegClasses_t *)pIe; |
| break; |
| #endif |
| |
| /* The following 5 elements, HT CAP, HT INFO, 20/40 |
| Coex, OBSS SCAN PARAM, and EXTENDED CAP, are |
| ignored here if 11n is not compiled. When 11n is |
| compiled these 5 elements would be handled in |
| ROM_parser_getAssocIEPtr routine. |
| |
| */ |
| case ELEM_ID_HT_CAPABILITY: |
| case ELEM_ID_HT_INFORMATION: |
| case ELEM_ID_2040_BSS_COEXISTENCE: |
| case ELEM_ID_OBSS_SCAN_PARAM: |
| case ELEM_ID_EXT_CAPABILITIES: |
| /* Do not process these elements in ROM routine |
| ROM_parser_getAssocIEPtr Note: a break here. */ |
| break; |
| |
| /* Add element not handled by ROM_parser_getAssocIEPtr |
| or override element processing in |
| ROM_parser_getAssocIEPtr here. \ */ |
| |
| case ELEM_ID_VENDOR_SPECIFIC: |
| default: |
| if (ROM_parser_getAssocIEPtr(priv, pIe, pIePointers) == |
| FALSE) { |
| // Add your code to process vendor specific |
| // elements not |
| // processed by above ROM_paser_getAssocIEPtr |
| // function. |
| if (!pIePointers->pHtCap || |
| !pIePointers->pHtInfo) { |
| switch (IsEpigramHTElement |
| (priv, (pIe + 2))) { |
| |
| case VendSpecIE_HT_Cap: |
| if (!pIePointers->pHtCap) { |
| *(pIe + 4) = |
| ELEM_ID_HT_CAPABILITY; |
| *(pIe + 5) = |
| sizeof |
| (IEEEtypes_HT_Capability_t); |
| pIePointers->pHtCap = |
| (IEEEtypes_HT_Capability_t |
| *)(pIe + 4); |
| } |
| break; |
| |
| case VendSpecIE_HT_Info: |
| if (!pIePointers->pHtInfo) { |
| *(pIe + 4) = |
| ELEM_ID_HT_INFORMATION; |
| *(pIe + 5) = |
| sizeof |
| (IEEEtypes_HT_Information_t); |
| pIePointers->pHtInfo = |
| (IEEEtypes_HT_Information_t |
| *)(pIe + 4); |
| } |
| break; |
| |
| case VendSpecIE_Other: |
| default: |
| break; |
| } |
| } |
| } |
| break; |
| |
| } |
| bufLen -= ieLen + 2; |
| pIe += ieLen + 2; |
| } |
| return ieParseSuccessful; |
| } |
| |
| UINT8 |
| parser_countNumInfoElements(UINT8 *pIe, int bufLen) |
| { |
| UINT8 ieCount = 0; |
| |
| while (bufLen) { |
| if (bufLen < (*(pIe + 1) + 2)) { |
| break; |
| } |
| |
| ieCount++; |
| |
| bufLen -= *(pIe + 1) + 2; |
| pIe += *(pIe + 1) + 2; |
| } |
| |
| return ieCount; |
| } |