Re: 2.6.18-mm1 -- ieee80211: Info elem: parse failed: info_element->len + 2 > left : info_element->len+2=28 left=9, id=221.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Miles Lane wrote:
> It occurs to me that these messages occured while I was connected to a
> public WIFI AP at the airport in Phoenix.  It may be that the network
> configuration or my distance from the AP had a part to play in the
> messages being triggered.  If so, I may have trouble reproducing the
> problem.  I'll be interested to hear from some of the IEEE80211
> developers on what these messages indicate.
> ieee80211: Info elem: parse failed: info_element->len + 2 > left :
> info_element->len+2=28 left=9, id=221.
> ieee80211: Info elem: parse failed: info_element->len + 2 > left :
> info_element->len+2=28 left=9, id=221.
> ieee80211: Info elem: parse failed: info_element->len + 2 > left :
> info_element->len+2=28 left=9, id=221.

Without the actual full data frame it is difficult to determine the root
cause (faulty AP, wireless attack, or bug in ieee80211_rx.c).  If you
happen to find yourself in a situation where this occurs repeatedly, try
performing a packet capture w/ ethereal or similar to grab the packet.  
If ethereal can parse the frame correctly but you still see the message
from ieee80211, chances are its a bug in ieee80211_parse_info_param.

If you don't have ethereal, you can use the attached untested (beyond
build) patch against ieee80211_rx.c to dump the frame to the kernel log
(borrows the printk_buf function from ipw2200.c).   From that raw frame
dump we should be able to figure out if its a bug
ieee80211_parse_info_param or a bogus over the air packet.

James
[DEBUG] Add hex dump of Rx'd 802.11 frames if they fail the IE parse tests

This patch just adds a call to do a data hex dump to the kernel log of 
Rx'd data frames when parsing fails.  The code is (more or less) 
borrowed from ipw2200.c.

Signed-off-by: James Ketrenos <[email protected]>

diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c
index 72d4d4e..ccde64b 100644
--- a/net/ieee80211/ieee80211_rx.c
+++ b/net/ieee80211/ieee80211_rx.c
@@ -1049,6 +1049,59 @@ static const char *get_info_element_stri
 }
 #endif
 
+
+static int snprint_line(char *buf, size_t count,
+			const u8 * data, u32 len, u32 ofs)
+{
+	int out, i, j, l;
+	char c;
+
+	out = snprintf(buf, count, "%08X", ofs);
+
+	for (l = 0, i = 0; i < 2; i++) {
+		out += snprintf(buf + out, count - out, " ");
+		for (j = 0; j < 8 && l < len; j++, l++)
+			out += snprintf(buf + out, count - out, "%02X ",
+					data[(i * 8 + j)]);
+		for (; j < 8; j++)
+			out += snprintf(buf + out, count - out, "   ");
+	}
+
+	out += snprintf(buf + out, count - out, " ");
+	for (l = 0, i = 0; i < 2; i++) {
+		out += snprintf(buf + out, count - out, " ");
+		for (j = 0; j < 8 && l < len; j++, l++) {
+			c = data[(i * 8 + j)];
+			if (!isascii(c) || !isprint(c))
+				c = '.';
+
+			out += snprintf(buf + out, count - out, "%c", c);
+		}
+
+		for (; j < 8; j++)
+			out += snprintf(buf + out, count - out, " ");
+	}
+
+	return out;
+}
+
+static void printk_buf(int level, const u8 * data, u32 len)
+{
+	char line[81];
+	u32 ofs = 0;
+	if (!(ieee80211_debug_level & level))
+		return;
+
+	while (len) {
+		snprint_line(line, sizeof(line), &data[ofs],
+			     min(len, 16U), ofs);
+		printk(KERN_DEBUG "%s\n", line);
+		ofs += 16;
+		len -= min(len, 16U);
+	}
+}
+
+
 static int ieee80211_parse_info_param(struct ieee80211_info_element
 				      *info_element, u16 length,
 				      struct ieee80211_network *network)
@@ -1304,9 +1357,12 @@ static int ieee80211_handle_assoc_resp(s
 	network->rsn_ie_len = 0;
 
 	if (ieee80211_parse_info_param
-	    (frame->info_element, stats->len - sizeof(*frame), network))
+	    (frame->info_element, stats->len - sizeof(*frame), network)) {
+		printk_buf(IEEE80211_DL_MGMT, (u8*)frame,
+			   stats->len);
 		return 1;
-
+	}
+	
 	network->mode = 0;
 	if (stats->freq == IEEE80211_52GHZ_BAND)
 		network->mode = IEEE_A;
@@ -1367,8 +1423,11 @@ static int ieee80211_network_init(struct
 	network->rsn_ie_len = 0;
 
 	if (ieee80211_parse_info_param
-	    (beacon->info_element, stats->len - sizeof(*beacon), network))
+	    (beacon->info_element, stats->len - sizeof(*beacon), network)) {
+		printk_buf(IEEE80211_DL_MGMT, (u8*)beacon,
+			   stats->len);
 		return 1;
+	}
 
 	network->mode = 0;
 	if (stats->freq == IEEE80211_52GHZ_BAND)

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux