1/*
2 * WPA Supplicant - Client mode MLME
3 * Copyright (c) 2003-2006, Jouni Malinen <j@w1.fi>
4 * Copyright (c) 2004, Instant802 Networks, Inc.
5 * Copyright (c) 2005-2006, Devicescape Software, Inc.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * Alternatively, this software may be distributed under the terms of BSD
12 * license.
13 *
14 * See README and COPYING for more details.
15 */
16
17#include "includes.h"
18
19#include "common.h"
20#include "eloop.h"
21#include "config.h"
22#include "wpa_supplicant.h"
23#include "wpa_supplicant_i.h"
24#include "wpa.h"
25#include "os.h"
26#include "l2_packet.h"
27#include "driver.h"
28#include "mlme.h"
29
30
31/* Timeouts and intervals in milliseconds */
32#define IEEE80211_AUTH_TIMEOUT (200)
33#define IEEE80211_AUTH_MAX_TRIES 3
34#define IEEE80211_ASSOC_TIMEOUT (200)
35#define IEEE80211_ASSOC_MAX_TRIES 3
36#define IEEE80211_MONITORING_INTERVAL (2000)
37#define IEEE80211_PROBE_INTERVAL (60000)
38#define IEEE80211_RETRY_AUTH_INTERVAL (1000)
39#define IEEE80211_SCAN_INTERVAL (2000)
40#define IEEE80211_SCAN_INTERVAL_SLOW (15000)
41#define IEEE80211_IBSS_JOIN_TIMEOUT (20000)
42
43#define IEEE80211_PROBE_DELAY (33)
44#define IEEE80211_CHANNEL_TIME (33)
45#define IEEE80211_PASSIVE_CHANNEL_TIME (200)
46#define IEEE80211_SCAN_RESULT_EXPIRE (10000)
47#define IEEE80211_IBSS_MERGE_INTERVAL (30000)
48#define IEEE80211_IBSS_INACTIVITY_LIMIT (60000)
49
50#define IEEE80211_IBSS_MAX_STA_ENTRIES 128
51
52
53/* Information Element IDs */
54#define WLAN_EID_SSID 0
55#define WLAN_EID_SUPP_RATES 1
56#define WLAN_EID_FH_PARAMS 2
57#define WLAN_EID_DS_PARAMS 3
58#define WLAN_EID_CF_PARAMS 4
59#define WLAN_EID_TIM 5
60#define WLAN_EID_IBSS_PARAMS 6
61#define WLAN_EID_COUNTRY 7
62#define WLAN_EID_CHALLENGE 16
63/* EIDs defined as part fo 11h - starts */
64#define WLAN_EID_PWR_CONSTRAINT	32
65#define WLAN_EID_PWR_CAPABILITY	33
66#define WLAN_EID_TPC_REQUEST	34
67#define WLAN_EID_TPC_REPORT	35
68#define WLAN_EID_SUPPORTED_CHANNELS	36
69#define WLAN_EID_CHANNEL_SWITCH	37
70#define WLAN_EID_MEASURE_REQUEST	38
71#define WLAN_EID_MEASURE_REPORT	39
72#define WLAN_EID_QUITE	40
73#define WLAN_EID_IBSS_DFS	41
74/* EIDs defined as part fo 11h - ends */
75#define WLAN_EID_ERP_INFO 42
76#define WLAN_EID_RSN 48
77#define WLAN_EID_EXT_SUPP_RATES 50
78#define WLAN_EID_VENDOR_SPECIFIC 221
79
80
81#ifdef _MSC_VER
82#pragma pack(push, 1)
83#endif /* _MSC_VER */
84
85struct ieee80211_mgmt {
86	u16 frame_control;
87	u16 duration;
88	u8 da[6];
89	u8 sa[6];
90	u8 bssid[6];
91	u16 seq_ctrl;
92	union {
93		struct {
94			u16 auth_alg;
95			u16 auth_transaction;
96			u16 status_code;
97			/* possibly followed by Challenge text */
98			u8 variable[0];
99		} STRUCT_PACKED auth;
100		struct {
101			u16 reason_code;
102		} STRUCT_PACKED deauth;
103		struct {
104			u16 capab_info;
105			u16 listen_interval;
106			/* followed by SSID and Supported rates */
107			u8 variable[0];
108		} STRUCT_PACKED assoc_req;
109		struct {
110			u16 capab_info;
111			u16 status_code;
112			u16 aid;
113			/* followed by Supported rates */
114			u8 variable[0];
115		} STRUCT_PACKED assoc_resp, reassoc_resp;
116		struct {
117			u16 capab_info;
118			u16 listen_interval;
119			u8 current_ap[6];
120			/* followed by SSID and Supported rates */
121			u8 variable[0];
122		} STRUCT_PACKED reassoc_req;
123		struct {
124			u16 reason_code;
125		} STRUCT_PACKED disassoc;
126		struct {
127			u8 timestamp[8];
128			u16 beacon_int;
129			u16 capab_info;
130			/* followed by some of SSID, Supported rates,
131			 * FH Params, DS Params, CF Params, IBSS Params, TIM */
132			u8 variable[0];
133		} STRUCT_PACKED beacon;
134		struct {
135			/* only variable items: SSID, Supported rates */
136			u8 variable[0];
137		} STRUCT_PACKED probe_req;
138		struct {
139			u8 timestamp[8];
140			u16 beacon_int;
141			u16 capab_info;
142			/* followed by some of SSID, Supported rates,
143			 * FH Params, DS Params, CF Params, IBSS Params */
144			u8 variable[0];
145		} STRUCT_PACKED probe_resp;
146		struct {
147			u8 category;
148			union {
149				struct {
150					u8 action_code;
151					u8 dialog_token;
152					u8 status_code;
153					u8 variable[0];
154				} STRUCT_PACKED wme_action;
155				struct{
156					u8 action_code;
157					u8 element_id;
158					u8 length;
159					u8 switch_mode;
160					u8 new_chan;
161					u8 switch_count;
162				} __attribute__((packed)) chan_switch;
163			} u;
164		} STRUCT_PACKED action;
165	} u;
166} STRUCT_PACKED;
167
168#ifdef _MSC_VER
169#pragma pack(pop)
170#endif /* _MSC_VER */
171
172/* Authentication algorithms */
173#define WLAN_AUTH_OPEN 0
174#define WLAN_AUTH_SHARED_KEY 1
175#define WLAN_AUTH_LEAP 128
176
177#define WLAN_AUTH_CHALLENGE_LEN 128
178
179#define WLAN_CAPABILITY_ESS BIT(0)
180#define WLAN_CAPABILITY_IBSS BIT(1)
181#define WLAN_CAPABILITY_CF_POLLABLE BIT(2)
182#define WLAN_CAPABILITY_CF_POLL_REQUEST BIT(3)
183#define WLAN_CAPABILITY_PRIVACY BIT(4)
184#define WLAN_CAPABILITY_SHORT_PREAMBLE BIT(5)
185#define WLAN_CAPABILITY_PBCC BIT(6)
186#define WLAN_CAPABILITY_CHANNEL_AGILITY BIT(7)
187/* 802.11h */
188#define WLAN_CAPABILITY_SPECTRUM_MGMT BIT(8)
189#define WLAN_CAPABILITY_SHORT_SLOT_TIME BIT(10)
190#define WLAN_CAPABILITY_DSSS_OFDM BIT(13)
191
192/* Status codes */
193#define WLAN_STATUS_SUCCESS 0
194#define WLAN_STATUS_UNSPECIFIED_FAILURE 1
195#define WLAN_STATUS_CAPS_UNSUPPORTED 10
196#define WLAN_STATUS_REASSOC_NO_ASSOC 11
197#define WLAN_STATUS_ASSOC_DENIED_UNSPEC 12
198#define WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG 13
199#define WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION 14
200#define WLAN_STATUS_CHALLENGE_FAIL 15
201#define WLAN_STATUS_AUTH_TIMEOUT 16
202#define WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA 17
203#define WLAN_STATUS_ASSOC_DENIED_RATES 18
204/* 802.11b */
205#define WLAN_STATUS_ASSOC_DENIED_NOSHORT 19
206#define WLAN_STATUS_ASSOC_DENIED_NOPBCC 20
207#define WLAN_STATUS_ASSOC_DENIED_NOAGILITY 21
208/* 802.11h */
209#define WLAN_STATUS_SPEC_MGMT_REQUIRED 22
210#define WLAN_STATUS_PWR_CAPABILITY_NOT_VALID 23
211#define WLAN_STATUS_SUPPORTED_CHANNEL_NOT_VALID 24
212/* 802.11g */
213#define WLAN_STATUS_ASSOC_DENOED_NO_SHORT_SLOT_TIME 25
214#define WLAN_STATUS_ASSOC_DENOED_NO_ER_PBCC 26
215#define WLAN_STATUS_ASSOC_DENOED_NO_DSSS_OFDM 27
216
217
218/* Reason codes */
219#define WLAN_REASON_UNSPECIFIED 1
220#define WLAN_REASON_PREV_AUTH_NOT_VALID 2
221#define WLAN_REASON_DEAUTH_LEAVING 3
222#define WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY 4
223#define WLAN_REASON_DISASSOC_AP_BUSY 5
224#define WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA 6
225#define WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA 7
226#define WLAN_REASON_DISASSOC_STA_HAS_LEFT 8
227#define WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH 9
228/* 802.11h */
229#define WLAN_REASON_PWR_CAPABILITY_NOT_VALID 10
230#define WLAN_REASON_SUPPORTED_CHANNEL_NOT_VALID 11
231
232#define WLAN_REASON_MIC_FAILURE 14
233
234
235#define WLAN_FC_PVER		0x0003
236#define WLAN_FC_TODS		0x0100
237#define WLAN_FC_FROMDS		0x0200
238#define WLAN_FC_MOREFRAG	0x0400
239#define WLAN_FC_RETRY		0x0800
240#define WLAN_FC_PWRMGT		0x1000
241#define WLAN_FC_MOREDATA	0x2000
242#define WLAN_FC_ISWEP		0x4000
243#define WLAN_FC_ORDER		0x8000
244
245#define WLAN_FC_GET_TYPE(fc)	(((fc) & 0x000c) >> 2)
246#define WLAN_FC_GET_STYPE(fc)	(((fc) & 0x00f0) >> 4)
247
248
249#define IEEE80211_FC(type, stype) host_to_le16((type << 2) | (stype << 4))
250
251#define WLAN_FC_TYPE_MGMT	0
252#define WLAN_FC_TYPE_CTRL	1
253#define WLAN_FC_TYPE_DATA	2
254
255/* management */
256#define WLAN_FC_STYPE_ASSOC_REQ		0
257#define WLAN_FC_STYPE_ASSOC_RESP	1
258#define WLAN_FC_STYPE_REASSOC_REQ	2
259#define WLAN_FC_STYPE_REASSOC_RESP	3
260#define WLAN_FC_STYPE_PROBE_REQ		4
261#define WLAN_FC_STYPE_PROBE_RESP	5
262#define WLAN_FC_STYPE_BEACON		8
263#define WLAN_FC_STYPE_ATIM		9
264#define WLAN_FC_STYPE_DISASSOC		10
265#define WLAN_FC_STYPE_AUTH		11
266#define WLAN_FC_STYPE_DEAUTH		12
267#define WLAN_FC_STYPE_ACTION		13
268
269
270#define ERP_INFO_USE_PROTECTION BIT(1)
271
272
273struct ieee80211_sta_bss {
274	struct ieee80211_sta_bss *next;
275	struct ieee80211_sta_bss *hnext;
276
277	u8 bssid[ETH_ALEN];
278	u8 ssid[MAX_SSID_LEN];
279	size_t ssid_len;
280	u16 capability; /* host byte order */
281	int hw_mode;
282	int channel;
283	int freq;
284	int rssi;
285	u8 *wpa_ie;
286	size_t wpa_ie_len;
287	u8 *rsn_ie;
288	size_t rsn_ie_len;
289	u8 *wmm_ie;
290	size_t wmm_ie_len;
291#define IEEE80211_MAX_SUPP_RATES 32
292	u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
293	size_t supp_rates_len;
294	int beacon_int;
295	u64 timestamp;
296
297	int probe_resp;
298	struct os_time last_update;
299};
300
301
302static void ieee80211_send_probe_req(struct wpa_supplicant *wpa_s,
303				     const u8 *dst,
304				     const u8 *ssid, size_t ssid_len);
305static struct ieee80211_sta_bss *
306ieee80211_bss_get(struct wpa_supplicant *wpa_s, const u8 *bssid);
307static int ieee80211_sta_find_ibss(struct wpa_supplicant *wpa_s);
308static int ieee80211_sta_wep_configured(struct wpa_supplicant *wpa_s);
309static void ieee80211_sta_timer(void *eloop_ctx, void *timeout_ctx);
310static void ieee80211_sta_scan_timer(void *eloop_ctx, void *timeout_ctx);
311
312
313/* Parsed Information Elements */
314struct ieee802_11_elems {
315	u8 *ssid;
316	u8 ssid_len;
317	u8 *supp_rates;
318	u8 supp_rates_len;
319	u8 *fh_params;
320	u8 fh_params_len;
321	u8 *ds_params;
322	u8 ds_params_len;
323	u8 *cf_params;
324	u8 cf_params_len;
325	u8 *tim;
326	u8 tim_len;
327	u8 *ibss_params;
328	u8 ibss_params_len;
329	u8 *challenge;
330	u8 challenge_len;
331	u8 *wpa;
332	u8 wpa_len;
333	u8 *rsn;
334	u8 rsn_len;
335	u8 *erp_info;
336	u8 erp_info_len;
337	u8 *ext_supp_rates;
338	u8 ext_supp_rates_len;
339	u8 *wmm_info;
340	u8 wmm_info_len;
341	u8 *wmm_param;
342	u8 wmm_param_len;
343};
344
345typedef enum { ParseOK = 0, ParseUnknown = 1, ParseFailed = -1 } ParseRes;
346
347
348static ParseRes ieee802_11_parse_elems(u8 *start, size_t len,
349				       struct ieee802_11_elems *elems)
350{
351	size_t left = len;
352	u8 *pos = start;
353	int unknown = 0;
354
355	os_memset(elems, 0, sizeof(*elems));
356
357	while (left >= 2) {
358		u8 id, elen;
359
360		id = *pos++;
361		elen = *pos++;
362		left -= 2;
363
364		if (elen > left) {
365#if 0
366			wpa_printf(MSG_MSGDUMP, "MLME: IEEE 802.11 element "
367				   "parse failed (id=%d elen=%d left=%d)",
368				   id, elen, left);
369#endif
370			return ParseFailed;
371		}
372
373		switch (id) {
374		case WLAN_EID_SSID:
375			elems->ssid = pos;
376			elems->ssid_len = elen;
377			break;
378		case WLAN_EID_SUPP_RATES:
379			elems->supp_rates = pos;
380			elems->supp_rates_len = elen;
381			break;
382		case WLAN_EID_FH_PARAMS:
383			elems->fh_params = pos;
384			elems->fh_params_len = elen;
385			break;
386		case WLAN_EID_DS_PARAMS:
387			elems->ds_params = pos;
388			elems->ds_params_len = elen;
389			break;
390		case WLAN_EID_CF_PARAMS:
391			elems->cf_params = pos;
392			elems->cf_params_len = elen;
393			break;
394		case WLAN_EID_TIM:
395			elems->tim = pos;
396			elems->tim_len = elen;
397			break;
398		case WLAN_EID_IBSS_PARAMS:
399			elems->ibss_params = pos;
400			elems->ibss_params_len = elen;
401			break;
402		case WLAN_EID_CHALLENGE:
403			elems->challenge = pos;
404			elems->challenge_len = elen;
405			break;
406		case WLAN_EID_VENDOR_SPECIFIC:
407			if (elen >= 4 && pos[0] == 0x00 && pos[1] == 0x50 &&
408			    pos[2] == 0xf2) {
409				/* Microsoft OUI (00:50:F2) */
410				if (pos[3] == 1) {
411					/* OUI Type 1 - WPA IE */
412					elems->wpa = pos;
413					elems->wpa_len = elen;
414				} else if (elen >= 5 && pos[3] == 2) {
415					if (pos[4] == 0) {
416						elems->wmm_info = pos;
417						elems->wmm_info_len = elen;
418					} else if (pos[4] == 1) {
419						elems->wmm_param = pos;
420						elems->wmm_param_len = elen;
421					}
422				}
423			}
424			break;
425		case WLAN_EID_RSN:
426			elems->rsn = pos;
427			elems->rsn_len = elen;
428			break;
429		case WLAN_EID_ERP_INFO:
430			elems->erp_info = pos;
431			elems->erp_info_len = elen;
432			break;
433		case WLAN_EID_EXT_SUPP_RATES:
434			elems->ext_supp_rates = pos;
435			elems->ext_supp_rates_len = elen;
436			break;
437		default:
438#if 0
439			wpa_printf(MSG_MSGDUMP "MLME: IEEE 802.11 element "
440				   "parse ignored unknown element (id=%d "
441				   "elen=%d)", id, elen);
442#endif
443			unknown++;
444			break;
445		}
446
447		left -= elen;
448		pos += elen;
449	}
450
451	if (left)
452		return ParseFailed;
453
454	return unknown ? ParseUnknown : ParseOK;
455}
456
457
458static int ieee80211_sta_set_channel(struct wpa_supplicant *wpa_s,
459				     wpa_hw_mode phymode, int chan,
460				     int freq)
461{
462	size_t i;
463	struct wpa_hw_modes *mode;
464
465	for (i = 0; i < wpa_s->mlme.num_modes; i++) {
466		mode = &wpa_s->mlme.modes[i];
467		if (mode->mode == phymode) {
468			wpa_s->mlme.curr_rates = mode->rates;
469			wpa_s->mlme.num_curr_rates = mode->num_rates;
470			break;
471		}
472	}
473
474	return wpa_drv_set_channel(wpa_s, phymode, chan, freq);
475}
476
477
478
479#if 0 /* FIX */
480static int ecw2cw(int ecw)
481{
482	int cw = 1;
483	while (ecw > 0) {
484		cw <<= 1;
485		ecw--;
486	}
487	return cw - 1;
488}
489#endif
490
491
492static void ieee80211_sta_wmm_params(struct wpa_supplicant *wpa_s,
493				     u8 *wmm_param, size_t wmm_param_len)
494{
495	size_t left;
496	int count;
497	u8 *pos;
498
499	if (wmm_param_len < 8 || wmm_param[5] /* version */ != 1)
500		return;
501	count = wmm_param[6] & 0x0f;
502	if (count == wpa_s->mlme.wmm_last_param_set)
503		return;
504	wpa_s->mlme.wmm_last_param_set = count;
505
506	pos = wmm_param + 8;
507	left = wmm_param_len - 8;
508
509#if 0 /* FIX */
510	wmm_acm = 0;
511	for (; left >= 4; left -= 4, pos += 4) {
512		int aci = (pos[0] >> 5) & 0x03;
513		int acm = (pos[0] >> 4) & 0x01;
514		int queue;
515
516		switch (aci) {
517		case 1:
518			queue = IEEE80211_TX_QUEUE_DATA3;
519			if (acm)
520				wmm_acm |= BIT(1) | BIT(2);
521			break;
522		case 2:
523			queue = IEEE80211_TX_QUEUE_DATA1;
524			if (acm)
525				wmm_acm |= BIT(4) | BIT(5);
526			break;
527		case 3:
528			queue = IEEE80211_TX_QUEUE_DATA0;
529			if (acm)
530				wmm_acm |= BIT(6) | BIT(7);
531			break;
532		case 0:
533		default:
534			queue = IEEE80211_TX_QUEUE_DATA2;
535			if (acm)
536				wpa_s->mlme.wmm_acm |= BIT(0) | BIT(3);
537			break;
538		}
539
540		params.aifs = pos[0] & 0x0f;
541		params.cw_max = ecw2cw((pos[1] & 0xf0) >> 4);
542		params.cw_min = ecw2cw(pos[1] & 0x0f);
543		/* TXOP is in units of 32 usec; burst_time in 0.1 ms */
544		params.burst_time = (pos[2] | (pos[3] << 8)) * 32 / 100;
545		wpa_printf(MSG_DEBUG, "MLME: WMM queue=%d aci=%d acm=%d "
546			   "aifs=%d cWmin=%d cWmax=%d burst=%d",
547			   queue, aci, acm, params.aifs, params.cw_min,
548			   params.cw_max, params.burst_time);
549		/* TODO: handle ACM (block TX, fallback to next lowest allowed
550		 * AC for now) */
551		if (local->hw->conf_tx(local->mdev, queue, &params)) {
552			wpa_printf(MSG_DEBUG, "MLME: failed to set TX queue "
553				   "parameters for queue %d", queue);
554		}
555	}
556#endif
557}
558
559
560static void ieee80211_set_associated(struct wpa_supplicant *wpa_s, int assoc)
561{
562	if (wpa_s->mlme.associated == assoc)
563		return;
564
565	wpa_s->mlme.associated = assoc;
566
567	if (assoc) {
568		union wpa_event_data data;
569		os_memset(&data, 0, sizeof(data));
570		wpa_s->mlme.prev_bssid_set = 1;
571		os_memcpy(wpa_s->mlme.prev_bssid, wpa_s->bssid, ETH_ALEN);
572		data.assoc_info.req_ies = wpa_s->mlme.assocreq_ies;
573		data.assoc_info.req_ies_len = wpa_s->mlme.assocreq_ies_len;
574		data.assoc_info.resp_ies = wpa_s->mlme.assocresp_ies;
575		data.assoc_info.resp_ies_len = wpa_s->mlme.assocresp_ies_len;
576		wpa_supplicant_event(wpa_s, EVENT_ASSOC, &data);
577	} else {
578		wpa_supplicant_event(wpa_s, EVENT_DISASSOC, NULL);
579	}
580	os_get_time(&wpa_s->mlme.last_probe);
581}
582
583
584static void ieee80211_sta_tx(struct wpa_supplicant *wpa_s, const u8 *buf,
585			     size_t len)
586{
587	wpa_drv_send_mlme(wpa_s, buf, len);
588}
589
590
591static void ieee80211_send_auth(struct wpa_supplicant *wpa_s,
592				int transaction, u8 *extra, size_t extra_len,
593				int encrypt)
594{
595	u8 *buf;
596	size_t len;
597	struct ieee80211_mgmt *mgmt;
598
599	buf = os_malloc(sizeof(*mgmt) + 6 + extra_len);
600	if (buf == NULL) {
601		wpa_printf(MSG_DEBUG, "MLME: failed to allocate buffer for "
602			   "auth frame");
603		return;
604	}
605
606	mgmt = (struct ieee80211_mgmt *) buf;
607	len = 24 + 6;
608	os_memset(mgmt, 0, 24 + 6);
609	mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
610					   WLAN_FC_STYPE_AUTH);
611	if (encrypt)
612		mgmt->frame_control |= host_to_le16(WLAN_FC_ISWEP);
613	os_memcpy(mgmt->da, wpa_s->bssid, ETH_ALEN);
614	os_memcpy(mgmt->sa, wpa_s->own_addr, ETH_ALEN);
615	os_memcpy(mgmt->bssid, wpa_s->bssid, ETH_ALEN);
616	mgmt->u.auth.auth_alg = host_to_le16(wpa_s->mlme.auth_alg);
617	mgmt->u.auth.auth_transaction = host_to_le16(transaction);
618	wpa_s->mlme.auth_transaction = transaction + 1;
619	mgmt->u.auth.status_code = host_to_le16(0);
620	if (extra) {
621		os_memcpy(buf + len, extra, extra_len);
622		len += extra_len;
623	}
624
625	ieee80211_sta_tx(wpa_s, buf, len);
626	os_free(buf);
627}
628
629
630static void ieee80211_reschedule_timer(struct wpa_supplicant *wpa_s, int ms)
631{
632	eloop_cancel_timeout(ieee80211_sta_timer, wpa_s, NULL);
633	eloop_register_timeout(ms / 1000, 1000 * (ms % 1000),
634			       ieee80211_sta_timer, wpa_s, NULL);
635}
636
637
638static void ieee80211_authenticate(struct wpa_supplicant *wpa_s)
639{
640	wpa_s->mlme.auth_tries++;
641	if (wpa_s->mlme.auth_tries > IEEE80211_AUTH_MAX_TRIES) {
642		wpa_printf(MSG_DEBUG, "MLME: authentication with AP " MACSTR
643			   " timed out", MAC2STR(wpa_s->bssid));
644		return;
645	}
646
647	wpa_s->mlme.state = IEEE80211_AUTHENTICATE;
648	wpa_printf(MSG_DEBUG, "MLME: authenticate with AP " MACSTR,
649		   MAC2STR(wpa_s->bssid));
650
651	ieee80211_send_auth(wpa_s, 1, NULL, 0, 0);
652
653	ieee80211_reschedule_timer(wpa_s, IEEE80211_AUTH_TIMEOUT);
654}
655
656
657static void ieee80211_send_assoc(struct wpa_supplicant *wpa_s)
658{
659	struct ieee80211_mgmt *mgmt;
660	u8 *pos, *ies, *buf;
661	int i, len;
662	u16 capab;
663	struct ieee80211_sta_bss *bss;
664	int wmm = 0;
665	size_t blen;
666
667	if (wpa_s->mlme.curr_rates == NULL) {
668		wpa_printf(MSG_DEBUG, "MLME: curr_rates not set for assoc");
669		return;
670	}
671
672	buf = os_malloc(sizeof(*mgmt) + 200 + wpa_s->mlme.extra_ie_len +
673			wpa_s->mlme.ssid_len);
674	if (buf == NULL) {
675		wpa_printf(MSG_DEBUG, "MLME: failed to allocate buffer for "
676			   "assoc frame");
677		return;
678	}
679	blen = 0;
680
681	capab = wpa_s->mlme.capab;
682	if (wpa_s->mlme.phymode == WPA_MODE_IEEE80211G) {
683		capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME |
684			WLAN_CAPABILITY_SHORT_PREAMBLE;
685	}
686	bss = ieee80211_bss_get(wpa_s, wpa_s->bssid);
687	if (bss) {
688		if (bss->capability & WLAN_CAPABILITY_PRIVACY)
689			capab |= WLAN_CAPABILITY_PRIVACY;
690		if (bss->wmm_ie) {
691			wmm = 1;
692		}
693	}
694
695	mgmt = (struct ieee80211_mgmt *) buf;
696	blen += 24;
697	os_memset(mgmt, 0, 24);
698	os_memcpy(mgmt->da, wpa_s->bssid, ETH_ALEN);
699	os_memcpy(mgmt->sa, wpa_s->own_addr, ETH_ALEN);
700	os_memcpy(mgmt->bssid, wpa_s->bssid, ETH_ALEN);
701
702	if (wpa_s->mlme.prev_bssid_set) {
703		blen += 10;
704		mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
705						   WLAN_FC_STYPE_REASSOC_REQ);
706		mgmt->u.reassoc_req.capab_info = host_to_le16(capab);
707		mgmt->u.reassoc_req.listen_interval = host_to_le16(1);
708		os_memcpy(mgmt->u.reassoc_req.current_ap,
709			  wpa_s->mlme.prev_bssid,
710			  ETH_ALEN);
711	} else {
712		blen += 4;
713		mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
714						   WLAN_FC_STYPE_ASSOC_REQ);
715		mgmt->u.assoc_req.capab_info = host_to_le16(capab);
716		mgmt->u.assoc_req.listen_interval = host_to_le16(1);
717	}
718
719	/* SSID */
720	ies = pos = buf + blen;
721	blen += 2 + wpa_s->mlme.ssid_len;
722	*pos++ = WLAN_EID_SSID;
723	*pos++ = wpa_s->mlme.ssid_len;
724	os_memcpy(pos, wpa_s->mlme.ssid, wpa_s->mlme.ssid_len);
725
726	len = wpa_s->mlme.num_curr_rates;
727	if (len > 8)
728		len = 8;
729	pos = buf + blen;
730	blen += len + 2;
731	*pos++ = WLAN_EID_SUPP_RATES;
732	*pos++ = len;
733	for (i = 0; i < len; i++) {
734		int rate = wpa_s->mlme.curr_rates[i].rate;
735		*pos++ = (u8) (rate / 5);
736	}
737
738	if (wpa_s->mlme.num_curr_rates > len) {
739		pos = buf + blen;
740		blen += wpa_s->mlme.num_curr_rates - len + 2;
741		*pos++ = WLAN_EID_EXT_SUPP_RATES;
742		*pos++ = wpa_s->mlme.num_curr_rates - len;
743		for (i = len; i < wpa_s->mlme.num_curr_rates; i++) {
744			int rate = wpa_s->mlme.curr_rates[i].rate;
745			*pos++ = (u8) (rate / 5);
746		}
747	}
748
749	if (wpa_s->mlme.extra_ie) {
750		pos = buf + blen;
751		blen += wpa_s->mlme.extra_ie_len;
752		os_memcpy(pos, wpa_s->mlme.extra_ie, wpa_s->mlme.extra_ie_len);
753	}
754
755	if (wmm && wpa_s->mlme.wmm_enabled) {
756		pos = buf + blen;
757		blen += 9;
758		*pos++ = WLAN_EID_VENDOR_SPECIFIC;
759		*pos++ = 7; /* len */
760		*pos++ = 0x00; /* Microsoft OUI 00:50:F2 */
761		*pos++ = 0x50;
762		*pos++ = 0xf2;
763		*pos++ = 2; /* WME */
764		*pos++ = 0; /* WME info */
765		*pos++ = 1; /* WME ver */
766		*pos++ = 0;
767	}
768
769	os_free(wpa_s->mlme.assocreq_ies);
770	wpa_s->mlme.assocreq_ies_len = (buf + blen) - ies;
771	wpa_s->mlme.assocreq_ies = os_malloc(wpa_s->mlme.assocreq_ies_len);
772	if (wpa_s->mlme.assocreq_ies) {
773		os_memcpy(wpa_s->mlme.assocreq_ies, ies,
774			  wpa_s->mlme.assocreq_ies_len);
775	}
776
777	ieee80211_sta_tx(wpa_s, buf, blen);
778	os_free(buf);
779}
780
781
782static void ieee80211_send_deauth(struct wpa_supplicant *wpa_s, u16 reason)
783{
784	u8 *buf;
785	size_t len;
786	struct ieee80211_mgmt *mgmt;
787
788	buf = os_zalloc(sizeof(*mgmt));
789	if (buf == NULL) {
790		wpa_printf(MSG_DEBUG, "MLME: failed to allocate buffer for "
791			   "deauth frame");
792		return;
793	}
794
795	mgmt = (struct ieee80211_mgmt *) buf;
796	len = 24;
797	os_memcpy(mgmt->da, wpa_s->bssid, ETH_ALEN);
798	os_memcpy(mgmt->sa, wpa_s->own_addr, ETH_ALEN);
799	os_memcpy(mgmt->bssid, wpa_s->bssid, ETH_ALEN);
800	mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
801					   WLAN_FC_STYPE_DEAUTH);
802	len += 2;
803	mgmt->u.deauth.reason_code = host_to_le16(reason);
804
805	ieee80211_sta_tx(wpa_s, buf, len);
806	os_free(buf);
807}
808
809
810static void ieee80211_send_disassoc(struct wpa_supplicant *wpa_s, u16 reason)
811{
812	u8 *buf;
813	size_t len;
814	struct ieee80211_mgmt *mgmt;
815
816	buf = os_zalloc(sizeof(*mgmt));
817	if (buf == NULL) {
818		wpa_printf(MSG_DEBUG, "MLME: failed to allocate buffer for "
819			   "disassoc frame");
820		return;
821	}
822
823	mgmt = (struct ieee80211_mgmt *) buf;
824	len = 24;
825	os_memcpy(mgmt->da, wpa_s->bssid, ETH_ALEN);
826	os_memcpy(mgmt->sa, wpa_s->own_addr, ETH_ALEN);
827	os_memcpy(mgmt->bssid, wpa_s->bssid, ETH_ALEN);
828	mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
829					   WLAN_FC_STYPE_DISASSOC);
830	len += 2;
831	mgmt->u.disassoc.reason_code = host_to_le16(reason);
832
833	ieee80211_sta_tx(wpa_s, buf, len);
834	os_free(buf);
835}
836
837
838static int ieee80211_privacy_mismatch(struct wpa_supplicant *wpa_s)
839{
840	struct ieee80211_sta_bss *bss;
841	int res = 0;
842
843	if (wpa_s->mlme.mixed_cell ||
844	    wpa_s->mlme.key_mgmt != KEY_MGMT_NONE)
845		return 0;
846
847	bss = ieee80211_bss_get(wpa_s, wpa_s->bssid);
848	if (bss == NULL)
849		return 0;
850
851	if (ieee80211_sta_wep_configured(wpa_s) !=
852	    !!(bss->capability & WLAN_CAPABILITY_PRIVACY))
853		res = 1;
854
855	return res;
856}
857
858
859static void ieee80211_associate(struct wpa_supplicant *wpa_s)
860{
861	wpa_s->mlme.assoc_tries++;
862	if (wpa_s->mlme.assoc_tries > IEEE80211_ASSOC_MAX_TRIES) {
863		wpa_printf(MSG_DEBUG, "MLME: association with AP " MACSTR
864			   " timed out", MAC2STR(wpa_s->bssid));
865		return;
866	}
867
868	wpa_s->mlme.state = IEEE80211_ASSOCIATE;
869	wpa_printf(MSG_DEBUG, "MLME: associate with AP " MACSTR,
870		   MAC2STR(wpa_s->bssid));
871	if (ieee80211_privacy_mismatch(wpa_s)) {
872		wpa_printf(MSG_DEBUG, "MLME: mismatch in privacy "
873			   "configuration and mixed-cell disabled - abort "
874			   "association");
875		return;
876	}
877
878	ieee80211_send_assoc(wpa_s);
879
880	ieee80211_reschedule_timer(wpa_s, IEEE80211_ASSOC_TIMEOUT);
881}
882
883
884static void ieee80211_associated(struct wpa_supplicant *wpa_s)
885{
886	int disassoc;
887
888	/* TODO: start monitoring current AP signal quality and number of
889	 * missed beacons. Scan other channels every now and then and search
890	 * for better APs. */
891	/* TODO: remove expired BSSes */
892
893	wpa_s->mlme.state = IEEE80211_ASSOCIATED;
894
895#if 0 /* FIX */
896	sta = sta_info_get(local, wpa_s->bssid);
897	if (sta == NULL) {
898		wpa_printf(MSG_DEBUG "MLME: No STA entry for own AP " MACSTR,
899			   MAC2STR(wpa_s->bssid));
900		disassoc = 1;
901	} else {
902		disassoc = 0;
903		if (time_after(jiffies,
904			       sta->last_rx + IEEE80211_MONITORING_INTERVAL)) {
905			if (wpa_s->mlme.probereq_poll) {
906				wpa_printf(MSG_DEBUG "MLME: No ProbeResp from "
907					   "current AP " MACSTR " - assume "
908					   "out of range",
909					   MAC2STR(wpa_s->bssid));
910				disassoc = 1;
911			} else {
912				ieee80211_send_probe_req(
913					wpa_s->bssid,
914					wpa_s->mlme.scan_ssid,
915					wpa_s->mlme.scan_ssid_len);
916				wpa_s->mlme.probereq_poll = 1;
917			}
918		} else {
919			wpa_s->mlme.probereq_poll = 0;
920			if (time_after(jiffies, wpa_s->mlme.last_probe +
921				       IEEE80211_PROBE_INTERVAL)) {
922				wpa_s->mlme.last_probe = jiffies;
923				ieee80211_send_probe_req(wpa_s->bssid,
924							 wpa_s->mlme.ssid,
925							 wpa_s->mlme.ssid_len);
926			}
927		}
928		sta_info_release(local, sta);
929	}
930#else
931	disassoc = 0;
932#endif
933	if (disassoc) {
934		wpa_supplicant_event(wpa_s, EVENT_DISASSOC, NULL);
935		ieee80211_reschedule_timer(wpa_s,
936					   IEEE80211_MONITORING_INTERVAL +
937					   30000);
938	} else {
939		ieee80211_reschedule_timer(wpa_s,
940					   IEEE80211_MONITORING_INTERVAL);
941	}
942}
943
944
945static void ieee80211_send_probe_req(struct wpa_supplicant *wpa_s,
946				     const u8 *dst,
947				     const u8 *ssid, size_t ssid_len)
948{
949	u8 *buf;
950	size_t len;
951	struct ieee80211_mgmt *mgmt;
952	u8 *pos, *supp_rates;
953	u8 *esupp_rates = NULL;
954	int i;
955
956	buf = os_malloc(sizeof(*mgmt) + 200);
957	if (buf == NULL) {
958		wpa_printf(MSG_DEBUG, "MLME: failed to allocate buffer for "
959			   "probe request");
960		return;
961	}
962
963	mgmt = (struct ieee80211_mgmt *) buf;
964	len = 24;
965	os_memset(mgmt, 0, 24);
966	mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
967					   WLAN_FC_STYPE_PROBE_REQ);
968	os_memcpy(mgmt->sa, wpa_s->own_addr, ETH_ALEN);
969	if (dst) {
970		os_memcpy(mgmt->da, dst, ETH_ALEN);
971		os_memcpy(mgmt->bssid, dst, ETH_ALEN);
972	} else {
973		os_memset(mgmt->da, 0xff, ETH_ALEN);
974		os_memset(mgmt->bssid, 0xff, ETH_ALEN);
975	}
976	pos = buf + len;
977	len += 2 + ssid_len;
978	*pos++ = WLAN_EID_SSID;
979	*pos++ = ssid_len;
980	os_memcpy(pos, ssid, ssid_len);
981
982	supp_rates = buf + len;
983	len += 2;
984	supp_rates[0] = WLAN_EID_SUPP_RATES;
985	supp_rates[1] = 0;
986	for (i = 0; i < wpa_s->mlme.num_curr_rates; i++) {
987		struct wpa_rate_data *rate = &wpa_s->mlme.curr_rates[i];
988		if (esupp_rates) {
989			pos = buf + len;
990			len++;
991			esupp_rates[1]++;
992		} else if (supp_rates[1] == 8) {
993			esupp_rates = pos;
994			esupp_rates[0] = WLAN_EID_EXT_SUPP_RATES;
995			esupp_rates[1] = 1;
996			pos = &esupp_rates[2];
997			len += 3;
998		} else {
999			pos = buf + len;
1000			len++;
1001			supp_rates[1]++;
1002		}
1003		*pos = rate->rate / 5;
1004	}
1005
1006	ieee80211_sta_tx(wpa_s, buf, len);
1007	os_free(buf);
1008}
1009
1010
1011static int ieee80211_sta_wep_configured(struct wpa_supplicant *wpa_s)
1012{
1013#if 0 /* FIX */
1014	if (sdata == NULL || sdata->default_key == NULL ||
1015	    sdata->default_key->alg != ALG_WEP)
1016		return 0;
1017	return 1;
1018#else
1019	return 0;
1020#endif
1021}
1022
1023
1024static void ieee80211_auth_completed(struct wpa_supplicant *wpa_s)
1025{
1026	wpa_printf(MSG_DEBUG, "MLME: authenticated");
1027	wpa_s->mlme.authenticated = 1;
1028	ieee80211_associate(wpa_s);
1029}
1030
1031
1032static void ieee80211_auth_challenge(struct wpa_supplicant *wpa_s,
1033				     struct ieee80211_mgmt *mgmt,
1034				     size_t len,
1035				     struct ieee80211_rx_status *rx_status)
1036{
1037	u8 *pos;
1038	struct ieee802_11_elems elems;
1039
1040	wpa_printf(MSG_DEBUG, "MLME: replying to auth challenge");
1041	pos = mgmt->u.auth.variable;
1042	if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems)
1043	    == ParseFailed) {
1044		wpa_printf(MSG_DEBUG, "MLME: failed to parse Auth(challenge)");
1045		return;
1046	}
1047	if (elems.challenge == NULL) {
1048		wpa_printf(MSG_DEBUG, "MLME: no challenge IE in shared key "
1049			   "auth frame");
1050		return;
1051	}
1052	ieee80211_send_auth(wpa_s, 3, elems.challenge - 2,
1053			    elems.challenge_len + 2, 1);
1054}
1055
1056
1057static void ieee80211_rx_mgmt_auth(struct wpa_supplicant *wpa_s,
1058				   struct ieee80211_mgmt *mgmt,
1059				   size_t len,
1060				   struct ieee80211_rx_status *rx_status)
1061{
1062	struct wpa_ssid *ssid = wpa_s->current_ssid;
1063	u16 auth_alg, auth_transaction, status_code;
1064	int adhoc;
1065
1066	adhoc = ssid && ssid->mode == 1;
1067
1068	if (wpa_s->mlme.state != IEEE80211_AUTHENTICATE && !adhoc) {
1069		wpa_printf(MSG_DEBUG, "MLME: authentication frame received "
1070			   "from " MACSTR ", but not in authenticate state - "
1071			   "ignored", MAC2STR(mgmt->sa));
1072		return;
1073	}
1074
1075	if (len < 24 + 6) {
1076		wpa_printf(MSG_DEBUG, "MLME: too short (%lu) authentication "
1077			   "frame received from " MACSTR " - ignored",
1078			   (unsigned long) len, MAC2STR(mgmt->sa));
1079		return;
1080	}
1081
1082	if (!adhoc && os_memcmp(wpa_s->bssid, mgmt->sa, ETH_ALEN) != 0) {
1083		wpa_printf(MSG_DEBUG, "MLME: authentication frame received "
1084			   "from unknown AP (SA=" MACSTR " BSSID=" MACSTR
1085			   ") - ignored",
1086			   MAC2STR(mgmt->sa), MAC2STR(mgmt->bssid));
1087		return;
1088	}
1089
1090	if (adhoc && os_memcmp(wpa_s->bssid, mgmt->bssid, ETH_ALEN) != 0) {
1091		wpa_printf(MSG_DEBUG, "MLME: authentication frame received "
1092			   "from unknown BSSID (SA=" MACSTR " BSSID=" MACSTR
1093			   ") - ignored",
1094			   MAC2STR(mgmt->sa), MAC2STR(mgmt->bssid));
1095		return;
1096	}
1097
1098	auth_alg = le_to_host16(mgmt->u.auth.auth_alg);
1099	auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction);
1100	status_code = le_to_host16(mgmt->u.auth.status_code);
1101
1102	wpa_printf(MSG_DEBUG, "MLME: RX authentication from " MACSTR
1103		   " (alg=%d transaction=%d status=%d)",
1104		   MAC2STR(mgmt->sa), auth_alg, auth_transaction, status_code);
1105
1106	if (adhoc) {
1107		/* IEEE 802.11 standard does not require authentication in IBSS
1108		 * networks and most implementations do not seem to use it.
1109		 * However, try to reply to authentication attempts if someone
1110		 * has actually implemented this.
1111		 * TODO: Could implement shared key authentication. */
1112		if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1) {
1113			wpa_printf(MSG_DEBUG, "MLME: unexpected IBSS "
1114				   "authentication frame (alg=%d "
1115				   "transaction=%d)",
1116				   auth_alg, auth_transaction);
1117			return;
1118		}
1119		ieee80211_send_auth(wpa_s, 2, NULL, 0, 0);
1120	}
1121
1122	if (auth_alg != wpa_s->mlme.auth_alg ||
1123	    auth_transaction != wpa_s->mlme.auth_transaction) {
1124		wpa_printf(MSG_DEBUG, "MLME: unexpected authentication frame "
1125			   "(alg=%d transaction=%d)",
1126			   auth_alg, auth_transaction);
1127		return;
1128	}
1129
1130	if (status_code != WLAN_STATUS_SUCCESS) {
1131		wpa_printf(MSG_DEBUG, "MLME: AP denied authentication "
1132			   "(auth_alg=%d code=%d)", wpa_s->mlme.auth_alg,
1133			   status_code);
1134		if (status_code == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) {
1135			const int num_algs = 3;
1136			u8 algs[num_algs];
1137			int i, pos;
1138			algs[0] = algs[1] = algs[2] = 0xff;
1139			if (wpa_s->mlme.auth_algs & IEEE80211_AUTH_ALG_OPEN)
1140				algs[0] = WLAN_AUTH_OPEN;
1141			if (wpa_s->mlme.auth_algs &
1142			    IEEE80211_AUTH_ALG_SHARED_KEY)
1143				algs[1] = WLAN_AUTH_SHARED_KEY;
1144			if (wpa_s->mlme.auth_algs & IEEE80211_AUTH_ALG_LEAP)
1145				algs[2] = WLAN_AUTH_LEAP;
1146			if (wpa_s->mlme.auth_alg == WLAN_AUTH_OPEN)
1147				pos = 0;
1148			else if (wpa_s->mlme.auth_alg == WLAN_AUTH_SHARED_KEY)
1149				pos = 1;
1150			else
1151				pos = 2;
1152			for (i = 0; i < num_algs; i++) {
1153				pos++;
1154				if (pos >= num_algs)
1155					pos = 0;
1156				if (algs[pos] == wpa_s->mlme.auth_alg ||
1157				    algs[pos] == 0xff)
1158					continue;
1159				if (algs[pos] == WLAN_AUTH_SHARED_KEY &&
1160				    !ieee80211_sta_wep_configured(wpa_s))
1161					continue;
1162				wpa_s->mlme.auth_alg = algs[pos];
1163				wpa_printf(MSG_DEBUG, "MLME: set auth_alg=%d "
1164					   "for next try",
1165					   wpa_s->mlme.auth_alg);
1166				break;
1167			}
1168		}
1169		return;
1170	}
1171
1172	switch (wpa_s->mlme.auth_alg) {
1173	case WLAN_AUTH_OPEN:
1174	case WLAN_AUTH_LEAP:
1175		ieee80211_auth_completed(wpa_s);
1176		break;
1177	case WLAN_AUTH_SHARED_KEY:
1178		if (wpa_s->mlme.auth_transaction == 4)
1179			ieee80211_auth_completed(wpa_s);
1180		else
1181			ieee80211_auth_challenge(wpa_s, mgmt, len,
1182						 rx_status);
1183		break;
1184	}
1185}
1186
1187
1188static void ieee80211_rx_mgmt_deauth(struct wpa_supplicant *wpa_s,
1189				     struct ieee80211_mgmt *mgmt,
1190				     size_t len,
1191				     struct ieee80211_rx_status *rx_status)
1192{
1193	u16 reason_code;
1194
1195	if (len < 24 + 2) {
1196		wpa_printf(MSG_DEBUG, "MLME: too short (%lu) deauthentication "
1197			   "frame received from " MACSTR " - ignored",
1198			   (unsigned long) len, MAC2STR(mgmt->sa));
1199		return;
1200	}
1201
1202	if (os_memcmp(wpa_s->bssid, mgmt->sa, ETH_ALEN) != 0) {
1203		wpa_printf(MSG_DEBUG, "MLME: deauthentication frame received "
1204			   "from unknown AP (SA=" MACSTR " BSSID=" MACSTR
1205			   ") - ignored",
1206			   MAC2STR(mgmt->sa), MAC2STR(mgmt->bssid));
1207		return;
1208	}
1209
1210	reason_code = le_to_host16(mgmt->u.deauth.reason_code);
1211
1212	wpa_printf(MSG_DEBUG, "MLME: RX deauthentication from " MACSTR
1213		   " (reason=%d)", MAC2STR(mgmt->sa), reason_code);
1214
1215	if (wpa_s->mlme.authenticated)
1216		wpa_printf(MSG_DEBUG, "MLME: deauthenticated");
1217
1218	if (wpa_s->mlme.state == IEEE80211_AUTHENTICATE ||
1219	    wpa_s->mlme.state == IEEE80211_ASSOCIATE ||
1220	    wpa_s->mlme.state == IEEE80211_ASSOCIATED) {
1221		wpa_s->mlme.state = IEEE80211_AUTHENTICATE;
1222		ieee80211_reschedule_timer(wpa_s,
1223					   IEEE80211_RETRY_AUTH_INTERVAL);
1224	}
1225
1226	ieee80211_set_associated(wpa_s, 0);
1227	wpa_s->mlme.authenticated = 0;
1228}
1229
1230
1231static void ieee80211_rx_mgmt_disassoc(struct wpa_supplicant *wpa_s,
1232				       struct ieee80211_mgmt *mgmt,
1233				       size_t len,
1234				       struct ieee80211_rx_status *rx_status)
1235{
1236	u16 reason_code;
1237
1238	if (len < 24 + 2) {
1239		wpa_printf(MSG_DEBUG, "MLME: too short (%lu) disassociation "
1240			   "frame received from " MACSTR " - ignored",
1241			   (unsigned long) len, MAC2STR(mgmt->sa));
1242		return;
1243	}
1244
1245	if (os_memcmp(wpa_s->bssid, mgmt->sa, ETH_ALEN) != 0) {
1246		wpa_printf(MSG_DEBUG, "MLME: disassociation frame received "
1247			   "from unknown AP (SA=" MACSTR " BSSID=" MACSTR
1248			   ") - ignored",
1249			   MAC2STR(mgmt->sa), MAC2STR(mgmt->bssid));
1250		return;
1251	}
1252
1253	reason_code = le_to_host16(mgmt->u.disassoc.reason_code);
1254
1255	wpa_printf(MSG_DEBUG, "MLME: RX disassociation from " MACSTR
1256		   " (reason=%d)", MAC2STR(mgmt->sa), reason_code);
1257
1258	if (wpa_s->mlme.associated)
1259		wpa_printf(MSG_DEBUG, "MLME: disassociated");
1260
1261	if (wpa_s->mlme.state == IEEE80211_ASSOCIATED) {
1262		wpa_s->mlme.state = IEEE80211_ASSOCIATE;
1263		ieee80211_reschedule_timer(wpa_s,
1264					   IEEE80211_RETRY_AUTH_INTERVAL);
1265	}
1266
1267	ieee80211_set_associated(wpa_s, 0);
1268}
1269
1270
1271static void ieee80211_rx_mgmt_assoc_resp(struct wpa_supplicant *wpa_s,
1272					 struct ieee80211_mgmt *mgmt,
1273					 size_t len,
1274					 struct ieee80211_rx_status *rx_status,
1275					 int reassoc)
1276{
1277	u8 rates[32];
1278	size_t rates_len;
1279	u16 capab_info, status_code, aid;
1280	struct ieee802_11_elems elems;
1281	u8 *pos;
1282
1283	/* AssocResp and ReassocResp have identical structure, so process both
1284	 * of them in this function. */
1285
1286	if (wpa_s->mlme.state != IEEE80211_ASSOCIATE) {
1287		wpa_printf(MSG_DEBUG, "MLME: association frame received from "
1288			   MACSTR ", but not in associate state - ignored",
1289			   MAC2STR(mgmt->sa));
1290		return;
1291	}
1292
1293	if (len < 24 + 6) {
1294		wpa_printf(MSG_DEBUG, "MLME: too short (%lu) association "
1295			   "frame received from " MACSTR " - ignored",
1296			   (unsigned long) len, MAC2STR(mgmt->sa));
1297		return;
1298	}
1299
1300	if (os_memcmp(wpa_s->bssid, mgmt->sa, ETH_ALEN) != 0) {
1301		wpa_printf(MSG_DEBUG, "MLME: association frame received from "
1302			   "unknown AP (SA=" MACSTR " BSSID=" MACSTR ") - "
1303			   "ignored", MAC2STR(mgmt->sa), MAC2STR(mgmt->bssid));
1304		return;
1305	}
1306
1307	capab_info = le_to_host16(mgmt->u.assoc_resp.capab_info);
1308	status_code = le_to_host16(mgmt->u.assoc_resp.status_code);
1309	aid = le_to_host16(mgmt->u.assoc_resp.aid);
1310	if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14)))
1311		wpa_printf(MSG_DEBUG, "MLME: invalid aid value %d; bits 15:14 "
1312			   "not set", aid);
1313	aid &= ~(BIT(15) | BIT(14));
1314
1315	wpa_printf(MSG_DEBUG, "MLME: RX %sssocResp from " MACSTR
1316		   " (capab=0x%x status=%d aid=%d)",
1317		   reassoc ? "Rea" : "A", MAC2STR(mgmt->sa),
1318		   capab_info, status_code, aid);
1319
1320	if (status_code != WLAN_STATUS_SUCCESS) {
1321		wpa_printf(MSG_DEBUG, "MLME: AP denied association (code=%d)",
1322			   status_code);
1323		return;
1324	}
1325
1326	pos = mgmt->u.assoc_resp.variable;
1327	if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems)
1328	    == ParseFailed) {
1329		wpa_printf(MSG_DEBUG, "MLME: failed to parse AssocResp");
1330		return;
1331	}
1332
1333	if (elems.supp_rates == NULL) {
1334		wpa_printf(MSG_DEBUG, "MLME: no SuppRates element in "
1335			   "AssocResp");
1336		return;
1337	}
1338
1339	wpa_printf(MSG_DEBUG, "MLME: associated");
1340	wpa_s->mlme.aid = aid;
1341	wpa_s->mlme.ap_capab = capab_info;
1342
1343	os_free(wpa_s->mlme.assocresp_ies);
1344	wpa_s->mlme.assocresp_ies_len = len - (pos - (u8 *) mgmt);
1345	wpa_s->mlme.assocresp_ies = os_malloc(wpa_s->mlme.assocresp_ies_len);
1346	if (wpa_s->mlme.assocresp_ies) {
1347		os_memcpy(wpa_s->mlme.assocresp_ies, pos,
1348			  wpa_s->mlme.assocresp_ies_len);
1349	}
1350
1351	ieee80211_set_associated(wpa_s, 1);
1352
1353	rates_len = elems.supp_rates_len;
1354	if (rates_len > sizeof(rates))
1355		rates_len = sizeof(rates);
1356	os_memcpy(rates, elems.supp_rates, rates_len);
1357	if (elems.ext_supp_rates) {
1358		size_t _len = elems.ext_supp_rates_len;
1359		if (_len > sizeof(rates) - rates_len)
1360			_len = sizeof(rates) - rates_len;
1361		os_memcpy(rates + rates_len, elems.ext_supp_rates, _len);
1362		rates_len += _len;
1363	}
1364
1365	if (wpa_drv_set_bssid(wpa_s, wpa_s->bssid) < 0) {
1366		wpa_printf(MSG_DEBUG, "MLME: failed to set BSSID for the "
1367			   "netstack");
1368	}
1369	if (wpa_drv_set_ssid(wpa_s, wpa_s->mlme.ssid, wpa_s->mlme.ssid_len) <
1370	    0) {
1371		wpa_printf(MSG_DEBUG, "MLME: failed to set SSID for the "
1372			   "netstack");
1373	}
1374
1375	/* Remove STA entry before adding a new one just in case to avoid
1376	 * problems with existing configuration (e.g., keys). */
1377	wpa_drv_mlme_remove_sta(wpa_s, wpa_s->bssid);
1378	if (wpa_drv_mlme_add_sta(wpa_s, wpa_s->bssid, rates, rates_len) < 0) {
1379		wpa_printf(MSG_DEBUG, "MLME: failed to add STA entry to the "
1380			   "netstack");
1381	}
1382
1383#if 0 /* FIX? */
1384	sta->assoc_ap = 1;
1385
1386	if (elems.wmm_param && wpa_s->mlme.wmm_enabled) {
1387		sta->flags |= WLAN_STA_WME;
1388		ieee80211_sta_wmm_params(wpa_s, elems.wmm_param,
1389					 elems.wmm_param_len);
1390	}
1391#endif
1392
1393	ieee80211_associated(wpa_s);
1394}
1395
1396
1397/* Caller must hold local->sta_bss_lock */
1398static void __ieee80211_bss_hash_add(struct wpa_supplicant *wpa_s,
1399				     struct ieee80211_sta_bss *bss)
1400{
1401	bss->hnext = wpa_s->mlme.sta_bss_hash[STA_HASH(bss->bssid)];
1402	wpa_s->mlme.sta_bss_hash[STA_HASH(bss->bssid)] = bss;
1403}
1404
1405
1406/* Caller must hold local->sta_bss_lock */
1407static void __ieee80211_bss_hash_del(struct wpa_supplicant *wpa_s,
1408				     struct ieee80211_sta_bss *bss)
1409{
1410	struct ieee80211_sta_bss *b, *prev = NULL;
1411	b = wpa_s->mlme.sta_bss_hash[STA_HASH(bss->bssid)];
1412	while (b) {
1413		if (b == bss) {
1414			if (prev == NULL) {
1415				wpa_s->mlme.sta_bss_hash[STA_HASH(bss->bssid)]
1416					= bss->hnext;
1417			} else {
1418				prev->hnext = bss->hnext;
1419			}
1420			break;
1421		}
1422		prev = b;
1423		b = b->hnext;
1424	}
1425}
1426
1427
1428static struct ieee80211_sta_bss *
1429ieee80211_bss_add(struct wpa_supplicant *wpa_s, const u8 *bssid)
1430{
1431	struct ieee80211_sta_bss *bss;
1432
1433	bss = os_zalloc(sizeof(*bss));
1434	if (bss == NULL)
1435		return NULL;
1436	os_memcpy(bss->bssid, bssid, ETH_ALEN);
1437
1438	/* TODO: order by RSSI? */
1439	bss->next = wpa_s->mlme.sta_bss_list;
1440	wpa_s->mlme.sta_bss_list = bss;
1441	__ieee80211_bss_hash_add(wpa_s, bss);
1442	return bss;
1443}
1444
1445
1446static struct ieee80211_sta_bss *
1447ieee80211_bss_get(struct wpa_supplicant *wpa_s, const u8 *bssid)
1448{
1449	struct ieee80211_sta_bss *bss;
1450
1451	bss = wpa_s->mlme.sta_bss_hash[STA_HASH(bssid)];
1452	while (bss) {
1453		if (os_memcmp(bss->bssid, bssid, ETH_ALEN) == 0)
1454			break;
1455		bss = bss->hnext;
1456	}
1457	return bss;
1458}
1459
1460
1461static void ieee80211_bss_free(struct wpa_supplicant *wpa_s,
1462			       struct ieee80211_sta_bss *bss)
1463{
1464	__ieee80211_bss_hash_del(wpa_s, bss);
1465	os_free(bss->wpa_ie);
1466	os_free(bss->rsn_ie);
1467	os_free(bss->wmm_ie);
1468	os_free(bss);
1469}
1470
1471
1472static void ieee80211_bss_list_deinit(struct wpa_supplicant *wpa_s)
1473{
1474	struct ieee80211_sta_bss *bss, *prev;
1475
1476	bss = wpa_s->mlme.sta_bss_list;
1477	wpa_s->mlme.sta_bss_list = NULL;
1478	while (bss) {
1479		prev = bss;
1480		bss = bss->next;
1481		ieee80211_bss_free(wpa_s, prev);
1482	}
1483}
1484
1485
1486static void ieee80211_bss_info(struct wpa_supplicant *wpa_s,
1487			       struct ieee80211_mgmt *mgmt,
1488			       size_t len,
1489			       struct ieee80211_rx_status *rx_status,
1490			       int beacon)
1491{
1492	struct ieee802_11_elems elems;
1493	size_t baselen;
1494	int channel, invalid = 0, clen;
1495	struct ieee80211_sta_bss *bss;
1496	u64 timestamp;
1497	u8 *pos;
1498
1499	if (!beacon && os_memcmp(mgmt->da, wpa_s->own_addr, ETH_ALEN))
1500		return; /* ignore ProbeResp to foreign address */
1501
1502#if 0
1503	wpa_printf(MSG_MSGDUMP, "MLME: RX %s from " MACSTR " to " MACSTR,
1504		   beacon ? "Beacon" : "Probe Response",
1505		   MAC2STR(mgmt->sa), MAC2STR(mgmt->da));
1506#endif
1507
1508	baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt;
1509	if (baselen > len)
1510		return;
1511
1512	pos = mgmt->u.beacon.timestamp;
1513	timestamp = ((u64) pos[7] << 56) | ((u64) pos[6] << 48) |
1514		((u64) pos[5] << 40) | ((u64) pos[4] << 32) |
1515		((u64) pos[3] << 24) | ((u64) pos[2] << 16) |
1516		((u64) pos[1] << 8) | ((u64) pos[0]);
1517
1518#if 0 /* FIX */
1519	if (local->conf.mode == IW_MODE_ADHOC && beacon &&
1520	    os_memcmp(mgmt->bssid, local->bssid, ETH_ALEN) == 0) {
1521#ifdef IEEE80211_IBSS_DEBUG
1522		static unsigned long last_tsf_debug = 0;
1523		u64 tsf;
1524		if (local->hw->get_tsf)
1525			tsf = local->hw->get_tsf(local->mdev);
1526		else
1527			tsf = -1LLU;
1528		if (time_after(jiffies, last_tsf_debug + 5 * HZ)) {
1529			wpa_printf(MSG_DEBUG, "RX beacon SA=" MACSTR " BSSID="
1530				   MACSTR " TSF=0x%llx BCN=0x%llx diff=%lld "
1531				   "@%ld",
1532				   MAC2STR(mgmt->sa), MAC2STR(mgmt->bssid),
1533				   tsf, timestamp, tsf - timestamp, jiffies);
1534			last_tsf_debug = jiffies;
1535		}
1536#endif /* IEEE80211_IBSS_DEBUG */
1537	}
1538#endif
1539
1540	if (ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen,
1541				   &elems) == ParseFailed)
1542		invalid = 1;
1543
1544#if 0 /* FIX */
1545	if (local->conf.mode == IW_MODE_ADHOC && elems.supp_rates &&
1546	    os_memcmp(mgmt->bssid, local->bssid, ETH_ALEN) == 0 &&
1547	    (sta = sta_info_get(local, mgmt->sa))) {
1548		struct ieee80211_rate *rates;
1549		size_t num_rates;
1550		u32 supp_rates, prev_rates;
1551		int i, j, oper_mode;
1552
1553		rates = local->curr_rates;
1554		num_rates = local->num_curr_rates;
1555		oper_mode = wpa_s->mlme.sta_scanning ?
1556			local->scan_oper_phymode : local->conf.phymode;
1557		for (i = 0; i < local->hw->num_modes; i++) {
1558			struct ieee80211_hw_modes *mode = &local->hw->modes[i];
1559			if (oper_mode == mode->mode) {
1560				rates = mode->rates;
1561				num_rates = mode->num_rates;
1562				break;
1563			}
1564		}
1565
1566		supp_rates = 0;
1567		for (i = 0; i < elems.supp_rates_len +
1568			     elems.ext_supp_rates_len; i++) {
1569			u8 rate = 0;
1570			int own_rate;
1571			if (i < elems.supp_rates_len)
1572				rate = elems.supp_rates[i];
1573			else if (elems.ext_supp_rates)
1574				rate = elems.ext_supp_rates
1575					[i - elems.supp_rates_len];
1576			own_rate = 5 * (rate & 0x7f);
1577			if (oper_mode == MODE_ATHEROS_TURBO)
1578				own_rate *= 2;
1579			for (j = 0; j < num_rates; j++)
1580				if (rates[j].rate == own_rate)
1581					supp_rates |= BIT(j);
1582		}
1583
1584		prev_rates = sta->supp_rates;
1585		sta->supp_rates &= supp_rates;
1586		if (sta->supp_rates == 0) {
1587			/* No matching rates - this should not really happen.
1588			 * Make sure that at least one rate is marked
1589			 * supported to avoid issues with TX rate ctrl. */
1590			sta->supp_rates = wpa_s->mlme.supp_rates_bits;
1591		}
1592		if (sta->supp_rates != prev_rates) {
1593			wpa_printf(MSG_DEBUG, "MLME: updated supp_rates set "
1594				   "for " MACSTR " based on beacon info "
1595				   "(0x%x & 0x%x -> 0x%x)",
1596				   MAC2STR(sta->addr), prev_rates,
1597				   supp_rates, sta->supp_rates);
1598		}
1599		sta_info_release(local, sta);
1600	}
1601#endif
1602
1603	if (elems.ssid == NULL)
1604		return;
1605
1606	if (elems.ds_params && elems.ds_params_len == 1)
1607		channel = elems.ds_params[0];
1608	else
1609		channel = rx_status->channel;
1610
1611	bss = ieee80211_bss_get(wpa_s, mgmt->bssid);
1612	if (bss == NULL) {
1613		bss = ieee80211_bss_add(wpa_s, mgmt->bssid);
1614		if (bss == NULL)
1615			return;
1616	} else {
1617#if 0
1618		/* TODO: order by RSSI? */
1619		spin_lock_bh(&local->sta_bss_lock);
1620		list_move_tail(&bss->list, &local->sta_bss_list);
1621		spin_unlock_bh(&local->sta_bss_lock);
1622#endif
1623	}
1624
1625	if (bss->probe_resp && beacon) {
1626		/* Do not allow beacon to override data from Probe Response. */
1627		return;
1628	}
1629
1630	bss->beacon_int = le_to_host16(mgmt->u.beacon.beacon_int);
1631	bss->capability = le_to_host16(mgmt->u.beacon.capab_info);
1632	if (elems.ssid && elems.ssid_len <= MAX_SSID_LEN) {
1633		os_memcpy(bss->ssid, elems.ssid, elems.ssid_len);
1634		bss->ssid_len = elems.ssid_len;
1635	}
1636
1637	bss->supp_rates_len = 0;
1638	if (elems.supp_rates) {
1639		clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len;
1640		if (clen > elems.supp_rates_len)
1641			clen = elems.supp_rates_len;
1642		os_memcpy(&bss->supp_rates[bss->supp_rates_len],
1643			  elems.supp_rates, clen);
1644		bss->supp_rates_len += clen;
1645	}
1646	if (elems.ext_supp_rates) {
1647		clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len;
1648		if (clen > elems.ext_supp_rates_len)
1649			clen = elems.ext_supp_rates_len;
1650		os_memcpy(&bss->supp_rates[bss->supp_rates_len],
1651			  elems.ext_supp_rates, clen);
1652		bss->supp_rates_len += clen;
1653	}
1654
1655	if (elems.wpa &&
1656	    (bss->wpa_ie == NULL || bss->wpa_ie_len != elems.wpa_len ||
1657	     os_memcmp(bss->wpa_ie, elems.wpa, elems.wpa_len))) {
1658		os_free(bss->wpa_ie);
1659		bss->wpa_ie = os_malloc(elems.wpa_len + 2);
1660		if (bss->wpa_ie) {
1661			os_memcpy(bss->wpa_ie, elems.wpa - 2,
1662				  elems.wpa_len + 2);
1663			bss->wpa_ie_len = elems.wpa_len + 2;
1664		} else
1665			bss->wpa_ie_len = 0;
1666	} else if (!elems.wpa && bss->wpa_ie) {
1667		os_free(bss->wpa_ie);
1668		bss->wpa_ie = NULL;
1669		bss->wpa_ie_len = 0;
1670	}
1671
1672	if (elems.rsn &&
1673	    (bss->rsn_ie == NULL || bss->rsn_ie_len != elems.rsn_len ||
1674	     os_memcmp(bss->rsn_ie, elems.rsn, elems.rsn_len))) {
1675		os_free(bss->rsn_ie);
1676		bss->rsn_ie = os_malloc(elems.rsn_len + 2);
1677		if (bss->rsn_ie) {
1678			os_memcpy(bss->rsn_ie, elems.rsn - 2,
1679				  elems.rsn_len + 2);
1680			bss->rsn_ie_len = elems.rsn_len + 2;
1681		} else
1682			bss->rsn_ie_len = 0;
1683	} else if (!elems.rsn && bss->rsn_ie) {
1684		os_free(bss->rsn_ie);
1685		bss->rsn_ie = NULL;
1686		bss->rsn_ie_len = 0;
1687	}
1688
1689	if (elems.wmm_param &&
1690	    (bss->wmm_ie == NULL || bss->wmm_ie_len != elems.wmm_param_len ||
1691	     os_memcmp(bss->wmm_ie, elems.wmm_param, elems.wmm_param_len))) {
1692		os_free(bss->wmm_ie);
1693		bss->wmm_ie = os_malloc(elems.wmm_param_len + 2);
1694		if (bss->wmm_ie) {
1695			os_memcpy(bss->wmm_ie, elems.wmm_param - 2,
1696				  elems.wmm_param_len + 2);
1697			bss->wmm_ie_len = elems.wmm_param_len + 2;
1698		} else
1699			bss->wmm_ie_len = 0;
1700	} else if (!elems.wmm_param && bss->wmm_ie) {
1701		os_free(bss->wmm_ie);
1702		bss->wmm_ie = NULL;
1703		bss->wmm_ie_len = 0;
1704	}
1705
1706
1707	bss->hw_mode = wpa_s->mlme.phymode;
1708	bss->channel = channel;
1709	bss->freq = wpa_s->mlme.freq;
1710	if (channel != wpa_s->mlme.channel &&
1711	    (wpa_s->mlme.phymode == WPA_MODE_IEEE80211G ||
1712	     wpa_s->mlme.phymode == WPA_MODE_IEEE80211B) &&
1713	    channel >= 1 && channel <= 14) {
1714		static const int freq_list[] = {
1715			2412, 2417, 2422, 2427, 2432, 2437, 2442,
1716			2447, 2452, 2457, 2462, 2467, 2472, 2484
1717		};
1718		/* IEEE 802.11g/b mode can receive packets from neighboring
1719		 * channels, so map the channel into frequency. */
1720		bss->freq = freq_list[channel - 1];
1721	}
1722	bss->timestamp = timestamp;
1723	os_get_time(&bss->last_update);
1724	bss->rssi = rx_status->ssi;
1725	if (!beacon)
1726		bss->probe_resp++;
1727}
1728
1729
1730static void ieee80211_rx_mgmt_probe_resp(struct wpa_supplicant *wpa_s,
1731					 struct ieee80211_mgmt *mgmt,
1732					 size_t len,
1733					 struct ieee80211_rx_status *rx_status)
1734{
1735	ieee80211_bss_info(wpa_s, mgmt, len, rx_status, 0);
1736}
1737
1738
1739static void ieee80211_rx_mgmt_beacon(struct wpa_supplicant *wpa_s,
1740				     struct ieee80211_mgmt *mgmt,
1741				     size_t len,
1742				     struct ieee80211_rx_status *rx_status)
1743{
1744	int use_protection;
1745	size_t baselen;
1746	struct ieee802_11_elems elems;
1747
1748	ieee80211_bss_info(wpa_s, mgmt, len, rx_status, 1);
1749
1750	if (!wpa_s->mlme.associated ||
1751	    os_memcmp(wpa_s->bssid, mgmt->bssid, ETH_ALEN) != 0)
1752		return;
1753
1754	/* Process beacon from the current BSS */
1755	baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt;
1756	if (baselen > len)
1757		return;
1758
1759	if (ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen,
1760				   &elems) == ParseFailed)
1761		return;
1762
1763	use_protection = 0;
1764	if (elems.erp_info && elems.erp_info_len >= 1) {
1765		use_protection =
1766			(elems.erp_info[0] & ERP_INFO_USE_PROTECTION) != 0;
1767	}
1768
1769	if (use_protection != !!wpa_s->mlme.use_protection) {
1770		wpa_printf(MSG_DEBUG, "MLME: CTS protection %s (BSSID=" MACSTR
1771			   ")",
1772			   use_protection ? "enabled" : "disabled",
1773			   MAC2STR(wpa_s->bssid));
1774		wpa_s->mlme.use_protection = use_protection ? 1 : 0;
1775		wpa_s->mlme.cts_protect_erp_frames = use_protection;
1776	}
1777
1778	if (elems.wmm_param && wpa_s->mlme.wmm_enabled) {
1779		ieee80211_sta_wmm_params(wpa_s, elems.wmm_param,
1780					 elems.wmm_param_len);
1781	}
1782}
1783
1784
1785static void ieee80211_rx_mgmt_probe_req(struct wpa_supplicant *wpa_s,
1786					struct ieee80211_mgmt *mgmt,
1787					size_t len,
1788					struct ieee80211_rx_status *rx_status)
1789{
1790	int tx_last_beacon, adhoc;
1791#if 0 /* FIX */
1792	struct ieee80211_mgmt *resp;
1793#endif
1794	u8 *pos, *end;
1795	struct wpa_ssid *ssid = wpa_s->current_ssid;
1796
1797	adhoc = ssid && ssid->mode == 1;
1798
1799	if (!adhoc || wpa_s->mlme.state != IEEE80211_IBSS_JOINED ||
1800	    len < 24 + 2 || wpa_s->mlme.probe_resp == NULL)
1801		return;
1802
1803#if 0 /* FIX */
1804	if (local->hw->tx_last_beacon)
1805		tx_last_beacon = local->hw->tx_last_beacon(local->mdev);
1806	else
1807#endif
1808		tx_last_beacon = 1;
1809
1810#ifdef IEEE80211_IBSS_DEBUG
1811	wpa_printf(MSG_DEBUG, "MLME: RX ProbeReq SA=" MACSTR " DA=" MACSTR
1812		   " BSSID=" MACSTR " (tx_last_beacon=%d)",
1813		   MAC2STR(mgmt->sa), MAC2STR(mgmt->da),
1814		   MAC2STR(mgmt->bssid), tx_last_beacon);
1815#endif /* IEEE80211_IBSS_DEBUG */
1816
1817	if (!tx_last_beacon)
1818		return;
1819
1820	if (os_memcmp(mgmt->bssid, wpa_s->bssid, ETH_ALEN) != 0 &&
1821	    os_memcmp(mgmt->bssid, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) != 0)
1822		return;
1823
1824	end = ((u8 *) mgmt) + len;
1825	pos = mgmt->u.probe_req.variable;
1826	if (pos[0] != WLAN_EID_SSID ||
1827	    pos + 2 + pos[1] > end) {
1828		wpa_printf(MSG_DEBUG, "MLME: Invalid SSID IE in ProbeReq from "
1829			   MACSTR, MAC2STR(mgmt->sa));
1830		return;
1831	}
1832	if (pos[1] != 0 &&
1833	    (pos[1] != wpa_s->mlme.ssid_len ||
1834	     os_memcmp(pos + 2, wpa_s->mlme.ssid, wpa_s->mlme.ssid_len) != 0))
1835	{
1836		/* Ignore ProbeReq for foreign SSID */
1837		return;
1838	}
1839
1840#if 0 /* FIX */
1841	/* Reply with ProbeResp */
1842	skb = skb_copy(wpa_s->mlme.probe_resp, GFP_ATOMIC);
1843	if (skb == NULL)
1844		return;
1845
1846	resp = (struct ieee80211_mgmt *) skb->data;
1847	os_memcpy(resp->da, mgmt->sa, ETH_ALEN);
1848#ifdef IEEE80211_IBSS_DEBUG
1849	wpa_printf(MSG_DEBUG, "MLME: Sending ProbeResp to " MACSTR,
1850		   MAC2STR(resp->da));
1851#endif /* IEEE80211_IBSS_DEBUG */
1852	ieee80211_sta_tx(wpa_s, skb, 0, 1);
1853#endif
1854}
1855
1856
1857static void ieee80211_sta_rx_mgmt(struct wpa_supplicant *wpa_s,
1858				  const u8 *buf, size_t len,
1859				  struct ieee80211_rx_status *rx_status)
1860{
1861	struct ieee80211_mgmt *mgmt;
1862	u16 fc;
1863
1864	if (len < 24)
1865		return;
1866
1867	mgmt = (struct ieee80211_mgmt *) buf;
1868	fc = le_to_host16(mgmt->frame_control);
1869
1870	switch (WLAN_FC_GET_STYPE(fc)) {
1871	case WLAN_FC_STYPE_PROBE_REQ:
1872		ieee80211_rx_mgmt_probe_req(wpa_s, mgmt, len, rx_status);
1873		break;
1874	case WLAN_FC_STYPE_PROBE_RESP:
1875		ieee80211_rx_mgmt_probe_resp(wpa_s, mgmt, len, rx_status);
1876		break;
1877	case WLAN_FC_STYPE_BEACON:
1878		ieee80211_rx_mgmt_beacon(wpa_s, mgmt, len, rx_status);
1879		break;
1880	case WLAN_FC_STYPE_AUTH:
1881		ieee80211_rx_mgmt_auth(wpa_s, mgmt, len, rx_status);
1882		break;
1883	case WLAN_FC_STYPE_ASSOC_RESP:
1884		ieee80211_rx_mgmt_assoc_resp(wpa_s, mgmt, len, rx_status, 0);
1885		break;
1886	case WLAN_FC_STYPE_REASSOC_RESP:
1887		ieee80211_rx_mgmt_assoc_resp(wpa_s, mgmt, len, rx_status, 1);
1888		break;
1889	case WLAN_FC_STYPE_DEAUTH:
1890		ieee80211_rx_mgmt_deauth(wpa_s, mgmt, len, rx_status);
1891		break;
1892	case WLAN_FC_STYPE_DISASSOC:
1893		ieee80211_rx_mgmt_disassoc(wpa_s, mgmt, len, rx_status);
1894		break;
1895	default:
1896		wpa_printf(MSG_DEBUG, "MLME: received unknown management "
1897			   "frame - stype=%d", WLAN_FC_GET_STYPE(fc));
1898		break;
1899	}
1900}
1901
1902
1903static void ieee80211_sta_rx_scan(struct wpa_supplicant *wpa_s,
1904				  const u8 *buf, size_t len,
1905				  struct ieee80211_rx_status *rx_status)
1906{
1907	struct ieee80211_mgmt *mgmt;
1908	u16 fc;
1909
1910	if (len < 24)
1911		return;
1912
1913	mgmt = (struct ieee80211_mgmt *) buf;
1914	fc = le_to_host16(mgmt->frame_control);
1915
1916	if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT) {
1917		if (WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_PROBE_RESP) {
1918			ieee80211_rx_mgmt_probe_resp(wpa_s, mgmt,
1919						     len, rx_status);
1920		} else if (WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON) {
1921			ieee80211_rx_mgmt_beacon(wpa_s, mgmt, len, rx_status);
1922		}
1923	}
1924}
1925
1926
1927static int ieee80211_sta_active_ibss(struct wpa_supplicant *wpa_s)
1928{
1929	int active = 0;
1930
1931#if 0 /* FIX */
1932	list_for_each(ptr, &local->sta_list) {
1933		sta = list_entry(ptr, struct sta_info, list);
1934		if (sta->dev == dev &&
1935		    time_after(sta->last_rx + IEEE80211_IBSS_MERGE_INTERVAL,
1936			       jiffies)) {
1937			active++;
1938			break;
1939		}
1940	}
1941#endif
1942
1943	return active;
1944}
1945
1946
1947static void ieee80211_sta_expire(struct wpa_supplicant *wpa_s)
1948{
1949#if 0 /* FIX */
1950	list_for_each_safe(ptr, n, &local->sta_list) {
1951		sta = list_entry(ptr, struct sta_info, list);
1952		if (time_after(jiffies, sta->last_rx +
1953			       IEEE80211_IBSS_INACTIVITY_LIMIT)) {
1954			wpa_printf(MSG_DEBUG, "MLME: expiring inactive STA "
1955				   MACSTR, MAC2STR(sta->addr));
1956			sta_info_free(local, sta, 1);
1957		}
1958	}
1959#endif
1960}
1961
1962
1963static void ieee80211_sta_merge_ibss(struct wpa_supplicant *wpa_s)
1964{
1965	ieee80211_reschedule_timer(wpa_s, IEEE80211_IBSS_MERGE_INTERVAL);
1966
1967	ieee80211_sta_expire(wpa_s);
1968	if (ieee80211_sta_active_ibss(wpa_s))
1969		return;
1970
1971	wpa_printf(MSG_DEBUG, "MLME: No active IBSS STAs - trying to scan for "
1972		   "other IBSS networks with same SSID (merge)");
1973	ieee80211_sta_req_scan(wpa_s, wpa_s->mlme.ssid, wpa_s->mlme.ssid_len);
1974}
1975
1976
1977static void ieee80211_sta_timer(void *eloop_ctx, void *timeout_ctx)
1978{
1979	struct wpa_supplicant *wpa_s = eloop_ctx;
1980
1981	switch (wpa_s->mlme.state) {
1982	case IEEE80211_DISABLED:
1983		break;
1984	case IEEE80211_AUTHENTICATE:
1985		ieee80211_authenticate(wpa_s);
1986		break;
1987	case IEEE80211_ASSOCIATE:
1988		ieee80211_associate(wpa_s);
1989		break;
1990	case IEEE80211_ASSOCIATED:
1991		ieee80211_associated(wpa_s);
1992		break;
1993	case IEEE80211_IBSS_SEARCH:
1994		ieee80211_sta_find_ibss(wpa_s);
1995		break;
1996	case IEEE80211_IBSS_JOINED:
1997		ieee80211_sta_merge_ibss(wpa_s);
1998		break;
1999	default:
2000		wpa_printf(MSG_DEBUG, "ieee80211_sta_timer: Unknown state %d",
2001			   wpa_s->mlme.state);
2002		break;
2003	}
2004
2005	if (ieee80211_privacy_mismatch(wpa_s)) {
2006		wpa_printf(MSG_DEBUG, "MLME: privacy configuration mismatch "
2007			   "and mixed-cell disabled - disassociate");
2008
2009		ieee80211_send_disassoc(wpa_s, WLAN_REASON_UNSPECIFIED);
2010		ieee80211_set_associated(wpa_s, 0);
2011	}
2012}
2013
2014
2015static void ieee80211_sta_new_auth(struct wpa_supplicant *wpa_s)
2016{
2017	struct wpa_ssid *ssid = wpa_s->current_ssid;
2018	if (ssid && ssid->mode != 0)
2019		return;
2020
2021#if 0 /* FIX */
2022	if (local->hw->reset_tsf) {
2023		/* Reset own TSF to allow time synchronization work. */
2024		local->hw->reset_tsf(local->mdev);
2025	}
2026#endif
2027
2028	wpa_s->mlme.wmm_last_param_set = -1; /* allow any WMM update */
2029
2030
2031	if (wpa_s->mlme.auth_algs & IEEE80211_AUTH_ALG_OPEN)
2032		wpa_s->mlme.auth_alg = WLAN_AUTH_OPEN;
2033	else if (wpa_s->mlme.auth_algs & IEEE80211_AUTH_ALG_SHARED_KEY)
2034		wpa_s->mlme.auth_alg = WLAN_AUTH_SHARED_KEY;
2035	else if (wpa_s->mlme.auth_algs & IEEE80211_AUTH_ALG_LEAP)
2036		wpa_s->mlme.auth_alg = WLAN_AUTH_LEAP;
2037	else
2038		wpa_s->mlme.auth_alg = WLAN_AUTH_OPEN;
2039	wpa_printf(MSG_DEBUG, "MLME: Initial auth_alg=%d",
2040		   wpa_s->mlme.auth_alg);
2041	wpa_s->mlme.auth_transaction = -1;
2042	wpa_s->mlme.auth_tries = wpa_s->mlme.assoc_tries = 0;
2043	ieee80211_authenticate(wpa_s);
2044}
2045
2046
2047static int ieee80211_ibss_allowed(struct wpa_supplicant *wpa_s)
2048{
2049#if 0 /* FIX */
2050	int m, c;
2051
2052	for (m = 0; m < local->hw->num_modes; m++) {
2053		struct ieee80211_hw_modes *mode = &local->hw->modes[m];
2054		if (mode->mode != local->conf.phymode)
2055			continue;
2056		for (c = 0; c < mode->num_channels; c++) {
2057			struct ieee80211_channel *chan = &mode->channels[c];
2058			if (chan->flag & IEEE80211_CHAN_W_SCAN &&
2059			    chan->chan == local->conf.channel) {
2060				if (chan->flag & IEEE80211_CHAN_W_IBSS)
2061					return 1;
2062				break;
2063			}
2064		}
2065	}
2066#endif
2067
2068	return 0;
2069}
2070
2071
2072static int ieee80211_sta_join_ibss(struct wpa_supplicant *wpa_s,
2073				   struct ieee80211_sta_bss *bss)
2074{
2075	int res = 0, rates, done = 0;
2076	struct ieee80211_mgmt *mgmt;
2077#if 0 /* FIX */
2078	struct ieee80211_tx_control control;
2079	struct ieee80211_rate *rate;
2080	struct rate_control_extra extra;
2081#endif
2082	u8 *pos, *buf;
2083	size_t len;
2084
2085	/* Remove possible STA entries from other IBSS networks. */
2086#if 0 /* FIX */
2087	sta_info_flush(local, NULL);
2088
2089	if (local->hw->reset_tsf) {
2090		/* Reset own TSF to allow time synchronization work. */
2091		local->hw->reset_tsf(local->mdev);
2092	}
2093#endif
2094	os_memcpy(wpa_s->bssid, bss->bssid, ETH_ALEN);
2095
2096#if 0 /* FIX */
2097	local->conf.beacon_int = bss->beacon_int >= 10 ? bss->beacon_int : 10;
2098
2099	sdata->drop_unencrypted = bss->capability &
2100		host_to_le16(WLAN_CAPABILITY_PRIVACY) ? 1 : 0;
2101#endif
2102
2103#if 0 /* FIX */
2104	os_memset(&rq, 0, sizeof(rq));
2105	rq.m = bss->freq * 100000;
2106	rq.e = 1;
2107	res = ieee80211_ioctl_siwfreq(wpa_s, NULL, &rq, NULL);
2108#endif
2109
2110	if (!ieee80211_ibss_allowed(wpa_s)) {
2111#if 0 /* FIX */
2112		wpa_printf(MSG_DEBUG, "MLME: IBSS not allowed on channel %d "
2113			   "(%d MHz)", local->conf.channel,
2114			   local->conf.freq);
2115#endif
2116		return -1;
2117	}
2118
2119	/* Set beacon template based on scan results */
2120	buf = os_malloc(400);
2121	len = 0;
2122	do {
2123		if (buf == NULL)
2124			break;
2125
2126		mgmt = (struct ieee80211_mgmt *) buf;
2127		len += 24 + sizeof(mgmt->u.beacon);
2128		os_memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon));
2129		mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
2130						   WLAN_FC_STYPE_BEACON);
2131		os_memset(mgmt->da, 0xff, ETH_ALEN);
2132		os_memcpy(mgmt->sa, wpa_s->own_addr, ETH_ALEN);
2133		os_memcpy(mgmt->bssid, wpa_s->bssid, ETH_ALEN);
2134#if 0 /* FIX */
2135		mgmt->u.beacon.beacon_int =
2136			host_to_le16(local->conf.beacon_int);
2137#endif
2138		mgmt->u.beacon.capab_info = host_to_le16(bss->capability);
2139
2140		pos = buf + len;
2141		len += 2 + wpa_s->mlme.ssid_len;
2142		*pos++ = WLAN_EID_SSID;
2143		*pos++ = wpa_s->mlme.ssid_len;
2144		os_memcpy(pos, wpa_s->mlme.ssid, wpa_s->mlme.ssid_len);
2145
2146		rates = bss->supp_rates_len;
2147		if (rates > 8)
2148			rates = 8;
2149		pos = buf + len;
2150		len += 2 + rates;
2151		*pos++ = WLAN_EID_SUPP_RATES;
2152		*pos++ = rates;
2153		os_memcpy(pos, bss->supp_rates, rates);
2154
2155		pos = buf + len;
2156		len += 2 + 1;
2157		*pos++ = WLAN_EID_DS_PARAMS;
2158		*pos++ = 1;
2159		*pos++ = bss->channel;
2160
2161		pos = buf + len;
2162		len += 2 + 2;
2163		*pos++ = WLAN_EID_IBSS_PARAMS;
2164		*pos++ = 2;
2165		/* FIX: set ATIM window based on scan results */
2166		*pos++ = 0;
2167		*pos++ = 0;
2168
2169		if (bss->supp_rates_len > 8) {
2170			rates = bss->supp_rates_len - 8;
2171			pos = buf + len;
2172			len += 2 + rates;
2173			*pos++ = WLAN_EID_EXT_SUPP_RATES;
2174			*pos++ = rates;
2175			os_memcpy(pos, &bss->supp_rates[8], rates);
2176		}
2177
2178#if 0 /* FIX */
2179		os_memset(&control, 0, sizeof(control));
2180		control.pkt_type = PKT_PROBE_RESP;
2181		os_memset(&extra, 0, sizeof(extra));
2182		extra.endidx = local->num_curr_rates;
2183		rate = rate_control_get_rate(wpa_s, skb, &extra);
2184		if (rate == NULL) {
2185			wpa_printf(MSG_DEBUG, "MLME: Failed to determine TX "
2186				   "rate for IBSS beacon");
2187			break;
2188		}
2189		control.tx_rate = (wpa_s->mlme.short_preamble &&
2190				   (rate->flags & IEEE80211_RATE_PREAMBLE2)) ?
2191			rate->val2 : rate->val;
2192		control.antenna_sel = local->conf.antenna_sel;
2193		control.power_level = local->conf.power_level;
2194		control.no_ack = 1;
2195		control.retry_limit = 1;
2196		control.rts_cts_duration = 0;
2197#endif
2198
2199#if 0 /* FIX */
2200		wpa_s->mlme.probe_resp = skb_copy(skb, GFP_ATOMIC);
2201		if (wpa_s->mlme.probe_resp) {
2202			mgmt = (struct ieee80211_mgmt *)
2203				wpa_s->mlme.probe_resp->data;
2204			mgmt->frame_control =
2205				IEEE80211_FC(WLAN_FC_TYPE_MGMT,
2206					     WLAN_FC_STYPE_PROBE_RESP);
2207		} else {
2208			wpa_printf(MSG_DEBUG, "MLME: Could not allocate "
2209				   "ProbeResp template for IBSS");
2210		}
2211
2212		if (local->hw->beacon_update &&
2213		    local->hw->beacon_update(wpa_s, skb, &control) == 0) {
2214			wpa_printf(MSG_DEBUG, "MLME: Configured IBSS beacon "
2215				   "template based on scan results");
2216			skb = NULL;
2217		}
2218
2219		rates = 0;
2220		for (i = 0; i < bss->supp_rates_len; i++) {
2221			int rate = (bss->supp_rates[i] & 0x7f) * 5;
2222			if (local->conf.phymode == MODE_ATHEROS_TURBO)
2223				rate *= 2;
2224			for (j = 0; j < local->num_curr_rates; j++)
2225				if (local->curr_rates[j].rate == rate)
2226					rates |= BIT(j);
2227		}
2228		wpa_s->mlme.supp_rates_bits = rates;
2229#endif
2230		done = 1;
2231	} while (0);
2232
2233	os_free(buf);
2234	if (!done) {
2235		wpa_printf(MSG_DEBUG, "MLME: Failed to configure IBSS beacon "
2236			   "template");
2237	}
2238
2239	wpa_s->mlme.state = IEEE80211_IBSS_JOINED;
2240	ieee80211_reschedule_timer(wpa_s, IEEE80211_IBSS_MERGE_INTERVAL);
2241
2242	return res;
2243}
2244
2245
2246#if 0 /* FIX */
2247static int ieee80211_sta_create_ibss(struct wpa_supplicant *wpa_s)
2248{
2249	struct ieee80211_sta_bss *bss;
2250	u8 bssid[ETH_ALEN], *pos;
2251	int i;
2252
2253#if 0
2254	/* Easier testing, use fixed BSSID. */
2255	os_memset(bssid, 0xfe, ETH_ALEN);
2256#else
2257	/* Generate random, not broadcast, locally administered BSSID. Mix in
2258	 * own MAC address to make sure that devices that do not have proper
2259	 * random number generator get different BSSID. */
2260	os_get_random(bssid, ETH_ALEN);
2261	for (i = 0; i < ETH_ALEN; i++)
2262		bssid[i] ^= wpa_s->own_addr[i];
2263	bssid[0] &= ~0x01;
2264	bssid[0] |= 0x02;
2265#endif
2266
2267	wpa_printf(MSG_DEBUG, "MLME: Creating new IBSS network, BSSID "
2268		   MACSTR "", MAC2STR(bssid));
2269
2270	bss = ieee80211_bss_add(wpa_s, bssid);
2271	if (bss == NULL)
2272		return -ENOMEM;
2273
2274#if 0 /* FIX */
2275	if (local->conf.beacon_int == 0)
2276		local->conf.beacon_int = 100;
2277	bss->beacon_int = local->conf.beacon_int;
2278	bss->hw_mode = local->conf.phymode;
2279	bss->channel = local->conf.channel;
2280	bss->freq = local->conf.freq;
2281#endif
2282	os_get_time(&bss->last_update);
2283	bss->capability = host_to_le16(WLAN_CAPABILITY_IBSS);
2284#if 0 /* FIX */
2285	if (sdata->default_key) {
2286		bss->capability |= host_to_le16(WLAN_CAPABILITY_PRIVACY);
2287	} else
2288		sdata->drop_unencrypted = 0;
2289	bss->supp_rates_len = local->num_curr_rates;
2290#endif
2291	pos = bss->supp_rates;
2292#if 0 /* FIX */
2293	for (i = 0; i < local->num_curr_rates; i++) {
2294		int rate = local->curr_rates[i].rate;
2295		if (local->conf.phymode == MODE_ATHEROS_TURBO)
2296			rate /= 2;
2297		*pos++ = (u8) (rate / 5);
2298	}
2299#endif
2300
2301	return ieee80211_sta_join_ibss(wpa_s, bss);
2302}
2303#endif
2304
2305
2306static int ieee80211_sta_find_ibss(struct wpa_supplicant *wpa_s)
2307{
2308	struct ieee80211_sta_bss *bss;
2309	int found = 0;
2310	u8 bssid[ETH_ALEN];
2311	int active_ibss;
2312	struct os_time now;
2313
2314	if (wpa_s->mlme.ssid_len == 0)
2315		return -EINVAL;
2316
2317	active_ibss = ieee80211_sta_active_ibss(wpa_s);
2318#ifdef IEEE80211_IBSS_DEBUG
2319	wpa_printf(MSG_DEBUG, "MLME: sta_find_ibss (active_ibss=%d)",
2320		   active_ibss);
2321#endif /* IEEE80211_IBSS_DEBUG */
2322	for (bss = wpa_s->mlme.sta_bss_list; bss; bss = bss->next) {
2323		if (wpa_s->mlme.ssid_len != bss->ssid_len ||
2324		    os_memcmp(wpa_s->mlme.ssid, bss->ssid, bss->ssid_len) != 0
2325		    || !(bss->capability & WLAN_CAPABILITY_IBSS))
2326			continue;
2327#ifdef IEEE80211_IBSS_DEBUG
2328		wpa_printf(MSG_DEBUG, "   bssid=" MACSTR " found",
2329			   MAC2STR(bss->bssid));
2330#endif /* IEEE80211_IBSS_DEBUG */
2331		os_memcpy(bssid, bss->bssid, ETH_ALEN);
2332		found = 1;
2333		if (active_ibss ||
2334		    os_memcmp(bssid, wpa_s->bssid, ETH_ALEN) != 0)
2335			break;
2336	}
2337
2338#ifdef IEEE80211_IBSS_DEBUG
2339	wpa_printf(MSG_DEBUG, "   sta_find_ibss: selected " MACSTR " current "
2340		   MACSTR, MAC2STR(bssid), MAC2STR(wpa_s->bssid));
2341#endif /* IEEE80211_IBSS_DEBUG */
2342	if (found && os_memcmp(wpa_s->bssid, bssid, ETH_ALEN) != 0 &&
2343	    (bss = ieee80211_bss_get(wpa_s, bssid))) {
2344		wpa_printf(MSG_DEBUG, "MLME: Selected IBSS BSSID " MACSTR
2345			   " based on configured SSID",
2346			   MAC2STR(bssid));
2347		return ieee80211_sta_join_ibss(wpa_s, bss);
2348	}
2349#ifdef IEEE80211_IBSS_DEBUG
2350	wpa_printf(MSG_DEBUG, "   did not try to join ibss");
2351#endif /* IEEE80211_IBSS_DEBUG */
2352
2353	/* Selected IBSS not found in current scan results - try to scan */
2354	os_get_time(&now);
2355#if 0 /* FIX */
2356	if (wpa_s->mlme.state == IEEE80211_IBSS_JOINED &&
2357	    !ieee80211_sta_active_ibss(wpa_s)) {
2358		ieee80211_reschedule_timer(wpa_s,
2359					   IEEE80211_IBSS_MERGE_INTERVAL);
2360	} else if (time_after(jiffies, wpa_s->mlme.last_scan_completed +
2361			      IEEE80211_SCAN_INTERVAL)) {
2362		wpa_printf(MSG_DEBUG, "MLME: Trigger new scan to find an IBSS "
2363			   "to join");
2364		return ieee80211_sta_req_scan(wpa_s->mlme.ssid,
2365					      wpa_s->mlme.ssid_len);
2366	} else if (wpa_s->mlme.state != IEEE80211_IBSS_JOINED) {
2367		int interval = IEEE80211_SCAN_INTERVAL;
2368
2369		if (time_after(jiffies, wpa_s->mlme.ibss_join_req +
2370			       IEEE80211_IBSS_JOIN_TIMEOUT)) {
2371			if (wpa_s->mlme.create_ibss &&
2372			    ieee80211_ibss_allowed(wpa_s))
2373				return ieee80211_sta_create_ibss(wpa_s);
2374			if (wpa_s->mlme.create_ibss) {
2375				wpa_printf(MSG_DEBUG, "MLME: IBSS not allowed "
2376					   "on the configured channel %d "
2377					   "(%d MHz)",
2378					   local->conf.channel,
2379					   local->conf.freq);
2380			}
2381
2382			/* No IBSS found - decrease scan interval and continue
2383			 * scanning. */
2384			interval = IEEE80211_SCAN_INTERVAL_SLOW;
2385		}
2386
2387		wpa_s->mlme.state = IEEE80211_IBSS_SEARCH;
2388		ieee80211_reschedule_timer(wpa_s, interval);
2389		return 0;
2390	}
2391#endif
2392
2393	return 0;
2394}
2395
2396
2397int ieee80211_sta_get_ssid(struct wpa_supplicant *wpa_s, u8 *ssid,
2398			   size_t *len)
2399{
2400	os_memcpy(ssid, wpa_s->mlme.ssid, wpa_s->mlme.ssid_len);
2401	*len = wpa_s->mlme.ssid_len;
2402	return 0;
2403}
2404
2405
2406int ieee80211_sta_associate(struct wpa_supplicant *wpa_s,
2407			    struct wpa_driver_associate_params *params)
2408{
2409	struct ieee80211_sta_bss *bss;
2410
2411	wpa_s->mlme.bssid_set = 0;
2412	wpa_s->mlme.freq = params->freq;
2413	if (params->bssid) {
2414		os_memcpy(wpa_s->bssid, params->bssid, ETH_ALEN);
2415		if (os_memcmp(params->bssid, "\x00\x00\x00\x00\x00\x00",
2416			      ETH_ALEN))
2417			wpa_s->mlme.bssid_set = 1;
2418		bss = ieee80211_bss_get(wpa_s, wpa_s->bssid);
2419		if (bss) {
2420			wpa_s->mlme.phymode = bss->hw_mode;
2421			wpa_s->mlme.channel = bss->channel;
2422			wpa_s->mlme.freq = bss->freq;
2423		}
2424	}
2425
2426#if 0 /* FIX */
2427	/* TODO: This should always be done for IBSS, even if IEEE80211_QOS is
2428	 * not defined. */
2429	if (local->hw->conf_tx) {
2430		struct ieee80211_tx_queue_params qparam;
2431		int i;
2432
2433		os_memset(&qparam, 0, sizeof(qparam));
2434		/* TODO: are these ok defaults for all hw_modes? */
2435		qparam.aifs = 2;
2436		qparam.cw_min =
2437			local->conf.phymode == MODE_IEEE80211B ? 31 : 15;
2438		qparam.cw_max = 1023;
2439		qparam.burst_time = 0;
2440		for (i = IEEE80211_TX_QUEUE_DATA0; i < NUM_TX_DATA_QUEUES; i++)
2441		{
2442			local->hw->conf_tx(wpa_s, i + IEEE80211_TX_QUEUE_DATA0,
2443					   &qparam);
2444		}
2445		/* IBSS uses different parameters for Beacon sending */
2446		qparam.cw_min++;
2447		qparam.cw_min *= 2;
2448		qparam.cw_min--;
2449		local->hw->conf_tx(wpa_s, IEEE80211_TX_QUEUE_BEACON, &qparam);
2450	}
2451#endif
2452
2453	if (wpa_s->mlme.ssid_len != params->ssid_len ||
2454	    os_memcmp(wpa_s->mlme.ssid, params->ssid, params->ssid_len) != 0)
2455		wpa_s->mlme.prev_bssid_set = 0;
2456	os_memcpy(wpa_s->mlme.ssid, params->ssid, params->ssid_len);
2457	os_memset(wpa_s->mlme.ssid + params->ssid_len, 0,
2458		  MAX_SSID_LEN - params->ssid_len);
2459	wpa_s->mlme.ssid_len = params->ssid_len;
2460	wpa_s->mlme.ssid_set = 1;
2461
2462	os_free(wpa_s->mlme.extra_ie);
2463	if (params->wpa_ie == NULL || params->wpa_ie_len == 0) {
2464		wpa_s->mlme.extra_ie = NULL;
2465		wpa_s->mlme.extra_ie_len = 0;
2466		return 0;
2467	}
2468	wpa_s->mlme.extra_ie = os_malloc(params->wpa_ie_len);
2469	if (wpa_s->mlme.extra_ie == NULL) {
2470		wpa_s->mlme.extra_ie_len = 0;
2471		return -1;
2472	}
2473	os_memcpy(wpa_s->mlme.extra_ie, params->wpa_ie, params->wpa_ie_len);
2474	wpa_s->mlme.extra_ie_len = params->wpa_ie_len;
2475
2476	wpa_s->mlme.key_mgmt = params->key_mgmt_suite;
2477
2478	ieee80211_sta_set_channel(wpa_s, wpa_s->mlme.phymode,
2479				  wpa_s->mlme.channel, wpa_s->mlme.freq);
2480
2481	if (params->mode == 1 && !wpa_s->mlme.bssid_set) {
2482		os_get_time(&wpa_s->mlme.ibss_join_req);
2483		wpa_s->mlme.state = IEEE80211_IBSS_SEARCH;
2484		return ieee80211_sta_find_ibss(wpa_s);
2485	}
2486
2487	if (wpa_s->mlme.bssid_set)
2488		ieee80211_sta_new_auth(wpa_s);
2489
2490	return 0;
2491}
2492
2493
2494static void ieee80211_sta_save_oper_chan(struct wpa_supplicant *wpa_s)
2495{
2496	wpa_s->mlme.scan_oper_channel = wpa_s->mlme.channel;
2497	wpa_s->mlme.scan_oper_freq = wpa_s->mlme.freq;
2498	wpa_s->mlme.scan_oper_phymode = wpa_s->mlme.phymode;
2499}
2500
2501
2502static int ieee80211_sta_restore_oper_chan(struct wpa_supplicant *wpa_s)
2503{
2504	wpa_s->mlme.channel = wpa_s->mlme.scan_oper_channel;
2505	wpa_s->mlme.freq = wpa_s->mlme.scan_oper_freq;
2506	wpa_s->mlme.phymode = wpa_s->mlme.scan_oper_phymode;
2507	if (wpa_s->mlme.freq == 0)
2508		return 0;
2509	return ieee80211_sta_set_channel(wpa_s, wpa_s->mlme.phymode,
2510					 wpa_s->mlme.channel,
2511					 wpa_s->mlme.freq);
2512}
2513
2514
2515static int ieee80211_active_scan(struct wpa_supplicant *wpa_s)
2516{
2517	size_t m;
2518	int c;
2519
2520	for (m = 0; m < wpa_s->mlme.num_modes; m++) {
2521		struct wpa_hw_modes *mode = &wpa_s->mlme.modes[m];
2522		if ((int) mode->mode != (int) wpa_s->mlme.phymode)
2523			continue;
2524		for (c = 0; c < mode->num_channels; c++) {
2525			struct wpa_channel_data *chan = &mode->channels[c];
2526			if (chan->flag & WPA_CHAN_W_SCAN &&
2527			    chan->chan == wpa_s->mlme.channel) {
2528				if (chan->flag & WPA_CHAN_W_ACTIVE_SCAN)
2529					return 1;
2530				break;
2531			}
2532		}
2533	}
2534
2535	return 0;
2536}
2537
2538
2539static void ieee80211_sta_scan_timer(void *eloop_ctx, void *timeout_ctx)
2540{
2541	struct wpa_supplicant *wpa_s = eloop_ctx;
2542	struct wpa_hw_modes *mode;
2543	struct wpa_channel_data *chan;
2544	int skip = 0;
2545	int timeout = 0;
2546	struct wpa_ssid *ssid = wpa_s->current_ssid;
2547	int adhoc;
2548
2549	if (!wpa_s->mlme.sta_scanning || wpa_s->mlme.modes == NULL)
2550		return;
2551
2552	adhoc = ssid && ssid->mode == 1;
2553
2554	switch (wpa_s->mlme.scan_state) {
2555	case SCAN_SET_CHANNEL:
2556		mode = &wpa_s->mlme.modes[wpa_s->mlme.scan_hw_mode_idx];
2557		if (wpa_s->mlme.scan_hw_mode_idx >=
2558		    (int) wpa_s->mlme.num_modes ||
2559		    (wpa_s->mlme.scan_hw_mode_idx + 1 ==
2560		     (int) wpa_s->mlme.num_modes
2561		     && wpa_s->mlme.scan_channel_idx >= mode->num_channels)) {
2562			if (ieee80211_sta_restore_oper_chan(wpa_s)) {
2563				wpa_printf(MSG_DEBUG, "MLME: failed to "
2564					   "restore operational channel after "
2565					   "scan");
2566			}
2567			wpa_printf(MSG_DEBUG, "MLME: scan completed");
2568			wpa_s->mlme.sta_scanning = 0;
2569			os_get_time(&wpa_s->mlme.last_scan_completed);
2570			wpa_supplicant_event(wpa_s, EVENT_SCAN_RESULTS, NULL);
2571			if (adhoc) {
2572				if (!wpa_s->mlme.bssid_set ||
2573				    (wpa_s->mlme.state ==
2574				     IEEE80211_IBSS_JOINED &&
2575				     !ieee80211_sta_active_ibss(wpa_s)))
2576					ieee80211_sta_find_ibss(wpa_s);
2577			}
2578			return;
2579		}
2580		skip = !(wpa_s->mlme.hw_modes & (1 << mode->mode));
2581		chan = &mode->channels[wpa_s->mlme.scan_channel_idx];
2582		if (!(chan->flag & WPA_CHAN_W_SCAN) ||
2583		    (adhoc && !(chan->flag & WPA_CHAN_W_IBSS)) ||
2584		    (wpa_s->mlme.hw_modes & (1 << WPA_MODE_IEEE80211G) &&
2585		     mode->mode == WPA_MODE_IEEE80211B &&
2586		     wpa_s->mlme.scan_skip_11b))
2587			skip = 1;
2588
2589		if (!skip) {
2590			wpa_printf(MSG_MSGDUMP,
2591				   "MLME: scan channel %d (%d MHz)",
2592				   chan->chan, chan->freq);
2593
2594			wpa_s->mlme.channel = chan->chan;
2595			wpa_s->mlme.freq = chan->freq;
2596			wpa_s->mlme.phymode = mode->mode;
2597			if (ieee80211_sta_set_channel(wpa_s, mode->mode,
2598						      chan->chan, chan->freq))
2599			{
2600				wpa_printf(MSG_DEBUG, "MLME: failed to set "
2601					   "channel %d (%d MHz) for scan",
2602					   chan->chan, chan->freq);
2603				skip = 1;
2604			}
2605		}
2606
2607		wpa_s->mlme.scan_channel_idx++;
2608		if (wpa_s->mlme.scan_channel_idx >=
2609		    wpa_s->mlme.modes[wpa_s->mlme.scan_hw_mode_idx].
2610		    num_channels) {
2611			wpa_s->mlme.scan_hw_mode_idx++;
2612			wpa_s->mlme.scan_channel_idx = 0;
2613		}
2614
2615		if (skip) {
2616			timeout = 0;
2617			break;
2618		}
2619
2620		timeout = IEEE80211_PROBE_DELAY;
2621		wpa_s->mlme.scan_state = SCAN_SEND_PROBE;
2622		break;
2623	case SCAN_SEND_PROBE:
2624		if (ieee80211_active_scan(wpa_s)) {
2625			ieee80211_send_probe_req(wpa_s, NULL,
2626						 wpa_s->mlme.scan_ssid,
2627						 wpa_s->mlme.scan_ssid_len);
2628			timeout = IEEE80211_CHANNEL_TIME;
2629		} else {
2630			timeout = IEEE80211_PASSIVE_CHANNEL_TIME;
2631		}
2632		wpa_s->mlme.scan_state = SCAN_SET_CHANNEL;
2633		break;
2634	}
2635
2636	eloop_register_timeout(timeout / 1000, 1000 * (timeout % 1000),
2637			       ieee80211_sta_scan_timer, wpa_s, NULL);
2638}
2639
2640
2641int ieee80211_sta_req_scan(struct wpa_supplicant *wpa_s, const u8 *ssid,
2642			   size_t ssid_len)
2643{
2644	if (ssid_len > MAX_SSID_LEN)
2645		return -1;
2646
2647	/* MLME-SCAN.request (page 118)  page 144 (11.1.3.1)
2648	 * BSSType: INFRASTRUCTURE, INDEPENDENT, ANY_BSS
2649	 * BSSID: MACAddress
2650	 * SSID
2651	 * ScanType: ACTIVE, PASSIVE
2652	 * ProbeDelay: delay (in microseconds) to be used prior to transmitting
2653	 *    a Probe frame during active scanning
2654	 * ChannelList
2655	 * MinChannelTime (>= ProbeDelay), in TU
2656	 * MaxChannelTime: (>= MinChannelTime), in TU
2657	 */
2658
2659	 /* MLME-SCAN.confirm
2660	  * BSSDescriptionSet
2661	  * ResultCode: SUCCESS, INVALID_PARAMETERS
2662	 */
2663
2664	/* TODO: if assoc, move to power save mode for the duration of the
2665	 * scan */
2666
2667	if (wpa_s->mlme.sta_scanning)
2668		return -1;
2669
2670	wpa_printf(MSG_DEBUG, "MLME: starting scan");
2671
2672	ieee80211_sta_save_oper_chan(wpa_s);
2673
2674	wpa_s->mlme.sta_scanning = 1;
2675	/* TODO: stop TX queue? */
2676
2677	if (ssid) {
2678		wpa_s->mlme.scan_ssid_len = ssid_len;
2679		os_memcpy(wpa_s->mlme.scan_ssid, ssid, ssid_len);
2680	} else
2681		wpa_s->mlme.scan_ssid_len = 0;
2682	wpa_s->mlme.scan_skip_11b = 1; /* FIX: clear this is 11g is not
2683					* supported */
2684	wpa_s->mlme.scan_state = SCAN_SET_CHANNEL;
2685	wpa_s->mlme.scan_hw_mode_idx = 0;
2686	wpa_s->mlme.scan_channel_idx = 0;
2687	eloop_register_timeout(0, 1, ieee80211_sta_scan_timer, wpa_s, NULL);
2688
2689	return 0;
2690}
2691
2692
2693int ieee80211_sta_get_scan_results(struct wpa_supplicant *wpa_s,
2694				   struct wpa_scan_result *results,
2695				   size_t max_size)
2696{
2697	size_t ap_num = 0;
2698	struct wpa_scan_result *r;
2699	struct ieee80211_sta_bss *bss;
2700
2701	os_memset(results, 0, max_size * sizeof(struct wpa_scan_result));
2702	for (bss = wpa_s->mlme.sta_bss_list; bss; bss = bss->next) {
2703		r = &results[ap_num];
2704		os_memcpy(r->bssid, bss->bssid, ETH_ALEN);
2705		os_memcpy(r->ssid, bss->ssid, bss->ssid_len);
2706		r->ssid_len = bss->ssid_len;
2707		if (bss->wpa_ie && bss->wpa_ie_len < SSID_MAX_WPA_IE_LEN) {
2708			os_memcpy(r->wpa_ie, bss->wpa_ie, bss->wpa_ie_len);
2709			r->wpa_ie_len = bss->wpa_ie_len;
2710		}
2711		if (bss->rsn_ie && bss->rsn_ie_len < SSID_MAX_WPA_IE_LEN) {
2712			os_memcpy(r->rsn_ie, bss->rsn_ie, bss->rsn_ie_len);
2713			r->rsn_ie_len = bss->rsn_ie_len;
2714		}
2715		r->freq = bss->freq;
2716		r->caps = bss->capability;
2717		r->level = bss->rssi;
2718
2719		ap_num++;
2720		if (ap_num >= max_size)
2721			break;
2722	}
2723
2724	return ap_num;
2725}
2726
2727
2728#if 0 /* FIX */
2729struct sta_info * ieee80211_ibss_add_sta(struct wpa_supplicant *wpa_s,
2730					 struct sk_buff *skb, u8 *bssid,
2731					 u8 *addr)
2732{
2733	struct ieee80211_local *local = dev->priv;
2734	struct list_head *ptr;
2735	struct sta_info *sta;
2736	struct wpa_supplicant *sta_dev = NULL;
2737
2738	/* TODO: Could consider removing the least recently used entry and
2739	 * allow new one to be added. */
2740	if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) {
2741		if (net_ratelimit()) {
2742			wpa_printf(MSG_DEBUG, "MLME: No room for a new IBSS "
2743				   "STA entry " MACSTR, MAC2STR(addr));
2744		}
2745		return NULL;
2746	}
2747
2748	spin_lock_bh(&local->sub_if_lock);
2749	list_for_each(ptr, &local->sub_if_list) {
2750		sdata = list_entry(ptr, struct ieee80211_sub_if_data, list);
2751		if (sdata->type == IEEE80211_SUB_IF_TYPE_STA &&
2752		    os_memcmp(bssid, sdata->u.sta.bssid, ETH_ALEN) == 0) {
2753			sta_dev = sdata->dev;
2754			break;
2755		}
2756	}
2757	spin_unlock_bh(&local->sub_if_lock);
2758
2759	if (sta_dev == NULL)
2760		return NULL;
2761
2762	wpa_printf(MSG_DEBUG, "MLME: Adding new IBSS station " MACSTR
2763		   " (dev=%s)", MAC2STR(addr), sta_dev->name);
2764
2765	sta = sta_info_add(wpa_s, addr);
2766	if (sta == NULL) {
2767		return NULL;
2768	}
2769
2770	sta->dev = sta_dev;
2771	sta->supp_rates = wpa_s->mlme.supp_rates_bits;
2772
2773	rate_control_rate_init(local, sta);
2774
2775	return sta; /* caller will call sta_info_release() */
2776}
2777#endif
2778
2779
2780int ieee80211_sta_deauthenticate(struct wpa_supplicant *wpa_s, u16 reason)
2781{
2782	wpa_printf(MSG_DEBUG, "MLME: deauthenticate(reason=%d)", reason);
2783
2784	ieee80211_send_deauth(wpa_s, reason);
2785	ieee80211_set_associated(wpa_s, 0);
2786	return 0;
2787}
2788
2789
2790int ieee80211_sta_disassociate(struct wpa_supplicant *wpa_s, u16 reason)
2791{
2792	wpa_printf(MSG_DEBUG, "MLME: disassociate(reason=%d)", reason);
2793
2794	if (!wpa_s->mlme.associated)
2795		return -1;
2796
2797	ieee80211_send_disassoc(wpa_s, reason);
2798	ieee80211_set_associated(wpa_s, 0);
2799	return 0;
2800}
2801
2802
2803void ieee80211_sta_rx(struct wpa_supplicant *wpa_s, const u8 *buf, size_t len,
2804		      struct ieee80211_rx_status *rx_status)
2805{
2806	struct ieee80211_mgmt *mgmt;
2807	u16 fc;
2808	const u8 *pos;
2809
2810	/* wpa_hexdump(MSG_MSGDUMP, "MLME: Received frame", buf, len); */
2811
2812	if (wpa_s->mlme.sta_scanning) {
2813		ieee80211_sta_rx_scan(wpa_s, buf, len, rx_status);
2814		return;
2815	}
2816
2817	if (len < 24)
2818		return;
2819
2820	mgmt = (struct ieee80211_mgmt *) buf;
2821	fc = le_to_host16(mgmt->frame_control);
2822
2823	if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT)
2824		ieee80211_sta_rx_mgmt(wpa_s, buf, len, rx_status);
2825	else if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA) {
2826		if ((fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) !=
2827		    WLAN_FC_FROMDS)
2828			return;
2829		/* mgmt->sa is actually BSSID for FromDS data frames */
2830		if (os_memcmp(mgmt->sa, wpa_s->bssid, ETH_ALEN) != 0)
2831			return;
2832		/* Skip IEEE 802.11 and LLC headers */
2833		pos = buf + 24 + 6;
2834		if (WPA_GET_BE16(pos) != ETH_P_EAPOL)
2835			return;
2836		pos += 2;
2837		/* mgmt->bssid is actually BSSID for SA data frames */
2838		wpa_supplicant_rx_eapol(wpa_s, mgmt->bssid,
2839					pos, buf + len - pos);
2840	}
2841}
2842
2843
2844void ieee80211_sta_free_hw_features(struct wpa_hw_modes *hw_features,
2845				    size_t num_hw_features)
2846{
2847	size_t i;
2848
2849	if (hw_features == NULL)
2850		return;
2851
2852	for (i = 0; i < num_hw_features; i++) {
2853		os_free(hw_features[i].channels);
2854		os_free(hw_features[i].rates);
2855	}
2856
2857	os_free(hw_features);
2858}
2859
2860
2861int ieee80211_sta_init(struct wpa_supplicant *wpa_s)
2862{
2863	u16 num_modes, flags;
2864
2865	wpa_s->mlme.modes = wpa_drv_get_hw_feature_data(wpa_s, &num_modes,
2866							&flags);
2867	if (wpa_s->mlme.modes == NULL) {
2868		wpa_printf(MSG_ERROR, "MLME: Failed to read supported "
2869			   "channels and rates from the driver");
2870		return -1;
2871	}
2872
2873	wpa_s->mlme.num_modes = num_modes;
2874
2875	wpa_s->mlme.hw_modes = 1 << WPA_MODE_IEEE80211A;
2876	wpa_s->mlme.hw_modes |= 1 << WPA_MODE_IEEE80211B;
2877	wpa_s->mlme.hw_modes |= 1 << WPA_MODE_IEEE80211G;
2878
2879	return 0;
2880}
2881
2882
2883void ieee80211_sta_deinit(struct wpa_supplicant *wpa_s)
2884{
2885	eloop_cancel_timeout(ieee80211_sta_timer, wpa_s, NULL);
2886	eloop_cancel_timeout(ieee80211_sta_scan_timer, wpa_s, NULL);
2887	os_free(wpa_s->mlme.extra_ie);
2888	wpa_s->mlme.extra_ie = NULL;
2889	os_free(wpa_s->mlme.assocreq_ies);
2890	wpa_s->mlme.assocreq_ies = NULL;
2891	os_free(wpa_s->mlme.assocresp_ies);
2892	wpa_s->mlme.assocresp_ies = NULL;
2893	ieee80211_bss_list_deinit(wpa_s);
2894	ieee80211_sta_free_hw_features(wpa_s->mlme.modes,
2895				       wpa_s->mlme.num_modes);
2896}
2897