1 /*************************************************************************
3 * 4F, No. 2 Technology 5th Rd. *
4 * Science-based Industrial Park *
5 * Hsin-chu, Taiwan, R.O.C. *
7 * (c) Copyright 2002, Ralink Technology, Inc. *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
14 * This program is distributed in the hope that it will be useful, *
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17 * GNU General Public License for more details. *
19 * You should have received a copy of the GNU General Public License *
20 * along with this program; if not, write to the *
21 * Free Software Foundation, Inc., *
22 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 *************************************************************************/
26 #include "rt_config.h"
28 UCHAR WPA_OUI
[] = {0x00, 0x50, 0xf2, 0x01};
31 ==========================================================================
33 MLME message sanity check
35 TRUE if all parameters are OK, FALSE otherwise
36 ==========================================================================
38 BOOLEAN
MlmeScanReqSanity(
47 MLME_SCAN_REQ_STRUCT
*Info
;
49 Info
= (MLME_SCAN_REQ_STRUCT
*)(Msg
);
50 *BssType
= Info
->BssType
;
51 *SsidLen
= Info
->SsidLen
;
52 NdisMoveMemory(Ssid
, Info
->Ssid
, *SsidLen
);
53 *ScanType
= Info
->ScanType
;
55 if ((*BssType
== BSS_INFRA
|| *BssType
== BSS_INDEP
|| *BssType
== BSS_ANY
) &&
56 (*ScanType
== SCAN_ACTIVE
|| *ScanType
== SCAN_PASSIVE
))
60 DBGPRINT(RT_DEBUG_TRACE
, "MlmeScanReqSanity fail - wrong BssType or ScanType\n");
66 ==========================================================================
68 MLME message sanity check
70 TRUE if all parameters are OK, FALSE otherwise
71 ==========================================================================
73 BOOLEAN
MlmeStartReqSanity(
80 MLME_START_REQ_STRUCT
*Info
;
82 Info
= (MLME_START_REQ_STRUCT
*)(Msg
);
84 if (Info
->SsidLen
> MAX_LEN_OF_SSID
)
86 DBGPRINT(RT_DEBUG_TRACE
, "MlmeStartReqSanity fail - wrong SSID length\n");
90 *SsidLen
= Info
->SsidLen
;
91 NdisMoveMemory(Ssid
, Info
->Ssid
, *SsidLen
);
97 ==========================================================================
99 MLME message sanity check
101 TRUE if all parameters are OK, FALSE otherwise
102 ==========================================================================
104 BOOLEAN
MlmeAssocReqSanity(
105 IN PRTMP_ADAPTER pAd
,
109 OUT USHORT
*CapabilityInfo
,
111 OUT USHORT
*ListenIntv
)
113 MLME_ASSOC_REQ_STRUCT
*Info
;
115 Info
= (MLME_ASSOC_REQ_STRUCT
*)Msg
;
116 *Timeout
= Info
->Timeout
; // timeout
117 COPY_MAC_ADDR(ApAddr
, &Info
->Addr
); // AP address
118 *CapabilityInfo
= Info
->CapabilityInfo
; // capability info
119 *ListenIntv
= Info
->ListenIntv
;
125 ==========================================================================
127 MLME message sanity check
129 TRUE if all parameters are OK, FALSE otherwise
130 ==========================================================================
132 BOOLEAN
MlmeAuthReqSanity(
133 IN PRTMP_ADAPTER pAd
,
140 MLME_AUTH_REQ_STRUCT
*Info
;
142 Info
= (MLME_AUTH_REQ_STRUCT
*)Msg
;
143 COPY_MAC_ADDR(Addr
, &Info
->Addr
);
144 *Timeout
= Info
->Timeout
;
147 if ((*Alg
== Ndis802_11AuthModeShared
|| *Alg
== Ndis802_11AuthModeOpen
) && !MAC_ADDR_IS_GROUP(*Addr
))
153 DBGPRINT(RT_DEBUG_TRACE
, "MlmeAuthReqSanity fail - wrong algorithm\n");
159 ==========================================================================
161 MLME message sanity check
163 TRUE if all parameters are OK, FALSE otherwise
164 ==========================================================================
166 BOOLEAN
PeerAssocRspSanity(
167 IN PRTMP_ADAPTER pAd
,
171 OUT USHORT
*CapabilityInfo
,
176 OUT BOOLEAN
*ExtendedRateIeExist
)
179 MACFRAME
*Fr
= (MACFRAME
*)Msg
;
180 PBEACON_EID_STRUCT eid_ptr
;
182 COPY_MAC_ADDR(Addr2
, &Fr
->Hdr
.Addr2
);
185 NdisMoveMemory(CapabilityInfo
, &Fr
->Octet
[0], 2);
186 NdisMoveMemory(Status
, &Fr
->Octet
[2], 2);
187 // Mask out unnecessary capability information
188 *CapabilityInfo
&= SUPPORTED_CAPABILITY_INFO
;
190 if (*Status
== MLME_SUCCESS
)
192 NdisMoveMemory(Aid
, &Fr
->Octet
[4], 2);
193 *Aid
= (*Aid
) & 0x3fff; // AID is low 14-bit
195 // -- get supported rates from payload and advance the pointer
196 IeType
= Fr
->Octet
[6];
197 *RatesLen
= Fr
->Octet
[7];
198 if ((IeType
!= IE_SUPP_RATES
) || (*RatesLen
> MAX_LEN_OF_SUPPORTED_RATES
))
200 DBGPRINT(RT_DEBUG_TRACE
, "PeerAssocRspSanity fail - wrong SupportedRates IE\n");
204 NdisMoveMemory(Rates
, &Fr
->Octet
[8], *RatesLen
);
206 // many AP implement proprietary IEs in non-standard order, we'd better
207 // tolerate mis-ordered IEs to get best compatibility
208 *ExtendedRateIeExist
= FALSE
;
209 eid_ptr
= (PBEACON_EID_STRUCT
) &Fr
->Octet
[8 + (*RatesLen
)];
211 // get variable fields from payload and advance the pointer
212 while (((UCHAR
*)eid_ptr
+ eid_ptr
->Len
+ 1) < ((UCHAR
*)Fr
+ MsgLen
))
214 switch (eid_ptr
->Eid
)
216 case IE_EXT_SUPP_RATES
:
217 *ExtendedRateIeExist
= TRUE
;
218 if ((*RatesLen
+ eid_ptr
->Len
) <= MAX_LEN_OF_SUPPORTED_RATES
)
220 NdisMoveMemory(&Rates
[*RatesLen
], eid_ptr
->Octet
, eid_ptr
->Len
);
221 *RatesLen
= (*RatesLen
) + eid_ptr
->Len
;
225 NdisMoveMemory(&Rates
[*RatesLen
], eid_ptr
->Octet
, MAX_LEN_OF_SUPPORTED_RATES
- (*RatesLen
));
226 *RatesLen
= MAX_LEN_OF_SUPPORTED_RATES
;
230 DBGPRINT(RT_DEBUG_TRACE
, "PeerAssocRspSanity - ignore unrecognized EID = %d\n", eid_ptr
->Eid
);
234 eid_ptr
= (PBEACON_EID_STRUCT
)((UCHAR
*)eid_ptr
+ 2 + eid_ptr
->Len
);
243 ==========================================================================
245 MLME message sanity check
247 TRUE if all parameters are OK, FALSE otherwise
248 ==========================================================================
250 BOOLEAN
PeerDisassocSanity(
251 IN PRTMP_ADAPTER pAd
,
257 MACFRAME
*Fr
= (MACFRAME
*)Msg
;
259 COPY_MAC_ADDR(Addr2
, &Fr
->Hdr
.Addr2
);
260 NdisMoveMemory(Reason
, &Fr
->Octet
[0], 2);
266 ==========================================================================
268 MLME message sanity check
270 TRUE if all parameters are OK, FALSE otherwise
271 ==========================================================================
273 BOOLEAN
PeerDeauthSanity(
274 IN PRTMP_ADAPTER pAd
,
280 MACFRAME
*Fr
= (MACFRAME
*)Msg
;
282 COPY_MAC_ADDR(Addr2
, &Fr
->Hdr
.Addr2
);
283 NdisMoveMemory(Reason
, &Fr
->Octet
[0], 2);
289 ==========================================================================
291 MLME message sanity check
293 TRUE if all parameters are OK, FALSE otherwise
294 ==========================================================================
296 BOOLEAN
PeerAuthSanity(
297 IN PRTMP_ADAPTER pAd
,
306 MACFRAME
*Fr
= (MACFRAME
*)Msg
;
308 COPY_MAC_ADDR(Addr
, &Fr
->Hdr
.Addr2
);
309 NdisMoveMemory(Alg
, &Fr
->Octet
[0], 2);
310 NdisMoveMemory(Seq
, &Fr
->Octet
[2], 2);
311 NdisMoveMemory(Status
, &Fr
->Octet
[4], 2);
313 if (*Alg
== Ndis802_11AuthModeOpen
)
315 if (*Seq
== 1 || *Seq
== 2)
321 DBGPRINT(RT_DEBUG_TRACE
, "PeerAuthSanity fail - wrong Seg#\n");
325 else if (*Alg
== Ndis802_11AuthModeShared
)
327 if (*Seq
== 1 || *Seq
== 4)
331 else if (*Seq
== 2 || *Seq
== 3)
333 NdisMoveMemory(ChlgText
, &Fr
->Octet
[8], CIPHER_TEXT_LEN
);
338 DBGPRINT(RT_DEBUG_TRACE
, "PeerAuthSanity fail - wrong Seg#\n");
344 DBGPRINT(RT_DEBUG_TRACE
, "PeerAuthSanity fail - wrong algorithm\n");
350 ==========================================================================
352 MLME message sanity check
354 TRUE if all parameters are OK, FALSE otherwise
355 ==========================================================================
357 BOOLEAN
PeerProbeReqSanity(
358 IN PRTMP_ADAPTER pAd
,
364 // OUT UCHAR Rates[],
365 // OUT UCHAR *RatesLen)
370 MACFRAME
*Fr
= (MACFRAME
*)Msg
;
372 COPY_MAC_ADDR(Addr2
, &Fr
->Hdr
.Addr2
);
374 if ((Fr
->Octet
[0] != IE_SSID
) || (Fr
->Octet
[1] > MAX_LEN_OF_SSID
))
376 DBGPRINT(RT_DEBUG_TRACE
, "PeerProbeReqSanity fail - wrong SSID IE(Type=%d,Len=%d)\n",Fr
->Octet
[0],Fr
->Octet
[1]);
380 *SsidLen
= Fr
->Octet
[1];
381 NdisMoveMemory(Ssid
, &Fr
->Octet
[2], *SsidLen
);
386 // -- get supported rates from payload and advance the pointer
387 IeType
= Fr
->Octet
[Idx
];
388 RateLen
= Fr
->Octet
[Idx
+ 1];
389 if (IeType
!= IE_SUPP_RATES
)
391 DBGPRINT(RT_DEBUG_TRACE
, "PeerProbeReqSanity fail - wrong SupportRates IE(Type=%d,Len=%d)\n",Fr
->Octet
[Idx
],Fr
->Octet
[Idx
+1]);
396 if ((pAd
->PortCfg
.AdhocMode
== 2) && (RateLen
< 8))
404 ==========================================================================
406 MLME message sanity check
408 TRUE if all parameters are OK, FALSE otherwise
409 ==========================================================================
411 BOOLEAN
PeerBeaconAndProbeRspSanity(
412 IN PRTMP_ADAPTER pAd
,
420 OUT USHORT
*BeaconPeriod
,
422 OUT LARGE_INTEGER
*Timestamp
,
423 OUT BOOLEAN
*CfExist
,
426 OUT USHORT
*CapabilityInfo
,
429 OUT BOOLEAN
*ExtendedRateIeExist
,
431 OUT UCHAR
*DtimCount
,
432 OUT UCHAR
*DtimPeriod
,
433 OUT UCHAR
*BcastFlag
,
434 OUT UCHAR
*MessageToMe
,
437 OUT UCHAR
*SupRateLen
,
439 OUT UCHAR
*ExtRateLen
,
440 OUT PNDIS_802_11_VARIABLE_IEs pVIE
)
444 PBEACON_EID_STRUCT eid_ptr
;
448 // Add for 3 necessary EID field check
451 *ExtendedRateIeExist
= FALSE
;
454 Fr
= (MACFRAME
*)Msg
;
456 // get subtype from header
457 SubType
= (UCHAR
)Fr
->Hdr
.SubType
;
459 // get Addr2 and BSSID from header
460 COPY_MAC_ADDR(Addr2
, &Fr
->Hdr
.Addr2
);
461 COPY_MAC_ADDR(Bssid
, &Fr
->Hdr
.Addr3
);
465 // get timestamp from payload and advance the pointer
466 NdisMoveMemory(Timestamp
, Ptr
, TIMESTAMP_LEN
);
467 Ptr
+= TIMESTAMP_LEN
;
469 // get beacon interval from payload and advance the pointer
470 NdisMoveMemory(BeaconPeriod
, Ptr
, 2);
473 // get capability info from payload and advance the pointer
474 NdisMoveMemory(CapabilityInfo
, Ptr
, 2);
476 if (CAP_IS_ESS_ON(*CapabilityInfo
))
478 *BssType
= BSS_INFRA
;
482 *BssType
= BSS_INDEP
;
485 // Mask out unnecessary capability information
486 *CapabilityInfo
&= SUPPORTED_CAPABILITY_INFO
;
488 eid_ptr
= (PBEACON_EID_STRUCT
) Ptr
;
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))