/** @file parser.c
|
*
|
* @brief This file defines function for 802.11 Management Frames Parsing
|
*
|
* Copyright (C) 2014-2017, 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;
|
}
|