summaryrefslogtreecommitdiff
path: root/sys/net80211
diff options
context:
space:
mode:
Diffstat (limited to 'sys/net80211')
-rw-r--r--sys/net80211/ieee80211_output.c92
-rw-r--r--sys/net80211/ieee80211_proto.h4
2 files changed, 94 insertions, 2 deletions
diff --git a/sys/net80211/ieee80211_output.c b/sys/net80211/ieee80211_output.c
index 1ef0ebfa51a..4a55a34d8b1 100644
--- a/sys/net80211/ieee80211_output.c
+++ b/sys/net80211/ieee80211_output.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee80211_output.c,v 1.6 2005/02/26 15:49:34 jsg Exp $ */
+/* $OpenBSD: ieee80211_output.c,v 1.7 2005/03/03 14:36:41 damien Exp $ */
/* $NetBSD: ieee80211_output.c,v 1.13 2004/05/31 11:02:55 dyoung Exp $ */
/*-
@@ -805,6 +805,96 @@ bad:
#undef senderr
}
+struct mbuf *
+ieee80211_beacon_alloc(struct ieee80211com *ic, struct ieee80211_node *ni)
+{
+ struct ieee80211_frame *wh;
+ struct mbuf *m;
+ int pktlen;
+ u_int8_t *frm;
+ u_int16_t capinfo;
+ struct ieee80211_rateset *rs;
+
+ rs = &ni->ni_rates;
+ pktlen = sizeof (struct ieee80211_frame)
+ + 8 + 2 + 2 + 2+ni->ni_esslen + 2+rs->rs_nrates + 3 + 6;
+ if (rs->rs_nrates > IEEE80211_RATE_SIZE)
+ pktlen += 2;
+ m = ieee80211_getmbuf(M_DONTWAIT, MT_DATA,
+ 2 + ic->ic_des_esslen
+ + 2 + IEEE80211_RATE_SIZE
+ + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE));
+ if (m == NULL)
+ return NULL;
+
+ wh = mtod(m, struct ieee80211_frame *);
+ wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT |
+ IEEE80211_FC0_SUBTYPE_BEACON;
+ wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
+ *(u_int16_t *)wh->i_dur = 0;
+ IEEE80211_ADDR_COPY(wh->i_addr1, etherbroadcastaddr);
+ IEEE80211_ADDR_COPY(wh->i_addr2, ic->ic_myaddr);
+ IEEE80211_ADDR_COPY(wh->i_addr3, ni->ni_bssid);
+ *(u_int16_t *)wh->i_seq = 0;
+
+ /*
+ * beacon frame format
+ * [8] time stamp
+ * [2] beacon interval
+ * [2] cabability information
+ * [tlv] ssid
+ * [tlv] supported rates
+ * [tlv] parameter set (IBSS)
+ * [tlv] extended supported rates
+ */
+ frm = (u_int8_t *)&wh[1];
+ bzero(frm, 8); /* timestamp is set by hardware */
+ frm += 8;
+ *(u_int16_t *)frm = htole16(ni->ni_intval);
+ frm += 2;
+ if (ic->ic_opmode == IEEE80211_M_IBSS) {
+ capinfo = IEEE80211_CAPINFO_IBSS;
+ } else {
+ capinfo = IEEE80211_CAPINFO_ESS;
+ }
+ if (ic->ic_flags & IEEE80211_F_WEPON)
+ capinfo |= IEEE80211_CAPINFO_PRIVACY;
+ if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
+ IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
+ capinfo |= IEEE80211_CAPINFO_SHORT_PREAMBLE;
+ if (ic->ic_flags & IEEE80211_F_SHSLOT)
+ capinfo |= IEEE80211_CAPINFO_SHORT_SLOTTIME;
+ *(u_int16_t *)frm = htole16(capinfo);
+ frm += 2;
+ *frm++ = IEEE80211_ELEMID_SSID;
+ *frm++ = ni->ni_esslen;
+ memcpy(frm, ni->ni_essid, ni->ni_esslen);
+ frm += ni->ni_esslen;
+ frm = ieee80211_add_rates(frm, rs);
+ *frm++ = IEEE80211_ELEMID_DSPARMS;
+ *frm++ = 1;
+ *frm++ = ieee80211_chan2ieee(ic, ni->ni_chan);
+ if (ic->ic_opmode == IEEE80211_M_IBSS) {
+ *frm++ = IEEE80211_ELEMID_IBSSPARMS;
+ *frm++ = 2;
+ *frm++ = 0; *frm++ = 0; /* TODO: ATIM window */
+ } else {
+ /* TODO: TIM */
+ *frm++ = IEEE80211_ELEMID_TIM;
+ *frm++ = 4; /* length */
+ *frm++ = 0; /* DTIM count */
+ *frm++ = 1; /* DTIM period */
+ *frm++ = 0; /* bitmap control */
+ *frm++ = 0; /* Partial Virtual Bitmap (variable length) */
+ }
+ frm = ieee80211_add_xrates(frm, rs);
+ m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
+ IASSERT(m->m_pkthdr.len <= pktlen,
+ ("beacon bigger than expected, len %u calculated %u",
+ m->m_pkthdr.len, pktlen));
+ return m;
+}
+
void
ieee80211_pwrsave(struct ieee80211com *ic, struct ieee80211_node *ni,
struct mbuf *m)
diff --git a/sys/net80211/ieee80211_proto.h b/sys/net80211/ieee80211_proto.h
index fc6427b7d79..0a59806594e 100644
--- a/sys/net80211/ieee80211_proto.h
+++ b/sys/net80211/ieee80211_proto.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee80211_proto.h,v 1.5 2004/12/25 20:40:19 deraadt Exp $ */
+/* $OpenBSD: ieee80211_proto.h,v 1.6 2005/03/03 14:36:41 damien Exp $ */
/* $NetBSD: ieee80211_proto.h,v 1.3 2003/10/13 04:23:56 dyoung Exp $ */
/*-
@@ -67,6 +67,8 @@ extern int ieee80211_send_mgmt(struct ieee80211com *, struct ieee80211_node *,
int, int);
extern struct mbuf *ieee80211_encap(struct ifnet *, struct mbuf *,
struct ieee80211_node **);
+extern struct mbuf *ieee80211_beacon_alloc(struct ieee80211com *,
+ struct ieee80211_node *);
extern void ieee80211_pwrsave(struct ieee80211com *, struct ieee80211_node *,
struct mbuf *);
extern struct mbuf *ieee80211_decap(struct ifnet *, struct mbuf *);