Date: Fri, 22 Feb 2008 17:48:39 GMT From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 135978 for review Message-ID: <200802221748.m1MHmdJ8034520@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=135978 Change 135978 by sam@sam_ebb on 2008/02/22 17:47:37 Apply long-overdue overhaul of probe response handling in ap mode: o eliminate use of temporary node to send probe response; use the bss node for a reference and pass the destination mac address explicitly (instead of taking it from the node) o drop atheros ie processing; not clear it was ever useful (though possibly it was used to propagate the default wep key for shared key auth) o don't avg rssi for received probe request frames o don't do rate set negotiation; it was unnecessary o check for 11b client better (I think); could still be optimized and should probably move to common code so it can be shared between ap and adhoc code o add ieee80211_send_proberesp to send a probe response frame; need to think about best way to integrate this into the tx mgt path so drivers can override Affected files ... .. //depot/projects/vap/sys/net80211/ieee80211_adhoc.c#7 edit .. //depot/projects/vap/sys/net80211/ieee80211_hostap.c#17 edit .. //depot/projects/vap/sys/net80211/ieee80211_output.c#35 edit .. //depot/projects/vap/sys/net80211/ieee80211_proto.h#14 edit Differences ... ==== //depot/projects/vap/sys/net80211/ieee80211_adhoc.c#7 (text+ko) ==== @@ -641,6 +641,23 @@ #undef SEQ_LEQ } +static int +is11bclient(const uint8_t *rates, const uint8_t *xrates) +{ + static const uint32_t brates = (1<<2*1)|(1<<2*2)|(1<<11)|(1<<2*11); + int i; + + /* NB: the 11b clients we care about will not have xrates */ + if (xrates != NULL || rates == NULL) + return 0; + for (i = 0; i < rates[1]; i++) { + int r = rates[2+i] & IEEE80211_RATE_VAL; + if (r > 2*11 || ((1<<r) & brates) == 0) + return 0; + } + return 1; +} + static void adhoc_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, int subtype, int rssi, int noise, uint32_t rstamp) @@ -649,9 +666,7 @@ struct ieee80211com *ic = ni->ni_ic; struct ieee80211_frame *wh; uint8_t *frm, *efrm, *sfrm; - uint8_t *ssid, *rates, *xrates, *ath; - int allocbs; - uint8_t rate; + uint8_t *ssid, *rates, *xrates; wh = mtod(m0, struct ieee80211_frame *); frm = (uint8_t *)&wh[1]; @@ -740,7 +755,7 @@ * [tlv] extended supported rates * [tlv] Atheros capabilities */ - ssid = rates = xrates = ath = NULL; + ssid = rates = xrates = NULL; sfrm = frm; while (efrm - frm > 1) { IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2, return); @@ -754,10 +769,6 @@ case IEEE80211_ELEMID_XRATES: xrates = frm; break; - case IEEE80211_ELEMID_VENDOR: - if (isatherosoui(frm)) - ath = frm; - break; } frm += frm[1] + 2; } @@ -775,62 +786,17 @@ return; } - if (ni == vap->iv_bss) { - 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 - * send the response so blindly add them to the - * neighbor table. - */ - ni = ieee80211_fakeup_adhoc_node(vap, - wh->i_addr2); - } - if (ni == NULL) - return; - allocbs = 1; - } else - allocbs = 0; /* XXX find a better class or define it's own */ IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_INPUT, wh->i_addr2, "%s", "recv probe req"); - IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi); - ni->ni_rstamp = rstamp; - rate = ieee80211_setup_rates(ni, rates, xrates, - IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE - | IEEE80211_F_DONEGO | IEEE80211_F_DODEL); - if (rate & IEEE80211_RATE_BASIC) { - IEEE80211_DISCARD(vap, IEEE80211_MSG_XRATE, - wh, NULL, "%s", "recv'd rate set invalid"); - } else { - /* - * Some legacy 11b clients cannot hack a complete - * probe response frame. When the request includes - * only a bare-bones rate set, communicate this to - * the transmit side through the "arg parameters". - * - * NB: using the max rate is a bit of a hack. - */ - IEEE80211_SEND_MGMT(ni, - IEEE80211_FC0_SUBTYPE_PROBE_RESP, - rate < 48 ? IEEE80211_SEND_LEGACY_11B : 0); - } - if (allocbs) { - /* - * Temporary node created just to send a - * response, reclaim immediately. - */ - ieee80211_free_node(ni); - } else if (ath != NULL) { - if (ieee80211_ies_init(&ni->ni_ies, sfrm, efrm-sfrm)) { - ieee80211_ies_setie(ni->ni_ies, ath_ie, - ath - sfrm); - ieee80211_parse_ath(ni, ni->ni_ies.ath_ie); - } else - ni->ni_ath_flags = 0; - } + /* + * Some legacy 11b clients cannot hack a complete + * probe response frame. When the request includes + * only a bare-bones rate set, communicate this to + * the transmit side. + */ + ieee80211_send_proberesp(vap, wh->i_addr2, + is11bclient(rates, xrates) ? IEEE80211_SEND_LEGACY_11B : 0); break; case IEEE80211_FC0_SUBTYPE_ACTION: { ==== //depot/projects/vap/sys/net80211/ieee80211_hostap.c#17 (text+ko) ==== @@ -1629,6 +1629,23 @@ IEEE80211_HTINFO_OPMODE_MIXED; } +static int +is11bclient(const uint8_t *rates, const uint8_t *xrates) +{ + static const uint32_t brates = (1<<2*1)|(1<<2*2)|(1<<11)|(1<<2*11); + int i; + + /* NB: the 11b clients we care about will not have xrates */ + if (xrates != NULL || rates == NULL) + return 0; + for (i = 0; i < rates[1]; i++) { + int r = rates[2+i] & IEEE80211_RATE_VAL; + if (r > 2*11 || ((1<<r) & brates) == 0) + return 0; + } + return 1; +} + static void hostap_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, int subtype, int rssi, int noise, uint32_t rstamp) @@ -1638,7 +1655,7 @@ struct ieee80211_frame *wh; uint8_t *frm, *efrm, *sfrm; uint8_t *ssid, *rates, *xrates, *wpa, *rsn, *wme, *ath, *htcap; - int reassoc, resp, allocbs; + int reassoc, resp; uint8_t rate; wh = mtod(m0, struct ieee80211_frame *); @@ -1750,15 +1767,13 @@ vap->iv_stats.is_rx_mgtdiscard++; return; } - /* * prreq frame format * [tlv] ssid * [tlv] supported rates * [tlv] extended supported rates - * [tlv] Atheros capabilities */ - ssid = rates = xrates = ath = NULL; + ssid = rates = xrates = NULL; sfrm = frm; while (efrm - frm > 1) { IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2, return); @@ -1772,10 +1787,6 @@ case IEEE80211_ELEMID_XRATES: xrates = frm; break; - case IEEE80211_ELEMID_VENDOR: - if (isatherosoui(frm)) - ath = frm; - break; } frm += frm[1] + 2; } @@ -1793,51 +1804,17 @@ return; } - if (ni == vap->iv_bss) { - ni = ieee80211_tmp_node(vap, wh->i_addr2); - if (ni == NULL) - return; - allocbs = 1; - } else - allocbs = 0; /* XXX find a better class or define it's own */ IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_INPUT, wh->i_addr2, "%s", "recv probe req"); - IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi); - ni->ni_rstamp = rstamp; - rate = ieee80211_setup_rates(ni, rates, xrates, - IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE - | IEEE80211_F_DONEGO | IEEE80211_F_DODEL); - if (rate & IEEE80211_RATE_BASIC) { - IEEE80211_DISCARD(vap, IEEE80211_MSG_XRATE, - wh, NULL, "%s", "recv'd rate set invalid"); - } else { - /* - * Some legacy 11b clients cannot hack a complete - * probe response frame. When the request includes - * only a bare-bones rate set, communicate this to - * the transmit side through the "arg parameters". - * - * NB: using the max rate is a bit of a hack. - */ - IEEE80211_SEND_MGMT(ni, - IEEE80211_FC0_SUBTYPE_PROBE_RESP, - rate < 48 ? IEEE80211_SEND_LEGACY_11B : 0); - } - if (allocbs) { - /* - * Temporary node created just to send a - * response, reclaim immediately. - */ - ieee80211_free_node(ni); - } else if (ath != NULL) { - if (ieee80211_ies_init(&ni->ni_ies, sfrm, efrm-sfrm)) { - ieee80211_ies_setie(ni->ni_ies, ath_ie, - ath - sfrm); - ieee80211_parse_ath(ni, ni->ni_ies.ath_ie); - } else - ni->ni_ath_flags = 0; - } + /* + * Some legacy 11b clients cannot hack a complete + * probe response frame. When the request includes + * only a bare-bones rate set, communicate this to + * the transmit side. + */ + ieee80211_send_proberesp(vap, wh->i_addr2, + is11bclient(rates, xrates) ? IEEE80211_SEND_LEGACY_11B : 0); break; case IEEE80211_FC0_SUBTYPE_AUTH: { ==== //depot/projects/vap/sys/net80211/ieee80211_output.c#35 (text+ko) ==== @@ -1721,7 +1721,6 @@ struct ieee80211vap *vap = ni->ni_vap; struct ieee80211com *ic = ni->ni_ic; struct ieee80211_node *bss = vap->iv_bss; - const struct ieee80211_rateset *rs; struct mbuf *m; uint8_t *frm; uint16_t capinfo; @@ -1742,139 +1741,7 @@ ieee80211_ref_node(ni); switch (type) { - case IEEE80211_FC0_SUBTYPE_PROBE_RESP: - /* - * probe response frame format - * [8] time stamp - * [2] beacon interval - * [2] cabability information - * [tlv] ssid - * [tlv] supported rates - * [tlv] parameter set (FH/DS) - * [tlv] parameter set (IBSS) - * [tlv] country (optional) - * [tlv] RSN (optional) - * [3] power control (optional) - * [5] channel switch announcement (CSA) (optional) - * [tlv] extended rate phy (ERP) - * [tlv] extended supported rates - * [tlv] HT capabilities - * [tlv] HT information - * [tlv] WPA (optional) - * [tlv] WME (optional) - * [tlv] Vendor OUI HT capabilities (optional) - * [tlv] Vendor OUI HT information (optional) - * [tlv] Atheros capabilities - * [tlv] AppIE's (optional) - */ - m = ieee80211_getmgtframe(&frm, - ic->ic_headroom + sizeof(struct ieee80211_frame), - 8 - + sizeof(uint16_t) - + sizeof(uint16_t) - + 2 + IEEE80211_NWID_LEN - + 2 + IEEE80211_RATE_SIZE - + 7 /* max(7,3) */ - + sizeof(struct ieee80211_country_ie) - + sizeof(struct ieee80211_ie_wpa) - + 3 - + sizeof(struct ieee80211_csa_ie) - + 3 - + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE) - + sizeof(struct ieee80211_ie_htcap) - + sizeof(struct ieee80211_ie_htinfo) - + sizeof(struct ieee80211_ie_wpa) - + sizeof(struct ieee80211_wme_param) - + 4 + sizeof(struct ieee80211_ie_htcap) - + 4 + sizeof(struct ieee80211_ie_htinfo) - + sizeof(struct ieee80211_ath_ie) - + (vap->iv_appie_proberesp != NULL ? - vap->iv_appie_proberesp->ie_len : 0) - ); - if (m == NULL) - senderr(ENOMEM, is_tx_nobuf); - - memset(frm, 0, 8); /* timestamp should be filled later */ - frm += 8; - *(uint16_t *)frm = htole16(bss->ni_intval); - frm += 2; - capinfo = getcapinfo(vap, bss->ni_chan); - *(uint16_t *)frm = htole16(capinfo); - frm += 2; - - frm = ieee80211_add_ssid(frm, bss->ni_essid, bss->ni_esslen); - rs = ieee80211_get_suprates(ic, bss->ni_chan); - frm = ieee80211_add_rates(frm, rs); - - if (IEEE80211_IS_CHAN_FHSS(bss->ni_chan)) { - *frm++ = IEEE80211_ELEMID_FHPARMS; - *frm++ = 5; - *frm++ = ni->ni_fhdwell & 0x00ff; - *frm++ = (ni->ni_fhdwell >> 8) & 0x00ff; - *frm++ = IEEE80211_FH_CHANSET( - ieee80211_chan2ieee(ic, bss->ni_chan)); - *frm++ = IEEE80211_FH_CHANPAT( - ieee80211_chan2ieee(ic, bss->ni_chan)); - *frm++ = ni->ni_fhindex; - } else { - *frm++ = IEEE80211_ELEMID_DSPARMS; - *frm++ = 1; - *frm++ = ieee80211_chan2ieee(ic, bss->ni_chan); - } - if (vap->iv_opmode == IEEE80211_M_IBSS) { - *frm++ = IEEE80211_ELEMID_IBSSPARMS; - *frm++ = 2; - *frm++ = 0; *frm++ = 0; /* TODO: ATIM window */ - } - if (vap->iv_flags & IEEE80211_F_DOTH) - frm = ieee80211_add_countryie(frm, ic); - if (vap->iv_flags & IEEE80211_F_WPA2) { - if (vap->iv_rsn_ie != NULL) - frm = add_ie(frm, vap->iv_rsn_ie); - /* XXX else complain? */ - } - if (vap->iv_flags & IEEE80211_F_DOTH) { - if (IEEE80211_IS_CHAN_5GHZ(bss->ni_chan)) - frm = ieee80211_add_powerconstraint(frm, vap); - if (ic->ic_flags & IEEE80211_F_CSAPENDING) - frm = ieee80211_add_csa(frm, vap); - } - if (IEEE80211_IS_CHAN_ANYG(bss->ni_chan)) - frm = ieee80211_add_erp(frm, ic); - frm = ieee80211_add_xrates(frm, rs); - /* - * NB: legacy 11b clients do not get certain ie's. - * The caller identifies such clients by passing - * a token in arg to us. Could expand this to be - * any legacy client for stuff like HT ie's. - */ - if (IEEE80211_IS_CHAN_HT(bss->ni_chan) && - arg != IEEE80211_SEND_LEGACY_11B) { - frm = ieee80211_add_htcap(frm, bss); - frm = ieee80211_add_htinfo(frm, bss); - } - if (vap->iv_flags & IEEE80211_F_WPA1) { - if (vap->iv_wpa_ie != NULL) - frm = add_ie(frm, vap->iv_wpa_ie); - /* XXX else complain? */ - } - if (vap->iv_flags & IEEE80211_F_WME) - frm = ieee80211_add_wme_param(frm, &ic->ic_wme); - if (IEEE80211_IS_CHAN_HT(bss->ni_chan) && - (vap->iv_flags_ext & IEEE80211_FEXT_HTCOMPAT) && - arg != IEEE80211_SEND_LEGACY_11B) { - frm = ieee80211_add_htcap_vendor(frm, bss); - frm = ieee80211_add_htinfo_vendor(frm, bss); - } - if (ni->ni_ies.ath_ie != NULL) - frm = ieee80211_add_ath(frm, ni->ni_ath_flags, - ni->ni_ath_defkeyix); - if (vap->iv_appie_proberesp != NULL) - frm = add_appie(frm, vap->iv_appie_proberesp); - m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); - break; - case IEEE80211_FC0_SUBTYPE_AUTH: status = arg >> 16; arg &= 0xffff; @@ -2169,6 +2036,195 @@ #undef HTFLAGS } +/* + * Send a probe response frame to the specified mac address. + * This does not go through the normal mgt frame api so we + * can specify the destination address and re-use the bss node + * for the sta reference. + */ +int +ieee80211_send_proberesp(struct ieee80211vap *vap, + const uint8_t da[IEEE80211_ADDR_LEN], int legacy) +{ + struct ieee80211_node *bss = vap->iv_bss; + struct ieee80211com *ic = vap->iv_ic; + struct ieee80211_frame *wh; + const struct ieee80211_rateset *rs; + struct mbuf *m; + uint16_t capinfo; + uint8_t *frm; + + if (vap->iv_state == IEEE80211_S_CAC) { + IEEE80211_NOTE(vap, IEEE80211_MSG_OUTPUT, bss, + "block %s frame in CAC state", "probe response"); + vap->iv_stats.is_tx_badstate++; + return EIO; /* XXX */ + } + + /* + * Hold a reference on the node so it doesn't go away until after + * the xmit is complete all the way in the driver. On error we + * will remove our reference. + */ + IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE, + "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n", + __func__, __LINE__, + bss, ether_sprintf(bss->ni_macaddr), + ieee80211_node_refcnt(bss)+1); + ieee80211_ref_node(bss); + + /* + * probe response frame format + * [8] time stamp + * [2] beacon interval + * [2] cabability information + * [tlv] ssid + * [tlv] supported rates + * [tlv] parameter set (FH/DS) + * [tlv] parameter set (IBSS) + * [tlv] country (optional) + * [tlv] RSN (optional) + * [3] power control (optional) + * [5] channel switch announcement (CSA) (optional) + * [tlv] extended rate phy (ERP) + * [tlv] extended supported rates + * [tlv] HT capabilities + * [tlv] HT information + * [tlv] WPA (optional) + * [tlv] WME (optional) + * [tlv] Vendor OUI HT capabilities (optional) + * [tlv] Vendor OUI HT information (optional) + * [tlv] Atheros capabilities + * [tlv] AppIE's (optional) + */ + m = ieee80211_getmgtframe(&frm, + ic->ic_headroom + sizeof(struct ieee80211_frame), + 8 + + sizeof(uint16_t) + + sizeof(uint16_t) + + 2 + IEEE80211_NWID_LEN + + 2 + IEEE80211_RATE_SIZE + + 7 /* max(7,3) */ + + sizeof(struct ieee80211_country_ie) + + sizeof(struct ieee80211_ie_wpa) + + 3 + + sizeof(struct ieee80211_csa_ie) + + 3 + + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE) + + sizeof(struct ieee80211_ie_htcap) + + sizeof(struct ieee80211_ie_htinfo) + + sizeof(struct ieee80211_ie_wpa) + + sizeof(struct ieee80211_wme_param) + + 4 + sizeof(struct ieee80211_ie_htcap) + + 4 + sizeof(struct ieee80211_ie_htinfo) + + sizeof(struct ieee80211_ath_ie) + + (vap->iv_appie_proberesp != NULL ? + vap->iv_appie_proberesp->ie_len : 0) + ); + if (m == NULL) { + vap->iv_stats.is_tx_nobuf++; + ieee80211_free_node(bss); + return ENOMEM; + } + + memset(frm, 0, 8); /* timestamp should be filled later */ + frm += 8; + *(uint16_t *)frm = htole16(bss->ni_intval); + frm += 2; + capinfo = getcapinfo(vap, bss->ni_chan); + *(uint16_t *)frm = htole16(capinfo); + frm += 2; + + frm = ieee80211_add_ssid(frm, bss->ni_essid, bss->ni_esslen); + rs = ieee80211_get_suprates(ic, bss->ni_chan); + frm = ieee80211_add_rates(frm, rs); + + if (IEEE80211_IS_CHAN_FHSS(bss->ni_chan)) { + *frm++ = IEEE80211_ELEMID_FHPARMS; + *frm++ = 5; + *frm++ = bss->ni_fhdwell & 0x00ff; + *frm++ = (bss->ni_fhdwell >> 8) & 0x00ff; + *frm++ = IEEE80211_FH_CHANSET( + ieee80211_chan2ieee(ic, bss->ni_chan)); + *frm++ = IEEE80211_FH_CHANPAT( + ieee80211_chan2ieee(ic, bss->ni_chan)); + *frm++ = bss->ni_fhindex; + } else { + *frm++ = IEEE80211_ELEMID_DSPARMS; + *frm++ = 1; + *frm++ = ieee80211_chan2ieee(ic, bss->ni_chan); + } + + if (vap->iv_opmode == IEEE80211_M_IBSS) { + *frm++ = IEEE80211_ELEMID_IBSSPARMS; + *frm++ = 2; + *frm++ = 0; *frm++ = 0; /* TODO: ATIM window */ + } + if (vap->iv_flags & IEEE80211_F_DOTH) + frm = ieee80211_add_countryie(frm, ic); + if (vap->iv_flags & IEEE80211_F_WPA2) { + if (vap->iv_rsn_ie != NULL) + frm = add_ie(frm, vap->iv_rsn_ie); + /* XXX else complain? */ + } + if (vap->iv_flags & IEEE80211_F_DOTH) { + if (IEEE80211_IS_CHAN_5GHZ(bss->ni_chan)) + frm = ieee80211_add_powerconstraint(frm, vap); + if (ic->ic_flags & IEEE80211_F_CSAPENDING) + frm = ieee80211_add_csa(frm, vap); + } + if (IEEE80211_IS_CHAN_ANYG(bss->ni_chan)) + frm = ieee80211_add_erp(frm, ic); + frm = ieee80211_add_xrates(frm, rs); + /* + * NB: legacy 11b clients do not get certain ie's. + * The caller identifies such clients by passing + * a token in legacy to us. Could expand this to be + * any legacy client for stuff like HT ie's. + */ + if (IEEE80211_IS_CHAN_HT(bss->ni_chan) && + legacy != IEEE80211_SEND_LEGACY_11B) { + frm = ieee80211_add_htcap(frm, bss); + frm = ieee80211_add_htinfo(frm, bss); + } + if (vap->iv_flags & IEEE80211_F_WPA1) { + if (vap->iv_wpa_ie != NULL) + frm = add_ie(frm, vap->iv_wpa_ie); + /* XXX else complain? */ + } + if (vap->iv_flags & IEEE80211_F_WME) + frm = ieee80211_add_wme_param(frm, &ic->ic_wme); + if (IEEE80211_IS_CHAN_HT(bss->ni_chan) && + (vap->iv_flags_ext & IEEE80211_FEXT_HTCOMPAT) && + legacy != IEEE80211_SEND_LEGACY_11B) { + frm = ieee80211_add_htcap_vendor(frm, bss); + frm = ieee80211_add_htinfo_vendor(frm, bss); + } + if (bss->ni_ies.ath_ie != NULL && legacy != IEEE80211_SEND_LEGACY_11B) + frm = ieee80211_add_ath(frm, bss->ni_ath_flags, + bss->ni_ath_defkeyix); + if (vap->iv_appie_proberesp != NULL) + frm = add_appie(frm, vap->iv_appie_proberesp); + m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); + + M_PREPEND(m, sizeof(struct ieee80211_frame), M_DONTWAIT); + KASSERT(m != NULL, ("no room for header")); + + wh = mtod(m, struct ieee80211_frame *); + ieee80211_send_setup(bss, wh, + IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP, + vap->iv_myaddr, da, bss->ni_bssid); + /* XXX power management? */ + + IEEE80211_NODE_STAT(bss, tx_mgmt); + + IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_DEBUG | IEEE80211_MSG_DUMPPKTS, + wh->i_addr1, "send probe resp on channel %u", + ieee80211_chan2ieee(ic, ic->ic_curchan)); + + return ic->ic_raw_xmit(bss, m, NULL); +} + static void ieee80211_tx_mgt_timeout(void *arg) { ==== //depot/projects/vap/sys/net80211/ieee80211_proto.h#14 (text+ko) ==== @@ -89,6 +89,8 @@ const uint8_t da[IEEE80211_ADDR_LEN], const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t *ssid, size_t ssidlen); +int ieee80211_send_proberesp(struct ieee80211vap *, + const uint8_t da[IEEE80211_ADDR_LEN], int); struct mbuf *ieee80211_encap(struct ieee80211_node *, struct mbuf *); void ieee80211_reset_erp(struct ieee80211com *);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200802221748.m1MHmdJ8034520>