* [PATCH] mac80211: make ieee802_11_parse_elems return void @ 2007-10-17 2:38 John W. Linville 2007-10-17 3:17 ` Michael Wu 2007-10-17 8:15 ` Johannes Berg 0 siblings, 2 replies; 6+ messages in thread From: John W. Linville @ 2007-10-17 2:38 UTC (permalink / raw) To: linux-wireless; +Cc: John W. Linville Some APs send management frames with junk padding after the last IE. We already account for a similar problem with some Apple Airport devices, but at least one device is known to send more than a single extra byte. The device in question is the Draytek Vigor2900: http://www.draytek.com.au/products/Vigor2900.php The junk in question looks like an IE that runs off the end of the frame. This cause us to return ParseFailed. Since the frame in question is an association response, this causes us to fail to associate with this AP. The return code from ieee802_11_parse_elems is superfluous. All callers still check for the presence of the specific IEs that interest them anyway. So, remove the return code so the parse never "fails". Signed-off-by: John W. Linville <linville@tuxdriver.com> --- net/mac80211/ieee80211_sta.c | 53 ++++++++---------------------------------- 1 files changed, 10 insertions(+), 43 deletions(-) diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c index db81aef..7f873b3 100644 --- a/net/mac80211/ieee80211_sta.c +++ b/net/mac80211/ieee80211_sta.c @@ -108,14 +108,11 @@ struct ieee802_11_elems { u8 wmm_param_len; }; -enum ParseRes { ParseOK = 0, ParseUnknown = 1, ParseFailed = -1 }; - -static enum ParseRes ieee802_11_parse_elems(u8 *start, size_t len, - struct ieee802_11_elems *elems) +static void ieee802_11_parse_elems(u8 *start, size_t len, + struct ieee802_11_elems *elems) { size_t left = len; u8 *pos = start; - int unknown = 0; memset(elems, 0, sizeof(*elems)); @@ -126,15 +123,8 @@ static enum ParseRes ieee802_11_parse_elems(u8 *start, size_t len, elen = *pos++; left -= 2; - if (elen > left) { -#if 0 - if (net_ratelimit()) - printk(KERN_DEBUG "IEEE 802.11 element parse " - "failed (id=%d elen=%d left=%d)\n", - id, elen, left); -#endif - return ParseFailed; - } + if (elen > left) + return; switch (id) { case WLAN_EID_SSID: @@ -201,12 +191,6 @@ static enum ParseRes ieee802_11_parse_elems(u8 *start, size_t len, elems->ext_supp_rates_len = elen; break; default: -#if 0 - printk(KERN_DEBUG "IEEE 802.11 element parse ignored " - "unknown element (id=%d elen=%d)\n", - id, elen); -#endif - unknown++; break; } @@ -214,10 +198,7 @@ static enum ParseRes ieee802_11_parse_elems(u8 *start, size_t len, pos += elen; } - /* Do not trigger error if left == 1 as Apple Airport base stations - * send AssocResps that are one spurious byte too long. */ - - return unknown ? ParseUnknown : ParseOK; + return; } @@ -931,12 +912,7 @@ static void ieee80211_auth_challenge(struct net_device *dev, printk(KERN_DEBUG "%s: replying to auth challenge\n", dev->name); pos = mgmt->u.auth.variable; - if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems) - == ParseFailed) { - printk(KERN_DEBUG "%s: failed to parse Auth(challenge)\n", - dev->name); - return; - } + ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems); if (!elems.challenge) { printk(KERN_DEBUG "%s: no challenge IE in shared key auth " "frame\n", dev->name); @@ -1230,12 +1206,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev, aid &= ~(BIT(15) | BIT(14)); pos = mgmt->u.assoc_resp.variable; - if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems) - == ParseFailed) { - printk(KERN_DEBUG "%s: failed to parse AssocResp\n", - dev->name); - return; - } + ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems); if (!elems.supp_rates) { printk(KERN_DEBUG "%s: no SuppRates element in AssocResp\n", @@ -1459,7 +1430,7 @@ static void ieee80211_rx_bss_info(struct net_device *dev, struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct ieee802_11_elems elems; size_t baselen; - int channel, invalid = 0, clen; + int channel, clen; struct ieee80211_sta_bss *bss; struct sta_info *sta; struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); @@ -1505,9 +1476,7 @@ static void ieee80211_rx_bss_info(struct net_device *dev, #endif /* CONFIG_MAC80211_IBSS_DEBUG */ } - if (ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, - &elems) == ParseFailed) - invalid = 1; + ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); if (sdata->type == IEEE80211_IF_TYPE_IBSS && elems.supp_rates && memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0 && @@ -1724,9 +1693,7 @@ static void ieee80211_rx_mgmt_beacon(struct net_device *dev, if (baselen > len) return; - if (ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, - &elems) == ParseFailed) - return; + ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); if (elems.erp_info && elems.erp_info_len >= 1) ieee80211_handle_erp_ie(dev, elems.erp_info[0]); -- 1.5.2.4 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH] mac80211: make ieee802_11_parse_elems return void 2007-10-17 2:38 [PATCH] mac80211: make ieee802_11_parse_elems return void John W. Linville @ 2007-10-17 3:17 ` Michael Wu 2007-10-17 8:15 ` Johannes Berg 1 sibling, 0 replies; 6+ messages in thread From: Michael Wu @ 2007-10-17 3:17 UTC (permalink / raw) To: John W. Linville; +Cc: linux-wireless [-- Attachment #1: Type: text/plain, Size: 951 bytes --] On Tuesday 16 October 2007 22:38:43 John W. Linville wrote: > Some APs send management frames with junk padding after the last IE. > We already account for a similar problem with some Apple Airport > devices, but at least one device is known to send more than a single > extra byte. The device in question is the Draytek Vigor2900: > > http://www.draytek.com.au/products/Vigor2900.php > > The junk in question looks like an IE that runs off the end of the > frame. This cause us to return ParseFailed. Since the frame in > question is an association response, this causes us to fail to associate > with this AP. > > The return code from ieee802_11_parse_elems is superfluous. > All callers still check for the presence of the specific IEs that > interest them anyway. So, remove the return code so the parse never > "fails". > > Signed-off-by: John W. Linville <linville@tuxdriver.com> Acked-by: Michael Wu <flamingice@sourmilk.net> -Michael Wu [-- Attachment #2: This is a digitally signed message part. --] [-- Type: application/pgp-signature, Size: 194 bytes --] ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] mac80211: make ieee802_11_parse_elems return void 2007-10-17 2:38 [PATCH] mac80211: make ieee802_11_parse_elems return void John W. Linville 2007-10-17 3:17 ` Michael Wu @ 2007-10-17 8:15 ` Johannes Berg 2007-10-17 14:04 ` John W. Linville 1 sibling, 1 reply; 6+ messages in thread From: Johannes Berg @ 2007-10-17 8:15 UTC (permalink / raw) To: John W. Linville; +Cc: linux-wireless [-- Attachment #1: Type: text/plain, Size: 308 bytes --] On Tue, 2007-10-16 at 22:38 -0400, John W. Linville wrote: Looks good to me, but > - /* Do not trigger error if left == 1 as Apple Airport base stations > - * send AssocResps that are one spurious byte too long. */ > - > - return unknown ? ParseUnknown : ParseOK; > + return; huh? johannes [-- Attachment #2: This is a digitally signed message part --] [-- Type: application/pgp-signature, Size: 828 bytes --] ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] mac80211: make ieee802_11_parse_elems return void 2007-10-17 8:15 ` Johannes Berg @ 2007-10-17 14:04 ` John W. Linville 2007-10-18 11:56 ` Johannes Berg 0 siblings, 1 reply; 6+ messages in thread From: John W. Linville @ 2007-10-17 14:04 UTC (permalink / raw) To: Johannes Berg; +Cc: linux-wireless On Wed, Oct 17, 2007 at 10:15:11AM +0200, Johannes Berg wrote: > On Tue, 2007-10-16 at 22:38 -0400, John W. Linville wrote: > > Looks good to me, but > > > - /* Do not trigger error if left == 1 as Apple Airport base stations > > - * send AssocResps that are one spurious byte too long. */ > > - > > - return unknown ? ParseUnknown : ParseOK; > > + return; > > huh? You don't like the bare return at the end? Or are you questioning something else? John -- John W. Linville linville@tuxdriver.com ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] mac80211: make ieee802_11_parse_elems return void 2007-10-17 14:04 ` John W. Linville @ 2007-10-18 11:56 ` Johannes Berg 0 siblings, 0 replies; 6+ messages in thread From: Johannes Berg @ 2007-10-18 11:56 UTC (permalink / raw) To: John W. Linville; +Cc: linux-wireless [-- Attachment #1: Type: text/plain, Size: 636 bytes --] On Wed, 2007-10-17 at 10:04 -0400, John W. Linville wrote: > On Wed, Oct 17, 2007 at 10:15:11AM +0200, Johannes Berg wrote: > > On Tue, 2007-10-16 at 22:38 -0400, John W. Linville wrote: > > > > Looks good to me, but > > > > > - /* Do not trigger error if left == 1 as Apple Airport base stations > > > - * send AssocResps that are one spurious byte too long. */ > > > - > > > - return unknown ? ParseUnknown : ParseOK; > > > + return; > > > > huh? > > You don't like the bare return at the end? Or are you questioning > something else? Bare return at the end of a void functions seems.. pointless. johannes [-- Attachment #2: This is a digitally signed message part --] [-- Type: application/pgp-signature, Size: 828 bytes --] ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH] Add get_unaligned to ieee80211_get_radiotap_len @ 2007-10-26 21:04 John W. Linville 2007-10-26 21:04 ` [PATCH] Improve sanity checks on injected packets John W. Linville 0 siblings, 1 reply; 6+ messages in thread From: John W. Linville @ 2007-10-26 21:04 UTC (permalink / raw) To: stable; +Cc: linux-wireless, warmcat, John W. Linville From: warmcat <andy@warmcat.com> ieee80211_get_radiotap_len() tries to dereference radiotap length without taking care that it is completely unaligned and get_unaligned() is required. Signed-off-by: Andy Green <andy@warmcat.com> Signed-off-by: John W. Linville <linville@tuxdriver.com> --- net/mac80211/ieee80211.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c index ff2172f..9b9d716 100644 --- a/net/mac80211/ieee80211.c +++ b/net/mac80211/ieee80211.c @@ -350,7 +350,7 @@ static int ieee80211_get_radiotap_len(struct sk_buff *skb) struct ieee80211_radiotap_header *hdr = (struct ieee80211_radiotap_header *) skb->data; - return le16_to_cpu(hdr->it_len); + return le16_to_cpu(get_unaligned(&hdr->it_len)); } #ifdef CONFIG_MAC80211_LOWTX_FRAME_DUMP -- 1.5.2.4 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH] Improve sanity checks on injected packets 2007-10-26 21:04 [PATCH] Add get_unaligned to ieee80211_get_radiotap_len John W. Linville @ 2007-10-26 21:04 ` John W. Linville 2007-10-26 21:04 ` [PATCH] mac80211: filter locally-originated multicast frames John W. Linville 0 siblings, 1 reply; 6+ messages in thread From: John W. Linville @ 2007-10-26 21:04 UTC (permalink / raw) To: stable; +Cc: linux-wireless, warmcat, John W. Linville From: warmcat <andy@warmcat.com> Michael Wu noticed that the skb length checking is not taken care of enough when a packet is presented on the Monitor interface for injection. This patch improves the sanity checking and removes fake offsets placed into the skb network and transport header. Signed-off-by: Andy Green <andy@warmcat.com> Signed-off-by: John W. Linville <linville@tuxdriver.com> --- net/mac80211/ieee80211.c | 48 ++++++++++++++++++++++++++------------------- 1 files changed, 28 insertions(+), 20 deletions(-) diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c index 9b9d716..ad73a40 100644 --- a/net/mac80211/ieee80211.c +++ b/net/mac80211/ieee80211.c @@ -1680,46 +1680,54 @@ int ieee80211_monitor_start_xmit(struct sk_buff *skb, struct ieee80211_tx_packet_data *pkt_data; struct ieee80211_radiotap_header *prthdr = (struct ieee80211_radiotap_header *)skb->data; - u16 len; + u16 len_rthdr; - /* - * there must be a radiotap header at the - * start in this case - */ - if (unlikely(prthdr->it_version)) { - /* only version 0 is supported */ - dev_kfree_skb(skb); - return NETDEV_TX_OK; - } + /* check for not even having the fixed radiotap header part */ + if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header))) + goto fail; /* too short to be possibly valid */ + + /* is it a header version we can trust to find length from? */ + if (unlikely(prthdr->it_version)) + goto fail; /* only version 0 is supported */ + + /* then there must be a radiotap header with a length we can use */ + len_rthdr = ieee80211_get_radiotap_len(skb); + + /* does the skb contain enough to deliver on the alleged length? */ + if (unlikely(skb->len < len_rthdr)) + goto fail; /* skb too short for claimed rt header extent */ skb->dev = local->mdev; pkt_data = (struct ieee80211_tx_packet_data *)skb->cb; memset(pkt_data, 0, sizeof(*pkt_data)); + /* needed because we set skb device to master */ pkt_data->ifindex = dev->ifindex; + pkt_data->mgmt_iface = 0; pkt_data->do_not_encrypt = 1; - /* above needed because we set skb device to master */ - /* * fix up the pointers accounting for the radiotap * header still being in there. We are being given * a precooked IEEE80211 header so no need for * normal processing */ - len = le16_to_cpu(get_unaligned(&prthdr->it_len)); - skb_set_mac_header(skb, len); - skb_set_network_header(skb, len + sizeof(struct ieee80211_hdr)); - skb_set_transport_header(skb, len + sizeof(struct ieee80211_hdr)); - + skb_set_mac_header(skb, len_rthdr); /* - * pass the radiotap header up to - * the next stage intact + * these are just fixed to the end of the rt area since we + * don't have any better information and at this point, nobody cares */ - dev_queue_xmit(skb); + skb_set_network_header(skb, len_rthdr); + skb_set_transport_header(skb, len_rthdr); + /* pass the radiotap header up to the next stage intact */ + dev_queue_xmit(skb); return NETDEV_TX_OK; + +fail: + dev_kfree_skb(skb); + return NETDEV_TX_OK; /* meaning, we dealt with the skb */ } -- 1.5.2.4 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH] mac80211: filter locally-originated multicast frames 2007-10-26 21:04 ` [PATCH] Improve sanity checks on injected packets John W. Linville @ 2007-10-26 21:04 ` John W. Linville 2007-10-26 21:04 ` [PATCH] libertas: fix endianness breakage John W. Linville 0 siblings, 1 reply; 6+ messages in thread From: John W. Linville @ 2007-10-26 21:04 UTC (permalink / raw) To: stable; +Cc: linux-wireless, John W. Linville From: John W. Linville <linville@tuxdriver.com> In STA mode, the AP will echo our traffic. This includes multicast traffic. Receiving these frames confuses some protocols and applications, notably IPv6 Duplicate Address Detection. Signed-off-by: John W. Linville <linville@tuxdriver.com> --- net/mac80211/ieee80211.c | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c index ad73a40..9e0da6e 100644 --- a/net/mac80211/ieee80211.c +++ b/net/mac80211/ieee80211.c @@ -2844,9 +2844,10 @@ ieee80211_rx_h_data(struct ieee80211_txrx_data *rx) memcpy(dst, hdr->addr1, ETH_ALEN); memcpy(src, hdr->addr3, ETH_ALEN); - if (sdata->type != IEEE80211_IF_TYPE_STA) { + if (sdata->type != IEEE80211_IF_TYPE_STA || + (is_multicast_ether_addr(dst) && + !compare_ether_addr(src, dev->dev_addr))) return TXRX_DROP; - } break; case 0: /* DA SA BSSID */ -- 1.5.2.4 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH] libertas: fix endianness breakage 2007-10-26 21:04 ` [PATCH] mac80211: filter locally-originated multicast frames John W. Linville @ 2007-10-26 21:04 ` John W. Linville 2007-10-26 21:04 ` [PATCH] libertas: more " John W. Linville 0 siblings, 1 reply; 6+ messages in thread From: John W. Linville @ 2007-10-26 21:04 UTC (permalink / raw) To: stable; +Cc: linux-wireless, Al Viro, Al Viro, John W. Linville From: Al Viro <viro@ftp.linux.org.uk> wep->keytype[] is u8 Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: John W. Linville <linville@tuxdriver.com> --- drivers/net/wireless/libertas/cmd.c | 6 ++---- 1 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index 4a8f5dc..86fff8d 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c @@ -185,14 +185,12 @@ static int wlan_cmd_802_11_set_wep(wlan_private * priv, switch (pkey->len) { case KEY_LEN_WEP_40: - wep->keytype[i] = - cpu_to_le16(cmd_type_wep_40_bit); + wep->keytype[i] = cmd_type_wep_40_bit; memmove(&wep->keymaterial[i], pkey->key, pkey->len); break; case KEY_LEN_WEP_104: - wep->keytype[i] = - cpu_to_le16(cmd_type_wep_104_bit); + wep->keytype[i] = cmd_type_wep_104_bit; memmove(&wep->keymaterial[i], pkey->key, pkey->len); break; -- 1.5.2.4 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH] libertas: more endianness breakage 2007-10-26 21:04 ` [PATCH] libertas: fix endianness breakage John W. Linville @ 2007-10-26 21:04 ` John W. Linville 2007-10-26 21:04 ` [PATCH] ieee80211: fix TKIP QoS bug John W. Linville 0 siblings, 1 reply; 6+ messages in thread From: John W. Linville @ 2007-10-26 21:04 UTC (permalink / raw) To: stable; +Cc: linux-wireless, Al Viro, Al Viro, John W. Linville From: Al Viro <viro@ftp.linux.org.uk> domain->header.len is le16 and has just been assigned cpu_to_le16(arithmetical expression). And all fields of adapter->logmsg are __le32; not a single 16-bit among them... That's incremental to the previous one Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: John W. Linville <linville@tuxdriver.com> --- drivers/net/wireless/libertas/11d.c | 2 +- drivers/net/wireless/libertas/wext.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/libertas/11d.c b/drivers/net/wireless/libertas/11d.c index 4cf0ff7..0560270 100644 --- a/drivers/net/wireless/libertas/11d.c +++ b/drivers/net/wireless/libertas/11d.c @@ -562,7 +562,7 @@ int libertas_cmd_802_11d_domain_info(wlan_private * priv, nr_subband * sizeof(struct ieeetypes_subbandset)); cmd->size = cpu_to_le16(sizeof(pdomaininfo->action) + - domain->header.len + + le16_to_cpu(domain->header.len) + sizeof(struct mrvlietypesheader) + S_DS_GEN); } else { diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c index 2fcc3bf..873c405 100644 --- a/drivers/net/wireless/libertas/wext.c +++ b/drivers/net/wireless/libertas/wext.c @@ -973,7 +973,7 @@ static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev) /* Quality by TX errors */ priv->wstats.discard.retries = priv->stats.tx_errors; - tx_retries = le16_to_cpu(adapter->logmsg.retry); + tx_retries = le32_to_cpu(adapter->logmsg.retry); if (tx_retries > 75) tx_qual = (90 - tx_retries) * POOR / 15; @@ -989,10 +989,10 @@ static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev) (PERFECT - VERY_GOOD) / 50 + VERY_GOOD; quality = min(quality, tx_qual); - priv->wstats.discard.code = le16_to_cpu(adapter->logmsg.wepundecryptable); - priv->wstats.discard.fragment = le16_to_cpu(adapter->logmsg.rxfrag); + priv->wstats.discard.code = le32_to_cpu(adapter->logmsg.wepundecryptable); + priv->wstats.discard.fragment = le32_to_cpu(adapter->logmsg.rxfrag); priv->wstats.discard.retries = tx_retries; - priv->wstats.discard.misc = le16_to_cpu(adapter->logmsg.ackfailure); + priv->wstats.discard.misc = le32_to_cpu(adapter->logmsg.ackfailure); /* Calculate quality */ priv->wstats.qual.qual = max(quality, (u32)100); -- 1.5.2.4 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH] ieee80211: fix TKIP QoS bug 2007-10-26 21:04 ` [PATCH] libertas: more " John W. Linville @ 2007-10-26 21:04 ` John W. Linville 2007-10-26 21:04 ` [PATCH] mac80211: reorder association debug output John W. Linville 0 siblings, 1 reply; 6+ messages in thread From: John W. Linville @ 2007-10-26 21:04 UTC (permalink / raw) To: stable; +Cc: linux-wireless, Johannes Berg, John W. Linville From: Johannes Berg <johannes@sipsolutions.net> The commit 65b6a277 titled "ieee80211: Fix header->qos_ctl endian issue" *introduced* an endianness bug. Partially revert it. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com> --- net/ieee80211/ieee80211_crypt_tkip.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/net/ieee80211/ieee80211_crypt_tkip.c b/net/ieee80211/ieee80211_crypt_tkip.c index 5a48d8e..7f11dd9 100644 --- a/net/ieee80211/ieee80211_crypt_tkip.c +++ b/net/ieee80211/ieee80211_crypt_tkip.c @@ -584,7 +584,7 @@ static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr) if (stype & IEEE80211_STYPE_QOS_DATA) { const struct ieee80211_hdr_3addrqos *qoshdr = (struct ieee80211_hdr_3addrqos *)skb->data; - hdr[12] = qoshdr->qos_ctl & cpu_to_le16(IEEE80211_QCTL_TID); + hdr[12] = le16_to_cpu(qoshdr->qos_ctl) & IEEE80211_QCTL_TID; } else hdr[12] = 0; /* priority */ -- 1.5.2.4 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH] mac80211: reorder association debug output 2007-10-26 21:04 ` [PATCH] ieee80211: fix TKIP QoS bug John W. Linville @ 2007-10-26 21:04 ` John W. Linville 2007-10-26 21:04 ` [PATCH] mac80211: store channel info in sta_bss_list John W. Linville 0 siblings, 1 reply; 6+ messages in thread From: John W. Linville @ 2007-10-26 21:04 UTC (permalink / raw) To: stable; +Cc: linux-wireless, Johannes Berg, John W. Linville From: Johannes Berg <johannes@sipsolutions.net> There's no reason to warn about an invalid AID field when the association was denied. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Acked-by: Michael Wu <flamingice@sourmilk.net> Signed-off-by: John W. Linville <linville@tuxdriver.com> --- net/mac80211/ieee80211_sta.c | 11 ++++++----- 1 files changed, 6 insertions(+), 5 deletions(-) diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c index 0d99b68..ae74c79 100644 --- a/net/mac80211/ieee80211_sta.c +++ b/net/mac80211/ieee80211_sta.c @@ -1174,15 +1174,11 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev, capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info); status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code); aid = le16_to_cpu(mgmt->u.assoc_resp.aid); - if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14))) - printk(KERN_DEBUG "%s: invalid aid value %d; bits 15:14 not " - "set\n", dev->name, aid); - aid &= ~(BIT(15) | BIT(14)); printk(KERN_DEBUG "%s: RX %sssocResp from " MAC_FMT " (capab=0x%x " "status=%d aid=%d)\n", dev->name, reassoc ? "Rea" : "A", MAC_ARG(mgmt->sa), - capab_info, status_code, aid); + capab_info, status_code, aid & ~(BIT(15) | BIT(14))); if (status_code != WLAN_STATUS_SUCCESS) { printk(KERN_DEBUG "%s: AP denied association (code=%d)\n", @@ -1192,6 +1188,11 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev, return; } + if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14))) + printk(KERN_DEBUG "%s: invalid aid value %d; bits 15:14 not " + "set\n", dev->name, aid); + aid &= ~(BIT(15) | BIT(14)); + pos = mgmt->u.assoc_resp.variable; if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems) == ParseFailed) { -- 1.5.2.4 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH] mac80211: store channel info in sta_bss_list 2007-10-26 21:04 ` [PATCH] mac80211: reorder association debug output John W. Linville @ 2007-10-26 21:04 ` John W. Linville 2007-10-26 21:04 ` [PATCH] mac80211: store SSID " John W. Linville 0 siblings, 1 reply; 6+ messages in thread From: John W. Linville @ 2007-10-26 21:04 UTC (permalink / raw) To: stable; +Cc: linux-wireless, John W. Linville From: John W. Linville <linville@tuxdriver.com> Some AP equipment "in the wild" uses the same BSSID on multiple channels (particularly "a" vs. "b/g"). This patch changes the key of sta_bss_list to include both the BSSID and the channel so as to prevent a BSSID on one channel from eclipsing the same BSSID on another channel. Signed-off-by: John W. Linville <linville@tuxdriver.com> --- net/mac80211/ieee80211_sta.c | 35 ++++++++++++++++++++--------------- 1 files changed, 20 insertions(+), 15 deletions(-) diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c index ae74c79..1991daa 100644 --- a/net/mac80211/ieee80211_sta.c +++ b/net/mac80211/ieee80211_sta.c @@ -61,7 +61,7 @@ static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst, u8 *ssid, size_t ssid_len); static struct ieee80211_sta_bss * -ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid); +ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel); static void ieee80211_rx_bss_put(struct net_device *dev, struct ieee80211_sta_bss *bss); static int ieee80211_sta_find_ibss(struct net_device *dev, @@ -387,6 +387,7 @@ static void ieee80211_set_associated(struct net_device *dev, struct ieee80211_if_sta *ifsta, int assoc) { union iwreq_data wrqu; + struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); if (ifsta->associated == assoc) @@ -401,7 +402,8 @@ static void ieee80211_set_associated(struct net_device *dev, if (sdata->type != IEEE80211_IF_TYPE_STA) return; - bss = ieee80211_rx_bss_get(dev, ifsta->bssid); + bss = ieee80211_rx_bss_get(dev, ifsta->bssid, + local->hw.conf.channel); if (bss) { if (bss->has_erp_value) ieee80211_handle_erp_ie(dev, bss->erp_value); @@ -543,7 +545,7 @@ static void ieee80211_send_assoc(struct net_device *dev, capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME | WLAN_CAPABILITY_SHORT_PREAMBLE; } - bss = ieee80211_rx_bss_get(dev, ifsta->bssid); + bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel); if (bss) { if (bss->capability & WLAN_CAPABILITY_PRIVACY) capab |= WLAN_CAPABILITY_PRIVACY; @@ -695,6 +697,7 @@ static void ieee80211_send_disassoc(struct net_device *dev, static int ieee80211_privacy_mismatch(struct net_device *dev, struct ieee80211_if_sta *ifsta) { + struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct ieee80211_sta_bss *bss; int res = 0; @@ -702,7 +705,7 @@ static int ieee80211_privacy_mismatch(struct net_device *dev, ifsta->key_mgmt != IEEE80211_KEY_MGMT_NONE) return 0; - bss = ieee80211_rx_bss_get(dev, ifsta->bssid); + bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel); if (!bss) return 0; @@ -1211,7 +1214,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev, * update our stored copy */ if (elems.erp_info && elems.erp_info_len >= 1) { struct ieee80211_sta_bss *bss - = ieee80211_rx_bss_get(dev, ifsta->bssid); + = ieee80211_rx_bss_get(dev, ifsta->bssid, + local->hw.conf.channel); if (bss) { bss->erp_value = elems.erp_info[0]; bss->has_erp_value = 1; @@ -1241,7 +1245,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev, " AP\n", dev->name); return; } - bss = ieee80211_rx_bss_get(dev, ifsta->bssid); + bss = ieee80211_rx_bss_get(dev, ifsta->bssid, + local->hw.conf.channel); if (bss) { sta->last_rssi = bss->rssi; sta->last_signal = bss->signal; @@ -1322,7 +1327,7 @@ static void __ieee80211_rx_bss_hash_del(struct net_device *dev, static struct ieee80211_sta_bss * -ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid) +ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid, int channel) { struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct ieee80211_sta_bss *bss; @@ -1333,6 +1338,7 @@ ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid) atomic_inc(&bss->users); atomic_inc(&bss->users); memcpy(bss->bssid, bssid, ETH_ALEN); + bss->channel = channel; spin_lock_bh(&local->sta_bss_lock); /* TODO: order by RSSI? */ @@ -1344,7 +1350,7 @@ ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid) static struct ieee80211_sta_bss * -ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid) +ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel) { struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct ieee80211_sta_bss *bss; @@ -1352,7 +1358,8 @@ ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid) spin_lock_bh(&local->sta_bss_lock); bss = local->sta_bss_hash[STA_HASH(bssid)]; while (bss) { - if (memcmp(bss->bssid, bssid, ETH_ALEN) == 0) { + if (memcmp(bss->bssid, bssid, ETH_ALEN) == 0 && + bss->channel == channel) { atomic_inc(&bss->users); break; } @@ -1520,9 +1527,9 @@ static void ieee80211_rx_bss_info(struct net_device *dev, else channel = rx_status->channel; - bss = ieee80211_rx_bss_get(dev, mgmt->bssid); + bss = ieee80211_rx_bss_get(dev, mgmt->bssid, channel); if (!bss) { - bss = ieee80211_rx_bss_add(dev, mgmt->bssid); + bss = ieee80211_rx_bss_add(dev, mgmt->bssid, channel); if (!bss) return; } else { @@ -1622,7 +1629,6 @@ static void ieee80211_rx_bss_info(struct net_device *dev, bss->hw_mode = rx_status->phymode; - bss->channel = channel; bss->freq = rx_status->freq; if (channel != rx_status->channel && (bss->hw_mode == MODE_IEEE80211G || @@ -2355,7 +2361,7 @@ static int ieee80211_sta_create_ibss(struct net_device *dev, printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID " MAC_FMT "\n", dev->name, MAC_ARG(bssid)); - bss = ieee80211_rx_bss_add(dev, bssid); + bss = ieee80211_rx_bss_add(dev, bssid, local->hw.conf.channel); if (!bss) return -ENOMEM; @@ -2366,7 +2372,6 @@ static int ieee80211_sta_create_ibss(struct net_device *dev, local->hw.conf.beacon_int = 100; bss->beacon_int = local->hw.conf.beacon_int; bss->hw_mode = local->hw.conf.phymode; - bss->channel = local->hw.conf.channel; bss->freq = local->hw.conf.freq; bss->last_update = jiffies; bss->capability = WLAN_CAPABILITY_IBSS; @@ -2426,7 +2431,7 @@ static int ieee80211_sta_find_ibss(struct net_device *dev, MAC_FMT "\n", MAC_ARG(bssid), MAC_ARG(ifsta->bssid)); #endif /* CONFIG_MAC80211_IBSS_DEBUG */ if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0 && - (bss = ieee80211_rx_bss_get(dev, bssid))) { + (bss = ieee80211_rx_bss_get(dev, bssid, local->hw.conf.channel))) { printk(KERN_DEBUG "%s: Selected IBSS BSSID " MAC_FMT " based on configured SSID\n", dev->name, MAC_ARG(bssid)); -- 1.5.2.4 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH] mac80211: store SSID in sta_bss_list 2007-10-26 21:04 ` [PATCH] mac80211: store channel info in sta_bss_list John W. Linville @ 2007-10-26 21:04 ` John W. Linville 2007-10-26 21:04 ` [PATCH] mac80211: honor IW_SCAN_THIS_ESSID in siwscan ioctl John W. Linville 0 siblings, 1 reply; 6+ messages in thread From: John W. Linville @ 2007-10-26 21:04 UTC (permalink / raw) To: stable; +Cc: linux-wireless, John W. Linville From: John W. Linville <linville@tuxdriver.com> Some AP equipment "in the wild" services multiple SSIDs using the same BSSID. This patch changes the key of sta_bss_list to include the SSID as well as the BSSID and the channel so as to prevent one SSID from eclipsing another SSID with the same BSSID. Signed-off-by: John W. Linville <linville@tuxdriver.com> --- net/mac80211/ieee80211_sta.c | 54 +++++++++++++++++++++++++---------------- 1 files changed, 33 insertions(+), 21 deletions(-) diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c index 1991daa..e78b51e 100644 --- a/net/mac80211/ieee80211_sta.c +++ b/net/mac80211/ieee80211_sta.c @@ -12,7 +12,6 @@ */ /* TODO: - * BSS table: use <BSSID,SSID> as the key to support multi-SSID APs * order BSS list by RSSI(?) ("quality of AP") * scan result table filtering (by capability (privacy, IBSS/BSS, WPA/RSN IE, * SSID) @@ -61,7 +60,8 @@ static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst, u8 *ssid, size_t ssid_len); static struct ieee80211_sta_bss * -ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel); +ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel, + u8 *ssid, u8 ssid_len); static void ieee80211_rx_bss_put(struct net_device *dev, struct ieee80211_sta_bss *bss); static int ieee80211_sta_find_ibss(struct net_device *dev, @@ -403,7 +403,8 @@ static void ieee80211_set_associated(struct net_device *dev, return; bss = ieee80211_rx_bss_get(dev, ifsta->bssid, - local->hw.conf.channel); + local->hw.conf.channel, + ifsta->ssid, ifsta->ssid_len); if (bss) { if (bss->has_erp_value) ieee80211_handle_erp_ie(dev, bss->erp_value); @@ -545,7 +546,8 @@ static void ieee80211_send_assoc(struct net_device *dev, capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME | WLAN_CAPABILITY_SHORT_PREAMBLE; } - bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel); + bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel, + ifsta->ssid, ifsta->ssid_len); if (bss) { if (bss->capability & WLAN_CAPABILITY_PRIVACY) capab |= WLAN_CAPABILITY_PRIVACY; @@ -705,7 +707,8 @@ static int ieee80211_privacy_mismatch(struct net_device *dev, ifsta->key_mgmt != IEEE80211_KEY_MGMT_NONE) return 0; - bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel); + bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel, + ifsta->ssid, ifsta->ssid_len); if (!bss) return 0; @@ -1215,7 +1218,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev, if (elems.erp_info && elems.erp_info_len >= 1) { struct ieee80211_sta_bss *bss = ieee80211_rx_bss_get(dev, ifsta->bssid, - local->hw.conf.channel); + local->hw.conf.channel, + ifsta->ssid, ifsta->ssid_len); if (bss) { bss->erp_value = elems.erp_info[0]; bss->has_erp_value = 1; @@ -1246,7 +1250,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev, return; } bss = ieee80211_rx_bss_get(dev, ifsta->bssid, - local->hw.conf.channel); + local->hw.conf.channel, + ifsta->ssid, ifsta->ssid_len); if (bss) { sta->last_rssi = bss->rssi; sta->last_signal = bss->signal; @@ -1327,7 +1332,8 @@ static void __ieee80211_rx_bss_hash_del(struct net_device *dev, static struct ieee80211_sta_bss * -ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid, int channel) +ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid, int channel, + u8 *ssid, u8 ssid_len) { struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct ieee80211_sta_bss *bss; @@ -1339,6 +1345,10 @@ ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid, int channel) atomic_inc(&bss->users); memcpy(bss->bssid, bssid, ETH_ALEN); bss->channel = channel; + if (ssid && ssid_len <= IEEE80211_MAX_SSID_LEN) { + memcpy(bss->ssid, ssid, ssid_len); + bss->ssid_len = ssid_len; + } spin_lock_bh(&local->sta_bss_lock); /* TODO: order by RSSI? */ @@ -1350,7 +1360,8 @@ ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid, int channel) static struct ieee80211_sta_bss * -ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel) +ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel, + u8 *ssid, u8 ssid_len) { struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct ieee80211_sta_bss *bss; @@ -1358,8 +1369,10 @@ ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel) spin_lock_bh(&local->sta_bss_lock); bss = local->sta_bss_hash[STA_HASH(bssid)]; while (bss) { - if (memcmp(bss->bssid, bssid, ETH_ALEN) == 0 && - bss->channel == channel) { + if (!memcmp(bss->bssid, bssid, ETH_ALEN) && + bss->channel == channel && + bss->ssid_len == ssid_len && + (ssid_len == 0 || !memcmp(bss->ssid, ssid, ssid_len))) { atomic_inc(&bss->users); break; } @@ -1527,9 +1540,11 @@ static void ieee80211_rx_bss_info(struct net_device *dev, else channel = rx_status->channel; - bss = ieee80211_rx_bss_get(dev, mgmt->bssid, channel); + bss = ieee80211_rx_bss_get(dev, mgmt->bssid, channel, + elems.ssid, elems.ssid_len); if (!bss) { - bss = ieee80211_rx_bss_add(dev, mgmt->bssid, channel); + bss = ieee80211_rx_bss_add(dev, mgmt->bssid, channel, + elems.ssid, elems.ssid_len); if (!bss) return; } else { @@ -1555,10 +1570,6 @@ static void ieee80211_rx_bss_info(struct net_device *dev, bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int); bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info); - if (elems.ssid && elems.ssid_len <= IEEE80211_MAX_SSID_LEN) { - memcpy(bss->ssid, elems.ssid, elems.ssid_len); - bss->ssid_len = elems.ssid_len; - } bss->supp_rates_len = 0; if (elems.supp_rates) { @@ -2339,7 +2350,7 @@ static int ieee80211_sta_create_ibss(struct net_device *dev, { struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct ieee80211_sta_bss *bss; - struct ieee80211_sub_if_data *sdata; + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct ieee80211_hw_mode *mode; u8 bssid[ETH_ALEN], *pos; int i; @@ -2361,11 +2372,11 @@ static int ieee80211_sta_create_ibss(struct net_device *dev, printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID " MAC_FMT "\n", dev->name, MAC_ARG(bssid)); - bss = ieee80211_rx_bss_add(dev, bssid, local->hw.conf.channel); + bss = ieee80211_rx_bss_add(dev, bssid, local->hw.conf.channel, + sdata->u.sta.ssid, sdata->u.sta.ssid_len); if (!bss) return -ENOMEM; - sdata = IEEE80211_DEV_TO_SUB_IF(dev); mode = local->oper_hw_mode; if (local->hw.conf.beacon_int == 0) @@ -2431,7 +2442,8 @@ static int ieee80211_sta_find_ibss(struct net_device *dev, MAC_FMT "\n", MAC_ARG(bssid), MAC_ARG(ifsta->bssid)); #endif /* CONFIG_MAC80211_IBSS_DEBUG */ if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0 && - (bss = ieee80211_rx_bss_get(dev, bssid, local->hw.conf.channel))) { + (bss = ieee80211_rx_bss_get(dev, bssid, local->hw.conf.channel, + ifsta->ssid, ifsta->ssid_len))) { printk(KERN_DEBUG "%s: Selected IBSS BSSID " MAC_FMT " based on configured SSID\n", dev->name, MAC_ARG(bssid)); -- 1.5.2.4 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH] mac80211: honor IW_SCAN_THIS_ESSID in siwscan ioctl 2007-10-26 21:04 ` [PATCH] mac80211: store SSID " John W. Linville @ 2007-10-26 21:04 ` John W. Linville 2007-10-26 21:04 ` [PATCH] mac80211: only honor IW_SCAN_THIS_ESSID in STA, IBSS, and AP modes John W. Linville 0 siblings, 1 reply; 6+ messages in thread From: John W. Linville @ 2007-10-26 21:04 UTC (permalink / raw) To: stable; +Cc: linux-wireless, Bill Moss, Abhijeet Kolekar, John W. Linville From: Bill Moss <bmoss@clemson.edu> This patch fixes the problem of associating with wpa_secured hidden AP. Please try out. The original author of this patch is Bill Moss <bmoss@clemson.edu> Signed-off-by: Abhijeet Kolekar <abhijeet.kolekar@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com> --- net/mac80211/ieee80211_ioctl.c | 40 ++++++++++++++++++++++++---------------- 1 files changed, 24 insertions(+), 16 deletions(-) diff --git a/net/mac80211/ieee80211_ioctl.c b/net/mac80211/ieee80211_ioctl.c index e7904db..5bd103a 100644 --- a/net/mac80211/ieee80211_ioctl.c +++ b/net/mac80211/ieee80211_ioctl.c @@ -687,32 +687,40 @@ static int ieee80211_ioctl_giwap(struct net_device *dev, static int ieee80211_ioctl_siwscan(struct net_device *dev, struct iw_request_info *info, - struct iw_point *data, char *extra) + union iwreq_data *wrqu, char *extra) { struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + struct iw_scan_req *req = NULL; u8 *ssid = NULL; size_t ssid_len = 0; if (!netif_running(dev)) return -ENETDOWN; - switch (sdata->type) { - case IEEE80211_IF_TYPE_STA: - case IEEE80211_IF_TYPE_IBSS: - if (local->scan_flags & IEEE80211_SCAN_MATCH_SSID) { - ssid = sdata->u.sta.ssid; - ssid_len = sdata->u.sta.ssid_len; - } - break; - case IEEE80211_IF_TYPE_AP: - if (local->scan_flags & IEEE80211_SCAN_MATCH_SSID) { - ssid = sdata->u.ap.ssid; - ssid_len = sdata->u.ap.ssid_len; + if (wrqu->data.length == sizeof(struct iw_scan_req) && + wrqu->data.flags & IW_SCAN_THIS_ESSID) { + req = (struct iw_scan_req *)extra; + ssid = req->essid; + ssid_len = req->essid_len; + } else { + switch (sdata->type) { + case IEEE80211_IF_TYPE_STA: + case IEEE80211_IF_TYPE_IBSS: + if (local->scan_flags & IEEE80211_SCAN_MATCH_SSID) { + ssid = sdata->u.sta.ssid; + ssid_len = sdata->u.sta.ssid_len; + } + break; + case IEEE80211_IF_TYPE_AP: + if (local->scan_flags & IEEE80211_SCAN_MATCH_SSID) { + ssid = sdata->u.ap.ssid; + ssid_len = sdata->u.ap.ssid_len; + } + break; + default: + return -EOPNOTSUPP; } - break; - default: - return -EOPNOTSUPP; } return ieee80211_sta_req_scan(dev, ssid, ssid_len); -- 1.5.2.4 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH] mac80211: only honor IW_SCAN_THIS_ESSID in STA, IBSS, and AP modes 2007-10-26 21:04 ` [PATCH] mac80211: honor IW_SCAN_THIS_ESSID in siwscan ioctl John W. Linville @ 2007-10-26 21:04 ` John W. Linville 2007-10-26 21:04 ` [PATCH] mac80211: make ieee802_11_parse_elems return void John W. Linville 0 siblings, 1 reply; 6+ messages in thread From: John W. Linville @ 2007-10-26 21:04 UTC (permalink / raw) To: stable; +Cc: linux-wireless, John W. Linville From: John W. Linville <linville@tuxdriver.com> The previous IW_SCAN_THIS_ESSID patch left a hole allowing scan requests on interfaces in inappropriate modes. Signed-off-by: John W. Linville <linville@tuxdriver.com> --- net/mac80211/ieee80211_ioctl.c | 37 +++++++++++++++++++------------------ 1 files changed, 19 insertions(+), 18 deletions(-) diff --git a/net/mac80211/ieee80211_ioctl.c b/net/mac80211/ieee80211_ioctl.c index 5bd103a..7b5b801 100644 --- a/net/mac80211/ieee80211_ioctl.c +++ b/net/mac80211/ieee80211_ioctl.c @@ -698,29 +698,30 @@ static int ieee80211_ioctl_siwscan(struct net_device *dev, if (!netif_running(dev)) return -ENETDOWN; + switch (sdata->type) { + case IEEE80211_IF_TYPE_STA: + case IEEE80211_IF_TYPE_IBSS: + if (local->scan_flags & IEEE80211_SCAN_MATCH_SSID) { + ssid = sdata->u.sta.ssid; + ssid_len = sdata->u.sta.ssid_len; + } + break; + case IEEE80211_IF_TYPE_AP: + if (local->scan_flags & IEEE80211_SCAN_MATCH_SSID) { + ssid = sdata->u.ap.ssid; + ssid_len = sdata->u.ap.ssid_len; + } + break; + default: + return -EOPNOTSUPP; + } + + /* if SSID was specified explicitly then use that */ if (wrqu->data.length == sizeof(struct iw_scan_req) && wrqu->data.flags & IW_SCAN_THIS_ESSID) { req = (struct iw_scan_req *)extra; ssid = req->essid; ssid_len = req->essid_len; - } else { - switch (sdata->type) { - case IEEE80211_IF_TYPE_STA: - case IEEE80211_IF_TYPE_IBSS: - if (local->scan_flags & IEEE80211_SCAN_MATCH_SSID) { - ssid = sdata->u.sta.ssid; - ssid_len = sdata->u.sta.ssid_len; - } - break; - case IEEE80211_IF_TYPE_AP: - if (local->scan_flags & IEEE80211_SCAN_MATCH_SSID) { - ssid = sdata->u.ap.ssid; - ssid_len = sdata->u.ap.ssid_len; - } - break; - default: - return -EOPNOTSUPP; - } } return ieee80211_sta_req_scan(dev, ssid, ssid_len); -- 1.5.2.4 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH] mac80211: make ieee802_11_parse_elems return void 2007-10-26 21:04 ` [PATCH] mac80211: only honor IW_SCAN_THIS_ESSID in STA, IBSS, and AP modes John W. Linville @ 2007-10-26 21:04 ` John W. Linville 0 siblings, 0 replies; 6+ messages in thread From: John W. Linville @ 2007-10-26 21:04 UTC (permalink / raw) To: stable; +Cc: linux-wireless, John W. Linville From: John W. Linville <linville@tuxdriver.com> Some APs send management frames with junk padding after the last IE. We already account for a similar problem with some Apple Airport devices, but at least one device is known to send more than a single extra byte. The device in question is the Draytek Vigor2900: http://www.draytek.com.au/products/Vigor2900.php The junk in question looks like an IE that runs off the end of the frame. This cause us to return ParseFailed. Since the frame in question is an association response, this causes us to fail to associate with this AP. The return code from ieee802_11_parse_elems is superfluous. All callers still check for the presence of the specific IEs that interest them anyway. So, remove the return code so the parse never "fails". Acked-by: Michael Wu <flamingice@sourmilk.net> Signed-off-by: John W. Linville <linville@tuxdriver.com> --- net/mac80211/ieee80211_sta.c | 56 ++++++----------------------------------- 1 files changed, 9 insertions(+), 47 deletions(-) diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c index e78b51e..73d39e1 100644 --- a/net/mac80211/ieee80211_sta.c +++ b/net/mac80211/ieee80211_sta.c @@ -108,15 +108,11 @@ struct ieee802_11_elems { u8 wmm_param_len; }; -typedef enum { ParseOK = 0, ParseUnknown = 1, ParseFailed = -1 } ParseRes; - - -static ParseRes ieee802_11_parse_elems(u8 *start, size_t len, - struct ieee802_11_elems *elems) +static void ieee802_11_parse_elems(u8 *start, size_t len, + struct ieee802_11_elems *elems) { size_t left = len; u8 *pos = start; - int unknown = 0; memset(elems, 0, sizeof(*elems)); @@ -127,15 +123,8 @@ static ParseRes ieee802_11_parse_elems(u8 *start, size_t len, elen = *pos++; left -= 2; - if (elen > left) { -#if 0 - if (net_ratelimit()) - printk(KERN_DEBUG "IEEE 802.11 element parse " - "failed (id=%d elen=%d left=%d)\n", - id, elen, left); -#endif - return ParseFailed; - } + if (elen > left) + return; switch (id) { case WLAN_EID_SSID: @@ -202,28 +191,15 @@ static ParseRes ieee802_11_parse_elems(u8 *start, size_t len, elems->ext_supp_rates_len = elen; break; default: -#if 0 - printk(KERN_DEBUG "IEEE 802.11 element parse ignored " - "unknown element (id=%d elen=%d)\n", - id, elen); -#endif - unknown++; break; } left -= elen; pos += elen; } - - /* Do not trigger error if left == 1 as Apple Airport base stations - * send AssocResps that are one spurious byte too long. */ - - return unknown ? ParseUnknown : ParseOK; } - - static int ecw2cw(int ecw) { int cw = 1; @@ -907,12 +883,7 @@ static void ieee80211_auth_challenge(struct net_device *dev, printk(KERN_DEBUG "%s: replying to auth challenge\n", dev->name); pos = mgmt->u.auth.variable; - if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems) - == ParseFailed) { - printk(KERN_DEBUG "%s: failed to parse Auth(challenge)\n", - dev->name); - return; - } + ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems); if (!elems.challenge) { printk(KERN_DEBUG "%s: no challenge IE in shared key auth " "frame\n", dev->name); @@ -1200,12 +1171,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev, aid &= ~(BIT(15) | BIT(14)); pos = mgmt->u.assoc_resp.variable; - if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems) - == ParseFailed) { - printk(KERN_DEBUG "%s: failed to parse AssocResp\n", - dev->name); - return; - } + ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems); if (!elems.supp_rates) { printk(KERN_DEBUG "%s: no SuppRates element in AssocResp\n", @@ -1434,7 +1400,7 @@ static void ieee80211_rx_bss_info(struct net_device *dev, struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct ieee802_11_elems elems; size_t baselen; - int channel, invalid = 0, clen; + int channel, clen; struct ieee80211_sta_bss *bss; struct sta_info *sta; struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); @@ -1478,9 +1444,7 @@ static void ieee80211_rx_bss_info(struct net_device *dev, #endif /* CONFIG_MAC80211_IBSS_DEBUG */ } - if (ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, - &elems) == ParseFailed) - invalid = 1; + ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); if (sdata->type == IEEE80211_IF_TYPE_IBSS && elems.supp_rates && memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0 && @@ -1699,9 +1663,7 @@ static void ieee80211_rx_mgmt_beacon(struct net_device *dev, if (baselen > len) return; - if (ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, - &elems) == ParseFailed) - return; + ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); if (elems.erp_info && elems.erp_info_len >= 1) ieee80211_handle_erp_ie(dev, elems.erp_info[0]); -- 1.5.2.4 ^ permalink raw reply related [flat|nested] 6+ messages in thread
end of thread, other threads:[~2007-10-26 21:07 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2007-10-17 2:38 [PATCH] mac80211: make ieee802_11_parse_elems return void John W. Linville 2007-10-17 3:17 ` Michael Wu 2007-10-17 8:15 ` Johannes Berg 2007-10-17 14:04 ` John W. Linville 2007-10-18 11:56 ` Johannes Berg -- strict thread matches above, loose matches on Subject: below -- 2007-10-26 21:04 [PATCH] Add get_unaligned to ieee80211_get_radiotap_len John W. Linville 2007-10-26 21:04 ` [PATCH] Improve sanity checks on injected packets John W. Linville 2007-10-26 21:04 ` [PATCH] mac80211: filter locally-originated multicast frames John W. Linville 2007-10-26 21:04 ` [PATCH] libertas: fix endianness breakage John W. Linville 2007-10-26 21:04 ` [PATCH] libertas: more " John W. Linville 2007-10-26 21:04 ` [PATCH] ieee80211: fix TKIP QoS bug John W. Linville 2007-10-26 21:04 ` [PATCH] mac80211: reorder association debug output John W. Linville 2007-10-26 21:04 ` [PATCH] mac80211: store channel info in sta_bss_list John W. Linville 2007-10-26 21:04 ` [PATCH] mac80211: store SSID " John W. Linville 2007-10-26 21:04 ` [PATCH] mac80211: honor IW_SCAN_THIS_ESSID in siwscan ioctl John W. Linville 2007-10-26 21:04 ` [PATCH] mac80211: only honor IW_SCAN_THIS_ESSID in STA, IBSS, and AP modes John W. Linville 2007-10-26 21:04 ` [PATCH] mac80211: make ieee802_11_parse_elems return void John W. Linville
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).