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:
parent
f8251d6325
commit
461cd4dbb5
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 *);
|
||||
|
Loading…
Reference in New Issue
Block a user