2 * Copyright (c) 2001 Atsushi Onoe
3 * Copyright (c) 2002-2004 Sam Leffler, Errno Consulting
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * Alternatively, this software may be distributed under the terms of the
18 * GNU General Public License ("GPL") version 2 as published by the Free
19 * Software Foundation.
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 * IEEE 802.11 input handling.
41 #include <ieee80211.h>
44 #define IEEE80211_VERIFY_LENGTH(_len, _minlen) do { \
45 if ((_len) < (_minlen)) { \
50 #define IEEE80211_VERIFY_ELEMENT(__elem, __maxlen) do { \
51 if ((__elem) == NULL) { \
54 if ((__elem)[1] > (__maxlen)) { \
60 /* unaligned little endian access */
61 #define LE_READ_2(p) \
63 ((((A_UINT8 *)(p))[0] ) | (((A_UINT8 *)(p))[1] << 8)))
65 #define LE_READ_4(p) \
67 ((((A_UINT8 *)(p))[0] ) | (((A_UINT8 *)(p))[1] << 8) | \
68 (((A_UINT8 *)(p))[2] << 16) | (((A_UINT8 *)(p))[3] << 24)))
72 iswpaoui(const A_UINT8
*frm
)
74 return frm
[1] > 3 && LE_READ_4(frm
+2) == ((WPA_OUI_TYPE
<<24)|WPA_OUI
);
78 iswmmoui(const A_UINT8
*frm
)
80 return frm
[1] > 3 && LE_READ_4(frm
+2) == ((WMM_OUI_TYPE
<<24)|WMM_OUI
);
84 iswmmparam(const A_UINT8
*frm
)
86 return frm
[1] > 5 && frm
[6] == WMM_PARAM_OUI_SUBTYPE
;
90 iswmminfo(const A_UINT8
*frm
)
92 return frm
[1] > 5 && frm
[6] == WMM_INFO_OUI_SUBTYPE
;
96 isatherosoui(const A_UINT8
*frm
)
98 return frm
[1] > 3 && LE_READ_4(frm
+2) == ((ATH_OUI_TYPE
<<24)|ATH_OUI
);
102 iswscoui(const A_UINT8
*frm
)
104 return frm
[1] > 3 && LE_READ_4(frm
+2) == ((0x04<<24)|WPA_OUI
);
108 wlan_parse_beacon(A_UINT8
*buf
, int framelen
, struct ieee80211_common_ie
*cie
)
113 efrm
= (A_UINT8
*) (frm
+ framelen
);
116 * beacon/probe response frame format
118 * [2] beacon interval
119 * [2] capability information
121 * [tlv] supported rates
122 * [tlv] country information
123 * [tlv] parameter set (FH/DS)
124 * [tlv] erp information
125 * [tlv] extended supported rates
128 * [tlv] Atheros Advanced Capabilities
130 IEEE80211_VERIFY_LENGTH(efrm
- frm
, 12);
131 A_MEMZERO(cie
, sizeof(*cie
));
133 cie
->ie_tstamp
= frm
; frm
+= 8;
134 cie
->ie_beaconInt
= A_LE2CPU16(*(A_UINT16
*)frm
); frm
+= 2;
135 cie
->ie_capInfo
= A_LE2CPU16(*(A_UINT16
*)frm
); frm
+= 2;
140 case IEEE80211_ELEMID_SSID
:
143 case IEEE80211_ELEMID_RATES
:
146 case IEEE80211_ELEMID_COUNTRY
:
147 cie
->ie_country
= frm
;
149 case IEEE80211_ELEMID_FHPARMS
:
151 case IEEE80211_ELEMID_DSPARMS
:
152 cie
->ie_chan
= frm
[2];
154 case IEEE80211_ELEMID_TIM
:
157 case IEEE80211_ELEMID_IBSSPARMS
:
159 case IEEE80211_ELEMID_XRATES
:
160 cie
->ie_xrates
= frm
;
162 case IEEE80211_ELEMID_ERP
:
164 //A_PRINTF("Discarding ERP Element - Bad Len\n");
167 cie
->ie_erp
= frm
[2];
169 case IEEE80211_ELEMID_RSN
:
172 case IEEE80211_ELEMID_VENDOR
:
175 } else if (iswmmoui(frm
)) {
177 } else if (isatherosoui(frm
)) {
179 } else if(iswscoui(frm
)) {
188 IEEE80211_VERIFY_ELEMENT(cie
->ie_rates
, IEEE80211_RATE_MAXSIZE
);
189 IEEE80211_VERIFY_ELEMENT(cie
->ie_ssid
, IEEE80211_NWID_LEN
);