linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH RFC] mac80211: Filter scan results
@ 2009-02-04 15:08 Samuel Ortiz
  2009-02-04 15:10 ` Johannes Berg
                   ` (2 more replies)
  0 siblings, 3 replies; 24+ messages in thread
From: Samuel Ortiz @ 2009-02-04 15:08 UTC (permalink / raw)
  To: John Linville; +Cc: Reinette Chatre, linux-wireless

From: Samuel Ortiz <samuel.ortiz@intel.com>

In very dense environment, the scan result buffer can get really large, mostly
due to the addition of proprietary IEs. iwlist fails, typically warning about:
"print_scanning_info: Allocation failed". wpa_supplicant fails as well, after
reallocating the scan result buffer several times, up to 132 Kbytes:
	[snip]
	Scan results did not fit - trying larger buffer (131072 bytes)
	ioctl[SIOCGIWSCAN]: Argument list too long

By adding a mac80211 module parameter, we can filter the scan results and keep
only the ones userspace currently worries about, i.e. WPA1, WPA2, WMM and WPS.

To activate this feature, 1 has to be written to
/sys/module/mac80211/parameters/ieee80211_scan_ie_filter

Signed-off-by: Samuel Ortiz <samuel.ortiz@intel.com>
---
 net/mac80211/ieee80211_i.h |    1 
 net/mac80211/scan.c        |   65 ++++++++++++++++++++++++++++++---------------
 net/mac80211/util.c        |   40 +++++++++++++++++++++++++++
 3 files changed, 85 insertions(+), 21 deletions(-)

Index: wireless-testing/net/mac80211/scan.c
===================================================================
--- wireless-testing.orig/net/mac80211/scan.c	2009-01-28 11:37:55.000000000 +0100
+++ wireless-testing/net/mac80211/scan.c	2009-01-28 17:32:48.000000000 +0100
@@ -31,6 +31,11 @@
 #define IEEE80211_CHANNEL_TIME (HZ / 33)
 #define IEEE80211_PASSIVE_CHANNEL_TIME (HZ / 5)
 
