1 /** @file parser.c
2 *
3 * @brief This file defines function for 802.11 Management Frames Parsing
4 *
5 * Copyright (C) 2014-2017, Marvell International Ltd.
6 *
7 * This software file (the "File") is distributed by Marvell International
8 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
9 * (the "License"). You may use, redistribute and/or modify this File in
10 * accordance with the terms and conditions of the License, a copy of which
11 * is available by writing to the Free Software Foundation, Inc.,
12 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
13 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
14 *
15 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
17 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
18 * this warranty disclaimer.
19 */
20
21 /******************************************************
22 Change log:
23 03/07/2014: Initial version
24 ******************************************************/
25 /*****************************************************************************
26 *
27 * File: parser.c
28 *
29 *
30 *
31 * Author(s): Rajesh Bhagwat
32 * Date: 2005-02-04
33 * Description: 802.11 Management Frames Parsing
34 *
35 ******************************************************************************/
36 #include "wltypes.h"
37 #include "wl_mib.h"
38 #include "IEEE_types.h"
39 #include "parser.h"
40 #include "parser_rom.h"
41
42 #include "hostsa_ext_def.h"
43 #include "authenticator.h"
44
45 VendorSpecificIEType_e
IsEpigramHTElement(void * priv,uint8 * pBuffer)46 IsEpigramHTElement(void *priv, uint8 *pBuffer)
47 {
48 phostsa_private psapriv = (phostsa_private)priv;
49 hostsa_util_fns *util_fns = &psapriv->util_fns;
50 VendorSpecificIEType_e retVal = VendSpecIE_Other;
51 const uint8 szMatchingCapElement[] = { 0x00, 0x90, 0x4c, 0x33 };
52 const uint8 szMatchingInfoElement[] = { 0x00, 0x90, 0x4c, 0x34 };
53
54 if (!memcmp(util_fns, pBuffer,
55 szMatchingInfoElement, sizeof(szMatchingInfoElement))) {
56 retVal = VendSpecIE_HT_Info;
57 } else if (!memcmp(util_fns, pBuffer,
58 szMatchingCapElement,
59 sizeof(szMatchingCapElement))) {
60 retVal = VendSpecIE_HT_Cap;
61 }
62
63 return retVal;
64 }
65
66 VendorSpecificIEType_e
IsWPSElement(void * priv,UINT8 * pBuffer)67 IsWPSElement(void *priv, UINT8 *pBuffer)
68 {
69 phostsa_private psapriv = (phostsa_private)priv;
70 hostsa_util_fns *util_fns = &psapriv->util_fns;
71 VendorSpecificIEType_e retVal = VendSpecIE_Other;
72 const UINT8 szMatchingInfoElement[] = { 0x00, 0x50, 0xf2, 0x04 };
73
74 if (!memcmp(util_fns, pBuffer,
75 szMatchingInfoElement, sizeof(szMatchingInfoElement))) {
76 retVal = VendSpecIE_WPS;
77 }
78
79 return retVal;
80 }
81
82 VendorSpecificIEType_e
IsSsIdLElement(void * priv,UINT8 * pBuffer)83 IsSsIdLElement(void *priv, UINT8 *pBuffer)
84 {
85 phostsa_private psapriv = (phostsa_private)priv;
86 hostsa_util_fns *util_fns = &psapriv->util_fns;
87 VendorSpecificIEType_e retVal = VendSpecIE_Other;
88 const UINT8 szMatchingInfoElement[] = { 0x00, 0x50, 0xf2, 0x05, 0x00 };
89
90 if (!memcmp(util_fns, pBuffer,
91 szMatchingInfoElement, sizeof(szMatchingInfoElement))) {
92 retVal = VendSpecIE_SsIdL;
93 }
94
95 return retVal;
96 }
97
98 int
ieBufValidate(UINT8 * pIe,int bufLen)99 ieBufValidate(UINT8 *pIe, int bufLen)
100 {
101 while (bufLen) {
102 UINT8 ieLen = *(pIe + 1);
103 if (bufLen < (ieLen + 2)) {
104 return MLME_FAILURE;
105 }
106 bufLen -= ieLen + 2;
107 pIe += ieLen + 2;
108 }
109
110 return MLME_SUCCESS;
111 }
112
113 int
GetIEPointers(void * priv,UINT8 * pIe,int bufLen,IEPointers_t * pIePointers)114 GetIEPointers(void *priv, UINT8 *pIe, int bufLen, IEPointers_t *pIePointers)
115 {
116 phostsa_private psapriv = (phostsa_private)priv;
117 hostsa_util_fns *util_fns = &psapriv->util_fns;
118 memset(util_fns, pIePointers, 0x00, sizeof(IEPointers_t));
119
120 while (bufLen) {
121 if (bufLen < (*(pIe + 1) + 2)) {
122 break;
123 }
124
125 /* Handle IEs not processed by ROM functions. */
126 switch (*pIe) {
127 case ELEM_ID_RSN:
128 pIePointers->pRsn = (IEEEtypes_RSNElement_t *)pIe;
129 break;
130 case ELEM_ID_WAPI:
131 pIePointers->pWapi = (IEEEtypes_WAPIElement_t *)pIe;
132 break;
133
134 /* Add element not handled by ROM_parser_getIEPtr or
135 ** override element processing in ROM_parser_getIEPtr
136 ** here.
137 */
138 case ELEM_ID_VENDOR_SPECIFIC:
139 default:
140 if (ROM_parser_getIEPtr(priv, pIe, pIePointers) ==
141 FALSE) {
142 if ((*pIe) == ELEM_ID_VENDOR_SPECIFIC) {
143 if (IsWPSElement(priv, (pIe + 2))) {
144 pIePointers->pWps =
145 (IEEEtypes_WPSElement_t
146 *)pIe;
147 }
148 }
149 // Add your code to process vendor specific elements not
150 // processed by above ROM_paser_getAssocIEPtr function.
151 }
152 break;
153 }
154 bufLen -= *(pIe + 1) + 2;
155 pIe += *(pIe + 1) + 2;
156 }
157 return bufLen;
158 }
159
160 BOOLEAN
parser_getAssocIEs(void * priv,UINT8 * pIe,int bufLen,AssocIePointers_t * pIePointers)161 parser_getAssocIEs(void *priv, UINT8 *pIe,
162 int bufLen, AssocIePointers_t *pIePointers)
163 {
164 phostsa_private psapriv = (phostsa_private)priv;
165 hostsa_util_fns *util_fns = &psapriv->util_fns;
166 BOOLEAN ieParseSuccessful = TRUE;
167
168 memset(util_fns, pIePointers, 0x00, sizeof(AssocIePointers_t));
169
170 while (bufLen) {
171 UINT8 ieType = *pIe;
172 UINT8 ieLen = *(pIe + 1);
173
174 if (bufLen < (ieLen + 2)) {
175 ieParseSuccessful = FALSE;
176 break;
177 }
178
179 switch (ieType) {
180 // add code for elements not handled in ROM function.
181 case ELEM_ID_AP_CHANNEL_REPORT:
182 pIePointers->pApChanRpt =
183 (IEEEtypes_ApChanRptElement_t *)pIe;
184 break;
185 #ifdef TDLS
186 case ELEM_ID_SUPPORTED_REGCLASS:
187 pIePointers->pSuppRegClass =
188 (IEEEtypes_SupportedRegClasses_t *)pIe;
189 break;
190 #endif
191
192 /* The following 5 elements, HT CAP, HT INFO, 20/40 Coex,
193 OBSS SCAN PARAM, and EXTENDED CAP, are ignored
194 here if 11n is not compiled. When 11n is compiled these
195 5 elements would be handled in ROM_parser_getAssocIEPtr
196 routine.
197
198 */
199 case ELEM_ID_HT_CAPABILITY:
200 case ELEM_ID_HT_INFORMATION:
201 case ELEM_ID_2040_BSS_COEXISTENCE:
202 case ELEM_ID_OBSS_SCAN_PARAM:
203 case ELEM_ID_EXT_CAPABILITIES:
204 /* Do not process these elements in ROM routine
205 ROM_parser_getAssocIEPtr
206 Note: a break here.
207 */
208 break;
209
210 /* Add element not handled by ROM_parser_getAssocIEPtr or
211 override element processing in ROM_parser_getAssocIEPtr
212 here.
213 \
214 */
215
216 case ELEM_ID_VENDOR_SPECIFIC:
217 default:
218 if (ROM_parser_getAssocIEPtr(priv, pIe, pIePointers) ==
219 FALSE) {
220 // Add your code to process vendor specific elements not
221 // processed by above ROM_paser_getAssocIEPtr function.
222 if (!pIePointers->pHtCap ||
223 !pIePointers->pHtInfo) {
224 switch (IsEpigramHTElement
225 (priv, (pIe + 2))) {
226
227 case VendSpecIE_HT_Cap:
228 if (!pIePointers->pHtCap) {
229 *(pIe + 4) =
230 ELEM_ID_HT_CAPABILITY;
231 *(pIe + 5) =
232 sizeof
233 (IEEEtypes_HT_Capability_t);
234 pIePointers->pHtCap =
235 (IEEEtypes_HT_Capability_t
236 *)(pIe + 4);
237 }
238 break;
239
240 case VendSpecIE_HT_Info:
241 if (!pIePointers->pHtInfo) {
242 *(pIe + 4) =
243 ELEM_ID_HT_INFORMATION;
244 *(pIe + 5) =
245 sizeof
246 (IEEEtypes_HT_Information_t);
247 pIePointers->pHtInfo =
248 (IEEEtypes_HT_Information_t
249 *)(pIe + 4);
250 }
251 break;
252
253 case VendSpecIE_Other:
254 default:
255 break;
256 }
257 }
258 }
259 break;
260
261 }
262 bufLen -= ieLen + 2;
263 pIe += ieLen + 2;
264 }
265 return ieParseSuccessful;
266 }
267
268 UINT8
parser_countNumInfoElements(UINT8 * pIe,int bufLen)269 parser_countNumInfoElements(UINT8 *pIe, int bufLen)
270 {
271 UINT8 ieCount = 0;
272
273 while (bufLen) {
274 if (bufLen < (*(pIe + 1) + 2)) {
275 break;
276 }
277
278 ieCount++;
279
280 bufLen -= *(pIe + 1) + 2;
281 pIe += *(pIe + 1) + 2;
282 }
283
284 return ieCount;
285 }
286