[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