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:
parent
f4e9888107
commit
be425a0f40
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=153073
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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 *);
|
||||
|
Loading…
Reference in New Issue
Block a user