Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 13d1ef29 authored by Jeff Garzik's avatar Jeff Garzik
Browse files
parents e2608361 ff0037b2
Loading
Loading
Loading
Loading
+29 −1
Original line number Diff line number Diff line
@@ -613,7 +613,7 @@ struct ieee80211_disassoc {
} __attribute__ ((packed));

/* Alias deauth for disassoc */
#define ieee82011_deauth ieee80211_disassoc
#define ieee80211_deauth ieee80211_disassoc

struct ieee80211_probe_request {
	struct ieee80211_hdr_3addr header;
@@ -1045,6 +1045,34 @@ static inline u8 *ieee80211_get_payload(struct ieee80211_hdr *hdr)

}

static inline int ieee80211_is_ofdm_rate(u8 rate)
{
	switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
	case IEEE80211_OFDM_RATE_6MB:
	case IEEE80211_OFDM_RATE_9MB:
	case IEEE80211_OFDM_RATE_12MB:
	case IEEE80211_OFDM_RATE_18MB:
	case IEEE80211_OFDM_RATE_24MB:
	case IEEE80211_OFDM_RATE_36MB:
	case IEEE80211_OFDM_RATE_48MB:
	case IEEE80211_OFDM_RATE_54MB:
		return 1;
	}
	return 0;
}

static inline int ieee80211_is_cck_rate(u8 rate)
{
	switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
	case IEEE80211_CCK_RATE_1MB:
	case IEEE80211_CCK_RATE_2MB:
	case IEEE80211_CCK_RATE_5MB:
	case IEEE80211_CCK_RATE_11MB:
		return 1;
	}
	return 0;
}

/* ieee80211.c */
extern void free_ieee80211(struct net_device *dev);
extern struct net_device *alloc_ieee80211(int sizeof_priv);
+134 −180
Original line number Diff line number Diff line
@@ -917,174 +917,24 @@ static int ieee80211_parse_qos_info_param_IE(struct ieee80211_info_element
	return rc;
}

static int ieee80211_handle_assoc_resp(struct ieee80211_device *ieee, struct ieee80211_assoc_response
				       *frame, struct ieee80211_rx_stats *stats)
{
	struct ieee80211_network network_resp;
	struct ieee80211_network *network = &network_resp;
	struct ieee80211_info_element *info_element;
	struct net_device *dev = ieee->dev;
	u16 left;

	network->flags = 0;
	network->qos_data.active = 0;
	network->qos_data.supported = 0;
	network->qos_data.param_count = 0;
	network->qos_data.old_param_count = 0;

	//network->atim_window = le16_to_cpu(frame->aid) & (0x3FFF);
	network->atim_window = le16_to_cpu(frame->aid);
	network->listen_interval = le16_to_cpu(frame->status);

	info_element = frame->info_element;
	left = stats->len - sizeof(*frame);

	while (left >= sizeof(struct ieee80211_info_element)) {
		if (sizeof(struct ieee80211_info_element) +
		    info_element->len > left) {
			IEEE80211_DEBUG_QOS("ASSOC RESP: parse failed: "
					    "info_element->len + 2 > left : "
					    "info_element->len+2=%zd left=%d, id=%d.\n",
					    info_element->len +
					    sizeof(struct
						   ieee80211_info_element),
					    left, info_element->id);
			return 1;
		}

		switch (info_element->id) {
		case MFIE_TYPE_SSID:
			if (ieee80211_is_empty_essid(info_element->data,
						     info_element->len)) {
				network->flags |= NETWORK_EMPTY_ESSID;
				break;
			}

			network->ssid_len = min(info_element->len,
						(u8) IW_ESSID_MAX_SIZE);
			memcpy(network->ssid, info_element->data,
			       network->ssid_len);
			if (network->ssid_len < IW_ESSID_MAX_SIZE)
				memset(network->ssid + network->ssid_len, 0,
				       IW_ESSID_MAX_SIZE - network->ssid_len);

			IEEE80211_DEBUG_QOS("MFIE_TYPE_SSID: '%s' len=%d.\n",
					    network->ssid, network->ssid_len);
			break;

		case MFIE_TYPE_TIM:
			IEEE80211_DEBUG_QOS("MFIE_TYPE_TIM: ignored\n");
			break;

		case MFIE_TYPE_IBSS_SET:
			IEEE80211_DEBUG_QOS("MFIE_TYPE_IBSS_SET: ignored\n");
			break;

		case MFIE_TYPE_CHALLENGE:
			IEEE80211_DEBUG_QOS("MFIE_TYPE_CHALLENGE: ignored\n");
			break;

		case MFIE_TYPE_GENERIC:
			IEEE80211_DEBUG_QOS("MFIE_TYPE_GENERIC: %d bytes\n",
					    info_element->len);
			ieee80211_parse_qos_info_param_IE(info_element,
							  network);
			break;

		case MFIE_TYPE_RSN:
			IEEE80211_DEBUG_QOS("MFIE_TYPE_RSN: %d bytes\n",
					    info_element->len);
			break;

		case MFIE_TYPE_QOS_PARAMETER:
			printk("QoS Error need to parse QOS_PARAMETER IE\n");
			break;

		default:
			IEEE80211_DEBUG_QOS("unsupported IE %d\n",
					    info_element->id);
			break;
		}

		left -= sizeof(struct ieee80211_info_element) +
		    info_element->len;
		info_element = (struct ieee80211_info_element *)
		    &info_element->data[info_element->len];
	}

	if (ieee->handle_assoc_response != NULL)
		ieee->handle_assoc_response(dev, frame, network);

	return 0;
}

