1 /****************************************************************************
3 * 4F, No. 2 Technology 5th Rd.
4 * Science-based Industrial Park
5 * Hsin-chu, Taiwan, R.O.C.
6 * (c) Copyright 2002, Ralink Technology, Inc.
8 * All rights reserved. Ralink's source code is an unpublished work and the
9 * use of a copyright notice does not imply otherwise. This source code
10 * contains confidential trade secret material of Ralink Tech. Any attemp
11 * or participation in deciphering, decoding, reverse engineering or in any
12 * way altering the source code is stricitly prohibited, unless the prior
13 * written consent of Ralink Technology, Inc. is obtained.
14 ****************************************************************************/
16 #include "rt_config.h"
18 UCHAR WPA_OUI
[] = {0x00, 0x50, 0xf2, 0x01};
21 ==========================================================================
23 MLME message sanity check
25 TRUE if all parameters are OK, FALSE otherwise
26 ==========================================================================
28 BOOLEAN
MlmeScanReqSanity(
37 MLME_SCAN_REQ_STRUCT
*Info
;
39 Info
= (MLME_SCAN_REQ_STRUCT
*)(Msg
);
40 *BssType
= Info
->BssType
;
41 *SsidLen
= Info
->SsidLen
;
42 NdisMoveMemory(Ssid
, Info
->Ssid
, *SsidLen
);
43 *ScanType
= Info
->ScanType
;
45 if ((*BssType
== BSS_INFRA
|| *BssType
== BSS_INDEP
|| *BssType
== BSS_ANY
) &&
46 (*ScanType
== SCAN_ACTIVE
|| *ScanType
== SCAN_PASSIVE
))
50 DBGPRINT(RT_DEBUG_TRACE
, "MlmeScanReqSanity fail - wrong BssType or ScanType\n");
56 ==========================================================================
58 MLME message sanity check
60 TRUE if all parameters are OK, FALSE otherwise
61 ==========================================================================
63 BOOLEAN
MlmeStartReqSanity(
70 MLME_START_REQ_STRUCT
*Info
;
72 Info
= (MLME_START_REQ_STRUCT
*)(Msg
);
74 if (Info
->SsidLen
> MAX_LEN_OF_SSID
)
76 DBGPRINT(RT_DEBUG_TRACE
, "MlmeStartReqSanity fail - wrong SSID length\n");
80 *SsidLen
= Info
->SsidLen
;
81 NdisMoveMemory(Ssid
, Info
->Ssid
, *SsidLen
);
87 ==========================================================================
89 MLME message sanity check
91 TRUE if all parameters are OK, FALSE otherwise
92 ==========================================================================
94 BOOLEAN
MlmeAssocReqSanity(
99 OUT USHORT
*CapabilityInfo
,
101 OUT USHORT
*ListenIntv
)
103 MLME_ASSOC_REQ_STRUCT
*Info
;
105 Info
= (MLME_ASSOC_REQ_STRUCT
*)Msg
;
106 *Timeout
= Info
->Timeout
; // timeout
107 COPY_MAC_ADDR(ApAddr
, &Info
->Addr
); // AP address
108 *CapabilityInfo
= Info
->CapabilityInfo
; // capability info
109 *ListenIntv
= Info
->ListenIntv
;
115 ==========================================================================
117 MLME message sanity check
119 TRUE if all parameters are OK, FALSE otherwise
120 ==========================================================================
122 BOOLEAN
MlmeAuthReqSanity(
123 IN PRTMP_ADAPTER pAd
,
130 MLME_AUTH_REQ_STRUCT
*Info
;
132 Info
= (MLME_AUTH_REQ_STRUCT
*)Msg
;
133 COPY_MAC_ADDR(Addr
, &Info
->Addr
);
134 *Timeout
= Info
->Timeout
;
137 if ((*Alg
== Ndis802_11AuthModeShared
|| *Alg
== Ndis802_11AuthModeOpen
) && !MAC_ADDR_IS_GROUP(*Addr
))
143 DBGPRINT(RT_DEBUG_TRACE
, "MlmeAuthReqSanity fail - wrong algorithm\n");
149 ==========================================================================
151 MLME message sanity check
153 TRUE if all parameters are OK, FALSE otherwise
154 ==========================================================================
156 BOOLEAN
PeerAssocRspSanity(
157 IN PRTMP_ADAPTER pAd
,
161 OUT USHORT
*CapabilityInfo
,
166 OUT BOOLEAN
*ExtendedRateIeExist
)
169 MACFRAME
*Fr
= (MACFRAME
*)Msg
;
170 PBEACON_EID_STRUCT eid_ptr
;
172 COPY_MAC_ADDR(Addr2
, &Fr
->Hdr
.Addr2
);
175 NdisMoveMemory(CapabilityInfo
, &Fr
->Octet
[0], 2);
176 NdisMoveMemory(Status
, &Fr
->Octet
[2], 2);
177 // Mask out unnecessary capability information
178 *CapabilityInfo
&= SUPPORTED_CAPABILITY_INFO
;
180 if (*Status
== MLME_SUCCESS
)
182 NdisMoveMemory(Aid
, &Fr
->Octet
[4], 2);
183 *Aid
= (*Aid
) & 0x3fff; // AID is low 14-bit
185 // -- get supported rates from payload and advance the pointer
186 IeType
= Fr
->Octet
[6];
187 *RatesLen
= Fr
->Octet
[7];
188 if ((IeType
!= IE_SUPP_RATES
) || (*RatesLen
> MAX_LEN_OF_SUPPORTED_RATES
))
190 DBGPRINT(RT_DEBUG_TRACE
, "PeerAssocRspSanity fail - wrong SupportedRates IE\n");
194 NdisMoveMemory(Rates
, &Fr
->Octet
[8], *RatesLen
);
196 // many AP implement proprietary IEs in non-standard order, we'd better
197 // tolerate mis-ordered IEs to get best compatibility
198 *ExtendedRateIeExist
= FALSE
;
199 eid_ptr
= (PBEACON_EID_STRUCT
) &Fr
->Octet
[8 + (*RatesLen
)];
201 // get variable fields from payload and advance the pointer
202 while (((UCHAR
*)eid_ptr
+ eid_ptr
->Len
+ 1) < ((UCHAR
*)Fr
+ MsgLen
))
204 switch (eid_ptr
->Eid
)
206 case IE_EXT_SUPP_RATES
:
207 *ExtendedRateIeExist
= TRUE
;
208 if ((*RatesLen
+ eid_ptr
->Len
) <= MAX_LEN_OF_SUPPORTED_RATES
)
210 NdisMoveMemory(&Rates
[*RatesLen
], eid_ptr
->Octet
, eid_ptr
->Len
);
211 *RatesLen
= (*RatesLen
) + eid_ptr
->Len
;
215 NdisMoveMemory(&Rates
[*RatesLen
], eid_ptr
->Octet
, MAX_LEN_OF_SUPPORTED_RATES
- (*RatesLen
));
216 *RatesLen
= MAX_LEN_OF_SUPPORTED_RATES
;
220 DBGPRINT(RT_DEBUG_TRACE
, "PeerAssocRspSanity - ignore unrecognized EID = %d\n", eid_ptr
->Eid
);
224 eid_ptr
= (PBEACON_EID_STRUCT
)((UCHAR
*)eid_ptr
+ 2 + eid_ptr
->Len
);
233 ==========================================================================
235 MLME message sanity check
237 TRUE if all parameters are OK, FALSE otherwise
238 ==========================================================================
240 BOOLEAN
PeerDisassocSanity(
241 IN PRTMP_ADAPTER pAd
,
247 MACFRAME
*Fr
= (MACFRAME
*)Msg
;
249 COPY_MAC_ADDR(Addr2
, &Fr
->Hdr
.Addr2
);
250 NdisMoveMemory(Reason
, &Fr
->Octet
[0], 2);
256 ==========================================================================
258 MLME message sanity check
260 TRUE if all parameters are OK, FALSE otherwise
261 ==========================================================================
263 BOOLEAN
PeerDeauthSanity(
264 IN PRTMP_ADAPTER pAd
,
270 MACFRAME
*Fr
= (MACFRAME
*)Msg
;
272 COPY_MAC_ADDR(Addr2
, &Fr
->Hdr
.Addr2
);
273 NdisMoveMemory(Reason
, &Fr
->Octet
[0], 2);
279 ==========================================================================
281 MLME message sanity check
283 TRUE if all parameters are OK, FALSE otherwise
284 ==========================================================================
286 BOOLEAN
PeerAuthSanity(
287 IN PRTMP_ADAPTER pAd
,
296 MACFRAME
*Fr
= (MACFRAME
*)Msg
;
298 COPY_MAC_ADDR(Addr
, &Fr
->Hdr
.Addr2
);
299 NdisMoveMemory(Alg
, &Fr
->Octet
[0], 2);
300 NdisMoveMemory(Seq
, &Fr
->Octet
[2], 2);
301 NdisMoveMemory(Status
, &Fr
->Octet
[4], 2);
303 if (*Alg
== Ndis802_11AuthModeOpen
)
305 if (*Seq
== 1 || *Seq
== 2)
311 DBGPRINT(RT_DEBUG_TRACE
, "PeerAuthSanity fail - wrong Seg#\n");
315 else if (*Alg
== Ndis802_11AuthModeShared
)
317 if (*Seq
== 1 || *Seq
== 4)
321 else if (*Seq
== 2 || *Seq
== 3)
323 NdisMoveMemory(ChlgText
, &Fr
->Octet
[8], CIPHER_TEXT_LEN
);
328 DBGPRINT(RT_DEBUG_TRACE
, "PeerAuthSanity fail - wrong Seg#\n");
334 DBGPRINT(RT_DEBUG_TRACE
, "PeerAuthSanity fail - wrong algorithm\n");
340 ==========================================================================
342 MLME message sanity check
344 TRUE if all parameters are OK, FALSE otherwise
345 ==========================================================================
347 BOOLEAN
PeerProbeReqSanity(
348 IN PRTMP_ADAPTER pAd
,
354 // OUT UCHAR Rates[],
355 // OUT UCHAR *RatesLen)
360 MACFRAME
*Fr
= (MACFRAME
*)Msg
;
362 COPY_MAC_ADDR(Addr2
, &Fr
->Hdr
.Addr2
);
364 if ((Fr
->Octet
[0] != IE_SSID
) || (Fr
->Octet
[1] > MAX_LEN_OF_SSID
))
366 DBGPRINT(RT_DEBUG_TRACE
, "PeerProbeReqSanity fail - wrong SSID IE(Type=%d,Len=%d)\n",Fr
->Octet
[0],Fr
->Octet
[1]);
370 *SsidLen
= Fr
->Octet
[1];
371 NdisMoveMemory(Ssid
, &Fr
->Octet
[2], *SsidLen
);
376 // -- get supported rates from payload and advance the pointer
377 IeType
= Fr
->Octet
[Idx
];
378 RateLen
= Fr
->Octet
[Idx
+ 1];
379 if (IeType
!= IE_SUPP_RATES
)
381 DBGPRINT(RT_DEBUG_TRACE
, "PeerProbeReqSanity fail - wrong SupportRates IE(Type=%d,Len=%d)\n",Fr
->Octet
[Idx
],Fr
->Octet
[Idx
+1]);
386 if ((pAd
->PortCfg
.AdhocMode
== 2) && (RateLen
< 8))
394 ==========================================================================
396 MLME message sanity check
398 TRUE if all parameters are OK, FALSE otherwise
399 ==========================================================================
401 BOOLEAN
PeerBeaconAndProbeRspSanity(
402 IN PRTMP_ADAPTER pAd
,
410 OUT USHORT
*BeaconPeriod
,
412 OUT LARGE_INTEGER
*Timestamp
,
413 OUT BOOLEAN
*CfExist
,
416 OUT USHORT
*CapabilityInfo
,
419 OUT BOOLEAN
*ExtendedRateIeExist
,
421 OUT UCHAR
*DtimCount
,
422 OUT UCHAR
*DtimPeriod
,
423 OUT UCHAR
*BcastFlag
,
424 OUT UCHAR
*MessageToMe
,
427 OUT UCHAR
*SupRateLen
,
429 OUT UCHAR
*ExtRateLen
,
430 OUT PNDIS_802_11_VARIABLE_IEs pVIE
)
434 PBEACON_EID_STRUCT eid_ptr
;
438 // Add for 3 necessary EID field check
441 *ExtendedRateIeExist
= FALSE
;
444 Fr
= (MACFRAME
*)Msg
;
446 // get subtype from header
447 SubType
= (UCHAR
)Fr
->Hdr
.SubType
;
449 // get Addr2 and BSSID from header
450 COPY_MAC_ADDR(Addr2
, &Fr
->Hdr
.Addr2
);
451 COPY_MAC_ADDR(Bssid
, &Fr
->Hdr
.Addr3
);
455 // get timestamp from payload and advance the pointer
456 NdisMoveMemory(Timestamp
, Ptr
, TIMESTAMP_LEN
);
457 Ptr
+= TIMESTAMP_LEN
;
459 // get beacon interval from payload and advance the pointer
460 NdisMoveMemory(BeaconPeriod
, Ptr
, 2);
463 // get capability info from payload and advance the pointer
464 NdisMoveMemory(CapabilityInfo
, Ptr
, 2);
466 if (CAP_IS_ESS_ON(*CapabilityInfo
))
468 *BssType
= BSS_INFRA
;
472 *BssType
= BSS_INDEP
;
475 // Mask out unnecessary capability information
476 *CapabilityInfo
&= SUPPORTED_CAPABILITY_INFO
;
478 eid_ptr
= (PBEACON_EID_STRUCT
) Ptr
;
482 unsigned long *aa
=(unsigned long *)eid_ptr
;
483 if (((UCHAR
*)eid_ptr
+ eid_ptr
->Len
+ 1) >= ((UCHAR
*)Fr
+ MsgLen
))
485 //DBGPRINT(RT_DEBUG_TRACE, "%08lX %08lX %08lX %08lX\n", aa[0], aa[1], aa[2], aa[3]);
486 DBGPRINT(RT_DEBUG_TRACE
, "Invalid length (eid_ptr=0x%X, eid_ptr->Len=%d, Fr=0x%X, MsgLen=%d)\n", eid_ptr
, eid_ptr
->Len
, Fr
, MsgLen
);
490 // get variable fields from payload and advance the pointer
491 while(((UCHAR
*)eid_ptr
+ eid_ptr
->Len
+ 1) < ((UCHAR
*)Fr
+ MsgLen
))
496 // Already has one SSID EID in this beacon, ignore the second one
499 if(eid_ptr
->Len
<= MAX_LEN_OF_SSID
)
501 NdisMoveMemory(Ssid
, eid_ptr
->Octet
, eid_ptr
->Len
);
502 *SsidLen
= eid_ptr
->Len
;
507 DBGPRINT(RT_DEBUG_TRACE
, "PeerBeaconAndProbeRspSanity - wrong IE_SSID (len=%d)\n",eid_ptr
->Len
);
513 if(eid_ptr
->Len
<= MAX_LEN_OF_SUPPORTED_RATES
)
520 eid_rate
= eid_ptr
->Octet
;
521 for (index
= 0; index
< eid_ptr
->Len
; index
++)
523 rate
= eid_rate
[index
] & 0x7f; // Mask out basic rate set bit
524 if ((rate
== 2) || (rate
== 4) || (rate
== 11) || (rate
== 22) ||
525 (rate
== 12) || (rate
== 18) || (rate
== 24) || (rate
== 36) ||
526 (rate
== 48) || (rate
== 72) || (rate
== 96) || (rate
== 108))
527 Rate
[i
++] = eid_rate
[index
]; // Save rate with basic rate set bit if exists
532 // Copy supported rate from desired AP's beacon. We are trying to match
533 // AP's supported and extended rate settings.
534 NdisMoveMemory(SupRate
, eid_ptr
->Octet
, eid_ptr
->Len
);
535 *SupRateLen
= eid_ptr
->Len
;
539 DBGPRINT(RT_DEBUG_TRACE
, "PeerBeaconAndProbeRspSanity - wrong IE_SUPP_RATES (len=%d)\n",eid_ptr
->Len
);
545 DBGPRINT(RT_DEBUG_TRACE
, "PeerBeaconAndProbeRspSanity(IE_FH_PARM) \n");
549 if(eid_ptr
->Len
== 1)
551 *Channel
= *eid_ptr
->Octet
;
552 if (ChannelSanity(pAd
, *Channel
) == 0)
554 DBGPRINT(RT_DEBUG_TRACE
, "PeerBeaconAndProbeRspSanity - wrong IE_DS_PARM (ch=%d)\n",*Channel
);
561 DBGPRINT(RT_DEBUG_TRACE
, "PeerBeaconAndProbeRspSanity - wrong IE_DS_PARM (len=%d)\n",eid_ptr
->Len
);
567 if(eid_ptr
->Len
== 6)
570 NdisMoveMemory(CfParm
, eid_ptr
->Octet
, eid_ptr
->Len
);
574 DBGPRINT(RT_DEBUG_TRACE
, "PeerBeaconAndProbeRspSanity - wrong IE_CF_PARM\n");
580 if(eid_ptr
->Len
== 2)
582 NdisMoveMemory(AtimWin
, eid_ptr
->Octet
, eid_ptr
->Len
);
586 DBGPRINT(RT_DEBUG_TRACE
, "PeerBeaconAndProbeRspSanity - wrong IE_IBSS_PARM\n");
592 if(INFRA_ON(pAd
) && SubType
== SUBTYPE_BEACON
)
594 GetTimBit((PUCHAR
)eid_ptr
, pAd
->PortCfg
.Aid
, &TimLen
, BcastFlag
, DtimCount
, DtimPeriod
, MessageToMe
);
600 // Check the OUI version, filter out non-standard usage
601 if (RTMPEqualMemory(eid_ptr
->Octet
, WPA_OUI
, 4))
603 // Copy to pVIE which will report to microsoft bssid list.
604 pVIE
->ElementID
= eid_ptr
->Eid
;
605 pVIE
->Length
= eid_ptr
->Len
;
606 NdisMoveMemory(pVIE
->data
, eid_ptr
->Octet
, eid_ptr
->Len
);
608 DBGPRINT(RT_DEBUG_INFO
, "PeerBeaconAndProbeRspSanity - Receive IE_WPA\n");
611 case IE_EXT_SUPP_RATES
:
612 // concatenate all extended rates to Rates[] and RateLen
613 *ExtendedRateIeExist
= TRUE
;
614 if (eid_ptr
->Len
<= MAX_LEN_OF_SUPPORTED_RATES
)
621 eid_rate
= eid_ptr
->Octet
;
622 for (index
= 0; index
< eid_ptr
->Len
; index
++)
624 rate
= eid_rate
[index
] & 0x7f; // Mask out basic rate set bit
625 if ((rate
== 2) || (rate
== 4) || (rate
== 11) || (rate
== 22) ||
626 (rate
== 12) || (rate
== 18) || (rate
== 24) || (rate
== 36) ||
627 (rate
== 48) || (rate
== 72) || (rate
== 96) || (rate
== 108))
628 Rate
[i
++] = eid_rate
[index
]; // Save rate with basic rate set bit if exists
630 if (i
>= MAX_LEN_OF_SUPPORTED_RATES
)
634 // Copy extended rate from desired AP's beacon. We are trying to match
635 // AP's supported and extended rate settings.
636 NdisMoveMemory(ExtRate
, eid_ptr
->Octet
, eid_ptr
->Len
);
637 *ExtRateLen
= eid_ptr
->Len
;
642 if (eid_ptr
->Len
== 1)
644 *Erp
= (UCHAR
)eid_ptr
->Octet
[0];
649 DBGPRINT(RT_DEBUG_INFO
, "PeerBeaconAndProbeRspSanity - unrecognized EID = %d\n", eid_ptr
->Eid
);
653 eid_ptr
= (PBEACON_EID_STRUCT
)((UCHAR
*)eid_ptr
+ 2 + eid_ptr
->Len
);
657 // in 802.11a band, AP may skip this DS IE in their BEACON
658 if ((pAd
->PortCfg
.Channel
> 14) && ((Sanity
& 0x04)==0))
660 *Channel
= pAd
->PortCfg
.Channel
;
666 DBGPRINT(RT_DEBUG_WARN
, "PeerBeaconAndProbeRspSanity - missing field, Sanity=0x%02x\n", Sanity
);
677 ==========================================================================
679 ==========================================================================
685 OUT UCHAR
*BcastFlag
,
686 OUT UCHAR
*DtimCount
,
687 OUT UCHAR
*DtimPeriod
,
688 OUT UCHAR
*MessageToMe
)
690 UCHAR BitCntl
, N1
, N2
, MyByte
, MyBit
;
698 // get DTIM Count from TIM element
700 *DtimCount
= *IdxPtr
;
702 // get DTIM Period from TIM element
704 *DtimPeriod
= *IdxPtr
;
706 // get Bitmap Control from TIM element
710 if ((*DtimCount
== 0) && (BitCntl
& 0x01))
716 // Parse Partial Virtual Bitmap from TIM element
717 N1
= BitCntl
& 0xfe; // N1 is the first bitmap byte#
718 N2
= *TimLen
- 4 + N1
; // N2 is the last bitmap byte#
720 if ((Aid
< (N1
<< 3)) || (Aid
>= ((N2
+ 1) << 3)))
721 *MessageToMe
= FALSE
;
724 MyByte
= (Aid
>> 3) - N1
; // my byte position in the bitmap byte-stream
725 MyBit
= Aid
% 16 - ((MyByte
& 0x01)? 8:0);
727 IdxPtr
+= (MyByte
+ 1);
730 // DBGPRINT(RT_DEBUG_WARN, ("TIM bitmap = 0x%02x\n", *IdxPtr));
732 if (*IdxPtr
& (0x01 << MyBit
))
735 *MessageToMe
= FALSE
;
738 *MessageToMe
= FALSE
;
746 * \brief Get legacy bit, right now for 11b it is always 0
748 * \return TRUE if the parameters are OK, FALSE otherwise. Always return TRUE
761 IN PRTMP_ADAPTER pAd
,
766 for (index
= 0; index
< pAd
->PortCfg
.ChannelListNum
; index
++)
768 if (channel
== pAd
->PortCfg
.ChannelList
[index
])
774 switch (pAd
->PortCfg
.CountryRegion
)
776 case REGION_FCC
: // 1 - 11
777 if ((channel
> 0) && (channel
< 12))
781 case REGION_IC
: // 1 -11
782 if ((channel
> 0) && (channel
< 12))
786 case REGION_ETSI
: // 1 - 13
787 if ((channel
> 0) && (channel
< 14))
791 case REGION_SPAIN
: // 10 - 11
792 if ((channel
> 9) && (channel
< 12))
796 case REGION_FRANCE
: // 10 -13
797 if ((channel
> 9) && (channel
< 14))
801 case REGION_MKK
: // 14
806 case REGION_MKK1
: // 1 - 14
807 if ((channel
> 0) && (channel
< 15))
811 case REGION_ISRAEL
: // 3 - 9
812 if ((channel
> 2) && (channel
< 10))