1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-15 10:17:20 +00:00

Adhoc mode fixups:

o plug memory leak in adhoc mode: on rx the sender may be the
  current master so simply checking against ic_bss is not enough
  to identify if the packet comes from an unknown sender; must
  also check the mac address
o split neighbor node creation into two routines and fillin state
  of nodes faked up on xmit when a beacon or probe response frame
  is later received; this ensures important state like the rate set
  and advertised capabilities are correct

Obtained from:	netbsd
MFC after:	1 week
This commit is contained in:
Sam Leffler 2005-12-04 04:50:27 +00:00
parent f4e9888107
commit be425a0f40
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=153073
3 changed files with 56 additions and 28 deletions

View File

@ -233,7 +233,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.
@ -1957,6 +1958,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) {
/*
* Update faked node created on transmit.
* Note this also updates the tsf.
*/
ieee80211_init_neighbor(ni, wh, &scan);
} else {
/*
* Record tsf for potential resync.
@ -2017,8 +2024,12 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
return;
}
allocbs = 0;
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);
allocbs = 1;
} else if (!IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) {
/*
* XXX Cannot tell if the sender is operating
* in ibss mode. But we need a new node to
@ -2027,13 +2038,10 @@ 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;
} else
allocbs = 0;
}
IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC,
"[%s] recv probe req\n", ether_sprintf(wh->i_addr2));
ni->ni_rssi = rssi;
@ -2050,8 +2058,11 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
IEEE80211_SEND_MGMT(ic, ni,
IEEE80211_FC0_SUBTYPE_PROBE_RESP, 0);
}
if (allocbs && ic->ic_opmode != IEEE80211_M_IBSS) {
/* reclaim immediately */
if (allocbs) {
/*
* Temporary node created just to send a
* response, reclaim immediately.
*/
ieee80211_free_node(ni);
}
break;

View File

@ -1077,6 +1077,8 @@ ieee80211_fakeup_adhoc_node(struct ieee80211_node_table *nt,
struct ieee80211com *ic = nt->nt_ic;
struct ieee80211_node *ni;
IEEE80211_DPRINTF(nt->nt_ic, IEEE80211_MSG_NODE,
"%s: mac<%s>\n", __func__, ether_sprintf(macaddr));
ni = ieee80211_dup_bss(nt, macaddr);
if (ni != NULL) {
/* XXX no rate negotiation; just dup */
@ -1218,6 +1220,34 @@ ieee80211_add_scan(struct ieee80211com *ic,
#undef ISPROBE
}
void
ieee80211_init_neighbor(struct ieee80211_node *ni,
const struct ieee80211_frame *wh,
const struct ieee80211_scanparams *sp)
{
IEEE80211_DPRINTF(ni->ni_ic, IEEE80211_MSG_NODE,
"%s: %p<%s>\n", __func__, ni, ether_sprintf(ni->ni_macaddr));
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 = ni->ni_ic->ic_curchan;
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);
}
/*
* Do node discovery in adhoc mode on receipt of a beacon
* or probe response frame. Note that for the driver's
@ -1231,27 +1261,11 @@ ieee80211_add_neighbor(struct ieee80211com *ic,
{
struct ieee80211_node *ni;
IEEE80211_DPRINTF(ic, IEEE80211_MSG_NODE,
"%s: mac<%s>\n", __func__, ether_sprintf(wh->i_addr2));
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);
ieee80211_init_neighbor(ni, wh, sp);
if (ic->ic_newassoc != NULL)
ic->ic_newassoc(ni, 1);
/* XXX not right for 802.1x/WPA */

View File

@ -324,6 +324,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 ieee80211_node *,
const struct ieee80211_frame *,
const struct ieee80211_scanparams *);
struct ieee80211_node *ieee80211_add_neighbor(struct ieee80211com *,
const struct ieee80211_frame *,
const struct ieee80211_scanparams *);