Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
[deliverable/linux.git] / drivers / staging / rt2860 / common / cmm_sanity.c
1 /*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 sanity.c
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 John Chang 2004-09-01 add WMM support
36 */
37 #include "../rt_config.h"
38
39
40 extern UCHAR CISCO_OUI[];
41
42 extern UCHAR WPA_OUI[];
43 extern UCHAR RSN_OUI[];
44 extern UCHAR WME_INFO_ELEM[];
45 extern UCHAR WME_PARM_ELEM[];
46 extern UCHAR Ccx2QosInfo[];
47 extern UCHAR RALINK_OUI[];
48 extern UCHAR BROADCOM_OUI[];
49 extern UCHAR WPS_OUI[];
50
51 /*
52 ==========================================================================
53 Description:
54 MLME message sanity check
55 Return:
56 TRUE if all parameters are OK, FALSE otherwise
57
58 IRQL = DISPATCH_LEVEL
59
60 ==========================================================================
61 */
62 BOOLEAN MlmeAddBAReqSanity(
63 IN PRTMP_ADAPTER pAd,
64 IN VOID *Msg,
65 IN ULONG MsgLen,
66 OUT PUCHAR pAddr2)
67 {
68 PMLME_ADDBA_REQ_STRUCT pInfo;
69
70 pInfo = (MLME_ADDBA_REQ_STRUCT *)Msg;
71
72 if ((MsgLen != sizeof(MLME_ADDBA_REQ_STRUCT)))
73 {
74 DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - message lenght not correct.\n"));
75 return FALSE;
76 }
77
78 if ((pInfo->Wcid >= MAX_LEN_OF_MAC_TABLE))
79 {
80 DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - The peer Mac is not associated yet.\n"));
81 return FALSE;
82 }
83
84 if ((pInfo->pAddr[0]&0x01) == 0x01)
85 {
86 DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - broadcast address not support BA\n"));
87 return FALSE;
88 }
89
90 return TRUE;
91 }
92
93 /*
94 ==========================================================================
95 Description:
96 MLME message sanity check
97 Return:
98 TRUE if all parameters are OK, FALSE otherwise
99
100 IRQL = DISPATCH_LEVEL
101
102 ==========================================================================
103 */
104 BOOLEAN MlmeDelBAReqSanity(
105 IN PRTMP_ADAPTER pAd,
106 IN VOID *Msg,
107 IN ULONG MsgLen)
108 {
109 MLME_DELBA_REQ_STRUCT *pInfo;
110 pInfo = (MLME_DELBA_REQ_STRUCT *)Msg;
111
112 if ((MsgLen != sizeof(MLME_DELBA_REQ_STRUCT)))
113 {
114 DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - message lenght not correct.\n"));
115 return FALSE;
116 }
117
118 if ((pInfo->Wcid >= MAX_LEN_OF_MAC_TABLE))
119 {
120 DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - The peer Mac is not associated yet.\n"));
121 return FALSE;
122 }
123
124 if ((pInfo->TID & 0xf0))
125 {
126 DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - The peer TID is incorrect.\n"));
127 return FALSE;
128 }
129
130 if (NdisEqualMemory(pAd->MacTab.Content[pInfo->Wcid].Addr, pInfo->Addr, MAC_ADDR_LEN) == 0)
131 {
132 DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - the peer addr dosen't exist.\n"));
133 return FALSE;
134 }
135
136 return TRUE;
137 }
138
139 BOOLEAN PeerAddBAReqActionSanity(
140 IN PRTMP_ADAPTER pAd,
141 IN VOID *pMsg,
142 IN ULONG MsgLen,
143 OUT PUCHAR pAddr2)
144 {
145 PFRAME_802_11 pFrame = (PFRAME_802_11)pMsg;
146 PFRAME_ADDBA_REQ pAddFrame;
147 pAddFrame = (PFRAME_ADDBA_REQ)(pMsg);
148 if (MsgLen < (sizeof(FRAME_ADDBA_REQ)))
149 {
150 DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Request frame length size = %ld incorrect\n", MsgLen));
151 return FALSE;
152 }
153 // we support immediate BA.
154 *(USHORT *)(&pAddFrame->BaParm) = cpu2le16(*(USHORT *)(&pAddFrame->BaParm));
155 pAddFrame->TimeOutValue = cpu2le16(pAddFrame->TimeOutValue);
156 pAddFrame->BaStartSeq.word = cpu2le16(pAddFrame->BaStartSeq.word);
157
158 if (pAddFrame->BaParm.BAPolicy != IMMED_BA)
159 {
160 DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Request Ba Policy[%d] not support\n", pAddFrame->BaParm.BAPolicy));
161 DBGPRINT(RT_DEBUG_ERROR,("ADDBA Request. tid=%x, Bufsize=%x, AMSDUSupported=%x \n", pAddFrame->BaParm.TID, pAddFrame->BaParm.BufSize, pAddFrame->BaParm.AMSDUSupported));
162 return FALSE;
163 }
164
165 // we support immediate BA.
166 if (pAddFrame->BaParm.TID &0xfff0)
167 {
168 DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Request incorrect TID = %d\n", pAddFrame->BaParm.TID));
169 return FALSE;
170 }
171 COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
172 return TRUE;
173 }
174
175 BOOLEAN PeerAddBARspActionSanity(
176 IN PRTMP_ADAPTER pAd,
177 IN VOID *pMsg,
178 IN ULONG MsgLen)
179 {
180 PFRAME_ADDBA_RSP pAddFrame;
181
182 pAddFrame = (PFRAME_ADDBA_RSP)(pMsg);
183 if (MsgLen < (sizeof(FRAME_ADDBA_RSP)))
184 {
185 DBGPRINT(RT_DEBUG_ERROR,("PeerAddBARspActionSanity: ADDBA Response frame length size = %ld incorrect\n", MsgLen));
186 return FALSE;
187 }
188 // we support immediate BA.
189 *(USHORT *)(&pAddFrame->BaParm) = cpu2le16(*(USHORT *)(&pAddFrame->BaParm));
190 pAddFrame->StatusCode = cpu2le16(pAddFrame->StatusCode);
191 pAddFrame->TimeOutValue = cpu2le16(pAddFrame->TimeOutValue);
192
193 if (pAddFrame->BaParm.BAPolicy != IMMED_BA)
194 {
195 DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Response Ba Policy[%d] not support\n", pAddFrame->BaParm.BAPolicy));
196 return FALSE;
197 }
198
199 // we support immediate BA.
200 if (pAddFrame->BaParm.TID &0xfff0)
201 {
202 DBGPRINT(RT_DEBUG_ERROR,("PeerAddBARspActionSanity: ADDBA Response incorrect TID = %d\n", pAddFrame->BaParm.TID));
203 return FALSE;
204 }
205 return TRUE;
206
207 }
208
209 BOOLEAN PeerDelBAActionSanity(
210 IN PRTMP_ADAPTER pAd,
211 IN UCHAR Wcid,
212 IN VOID *pMsg,
213 IN ULONG MsgLen )
214 {
215 //PFRAME_802_11 pFrame = (PFRAME_802_11)pMsg;
216 PFRAME_DELBA_REQ pDelFrame;
217 if (MsgLen != (sizeof(FRAME_DELBA_REQ)))
218 return FALSE;
219
220 if (Wcid >= MAX_LEN_OF_MAC_TABLE)
221 return FALSE;
222
223 pDelFrame = (PFRAME_DELBA_REQ)(pMsg);
224
225 *(USHORT *)(&pDelFrame->DelbaParm) = cpu2le16(*(USHORT *)(&pDelFrame->DelbaParm));
226 pDelFrame->ReasonCode = cpu2le16(pDelFrame->ReasonCode);
227
228 if (pDelFrame->DelbaParm.TID &0xfff0)
229 return FALSE;
230
231 return TRUE;
232 }
233
234 /*
235 ==========================================================================
236 Description:
237 MLME message sanity check
238 Return:
239 TRUE if all parameters are OK, FALSE otherwise
240
241 IRQL = DISPATCH_LEVEL
242
243 ==========================================================================
244 */
245 BOOLEAN PeerBeaconAndProbeRspSanity(
246 IN PRTMP_ADAPTER pAd,
247 IN VOID *Msg,
248 IN ULONG MsgLen,
249 IN UCHAR MsgChannel,
250 OUT PUCHAR pAddr2,
251 OUT PUCHAR pBssid,
252 OUT CHAR Ssid[],
253 OUT UCHAR *pSsidLen,
254 OUT UCHAR *pBssType,
255 OUT USHORT *pBeaconPeriod,
256 OUT UCHAR *pChannel,
257 OUT UCHAR *pNewChannel,
258 OUT LARGE_INTEGER *pTimestamp,
259 OUT CF_PARM *pCfParm,
260 OUT USHORT *pAtimWin,
261 OUT USHORT *pCapabilityInfo,
262 OUT UCHAR *pErp,
263 OUT UCHAR *pDtimCount,
264 OUT UCHAR *pDtimPeriod,
265 OUT UCHAR *pBcastFlag,
266 OUT UCHAR *pMessageToMe,
267 OUT UCHAR SupRate[],
268 OUT UCHAR *pSupRateLen,
269 OUT UCHAR ExtRate[],
270 OUT UCHAR *pExtRateLen,
271 OUT UCHAR *pCkipFlag,
272 OUT UCHAR *pAironetCellPowerLimit,
273 OUT PEDCA_PARM pEdcaParm,
274 OUT PQBSS_LOAD_PARM pQbssLoad,
275 OUT PQOS_CAPABILITY_PARM pQosCapability,
276 OUT ULONG *pRalinkIe,
277 OUT UCHAR *pHtCapabilityLen,
278 OUT UCHAR *pPreNHtCapabilityLen,
279 OUT HT_CAPABILITY_IE *pHtCapability,
280 OUT UCHAR *AddHtInfoLen,
281 OUT ADD_HT_INFO_IE *AddHtInfo,
282 OUT UCHAR *NewExtChannelOffset, // Ht extension channel offset(above or below)
283 OUT USHORT *LengthVIE,
284 OUT PNDIS_802_11_VARIABLE_IEs pVIE)
285 {
286 CHAR *Ptr;
287 CHAR TimLen;
288 PFRAME_802_11 pFrame;
289 PEID_STRUCT pEid;
290 UCHAR SubType;
291 UCHAR Sanity;
292 //UCHAR ECWMin, ECWMax;
293 //MAC_CSR9_STRUC Csr9;
294 ULONG Length = 0;
295
296 // For some 11a AP which didn't have DS_IE, we use two conditions to decide the channel
297 // 1. If the AP is 11n enabled, then check the control channel.
298 // 2. If the AP didn't have any info about channel, use the channel we received this frame as the channel. (May inaccuracy!!)
299 UCHAR CtrlChannel = 0;
300
301 // Add for 3 necessary EID field check
302 Sanity = 0;
303
304 *pAtimWin = 0;
305 *pErp = 0;
306 *pDtimCount = 0;
307 *pDtimPeriod = 0;
308 *pBcastFlag = 0;
309 *pMessageToMe = 0;
310 *pExtRateLen = 0;
311 *pCkipFlag = 0; // Default of CkipFlag is 0
312 *pAironetCellPowerLimit = 0xFF; // Default of AironetCellPowerLimit is 0xFF
313 *LengthVIE = 0; // Set the length of VIE to init value 0
314 *pHtCapabilityLen = 0; // Set the length of VIE to init value 0
315 if (pAd->OpMode == OPMODE_STA)
316 *pPreNHtCapabilityLen = 0; // Set the length of VIE to init value 0
317 *AddHtInfoLen = 0; // Set the length of VIE to init value 0
318 *pRalinkIe = 0;
319 *pNewChannel = 0;
320 *NewExtChannelOffset = 0xff; //Default 0xff means no such IE
321 pCfParm->bValid = FALSE; // default: no IE_CF found
322 pQbssLoad->bValid = FALSE; // default: no IE_QBSS_LOAD found
323 pEdcaParm->bValid = FALSE; // default: no IE_EDCA_PARAMETER found
324 pQosCapability->bValid = FALSE; // default: no IE_QOS_CAPABILITY found
325
326 pFrame = (PFRAME_802_11)Msg;
327
328 // get subtype from header
329 SubType = (UCHAR)pFrame->Hdr.FC.SubType;
330
331 // get Addr2 and BSSID from header
332 COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
333 COPY_MAC_ADDR(pBssid, pFrame->Hdr.Addr3);
334
335 Ptr = pFrame->Octet;
336 Length += LENGTH_802_11;
337
338 // get timestamp from payload and advance the pointer
339 NdisMoveMemory(pTimestamp, Ptr, TIMESTAMP_LEN);
340
341 pTimestamp->u.LowPart = cpu2le32(pTimestamp->u.LowPart);
342 pTimestamp->u.HighPart = cpu2le32(pTimestamp->u.HighPart);
343
344 Ptr += TIMESTAMP_LEN;
345 Length += TIMESTAMP_LEN;
346
347 // get beacon interval from payload and advance the pointer
348 NdisMoveMemory(pBeaconPeriod, Ptr, 2);
349 Ptr += 2;
350 Length += 2;
351
352 // get capability info from payload and advance the pointer
353 NdisMoveMemory(pCapabilityInfo, Ptr, 2);
354 Ptr += 2;
355 Length += 2;
356
357 if (CAP_IS_ESS_ON(*pCapabilityInfo))
358 *pBssType = BSS_INFRA;
359 else
360 *pBssType = BSS_ADHOC;
361
362 pEid = (PEID_STRUCT) Ptr;
363
364 // get variable fields from payload and advance the pointer
365 while ((Length + 2 + pEid->Len) <= MsgLen)
366 {
367 //
368 // Secure copy VIE to VarIE[MAX_VIE_LEN] didn't overflow.
369 //
370 if ((*LengthVIE + pEid->Len + 2) >= MAX_VIE_LEN)
371 {
372 DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - Variable IEs out of resource [len(=%d) > MAX_VIE_LEN(=%d)]\n",
373 (*LengthVIE + pEid->Len + 2), MAX_VIE_LEN));
374 break;
375 }
376
377 switch(pEid->Eid)
378 {
379 case IE_SSID:
380 // Already has one SSID EID in this beacon, ignore the second one
381 if (Sanity & 0x1)
382 break;
383 if(pEid->Len <= MAX_LEN_OF_SSID)
384 {
385 NdisMoveMemory(Ssid, pEid->Octet, pEid->Len);
386 *pSsidLen = pEid->Len;
387 Sanity |= 0x1;
388 }
389 else
390 {
391 DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_SSID (len=%d)\n",pEid->Len));
392 return FALSE;
393 }
394 break;
395
396 case IE_SUPP_RATES:
397 if(pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES)
398 {
399 Sanity |= 0x2;
400 NdisMoveMemory(SupRate, pEid->Octet, pEid->Len);
401 *pSupRateLen = pEid->Len;
402
403 // TODO: 2004-09-14 not a good design here, cause it exclude extra rates
404 // from ScanTab. We should report as is. And filter out unsupported
405 // rates in MlmeAux.
406 // Check against the supported rates
407 // RTMPCheckRates(pAd, SupRate, pSupRateLen);
408 }
409 else
410 {
411 DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_SUPP_RATES (len=%d)\n",pEid->Len));
412 return FALSE;
413 }
414 break;
415
416 case IE_HT_CAP:
417 if (pEid->Len >= SIZE_HT_CAP_IE) //Note: allow extension.!!
418 {
419 NdisMoveMemory(pHtCapability, pEid->Octet, sizeof(HT_CAPABILITY_IE));
420 *pHtCapabilityLen = SIZE_HT_CAP_IE; // Nnow we only support 26 bytes.
421
422 *(USHORT *)(&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo));
423 *(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo));
424
425 {
426 *pPreNHtCapabilityLen = 0; // Nnow we only support 26 bytes.
427
428 Ptr = (PUCHAR) pVIE;
429 NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
430 *LengthVIE += (pEid->Len + 2);
431 }
432 }
433 else
434 {
435 DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - wrong IE_HT_CAP. pEid->Len = %d\n", pEid->Len));
436 }
437
438 break;
439 case IE_ADD_HT:
440 if (pEid->Len >= sizeof(ADD_HT_INFO_IE))
441 {
442 // This IE allows extension, but we can ignore extra bytes beyond our knowledge , so only
443 // copy first sizeof(ADD_HT_INFO_IE)
444 NdisMoveMemory(AddHtInfo, pEid->Octet, sizeof(ADD_HT_INFO_IE));
445 *AddHtInfoLen = SIZE_ADD_HT_INFO_IE;
446
447 CtrlChannel = AddHtInfo->ControlChan;
448
449 *(USHORT *)(&AddHtInfo->AddHtInfo2) = cpu2le16(*(USHORT *)(&AddHtInfo->AddHtInfo2));
450 *(USHORT *)(&AddHtInfo->AddHtInfo3) = cpu2le16(*(USHORT *)(&AddHtInfo->AddHtInfo3));
451
452 {
453 Ptr = (PUCHAR) pVIE;
454 NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
455 *LengthVIE += (pEid->Len + 2);
456 }
457 }
458 else
459 {
460 DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - wrong IE_ADD_HT. \n"));
461 }
462
463 break;
464 case IE_SECONDARY_CH_OFFSET:
465 if (pEid->Len == 1)
466 {
467 *NewExtChannelOffset = pEid->Octet[0];
468 }
469 else
470 {
471 DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - wrong IE_SECONDARY_CH_OFFSET. \n"));
472 }
473
474 break;
475 case IE_FH_PARM:
476 DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity(IE_FH_PARM) \n"));
477 break;
478
479 case IE_DS_PARM:
480 if(pEid->Len == 1)
481 {
482 *pChannel = *pEid->Octet;
483
484 {
485 if (ChannelSanity(pAd, *pChannel) == 0)
486 {
487
488 return FALSE;
489 }
490 }
491
492 Sanity |= 0x4;
493 }
494 else
495 {
496 DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_DS_PARM (len=%d)\n",pEid->Len));
497 return FALSE;
498 }
499 break;
500
501 case IE_CF_PARM:
502 if(pEid->Len == 6)
503 {
504 pCfParm->bValid = TRUE;
505 pCfParm->CfpCount = pEid->Octet[0];
506 pCfParm->CfpPeriod = pEid->Octet[1];
507 pCfParm->CfpMaxDuration = pEid->Octet[2] + 256 * pEid->Octet[3];
508 pCfParm->CfpDurRemaining = pEid->Octet[4] + 256 * pEid->Octet[5];
509 }
510 else
511 {
512 DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_CF_PARM\n"));
513 return FALSE;
514 }
515 break;
516
517 case IE_IBSS_PARM:
518 if(pEid->Len == 2)
519 {
520 NdisMoveMemory(pAtimWin, pEid->Octet, pEid->Len);
521 }
522 else
523 {
524 DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_IBSS_PARM\n"));
525 return FALSE;
526 }
527 break;
528
529 case IE_TIM:
530 if(INFRA_ON(pAd) && SubType == SUBTYPE_BEACON)
531 {
532 GetTimBit((PUCHAR)pEid, pAd->StaActive.Aid, &TimLen, pBcastFlag, pDtimCount, pDtimPeriod, pMessageToMe);
533 }
534 break;
535
536 case IE_CHANNEL_SWITCH_ANNOUNCEMENT:
537 if(pEid->Len == 3)
538 {
539 *pNewChannel = pEid->Octet[1]; //extract new channel number
540 }
541 break;
542
543 // New for WPA
544 // CCX v2 has the same IE, we need to parse that too
545 // Wifi WMM use the same IE vale, need to parse that too
546 // case IE_WPA:
547 case IE_VENDOR_SPECIFIC:
548 // Check the OUI version, filter out non-standard usage
549 if (NdisEqualMemory(pEid->Octet, RALINK_OUI, 3) && (pEid->Len == 7))
550 {
551 //*pRalinkIe = pEid->Octet[3];
552 if (pEid->Octet[3] != 0)
553 *pRalinkIe = pEid->Octet[3];
554 else
555 *pRalinkIe = 0xf0000000; // Set to non-zero value (can't set bit0-2) to represent this is Ralink Chip. So at linkup, we will set ralinkchip flag.
556 }
557 // This HT IE is before IEEE draft set HT IE value.2006-09-28 by Jan.
558
559 // Other vendors had production before IE_HT_CAP value is assigned. To backward support those old-firmware AP,
560 // Check broadcom-defiend pre-802.11nD1.0 OUI for HT related IE, including HT Capatilities IE and HT Information IE
561 else if ((*pHtCapabilityLen == 0) && NdisEqualMemory(pEid->Octet, PRE_N_HT_OUI, 3) && (pEid->Len >= 4) && (pAd->OpMode == OPMODE_STA))
562 {
563 if ((pEid->Octet[3] == OUI_PREN_HT_CAP) && (pEid->Len >= 30) && (*pHtCapabilityLen == 0))
564 {
565 NdisMoveMemory(pHtCapability, &pEid->Octet[4], sizeof(HT_CAPABILITY_IE));
566 *pPreNHtCapabilityLen = SIZE_HT_CAP_IE;
567 }
568
569 if ((pEid->Octet[3] == OUI_PREN_ADD_HT) && (pEid->Len >= 26))
570 {
571 NdisMoveMemory(AddHtInfo, &pEid->Octet[4], sizeof(ADD_HT_INFO_IE));
572 *AddHtInfoLen = SIZE_ADD_HT_INFO_IE;
573 }
574 }
575 else if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))
576 {
577 // Copy to pVIE which will report to microsoft bssid list.
578 Ptr = (PUCHAR) pVIE;
579 NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
580 *LengthVIE += (pEid->Len + 2);
581 }
582 else if (NdisEqualMemory(pEid->Octet, WME_PARM_ELEM, 6) && (pEid->Len == 24))
583 {
584 PUCHAR ptr;
585 int i;
586
587 // parsing EDCA parameters
588 pEdcaParm->bValid = TRUE;
589 pEdcaParm->bQAck = FALSE; // pEid->Octet[0] & 0x10;
590 pEdcaParm->bQueueRequest = FALSE; // pEid->Octet[0] & 0x20;
591 pEdcaParm->bTxopRequest = FALSE; // pEid->Octet[0] & 0x40;
592 pEdcaParm->EdcaUpdateCount = pEid->Octet[6] & 0x0f;
593 pEdcaParm->bAPSDCapable = (pEid->Octet[6] & 0x80) ? 1 : 0;
594 ptr = &pEid->Octet[8];
595 for (i=0; i<4; i++)
596 {
597 UCHAR aci = (*ptr & 0x60) >> 5; // b5~6 is AC INDEX
598 pEdcaParm->bACM[aci] = (((*ptr) & 0x10) == 0x10); // b5 is ACM
599 pEdcaParm->Aifsn[aci] = (*ptr) & 0x0f; // b0~3 is AIFSN
600 pEdcaParm->Cwmin[aci] = *(ptr+1) & 0x0f; // b0~4 is Cwmin
601 pEdcaParm->Cwmax[aci] = *(ptr+1) >> 4; // b5~8 is Cwmax
602 pEdcaParm->Txop[aci] = *(ptr+2) + 256 * (*(ptr+3)); // in unit of 32-us
603 ptr += 4; // point to next AC
604 }
605 }
606 else if (NdisEqualMemory(pEid->Octet, WME_INFO_ELEM, 6) && (pEid->Len == 7))
607 {
608 // parsing EDCA parameters
609 pEdcaParm->bValid = TRUE;
610 pEdcaParm->bQAck = FALSE; // pEid->Octet[0] & 0x10;
611 pEdcaParm->bQueueRequest = FALSE; // pEid->Octet[0] & 0x20;
612 pEdcaParm->bTxopRequest = FALSE; // pEid->Octet[0] & 0x40;
613 pEdcaParm->EdcaUpdateCount = pEid->Octet[6] & 0x0f;
614 pEdcaParm->bAPSDCapable = (pEid->Octet[6] & 0x80) ? 1 : 0;
615
616 // use default EDCA parameter
617 pEdcaParm->bACM[QID_AC_BE] = 0;
618 pEdcaParm->Aifsn[QID_AC_BE] = 3;
619 pEdcaParm->Cwmin[QID_AC_BE] = CW_MIN_IN_BITS;
620 pEdcaParm->Cwmax[QID_AC_BE] = CW_MAX_IN_BITS;
621 pEdcaParm->Txop[QID_AC_BE] = 0;
622
623 pEdcaParm->bACM[QID_AC_BK] = 0;
624 pEdcaParm->Aifsn[QID_AC_BK] = 7;
625 pEdcaParm->Cwmin[QID_AC_BK] = CW_MIN_IN_BITS;
626 pEdcaParm->Cwmax[QID_AC_BK] = CW_MAX_IN_BITS;
627 pEdcaParm->Txop[QID_AC_BK] = 0;
628
629 pEdcaParm->bACM[QID_AC_VI] = 0;
630 pEdcaParm->Aifsn[QID_AC_VI] = 2;
631 pEdcaParm->Cwmin[QID_AC_VI] = CW_MIN_IN_BITS-1;
632 pEdcaParm->Cwmax[QID_AC_VI] = CW_MAX_IN_BITS;
633 pEdcaParm->Txop[QID_AC_VI] = 96; // AC_VI: 96*32us ~= 3ms
634
635 pEdcaParm->bACM[QID_AC_VO] = 0;
636 pEdcaParm->Aifsn[QID_AC_VO] = 2;
637 pEdcaParm->Cwmin[QID_AC_VO] = CW_MIN_IN_BITS-2;
638 pEdcaParm->Cwmax[QID_AC_VO] = CW_MAX_IN_BITS-1;
639 pEdcaParm->Txop[QID_AC_VO] = 48; // AC_VO: 48*32us ~= 1.5ms
640 }
641 break;
642
643 case IE_EXT_SUPP_RATES:
644 if (pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES)
645 {
646 NdisMoveMemory(ExtRate, pEid->Octet, pEid->Len);
647 *pExtRateLen = pEid->Len;
648
649 // TODO: 2004-09-14 not a good design here, cause it exclude extra rates
650 // from ScanTab. We should report as is. And filter out unsupported
651 // rates in MlmeAux.
652 // Check against the supported rates
653 // RTMPCheckRates(pAd, ExtRate, pExtRateLen);
654 }
655 break;
656
657 case IE_ERP:
658 if (pEid->Len == 1)
659 {
660 *pErp = (UCHAR)pEid->Octet[0];
661 }
662 break;
663
664 case IE_AIRONET_CKIP:
665 // 0. Check Aironet IE length, it must be larger or equal to 28
666 // Cisco AP350 used length as 28
667 // Cisco AP12XX used length as 30
668 if (pEid->Len < (CKIP_NEGOTIATION_LENGTH - 2))
669 break;
670
671 // 1. Copy CKIP flag byte to buffer for process
672 *pCkipFlag = *(pEid->Octet + 8);
673 break;
674
675 case IE_AP_TX_POWER:
676 // AP Control of Client Transmit Power
677 //0. Check Aironet IE length, it must be 6
678 if (pEid->Len != 0x06)
679 break;
680
681 // Get cell power limit in dBm
682 if (NdisEqualMemory(pEid->Octet, CISCO_OUI, 3) == 1)
683 *pAironetCellPowerLimit = *(pEid->Octet + 4);
684 break;
685
686 // WPA2 & 802.11i RSN
687 case IE_RSN:
688 // There is no OUI for version anymore, check the group cipher OUI before copying
689 if (RTMPEqualMemory(pEid->Octet + 2, RSN_OUI, 3))
690 {
691 // Copy to pVIE which will report to microsoft bssid list.
692 Ptr = (PUCHAR) pVIE;
693 NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
694 *LengthVIE += (pEid->Len + 2);
695 }
696 break;
697
698 default:
699 break;
700 }
701
702 Length = Length + 2 + pEid->Len; // Eid[1] + Len[1]+ content[Len]
703 pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
704 }
705
706 // For some 11a AP. it did not have the channel EID, patch here
707 {
708 UCHAR LatchRfChannel = MsgChannel;
709 if ((pAd->LatchRfRegs.Channel > 14) && ((Sanity & 0x4) == 0))
710 {
711 if (CtrlChannel != 0)
712 *pChannel = CtrlChannel;
713 else
714 *pChannel = LatchRfChannel;
715 Sanity |= 0x4;
716 }
717 }
718
719 if (Sanity != 0x7)
720 {
721 DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - missing field, Sanity=0x%02x\n", Sanity));
722 return FALSE;
723 }
724 else
725 {
726 return TRUE;
727 }
728
729 }
730
731 /*
732 ==========================================================================
733 Description:
734 MLME message sanity check
735 Return:
736 TRUE if all parameters are OK, FALSE otherwise
737 ==========================================================================
738 */
739 BOOLEAN MlmeScanReqSanity(
740 IN PRTMP_ADAPTER pAd,
741 IN VOID *Msg,
742 IN ULONG MsgLen,
743 OUT UCHAR *pBssType,
744 OUT CHAR Ssid[],
745 OUT UCHAR *pSsidLen,
746 OUT UCHAR *pScanType)
747 {
748 MLME_SCAN_REQ_STRUCT *Info;
749
750 Info = (MLME_SCAN_REQ_STRUCT *)(Msg);
751 *pBssType = Info->BssType;
752 *pSsidLen = Info->SsidLen;
753 NdisMoveMemory(Ssid, Info->Ssid, *pSsidLen);
754 *pScanType = Info->ScanType;
755
756 if ((*pBssType == BSS_INFRA || *pBssType == BSS_ADHOC || *pBssType == BSS_ANY)
757 && (*pScanType == SCAN_ACTIVE || *pScanType == SCAN_PASSIVE
758 || *pScanType == SCAN_CISCO_PASSIVE || *pScanType == SCAN_CISCO_ACTIVE
759 || *pScanType == SCAN_CISCO_CHANNEL_LOAD || *pScanType == SCAN_CISCO_NOISE
760 ))
761 {
762 return TRUE;
763 }
764 else
765 {
766 DBGPRINT(RT_DEBUG_TRACE, ("MlmeScanReqSanity fail - wrong BssType or ScanType\n"));
767 return FALSE;
768 }
769 }
770
771 // IRQL = DISPATCH_LEVEL
772 UCHAR ChannelSanity(
773 IN PRTMP_ADAPTER pAd,
774 IN UCHAR channel)
775 {
776 int i;
777
778 for (i = 0; i < pAd->ChannelListNum; i ++)
779 {
780 if (channel == pAd->ChannelList[i].Channel)
781 return 1;
782 }
783 return 0;
784 }
785
786 /*
787 ==========================================================================
788 Description:
789 MLME message sanity check
790 Return:
791 TRUE if all parameters are OK, FALSE otherwise
792
793 IRQL = DISPATCH_LEVEL
794
795 ==========================================================================
796 */
797 BOOLEAN PeerDeauthSanity(
798 IN PRTMP_ADAPTER pAd,
799 IN VOID *Msg,
800 IN ULONG MsgLen,
801 OUT PUCHAR pAddr2,
802 OUT USHORT *pReason)
803 {
804 PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
805
806 COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
807 NdisMoveMemory(pReason, &pFrame->Octet[0], 2);
808
809 return TRUE;
810 }
811
812 /*
813 ==========================================================================
814 Description:
815 MLME message sanity check
816 Return:
817 TRUE if all parameters are OK, FALSE otherwise
818
819 IRQL = DISPATCH_LEVEL
820
821 ==========================================================================
822 */
823 BOOLEAN PeerAuthSanity(
824 IN PRTMP_ADAPTER pAd,
825 IN VOID *Msg,
826 IN ULONG MsgLen,
827 OUT PUCHAR pAddr,
828 OUT USHORT *pAlg,
829 OUT USHORT *pSeq,
830 OUT USHORT *pStatus,
831 CHAR *pChlgText)
832 {
833 PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
834
835 COPY_MAC_ADDR(pAddr, pFrame->Hdr.Addr2);
836 NdisMoveMemory(pAlg, &pFrame->Octet[0], 2);
837 NdisMoveMemory(pSeq, &pFrame->Octet[2], 2);
838 NdisMoveMemory(pStatus, &pFrame->Octet[4], 2);
839
840 if ((*pAlg == Ndis802_11AuthModeOpen)
841 )
842 {
843 if (*pSeq == 1 || *pSeq == 2)
844 {
845 return TRUE;
846 }
847 else
848 {
849 DBGPRINT(RT_DEBUG_TRACE, ("PeerAuthSanity fail - wrong Seg#\n"));
850 return FALSE;
851 }
852 }
853 else if (*pAlg == Ndis802_11AuthModeShared)
854 {
855 if (*pSeq == 1 || *pSeq == 4)
856 {
857 return TRUE;
858 }
859 else if (*pSeq == 2 || *pSeq == 3)
860 {
861 NdisMoveMemory(pChlgText, &pFrame->Octet[8], CIPHER_TEXT_LEN);
862 return TRUE;
863 }
864 else
865 {
866 DBGPRINT(RT_DEBUG_TRACE, ("PeerAuthSanity fail - wrong Seg#\n"));
867 return FALSE;
868 }
869 }
870 else
871 {
872 DBGPRINT(RT_DEBUG_TRACE, ("PeerAuthSanity fail - wrong algorithm\n"));
873 return FALSE;
874 }
875 }
876
877 /*
878 ==========================================================================
879 Description:
880 MLME message sanity check
881 Return:
882 TRUE if all parameters are OK, FALSE otherwise
883 ==========================================================================
884 */
885 BOOLEAN MlmeAuthReqSanity(
886 IN PRTMP_ADAPTER pAd,
887 IN VOID *Msg,
888 IN ULONG MsgLen,
889 OUT PUCHAR pAddr,
890 OUT ULONG *pTimeout,
891 OUT USHORT *pAlg)
892 {
893 MLME_AUTH_REQ_STRUCT *pInfo;
894
895 pInfo = (MLME_AUTH_REQ_STRUCT *)Msg;
896 COPY_MAC_ADDR(pAddr, pInfo->Addr);
897 *pTimeout = pInfo->Timeout;
898 *pAlg = pInfo->Alg;
899
900 if (((*pAlg == Ndis802_11AuthModeShared) ||(*pAlg == Ndis802_11AuthModeOpen)
901 ) &&
902 ((*pAddr & 0x01) == 0))
903 {
904 return TRUE;
905 }
906 else
907 {
908 DBGPRINT(RT_DEBUG_TRACE, ("MlmeAuthReqSanity fail - wrong algorithm\n"));
909 return FALSE;
910 }
911 }
912
913 /*
914 ==========================================================================
915 Description:
916 MLME message sanity check
917 Return:
918 TRUE if all parameters are OK, FALSE otherwise
919
920 IRQL = DISPATCH_LEVEL
921
922 ==========================================================================
923 */
924 BOOLEAN MlmeAssocReqSanity(
925 IN PRTMP_ADAPTER pAd,
926 IN VOID *Msg,
927 IN ULONG MsgLen,
928 OUT PUCHAR pApAddr,
929 OUT USHORT *pCapabilityInfo,
930 OUT ULONG *pTimeout,
931 OUT USHORT *pListenIntv)
932 {
933 MLME_ASSOC_REQ_STRUCT *pInfo;
934
935 pInfo = (MLME_ASSOC_REQ_STRUCT *)Msg;
936 *pTimeout = pInfo->Timeout; // timeout
937 COPY_MAC_ADDR(pApAddr, pInfo->Addr); // AP address
938 *pCapabilityInfo = pInfo->CapabilityInfo; // capability info
939 *pListenIntv = pInfo->ListenIntv;
940
941 return TRUE;
942 }
943
944 /*
945 ==========================================================================
946 Description:
947 MLME message sanity check
948 Return:
949 TRUE if all parameters are OK, FALSE otherwise
950
951 IRQL = DISPATCH_LEVEL
952
953 ==========================================================================
954 */
955 BOOLEAN PeerDisassocSanity(
956 IN PRTMP_ADAPTER pAd,
957 IN VOID *Msg,
958 IN ULONG MsgLen,
959 OUT PUCHAR pAddr2,
960 OUT USHORT *pReason)
961 {
962 PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
963
964 COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
965 NdisMoveMemory(pReason, &pFrame->Octet[0], 2);
966
967 return TRUE;
968 }
969
970 /*
971 ========================================================================
972 Routine Description:
973 Sanity check NetworkType (11b, 11g or 11a)
974
975 Arguments:
976 pBss - Pointer to BSS table.
977
978 Return Value:
979 Ndis802_11DS .......(11b)
980 Ndis802_11OFDM24....(11g)
981 Ndis802_11OFDM5.....(11a)
982
983 IRQL = DISPATCH_LEVEL
984
985 ========================================================================
986 */
987 NDIS_802_11_NETWORK_TYPE NetworkTypeInUseSanity(
988 IN PBSS_ENTRY pBss)
989 {
990 NDIS_802_11_NETWORK_TYPE NetWorkType;
991 UCHAR rate, i;
992
993 NetWorkType = Ndis802_11DS;
994
995 if (pBss->Channel <= 14)
996 {
997 //
998 // First check support Rate.
999 //
1000 for (i = 0; i < pBss->SupRateLen; i++)
1001 {
1002 rate = pBss->SupRate[i] & 0x7f; // Mask out basic rate set bit
1003 if ((rate == 2) || (rate == 4) || (rate == 11) || (rate == 22))
1004 {
1005 continue;
1006 }
1007 else
1008 {
1009 //
1010 // Otherwise (even rate > 108) means Ndis802_11OFDM24
1011 //
1012 NetWorkType = Ndis802_11OFDM24;
1013 break;
1014 }
1015 }
1016
1017 //
1018 // Second check Extend Rate.
1019 //
1020 if (NetWorkType != Ndis802_11OFDM24)
1021 {
1022 for (i = 0; i < pBss->ExtRateLen; i++)
1023 {
1024 rate = pBss->SupRate[i] & 0x7f; // Mask out basic rate set bit
1025 if ((rate == 2) || (rate == 4) || (rate == 11) || (rate == 22))
1026 {
1027 continue;
1028 }
1029 else
1030 {
1031 //
1032 // Otherwise (even rate > 108) means Ndis802_11OFDM24
1033 //
1034 NetWorkType = Ndis802_11OFDM24;
1035 break;
1036 }
1037 }
1038 }
1039 }
1040 else
1041 {
1042 NetWorkType = Ndis802_11OFDM5;
1043 }
1044
1045 if (pBss->HtCapabilityLen != 0)
1046 {
1047 if (NetWorkType == Ndis802_11OFDM5)
1048 NetWorkType = Ndis802_11OFDM5_N;
1049 else
1050 NetWorkType = Ndis802_11OFDM24_N;
1051 }
1052
1053 return NetWorkType;
1054 }
This page took 0.060461 seconds and 6 git commands to generate.