2 *************************************************************************
4 * 5F., No.36, Taiyuan St., Jhubei City,
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
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. *
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. *
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. *
25 *************************************************************************
34 -------- ---------- ----------------------------------------------
35 John Chang 2004-09-01 add WMM support
37 #include "../rt_config.h"
40 extern UCHAR CISCO_OUI
[];
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
[];
52 ==========================================================================
54 MLME message sanity check
56 TRUE if all parameters are OK, FALSE otherwise
60 ==========================================================================
62 BOOLEAN
MlmeAddBAReqSanity(
68 PMLME_ADDBA_REQ_STRUCT pInfo
;
70 pInfo
= (MLME_ADDBA_REQ_STRUCT
*)Msg
;
72 if ((MsgLen
!= sizeof(MLME_ADDBA_REQ_STRUCT
)))
74 DBGPRINT(RT_DEBUG_TRACE
, ("MlmeAddBAReqSanity fail - message lenght not correct.\n"));
78 if ((pInfo
->Wcid
>= MAX_LEN_OF_MAC_TABLE
))
80 DBGPRINT(RT_DEBUG_TRACE
, ("MlmeAddBAReqSanity fail - The peer Mac is not associated yet.\n"));
84 if ((pInfo
->pAddr
[0]&0x01) == 0x01)
86 DBGPRINT(RT_DEBUG_TRACE
, ("MlmeAddBAReqSanity fail - broadcast address not support BA\n"));
94 ==========================================================================
96 MLME message sanity check
98 TRUE if all parameters are OK, FALSE otherwise
100 IRQL = DISPATCH_LEVEL
102 ==========================================================================
104 BOOLEAN
MlmeDelBAReqSanity(
105 IN PRTMP_ADAPTER pAd
,
109 MLME_DELBA_REQ_STRUCT
*pInfo
;
110 pInfo
= (MLME_DELBA_REQ_STRUCT
*)Msg
;
112 if ((MsgLen
!= sizeof(MLME_DELBA_REQ_STRUCT
)))
114 DBGPRINT(RT_DEBUG_ERROR
, ("MlmeDelBAReqSanity fail - message lenght not correct.\n"));
118 if ((pInfo
->Wcid
>= MAX_LEN_OF_MAC_TABLE
))
120 DBGPRINT(RT_DEBUG_ERROR
, ("MlmeDelBAReqSanity fail - The peer Mac is not associated yet.\n"));
124 if ((pInfo
->TID
& 0xf0))
126 DBGPRINT(RT_DEBUG_ERROR
, ("MlmeDelBAReqSanity fail - The peer TID is incorrect.\n"));
130 if (NdisEqualMemory(pAd
->MacTab
.Content
[pInfo
->Wcid
].Addr
, pInfo
->Addr
, MAC_ADDR_LEN
) == 0)
132 DBGPRINT(RT_DEBUG_ERROR
, ("MlmeDelBAReqSanity fail - the peer addr dosen't exist.\n"));
139 BOOLEAN
PeerAddBAReqActionSanity(
140 IN PRTMP_ADAPTER pAd
,
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
)))
150 DBGPRINT(RT_DEBUG_ERROR
,("PeerAddBAReqActionSanity: ADDBA Request frame length size = %ld incorrect\n", MsgLen
));
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
);
158 if (pAddFrame
->BaParm
.BAPolicy
!= IMMED_BA
)
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
));
165 // we support immediate BA.
166 if (pAddFrame
->BaParm
.TID
&0xfff0)
168 DBGPRINT(RT_DEBUG_ERROR
,("PeerAddBAReqActionSanity: ADDBA Request incorrect TID = %d\n", pAddFrame
->BaParm
.TID
));
171 COPY_MAC_ADDR(pAddr2
, pFrame
->Hdr
.Addr2
);
175 BOOLEAN
PeerAddBARspActionSanity(
176 IN PRTMP_ADAPTER pAd
,
180 PFRAME_ADDBA_RSP pAddFrame
;
182 pAddFrame
= (PFRAME_ADDBA_RSP
)(pMsg
);
183 if (MsgLen
< (sizeof(FRAME_ADDBA_RSP
)))
185 DBGPRINT(RT_DEBUG_ERROR
,("PeerAddBARspActionSanity: ADDBA Response frame length size = %ld incorrect\n", MsgLen
));
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
);
193 if (pAddFrame
->BaParm
.BAPolicy
!= IMMED_BA
)
195 DBGPRINT(RT_DEBUG_ERROR
,("PeerAddBAReqActionSanity: ADDBA Response Ba Policy[%d] not support\n", pAddFrame
->BaParm
.BAPolicy
));
199 // we support immediate BA.
200 if (pAddFrame
->BaParm
.TID
&0xfff0)
202 DBGPRINT(RT_DEBUG_ERROR
,("PeerAddBARspActionSanity: ADDBA Response incorrect TID = %d\n", pAddFrame
->BaParm
.TID
));
209 BOOLEAN
PeerDelBAActionSanity(
210 IN PRTMP_ADAPTER pAd
,
215 //PFRAME_802_11 pFrame = (PFRAME_802_11)pMsg;
216 PFRAME_DELBA_REQ pDelFrame
;
217 if (MsgLen
!= (sizeof(FRAME_DELBA_REQ
)))
220 if (Wcid
>= MAX_LEN_OF_MAC_TABLE
)
223 pDelFrame
= (PFRAME_DELBA_REQ
)(pMsg
);
225 *(USHORT
*)(&pDelFrame
->DelbaParm
) = cpu2le16(*(USHORT
*)(&pDelFrame
->DelbaParm
));
226 pDelFrame
->ReasonCode
= cpu2le16(pDelFrame
->ReasonCode
);
228 if (pDelFrame
->DelbaParm
.TID
&0xfff0)
235 ==========================================================================
237 MLME message sanity check
239 TRUE if all parameters are OK, FALSE otherwise
241 IRQL = DISPATCH_LEVEL
243 ==========================================================================
245 BOOLEAN
PeerBeaconAndProbeRspSanity(
246 IN PRTMP_ADAPTER pAd
,
255 OUT USHORT
*pBeaconPeriod
,
257 OUT UCHAR
*pNewChannel
,
258 OUT LARGE_INTEGER
*pTimestamp
,
259 OUT CF_PARM
*pCfParm
,
260 OUT USHORT
*pAtimWin
,
261 OUT USHORT
*pCapabilityInfo
,
263 OUT UCHAR
*pDtimCount
,
264 OUT UCHAR
*pDtimPeriod
,
265 OUT UCHAR
*pBcastFlag
,
266 OUT UCHAR
*pMessageToMe
,
268 OUT UCHAR
*pSupRateLen
,
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 #ifdef CONFIG_STA_SUPPORT
279 OUT UCHAR
*pPreNHtCapabilityLen
,
280 #endif // CONFIG_STA_SUPPORT //
281 OUT HT_CAPABILITY_IE
*pHtCapability
,
282 OUT UCHAR
*AddHtInfoLen
,
283 OUT ADD_HT_INFO_IE
*AddHtInfo
,
284 OUT UCHAR
*NewExtChannelOffset
, // Ht extension channel offset(above or below)
285 OUT USHORT
*LengthVIE
,
286 OUT PNDIS_802_11_VARIABLE_IEs pVIE
)
289 #ifdef CONFIG_STA_SUPPORT
291 #endif // CONFIG_STA_SUPPORT //
292 PFRAME_802_11 pFrame
;
296 //UCHAR ECWMin, ECWMax;
297 //MAC_CSR9_STRUC Csr9;
300 // For some 11a AP which didn't have DS_IE, we use two conditions to decide the channel
301 // 1. If the AP is 11n enabled, then check the control channel.
302 // 2. If the AP didn't have any info about channel, use the channel we received this frame as the channel. (May inaccuracy!!)
303 UCHAR CtrlChannel
= 0;
305 // Add for 3 necessary EID field check
315 *pCkipFlag
= 0; // Default of CkipFlag is 0
316 *pAironetCellPowerLimit
= 0xFF; // Default of AironetCellPowerLimit is 0xFF
317 *LengthVIE
= 0; // Set the length of VIE to init value 0
318 *pHtCapabilityLen
= 0; // Set the length of VIE to init value 0
319 #ifdef CONFIG_STA_SUPPORT
320 if (pAd
->OpMode
== OPMODE_STA
)
321 *pPreNHtCapabilityLen
= 0; // Set the length of VIE to init value 0
322 #endif // CONFIG_STA_SUPPORT //
323 *AddHtInfoLen
= 0; // Set the length of VIE to init value 0
326 *NewExtChannelOffset
= 0xff; //Default 0xff means no such IE
327 pCfParm
->bValid
= FALSE
; // default: no IE_CF found
328 pQbssLoad
->bValid
= FALSE
; // default: no IE_QBSS_LOAD found
329 pEdcaParm
->bValid
= FALSE
; // default: no IE_EDCA_PARAMETER found
330 pQosCapability
->bValid
= FALSE
; // default: no IE_QOS_CAPABILITY found
332 pFrame
= (PFRAME_802_11
)Msg
;
334 // get subtype from header
335 SubType
= (UCHAR
)pFrame
->Hdr
.FC
.SubType
;
337 // get Addr2 and BSSID from header
338 COPY_MAC_ADDR(pAddr2
, pFrame
->Hdr
.Addr2
);
339 COPY_MAC_ADDR(pBssid
, pFrame
->Hdr
.Addr3
);
342 Length
+= LENGTH_802_11
;
344 // get timestamp from payload and advance the pointer
345 NdisMoveMemory(pTimestamp
, Ptr
, TIMESTAMP_LEN
);
347 pTimestamp
->u
.LowPart
= cpu2le32(pTimestamp
->u
.LowPart
);
348 pTimestamp
->u
.HighPart
= cpu2le32(pTimestamp
->u
.HighPart
);
350 Ptr
+= TIMESTAMP_LEN
;
351 Length
+= TIMESTAMP_LEN
;
353 // get beacon interval from payload and advance the pointer
354 NdisMoveMemory(pBeaconPeriod
, Ptr
, 2);
358 // get capability info from payload and advance the pointer
359 NdisMoveMemory(pCapabilityInfo
, Ptr
, 2);
363 if (CAP_IS_ESS_ON(*pCapabilityInfo
))
364 *pBssType
= BSS_INFRA
;
366 *pBssType
= BSS_ADHOC
;
368 pEid
= (PEID_STRUCT
) Ptr
;
370 // get variable fields from payload and advance the pointer
371 while ((Length
+ 2 + pEid
->Len
) <= MsgLen
)
374 // Secure copy VIE to VarIE[MAX_VIE_LEN] didn't overflow.
376 if ((*LengthVIE
+ pEid
->Len
+ 2) >= MAX_VIE_LEN
)
378 DBGPRINT(RT_DEBUG_WARN
, ("PeerBeaconAndProbeRspSanity - Variable IEs out of resource [len(=%d) > MAX_VIE_LEN(=%d)]\n",
379 (*LengthVIE
+ pEid
->Len
+ 2), MAX_VIE_LEN
));
386 // Already has one SSID EID in this beacon, ignore the second one
389 if(pEid
->Len
<= MAX_LEN_OF_SSID
)
391 NdisMoveMemory(Ssid
, pEid
->Octet
, pEid
->Len
);
392 *pSsidLen
= pEid
->Len
;
397 DBGPRINT(RT_DEBUG_TRACE
, ("PeerBeaconAndProbeRspSanity - wrong IE_SSID (len=%d)\n",pEid
->Len
));
403 if(pEid
->Len
<= MAX_LEN_OF_SUPPORTED_RATES
)
406 NdisMoveMemory(SupRate
, pEid
->Octet
, pEid
->Len
);
407 *pSupRateLen
= pEid
->Len
;
409 // TODO: 2004-09-14 not a good design here, cause it exclude extra rates
410 // from ScanTab. We should report as is. And filter out unsupported
412 // Check against the supported rates
413 // RTMPCheckRates(pAd, SupRate, pSupRateLen);
417 DBGPRINT(RT_DEBUG_TRACE
, ("PeerBeaconAndProbeRspSanity - wrong IE_SUPP_RATES (len=%d)\n",pEid
->Len
));
423 if (pEid
->Len
>= SIZE_HT_CAP_IE
) //Note: allow extension.!!
425 NdisMoveMemory(pHtCapability
, pEid
->Octet
, sizeof(HT_CAPABILITY_IE
));
426 *pHtCapabilityLen
= SIZE_HT_CAP_IE
; // Nnow we only support 26 bytes.
428 *(USHORT
*)(&pHtCapability
->HtCapInfo
) = cpu2le16(*(USHORT
*)(&pHtCapability
->HtCapInfo
));
429 *(USHORT
*)(&pHtCapability
->ExtHtCapInfo
) = cpu2le16(*(USHORT
*)(&pHtCapability
->ExtHtCapInfo
));
431 #ifdef CONFIG_STA_SUPPORT
432 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
434 *pPreNHtCapabilityLen
= 0; // Nnow we only support 26 bytes.
437 NdisMoveMemory(Ptr
+ *LengthVIE
, &pEid
->Eid
, pEid
->Len
+ 2);
438 *LengthVIE
+= (pEid
->Len
+ 2);
440 #endif // CONFIG_STA_SUPPORT //
444 DBGPRINT(RT_DEBUG_WARN
, ("PeerBeaconAndProbeRspSanity - wrong IE_HT_CAP. pEid->Len = %d\n", pEid
->Len
));
449 if (pEid
->Len
>= sizeof(ADD_HT_INFO_IE
))
451 // This IE allows extension, but we can ignore extra bytes beyond our knowledge , so only
452 // copy first sizeof(ADD_HT_INFO_IE)
453 NdisMoveMemory(AddHtInfo
, pEid
->Octet
, sizeof(ADD_HT_INFO_IE
));
454 *AddHtInfoLen
= SIZE_ADD_HT_INFO_IE
;
456 CtrlChannel
= AddHtInfo
->ControlChan
;
458 *(USHORT
*)(&AddHtInfo
->AddHtInfo2
) = cpu2le16(*(USHORT
*)(&AddHtInfo
->AddHtInfo2
));
459 *(USHORT
*)(&AddHtInfo
->AddHtInfo3
) = cpu2le16(*(USHORT
*)(&AddHtInfo
->AddHtInfo3
));
461 #ifdef CONFIG_STA_SUPPORT
462 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
465 NdisMoveMemory(Ptr
+ *LengthVIE
, &pEid
->Eid
, pEid
->Len
+ 2);
466 *LengthVIE
+= (pEid
->Len
+ 2);
468 #endif // CONFIG_STA_SUPPORT //
472 DBGPRINT(RT_DEBUG_WARN
, ("PeerBeaconAndProbeRspSanity - wrong IE_ADD_HT. \n"));
476 case IE_SECONDARY_CH_OFFSET
:
479 *NewExtChannelOffset
= pEid
->Octet
[0];
483 DBGPRINT(RT_DEBUG_WARN
, ("PeerBeaconAndProbeRspSanity - wrong IE_SECONDARY_CH_OFFSET. \n"));
488 DBGPRINT(RT_DEBUG_TRACE
, ("PeerBeaconAndProbeRspSanity(IE_FH_PARM) \n"));
494 *pChannel
= *pEid
->Octet
;
495 #ifdef CONFIG_STA_SUPPORT
496 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
498 if (ChannelSanity(pAd
, *pChannel
) == 0)
504 #endif // CONFIG_STA_SUPPORT //
509 DBGPRINT(RT_DEBUG_TRACE
, ("PeerBeaconAndProbeRspSanity - wrong IE_DS_PARM (len=%d)\n",pEid
->Len
));
517 pCfParm
->bValid
= TRUE
;
518 pCfParm
->CfpCount
= pEid
->Octet
[0];
519 pCfParm
->CfpPeriod
= pEid
->Octet
[1];
520 pCfParm
->CfpMaxDuration
= pEid
->Octet
[2] + 256 * pEid
->Octet
[3];
521 pCfParm
->CfpDurRemaining
= pEid
->Octet
[4] + 256 * pEid
->Octet
[5];
525 DBGPRINT(RT_DEBUG_TRACE
, ("PeerBeaconAndProbeRspSanity - wrong IE_CF_PARM\n"));
533 NdisMoveMemory(pAtimWin
, pEid
->Octet
, pEid
->Len
);
537 DBGPRINT(RT_DEBUG_TRACE
, ("PeerBeaconAndProbeRspSanity - wrong IE_IBSS_PARM\n"));
542 #ifdef CONFIG_STA_SUPPORT
544 if(INFRA_ON(pAd
) && SubType
== SUBTYPE_BEACON
)
546 GetTimBit((PUCHAR
)pEid
, pAd
->StaActive
.Aid
, &TimLen
, pBcastFlag
, pDtimCount
, pDtimPeriod
, pMessageToMe
);
549 #endif // CONFIG_STA_SUPPORT //
550 case IE_CHANNEL_SWITCH_ANNOUNCEMENT
:
553 *pNewChannel
= pEid
->Octet
[1]; //extract new channel number
558 // CCX v2 has the same IE, we need to parse that too
559 // Wifi WMM use the same IE vale, need to parse that too
561 case IE_VENDOR_SPECIFIC
:
562 // Check the OUI version, filter out non-standard usage
563 if (NdisEqualMemory(pEid
->Octet
, RALINK_OUI
, 3) && (pEid
->Len
== 7))
565 //*pRalinkIe = pEid->Octet[3];
566 if (pEid
->Octet
[3] != 0)
567 *pRalinkIe
= pEid
->Octet
[3];
569 *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.
571 #ifdef CONFIG_STA_SUPPORT
572 #ifdef DOT11_N_SUPPORT
573 // This HT IE is before IEEE draft set HT IE value.2006-09-28 by Jan.
575 // Other vendors had production before IE_HT_CAP value is assigned. To backward support those old-firmware AP,
576 // Check broadcom-defiend pre-802.11nD1.0 OUI for HT related IE, including HT Capatilities IE and HT Information IE
577 else if ((*pHtCapabilityLen
== 0) && NdisEqualMemory(pEid
->Octet
, PRE_N_HT_OUI
, 3) && (pEid
->Len
>= 4) && (pAd
->OpMode
== OPMODE_STA
))
579 if ((pEid
->Octet
[3] == OUI_PREN_HT_CAP
) && (pEid
->Len
>= 30) && (*pHtCapabilityLen
== 0))
581 NdisMoveMemory(pHtCapability
, &pEid
->Octet
[4], sizeof(HT_CAPABILITY_IE
));
582 *pPreNHtCapabilityLen
= SIZE_HT_CAP_IE
;
585 if ((pEid
->Octet
[3] == OUI_PREN_ADD_HT
) && (pEid
->Len
>= 26))
587 NdisMoveMemory(AddHtInfo
, &pEid
->Octet
[4], sizeof(ADD_HT_INFO_IE
));
588 *AddHtInfoLen
= SIZE_ADD_HT_INFO_IE
;
591 #endif // DOT11_N_SUPPORT //
592 #endif // CONFIG_STA_SUPPORT //
593 else if (NdisEqualMemory(pEid
->Octet
, WPA_OUI
, 4))
595 // Copy to pVIE which will report to microsoft bssid list.
597 NdisMoveMemory(Ptr
+ *LengthVIE
, &pEid
->Eid
, pEid
->Len
+ 2);
598 *LengthVIE
+= (pEid
->Len
+ 2);
600 else if (NdisEqualMemory(pEid
->Octet
, WME_PARM_ELEM
, 6) && (pEid
->Len
== 24))
605 // parsing EDCA parameters
606 pEdcaParm
->bValid
= TRUE
;
607 pEdcaParm
->bQAck
= FALSE
; // pEid->Octet[0] & 0x10;
608 pEdcaParm
->bQueueRequest
= FALSE
; // pEid->Octet[0] & 0x20;
609 pEdcaParm
->bTxopRequest
= FALSE
; // pEid->Octet[0] & 0x40;
610 pEdcaParm
->EdcaUpdateCount
= pEid
->Octet
[6] & 0x0f;
611 pEdcaParm
->bAPSDCapable
= (pEid
->Octet
[6] & 0x80) ? 1 : 0;
612 ptr
= &pEid
->Octet
[8];
615 UCHAR aci
= (*ptr
& 0x60) >> 5; // b5~6 is AC INDEX
616 pEdcaParm
->bACM
[aci
] = (((*ptr
) & 0x10) == 0x10); // b5 is ACM
617 pEdcaParm
->Aifsn
[aci
] = (*ptr
) & 0x0f; // b0~3 is AIFSN
618 pEdcaParm
->Cwmin
[aci
] = *(ptr
+1) & 0x0f; // b0~4 is Cwmin
619 pEdcaParm
->Cwmax
[aci
] = *(ptr
+1) >> 4; // b5~8 is Cwmax
620 pEdcaParm
->Txop
[aci
] = *(ptr
+2) + 256 * (*(ptr
+3)); // in unit of 32-us
621 ptr
+= 4; // point to next AC
624 else if (NdisEqualMemory(pEid
->Octet
, WME_INFO_ELEM
, 6) && (pEid
->Len
== 7))
626 // parsing EDCA parameters
627 pEdcaParm
->bValid
= TRUE
;
628 pEdcaParm
->bQAck
= FALSE
; // pEid->Octet[0] & 0x10;
629 pEdcaParm
->bQueueRequest
= FALSE
; // pEid->Octet[0] & 0x20;
630 pEdcaParm
->bTxopRequest
= FALSE
; // pEid->Octet[0] & 0x40;
631 pEdcaParm
->EdcaUpdateCount
= pEid
->Octet
[6] & 0x0f;
632 pEdcaParm
->bAPSDCapable
= (pEid
->Octet
[6] & 0x80) ? 1 : 0;
634 // use default EDCA parameter
635 pEdcaParm
->bACM
[QID_AC_BE
] = 0;
636 pEdcaParm
->Aifsn
[QID_AC_BE
] = 3;
637 pEdcaParm
->Cwmin
[QID_AC_BE
] = CW_MIN_IN_BITS
;
638 pEdcaParm
->Cwmax
[QID_AC_BE
] = CW_MAX_IN_BITS
;
639 pEdcaParm
->Txop
[QID_AC_BE
] = 0;
641 pEdcaParm
->bACM
[QID_AC_BK
] = 0;
642 pEdcaParm
->Aifsn
[QID_AC_BK
] = 7;
643 pEdcaParm
->Cwmin
[QID_AC_BK
] = CW_MIN_IN_BITS
;
644 pEdcaParm
->Cwmax
[QID_AC_BK
] = CW_MAX_IN_BITS
;
645 pEdcaParm
->Txop
[QID_AC_BK
] = 0;
647 pEdcaParm
->bACM
[QID_AC_VI
] = 0;
648 pEdcaParm
->Aifsn
[QID_AC_VI
] = 2;
649 pEdcaParm
->Cwmin
[QID_AC_VI
] = CW_MIN_IN_BITS
-1;
650 pEdcaParm
->Cwmax
[QID_AC_VI
] = CW_MAX_IN_BITS
;
651 pEdcaParm
->Txop
[QID_AC_VI
] = 96; // AC_VI: 96*32us ~= 3ms
653 pEdcaParm
->bACM
[QID_AC_VO
] = 0;
654 pEdcaParm
->Aifsn
[QID_AC_VO
] = 2;
655 pEdcaParm
->Cwmin
[QID_AC_VO
] = CW_MIN_IN_BITS
-2;
656 pEdcaParm
->Cwmax
[QID_AC_VO
] = CW_MAX_IN_BITS
-1;
657 pEdcaParm
->Txop
[QID_AC_VO
] = 48; // AC_VO: 48*32us ~= 1.5ms
661 case IE_EXT_SUPP_RATES
:
662 if (pEid
->Len
<= MAX_LEN_OF_SUPPORTED_RATES
)
664 NdisMoveMemory(ExtRate
, pEid
->Octet
, pEid
->Len
);
665 *pExtRateLen
= pEid
->Len
;
667 // TODO: 2004-09-14 not a good design here, cause it exclude extra rates
668 // from ScanTab. We should report as is. And filter out unsupported
670 // Check against the supported rates
671 // RTMPCheckRates(pAd, ExtRate, pExtRateLen);
678 *pErp
= (UCHAR
)pEid
->Octet
[0];
682 case IE_AIRONET_CKIP
:
683 // 0. Check Aironet IE length, it must be larger or equal to 28
684 // Cisco AP350 used length as 28
685 // Cisco AP12XX used length as 30
686 if (pEid
->Len
< (CKIP_NEGOTIATION_LENGTH
- 2))
689 // 1. Copy CKIP flag byte to buffer for process
690 *pCkipFlag
= *(pEid
->Octet
+ 8);
694 // AP Control of Client Transmit Power
695 //0. Check Aironet IE length, it must be 6
696 if (pEid
->Len
!= 0x06)
699 // Get cell power limit in dBm
700 if (NdisEqualMemory(pEid
->Octet
, CISCO_OUI
, 3) == 1)
701 *pAironetCellPowerLimit
= *(pEid
->Octet
+ 4);
704 // WPA2 & 802.11i RSN
706 // There is no OUI for version anymore, check the group cipher OUI before copying
707 if (RTMPEqualMemory(pEid
->Octet
+ 2, RSN_OUI
, 3))
709 // Copy to pVIE which will report to microsoft bssid list.
711 NdisMoveMemory(Ptr
+ *LengthVIE
, &pEid
->Eid
, pEid
->Len
+ 2);
712 *LengthVIE
+= (pEid
->Len
+ 2);
720 Length
= Length
+ 2 + pEid
->Len
; // Eid[1] + Len[1]+ content[Len]
721 pEid
= (PEID_STRUCT
)((UCHAR
*)pEid
+ 2 + pEid
->Len
);
724 // For some 11a AP. it did not have the channel EID, patch here
725 #ifdef CONFIG_STA_SUPPORT
726 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
728 UCHAR LatchRfChannel
= MsgChannel
;
729 if ((pAd
->LatchRfRegs
.Channel
> 14) && ((Sanity
& 0x4) == 0))
731 if (CtrlChannel
!= 0)
732 *pChannel
= CtrlChannel
;
734 *pChannel
= LatchRfChannel
;
738 #endif // CONFIG_STA_SUPPORT //
742 DBGPRINT(RT_DEBUG_WARN
, ("PeerBeaconAndProbeRspSanity - missing field, Sanity=0x%02x\n", Sanity
));
753 ==========================================================================
755 MLME message sanity check
757 TRUE if all parameters are OK, FALSE otherwise
758 ==========================================================================
760 BOOLEAN
MlmeScanReqSanity(
761 IN PRTMP_ADAPTER pAd
,
767 OUT UCHAR
*pScanType
)
769 MLME_SCAN_REQ_STRUCT
*Info
;
771 Info
= (MLME_SCAN_REQ_STRUCT
*)(Msg
);
772 *pBssType
= Info
->BssType
;
773 *pSsidLen
= Info
->SsidLen
;
774 NdisMoveMemory(Ssid
, Info
->Ssid
, *pSsidLen
);
775 *pScanType
= Info
->ScanType
;
777 if ((*pBssType
== BSS_INFRA
|| *pBssType
== BSS_ADHOC
|| *pBssType
== BSS_ANY
)
778 && (*pScanType
== SCAN_ACTIVE
|| *pScanType
== SCAN_PASSIVE
779 #ifdef CONFIG_STA_SUPPORT
780 || *pScanType
== SCAN_CISCO_PASSIVE
|| *pScanType
== SCAN_CISCO_ACTIVE
781 || *pScanType
== SCAN_CISCO_CHANNEL_LOAD
|| *pScanType
== SCAN_CISCO_NOISE
782 #endif // CONFIG_STA_SUPPORT //
789 DBGPRINT(RT_DEBUG_TRACE
, ("MlmeScanReqSanity fail - wrong BssType or ScanType\n"));
794 // IRQL = DISPATCH_LEVEL
796 IN PRTMP_ADAPTER pAd
,
801 for (i
= 0; i
< pAd
->ChannelListNum
; i
++)
803 if (channel
== pAd
->ChannelList
[i
].Channel
)
810 ==========================================================================
812 MLME message sanity check
814 TRUE if all parameters are OK, FALSE otherwise
816 IRQL = DISPATCH_LEVEL
818 ==========================================================================
820 BOOLEAN
PeerDeauthSanity(
821 IN PRTMP_ADAPTER pAd
,
827 PFRAME_802_11 pFrame
= (PFRAME_802_11
)Msg
;
829 COPY_MAC_ADDR(pAddr2
, pFrame
->Hdr
.Addr2
);
830 NdisMoveMemory(pReason
, &pFrame
->Octet
[0], 2);
836 ==========================================================================
838 MLME message sanity check
840 TRUE if all parameters are OK, FALSE otherwise
842 IRQL = DISPATCH_LEVEL
844 ==========================================================================
846 BOOLEAN
PeerAuthSanity(
847 IN PRTMP_ADAPTER pAd
,
856 PFRAME_802_11 pFrame
= (PFRAME_802_11
)Msg
;
858 COPY_MAC_ADDR(pAddr
, pFrame
->Hdr
.Addr2
);
859 NdisMoveMemory(pAlg
, &pFrame
->Octet
[0], 2);
860 NdisMoveMemory(pSeq
, &pFrame
->Octet
[2], 2);
861 NdisMoveMemory(pStatus
, &pFrame
->Octet
[4], 2);
863 if ((*pAlg
== Ndis802_11AuthModeOpen
)
866 if (*pSeq
== 1 || *pSeq
== 2)
872 DBGPRINT(RT_DEBUG_TRACE
, ("PeerAuthSanity fail - wrong Seg#\n"));
876 else if (*pAlg
== Ndis802_11AuthModeShared
)
878 if (*pSeq
== 1 || *pSeq
== 4)
882 else if (*pSeq
== 2 || *pSeq
== 3)
884 NdisMoveMemory(pChlgText
, &pFrame
->Octet
[8], CIPHER_TEXT_LEN
);
889 DBGPRINT(RT_DEBUG_TRACE
, ("PeerAuthSanity fail - wrong Seg#\n"));
895 DBGPRINT(RT_DEBUG_TRACE
, ("PeerAuthSanity fail - wrong algorithm\n"));
901 ==========================================================================
903 MLME message sanity check
905 TRUE if all parameters are OK, FALSE otherwise
906 ==========================================================================
908 BOOLEAN
MlmeAuthReqSanity(
909 IN PRTMP_ADAPTER pAd
,
916 MLME_AUTH_REQ_STRUCT
*pInfo
;
918 pInfo
= (MLME_AUTH_REQ_STRUCT
*)Msg
;
919 COPY_MAC_ADDR(pAddr
, pInfo
->Addr
);
920 *pTimeout
= pInfo
->Timeout
;
923 if (((*pAlg
== Ndis802_11AuthModeShared
) ||(*pAlg
== Ndis802_11AuthModeOpen
)
925 ((*pAddr
& 0x01) == 0))
931 DBGPRINT(RT_DEBUG_TRACE
, ("MlmeAuthReqSanity fail - wrong algorithm\n"));
937 ==========================================================================
939 MLME message sanity check
941 TRUE if all parameters are OK, FALSE otherwise
943 IRQL = DISPATCH_LEVEL
945 ==========================================================================
947 BOOLEAN
MlmeAssocReqSanity(
948 IN PRTMP_ADAPTER pAd
,
952 OUT USHORT
*pCapabilityInfo
,
954 OUT USHORT
*pListenIntv
)
956 MLME_ASSOC_REQ_STRUCT
*pInfo
;
958 pInfo
= (MLME_ASSOC_REQ_STRUCT
*)Msg
;
959 *pTimeout
= pInfo
->Timeout
; // timeout
960 COPY_MAC_ADDR(pApAddr
, pInfo
->Addr
); // AP address
961 *pCapabilityInfo
= pInfo
->CapabilityInfo
; // capability info
962 *pListenIntv
= pInfo
->ListenIntv
;
968 ==========================================================================
970 MLME message sanity check
972 TRUE if all parameters are OK, FALSE otherwise
974 IRQL = DISPATCH_LEVEL
976 ==========================================================================
978 BOOLEAN
PeerDisassocSanity(
979 IN PRTMP_ADAPTER pAd
,
985 PFRAME_802_11 pFrame
= (PFRAME_802_11
)Msg
;
987 COPY_MAC_ADDR(pAddr2
, pFrame
->Hdr
.Addr2
);
988 NdisMoveMemory(pReason
, &pFrame
->Octet
[0], 2);
994 ========================================================================
996 Sanity check NetworkType (11b, 11g or 11a)
999 pBss - Pointer to BSS table.
1002 Ndis802_11DS .......(11b)
1003 Ndis802_11OFDM24....(11g)
1004 Ndis802_11OFDM5.....(11a)
1006 IRQL = DISPATCH_LEVEL
1008 ========================================================================
1010 NDIS_802_11_NETWORK_TYPE
NetworkTypeInUseSanity(
1013 NDIS_802_11_NETWORK_TYPE NetWorkType
;
1016 NetWorkType
= Ndis802_11DS
;
1018 if (pBss
->Channel
<= 14)
1021 // First check support Rate.
1023 for (i
= 0; i
< pBss
->SupRateLen
; i
++)
1025 rate
= pBss
->SupRate
[i
] & 0x7f; // Mask out basic rate set bit
1026 if ((rate
== 2) || (rate
== 4) || (rate
== 11) || (rate
== 22))
1033 // Otherwise (even rate > 108) means Ndis802_11OFDM24
1035 NetWorkType
= Ndis802_11OFDM24
;
1041 // Second check Extend Rate.
1043 if (NetWorkType
!= Ndis802_11OFDM24
)
1045 for (i
= 0; i
< pBss
->ExtRateLen
; i
++)
1047 rate
= pBss
->SupRate
[i
] & 0x7f; // Mask out basic rate set bit
1048 if ((rate
== 2) || (rate
== 4) || (rate
== 11) || (rate
== 22))
1055 // Otherwise (even rate > 108) means Ndis802_11OFDM24
1057 NetWorkType
= Ndis802_11OFDM24
;
1065 NetWorkType
= Ndis802_11OFDM5
;
1068 if (pBss
->HtCapabilityLen
!= 0)
1070 if (NetWorkType
== Ndis802_11OFDM5
)
1071 NetWorkType
= Ndis802_11OFDM5_N
;
1073 NetWorkType
= Ndis802_11OFDM24_N
;
1080 ==========================================================================
1082 WPA message sanity check
1084 TRUE if all parameters are OK, FALSE otherwise
1085 ==========================================================================
1087 BOOLEAN
PeerWpaMessageSanity(
1088 IN PRTMP_ADAPTER pAd
,
1089 IN PEAPOL_PACKET pMsg
,
1092 IN MAC_TABLE_ENTRY
*pEntry
)
1094 UCHAR mic
[LEN_KEY_DESC_MIC
], digest
[80], KEYDATA
[MAX_LEN_OF_RSNIE
];
1095 BOOLEAN bReplayDiff
= FALSE
;
1096 BOOLEAN bWPA2
= FALSE
;
1097 KEY_INFO EapolKeyInfo
;
1098 UCHAR GroupKeyIndex
= 0;
1101 NdisZeroMemory(mic
, sizeof(mic
));
1102 NdisZeroMemory(digest
, sizeof(digest
));
1103 NdisZeroMemory(KEYDATA
, sizeof(KEYDATA
));
1104 NdisZeroMemory((PUCHAR
)&EapolKeyInfo
, sizeof(EapolKeyInfo
));
1106 NdisMoveMemory((PUCHAR
)&EapolKeyInfo
, (PUCHAR
)&pMsg
->KeyDesc
.KeyInfo
, sizeof(KEY_INFO
));
1108 *((USHORT
*)&EapolKeyInfo
) = cpu2le16(*((USHORT
*)&EapolKeyInfo
));
1110 // Choose WPA2 or not
1111 if ((pEntry
->AuthMode
== Ndis802_11AuthModeWPA2
) || (pEntry
->AuthMode
== Ndis802_11AuthModeWPA2PSK
))
1115 if ((MsgType
> EAPOL_GROUP_MSG_2
) || (MsgType
< EAPOL_PAIR_MSG_1
))
1117 DBGPRINT(RT_DEBUG_ERROR
, ("The message type is invalid(%d)! \n", MsgType
));
1121 // 1. Replay counter check
1122 if (MsgType
== EAPOL_PAIR_MSG_1
|| MsgType
== EAPOL_PAIR_MSG_3
|| MsgType
== EAPOL_GROUP_MSG_1
) // For supplicant
1124 // First validate replay counter, only accept message with larger replay counter.
1125 // Let equal pass, some AP start with all zero replay counter
1126 UCHAR ZeroReplay
[LEN_KEY_DESC_REPLAY
];
1128 NdisZeroMemory(ZeroReplay
, LEN_KEY_DESC_REPLAY
);
1129 if ((RTMPCompareMemory(pMsg
->KeyDesc
.ReplayCounter
, pEntry
->R_Counter
, LEN_KEY_DESC_REPLAY
) != 1) &&
1130 (RTMPCompareMemory(pMsg
->KeyDesc
.ReplayCounter
, ZeroReplay
, LEN_KEY_DESC_REPLAY
) != 0))
1135 else if (MsgType
== EAPOL_PAIR_MSG_2
|| MsgType
== EAPOL_PAIR_MSG_4
|| MsgType
== EAPOL_GROUP_MSG_2
) // For authenticator
1137 // check Replay Counter coresponds to MSG from authenticator, otherwise discard
1138 if (!NdisEqualMemory(pMsg
->KeyDesc
.ReplayCounter
, pEntry
->R_Counter
, LEN_KEY_DESC_REPLAY
))
1144 // Replay Counter different condition
1147 // send wireless event - for replay counter different
1148 if (pAd
->CommonCfg
.bWirelessEvent
)
1149 RTMPSendWirelessEvent(pAd
, IW_REPLAY_COUNTER_DIFF_EVENT_FLAG
, pEntry
->Addr
, pEntry
->apidx
, 0);
1151 if (MsgType
< EAPOL_GROUP_MSG_1
)
1153 DBGPRINT(RT_DEBUG_ERROR
, ("Replay Counter Different in pairwise msg %d of 4-way handshake!\n", MsgType
));
1157 DBGPRINT(RT_DEBUG_ERROR
, ("Replay Counter Different in group msg %d of 2-way handshake!\n", (MsgType
- EAPOL_PAIR_MSG_4
)));
1160 hex_dump("Receive replay counter ", pMsg
->KeyDesc
.ReplayCounter
, LEN_KEY_DESC_REPLAY
);
1161 hex_dump("Current replay counter ", pEntry
->R_Counter
, LEN_KEY_DESC_REPLAY
);
1165 // 2. Verify MIC except Pairwise Msg1
1166 if (MsgType
!= EAPOL_PAIR_MSG_1
)
1168 UCHAR rcvd_mic
[LEN_KEY_DESC_MIC
];
1170 // Record the received MIC for check later
1171 NdisMoveMemory(rcvd_mic
, pMsg
->KeyDesc
.KeyMic
, LEN_KEY_DESC_MIC
);
1172 NdisZeroMemory(pMsg
->KeyDesc
.KeyMic
, LEN_KEY_DESC_MIC
);
1174 if (pEntry
->WepStatus
== Ndis802_11Encryption2Enabled
) // TKIP
1176 hmac_md5(pEntry
->PTK
, LEN_EAP_MICK
, (PUCHAR
)pMsg
, MsgLen
, mic
);
1178 else if (pEntry
->WepStatus
== Ndis802_11Encryption3Enabled
) // AES
1180 HMAC_SHA1((PUCHAR
)pMsg
, MsgLen
, pEntry
->PTK
, LEN_EAP_MICK
, digest
);
1181 NdisMoveMemory(mic
, digest
, LEN_KEY_DESC_MIC
);
1184 if (!NdisEqualMemory(rcvd_mic
, mic
, LEN_KEY_DESC_MIC
))
1186 // send wireless event - for MIC different
1187 if (pAd
->CommonCfg
.bWirelessEvent
)
1188 RTMPSendWirelessEvent(pAd
, IW_MIC_DIFF_EVENT_FLAG
, pEntry
->Addr
, pEntry
->apidx
, 0);
1190 if (MsgType
< EAPOL_GROUP_MSG_1
)
1192 DBGPRINT(RT_DEBUG_ERROR
, ("MIC Different in pairwise msg %d of 4-way handshake!\n", MsgType
));
1196 DBGPRINT(RT_DEBUG_ERROR
, ("MIC Different in group msg %d of 2-way handshake!\n", (MsgType
- EAPOL_PAIR_MSG_4
)));
1199 hex_dump("Received MIC", rcvd_mic
, LEN_KEY_DESC_MIC
);
1200 hex_dump("Desired MIC", mic
, LEN_KEY_DESC_MIC
);
1206 // Extract the context of the Key Data field if it exist
1207 // The field in pairwise_msg_2_WPA1(WPA2) & pairwise_msg_3_WPA1 is un-encrypted.
1208 // The field in group_msg_1_WPA1(WPA2) & pairwise_msg_3_WPA2 is encrypted.
1209 if (pMsg
->KeyDesc
.KeyDataLen
[1] > 0)
1211 // Decrypt this field
1212 if ((MsgType
== EAPOL_PAIR_MSG_3
&& bWPA2
) || (MsgType
== EAPOL_GROUP_MSG_1
))
1214 if(pEntry
->WepStatus
== Ndis802_11Encryption3Enabled
)
1217 AES_GTK_KEY_UNWRAP(&pEntry
->PTK
[16], KEYDATA
, pMsg
->KeyDesc
.KeyDataLen
[1],pMsg
->KeyDesc
.KeyData
);
1224 // Construct 32 bytes RC4 Key
1225 NdisMoveMemory(Key
, pMsg
->KeyDesc
.KeyIv
, 16);
1226 NdisMoveMemory(&Key
[16], &pEntry
->PTK
[16], 16);
1227 ARCFOUR_INIT(&pAd
->PrivateInfo
.WEPCONTEXT
, Key
, 32);
1228 //discard first 256 bytes
1229 for(i
= 0; i
< 256; i
++)
1230 ARCFOUR_BYTE(&pAd
->PrivateInfo
.WEPCONTEXT
);
1231 // Decrypt GTK. Becareful, there is no ICV to check the result is correct or not
1232 ARCFOUR_DECRYPT(&pAd
->PrivateInfo
.WEPCONTEXT
, KEYDATA
, pMsg
->KeyDesc
.KeyData
, pMsg
->KeyDesc
.KeyDataLen
[1]);
1235 if (!bWPA2
&& (MsgType
== EAPOL_GROUP_MSG_1
))
1236 GroupKeyIndex
= EapolKeyInfo
.KeyIndex
;
1239 else if ((MsgType
== EAPOL_PAIR_MSG_2
) || (MsgType
== EAPOL_PAIR_MSG_3
&& !bWPA2
))
1241 NdisMoveMemory(KEYDATA
, pMsg
->KeyDesc
.KeyData
, pMsg
->KeyDesc
.KeyDataLen
[1]);
1249 // Parse Key Data field to
1250 // 1. verify RSN IE for pairwise_msg_2_WPA1(WPA2) ,pairwise_msg_3_WPA1(WPA2)
1251 // 2. verify KDE format for pairwise_msg_3_WPA2, group_msg_1_WPA2
1252 // 3. update shared key for pairwise_msg_3_WPA2, group_msg_1_WPA1(WPA2)
1253 if (!RTMPParseEapolKeyData(pAd
, KEYDATA
, pMsg
->KeyDesc
.KeyDataLen
[1], GroupKeyIndex
, MsgType
, bWPA2
, pEntry
))