sync hh.org
[hh.org.git] / drivers / net / wireless / acx / wlan.c
blobded598d2818a5b52113828f01f65ce424fe08764
1 /***********************************************************************
2 ** Copyright (C) 2003 ACX100 Open Source Project
3 **
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/
8 **
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
26 ** made directly to:
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>
46 #include "acx.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.
64 ** Assumptions:
65 ** 1) f->len and f->hdr are already set
66 ** 2) f->len is the length of the MAC header + data, the FCS
67 ** is NOT included
68 ** 3) all members except len and hdr are zero
69 ** Arguments:
70 ** f frame structure
72 ** Returns:
73 ** nothing
75 ** Side effects:
76 ** frame structure members are pointing at their
77 ** respective portions of the frame buffer.
79 void
80 wlan_mgmt_decode_beacon(wlan_fr_beacon_t * f)
82 u8 *ie_ptr;
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)) {
96 case WLAN_EID_SSID:
97 f->ssid = (wlan_ie_ssid_t *) ie_ptr;
98 break;
99 case WLAN_EID_SUPP_RATES:
100 f->supp_rates = (wlan_ie_supp_rates_t *) ie_ptr;
101 break;
102 case WLAN_EID_EXT_RATES:
103 f->ext_rates = (wlan_ie_supp_rates_t *) ie_ptr;
104 break;
105 case WLAN_EID_FH_PARMS:
106 f->fh_parms = (wlan_ie_fh_parms_t *) ie_ptr;
107 break;
108 case WLAN_EID_DS_PARMS:
109 f->ds_parms = (wlan_ie_ds_parms_t *) ie_ptr;
110 break;
111 case WLAN_EID_CF_PARMS:
112 f->cf_parms = (wlan_ie_cf_parms_t *) ie_ptr;
113 break;
114 case WLAN_EID_IBSS_PARMS:
115 f->ibss_parms = (wlan_ie_ibss_parms_t *) ie_ptr;
116 break;
117 case WLAN_EID_TIM:
118 f->tim = (wlan_ie_tim_t *) ie_ptr;
119 break;
120 case WLAN_EID_ERP_INFO:
121 f->erp = (wlan_ie_erp_t *) ie_ptr;
122 break;
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: */
129 /* 20 01 00 */
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:
144 /* WPA: hostap code:
145 if (pos[1] >= 4 &&
146 pos[2] == 0x00 && pos[3] == 0x50 &&
147 pos[4] == 0xf2 && pos[5] == 1) {
148 wpa = pos;
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
155 case WLAN_EID_RSN:
156 /* hostap does something with it:
157 rsn = pos;
158 rsn_len = pos[1] + 2;
160 break;
162 default:
163 LOG_BAD_EID(f->hdr, f->len, ie_ptr);
164 break;
166 ie_ptr = ie_ptr + 2 + IE_LEN(ie_ptr);
171 #ifdef UNUSED
172 void wlan_mgmt_decode_ibssatim(wlan_fr_ibssatim_t * f)
174 f->type = WLAN_FSTYPE_ATIM;
175 /*-- Fixed Fields ----*/
176 /*-- Information elements */
178 #endif /* UNUSED */
180 void
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 */
192 void
193 wlan_mgmt_decode_assocreq(wlan_fr_assocreq_t * f)
195 u8 *ie_ptr;
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)) {
209 case WLAN_EID_SSID:
210 f->ssid = (wlan_ie_ssid_t *) ie_ptr;
211 break;
212 case WLAN_EID_SUPP_RATES:
213 f->supp_rates = (wlan_ie_supp_rates_t *) ie_ptr;
214 break;
215 case WLAN_EID_EXT_RATES:
216 f->ext_rates = (wlan_ie_supp_rates_t *) ie_ptr;
217 break;
218 default:
219 LOG_BAD_EID(f->hdr, f->len, ie_ptr);
220 break;
222 ie_ptr = ie_ptr + 2 + IE_LEN(ie_ptr);
227 void
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);
243 #ifdef UNUSED
244 void
245 wlan_mgmt_decode_reassocreq(wlan_fr_reassocreq_t * f)
247 u8 *ie_ptr;
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)) {
261 case WLAN_EID_SSID:
262 f->ssid = (wlan_ie_ssid_t *) ie_ptr;
263 break;
264 case WLAN_EID_SUPP_RATES:
265 f->supp_rates = (wlan_ie_supp_rates_t *) ie_ptr;
266 break;
267 case WLAN_EID_EXT_RATES:
268 f->ext_rates = (wlan_ie_supp_rates_t *) ie_ptr;
269 break;
270 default:
271 LOG_BAD_EID(f->hdr, f->len, ie_ptr);
272 break;
274 ie_ptr = ie_ptr + 2 + IE_LEN(ie_ptr);
279 void
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);
295 void
296 wlan_mgmt_decode_probereq(wlan_fr_probereq_t * f)
298 u8 *ie_ptr;
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)) {
309 case WLAN_EID_SSID:
310 f->ssid = (wlan_ie_ssid_t *) ie_ptr;
311 break;
312 case WLAN_EID_SUPP_RATES:
313 f->supp_rates = (wlan_ie_supp_rates_t *) ie_ptr;
314 break;
315 case WLAN_EID_EXT_RATES:
316 f->ext_rates = (wlan_ie_supp_rates_t *) ie_ptr;
317 break;
318 default:
319 LOG_BAD_EID(f->hdr, f->len, ie_ptr);
320 break;
322 ie_ptr = ie_ptr + 2 + IE_LEN(ie_ptr);
325 #endif /* UNUSED */
328 /* TODO: decoding of beacon and proberesp can be merged (similar structure) */
329 void
330 wlan_mgmt_decode_proberesp(wlan_fr_proberesp_t * f)
332 u8 *ie_ptr;
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)) {
346 case WLAN_EID_SSID:
347 f->ssid = (wlan_ie_ssid_t *) ie_ptr;
348 break;
349 case WLAN_EID_SUPP_RATES:
350 f->supp_rates = (wlan_ie_supp_rates_t *) ie_ptr;
351 break;
352 case WLAN_EID_EXT_RATES:
353 f->ext_rates = (wlan_ie_supp_rates_t *) ie_ptr;
354 break;
355 case WLAN_EID_FH_PARMS:
356 f->fh_parms = (wlan_ie_fh_parms_t *) ie_ptr;
357 break;
358 case WLAN_EID_DS_PARMS:
359 f->ds_parms = (wlan_ie_ds_parms_t *) ie_ptr;
360 break;
361 case WLAN_EID_CF_PARMS:
362 f->cf_parms = (wlan_ie_cf_parms_t *) ie_ptr;
363 break;
364 case WLAN_EID_IBSS_PARMS:
365 f->ibss_parms = (wlan_ie_ibss_parms_t *) ie_ptr;
366 break;
367 #ifdef DONT_DO_IT_ADD_REAL_HANDLING_INSTEAD
368 case WLAN_EID_COUNTRY:
369 break;
371 #endif
372 #ifdef SENT_HERE_BY_OPENWRT
373 /* should those be trapped or handled?? */
374 case WLAN_EID_ERP_INFO:
375 break;
376 case WLAN_EID_NONERP:
377 break;
378 case WLAN_EID_GENERIC:
379 break;
380 #endif
381 default:
382 LOG_BAD_EID(f->hdr, f->len, ie_ptr);
383 break;
386 ie_ptr = ie_ptr + 2 + IE_LEN(ie_ptr);
391 void
392 wlan_mgmt_decode_authen(wlan_fr_authen_t * f)
394 u8 *ie_ptr;
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;
412 void
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 */