blob: 517dc31dda75b2ef37a961a8bc3bc6a69e511ae7 [file] [log] [blame]
/** @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;
}