Explorar el Código

Merge rsync://bughost.org/repos/ieee80211-delta/

Jeff Garzik hace 19 años
padre
commit
13d1ef29bc
Se han modificado 3 ficheros con 166 adiciones y 184 borrados
  1. 29 1
      include/net/ieee80211.h
  2. 3 3
      include/net/ieee80211_crypt.h
  3. 134 180
      net/ieee80211/ieee80211_rx.c

+ 29 - 1
include/net/ieee80211.h

@@ -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);

+ 3 - 3
include/net/ieee80211_crypt.h

@@ -26,7 +26,7 @@
 #include <linux/skbuff.h>
 
 enum {
-	IEEE80211_CRYPTO_TKIP_COUNTERMEASURES = (1<<0),
+	IEEE80211_CRYPTO_TKIP_COUNTERMEASURES = (1 << 0),
 };
 
 struct ieee80211_crypto_ops {
@@ -65,8 +65,8 @@ struct ieee80211_crypto_ops {
 	char *(*print_stats) (char *p, void *priv);
 
 	/* Crypto specific flag get/set for configuration settings */
-	unsigned long (*get_flags)(void *priv);
-	unsigned long (*set_flags)(unsigned long flags, void *priv);
+	unsigned long (*get_flags) (void *priv);
+	unsigned long (*set_flags) (unsigned long flags, void *priv);
 
 	/* maximum number of bytes added by encryption; encrypt buf is
 	 * allocated with extra_prefix_len bytes, copy of in_buf, and

+ 134 - 180
net/ieee80211/ieee80211_rx.c

@@ -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];
+			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;