xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/rockchip_wlan/mvl88w8977/mlan/esa/common/parser.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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