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

📄 mlme.c

📁 WLAN无线网络管理的最新程序
💻 C
📖 第 1 页 / 共 5 页
字号:
static void ieee80211_bss_info(struct wpa_supplicant *wpa_s,			       struct ieee80211_mgmt *mgmt,			       size_t len,			       struct ieee80211_rx_status *rx_status,			       int beacon){	struct ieee802_11_elems elems;	size_t baselen;	int channel, invalid = 0, clen;	struct ieee80211_sta_bss *bss;	u64 timestamp;	u8 *pos;	if (!beacon && os_memcmp(mgmt->da, wpa_s->own_addr, ETH_ALEN))		return; /* ignore ProbeResp to foreign address */#if 0	wpa_printf(MSG_MSGDUMP, "MLME: RX %s from " MACSTR " to " MACSTR,		   beacon ? "Beacon" : "Probe Response",		   MAC2STR(mgmt->sa), MAC2STR(mgmt->da));#endif	baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt;	if (baselen > len)		return;	pos = mgmt->u.beacon.timestamp;	timestamp = ((u64) pos[7] << 56) | ((u64) pos[6] << 48) |		((u64) pos[5] << 40) | ((u64) pos[4] << 32) |		((u64) pos[3] << 24) | ((u64) pos[2] << 16) |		((u64) pos[1] << 8) | ((u64) pos[0]);#if 0 /* FIX */	if (local->conf.mode == IW_MODE_ADHOC && beacon &&	    os_memcmp(mgmt->bssid, local->bssid, ETH_ALEN) == 0) {#ifdef IEEE80211_IBSS_DEBUG		static unsigned long last_tsf_debug = 0;		u64 tsf;		if (local->hw->get_tsf)			tsf = local->hw->get_tsf(local->mdev);		else			tsf = -1LLU;		if (time_after(jiffies, last_tsf_debug + 5 * HZ)) {			wpa_printf(MSG_DEBUG, "RX beacon SA=" MACSTR " BSSID="				   MACSTR " TSF=0x%llx BCN=0x%llx diff=%lld "				   "@%ld",				   MAC2STR(mgmt->sa), MAC2STR(mgmt->bssid),				   tsf, timestamp, tsf - timestamp, jiffies);			last_tsf_debug = jiffies;		}#endif /* IEEE80211_IBSS_DEBUG */	}#endif	if (ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen,				   &elems) == ParseFailed)		invalid = 1;#if 0 /* FIX */	if (local->conf.mode == IW_MODE_ADHOC && elems.supp_rates &&	    os_memcmp(mgmt->bssid, local->bssid, ETH_ALEN) == 0 &&	    (sta = sta_info_get(local, mgmt->sa))) {		struct ieee80211_rate *rates;		size_t num_rates;		u32 supp_rates, prev_rates;		int i, j, oper_mode;		rates = local->curr_rates;		num_rates = local->num_curr_rates;		oper_mode = wpa_s->mlme.sta_scanning ?			local->scan_oper_phymode : local->conf.phymode;		for (i = 0; i < local->hw->num_modes; i++) {			struct ieee80211_hw_modes *mode = &local->hw->modes[i];			if (oper_mode == mode->mode) {				rates = mode->rates;				num_rates = mode->num_rates;				break;			}		}		supp_rates = 0;		for (i = 0; i < elems.supp_rates_len +			     elems.ext_supp_rates_len; i++) {			u8 rate = 0;			int own_rate;			if (i < elems.supp_rates_len)				rate = elems.supp_rates[i];			else if (elems.ext_supp_rates)				rate = elems.ext_supp_rates					[i - elems.supp_rates_len];			own_rate = 5 * (rate & 0x7f);			if (oper_mode == MODE_ATHEROS_TURBO)				own_rate *= 2;			for (j = 0; j < num_rates; j++)				if (rates[j].rate == own_rate)					supp_rates |= BIT(j);		}		prev_rates = sta->supp_rates;		sta->supp_rates &= supp_rates;		if (sta->supp_rates == 0) {			/* No matching rates - this should not really happen.			 * Make sure that at least one rate is marked			 * supported to avoid issues with TX rate ctrl. */			sta->supp_rates = wpa_s->mlme.supp_rates_bits;		}		if (sta->supp_rates != prev_rates) {			wpa_printf(MSG_DEBUG, "MLME: updated supp_rates set "				   "for " MACSTR " based on beacon info "				   "(0x%x & 0x%x -> 0x%x)",				   MAC2STR(sta->addr), prev_rates,				   supp_rates, sta->supp_rates);		}		sta_info_release(local, sta);	}#endif	if (elems.ssid == NULL)		return;	if (elems.ds_params && elems.ds_params_len == 1)		channel = elems.ds_params[0];	else		channel = rx_status->channel;	bss = ieee80211_bss_get(wpa_s, mgmt->bssid);	if (bss == NULL) {		bss = ieee80211_bss_add(wpa_s, mgmt->bssid);		if (bss == NULL)			return;	} else {#if 0		/* TODO: order by RSSI? */		spin_lock_bh(&local->sta_bss_lock);		list_move_tail(&bss->list, &local->sta_bss_list);		spin_unlock_bh(&local->sta_bss_lock);#endif	}	if (bss->probe_resp && beacon) {		/* Do not allow beacon to override data from Probe Response. */		return;	}	bss->beacon_int = le_to_host16(mgmt->u.beacon.beacon_int);	bss->capability = le_to_host16(mgmt->u.beacon.capab_info);	if (elems.ssid && elems.ssid_len <= MAX_SSID_LEN) {		os_memcpy(bss->ssid, elems.ssid, elems.ssid_len);		bss->ssid_len = elems.ssid_len;	}	bss->supp_rates_len = 0;	if (elems.supp_rates) {		clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len;		if (clen > elems.supp_rates_len)			clen = elems.supp_rates_len;		os_memcpy(&bss->supp_rates[bss->supp_rates_len],			  elems.supp_rates, clen);		bss->supp_rates_len += clen;	}	if (elems.ext_supp_rates) {		clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len;		if (clen > elems.ext_supp_rates_len)			clen = elems.ext_supp_rates_len;		os_memcpy(&bss->supp_rates[bss->supp_rates_len],			  elems.ext_supp_rates, clen);		bss->supp_rates_len += clen;	}	if (elems.wpa &&	    (bss->wpa_ie == NULL || bss->wpa_ie_len != elems.wpa_len ||	     os_memcmp(bss->wpa_ie, elems.wpa, elems.wpa_len))) {		os_free(bss->wpa_ie);		bss->wpa_ie = os_malloc(elems.wpa_len + 2);		if (bss->wpa_ie) {			os_memcpy(bss->wpa_ie, elems.wpa - 2,				  elems.wpa_len + 2);			bss->wpa_ie_len = elems.wpa_len + 2;		} else			bss->wpa_ie_len = 0;	} else if (!elems.wpa && bss->wpa_ie) {		os_free(bss->wpa_ie);		bss->wpa_ie = NULL;		bss->wpa_ie_len = 0;	}	if (elems.rsn &&	    (bss->rsn_ie == NULL || bss->rsn_ie_len != elems.rsn_len ||	     os_memcmp(bss->rsn_ie, elems.rsn, elems.rsn_len))) {		os_free(bss->rsn_ie);		bss->rsn_ie = os_malloc(elems.rsn_len + 2);		if (bss->rsn_ie) {			os_memcpy(bss->rsn_ie, elems.rsn - 2,				  elems.rsn_len + 2);			bss->rsn_ie_len = elems.rsn_len + 2;		} else			bss->rsn_ie_len = 0;	} else if (!elems.rsn && bss->rsn_ie) {		os_free(bss->rsn_ie);		bss->rsn_ie = NULL;		bss->rsn_ie_len = 0;	}	if (elems.wmm_param &&	    (bss->wmm_ie == NULL || bss->wmm_ie_len != elems.wmm_param_len ||	     os_memcmp(bss->wmm_ie, elems.wmm_param, elems.wmm_param_len))) {		os_free(bss->wmm_ie);		bss->wmm_ie = os_malloc(elems.wmm_param_len + 2);		if (bss->wmm_ie) {			os_memcpy(bss->wmm_ie, elems.wmm_param - 2,				  elems.wmm_param_len + 2);			bss->wmm_ie_len = elems.wmm_param_len + 2;		} else			bss->wmm_ie_len = 0;	} else if (!elems.wmm_param && bss->wmm_ie) {		os_free(bss->wmm_ie);		bss->wmm_ie = NULL;		bss->wmm_ie_len = 0;	}	bss->hw_mode = wpa_s->mlme.phymode;	bss->channel = channel;	bss->freq = wpa_s->mlme.freq;	if (channel != wpa_s->mlme.channel &&	    (wpa_s->mlme.phymode == WPA_MODE_IEEE80211G ||	     wpa_s->mlme.phymode == WPA_MODE_IEEE80211B) &&	    channel >= 1 && channel <= 14) {		static const int freq_list[] = {			2412, 2417, 2422, 2427, 2432, 2437, 2442,			2447, 2452, 2457, 2462, 2467, 2472, 2484		};		/* IEEE 802.11g/b mode can receive packets from neighboring		 * channels, so map the channel into frequency. */		bss->freq = freq_list[channel - 1];	}	bss->timestamp = timestamp;	os_get_time(&bss->last_update);	bss->rssi = rx_status->ssi;	if (!beacon)		bss->probe_resp++;}static void ieee80211_rx_mgmt_probe_resp(struct wpa_supplicant *wpa_s,					 struct ieee80211_mgmt *mgmt,					 size_t len,					 struct ieee80211_rx_status *rx_status){	ieee80211_bss_info(wpa_s, mgmt, len, rx_status, 0);}static void ieee80211_rx_mgmt_beacon(struct wpa_supplicant *wpa_s,				     struct ieee80211_mgmt *mgmt,				     size_t len,				     struct ieee80211_rx_status *rx_status){	int use_protection;	size_t baselen;	struct ieee802_11_elems elems;	ieee80211_bss_info(wpa_s, mgmt, len, rx_status, 1);	if (!wpa_s->mlme.associated ||	    os_memcmp(wpa_s->bssid, mgmt->bssid, ETH_ALEN) != 0)		return;	/* Process beacon from the current BSS */	baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt;	if (baselen > len)		return;	if (ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen,				   &elems) == ParseFailed)		return;	use_protection = 0;	if (elems.erp_info && elems.erp_info_len >= 1) {		use_protection =			(elems.erp_info[0] & ERP_INFO_USE_PROTECTION) != 0;	}	if (use_protection != !!wpa_s->mlme.use_protection) {		wpa_printf(MSG_DEBUG, "MLME: CTS protection %s (BSSID=" MACSTR			   ")",			   use_protection ? "enabled" : "disabled",			   MAC2STR(wpa_s->bssid));		wpa_s->mlme.use_protection = use_protection ? 1 : 0;		wpa_s->mlme.cts_protect_erp_frames = use_protection;	}	if (elems.wmm_param && wpa_s->mlme.wmm_enabled) {		ieee80211_sta_wmm_params(wpa_s, elems.wmm_param,					 elems.wmm_param_len);	}}static void ieee80211_rx_mgmt_probe_req(struct wpa_supplicant *wpa_s,					struct ieee80211_mgmt *mgmt,					size_t len,					struct ieee80211_rx_status *rx_status){	int tx_last_beacon, adhoc;#if 0 /* FIX */	struct ieee80211_mgmt *resp;#endif	u8 *pos, *end;	struct wpa_ssid *ssid = wpa_s->current_ssid;	adhoc = ssid && ssid->mode == 1;	if (!adhoc || wpa_s->mlme.state != IEEE80211_IBSS_JOINED ||	    len < 24 + 2 || wpa_s->mlme.probe_resp == NULL)		return;#if 0 /* FIX */	if (local->hw->tx_last_beacon)		tx_last_beacon = local->hw->tx_last_beacon(local->mdev);	else#endif		tx_last_beacon = 1;#ifdef IEEE80211_IBSS_DEBUG	wpa_printf(MSG_DEBUG, "MLME: RX ProbeReq SA=" MACSTR " DA=" MACSTR		   " BSSID=" MACSTR " (tx_last_beacon=%d)",		   MAC2STR(mgmt->sa), MAC2STR(mgmt->da),		   MAC2STR(mgmt->bssid), tx_last_beacon);#endif /* IEEE80211_IBSS_DEBUG */	if (!tx_last_beacon)		return;	if (os_memcmp(mgmt->bssid, wpa_s->bssid, ETH_ALEN) != 0 &&	    os_memcmp(mgmt->bssid, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) != 0)		return;	end = ((u8 *) mgmt) + len;	pos = mgmt->u.probe_req.variable;	if (pos[0] != WLAN_EID_SSID ||	    pos + 2 + pos[1] > end) {		wpa_printf(MSG_DEBUG, "MLME: Invalid SSID IE in ProbeReq from "			   MACSTR, MAC2STR(mgmt->sa));		return;	}	if (pos[1] != 0 &&	    (pos[1] != wpa_s->mlme.ssid_len ||	     os_memcmp(pos + 2, wpa_s->mlme.ssid, wpa_s->mlme.ssid_len) != 0))	{		/* Ignore ProbeReq for foreign SSID */		return;	}#if 0 /* FIX */	/* Reply with ProbeResp */	skb = skb_copy(wpa_s->mlme.probe_resp, GFP_ATOMIC);	if (skb == NULL)		return;	resp = (struct ieee80211_mgmt *) skb->data;	os_memcpy(resp->da, mgmt->sa, ETH_ALEN);#ifdef IEEE80211_IBSS_DEBUG	wpa_printf(MSG_DEBUG, "MLME: Sending ProbeResp to " MACSTR,		   MAC2STR(resp->da));#endif /* IEEE80211_IBSS_DEBUG */	ieee80211_sta_tx(wpa_s, skb, 0, 1);#endif}static void ieee80211_sta_rx_mgmt(struct wpa_supplicant *wpa_s,				  const u8 *buf, size_t len,				  struct ieee80211_rx_status *rx_status){	struct ieee80211_mgmt *mgmt;	u16 fc;	if (len < 24)		return;	mgmt = (struct ieee80211_mgmt *) buf;	fc = le_to_host16(mgmt->frame_control);	switch (WLAN_FC_GET_STYPE(fc)) {	case WLAN_FC_STYPE_PROBE_REQ:		ieee80211_rx_mgmt_probe_req(wpa_s, mgmt, len, rx_status);		break;	case WLAN_FC_STYPE_PROBE_RESP:		ieee80211_rx_mgmt_probe_resp(wpa_s, mgmt, len, rx_status);		break;	case WLAN_FC_STYPE_BEACON:		ieee80211_rx_mgmt_beacon(wpa_s, mgmt, len, rx_status);		break;	case WLAN_FC_STYPE_AUTH:		ieee80211_rx_mgmt_auth(wpa_s, mgmt, len, rx_status);		break;	case WLAN_FC_STYPE_ASSOC_RESP:		ieee80211_rx_mgmt_assoc_resp(wpa_s, mgmt, len, rx_status, 0);		break;	case WLAN_FC_STYPE_REASSOC_RESP:		ieee80211_rx_mgmt_assoc_resp(wpa_s, mgmt, len, rx_status, 1);		break;	case WLAN_FC_STYPE_DEAUTH:		ieee80211_rx_mgmt_deauth(wpa_s, mgmt, len, rx_status);		break;	case WLAN_FC_STYPE_DISASSOC:		ieee80211_rx_mgmt_disassoc(wpa_s, mgmt, len, rx_status);		break;	default:		wpa_printf(MSG_DEBUG, "MLME: received unknown management "			   "frame - stype=%d", WLAN_FC_GET_STYPE(fc));		break;	}}static void ieee80211_sta_rx_scan(struct wpa_supplicant *wpa_s,				  const u8 *buf, size_t len,				  struct ieee80211_rx_status *rx_status){	struct ieee80211_mgmt *mgmt;	u16 fc;	if (len < 24)		return;	mgmt = (struct ieee80211_mgmt *) buf;	fc = le_to_host16(mgmt->frame_control);	if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT) {		if (WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_PROBE_RESP) {			ieee80211_rx_mgmt_probe_resp(wpa_s, mgmt,						     len, rx_status);		} else if (WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON) {			ieee80211_rx_mgmt_beacon(wpa_s, mgmt, len, rx_status);		}	}}static int ieee80211_sta_active_ibss(struct wpa_supplicant *wpa_s){	int active = 0;#if 0 /* FIX */	list_for_each(ptr, &local->sta_list) {		sta = list_entry(ptr, struct sta_info, list);		if (sta->dev == dev &&		    time_after(sta->last_rx + IEEE80211_IBSS_MERGE_INTERVAL,			       jiffies)) {			active++;			break;		}	}#endif	return active;}static void ieee80211_sta_expire(struct wpa_supplicant *wpa_s){#if 0 /* FIX */	list_for_each_safe(ptr, n, &local->sta_list) {		sta = list_entry(ptr, struct sta_info, list);		if (time_after(jiffies, sta->last_rx +			       IEEE80211_IBSS_INACTIVITY_LIMIT)) {			wpa_printf(MSG_DEBUG, "MLME: expiring inactive STA "				   MACSTR, MAC2STR(sta->addr));			sta_info_free(local, sta, 1);		}	}#endif}static void ieee80211_sta_merge_ibss(struct wpa_supplicant *wpa_s){	ieee80211_reschedule_timer(wpa_s, IEEE80211_IBSS_MERGE_INTERVAL);	ieee80211_sta_expire(wpa_s);	if (ieee80211_sta_active_ibss(wpa_s))		return;	wpa_printf(MSG_DEBUG, "MLME: No active IBSS STAs - trying to scan for "		   "other IBSS networks with same SSID (merge)");	ieee80211_sta_req_scan(wpa_s, wpa_s->mlme.ssid, wpa_s->mlme.ssid_len);}static void ieee80211_sta_timer(void *eloop_ctx, void *timeout_ctx){	struct wpa_supplicant *wpa_s = eloop_ctx;

⌨️ 快捷键说明

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