Commit 13d1ef29 authored by Jeff Garzik's avatar Jeff Garzik
parents e2608361 ff0037b2
...@@ -613,7 +613,7 @@ struct ieee80211_disassoc { ...@@ -613,7 +613,7 @@ struct ieee80211_disassoc {
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Alias deauth for disassoc */ /* Alias deauth for disassoc */
#define ieee82011_deauth ieee80211_disassoc #define ieee80211_deauth ieee80211_disassoc
struct ieee80211_probe_request { struct ieee80211_probe_request {
struct ieee80211_hdr_3addr header; struct ieee80211_hdr_3addr header;
...@@ -1045,6 +1045,34 @@ static inline u8 *ieee80211_get_payload(struct ieee80211_hdr *hdr) ...@@ -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 */ /* ieee80211.c */
extern void free_ieee80211(struct net_device *dev); extern void free_ieee80211(struct net_device *dev);
extern struct net_device *alloc_ieee80211(int sizeof_priv); extern struct net_device *alloc_ieee80211(int sizeof_priv);
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#include <linux/skbuff.h> #include <linux/skbuff.h>
enum { enum {
IEEE80211_CRYPTO_TKIP_COUNTERMEASURES = (1<<0), IEEE80211_CRYPTO_TKIP_COUNTERMEASURES = (1 << 0),
}; };
struct ieee80211_crypto_ops { struct ieee80211_crypto_ops {
...@@ -65,8 +65,8 @@ struct ieee80211_crypto_ops { ...@@ -65,8 +65,8 @@ struct ieee80211_crypto_ops {
char *(*print_stats) (char *p, void *priv); char *(*print_stats) (char *p, void *priv);
/* Crypto specific flag get/set for configuration settings */ /* Crypto specific flag get/set for configuration settings */
unsigned long (*get_flags)(void *priv); unsigned long (*get_flags) (void *priv);
unsigned long (*set_flags)(unsigned long flags, void *priv); unsigned long (*set_flags) (unsigned long flags, void *priv);
/* maximum number of bytes added by encryption; encrypt buf is /* maximum number of bytes added by encryption; encrypt buf is
* allocated with extra_prefix_len bytes, copy of in_buf, and * allocated with extra_prefix_len bytes, copy of in_buf, and
......
...@@ -917,174 +917,24 @@ static int ieee80211_parse_qos_info_param_IE(struct ieee80211_info_element ...@@ -917,174 +917,24 @@ static int ieee80211_parse_qos_info_param_IE(struct ieee80211_info_element
return rc; return rc;
} }
static int ieee80211_handle_assoc_resp(struct ieee80211_device *ieee, struct ieee80211_assoc_response static int ieee80211_parse_info_param(struct ieee80211_info_element
*frame, struct ieee80211_rx_stats *stats) *info_element, u16 length,
{ struct ieee80211_network *network)
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)
{ {
u8 i;
#ifdef CONFIG_IEEE80211_DEBUG #ifdef CONFIG_IEEE80211_DEBUG
char rates_str[64]; char rates_str[64];
char *p; char *p;
#endif #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 */ while (length >= sizeof(*info_element)) {
memcpy(network->bssid, beacon->header.addr3, ETH_ALEN); if (sizeof(*info_element) + info_element->len > length) {
network->capability = le16_to_cpu(beacon->capability); IEEE80211_DEBUG_MGMT("Info elem: parse failed: "
network->last_scanned = jiffies; "info_element->len + 2 > left : "
network->time_stamp[0] = le32_to_cpu(beacon->time_stamp[0]); "info_element->len+2=%zd left=%d, id=%d.\n",
network->time_stamp[1] = le32_to_cpu(beacon->time_stamp[1]); info_element->len +
network->beacon_interval = le16_to_cpu(beacon->beacon_interval); sizeof(*info_element),
/* Where to pull this? beacon->listen_interval; */ length, info_element->id);
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);
return 1; return 1;
} }
...@@ -1104,7 +954,7 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee, struct i ...@@ -1104,7 +954,7 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee, struct i
memset(network->ssid + network->ssid_len, 0, memset(network->ssid + network->ssid_len, 0,
IW_ESSID_MAX_SIZE - network->ssid_len); 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); network->ssid, network->ssid_len);
break; break;
...@@ -1131,7 +981,7 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee, struct i ...@@ -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); rates_str, network->rates_len);
break; break;
...@@ -1158,47 +1008,46 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee, struct i ...@@ -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); rates_str, network->rates_ex_len);
break; break;
case MFIE_TYPE_DS_SET: 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]); info_element->data[0]);
if (stats->freq == IEEE80211_24GHZ_BAND)
network->channel = info_element->data[0]; network->channel = info_element->data[0];
break; break;
case MFIE_TYPE_FH_SET: case MFIE_TYPE_FH_SET:
IEEE80211_DEBUG_SCAN("MFIE_TYPE_FH_SET: ignored\n"); IEEE80211_DEBUG_MGMT("MFIE_TYPE_FH_SET: ignored\n");
break; break;
case MFIE_TYPE_CF_SET: case MFIE_TYPE_CF_SET:
IEEE80211_DEBUG_SCAN("MFIE_TYPE_CF_SET: ignored\n"); IEEE80211_DEBUG_MGMT("MFIE_TYPE_CF_SET: ignored\n");
break; break;
case MFIE_TYPE_TIM: case MFIE_TYPE_TIM:
IEEE80211_DEBUG_SCAN("MFIE_TYPE_TIM: ignored\n"); IEEE80211_DEBUG_MGMT("MFIE_TYPE_TIM: ignored\n");
break; break;
case MFIE_TYPE_ERP_INFO: case MFIE_TYPE_ERP_INFO:
network->erp_value = info_element->data[0]; 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); network->erp_value);
break; break;
case MFIE_TYPE_IBSS_SET: case MFIE_TYPE_IBSS_SET:
network->atim_window = info_element->data[0]; 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); network->atim_window);
break; break;
case MFIE_TYPE_CHALLENGE: case MFIE_TYPE_CHALLENGE:
IEEE80211_DEBUG_SCAN("MFIE_TYPE_CHALLENGE: ignored\n"); IEEE80211_DEBUG_MGMT("MFIE_TYPE_CHALLENGE: ignored\n");
break; break;
case MFIE_TYPE_GENERIC: 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); info_element->len);
if (!ieee80211_parse_qos_info_param_IE(info_element, if (!ieee80211_parse_qos_info_param_IE(info_element,
network)) network))
...@@ -1217,7 +1066,7 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee, struct i ...@@ -1217,7 +1066,7 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee, struct i
break; break;
case MFIE_TYPE_RSN: 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); info_element->len);
network->rsn_ie_len = min(info_element->len + 2, network->rsn_ie_len = min(info_element->len + 2,
MAX_WPA_IE_LEN); MAX_WPA_IE_LEN);
...@@ -1231,16 +1080,121 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee, struct i ...@@ -1231,16 +1080,121 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee, struct i
break; break;
default: default:
IEEE80211_DEBUG_SCAN("unsupported IE %d\n", IEEE80211_DEBUG_MGMT("unsupported IE %d\n",
info_element->id); info_element->id);
break; break;
} }
left -= sizeof(*info_element) + info_element->len; length -= sizeof(*info_element) + info_element->len;
info_element = (struct ieee80211_info_element *) info_element =
&info_element->data[info_element->len]; (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; network->mode = 0;
if (stats->freq == IEEE80211_52GHZ_BAND) if (stats->freq == IEEE80211_52GHZ_BAND)
network->mode = IEEE_A; network->mode = IEEE_A;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment