Repair adhoc mode.

1 Complete initialization of "faked up" ieee80211_nodes,
          whose capabilities and other fields are wrong, when we
          first receive a beacon or probe response from the
          corresponding neighbor.  This entails factoring
          ieee80211_init_neighbor out of ieee80211_add_neighbor.

        2 In adhoc mode, ic->ic_bss is present in the neighbors
          table, ic->ic_sta, and it is not necessarily the wrong
          node on which to mark statistics for a rx'd packet.  Do
          not reject ic->ic_bss and fake-up a new node without
          comparing its MAC address with the address of the sender
          in the rx'd packet.  This fixes a memory leak.
This commit is contained in:
dyoung 2005-11-20 10:04:21 +00:00
parent f8251d6325
commit 461cd4dbb5
3 changed files with 52 additions and 30 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: ieee80211_input.c,v 1.49 2005/11/19 21:09:17 he Exp $ */
/* $NetBSD: ieee80211_input.c,v 1.50 2005/11/20 10:04:21 dyoung Exp $ */
/*-
* Copyright (c) 2001 Atsushi Onoe
* Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
@ -36,7 +36,7 @@
__FBSDID("$FreeBSD: src/sys/net80211/ieee80211_input.c,v 1.81 2005/08/10 16:22:29 sam Exp $");
#endif
#ifdef __NetBSD__
__KERNEL_RCSID(0, "$NetBSD: ieee80211_input.c,v 1.49 2005/11/19 21:09:17 he Exp $");
__KERNEL_RCSID(0, "$NetBSD: ieee80211_input.c,v 1.50 2005/11/20 10:04:21 dyoung Exp $");
#endif
#include "opt_inet.h"
@ -262,7 +262,8 @@ ieee80211_input(struct ieee80211com *ic, struct mbuf *m,
* exist. This should probably done after an ACL check.
*/
if (ni == ic->ic_bss &&
ic->ic_opmode != IEEE80211_M_HOSTAP) {
ic->ic_opmode != IEEE80211_M_HOSTAP &&
!IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) {
/*
* Fake up a node for this newly
* discovered member of the IBSS.
@ -2035,6 +2036,12 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
* Create a new entry in the neighbor table.
*/
ni = ieee80211_add_neighbor(ic, wh, &scan);
} else if (ni->ni_capinfo == 0) {
/*
* Initialize a node that was "faked
* up." This updates the TSF, too.
*/
ieee80211_init_neighbor(ic, ni, wh, &scan, 0);
} else {
/*
* Record tsf for potential resync.
@ -2096,7 +2103,11 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
}
if (ni == ic->ic_bss) {
if (ic->ic_opmode == IEEE80211_M_IBSS) {
if (ic->ic_opmode != IEEE80211_M_IBSS)
ni = ieee80211_tmp_node(ic, wh->i_addr2);
else if (IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr))
;
else {
/*
* XXX Cannot tell if the sender is operating
* in ibss mode. But we need a new node to
@ -2105,8 +2116,7 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
*/
ni = ieee80211_fakeup_adhoc_node(&ic->ic_sta,
wh->i_addr2);
} else
ni = ieee80211_tmp_node(ic, wh->i_addr2);
}
if (ni == NULL)
return;
allocbs = 1;

View File

@ -1,4 +1,4 @@
/* $NetBSD: ieee80211_node.c,v 1.45 2005/11/18 16:40:09 skrll Exp $ */
/* $NetBSD: ieee80211_node.c,v 1.46 2005/11/20 10:04:21 dyoung Exp $ */
/*-
* Copyright (c) 2001 Atsushi Onoe
* Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
@ -36,7 +36,7 @@
__FBSDID("$FreeBSD: src/sys/net80211/ieee80211_node.c,v 1.65 2005/08/13 17:50:21 sam Exp $");
#endif
#ifdef __NetBSD__
__KERNEL_RCSID(0, "$NetBSD: ieee80211_node.c,v 1.45 2005/11/18 16:40:09 skrll Exp $");
__KERNEL_RCSID(0, "$NetBSD: ieee80211_node.c,v 1.46 2005/11/20 10:04:21 dyoung Exp $");
#endif
#include "opt_inet.h"
@ -1259,6 +1259,35 @@ ieee80211_add_scan(struct ieee80211com *ic,
#undef ISPROBE
}
void
ieee80211_init_neighbor(struct ieee80211com *ic, struct ieee80211_node *ni,
const struct ieee80211_frame *wh, const struct ieee80211_scanparams *sp,
int isnew)
{
ni->ni_esslen = sp->ssid[1];
memcpy(ni->ni_essid, sp->ssid + 2, sp->ssid[1]);
IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3);
memcpy(ni->ni_tstamp.data, sp->tstamp, sizeof(ni->ni_tstamp));
ni->ni_intval = sp->bintval;
ni->ni_capinfo = sp->capinfo;
ni->ni_chan = ic->ic_bss->ni_chan;
ni->ni_fhdwell = sp->fhdwell;
ni->ni_fhindex = sp->fhindex;
ni->ni_erp = sp->erp;
ni->ni_timoff = sp->timoff;
if (sp->wme != NULL)
ieee80211_saveie(&ni->ni_wme_ie, sp->wme);
if (sp->wpa != NULL)
ieee80211_saveie(&ni->ni_wpa_ie, sp->wpa);
/* NB: must be after ni_chan is setup */
ieee80211_setup_rates(ni, sp->rates, sp->xrates,
IEEE80211_F_DONEGO | IEEE80211_F_DOSORT);
if (ic->ic_newassoc != NULL)
ic->ic_newassoc(ni, isnew);
}
/*
* Do node discovery in adhoc mode on receipt of a beacon
* or probe response frame. Note that for the driver's
@ -1274,27 +1303,7 @@ ieee80211_add_neighbor(struct ieee80211com *ic,
ni = ieee80211_dup_bss(&ic->ic_sta, wh->i_addr2);/* XXX alloc_node? */
if (ni != NULL) {
ni->ni_esslen = sp->ssid[1];
memcpy(ni->ni_essid, sp->ssid + 2, sp->ssid[1]);
IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3);
memcpy(ni->ni_tstamp.data, sp->tstamp, sizeof(ni->ni_tstamp));
ni->ni_intval = sp->bintval;
ni->ni_capinfo = sp->capinfo;
ni->ni_chan = ic->ic_bss->ni_chan;
ni->ni_fhdwell = sp->fhdwell;
ni->ni_fhindex = sp->fhindex;
ni->ni_erp = sp->erp;
ni->ni_timoff = sp->timoff;
if (sp->wme != NULL)
ieee80211_saveie(&ni->ni_wme_ie, sp->wme);
if (sp->wpa != NULL)
ieee80211_saveie(&ni->ni_wpa_ie, sp->wpa);
/* NB: must be after ni_chan is setup */
ieee80211_setup_rates(ni, sp->rates, sp->xrates, IEEE80211_F_DOSORT);
if (ic->ic_newassoc != NULL)
ic->ic_newassoc(ni, 1);
ieee80211_init_neighbor(ic, ni, wh, sp, 1);
/* XXX not right for 802.1x/WPA */
ieee80211_node_authorize(ni);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: ieee80211_node.h,v 1.19 2005/11/18 16:40:09 skrll Exp $ */
/* $NetBSD: ieee80211_node.h,v 1.20 2005/11/20 10:04:21 dyoung Exp $ */
/*-
* Copyright (c) 2001 Atsushi Onoe
* Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
@ -331,6 +331,9 @@ void ieee80211_add_scan(struct ieee80211com *,
const struct ieee80211_scanparams *,
const struct ieee80211_frame *,
int subtype, int rssi, int rstamp);
void ieee80211_init_neighbor(struct ieee80211com *, struct ieee80211_node *,
const struct ieee80211_frame *,
const struct ieee80211_scanparams *, int);
struct ieee80211_node *ieee80211_add_neighbor(struct ieee80211com *,
const struct ieee80211_frame *,
const struct ieee80211_scanparams *);