From 44d7a8cfbdc1112fd80546591fd6f5c831ea0363 Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Wed, 18 Jan 2006 12:02:33 +0200 Subject: [PATCH] WEP fields are incorrectly shown to be INSIDE snap in the doc >If encryption is enabled, each fragment payload size is reduced by enough space >to add the prefix and postfix (IV and ICV totalling 8 bytes in the case of WEP) >So if you have 1500 bytes of payload with ieee->fts set to 500 without >encryption it will take 3 frames. With WEP it will take 4 frames as the >payload of each frame is reduced to 492 bytes. Text is correct, but in picture (IV,payload,ICV) sits inside SNAP. Patch corrects this. Signed-Off-By: Denis Vlasenko Acked-By: Johannes Berg Signed-off-by: John W. Linville --- net/ieee80211/ieee80211_tx.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'net') diff --git a/net/ieee80211/ieee80211_tx.c b/net/ieee80211/ieee80211_tx.c index 8fdd943ebe8..0949803b9c7 100644 --- a/net/ieee80211/ieee80211_tx.c +++ b/net/ieee80211/ieee80211_tx.c @@ -56,7 +56,18 @@ Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | Frame | fcs | `--------------------------------------------------| |------' Total: 28 non-data bytes `----.----' | - .- 'Frame data' expands to <---------------------------' + .- 'Frame data' expands, if WEP enabled, to <----------' + | + V + ,-----------------------. +Bytes | 4 | 0-2296 | 4 | + |-----|-----------|-----| +Desc. | IV | Encrypted | ICV | + | | Packet | | + `-----| |-----' + `-----.-----' + | + .- 'Encrypted Packet' expands to | V ,---------------------------------------------------. @@ -65,18 +76,7 @@ Bytes | 1 | 1 | 1 | 3 | 2 | 0-2304 | Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP | | DSAP | SSAP | | | | Packet | | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8| | | - `-----------------------------------------| | -Total: 8 non-data bytes `----.----' - | - .- 'IP Packet' expands, if WEP enabled, to <--' - | - V - ,-----------------------. -Bytes | 4 | 0-2296 | 4 | - |-----|-----------|-----| -Desc. | IV | Encrypted | ICV | - | | IP Packet | | - `-----------------------' + `---------------------------------------------------- Total: 8 non-data bytes 802.3 Ethernet Data Frame -- cgit v1.2.3 From d65292375154085feb7217ed8fccc8edf163c6b2 Mon Sep 17 00:00:00 2001 From: Zhu Yi Date: Thu, 19 Jan 2006 16:20:49 +0800 Subject: [PATCH] ieee80211: Log if netif_rx() drops the packet Log to wireless network stats if netif_rx() drops the packet. (also trailing whitespace and Lindent cleanups as part of patch-apply process) Signed-off-by: James Ketrenos Signed-off-by: Zhu Yi Signed-off-by: John W. Linville --- net/ieee80211/ieee80211_crypt.c | 11 +++++------ net/ieee80211/ieee80211_rx.c | 9 ++++++++- 2 files changed, 13 insertions(+), 7 deletions(-) (limited to 'net') diff --git a/net/ieee80211/ieee80211_crypt.c b/net/ieee80211/ieee80211_crypt.c index ecc9bb196ab..cb71d794a7d 100644 --- a/net/ieee80211/ieee80211_crypt.c +++ b/net/ieee80211/ieee80211_crypt.c @@ -18,7 +18,6 @@ #include #include - MODULE_AUTHOR("Jouni Malinen"); MODULE_DESCRIPTION("HostAP crypto"); MODULE_LICENSE("GPL"); @@ -33,11 +32,11 @@ static DEFINE_SPINLOCK(ieee80211_crypto_lock); void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force) { - struct ieee80211_crypt_data *entry, *next; + struct ieee80211_crypt_data *entry, *next; unsigned long flags; spin_lock_irqsave(&ieee->lock, flags); - list_for_each_entry_safe(entry, next, &ieee->crypt_deinit_list, list) { + list_for_each_entry_safe(entry, next, &ieee->crypt_deinit_list, list) { if (atomic_read(&entry->refcnt) != 0 && !force) continue; @@ -141,9 +140,9 @@ int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops) spin_unlock_irqrestore(&ieee80211_crypto_lock, flags); return -EINVAL; - found: + found: printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm " - "'%s'\n", ops->name); + "'%s'\n", ops->name); list_del(&alg->list); spin_unlock_irqrestore(&ieee80211_crypto_lock, flags); kfree(alg); @@ -163,7 +162,7 @@ struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name) spin_unlock_irqrestore(&ieee80211_crypto_lock, flags); return NULL; - found: + found: spin_unlock_irqrestore(&ieee80211_crypto_lock, flags); return alg->ops; } diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c index 695d0478fd1..3ae91118c73 100644 --- a/net/ieee80211/ieee80211_rx.c +++ b/net/ieee80211/ieee80211_rx.c @@ -754,7 +754,14 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, memset(skb->cb, 0, sizeof(skb->cb)); skb->dev = dev; skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */ - netif_rx(skb); + if (netif_rx(skb) == NET_RX_DROP) { + /* netif_rx always succeeds, but it might drop + * the packet. If it drops the packet, we log that + * in our stats. */ + IEEE80211_DEBUG_DROP + ("RX: netif_rx dropped the packet\n"); + stats->rx_dropped++; + } } rx_exit: -- cgit v1.2.3 From d128f6c176bff9c4929476e13132804321a6d5c5 Mon Sep 17 00:00:00 2001 From: Zhu Yi Date: Thu, 19 Jan 2006 16:21:45 +0800 Subject: [PATCH] ieee80211: add flags for all geo channels Signed-off-by: Zhu Yi Signed-off-by: John W. Linville --- net/ieee80211/ieee80211_geo.c | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) (limited to 'net') diff --git a/net/ieee80211/ieee80211_geo.c b/net/ieee80211/ieee80211_geo.c index 610cc5cbc25..3027153940f 100644 --- a/net/ieee80211/ieee80211_geo.c +++ b/net/ieee80211/ieee80211_geo.c @@ -58,13 +58,15 @@ int ieee80211_is_valid_channel(struct ieee80211_device *ieee, u8 channel) * this is a B only channel, we don't see it * as valid. */ if ((ieee->geo.bg[i].channel == channel) && + !(ieee->geo.bg[i].flags & IEEE80211_CH_INVALID) && (!(ieee->mode & IEEE_G) || !(ieee->geo.bg[i].flags & IEEE80211_CH_B_ONLY))) return IEEE80211_24GHZ_BAND; if (ieee->freq_band & IEEE80211_52GHZ_BAND) for (i = 0; i < ieee->geo.a_channels; i++) - if (ieee->geo.a[i].channel == channel) + if ((ieee->geo.a[i].channel == channel) && + !(ieee->geo.a[i].flags & IEEE80211_CH_INVALID)) return IEEE80211_52GHZ_BAND; return 0; @@ -133,6 +135,41 @@ const struct ieee80211_geo *ieee80211_get_geo(struct ieee80211_device *ieee) return &ieee->geo; } +u8 ieee80211_get_channel_flags(struct ieee80211_device * ieee, u8 channel) +{ + int index = ieee80211_channel_to_index(ieee, channel); + + if (index == -1) + return IEEE80211_CH_INVALID; + + if (channel <= IEEE80211_24GHZ_CHANNELS) + return ieee->geo.bg[index].flags; + + return ieee->geo.a[index].flags; +} + +static const struct ieee80211_channel bad_channel = { + .channel = 0, + .flags = IEEE80211_CH_INVALID, + .max_power = 0, +}; + +const struct ieee80211_channel *ieee80211_get_channel(struct ieee80211_device + *ieee, u8 channel) +{ + int index = ieee80211_channel_to_index(ieee, channel); + + if (index == -1) + return &bad_channel; + + if (channel <= IEEE80211_24GHZ_CHANNELS) + return &ieee->geo.bg[index]; + + return &ieee->geo.a[index]; +} + +EXPORT_SYMBOL(ieee80211_get_channel); +EXPORT_SYMBOL(ieee80211_get_channel_flags); EXPORT_SYMBOL(ieee80211_is_valid_channel); EXPORT_SYMBOL(ieee80211_freq_to_channel); EXPORT_SYMBOL(ieee80211_channel_to_index); -- cgit v1.2.3 From 7bd64366044565d6861783613db191c8aaec691e Mon Sep 17 00:00:00 2001 From: Zhu Yi Date: Thu, 19 Jan 2006 16:21:54 +0800 Subject: [PATCH] ieee80211: Add spectrum management information Add spectrum management information and use stat.signal to provide signal level information. Signed-off-by: Zhu Yi Signed-off-by: John W. Linville --- net/ieee80211/ieee80211_wx.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) (limited to 'net') diff --git a/net/ieee80211/ieee80211_wx.c b/net/ieee80211/ieee80211_wx.c index f87c6b89f84..9496918e610 100644 --- a/net/ieee80211/ieee80211_wx.c +++ b/net/ieee80211/ieee80211_wx.c @@ -149,9 +149,7 @@ static char *ipw2100_translate_scan(struct ieee80211_device *ieee, iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID; iwe.u.qual.qual = 0; - iwe.u.qual.level = 0; } else { - iwe.u.qual.level = network->stats.rssi; if (ieee->perfect_rssi == ieee->worst_rssi) iwe.u.qual.qual = 100; else @@ -179,6 +177,13 @@ static char *ipw2100_translate_scan(struct ieee80211_device *ieee, iwe.u.qual.noise = network->stats.noise; } + if (!(network->stats.mask & IEEE80211_STATMASK_SIGNAL)) { + iwe.u.qual.updated |= IW_QUAL_LEVEL_INVALID; + iwe.u.qual.level = 0; + } else { + iwe.u.qual.level = network->stats.signal; + } + start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN); iwe.cmd = IWEVCUSTOM; @@ -229,6 +234,28 @@ static char *ipw2100_translate_scan(struct ieee80211_device *ieee, if (iwe.u.data.length) start = iwe_stream_add_point(start, stop, &iwe, custom); + /* Add spectrum management information */ + iwe.cmd = -1; + p = custom; + p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Channel flags: "); + + if (ieee80211_get_channel_flags(ieee, network->channel) & + IEEE80211_CH_INVALID) { + iwe.cmd = IWEVCUSTOM; + p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), "INVALID "); + } + + if (ieee80211_get_channel_flags(ieee, network->channel) & + IEEE80211_CH_RADAR_DETECT) { + iwe.cmd = IWEVCUSTOM; + p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), "DFS "); + } + + if (iwe.cmd == IWEVCUSTOM) { + iwe.u.data.length = p - custom; + start = iwe_stream_add_point(start, stop, &iwe, custom); + } + return start; } -- cgit v1.2.3 From 8aa914b747b650fc1735f3a3171753ac15ed93ab Mon Sep 17 00:00:00 2001 From: Zhu Yi Date: Thu, 19 Jan 2006 16:22:07 +0800 Subject: [PATCH] ieee80211: kmalloc+memset -> kzalloc cleanups kmalloc+memset -> kzalloc cleanups in ieee80211_crypt_tkip Signed-off-by: Zhu Yi Signed-off-by: John W. Linville --- net/ieee80211/ieee80211_crypt_tkip.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'net') diff --git a/net/ieee80211/ieee80211_crypt_tkip.c b/net/ieee80211/ieee80211_crypt_tkip.c index e0988320efb..de56a47edb0 100644 --- a/net/ieee80211/ieee80211_crypt_tkip.c +++ b/net/ieee80211/ieee80211_crypt_tkip.c @@ -80,10 +80,9 @@ static void *ieee80211_tkip_init(int key_idx) { struct ieee80211_tkip_data *priv; - priv = kmalloc(sizeof(*priv), GFP_ATOMIC); + priv = kzalloc(sizeof(*priv), GFP_ATOMIC); if (priv == NULL) goto fail; - memset(priv, 0, sizeof(*priv)); priv->key_idx = key_idx; -- cgit v1.2.3 From 41a25c616b3140c388ff6009a1cb0b6b06a10f29 Mon Sep 17 00:00:00 2001 From: Zhu Yi Date: Thu, 19 Jan 2006 16:22:23 +0800 Subject: [PATCH] ieee80211: TIM information element parsing Added partial support of TIM information element parsing Signed-off-by: James Ketrenos Signed-off-by: Zhu Yi Signed-off-by: John W. Linville --- net/ieee80211/ieee80211_rx.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'net') diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c index 3ae91118c73..de402b75c42 100644 --- a/net/ieee80211/ieee80211_rx.c +++ b/net/ieee80211/ieee80211_rx.c @@ -1047,7 +1047,9 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element break; case MFIE_TYPE_TIM: - IEEE80211_DEBUG_MGMT("MFIE_TYPE_TIM: ignored\n"); + network->tim.tim_count = info_element->data[0]; + network->tim.tim_period = info_element->data[1]; + IEEE80211_DEBUG_MGMT("MFIE_TYPE_TIM: partially ignored\n"); break; case MFIE_TYPE_ERP_INFO: @@ -1276,6 +1278,7 @@ static void update_network(struct ieee80211_network *dst, 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; -- cgit v1.2.3 From 9184d9348a7a0e60d70d5f4c23de79fdbc72b9a3 Mon Sep 17 00:00:00 2001 From: Zhu Yi Date: Thu, 19 Jan 2006 16:22:32 +0800 Subject: [PATCH] ieee80211: Add TKIP crypt->build_iv This patch adds ieee80211 TKIP build_iv() method to support hardwares that can do TKIP encryption but relies on ieee80211 layer to build the IV. It also changes the build_iv() interface to return the key if possible after the IV is built (this is required by TKIP). Signed-off-by: Zhu Yi Signed-off-by: John W. Linville --- net/ieee80211/ieee80211_crypt_ccmp.c | 8 ++++-- net/ieee80211/ieee80211_crypt_tkip.c | 53 ++++++++++++++++++------------------ net/ieee80211/ieee80211_crypt_wep.c | 5 ++-- net/ieee80211/ieee80211_tx.c | 4 ++- 4 files changed, 39 insertions(+), 31 deletions(-) (limited to 'net') diff --git a/net/ieee80211/ieee80211_crypt_ccmp.c b/net/ieee80211/ieee80211_crypt_ccmp.c index 47022172850..097bcea2129 100644 --- a/net/ieee80211/ieee80211_crypt_ccmp.c +++ b/net/ieee80211/ieee80211_crypt_ccmp.c @@ -190,7 +190,8 @@ static void ccmp_init_blocks(struct crypto_tfm *tfm, ieee80211_ccmp_aes_encrypt(tfm, b0, s0); } -static int ieee80211_ccmp_hdr(struct sk_buff *skb, int hdr_len, void *priv) +static int ieee80211_ccmp_hdr(struct sk_buff *skb, int hdr_len, + u8 *aeskey, int keylen, void *priv) { struct ieee80211_ccmp_data *key = priv; int i; @@ -199,6 +200,9 @@ static int ieee80211_ccmp_hdr(struct sk_buff *skb, int hdr_len, void *priv) if (skb_headroom(skb) < CCMP_HDR_LEN || skb->len < hdr_len) return -1; + if (aeskey != NULL && keylen >= CCMP_TK_LEN) + memcpy(aeskey, key->key, CCMP_TK_LEN); + pos = skb_push(skb, CCMP_HDR_LEN); memmove(pos, pos + CCMP_HDR_LEN, hdr_len); pos += hdr_len; @@ -238,7 +242,7 @@ static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv) return -1; data_len = skb->len - hdr_len; - len = ieee80211_ccmp_hdr(skb, hdr_len, priv); + len = ieee80211_ccmp_hdr(skb, hdr_len, NULL, 0, priv); if (len < 0) return -1; diff --git a/net/ieee80211/ieee80211_crypt_tkip.c b/net/ieee80211/ieee80211_crypt_tkip.c index de56a47edb0..93def94c1b3 100644 --- a/net/ieee80211/ieee80211_crypt_tkip.c +++ b/net/ieee80211/ieee80211_crypt_tkip.c @@ -270,34 +270,33 @@ static void tkip_mixing_phase2(u8 * WEPSeed, const u8 * TK, const u16 * TTAK, #endif } -static u8 *ieee80211_tkip_hdr(struct sk_buff *skb, int hdr_len, void *priv) +static int ieee80211_tkip_hdr(struct sk_buff *skb, int hdr_len, + u8 * rc4key, int keylen, void *priv) { struct ieee80211_tkip_data *tkey = priv; int len; - u8 *rc4key, *pos, *icv; + u8 *pos; struct ieee80211_hdr_4addr *hdr; - u32 crc; hdr = (struct ieee80211_hdr_4addr *)skb->data; if (skb_headroom(skb) < 8 || skb->len < hdr_len) - return NULL; + return -1; + + if (rc4key == NULL || keylen < 16) + return -1; if (!tkey->tx_phase1_done) { tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2, tkey->tx_iv32); tkey->tx_phase1_done = 1; } - rc4key = kmalloc(16, GFP_ATOMIC); - if (!rc4key) - return NULL; tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16); len = skb->len - hdr_len; pos = skb_push(skb, 8); memmove(pos, pos + 8, hdr_len); pos += hdr_len; - icv = skb_put(skb, 4); *pos++ = *rc4key; *pos++ = *(rc4key + 1); @@ -308,28 +307,28 @@ static u8 *ieee80211_tkip_hdr(struct sk_buff *skb, int hdr_len, void *priv) *pos++ = (tkey->tx_iv32 >> 16) & 0xff; *pos++ = (tkey->tx_iv32 >> 24) & 0xff; - crc = ~crc32_le(~0, pos, len); - icv[0] = crc; - icv[1] = crc >> 8; - icv[2] = crc >> 16; - icv[3] = crc >> 24; + tkey->tx_iv16++; + if (tkey->tx_iv16 == 0) { + tkey->tx_phase1_done = 0; + tkey->tx_iv32++; + } - return rc4key; + return 8; } static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) { struct ieee80211_tkip_data *tkey = priv; int len; - const u8 *rc4key; - u8 *pos; + u8 rc4key[16], *pos, *icv; + u32 crc; struct scatterlist sg; if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) { if (net_ratelimit()) { struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *)skb->data; - printk(KERN_DEBUG "TKIP countermeasures: dropped " + printk(KERN_DEBUG ": TKIP countermeasures: dropped " "TX packet to " MAC_FMT "\n", MAC_ARG(hdr->addr1)); } @@ -342,22 +341,23 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) len = skb->len - hdr_len; pos = skb->data + hdr_len; - rc4key = ieee80211_tkip_hdr(skb, hdr_len, priv); - if (!rc4key) + if ((ieee80211_tkip_hdr(skb, hdr_len, rc4key, 16, priv)) < 0) return -1; + icv = skb_put(skb, 4); + + crc = ~crc32_le(~0, pos, len); + icv[0] = crc; + icv[1] = crc >> 8; + icv[2] = crc >> 16; + icv[3] = crc >> 24; + crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16); sg.page = virt_to_page(pos); sg.offset = offset_in_page(pos); sg.length = len + 4; crypto_cipher_encrypt(tkey->tfm_arc4, &sg, &sg, len + 4); - tkey->tx_iv16++; - if (tkey->tx_iv16 == 0) { - tkey->tx_phase1_done = 0; - tkey->tx_iv32++; - } - return 0; } @@ -378,7 +378,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) { if (net_ratelimit()) { - printk(KERN_DEBUG "TKIP countermeasures: dropped " + printk(KERN_DEBUG ": TKIP countermeasures: dropped " "received packet from " MAC_FMT "\n", MAC_ARG(hdr->addr2)); } @@ -694,6 +694,7 @@ static struct ieee80211_crypto_ops ieee80211_crypt_tkip = { .name = "TKIP", .init = ieee80211_tkip_init, .deinit = ieee80211_tkip_deinit, + .build_iv = ieee80211_tkip_hdr, .encrypt_mpdu = ieee80211_tkip_encrypt, .decrypt_mpdu = ieee80211_tkip_decrypt, .encrypt_msdu = ieee80211_michael_mic_add, diff --git a/net/ieee80211/ieee80211_crypt_wep.c b/net/ieee80211/ieee80211_crypt_wep.c index f8dca31be5d..649e581fa56 100644 --- a/net/ieee80211/ieee80211_crypt_wep.c +++ b/net/ieee80211/ieee80211_crypt_wep.c @@ -76,7 +76,8 @@ static void prism2_wep_deinit(void *priv) } /* Add WEP IV/key info to a frame that has at least 4 bytes of headroom */ -static int prism2_wep_build_iv(struct sk_buff *skb, int hdr_len, void *priv) +static int prism2_wep_build_iv(struct sk_buff *skb, int hdr_len, + u8 *key, int keylen, void *priv) { struct prism2_wep_data *wep = priv; u32 klen, len; @@ -131,7 +132,7 @@ static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv) return -1; /* add the IV to the frame */ - if (prism2_wep_build_iv(skb, hdr_len, priv)) + if (prism2_wep_build_iv(skb, hdr_len, NULL, 0, priv)) return -1; /* Copy the IV into the first 3 bytes of the key */ diff --git a/net/ieee80211/ieee80211_tx.c b/net/ieee80211/ieee80211_tx.c index 0949803b9c7..8b4332f5339 100644 --- a/net/ieee80211/ieee80211_tx.c +++ b/net/ieee80211/ieee80211_tx.c @@ -470,7 +470,9 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) atomic_inc(&crypt->refcnt); if (crypt->ops->build_iv) crypt->ops->build_iv(skb_frag, hdr_len, - crypt->priv); + ieee->sec.keys[ieee->sec.active_key], + ieee->sec.key_sizes[ieee->sec.active_key], + crypt->priv); atomic_dec(&crypt->refcnt); } -- cgit v1.2.3 From b79e20b60997e427b701055a2c69fb0c1d507aa9 Mon Sep 17 00:00:00 2001 From: Zhu Yi Date: Thu, 19 Jan 2006 16:21:27 +0800 Subject: [PATCH] ieee80211: Add 802.11h data type and structures Add 802.11h data types and structure definitions to ieee80211.h. Signed-off-by: Hong Liu Signed-off-by: Zhu Yi Signed-off-by: John W. Linville --- net/ieee80211/ieee80211_rx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c index de402b75c42..4165da7ecff 100644 --- a/net/ieee80211/ieee80211_rx.c +++ b/net/ieee80211/ieee80211_rx.c @@ -1514,7 +1514,7 @@ void ieee80211_rx_mgt(struct ieee80211_device *ieee, case IEEE80211_STYPE_DEAUTH: printk("DEAUTH from AP\n"); if (ieee->handle_deauth != NULL) - ieee->handle_deauth(ieee->dev, (struct ieee80211_auth *) + ieee->handle_deauth(ieee->dev, (struct ieee80211_deauth *) header); break; default: -- cgit v1.2.3 From 15f385982e3a4782fe8ed71a9a6beb64a2160c30 Mon Sep 17 00:00:00 2001 From: Zhu Yi Date: Thu, 19 Jan 2006 16:21:35 +0800 Subject: [PATCH] ieee80211: Add helpers for IBSS DFS handling To support IEEE 802.11h in IBSS, an ibss_dfs field is added to struct ieee80211_network. In IBSS, if one STA sends a beacon with DFS info (for radar detection), all the other STAs should receive and store this DFS. All STAs should send the DFS as one of the information element in the beacon they are scheduled to send (if possible) in the future. Since the ibss_dfs has variable length, it must be allocated dynamically. ieee80211_network_reset() is added to clear the ibss_dfs field. ieee80211_network_free() is also updated to free the ibss_dfs field if it is not NULL. Signed-off-by: Zhu Yi Signed-off-by: John W. Linville --- net/ieee80211/ieee80211_module.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'net') diff --git a/net/ieee80211/ieee80211_module.c b/net/ieee80211/ieee80211_module.c index 90d18b72da3..5f67c684afc 100644 --- a/net/ieee80211/ieee80211_module.c +++ b/net/ieee80211/ieee80211_module.c @@ -82,10 +82,28 @@ static int ieee80211_networks_allocate(struct ieee80211_device *ieee) return 0; } +void ieee80211_network_reset(struct ieee80211_network *network) +{ + if (!network) + return; + + if (network->ibss_dfs) { + kfree(network->ibss_dfs); + network->ibss_dfs = NULL; + } +} + static inline void ieee80211_networks_free(struct ieee80211_device *ieee) { + int i; + if (!ieee->networks) return; + + for (i = 0; i < MAX_NETWORK_COUNT; i++) + if (ieee->networks[i].ibss_dfs) + kfree(ieee->networks[i].ibss_dfs); + kfree(ieee->networks); ieee->networks = NULL; } -- cgit v1.2.3 From d1b46b0fba8c1049135ee5d60910b04463dccc95 Mon Sep 17 00:00:00 2001 From: Zhu Yi Date: Thu, 19 Jan 2006 16:22:15 +0800 Subject: [PATCH] ieee80211: Add 802.11h information element parsing Added default handlers for various 802.11h DFS and TPC information elements. Moved all information elements into single location (called from two places). Added debug message with information on unparsed IEs if debug_level set. Added code to reset network IBSS DFS information when appropriate. Added code to invoke driver callback for 802.11h ACTION STYPE. Changed a few printk's to IEEE80211_DEBUG_MGMT. Signed-off-by: James Ketrenos Signed-off-by: Zhu Yi Signed-off-by: John W. Linville --- net/ieee80211/ieee80211_rx.c | 109 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 103 insertions(+), 6 deletions(-) (limited to 'net') diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c index 4165da7ecff..a4ebc22ee71 100644 --- a/net/ieee80211/ieee80211_rx.c +++ b/net/ieee80211/ieee80211_rx.c @@ -937,6 +937,45 @@ static int ieee80211_parse_qos_info_param_IE(struct ieee80211_info_element return rc; } +#ifdef CONFIG_IEEE80211_DEBUG +#define MFIE_STRING(x) case MFIE_TYPE_ ##x: return #x + +static const char *get_info_element_string(u16 id) +{ + switch (id) { + MFIE_STRING(SSID); + MFIE_STRING(RATES); + MFIE_STRING(FH_SET); + MFIE_STRING(DS_SET); + MFIE_STRING(CF_SET); + MFIE_STRING(TIM); + MFIE_STRING(IBSS_SET); + MFIE_STRING(COUNTRY); + MFIE_STRING(HOP_PARAMS); + MFIE_STRING(HOP_TABLE); + MFIE_STRING(REQUEST); + MFIE_STRING(CHALLENGE); + MFIE_STRING(POWER_CONSTRAINT); + MFIE_STRING(POWER_CAPABILITY); + MFIE_STRING(TPC_REQUEST); + MFIE_STRING(TPC_REPORT); + MFIE_STRING(SUPP_CHANNELS); + MFIE_STRING(CSA); + MFIE_STRING(MEASURE_REQUEST); + MFIE_STRING(MEASURE_REPORT); + MFIE_STRING(QUIET); + MFIE_STRING(IBSS_DFS); + MFIE_STRING(ERP_INFO); + MFIE_STRING(RSN); + MFIE_STRING(RATES_EX); + MFIE_STRING(GENERIC); + MFIE_STRING(QOS_PARAMETER); + default: + return "UNKNOWN"; + } +} +#endif + static int ieee80211_parse_info_param(struct ieee80211_info_element *info_element, u16 length, struct ieee80211_network *network) @@ -1100,10 +1139,49 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element printk(KERN_ERR "QoS Error need to parse QOS_PARAMETER IE\n"); break; + /* 802.11h */ + case MFIE_TYPE_POWER_CONSTRAINT: + network->power_constraint = info_element->data[0]; + network->flags |= NETWORK_HAS_POWER_CONSTRAINT; + break; + + case MFIE_TYPE_CSA: + network->power_constraint = info_element->data[0]; + network->flags |= NETWORK_HAS_CSA; + break; + + case MFIE_TYPE_QUIET: + network->quiet.count = info_element->data[0]; + network->quiet.period = info_element->data[1]; + network->quiet.duration = info_element->data[2]; + network->quiet.offset = info_element->data[3]; + network->flags |= NETWORK_HAS_QUIET; + break; + + case MFIE_TYPE_IBSS_DFS: + if (network->ibss_dfs) + break; + network->ibss_dfs = + kmalloc(info_element->len, GFP_ATOMIC); + if (!network->ibss_dfs) + return 1; + memcpy(network->ibss_dfs, info_element->data, + info_element->len); + network->flags |= NETWORK_HAS_IBSS_DFS; + break; + + case MFIE_TYPE_TPC_REPORT: + network->tpc_report.transmit_power = + info_element->data[0]; + network->tpc_report.link_margin = info_element->data[1]; + network->flags |= NETWORK_HAS_TPC_REPORT; + break; default: - IEEE80211_DEBUG_MGMT("unsupported IE %d\n", - info_element->id); + IEEE80211_DEBUG_MGMT + ("Unsupported info element: %s (%d)\n", + get_info_element_string(info_element->id), + info_element->id); break; } @@ -1119,7 +1197,9 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element 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_resp = { + .ibss_dfs = NULL, + }; struct ieee80211_network *network = &network_resp; struct net_device *dev = ieee->dev; @@ -1262,6 +1342,9 @@ static void update_network(struct ieee80211_network *dst, int qos_active; u8 old_param; + ieee80211_network_reset(dst); + dst->ibss_dfs = src->ibss_dfs; + memcpy(&dst->stats, &src->stats, sizeof(struct ieee80211_rx_stats)); dst->capability = src->capability; memcpy(dst->rates, src->rates, src->rates_len); @@ -1323,7 +1406,9 @@ static void ieee80211_process_probe_response(struct ieee80211_device *stats) { struct net_device *dev = ieee->dev; - struct ieee80211_network network; + struct ieee80211_network network = { + .ibss_dfs = NULL, + }; struct ieee80211_network *target; struct ieee80211_network *oldest = NULL; #ifdef CONFIG_IEEE80211_DEBUG @@ -1398,6 +1483,7 @@ static void ieee80211_process_probe_response(struct ieee80211_device escape_essid(target->ssid, target->ssid_len), MAC_ARG(target->bssid)); + ieee80211_network_reset(target); } else { /* Otherwise just pull from the free list */ target = list_entry(ieee->network_free_list.next, @@ -1416,6 +1502,7 @@ static void ieee80211_process_probe_response(struct ieee80211_device "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' (" MAC_FMT ") via %s.\n", @@ -1427,6 +1514,7 @@ static void ieee80211_process_probe_response(struct ieee80211_device frame_ctl)) ? "BEACON" : "PROBE RESPONSE"); update_network(target, &network); + network.ibss_dfs = NULL; } spin_unlock_irqrestore(&ieee->lock, flags); @@ -1511,10 +1599,19 @@ void ieee80211_rx_mgt(struct ieee80211_device *ieee, 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_DEAUTH: - printk("DEAUTH from AP\n"); + IEEE80211_DEBUG_MGMT("DEAUTH\n"); if (ieee->handle_deauth != NULL) - ieee->handle_deauth(ieee->dev, (struct ieee80211_deauth *) + ieee->handle_deauth(ieee->dev, + (struct ieee80211_deauth *) header); break; default: -- cgit v1.2.3 From d86b5e0e6bf5980d3136ab4a855522143f2dcb5d Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sat, 21 Jan 2006 00:46:55 +0100 Subject: [PATCH] net/: fix the WIRELESS_EXT abuse This patch contains the following changes: - add a CONFIG_WIRELESS_EXT select'ed by NET_RADIO for conditional code - remove the now no longer required #ifdef CONFIG_NET_RADIO from some #include's Based on a patch by Jean Tourrilhes . Signed-off-by: Adrian Bunk Signed-off-by: John W. Linville --- net/Kconfig | 3 +++ net/core/Makefile | 2 +- net/core/dev.c | 10 ++++------ net/ieee80211/ieee80211_rx.c | 4 ++-- net/socket.c | 9 +++------ 5 files changed, 13 insertions(+), 15 deletions(-) (limited to 'net') diff --git a/net/Kconfig b/net/Kconfig index bc603d9aea5..d6216888c3a 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -217,6 +217,9 @@ source "net/irda/Kconfig" source "net/bluetooth/Kconfig" source "net/ieee80211/Kconfig" +config WIRELESS_EXT + bool + endif # if NET endmenu # Networking diff --git a/net/core/Makefile b/net/core/Makefile index 630da0f0579..79fe12cced2 100644 --- a/net/core/Makefile +++ b/net/core/Makefile @@ -14,5 +14,5 @@ obj-$(CONFIG_XFRM) += flow.o obj-$(CONFIG_SYSFS) += net-sysfs.o obj-$(CONFIG_NET_DIVERT) += dv.o obj-$(CONFIG_NET_PKTGEN) += pktgen.o -obj-$(CONFIG_NET_RADIO) += wireless.o +obj-$(CONFIG_WIRELESS_EXT) += wireless.o obj-$(CONFIG_NETPOLL) += netpoll.o diff --git a/net/core/dev.c b/net/core/dev.c index fd070a098f2..41ac7a8ddb0 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -110,10 +110,8 @@ #include #include #include -#ifdef CONFIG_NET_RADIO -#include /* Note : will define WIRELESS_EXT */ +#include #include -#endif /* CONFIG_NET_RADIO */ #include /* @@ -2028,7 +2026,7 @@ static struct file_operations softnet_seq_fops = { .release = seq_release, }; -#ifdef WIRELESS_EXT +#ifdef CONFIG_WIRELESS_EXT extern int wireless_proc_init(void); #else #define wireless_proc_init() 0 @@ -2581,7 +2579,7 @@ int dev_ioctl(unsigned int cmd, void __user *arg) ret = -EFAULT; return ret; } -#ifdef WIRELESS_EXT +#ifdef CONFIG_WIRELESS_EXT /* Take care of Wireless Extensions */ if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) { /* If command is `set a parameter', or @@ -2602,7 +2600,7 @@ int dev_ioctl(unsigned int cmd, void __user *arg) ret = -EFAULT; return ret; } -#endif /* WIRELESS_EXT */ +#endif /* CONFIG_WIRELESS_EXT */ return -EINVAL; } } diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c index 6c070bc155e..e2f1553ecb7 100644 --- a/net/ieee80211/ieee80211_rx.c +++ b/net/ieee80211/ieee80211_rx.c @@ -369,8 +369,8 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, /* Put this code here so that we avoid duplicating it in all * Rx paths. - Jean II */ +#ifdef CONFIG_WIRELESS_EXT #ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */ -#ifdef CONFIG_NET_RADIO /* If spy monitoring on */ if (ieee->spy_data.spy_number > 0) { struct iw_quality wstats; @@ -397,8 +397,8 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, /* Update spy records */ wireless_spy_update(ieee->dev, hdr->addr2, &wstats); } -#endif /* CONFIG_NET_RADIO */ #endif /* IW_WIRELESS_SPY */ +#endif /* CONFIG_WIRELESS_EXT */ #ifdef NOT_YET hostap_update_rx_stats(local->ap, hdr, rx_stats); diff --git a/net/socket.c b/net/socket.c index b38a263853c..8aa5f1188e9 100644 --- a/net/socket.c +++ b/net/socket.c @@ -84,10 +84,7 @@ #include #include #include - -#ifdef CONFIG_NET_RADIO -#include /* Note : will define WIRELESS_EXT */ -#endif /* CONFIG_NET_RADIO */ +#include #include #include @@ -840,11 +837,11 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg) if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) { err = dev_ioctl(cmd, argp); } else -#ifdef WIRELESS_EXT +#ifdef CONFIG_WIRELESS_EXT if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) { err = dev_ioctl(cmd, argp); } else -#endif /* WIRELESS_EXT */ +#endif /* CONFIG_WIRELESS_EXT */ switch (cmd) { case FIOSETOWN: case SIOCSPGRP: -- cgit v1.2.3 From 9eafe76b8a5e1420cd6105bc11830914d90bddb4 Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Sun, 22 Jan 2006 13:57:10 +0200 Subject: [PATCH] ieee80211: trivial fix for misplaced ()'s Patch fixes misplaced (). Diffed against wireless-2.6.git Signed-off-by: Denis Vlasenko Signed-off-by: John W. Linville --- net/ieee80211/ieee80211_rx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c index e2f1553ecb7..c032b82eb56 100644 --- a/net/ieee80211/ieee80211_rx.c +++ b/net/ieee80211/ieee80211_rx.c @@ -574,7 +574,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, /* skb: hdr + (possibly fragmented) plaintext payload */ // PR: FIXME: hostap has additional conditions in the "if" below: // ieee->host_decrypt && (fc & IEEE80211_FCTL_PROTECTED) && - if ((frag != 0 || (fc & IEEE80211_FCTL_MOREFRAGS))) { + if ((frag != 0) || (fc & IEEE80211_FCTL_MOREFRAGS)) { int flen; struct sk_buff *frag_skb = ieee80211_frag_cache_get(ieee, hdr); IEEE80211_DEBUG_FRAG("Rx Fragment received (%u)\n", frag); -- cgit v1.2.3 From dd5eeb461ea572f82d34e1f2c4b88037df5afedb Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Mon, 30 Jan 2006 13:12:50 +0100 Subject: [PATCH] ieee80211: common wx auth code This patch creates two functions ieee80211_wx_set_auth and ieee80211_wx_get_auth that can be used by drivers for the wireless extension handlers instead of writing their own, if the implementation should be software only. These patches enable using bcm43xx devices with WPA and this seems (as far as I can tell) to be the only difference between the stock ieee80211 and softmac's ieee80211 left. Signed-Off-By: Johannes Berg Signed-off-by: John W. Linville --- net/ieee80211/ieee80211_wx.c | 89 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) (limited to 'net') diff --git a/net/ieee80211/ieee80211_wx.c b/net/ieee80211/ieee80211_wx.c index 9496918e610..e8c55a4d583 100644 --- a/net/ieee80211/ieee80211_wx.c +++ b/net/ieee80211/ieee80211_wx.c @@ -761,9 +761,98 @@ int ieee80211_wx_get_encodeext(struct ieee80211_device *ieee, return 0; } +int ieee80211_wx_set_auth(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct ieee80211_device *ieee = netdev_priv(dev); + unsigned long flags; + int err = 0; + + spin_lock_irqsave(&ieee->lock, flags); + + switch (wrqu->param.flags & IW_AUTH_INDEX) { + case IW_AUTH_WPA_VERSION: + case IW_AUTH_CIPHER_PAIRWISE: + case IW_AUTH_CIPHER_GROUP: + case IW_AUTH_KEY_MGMT: + /* + * Host AP driver does not use these parameters and allows + * wpa_supplicant to control them internally. + */ + break; + case IW_AUTH_TKIP_COUNTERMEASURES: + break; /* FIXME */ + case IW_AUTH_DROP_UNENCRYPTED: + ieee->drop_unencrypted = !!wrqu->param.value; + break; + case IW_AUTH_80211_AUTH_ALG: + break; /* FIXME */ + case IW_AUTH_WPA_ENABLED: + ieee->privacy_invoked = ieee->wpa_enabled = !!wrqu->param.value; + break; + case IW_AUTH_RX_UNENCRYPTED_EAPOL: + ieee->ieee802_1x = !!wrqu->param.value; + break; + case IW_AUTH_PRIVACY_INVOKED: + ieee->privacy_invoked = !!wrqu->param.value; + break; + default: + err = -EOPNOTSUPP; + break; + } + spin_unlock_irqrestore(&ieee->lock, flags); + return err; +} + +int ieee80211_wx_get_auth(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct ieee80211_device *ieee = netdev_priv(dev); + unsigned long flags; + int err = 0; + + spin_lock_irqsave(&ieee->lock, flags); + + switch (wrqu->param.flags & IW_AUTH_INDEX) { + case IW_AUTH_WPA_VERSION: + case IW_AUTH_CIPHER_PAIRWISE: + case IW_AUTH_CIPHER_GROUP: + case IW_AUTH_KEY_MGMT: + case IW_AUTH_TKIP_COUNTERMEASURES: /* FIXME */ + case IW_AUTH_80211_AUTH_ALG: /* FIXME */ + /* + * Host AP driver does not use these parameters and allows + * wpa_supplicant to control them internally. + */ + err = -EOPNOTSUPP; + break; + case IW_AUTH_DROP_UNENCRYPTED: + wrqu->param.value = ieee->drop_unencrypted; + break; + case IW_AUTH_WPA_ENABLED: + wrqu->param.value = ieee->wpa_enabled; + break; + case IW_AUTH_RX_UNENCRYPTED_EAPOL: + wrqu->param.value = ieee->ieee802_1x; + break; + default: + err = -EOPNOTSUPP; + break; + } + spin_unlock_irqrestore(&ieee->lock, flags); + return err; +} + EXPORT_SYMBOL(ieee80211_wx_set_encodeext); EXPORT_SYMBOL(ieee80211_wx_get_encodeext); EXPORT_SYMBOL(ieee80211_wx_get_scan); EXPORT_SYMBOL(ieee80211_wx_set_encode); EXPORT_SYMBOL(ieee80211_wx_get_encode); + +EXPORT_SYMBOL_GPL(ieee80211_wx_set_auth); +EXPORT_SYMBOL_GPL(ieee80211_wx_get_auth); -- cgit v1.2.3 From 2f633db5e9c57e07a971b65e9a72f090f59fd5f6 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Mon, 30 Jan 2006 23:25:10 -0600 Subject: [PATCH] Add two management functions to ieee80211_rx.c On my system, I get unhandled management functions corresponding to IEEE80211_STYPE_REASSOC_REQ and IEEE80211_STYPE_ASSOC_REQ. The attached patch adds the logic to pass these requests off to a user stack. The patches to implement these requests in softmac have already been sent to Johannes Berg. Signed-Off-By: Larry Finger Signed-off-by: John W. Linville --- net/ieee80211/ieee80211_rx.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'net') diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c index c032b82eb56..fcf4382ef7d 100644 --- a/net/ieee80211/ieee80211_rx.c +++ b/net/ieee80211/ieee80211_rx.c @@ -1607,6 +1607,30 @@ void ieee80211_rx_mgt(struct ieee80211_device *ieee, 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_WARNING("%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_WARNING("%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) -- cgit v1.2.3 From 471680828330e6b2aac295cf7ac9d8e5820df2eb Mon Sep 17 00:00:00 2001 From: Zhu Yi Date: Mon, 13 Feb 2006 13:37:03 +0800 Subject: [PATCH] ieee80211: Use IWEVGENIE to set WPA IE It replaces returning WPA/RSN IEs as custom events with returning them as IWEVGENIE events. I have tested that it returns proper information with both Xsupplicant, and the latest development version of the Linux wireless tools. Signed-off-by: Chris Hessing Signed-off-by: Zhu Yi Signed-off-by: John W. Linville --- net/ieee80211/ieee80211_wx.c | 32 ++++++++++---------------------- 1 file changed, 10 insertions(+), 22 deletions(-) (limited to 'net') diff --git a/net/ieee80211/ieee80211_wx.c b/net/ieee80211/ieee80211_wx.c index e8c55a4d583..af7f9bbfd18 100644 --- a/net/ieee80211/ieee80211_wx.c +++ b/net/ieee80211/ieee80211_wx.c @@ -193,33 +193,21 @@ static char *ipw2100_translate_scan(struct ieee80211_device *ieee, if (iwe.u.data.length) start = iwe_stream_add_point(start, stop, &iwe, custom); + memset(&iwe, 0, sizeof(iwe)); if (network->wpa_ie_len) { - char buf[MAX_WPA_IE_LEN * 2 + 30]; - - u8 *p = buf; - p += sprintf(p, "wpa_ie="); - for (i = 0; i < network->wpa_ie_len; i++) { - p += sprintf(p, "%02x", network->wpa_ie[i]); - } - - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = IWEVCUSTOM; - iwe.u.data.length = strlen(buf); + char buf[MAX_WPA_IE_LEN]; + memcpy(buf, network->wpa_ie, network->wpa_ie_len); + iwe.cmd = IWEVGENIE; + iwe.u.data.length = network->wpa_ie_len; start = iwe_stream_add_point(start, stop, &iwe, buf); } + memset(&iwe, 0, sizeof(iwe)); if (network->rsn_ie_len) { - char buf[MAX_WPA_IE_LEN * 2 + 30]; - - u8 *p = buf; - p += sprintf(p, "rsn_ie="); - for (i = 0; i < network->rsn_ie_len; i++) { - p += sprintf(p, "%02x", network->rsn_ie[i]); - } - - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = IWEVCUSTOM; - iwe.u.data.length = strlen(buf); + char buf[MAX_WPA_IE_LEN]; + memcpy(buf, network->rsn_ie, network->rsn_ie_len); + iwe.cmd = IWEVGENIE; + iwe.u.data.length = network->rsn_ie_len; start = iwe_stream_add_point(start, stop, &iwe, buf); } -- cgit v1.2.3 From b7cffb028abbffff3ba0b87268ecb775ed354049 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 4 Jan 2006 20:58:10 +0100 Subject: [PATCH] ieee80211: fix sparse warning about missing "static" This patch adds a missing "static" on a variable (sparse complaint) Signed-off-by: John W. Linville --- net/ieee80211/ieee80211_module.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/ieee80211/ieee80211_module.c b/net/ieee80211/ieee80211_module.c index 5f67c684afc..2cb84d84f67 100644 --- a/net/ieee80211/ieee80211_module.c +++ b/net/ieee80211/ieee80211_module.c @@ -213,7 +213,7 @@ void free_ieee80211(struct net_device *dev) static int debug = 0; u32 ieee80211_debug_level = 0; -struct proc_dir_entry *ieee80211_proc = NULL; +static struct proc_dir_entry *ieee80211_proc = NULL; static int show_debug_level(char *page, char **start, off_t offset, int count, int *eof, void *data) -- cgit v1.2.3 From 07981aa43f6aec32b875f360755ed3d14f9d5139 Mon Sep 17 00:00:00 2001 From: Pete Zaitcev Date: Sun, 26 Feb 2006 16:29:51 -0800 Subject: [PATCH] ieee80211_geo.c: remove frivolous BUG_ON's I have come to consider BUG_ON generally harmful. The idea of an assert is to prevent a program to execute past a point where its state is known erroneous, thus preventing it from dealing more damage to the data (or hiding the traces of malfunction). The problem is, in kernel this harm has to be balanced against the harm of forced reboot. The last straw was our softmac tree, where "iwlist eth1 scan" causes a lockup. It is absolutely frivolus and provides no advantages a normal assert has to provide. In fact, doing this impedes debugging. Signed-off-by: Pete Zaitcev Signed-off-by: John W. Linville --- net/ieee80211/ieee80211_geo.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'net') diff --git a/net/ieee80211/ieee80211_geo.c b/net/ieee80211/ieee80211_geo.c index 3027153940f..192243ab35e 100644 --- a/net/ieee80211/ieee80211_geo.c +++ b/net/ieee80211/ieee80211_geo.c @@ -50,7 +50,8 @@ int ieee80211_is_valid_channel(struct ieee80211_device *ieee, u8 channel) /* Driver needs to initialize the geography map before using * these helper functions */ - BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0); + if (ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0) + return 0; if (ieee->freq_band & IEEE80211_24GHZ_BAND) for (i = 0; i < ieee->geo.bg_channels; i++) @@ -78,7 +79,8 @@ int ieee80211_channel_to_index(struct ieee80211_device *ieee, u8 channel) /* Driver needs to initialize the geography map before using * these helper functions */ - BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0); + if (ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0) + return -1; if (ieee->freq_band & IEEE80211_24GHZ_BAND) for (i = 0; i < ieee->geo.bg_channels; i++) @@ -99,7 +101,8 @@ u8 ieee80211_freq_to_channel(struct ieee80211_device * ieee, u32 freq) /* Driver needs to initialize the geography map before using * these helper functions */ - BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0); + if (ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0) + return 0; freq /= 100000; -- cgit v1.2.3 From 8f903c708fcc2b579ebf16542bf6109bad593a1d Mon Sep 17 00:00:00 2001 From: Jay Vosburgh Date: Tue, 21 Feb 2006 16:36:44 -0800 Subject: [PATCH] bonding: suppress duplicate packets Originally submitted by Kenzo Iwami; his original description is: The current bonding driver receives duplicate packets when broadcast/ multicast packets are sent by other devices or packets are flooded by the switch. In this patch, new flags are added in priv_flags of net_device structure to let the bonding driver discard duplicate packets in dev.c:skb_bond(). Modified by Jay Vosburgh to change a define name, update some comments, rearrange the new skb_bond() for clarity, clear all bonding priv_flags on slave release, and update the driver version. Signed-off-by: Kenzo Iwami Signed-off-by: Jay Vosburgh Signed-off-by: Jeff Garzik --- net/core/dev.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'net') diff --git a/net/core/dev.c b/net/core/dev.c index 225e38ff57c..ef56c035d44 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1446,8 +1446,29 @@ static inline struct net_device *skb_bond(struct sk_buff *skb) { struct net_device *dev = skb->dev; - if (dev->master) + if (dev->master) { + /* + * On bonding slaves other than the currently active + * slave, suppress duplicates except for 802.3ad + * ETH_P_SLOW and alb non-mcast/bcast. + */ + if (dev->priv_flags & IFF_SLAVE_INACTIVE) { + if (dev->master->priv_flags & IFF_MASTER_ALB) { + if (skb->pkt_type != PACKET_BROADCAST && + skb->pkt_type != PACKET_MULTICAST) + goto keep; + } + + if (dev->master->priv_flags & IFF_MASTER_8023AD && + skb->protocol == __constant_htons(ETH_P_SLOW)) + goto keep; + + kfree_skb(skb); + return NULL; + } +keep: skb->dev = dev->master; + } return dev; } @@ -1591,6 +1612,9 @@ int netif_receive_skb(struct sk_buff *skb) orig_dev = skb_bond(skb); + if (!orig_dev) + return NET_RX_DROP; + __get_cpu_var(netdev_rx_stat).total++; skb->h.raw = skb->nh.raw = skb->data; -- cgit v1.2.3 From f44349f2217d05e4575f24edc3c0e0022f5d448f Mon Sep 17 00:00:00 2001 From: James Ketrenos Date: Wed, 8 Mar 2006 13:14:45 -0600 Subject: [PATCH] ieee80211: Don't update network statistics from off-channel packets. This patch fixes a problem in the ieee80211 probe response and beacon reception code that would use the packet statistics for a network even if they were received on a channel other than that which the network exists on. This causes a problem in overlapping channels where, for example, a strong AP on channel 2 could have its beacons received on channels 1 and 3, but at much lower signal levels. If scanning was done sequentially, this means the beacon received on channel 3 would update the AP's signal level as being much lower than it really is, which subsequently could cause that AP to be passed over and an alternate AP selected. Signed-off-by: James Ketrenos Signed-off-by: John W. Linville --- net/ieee80211/ieee80211_rx.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'net') diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c index 785d5a170a7..a7f2a642a51 100644 --- a/net/ieee80211/ieee80211_rx.c +++ b/net/ieee80211/ieee80211_rx.c @@ -1345,7 +1345,19 @@ static void update_network(struct ieee80211_network *dst, ieee80211_network_reset(dst); dst->ibss_dfs = src->ibss_dfs; - memcpy(&dst->stats, &src->stats, sizeof(struct ieee80211_rx_stats)); + /* 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 " MAC_FMT " info received " + "off channel (%d vs. %d)\n", MAC_ARG(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; -- cgit v1.2.3