⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mlme.c

📁 WLAN无线网络管理的最新程序
💻 C
📖 第 1 页 / 共 5 页
字号:
	int count;	u8 *pos;	if (wmm_param_len < 8 || wmm_param[5] /* version */ != 1)		return;	count = wmm_param[6] & 0x0f;	if (count == wpa_s->mlme.wmm_last_param_set)		return;	wpa_s->mlme.wmm_last_param_set = count;	pos = wmm_param + 8;	left = wmm_param_len - 8;#if 0 /* FIX */	wmm_acm = 0;	for (; left >= 4; left -= 4, pos += 4) {		int aci = (pos[0] >> 5) & 0x03;		int acm = (pos[0] >> 4) & 0x01;		int queue;		switch (aci) {		case 1:			queue = IEEE80211_TX_QUEUE_DATA3;			if (acm)				wmm_acm |= BIT(1) | BIT(2);			break;		case 2:			queue = IEEE80211_TX_QUEUE_DATA1;			if (acm)				wmm_acm |= BIT(4) | BIT(5);			break;		case 3:			queue = IEEE80211_TX_QUEUE_DATA0;			if (acm)				wmm_acm |= BIT(6) | BIT(7);			break;		case 0:		default:			queue = IEEE80211_TX_QUEUE_DATA2;			if (acm)				wpa_s->mlme.wmm_acm |= BIT(0) | BIT(3);			break;		}		params.aifs = pos[0] & 0x0f;		params.cw_max = ecw2cw((pos[1] & 0xf0) >> 4);		params.cw_min = ecw2cw(pos[1] & 0x0f);		/* TXOP is in units of 32 usec; burst_time in 0.1 ms */		params.burst_time = (pos[2] | (pos[3] << 8)) * 32 / 100;		wpa_printf(MSG_DEBUG, "MLME: WMM queue=%d aci=%d acm=%d "			   "aifs=%d cWmin=%d cWmax=%d burst=%d",			   queue, aci, acm, params.aifs, params.cw_min,			   params.cw_max, params.burst_time);		/* TODO: handle ACM (block TX, fallback to next lowest allowed		 * AC for now) */		if (local->hw->conf_tx(local->mdev, queue, &params)) {			wpa_printf(MSG_DEBUG, "MLME: failed to set TX queue "				   "parameters for queue %d", queue);		}	}#endif}static void ieee80211_set_associated(struct wpa_supplicant *wpa_s, int assoc){	if (wpa_s->mlme.associated == assoc)		return;	wpa_s->mlme.associated = assoc;	if (assoc) {		union wpa_event_data data;		os_memset(&data, 0, sizeof(data));		wpa_s->mlme.prev_bssid_set = 1;		os_memcpy(wpa_s->mlme.prev_bssid, wpa_s->bssid, ETH_ALEN);		data.assoc_info.req_ies = wpa_s->mlme.assocreq_ies;		data.assoc_info.req_ies_len = wpa_s->mlme.assocreq_ies_len;		data.assoc_info.resp_ies = wpa_s->mlme.assocresp_ies;		data.assoc_info.resp_ies_len = wpa_s->mlme.assocresp_ies_len;		wpa_supplicant_event(wpa_s, EVENT_ASSOC, &data);	} else {		wpa_supplicant_event(wpa_s, EVENT_DISASSOC, NULL);	}	os_get_time(&wpa_s->mlme.last_probe);}static void ieee80211_sta_tx(struct wpa_supplicant *wpa_s, const u8 *buf,			     size_t len){	wpa_drv_send_mlme(wpa_s, buf, len);}static void ieee80211_send_auth(struct wpa_supplicant *wpa_s,				int transaction, u8 *extra, size_t extra_len,				int encrypt){	u8 *buf;	size_t len;	struct ieee80211_mgmt *mgmt;	buf = os_malloc(sizeof(*mgmt) + 6 + extra_len);	if (buf == NULL) {		wpa_printf(MSG_DEBUG, "MLME: failed to allocate buffer for "			   "auth frame");		return;	}	mgmt = (struct ieee80211_mgmt *) buf;	len = 24 + 6;	os_memset(mgmt, 0, 24 + 6);	mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,					   WLAN_FC_STYPE_AUTH);	if (encrypt)		mgmt->frame_control |= host_to_le16(WLAN_FC_ISWEP);	os_memcpy(mgmt->da, wpa_s->bssid, ETH_ALEN);	os_memcpy(mgmt->sa, wpa_s->own_addr, ETH_ALEN);	os_memcpy(mgmt->bssid, wpa_s->bssid, ETH_ALEN);	mgmt->u.auth.auth_alg = host_to_le16(wpa_s->mlme.auth_alg);	mgmt->u.auth.auth_transaction = host_to_le16(transaction);	wpa_s->mlme.auth_transaction = transaction + 1;	mgmt->u.auth.status_code = host_to_le16(0);	if (extra) {		os_memcpy(buf + len, extra, extra_len);		len += extra_len;	}	ieee80211_sta_tx(wpa_s, buf, len);	os_free(buf);}static void ieee80211_reschedule_timer(struct wpa_supplicant *wpa_s, int ms){	eloop_cancel_timeout(ieee80211_sta_timer, wpa_s, NULL);	eloop_register_timeout(ms / 1000, 1000 * (ms % 1000),			       ieee80211_sta_timer, wpa_s, NULL);}static void ieee80211_authenticate(struct wpa_supplicant *wpa_s){	wpa_s->mlme.auth_tries++;	if (wpa_s->mlme.auth_tries > IEEE80211_AUTH_MAX_TRIES) {		wpa_printf(MSG_DEBUG, "MLME: authentication with AP " MACSTR			   " timed out", MAC2STR(wpa_s->bssid));		return;	}	wpa_s->mlme.state = IEEE80211_AUTHENTICATE;	wpa_printf(MSG_DEBUG, "MLME: authenticate with AP " MACSTR,		   MAC2STR(wpa_s->bssid));	ieee80211_send_auth(wpa_s, 1, NULL, 0, 0);	ieee80211_reschedule_timer(wpa_s, IEEE80211_AUTH_TIMEOUT);}static void ieee80211_send_assoc(struct wpa_supplicant *wpa_s){	struct ieee80211_mgmt *mgmt;	u8 *pos, *ies, *buf;	int i, len;	u16 capab;	struct ieee80211_sta_bss *bss;	int wmm = 0;	size_t blen;	if (wpa_s->mlme.curr_rates == NULL) {		wpa_printf(MSG_DEBUG, "MLME: curr_rates not set for assoc");		return;	}	buf = os_malloc(sizeof(*mgmt) + 200 + wpa_s->mlme.extra_ie_len +			wpa_s->mlme.ssid_len);	if (buf == NULL) {		wpa_printf(MSG_DEBUG, "MLME: failed to allocate buffer for "			   "assoc frame");		return;	}	blen = 0;	capab = wpa_s->mlme.capab;	if (wpa_s->mlme.phymode == WPA_MODE_IEEE80211G) {		capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME |			WLAN_CAPABILITY_SHORT_PREAMBLE;	}	bss = ieee80211_bss_get(wpa_s, wpa_s->bssid);	if (bss) {		if (bss->capability & WLAN_CAPABILITY_PRIVACY)			capab |= WLAN_CAPABILITY_PRIVACY;		if (bss->wmm_ie) {			wmm = 1;		}	}	mgmt = (struct ieee80211_mgmt *) buf;	blen += 24;	os_memset(mgmt, 0, 24);	os_memcpy(mgmt->da, wpa_s->bssid, ETH_ALEN);	os_memcpy(mgmt->sa, wpa_s->own_addr, ETH_ALEN);	os_memcpy(mgmt->bssid, wpa_s->bssid, ETH_ALEN);	if (wpa_s->mlme.prev_bssid_set) {		blen += 10;		mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,						   WLAN_FC_STYPE_REASSOC_REQ);		mgmt->u.reassoc_req.capab_info = host_to_le16(capab);		mgmt->u.reassoc_req.listen_interval = host_to_le16(1);		os_memcpy(mgmt->u.reassoc_req.current_ap,			  wpa_s->mlme.prev_bssid,			  ETH_ALEN);	} else {		blen += 4;		mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,						   WLAN_FC_STYPE_ASSOC_REQ);		mgmt->u.assoc_req.capab_info = host_to_le16(capab);		mgmt->u.assoc_req.listen_interval = host_to_le16(1);	}	/* SSID */	ies = pos = buf + blen;	blen += 2 + wpa_s->mlme.ssid_len;	*pos++ = WLAN_EID_SSID;	*pos++ = wpa_s->mlme.ssid_len;	os_memcpy(pos, wpa_s->mlme.ssid, wpa_s->mlme.ssid_len);	len = wpa_s->mlme.num_curr_rates;	if (len > 8)		len = 8;	pos = buf + blen;	blen += len + 2;	*pos++ = WLAN_EID_SUPP_RATES;	*pos++ = len;	for (i = 0; i < len; i++) {		int rate = wpa_s->mlme.curr_rates[i].rate;		*pos++ = (u8) (rate / 5);	}	if (wpa_s->mlme.num_curr_rates > len) {		pos = buf + blen;		blen += wpa_s->mlme.num_curr_rates - len + 2;		*pos++ = WLAN_EID_EXT_SUPP_RATES;		*pos++ = wpa_s->mlme.num_curr_rates - len;		for (i = len; i < wpa_s->mlme.num_curr_rates; i++) {			int rate = wpa_s->mlme.curr_rates[i].rate;			*pos++ = (u8) (rate / 5);		}	}	if (wpa_s->mlme.extra_ie) {		pos = buf + blen;		blen += wpa_s->mlme.extra_ie_len;		os_memcpy(pos, wpa_s->mlme.extra_ie, wpa_s->mlme.extra_ie_len);	}	if (wmm && wpa_s->mlme.wmm_enabled) {		pos = buf + blen;		blen += 9;		*pos++ = WLAN_EID_VENDOR_SPECIFIC;		*pos++ = 7; /* len */		*pos++ = 0x00; /* Microsoft OUI 00:50:F2 */		*pos++ = 0x50;		*pos++ = 0xf2;		*pos++ = 2; /* WME */		*pos++ = 0; /* WME info */		*pos++ = 1; /* WME ver */		*pos++ = 0;	}	os_free(wpa_s->mlme.assocreq_ies);	wpa_s->mlme.assocreq_ies_len = (buf + blen) - ies;	wpa_s->mlme.assocreq_ies = os_malloc(wpa_s->mlme.assocreq_ies_len);	if (wpa_s->mlme.assocreq_ies) {		os_memcpy(wpa_s->mlme.assocreq_ies, ies,			  wpa_s->mlme.assocreq_ies_len);	}	ieee80211_sta_tx(wpa_s, buf, blen);	os_free(buf);}static void ieee80211_send_deauth(struct wpa_supplicant *wpa_s, u16 reason){	u8 *buf;	size_t len;	struct ieee80211_mgmt *mgmt;	buf = os_zalloc(sizeof(*mgmt));	if (buf == NULL) {		wpa_printf(MSG_DEBUG, "MLME: failed to allocate buffer for "			   "deauth frame");		return;	}	mgmt = (struct ieee80211_mgmt *) buf;	len = 24;	os_memcpy(mgmt->da, wpa_s->bssid, ETH_ALEN);	os_memcpy(mgmt->sa, wpa_s->own_addr, ETH_ALEN);	os_memcpy(mgmt->bssid, wpa_s->bssid, ETH_ALEN);	mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,					   WLAN_FC_STYPE_DEAUTH);	len += 2;	mgmt->u.deauth.reason_code = host_to_le16(reason);	ieee80211_sta_tx(wpa_s, buf, len);	os_free(buf);}static void ieee80211_send_disassoc(struct wpa_supplicant *wpa_s, u16 reason){	u8 *buf;	size_t len;	struct ieee80211_mgmt *mgmt;	buf = os_zalloc(sizeof(*mgmt));	if (buf == NULL) {		wpa_printf(MSG_DEBUG, "MLME: failed to allocate buffer for "			   "disassoc frame");		return;	}	mgmt = (struct ieee80211_mgmt *) buf;	len = 24;	os_memcpy(mgmt->da, wpa_s->bssid, ETH_ALEN);	os_memcpy(mgmt->sa, wpa_s->own_addr, ETH_ALEN);	os_memcpy(mgmt->bssid, wpa_s->bssid, ETH_ALEN);	mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,					   WLAN_FC_STYPE_DISASSOC);	len += 2;	mgmt->u.disassoc.reason_code = host_to_le16(reason);	ieee80211_sta_tx(wpa_s, buf, len);	os_free(buf);}static int ieee80211_privacy_mismatch(struct wpa_supplicant *wpa_s){	struct ieee80211_sta_bss *bss;	int res = 0;	if (wpa_s->mlme.mixed_cell ||	    wpa_s->mlme.key_mgmt != KEY_MGMT_NONE)		return 0;	bss = ieee80211_bss_get(wpa_s, wpa_s->bssid);	if (bss == NULL)		return 0;	if (ieee80211_sta_wep_configured(wpa_s) !=	    !!(bss->capability & WLAN_CAPABILITY_PRIVACY))		res = 1;	return res;}static void ieee80211_associate(struct wpa_supplicant *wpa_s){	wpa_s->mlme.assoc_tries++;	if (wpa_s->mlme.assoc_tries > IEEE80211_ASSOC_MAX_TRIES) {		wpa_printf(MSG_DEBUG, "MLME: association with AP " MACSTR			   " timed out", MAC2STR(wpa_s->bssid));		return;	}	wpa_s->mlme.state = IEEE80211_ASSOCIATE;	wpa_printf(MSG_DEBUG, "MLME: associate with AP " MACSTR,		   MAC2STR(wpa_s->bssid));	if (ieee80211_privacy_mismatch(wpa_s)) {		wpa_printf(MSG_DEBUG, "MLME: mismatch in privacy "			   "configuration and mixed-cell disabled - abort "			   "association");		return;	}	ieee80211_send_assoc(wpa_s);	ieee80211_reschedule_timer(wpa_s, IEEE80211_ASSOC_TIMEOUT);}static void ieee80211_associated(struct wpa_supplicant *wpa_s){	int disassoc;	/* TODO: start monitoring current AP signal quality and number of	 * missed beacons. Scan other channels every now and then and search	 * for better APs. */	/* TODO: remove expired BSSes */	wpa_s->mlme.state = IEEE80211_ASSOCIATED;#if 0 /* FIX */	sta = sta_info_get(local, wpa_s->bssid);	if (sta == NULL) {		wpa_printf(MSG_DEBUG "MLME: No STA entry for own AP " MACSTR,			   MAC2STR(wpa_s->bssid));		disassoc = 1;	} else {		disassoc = 0;		if (time_after(jiffies,			       sta->last_rx + IEEE80211_MONITORING_INTERVAL)) {			if (wpa_s->mlme.probereq_poll) {				wpa_printf(MSG_DEBUG "MLME: No ProbeResp from "					   "current AP " MACSTR " - assume "					   "out of range",					   MAC2STR(wpa_s->bssid));				disassoc = 1;			} else {				ieee80211_send_probe_req(					wpa_s->bssid,					wpa_s->mlme.scan_ssid,					wpa_s->mlme.scan_ssid_len);				wpa_s->mlme.probereq_poll = 1;			}		} else {			wpa_s->mlme.probereq_poll = 0;			if (time_after(jiffies, wpa_s->mlme.last_probe +				       IEEE80211_PROBE_INTERVAL)) {				wpa_s->mlme.last_probe = jiffies;				ieee80211_send_probe_req(wpa_s->bssid,							 wpa_s->mlme.ssid,							 wpa_s->mlme.ssid_len);			}		}		sta_info_release(local, sta);	}#else	disassoc = 0;#endif	if (disassoc) {		wpa_supplicant_event(wpa_s, EVENT_DISASSOC, NULL);		ieee80211_reschedule_timer(wpa_s,					   IEEE80211_MONITORING_INTERVAL +					   30000);	} else {		ieee80211_reschedule_timer(wpa_s,					   IEEE80211_MONITORING_INTERVAL);	}}static void ieee80211_send_probe_req(struct wpa_supplicant *wpa_s,				     const u8 *dst,				     const u8 *ssid, size_t ssid_len){	u8 *buf;	size_t len;	struct ieee80211_mgmt *mgmt;	u8 *pos, *supp_rates;	u8 *esupp_rates = NULL;	int i;	buf = os_malloc(sizeof(*mgmt) + 200);	if (buf == NULL) {		wpa_printf(MSG_DEBUG, "MLME: failed to allocate buffer for "			   "probe request");		return;	}	mgmt = (struct ieee80211_mgmt *) buf;	len = 24;	os_memset(mgmt, 0, 24);	mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,					   WLAN_FC_STYPE_PROBE_REQ);	os_memcpy(mgmt->sa, wpa_s->own_addr, ETH_ALEN);	if (dst) {		os_memcpy(mgmt->da, dst, ETH_ALEN);		os_memcpy(mgmt->bssid, dst, ETH_ALEN);	} else {		os_memset(mgmt->da, 0xff, ETH_ALEN);		os_memset(mgmt->bssid, 0xff, ETH_ALEN);	}	pos = buf + len;	len += 2 + ssid_len;	*pos++ = WLAN_EID_SSID;	*pos++ = ssid_len;	os_memcpy(pos, ssid, ssid_len);	supp_rates = buf + len;	len += 2;	supp_rates[0] = WLAN_EID_SUPP_RATES;	supp_rates[1] = 0;	for (i = 0; i < wpa_s->mlme.num_curr_rates; i++) {		struct wpa_rate_data *rate = &wpa_s->mlme.curr_rates[i];		if (!(rate->flags & WPA_RATE_SUPPORTED))			continue;		if (esupp_rates) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -