1 /***********************************************************************
2 ** Copyright (C) 2003 ACX100 Open Source Project
4 ** The contents of this file are subject to the Mozilla Public
5 ** License Version 1.1 (the "License"); you may not use this file
6 ** except in compliance with the License. You may obtain a copy of
7 ** the License at http://www.mozilla.org/MPL/
9 ** Software distributed under the License is distributed on an "AS
10 ** IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
11 ** implied. See the License for the specific language governing
12 ** rights and limitations under the License.
14 ** Alternatively, the contents of this file may be used under the
15 ** terms of the GNU Public License version 2 (the "GPL"), in which
16 ** case the provisions of the GPL are applicable instead of the
17 ** above. If you wish to allow the use of your version of this file
18 ** only under the terms of the GPL and not to allow others to use
19 ** your version of this file under the MPL, indicate your decision
20 ** by deleting the provisions above and replace them with the notice
21 ** and other provisions required by the GPL. If you do not delete
22 ** the provisions above, a recipient may use your version of this
23 ** file under either the MPL or the GPL.
24 ** ---------------------------------------------------------------------
25 ** Inquiries regarding the ACX100 Open Source Project can be
28 ** acx100-users@lists.sf.net
29 ** http://acx100.sf.net
30 ** ---------------------------------------------------------------------
33 /***********************************************************************
34 ** This code is based on elements which are
35 ** Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
36 ** info@linux-wlan.com
37 ** http://www.linux-wlan.com
40 #include <linux/version.h>
41 #include <linux/types.h>
42 #include <linux/if_arp.h>
43 #include <linux/wireless.h>
44 #include <net/iw_handler.h>
49 /***********************************************************************
51 #define LOG_BAD_EID(hdr,len,ie_ptr) acx_log_bad_eid(hdr, len, ((wlan_ie_t*)ie_ptr))
53 #define IE_EID(ie_ptr) (((wlan_ie_t*)(ie_ptr))->eid)
54 #define IE_LEN(ie_ptr) (((wlan_ie_t*)(ie_ptr))->len)
55 #define OFFSET(hdr,off) (WLAN_HDR_A3_DATAP(hdr) + (off))
58 /***********************************************************************
59 ** wlan_mgmt_decode_XXX
61 ** Given a complete frame in f->hdr, sets the pointers in f to
62 ** the areas that correspond to the parts of the frame.
65 ** 1) f->len and f->hdr are already set
66 ** 2) f->len is the length of the MAC header + data, the FCS
68 ** 3) all members except len and hdr are zero
76 ** frame structure members are pointing at their
77 ** respective portions of the frame buffer.
80 wlan_mgmt_decode_beacon(wlan_fr_beacon_t
* f
)
83 u8
*end
= (u8
*)f
->hdr
+ f
->len
;
85 f
->type
= WLAN_FSTYPE_BEACON
;
87 /*-- Fixed Fields ----*/
88 f
->ts
= (u64
*) OFFSET(f
->hdr
, WLAN_BEACON_OFF_TS
);
89 f
->bcn_int
= (u16
*) OFFSET(f
->hdr
, WLAN_BEACON_OFF_BCN_INT
);
90 f
->cap_info
= (u16
*) OFFSET(f
->hdr
, WLAN_BEACON_OFF_CAPINFO
);
92 /*-- Information elements */
93 ie_ptr
= OFFSET(f
->hdr
, WLAN_BEACON_OFF_SSID
);
94 while (ie_ptr
< end
) {
95 switch (IE_EID(ie_ptr
)) {
97 f
->ssid
= (wlan_ie_ssid_t
*) ie_ptr
;
99 case WLAN_EID_SUPP_RATES
:
100 f
->supp_rates
= (wlan_ie_supp_rates_t
*) ie_ptr
;
102 case WLAN_EID_EXT_RATES
:
103 f
->ext_rates
= (wlan_ie_supp_rates_t
*) ie_ptr
;
105 case WLAN_EID_FH_PARMS
:
106 f
->fh_parms
= (wlan_ie_fh_parms_t
*) ie_ptr
;
108 case WLAN_EID_DS_PARMS
:
109 f
->ds_parms
= (wlan_ie_ds_parms_t
*) ie_ptr
;
111 case WLAN_EID_CF_PARMS
:
112 f
->cf_parms
= (wlan_ie_cf_parms_t
*) ie_ptr
;
114 case WLAN_EID_IBSS_PARMS
:
115 f
->ibss_parms
= (wlan_ie_ibss_parms_t
*) ie_ptr
;
118 f
->tim
= (wlan_ie_tim_t
*) ie_ptr
;
120 case WLAN_EID_ERP_INFO
:
121 f
->erp
= (wlan_ie_erp_t
*) ie_ptr
;
124 case WLAN_EID_COUNTRY
:
125 /* was seen: 07 06 47 42 20 01 0D 14 */
126 case WLAN_EID_PWR_CONSTRAINT
:
127 /* was seen by Ashwin Mansinghka <ashwin_man@yahoo.com> from
128 Atheros-based PCI card in AP mode using madwifi drivers: */
130 case WLAN_EID_NONERP
:
131 /* was seen from WRT54GS with OpenWrt: 2F 01 07 */
132 case WLAN_EID_UNKNOWN128
:
133 /* was seen by Jacek Jablonski <conexion2000@gmail.com> from Orinoco AP */
134 /* 80 06 00 60 1D 2C 3B 00 */
135 case WLAN_EID_UNKNOWN133
:
136 /* was seen by David Bronaugh <dbronaugh@linuxboxen.org> from ???? */
137 /* 85 1E 00 00 84 12 07 00 FF 00 11 00 61 70 63 31 */
138 /* 63 73 72 30 34 32 00 00 00 00 00 00 00 00 00 25 */
139 case WLAN_EID_UNKNOWN223
:
140 /* was seen by Carlos Martin <carlosmn@gmail.com> from ???? */
141 /* DF 20 01 1E 04 00 00 00 06 63 09 02 FF 0F 30 30 */
142 /* 30 42 36 42 33 34 30 39 46 31 00 00 00 00 00 00 00 00 */
143 case WLAN_EID_GENERIC
:
146 pos[2] == 0x00 && pos[3] == 0x50 &&
147 pos[4] == 0xf2 && pos[5] == 1) {
149 wpa_len = pos[1] + 2;
151 TI x4 mode: seen DD 04 08 00 28 00
152 (08 00 28 is TI's OUI)
153 last byte is probably 0/1 - disabled/enabled
156 /* hostap does something with it:
158 rsn_len = pos[1] + 2;
163 LOG_BAD_EID(f
->hdr
, f
->len
, ie_ptr
);
166 ie_ptr
= ie_ptr
+ 2 + IE_LEN(ie_ptr
);
172 void wlan_mgmt_decode_ibssatim(wlan_fr_ibssatim_t
* f
)
174 f
->type
= WLAN_FSTYPE_ATIM
;
175 /*-- Fixed Fields ----*/
176 /*-- Information elements */
181 wlan_mgmt_decode_disassoc(wlan_fr_disassoc_t
* f
)
183 f
->type
= WLAN_FSTYPE_DISASSOC
;
185 /*-- Fixed Fields ----*/
186 f
->reason
= (u16
*) OFFSET(f
->hdr
, WLAN_DISASSOC_OFF_REASON
);
188 /*-- Information elements */
193 wlan_mgmt_decode_assocreq(wlan_fr_assocreq_t
* f
)
196 u8
*end
= (u8
*)f
->hdr
+ f
->len
;
199 f
->type
= WLAN_FSTYPE_ASSOCREQ
;
201 /*-- Fixed Fields ----*/
202 f
->cap_info
= (u16
*) OFFSET(f
->hdr
, WLAN_ASSOCREQ_OFF_CAP_INFO
);
203 f
->listen_int
= (u16
*) OFFSET(f
->hdr
, WLAN_ASSOCREQ_OFF_LISTEN_INT
);
205 /*-- Information elements */
206 ie_ptr
= OFFSET(f
->hdr
, WLAN_ASSOCREQ_OFF_SSID
);
207 while (ie_ptr
< end
) {
208 switch (IE_EID(ie_ptr
)) {
210 f
->ssid
= (wlan_ie_ssid_t
*) ie_ptr
;
212 case WLAN_EID_SUPP_RATES
:
213 f
->supp_rates
= (wlan_ie_supp_rates_t
*) ie_ptr
;
215 case WLAN_EID_EXT_RATES
:
216 f
->ext_rates
= (wlan_ie_supp_rates_t
*) ie_ptr
;
219 LOG_BAD_EID(f
->hdr
, f
->len
, ie_ptr
);
222 ie_ptr
= ie_ptr
+ 2 + IE_LEN(ie_ptr
);
228 wlan_mgmt_decode_assocresp(wlan_fr_assocresp_t
* f
)
230 f
->type
= WLAN_FSTYPE_ASSOCRESP
;
232 /*-- Fixed Fields ----*/
233 f
->cap_info
= (u16
*) OFFSET(f
->hdr
, WLAN_ASSOCRESP_OFF_CAP_INFO
);
234 f
->status
= (u16
*) OFFSET(f
->hdr
, WLAN_ASSOCRESP_OFF_STATUS
);
235 f
->aid
= (u16
*) OFFSET(f
->hdr
, WLAN_ASSOCRESP_OFF_AID
);
237 /*-- Information elements */
238 f
->supp_rates
= (wlan_ie_supp_rates_t
*)
239 OFFSET(f
->hdr
, WLAN_ASSOCRESP_OFF_SUPP_RATES
);
245 wlan_mgmt_decode_reassocreq(wlan_fr_reassocreq_t
* f
)
248 u8
*end
= (u8
*)f
->hdr
+ f
->len
;
250 f
->type
= WLAN_FSTYPE_REASSOCREQ
;
252 /*-- Fixed Fields ----*/
253 f
->cap_info
= (u16
*) OFFSET(f
->hdr
, WLAN_REASSOCREQ_OFF_CAP_INFO
);
254 f
->listen_int
= (u16
*) OFFSET(f
->hdr
, WLAN_REASSOCREQ_OFF_LISTEN_INT
);
255 f
->curr_ap
= (u8
*) OFFSET(f
->hdr
, WLAN_REASSOCREQ_OFF_CURR_AP
);
257 /*-- Information elements */
258 ie_ptr
= OFFSET(f
->hdr
, WLAN_REASSOCREQ_OFF_SSID
);
259 while (ie_ptr
< end
) {
260 switch (IE_EID(ie_ptr
)) {
262 f
->ssid
= (wlan_ie_ssid_t
*) ie_ptr
;
264 case WLAN_EID_SUPP_RATES
:
265 f
->supp_rates
= (wlan_ie_supp_rates_t
*) ie_ptr
;
267 case WLAN_EID_EXT_RATES
:
268 f
->ext_rates
= (wlan_ie_supp_rates_t
*) ie_ptr
;
271 LOG_BAD_EID(f
->hdr
, f
->len
, ie_ptr
);
274 ie_ptr
= ie_ptr
+ 2 + IE_LEN(ie_ptr
);
280 wlan_mgmt_decode_reassocresp(wlan_fr_reassocresp_t
* f
)
282 f
->type
= WLAN_FSTYPE_REASSOCRESP
;
284 /*-- Fixed Fields ----*/
285 f
->cap_info
= (u16
*) OFFSET(f
->hdr
, WLAN_REASSOCRESP_OFF_CAP_INFO
);
286 f
->status
= (u16
*) OFFSET(f
->hdr
, WLAN_REASSOCRESP_OFF_STATUS
);
287 f
->aid
= (u16
*) OFFSET(f
->hdr
, WLAN_REASSOCRESP_OFF_AID
);
289 /*-- Information elements */
290 f
->supp_rates
= (wlan_ie_supp_rates_t
*)
291 OFFSET(f
->hdr
, WLAN_REASSOCRESP_OFF_SUPP_RATES
);
296 wlan_mgmt_decode_probereq(wlan_fr_probereq_t
* f
)
299 u8
*end
= (u8
*)f
->hdr
+ f
->len
;
301 f
->type
= WLAN_FSTYPE_PROBEREQ
;
303 /*-- Fixed Fields ----*/
305 /*-- Information elements */
306 ie_ptr
= OFFSET(f
->hdr
, WLAN_PROBEREQ_OFF_SSID
);
307 while (ie_ptr
< end
) {
308 switch (IE_EID(ie_ptr
)) {
310 f
->ssid
= (wlan_ie_ssid_t
*) ie_ptr
;
312 case WLAN_EID_SUPP_RATES
:
313 f
->supp_rates
= (wlan_ie_supp_rates_t
*) ie_ptr
;
315 case WLAN_EID_EXT_RATES
:
316 f
->ext_rates
= (wlan_ie_supp_rates_t
*) ie_ptr
;
319 LOG_BAD_EID(f
->hdr
, f
->len
, ie_ptr
);
322 ie_ptr
= ie_ptr
+ 2 + IE_LEN(ie_ptr
);
328 /* TODO: decoding of beacon and proberesp can be merged (similar structure) */
330 wlan_mgmt_decode_proberesp(wlan_fr_proberesp_t
* f
)
333 u8
*end
= (u8
*)f
->hdr
+ f
->len
;
335 f
->type
= WLAN_FSTYPE_PROBERESP
;
337 /*-- Fixed Fields ----*/
338 f
->ts
= (u64
*) OFFSET(f
->hdr
, WLAN_PROBERESP_OFF_TS
);
339 f
->bcn_int
= (u16
*) OFFSET(f
->hdr
, WLAN_PROBERESP_OFF_BCN_INT
);
340 f
->cap_info
= (u16
*) OFFSET(f
->hdr
, WLAN_PROBERESP_OFF_CAP_INFO
);
342 /*-- Information elements */
343 ie_ptr
= OFFSET(f
->hdr
, WLAN_PROBERESP_OFF_SSID
);
344 while (ie_ptr
< end
) {
345 switch (IE_EID(ie_ptr
)) {
347 f
->ssid
= (wlan_ie_ssid_t
*) ie_ptr
;
349 case WLAN_EID_SUPP_RATES
:
350 f
->supp_rates
= (wlan_ie_supp_rates_t
*) ie_ptr
;
352 case WLAN_EID_EXT_RATES
:
353 f
->ext_rates
= (wlan_ie_supp_rates_t
*) ie_ptr
;
355 case WLAN_EID_FH_PARMS
:
356 f
->fh_parms
= (wlan_ie_fh_parms_t
*) ie_ptr
;
358 case WLAN_EID_DS_PARMS
:
359 f
->ds_parms
= (wlan_ie_ds_parms_t
*) ie_ptr
;
361 case WLAN_EID_CF_PARMS
:
362 f
->cf_parms
= (wlan_ie_cf_parms_t
*) ie_ptr
;
364 case WLAN_EID_IBSS_PARMS
:
365 f
->ibss_parms
= (wlan_ie_ibss_parms_t
*) ie_ptr
;
367 #ifdef DONT_DO_IT_ADD_REAL_HANDLING_INSTEAD
368 case WLAN_EID_COUNTRY
:
372 #ifdef SENT_HERE_BY_OPENWRT
373 /* should those be trapped or handled?? */
374 case WLAN_EID_ERP_INFO
:
376 case WLAN_EID_NONERP
:
378 case WLAN_EID_GENERIC
:
382 LOG_BAD_EID(f
->hdr
, f
->len
, ie_ptr
);
386 ie_ptr
= ie_ptr
+ 2 + IE_LEN(ie_ptr
);
392 wlan_mgmt_decode_authen(wlan_fr_authen_t
* f
)
395 u8
*end
= (u8
*)f
->hdr
+ f
->len
;
397 f
->type
= WLAN_FSTYPE_AUTHEN
;
399 /*-- Fixed Fields ----*/
400 f
->auth_alg
= (u16
*) OFFSET(f
->hdr
, WLAN_AUTHEN_OFF_AUTH_ALG
);
401 f
->auth_seq
= (u16
*) OFFSET(f
->hdr
, WLAN_AUTHEN_OFF_AUTH_SEQ
);
402 f
->status
= (u16
*) OFFSET(f
->hdr
, WLAN_AUTHEN_OFF_STATUS
);
404 /*-- Information elements */
405 ie_ptr
= OFFSET(f
->hdr
, WLAN_AUTHEN_OFF_CHALLENGE
);
406 if ((ie_ptr
< end
) && (IE_EID(ie_ptr
) == WLAN_EID_CHALLENGE
)) {
407 f
->challenge
= (wlan_ie_challenge_t
*) ie_ptr
;
413 wlan_mgmt_decode_deauthen(wlan_fr_deauthen_t
* f
)
415 f
->type
= WLAN_FSTYPE_DEAUTHEN
;
417 /*-- Fixed Fields ----*/
418 f
->reason
= (u16
*) OFFSET(f
->hdr
, WLAN_DEAUTHEN_OFF_REASON
);
420 /*-- Information elements */