+static int ieee80211_scan_ie_filter;
+module_param(ieee80211_scan_ie_filter, bool, 0644);
+MODULE_PARM_DESC(ieee80211_scan_ie_filter,
+		 "Filter IEs from scan results");
+
 void ieee80211_rx_bss_list_init(struct ieee80211_local *local)
 {
 	spin_lock_init(&local->bss_lock);
@@ -725,33 +730,51 @@ static void ieee80211_scan_add_ies(struc
 	if (bss == NULL || bss->ies == NULL)
 		return;
 
-	/*
-	 * If needed, fragment the IEs buffer (at IE boundaries) into short
-	 * enough fragments to fit into IW_GENERIC_IE_MAX octet messages.
-	 */
 	pos = bss->ies;
 	end = pos + bss->ies_len;
 
-	while (end - pos > IW_GENERIC_IE_MAX) {
-		next = pos + 2 + pos[1];
-		while (next + 2 + next[1] - pos < IW_GENERIC_IE_MAX)
-			next = next + 2 + next[1];
+	if (ieee80211_scan_ie_filter) {
+		while (pos - end) {
+			next = pos + 2 + pos[1];
+			if (ieee80211_filter_ie(pos)) {
+				memset(&iwe, 0, sizeof(iwe));
+				iwe.cmd = IWEVGENIE;
+				iwe.u.data.length = next - pos;
+				*current_ev =
+					iwe_stream_add_point(info, *current_ev,
+							     end_buf, &iwe,
+							     pos);
+			}
+			pos = next;
+		}
+	} else {
+		/*
+		 * If needed, fragment the IEs buffer (at IE boundaries) into
+		 * short enough fragments to fit into IW_GENERIC_IE_MAX octet
+		 * messages.
+		 */
+
+		while (end - pos > IW_GENERIC_IE_MAX) {
+			next = pos + 2 + pos[1];
+			while (next + 2 + next[1] - pos < IW_GENERIC_IE_MAX)
+				next = next + 2 + next[1];
 
-		memset(&iwe, 0, sizeof(iwe));
-		iwe.cmd = IWEVGENIE;
-		iwe.u.data.length = next - pos;
-		*current_ev = iwe_stream_add_point(info, *current_ev,
-						   end_buf, &iwe, pos);
+			memset(&iwe, 0, sizeof(iwe));
+			iwe.cmd = IWEVGENIE;
+			iwe.u.data.length = next - pos;
+			*current_ev = iwe_stream_add_point(info, *current_ev,
+							   end_buf, &iwe, pos);
 
-		pos = next;
-	}
+			pos = next;
+		}
 
-	if (end > pos) {
-		memset(&iwe, 0, sizeof(iwe));
-		iwe.cmd = IWEVGENIE;
-		iwe.u.data.length = end - pos;
-		*current_ev = iwe_stream_add_point(info, *current_ev,
-						   end_buf, &iwe, pos);
+		if (end > pos) {
+			memset(&iwe, 0, sizeof(iwe));
+			iwe.cmd = IWEVGENIE;
+			iwe.u.data.length = end - pos;
+			*current_ev = iwe_stream_add_point(info, *current_ev,
+							   end_buf, &iwe, pos);
+		}
 	}
 }
 
Index: wireless-testing/net/mac80211/util.c
===================================================================
--- wireless-testing.orig/net/mac80211/util.c	2009-01-28 11:37:41.000000000 +0100
+++ wireless-testing/net/mac80211/util.c	2009-01-28 15:57:03.000000000 +0100
@@ -675,6 +675,46 @@ void ieee802_11_parse_elems(u8 *start, s
 	}
 }
 
+/*
+ * ieee80211_filter_ie() tries to keep only the relevant IEs for
+ * userspace (mostly hostap code).
+ */
+int ieee80211_filter_ie(u8 *ie)
+{
+	u8 id, ie_len, *pos;
+	u8 microsoft_oui[4] = {0x00, 0x50, 0xf2};
+	u8 wpa2_oui[3] = {0x00, 0x0f, 0xac};
+
+	pos = ie;
+	id = *pos++;
+	ie_len = *pos++;
+
+	switch (id) {
+	case WLAN_EID_RSN:
+		/* WPA2 */
+		if (ie_len >= 3 &&
+		    !memcmp(pos, wpa2_oui, 3))
+			return 1;
+
+		return 0;
+
+	case WLAN_EID_VENDOR_SPECIFIC:
+		/* We're trying to catch WPA1, WMM and WPS IEs. */
+		if (ie_len >= 3 &&
+		    !memcmp(pos, microsoft_oui, 3)) {
+			if ((pos[3] == 1) || /* WPA1 */
+			    (pos[3] == 2) || /* WMM */
+			    (pos[3] == 4))   /* WPS */
+				return 1;
+		}
+
+		return 0;
+
+	default:
+		return 0;
+	}
+}
+
 void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata)
 {
 	struct ieee80211_local *local = sdata->local;
Index: wireless-testing/net/mac80211/ieee80211_i.h
===================================================================
--- wireless-testing.orig/net/mac80211/ieee80211_i.h	2009-01-28 11:37:41.000000000 +0100
+++ wireless-testing/net/mac80211/ieee80211_i.h	2009-01-28 13:49:17.000000000 +0100
@@ -1028,6 +1028,7 @@ void ieee80211_tx_skb(struct ieee80211_s
 		      int encrypt);
 void ieee802_11_parse_elems(u8 *start, size_t len,
 			    struct ieee802_11_elems *elems);
+int ieee80211_filter_ie(u8 *ie);
 int ieee80211_set_freq(struct ieee80211_sub_if_data *sdata, int freq);
 u32 ieee80211_mandatory_rates(struct ieee80211_local *local,
 			      enum ieee80211_band band);
-- 
Intel Open Source Technology Centre
http://oss.intel.com/

^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2009-02-05 22:43 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-02-04 15:08 [PATCH RFC] mac80211: Filter scan results Samuel Ortiz
2009-02-04 15:10 ` Johannes Berg
2009-02-04 23:18   ` Marcel Holtmann
2009-02-04 23:20     ` Dan Williams
2009-02-04 23:29       ` Marcel Holtmann
2009-02-04 23:31     ` Johannes Berg
2009-02-04 16:09 ` Dan Williams
2009-02-04 23:19   ` Marcel Holtmann
2009-02-04 23:22     ` Dan Williams
2009-02-04 23:23 ` Dan Williams
2009-02-04 23:35   ` Johannes Berg
2009-02-05  8:44     ` Jouni Malinen
2009-02-05  9:52       ` Jouni Malinen
2009-02-05 11:44         ` Tomas Winkler
2009-02-05 12:12           ` Jouni Malinen
2009-02-05 13:00             ` Tomas Winkler
2009-02-05 14:57               ` Dan Williams
2009-02-05 15:36                 ` Tomas Winkler
2009-02-05 11:10       ` Jouni Malinen
2009-02-05 11:55         ` Johannes Berg
2009-02-05 12:07           ` Jouni Malinen
2009-02-05 12:10             ` Johannes Berg
2009-02-05 12:26               ` Jouni Malinen
2009-02-05 22:42                 ` Johannes Berg

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).