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

📄 ieee80211_rx.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	network->listen_interval = le16_to_cpu(frame->status);	memcpy(network->bssid, frame->header.addr3, ETH_ALEN);	network->capability = le16_to_cpu(frame->capability);	network->last_scanned = jiffies;	network->rates_len = network->rates_ex_len = 0;	network->last_associate = 0;	network->ssid_len = 0;	network->erp_value =	    (network->capability & WLAN_CAPABILITY_IBSS) ? 0x3 : 0x0;	if (stats->freq == IEEE80211_52GHZ_BAND) {		/* for A band (No DS info) */		network->channel = stats->received_channel;	} else		network->flags |= NETWORK_HAS_CCK;	network->wpa_ie_len = 0;	network->rsn_ie_len = 0;	if (ieee80211_parse_info_param	    (frame->info_element, stats->len - sizeof(*frame), network))		return 1;	network->mode = 0;	if (stats->freq == IEEE80211_52GHZ_BAND)		network->mode = IEEE_A;	else {		if (network->flags & NETWORK_HAS_OFDM)			network->mode |= IEEE_G;		if (network->flags & NETWORK_HAS_CCK)			network->mode |= IEEE_B;	}	if (ieee80211_is_empty_essid(network->ssid, network->ssid_len))		network->flags |= NETWORK_EMPTY_ESSID;	memcpy(&network->stats, stats, sizeof(network->stats));	if (ieee->handle_assoc_response != NULL)		ieee->handle_assoc_response(dev, frame, network);	return 0;}/***************************************************/static int ieee80211_network_init(struct ieee80211_device *ieee, struct ieee80211_probe_response					 *beacon,					 struct ieee80211_network *network,					 struct ieee80211_rx_stats *stats){	DECLARE_MAC_BUF(mac);	network->qos_data.active = 0;	network->qos_data.supported = 0;	network->qos_data.param_count = 0;	network->qos_data.old_param_count = 0;	/* Pull out fixed field data */	memcpy(network->bssid, beacon->header.addr3, ETH_ALEN);	network->capability = le16_to_cpu(beacon->capability);	network->last_scanned = jiffies;	network->time_stamp[0] = le32_to_cpu(beacon->time_stamp[0]);	network->time_stamp[1] = le32_to_cpu(beacon->time_stamp[1]);	network->beacon_interval = le16_to_cpu(beacon->beacon_interval);	/* Where to pull this? beacon->listen_interval; */	network->listen_interval = 0x0A;	network->rates_len = network->rates_ex_len = 0;	network->last_associate = 0;	network->ssid_len = 0;	network->flags = 0;	network->atim_window = 0;	network->erp_value = (network->capability & WLAN_CAPABILITY_IBSS) ?	    0x3 : 0x0;	if (stats->freq == IEEE80211_52GHZ_BAND) {		/* for A band (No DS info) */		network->channel = stats->received_channel;	} else		network->flags |= NETWORK_HAS_CCK;	network->wpa_ie_len = 0;	network->rsn_ie_len = 0;	if (ieee80211_parse_info_param	    (beacon->info_element, stats->len - sizeof(*beacon), network))		return 1;	network->mode = 0;	if (stats->freq == IEEE80211_52GHZ_BAND)		network->mode = IEEE_A;	else {		if (network->flags & NETWORK_HAS_OFDM)			network->mode |= IEEE_G;		if (network->flags & NETWORK_HAS_CCK)			network->mode |= IEEE_B;	}	if (network->mode == 0) {		IEEE80211_DEBUG_SCAN("Filtered out '%s (%s)' "				     "network.\n",				     escape_essid(network->ssid,						  network->ssid_len),				     print_mac(mac, network->bssid));		return 1;	}	if (ieee80211_is_empty_essid(network->ssid, network->ssid_len))		network->flags |= NETWORK_EMPTY_ESSID;	memcpy(&network->stats, stats, sizeof(network->stats));	return 0;}static inline int is_same_network(struct ieee80211_network *src,				  struct ieee80211_network *dst){	/* A network is only a duplicate if the channel, BSSID, and ESSID	 * all match.  We treat all <hidden> with the same BSSID and channel	 * as one network */	return ((src->ssid_len == dst->ssid_len) &&		(src->channel == dst->channel) &&		!compare_ether_addr(src->bssid, dst->bssid) &&		!memcmp(src->ssid, dst->ssid, src->ssid_len));}static void update_network(struct ieee80211_network *dst,				  struct ieee80211_network *src){	int qos_active;	u8 old_param;	DECLARE_MAC_BUF(mac);	ieee80211_network_reset(dst);	dst->ibss_dfs = src->ibss_dfs;	/* We only update the statistics if they were created by receiving	 * the network information on the actual channel the network is on.	 *	 * This keeps beacons received on neighbor channels from bringing	 * down the signal level of an AP. */	if (dst->channel == src->stats.received_channel)		memcpy(&dst->stats, &src->stats,		       sizeof(struct ieee80211_rx_stats));	else		IEEE80211_DEBUG_SCAN("Network %s info received "			"off channel (%d vs. %d)\n", print_mac(mac, src->bssid),			dst->channel, src->stats.received_channel);	dst->capability = src->capability;	memcpy(dst->rates, src->rates, src->rates_len);	dst->rates_len = src->rates_len;	memcpy(dst->rates_ex, src->rates_ex, src->rates_ex_len);	dst->rates_ex_len = src->rates_ex_len;	dst->mode = src->mode;	dst->flags = src->flags;	dst->time_stamp[0] = src->time_stamp[0];	dst->time_stamp[1] = src->time_stamp[1];	dst->beacon_interval = src->beacon_interval;	dst->listen_interval = src->listen_interval;	dst->atim_window = src->atim_window;	dst->erp_value = src->erp_value;	dst->tim = src->tim;	memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len);	dst->wpa_ie_len = src->wpa_ie_len;	memcpy(dst->rsn_ie, src->rsn_ie, src->rsn_ie_len);	dst->rsn_ie_len = src->rsn_ie_len;	dst->last_scanned = jiffies;	qos_active = src->qos_data.active;	old_param = dst->qos_data.old_param_count;	if (dst->flags & NETWORK_HAS_QOS_MASK)		memcpy(&dst->qos_data, &src->qos_data,		       sizeof(struct ieee80211_qos_data));	else {		dst->qos_data.supported = src->qos_data.supported;		dst->qos_data.param_count = src->qos_data.param_count;	}	if (dst->qos_data.supported == 1) {		if (dst->ssid_len)			IEEE80211_DEBUG_QOS			    ("QoS the network %s is QoS supported\n",			     dst->ssid);		else			IEEE80211_DEBUG_QOS			    ("QoS the network is QoS supported\n");	}	dst->qos_data.active = qos_active;	dst->qos_data.old_param_count = old_param;	/* dst->last_associate is not overwritten */}static inline int is_beacon(__le16 fc){	return (WLAN_FC_GET_STYPE(le16_to_cpu(fc)) == IEEE80211_STYPE_BEACON);}static void ieee80211_process_probe_response(struct ieee80211_device						    *ieee, struct						    ieee80211_probe_response						    *beacon, struct ieee80211_rx_stats						    *stats){	struct net_device *dev = ieee->dev;	struct ieee80211_network network = {		.ibss_dfs = NULL,	};	struct ieee80211_network *target;	struct ieee80211_network *oldest = NULL;#ifdef CONFIG_IEEE80211_DEBUG	struct ieee80211_info_element *info_element = beacon->info_element;#endif	unsigned long flags;	DECLARE_MAC_BUF(mac);	IEEE80211_DEBUG_SCAN("'%s' (%s"			     "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",			     escape_essid(info_element->data,					  info_element->len),			     print_mac(mac, beacon->header.addr3),			     (beacon->capability & (1 << 0xf)) ? '1' : '0',			     (beacon->capability & (1 << 0xe)) ? '1' : '0',			     (beacon->capability & (1 << 0xd)) ? '1' : '0',			     (beacon->capability & (1 << 0xc)) ? '1' : '0',			     (beacon->capability & (1 << 0xb)) ? '1' : '0',			     (beacon->capability & (1 << 0xa)) ? '1' : '0',			     (beacon->capability & (1 << 0x9)) ? '1' : '0',			     (beacon->capability & (1 << 0x8)) ? '1' : '0',			     (beacon->capability & (1 << 0x7)) ? '1' : '0',			     (beacon->capability & (1 << 0x6)) ? '1' : '0',			     (beacon->capability & (1 << 0x5)) ? '1' : '0',			     (beacon->capability & (1 << 0x4)) ? '1' : '0',			     (beacon->capability & (1 << 0x3)) ? '1' : '0',			     (beacon->capability & (1 << 0x2)) ? '1' : '0',			     (beacon->capability & (1 << 0x1)) ? '1' : '0',			     (beacon->capability & (1 << 0x0)) ? '1' : '0');	if (ieee80211_network_init(ieee, beacon, &network, stats)) {		IEEE80211_DEBUG_SCAN("Dropped '%s' (%s) via %s.\n",				     escape_essid(info_element->data,						  info_element->len),				     print_mac(mac, beacon->header.addr3),				     is_beacon(beacon->header.frame_ctl) ?				     "BEACON" : "PROBE RESPONSE");		return;	}	/* The network parsed correctly -- so now we scan our known networks	 * to see if we can find it in our list.	 *	 * NOTE:  This search is definitely not optimized.  Once its doing	 *        the "right thing" we'll optimize it for efficiency if	 *        necessary */	/* Search for this entry in the list and update it if it is	 * already there. */	spin_lock_irqsave(&ieee->lock, flags);	list_for_each_entry(target, &ieee->network_list, list) {		if (is_same_network(target, &network))			break;		if ((oldest == NULL) ||		    (target->last_scanned < oldest->last_scanned))			oldest = target;	}	/* If we didn't find a match, then get a new network slot to initialize	 * with this beacon's information */	if (&target->list == &ieee->network_list) {		if (list_empty(&ieee->network_free_list)) {			/* If there are no more slots, expire the oldest */			list_del(&oldest->list);			target = oldest;			IEEE80211_DEBUG_SCAN("Expired '%s' (%s) from "					     "network list.\n",					     escape_essid(target->ssid,							  target->ssid_len),					     print_mac(mac, target->bssid));			ieee80211_network_reset(target);		} else {			/* Otherwise just pull from the free list */			target = list_entry(ieee->network_free_list.next,					    struct ieee80211_network, list);			list_del(ieee->network_free_list.next);		}#ifdef CONFIG_IEEE80211_DEBUG		IEEE80211_DEBUG_SCAN("Adding '%s' (%s) via %s.\n",				     escape_essid(network.ssid,						  network.ssid_len),				     print_mac(mac, network.bssid),				     is_beacon(beacon->header.frame_ctl) ?				     "BEACON" : "PROBE RESPONSE");#endif		memcpy(target, &network, sizeof(*target));		network.ibss_dfs = NULL;		list_add_tail(&target->list, &ieee->network_list);	} else {		IEEE80211_DEBUG_SCAN("Updating '%s' (%s) via %s.\n",				     escape_essid(target->ssid,						  target->ssid_len),				     print_mac(mac, target->bssid),				     is_beacon(beacon->header.frame_ctl) ?				     "BEACON" : "PROBE RESPONSE");		update_network(target, &network);		network.ibss_dfs = NULL;	}	spin_unlock_irqrestore(&ieee->lock, flags);	if (is_beacon(beacon->header.frame_ctl)) {		if (ieee->handle_beacon != NULL)			ieee->handle_beacon(dev, beacon, target);	} else {		if (ieee->handle_probe_response != NULL)			ieee->handle_probe_response(dev, beacon, target);	}}void ieee80211_rx_mgt(struct ieee80211_device *ieee,		      struct ieee80211_hdr_4addr *header,		      struct ieee80211_rx_stats *stats){	switch (WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl))) {	case IEEE80211_STYPE_ASSOC_RESP:		IEEE80211_DEBUG_MGMT("received ASSOCIATION RESPONSE (%d)\n",				     WLAN_FC_GET_STYPE(le16_to_cpu						       (header->frame_ctl)));		ieee80211_handle_assoc_resp(ieee,					    (struct ieee80211_assoc_response *)					    header, stats);		break;	case IEEE80211_STYPE_REASSOC_RESP:		IEEE80211_DEBUG_MGMT("received REASSOCIATION RESPONSE (%d)\n",				     WLAN_FC_GET_STYPE(le16_to_cpu						       (header->frame_ctl)));		break;	case IEEE80211_STYPE_PROBE_REQ:		IEEE80211_DEBUG_MGMT("received auth (%d)\n",				     WLAN_FC_GET_STYPE(le16_to_cpu						       (header->frame_ctl)));		if (ieee->handle_probe_request != NULL)			ieee->handle_probe_request(ieee->dev,						   (struct						    ieee80211_probe_request *)						   header, stats);		break;	case IEEE80211_STYPE_PROBE_RESP:		IEEE80211_DEBUG_MGMT("received PROBE RESPONSE (%d)\n",				     WLAN_FC_GET_STYPE(le16_to_cpu						       (header->frame_ctl)));		IEEE80211_DEBUG_SCAN("Probe response\n");		ieee80211_process_probe_response(ieee,						 (struct						  ieee80211_probe_response *)						 header, stats);		break;	case IEEE80211_STYPE_BEACON:		IEEE80211_DEBUG_MGMT("received BEACON (%d)\n",				     WLAN_FC_GET_STYPE(le16_to_cpu						       (header->frame_ctl)));		IEEE80211_DEBUG_SCAN("Beacon\n");		ieee80211_process_probe_response(ieee,						 (struct						  ieee80211_probe_response *)						 header, stats);		break;	case IEEE80211_STYPE_AUTH:		IEEE80211_DEBUG_MGMT("received auth (%d)\n",				     WLAN_FC_GET_STYPE(le16_to_cpu						       (header->frame_ctl)));		if (ieee->handle_auth != NULL)			ieee->handle_auth(ieee->dev,					  (struct ieee80211_auth *)header);		break;	case IEEE80211_STYPE_DISASSOC:		if (ieee->handle_disassoc != NULL)			ieee->handle_disassoc(ieee->dev,					      (struct ieee80211_disassoc *)					      header);		break;	case IEEE80211_STYPE_ACTION:		IEEE80211_DEBUG_MGMT("ACTION\n");		if (ieee->handle_action)			ieee->handle_action(ieee->dev,					    (struct ieee80211_action *)					    header, stats);		break;	case IEEE80211_STYPE_REASSOC_REQ:		IEEE80211_DEBUG_MGMT("received reassoc (%d)\n",				     WLAN_FC_GET_STYPE(le16_to_cpu						       (header->frame_ctl)));		IEEE80211_DEBUG_MGMT("%s: IEEE80211_REASSOC_REQ received\n",				     ieee->dev->name);		if (ieee->handle_reassoc_request != NULL)			ieee->handle_reassoc_request(ieee->dev,						    (struct ieee80211_reassoc_request *)						     header);		break;	case IEEE80211_STYPE_ASSOC_REQ:		IEEE80211_DEBUG_MGMT("received assoc (%d)\n",				     WLAN_FC_GET_STYPE(le16_to_cpu						       (header->frame_ctl)));		IEEE80211_DEBUG_MGMT("%s: IEEE80211_ASSOC_REQ received\n",				     ieee->dev->name);		if (ieee->handle_assoc_request != NULL)			ieee->handle_assoc_request(ieee->dev);		break;	case IEEE80211_STYPE_DEAUTH:		IEEE80211_DEBUG_MGMT("DEAUTH\n");		if (ieee->handle_deauth != NULL)			ieee->handle_deauth(ieee->dev,					    (struct ieee80211_deauth *)					    header);		break;	default:		IEEE80211_DEBUG_MGMT("received UNKNOWN (%d)\n",				     WLAN_FC_GET_STYPE(le16_to_cpu						       (header->frame_ctl)));		IEEE80211_DEBUG_MGMT("%s: Unknown management packet: %d\n",				     ieee->dev->name,				     WLAN_FC_GET_STYPE(le16_to_cpu						       (header->frame_ctl)));		break;	}}EXPORT_SYMBOL_GPL(ieee80211_rx_any);EXPORT_SYMBOL(ieee80211_rx_mgt);EXPORT_SYMBOL(ieee80211_rx);

⌨️ 快捷键说明

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