summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2005-07-22 21:11:26 +0000
committersam <sam@FreeBSD.org>2005-07-22 21:11:26 +0000
commite4bb8fb68f00d88f5362f278abb4cd2e326285f7 (patch)
tree2cd048b051600ca3675d42b8b6ea39c9bd58c781 /sys
parentbd0efadacda73f031838bab860b64bc4f02b89c4 (diff)
downloadFreeBSD-src-e4bb8fb68f00d88f5362f278abb4cd2e326285f7.zip
FreeBSD-src-e4bb8fb68f00d88f5362f278abb4cd2e326285f7.tar.gz
split xmit of probe request frame out into a separate routine that
takes explicit parameters; this will be needed when scanning is decoupled from the state machine to do bg scanning MFC after: 3 days
Diffstat (limited to 'sys')
-rw-r--r--sys/net80211/ieee80211_node.c15
-rw-r--r--sys/net80211/ieee80211_output.c118
-rw-r--r--sys/net80211/ieee80211_proto.c7
-rw-r--r--sys/net80211/ieee80211_proto.h6
4 files changed, 96 insertions, 50 deletions
diff --git a/sys/net80211/ieee80211_node.c b/sys/net80211/ieee80211_node.c
index a2fe867..29b8d99 100644
--- a/sys/net80211/ieee80211_node.c
+++ b/sys/net80211/ieee80211_node.c
@@ -335,22 +335,7 @@ ieee80211_next_scan(struct ieee80211com *ic)
ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan),
ieee80211_chan2ieee(ic, chan));
ieee80211_set_chan(ic, ic->ic_bss, chan);
-#ifdef notyet
- /* XXX driver state change */
- /*
- * Scan next channel. If doing an active scan
- * and the channel is not marked passive-only
- * then send a probe request. Otherwise just
- * listen for beacons on the channel.
- */
- if ((ic->ic_flags & IEEE80211_F_ASCAN) &&
- (ni->ni_chan->ic_flags & IEEE80211_CHAN_PASSIVE) == 0) {
- IEEE80211_SEND_MGMT(ic, ni,
- IEEE80211_FC0_SUBTYPE_PROBE_REQ, 0);
- }
-#else
ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
-#endif
return 1;
}
} while (chan != ic->ic_bss->ni_chan);
diff --git a/sys/net80211/ieee80211_output.c b/sys/net80211/ieee80211_output.c
index d92603d..eb558a5 100644
--- a/sys/net80211/ieee80211_output.c
+++ b/sys/net80211/ieee80211_output.c
@@ -945,6 +945,91 @@ ieee80211_add_wme_param(u_int8_t *frm, struct ieee80211_wme_state *wme)
#undef WME_OUI_BYTES
/*
+ * Send a probe request frame with the specified ssid
+ * and any optional information element data.
+ */
+int
+ieee80211_send_probereq(struct ieee80211_node *ni,
+ const u_int8_t sa[IEEE80211_ADDR_LEN],
+ const u_int8_t da[IEEE80211_ADDR_LEN],
+ const u_int8_t bssid[IEEE80211_ADDR_LEN],
+ const u_int8_t *ssid, size_t ssidlen,
+ const void *optie, size_t optielen)
+{
+ struct ieee80211com *ic = ni->ni_ic;
+ enum ieee80211_phymode mode;
+ struct ieee80211_frame *wh;
+ struct mbuf *m;
+ u_int8_t *frm;
+
+ /*
+ * 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(ic, IEEE80211_MSG_NODE,
+ "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n",
+ __func__, __LINE__,
+ ni, ether_sprintf(ni->ni_macaddr),
+ ieee80211_node_refcnt(ni)+1);
+ ieee80211_ref_node(ni);
+
+ /*
+ * prreq frame format
+ * [tlv] ssid
+ * [tlv] supported rates
+ * [tlv] extended supported rates
+ * [tlv] user-specified ie's
+ */
+ m = ieee80211_getmgtframe(&frm,
+ 2 + IEEE80211_NWID_LEN
+ + 2 + IEEE80211_RATE_SIZE
+ + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE)
+ + (optie != NULL ? optielen : 0)
+ );
+ if (m == NULL) {
+ ic->ic_stats.is_tx_nobuf++;
+ ieee80211_free_node(ni);
+ return ENOMEM;
+ }
+
+ frm = ieee80211_add_ssid(frm, ssid, ssidlen);
+ mode = ieee80211_chan2mode(ic, ni->ni_chan);
+ frm = ieee80211_add_rates(frm, &ic->ic_sup_rates[mode]);
+ frm = ieee80211_add_xrates(frm, &ic->ic_sup_rates[mode]);
+
+ if (optie != NULL) {
+ memcpy(frm, optie, optielen);
+ frm += optielen;
+ }
+ m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
+
+ M_PREPEND(m, sizeof(struct ieee80211_frame), M_DONTWAIT);
+ if (m == NULL)
+ return ENOMEM;
+ KASSERT(m->m_pkthdr.rcvif == NULL, ("rcvif not null"));
+ m->m_pkthdr.rcvif = (void *)ni;
+
+ wh = mtod(m, struct ieee80211_frame *);
+ ieee80211_send_setup(ic, ni, wh,
+ IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_REQ,
+ sa, da, bssid);
+ /* XXX power management? */
+
+ IEEE80211_NODE_STAT(ni, tx_probereq);
+ IEEE80211_NODE_STAT(ni, tx_mgmt);
+
+ 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));
+
+ IF_ENQUEUE(&ic->ic_mgtq, m);
+ if_start(ic->ic_ifp);
+ return 0;
+}
+
+/*
* Send a management frame. The node is for the destination (or ic_bss
* when in station mode). Nodes other than ic_bss have their reference
* count bumped to reflect our use for an indeterminant time.
@@ -956,7 +1041,6 @@ ieee80211_send_mgmt(struct ieee80211com *ic, struct ieee80211_node *ni,
#define senderr(_x, _v) do { ic->ic_stats._v++; ret = _x; goto bad; } while (0)
struct mbuf *m;
u_int8_t *frm;
- enum ieee80211_phymode mode;
u_int16_t capinfo;
int has_challenge, is_shared_key, ret, timer, status;
@@ -976,38 +1060,6 @@ ieee80211_send_mgmt(struct ieee80211com *ic, struct ieee80211_node *ni,
timer = 0;
switch (type) {
- case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
- /*
- * prreq frame format
- * [tlv] ssid
- * [tlv] supported rates
- * [tlv] extended supported rates
- * [tlv] user-specified ie's
- */
- m = ieee80211_getmgtframe(&frm,
- 2 + IEEE80211_NWID_LEN
- + 2 + IEEE80211_RATE_SIZE
- + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE)
- + (ic->ic_opt_ie != NULL ? ic->ic_opt_ie_len : 0)
- );
- if (m == NULL)
- senderr(ENOMEM, is_tx_nobuf);
-
- frm = ieee80211_add_ssid(frm, ic->ic_des_essid, ic->ic_des_esslen);
- mode = ieee80211_chan2mode(ic, ni->ni_chan);
- frm = ieee80211_add_rates(frm, &ic->ic_sup_rates[mode]);
- frm = ieee80211_add_xrates(frm, &ic->ic_sup_rates[mode]);
- if (ic->ic_opt_ie != NULL) {
- memcpy(frm, ic->ic_opt_ie, ic->ic_opt_ie_len);
- frm += ic->ic_opt_ie_len;
- }
- m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
-
- IEEE80211_NODE_STAT(ni, tx_probereq);
- if (ic->ic_opmode == IEEE80211_M_STA)
- timer = IEEE80211_TRANS_WAIT;
- break;
-
case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
/*
* probe response frame format
diff --git a/sys/net80211/ieee80211_proto.c b/sys/net80211/ieee80211_proto.c
index 0288b0d..b76d576 100644
--- a/sys/net80211/ieee80211_proto.c
+++ b/sys/net80211/ieee80211_proto.c
@@ -923,8 +923,11 @@ ieee80211_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg
*/
if ((ic->ic_flags & IEEE80211_F_ASCAN) &&
(ni->ni_chan->ic_flags & IEEE80211_CHAN_PASSIVE) == 0) {
- IEEE80211_SEND_MGMT(ic, ni,
- IEEE80211_FC0_SUBTYPE_PROBE_REQ, 0);
+ ieee80211_send_probereq(ni,
+ ic->ic_myaddr, ifp->if_broadcastaddr,
+ ifp->if_broadcastaddr,
+ ic->ic_des_essid, ic->ic_des_esslen,
+ ic->ic_opt_ie, ic->ic_opt_ie_len);
}
break;
case IEEE80211_S_RUN:
diff --git a/sys/net80211/ieee80211_proto.h b/sys/net80211/ieee80211_proto.h
index 6e14824..18a4211 100644
--- a/sys/net80211/ieee80211_proto.h
+++ b/sys/net80211/ieee80211_proto.h
@@ -64,6 +64,12 @@ int ieee80211_setup_rates(struct ieee80211_node *ni,
void ieee80211_recv_mgmt(struct ieee80211com *, struct mbuf *,
struct ieee80211_node *, int, int, u_int32_t);
int ieee80211_send_nulldata(struct ieee80211_node *);
+int ieee80211_send_probereq(struct ieee80211_node *ni,
+ const u_int8_t sa[IEEE80211_ADDR_LEN],
+ const u_int8_t da[IEEE80211_ADDR_LEN],
+ const u_int8_t bssid[IEEE80211_ADDR_LEN],
+ const u_int8_t *ssid, size_t ssidlen,
+ const void *optie, size_t optielen);
int ieee80211_send_mgmt(struct ieee80211com *, struct ieee80211_node *,
int, int);
int ieee80211_classify(struct ieee80211com *, struct mbuf *,
OpenPOWER on IntegriCloud