[Prism54-devel] ieee80211_input() problems
Sebastien B
sebastien.b at swissinfo.org
Sun Mar 6 14:12:06 UTC 2005
Hello,
I'm in real trouble with that function :(
I have the following code, "frame" is a pointer to data corresponding to the
802.11 frame and "frame_size" is its length in bytes :
if(ic->ic_opmode != IEEE80211_M_STA) {
struct ieee80211_frame_min *wh = (struct ieee80211_frame_min
*)frame; //data_head;
ni = ieee80211_find_node(ic, wh->i_addr2);
if(ni == NULL) ni = ieee80211_ref_node(ic->ic_bss);
} else ni = ieee80211_ref_node(ic->ic_bss);
/* Put the data into an mbuf and pass it to the upper layers */
if(frame_size > MCLBYTES) {
p54u_err("Frame too large for mbuf cluster");
return;
}
MGETHDR(buf, M_DONTWAIT, MT_DATA);
if(buf == NULL) {
p54u_err("mbuf allocation failed");
return;
}
if(frame_size > MHLEN) {
p54u_dbg("allocating mbuf cluster");
MCLGET(buf, M_DONTWAIT);
if((buf->m_flags & M_EXT) == 0) {
p54u_err("mbuf cluster allocation failed");
m_freem(buf);
return;
}
}
buffer = mtod(buf, char *);
memcpy(buffer, frame, frame_size);
buf->m_pkthdr.rcvif = &sc->sc_if;
buf->m_pkthdr.len = buf->m_len = frame_size;
ieee80211_input(&sc->sc_if, buf, ni, data_head->signal_strength,
le32toh(data_head->timestamp));
/*
* Reclaim node reference.
*/
if (ni == ic->ic_bss) ieee80211_unref_node(&ni); else
ieee80211_free_node(ic, ni);
With this, the kernel panics every time a frame is received :(
The kernel messages are :
Fatal trap 12: page fault while in kernel mode
fault virtual address = 0x23
fault code = supervisor read, page not present
instruction pointer = 0x8:0xc07c3d82
stack pointer = 0x10:0xd4cf9c20
frame pointer = 0x10:0xd4cf9c60
code segment = base 0x0, limit 0xfffff, type 0x1b
= DPL 0, pres 1, def32 1, gran 1
processor eflags = interrupt enabled, resume, IOPL = 0
current process = 493 (swi7: int_ack++)
It suggests that software is attempting to read from an invalid memory
location.
- I tried commenting out ieee80211_input. No more crashes, but the function's
useless...
- In case there was not enough space in mbuf (thus ieee80211_input() would try
to access memory which doesn't belong to us), I tried reading frame_size
bytes from the adress pointed to by "buffer". No crash. Moreover, the mbuf
data seems consistent, I can see the ESSID in it (anyway I think that
ieee80211_input() shouldn't crash because of an unconsistent frame ;
otherwise someone could crash all computers around by sending forged 802.11
frames...)
- I tried with and without referencing ic->ic_bss. No effect.
- Making frame_size deliberately too small before the call to
ieee80211_input() makes the kernel not crash. So ieee80211_input() seems to
ignore the packet in case it's too small, it seems to read correctly the size
field (I tried 10 bytes).
- The data_head->signal_strength and data_head->timestamp dereferencings don't
cause the kernel panic, and they return the correct data.
- For an IBSS beacon packet, frame_size is 67 and magic1 is 77. Is that
correct ?
I hope someone can help, I just can't figure out what's going wrong after
hours of debugging, and constantly rebooting is really tedious.
Thanks,
Sebastien
More information about the Prism54-devel
mailing list