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
38 #include "../rt_config.h"
41 extern UCHAR CISCO_OUI
[];
43 extern UCHAR WPA_OUI
[];
44 extern UCHAR RSN_OUI
[];
45 extern UCHAR WME_INFO_ELEM
[];
46 extern UCHAR WME_PARM_ELEM
[];
47 extern UCHAR Ccx2QosInfo
[];
48 extern UCHAR RALINK_OUI
[];
49 extern UCHAR BROADCOM_OUI
[];
50 extern UCHAR WPS_OUI
[];
53 ==========================================================================
55 MLME message sanity check
57 TRUE if all parameters are OK, FALSE otherwise
61 ==========================================================================
63 BOOLEAN
MlmeAddBAReqSanity(
69 PMLME_ADDBA_REQ_STRUCT pInfo
;
71 pInfo
= (MLME_ADDBA_REQ_STRUCT
*)Msg
;
73 if ((MsgLen
!= sizeof(MLME_ADDBA_REQ_STRUCT
)))
75 DBGPRINT(RT_DEBUG_TRACE
, ("MlmeAddBAReqSanity fail - message lenght not correct.\n"));
79 if ((pInfo
->Wcid
>= MAX_LEN_OF_MAC_TABLE
))
81 DBGPRINT(RT_DEBUG_TRACE
, ("MlmeAddBAReqSanity fail - The peer Mac is not associated yet.\n"));
86 if ((pInfo->BaBufSize > MAX_RX_REORDERBUF) || (pInfo->BaBufSize < 2))
88 DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - Rx Reordering buffer too big or too small\n"));
93 if ((pInfo
->pAddr
[0]&0x01) == 0x01)
95 DBGPRINT(RT_DEBUG_TRACE
, ("MlmeAddBAReqSanity fail - broadcast address not support BA\n"));
103 ==========================================================================
105 MLME message sanity check
107 TRUE if all parameters are OK, FALSE otherwise
109 IRQL = DISPATCH_LEVEL
111 ==========================================================================
113 BOOLEAN
MlmeDelBAReqSanity(
114 IN PRTMP_ADAPTER pAd
,
118 MLME_DELBA_REQ_STRUCT
*pInfo
;
119 pInfo
= (MLME_DELBA_REQ_STRUCT
*)Msg
;
121 if ((MsgLen
!= sizeof(MLME_DELBA_REQ_STRUCT
)))
123 DBGPRINT(RT_DEBUG_ERROR
, ("MlmeDelBAReqSanity fail - message lenght not correct.\n"));
127 if ((pInfo
->Wcid
>= MAX_LEN_OF_MAC_TABLE
))
129 DBGPRINT(RT_DEBUG_ERROR
, ("MlmeDelBAReqSanity fail - The peer Mac is not associated yet.\n"));
133 if ((pInfo
->TID
& 0xf0))
135 DBGPRINT(RT_DEBUG_ERROR
, ("MlmeDelBAReqSanity fail - The peer TID is incorrect.\n"));
139 if (NdisEqualMemory(pAd
->MacTab
.Content
[pInfo
->Wcid
].Addr
, pInfo
->Addr
, MAC_ADDR_LEN
) == 0)
141 DBGPRINT(RT_DEBUG_ERROR
, ("MlmeDelBAReqSanity fail - the peer addr dosen't exist.\n"));
148 BOOLEAN
PeerAddBAReqActionSanity(
149 IN PRTMP_ADAPTER pAd
,
154 PFRAME_802_11 pFrame
= (PFRAME_802_11
)pMsg
;
155 PFRAME_ADDBA_REQ pAddFrame
;
156 pAddFrame
= (PFRAME_ADDBA_REQ
)(pMsg
);
157 if (MsgLen
< (sizeof(FRAME_ADDBA_REQ
)))
159 DBGPRINT(RT_DEBUG_ERROR
,("PeerAddBAReqActionSanity: ADDBA Request frame length size = %ld incorrect\n", MsgLen
));
162 // we support immediate BA.
163 #ifdef UNALIGNMENT_SUPPORT
167 NdisMoveMemory((PUCHAR
)(&tmpBaParm
), (PUCHAR
)(&pAddFrame
->BaParm
), sizeof(BA_PARM
));
168 *(USHORT
*)(&tmpBaParm
) = cpu2le16(*(USHORT
*)(&tmpBaParm
));
169 NdisMoveMemory((PUCHAR
)(&pAddFrame
->BaParm
), (PUCHAR
)(&tmpBaParm
), sizeof(BA_PARM
));
172 *(USHORT
*)(&pAddFrame
->BaParm
) = cpu2le16(*(USHORT
*)(&pAddFrame
->BaParm
));
174 pAddFrame
->TimeOutValue
= cpu2le16(pAddFrame
->TimeOutValue
);
175 pAddFrame
->BaStartSeq
.word
= cpu2le16(pAddFrame
->BaStartSeq
.word
);
177 if (pAddFrame
->BaParm
.BAPolicy
!= IMMED_BA
)
179 DBGPRINT(RT_DEBUG_ERROR
,("PeerAddBAReqActionSanity: ADDBA Request Ba Policy[%d] not support\n", pAddFrame
->BaParm
.BAPolicy
));
180 DBGPRINT(RT_DEBUG_ERROR
,("ADDBA Request. tid=%x, Bufsize=%x, AMSDUSupported=%x \n", pAddFrame
->BaParm
.TID
, pAddFrame
->BaParm
.BufSize
, pAddFrame
->BaParm
.AMSDUSupported
));
184 // we support immediate BA.
185 if (pAddFrame
->BaParm
.TID
&0xfff0)
187 DBGPRINT(RT_DEBUG_ERROR
,("PeerAddBAReqActionSanity: ADDBA Request incorrect TID = %d\n", pAddFrame
->BaParm
.TID
));
190 COPY_MAC_ADDR(pAddr2
, pFrame
->Hdr
.Addr2
);
194 BOOLEAN
PeerAddBARspActionSanity(
195 IN PRTMP_ADAPTER pAd
,
199 //PFRAME_802_11 pFrame = (PFRAME_802_11)pMsg;
200 PFRAME_ADDBA_RSP pAddFrame
;
202 pAddFrame
= (PFRAME_ADDBA_RSP
)(pMsg
);
203 if (MsgLen
< (sizeof(FRAME_ADDBA_RSP
)))
205 DBGPRINT(RT_DEBUG_ERROR
,("PeerAddBARspActionSanity: ADDBA Response frame length size = %ld incorrect\n", MsgLen
));
208 // we support immediate BA.
209 #ifdef UNALIGNMENT_SUPPORT
213 NdisMoveMemory((PUCHAR
)(&tmpBaParm
), (PUCHAR
)(&pAddFrame
->BaParm
), sizeof(BA_PARM
));
214 *(USHORT
*)(&tmpBaParm
) = cpu2le16(*(USHORT
*)(&tmpBaParm
));
215 NdisMoveMemory((PUCHAR
)(&pAddFrame
->BaParm
), (PUCHAR
)(&tmpBaParm
), sizeof(BA_PARM
));
218 *(USHORT
*)(&pAddFrame
->BaParm
) = cpu2le16(*(USHORT
*)(&pAddFrame
->BaParm
));
220 pAddFrame
->StatusCode
= cpu2le16(pAddFrame
->StatusCode
);
221 pAddFrame
->TimeOutValue
= cpu2le16(pAddFrame
->TimeOutValue
);
223 if (pAddFrame
->BaParm
.BAPolicy
!= IMMED_BA
)
225 DBGPRINT(RT_DEBUG_ERROR
,("PeerAddBAReqActionSanity: ADDBA Response Ba Policy[%d] not support\n", pAddFrame
->BaParm
.BAPolicy
));
229 // we support immediate BA.
230 if (pAddFrame
->BaParm
.TID
&0xfff0)
232 DBGPRINT(RT_DEBUG_ERROR
,("PeerAddBARspActionSanity: ADDBA Response incorrect TID = %d\n", pAddFrame
->BaParm
.TID
));
239 BOOLEAN
PeerDelBAActionSanity(
240 IN PRTMP_ADAPTER pAd
,
245 //PFRAME_802_11 pFrame = (PFRAME_802_11)pMsg;
246 PFRAME_DELBA_REQ pDelFrame
;
247 if (MsgLen
!= (sizeof(FRAME_DELBA_REQ
)))
250 if (Wcid
>= MAX_LEN_OF_MAC_TABLE
)
253 pDelFrame
= (PFRAME_DELBA_REQ
)(pMsg
);
255 *(USHORT
*)(&pDelFrame
->DelbaParm
) = cpu2le16(*(USHORT
*)(&pDelFrame
->DelbaParm
));
256 pDelFrame
->ReasonCode
= cpu2le16(pDelFrame
->ReasonCode
);
258 if (pDelFrame
->DelbaParm
.TID
&0xfff0)
265 ==========================================================================
267 MLME message sanity check
269 TRUE if all parameters are OK, FALSE otherwise
271 IRQL = DISPATCH_LEVEL
273 ==========================================================================
275 BOOLEAN
PeerBeaconAndProbeRspSanity(
276 IN PRTMP_ADAPTER pAd
,
285 OUT USHORT
*pBeaconPeriod
,
287 OUT UCHAR
*pNewChannel
,
288 OUT LARGE_INTEGER
*pTimestamp
,
289 OUT CF_PARM
*pCfParm
,
290 OUT USHORT
*pAtimWin
,
291 OUT USHORT
*pCapabilityInfo
,
293 OUT UCHAR
*pDtimCount
,
294 OUT UCHAR
*pDtimPeriod
,
295 OUT UCHAR
*pBcastFlag
,
296 OUT UCHAR
*pMessageToMe
,
298 OUT UCHAR
*pSupRateLen
,
300 OUT UCHAR
*pExtRateLen
,
301 OUT UCHAR
*pCkipFlag
,
302 OUT UCHAR
*pAironetCellPowerLimit
,
303 OUT PEDCA_PARM pEdcaParm
,
304 OUT PQBSS_LOAD_PARM pQbssLoad
,
305 OUT PQOS_CAPABILITY_PARM pQosCapability
,
306 OUT ULONG
*pRalinkIe
,
307 OUT UCHAR
*pHtCapabilityLen
,
308 #ifdef CONFIG_STA_SUPPORT
309 OUT UCHAR
*pPreNHtCapabilityLen
,
310 #endif // CONFIG_STA_SUPPORT //
311 OUT HT_CAPABILITY_IE
*pHtCapability
,
312 OUT UCHAR
*AddHtInfoLen
,
313 OUT ADD_HT_INFO_IE
*AddHtInfo
,
314 OUT UCHAR
*NewExtChannelOffset
, // Ht extension channel offset(above or below)
315 OUT USHORT
*LengthVIE
,
316 OUT PNDIS_802_11_VARIABLE_IEs pVIE
)
319 #ifdef CONFIG_STA_SUPPORT
321 #endif // CONFIG_STA_SUPPORT //
322 PFRAME_802_11 pFrame
;
326 //UCHAR ECWMin, ECWMax;
327 //MAC_CSR9_STRUC Csr9;
330 // For some 11a AP which didn't have DS_IE, we use two conditions to decide the channel
331 // 1. If the AP is 11n enabled, then check the control channel.
332 // 2. If the AP didn't have any info about channel, use the channel we received this frame as the channel. (May inaccuracy!!)
333 UCHAR CtrlChannel
= 0;
335 // Add for 3 necessary EID field check
345 *pCkipFlag
= 0; // Default of CkipFlag is 0
346 *pAironetCellPowerLimit
= 0xFF; // Default of AironetCellPowerLimit is 0xFF
347 *LengthVIE
= 0; // Set the length of VIE to init value 0
348 *pHtCapabilityLen
= 0; // Set the length of VIE to init value 0
349 #ifdef CONFIG_STA_SUPPORT
350 if (pAd
->OpMode
== OPMODE_STA
)
351 *pPreNHtCapabilityLen
= 0; // Set the length of VIE to init value 0
352 #endif // CONFIG_STA_SUPPORT //
353 *AddHtInfoLen
= 0; // Set the length of VIE to init value 0
356 *NewExtChannelOffset
= 0xff; //Default 0xff means no such IE
357 pCfParm
->bValid
= FALSE
; // default: no IE_CF found
358 pQbssLoad
->bValid
= FALSE
; // default: no IE_QBSS_LOAD found
359 pEdcaParm
->bValid
= FALSE
; // default: no IE_EDCA_PARAMETER found
360 pQosCapability
->bValid
= FALSE
; // default: no IE_QOS_CAPABILITY found
362 pFrame
= (PFRAME_802_11
)Msg
;
364 // get subtype from header
365 SubType
= (UCHAR
)pFrame
->Hdr
.FC
.SubType
;
367 // get Addr2 and BSSID from header
368 COPY_MAC_ADDR(pAddr2
, pFrame
->Hdr
.Addr2
);
369 COPY_MAC_ADDR(pBssid
, pFrame
->Hdr
.Addr3
);
371 // hex_dump("Beacon", Msg, MsgLen);
374 Length
+= LENGTH_802_11
;
376 // get timestamp from payload and advance the pointer
377 NdisMoveMemory(pTimestamp
, Ptr
, TIMESTAMP_LEN
);
379 pTimestamp
->u
.LowPart
= cpu2le32(pTimestamp
->u
.LowPart
);
380 pTimestamp
->u
.HighPart
= cpu2le32(pTimestamp
->u
.HighPart
);
382 Ptr
+= TIMESTAMP_LEN
;
383 Length
+= TIMESTAMP_LEN
;
385 // get beacon interval from payload and advance the pointer
386 NdisMoveMemory(pBeaconPeriod
, Ptr
, 2);
390 // get capability info from payload and advance the pointer
391 NdisMoveMemory(pCapabilityInfo
, Ptr
, 2);
395 if (CAP_IS_ESS_ON(*pCapabilityInfo
))
396 *pBssType
= BSS_INFRA
;
398 *pBssType
= BSS_ADHOC
;
400 pEid
= (PEID_STRUCT
) Ptr
;
402 // get variable fields from payload and advance the pointer
403 while ((Length
+ 2 + pEid
->Len
) <= MsgLen
)
406 // Secure copy VIE to VarIE[MAX_VIE_LEN] didn't overflow.
408 if ((*LengthVIE
+ pEid
->Len
+ 2) >= MAX_VIE_LEN
)
410 DBGPRINT(RT_DEBUG_WARN
, ("PeerBeaconAndProbeRspSanity - Variable IEs out of resource [len(=%d) > MAX_VIE_LEN(=%d)]\n",
411 (*LengthVIE
+ pEid
->Len
+ 2), MAX_VIE_LEN
));
418 // Already has one SSID EID in this beacon, ignore the second one
421 if(pEid
->Len
<= MAX_LEN_OF_SSID
)
423 NdisMoveMemory(Ssid
, pEid
->Octet
, pEid
->Len
);
424 *pSsidLen
= pEid
->Len
;
429 DBGPRINT(RT_DEBUG_TRACE
, ("PeerBeaconAndProbeRspSanity - wrong IE_SSID (len=%d)\n",pEid
->Len
));
435 if(pEid
->Len
<= MAX_LEN_OF_SUPPORTED_RATES
)
438 NdisMoveMemory(SupRate
, pEid
->Octet
, pEid
->Len
);
439 *pSupRateLen
= pEid
->Len
;
441 // TODO: 2004-09-14 not a good design here, cause it exclude extra rates
442 // from ScanTab. We should report as is. And filter out unsupported
444 // Check against the supported rates
445 // RTMPCheckRates(pAd, SupRate, pSupRateLen);
449 DBGPRINT(RT_DEBUG_TRACE
, ("PeerBeaconAndProbeRspSanity - wrong IE_SUPP_RATES (len=%d)\n",pEid
->Len
));
455 if (pEid
->Len
>= SIZE_HT_CAP_IE
) //Note: allow extension.!!
457 NdisMoveMemory(pHtCapability
, pEid
->Octet
, sizeof(HT_CAPABILITY_IE
));
458 *pHtCapabilityLen
= SIZE_HT_CAP_IE
; // Nnow we only support 26 bytes.
460 *(USHORT
*)(&pHtCapability
->HtCapInfo
) = cpu2le16(*(USHORT
*)(&pHtCapability
->HtCapInfo
));
461 #ifdef UNALIGNMENT_SUPPORT
463 EXT_HT_CAP_INFO extHtCapInfo
;
464 NdisMoveMemory((PUCHAR
)(&extHtCapInfo
), (PUCHAR
)(&pHtCapability
->ExtHtCapInfo
), sizeof(EXT_HT_CAP_INFO
));
465 *(USHORT
*)(&extHtCapInfo
) = cpu2le16(*(USHORT
*)(&extHtCapInfo
));
466 NdisMoveMemory((PUCHAR
)(&pHtCapability
->ExtHtCapInfo
), (PUCHAR
)(&extHtCapInfo
), sizeof(EXT_HT_CAP_INFO
));
469 *(USHORT
*)(&pHtCapability
->ExtHtCapInfo
) = cpu2le16(*(USHORT
*)(&pHtCapability
->ExtHtCapInfo
));
470 #endif // UNALIGNMENT_SUPPORT //
472 #ifdef CONFIG_STA_SUPPORT
473 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
475 *pPreNHtCapabilityLen
= 0; // Now we only support 26 bytes.
478 NdisMoveMemory(Ptr
+ *LengthVIE
, &pEid
->Eid
, pEid
->Len
+ 2);
479 *LengthVIE
+= (pEid
->Len
+ 2);
481 #endif // CONFIG_STA_SUPPORT //
485 DBGPRINT(RT_DEBUG_WARN
, ("PeerBeaconAndProbeRspSanity - wrong IE_HT_CAP. pEid->Len = %d\n", pEid
->Len
));
490 if (pEid
->Len
>= sizeof(ADD_HT_INFO_IE
))
492 // This IE allows extension, but we can ignore extra bytes beyond our knowledge , so only
493 // copy first sizeof(ADD_HT_INFO_IE)
494 NdisMoveMemory(AddHtInfo
, pEid
->Octet
, sizeof(ADD_HT_INFO_IE
));
495 *AddHtInfoLen
= SIZE_ADD_HT_INFO_IE
;
497 CtrlChannel
= AddHtInfo
->ControlChan
;
499 *(USHORT
*)(&AddHtInfo
->AddHtInfo2
) = cpu2le16(*(USHORT
*)(&AddHtInfo
->AddHtInfo2
));
500 *(USHORT
*)(&AddHtInfo
->AddHtInfo3
) = cpu2le16(*(USHORT
*)(&AddHtInfo
->AddHtInfo3
));
502 #ifdef CONFIG_STA_SUPPORT
503 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
506 NdisMoveMemory(Ptr
+ *LengthVIE
, &pEid
->Eid
, pEid
->Len
+ 2);
507 *LengthVIE
+= (pEid
->Len
+ 2);
509 #endif // CONFIG_STA_SUPPORT //
513 DBGPRINT(RT_DEBUG_WARN
, ("PeerBeaconAndProbeRspSanity - wrong IE_ADD_HT. \n"));
517 case IE_SECONDARY_CH_OFFSET
:
520 *NewExtChannelOffset
= pEid
->Octet
[0];
524 DBGPRINT(RT_DEBUG_WARN
, ("PeerBeaconAndProbeRspSanity - wrong IE_SECONDARY_CH_OFFSET. \n"));
529 DBGPRINT(RT_DEBUG_TRACE
, ("PeerBeaconAndProbeRspSanity(IE_FH_PARM) \n"));
535 *pChannel
= *pEid
->Octet
;
536 #ifdef CONFIG_STA_SUPPORT
537 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
539 if (ChannelSanity(pAd
, *pChannel
) == 0)
545 #endif // CONFIG_STA_SUPPORT //
550 DBGPRINT(RT_DEBUG_TRACE
, ("PeerBeaconAndProbeRspSanity - wrong IE_DS_PARM (len=%d)\n",pEid
->Len
));
558 pCfParm
->bValid
= TRUE
;
559 pCfParm
->CfpCount
= pEid
->Octet
[0];
560 pCfParm
->CfpPeriod
= pEid
->Octet
[1];
561 pCfParm
->CfpMaxDuration
= pEid
->Octet
[2] + 256 * pEid
->Octet
[3];
562 pCfParm
->CfpDurRemaining
= pEid
->Octet
[4] + 256 * pEid
->Octet
[5];
566 DBGPRINT(RT_DEBUG_TRACE
, ("PeerBeaconAndProbeRspSanity - wrong IE_CF_PARM\n"));
574 NdisMoveMemory(pAtimWin
, pEid
->Octet
, pEid
->Len
);
578 DBGPRINT(RT_DEBUG_TRACE
, ("PeerBeaconAndProbeRspSanity - wrong IE_IBSS_PARM\n"));
583 #ifdef CONFIG_STA_SUPPORT
585 if(INFRA_ON(pAd
) && SubType
== SUBTYPE_BEACON
)
587 GetTimBit((PCHAR
)pEid
, pAd
->StaActive
.Aid
, &TimLen
, pBcastFlag
, pDtimCount
, pDtimPeriod
, pMessageToMe
);
590 #endif // CONFIG_STA_SUPPORT //
591 case IE_CHANNEL_SWITCH_ANNOUNCEMENT
:
594 *pNewChannel
= pEid
->Octet
[1]; //extract new channel number
599 // CCX v2 has the same IE, we need to parse that too
600 // Wifi WMM use the same IE vale, need to parse that too
602 case IE_VENDOR_SPECIFIC
:
603 // Check Broadcom/Atheros 802.11n OUI version, for HT Capability IE.
604 // This HT IE is before IEEE draft set HT IE value.2006-09-28 by Jan.
605 /*if (NdisEqualMemory(pEid->Octet, BROADCOM_OUI, 3) && (pEid->Len >= 4))
607 if ((pEid->Octet[3] == OUI_BROADCOM_HT) && (pEid->Len >= 30))
610 NdisMoveMemory(pHtCapability, &pEid->Octet[4], sizeof(HT_CAPABILITY_IE));
611 *pHtCapabilityLen = SIZE_HT_CAP_IE; // Nnow we only support 26 bytes.
614 if ((pEid->Octet[3] == OUI_BROADCOM_HT) && (pEid->Len >= 26))
617 NdisMoveMemory(AddHtInfo, &pEid->Octet[4], sizeof(ADD_HT_INFO_IE));
618 *AddHtInfoLen = SIZE_ADD_HT_INFO_IE; // Nnow we only support 26 bytes.
623 // Check the OUI version, filter out non-standard usage
624 if (NdisEqualMemory(pEid
->Octet
, RALINK_OUI
, 3) && (pEid
->Len
== 7))
626 //*pRalinkIe = pEid->Octet[3];
627 if (pEid
->Octet
[3] != 0)
628 *pRalinkIe
= pEid
->Octet
[3];
630 *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.
632 #ifdef CONFIG_STA_SUPPORT
633 #ifdef DOT11_N_SUPPORT
634 // This HT IE is before IEEE draft set HT IE value.2006-09-28 by Jan.
636 // Other vendors had production before IE_HT_CAP value is assigned. To backward support those old-firmware AP,
637 // Check broadcom-defiend pre-802.11nD1.0 OUI for HT related IE, including HT Capatilities IE and HT Information IE
638 else if ((*pHtCapabilityLen
== 0) && NdisEqualMemory(pEid
->Octet
, PRE_N_HT_OUI
, 3) && (pEid
->Len
>= 4) && (pAd
->OpMode
== OPMODE_STA
))
640 if ((pEid
->Octet
[3] == OUI_PREN_HT_CAP
) && (pEid
->Len
>= 30) && (*pHtCapabilityLen
== 0))
642 NdisMoveMemory(pHtCapability
, &pEid
->Octet
[4], sizeof(HT_CAPABILITY_IE
));
643 *pPreNHtCapabilityLen
= SIZE_HT_CAP_IE
;
646 if ((pEid
->Octet
[3] == OUI_PREN_ADD_HT
) && (pEid
->Len
>= 26))
648 NdisMoveMemory(AddHtInfo
, &pEid
->Octet
[4], sizeof(ADD_HT_INFO_IE
));
649 *AddHtInfoLen
= SIZE_ADD_HT_INFO_IE
;
652 #endif // DOT11_N_SUPPORT //
653 #endif // CONFIG_STA_SUPPORT //
654 else if (NdisEqualMemory(pEid
->Octet
, WPA_OUI
, 4))
656 // Copy to pVIE which will report to microsoft bssid list.
658 NdisMoveMemory(Ptr
+ *LengthVIE
, &pEid
->Eid
, pEid
->Len
+ 2);
659 *LengthVIE
+= (pEid
->Len
+ 2);
661 else if (NdisEqualMemory(pEid
->Octet
, WME_PARM_ELEM
, 6) && (pEid
->Len
== 24))
666 // parsing EDCA parameters
667 pEdcaParm
->bValid
= TRUE
;
668 pEdcaParm
->bQAck
= FALSE
; // pEid->Octet[0] & 0x10;
669 pEdcaParm
->bQueueRequest
= FALSE
; // pEid->Octet[0] & 0x20;
670 pEdcaParm
->bTxopRequest
= FALSE
; // pEid->Octet[0] & 0x40;
671 pEdcaParm
->EdcaUpdateCount
= pEid
->Octet
[6] & 0x0f;
672 pEdcaParm
->bAPSDCapable
= (pEid
->Octet
[6] & 0x80) ? 1 : 0;
673 ptr
= &pEid
->Octet
[8];
676 UCHAR aci
= (*ptr
& 0x60) >> 5; // b5~6 is AC INDEX
677 pEdcaParm
->bACM
[aci
] = (((*ptr
) & 0x10) == 0x10); // b5 is ACM
678 pEdcaParm
->Aifsn
[aci
] = (*ptr
) & 0x0f; // b0~3 is AIFSN
679 pEdcaParm
->Cwmin
[aci
] = *(ptr
+1) & 0x0f; // b0~4 is Cwmin
680 pEdcaParm
->Cwmax
[aci
] = *(ptr
+1) >> 4; // b5~8 is Cwmax
681 pEdcaParm
->Txop
[aci
] = *(ptr
+2) + 256 * (*(ptr
+3)); // in unit of 32-us
682 ptr
+= 4; // point to next AC
685 else if (NdisEqualMemory(pEid
->Octet
, WME_INFO_ELEM
, 6) && (pEid
->Len
== 7))
687 // parsing EDCA parameters
688 pEdcaParm
->bValid
= TRUE
;
689 pEdcaParm
->bQAck
= FALSE
; // pEid->Octet[0] & 0x10;
690 pEdcaParm
->bQueueRequest
= FALSE
; // pEid->Octet[0] & 0x20;
691 pEdcaParm
->bTxopRequest
= FALSE
; // pEid->Octet[0] & 0x40;
692 pEdcaParm
->EdcaUpdateCount
= pEid
->Octet
[6] & 0x0f;
693 pEdcaParm
->bAPSDCapable
= (pEid
->Octet
[6] & 0x80) ? 1 : 0;
695 // use default EDCA parameter
696 pEdcaParm
->bACM
[QID_AC_BE
] = 0;
697 pEdcaParm
->Aifsn
[QID_AC_BE
] = 3;
698 pEdcaParm
->Cwmin
[QID_AC_BE
] = CW_MIN_IN_BITS
;
699 pEdcaParm
->Cwmax
[QID_AC_BE
] = CW_MAX_IN_BITS
;
700 pEdcaParm
->Txop
[QID_AC_BE
] = 0;
702 pEdcaParm
->bACM
[QID_AC_BK
] = 0;
703 pEdcaParm
->Aifsn
[QID_AC_BK
] = 7;
704 pEdcaParm
->Cwmin
[QID_AC_BK
] = CW_MIN_IN_BITS
;
705 pEdcaParm
->Cwmax
[QID_AC_BK
] = CW_MAX_IN_BITS
;
706 pEdcaParm
->Txop
[QID_AC_BK
] = 0;
708 pEdcaParm
->bACM
[QID_AC_VI
] = 0;
709 pEdcaParm
->Aifsn
[QID_AC_VI
] = 2;
710 pEdcaParm
->Cwmin
[QID_AC_VI
] = CW_MIN_IN_BITS
-1;
711 pEdcaParm
->Cwmax
[QID_AC_VI
] = CW_MAX_IN_BITS
;
712 pEdcaParm
->Txop
[QID_AC_VI
] = 96; // AC_VI: 96*32us ~= 3ms
714 pEdcaParm
->bACM
[QID_AC_VO
] = 0;
715 pEdcaParm
->Aifsn
[QID_AC_VO
] = 2;
716 pEdcaParm
->Cwmin
[QID_AC_VO
] = CW_MIN_IN_BITS
-2;
717 pEdcaParm
->Cwmax
[QID_AC_VO
] = CW_MAX_IN_BITS
-1;
718 pEdcaParm
->Txop
[QID_AC_VO
] = 48; // AC_VO: 48*32us ~= 1.5ms
720 #ifdef CONFIG_STA_SUPPORT
721 #endif // CONFIG_STA_SUPPORT //
726 case IE_EXT_SUPP_RATES
:
727 if (pEid
->Len
<= MAX_LEN_OF_SUPPORTED_RATES
)
729 NdisMoveMemory(ExtRate
, pEid
->Octet
, pEid
->Len
);
730 *pExtRateLen
= pEid
->Len
;
732 // TODO: 2004-09-14 not a good design here, cause it exclude extra rates
733 // from ScanTab. We should report as is. And filter out unsupported
735 // Check against the supported rates
736 // RTMPCheckRates(pAd, ExtRate, pExtRateLen);
743 *pErp
= (UCHAR
)pEid
->Octet
[0];
747 case IE_AIRONET_CKIP
:
748 // 0. Check Aironet IE length, it must be larger or equal to 28
749 // Cisco AP350 used length as 28
750 // Cisco AP12XX used length as 30
751 if (pEid
->Len
< (CKIP_NEGOTIATION_LENGTH
- 2))
754 // 1. Copy CKIP flag byte to buffer for process
755 *pCkipFlag
= *(pEid
->Octet
+ 8);
759 // AP Control of Client Transmit Power
760 //0. Check Aironet IE length, it must be 6
761 if (pEid
->Len
!= 0x06)
764 // Get cell power limit in dBm
765 if (NdisEqualMemory(pEid
->Octet
, CISCO_OUI
, 3) == 1)
766 *pAironetCellPowerLimit
= *(pEid
->Octet
+ 4);
769 // WPA2 & 802.11i RSN
771 // There is no OUI for version anymore, check the group cipher OUI before copying
772 if (RTMPEqualMemory(pEid
->Octet
+ 2, RSN_OUI
, 3))
774 // Copy to pVIE which will report to microsoft bssid list.
776 NdisMoveMemory(Ptr
+ *LengthVIE
, &pEid
->Eid
, pEid
->Len
+ 2);
777 *LengthVIE
+= (pEid
->Len
+ 2);
780 #ifdef CONFIG_STA_SUPPORT
781 #ifdef EXT_BUILD_CHANNEL_LIST
784 NdisMoveMemory(Ptr
+ *LengthVIE
, &pEid
->Eid
, pEid
->Len
+ 2);
785 *LengthVIE
+= (pEid
->Len
+ 2);
787 #endif // EXT_BUILD_CHANNEL_LIST //
788 #endif // CONFIG_STA_SUPPORT //
795 Length
= Length
+ 2 + pEid
->Len
; // Eid[1] + Len[1]+ content[Len]
796 pEid
= (PEID_STRUCT
)((UCHAR
*)pEid
+ 2 + pEid
->Len
);
799 // For some 11a AP. it did not have the channel EID, patch here
800 #ifdef CONFIG_STA_SUPPORT
801 IF_DEV_CONFIG_OPMODE_ON_STA(pAd
)
803 UCHAR LatchRfChannel
= MsgChannel
;
804 if ((pAd
->LatchRfRegs
.Channel
> 14) && ((Sanity
& 0x4) == 0))
806 if (CtrlChannel
!= 0)
807 *pChannel
= CtrlChannel
;
809 *pChannel
= LatchRfChannel
;
813 #endif // CONFIG_STA_SUPPORT //
817 DBGPRINT(RT_DEBUG_LOUD
, ("PeerBeaconAndProbeRspSanity - missing field, Sanity=0x%02x\n", Sanity
));
829 ==========================================================================
831 MLME message sanity check for some IE addressed in 802.11n d3.03.
833 TRUE if all parameters are OK, FALSE otherwise
835 IRQL = DISPATCH_LEVEL
837 ==========================================================================
839 BOOLEAN
PeerBeaconAndProbeRspSanity2(
840 IN PRTMP_ADAPTER pAd
,
846 PFRAME_802_11 pFrame
;
850 pFrame
= (PFRAME_802_11
)Msg
;
853 Ptr
= (PCHAR
) pFrame
->Octet
;
854 Length
+= LENGTH_802_11
;
856 // get timestamp from payload and advance the pointer
857 Ptr
+= TIMESTAMP_LEN
;
858 Length
+= TIMESTAMP_LEN
;
860 // get beacon interval from payload and advance the pointer
864 // get capability info from payload and advance the pointer
868 pEid
= (PEID_STRUCT
) Ptr
;
870 // get variable fields from payload and advance the pointer
871 while ((Length
+ 2 + pEid
->Len
) <= MsgLen
)
875 case IE_SUPP_REG_CLASS
:
878 *RegClass
= *pEid
->Octet
;
882 DBGPRINT(RT_DEBUG_TRACE
, ("PeerBeaconAndProbeRspSanity - wrong IE_SSID (len=%d)\n",pEid
->Len
));
888 Length
= Length
+ 2 + pEid
->Len
; // Eid[1] + Len[1]+ content[Len]
889 pEid
= (PEID_STRUCT
)((UCHAR
*)pEid
+ 2 + pEid
->Len
);
895 #endif // DOT11N_DRAFT3 //
898 ==========================================================================
900 MLME message sanity check
902 TRUE if all parameters are OK, FALSE otherwise
903 ==========================================================================
905 BOOLEAN
MlmeScanReqSanity(
906 IN PRTMP_ADAPTER pAd
,
912 OUT UCHAR
*pScanType
)
914 MLME_SCAN_REQ_STRUCT
*Info
;
916 Info
= (MLME_SCAN_REQ_STRUCT
*)(Msg
);
917 *pBssType
= Info
->BssType
;
918 *pSsidLen
= Info
->SsidLen
;
919 NdisMoveMemory(Ssid
, Info
->Ssid
, *pSsidLen
);
920 *pScanType
= Info
->ScanType
;
922 if ((*pBssType
== BSS_INFRA
|| *pBssType
== BSS_ADHOC
|| *pBssType
== BSS_ANY
)
923 && (*pScanType
== SCAN_ACTIVE
|| *pScanType
== SCAN_PASSIVE
924 #ifdef CONFIG_STA_SUPPORT
925 #endif // CONFIG_STA_SUPPORT //
932 DBGPRINT(RT_DEBUG_TRACE
, ("MlmeScanReqSanity fail - wrong BssType or ScanType\n"));
937 // IRQL = DISPATCH_LEVEL
939 IN PRTMP_ADAPTER pAd
,
944 for (i
= 0; i
< pAd
->ChannelListNum
; i
++)
946 if (channel
== pAd
->ChannelList
[i
].Channel
)
953 ==========================================================================
955 MLME message sanity check
957 TRUE if all parameters are OK, FALSE otherwise
959 IRQL = DISPATCH_LEVEL
961 ==========================================================================
963 BOOLEAN
PeerDeauthSanity(
964 IN PRTMP_ADAPTER pAd
,
970 PFRAME_802_11 pFrame
= (PFRAME_802_11
)Msg
;
972 COPY_MAC_ADDR(pAddr2
, pFrame
->Hdr
.Addr2
);
973 NdisMoveMemory(pReason
, &pFrame
->Octet
[0], 2);
979 ==========================================================================
981 MLME message sanity check
983 TRUE if all parameters are OK, FALSE otherwise
985 IRQL = DISPATCH_LEVEL
987 ==========================================================================
989 BOOLEAN
PeerAuthSanity(
990 IN PRTMP_ADAPTER pAd
,
999 PFRAME_802_11 pFrame
= (PFRAME_802_11
)Msg
;
1001 COPY_MAC_ADDR(pAddr
, pFrame
->Hdr
.Addr2
);
1002 NdisMoveMemory(pAlg
, &pFrame
->Octet
[0], 2);
1003 NdisMoveMemory(pSeq
, &pFrame
->Octet
[2], 2);
1004 NdisMoveMemory(pStatus
, &pFrame
->Octet
[4], 2);
1006 if (*pAlg
== AUTH_MODE_OPEN
)
1008 if (*pSeq
== 1 || *pSeq
== 2)
1014 DBGPRINT(RT_DEBUG_TRACE
, ("PeerAuthSanity fail - wrong Seg#\n"));
1018 else if (*pAlg
== AUTH_MODE_KEY
)
1020 if (*pSeq
== 1 || *pSeq
== 4)
1024 else if (*pSeq
== 2 || *pSeq
== 3)
1026 NdisMoveMemory(pChlgText
, &pFrame
->Octet
[8], CIPHER_TEXT_LEN
);
1031 DBGPRINT(RT_DEBUG_TRACE
, ("PeerAuthSanity fail - wrong Seg#\n"));
1037 DBGPRINT(RT_DEBUG_TRACE
, ("PeerAuthSanity fail - wrong algorithm\n"));
1043 ==========================================================================
1045 MLME message sanity check
1047 TRUE if all parameters are OK, FALSE otherwise
1048 ==========================================================================
1050 BOOLEAN
MlmeAuthReqSanity(
1051 IN PRTMP_ADAPTER pAd
,
1055 OUT ULONG
*pTimeout
,
1058 MLME_AUTH_REQ_STRUCT
*pInfo
;
1060 pInfo
= (MLME_AUTH_REQ_STRUCT
*)Msg
;
1061 COPY_MAC_ADDR(pAddr
, pInfo
->Addr
);
1062 *pTimeout
= pInfo
->Timeout
;
1065 if (((*pAlg
== AUTH_MODE_KEY
) ||(*pAlg
== AUTH_MODE_OPEN
)
1067 ((*pAddr
& 0x01) == 0))
1073 DBGPRINT(RT_DEBUG_TRACE
, ("MlmeAuthReqSanity fail - wrong algorithm\n"));
1079 ==========================================================================
1081 MLME message sanity check
1083 TRUE if all parameters are OK, FALSE otherwise
1085 IRQL = DISPATCH_LEVEL
1087 ==========================================================================
1089 BOOLEAN
MlmeAssocReqSanity(
1090 IN PRTMP_ADAPTER pAd
,
1094 OUT USHORT
*pCapabilityInfo
,
1095 OUT ULONG
*pTimeout
,
1096 OUT USHORT
*pListenIntv
)
1098 MLME_ASSOC_REQ_STRUCT
*pInfo
;
1100 pInfo
= (MLME_ASSOC_REQ_STRUCT
*)Msg
;
1101 *pTimeout
= pInfo
->Timeout
; // timeout
1102 COPY_MAC_ADDR(pApAddr
, pInfo
->Addr
); // AP address
1103 *pCapabilityInfo
= pInfo
->CapabilityInfo
; // capability info
1104 *pListenIntv
= pInfo
->ListenIntv
;
1110 ==========================================================================
1112 MLME message sanity check
1114 TRUE if all parameters are OK, FALSE otherwise
1116 IRQL = DISPATCH_LEVEL
1118 ==========================================================================
1120 BOOLEAN
PeerDisassocSanity(
1121 IN PRTMP_ADAPTER pAd
,
1125 OUT USHORT
*pReason
)
1127 PFRAME_802_11 pFrame
= (PFRAME_802_11
)Msg
;
1129 COPY_MAC_ADDR(pAddr2
, pFrame
->Hdr
.Addr2
);
1130 NdisMoveMemory(pReason
, &pFrame
->Octet
[0], 2);
1136 ========================================================================
1137 Routine Description:
1138 Sanity check NetworkType (11b, 11g or 11a)
1141 pBss - Pointer to BSS table.
1144 Ndis802_11DS .......(11b)
1145 Ndis802_11OFDM24....(11g)
1146 Ndis802_11OFDM5.....(11a)
1148 IRQL = DISPATCH_LEVEL
1150 ========================================================================
1152 NDIS_802_11_NETWORK_TYPE
NetworkTypeInUseSanity(
1155 NDIS_802_11_NETWORK_TYPE NetWorkType
;
1158 NetWorkType
= Ndis802_11DS
;
1160 if (pBss
->Channel
<= 14)
1163 // First check support Rate.
1165 for (i
= 0; i
< pBss
->SupRateLen
; i
++)
1167 rate
= pBss
->SupRate
[i
] & 0x7f; // Mask out basic rate set bit
1168 if ((rate
== 2) || (rate
== 4) || (rate
== 11) || (rate
== 22))
1175 // Otherwise (even rate > 108) means Ndis802_11OFDM24
1177 NetWorkType
= Ndis802_11OFDM24
;
1183 // Second check Extend Rate.
1185 if (NetWorkType
!= Ndis802_11OFDM24
)
1187 for (i
= 0; i
< pBss
->ExtRateLen
; i
++)
1189 rate
= pBss
->SupRate
[i
] & 0x7f; // Mask out basic rate set bit
1190 if ((rate
== 2) || (rate
== 4) || (rate
== 11) || (rate
== 22))
1197 // Otherwise (even rate > 108) means Ndis802_11OFDM24
1199 NetWorkType
= Ndis802_11OFDM24
;
1207 NetWorkType
= Ndis802_11OFDM5
;
1210 if (pBss
->HtCapabilityLen
!= 0)
1212 if (NetWorkType
== Ndis802_11OFDM5
)
1213 NetWorkType
= Ndis802_11OFDM5_N
;
1215 NetWorkType
= Ndis802_11OFDM24_N
;
1222 ==========================================================================
1224 Check the validity of the received EAPoL frame
1226 TRUE if all parameters are OK,
1228 ==========================================================================
1230 BOOLEAN
PeerWpaMessageSanity(
1231 IN PRTMP_ADAPTER pAd
,
1232 IN PEAPOL_PACKET pMsg
,
1235 IN MAC_TABLE_ENTRY
*pEntry
)
1237 UCHAR mic
[LEN_KEY_DESC_MIC
], digest
[80], KEYDATA
[MAX_LEN_OF_RSNIE
];
1238 BOOLEAN bReplayDiff
= FALSE
;
1239 BOOLEAN bWPA2
= FALSE
;
1240 KEY_INFO EapolKeyInfo
;
1241 UCHAR GroupKeyIndex
= 0;
1244 NdisZeroMemory(mic
, sizeof(mic
));
1245 NdisZeroMemory(digest
, sizeof(digest
));
1246 NdisZeroMemory(KEYDATA
, sizeof(KEYDATA
));
1247 NdisZeroMemory((PUCHAR
)&EapolKeyInfo
, sizeof(EapolKeyInfo
));
1249 NdisMoveMemory((PUCHAR
)&EapolKeyInfo
, (PUCHAR
)&pMsg
->KeyDesc
.KeyInfo
, sizeof(KEY_INFO
));
1251 *((USHORT
*)&EapolKeyInfo
) = cpu2le16(*((USHORT
*)&EapolKeyInfo
));
1253 // Choose WPA2 or not
1254 if ((pEntry
->AuthMode
== Ndis802_11AuthModeWPA2
) || (pEntry
->AuthMode
== Ndis802_11AuthModeWPA2PSK
))
1258 if ((MsgType
> EAPOL_GROUP_MSG_2
) || (MsgType
< EAPOL_PAIR_MSG_1
))
1260 DBGPRINT(RT_DEBUG_ERROR
, ("The message type is invalid(%d)! \n", MsgType
));
1264 // 1. Replay counter check
1265 if (MsgType
== EAPOL_PAIR_MSG_1
|| MsgType
== EAPOL_PAIR_MSG_3
|| MsgType
== EAPOL_GROUP_MSG_1
) // For supplicant
1267 // First validate replay counter, only accept message with larger replay counter.
1268 // Let equal pass, some AP start with all zero replay counter
1269 UCHAR ZeroReplay
[LEN_KEY_DESC_REPLAY
];
1271 NdisZeroMemory(ZeroReplay
, LEN_KEY_DESC_REPLAY
);
1272 if ((RTMPCompareMemory(pMsg
->KeyDesc
.ReplayCounter
, pEntry
->R_Counter
, LEN_KEY_DESC_REPLAY
) != 1) &&
1273 (RTMPCompareMemory(pMsg
->KeyDesc
.ReplayCounter
, ZeroReplay
, LEN_KEY_DESC_REPLAY
) != 0))
1278 else if (MsgType
== EAPOL_PAIR_MSG_2
|| MsgType
== EAPOL_PAIR_MSG_4
|| MsgType
== EAPOL_GROUP_MSG_2
) // For authenticator
1280 // check Replay Counter coresponds to MSG from authenticator, otherwise discard
1281 if (!NdisEqualMemory(pMsg
->KeyDesc
.ReplayCounter
, pEntry
->R_Counter
, LEN_KEY_DESC_REPLAY
))
1287 // Replay Counter different condition
1290 // send wireless event - for replay counter different
1291 if (pAd
->CommonCfg
.bWirelessEvent
)
1292 RTMPSendWirelessEvent(pAd
, IW_REPLAY_COUNTER_DIFF_EVENT_FLAG
, pEntry
->Addr
, pEntry
->apidx
, 0);
1294 if (MsgType
< EAPOL_GROUP_MSG_1
)
1296 DBGPRINT(RT_DEBUG_ERROR
, ("Replay Counter Different in pairwise msg %d of 4-way handshake!\n", MsgType
));
1300 DBGPRINT(RT_DEBUG_ERROR
, ("Replay Counter Different in group msg %d of 2-way handshake!\n", (MsgType
- EAPOL_PAIR_MSG_4
)));
1303 hex_dump("Receive replay counter ", pMsg
->KeyDesc
.ReplayCounter
, LEN_KEY_DESC_REPLAY
);
1304 hex_dump("Current replay counter ", pEntry
->R_Counter
, LEN_KEY_DESC_REPLAY
);
1308 // 2. Verify MIC except Pairwise Msg1
1309 if (MsgType
!= EAPOL_PAIR_MSG_1
)
1311 UCHAR rcvd_mic
[LEN_KEY_DESC_MIC
];
1313 // Record the received MIC for check later
1314 NdisMoveMemory(rcvd_mic
, pMsg
->KeyDesc
.KeyMic
, LEN_KEY_DESC_MIC
);
1315 NdisZeroMemory(pMsg
->KeyDesc
.KeyMic
, LEN_KEY_DESC_MIC
);
1317 if (EapolKeyInfo
.KeyDescVer
== DESC_TYPE_TKIP
) // TKIP
1319 HMAC_MD5(pEntry
->PTK
, LEN_EAP_MICK
, (PUCHAR
)pMsg
, MsgLen
, mic
, MD5_DIGEST_SIZE
);
1321 else if (EapolKeyInfo
.KeyDescVer
== DESC_TYPE_AES
) // AES
1323 HMAC_SHA1(pEntry
->PTK
, LEN_EAP_MICK
, (PUCHAR
)pMsg
, MsgLen
, digest
, SHA1_DIGEST_SIZE
);
1324 NdisMoveMemory(mic
, digest
, LEN_KEY_DESC_MIC
);
1327 if (!NdisEqualMemory(rcvd_mic
, mic
, LEN_KEY_DESC_MIC
))
1329 // send wireless event - for MIC different
1330 if (pAd
->CommonCfg
.bWirelessEvent
)
1331 RTMPSendWirelessEvent(pAd
, IW_MIC_DIFF_EVENT_FLAG
, pEntry
->Addr
, pEntry
->apidx
, 0);
1333 if (MsgType
< EAPOL_GROUP_MSG_1
)
1335 DBGPRINT(RT_DEBUG_ERROR
, ("MIC Different in pairwise msg %d of 4-way handshake!\n", MsgType
));
1339 DBGPRINT(RT_DEBUG_ERROR
, ("MIC Different in group msg %d of 2-way handshake!\n", (MsgType
- EAPOL_PAIR_MSG_4
)));
1342 hex_dump("Received MIC", rcvd_mic
, LEN_KEY_DESC_MIC
);
1343 hex_dump("Desired MIC", mic
, LEN_KEY_DESC_MIC
);
1349 // 1. Decrypt the Key Data field if GTK is included.
1350 // 2. Extract the context of the Key Data field if it exist.
1351 // The field in pairwise_msg_2_WPA1(WPA2) & pairwise_msg_3_WPA1 is clear.
1352 // The field in group_msg_1_WPA1(WPA2) & pairwise_msg_3_WPA2 is encrypted.
1353 if (CONV_ARRARY_TO_UINT16(pMsg
->KeyDesc
.KeyDataLen
) > 0)
1355 // Decrypt this field
1356 if ((MsgType
== EAPOL_PAIR_MSG_3
&& bWPA2
) || (MsgType
== EAPOL_GROUP_MSG_1
))
1359 (EapolKeyInfo
.KeyDescVer
== DESC_TYPE_AES
))
1362 AES_GTK_KEY_UNWRAP(&pEntry
->PTK
[16], KEYDATA
,
1363 CONV_ARRARY_TO_UINT16(pMsg
->KeyDesc
.KeyDataLen
),
1364 pMsg
->KeyDesc
.KeyData
);
1371 // Construct 32 bytes RC4 Key
1372 NdisMoveMemory(Key
, pMsg
->KeyDesc
.KeyIv
, 16);
1373 NdisMoveMemory(&Key
[16], &pEntry
->PTK
[16], 16);
1374 ARCFOUR_INIT(&pAd
->PrivateInfo
.WEPCONTEXT
, Key
, 32);
1375 //discard first 256 bytes
1376 for(i
= 0; i
< 256; i
++)
1377 ARCFOUR_BYTE(&pAd
->PrivateInfo
.WEPCONTEXT
);
1378 // Decrypt GTK. Becareful, there is no ICV to check the result is correct or not
1379 ARCFOUR_DECRYPT(&pAd
->PrivateInfo
.WEPCONTEXT
, KEYDATA
,
1380 pMsg
->KeyDesc
.KeyData
,
1381 CONV_ARRARY_TO_UINT16(pMsg
->KeyDesc
.KeyDataLen
));
1384 if (!bWPA2
&& (MsgType
== EAPOL_GROUP_MSG_1
))
1385 GroupKeyIndex
= EapolKeyInfo
.KeyIndex
;
1388 else if ((MsgType
== EAPOL_PAIR_MSG_2
) || (MsgType
== EAPOL_PAIR_MSG_3
&& !bWPA2
))
1390 NdisMoveMemory(KEYDATA
, pMsg
->KeyDesc
.KeyData
, CONV_ARRARY_TO_UINT16(pMsg
->KeyDesc
.KeyDataLen
));
1398 // Parse Key Data field to
1399 // 1. verify RSN IE for pairwise_msg_2_WPA1(WPA2) ,pairwise_msg_3_WPA1(WPA2)
1400 // 2. verify KDE format for pairwise_msg_3_WPA2, group_msg_1_WPA2
1401 // 3. update shared key for pairwise_msg_3_WPA2, group_msg_1_WPA1(WPA2)
1402 if (!RTMPParseEapolKeyData(pAd
, KEYDATA
,
1403 CONV_ARRARY_TO_UINT16(pMsg
->KeyDesc
.KeyDataLen
),
1404 GroupKeyIndex
, MsgType
, bWPA2
, pEntry
))
1414 #ifdef CONFIG_STA_SUPPORT
1415 #ifdef QOS_DLS_SUPPORT
1416 BOOLEAN
MlmeDlsReqSanity(
1417 IN PRTMP_ADAPTER pAd
,
1420 OUT PRT_802_11_DLS
*pDLS
,
1421 OUT PUSHORT pReason
)
1423 MLME_DLS_REQ_STRUCT
*pInfo
;
1425 pInfo
= (MLME_DLS_REQ_STRUCT
*)Msg
;
1427 *pDLS
= pInfo
->pDLS
;
1428 *pReason
= pInfo
->Reason
;
1432 #endif // QOS_DLS_SUPPORT //
1433 #endif // CONFIG_STA_SUPPORT //
1435 #ifdef QOS_DLS_SUPPORT
1436 BOOLEAN
PeerDlsReqSanity(
1437 IN PRTMP_ADAPTER pAd
,
1442 OUT USHORT
*pCapabilityInfo
,
1443 OUT USHORT
*pDlsTimeout
,
1444 OUT UCHAR
*pRatesLen
,
1446 OUT UCHAR
*pHtCapabilityLen
,
1447 OUT HT_CAPABILITY_IE
*pHtCapability
)
1450 PFRAME_802_11 Fr
= (PFRAME_802_11
)Msg
;
1451 PEID_STRUCT eid_ptr
;
1453 // to prevent caller from using garbage output value
1454 *pCapabilityInfo
= 0;
1456 *pHtCapabilityLen
= 0;
1458 Ptr
= (PCHAR
)Fr
->Octet
;
1460 // offset to destination MAC address (Category and Action field)
1463 // get DA from payload and advance the pointer
1464 NdisMoveMemory(pDA
, Ptr
, MAC_ADDR_LEN
);
1465 Ptr
+= MAC_ADDR_LEN
;
1467 // get SA from payload and advance the pointer
1468 NdisMoveMemory(pSA
, Ptr
, MAC_ADDR_LEN
);
1469 Ptr
+= MAC_ADDR_LEN
;
1471 // get capability info from payload and advance the pointer
1472 NdisMoveMemory(pCapabilityInfo
, Ptr
, 2);
1475 // get capability info from payload and advance the pointer
1476 NdisMoveMemory(pDlsTimeout
, Ptr
, 2);
1479 // Category and Action field + DA + SA + capability + Timeout
1480 eid_ptr
= (PEID_STRUCT
) &Fr
->Octet
[18];
1482 while (((UCHAR
*)eid_ptr
+ eid_ptr
->Len
+ 1) < ((UCHAR
*)Fr
+ MsgLen
))
1484 switch(eid_ptr
->Eid
)
1487 if ((eid_ptr
->Len
<= MAX_LEN_OF_SUPPORTED_RATES
) && (eid_ptr
->Len
> 0))
1489 NdisMoveMemory(Rates
, eid_ptr
->Octet
, eid_ptr
->Len
);
1490 DBGPRINT(RT_DEBUG_TRACE
, ("PeerDlsReqSanity - IE_SUPP_RATES., Len=%d. Rates[0]=%x\n",eid_ptr
->Len
, Rates
[0]));
1491 DBGPRINT(RT_DEBUG_TRACE
, ("Rates[1]=%x %x %x %x %x %x %x\n", Rates
[1], Rates
[2], Rates
[3], Rates
[4], Rates
[5], Rates
[6], Rates
[7]));
1492 *pRatesLen
= eid_ptr
->Len
;
1505 DBGPRINT(RT_DEBUG_TRACE
, ("PeerDlsReqSanity - wrong IE_SUPP_RATES., Len=%d\n",eid_ptr
->Len
));
1509 case IE_EXT_SUPP_RATES
:
1510 if (eid_ptr
->Len
+ *pRatesLen
<= MAX_LEN_OF_SUPPORTED_RATES
)
1512 NdisMoveMemory(&Rates
[*pRatesLen
], eid_ptr
->Octet
, eid_ptr
->Len
);
1513 *pRatesLen
= (*pRatesLen
) + eid_ptr
->Len
;
1517 NdisMoveMemory(&Rates
[*pRatesLen
], eid_ptr
->Octet
, MAX_LEN_OF_SUPPORTED_RATES
- (*pRatesLen
));
1518 *pRatesLen
= MAX_LEN_OF_SUPPORTED_RATES
;
1523 if (eid_ptr
->Len
>= sizeof(HT_CAPABILITY_IE
))
1525 NdisMoveMemory(pHtCapability
, eid_ptr
->Octet
, sizeof(HT_CAPABILITY_IE
));
1527 *(USHORT
*)(&pHtCapability
->HtCapInfo
) = cpu2le16(*(USHORT
*)(&pHtCapability
->HtCapInfo
));
1528 #ifdef UNALIGNMENT_SUPPORT
1530 EXT_HT_CAP_INFO extHtCapInfo
;
1532 NdisMoveMemory((PUCHAR
)(&extHtCapInfo
), (PUCHAR
)(&pHtCapability
->ExtHtCapInfo
), sizeof(EXT_HT_CAP_INFO
));
1533 *(USHORT
*)(&extHtCapInfo
) = cpu2le16(*(USHORT
*)(&extHtCapInfo
));
1534 NdisMoveMemory((PUCHAR
)(&pHtCapability
->ExtHtCapInfo
), (PUCHAR
)(&extHtCapInfo
), sizeof(EXT_HT_CAP_INFO
));
1537 *(USHORT
*)(&pHtCapability
->ExtHtCapInfo
) = cpu2le16(*(USHORT
*)(&pHtCapability
->ExtHtCapInfo
));
1538 #endif // UNALIGNMENT_SUPPORT //
1539 *pHtCapabilityLen
= sizeof(HT_CAPABILITY_IE
);
1541 DBGPRINT(RT_DEBUG_TRACE
, ("PeerDlsReqSanity - IE_HT_CAP\n"));
1545 DBGPRINT(RT_DEBUG_TRACE
, ("PeerDlsReqSanity - wrong IE_HT_CAP.eid_ptr->Len = %d\n", eid_ptr
->Len
));
1553 eid_ptr
= (PEID_STRUCT
)((UCHAR
*)eid_ptr
+ 2 + eid_ptr
->Len
);
1559 BOOLEAN
PeerDlsRspSanity(
1560 IN PRTMP_ADAPTER pAd
,
1565 OUT USHORT
*pCapabilityInfo
,
1566 OUT USHORT
*pStatus
,
1567 OUT UCHAR
*pRatesLen
,
1569 OUT UCHAR
*pHtCapabilityLen
,
1570 OUT HT_CAPABILITY_IE
*pHtCapability
)
1573 PFRAME_802_11 Fr
= (PFRAME_802_11
)Msg
;
1574 PEID_STRUCT eid_ptr
;
1576 // to prevent caller from using garbage output value
1578 *pCapabilityInfo
= 0;
1579 *pHtCapabilityLen
= 0;
1581 Ptr
= (PCHAR
)Fr
->Octet
;
1583 // offset to destination MAC address (Category and Action field)
1586 // get status code from payload and advance the pointer
1587 NdisMoveMemory(pStatus
, Ptr
, 2);
1590 // get DA from payload and advance the pointer
1591 NdisMoveMemory(pDA
, Ptr
, MAC_ADDR_LEN
);
1592 Ptr
+= MAC_ADDR_LEN
;
1594 // get SA from payload and advance the pointer
1595 NdisMoveMemory(pSA
, Ptr
, MAC_ADDR_LEN
);
1596 Ptr
+= MAC_ADDR_LEN
;
1600 // get capability info from payload and advance the pointer
1601 NdisMoveMemory(pCapabilityInfo
, Ptr
, 2);
1605 // Category and Action field + status code + DA + SA + capability
1606 eid_ptr
= (PEID_STRUCT
) &Fr
->Octet
[18];
1608 while (((UCHAR
*)eid_ptr
+ eid_ptr
->Len
+ 1) < ((UCHAR
*)Fr
+ MsgLen
))
1610 switch(eid_ptr
->Eid
)
1613 if ((eid_ptr
->Len
<= MAX_LEN_OF_SUPPORTED_RATES
) && (eid_ptr
->Len
> 0))
1615 NdisMoveMemory(Rates
, eid_ptr
->Octet
, eid_ptr
->Len
);
1616 DBGPRINT(RT_DEBUG_TRACE
, ("PeerDlsRspSanity - IE_SUPP_RATES., Len=%d. Rates[0]=%x\n",eid_ptr
->Len
, Rates
[0]));
1617 DBGPRINT(RT_DEBUG_TRACE
, ("Rates[1]=%x %x %x %x %x %x %x\n", Rates
[1], Rates
[2], Rates
[3], Rates
[4], Rates
[5], Rates
[6], Rates
[7]));
1618 *pRatesLen
= eid_ptr
->Len
;
1631 DBGPRINT(RT_DEBUG_TRACE
, ("PeerDlsRspSanity - wrong IE_SUPP_RATES., Len=%d\n",eid_ptr
->Len
));
1635 case IE_EXT_SUPP_RATES
:
1636 if (eid_ptr
->Len
+ *pRatesLen
<= MAX_LEN_OF_SUPPORTED_RATES
)
1638 NdisMoveMemory(&Rates
[*pRatesLen
], eid_ptr
->Octet
, eid_ptr
->Len
);
1639 *pRatesLen
= (*pRatesLen
) + eid_ptr
->Len
;
1643 NdisMoveMemory(&Rates
[*pRatesLen
], eid_ptr
->Octet
, MAX_LEN_OF_SUPPORTED_RATES
- (*pRatesLen
));
1644 *pRatesLen
= MAX_LEN_OF_SUPPORTED_RATES
;
1649 if (eid_ptr
->Len
>= sizeof(HT_CAPABILITY_IE
))
1651 NdisMoveMemory(pHtCapability
, eid_ptr
->Octet
, sizeof(HT_CAPABILITY_IE
));
1653 *(USHORT
*)(&pHtCapability
->HtCapInfo
) = cpu2le16(*(USHORT
*)(&pHtCapability
->HtCapInfo
));
1654 #ifdef UNALIGNMENT_SUPPORT
1656 EXT_HT_CAP_INFO extHtCapInfo
;
1658 NdisMoveMemory((PUCHAR
)(&extHtCapInfo
), (PUCHAR
)(&pHtCapability
->ExtHtCapInfo
), sizeof(EXT_HT_CAP_INFO
));
1659 *(USHORT
*)(&extHtCapInfo
) = cpu2le16(*(USHORT
*)(&extHtCapInfo
));
1660 NdisMoveMemory((PUCHAR
)(&pHtCapability
->ExtHtCapInfo
), (PUCHAR
)(&extHtCapInfo
), sizeof(EXT_HT_CAP_INFO
));
1663 *(USHORT
*)(&pHtCapability
->ExtHtCapInfo
) = cpu2le16(*(USHORT
*)(&pHtCapability
->ExtHtCapInfo
));
1664 #endif // UNALIGNMENT_SUPPORT //
1665 *pHtCapabilityLen
= sizeof(HT_CAPABILITY_IE
);
1667 DBGPRINT(RT_DEBUG_TRACE
, ("PeerDlsRspSanity - IE_HT_CAP\n"));
1671 DBGPRINT(RT_DEBUG_TRACE
, ("PeerDlsRspSanity - wrong IE_HT_CAP.eid_ptr->Len = %d\n", eid_ptr
->Len
));
1679 eid_ptr
= (PEID_STRUCT
)((UCHAR
*)eid_ptr
+ 2 + eid_ptr
->Len
);
1685 BOOLEAN
PeerDlsTearDownSanity(
1686 IN PRTMP_ADAPTER pAd
,
1691 OUT USHORT
*pReason
)
1694 PFRAME_802_11 Fr
= (PFRAME_802_11
)Msg
;
1696 // to prevent caller from using garbage output value
1699 Ptr
= (PCHAR
)Fr
->Octet
;
1701 // offset to destination MAC address (Category and Action field)
1704 // get DA from payload and advance the pointer
1705 NdisMoveMemory(pDA
, Ptr
, MAC_ADDR_LEN
);
1706 Ptr
+= MAC_ADDR_LEN
;
1708 // get SA from payload and advance the pointer
1709 NdisMoveMemory(pSA
, Ptr
, MAC_ADDR_LEN
);
1710 Ptr
+= MAC_ADDR_LEN
;
1712 // get reason code from payload and advance the pointer
1713 NdisMoveMemory(pReason
, Ptr
, 2);
1718 #endif // QOS_DLS_SUPPORT //