blob: 550231ff03dafe24b0c28f2e02cd333fb13d494a [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
2 * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
3 *
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 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
28/*
29 *
30 * This file lim_sme_req_utils.cc contains the utility functions
31 * for processing SME request messages.
32 * Author: Chandra Modumudi
33 * Date: 02/11/02
34 * History:-
35 * Date Modified by Modification Information
36 * --------------------------------------------------------------------
37 * 05/26/10 js WPA handling in (Re)Assoc frames
38 *
39 */
40
41#include "wni_api.h"
42#include "wni_cfg.h"
43#include "cfg_api.h"
44#include "sir_api.h"
45#include "sch_api.h"
46#include "utils_api.h"
47#include "lim_types.h"
48#include "lim_utils.h"
49#include "lim_assoc_utils.h"
50#include "lim_security_utils.h"
51#include "lim_ser_des_utils.h"
52
53/**
54 * lim_is_rs_nie_valid_in_sme_req_message()
55 *
56 * @mac_ctx Pointer to Global MAC structure
57 * @rsn_ie Pointer to received RSN IE
58 *
59 * This function is called to verify if the RSN IE received in various SME_REQ
60 * messages is valid or not
61 *
62 * Return: true when RSN IE is valid, false otherwise
63 *
64 */
65
66static uint8_t
67lim_is_rsn_ie_valid_in_sme_req_message(tpAniSirGlobal mac_ctx, tpSirRSNie rsn_ie)
68{
69 uint8_t start = 0;
70 uint32_t privacy, val;
71 int len;
72
73 if (wlan_cfg_get_int(mac_ctx, WNI_CFG_PRIVACY_ENABLED,
74 &privacy) != eSIR_SUCCESS) {
75 lim_log(mac_ctx, LOGP, FL("Unable to retrieve POI from CFG"));
76 }
77
78 if (wlan_cfg_get_int(mac_ctx, WNI_CFG_RSN_ENABLED, &val)
79 != eSIR_SUCCESS) {
80 lim_log(mac_ctx, LOGP,
81 FL("Unable to retrieve RSN_ENABLED from CFG"));
82 }
83
84 if (rsn_ie->length && (!privacy || !val)) {
85 /* Privacy & RSN not enabled in CFG.
86 * In order to allow mixed mode for Guest access
87 * allow BSS creation/join with no Privacy capability
88 * yet advertising WPA IE
89 */
90 PELOG1(lim_log(mac_ctx, LOG1,
91 FL("RSN ie len %d PRIVACY %d RSN %d"),
92 rsn_ie->length, privacy, val);)
93 }
94
95 if (!rsn_ie->length)
96 return true;
97
98 if ((rsn_ie->rsnIEdata[0] != DOT11F_EID_RSN)
99#ifdef FEATURE_WLAN_WAPI
100 && (rsn_ie->rsnIEdata[0] != DOT11F_EID_WAPI)
101#endif
102 && (rsn_ie->rsnIEdata[0] != DOT11F_EID_WPA)) {
103 lim_log(mac_ctx, LOGE, FL("RSN/WPA/WAPI EID %d not [%d || %d]"),
104 rsn_ie->rsnIEdata[0], DOT11F_EID_RSN,
105 DOT11F_EID_WPA);
106 return false;
107 }
108
109 len = rsn_ie->length;
110 start = 0;
111 while (len > 0) {
112 switch (rsn_ie->rsnIEdata[start]) {
113 case DOT11F_EID_RSN:
114 /* Check validity of RSN IE */
115 if ((rsn_ie->rsnIEdata[start + 1] >
116 DOT11F_IE_RSN_MAX_LEN)
117 || (rsn_ie->rsnIEdata[start + 1] <
118 DOT11F_IE_RSN_MIN_LEN)) {
119 lim_log(mac_ctx, LOGE,
120 FL("RSN IE len %d not [%d,%d]"),
121 rsn_ie->rsnIEdata[start + 1],
122 DOT11F_IE_RSN_MIN_LEN,
123 DOT11F_IE_RSN_MAX_LEN);
124 return false;
125 }
126 break;
127 case DOT11F_EID_WPA:
128 /* Check validity of WPA IE */
129 if (SIR_MAC_MAX_IE_LENGTH <= start)
130 break;
131
132 if (start <= (SIR_MAC_MAX_IE_LENGTH - sizeof(uint32_t)))
133 val = sir_read_u32((uint8_t *) &
134 rsn_ie->rsnIEdata[start + 2]);
135
136 if ((rsn_ie->rsnIEdata[start + 1] <
137 DOT11F_IE_WPA_MIN_LEN)
138 || (rsn_ie->rsnIEdata[start + 1] >
139 DOT11F_IE_WPA_MAX_LEN)
140 || (SIR_MAC_WPA_OUI != val)) {
141 lim_log(mac_ctx, LOGE,
142 FL("WPA IE len %d not [%d,%d] OR data 0x%x not 0x%x"),
143 rsn_ie->rsnIEdata[start + 1],
144 DOT11F_IE_WPA_MIN_LEN,
145 DOT11F_IE_WPA_MAX_LEN,
146 val, SIR_MAC_WPA_OUI);
147 return false;
148 }
149 break;
150#ifdef FEATURE_WLAN_WAPI
151 case DOT11F_EID_WAPI:
152 if ((rsn_ie->rsnIEdata[start + 1] >
153 DOT11F_IE_WAPI_MAX_LEN)
154 || (rsn_ie->rsnIEdata[start + 1] <
155 DOT11F_IE_WAPI_MIN_LEN)) {
156 lim_log(mac_ctx, LOGE,
157 FL("WAPI IE len %d not [%d,%d]"),
158 rsn_ie->rsnIEdata[start + 1],
159 DOT11F_IE_WAPI_MIN_LEN,
160 DOT11F_IE_WAPI_MAX_LEN);
161 return false;
162 }
163 break;
164#endif
165 default:
166 /* we will never be here, simply for completeness */
167 return false;
168 } /* end of switch */
169 /* EID + length field + length */
170 start += 2 + rsn_ie->rsnIEdata[start + 1];
171 len -= start;
172 } /* end while loop */
173 return true;
174} /*** end lim_is_rs_nie_valid_in_sme_req_message() ***/
175
176/**
177 * lim_is_addie_valid_in_sme_req_message()
178 *
179 ***FUNCTION:
180 * This function is called to verify if the Add IE
181 * received in various SME_REQ messages is valid or not
182 *
183 ***LOGIC:
184 * Add IE validity checks are performed on only length
185 *
186 ***ASSUMPTIONS:
187 *
188 ***NOTE:
189 *
190 * @param pMac Pointer to Global MAC structure
191 * @param pWSCie Pointer to received WSC IE
192 * @return true when WSC IE is valid, false otherwise
193 */
194
195static uint8_t
196lim_is_addie_valid_in_sme_req_message(tpAniSirGlobal pMac, tpSirAddie pAddie)
197{
198 int left = pAddie->length;
199 uint8_t *ptr = pAddie->addIEdata;
200 uint8_t elem_id, elem_len;
201
202 if (left == 0)
203 return true;
204
205 while (left >= 2) {
206 elem_id = ptr[0];
207 elem_len = ptr[1];
208 left -= 2;
209 if (elem_len > left) {
210 lim_log(pMac, LOGE,
211 FL
212 ("****Invalid Add IEs eid = %d elem_len=%d left=%d*****"),
213 elem_id, elem_len, left);
214 return false;
215 }
216
217 left -= elem_len;
218 ptr += (elem_len + 2);
219 }
220 /* there shouldn't be any left byte */
221
222 return true;
223} /*** end lim_is_addie_valid_in_sme_req_message() ***/
224
225/**
226 * lim_set_rs_nie_wp_aiefrom_sme_start_bss_req_message() - to set rsnie/wpaie
227 *
228 * @mac_ctx : Pointer to Global MAC structure
229 * @rsn_ie : Pointer to received RSN IE
230 * @session : Pointer to pe session
231 *
232 * This function is called to verify if the RSN IE received in various
233 * SME_REQ messages is valid or not. RSN IE validity checks are performed in
234 * this function
235 *
236 * Return: true when RSN IE is valid, false otherwise
237 */
238uint8_t
239lim_set_rs_nie_wp_aiefrom_sme_start_bss_req_message(tpAniSirGlobal mac_ctx,
240 tpSirRSNie rsn_ie,
241 tpPESession session)
242{
243 uint8_t wpa_idx = 0;
244 uint32_t privacy, val;
245
246 if (wlan_cfg_get_int(mac_ctx, WNI_CFG_PRIVACY_ENABLED,
247 &privacy) != eSIR_SUCCESS)
248 lim_log(mac_ctx, LOGP, FL("Unable to retrieve POI from CFG"));
249
250 if (wlan_cfg_get_int(mac_ctx, WNI_CFG_RSN_ENABLED,
251 &val) != eSIR_SUCCESS)
252 lim_log(mac_ctx, LOGP,
253 FL("Unable to retrieve RSN_ENABLED from CFG"));
254
255 if (rsn_ie->length && (!privacy || !val)) {
256 /*
257 * Privacy & RSN not enabled in CFG.
258 * In order to allow mixed mode for Guest access
259 * allow BSS creation/join with no Privacy capability
260 * yet advertising WPA IE
261 */
262 lim_log(mac_ctx, LOG1,
263 FL("RSN ie len %d but PRIVACY %d RSN %d"),
264 rsn_ie->length, privacy, val);
265 }
266
267 if (!rsn_ie->length)
268 return true;
269
270 if ((rsn_ie->rsnIEdata[0] != SIR_MAC_RSN_EID) &&
271 (rsn_ie->rsnIEdata[0] != SIR_MAC_WPA_EID)) {
272 lim_log(mac_ctx, LOGE, FL("RSN/WPA EID %d not [%d || %d]"),
273 rsn_ie->rsnIEdata[0], SIR_MAC_RSN_EID,
274 SIR_MAC_WPA_EID);
275 return false;
276 }
277 /* Check validity of RSN IE */
278 if ((rsn_ie->rsnIEdata[0] == SIR_MAC_RSN_EID) &&
279 (rsn_ie->rsnIEdata[1] < SIR_MAC_RSN_IE_MIN_LENGTH)) {
280 lim_log(mac_ctx, LOGE, FL("RSN IE len %d not [%d,%d]"),
281 rsn_ie->rsnIEdata[1], SIR_MAC_RSN_IE_MIN_LENGTH,
282 SIR_MAC_RSN_IE_MAX_LENGTH);
283 return false;
284 }
285
286 if (rsn_ie->length > rsn_ie->rsnIEdata[1] + 2) {
287 if (rsn_ie->rsnIEdata[0] != SIR_MAC_RSN_EID) {
288 lim_log(mac_ctx, LOGE,
289 FL("First byte[%d] in rsnIEdata isn't RSN_EID"),
290 rsn_ie->rsnIEdata[1]);
291 return false;
292 }
293 lim_log(mac_ctx, LOG1,
294 FL("WPA IE is present along with WPA2 IE"));
295 wpa_idx = 2 + rsn_ie->rsnIEdata[1];
296 } else if ((rsn_ie->length == rsn_ie->rsnIEdata[1] + 2) &&
297 (rsn_ie->rsnIEdata[0] == SIR_MAC_RSN_EID)) {
298 lim_log(mac_ctx, LOG1, FL("Only RSN IE is present"));
299 dot11f_unpack_ie_rsn(mac_ctx, &rsn_ie->rsnIEdata[2],
300 (uint8_t) rsn_ie->length,
301 &session->gStartBssRSNIe);
302 } else if ((rsn_ie->length == rsn_ie->rsnIEdata[1] + 2)
303 && (rsn_ie->rsnIEdata[0] == SIR_MAC_WPA_EID)) {
304 lim_log(mac_ctx, LOG1, FL("Only WPA IE is present"));
305 dot11f_unpack_ie_wpa(mac_ctx, &rsn_ie->rsnIEdata[6],
306 (uint8_t) rsn_ie->length - 4,
307 &session->gStartBssWPAIe);
308 }
309 /* Check validity of WPA IE */
310 if (wpa_idx + 6 >= SIR_MAC_MAX_IE_LENGTH)
311 return false;
312
313 val = sir_read_u32((uint8_t *)&rsn_ie->rsnIEdata[wpa_idx + 2]);
314 if ((rsn_ie->rsnIEdata[wpa_idx] == SIR_MAC_WPA_EID)
315 && ((rsn_ie->rsnIEdata[wpa_idx + 1] < SIR_MAC_WPA_IE_MIN_LENGTH)
316 || (SIR_MAC_WPA_OUI != val))) {
317 lim_log(mac_ctx, LOGE,
318 FL("WPA IE len %d not [%d,%d] OR data 0x%x not 0x%x"),
319 rsn_ie->rsnIEdata[1],
320 SIR_MAC_RSN_IE_MIN_LENGTH,
321 SIR_MAC_RSN_IE_MAX_LENGTH, val,
322 SIR_MAC_WPA_OUI);
323 return false;
324 } else {
325 /* Both RSN and WPA IEs are present */
326 dot11f_unpack_ie_rsn(mac_ctx, &rsn_ie->rsnIEdata[2],
327 (uint8_t) rsn_ie->length,
328 &session->gStartBssRSNIe);
329 dot11f_unpack_ie_wpa(mac_ctx, &rsn_ie->rsnIEdata[wpa_idx + 6],
330 rsn_ie->rsnIEdata[wpa_idx + 1] - 4,
331 &session->gStartBssWPAIe);
332 }
333 return true;
334}
335
336/**
337 * lim_is_bss_descr_valid_in_sme_req_message()
338 *
339 ***FUNCTION:
340 * This function is called to verify if the BSS Descr
341 * received in various SME_REQ messages is valid or not
342 *
343 ***LOGIC:
344 * BSS Descritipion validity checks are performed in this function
345 *
346 ***ASSUMPTIONS:
347 *
348 ***NOTE:
349 *
350 * @param pMac Pointer to Global MAC structure
351 * @param pBssDescr Pointer to received Bss Descritipion
352 * @return true when BSS description is valid, false otherwise
353 */
354
355static uint8_t
356lim_is_bss_descr_valid_in_sme_req_message(tpAniSirGlobal pMac,
357 tpSirBssDescription pBssDescr)
358{
359 uint8_t valid = true;
360
361 if (lim_is_addr_bc(pBssDescr->bssId) || !pBssDescr->channelId) {
362 valid = false;
363 goto end;
364 }
365
366end:
367 return valid;
368} /*** end lim_is_bss_descr_valid_in_sme_req_message() ***/
369
370/**
371 * lim_is_sme_start_bss_req_valid() - To validate sme start bss request
372 *
373 * @mac_ctx: Pointer to Global MAC structure
374 * @start_bss_req: Pointer to received SME_START_BSS_REQ message
375 *
376 * This function is called by lim_process_sme_req_messages() upon
377 * receiving SME_START_BSS_REQ message from application.
378 *
379 * Return: true when received SME_START_BSS_REQ is formatted correctly false
380 * otherwise
381 */
382
383uint8_t
384lim_is_sme_start_bss_req_valid(tpAniSirGlobal mac_ctx,
385 tpSirSmeStartBssReq start_bss_req)
386{
387 uint8_t i = 0;
388 tSirMacRateSet *opr_rates = &start_bss_req->operationalRateSet;
389
390 PELOG1(lim_log(mac_ctx, LOG1,
391 FL("Parsed START_BSS_REQ fields are bssType=%d, channelId=%d, SSID len=%d, rsnIE len=%d, nwType=%d, rateset len=%d"),
392 start_bss_req->bssType, start_bss_req->channelId,
393 start_bss_req->ssId.length, start_bss_req->rsnIE.length,
394 start_bss_req->nwType, opr_rates->numRates);)
395
396 switch (start_bss_req->bssType) {
397 case eSIR_INFRASTRUCTURE_MODE:
398 /**
399 * Should not have received start BSS req with bssType
400 * Infrastructure on STA.
401 */
402 lim_log(mac_ctx, LOGE,
403 FL("Invalid bssType %d in eWNI_SME_START_BSS_REQ"),
404 start_bss_req->bssType);
405 return false;
406 break;
407 case eSIR_IBSS_MODE:
408 break;
409 case eSIR_BTAMP_STA_MODE:
410 break;
411 case eSIR_BTAMP_AP_MODE:
412 break;
413 case eSIR_INFRA_AP_MODE:
414 break;
415 default:
416 /**
417 * Should not have received start BSS req with bssType
418 * other than Infrastructure/IBSS.
419 */
420 lim_log(mac_ctx, LOGW,
421 FL("Invalid bssType %d in eWNI_SME_START_BSS_REQ"),
422 start_bss_req->bssType);
423 return false;
424 }
425
426 if (start_bss_req->bssType == eSIR_IBSS_MODE
427 && (!start_bss_req->ssId.length
428 || start_bss_req->ssId.length > SIR_MAC_MAX_SSID_LENGTH)) {
429 lim_log(mac_ctx, LOGW,
430 FL("Invalid SSID length in eWNI_SME_START_BSS_REQ"));
431 return false;
432 }
433
434 if (!lim_is_rsn_ie_valid_in_sme_req_message(mac_ctx,
435 &start_bss_req->rsnIE))
436 return false;
437
438 if (start_bss_req->nwType != eSIR_11A_NW_TYPE
439 && start_bss_req->nwType != eSIR_11B_NW_TYPE
440 && start_bss_req->nwType != eSIR_11G_NW_TYPE)
441 return false;
442
443 if (start_bss_req->nwType == eSIR_11A_NW_TYPE) {
444 for (i = 0; i < opr_rates->numRates; i++) {
445 if (sirIsArate(opr_rates->rate[i] & 0x7F))
446 continue;
447
448 lim_log(mac_ctx, LOGW,
449 FL("Invalid operational 11A rates"));
450 sir_dump_buf(mac_ctx, SIR_LIM_MODULE_ID, LOG2,
451 opr_rates->rate, opr_rates->numRates);
452 return false;
453 }
454 return true;
455 }
456 /* check if all the rates in the opr rate set are legal 11G rates */
457 if (start_bss_req->nwType == eSIR_11G_NW_TYPE) {
458 for (i = 0; i < opr_rates->numRates; i++) {
459 if (sirIsGrate(opr_rates->rate[i] & 0x7F))
460 continue;
461
462 lim_log(mac_ctx, LOGW,
463 FL("Invalid operational 11G rates"));
464 sir_dump_buf(mac_ctx, SIR_LIM_MODULE_ID, LOG2,
465 opr_rates->rate, opr_rates->numRates);
466 return false;
467 }
468 return true;
469 }
470
471 for (i = 0; i < opr_rates->numRates; i++) {
472 if (sirIsBrate(opr_rates->rate[i] & 0x7F))
473 continue;
474
475 lim_log(mac_ctx, LOGW,
476 FL("Invalid operational 11B rates"));
477 sir_dump_buf(mac_ctx, SIR_LIM_MODULE_ID, LOG2,
478 opr_rates->rate, opr_rates->numRates);
479 return false;
480 }
481 return true;
482}
483
484/**
485 * lim_is_sme_join_req_valid()
486 *
487 ***FUNCTION:
488 * This function is called by lim_process_sme_req_messages() upon
489 * receiving SME_JOIN_REQ message from application.
490 *
491 ***LOGIC:
492 * Message validity checks are performed in this function
493 *
494 ***ASSUMPTIONS:
495 *
496 ***NOTE:
497 *
498 * @param pMac Pointer to Global MAC structure
499 * @param pJoinReq Pointer to received SME_JOIN_REQ message
500 * @return true when received SME_JOIN_REQ is formatted correctly
501 * false otherwise
502 */
503
504uint8_t lim_is_sme_join_req_valid(tpAniSirGlobal pMac, tpSirSmeJoinReq pJoinReq)
505{
506 uint8_t valid = true;
507
508 if (!lim_is_rsn_ie_valid_in_sme_req_message(pMac, &pJoinReq->rsnIE)) {
509 lim_log(pMac, LOGE,
510 FL("received SME_JOIN_REQ with invalid RSNIE"));
511 valid = false;
512 goto end;
513 }
514
515 if (!lim_is_addie_valid_in_sme_req_message(pMac, &pJoinReq->addIEScan)) {
516 lim_log(pMac, LOGE,
517 FL
518 ("received SME_JOIN_REQ with invalid additional IE for scan"));
519 valid = false;
520 goto end;
521 }
522
523 if (!lim_is_addie_valid_in_sme_req_message(pMac, &pJoinReq->addIEAssoc)) {
524 lim_log(pMac, LOGE,
525 FL
526 ("received SME_JOIN_REQ with invalid additional IE for assoc"));
527 valid = false;
528 goto end;
529 }
530
531 if (!lim_is_bss_descr_valid_in_sme_req_message(pMac, &pJoinReq->bssDescription)) {
532 /* / Received eWNI_SME_JOIN_REQ with invalid BSS Info */
533 /* Log the event */
534 lim_log(pMac, LOGE,
535 FL("received SME_JOIN_REQ with invalid bssInfo"));
536
537 valid = false;
538 goto end;
539 }
540
541 /*
542 Reject Join Req if the Self Mac Address and
543 the Ap's Mac Address is same
544 */
545 if (cdf_mem_compare((uint8_t *) pJoinReq->selfMacAddr,
546 (uint8_t *) pJoinReq->bssDescription.bssId,
547 (uint8_t) (sizeof(tSirMacAddr)))) {
548 /* Log the event */
549 lim_log(pMac, LOGE,
550 FL
551 ("received SME_JOIN_REQ with Self Mac and BSSID Same"));
552
553 valid = false;
554 goto end;
555 }
556
557end:
558 return valid;
559} /*** end lim_is_sme_join_req_valid() ***/
560
561/**
562 * lim_is_sme_disassoc_req_valid()
563 *
564 ***FUNCTION:
565 * This function is called by lim_process_sme_req_messages() upon
566 * receiving SME_DISASSOC_REQ message from application.
567 *
568 ***LOGIC:
569 * Message validity checks are performed in this function
570 *
571 ***ASSUMPTIONS:
572 *
573 ***NOTE:
574 *
575 * @param pMac Pointer to Global MAC structure
576 * @param pDisassocReq Pointer to received SME_DISASSOC_REQ message
577 * @return true When received SME_DISASSOC_REQ is formatted
578 * correctly
579 * false otherwise
580 */
581
582uint8_t
583lim_is_sme_disassoc_req_valid(tpAniSirGlobal pMac,
584 tpSirSmeDisassocReq pDisassocReq,
585 tpPESession psessionEntry)
586{
587 if (lim_is_group_addr(pDisassocReq->peerMacAddr) &&
588 !lim_is_addr_bc(pDisassocReq->peerMacAddr))
589 return false;
590
591 return true;
592} /*** end lim_is_sme_disassoc_req_valid() ***/
593
594/**
595 * lim_is_sme_disassoc_cnf_valid()
596 *
597 ***FUNCTION:
598 * This function is called by lim_process_sme_req_messages() upon
599 * receiving SME_DISASSOC_CNF message from application.
600 *
601 ***LOGIC:
602 * Message validity checks are performed in this function
603 *
604 ***ASSUMPTIONS:
605 *
606 ***NOTE:
607 *
608 * @param pMac Pointer to Global MAC structure
609 * @param pDisassocCnf Pointer to received SME_DISASSOC_REQ message
610 * @return true When received SME_DISASSOC_CNF is formatted
611 * correctly
612 * false otherwise
613 */
614
615uint8_t
616lim_is_sme_disassoc_cnf_valid(tpAniSirGlobal pMac,
617 tpSirSmeDisassocCnf pDisassocCnf,
618 tpPESession psessionEntry)
619{
620 if (lim_is_group_addr(pDisassocCnf->peerMacAddr))
621 return false;
622
623 return true;
624} /*** end lim_is_sme_disassoc_cnf_valid() ***/
625
626/**
627 * lim_is_sme_deauth_req_valid()
628 *
629 ***FUNCTION:
630 * This function is called by lim_process_sme_req_messages() upon
631 * receiving SME_DEAUTH_REQ message from application.
632 *
633 ***LOGIC:
634 * Message validity checks are performed in this function
635 *
636 ***ASSUMPTIONS:
637 *
638 ***NOTE:
639 *
640 * @param pMac Pointer to Global MAC structure
641 * @param pDeauthReq Pointer to received SME_DEAUTH_REQ message
642 * @return true When received SME_DEAUTH_REQ is formatted correctly
643 * false otherwise
644 */
645
646uint8_t
647lim_is_sme_deauth_req_valid(tpAniSirGlobal pMac, tpSirSmeDeauthReq pDeauthReq,
648 tpPESession psessionEntry)
649{
650 if (lim_is_group_addr(pDeauthReq->peerMacAddr) &&
651 !lim_is_addr_bc(pDeauthReq->peerMacAddr))
652 return false;
653
654 return true;
655} /*** end lim_is_sme_deauth_req_valid() ***/
656
657/**
658 * lim_is_sme_scan_req_valid()
659 *
660 ***FUNCTION:
661 * This function is called by lim_process_sme_req_messages() upon
662 * receiving SME_SCAN_REQ message from application.
663 *
664 ***LOGIC:
665 * Message validity checks are performed in this function
666 *
667 ***ASSUMPTIONS:
668 *
669 ***NOTE:
670 *
671 * @param pScanReq Pointer to received SME_SCAN_REQ message
672 * @return true when received SME_SCAN_REQ is formatted correctly
673 * false otherwise
674 */
675
676uint8_t lim_is_sme_scan_req_valid(tpAniSirGlobal pMac, tpSirSmeScanReq pScanReq)
677{
678 uint8_t valid = true;
679 uint8_t i = 0;
680
681 if (pScanReq->numSsid > SIR_SCAN_MAX_NUM_SSID) {
682 valid = false;
683 lim_log(pMac, LOGE,
684 FL("Number of SSIDs > SIR_SCAN_MAX_NUM_SSID"));
685 goto end;
686 }
687
688 for (i = 0; i < pScanReq->numSsid; i++) {
689 if (pScanReq->ssId[i].length > SIR_MAC_MAX_SSID_LENGTH) {
690 lim_log(pMac, LOGE,
691 FL
692 ("Requested SSID length > SIR_MAC_MAX_SSID_LENGTH"));
693 valid = false;
694 goto end;
695 }
696 }
697 if ((pScanReq->bssType < 0) || (pScanReq->bssType > eSIR_AUTO_MODE)) {
698 lim_log(pMac, LOGE, FL("Invalid BSS Type"));
699 valid = false;
700 }
701 if (lim_is_group_addr(pScanReq->bssId) && !lim_is_addr_bc(pScanReq->bssId)) {
702 valid = false;
703 lim_log(pMac, LOGE,
704 FL("BSSID is group addr and is not Broadcast Addr"));
705 }
706 if (!
707 (pScanReq->scanType == eSIR_PASSIVE_SCAN
708 || pScanReq->scanType == eSIR_ACTIVE_SCAN)) {
709 valid = false;
710 lim_log(pMac, LOGE, FL("Invalid Scan Type"));
711 }
712 if (pScanReq->channelList.numChannels > SIR_MAX_NUM_CHANNELS) {
713 valid = false;
714 lim_log(pMac, LOGE,
715 FL("Number of Channels > SIR_MAX_NUM_CHANNELS"));
716 }
717
718 /*
719 ** check min/max channelTime range
720 **/
721 if (valid) {
722 if ((pScanReq->scanType == eSIR_ACTIVE_SCAN) &&
723 (pScanReq->maxChannelTime < pScanReq->minChannelTime)) {
724 lim_log(pMac, LOGE,
725 FL("Max Channel Time < Min Channel Time"));
726 valid = false;
727 goto end;
728 }
729 }
730
731end:
732 return valid;
733} /*** end lim_is_sme_scan_req_valid() ***/
734
735/**
736 * lim_is_sme_set_context_req_valid()
737 *
738 ***FUNCTION:
739 * This function is called by lim_process_sme_req_messages() upon
740 * receiving SME_SET_CONTEXT_REQ message from application.
741 *
742 ***LOGIC:
743 * Message validity checks are performed in this function
744 *
745 ***ASSUMPTIONS:
746 *
747 ***NOTE:
748 *
749 * @param pMsg - Pointer to received SME_SET_CONTEXT_REQ message
750 * @return true when received SME_SET_CONTEXT_REQ is formatted correctly
751 * false otherwise
752 */
753
754uint8_t
755lim_is_sme_set_context_req_valid(tpAniSirGlobal pMac,
756 tpSirSmeSetContextReq pSetContextReq)
757{
758 uint8_t i = 0;
759 uint8_t valid = true;
760 tpSirKeys pKey = pSetContextReq->keyMaterial.key;
761
762 if ((pSetContextReq->keyMaterial.edType != eSIR_ED_WEP40) &&
763 (pSetContextReq->keyMaterial.edType != eSIR_ED_WEP104) &&
764 (pSetContextReq->keyMaterial.edType != eSIR_ED_NONE) &&
765#ifdef FEATURE_WLAN_WAPI
766 (pSetContextReq->keyMaterial.edType != eSIR_ED_WPI) &&
767#endif
768 !pSetContextReq->keyMaterial.numKeys) {
769 /**
770 * No keys present in case of TKIP or CCMP
771 * Log error.
772 */
773 lim_log(pMac, LOGW,
774 FL
775 ("No keys present in SME_SETCONTEXT_REQ for edType=%d"),
776 pSetContextReq->keyMaterial.edType);
777
778 valid = false;
779 goto end;
780 }
781
782 if (pSetContextReq->keyMaterial.numKeys &&
783 (pSetContextReq->keyMaterial.edType == eSIR_ED_NONE)) {
784 /**
785 * Keys present in case of no ED policy
786 * Log error.
787 */
788 lim_log(pMac, LOGW,
789 FL("Keys present in SME_SETCONTEXT_REQ for edType=%d"),
790 pSetContextReq->keyMaterial.edType);
791
792 valid = false;
793 goto end;
794 }
795
796 if (pSetContextReq->keyMaterial.edType >= eSIR_ED_NOT_IMPLEMENTED) {
797 /**
798 * Invalid edType in the message
799 * Log error.
800 */
801 lim_log(pMac, LOGW,
802 FL("Invalid edType=%d in SME_SETCONTEXT_REQ"),
803 pSetContextReq->keyMaterial.edType);
804
805 valid = false;
806 goto end;
807 } else if (pSetContextReq->keyMaterial.edType > eSIR_ED_NONE) {
808 uint32_t poi;
809
810 if (wlan_cfg_get_int(pMac, WNI_CFG_PRIVACY_ENABLED,
811 &poi) != eSIR_SUCCESS) {
812 lim_log(pMac, LOGP,
813 FL("Unable to retrieve POI from CFG"));
814 }
815
816 if (!poi) {
817 /**
818 * Privacy is not enabled
819 * In order to allow mixed mode for Guest access
820 * allow BSS creation/join with no Privacy capability
821 * yet advertising WPA IE
822 */
823 PELOG1(lim_log(pMac, LOG1,
824 FL
825 ("Privacy is not enabled, yet non-None EDtype=%d in SME_SETCONTEXT_REQ"),
826 pSetContextReq->keyMaterial.edType);
827 )
828 }
829 }
830
831 for (i = 0; i < pSetContextReq->keyMaterial.numKeys; i++) {
832 if (((pSetContextReq->keyMaterial.edType == eSIR_ED_WEP40) &&
833 (pKey->keyLength != 5)) ||
834 ((pSetContextReq->keyMaterial.edType == eSIR_ED_WEP104) &&
835 (pKey->keyLength != 13)) ||
836 ((pSetContextReq->keyMaterial.edType == eSIR_ED_TKIP) &&
837 (pKey->keyLength != 32)) ||
838#ifdef FEATURE_WLAN_WAPI
839 ((pSetContextReq->keyMaterial.edType == eSIR_ED_WPI) &&
840 (pKey->keyLength != 32)) ||
841#endif
842 ((pSetContextReq->keyMaterial.edType == eSIR_ED_CCMP) &&
843 (pKey->keyLength != 16))) {
844 /**
845 * Invalid key length for a given ED type
846 * Log error.
847 */
848 lim_log(pMac, LOGW,
849 FL
850 ("Invalid keyLength =%d for edType=%d in SME_SETCONTEXT_REQ"),
851 pKey->keyLength,
852 pSetContextReq->keyMaterial.edType);
853
854 valid = false;
855 goto end;
856 }
857 pKey++;
858 }
859
860end:
861 return valid;
862} /*** end lim_is_sme_set_context_req_valid() ***/
863
864/**
865 * lim_is_sme_stop_bss_req_valid()
866 *
867 ***FUNCTION:
868 * This function is called by lim_process_sme_req_messages() upon
869 * receiving SME_STOP_BSS_REQ message from application.
870 *
871 ***LOGIC:
872 * Message validity checks are performed in this function
873 *
874 ***ASSUMPTIONS:
875 *
876 ***NOTE:
877 *
878 * @param pMsg - Pointer to received SME_STOP_BSS_REQ message
879 * @return true when received SME_STOP_BSS_REQ is formatted correctly
880 * false otherwise
881 */
882
883uint8_t lim_is_sme_stop_bss_req_valid(uint32_t *pMsg)
884{
885 uint8_t valid = true;
886
887 return valid;
888} /*** end lim_is_sme_stop_bss_req_valid() ***/
889
890/**
891 * lim_get_bss_id_from_sme_join_req_msg()
892 *
893 ***FUNCTION:
894 * This function is called in various places to get BSSID
895 * from BSS description/Neighbor BSS Info in the SME_JOIN_REQ/
896 * SME_REASSOC_REQ message.
897 *
898 ***PARAMS:
899 *
900 ***LOGIC:
901 *
902 ***ASSUMPTIONS:
903 * NA
904 *
905 ***NOTE:
906 * NA
907 *
908 * @param pBuf - Pointer to received SME_JOIN/SME_REASSOC_REQ
909 * message
910 * @return pBssId - Pointer to BSSID
911 */
912
913uint8_t *lim_get_bss_id_from_sme_join_req_msg(uint8_t *pBuf)
914{
915 if (!pBuf)
916 return NULL;
917
918 pBuf += sizeof(uint32_t); /* skip message header */
919
920 pBuf += lim_get_u16(pBuf) + sizeof(uint16_t); /* skip RSN IE */
921
922 pBuf += sizeof(uint16_t); /* skip length of BSS description */
923
924 return (pBuf);
925} /*** end lim_get_bss_id_from_sme_join_req_msg() ***/