Clarify/fix handling of the current channel:
o add ic_curchan and use it uniformly for specifying the current channel instead of overloading ic->ic_bss->ni_chan (or in some drivers ic_ibss_chan) o add ieee80211_scanparams structure to encapsulate scanning-related state captured for rx frames o move rx beacon+probe response frame handling into separate routines o change beacon+probe response handling to treat the scan table more like a scan cache--look for an existing entry before adding a new one; this combined with ic_curchan use corrects handling of stations that were previously found at a different channel o move adhoc neighbor discovery by beacon+probe response frames to a new ieee80211_add_neighbor routine Reviewed by: avatar Tested by: avatar, Michal Mertl MFC after: 2 weeks
This commit is contained in:
parent
44938dbf6d
commit
b5c9941514
@ -844,7 +844,6 @@ ath_init(void *arg)
|
||||
struct ath_softc *sc = (struct ath_softc *) arg;
|
||||
struct ieee80211com *ic = &sc->sc_ic;
|
||||
struct ifnet *ifp = sc->sc_ifp;
|
||||
struct ieee80211_node *ni;
|
||||
struct ath_hal *ah = sc->sc_ah;
|
||||
HAL_STATUS status;
|
||||
|
||||
@ -865,8 +864,8 @@ ath_init(void *arg)
|
||||
* be followed by initialization of the appropriate bits
|
||||
* and then setup of the interrupt mask.
|
||||
*/
|
||||
sc->sc_curchan.channel = ic->ic_ibss_chan->ic_freq;
|
||||
sc->sc_curchan.channelFlags = ath_chan2flags(ic, ic->ic_ibss_chan);
|
||||
sc->sc_curchan.channel = ic->ic_curchan->ic_freq;
|
||||
sc->sc_curchan.channelFlags = ath_chan2flags(ic, ic->ic_curchan);
|
||||
if (!ath_hal_reset(ah, ic->ic_opmode, &sc->sc_curchan, AH_FALSE, &status)) {
|
||||
if_printf(ifp, "unable to reset hardware; hal status %u\n",
|
||||
status);
|
||||
@ -918,9 +917,7 @@ ath_init(void *arg)
|
||||
* to kick the 802.11 state machine as it's likely to
|
||||
* immediately call back to us to send mgmt frames.
|
||||
*/
|
||||
ni = ic->ic_bss;
|
||||
ni->ni_chan = ic->ic_ibss_chan;
|
||||
ath_chan_change(sc, ni->ni_chan);
|
||||
ath_chan_change(sc, ic->ic_curchan);
|
||||
if (ic->ic_opmode != IEEE80211_M_MONITOR) {
|
||||
if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL)
|
||||
ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
|
||||
@ -1022,7 +1019,7 @@ ath_reset(struct ifnet *ifp)
|
||||
* Convert to a HAL channel description with the flags
|
||||
* constrained to reflect the current operating mode.
|
||||
*/
|
||||
c = ic->ic_ibss_chan;
|
||||
c = ic->ic_curchan;
|
||||
sc->sc_curchan.channel = c->ic_freq;
|
||||
sc->sc_curchan.channelFlags = ath_chan2flags(ic, c);
|
||||
|
||||
@ -4114,7 +4111,7 @@ ath_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
|
||||
goto done;
|
||||
}
|
||||
ni = ic->ic_bss;
|
||||
error = ath_chan_set(sc, ni->ni_chan);
|
||||
error = ath_chan_set(sc, ic->ic_curchan);
|
||||
if (error != 0)
|
||||
goto bad;
|
||||
rfilt = ath_calcrxfilter(sc, nstate);
|
||||
@ -4153,7 +4150,7 @@ ath_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
|
||||
, ni->ni_intval
|
||||
, ether_sprintf(ni->ni_bssid)
|
||||
, ni->ni_capinfo
|
||||
, ieee80211_chan2ieee(ic, ni->ni_chan));
|
||||
, ieee80211_chan2ieee(ic, ic->ic_curchan));
|
||||
|
||||
switch (ic->ic_opmode) {
|
||||
case IEEE80211_M_HOSTAP:
|
||||
|
@ -1002,7 +1002,7 @@ ipw_fix_channel(struct ieee80211com *ic, struct mbuf *m)
|
||||
#if IEEE80211_CHAN_MAX < 255
|
||||
if (frm[2] <= IEEE80211_CHAN_MAX)
|
||||
#endif
|
||||
ic->ic_bss->ni_chan = &ic->ic_channels[frm[2]];
|
||||
ic->ic_curchan = &ic->ic_channels[frm[2]];
|
||||
|
||||
frm += frm[1] + 2;
|
||||
}
|
||||
|
@ -990,21 +990,21 @@ ral_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
|
||||
break;
|
||||
|
||||
case IEEE80211_S_SCAN:
|
||||
ral_set_chan(sc, ic->ic_bss->ni_chan);
|
||||
ral_set_chan(sc, ic->ic_curchan);
|
||||
callout_reset(&sc->scan_ch, (sc->dwelltime * hz) / 1000,
|
||||
ral_next_scan, sc);
|
||||
break;
|
||||
|
||||
case IEEE80211_S_AUTH:
|
||||
ral_set_chan(sc, ic->ic_bss->ni_chan);
|
||||
ral_set_chan(sc, ic->ic_curchan);
|
||||
break;
|
||||
|
||||
case IEEE80211_S_ASSOC:
|
||||
ral_set_chan(sc, ic->ic_bss->ni_chan);
|
||||
ral_set_chan(sc, ic->ic_curchan);
|
||||
break;
|
||||
|
||||
case IEEE80211_S_RUN:
|
||||
ral_set_chan(sc, ic->ic_bss->ni_chan);
|
||||
ral_set_chan(sc, ic->ic_curchan);
|
||||
|
||||
if (ic->ic_opmode != IEEE80211_M_MONITOR)
|
||||
ral_set_bssid(sc, ic->ic_bss->ni_bssid);
|
||||
@ -1768,7 +1768,7 @@ ral_tx_mgt(struct ral_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
|
||||
desc = &sc->prioq.desc[sc->prioq.cur];
|
||||
data = &sc->prioq.data[sc->prioq.cur];
|
||||
|
||||
rate = IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) ? 12 : 4;
|
||||
rate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 4;
|
||||
|
||||
error = bus_dmamap_load_mbuf_sg(sc->prioq.data_dmat, data->map, m0,
|
||||
segs, &nsegs, 0);
|
||||
@ -1910,7 +1910,7 @@ ral_tx_data(struct ral_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
|
||||
uint16_t dur;
|
||||
int rtsrate, ackrate;
|
||||
|
||||
rtsrate = IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) ? 12 : 4;
|
||||
rtsrate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 4;
|
||||
ackrate = ral_ack_rate(rate);
|
||||
|
||||
dur = ral_txtime(m0->m_pkthdr.len + 4, rate, ic->ic_flags) +
|
||||
@ -2739,7 +2739,8 @@ ral_init(void *priv)
|
||||
|
||||
/* set default BSS channel */
|
||||
ic->ic_bss->ni_chan = ic->ic_ibss_chan;
|
||||
ral_set_chan(sc, ic->ic_bss->ni_chan);
|
||||
ic->ic_curchan = ic->ic_ibss_chan;
|
||||
ral_set_chan(sc, ic->ic_curchan);
|
||||
|
||||
/* kick Rx */
|
||||
tmp = RAL_DROP_PHY_ERROR | RAL_DROP_CRC_ERROR;
|
||||
|
@ -722,20 +722,20 @@ ural_task(void *arg)
|
||||
break;
|
||||
|
||||
case IEEE80211_S_SCAN:
|
||||
ural_set_chan(sc, ic->ic_bss->ni_chan);
|
||||
ural_set_chan(sc, ic->ic_curchan);
|
||||
callout_reset(&sc->scan_ch, hz / 5, ural_next_scan, sc);
|
||||
break;
|
||||
|
||||
case IEEE80211_S_AUTH:
|
||||
ural_set_chan(sc, ic->ic_bss->ni_chan);
|
||||
ural_set_chan(sc, ic->ic_curchan);
|
||||
break;
|
||||
|
||||
case IEEE80211_S_ASSOC:
|
||||
ural_set_chan(sc, ic->ic_bss->ni_chan);
|
||||
ural_set_chan(sc, ic->ic_curchan);
|
||||
break;
|
||||
|
||||
case IEEE80211_S_RUN:
|
||||
ural_set_chan(sc, ic->ic_bss->ni_chan);
|
||||
ural_set_chan(sc, ic->ic_curchan);
|
||||
|
||||
if (ic->ic_opmode != IEEE80211_M_MONITOR)
|
||||
ural_set_bssid(sc, ic->ic_bss->ni_bssid);
|
||||
@ -1125,7 +1125,7 @@ ural_tx_mgt(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
|
||||
data = &sc->tx_data[0];
|
||||
desc = (struct ural_tx_desc *)data->buf;
|
||||
|
||||
rate = IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) ? 12 : 4;
|
||||
rate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 4;
|
||||
|
||||
if (sc->sc_drvbpf != NULL) {
|
||||
struct ural_tx_radiotap_header *tap = &sc->sc_txtap;
|
||||
@ -1956,7 +1956,8 @@ ural_init(void *priv)
|
||||
|
||||
/* set default BSS channel */
|
||||
ic->ic_bss->ni_chan = ic->ic_ibss_chan;
|
||||
ural_set_chan(sc, ic->ic_bss->ni_chan);
|
||||
ic->ic_curchan = ic->ic_ibss_chan;
|
||||
ural_set_chan(sc, ic->ic_curchan);
|
||||
|
||||
/* clear statistic registers (STA_CSR0 to STA_CSR10) */
|
||||
ural_read_multi(sc, RAL_STA_CSR0, sta, sizeof sta);
|
||||
|
@ -2736,6 +2736,7 @@ wi_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
|
||||
wi_read_rid(sc, WI_RID_CURRENT_CHAN, &val, &buflen);
|
||||
/* XXX validate channel */
|
||||
ni->ni_chan = &ic->ic_channels[le16toh(val)];
|
||||
ic->ic_curchan = ni->ni_chan;
|
||||
ic->ic_ibss_chan = ni->ni_chan;
|
||||
#if NBPFILTER > 0
|
||||
sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq =
|
||||
|
@ -167,6 +167,10 @@ ieee80211_ifattach(struct ieee80211com *ic)
|
||||
ic->ic_modecaps |= 1<<IEEE80211_MODE_TURBO_A;
|
||||
if (IEEE80211_IS_CHAN_108G(c))
|
||||
ic->ic_modecaps |= 1<<IEEE80211_MODE_TURBO_G;
|
||||
if (ic->ic_curchan == NULL) {
|
||||
/* arbitrarily pick the first channel */
|
||||
ic->ic_curchan = &ic->ic_channels[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
/* validate ic->ic_curmode */
|
||||
|
@ -1692,7 +1692,7 @@ ieee80211_parse_wmeparams(struct ieee80211com *ic, u_int8_t *frm,
|
||||
#undef MS
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
ieee80211_saveie(u_int8_t **iep, const u_int8_t *ie)
|
||||
{
|
||||
u_int ielen = ie[1]+2;
|
||||
@ -1709,38 +1709,6 @@ ieee80211_saveie(u_int8_t **iep, const u_int8_t *ie)
|
||||
/* XXX note failure */
|
||||
}
|
||||
|
||||
#ifdef IEEE80211_DEBUG
|
||||
static void
|
||||
dump_probe_beacon(u_int8_t subtype, int isnew,
|
||||
const u_int8_t mac[IEEE80211_ADDR_LEN],
|
||||
u_int8_t chan, u_int8_t bchan, u_int16_t capinfo, u_int16_t bintval,
|
||||
u_int8_t erp, u_int8_t *ssid, u_int8_t *country)
|
||||
{
|
||||
printf("[%s] %s%s on chan %u (bss chan %u) ",
|
||||
ether_sprintf(mac), isnew ? "new " : "",
|
||||
ieee80211_mgt_subtype_name[subtype >> IEEE80211_FC0_SUBTYPE_SHIFT],
|
||||
chan, bchan);
|
||||
ieee80211_print_essid(ssid + 2, ssid[1]);
|
||||
printf("\n");
|
||||
|
||||
if (isnew) {
|
||||
printf("[%s] caps 0x%x bintval %u erp 0x%x",
|
||||
ether_sprintf(mac), capinfo, bintval, erp);
|
||||
if (country) {
|
||||
#ifdef __FreeBSD__
|
||||
printf(" country info %*D", country[1], country+2, " ");
|
||||
#else
|
||||
int i;
|
||||
printf(" country info");
|
||||
for (i = 0; i < country[1]; i++)
|
||||
printf(" %02x", country[i+2]);
|
||||
#endif
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
#endif /* IEEE80211_DEBUG */
|
||||
|
||||
void
|
||||
ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
|
||||
struct ieee80211_node *ni,
|
||||
@ -1760,10 +1728,7 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
|
||||
switch (subtype) {
|
||||
case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
|
||||
case IEEE80211_FC0_SUBTYPE_BEACON: {
|
||||
u_int8_t *tstamp, *country, *tim;
|
||||
u_int8_t chan, bchan, fhindex, erp;
|
||||
u_int16_t capinfo, bintval, timoff;
|
||||
u_int16_t fhdwell;
|
||||
struct ieee80211_scanparams scan;
|
||||
|
||||
/*
|
||||
* We process beacon/probe response frames:
|
||||
@ -1794,32 +1759,29 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
|
||||
* [tlv] WPA or RSN
|
||||
*/
|
||||
IEEE80211_VERIFY_LENGTH(efrm - frm, 12);
|
||||
tstamp = frm; frm += 8;
|
||||
bintval = le16toh(*(u_int16_t *)frm); frm += 2;
|
||||
capinfo = le16toh(*(u_int16_t *)frm); frm += 2;
|
||||
ssid = rates = xrates = country = wpa = wme = tim = NULL;
|
||||
bchan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
|
||||
chan = bchan;
|
||||
fhdwell = 0;
|
||||
fhindex = 0;
|
||||
erp = 0;
|
||||
timoff = 0;
|
||||
memset(&scan, 0, sizeof(scan));
|
||||
scan.tstamp = frm; frm += 8;
|
||||
scan.bintval = le16toh(*(u_int16_t *)frm); frm += 2;
|
||||
scan.capinfo = le16toh(*(u_int16_t *)frm); frm += 2;
|
||||
scan.bchan = ieee80211_chan2ieee(ic, ic->ic_curchan);
|
||||
scan.chan = scan.bchan;
|
||||
|
||||
while (frm < efrm) {
|
||||
switch (*frm) {
|
||||
case IEEE80211_ELEMID_SSID:
|
||||
ssid = frm;
|
||||
scan.ssid = frm;
|
||||
break;
|
||||
case IEEE80211_ELEMID_RATES:
|
||||
rates = frm;
|
||||
scan.rates = frm;
|
||||
break;
|
||||
case IEEE80211_ELEMID_COUNTRY:
|
||||
country = frm;
|
||||
scan.country = frm;
|
||||
break;
|
||||
case IEEE80211_ELEMID_FHPARMS:
|
||||
if (ic->ic_phytype == IEEE80211_T_FH) {
|
||||
fhdwell = LE_READ_2(&frm[2]);
|
||||
chan = IEEE80211_FH_CHAN(frm[4], frm[5]);
|
||||
fhindex = frm[6];
|
||||
scan.fhdwell = LE_READ_2(&frm[2]);
|
||||
scan.chan = IEEE80211_FH_CHAN(frm[4], frm[5]);
|
||||
scan.fhindex = frm[6];
|
||||
}
|
||||
break;
|
||||
case IEEE80211_ELEMID_DSPARMS:
|
||||
@ -1828,17 +1790,17 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
|
||||
* is problematic for multi-mode devices.
|
||||
*/
|
||||
if (ic->ic_phytype != IEEE80211_T_FH)
|
||||
chan = frm[2];
|
||||
scan.chan = frm[2];
|
||||
break;
|
||||
case IEEE80211_ELEMID_TIM:
|
||||
/* XXX ATIM? */
|
||||
tim = frm;
|
||||
timoff = frm - mtod(m0, u_int8_t *);
|
||||
scan.tim = frm;
|
||||
scan.timoff = frm - mtod(m0, u_int8_t *);
|
||||
break;
|
||||
case IEEE80211_ELEMID_IBSSPARMS:
|
||||
break;
|
||||
case IEEE80211_ELEMID_XRATES:
|
||||
xrates = frm;
|
||||
scan.xrates = frm;
|
||||
break;
|
||||
case IEEE80211_ELEMID_ERP:
|
||||
if (frm[1] != 1) {
|
||||
@ -1848,16 +1810,16 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
|
||||
ic->ic_stats.is_rx_elem_toobig++;
|
||||
break;
|
||||
}
|
||||
erp = frm[2];
|
||||
scan.erp = frm[2];
|
||||
break;
|
||||
case IEEE80211_ELEMID_RSN:
|
||||
wpa = frm;
|
||||
scan.wpa = frm;
|
||||
break;
|
||||
case IEEE80211_ELEMID_VENDOR:
|
||||
if (iswpaoui(frm))
|
||||
wpa = frm;
|
||||
scan.wpa = frm;
|
||||
else if (iswmeparam(frm) || iswmeinfo(frm))
|
||||
wme = frm;
|
||||
scan.wme = frm;
|
||||
/* XXX Atheros OUI support */
|
||||
break;
|
||||
default:
|
||||
@ -1869,21 +1831,23 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
|
||||
}
|
||||
frm += frm[1] + 2;
|
||||
}
|
||||
IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE);
|
||||
IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN);
|
||||
IEEE80211_VERIFY_ELEMENT(scan.rates, IEEE80211_RATE_MAXSIZE);
|
||||
IEEE80211_VERIFY_ELEMENT(scan.ssid, IEEE80211_NWID_LEN);
|
||||
if (
|
||||
#if IEEE80211_CHAN_MAX < 255
|
||||
chan > IEEE80211_CHAN_MAX ||
|
||||
scan.chan > IEEE80211_CHAN_MAX ||
|
||||
#endif
|
||||
isclr(ic->ic_chan_active, chan)) {
|
||||
IEEE80211_DISCARD(ic, IEEE80211_MSG_ELEMID,
|
||||
isclr(ic->ic_chan_active, scan.chan)) {
|
||||
IEEE80211_DISCARD(ic,
|
||||
IEEE80211_MSG_ELEMID | IEEE80211_MSG_INPUT,
|
||||
wh, ieee80211_mgt_subtype_name[subtype >>
|
||||
IEEE80211_FC0_SUBTYPE_SHIFT],
|
||||
"invalid channel %u", chan);
|
||||
"invalid channel %u", scan.chan);
|
||||
ic->ic_stats.is_rx_badchan++;
|
||||
return;
|
||||
}
|
||||
if (chan != bchan && ic->ic_phytype != IEEE80211_T_FH) {
|
||||
if (scan.chan != scan.bchan &&
|
||||
ic->ic_phytype != IEEE80211_T_FH) {
|
||||
/*
|
||||
* Frame was received on a channel different from the
|
||||
* one indicated in the DS params element id;
|
||||
@ -1894,20 +1858,21 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
|
||||
* the rssi value should be correct even for
|
||||
* different hop pattern in FH.
|
||||
*/
|
||||
IEEE80211_DISCARD(ic, IEEE80211_MSG_ELEMID,
|
||||
wh, ieee80211_mgt_subtype_name[subtype >>
|
||||
IEEE80211_FC0_SUBTYPE_SHIFT],
|
||||
"for off-channel %u", chan);
|
||||
ic->ic_stats.is_rx_chanmismatch++;
|
||||
return;
|
||||
}
|
||||
if (!(IEEE80211_BINTVAL_MIN <= bintval &&
|
||||
bintval <= IEEE80211_BINTVAL_MAX)) {
|
||||
IEEE80211_DISCARD(ic,
|
||||
IEEE80211_MSG_ELEMID | IEEE80211_MSG_INPUT,
|
||||
wh, ieee80211_mgt_subtype_name[subtype >>
|
||||
IEEE80211_FC0_SUBTYPE_SHIFT],
|
||||
"bogus beacon interval", bintval);
|
||||
"for off-channel %u", scan.chan);
|
||||
ic->ic_stats.is_rx_chanmismatch++;
|
||||
return;
|
||||
}
|
||||
if (!(IEEE80211_BINTVAL_MIN <= scan.bintval &&
|
||||
scan.bintval <= IEEE80211_BINTVAL_MAX)) {
|
||||
IEEE80211_DISCARD(ic,
|
||||
IEEE80211_MSG_ELEMID | IEEE80211_MSG_INPUT,
|
||||
wh, ieee80211_mgt_subtype_name[subtype >>
|
||||
IEEE80211_FC0_SUBTYPE_SHIFT],
|
||||
"bogus beacon interval", scan.bintval);
|
||||
ic->ic_stats.is_rx_badbintval++;
|
||||
return;
|
||||
}
|
||||
@ -1931,27 +1896,27 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
|
||||
((ic->ic_flags & IEEE80211_F_SCAN) == 0 ||
|
||||
IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_bssid))) {
|
||||
/* record tsf of last beacon */
|
||||
memcpy(ni->ni_tstamp.data, tstamp,
|
||||
memcpy(ni->ni_tstamp.data, scan.tstamp,
|
||||
sizeof(ni->ni_tstamp));
|
||||
if (ni->ni_erp != erp) {
|
||||
if (ni->ni_erp != scan.erp) {
|
||||
IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC,
|
||||
"[%s] erp change: was 0x%x, now 0x%x\n",
|
||||
ether_sprintf(wh->i_addr2),
|
||||
ni->ni_erp, erp);
|
||||
ni->ni_erp, scan.erp);
|
||||
if (ic->ic_curmode == IEEE80211_MODE_11G &&
|
||||
(ni->ni_erp & IEEE80211_ERP_USE_PROTECTION))
|
||||
ic->ic_flags |= IEEE80211_F_USEPROT;
|
||||
else
|
||||
ic->ic_flags &= ~IEEE80211_F_USEPROT;
|
||||
ni->ni_erp = erp;
|
||||
ni->ni_erp = scan.erp;
|
||||
/* XXX statistic */
|
||||
}
|
||||
if ((ni->ni_capinfo ^ capinfo) & IEEE80211_CAPINFO_SHORT_SLOTTIME) {
|
||||
if ((ni->ni_capinfo ^ scan.capinfo) & IEEE80211_CAPINFO_SHORT_SLOTTIME) {
|
||||
IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC,
|
||||
"[%s] capabilities change: before 0x%x,"
|
||||
" now 0x%x\n",
|
||||
ether_sprintf(wh->i_addr2),
|
||||
ni->ni_capinfo, capinfo);
|
||||
ni->ni_capinfo, scan.capinfo);
|
||||
/*
|
||||
* NB: we assume short preamble doesn't
|
||||
* change dynamically
|
||||
@ -1959,105 +1924,51 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
|
||||
ieee80211_set_shortslottime(ic,
|
||||
ic->ic_curmode == IEEE80211_MODE_11A ||
|
||||
(ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME));
|
||||
ni->ni_capinfo = capinfo;
|
||||
ni->ni_capinfo = scan.capinfo;
|
||||
/* XXX statistic */
|
||||
}
|
||||
if (wme != NULL &&
|
||||
if (scan.wme != NULL &&
|
||||
(ni->ni_flags & IEEE80211_NODE_QOS) &&
|
||||
ieee80211_parse_wmeparams(ic, wme, wh) > 0)
|
||||
ieee80211_parse_wmeparams(ic, scan.wme, wh) > 0)
|
||||
ieee80211_wme_updateparams(ic);
|
||||
if (tim != NULL) {
|
||||
if (scan.tim != NULL) {
|
||||
struct ieee80211_tim_ie *ie =
|
||||
(struct ieee80211_tim_ie *) tim;
|
||||
(struct ieee80211_tim_ie *) scan.tim;
|
||||
|
||||
ni->ni_dtim_count = ie->tim_count;
|
||||
ni->ni_dtim_period = ie->tim_period;
|
||||
}
|
||||
/* NB: don't need the rest of this */
|
||||
if ((ic->ic_flags & IEEE80211_F_SCAN) == 0)
|
||||
return;
|
||||
}
|
||||
|
||||
if (ni == ic->ic_bss &&
|
||||
!IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_bssid)) {
|
||||
#ifdef IEEE80211_DEBUG
|
||||
if (ieee80211_msg_scan(ic))
|
||||
dump_probe_beacon(subtype, 1,
|
||||
wh->i_addr2, chan, bchan, capinfo,
|
||||
bintval, erp, ssid, country);
|
||||
#endif
|
||||
/*
|
||||
* Create a new entry. If scanning the entry goes
|
||||
* in the scan cache. Otherwise, be particular when
|
||||
* operating in adhoc mode--only take nodes marked
|
||||
* as ibss participants so we don't populate our
|
||||
* neighbor table with unintersting sta's.
|
||||
*/
|
||||
if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) {
|
||||
if ((capinfo & IEEE80211_CAPINFO_IBSS) == 0)
|
||||
return;
|
||||
ni = ieee80211_fakeup_adhoc_node(&ic->ic_sta,
|
||||
wh->i_addr2);
|
||||
} else
|
||||
ni = ieee80211_dup_bss(&ic->ic_scan, wh->i_addr2);
|
||||
if (ni == NULL)
|
||||
return;
|
||||
ni->ni_esslen = ssid[1];
|
||||
memset(ni->ni_essid, 0, sizeof(ni->ni_essid));
|
||||
memcpy(ni->ni_essid, ssid + 2, ssid[1]);
|
||||
} else if (ssid[1] != 0 &&
|
||||
(ISPROBE(subtype) || ni->ni_esslen == 0)) {
|
||||
/*
|
||||
* Update ESSID at probe response to adopt
|
||||
* hidden AP by Lucent/Cisco, which announces
|
||||
* null ESSID in beacon.
|
||||
*/
|
||||
#ifdef IEEE80211_DEBUG
|
||||
if (ieee80211_msg_scan(ic) ||
|
||||
ieee80211_msg_debug(ic))
|
||||
dump_probe_beacon(subtype, 0,
|
||||
wh->i_addr2, chan, bchan, capinfo,
|
||||
bintval, erp, ssid, country);
|
||||
#endif
|
||||
ni->ni_esslen = ssid[1];
|
||||
memset(ni->ni_essid, 0, sizeof(ni->ni_essid));
|
||||
memcpy(ni->ni_essid, ssid + 2, ssid[1]);
|
||||
}
|
||||
ni->ni_scangen = ic->ic_scan.nt_scangen;
|
||||
IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3);
|
||||
ni->ni_rssi = rssi;
|
||||
ni->ni_rstamp = rstamp;
|
||||
memcpy(ni->ni_tstamp.data, tstamp, sizeof(ni->ni_tstamp));
|
||||
ni->ni_intval = bintval;
|
||||
ni->ni_capinfo = capinfo;
|
||||
ni->ni_chan = &ic->ic_channels[chan];
|
||||
ni->ni_fhdwell = fhdwell;
|
||||
ni->ni_fhindex = fhindex;
|
||||
ni->ni_erp = erp;
|
||||
if (tim != NULL) {
|
||||
struct ieee80211_tim_ie *ie =
|
||||
(struct ieee80211_tim_ie *) tim;
|
||||
|
||||
ni->ni_dtim_count = ie->tim_count;
|
||||
ni->ni_dtim_period = ie->tim_period;
|
||||
if (ic->ic_flags & IEEE80211_F_SCAN)
|
||||
ieee80211_add_scan(ic, &scan, wh,
|
||||
subtype, rssi, rstamp);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* Record the byte offset from the mac header to
|
||||
* the start of the TIM information element for
|
||||
* use by hardware and/or to speedup software
|
||||
* processing of beacon frames.
|
||||
* If scanning, just pass information to the scan module.
|
||||
*/
|
||||
ni->ni_timoff = timoff;
|
||||
/*
|
||||
* Record optional information elements that might be
|
||||
* used by applications or drivers.
|
||||
*/
|
||||
if (wme != NULL)
|
||||
ieee80211_saveie(&ni->ni_wme_ie, wme);
|
||||
if (wpa != NULL)
|
||||
ieee80211_saveie(&ni->ni_wpa_ie, wpa);
|
||||
/* NB: must be after ni_chan is setup */
|
||||
ieee80211_setup_rates(ni, rates, xrates, IEEE80211_F_DOSORT);
|
||||
if (ic->ic_flags & IEEE80211_F_SCAN) {
|
||||
ieee80211_add_scan(ic, &scan, wh,
|
||||
subtype, rssi, rstamp);
|
||||
return;
|
||||
}
|
||||
if (scan.capinfo & IEEE80211_CAPINFO_IBSS) {
|
||||
if (!IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) {
|
||||
/*
|
||||
* Create a new entry in the neighbor table.
|
||||
*/
|
||||
ni = ieee80211_add_neighbor(ic, wh, &scan);
|
||||
} else {
|
||||
/*
|
||||
* Record tsf for potential resync.
|
||||
*/
|
||||
memcpy(ni->ni_tstamp.data, scan.tstamp,
|
||||
sizeof(ni->ni_tstamp));
|
||||
}
|
||||
if (ni != NULL) {
|
||||
ni->ni_rssi = rssi;
|
||||
ni->ni_rstamp = rstamp;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -252,7 +252,7 @@ ieee80211_cfgget(struct ieee80211com *ic, u_long cmd, caddr_t data)
|
||||
break;
|
||||
case WI_RID_CURRENT_CHAN:
|
||||
wreq.wi_val[0] = htole16(
|
||||
ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan));
|
||||
ieee80211_chan2ieee(ic, ic->ic_curchan));
|
||||
wreq.wi_len = 1;
|
||||
break;
|
||||
case WI_RID_COMMS_QUALITY:
|
||||
@ -448,7 +448,6 @@ findrate(struct ieee80211com *ic, enum ieee80211_phymode mode, int rate)
|
||||
static int
|
||||
ieee80211_setupscan(struct ieee80211com *ic, const u_int8_t chanlist[])
|
||||
{
|
||||
int i;
|
||||
|
||||
/*
|
||||
* XXX don't permit a scan to be started unless we
|
||||
@ -460,20 +459,6 @@ ieee80211_setupscan(struct ieee80211com *ic, const u_int8_t chanlist[])
|
||||
*/
|
||||
if (!IS_UP(ic))
|
||||
return EINVAL;
|
||||
if (ic->ic_ibss_chan == NULL ||
|
||||
isclr(chanlist, ieee80211_chan2ieee(ic, ic->ic_ibss_chan))) {
|
||||
for (i = 0; i <= IEEE80211_CHAN_MAX; i++)
|
||||
if (isset(chanlist, i)) {
|
||||
ic->ic_ibss_chan = &ic->ic_channels[i];
|
||||
goto found;
|
||||
}
|
||||
return EINVAL; /* no active channels */
|
||||
found:
|
||||
;
|
||||
}
|
||||
if (ic->ic_bss->ni_chan == IEEE80211_CHAN_ANYC ||
|
||||
isclr(chanlist, ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan)))
|
||||
ic->ic_bss->ni_chan = ic->ic_ibss_chan;
|
||||
memcpy(ic->ic_chan_active, chanlist, sizeof(ic->ic_chan_active));
|
||||
/*
|
||||
* We force the state to INIT before calling ieee80211_new_state
|
||||
@ -827,18 +812,6 @@ ieee80211_cfgset(struct ieee80211com *ic, u_long cmd, caddr_t data)
|
||||
return error;
|
||||
}
|
||||
|
||||
static struct ieee80211_channel *
|
||||
getcurchan(struct ieee80211com *ic)
|
||||
{
|
||||
switch (ic->ic_state) {
|
||||
case IEEE80211_S_INIT:
|
||||
case IEEE80211_S_SCAN:
|
||||
return ic->ic_des_chan;
|
||||
default:
|
||||
return ic->ic_ibss_chan;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
cap2cipher(int flag)
|
||||
{
|
||||
@ -1351,7 +1324,7 @@ ieee80211_ioctl_get80211(struct ieee80211com *ic, u_long cmd, struct ieee80211re
|
||||
ireq->i_val = ic->ic_bss->ni_authmode;
|
||||
break;
|
||||
case IEEE80211_IOC_CHANNEL:
|
||||
ireq->i_val = ieee80211_chan2ieee(ic, getcurchan(ic));
|
||||
ireq->i_val = ieee80211_chan2ieee(ic, ic->ic_curchan);
|
||||
break;
|
||||
case IEEE80211_IOC_POWERSAVE:
|
||||
if (ic->ic_flags & IEEE80211_F_PMGTON)
|
||||
@ -1841,9 +1814,6 @@ ieee80211_ioctl_setchanlist(struct ieee80211com *ic, struct ieee80211req *ireq)
|
||||
;
|
||||
}
|
||||
memcpy(ic->ic_chan_active, chanlist, sizeof(ic->ic_chan_active));
|
||||
if (ic->ic_bss->ni_chan == IEEE80211_CHAN_ANYC ||
|
||||
isclr(chanlist, ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan)))
|
||||
ic->ic_bss->ni_chan = ic->ic_ibss_chan;
|
||||
return IS_UP_AUTO(ic) ? ENETRESET : 0;
|
||||
}
|
||||
|
||||
|
@ -261,16 +261,12 @@ ieee80211_reset_scan(struct ieee80211com *ic)
|
||||
} else
|
||||
memcpy(ic->ic_chan_scan, ic->ic_chan_active,
|
||||
sizeof(ic->ic_chan_active));
|
||||
/* NB: hack, setup so next_scan starts with the first channel */
|
||||
if (ic->ic_bss->ni_chan == IEEE80211_CHAN_ANYC)
|
||||
ieee80211_set_chan(ic, ic->ic_bss,
|
||||
&ic->ic_channels[IEEE80211_CHAN_MAX]);
|
||||
#ifdef IEEE80211_DEBUG
|
||||
if (ieee80211_msg_scan(ic)) {
|
||||
printf("%s: scan set:", __func__);
|
||||
dump_chanlist(ic->ic_chan_scan);
|
||||
printf(" start chan %u\n",
|
||||
ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan));
|
||||
ieee80211_chan2ieee(ic, ic->ic_curchan));
|
||||
}
|
||||
#endif /* IEEE80211_DEBUG */
|
||||
}
|
||||
@ -324,7 +320,7 @@ ieee80211_next_scan(struct ieee80211com *ic)
|
||||
*/
|
||||
ic->ic_mgt_timer = 0;
|
||||
|
||||
chan = ic->ic_bss->ni_chan;
|
||||
chan = ic->ic_curchan;
|
||||
do {
|
||||
if (++chan > &ic->ic_channels[IEEE80211_CHAN_MAX])
|
||||
chan = &ic->ic_channels[0];
|
||||
@ -332,13 +328,19 @@ ieee80211_next_scan(struct ieee80211com *ic)
|
||||
clrbit(ic->ic_chan_scan, ieee80211_chan2ieee(ic, chan));
|
||||
IEEE80211_DPRINTF(ic, IEEE80211_MSG_SCAN,
|
||||
"%s: chan %d->%d\n", __func__,
|
||||
ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan),
|
||||
ieee80211_chan2ieee(ic, ic->ic_curchan),
|
||||
ieee80211_chan2ieee(ic, chan));
|
||||
ieee80211_set_chan(ic, ic->ic_bss, chan);
|
||||
ic->ic_curchan = chan;
|
||||
/*
|
||||
* XXX drivers should do this as needed,
|
||||
* XXX for now maintain compatibility
|
||||
*/
|
||||
ic->ic_bss->ni_rates =
|
||||
ic->ic_sup_rates[ieee80211_chan2mode(ic, chan)];
|
||||
ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
|
||||
return 1;
|
||||
}
|
||||
} while (chan != ic->ic_bss->ni_chan);
|
||||
} while (chan != ic->ic_curchan);
|
||||
ieee80211_end_scan(ic);
|
||||
return 0;
|
||||
}
|
||||
@ -408,6 +410,7 @@ ieee80211_create_ibss(struct ieee80211com* ic, struct ieee80211_channel *chan)
|
||||
* Fix the channel and related attributes.
|
||||
*/
|
||||
ieee80211_set_chan(ic, ni, chan);
|
||||
ic->ic_curchan = chan;
|
||||
ic->ic_curmode = ieee80211_chan2mode(ic, chan);
|
||||
/*
|
||||
* Do mode-specific rate setup.
|
||||
@ -790,6 +793,7 @@ ieee80211_sta_join(struct ieee80211com *ic, struct ieee80211_node *selbs)
|
||||
* mode is locked.
|
||||
*/
|
||||
ic->ic_curmode = ieee80211_chan2mode(ic, selbs->ni_chan);
|
||||
ic->ic_curchan = selbs->ni_chan;
|
||||
ieee80211_reset_erp(ic);
|
||||
ieee80211_wme_initparams(ic);
|
||||
|
||||
@ -1085,6 +1089,177 @@ ieee80211_fakeup_adhoc_node(struct ieee80211_node_table *nt,
|
||||
return ni;
|
||||
}
|
||||
|
||||
#ifdef IEEE80211_DEBUG
|
||||
static void
|
||||
dump_probe_beacon(u_int8_t subtype, int isnew,
|
||||
const u_int8_t mac[IEEE80211_ADDR_LEN],
|
||||
const struct ieee80211_scanparams *sp)
|
||||
{
|
||||
|
||||
printf("[%s] %s%s on chan %u (bss chan %u) ",
|
||||
ether_sprintf(mac), isnew ? "new " : "",
|
||||
ieee80211_mgt_subtype_name[subtype >> IEEE80211_FC0_SUBTYPE_SHIFT],
|
||||
sp->chan, sp->bchan);
|
||||
ieee80211_print_essid(sp->ssid + 2, sp->ssid[1]);
|
||||
printf("\n");
|
||||
|
||||
if (isnew) {
|
||||
printf("[%s] caps 0x%x bintval %u erp 0x%x",
|
||||
ether_sprintf(mac), sp->capinfo, sp->bintval, sp->erp);
|
||||
if (sp->country != NULL) {
|
||||
#ifdef __FreeBSD__
|
||||
printf(" country info %*D",
|
||||
sp->country[1], sp->country+2, " ");
|
||||
#else
|
||||
int i;
|
||||
printf(" country info");
|
||||
for (i = 0; i < sp->country[1]; i++)
|
||||
printf(" %02x", sp->country[i+2]);
|
||||
#endif
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
#endif /* IEEE80211_DEBUG */
|
||||
|
||||
static void
|
||||
saveie(u_int8_t **iep, const u_int8_t *ie)
|
||||
{
|
||||
|
||||
if (ie == NULL)
|
||||
*iep = NULL;
|
||||
else
|
||||
ieee80211_saveie(iep, ie);
|
||||
}
|
||||
|
||||
/*
|
||||
* Process a beacon or probe response frame.
|
||||
*/
|
||||
void
|
||||
ieee80211_add_scan(struct ieee80211com *ic,
|
||||
const struct ieee80211_scanparams *sp,
|
||||
const struct ieee80211_frame *wh,
|
||||
int subtype, int rssi, int rstamp)
|
||||
{
|
||||
#define ISPROBE(_st) ((_st) == IEEE80211_FC0_SUBTYPE_PROBE_RESP)
|
||||
struct ieee80211_node_table *nt = &ic->ic_scan;
|
||||
struct ieee80211_node *ni;
|
||||
int newnode = 0;
|
||||
|
||||
ni = ieee80211_find_node(nt, wh->i_addr2);
|
||||
if (ni == NULL) {
|
||||
/*
|
||||
* Create a new entry.
|
||||
*/
|
||||
ni = ic->ic_node_alloc(nt);
|
||||
if (ni == NULL) {
|
||||
ic->ic_stats.is_rx_nodealloc++;
|
||||
return;
|
||||
}
|
||||
ieee80211_setup_node(nt, ni, wh->i_addr2);
|
||||
/*
|
||||
* XXX inherit from ic_bss.
|
||||
*/
|
||||
ni->ni_authmode = ic->ic_bss->ni_authmode;
|
||||
ni->ni_txpower = ic->ic_bss->ni_txpower;
|
||||
ni->ni_vlan = ic->ic_bss->ni_vlan; /* XXX?? */
|
||||
ieee80211_set_chan(ic, ni, ic->ic_curchan);
|
||||
ni->ni_rsn = ic->ic_bss->ni_rsn;
|
||||
newnode = 1;
|
||||
}
|
||||
#ifdef IEEE80211_DEBUG
|
||||
if (ieee80211_msg_scan(ic) && (ic->ic_flags & IEEE80211_F_SCAN))
|
||||
dump_probe_beacon(subtype, newnode, wh->i_addr2, sp);
|
||||
#endif
|
||||
/* XXX ap beaconing multiple ssid w/ same bssid */
|
||||
if (sp->ssid[1] != 0 &&
|
||||
(ISPROBE(subtype) || ni->ni_esslen == 0)) {
|
||||
ni->ni_esslen = sp->ssid[1];
|
||||
memset(ni->ni_essid, 0, sizeof(ni->ni_essid));
|
||||
memcpy(ni->ni_essid, sp->ssid + 2, sp->ssid[1]);
|
||||
}
|
||||
ni->ni_scangen = ic->ic_scan.nt_scangen;
|
||||
IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3);
|
||||
ni->ni_rssi = rssi;
|
||||
ni->ni_rstamp = rstamp;
|
||||
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_channels[sp->chan];
|
||||
ni->ni_fhdwell = sp->fhdwell;
|
||||
ni->ni_fhindex = sp->fhindex;
|
||||
ni->ni_erp = sp->erp;
|
||||
if (sp->tim != NULL) {
|
||||
struct ieee80211_tim_ie *ie =
|
||||
(struct ieee80211_tim_ie *) sp->tim;
|
||||
|
||||
ni->ni_dtim_count = ie->tim_count;
|
||||
ni->ni_dtim_period = ie->tim_period;
|
||||
}
|
||||
/*
|
||||
* Record the byte offset from the mac header to
|
||||
* the start of the TIM information element for
|
||||
* use by hardware and/or to speedup software
|
||||
* processing of beacon frames.
|
||||
*/
|
||||
ni->ni_timoff = sp->timoff;
|
||||
/*
|
||||
* Record optional information elements that might be
|
||||
* used by applications or drivers.
|
||||
*/
|
||||
saveie(&ni->ni_wme_ie, sp->wme);
|
||||
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 (!newnode)
|
||||
ieee80211_free_node(ni);
|
||||
#undef ISPROBE
|
||||
}
|
||||
|
||||
/*
|
||||
* Do node discovery in adhoc mode on receipt of a beacon
|
||||
* or probe response frame. Note that for the driver's
|
||||
* benefit we we treat this like an association so the
|
||||
* driver has an opportunity to setup it's private state.
|
||||
*/
|
||||
struct ieee80211_node *
|
||||
ieee80211_add_neighbor(struct ieee80211com *ic,
|
||||
const struct ieee80211_frame *wh,
|
||||
const struct ieee80211_scanparams *sp)
|
||||
{
|
||||
struct ieee80211_node *ni;
|
||||
|
||||
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);
|
||||
/* XXX not right for 802.1x/WPA */
|
||||
ieee80211_node_authorize(ni);
|
||||
}
|
||||
return ni;
|
||||
}
|
||||
|
||||
#define IS_CTL(wh) \
|
||||
((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL)
|
||||
#define IS_PSPOLL(wh) \
|
||||
|
@ -132,7 +132,7 @@ struct ieee80211_node {
|
||||
u_int8_t ni_esslen;
|
||||
u_int8_t ni_essid[IEEE80211_NWID_LEN];
|
||||
struct ieee80211_rateset ni_rates; /* negotiated rate set */
|
||||
struct ieee80211_channel *ni_chan;
|
||||
struct ieee80211_channel *ni_chan; /* XXX multiple uses */
|
||||
u_int16_t ni_fhdwell; /* FH only */
|
||||
u_int8_t ni_fhindex; /* FH only */
|
||||
u_int8_t ni_erp; /* ERP from beacon/probe resp */
|
||||
@ -293,4 +293,38 @@ struct ieee80211_node *ieee80211_fakeup_adhoc_node(
|
||||
void ieee80211_node_join(struct ieee80211com *, struct ieee80211_node *,int);
|
||||
void ieee80211_node_leave(struct ieee80211com *, struct ieee80211_node *);
|
||||
u_int8_t ieee80211_getrssi(struct ieee80211com *ic);
|
||||
|
||||
/*
|
||||
* Parameters supplied when adding/updating an entry in a
|
||||
* scan cache. Pointer variables should be set to NULL
|
||||
* if no data is available. Pointer references can be to
|
||||
* local data; any information that is saved will be copied.
|
||||
* All multi-byte values must be in host byte order.
|
||||
*/
|
||||
struct ieee80211_scanparams {
|
||||
u_int16_t capinfo; /* 802.11 capabilities */
|
||||
u_int16_t fhdwell; /* FHSS dwell interval */
|
||||
u_int8_t chan; /* */
|
||||
u_int8_t bchan;
|
||||
u_int8_t fhindex;
|
||||
u_int8_t erp;
|
||||
u_int16_t bintval;
|
||||
u_int8_t timoff;
|
||||
u_int8_t *tim;
|
||||
u_int8_t *tstamp;
|
||||
u_int8_t *country;
|
||||
u_int8_t *ssid;
|
||||
u_int8_t *rates;
|
||||
u_int8_t *xrates;
|
||||
u_int8_t *wpa;
|
||||
u_int8_t *wme;
|
||||
};
|
||||
|
||||
void ieee80211_add_scan(struct ieee80211com *,
|
||||
const struct ieee80211_scanparams *,
|
||||
const struct ieee80211_frame *,
|
||||
int subtype, int rssi, int rstamp);
|
||||
struct ieee80211_node *ieee80211_add_neighbor(struct ieee80211com *,
|
||||
const struct ieee80211_frame *,
|
||||
const struct ieee80211_scanparams *);
|
||||
#endif /* _NET80211_IEEE80211_NODE_H_ */
|
||||
|
@ -187,7 +187,7 @@ ieee80211_mgmt_output(struct ieee80211com *ic, struct ieee80211_node *ni,
|
||||
ieee80211_mgt_subtype_name[
|
||||
(type & IEEE80211_FC0_SUBTYPE_MASK) >>
|
||||
IEEE80211_FC0_SUBTYPE_SHIFT],
|
||||
ieee80211_chan2ieee(ic, ni->ni_chan));
|
||||
ieee80211_chan2ieee(ic, ic->ic_curchan));
|
||||
}
|
||||
#endif
|
||||
IEEE80211_NODE_STAT(ni, tx_mgmt);
|
||||
@ -236,7 +236,7 @@ ieee80211_send_nulldata(struct ieee80211_node *ni)
|
||||
IEEE80211_DPRINTF(ic, IEEE80211_MSG_DEBUG | IEEE80211_MSG_DUMPPKTS,
|
||||
"[%s] send null data frame on channel %u, pwr mgt %s\n",
|
||||
ether_sprintf(ni->ni_macaddr),
|
||||
ieee80211_chan2ieee(ic, ni->ni_chan),
|
||||
ieee80211_chan2ieee(ic, ic->ic_curchan),
|
||||
wh->i_fc[1] & IEEE80211_FC1_PWR_MGT ? "ena" : "dis");
|
||||
|
||||
IF_ENQUEUE(&ic->ic_mgtq, m); /* cheat */
|
||||
@ -999,7 +999,7 @@ ieee80211_send_probereq(struct ieee80211_node *ni,
|
||||
}
|
||||
|
||||
frm = ieee80211_add_ssid(frm, ssid, ssidlen);
|
||||
mode = ieee80211_chan2mode(ic, ni->ni_chan);
|
||||
mode = ieee80211_chan2mode(ic, ic->ic_curchan);
|
||||
frm = ieee80211_add_rates(frm, &ic->ic_sup_rates[mode]);
|
||||
frm = ieee80211_add_xrates(frm, &ic->ic_sup_rates[mode]);
|
||||
|
||||
@ -1027,7 +1027,7 @@ ieee80211_send_probereq(struct ieee80211_node *ni,
|
||||
IEEE80211_DPRINTF(ic, IEEE80211_MSG_DEBUG | IEEE80211_MSG_DUMPPKTS,
|
||||
"[%s] send probe req on channel %u\n",
|
||||
ether_sprintf(wh->i_addr1),
|
||||
ieee80211_chan2ieee(ic, ni->ni_chan));
|
||||
ieee80211_chan2ieee(ic, ic->ic_curchan));
|
||||
|
||||
IF_ENQUEUE(&ic->ic_mgtq, m);
|
||||
if_start(ic->ic_ifp);
|
||||
@ -1109,7 +1109,7 @@ ieee80211_send_mgmt(struct ieee80211com *ic, struct ieee80211_node *ni,
|
||||
if (ic->ic_flags & IEEE80211_F_PRIVACY)
|
||||
capinfo |= IEEE80211_CAPINFO_PRIVACY;
|
||||
if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
|
||||
IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
|
||||
IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
|
||||
capinfo |= IEEE80211_CAPINFO_SHORT_PREAMBLE;
|
||||
if (ic->ic_flags & IEEE80211_F_SHSLOT)
|
||||
capinfo |= IEEE80211_CAPINFO_SHORT_SLOTTIME;
|
||||
@ -1126,14 +1126,14 @@ ieee80211_send_mgmt(struct ieee80211com *ic, struct ieee80211_node *ni,
|
||||
*frm++ = ni->ni_fhdwell & 0x00ff;
|
||||
*frm++ = (ni->ni_fhdwell >> 8) & 0x00ff;
|
||||
*frm++ = IEEE80211_FH_CHANSET(
|
||||
ieee80211_chan2ieee(ic, ni->ni_chan));
|
||||
ieee80211_chan2ieee(ic, ic->ic_curchan));
|
||||
*frm++ = IEEE80211_FH_CHANPAT(
|
||||
ieee80211_chan2ieee(ic, ni->ni_chan));
|
||||
ieee80211_chan2ieee(ic, ic->ic_curchan));
|
||||
*frm++ = ni->ni_fhindex;
|
||||
} else {
|
||||
*frm++ = IEEE80211_ELEMID_DSPARMS;
|
||||
*frm++ = 1;
|
||||
*frm++ = ieee80211_chan2ieee(ic, ni->ni_chan);
|
||||
*frm++ = ieee80211_chan2ieee(ic, ic->ic_curchan);
|
||||
}
|
||||
|
||||
if (ic->ic_opmode == IEEE80211_M_IBSS) {
|
||||
@ -1265,7 +1265,7 @@ ieee80211_send_mgmt(struct ieee80211com *ic, struct ieee80211_node *ni,
|
||||
* short premable is set.
|
||||
*/
|
||||
if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
|
||||
IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
|
||||
IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
|
||||
capinfo |= IEEE80211_CAPINFO_SHORT_PREAMBLE;
|
||||
if ((ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME) &&
|
||||
(ic->ic_caps & IEEE80211_C_SHSLOT))
|
||||
@ -1321,7 +1321,7 @@ ieee80211_send_mgmt(struct ieee80211com *ic, struct ieee80211_node *ni,
|
||||
if (ic->ic_flags & IEEE80211_F_PRIVACY)
|
||||
capinfo |= IEEE80211_CAPINFO_PRIVACY;
|
||||
if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
|
||||
IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
|
||||
IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
|
||||
capinfo |= IEEE80211_CAPINFO_SHORT_PREAMBLE;
|
||||
if (ic->ic_flags & IEEE80211_F_SHSLOT)
|
||||
capinfo |= IEEE80211_CAPINFO_SHORT_SLOTTIME;
|
||||
|
@ -922,7 +922,7 @@ ieee80211_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg
|
||||
* beacons on the channel.
|
||||
*/
|
||||
if ((ic->ic_flags & IEEE80211_F_ASCAN) &&
|
||||
(ni->ni_chan->ic_flags & IEEE80211_CHAN_PASSIVE) == 0) {
|
||||
(ic->ic_curchan->ic_flags & IEEE80211_CHAN_PASSIVE) == 0) {
|
||||
ieee80211_send_probereq(ni,
|
||||
ic->ic_myaddr, ifp->if_broadcastaddr,
|
||||
ifp->if_broadcastaddr,
|
||||
@ -1043,7 +1043,7 @@ ieee80211_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg
|
||||
ieee80211_print_essid(ic->ic_bss->ni_essid,
|
||||
ni->ni_esslen);
|
||||
printf(" channel %d start %uMb\n",
|
||||
ieee80211_chan2ieee(ic, ni->ni_chan),
|
||||
ieee80211_chan2ieee(ic, ic->ic_curchan),
|
||||
IEEE80211_RATE2MBS(ni->ni_rates.rs_rates[ni->ni_txrate]));
|
||||
}
|
||||
#endif
|
||||
|
@ -61,6 +61,7 @@ int ieee80211_input(struct ieee80211com *, struct mbuf *,
|
||||
struct ieee80211_node *, int, u_int32_t);
|
||||
int ieee80211_setup_rates(struct ieee80211_node *ni,
|
||||
const u_int8_t *rates, const u_int8_t *xrates, int flags);
|
||||
void ieee80211_saveie(u_int8_t **, const u_int8_t *);
|
||||
void ieee80211_recv_mgmt(struct ieee80211com *, struct mbuf *,
|
||||
struct ieee80211_node *, int, int, u_int32_t);
|
||||
int ieee80211_send_nulldata(struct ieee80211_node *);
|
||||
|
@ -136,6 +136,7 @@ struct ieee80211com {
|
||||
struct bpf_if *ic_rawbpf; /* packet filter structure */
|
||||
struct ieee80211_node *ic_bss; /* information for this node */
|
||||
struct ieee80211_channel *ic_ibss_chan;
|
||||
struct ieee80211_channel *ic_curchan; /* current channel */
|
||||
int ic_fixed_rate; /* index to ic_sup_rates[] */
|
||||
u_int16_t ic_rtsthreshold;
|
||||
u_int16_t ic_fragthreshold;
|
||||
|
Loading…
Reference in New Issue
Block a user