/***************************************************/

static inline int ieee80211_is_ofdm_rate(u8 rate)
{
	switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
	case IEEE80211_OFDM_RATE_6MB:
	case IEEE80211_OFDM_RATE_9MB:
	case IEEE80211_OFDM_RATE_12MB:
	case IEEE80211_OFDM_RATE_18MB:
	case IEEE80211_OFDM_RATE_24MB:
	case IEEE80211_OFDM_RATE_36MB:
	case IEEE80211_OFDM_RATE_48MB:
	case IEEE80211_OFDM_RATE_54MB:
		return 1;
	}
	return 0;
}

static inline int ieee80211_network_init(struct ieee80211_device *ieee, struct ieee80211_probe_response
					 *beacon,
					 struct ieee80211_network *network,
					 struct ieee80211_rx_stats *stats)
static int ieee80211_parse_info_param(struct ieee80211_info_element
				      *info_element, u16 length,
				      struct ieee80211_network *network)
{
	u8 i;
#ifdef CONFIG_IEEE80211_DEBUG
	char rates_str[64];
	char *p;
#endif
	struct ieee80211_info_element *info_element;
	u16 left;
	u8 i;
	network->qos_data.active = 0;
	network->qos_data.supported = 0;
	network->qos_data.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;

	info_element = beacon->info_element;
	left = stats->len - sizeof(*beacon);
	while (left >= sizeof(*info_element)) {
		if (sizeof(*info_element) + info_element->len > left) {
			IEEE80211_DEBUG_SCAN
			    ("SCAN: parse failed: info_element->len + 2 > left : info_element->len+2=%Zd left=%d.\n",
			     info_element->len + sizeof(*info_element), left);
	while (length >= sizeof(*info_element)) {
		if (sizeof(*info_element) + info_element->len > length) {
			IEEE80211_DEBUG_MGMT("Info elem: parse failed: "
					     "info_element->len + 2 > left : "
					     "info_element->len+2=%zd left=%d, id=%d.\n",
					     info_element->len +
					     sizeof(*info_element),
					     length, info_element->id);
			return 1;
		}

@@ -1104,7 +954,7 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee, struct i
				memset(network->ssid + network->ssid_len, 0,
				       IW_ESSID_MAX_SIZE - network->ssid_len);

			IEEE80211_DEBUG_SCAN("MFIE_TYPE_SSID: '%s' len=%d.\n",
			IEEE80211_DEBUG_MGMT("MFIE_TYPE_SSID: '%s' len=%d.\n",
					     network->ssid, network->ssid_len);
			break;

@@ -1131,7 +981,7 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee, struct i
				}
			}

			IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES: '%s' (%d)\n",
			IEEE80211_DEBUG_MGMT("MFIE_TYPE_RATES: '%s' (%d)\n",
					     rates_str, network->rates_len);
			break;

@@ -1158,47 +1008,46 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee, struct i
				}
			}

			IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES_EX: '%s' (%d)\n",
			IEEE80211_DEBUG_MGMT("MFIE_TYPE_RATES_EX: '%s' (%d)\n",
					     rates_str, network->rates_ex_len);
			break;

