blob: 679ef1293d5f57ab56a6a6d553e7e92e0a6f4d9a [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Jeff Johnson32d95a32012-09-10 13:15:23 -07002 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -07003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 *
24 * Airgo Networks, Inc proprietary. All rights reserved.
25 * This file limSmeReqUtils.cc contains the utility functions
26 * for processing SME request messages.
27 * Author: Chandra Modumudi
28 * Date: 02/11/02
29 * History:-
30 * Date Modified by Modification Information
31 * --------------------------------------------------------------------
32 * 05/26/10 js WPA handling in (Re)Assoc frames
33 *
34 */
35
36#include "wniApi.h"
37#if (WNI_POLARIS_FW_PRODUCT == AP)
38#include "wniCfgAp.h"
39#else
40#include "wniCfgSta.h"
41#endif
42#include "cfgApi.h"
43#include "sirApi.h"
44#include "schApi.h"
45#include "utilsApi.h"
46#include "limTypes.h"
47#include "limUtils.h"
48#include "limAssocUtils.h"
49#include "limSecurityUtils.h"
50#include "limSerDesUtils.h"
51
52
53
54/**
55 * limIsRSNieValidInSmeReqMessage()
56 *
57 *FUNCTION:
58 * This function is called to verify if the RSN IE
59 * received in various SME_REQ messages is valid or not
60 *
61 *LOGIC:
62 * RSN IE validity checks are performed in this function
63 *
64 *ASSUMPTIONS:
65 *
66 *NOTE:
67 *
68 * @param pMac Pointer to Global MAC structure
69 * @param pRSNie Pointer to received RSN IE
70 * @return true when RSN IE is valid, false otherwise
71 */
72
73static tANI_U8
74limIsRSNieValidInSmeReqMessage(tpAniSirGlobal pMac, tpSirRSNie pRSNie)
75{
76 tANI_U8 startPos = 0;
77 tANI_U32 privacy, val;
78 int len;
79
80 if (wlan_cfgGetInt(pMac, WNI_CFG_PRIVACY_ENABLED,
81 &privacy) != eSIR_SUCCESS)
82 {
83 limLog(pMac, LOGP,
84 FL("Unable to retrieve POI from CFG\n"));
85 }
86
87 if (wlan_cfgGetInt(pMac, WNI_CFG_RSN_ENABLED,
88 &val) != eSIR_SUCCESS)
89 {
90 limLog(pMac, LOGP,
91 FL("Unable to retrieve RSN_ENABLED from CFG\n"));
92 }
93
94 if (pRSNie->length && (!privacy || !val))
95 {
96 // Privacy & RSN not enabled in CFG.
97 /**
98 * In order to allow mixed mode for Guest access
99 * allow BSS creation/join with no Privacy capability
100 * yet advertising WPA IE
101 */
102 PELOG1(limLog(pMac, LOG1, FL("RSN ie len %d but PRIVACY %d RSN %d\n"),
103 pRSNie->length, privacy, val);)
104 }
105
106 if (pRSNie->length)
107 {
108 if ((pRSNie->rsnIEdata[0] != DOT11F_EID_RSN) &&
109 (pRSNie->rsnIEdata[0] != DOT11F_EID_WPA)
110#ifdef FEATURE_WLAN_WAPI
111 && (pRSNie->rsnIEdata[0] != DOT11F_EID_WAPI)
112#endif
113 )
114 {
115 limLog(pMac, LOGE, FL("RSN/WPA/WAPI EID %d not [%d || %d]\n"),
116 pRSNie->rsnIEdata[0], DOT11F_EID_RSN,
117 DOT11F_EID_WPA);
118 return false;
119 }
120
121 len = pRSNie->length;
122 startPos = 0;
123 while(len > 0)
124 {
125 // Check validity of RSN IE
126 if (pRSNie->rsnIEdata[startPos] == DOT11F_EID_RSN)
127 {
128 if((pRSNie->rsnIEdata[startPos+1] > DOT11F_IE_RSN_MAX_LEN) ||
129 (pRSNie->rsnIEdata[startPos+1] < DOT11F_IE_RSN_MIN_LEN))
130 {
131 limLog(pMac, LOGE, FL("RSN IE len %d not [%d,%d]\n"),
132 pRSNie->rsnIEdata[startPos+1], DOT11F_IE_RSN_MIN_LEN,
133 DOT11F_IE_RSN_MAX_LEN);
134 return false;
135 }
136 }
137 else if(pRSNie->rsnIEdata[startPos] == DOT11F_EID_WPA)
138 {
139 // Check validity of WPA IE
140 val = sirReadU32((tANI_U8 *) &pRSNie->rsnIEdata[startPos + 2]);
141 if((pRSNie->rsnIEdata[startPos + 1] < DOT11F_IE_WPA_MIN_LEN) ||
142 (pRSNie->rsnIEdata[startPos + 1] > DOT11F_IE_WPA_MAX_LEN) ||
143 (SIR_MAC_WPA_OUI != val))
144 {
145 limLog(pMac, LOGE,
146 FL("WPA IE len %d not [%d,%d] OR data 0x%x not 0x%x\n"),
147 pRSNie->rsnIEdata[startPos+1], DOT11F_IE_WPA_MIN_LEN,
148 DOT11F_IE_WPA_MAX_LEN, val, SIR_MAC_WPA_OUI);
149
150 return false;
151 }
152 }
153#ifdef FEATURE_WLAN_WAPI
154 else if(pRSNie->rsnIEdata[startPos] == DOT11F_EID_WAPI)
155 {
156 if((pRSNie->rsnIEdata[startPos+1] > DOT11F_IE_WAPI_MAX_LEN) ||
157 (pRSNie->rsnIEdata[startPos+1] < DOT11F_IE_WAPI_MIN_LEN))
158 {
159 limLog(pMac, LOGE,
160 FL("WAPI IE len %d not [%d,%d]\n"),
161 pRSNie->rsnIEdata[startPos+1], DOT11F_IE_WAPI_MIN_LEN,
162 DOT11F_IE_WAPI_MAX_LEN);
163
164 return false;
165 }
166 }
167#endif
168 else
169 {
170 //we will never be here, simply for completeness
171 return false;
172 }
173 startPos += 2 + pRSNie->rsnIEdata[startPos+1]; //EID + length field + length
174 len -= startPos;
175 }//while
176
177 }
178
179 return true;
180} /*** end limIsRSNieValidInSmeReqMessage() ***/
181
182/**
183 * limIsAddieValidInSmeReqMessage()
184 *
185 *FUNCTION:
186 * This function is called to verify if the Add IE
187 * received in various SME_REQ messages is valid or not
188 *
189 *LOGIC:
190 * Add IE validity checks are performed on only length
191 *
192 *ASSUMPTIONS:
193 *
194 *NOTE:
195 *
196 * @param pMac Pointer to Global MAC structure
197 * @param pWSCie Pointer to received WSC IE
198 * @return true when WSC IE is valid, false otherwise
199 */
200
201static tANI_U8
202limIsAddieValidInSmeReqMessage(tpAniSirGlobal pMac, tpSirAddie pAddie)
203{
204 int left = pAddie->length;
205 tANI_U8 *ptr = pAddie->addIEdata;
206 tANI_U8 elem_id, elem_len;
207
208 if (left == 0)
209 return true;
210
211 while(left >= 2)
212 {
213 elem_id = ptr[0];
214 elem_len = ptr[1];
215 left -= 2;
216 if(elem_len > left)
217 {
218 limLog( pMac, LOGE,
219 FL("****Invalid Add IEs eid = %d elem_len=%d left=%d*****\n"),
220 elem_id,elem_len,left);
221 return false;
222 }
223
224 left -= elem_len;
225 ptr += (elem_len + 2);
226 }
227 // there shouldn't be any left byte
228
229
230 return true;
231} /*** end limIsAddieValidInSmeReqMessage() ***/
232
233#ifdef WLAN_SOFTAP_FEATURE
234/**
235 * limSetRSNieWPAiefromSmeStartBSSReqMessage()
236 *
237 *FUNCTION:
238 * This function is called to verify if the RSN IE
239 * received in various SME_REQ messages is valid or not
240 *
241 *LOGIC:
242 * RSN IE validity checks are performed in this function
243 *
244 *ASSUMPTIONS:
245 *
246 *NOTE:
247 *
248 * @param pMac Pointer to Global MAC structure
249 * @param pRSNie Pointer to received RSN IE
250 * @return true when RSN IE is valid, false otherwise
251 */
252
253tANI_U8
254limSetRSNieWPAiefromSmeStartBSSReqMessage(tpAniSirGlobal pMac,
255 tpSirRSNie pRSNie,
256 tpPESession pSessionEntry)
257{
258 tANI_U8 wpaIndex = 0;
259 tANI_U32 privacy, val;
260
261 if (wlan_cfgGetInt(pMac, WNI_CFG_PRIVACY_ENABLED,
262 &privacy) != eSIR_SUCCESS)
263 {
264 limLog(pMac, LOGP,
265 FL("Unable to retrieve POI from CFG\n"));
266 }
267
268 if (wlan_cfgGetInt(pMac, WNI_CFG_RSN_ENABLED,
269 &val) != eSIR_SUCCESS)
270 {
271 limLog(pMac, LOGP,
272 FL("Unable to retrieve RSN_ENABLED from CFG\n"));
273 }
274
275 if (pRSNie->length && (!privacy || !val))
276 {
277 // Privacy & RSN not enabled in CFG.
278 /**
279 * In order to allow mixed mode for Guest access
280 * allow BSS creation/join with no Privacy capability
281 * yet advertising WPA IE
282 */
283 PELOG1(limLog(pMac, LOG1, FL("RSN ie len %d but PRIVACY %d RSN %d\n"),
284 pRSNie->length, privacy, val);)
285 }
286
287 if (pRSNie->length)
288 {
289 if ((pRSNie->rsnIEdata[0] != SIR_MAC_RSN_EID) &&
290 (pRSNie->rsnIEdata[0] != SIR_MAC_WPA_EID))
291 {
292 limLog(pMac, LOGE, FL("RSN/WPA EID %d not [%d || %d]\n"),
293 pRSNie->rsnIEdata[0], SIR_MAC_RSN_EID,
294 SIR_MAC_WPA_EID);
295 return false;
296 }
297
298 // Check validity of RSN IE
299 if ((pRSNie->rsnIEdata[0] == SIR_MAC_RSN_EID) &&
300#if 0 // Comparison always false
301 (pRSNie->rsnIEdata[1] > SIR_MAC_RSN_IE_MAX_LENGTH) ||
302#endif
303 (pRSNie->rsnIEdata[1] < SIR_MAC_RSN_IE_MIN_LENGTH))
304 {
305 limLog(pMac, LOGE, FL("RSN IE len %d not [%d,%d]\n"),
306 pRSNie->rsnIEdata[1], SIR_MAC_RSN_IE_MIN_LENGTH,
307 SIR_MAC_RSN_IE_MAX_LENGTH);
308 return false;
309 }
310
311 if (pRSNie->length > pRSNie->rsnIEdata[1] + 2)
312 {
313 if (pRSNie->rsnIEdata[0] != SIR_MAC_RSN_EID)
314 {
315 limLog(pMac,
316 LOGE,
317 FL("First byte[%d] in rsnIEdata is not RSN_EID\n"),
318 pRSNie->rsnIEdata[1]);
319 return false;
320 }
321
322 limLog(pMac,
323 LOG1,
324 FL("WPA IE is present along with WPA2 IE\n"));
325 wpaIndex = 2 + pRSNie->rsnIEdata[1];
326 }
327 else if ((pRSNie->length == pRSNie->rsnIEdata[1] + 2) &&
328 (pRSNie->rsnIEdata[0] == SIR_MAC_RSN_EID))
329 {
330 limLog(pMac,
331 LOG1,
332 FL("Only RSN IE is present\n"));
333 dot11fUnpackIeRSN(pMac,&pRSNie->rsnIEdata[2],
334 (tANI_U8)pRSNie->length,&pSessionEntry->gStartBssRSNIe);
335 }
336 else if ((pRSNie->length == pRSNie->rsnIEdata[1] + 2) &&
337 (pRSNie->rsnIEdata[0] == SIR_MAC_WPA_EID))
338 {
339 limLog(pMac,
340 LOG1,
341 FL("Only WPA IE is present\n"));
342
343 dot11fUnpackIeWPA(pMac,&pRSNie->rsnIEdata[6],(tANI_U8)pRSNie->length-4,
344 &pSessionEntry->gStartBssWPAIe);
345 }
346
347 // Check validity of WPA IE
348 val = sirReadU32((tANI_U8 *) &pRSNie->rsnIEdata[wpaIndex + 2]);
349
350 if ((pRSNie->rsnIEdata[wpaIndex] == SIR_MAC_WPA_EID) &&
351#if 0 // Comparison always false
352 (pRSNie->rsnIEdata[wpaIndex + 1] > SIR_MAC_WPA_IE_MAX_LENGTH) ||
353#endif
354 ((pRSNie->rsnIEdata[wpaIndex + 1] < SIR_MAC_WPA_IE_MIN_LENGTH) ||
355 (SIR_MAC_WPA_OUI != val)))
356 {
357 limLog(pMac, LOGE,
358 FL("WPA IE len %d not [%d,%d] OR data 0x%x not 0x%x\n"),
359 pRSNie->rsnIEdata[1], SIR_MAC_RSN_IE_MIN_LENGTH,
360 SIR_MAC_RSN_IE_MAX_LENGTH, val, SIR_MAC_WPA_OUI);
361
362 return false;
363 }
364 else
365 {
366 /* Both RSN and WPA IEs are present */
367 dot11fUnpackIeRSN(pMac,&pRSNie->rsnIEdata[2],
368 (tANI_U8)pRSNie->length,&pSessionEntry->gStartBssRSNIe);
369
370 dot11fUnpackIeWPA(pMac,&pRSNie->rsnIEdata[wpaIndex + 6],
371 pRSNie->rsnIEdata[wpaIndex + 1]-4,
372 &pSessionEntry->gStartBssWPAIe);
373
374 }
375 }
376
377 return true;
378} /*** end limSetRSNieWPAiefromSmeStartBSSReqMessage() ***/
379#endif
380
381#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && (WNI_POLARIS_FW_PRODUCT == AP)
382/**
383 * limIsBssInfoValidInSmeReqMessage()
384 *
385 *FUNCTION:
386 * This function is called to verify if the BSS info
387 * received in various SME_REQ messages is valid or not
388 *
389 *LOGIC:
390 * BSS info validity checks are performed in this function
391 *
392 *ASSUMPTIONS:
393 *
394 *NOTE:
395 *
396 * @param pMac Pointer to Global MAC structure
397 * @param pBssInfo Pointer to received Bss Information
398 * @return true when BSS info is valid, false otherwise
399 */
400
401static tANI_U8
402limIsBssInfoValidInSmeReqMessage(tpAniSirGlobal pMac,
403 tpSirNeighborBssInfo pBssInfo)
404{
405 tANI_U8 valid = true;
406
407 if ((pBssInfo->bssType != eSIR_INFRASTRUCTURE_MODE) ||
408 limIsGroupAddr(pBssInfo->bssId) ||
409 !pBssInfo->channelId ||
410 !pBssInfo->ssId.length ||
411 (pBssInfo->ssId.length > SIR_MAC_MAX_SSID_LENGTH) ||
412 !limIsRSNieValidInSmeReqMessage(pMac, &pBssInfo->rsnIE))
413 {
414 valid = false;
415 goto end;
416 }
417
418end:
419 return valid;
420} /*** end limIsBssInfoValidInSmeReqMessage() ***/
421#else
422
423
424
425/**
426 * limIsBssDescrValidInSmeReqMessage()
427 *
428 *FUNCTION:
429 * This function is called to verify if the BSS Descr
430 * received in various SME_REQ messages is valid or not
431 *
432 *LOGIC:
433 * BSS Descritipion validity checks are performed in this function
434 *
435 *ASSUMPTIONS:
436 *
437 *NOTE:
438 *
439 * @param pMac Pointer to Global MAC structure
440 * @param pBssDescr Pointer to received Bss Descritipion
441 * @return true when BSS description is valid, false otherwise
442 */
443
444static tANI_U8
445limIsBssDescrValidInSmeReqMessage(tpAniSirGlobal pMac,
446 tpSirBssDescription pBssDescr)
447{
448 tANI_U8 valid = true;
449
450 if (limIsAddrBC(pBssDescr->bssId) ||
451 !pBssDescr->channelId)
452 {
453 valid = false;
454 goto end;
455 }
456
457end:
458 return valid;
459} /*** end limIsBssDescrValidInSmeReqMessage() ***/
460#endif
461
462
463
464/**
465 * limIsSmeStartReqValid()
466 *
467 *FUNCTION:
468 * This function is called by limProcessSmeReqMessages() upon
469 * receiving SME_START_REQ message from application.
470 *
471 *LOGIC:
472 * Message validity checks are performed in this function
473 *
474 *ASSUMPTIONS:
475 *
476 *NOTE:
477 *
478 * @param pMsg - Pointer to received SME_START_BSS_REQ message
479 * @return true when received SME_START_REQ is formatted correctly
480 * false otherwise
481 */
482
483tANI_U8
484limIsSmeStartReqValid(tpAniSirGlobal pMac, tANI_U32 *pMsg)
485{
486 tANI_U8 valid = true;
487
488 if (((tpSirSmeStartReq) pMsg)->length != sizeof(tSirSmeStartReq))
489 {
490 /**
491 * Invalid length in START_REQ message
492 * Log error.
493 */
494 limLog(pMac, LOGW,
495 FL("Invalid length %d in eWNI_SME_START_REQ\n"),
496 ((tpSirSmeStartReq) pMsg)->length);
497
498 valid = false;
499 goto end;
500 }
501
502end:
503 return valid;
504} /*** end limIsSmeStartReqValid() ***/
505
506
507
508/**
509 * limIsSmeStartBssReqValid()
510 *
511 *FUNCTION:
512 * This function is called by limProcessSmeReqMessages() upon
513 * receiving SME_START_BSS_REQ message from application.
514 *
515 *LOGIC:
516 * Message validity checks are performed in this function
517 *
518 *ASSUMPTIONS:
519 *
520 *NOTE:
521 *
522 * @param pMac Pointer to Global MAC structure
523 * @param pStartBssReq Pointer to received SME_START_BSS_REQ message
524 * @return true when received SME_START_BSS_REQ is formatted correctly
525 * false otherwise
526 */
527
528tANI_U8
529limIsSmeStartBssReqValid(tpAniSirGlobal pMac,
530 tpSirSmeStartBssReq pStartBssReq)
531{
532 tANI_U8 i = 0;
533 tANI_U8 valid = true;
534
535 PELOG1(limLog(pMac, LOG1,
536 FL("Parsed START_BSS_REQ fields are bssType=%d, channelId=%d, SSID len=%d, rsnIE len=%d, nwType=%d, rateset len=%d\n"),
537 pStartBssReq->bssType,
538 pStartBssReq->channelId,
539 pStartBssReq->ssId.length,
540 pStartBssReq->rsnIE.length,
541 pStartBssReq->nwType,
542 pStartBssReq->operationalRateSet.numRates);)
543
544 switch (pStartBssReq->bssType)
545 {
546 case eSIR_INFRASTRUCTURE_MODE:
547#if (WNI_POLARIS_FW_PRODUCT == AP)
548 /* Check for the AP Role/Station role here and act accordingly.
549 * Currently assuming this as AP and breaks TODO */
550 break;
551#endif
552 /**
553 * Should not have received start BSS req with bssType
554 * Infrastructure on STA.
555 * Log error.
556 */
557 limLog(pMac, LOGE, FL("Invalid bssType %d in eWNI_SME_START_BSS_REQ\n"),pStartBssReq->bssType);
558 valid = false;
559 goto end;
560 break;
561
562 case eSIR_IBSS_MODE:
563 break;
564
565 /* Added for BT AMP support */
566 case eSIR_BTAMP_STA_MODE:
567 break;
568
569 /* Added for BT AMP support */
570 case eSIR_BTAMP_AP_MODE:
571 break;
572
573#ifdef WLAN_SOFTAP_FEATURE
574 /* Added for SoftAP support */
575 case eSIR_INFRA_AP_MODE:
576 break;
577#endif
578
579 default:
580 /**
581 * Should not have received start BSS req with bssType
582 * other than Infrastructure/IBSS.
583 * Log error
584 */
585 limLog(pMac, LOGW,
586 FL("Invalid bssType %d in eWNI_SME_START_BSS_REQ\n"),
587 pStartBssReq->bssType);
588
589 valid = false;
590 goto end;
591 }
592
593#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && (WNI_POLARIS_FW_PRODUCT == AP)
594
595 /* Assumed as AP again, need to check the role and change accordingly */
596 if (pStartBssReq->bssType == eSIR_INFRASTRUCTURE_MODE)
597 {
598 if ((pStartBssReq->numSSID == 1) && pStartBssReq->ssId.length &&
599 ((pStartBssReq->ssId.length != pStartBssReq->ssIdList[0].length) ||
600 ( !palEqualMemory( pMac->hHdd,pStartBssReq->ssId.ssId,
601 pStartBssReq->ssIdList[0].ssId,
602 pStartBssReq->ssId.length) )))
603 {
604 /**
605 * Invalid combination of ssID length
606 * and number of SSIDs present.
607 * Reject START_BSS_REQ.
608 */
609 limLog(pMac, LOGW,
610 FL("Mismatch in SSID length & numSSID in SME_START_BSS_REQ\n"));
611
612 valid = false;
613 goto end;
614 }
615
616 if (!pStartBssReq->numSSID ||
617 (pStartBssReq->ssId.length && (pStartBssReq->numSSID != 1)))
618 {
619 /**
620 * Invalid combination of ssID length
621 * and number of SSIDs present.
622 * Reject START_BSS_REQ.
623 */
624 limLog(pMac, LOGW,
625 FL("Mismatch in SSID length[%d] & numSSID[%d] in SME_START_BSS_REQ\n"),
626 pStartBssReq->ssId.length, pStartBssReq->numSSID);
627
628 valid = false;
629 goto end;
630 }
631 }
632#endif
633#if defined(ANI_PRODUCT_TYPE_CLIENT) || defined(ANI_AP_CLIENT_SDK)
634 /* This below code is client specific code. TODO */
635 if (pStartBssReq->bssType == eSIR_IBSS_MODE)
636 {
637 if (!pStartBssReq->ssId.length ||
638 (pStartBssReq->ssId.length > SIR_MAC_MAX_SSID_LENGTH))
639 {
640 // Invalid length for SSID.
641 // Reject START_BSS_REQ
642 limLog(pMac, LOGW,
643 FL("Invalid SSID length in eWNI_SME_START_BSS_REQ\n"));
644
645 valid = false;
646 goto end;
647 }
648 }
649#endif
650
651#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && (WNI_POLARIS_FW_PRODUCT == AP)
652 /* Assumed as AP TODO */
653 if (pStartBssReq->bssType == eSIR_INFRASTRUCTURE_MODE)
654 {
655 tpSirAlternateRadioInfo pRadioInfo;
656
657 pRadioInfo = pStartBssReq->alternateRadioList.alternateRadio;
658 for (i = 0; i < pStartBssReq->alternateRadioList.numBss; i++)
659 {
660 if (limIsGroupAddr(pRadioInfo->bssId))
661 {
662 // Invalid mate BSSID.
663 // Reject START_BSS_REQ
664 limLog(pMac, LOGW,
665 FL("Invalid mate BSSID in eWNI_SME_START_BSS_REQ\n"));
666
667 valid = false;
668 goto end;
669 }
670 pRadioInfo += sizeof(tSirAlternateRadioInfo);
671 }
672
673 /*
674 ** check WDS info length
675 **/
676 if (pStartBssReq->wdsInfo.wdsLength > ANI_WDS_INFO_MAX_LENGTH)
677 {
678 PELOGW(limLog(pMac, LOGW, FL("Illegal WDS info length\n"));)
679 valid = false;
680 goto end;
681 }
682 }
683#endif
684
685 if (!limIsRSNieValidInSmeReqMessage(pMac, &pStartBssReq->rsnIE))
686 {
687 valid = false;
688 goto end;
689 }
690
691 if (pStartBssReq->nwType != eSIR_11A_NW_TYPE &&
692 pStartBssReq->nwType != eSIR_11B_NW_TYPE &&
693 pStartBssReq->nwType != eSIR_11G_NW_TYPE)
694 {
695 valid = false;
696 goto end;
697 }
698
699 if (pStartBssReq->nwType == eSIR_11A_NW_TYPE)
700 {
701 for (i = 0; i < pStartBssReq->operationalRateSet.numRates; i++)
702 if (!sirIsArate(pStartBssReq->operationalRateSet.rate[i] & 0x7F))
703 {
704 // Invalid Operational rates
705 // Reject START_BSS_REQ
706 limLog(pMac, LOGW,
707 FL("Invalid operational rates in eWNI_SME_START_BSS_REQ\n"));
708 sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOGW,
709 pStartBssReq->operationalRateSet.rate,
710 pStartBssReq->operationalRateSet.numRates);
711
712 valid = false;
713 goto end;
714 }
715 }
716 // check if all the rates in the operatioal rate set are legal 11G rates
717 else if (pStartBssReq->nwType == eSIR_11G_NW_TYPE)
718 {
719 for (i = 0; i < pStartBssReq->operationalRateSet.numRates; i++)
720 if (!sirIsGrate(pStartBssReq->operationalRateSet.rate[i] & 0x7F))
721 {
722 // Invalid Operational rates
723 // Reject START_BSS_REQ
724 limLog(pMac, LOGW,
725 FL("Invalid operational rates in eWNI_SME_START_BSS_REQ\n"));
726 sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOGW,
727 pStartBssReq->operationalRateSet.rate,
728 pStartBssReq->operationalRateSet.numRates);
729
730 valid = false;
731 goto end;
732 }
733 }
734 else
735 {
736 for (i = 0; i < pStartBssReq->operationalRateSet.numRates; i++)
737 if (!sirIsBrate(pStartBssReq->operationalRateSet.rate[i] & 0x7F))
738 {
739 // Invalid Operational rates
740 // Reject START_BSS_REQ
741 limLog(pMac, LOGW,
742 FL("Invalid operational rates in eWNI_SME_START_BSS_REQ\n"));
743 sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOGW,
744 pStartBssReq->operationalRateSet.rate,
745 pStartBssReq->operationalRateSet.numRates);
746
747 valid = false;
748 goto end;
749 }
750 }
751
752end:
753 return valid;
754} /*** end limIsSmeStartBssReqValid() ***/
755
756
757
758/**
759 * limIsSmeJoinReqValid()
760 *
761 *FUNCTION:
762 * This function is called by limProcessSmeReqMessages() upon
763 * receiving SME_JOIN_REQ message from application.
764 *
765 *LOGIC:
766 * Message validity checks are performed in this function
767 *
768 *ASSUMPTIONS:
769 *
770 *NOTE:
771 *
772 * @param pMac Pointer to Global MAC structure
773 * @param pJoinReq Pointer to received SME_JOIN_REQ message
774 * @return true when received SME_JOIN_REQ is formatted correctly
775 * false otherwise
776 */
777
778tANI_U8
779limIsSmeJoinReqValid(tpAniSirGlobal pMac, tpSirSmeJoinReq pJoinReq)
780{
781 tANI_U8 valid = true;
782
783#if (WNI_POLARIS_FW_PACKAGE == ADVANCED)
784 if (pJoinReq->assocType > eSIR_TRANSFERRED)
785 {
786 /// Received eWNI_SME_JOIN_REQ with invalid assocType
787 // Log the event
788 limLog(pMac, LOGW,
789 FL("received SME_JOIN_REQ with invalid assocType\n"));
790
791 valid = false;
792 goto end;
793 }
794#endif
795
796 if (!limIsRSNieValidInSmeReqMessage(pMac, &pJoinReq->rsnIE))
797 {
798 limLog(pMac, LOGE,
799 FL("received SME_JOIN_REQ with invalid RSNIE\n"));
800 valid = false;
801 goto end;
802 }
803
804 if (!limIsAddieValidInSmeReqMessage(pMac, &pJoinReq->addIEScan))
805 {
806 limLog(pMac, LOGE,
807 FL("received SME_JOIN_REQ with invalid additional IE for scan\n"));
808 valid = false;
809 goto end;
810 }
811
812 if (!limIsAddieValidInSmeReqMessage(pMac, &pJoinReq->addIEAssoc))
813 {
814 limLog(pMac, LOGE,
815 FL("received SME_JOIN_REQ with invalid additional IE for assoc\n"));
816 valid = false;
817 goto end;
818 }
819
820
821#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && (WNI_POLARIS_FW_PRODUCT == AP)
822 if (!limIsBssInfoValidInSmeReqMessage(
823 pMac,
824 pJoinReq->neighborBssList.bssList))
825#else
826 if (!limIsBssDescrValidInSmeReqMessage(pMac,
827 &pJoinReq->bssDescription))
828#endif
829 {
830 /// Received eWNI_SME_JOIN_REQ with invalid BSS Info
831 // Log the event
832 limLog(pMac, LOGE,
833 FL("received SME_JOIN_REQ with invalid bssInfo\n"));
834
835 valid = false;
836 goto end;
837 }
838
Jeff Johnsone7245742012-09-05 17:12:55 -0700839 /*
840 Reject Join Req if the Self Mac Address and
841 the Ap's Mac Address is same
842 */
843 if( palEqualMemory( pMac->hHdd, (tANI_U8* ) pJoinReq->selfMacAddr,
844 (tANI_U8 *) pJoinReq->bssDescription.bssId,
845 (tANI_U8) (sizeof(tSirMacAddr))))
846 {
847 // Log the event
848 limLog(pMac, LOGE,
849 FL("received SME_JOIN_REQ with Self Mac and BSSID Same\n"));
850
851 valid = false;
852 goto end;
853 }
854
Jeff Johnson295189b2012-06-20 16:38:30 -0700855end:
856 return valid;
857} /*** end limIsSmeJoinReqValid() ***/
858
859
860
861/**
862 * limIsSmeDisassocReqValid()
863 *
864 *FUNCTION:
865 * This function is called by limProcessSmeReqMessages() upon
866 * receiving SME_DISASSOC_REQ message from application.
867 *
868 *LOGIC:
869 * Message validity checks are performed in this function
870 *
871 *ASSUMPTIONS:
872 *
873 *NOTE:
874 *
875 * @param pMac Pointer to Global MAC structure
876 * @param pDisassocReq Pointer to received SME_DISASSOC_REQ message
877 * @return true When received SME_DISASSOC_REQ is formatted
878 * correctly
879 * false otherwise
880 */
881
882tANI_U8
883limIsSmeDisassocReqValid(tpAniSirGlobal pMac,
884 tpSirSmeDisassocReq pDisassocReq, tpPESession psessionEntry)
885{
886 if (limIsGroupAddr(pDisassocReq->peerMacAddr) &&
887 !limIsAddrBC(pDisassocReq->peerMacAddr))
888 return false;
889
890#if (WNI_POLARIS_FW_PRODUCT == AP)
891 if (((psessionEntry->limSystemRole == eLIM_AP_ROLE) &&
892 ((pDisassocReq->aid < 2) || (pDisassocReq->aid > 2007))) ||
893 ((psessionEntry->limSystemRole == eLIM_STA_ROLE) &&
894 (pDisassocReq->aid != 1)))
895 return false;
896#endif
897
898 return true;
899} /*** end limIsSmeDisassocReqValid() ***/
900
901
902
903/**
904 * limIsSmeDisassocCnfValid()
905 *
906 *FUNCTION:
907 * This function is called by limProcessSmeReqMessages() upon
908 * receiving SME_DISASSOC_CNF message from application.
909 *
910 *LOGIC:
911 * Message validity checks are performed in this function
912 *
913 *ASSUMPTIONS:
914 *
915 *NOTE:
916 *
917 * @param pMac Pointer to Global MAC structure
918 * @param pDisassocCnf Pointer to received SME_DISASSOC_REQ message
919 * @return true When received SME_DISASSOC_CNF is formatted
920 * correctly
921 * false otherwise
922 */
923
924tANI_U8
925limIsSmeDisassocCnfValid(tpAniSirGlobal pMac,
926 tpSirSmeDisassocCnf pDisassocCnf, tpPESession psessionEntry)
927{
928 if (limIsGroupAddr(pDisassocCnf->peerMacAddr))
929 return false;
930
931#if (WNI_POLARIS_FW_PRODUCT == AP)
932 if (((psessionEntry->limSystemRole == eLIM_AP_ROLE) &&
933 ((pDisassocCnf->aid < 2) || (pDisassocCnf->aid > 2007))) ||
934 ((psessionEntry->limSystemRole == eLIM_STA_ROLE) &&
935 (pDisassocCnf->aid != 1)))
936 return false;
937#endif
938 return true;
939} /*** end limIsSmeDisassocCnfValid() ***/
940
941
942
943/**
944 * limIsSmeDeauthReqValid()
945 *
946 *FUNCTION:
947 * This function is called by limProcessSmeReqMessages() upon
948 * receiving SME_DEAUTH_REQ message from application.
949 *
950 *LOGIC:
951 * Message validity checks are performed in this function
952 *
953 *ASSUMPTIONS:
954 *
955 *NOTE:
956 *
957 * @param pMac Pointer to Global MAC structure
958 * @param pDeauthReq Pointer to received SME_DEAUTH_REQ message
959 * @return true When received SME_DEAUTH_REQ is formatted correctly
960 * false otherwise
961 */
962
963tANI_U8
964limIsSmeDeauthReqValid(tpAniSirGlobal pMac, tpSirSmeDeauthReq pDeauthReq, tpPESession psessionEntry)
965{
966 if (limIsGroupAddr(pDeauthReq->peerMacAddr) &&
967 !limIsAddrBC(pDeauthReq->peerMacAddr))
968 return false;
969
970#if (WNI_POLARIS_FW_PRODUCT == AP)
971 if (((psessionEntryp->limSystemRole == eLIM_AP_ROLE) &&
972 ((pDeauthReq->aid < 2) || (pDeauthReq->aid > 2007))) ||
973 ((psessionEntryp->limSystemRole == eLIM_STA_ROLE) &&
974 (pDeauthReq->aid != 1)))
975 return false;
976#endif
977 return true;
978} /*** end limIsSmeDeauthReqValid() ***/
979
980
981
982/**
983 * limIsSmeScanReqValid()
984 *
985 *FUNCTION:
986 * This function is called by limProcessSmeReqMessages() upon
987 * receiving SME_SCAN_REQ message from application.
988 *
989 *LOGIC:
990 * Message validity checks are performed in this function
991 *
992 *ASSUMPTIONS:
993 *
994 *NOTE:
995 *
996 * @param pScanReq Pointer to received SME_SCAN_REQ message
997 * @return true when received SME_SCAN_REQ is formatted correctly
998 * false otherwise
999 */
1000
1001tANI_U8
1002limIsSmeScanReqValid(tpAniSirGlobal pMac, tpSirSmeScanReq pScanReq)
1003{
1004 tANI_U8 valid = true;
1005 tANI_U8 i = 0;
1006
1007 for (i = 0; i < pScanReq->numSsid; i++)
1008 {
1009 if (pScanReq->ssId[i].length > SIR_MAC_MAX_SSID_LENGTH)
1010 {
1011 valid = false;
1012 goto end;
1013 }
1014 }
1015 if ((pScanReq->bssType > eSIR_AUTO_MODE) ||
1016 (limIsGroupAddr(pScanReq->bssId) && !limIsAddrBC(pScanReq->bssId)) ||
1017 (!(pScanReq->scanType == eSIR_PASSIVE_SCAN || pScanReq->scanType == eSIR_ACTIVE_SCAN)) ||
1018 (pScanReq->channelList.numChannels > SIR_MAX_NUM_CHANNELS))
1019 {
1020 valid = false;
1021 goto end;
1022 }
1023
1024 /*
1025 ** check min/max channelTime range
1026 **/
1027
1028 if ((pScanReq->scanType == eSIR_ACTIVE_SCAN) &&
1029 (pScanReq->maxChannelTime < pScanReq->minChannelTime))
1030 {
1031 PELOGW(limLog(pMac, LOGW, FL("Max Channel Time < Min Channel Time\n"));)
1032 valid = false;
1033 goto end;
1034 }
1035
1036end:
1037 return valid;
1038} /*** end limIsSmeScanReqValid() ***/
1039
1040
1041
1042/**
1043 * limIsSmeAuthReqValid()
1044 *
1045 *FUNCTION:
1046 * This function is called by limProcessSmeReqMessages() upon
1047 * receiving SME_AUTH_REQ message from application.
1048 *
1049 *LOGIC:
1050 * Message validity checks are performed in this function
1051 *
1052 *ASSUMPTIONS:
1053 *
1054 *NOTE:
1055 *
1056 * @param pAuthReq Pointer to received SME_AUTH_REQ message
1057 * @return true when received SME_AUTH_REQ is formatted correctly
1058 * false otherwise
1059 */
1060
1061tANI_U8
1062limIsSmeAuthReqValid(tpSirSmeAuthReq pAuthReq)
1063{
1064 tANI_U8 valid = true;
1065
1066 if (limIsGroupAddr(pAuthReq->peerMacAddr) ||
1067 (pAuthReq->authType > eSIR_AUTO_SWITCH) ||
1068 !pAuthReq->channelNumber)
1069 {
1070 valid = false;
1071 goto end;
1072 }
1073
1074end:
1075 return valid;
1076} /*** end limIsSmeAuthReqValid() ***/
1077
1078
1079
1080/**
1081 * limIsSmeSetContextReqValid()
1082 *
1083 *FUNCTION:
1084 * This function is called by limProcessSmeReqMessages() upon
1085 * receiving SME_SET_CONTEXT_REQ message from application.
1086 *
1087 *LOGIC:
1088 * Message validity checks are performed in this function
1089 *
1090 *ASSUMPTIONS:
1091 *
1092 *NOTE:
1093 *
1094 * @param pMsg - Pointer to received SME_SET_CONTEXT_REQ message
1095 * @return true when received SME_SET_CONTEXT_REQ is formatted correctly
1096 * false otherwise
1097 */
1098
1099tANI_U8
1100limIsSmeSetContextReqValid(tpAniSirGlobal pMac, tpSirSmeSetContextReq pSetContextReq)
1101{
1102 tANI_U8 i = 0;
1103 tANI_U8 valid = true;
1104 tpSirKeys pKey = pSetContextReq->keyMaterial.key;
1105
1106 if ((pSetContextReq->keyMaterial.edType != eSIR_ED_WEP40) &&
1107 (pSetContextReq->keyMaterial.edType != eSIR_ED_WEP104) &&
1108 (pSetContextReq->keyMaterial.edType != eSIR_ED_NONE) &&
1109#ifdef FEATURE_WLAN_WAPI
1110 (pSetContextReq->keyMaterial.edType != eSIR_ED_WPI) &&
1111#endif
1112 !pSetContextReq->keyMaterial.numKeys)
1113 {
1114 /**
1115 * No keys present in case of TKIP or CCMP
1116 * Log error.
1117 */
1118 limLog(pMac, LOGW,
1119 FL("No keys present in SME_SETCONTEXT_REQ for edType=%d\n"),
1120 pSetContextReq->keyMaterial.edType);
1121
1122 valid = false;
1123 goto end;
1124 }
1125
1126 if (pSetContextReq->keyMaterial.numKeys &&
1127 (pSetContextReq->keyMaterial.edType == eSIR_ED_NONE))
1128 {
1129 /**
1130 * Keys present in case of no ED policy
1131 * Log error.
1132 */
1133 limLog(pMac, LOGW,
1134 FL("Keys present in SME_SETCONTEXT_REQ for edType=%d\n"),
1135 pSetContextReq->keyMaterial.edType);
1136
1137 valid = false;
1138 goto end;
1139 }
1140
1141 if (pSetContextReq->keyMaterial.edType >= eSIR_ED_NOT_IMPLEMENTED)
1142 {
1143 /**
1144 * Invalid edType in the message
1145 * Log error.
1146 */
1147 limLog(pMac, LOGW,
1148 FL("Invalid edType=%d in SME_SETCONTEXT_REQ\n"),
1149 pSetContextReq->keyMaterial.edType);
1150
1151 valid = false;
1152 goto end;
1153 }
1154 else if (pSetContextReq->keyMaterial.edType > eSIR_ED_NONE)
1155 {
1156 tANI_U32 poi;
1157
1158 if (wlan_cfgGetInt(pMac, WNI_CFG_PRIVACY_ENABLED,
1159 &poi) != eSIR_SUCCESS)
1160 {
1161 limLog(pMac, LOGP,
1162 FL("Unable to retrieve POI from CFG\n"));
1163 }
1164
1165 if (!poi)
1166 {
1167 /**
1168 * Privacy is not enabled
1169 * In order to allow mixed mode for Guest access
1170 * allow BSS creation/join with no Privacy capability
1171 * yet advertising WPA IE
1172 */
1173 PELOG1(limLog(pMac, LOG1,
1174 FL("Privacy is not enabled, yet non-None EDtype=%d in SME_SETCONTEXT_REQ\n"),
1175 pSetContextReq->keyMaterial.edType);)
1176 }
1177 }
1178
1179 for (i = 0; i < pSetContextReq->keyMaterial.numKeys; i++)
1180 {
1181 if (((pSetContextReq->keyMaterial.edType == eSIR_ED_WEP40) &&
1182 (pKey->keyLength != 5)) ||
1183 ((pSetContextReq->keyMaterial.edType == eSIR_ED_WEP104) &&
1184 (pKey->keyLength != 13)) ||
1185 ((pSetContextReq->keyMaterial.edType == eSIR_ED_TKIP) &&
1186 (pKey->keyLength != 32)) ||
1187#ifdef FEATURE_WLAN_WAPI
1188 ((pSetContextReq->keyMaterial.edType == eSIR_ED_WPI) &&
1189 (pKey->keyLength != 32)) ||
1190#endif
1191 ((pSetContextReq->keyMaterial.edType == eSIR_ED_CCMP) &&
1192 (pKey->keyLength != 16)))
1193 {
1194 /**
1195 * Invalid key length for a given ED type
1196 * Log error.
1197 */
1198 limLog(pMac, LOGW,
1199 FL("Invalid keyLength =%d for edType=%d in SME_SETCONTEXT_REQ\n"),
1200 pKey->keyLength, pSetContextReq->keyMaterial.edType);
1201
1202 valid = false;
1203 goto end;
1204 }
1205 pKey++;
1206 }
1207
1208end:
1209 return valid;
1210} /*** end limIsSmeSetContextReqValid() ***/
1211
1212
1213
1214/**
1215 * limIsSmeStopBssReqValid()
1216 *
1217 *FUNCTION:
1218 * This function is called by limProcessSmeReqMessages() upon
1219 * receiving SME_STOP_BSS_REQ message from application.
1220 *
1221 *LOGIC:
1222 * Message validity checks are performed in this function
1223 *
1224 *ASSUMPTIONS:
1225 *
1226 *NOTE:
1227 *
1228 * @param pMsg - Pointer to received SME_STOP_BSS_REQ message
1229 * @return true when received SME_STOP_BSS_REQ is formatted correctly
1230 * false otherwise
1231 */
1232
1233tANI_U8
1234limIsSmeStopBssReqValid(tANI_U32 *pMsg)
1235{
1236 tANI_U8 valid = true;
1237
1238 return valid;
1239} /*** end limIsSmeStopBssReqValid() ***/
1240
1241
1242/**
1243 * limGetBssIdFromSmeJoinReqMsg()
1244 *
1245 *FUNCTION:
1246 * This function is called in various places to get BSSID
1247 * from BSS description/Neighbor BSS Info in the SME_JOIN_REQ/
1248 * SME_REASSOC_REQ message.
1249 *
1250 *PARAMS:
1251 *
1252 *LOGIC:
1253 *
1254 *ASSUMPTIONS:
1255 * NA
1256 *
1257 *NOTE:
1258 * NA
1259 *
1260 * @param pBuf - Pointer to received SME_JOIN/SME_REASSOC_REQ
1261 * message
1262 * @return pBssId - Pointer to BSSID
1263 */
1264
1265tANI_U8*
1266limGetBssIdFromSmeJoinReqMsg(tANI_U8 *pBuf)
1267{
1268 if (!pBuf)
1269 return NULL;
1270
1271 pBuf += sizeof(tANI_U32); // skip message header
1272
1273#if (WNI_POLARIS_FW_PACKAGE == ADVANCED)
1274 pBuf += sizeof(tSirAssocType); // skip assocType
1275#endif
1276
1277 pBuf += limGetU16(pBuf) + sizeof(tANI_U16); // skip RSN IE
1278
1279#if (WNI_POLARIS_FW_PACKAGE == ADVANCED) && (WNI_POLARIS_FW_PRODUCT == AP)
1280 pBuf += sizeof(tAniBool); // skip BP indicator
1281 pBuf += sizeof(tSirBpIndicatorType); // skip BP indicator type
1282 pBuf += sizeof(tANI_U32); // skip number of neighbor BSS
1283#else
1284 pBuf += sizeof(tANI_U16); // skip length of BSS description
1285#endif
1286
1287 return (pBuf);
1288} /*** end limGetBssIdFromSmeJoinReqMsg() ***/
1289
1290