		case MFIE_TYPE_DS_SET:
			IEEE80211_DEBUG_SCAN("MFIE_TYPE_DS_SET: %d\n",
			IEEE80211_DEBUG_MGMT("MFIE_TYPE_DS_SET: %d\n",
					     info_element->data[0]);
			if (stats->freq == IEEE80211_24GHZ_BAND)
			network->channel = info_element->data[0];
			break;

		case MFIE_TYPE_FH_SET:
			IEEE80211_DEBUG_SCAN("MFIE_TYPE_FH_SET: ignored\n");
			IEEE80211_DEBUG_MGMT("MFIE_TYPE_FH_SET: ignored\n");
			break;

		case MFIE_TYPE_CF_SET:
			IEEE80211_DEBUG_SCAN("MFIE_TYPE_CF_SET: ignored\n");
			IEEE80211_DEBUG_MGMT("MFIE_TYPE_CF_SET: ignored\n");
			break;

		case MFIE_TYPE_TIM:
			IEEE80211_DEBUG_SCAN("MFIE_TYPE_TIM: ignored\n");
			IEEE80211_DEBUG_MGMT("MFIE_TYPE_TIM: ignored\n");
			break;

		case MFIE_TYPE_ERP_INFO:
			network->erp_value = info_element->data[0];
			IEEE80211_DEBUG_SCAN("MFIE_TYPE_ERP_SET: %d\n",
			IEEE80211_DEBUG_MGMT("MFIE_TYPE_ERP_SET: %d\n",
					     network->erp_value);
			break;

		case MFIE_TYPE_IBSS_SET:
			network->atim_window = info_element->data[0];
			IEEE80211_DEBUG_SCAN("MFIE_TYPE_IBSS_SET: %d\n",
			IEEE80211_DEBUG_MGMT("MFIE_TYPE_IBSS_SET: %d\n",
					     network->atim_window);
			break;

		case MFIE_TYPE_CHALLENGE:
			IEEE80211_DEBUG_SCAN("MFIE_TYPE_CHALLENGE: ignored\n");
			IEEE80211_DEBUG_MGMT("MFIE_TYPE_CHALLENGE: ignored\n");
			break;

		case MFIE_TYPE_GENERIC:
			IEEE80211_DEBUG_SCAN("MFIE_TYPE_GENERIC: %d bytes\n",
			IEEE80211_DEBUG_MGMT("MFIE_TYPE_GENERIC: %d bytes\n",
					     info_element->len);
			if (!ieee80211_parse_qos_info_param_IE(info_element,
							       network))
@@ -1217,7 +1066,7 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee, struct i
			break;

		case MFIE_TYPE_RSN:
			IEEE80211_DEBUG_SCAN("MFIE_TYPE_RSN: %d bytes\n",
			IEEE80211_DEBUG_MGMT("MFIE_TYPE_RSN: %d bytes\n",
					     info_element->len);
			network->rsn_ie_len = min(info_element->len + 2,
						  MAX_WPA_IE_LEN);
@@ -1231,16 +1080,121 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee, struct i
			break;

		default:
			IEEE80211_DEBUG_SCAN("unsupported IE %d\n",
			IEEE80211_DEBUG_MGMT("unsupported IE %d\n",
					     info_element->id);
			break;
		}

		left -= sizeof(*info_element) + info_element->len;
		info_element = (struct ieee80211_info_element *)
		    &info_element->data[info_element->len];
		length -= sizeof(*info_element) + info_element->len;
		info_element =
		    (struct ieee80211_info_element *)&info_element->
		    data[info_element->len];
	}

	return 0;
}

static int ieee80211_handle_assoc_resp(struct ieee80211_device *ieee, struct ieee80211_assoc_response
				       *frame, struct ieee80211_rx_stats *stats)
{
	struct ieee80211_network network_resp;
	struct ieee80211_network *network = &network_resp;
	struct net_device *dev = ieee->dev;

	network->flags = 0;
	network->qos_data.active = 0;
	network->qos_data.supported = 0;
	network->qos_data.param_count = 0;
	network->qos_data.old_param_count = 0;

	//network->atim_window = le16_to_cpu(frame->aid) & (0x3FFF);
	network->atim_window = le16_to_cpu(frame->aid);
	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 inline int ieee80211_network_init(struct ieee80211_device *ieee, struct ieee80211_probe_response
					 *beacon,
					 struct ieee80211_network *network,
					 struct ieee80211_rx_stats *stats)
{
	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;
+3 −3

File changed.

Contains only whitespace changes.