Deleted Added
full compact
ieee80211_input.c (130416) ieee80211_input.c (138568)
1/*-
2 * Copyright (c) 2001 Atsushi Onoe
1/*-
2 * Copyright (c) 2001 Atsushi Onoe
3 * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting
3 * Copyright (c) 2002-2004 Sam Leffler, Errno Consulting
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright

--- 14 unchanged lines hidden (view full) ---

26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include <sys/cdefs.h>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright

--- 14 unchanged lines hidden (view full) ---

26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include <sys/cdefs.h>
34__FBSDID("$FreeBSD: head/sys/net80211/ieee80211_input.c 130416 2004-06-13 17:29:10Z mlaier $");
34__FBSDID("$FreeBSD: head/sys/net80211/ieee80211_input.c 138568 2004-12-08 17:26:47Z sam $");
35
35
36#include "opt_inet.h"
37
38#include <sys/param.h>
36#include <sys/param.h>
39#include <sys/systm.h>
37#include
40#include <sys/mbuf.h>
41#include <sys/malloc.h>
38#include <sys/mbuf.h>
39#include <sys/malloc.h>
42#include <sys/kernel.h>
43#include <sys/socket.h>
44#include <sys/sockio.h>
45#include <sys/endian.h>
40#include <sys/endian.h>
46#include <sys/errno.h>
47#include <sys/bus.h>
48#include <sys/proc.h>
49#include <sys/sysctl.h>
50
51#include <machine/atomic.h>
52
41
42#include <sys/socket.h>
43
53#include <net/if.h>
44#include <net/if.h>
54#include <net/if_dl.h>
55#include <net/if_media.h>
45#include <net/if_media.h>
56#include <net/if_arp.h>
57#include <net/ethernet.h>
58#include <net/if_llc.h>
46#include <net/ethernet.h>
47#include <net/if_llc.h>
48#include <net/if_vlan_var.h>
59
60#include <net80211/ieee80211_var.h>
61
62#include <net/bpf.h>
63
49
50#include <net80211/ieee80211_var.h>
51
52#include <net/bpf.h>
53
64#ifdef INET
65#include <netinet/in.h>
66#include <netinet/if_ether.h>
67#endif
54#ifdef IEEE80211_DEBUG
55#include <machine/stdarg.h>
68
69/*
56
57/*
58 * Decide if a received management frame should be
59 * printed when debugging is enabled. This filters some
60 * of the less interesting frames that come frequently
61 * (e.g. beacons).
62 */
63static __inline int
64doprint(struct ieee80211com *ic, int subtype)
65{
66 switch (subtype) {
67 case IEEE80211_FC0_SUBTYPE_BEACON:
68 return (ic->ic_flags & IEEE80211_F_SCAN);
69 case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
70 return (ic->ic_opmode == IEEE80211_M_IBSS);
71 }
72 return 1;
73}
74
75/*
76 * Emit a debug message about discarding a frame or information
77 * element. One format is for extracting the mac address from
78 * the frame header; the other is for when a header is not
79 * available or otherwise appropriate.
80 */
81#define IEEE80211_DISCARD(_ic, _m, _wh, _type, _fmt, ...) do { \
82 if ((_ic)->ic_debug & (_m)) \
83 ieee80211_discard_frame(_ic, _wh, _type, _fmt, __VA_ARGS__);\
84} while (0)
85#define IEEE80211_DISCARD_IE(_ic, _m, _wh, _type, _fmt, ...) do { \
86 if ((_ic)->ic_debug & (_m)) \
87 ieee80211_discard_ie(_ic, _wh, _type, _fmt, __VA_ARGS__);\
88} while (0)
89#define IEEE80211_DISCARD_MAC(_ic, _m, _mac, _type, _fmt, ...) do { \
90 if ((_ic)->ic_debug & (_m)) \
91 ieee80211_discard_mac(_ic, _mac, _type, _fmt, __VA_ARGS__);\
92} while (0)
93
94static const u_int8_t *ieee80211_getbssid(struct ieee80211com *,
95 const struct ieee80211_frame *);
96static void ieee80211_discard_frame(struct ieee80211com *,
97 const struct ieee80211_frame *, const char *type, const char *fmt, ...);
98static void ieee80211_discard_ie(struct ieee80211com *,
99 const struct ieee80211_frame *, const char *type, const char *fmt, ...);
100static void ieee80211_discard_mac(struct ieee80211com *,
101 const u_int8_t mac[IEEE80211_ADDR_LEN], const char *type,
102 const char *fmt, ...);
103#else
104#define IEEE80211_DISCARD(_ic, _m, _wh, _type, _fmt, ...)
105#define IEEE80211_DISCARD_IE(_ic, _m, _wh, _type, _fmt, ...)
106#define IEEE80211_DISCARD_MAC(_ic, _m, _mac, _type, _fmt, ...)
107#endif /* IEEE80211_DEBUG */
108
109static struct mbuf *ieee80211_defrag(struct ieee80211com *,
110 struct ieee80211_node *, struct mbuf *);
111static struct mbuf *ieee80211_decap(struct ieee80211com *, struct mbuf *);
112static void ieee80211_node_pwrsave(struct ieee80211_node *, int enable);
113static void ieee80211_recv_pspoll(struct ieee80211com *,
114 struct ieee80211_node *, struct mbuf *);
115
116/*
70 * Process a received frame. The node associated with the sender
71 * should be supplied. If nothing was found in the node table then
72 * the caller is assumed to supply a reference to ic_bss instead.
73 * The RSSI and a timestamp are also supplied. The RSSI data is used
74 * during AP scanning to select a AP to associate with; it can have
75 * any units so long as values have consistent units and higher values
76 * mean ``better signal''. The receive timestamp is currently not used
77 * by the 802.11 layer.
78 */
79void
117 * Process a received frame. The node associated with the sender
118 * should be supplied. If nothing was found in the node table then
119 * the caller is assumed to supply a reference to ic_bss instead.
120 * The RSSI and a timestamp are also supplied. The RSSI data is used
121 * during AP scanning to select a AP to associate with; it can have
122 * any units so long as values have consistent units and higher values
123 * mean ``better signal''. The receive timestamp is currently not used
124 * by the 802.11 layer.
125 */
126void
80ieee80211_input(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni,
81 int rssi, u_int32_t rstamp)
127ieee80211_input(struct ieee80211com *ic, struct mbuf *m,
128 struct ieee80211_node *ni, int rssi, u_int32_t rstamp)
82{
129{
83 struct ieee80211com *ic = (void *)ifp;
130#define SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0)
131#define HAS_SEQ(type) ((type & 0x4) == 0)
132 struct ifnet *ifp = ic->ic_ifp;
84 struct ieee80211_frame *wh;
133 struct ieee80211_frame *wh;
134 struct ieee80211_key *key;
85 struct ether_header *eh;
135 struct ether_header *eh;
86 struct mbuf *m1;
87 int len;
136 int len, hdrsize, off;
88 u_int8_t dir, type, subtype;
89 u_int8_t *bssid;
90 u_int16_t rxseq;
91
92 KASSERT(ni != NULL, ("null node"));
137 u_int8_t dir, type, subtype;
138 u_int8_t *bssid;
139 u_int16_t rxseq;
140
141 KASSERT(ni != NULL, ("null node"));
142 ni->ni_inact = ni->ni_inact_reload;
93
94 /* trim CRC here so WEP can find its own CRC at the end of packet. */
95 if (m->m_flags & M_HASFCS) {
96 m_adj(m, -IEEE80211_CRC_LEN);
97 m->m_flags &= ~M_HASFCS;
98 }
99 KASSERT(m->m_pkthdr.len >= sizeof(struct ieee80211_frame_min),
100 ("frame length too short: %u", m->m_pkthdr.len));
101
102 /*
103 * In monitor mode, send everything directly to bpf.
104 * XXX may want to include the CRC
105 */
106 if (ic->ic_opmode == IEEE80211_M_MONITOR)
107 goto out;
108
143
144 /* trim CRC here so WEP can find its own CRC at the end of packet. */
145 if (m->m_flags & M_HASFCS) {
146 m_adj(m, -IEEE80211_CRC_LEN);
147 m->m_flags &= ~M_HASFCS;
148 }
149 KASSERT(m->m_pkthdr.len >= sizeof(struct ieee80211_frame_min),
150 ("frame length too short: %u", m->m_pkthdr.len));
151
152 /*
153 * In monitor mode, send everything directly to bpf.
154 * XXX may want to include the CRC
155 */
156 if (ic->ic_opmode == IEEE80211_M_MONITOR)
157 goto out;
158
159 if (m->m_pkthdr.len < sizeof(struct ieee80211_frame_min)) {
160 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_ANY,
161 ni->ni_macaddr, NULL,
162 "too short (1): len %u", m->m_pkthdr.len);
163 ic->ic_stats.is_rx_tooshort++;
164 goto out;
165 }
166 /*
167 * Bit of a cheat here, we use a pointer for a 3-address
168 * frame format but don't reference fields past outside
169 * ieee80211_frame_min w/o first validating the data is
170 * present.
171 */
109 wh = mtod(m, struct ieee80211_frame *);
172 wh = mtod(m, struct ieee80211_frame *);
173
110 if ((wh->i_fc[0] & IEEE80211_FC0_VERSION_MASK) !=
111 IEEE80211_FC0_VERSION_0) {
174 if ((wh->i_fc[0] & IEEE80211_FC0_VERSION_MASK) !=
175 IEEE80211_FC0_VERSION_0) {
112 if (ifp->if_flags & IFF_DEBUG)
113 if_printf(ifp, "receive packet with wrong version: %x\n",
114 wh->i_fc[0]);
176 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_ANY,
177 ni->ni_macaddr, NULL, "wrong version %x", wh->i_fc[0]);
115 ic->ic_stats.is_rx_badversion++;
116 goto err;
117 }
118
119 dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK;
120 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
178 ic->ic_stats.is_rx_badversion++;
179 goto err;
180 }
181
182 dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK;
183 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
121 /*
122 * NB: We are not yet prepared to handle control frames,
123 * but permitting drivers to send them to us allows
124 * them to go through bpf tapping at the 802.11 layer.
125 */
126 if (m->m_pkthdr.len < sizeof(struct ieee80211_frame)) {
127 /* XXX statistic */
128 IEEE80211_DPRINTF2(("%s: frame too short, len %u\n",
129 __func__, m->m_pkthdr.len));
130 ic->ic_stats.is_rx_tooshort++;
131 goto out; /* XXX */
132 }
133 if (ic->ic_state != IEEE80211_S_SCAN) {
184 subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
185 if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) {
134 switch (ic->ic_opmode) {
135 case IEEE80211_M_STA:
186 switch (ic->ic_opmode) {
187 case IEEE80211_M_STA:
136 if (!IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_bssid)) {
188 bssid = wh->i_addr2;
189 if (!IEEE80211_ADDR_EQ(bssid, ni->ni_bssid)) {
137 /* not interested in */
190 /* not interested in */
138 IEEE80211_DPRINTF2(("%s: discard frame from "
139 "bss %s\n", __func__,
140 ether_sprintf(wh->i_addr2)));
191 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_INPUT,
192 bssid, NULL, "%s", "not to bss");
141 ic->ic_stats.is_rx_wrongbss++;
142 goto out;
143 }
144 break;
145 case IEEE80211_M_IBSS:
146 case IEEE80211_M_AHDEMO:
147 case IEEE80211_M_HOSTAP:
193 ic->ic_stats.is_rx_wrongbss++;
194 goto out;
195 }
196 break;
197 case IEEE80211_M_IBSS:
198 case IEEE80211_M_AHDEMO:
199 case IEEE80211_M_HOSTAP:
148 if (dir == IEEE80211_FC1_DIR_NODS)
149 bssid = wh->i_addr3;
150 else
200 if (dir != IEEE80211_FC1_DIR_NODS)
151 bssid = wh->i_addr1;
201 bssid = wh->i_addr1;
202 else if (type == IEEE80211_FC0_TYPE_CTL)
203 bssid = wh->i_addr1;
204 else {
205 if (m->m_pkthdr.len < sizeof(struct ieee80211_frame)) {
206 IEEE80211_DISCARD_MAC(ic,
207 IEEE80211_MSG_ANY, ni->ni_macaddr,
208 NULL, "too short (2): len %u",
209 m->m_pkthdr.len);
210 ic->ic_stats.is_rx_tooshort++;
211 goto out;
212 }
213 bssid = wh->i_addr3;
214 }
215 if (type != IEEE80211_FC0_TYPE_DATA)
216 break;
217 /*
218 * Data frame, validate the bssid.
219 */
152 if (!IEEE80211_ADDR_EQ(bssid, ic->ic_bss->ni_bssid) &&
153 !IEEE80211_ADDR_EQ(bssid, ifp->if_broadcastaddr)) {
154 /* not interested in */
220 if (!IEEE80211_ADDR_EQ(bssid, ic->ic_bss->ni_bssid) &&
221 !IEEE80211_ADDR_EQ(bssid, ifp->if_broadcastaddr)) {
222 /* not interested in */
155 IEEE80211_DPRINTF2(("%s: discard frame from "
156 "bss %s\n", __func__,
157 ether_sprintf(bssid)));
223 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_INPUT,
224 bssid, NULL, "%s", "not to bss");
158 ic->ic_stats.is_rx_wrongbss++;
159 goto out;
160 }
225 ic->ic_stats.is_rx_wrongbss++;
226 goto out;
227 }
228 /*
229 * For adhoc mode we cons up a node when it doesn't
230 * exist. This should probably done after an ACL check.
231 */
232 if (ni == ic->ic_bss &&
233 ic->ic_opmode != IEEE80211_M_HOSTAP) {
234 /*
235 * Fake up a node for this newly
236 * discovered member of the IBSS.
237 */
238 ni = ieee80211_fakeup_adhoc_node(ic->ic_sta,
239 type == IEEE80211_FC0_TYPE_CTL ?
240 wh->i_addr1 : wh->i_addr2);
241 if (ni == NULL) {
242 /* NB: stat kept for alloc failure */
243 goto err;
244 }
245 }
161 break;
246 break;
162 case IEEE80211_M_MONITOR:
163 goto out;
164 default:
247 default:
165 /* XXX catch bad values */
166 break;
248 goto out;
167 }
168 ni->ni_rssi = rssi;
169 ni->ni_rstamp = rstamp;
249 }
250 ni->ni_rssi = rssi;
251 ni->ni_rstamp = rstamp;
170 rxseq = ni->ni_rxseq;
171 ni->ni_rxseq =
172 le16toh(*(u_int16_t *)wh->i_seq) >> IEEE80211_SEQ_SEQ_SHIFT;
173 /* TODO: fragment */
174 if ((wh->i_fc[1] & IEEE80211_FC1_RETRY) &&
175 rxseq == ni->ni_rxseq) {
176 /* duplicate, silently discarded */
177 ic->ic_stats.is_rx_dup++; /* XXX per-station stat */
178 goto out;
252 if (HAS_SEQ(type)) {
253 u_int8_t tid;
254 if (IEEE80211_QOS_HAS_SEQ(wh)) {
255 tid = ((struct ieee80211_qosframe *)wh)->
256 i_qos[0] & IEEE80211_QOS_TID;
257 if (tid >= WME_AC_VI)
258 ic->ic_wme.wme_hipri_traffic++;
259 tid++;
260 } else
261 tid = 0;
262 rxseq = le16toh(*(u_int16_t *)wh->i_seq);
263 if ((wh->i_fc[1] & IEEE80211_FC1_RETRY) &&
264 SEQ_LEQ(rxseq, ni->ni_rxseqs[tid])) {
265 /* duplicate, discard */
266 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_INPUT,
267 bssid, "duplicate",
268 "seqno <%u,%u> fragno <%u,%u> tid %u",
269 rxseq >> IEEE80211_SEQ_SEQ_SHIFT,
270 ni->ni_rxseqs[tid] >>
271 IEEE80211_SEQ_SEQ_SHIFT,
272 rxseq & IEEE80211_SEQ_FRAG_MASK,
273 ni->ni_rxseqs[tid] &
274 IEEE80211_SEQ_FRAG_MASK,
275 tid);
276 ic->ic_stats.is_rx_dup++;
277 IEEE80211_NODE_STAT(ni, rx_dup);
278 goto out;
279 }
280 ni->ni_rxseqs[tid] = rxseq;
179 }
281 }
180 ni->ni_inact = 0;
181 }
182
183 switch (type) {
184 case IEEE80211_FC0_TYPE_DATA:
282 }
283
284 switch (type) {
285 case IEEE80211_FC0_TYPE_DATA:
286 hdrsize = ieee80211_hdrsize(wh);
287 if (ic->ic_flags & IEEE80211_F_DATAPAD)
288 hdrsize = roundup(hdrsize, sizeof(u_int32_t));
289 if (m->m_len < hdrsize &&
290 (m = m_pullup(m, hdrsize)) == NULL) {
291 IEEE80211_DISCARD(ic, IEEE80211_MSG_ANY,
292 wh, "data", "too short: len %u, expecting %u",
293 m->m_pkthdr.len, hdrsize);
294 ic->ic_stats.is_rx_tooshort++;
295 goto out; /* XXX */
296 }
297 if (subtype & IEEE80211_FC0_SUBTYPE_QOS) {
298 /* XXX discard if node w/o IEEE80211_NODE_QOS? */
299 /*
300 * Strip QoS control and any padding so only a
301 * stock 802.11 header is at the front.
302 */
303 /* XXX 4-address QoS frame */
304 off = hdrsize - sizeof(struct ieee80211_frame);
305 ovbcopy(mtod(m, u_int8_t *), mtod(m, u_int8_t *) + off,
306 hdrsize - off);
307 m_adj(m, off);
308 wh = mtod(m, struct ieee80211_frame *);
309 wh->i_fc[0] &= ~IEEE80211_FC0_SUBTYPE_QOS;
310 } else {
311 /* XXX copy up for 4-address frames w/ padding */
312 }
185 switch (ic->ic_opmode) {
186 case IEEE80211_M_STA:
187 if (dir != IEEE80211_FC1_DIR_FROMDS) {
188 ic->ic_stats.is_rx_wrongdir++;
189 goto out;
190 }
191 if ((ifp->if_flags & IFF_SIMPLEX) &&
192 IEEE80211_IS_MULTICAST(wh->i_addr1) &&
193 IEEE80211_ADDR_EQ(wh->i_addr3, ic->ic_myaddr)) {
194 /*
195 * In IEEE802.11 network, multicast packet
196 * sent from me is broadcasted from AP.
197 * It should be silently discarded for
198 * SIMPLEX interface.
199 */
313 switch (ic->ic_opmode) {
314 case IEEE80211_M_STA:
315 if (dir != IEEE80211_FC1_DIR_FROMDS) {
316 ic->ic_stats.is_rx_wrongdir++;
317 goto out;
318 }
319 if ((ifp->if_flags & IFF_SIMPLEX) &&
320 IEEE80211_IS_MULTICAST(wh->i_addr1) &&
321 IEEE80211_ADDR_EQ(wh->i_addr3, ic->ic_myaddr)) {
322 /*
323 * In IEEE802.11 network, multicast packet
324 * sent from me is broadcasted from AP.
325 * It should be silently discarded for
326 * SIMPLEX interface.
327 */
328 IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT,
329 wh, NULL, "%s", "multicast echo");
200 ic->ic_stats.is_rx_mcastecho++;
201 goto out;
202 }
203 break;
204 case IEEE80211_M_IBSS:
205 case IEEE80211_M_AHDEMO:
206 if (dir != IEEE80211_FC1_DIR_NODS) {
207 ic->ic_stats.is_rx_wrongdir++;
208 goto out;
209 }
330 ic->ic_stats.is_rx_mcastecho++;
331 goto out;
332 }
333 break;
334 case IEEE80211_M_IBSS:
335 case IEEE80211_M_AHDEMO:
336 if (dir != IEEE80211_FC1_DIR_NODS) {
337 ic->ic_stats.is_rx_wrongdir++;
338 goto out;
339 }
340 /* XXX no power-save support */
210 break;
211 case IEEE80211_M_HOSTAP:
212 if (dir != IEEE80211_FC1_DIR_TODS) {
213 ic->ic_stats.is_rx_wrongdir++;
214 goto out;
215 }
216 /* check if source STA is associated */
217 if (ni == ic->ic_bss) {
341 break;
342 case IEEE80211_M_HOSTAP:
343 if (dir != IEEE80211_FC1_DIR_TODS) {
344 ic->ic_stats.is_rx_wrongdir++;
345 goto out;
346 }
347 /* check if source STA is associated */
348 if (ni == ic->ic_bss) {
218 IEEE80211_DPRINTF(("%s: data from unknown src "
219 "%s\n", __func__,
220 ether_sprintf(wh->i_addr2)));
349 IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT,
350 wh, "data", "%s", "unknown src");
221 /* NB: caller deals with reference */
351 /* NB: caller deals with reference */
222 ni = ieee80211_dup_bss(ic, wh->i_addr2);
352 ni = ieee80211_dup_bss(ic->ic_sta, wh->i_addr2);
223 if (ni != NULL) {
224 IEEE80211_SEND_MGMT(ic, ni,
225 IEEE80211_FC0_SUBTYPE_DEAUTH,
226 IEEE80211_REASON_NOT_AUTHED);
353 if (ni != NULL) {
354 IEEE80211_SEND_MGMT(ic, ni,
355 IEEE80211_FC0_SUBTYPE_DEAUTH,
356 IEEE80211_REASON_NOT_AUTHED);
227 ieee80211_free_node(ic, ni);
357 ieee80211_free_node(ni);
228 }
229 ic->ic_stats.is_rx_notassoc++;
230 goto err;
231 }
232 if (ni->ni_associd == 0) {
358 }
359 ic->ic_stats.is_rx_notassoc++;
360 goto err;
361 }
362 if (ni->ni_associd == 0) {
233 IEEE80211_DPRINTF(("ieee80211_input: "
234 "data from unassoc src %s\n",
235 ether_sprintf(wh->i_addr2)));
363 IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT,
364 wh, "data", "%s", "unassoc src");
236 IEEE80211_SEND_MGMT(ic, ni,
237 IEEE80211_FC0_SUBTYPE_DISASSOC,
238 IEEE80211_REASON_NOT_ASSOCED);
365 IEEE80211_SEND_MGMT(ic, ni,
366 IEEE80211_FC0_SUBTYPE_DISASSOC,
367 IEEE80211_REASON_NOT_ASSOCED);
239 ieee80211_unref_node(&ni);
240 ic->ic_stats.is_rx_notassoc++;
241 goto err;
242 }
368 ic->ic_stats.is_rx_notassoc++;
369 goto err;
370 }
371
372 /*
373 * Check for power save state change.
374 */
375 if (((wh->i_fc[1] & IEEE80211_FC1_PWR_MGT) ^
376 (ni->ni_flags & IEEE80211_NODE_PWR_MGT)))
377 ieee80211_node_pwrsave(ni,
378 wh->i_fc[1] & IEEE80211_FC1_PWR_MGT);
243 break;
379 break;
244 case IEEE80211_M_MONITOR:
245 break;
380 default:
381 /* XXX here to keep compiler happy */
382 goto out;
246 }
383 }
384
385 /*
386 * Handle privacy requirements. Note that we
387 * must not be preempted from here until after
388 * we (potentially) call ieee80211_crypto_demic;
389 * otherwise we may violate assumptions in the
390 * crypto cipher modules used to do delayed update
391 * of replay sequence numbers.
392 */
247 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
393 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
248 if (ic->ic_flags & IEEE80211_F_WEPON) {
249 m = ieee80211_wep_crypt(ifp, m, 0);
250 if (m == NULL) {
251 ic->ic_stats.is_rx_wepfail++;
252 goto err;
253 }
254 wh = mtod(m, struct ieee80211_frame *);
255 } else {
256 ic->ic_stats.is_rx_nowep++;
394 if ((ic->ic_flags & IEEE80211_F_PRIVACY) == 0) {
395 /*
396 * Discard encrypted frames when privacy is off.
397 */
398 IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT,
399 wh, "WEP", "%s", "PRIVACY off");
400 ic->ic_stats.is_rx_noprivacy++;
401 IEEE80211_NODE_STAT(ni, rx_noprivacy);
257 goto out;
258 }
402 goto out;
403 }
404 key = ieee80211_crypto_decap(ic, ni, m);
405 if (key == NULL) {
406 /* NB: stats+msgs handled in crypto_decap */
407 IEEE80211_NODE_STAT(ni, rx_wepfail);
408 goto out;
409 }
410 wh = mtod(m, struct ieee80211_frame *);
411 } else {
412 key = NULL;
259 }
413 }
414
415 /*
416 * Next up, any fragmentation.
417 */
418 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
419 m = ieee80211_defrag(ic, ni, m);
420 if (m == NULL) {
421 /* Fragment dropped or frame not complete yet */
422 goto out;
423 }
424 }
425 wh = NULL; /* no longer valid, catch any uses */
426
427 /*
428 * Next strip any MSDU crypto bits.
429 */
430 if (key != NULL && !ieee80211_crypto_demic(ic, key, m)) {
431 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_INPUT,
432 ni->ni_macaddr, "data", "%s", "demic error");
433 IEEE80211_NODE_STAT(ni, rx_demicfail);
434 goto out;
435 }
436
260 /* copy to listener after decrypt */
261 if (ic->ic_rawbpf)
262 bpf_mtap(ic->ic_rawbpf, m);
437 /* copy to listener after decrypt */
438 if (ic->ic_rawbpf)
439 bpf_mtap(ic->ic_rawbpf, m);
263 m = ieee80211_decap(ifp, m);
440
441 /*
442 * Finally, strip the 802.11 header.
443 */
444 m = ieee80211_decap(ic, m);
264 if (m == NULL) {
445 if (m == NULL) {
446 /* don't count Null data frames as errors */
447 if (subtype == IEEE80211_FC0_SUBTYPE_NODATA)
448 goto out;
449 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_INPUT,
450 ni->ni_macaddr, "data", "%s", "decap error");
265 ic->ic_stats.is_rx_decap++;
451 ic->ic_stats.is_rx_decap++;
452 IEEE80211_NODE_STAT(ni, rx_decap);
266 goto err;
267 }
453 goto err;
454 }
455 eh = mtod(m, struct ether_header *);
456 if (!ieee80211_node_is_authorized(ni)) {
457 /*
458 * Deny any non-PAE frames received prior to
459 * authorization. For open/shared-key
460 * authentication the port is mark authorized
461 * after authentication completes. For 802.1x
462 * the port is not marked authorized by the
463 * authenticator until the handshake has completed.
464 */
465 if (eh->ether_type != htons(ETHERTYPE_PAE)) {
466 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_INPUT,
467 eh->ether_shost, "data",
468 "unauthorized port: ether type 0x%x len %u",
469 eh->ether_type, m->m_pkthdr.len);
470 ic->ic_stats.is_rx_unauth++;
471 IEEE80211_NODE_STAT(ni, rx_unauth);
472 goto err;
473 }
474 } else {
475 /*
476 * When denying unencrypted frames, discard
477 * any non-PAE frames received without encryption.
478 */
479 if ((ic->ic_flags & IEEE80211_F_DROPUNENC) &&
480 key == NULL &&
481 eh->ether_type != htons(ETHERTYPE_PAE)) {
482 /*
483 * Drop unencrypted frames.
484 */
485 ic->ic_stats.is_rx_unencrypted++;
486 IEEE80211_NODE_STAT(ni, rx_unencrypted);
487 goto out;
488 }
489 }
268 ifp->if_ipackets++;
490 ifp->if_ipackets++;
491 IEEE80211_NODE_STAT(ni, rx_data);
492 IEEE80211_NODE_STAT_ADD(ni, rx_bytes, m->m_pkthdr.len);
269
270 /* perform as a bridge within the AP */
493
494 /* perform as a bridge within the AP */
271 m1 = NULL;
272 if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
273 eh = mtod(m, struct ether_header *);
495 if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
496 (ic->ic_flags & IEEE80211_F_NOBRIDGE) == 0) {
497 struct mbuf *m1 = NULL;
498
274 if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
275 m1 = m_copypacket(m, M_DONTWAIT);
276 if (m1 == NULL)
277 ifp->if_oerrors++;
278 else
279 m1->m_flags |= M_MCAST;
280 } else {
499 if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
500 m1 = m_copypacket(m, M_DONTWAIT);
501 if (m1 == NULL)
502 ifp->if_oerrors++;
503 else
504 m1->m_flags |= M_MCAST;
505 } else {
281 ni = ieee80211_find_node(ic, eh->ether_dhost);
282 if (ni != NULL) {
283 if (ni->ni_associd != 0) {
506 /* XXX this dups work done in ieee80211_encap */
507 /* check if destination is associated */
508 struct ieee80211_node *ni1 =
509 ieee80211_find_node(ic->ic_sta,
510 eh->ether_dhost);
511 if (ni1 != NULL) {
512 /* XXX check if authorized */
513 if (ni1->ni_associd != 0) {
284 m1 = m;
285 m = NULL;
286 }
514 m1 = m;
515 m = NULL;
516 }
287 ieee80211_free_node(ic, ni);
517 /* XXX statistic? */
518 ieee80211_free_node(ni1);
288 }
289 }
290 if (m1 != NULL) {
291 len = m1->m_pkthdr.len;
292 IF_ENQUEUE(&ifp->if_snd, m1);
293 if (m != NULL)
294 ifp->if_omcasts++;
295 ifp->if_obytes += len;
296 }
297 }
519 }
520 }
521 if (m1 != NULL) {
522 len = m1->m_pkthdr.len;
523 IF_ENQUEUE(&ifp->if_snd, m1);
524 if (m != NULL)
525 ifp->if_omcasts++;
526 ifp->if_obytes += len;
527 }
528 }
298 if (m != NULL)
529 if (m != NULL) {
530 if (ni->ni_vlan != 0) {
531 /* attach vlan tag */
532 /* XXX goto err? */
533 VLAN_INPUT_TAG(ifp, m, ni->ni_vlan, goto out);
534 }
299 (*ifp->if_input)(ifp, m);
535 (*ifp->if_input)(ifp, m);
536 }
300 return;
301
302 case IEEE80211_FC0_TYPE_MGT:
537 return;
538
539 case IEEE80211_FC0_TYPE_MGT:
540 IEEE80211_NODE_STAT(ni, rx_mgmt);
303 if (dir != IEEE80211_FC1_DIR_NODS) {
304 ic->ic_stats.is_rx_wrongdir++;
305 goto err;
306 }
541 if (dir != IEEE80211_FC1_DIR_NODS) {
542 ic->ic_stats.is_rx_wrongdir++;
543 goto err;
544 }
307 if (ic->ic_opmode == IEEE80211_M_AHDEMO) {
308 ic->ic_stats.is_rx_ahdemo_mgt++;
545 if (m->m_pkthdr.len < sizeof(struct ieee80211_frame)) {
546 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_ANY,
547 ni->ni_macaddr, "mgt", "too short: len %u",
548 m->m_pkthdr.len);
549 ic->ic_stats.is_rx_tooshort++;
309 goto out;
310 }
550 goto out;
551 }
311 subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
312
313 /* drop frames without interest */
314 if (ic->ic_state == IEEE80211_S_SCAN) {
315 if (subtype != IEEE80211_FC0_SUBTYPE_BEACON &&
316 subtype != IEEE80211_FC0_SUBTYPE_PROBE_RESP) {
317 ic->ic_stats.is_rx_mgtdiscard++;
552#ifdef IEEE80211_DEBUG
553 if ((ieee80211_msg_debug(ic) && doprint(ic, subtype)) ||
554 ieee80211_msg_dumppkts(ic)) {
555 if_printf(ic->ic_ifp, "received %s from %s rssi %d\n",
556 ieee80211_mgt_subtype_name[subtype >>
557 IEEE80211_FC0_SUBTYPE_SHIFT],
558 ether_sprintf(wh->i_addr2), rssi);
559 }
560#endif
561 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
562 if (subtype != IEEE80211_FC0_SUBTYPE_AUTH) {
563 /*
564 * Only shared key auth frames with a challenge
565 * should be encrypted, discard all others.
566 */
567 IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT,
568 wh, ieee80211_mgt_subtype_name[subtype >>
569 IEEE80211_FC0_SUBTYPE_SHIFT],
570 "%s", "WEP set but not permitted");
571 ic->ic_stats.is_rx_mgtdiscard++; /* XXX */
318 goto out;
319 }
572 goto out;
573 }
320 } else {
321 if (ic->ic_opmode != IEEE80211_M_IBSS &&
322 subtype == IEEE80211_FC0_SUBTYPE_BEACON) {
323 ic->ic_stats.is_rx_mgtdiscard++;
574 if ((ic->ic_flags & IEEE80211_F_PRIVACY) == 0) {
575 /*
576 * Discard encrypted frames when privacy is off.
577 */
578 IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT,
579 wh, "mgt", "%s", "WEP set but PRIVACY off");
580 ic->ic_stats.is_rx_noprivacy++;
324 goto out;
325 }
581 goto out;
582 }
326 }
327
328 if (ifp->if_flags & IFF_DEBUG) {
329 /* avoid to print too many frames */
330 int doprint = 0;
331
332 switch (subtype) {
333 case IEEE80211_FC0_SUBTYPE_BEACON:
334 if (ic->ic_state == IEEE80211_S_SCAN)
335 doprint = 1;
336 break;
337 case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
338 if (ic->ic_opmode == IEEE80211_M_IBSS)
339 doprint = 1;
340 break;
341 default:
342 doprint = 1;
343 break;
583 key = ieee80211_crypto_decap(ic, ni, m);
584 if (key == NULL) {
585 /* NB: stats+msgs handled in crypto_decap */
586 goto out;
344 }
587 }
345#ifdef IEEE80211_DEBUG
346 doprint += ieee80211_debug;
347#endif
348 if (doprint)
349 if_printf(ifp, "received %s from %s rssi %d\n",
350 ieee80211_mgt_subtype_name[subtype
351 >> IEEE80211_FC0_SUBTYPE_SHIFT],
352 ether_sprintf(wh->i_addr2), rssi);
353 }
354 if (ic->ic_rawbpf)
355 bpf_mtap(ic->ic_rawbpf, m);
356 (*ic->ic_recv_mgmt)(ic, m, ni, subtype, rssi, rstamp);
357 m_freem(m);
358 return;
359
360 case IEEE80211_FC0_TYPE_CTL:
588 }
589 if (ic->ic_rawbpf)
590 bpf_mtap(ic->ic_rawbpf, m);
591 (*ic->ic_recv_mgmt)(ic, m, ni, subtype, rssi, rstamp);
592 m_freem(m);
593 return;
594
595 case IEEE80211_FC0_TYPE_CTL:
596 IEEE80211_NODE_STAT(ni, rx_ctrl);
361 ic->ic_stats.is_rx_ctl++;
597 ic->ic_stats.is_rx_ctl++;
598 if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
599 switch (subtype) {
600 case IEEE80211_FC0_SUBTYPE_PS_POLL:
601 ieee80211_recv_pspoll(ic, ni, m);
602 break;
603 }
604 }
362 goto out;
363 default:
605 goto out;
606 default:
364 IEEE80211_DPRINTF(("%s: bad type %x\n", __func__, type));
607 IEEE80211_DISCARD(ic, IEEE80211_MSG_ANY,
608 wh, NULL, "bad frame type 0x%x", type);
365 /* should not come here */
366 break;
367 }
368 err:
369 ifp->if_ierrors++;
370 out:
371 if (m != NULL) {
372 if (ic->ic_rawbpf)
373 bpf_mtap(ic->ic_rawbpf, m);
374 m_freem(m);
375 }
609 /* should not come here */
610 break;
611 }
612 err:
613 ifp->if_ierrors++;
614 out:
615 if (m != NULL) {
616 if (ic->ic_rawbpf)
617 bpf_mtap(ic->ic_rawbpf, m);
618 m_freem(m);
619 }
620#undef SEQ_LEQ
376}
377
621}
622
378struct mbuf *
379ieee80211_decap(struct ifnet *ifp, struct mbuf *m)
623/*
624 * This function reassemble fragments.
625 */
626static struct mbuf *
627ieee80211_defrag(struct ieee80211com *ic, struct ieee80211_node *ni,
628 struct mbuf *m)
380{
629{
630 struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *);
631 struct ieee80211_frame *lwh;
632 u_int16_t rxseq;
633 u_int8_t fragno;
634 u_int8_t more_frag = wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG;
635 struct mbuf *mfrag;
636
637 KASSERT(!IEEE80211_IS_MULTICAST(wh->i_addr1), ("multicast fragm?"));
638
639 rxseq = le16toh(*(u_int16_t *)wh->i_seq);
640 fragno = rxseq & IEEE80211_SEQ_FRAG_MASK;
641
642 /* Quick way out, if there's nothing to defragment */
643 if (!more_frag && fragno == 0 && ni->ni_rxfrag[0] == NULL)
644 return m;
645
646 /*
647 * Remove frag to insure it doesn't get reaped by timer.
648 */
649 if (ni->ni_table == NULL) {
650 /*
651 * Should never happen. If the node is orphaned (not in
652 * the table) then input packets should not reach here.
653 * Otherwise, a concurrent request that yanks the table
654 * should be blocked by other interlocking and/or by first
655 * shutting the driver down. Regardless, be defensive
656 * here and just bail
657 */
658 /* XXX need msg+stat */
659 m_freem(m);
660 return NULL;
661 }
662 IEEE80211_NODE_LOCK(ni->ni_table);
663 mfrag = ni->ni_rxfrag[0];
664 ni->ni_rxfrag[0] = NULL;
665 IEEE80211_NODE_UNLOCK(ni->ni_table);
666
667 /*
668 * Validate new fragment is in order and
669 * related to the previous ones.
670 */
671 if (mfrag != NULL) {
672 u_int16_t last_rxseq;
673
674 lwh = mtod(mfrag, struct ieee80211_frame *);
675 last_rxseq = le16toh(*(u_int16_t *)lwh->i_seq);
676 /* NB: check seq # and frag together */
677 if (rxseq != last_rxseq+1 ||
678 !IEEE80211_ADDR_EQ(wh->i_addr1, lwh->i_addr1) ||
679 !IEEE80211_ADDR_EQ(wh->i_addr2, lwh->i_addr2)) {
680 /*
681 * Unrelated fragment or no space for it,
682 * clear current fragments.
683 */
684 m_freem(mfrag);
685 mfrag = NULL;
686 }
687 }
688
689 if (mfrag == NULL) {
690 if (fragno != 0) { /* !first fragment, discard */
691 IEEE80211_NODE_STAT(ni, rx_defrag);
692 m_freem(m);
693 return NULL;
694 }
695 mfrag = m;
696 } else { /* concatenate */
697 m_cat(mfrag, m);
698 /* NB: m_cat doesn't update the packet header */
699 mfrag->m_pkthdr.len += m->m_pkthdr.len;
700 /* track last seqnum and fragno */
701 lwh = mtod(mfrag, struct ieee80211_frame *);
702 *(u_int16_t *) lwh->i_seq = *(u_int16_t *) wh->i_seq;
703 }
704 if (more_frag) { /* more to come, save */
705 ni->ni_rxfrag[0] = mfrag;
706 mfrag = NULL;
707 }
708 return mfrag;
709}
710
711static struct mbuf *
712ieee80211_decap(struct ieee80211com *ic, struct mbuf *m)
713{
714 struct ieee80211_frame wh; /* NB: QoS stripped above */
381 struct ether_header *eh;
715 struct ether_header *eh;
382 struct ieee80211_frame wh;
383 struct llc *llc;
384
716 struct llc *llc;
717
385 if (m->m_len < sizeof(wh) + sizeof(*llc)) {
386 m = m_pullup(m, sizeof(wh) + sizeof(*llc));
387 if (m == NULL)
388 return NULL;
718 if (m->m_len < sizeof(wh) + sizeof(*llc) &&
719 (m = m_pullup(m, sizeof(wh) + sizeof(*llc))) == NULL) {
720 /* XXX stat, msg */
721 return NULL;
389 }
390 memcpy(&wh, mtod(m, caddr_t), sizeof(wh));
391 llc = (struct llc *)(mtod(m, caddr_t) + sizeof(wh));
392 if (llc->llc_dsap == LLC_SNAP_LSAP && llc->llc_ssap == LLC_SNAP_LSAP &&
393 llc->llc_control == LLC_UI && llc->llc_snap.org_code[0] == 0 &&
394 llc->llc_snap.org_code[1] == 0 && llc->llc_snap.org_code[2] == 0) {
395 m_adj(m, sizeof(wh) + sizeof(struct llc) - sizeof(*eh));
396 llc = NULL;

--- 11 unchanged lines hidden (view full) ---

408 IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr2);
409 break;
410 case IEEE80211_FC1_DIR_FROMDS:
411 IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr1);
412 IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr3);
413 break;
414 case IEEE80211_FC1_DIR_DSTODS:
415 /* not yet supported */
722 }
723 memcpy(&wh, mtod(m, caddr_t), sizeof(wh));
724 llc = (struct llc *)(mtod(m, caddr_t) + sizeof(wh));
725 if (llc->llc_dsap == LLC_SNAP_LSAP && llc->llc_ssap == LLC_SNAP_LSAP &&
726 llc->llc_control == LLC_UI && llc->llc_snap.org_code[0] == 0 &&
727 llc->llc_snap.org_code[1] == 0 && llc->llc_snap.org_code[2] == 0) {
728 m_adj(m, sizeof(wh) + sizeof(struct llc) - sizeof(*eh));
729 llc = NULL;

--- 11 unchanged lines hidden (view full) ---

741 IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr2);
742 break;
743 case IEEE80211_FC1_DIR_FROMDS:
744 IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr1);
745 IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr3);
746 break;
747 case IEEE80211_FC1_DIR_DSTODS:
748 /* not yet supported */
416 IEEE80211_DPRINTF(("%s: DS to DS\n", __func__));
749 IEEE80211_DISCARD(ic, IEEE80211_MSG_ANY,
750 &wh, "data", "%s", "DS to DS not supported");
417 m_freem(m);
418 return NULL;
419 }
420#ifdef ALIGNED_POINTER
421 if (!ALIGNED_POINTER(mtod(m, caddr_t) + sizeof(*eh), u_int32_t)) {
422 struct mbuf *n, *n0, **np;
423 caddr_t newdata;
424 int off, pktlen;

--- 65 unchanged lines hidden (view full) ---

490 if (xrates != NULL) {
491 u_int8_t nxrates;
492 /*
493 * Tack on 11g extended supported rate element.
494 */
495 nxrates = xrates[1];
496 if (rs->rs_nrates + nxrates > IEEE80211_RATE_MAXSIZE) {
497 nxrates = IEEE80211_RATE_MAXSIZE - rs->rs_nrates;
751 m_freem(m);
752 return NULL;
753 }
754#ifdef ALIGNED_POINTER
755 if (!ALIGNED_POINTER(mtod(m, caddr_t) + sizeof(*eh), u_int32_t)) {
756 struct mbuf *n, *n0, **np;
757 caddr_t newdata;
758 int off, pktlen;

--- 65 unchanged lines hidden (view full) ---

824 if (xrates != NULL) {
825 u_int8_t nxrates;
826 /*
827 * Tack on 11g extended supported rate element.
828 */
829 nxrates = xrates[1];
830 if (rs->rs_nrates + nxrates > IEEE80211_RATE_MAXSIZE) {
831 nxrates = IEEE80211_RATE_MAXSIZE - rs->rs_nrates;
498 IEEE80211_DPRINTF(("%s: extended rate set too large;"
499 " only using %u of %u rates\n",
500 __func__, nxrates, xrates[1]));
832 IEEE80211_DPRINTF(ic, IEEE80211_MSG_XRATE,
833 "[%s] extended rate set too large;"
834 " only using %u of %u rates\n",
835 ether_sprintf(ni->ni_macaddr), nxrates, xrates[1]);
501 ic->ic_stats.is_rx_rstoobig++;
502 }
503 memcpy(rs->rs_rates + rs->rs_nrates, xrates+2, nxrates);
504 rs->rs_nrates += nxrates;
505 }
506 return ieee80211_fix_rate(ic, ni, flags);
507}
508
836 ic->ic_stats.is_rx_rstoobig++;
837 }
838 memcpy(rs->rs_rates + rs->rs_nrates, xrates+2, nxrates);
839 rs->rs_nrates += nxrates;
840 }
841 return ieee80211_fix_rate(ic, ni, flags);
842}
843
844static void
845ieee80211_auth_open(struct ieee80211com *ic, struct ieee80211_frame *wh,
846 struct ieee80211_node *ni, int rssi, u_int32_t rstamp, u_int16_t seq,
847 u_int16_t status)
848{
849
850 switch (ic->ic_opmode) {
851 case IEEE80211_M_IBSS:
852 if (ic->ic_state != IEEE80211_S_RUN ||
853 seq != IEEE80211_AUTH_OPEN_REQUEST) {
854 ic->ic_stats.is_rx_bad_auth++;
855 return;
856 }
857 ieee80211_new_state(ic, IEEE80211_S_AUTH,
858 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
859 break;
860
861 case IEEE80211_M_AHDEMO:
862 /* should not come here */
863 break;
864
865 case IEEE80211_M_HOSTAP:
866 if (ic->ic_state != IEEE80211_S_RUN ||
867 seq != IEEE80211_AUTH_OPEN_REQUEST) {
868 ic->ic_stats.is_rx_bad_auth++;
869 return;
870 }
871 /* always accept open authentication requests */
872 if (ni == ic->ic_bss) {
873 ni = ieee80211_dup_bss(ic->ic_sta, wh->i_addr2);
874 if (ni == NULL)
875 return;
876 } else
877 (void) ieee80211_ref_node(ni);
878 ni->ni_inact_reload = ic->ic_inact_auth;
879 IEEE80211_SEND_MGMT(ic, ni,
880 IEEE80211_FC0_SUBTYPE_AUTH, seq + 1);
881 IEEE80211_DPRINTF(ic, IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH,
882 "[%s] station authenticated (open)\n",
883 ether_sprintf(ni->ni_macaddr));
884 break;
885
886 case IEEE80211_M_STA:
887 if (ic->ic_state != IEEE80211_S_AUTH ||
888 seq != IEEE80211_AUTH_OPEN_RESPONSE) {
889 ic->ic_stats.is_rx_bad_auth++;
890 return;
891 }
892 if (status != 0) {
893 IEEE80211_DPRINTF(ic,
894 IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH,
895 "[%s] open auth failed (reason %d)\n",
896 ether_sprintf(ni->ni_macaddr), status);
897 /* XXX can this happen? */
898 if (ni != ic->ic_bss)
899 ni->ni_fails++;
900 ic->ic_stats.is_rx_auth_fail++;
901 return;
902 }
903 ieee80211_new_state(ic, IEEE80211_S_ASSOC,
904 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
905 break;
906 case IEEE80211_M_MONITOR:
907 break;
908 }
909}
910
911static int
912alloc_challenge(struct ieee80211com *ic, struct ieee80211_node *ni)
913{
914 if (ni->ni_challenge == NULL)
915 MALLOC(ni->ni_challenge, u_int32_t*, IEEE80211_CHALLENGE_LEN,
916 M_DEVBUF, M_NOWAIT);
917 if (ni->ni_challenge == NULL) {
918 IEEE80211_DPRINTF(ic, IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH,
919 "[%s] shared key challenge alloc failed\n",
920 ether_sprintf(ni->ni_macaddr));
921 /* XXX statistic */
922 }
923 return (ni->ni_challenge != NULL);
924}
925
926/* XXX TODO: add statistics */
927static void
928ieee80211_auth_shared(struct ieee80211com *ic, struct ieee80211_frame *wh,
929 u_int8_t *frm, u_int8_t *efrm, struct ieee80211_node *ni, int rssi,
930 u_int32_t rstamp, u_int16_t seq, u_int16_t status)
931{
932 u_int8_t *challenge;
933 int allocbs, estatus;
934
935 /*
936 * NB: this can happen as we allow pre-shared key
937 * authentication to be enabled w/o wep being turned
938 * on so that configuration of these can be done
939 * in any order. It may be better to enforce the
940 * ordering in which case this check would just be
941 * for sanity/consistency.
942 */
943 if ((ic->ic_flags & IEEE80211_F_PRIVACY) == 0) {
944 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH,
945 ni->ni_macaddr, "shared key auth",
946 "%s", " PRIVACY is disabled");
947 estatus = IEEE80211_STATUS_ALG;
948 goto bad;
949 }
950 /*
951 * Pre-shared key authentication is evil; accept
952 * it only if explicitly configured (it is supported
953 * mainly for compatibility with clients like OS X).
954 */
955 if (ni->ni_authmode != IEEE80211_AUTH_AUTO &&
956 ni->ni_authmode != IEEE80211_AUTH_SHARED) {
957 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH,
958 ni->ni_macaddr, "shared key auth",
959 "bad sta auth mode %u", ni->ni_authmode);
960 ic->ic_stats.is_rx_bad_auth++; /* XXX maybe a unique error? */
961 estatus = IEEE80211_STATUS_ALG;
962 goto bad;
963 }
964
965 challenge = NULL;
966 if (frm + 1 < efrm) {
967 if ((frm[1] + 2) > (efrm - frm)) {
968 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH,
969 ni->ni_macaddr, "shared key auth",
970 "ie %d/%d too long",
971 frm[0], (frm[1] + 2) - (efrm - frm));
972 ic->ic_stats.is_rx_bad_auth++;
973 estatus = IEEE80211_STATUS_CHALLENGE;
974 goto bad;
975 }
976 if (*frm == IEEE80211_ELEMID_CHALLENGE)
977 challenge = frm;
978 frm += frm[1] + 2;
979 }
980 switch (seq) {
981 case IEEE80211_AUTH_SHARED_CHALLENGE:
982 case IEEE80211_AUTH_SHARED_RESPONSE:
983 if (challenge == NULL) {
984 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH,
985 ni->ni_macaddr, "shared key auth",
986 "%s", "no challenge");
987 ic->ic_stats.is_rx_bad_auth++;
988 estatus = IEEE80211_STATUS_CHALLENGE;
989 goto bad;
990 }
991 if (challenge[1] != IEEE80211_CHALLENGE_LEN) {
992 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH,
993 ni->ni_macaddr, "shared key auth",
994 "bad challenge len %d", challenge[1]);
995 ic->ic_stats.is_rx_bad_auth++;
996 estatus = IEEE80211_STATUS_CHALLENGE;
997 goto bad;
998 }
999 default:
1000 break;
1001 }
1002 switch (ic->ic_opmode) {
1003 case IEEE80211_M_MONITOR:
1004 case IEEE80211_M_AHDEMO:
1005 case IEEE80211_M_IBSS:
1006 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH,
1007 ni->ni_macaddr, "shared key auth",
1008 "bad operating mode %u", ic->ic_opmode);
1009 return;
1010 case IEEE80211_M_HOSTAP:
1011 if (ic->ic_state != IEEE80211_S_RUN) {
1012 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH,
1013 ni->ni_macaddr, "shared key auth",
1014 "bad state %u", ic->ic_state);
1015 estatus = IEEE80211_STATUS_ALG; /* XXX */
1016 goto bad;
1017 }
1018 switch (seq) {
1019 case IEEE80211_AUTH_SHARED_REQUEST:
1020 if (ni == ic->ic_bss) {
1021 ni = ieee80211_dup_bss(ic->ic_sta, wh->i_addr2);
1022 if (ni == NULL) {
1023 /* NB: no way to return an error */
1024 return;
1025 }
1026 allocbs = 1;
1027 } else {
1028 (void) ieee80211_ref_node(ni);
1029 allocbs = 0;
1030 }
1031 ni->ni_rssi = rssi;
1032 ni->ni_rstamp = rstamp;
1033 if (!alloc_challenge(ic, ni)) {
1034 /* NB: don't return error so they rexmit */
1035 return;
1036 }
1037 get_random_bytes(ni->ni_challenge,
1038 IEEE80211_CHALLENGE_LEN);
1039 IEEE80211_DPRINTF(ic,
1040 IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH,
1041 "[%s] shared key %sauth request\n",
1042 ether_sprintf(ni->ni_macaddr),
1043 allocbs ? "" : "re");
1044 break;
1045 case IEEE80211_AUTH_SHARED_RESPONSE:
1046 if (ni == ic->ic_bss) {
1047 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH,
1048 ni->ni_macaddr, "shared key response",
1049 "%s", "unknown station");
1050 /* NB: don't send a response */
1051 return;
1052 }
1053 if (ni->ni_challenge == NULL) {
1054 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH,
1055 ni->ni_macaddr, "shared key response",
1056 "%s", "no challenge recorded");
1057 ic->ic_stats.is_rx_bad_auth++;
1058 estatus = IEEE80211_STATUS_CHALLENGE;
1059 goto bad;
1060 }
1061 if (memcmp(ni->ni_challenge, &challenge[2],
1062 challenge[1]) != 0) {
1063 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH,
1064 ni->ni_macaddr, "shared key response",
1065 "%s", "challenge mismatch");
1066 ic->ic_stats.is_rx_auth_fail++;
1067 estatus = IEEE80211_STATUS_CHALLENGE;
1068 goto bad;
1069 }
1070 ni->ni_inact_reload = ic->ic_inact_auth;
1071 IEEE80211_DPRINTF(ic,
1072 IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH,
1073 "[%s] station authenticated (shared key)\n",
1074 ether_sprintf(ni->ni_macaddr));
1075 break;
1076 default:
1077 IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH,
1078 ni->ni_macaddr, "shared key auth",
1079 "bad seq %d", seq);
1080 ic->ic_stats.is_rx_bad_auth++;
1081 estatus = IEEE80211_STATUS_SEQUENCE;
1082 goto bad;
1083 }
1084 IEEE80211_SEND_MGMT(ic, ni,
1085 IEEE80211_FC0_SUBTYPE_AUTH, seq + 1);
1086 break;
1087
1088 case IEEE80211_M_STA:
1089 if (ic->ic_state != IEEE80211_S_AUTH)
1090 return;
1091 switch (seq) {
1092 case IEEE80211_AUTH_SHARED_PASS:
1093 if (ni->ni_challenge != NULL) {
1094 FREE(ni->ni_challenge, M_DEVBUF);
1095 ni->ni_challenge = NULL;
1096 }
1097 if (status != 0) {
1098 IEEE80211_DPRINTF(ic,
1099 IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH,
1100 "[%s] shared key auth failed (reason %d)\n",
1101 ether_sprintf(ieee80211_getbssid(ic, wh)),
1102 status);
1103 /* XXX can this happen? */
1104 if (ni != ic->ic_bss)
1105 ni->ni_fails++;
1106 ic->ic_stats.is_rx_auth_fail++;
1107 return;
1108 }
1109 ieee80211_new_state(ic, IEEE80211_S_ASSOC,
1110 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
1111 break;
1112 case IEEE80211_AUTH_SHARED_CHALLENGE:
1113 if (!alloc_challenge(ic, ni))
1114 return;
1115 /* XXX could optimize by passing recvd challenge */
1116 memcpy(ni->ni_challenge, &challenge[2], challenge[1]);
1117 IEEE80211_SEND_MGMT(ic, ni,
1118 IEEE80211_FC0_SUBTYPE_AUTH, seq + 1);
1119 break;
1120 default:
1121 IEEE80211_DISCARD(ic, IEEE80211_MSG_AUTH,
1122 wh, "shared key auth", "bad seq %d", seq);
1123 ic->ic_stats.is_rx_bad_auth++;
1124 return;
1125 }
1126 break;
1127 }
1128 return;
1129bad:
1130 /*
1131 * Send an error response; but only when operating as an AP.
1132 */
1133 if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
1134 /* XXX hack to workaround calling convention */
1135 IEEE80211_SEND_MGMT(ic, ni,
1136 IEEE80211_FC0_SUBTYPE_AUTH,
1137 (seq + 1) | (estatus<<16));
1138 }
1139}
1140
509/* Verify the existence and length of __elem or get out. */
510#define IEEE80211_VERIFY_ELEMENT(__elem, __maxlen) do { \
511 if ((__elem) == NULL) { \
1141/* Verify the existence and length of __elem or get out. */
1142#define IEEE80211_VERIFY_ELEMENT(__elem, __maxlen) do { \
1143 if ((__elem) == NULL) { \
512 IEEE80211_DPRINTF(("%s: no " #__elem "in %s frame\n", \
513 __func__, ieee80211_mgt_subtype_name[subtype >> \
514 IEEE80211_FC0_SUBTYPE_SHIFT])); \
1144 IEEE80211_DISCARD(ic, IEEE80211_MSG_ELEMID, \
1145 wh, ieee80211_mgt_subtype_name[subtype >> \
1146 IEEE80211_FC0_SUBTYPE_SHIFT], \
1147 "%s", "no " #__elem ); \
515 ic->ic_stats.is_rx_elem_missing++; \
516 return; \
517 } \
518 if ((__elem)[1] > (__maxlen)) { \
1148 ic->ic_stats.is_rx_elem_missing++; \
1149 return; \
1150 } \
1151 if ((__elem)[1] > (__maxlen)) { \
519 IEEE80211_DPRINTF(("%s: bad " #__elem " len %d in %s " \
520 "frame from %s\n", __func__, (__elem)[1], \
521 ieee80211_mgt_subtype_name[subtype >> \
522 IEEE80211_FC0_SUBTYPE_SHIFT], \
523 ether_sprintf(wh->i_addr2))); \
1152 IEEE80211_DISCARD(ic, IEEE80211_MSG_ELEMID, \
1153 wh, ieee80211_mgt_subtype_name[subtype >> \
1154 IEEE80211_FC0_SUBTYPE_SHIFT], \
1155 "bad " #__elem " len %d", (__elem)[1]); \
524 ic->ic_stats.is_rx_elem_toobig++; \
525 return; \
526 } \
527} while (0)
528
529#define IEEE80211_VERIFY_LENGTH(_len, _minlen) do { \
530 if ((_len) < (_minlen)) { \
1156 ic->ic_stats.is_rx_elem_toobig++; \
1157 return; \
1158 } \
1159} while (0)
1160
1161#define IEEE80211_VERIFY_LENGTH(_len, _minlen) do { \
1162 if ((_len) < (_minlen)) { \
531 IEEE80211_DPRINTF(("%s: %s frame too short from %s\n", \
532 __func__, \
533 ieee80211_mgt_subtype_name[subtype >> \
534 IEEE80211_FC0_SUBTYPE_SHIFT], \
535 ether_sprintf(wh->i_addr2))); \
1163 IEEE80211_DISCARD(ic, IEEE80211_MSG_ELEMID, \
1164 wh, ieee80211_mgt_subtype_name[subtype >> \
1165 IEEE80211_FC0_SUBTYPE_SHIFT], \
1166 "%s", "ie too short"); \
536 ic->ic_stats.is_rx_elem_toosmall++; \
537 return; \
538 } \
539} while (0)
540
1167 ic->ic_stats.is_rx_elem_toosmall++; \
1168 return; \
1169 } \
1170} while (0)
1171
1172#ifdef IEEE80211_DEBUG
1173static void
1174ieee80211_ssid_mismatch(struct ieee80211com *ic, const char *tag,
1175 u_int8_t mac[IEEE80211_ADDR_LEN], u_int8_t *ssid)
1176{
1177 printf("[%s] discard %s frame, ssid mismatch: ",
1178 ether_sprintf(mac), tag);
1179 ieee80211_print_essid(ssid + 2, ssid[1]);
1180 printf("\n");
1181}
1182
1183#define IEEE80211_VERIFY_SSID(_ni, _ssid) do { \
1184 if ((_ssid)[1] != 0 && \
1185 ((_ssid)[1] != (_ni)->ni_esslen || \
1186 memcmp((_ssid) + 2, (_ni)->ni_essid, (_ssid)[1]) != 0)) { \
1187 if (ieee80211_msg_input(ic)) \
1188 ieee80211_ssid_mismatch(ic, \
1189 ieee80211_mgt_subtype_name[subtype >> \
1190 IEEE80211_FC0_SUBTYPE_SHIFT], \
1191 wh->i_addr2, _ssid); \
1192 ic->ic_stats.is_rx_ssidmismatch++; \
1193 return; \
1194 } \
1195} while (0)
1196#else /* !IEEE80211_DEBUG */
1197#define IEEE80211_VERIFY_SSID(_ni, _ssid) do { \
1198 if ((_ssid)[1] != 0 && \
1199 ((_ssid)[1] != (_ni)->ni_esslen || \
1200 memcmp((_ssid) + 2, (_ni)->ni_essid, (_ssid)[1]) != 0)) { \
1201 ic->ic_stats.is_rx_ssidmismatch++; \
1202 return; \
1203 } \
1204} while (0)
1205#endif /* !IEEE80211_DEBUG */
1206
1207/* unalligned little endian access */
1208#define LE_READ_2(p) \
1209 ((u_int16_t) \
1210 ((((const u_int8_t *)(p))[0] ) | \
1211 (((const u_int8_t *)(p))[1] << 8)))
1212#define LE_READ_4(p) \
1213 ((u_int32_t) \
1214 ((((const u_int8_t *)(p))[0] ) | \
1215 (((const u_int8_t *)(p))[1] << 8) | \
1216 (((const u_int8_t *)(p))[2] << 16) | \
1217 (((const u_int8_t *)(p))[3] << 24)))
1218
1219static int __inline
1220iswpaoui(const u_int8_t *frm)
1221{
1222 return frm[1] > 3 && LE_READ_4(frm+2) == ((WPA_OUI_TYPE<<24)|WPA_OUI);
1223}
1224
1225static int __inline
1226iswmeoui(const u_int8_t *frm)
1227{
1228 return frm[1] > 3 && LE_READ_4(frm+2) == ((WME_OUI_TYPE<<24)|WME_OUI);
1229}
1230
1231static int __inline
1232iswmeparam(const u_int8_t *frm)
1233{
1234 return frm[1] > 5 && LE_READ_4(frm+2) == ((WME_OUI_TYPE<<24)|WME_OUI) &&
1235 frm[6] == WME_PARAM_OUI_SUBTYPE;
1236}
1237
1238static int __inline
1239iswmeinfo(const u_int8_t *frm)
1240{
1241 return frm[1] > 5 && LE_READ_4(frm+2) == ((WME_OUI_TYPE<<24)|WME_OUI) &&
1242 frm[6] == WME_INFO_OUI_SUBTYPE;
1243}
1244
1245static int __inline
1246isatherosoui(const u_int8_t *frm)
1247{
1248 return frm[1] > 3 && LE_READ_4(frm+2) == ((ATH_OUI_TYPE<<24)|ATH_OUI);
1249}
1250
1251/*
1252 * Convert a WPA cipher selector OUI to an internal
1253 * cipher algorithm. Where appropriate we also
1254 * record any key length.
1255 */
1256static int
1257wpa_cipher(u_int8_t *sel, u_int8_t *keylen)
1258{
1259#define WPA_SEL(x) (((x)<<24)|WPA_OUI)
1260 u_int32_t w = LE_READ_4(sel);
1261
1262 switch (w) {
1263 case WPA_SEL(WPA_CSE_NULL):
1264 return IEEE80211_CIPHER_NONE;
1265 case WPA_SEL(WPA_CSE_WEP40):
1266 if (keylen)
1267 *keylen = 40 / NBBY;
1268 return IEEE80211_CIPHER_WEP;
1269 case WPA_SEL(WPA_CSE_WEP104):
1270 if (keylen)
1271 *keylen = 104 / NBBY;
1272 return IEEE80211_CIPHER_WEP;
1273 case WPA_SEL(WPA_CSE_TKIP):
1274 return IEEE80211_CIPHER_TKIP;
1275 case WPA_SEL(WPA_CSE_CCMP):
1276 return IEEE80211_CIPHER_AES_CCM;
1277 }
1278 return 32; /* NB: so 1<< is discarded */
1279#undef WPA_SEL
1280}
1281
1282/*
1283 * Convert a WPA key management/authentication algorithm
1284 * to an internal code.
1285 */
1286static int
1287wpa_keymgmt(u_int8_t *sel)
1288{
1289#define WPA_SEL(x) (((x)<<24)|WPA_OUI)
1290 u_int32_t w = LE_READ_4(sel);
1291
1292 switch (w) {
1293 case WPA_SEL(WPA_ASE_8021X_UNSPEC):
1294 return WPA_ASE_8021X_UNSPEC;
1295 case WPA_SEL(WPA_ASE_8021X_PSK):
1296 return WPA_ASE_8021X_PSK;
1297 case WPA_SEL(WPA_ASE_NONE):
1298 return WPA_ASE_NONE;
1299 }
1300 return 0; /* NB: so is discarded */
1301#undef WPA_SEL
1302}
1303
1304/*
1305 * Parse a WPA information element to collect parameters
1306 * and validate the parameters against what has been
1307 * configured for the system.
1308 */
1309static int
1310ieee80211_parse_wpa(struct ieee80211com *ic, u_int8_t *frm,
1311 struct ieee80211_rsnparms *rsn, const struct ieee80211_frame *wh)
1312{
1313 u_int8_t len = frm[1];
1314 u_int32_t w;
1315 int n;
1316
1317 /*
1318 * Check the length once for fixed parts: OUI, type,
1319 * version, mcast cipher, and 2 selector counts.
1320 * Other, variable-length data, must be checked separately.
1321 */
1322 KASSERT(ic->ic_flags & IEEE80211_F_WPA1,
1323 ("not WPA, flags 0x%x", ic->ic_flags));
1324 if (len < 14) {
1325 IEEE80211_DISCARD_IE(ic,
1326 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1327 wh, "WPA", "too short, len %u", len);
1328 return IEEE80211_REASON_IE_INVALID;
1329 }
1330 frm += 6, len -= 4; /* NB: len is payload only */
1331 /* NB: iswapoui already validated the OUI and type */
1332 w = LE_READ_2(frm);
1333 if (w != WPA_VERSION) {
1334 IEEE80211_DISCARD_IE(ic,
1335 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1336 wh, "WPA", "bad version %u", w);
1337 return IEEE80211_REASON_IE_INVALID;
1338 }
1339 frm += 2, len -= 2;
1340
1341 /* multicast/group cipher */
1342 w = wpa_cipher(frm, &rsn->rsn_mcastkeylen);
1343 if (w != rsn->rsn_mcastcipher) {
1344 IEEE80211_DISCARD_IE(ic,
1345 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1346 wh, "WPA", "mcast cipher mismatch; got %u, expected %u",
1347 w, rsn->rsn_mcastcipher);
1348 return IEEE80211_REASON_IE_INVALID;
1349 }
1350 frm += 4, len -= 4;
1351
1352 /* unicast ciphers */
1353 n = LE_READ_2(frm);
1354 frm += 2, len -= 2;
1355 if (len < n*4+2) {
1356 IEEE80211_DISCARD_IE(ic,
1357 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1358 wh, "WPA", "ucast cipher data too short; len %u, n %u",
1359 len, n);
1360 return IEEE80211_REASON_IE_INVALID;
1361 }
1362 w = 0;
1363 for (; n > 0; n--) {
1364 w |= 1<<wpa_cipher(frm, &rsn->rsn_ucastkeylen);
1365 frm += 4, len -= 4;
1366 }
1367 w &= rsn->rsn_ucastcipherset;
1368 if (w == 0) {
1369 IEEE80211_DISCARD_IE(ic,
1370 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1371 wh, "WPA", "%s", "ucast cipher set empty");
1372 return IEEE80211_REASON_IE_INVALID;
1373 }
1374 if (w & (1<<IEEE80211_CIPHER_TKIP))
1375 rsn->rsn_ucastcipher = IEEE80211_CIPHER_TKIP;
1376 else
1377 rsn->rsn_ucastcipher = IEEE80211_CIPHER_AES_CCM;
1378
1379 /* key management algorithms */
1380 n = LE_READ_2(frm);
1381 frm += 2, len -= 2;
1382 if (len < n*4) {
1383 IEEE80211_DISCARD_IE(ic,
1384 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1385 wh, "WPA", "key mgmt alg data too short; len %u, n %u",
1386 len, n);
1387 return IEEE80211_REASON_IE_INVALID;
1388 }
1389 w = 0;
1390 for (; n > 0; n--) {
1391 w |= wpa_keymgmt(frm);
1392 frm += 4, len -= 4;
1393 }
1394 w &= rsn->rsn_keymgmtset;
1395 if (w == 0) {
1396 IEEE80211_DISCARD_IE(ic,
1397 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1398 wh, "WPA", "%s", "no acceptable key mgmt alg");
1399 return IEEE80211_REASON_IE_INVALID;
1400 }
1401 if (w & WPA_ASE_8021X_UNSPEC)
1402 rsn->rsn_keymgmt = WPA_ASE_8021X_UNSPEC;
1403 else
1404 rsn->rsn_keymgmt = WPA_ASE_8021X_PSK;
1405
1406 if (len > 2) /* optional capabilities */
1407 rsn->rsn_caps = LE_READ_2(frm);
1408
1409 return 0;
1410}
1411
1412/*
1413 * Convert an RSN cipher selector OUI to an internal
1414 * cipher algorithm. Where appropriate we also
1415 * record any key length.
1416 */
1417static int
1418rsn_cipher(u_int8_t *sel, u_int8_t *keylen)
1419{
1420#define RSN_SEL(x) (((x)<<24)|RSN_OUI)
1421 u_int32_t w = LE_READ_4(sel);
1422
1423 switch (w) {
1424 case RSN_SEL(RSN_CSE_NULL):
1425 return IEEE80211_CIPHER_NONE;
1426 case RSN_SEL(RSN_CSE_WEP40):
1427 if (keylen)
1428 *keylen = 40 / NBBY;
1429 return IEEE80211_CIPHER_WEP;
1430 case RSN_SEL(RSN_CSE_WEP104):
1431 if (keylen)
1432 *keylen = 104 / NBBY;
1433 return IEEE80211_CIPHER_WEP;
1434 case RSN_SEL(RSN_CSE_TKIP):
1435 return IEEE80211_CIPHER_TKIP;
1436 case RSN_SEL(RSN_CSE_CCMP):
1437 return IEEE80211_CIPHER_AES_CCM;
1438 case RSN_SEL(RSN_CSE_WRAP):
1439 return IEEE80211_CIPHER_AES_OCB;
1440 }
1441 return 32; /* NB: so 1<< is discarded */
1442#undef WPA_SEL
1443}
1444
1445/*
1446 * Convert an RSN key management/authentication algorithm
1447 * to an internal code.
1448 */
1449static int
1450rsn_keymgmt(u_int8_t *sel)
1451{
1452#define RSN_SEL(x) (((x)<<24)|RSN_OUI)
1453 u_int32_t w = LE_READ_4(sel);
1454
1455 switch (w) {
1456 case RSN_SEL(RSN_ASE_8021X_UNSPEC):
1457 return RSN_ASE_8021X_UNSPEC;
1458 case RSN_SEL(RSN_ASE_8021X_PSK):
1459 return RSN_ASE_8021X_PSK;
1460 case RSN_SEL(RSN_ASE_NONE):
1461 return RSN_ASE_NONE;
1462 }
1463 return 0; /* NB: so is discarded */
1464#undef RSN_SEL
1465}
1466
1467/*
1468 * Parse a WPA/RSN information element to collect parameters
1469 * and validate the parameters against what has been
1470 * configured for the system.
1471 */
1472static int
1473ieee80211_parse_rsn(struct ieee80211com *ic, u_int8_t *frm,
1474 struct ieee80211_rsnparms *rsn, const struct ieee80211_frame *wh)
1475{
1476 u_int8_t len = frm[1];
1477 u_int32_t w;
1478 int n;
1479
1480 /*
1481 * Check the length once for fixed parts:
1482 * version, mcast cipher, and 2 selector counts.
1483 * Other, variable-length data, must be checked separately.
1484 */
1485 KASSERT(ic->ic_flags & IEEE80211_F_WPA2,
1486 ("not RSN, flags 0x%x", ic->ic_flags));
1487 if (len < 10) {
1488 IEEE80211_DISCARD_IE(ic,
1489 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1490 wh, "RSN", "too short, len %u", len);
1491 return IEEE80211_REASON_IE_INVALID;
1492 }
1493 frm += 2;
1494 w = LE_READ_2(frm);
1495 if (w != RSN_VERSION) {
1496 IEEE80211_DISCARD_IE(ic,
1497 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1498 wh, "RSN", "bad version %u", w);
1499 return IEEE80211_REASON_IE_INVALID;
1500 }
1501 frm += 2, len -= 2;
1502
1503 /* multicast/group cipher */
1504 w = rsn_cipher(frm, &rsn->rsn_mcastkeylen);
1505 if (w != rsn->rsn_mcastcipher) {
1506 IEEE80211_DISCARD_IE(ic,
1507 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1508 wh, "RSN", "mcast cipher mismatch; got %u, expected %u",
1509 w, rsn->rsn_mcastcipher);
1510 return IEEE80211_REASON_IE_INVALID;
1511 }
1512 frm += 4, len -= 4;
1513
1514 /* unicast ciphers */
1515 n = LE_READ_2(frm);
1516 frm += 2, len -= 2;
1517 if (len < n*4+2) {
1518 IEEE80211_DISCARD_IE(ic,
1519 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1520 wh, "RSN", "ucast cipher data too short; len %u, n %u",
1521 len, n);
1522 return IEEE80211_REASON_IE_INVALID;
1523 }
1524 w = 0;
1525 for (; n > 0; n--) {
1526 w |= 1<<rsn_cipher(frm, &rsn->rsn_ucastkeylen);
1527 frm += 4, len -= 4;
1528 }
1529 w &= rsn->rsn_ucastcipherset;
1530 if (w == 0) {
1531 IEEE80211_DISCARD_IE(ic,
1532 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1533 wh, "RSN", "%s", "ucast cipher set empty");
1534 return IEEE80211_REASON_IE_INVALID;
1535 }
1536 if (w & (1<<IEEE80211_CIPHER_TKIP))
1537 rsn->rsn_ucastcipher = IEEE80211_CIPHER_TKIP;
1538 else
1539 rsn->rsn_ucastcipher = IEEE80211_CIPHER_AES_CCM;
1540
1541 /* key management algorithms */
1542 n = LE_READ_2(frm);
1543 frm += 2, len -= 2;
1544 if (len < n*4) {
1545 IEEE80211_DISCARD_IE(ic,
1546 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1547 wh, "RSN", "key mgmt alg data too short; len %u, n %u",
1548 len, n);
1549 return IEEE80211_REASON_IE_INVALID;
1550 }
1551 w = 0;
1552 for (; n > 0; n--) {
1553 w |= rsn_keymgmt(frm);
1554 frm += 4, len -= 4;
1555 }
1556 w &= rsn->rsn_keymgmtset;
1557 if (w == 0) {
1558 IEEE80211_DISCARD_IE(ic,
1559 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA,
1560 wh, "RSN", "%s", "no acceptable key mgmt alg");
1561 return IEEE80211_REASON_IE_INVALID;
1562 }
1563 if (w & RSN_ASE_8021X_UNSPEC)
1564 rsn->rsn_keymgmt = RSN_ASE_8021X_UNSPEC;
1565 else
1566 rsn->rsn_keymgmt = RSN_ASE_8021X_PSK;
1567
1568 /* optional RSN capabilities */
1569 if (len > 2)
1570 rsn->rsn_caps = LE_READ_2(frm);
1571 /* XXXPMKID */
1572
1573 return 0;
1574}
1575
1576static int
1577ieee80211_parse_wmeparams(struct ieee80211com *ic, u_int8_t *frm,
1578 const struct ieee80211_frame *wh)
1579{
1580#define MS(_v, _f) (((_v) & _f) >> _f##_S)
1581 struct ieee80211_wme_state *wme = &ic->ic_wme;
1582 u_int len = frm[1], qosinfo;
1583 int i;
1584
1585 if (len < sizeof(struct ieee80211_wme_param)-2) {
1586 IEEE80211_DISCARD_IE(ic,
1587 IEEE80211_MSG_ELEMID | IEEE80211_MSG_WME,
1588 wh, "WME", "too short, len %u", len);
1589 return 0;
1590 }
1591 qosinfo = frm[__offsetof(struct ieee80211_wme_param, param_qosInfo)];
1592 qosinfo &= WME_QOSINFO_COUNT;
1593 /* XXX do proper check for wraparound */
1594 if (qosinfo == wme->wme_wmeChanParams.cap_info)
1595 return 0;
1596 frm += __offsetof(struct ieee80211_wme_param, params_acParams);
1597 for (i = 0; i < WME_NUM_AC; i++) {
1598 struct wmeParams *wmep =
1599 &wme->wme_wmeChanParams.cap_wmeParams[i];
1600 /* NB: ACI not used */
1601 wmep->wmep_acm = MS(frm[0], WME_PARAM_ACM);
1602 wmep->wmep_aifsn = MS(frm[0], WME_PARAM_AIFSN);
1603 wmep->wmep_logcwmin = MS(frm[1], WME_PARAM_LOGCWMIN);
1604 wmep->wmep_logcwmax = MS(frm[1], WME_PARAM_LOGCWMAX);
1605 wmep->wmep_txopLimit = LE_READ_2(frm+2);
1606 frm += 4;
1607 }
1608 wme->wme_wmeChanParams.cap_info = qosinfo;
1609 return 1;
1610#undef MS
1611}
1612
1613static void
1614ieee80211_saveie(u_int8_t **iep, const u_int8_t *ie)
1615{
1616 u_int ielen = ie[1]+2;
1617 /*
1618 * Record information element for later use.
1619 */
1620 if (*iep == NULL || (*iep)[1] != ie[1]) {
1621 if (*iep != NULL)
1622 FREE(*iep, M_DEVBUF);
1623 MALLOC(*iep, void*, ielen, M_DEVBUF, M_NOWAIT);
1624 }
1625 if (*iep != NULL)
1626 memcpy(*iep, ie, ielen);
1627 /* XXX note failure */
1628}
1629
1630#ifdef IEEE80211_DEBUG
1631static void
1632dump_probe_beacon(u_int8_t subtype, int isnew,
1633 const u_int8_t mac[IEEE80211_ADDR_LEN],
1634 u_int8_t chan, u_int8_t bchan, u_int16_t capinfo, u_int16_t bintval,
1635 u_int8_t erp, u_int8_t *ssid, u_int8_t *country)
1636{
1637 printf("[%s] %s%s on chan %u (bss chan %u) ",
1638 ether_sprintf(mac), isnew ? "new " : "",
1639 ieee80211_mgt_subtype_name[subtype >> IEEE80211_FC0_SUBTYPE_SHIFT],
1640 chan, bchan);
1641 ieee80211_print_essid(ssid + 2, ssid[1]);
1642 printf("\n");
1643
1644 if (isnew) {
1645 printf("[%s] caps 0x%x bintval %u erp 0x%x",
1646 ether_sprintf(mac), capinfo, bintval, erp);
1647 if (country) {
1648#ifdef __FreeBSD__
1649 printf(" country info %*D", country[1], country+2, " ");
1650#else
1651 int i;
1652 printf(" country info");
1653 for (i = 0; i < country[1]; i++)
1654 printf(" %02x", country[i+2]);
1655#endif
1656 }
1657 printf("\n");
1658 }
1659}
1660#endif /* IEEE80211_DEBUG */
1661
541void
542ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
543 struct ieee80211_node *ni,
544 int subtype, int rssi, u_int32_t rstamp)
545{
1662void
1663ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
1664 struct ieee80211_node *ni,
1665 int subtype, int rssi, u_int32_t rstamp)
1666{
546 struct ifnet *ifp = &ic->ic_if;
1667#define ISPROBE(_st) ((_st) == IEEE80211_FC0_SUBTYPE_PROBE_RESP)
1668#define ISREASSOC(_st) ((_st) == IEEE80211_FC0_SUBTYPE_REASSOC_RESP)
547 struct ieee80211_frame *wh;
548 u_int8_t *frm, *efrm;
1669 struct ieee80211_frame *wh;
1670 u_int8_t *frm, *efrm;
549 u_int8_t *ssid, *rates, *xrates;
550 int reassoc, resp, newassoc, allocbs;
1671 u_int8_t *ssid, *rates, *xrates, *wpa, *wme;
1672 int reassoc, resp, allocbs;
551
552 wh = mtod(m0, struct ieee80211_frame *);
553 frm = (u_int8_t *)&wh[1];
554 efrm = mtod(m0, u_int8_t *) + m0->m_len;
555 switch (subtype) {
556 case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
557 case IEEE80211_FC0_SUBTYPE_BEACON: {
1673
1674 wh = mtod(m0, struct ieee80211_frame *);
1675 frm = (u_int8_t *)&wh[1];
1676 efrm = mtod(m0, u_int8_t *) + m0->m_len;
1677 switch (subtype) {
1678 case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
1679 case IEEE80211_FC0_SUBTYPE_BEACON: {
558 u_int8_t *tstamp, *bintval, *capinfo, *country;
1680 u_int8_t *tstamp, *country;
559 u_int8_t chan, bchan, fhindex, erp;
1681 u_int8_t chan, bchan, fhindex, erp;
1682 u_int16_t capinfo, bintval, timoff;
560 u_int16_t fhdwell;
1683 u_int16_t fhdwell;
561 int isprobe;
562
1684
563 if (ic->ic_opmode != IEEE80211_M_IBSS &&
564 ic->ic_state != IEEE80211_S_SCAN) {
565 /* XXX: may be useful for background scan */
1685 if (subtype == IEEE80211_FC0_SUBTYPE_BEACON) {
1686 /*
1687 * Count beacon frames specially, some drivers
1688 * use this info to do things like update LED's.
1689 */
1690 ic->ic_stats.is_rx_beacon++;
1691 IEEE80211_NODE_STAT(ni, rx_beacons);
1692 } else
1693 IEEE80211_NODE_STAT(ni, rx_proberesp);
1694 /*
1695 * We process beacon/probe response frames:
1696 * o when scanning, or
1697 * o station mode when associated (to collect state
1698 * updates such as 802.11g slot time), or
1699 * o adhoc mode (to discover neighbors)
1700 * Frames otherwise received are discarded.
1701 */
1702 if (!((ic->ic_flags & IEEE80211_F_SCAN) ||
1703 (ic->ic_opmode == IEEE80211_M_STA && ni->ni_associd) ||
1704 ic->ic_opmode != IEEE80211_M_IBSS)) {
1705 ic->ic_stats.is_rx_mgtdiscard++;
566 return;
567 }
1706 return;
1707 }
568 isprobe = (subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP);
569
570 /*
571 * beacon/probe response frame format
572 * [8] time stamp
573 * [2] beacon interval
574 * [2] capability information
575 * [tlv] ssid
576 * [tlv] supported rates
577 * [tlv] country information
578 * [tlv] parameter set (FH/DS)
579 * [tlv] erp information
580 * [tlv] extended supported rates
1708 /*
1709 * beacon/probe response frame format
1710 * [8] time stamp
1711 * [2] beacon interval
1712 * [2] capability information
1713 * [tlv] ssid
1714 * [tlv] supported rates
1715 * [tlv] country information
1716 * [tlv] parameter set (FH/DS)
1717 * [tlv] erp information
1718 * [tlv] extended supported rates
1719 * [tlv] WME
1720 * [tlv] WPA or RSN
581 */
582 IEEE80211_VERIFY_LENGTH(efrm - frm, 12);
1721 */
1722 IEEE80211_VERIFY_LENGTH(efrm - frm, 12);
583 tstamp = frm; frm += 8;
584 bintval = frm; frm += 2;
585 capinfo = frm; frm += 2;
586 ssid = rates = xrates = country = NULL;
1723 tstamp = frm; frm += 8;
1724 bintval = le16toh(*(u_int16_t *)frm); frm += 2;
1725 capinfo = le16toh(*(u_int16_t *)frm); frm += 2;
1726 ssid = rates = xrates = country = wpa = wme = NULL;
587 bchan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
588 chan = bchan;
589 fhdwell = 0;
590 fhindex = 0;
591 erp = 0;
1727 bchan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
1728 chan = bchan;
1729 fhdwell = 0;
1730 fhindex = 0;
1731 erp = 0;
1732 timoff = 0;
592 while (frm < efrm) {
593 switch (*frm) {
594 case IEEE80211_ELEMID_SSID:
595 ssid = frm;
596 break;
597 case IEEE80211_ELEMID_RATES:
598 rates = frm;
599 break;
600 case IEEE80211_ELEMID_COUNTRY:
601 country = frm;
602 break;
603 case IEEE80211_ELEMID_FHPARMS:
604 if (ic->ic_phytype == IEEE80211_T_FH) {
1733 while (frm < efrm) {
1734 switch (*frm) {
1735 case IEEE80211_ELEMID_SSID:
1736 ssid = frm;
1737 break;
1738 case IEEE80211_ELEMID_RATES:
1739 rates = frm;
1740 break;
1741 case IEEE80211_ELEMID_COUNTRY:
1742 country = frm;
1743 break;
1744 case IEEE80211_ELEMID_FHPARMS:
1745 if (ic->ic_phytype == IEEE80211_T_FH) {
605 fhdwell = (frm[3] << 8) | frm[2];
1746 fhdwell = LE_READ_2(&frm[2]);
606 chan = IEEE80211_FH_CHAN(frm[4], frm[5]);
607 fhindex = frm[6];
608 }
609 break;
610 case IEEE80211_ELEMID_DSPARMS:
611 /*
612 * XXX hack this since depending on phytype
613 * is problematic for multi-mode devices.
614 */
615 if (ic->ic_phytype != IEEE80211_T_FH)
616 chan = frm[2];
617 break;
618 case IEEE80211_ELEMID_TIM:
1747 chan = IEEE80211_FH_CHAN(frm[4], frm[5]);
1748 fhindex = frm[6];
1749 }
1750 break;
1751 case IEEE80211_ELEMID_DSPARMS:
1752 /*
1753 * XXX hack this since depending on phytype
1754 * is problematic for multi-mode devices.
1755 */
1756 if (ic->ic_phytype != IEEE80211_T_FH)
1757 chan = frm[2];
1758 break;
1759 case IEEE80211_ELEMID_TIM:
1760 /* XXX ATIM? */
1761 timoff = frm - mtod(m0, u_int8_t *);
619 break;
620 case IEEE80211_ELEMID_IBSSPARMS:
621 break;
622 case IEEE80211_ELEMID_XRATES:
623 xrates = frm;
624 break;
625 case IEEE80211_ELEMID_ERP:
626 if (frm[1] != 1) {
1762 break;
1763 case IEEE80211_ELEMID_IBSSPARMS:
1764 break;
1765 case IEEE80211_ELEMID_XRATES:
1766 xrates = frm;
1767 break;
1768 case IEEE80211_ELEMID_ERP:
1769 if (frm[1] != 1) {
627 IEEE80211_DPRINTF(("%s: invalid ERP "
628 "element; length %u, expecting "
629 "1\n", __func__, frm[1]));
1770 IEEE80211_DISCARD_IE(ic,
1771 IEEE80211_MSG_ELEMID, wh, "ERP",
1772 "bad len %u", frm[1]);
630 ic->ic_stats.is_rx_elem_toobig++;
631 break;
632 }
633 erp = frm[2];
634 break;
1773 ic->ic_stats.is_rx_elem_toobig++;
1774 break;
1775 }
1776 erp = frm[2];
1777 break;
1778 case IEEE80211_ELEMID_RSN:
1779 wpa = frm;
1780 break;
1781 case IEEE80211_ELEMID_VENDOR:
1782 if (iswpaoui(frm))
1783 wpa = frm;
1784 else if (iswmeparam(frm) || iswmeinfo(frm))
1785 wme = frm;
1786 /* XXX Atheros OUI support */
1787 break;
635 default:
1788 default:
636 IEEE80211_DPRINTF2(("%s: element id %u/len %u "
637 "ignored\n", __func__, *frm, frm[1]));
1789 IEEE80211_DISCARD_IE(ic, IEEE80211_MSG_ELEMID,
1790 wh, "unhandled",
1791 "id %u, len %u", *frm, frm[1]);
638 ic->ic_stats.is_rx_elem_unknown++;
639 break;
640 }
641 frm += frm[1] + 2;
642 }
643 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE);
644 IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN);
645 if (
646#if IEEE80211_CHAN_MAX < 255
647 chan > IEEE80211_CHAN_MAX ||
648#endif
649 isclr(ic->ic_chan_active, chan)) {
1792 ic->ic_stats.is_rx_elem_unknown++;
1793 break;
1794 }
1795 frm += frm[1] + 2;
1796 }
1797 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE);
1798 IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN);
1799 if (
1800#if IEEE80211_CHAN_MAX < 255
1801 chan > IEEE80211_CHAN_MAX ||
1802#endif
1803 isclr(ic->ic_chan_active, chan)) {
650 IEEE80211_DPRINTF(("%s: ignore %s with invalid channel "
651 "%u\n", __func__,
652 isprobe ? "probe response" : "beacon",
653 chan));
1804 IEEE80211_DISCARD(ic, IEEE80211_MSG_ELEMID,
1805 wh, ieee80211_mgt_subtype_name[subtype >>
1806 IEEE80211_FC0_SUBTYPE_SHIFT],
1807 "invalid channel %u", chan);
654 ic->ic_stats.is_rx_badchan++;
655 return;
656 }
657 if (chan != bchan && ic->ic_phytype != IEEE80211_T_FH) {
658 /*
659 * Frame was received on a channel different from the
660 * one indicated in the DS params element id;
661 * silently discard it.
662 *
663 * NB: this can happen due to signal leakage.
664 * But we should take it for FH phy because
665 * the rssi value should be correct even for
666 * different hop pattern in FH.
667 */
1808 ic->ic_stats.is_rx_badchan++;
1809 return;
1810 }
1811 if (chan != bchan && ic->ic_phytype != IEEE80211_T_FH) {
1812 /*
1813 * Frame was received on a channel different from the
1814 * one indicated in the DS params element id;
1815 * silently discard it.
1816 *
1817 * NB: this can happen due to signal leakage.
1818 * But we should take it for FH phy because
1819 * the rssi value should be correct even for
1820 * different hop pattern in FH.
1821 */
668 IEEE80211_DPRINTF(("%s: ignore %s on channel %u marked "
669 "for channel %u\n", __func__,
670 isprobe ? "probe response" : "beacon",
671 bchan, chan));
1822 IEEE80211_DISCARD(ic, IEEE80211_MSG_ELEMID,
1823 wh, ieee80211_mgt_subtype_name[subtype >>
1824 IEEE80211_FC0_SUBTYPE_SHIFT],
1825 "for off-channel %u\n", chan);
672 ic->ic_stats.is_rx_chanmismatch++;
673 return;
674 }
675
676 /*
1826 ic->ic_stats.is_rx_chanmismatch++;
1827 return;
1828 }
1829
1830 /*
677 * Use mac and channel for lookup so we collect all
678 * potential AP's when scanning. Otherwise we may
679 * see the same AP on multiple channels and will only
680 * record the last one. We could filter APs here based
681 * on rssi, etc. but leave that to the end of the scan
682 * so we can keep the selection criteria in one spot.
683 * This may result in a bloat of the scanned AP list but
684 * it shouldn't be too much.
1831 * When operating in station mode, check for state updates.
1832 * Be careful to ignore beacons received while doing a
1833 * background scan. We consider only 11g/WMM stuff right now.
685 */
1834 */
686 ni = ieee80211_lookup_node(ic, wh->i_addr2,
687 &ic->ic_channels[chan]);
688#ifdef IEEE80211_DEBUG
689 if (ieee80211_debug &&
690 (ni == NULL || ic->ic_state == IEEE80211_S_SCAN)) {
691 printf("%s: %s%s on chan %u (bss chan %u) ",
692 __func__, (ni == NULL ? "new " : ""),
693 isprobe ? "probe response" : "beacon",
694 chan, bchan);
695 ieee80211_print_essid(ssid + 2, ssid[1]);
696 printf(" from %s\n", ether_sprintf(wh->i_addr2));
697 printf("%s: caps 0x%x bintval %u erp 0x%x\n",
698 __func__, le16toh(*(u_int16_t *)capinfo),
699 le16toh(*(u_int16_t *)bintval), erp);
700 if (country)
701 printf("%s: country info %*D\n",
702 __func__, country[1], country+2, " ");
1835 if (ic->ic_opmode == IEEE80211_M_STA &&
1836 ni->ni_associd != 0 &&
1837 ((ic->ic_flags & IEEE80211_F_SCAN) == 0 ||
1838 IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_bssid))) {
1839 if (ni->ni_erp != erp) {
1840 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC,
1841 "[%s] erp change: was 0x%x, now 0x%x\n",
1842 ether_sprintf(wh->i_addr2),
1843 ni->ni_erp, erp);
1844 if (erp & IEEE80211_ERP_USE_PROTECTION)
1845 ic->ic_flags |= IEEE80211_F_USEPROT;
1846 else
1847 ic->ic_flags &= ~IEEE80211_F_USEPROT;
1848 ni->ni_erp = erp;
1849 /* XXX statistic */
1850 }
1851 if ((ni->ni_capinfo ^ capinfo) & IEEE80211_CAPINFO_SHORT_SLOTTIME) {
1852 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC,
1853 "[%s] capabilities change: before 0x%x,"
1854 " now 0x%x\n",
1855 ether_sprintf(wh->i_addr2),
1856 ni->ni_capinfo, capinfo);
1857 /*
1858 * NB: we assume short preamble doesn't
1859 * change dynamically
1860 */
1861 ieee80211_set_shortslottime(ic,
1862 ic->ic_curmode == IEEE80211_MODE_11A ||
1863 (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME));
1864 ni->ni_capinfo = capinfo;
1865 /* XXX statistic */
1866 }
1867 if (wme != NULL &&
1868 ieee80211_parse_wmeparams(ic, wme, wh))
1869 ieee80211_wme_updateparams(ic);
1870 /* NB: don't need the rest of this */
1871 return;
703 }
1872 }
1873
1874 if (ni == ic->ic_bss) {
1875#ifdef IEEE80211_DEBUG
1876 if (ieee80211_msg_scan(ic))
1877 dump_probe_beacon(subtype, 1,
1878 wh->i_addr2, chan, bchan, capinfo,
1879 bintval, erp, ssid, country);
704#endif
1880#endif
705 if (ni == NULL) {
706 ni = ieee80211_alloc_node(ic, wh->i_addr2);
1881 /*
1882 * Create a new entry. If scanning the entry goes
1883 * in the scan cache. Otherwise, be particular when
1884 * operating in adhoc mode--only take nodes marked
1885 * as ibss participants so we don't populate our
1886 * neighbor table with unintersting sta's.
1887 */
1888 if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) {
1889 if ((capinfo & IEEE80211_CAPINFO_IBSS) == 0)
1890 return;
1891 ni = ieee80211_fakeup_adhoc_node(ic->ic_sta,
1892 wh->i_addr2);
1893 } else
1894 ni = ieee80211_dup_bss(&ic->ic_scan, wh->i_addr2);
707 if (ni == NULL)
708 return;
709 ni->ni_esslen = ssid[1];
710 memset(ni->ni_essid, 0, sizeof(ni->ni_essid));
711 memcpy(ni->ni_essid, ssid + 2, ssid[1]);
1895 if (ni == NULL)
1896 return;
1897 ni->ni_esslen = ssid[1];
1898 memset(ni->ni_essid, 0, sizeof(ni->ni_essid));
1899 memcpy(ni->ni_essid, ssid + 2, ssid[1]);
712 allocbs = 1;
713 } else if (ssid[1] != 0 && isprobe) {
1900 } else if (ssid[1] != 0 &&
1901 (ISPROBE(subtype) || ni->ni_esslen == 0)) {
714 /*
1902 /*
715 * Update ESSID at probe response to adopt hidden AP by
716 * Lucent/Cisco, which announces null ESSID in beacon.
1903 * Update ESSID at probe response to adopt
1904 * hidden AP by Lucent/Cisco, which announces
1905 * null ESSID in beacon.
717 */
1906 */
1907#ifdef IEEE80211_DEBUG
1908 if (ieee80211_msg_scan(ic) ||
1909 ieee80211_msg_debug(ic))
1910 dump_probe_beacon(subtype, 0,
1911 wh->i_addr2, chan, bchan, capinfo,
1912 bintval, erp, ssid, country);
1913#endif
718 ni->ni_esslen = ssid[1];
719 memset(ni->ni_essid, 0, sizeof(ni->ni_essid));
720 memcpy(ni->ni_essid, ssid + 2, ssid[1]);
1914 ni->ni_esslen = ssid[1];
1915 memset(ni->ni_essid, 0, sizeof(ni->ni_essid));
1916 memcpy(ni->ni_essid, ssid + 2, ssid[1]);
721 allocbs = 0;
722 } else
723 allocbs = 0;
1917 }
1918 ni->ni_scangen = ic->ic_scan.nt_scangen;
724 IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3);
725 ni->ni_rssi = rssi;
726 ni->ni_rstamp = rstamp;
1919 IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3);
1920 ni->ni_rssi = rssi;
1921 ni->ni_rstamp = rstamp;
727 memcpy(ni->ni_tstamp, tstamp, sizeof(ni->ni_tstamp));
728 ni->ni_intval = le16toh(*(u_int16_t *)bintval);
729 ni->ni_capinfo = le16toh(*(u_int16_t *)capinfo);
730 /* XXX validate channel # */
1922 memcpy(ni->ni_tstamp.data, tstamp, sizeof(ni->ni_tstamp));
1923 ni->ni_intval = bintval;
1924 ni->ni_capinfo = capinfo;
731 ni->ni_chan = &ic->ic_channels[chan];
732 ni->ni_fhdwell = fhdwell;
733 ni->ni_fhindex = fhindex;
734 ni->ni_erp = erp;
1925 ni->ni_chan = &ic->ic_channels[chan];
1926 ni->ni_fhdwell = fhdwell;
1927 ni->ni_fhindex = fhindex;
1928 ni->ni_erp = erp;
735 /* NB: must be after ni_chan is setup */
736 ieee80211_setup_rates(ic, ni, rates, xrates, IEEE80211_F_DOSORT);
737 /*
1929 /*
738 * When scanning we record results (nodes) with a zero
739 * refcnt. Otherwise we want to hold the reference for
740 * ibss neighbors so the nodes don't get released prematurely.
741 * Anything else can be discarded (XXX and should be handled
742 * above so we don't do so much work).
1930 * Record the byte offset from the mac header to
1931 * the start of the TIM information element for
1932 * use by hardware and/or to speedup software
1933 * processing of beacon frames.
743 */
1934 */
744 if (ic->ic_state == IEEE80211_S_SCAN)
745 ieee80211_unref_node(&ni); /* NB: do not free */
746 else if (ic->ic_opmode == IEEE80211_M_IBSS &&
747 allocbs && isprobe) {
748 /*
749 * Fake an association so the driver can setup it's
750 * private state. The rate set has been setup above;
751 * there is no handshake as in ap/station operation.
752 */
753 if (ic->ic_newassoc)
754 (*ic->ic_newassoc)(ic, ni, 1);
755 /* NB: hold reference */
756 } else {
757 /* XXX optimize to avoid work done above */
758 ieee80211_free_node(ic, ni);
759 }
1935 ni->ni_timoff = timoff;
1936 /*
1937 * Record optional information elements that might be
1938 * used by applications or drivers.
1939 */
1940 if (wme != NULL)
1941 ieee80211_saveie(&ni->ni_wme_ie, wme);
1942 if (wpa != NULL)
1943 ieee80211_saveie(&ni->ni_wpa_ie, wpa);
1944 /* NB: must be after ni_chan is setup */
1945 ieee80211_setup_rates(ic, ni, rates, xrates, IEEE80211_F_DOSORT);
760 break;
761 }
762
763 case IEEE80211_FC0_SUBTYPE_PROBE_REQ: {
764 u_int8_t rate;
765
1946 break;
1947 }
1948
1949 case IEEE80211_FC0_SUBTYPE_PROBE_REQ: {
1950 u_int8_t rate;
1951
766 if (ic->ic_opmode == IEEE80211_M_STA)
1952 if (ic->ic_opmode == IEEE80211_M_STA ||
1953 ic->ic_state != IEEE80211_S_RUN) {
1954 ic->ic_stats.is_rx_mgtdiscard++;
767 return;
1955 return;
768 if (ic->ic_state != IEEE80211_S_RUN)
1956 }
1957 if (IEEE80211_IS_MULTICAST(wh->i_addr2)) {
1958 /* frame must be directed */
1959 ic->ic_stats.is_rx_mgtdiscard++; /* XXX stat */
769 return;
1960 return;
1961 }
770
771 /*
772 * prreq frame format
773 * [tlv] ssid
774 * [tlv] supported rates
775 * [tlv] extended supported rates
776 */
777 ssid = rates = xrates = NULL;

--- 8 unchanged lines hidden (view full) ---

786 case IEEE80211_ELEMID_XRATES:
787 xrates = frm;
788 break;
789 }
790 frm += frm[1] + 2;
791 }
792 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE);
793 IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN);
1962
1963 /*
1964 * prreq frame format
1965 * [tlv] ssid
1966 * [tlv] supported rates
1967 * [tlv] extended supported rates
1968 */
1969 ssid = rates = xrates = NULL;

--- 8 unchanged lines hidden (view full) ---

1978 case IEEE80211_ELEMID_XRATES:
1979 xrates = frm;
1980 break;
1981 }
1982 frm += frm[1] + 2;
1983 }
1984 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE);
1985 IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN);
794 if (ssid[1] != 0 &&
795 (ssid[1] != ic->ic_bss->ni_esslen ||
796 memcmp(ssid + 2, ic->ic_bss->ni_essid, ic->ic_bss->ni_esslen) != 0)) {
797#ifdef IEEE80211_DEBUG
798 if (ieee80211_debug) {
799 printf("%s: ssid unmatch ", __func__);
800 ieee80211_print_essid(ssid + 2, ssid[1]);
801 printf(" from %s\n", ether_sprintf(wh->i_addr2));
802 }
803#endif
804 ic->ic_stats.is_rx_ssidmismatch++;
805 return;
806 }
1986 IEEE80211_VERIFY_SSID(ic->ic_bss, ssid);
807
808 if (ni == ic->ic_bss) {
1987
1988 if (ni == ic->ic_bss) {
809 ni = ieee80211_dup_bss(ic, wh->i_addr2);
1989 if (ic->ic_opmode == IEEE80211_M_IBSS) {
1990 /*
1991 * XXX Cannot tell if the sender is operating
1992 * in ibss mode. But we need a new node to
1993 * send the response so blindly add them to the
1994 * neighbor table.
1995 */
1996 ni = ieee80211_fakeup_adhoc_node(ic->ic_sta,
1997 wh->i_addr2);
1998 } else
1999 ni = ieee80211_dup_bss(ic->ic_sta, wh->i_addr2);
810 if (ni == NULL)
811 return;
2000 if (ni == NULL)
2001 return;
812 IEEE80211_DPRINTF(("%s: new req from %s\n",
813 __func__, ether_sprintf(wh->i_addr2)));
814 allocbs = 1;
815 } else
816 allocbs = 0;
2002 allocbs = 1;
2003 } else
2004 allocbs = 0;
2005 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC,
2006 "[%s] recv probe req\n", ether_sprintf(wh->i_addr2));
817 ni->ni_rssi = rssi;
818 ni->ni_rstamp = rstamp;
819 rate = ieee80211_setup_rates(ic, ni, rates, xrates,
2007 ni->ni_rssi = rssi;
2008 ni->ni_rstamp = rstamp;
2009 rate = ieee80211_setup_rates(ic, ni, rates, xrates,
820 IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE
821 | IEEE80211_F_DONEGO | IEEE80211_F_DODEL);
2010 IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE
2011 | IEEE80211_F_DONEGO | IEEE80211_F_DODEL);
822 if (rate & IEEE80211_RATE_BASIC) {
2012 if (rate & IEEE80211_RATE_BASIC) {
823 IEEE80211_DPRINTF(("%s: rate negotiation failed: %s\n",
824 __func__,ether_sprintf(wh->i_addr2)));
2013 IEEE80211_DISCARD(ic, IEEE80211_MSG_XRATE,
2014 wh, ieee80211_mgt_subtype_name[subtype >>
2015 IEEE80211_FC0_SUBTYPE_SHIFT],
2016 "%s", "recv'd rate set invalid");
825 } else {
826 IEEE80211_SEND_MGMT(ic, ni,
827 IEEE80211_FC0_SUBTYPE_PROBE_RESP, 0);
828 }
2017 } else {
2018 IEEE80211_SEND_MGMT(ic, ni,
2019 IEEE80211_FC0_SUBTYPE_PROBE_RESP, 0);
2020 }
829 if (allocbs)
830 ieee80211_free_node(ic, ni);
2021 if (allocbs && ic->ic_opmode != IEEE80211_M_IBSS) {
2022 /* reclaim immediately */
2023 ieee80211_free_node(ni);
2024 }
831 break;
832 }
833
834 case IEEE80211_FC0_SUBTYPE_AUTH: {
835 u_int16_t algo, seq, status;
836 /*
837 * auth frame format
838 * [2] algorithm
839 * [2] sequence
840 * [2] status
841 * [tlv*] challenge
842 */
843 IEEE80211_VERIFY_LENGTH(efrm - frm, 6);
844 algo = le16toh(*(u_int16_t *)frm);
845 seq = le16toh(*(u_int16_t *)(frm + 2));
846 status = le16toh(*(u_int16_t *)(frm + 4));
2025 break;
2026 }
2027
2028 case IEEE80211_FC0_SUBTYPE_AUTH: {
2029 u_int16_t algo, seq, status;
2030 /*
2031 * auth frame format
2032 * [2] algorithm
2033 * [2] sequence
2034 * [2] status
2035 * [tlv*] challenge
2036 */
2037 IEEE80211_VERIFY_LENGTH(efrm - frm, 6);
2038 algo = le16toh(*(u_int16_t *)frm);
2039 seq = le16toh(*(u_int16_t *)(frm + 2));
2040 status = le16toh(*(u_int16_t *)(frm + 4));
847 if (algo != IEEE80211_AUTH_ALG_OPEN) {
848 /* TODO: shared key auth */
849 IEEE80211_DPRINTF(("%s: unsupported auth %d from %s\n",
850 __func__, algo, ether_sprintf(wh->i_addr2)));
851 ic->ic_stats.is_rx_auth_unsupported++;
2041 IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH,
2042 "[%s] recv auth frame with algorithm %d seq %d\n",
2043 ether_sprintf(wh->i_addr2), algo, seq);
2044 /*
2045 * Consult the ACL policy module if setup.
2046 */
2047 if (ic->ic_acl != NULL &&
2048 !ic->ic_acl->iac_check(ic, wh->i_addr2)) {
2049 IEEE80211_DISCARD(ic, IEEE80211_MSG_ACL,
2050 wh, "auth", "%s", "disallowed by ACL");
2051 ic->ic_stats.is_rx_acl++;
852 return;
853 }
2052 return;
2053 }
854 switch (ic->ic_opmode) {
855 case IEEE80211_M_IBSS:
856 if (ic->ic_state != IEEE80211_S_RUN || seq != 1) {
857 IEEE80211_DPRINTF(("%s: discard auth from %s; "
858 "state %u, seq %u\n", __func__,
859 ether_sprintf(wh->i_addr2),
860 ic->ic_state, seq));
861 ic->ic_stats.is_rx_bad_auth++;
862 break;
2054 if (ic->ic_flags & IEEE80211_F_COUNTERM) {
2055 IEEE80211_DISCARD(ic,
2056 IEEE80211_MSG_AUTH | IEEE80211_MSG_CRYPTO,
2057 wh, "auth", "%s", "TKIP countermeasures enabled");
2058 ic->ic_stats.is_rx_auth_countermeasures++;
2059 if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
2060 IEEE80211_SEND_MGMT(ic, ni,
2061 IEEE80211_FC0_SUBTYPE_AUTH,
2062 IEEE80211_REASON_MIC_FAILURE);
863 }
2063 }
864 ieee80211_new_state(ic, IEEE80211_S_AUTH,
865 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
866 break;
867
868 case IEEE80211_M_AHDEMO:
869 /* should not come here */
870 break;
871
872 case IEEE80211_M_HOSTAP:
873 if (ic->ic_state != IEEE80211_S_RUN || seq != 1) {
874 IEEE80211_DPRINTF(("%s: discard auth from %s; "
875 "state %u, seq %u\n", __func__,
876 ether_sprintf(wh->i_addr2),
877 ic->ic_state, seq));
878 ic->ic_stats.is_rx_bad_auth++;
879 break;
880 }
881 if (ni == ic->ic_bss) {
882 ni = ieee80211_alloc_node(ic, wh->i_addr2);
883 if (ni == NULL)
884 return;
885 IEEE80211_ADDR_COPY(ni->ni_bssid, ic->ic_bss->ni_bssid);
886 ni->ni_rssi = rssi;
887 ni->ni_rstamp = rstamp;
888 ni->ni_chan = ic->ic_bss->ni_chan;
889 allocbs = 1;
890 } else
891 allocbs = 0;
892 IEEE80211_SEND_MGMT(ic, ni,
893 IEEE80211_FC0_SUBTYPE_AUTH, 2);
894 if (ifp->if_flags & IFF_DEBUG)
895 if_printf(ifp, "station %s %s authenticated\n",
896 (allocbs ? "newly" : "already"),
897 ether_sprintf(ni->ni_macaddr));
898 break;
899
900 case IEEE80211_M_STA:
901 if (ic->ic_state != IEEE80211_S_AUTH || seq != 2) {
902 IEEE80211_DPRINTF(("%s: discard auth from %s; "
903 "state %u, seq %u\n", __func__,
904 ether_sprintf(wh->i_addr2),
905 ic->ic_state, seq));
906 ic->ic_stats.is_rx_bad_auth++;
907 break;
908 }
909 if (status != 0) {
910 if_printf(&ic->ic_if,
911 "authentication failed (reason %d) for %s\n",
912 status,
913 ether_sprintf(wh->i_addr3));
914 if (ni != ic->ic_bss)
915 ni->ni_fails++;
916 ic->ic_stats.is_rx_auth_fail++;
917 return;
918 }
919 ieee80211_new_state(ic, IEEE80211_S_ASSOC,
920 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
921 break;
922 case IEEE80211_M_MONITOR:
923 break;
2064 return;
924 }
2065 }
2066 if (algo == IEEE80211_AUTH_ALG_SHARED)
2067 ieee80211_auth_shared(ic, wh, frm + 6, efrm, ni, rssi,
2068 rstamp, seq, status);
2069 else if (algo == IEEE80211_AUTH_ALG_OPEN)
2070 ieee80211_auth_open(ic, wh, ni, rssi, rstamp, seq,
2071 status);
2072 else {
2073 IEEE80211_DISCARD(ic, IEEE80211_MSG_ANY,
2074 wh, "auth", "unsupported alg %d", algo);
2075 ic->ic_stats.is_rx_auth_unsupported++;
2076 if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
2077 /* XXX not right */
2078 IEEE80211_SEND_MGMT(ic, ni,
2079 IEEE80211_FC0_SUBTYPE_AUTH,
2080 (seq+1) | (IEEE80211_STATUS_ALG<<16));
2081 }
2082 return;
2083 }
925 break;
926 }
927
928 case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
929 case IEEE80211_FC0_SUBTYPE_REASSOC_REQ: {
930 u_int16_t capinfo, bintval;
2084 break;
2085 }
2086
2087 case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
2088 case IEEE80211_FC0_SUBTYPE_REASSOC_REQ: {
2089 u_int16_t capinfo, bintval;
2090 struct ieee80211_rsnparms rsn;
2091 u_int8_t reason;
931
932 if (ic->ic_opmode != IEEE80211_M_HOSTAP ||
2092
2093 if (ic->ic_opmode != IEEE80211_M_HOSTAP ||
933 (ic->ic_state != IEEE80211_S_RUN))
2094 ic->ic_state != IEEE80211_S_RUN) {
2095 ic->ic_stats.is_rx_mgtdiscard++;
934 return;
2096 return;
2097 }
935
936 if (subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ) {
937 reassoc = 1;
938 resp = IEEE80211_FC0_SUBTYPE_REASSOC_RESP;
939 } else {
940 reassoc = 0;
941 resp = IEEE80211_FC0_SUBTYPE_ASSOC_RESP;
942 }
943 /*
944 * asreq frame format
945 * [2] capability information
946 * [2] listen interval
947 * [6*] current AP address (reassoc only)
948 * [tlv] ssid
949 * [tlv] supported rates
950 * [tlv] extended supported rates
2098
2099 if (subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ) {
2100 reassoc = 1;
2101 resp = IEEE80211_FC0_SUBTYPE_REASSOC_RESP;
2102 } else {
2103 reassoc = 0;
2104 resp = IEEE80211_FC0_SUBTYPE_ASSOC_RESP;
2105 }
2106 /*
2107 * asreq frame format
2108 * [2] capability information
2109 * [2] listen interval
2110 * [6*] current AP address (reassoc only)
2111 * [tlv] ssid
2112 * [tlv] supported rates
2113 * [tlv] extended supported rates
2114 * [tlv] WPA or RSN
951 */
952 IEEE80211_VERIFY_LENGTH(efrm - frm, (reassoc ? 10 : 4));
953 if (!IEEE80211_ADDR_EQ(wh->i_addr3, ic->ic_bss->ni_bssid)) {
2115 */
2116 IEEE80211_VERIFY_LENGTH(efrm - frm, (reassoc ? 10 : 4));
2117 if (!IEEE80211_ADDR_EQ(wh->i_addr3, ic->ic_bss->ni_bssid)) {
954 IEEE80211_DPRINTF(("%s: ignore other bss from %s\n",
955 __func__, ether_sprintf(wh->i_addr2)));
2118 IEEE80211_DISCARD(ic, IEEE80211_MSG_ANY,
2119 wh, ieee80211_mgt_subtype_name[subtype >>
2120 IEEE80211_FC0_SUBTYPE_SHIFT],
2121 "%s", "wrong bssid");
956 ic->ic_stats.is_rx_assoc_bss++;
957 return;
958 }
959 capinfo = le16toh(*(u_int16_t *)frm); frm += 2;
960 bintval = le16toh(*(u_int16_t *)frm); frm += 2;
961 if (reassoc)
962 frm += 6; /* ignore current AP info */
2122 ic->ic_stats.is_rx_assoc_bss++;
2123 return;
2124 }
2125 capinfo = le16toh(*(u_int16_t *)frm); frm += 2;
2126 bintval = le16toh(*(u_int16_t *)frm); frm += 2;
2127 if (reassoc)
2128 frm += 6; /* ignore current AP info */
963 ssid = rates = xrates = NULL;
2129 ssid = rates = xrates = wpa = wme = NULL;
964 while (frm < efrm) {
965 switch (*frm) {
966 case IEEE80211_ELEMID_SSID:
967 ssid = frm;
968 break;
969 case IEEE80211_ELEMID_RATES:
970 rates = frm;
971 break;
972 case IEEE80211_ELEMID_XRATES:
973 xrates = frm;
974 break;
2130 while (frm < efrm) {
2131 switch (*frm) {
2132 case IEEE80211_ELEMID_SSID:
2133 ssid = frm;
2134 break;
2135 case IEEE80211_ELEMID_RATES:
2136 rates = frm;
2137 break;
2138 case IEEE80211_ELEMID_XRATES:
2139 xrates = frm;
2140 break;
2141 /* XXX verify only one of RSN and WPA ie's? */
2142 case IEEE80211_ELEMID_RSN:
2143 wpa = frm;
2144 break;
2145 case IEEE80211_ELEMID_VENDOR:
2146 if (iswpaoui(frm)) {
2147 if (ic->ic_flags & IEEE80211_F_WPA1)
2148 wpa = frm;
2149 } else if (iswmeinfo(frm))
2150 wme = frm;
2151 /* XXX Atheros OUI support */
2152 break;
975 }
976 frm += frm[1] + 2;
977 }
978 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE);
979 IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN);
2153 }
2154 frm += frm[1] + 2;
2155 }
2156 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE);
2157 IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN);
980 if (ssid[1] != ic->ic_bss->ni_esslen ||
981 memcmp(ssid + 2, ic->ic_bss->ni_essid, ssid[1]) != 0) {
982#ifdef IEEE80211_DEBUG
983 if (ieee80211_debug) {
984 printf("%s: ssid unmatch ", __func__);
985 ieee80211_print_essid(ssid + 2, ssid[1]);
986 printf(" from %s\n", ether_sprintf(wh->i_addr2));
987 }
988#endif
989 ic->ic_stats.is_rx_ssidmismatch++;
990 return;
991 }
2158 IEEE80211_VERIFY_SSID(ic->ic_bss, ssid);
2159
992 if (ni == ic->ic_bss) {
2160 if (ni == ic->ic_bss) {
993 IEEE80211_DPRINTF(("%s: not authenticated for %s\n",
994 __func__, ether_sprintf(wh->i_addr2)));
995 ni = ieee80211_dup_bss(ic, wh->i_addr2);
2161 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY,
2162 "[%s] deny %s request, sta not authenticated\n",
2163 ether_sprintf(wh->i_addr2),
2164 reassoc ? "reassoc" : "assoc");
2165 ni = ieee80211_dup_bss(ic->ic_sta, wh->i_addr2);
996 if (ni != NULL) {
997 IEEE80211_SEND_MGMT(ic, ni,
998 IEEE80211_FC0_SUBTYPE_DEAUTH,
999 IEEE80211_REASON_ASSOC_NOT_AUTHED);
2166 if (ni != NULL) {
2167 IEEE80211_SEND_MGMT(ic, ni,
2168 IEEE80211_FC0_SUBTYPE_DEAUTH,
2169 IEEE80211_REASON_ASSOC_NOT_AUTHED);
1000 ieee80211_free_node(ic, ni);
2170 ieee80211_free_node(ni);
1001 }
1002 ic->ic_stats.is_rx_assoc_notauth++;
1003 return;
1004 }
2171 }
2172 ic->ic_stats.is_rx_assoc_notauth++;
2173 return;
2174 }
1005 /* XXX per-node cipher suite */
2175 if (wpa != NULL) {
2176 /*
2177 * Parse WPA information element. Note that
2178 * we initialize the param block from the node
2179 * state so that information in the IE overrides
2180 * our defaults. The resulting parameters are
2181 * installed below after the association is assured.
2182 */
2183 rsn = ni->ni_rsn;
2184 if (wpa[0] != IEEE80211_ELEMID_RSN)
2185 reason = ieee80211_parse_wpa(ic, wpa, &rsn, wh);
2186 else
2187 reason = ieee80211_parse_rsn(ic, wpa, &rsn, wh);
2188 if (reason != 0) {
2189 IEEE80211_SEND_MGMT(ic, ni,
2190 IEEE80211_FC0_SUBTYPE_DEAUTH, reason);
2191 ieee80211_node_leave(ic, ni);
2192 /* XXX distinguish WPA/RSN? */
2193 ic->ic_stats.is_rx_assoc_badwpaie++;
2194 return;
2195 }
2196 IEEE80211_DPRINTF(ic,
2197 IEEE80211_MSG_ASSOC | IEEE80211_MSG_WPA,
2198 "[%s] %s ie: mc %u/%u uc %u/%u key %u caps 0x%x\n",
2199 ether_sprintf(wh->i_addr2),
2200 wpa[0] != IEEE80211_ELEMID_RSN ? "WPA" : "RSN",
2201 rsn.rsn_mcastcipher, rsn.rsn_mcastkeylen,
2202 rsn.rsn_ucastcipher, rsn.rsn_ucastkeylen,
2203 rsn.rsn_keymgmt, rsn.rsn_caps);
2204 }
2205 /* discard challenge after association */
2206 if (ni->ni_challenge != NULL) {
2207 FREE(ni->ni_challenge, M_DEVBUF);
2208 ni->ni_challenge = NULL;
2209 }
1006 /* XXX some stations use the privacy bit for handling APs
1007 that suport both encrypted and unencrypted traffic */
2210 /* XXX some stations use the privacy bit for handling APs
2211 that suport both encrypted and unencrypted traffic */
2212 /* NB: PRIVACY flag bits are assumed to match */
1008 if ((capinfo & IEEE80211_CAPINFO_ESS) == 0 ||
2213 if ((capinfo & IEEE80211_CAPINFO_ESS) == 0 ||
1009 (capinfo & IEEE80211_CAPINFO_PRIVACY) !=
1010 ((ic->ic_flags & IEEE80211_F_WEPON) ?
1011 IEEE80211_CAPINFO_PRIVACY : 0)) {
1012 IEEE80211_DPRINTF(("%s: capability mismatch %x for %s\n",
1013 __func__, capinfo, ether_sprintf(wh->i_addr2)));
1014 ni->ni_associd = 0;
2214 (capinfo & IEEE80211_CAPINFO_PRIVACY) ^
2215 (ic->ic_flags & IEEE80211_F_PRIVACY)) {
2216 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY,
2217 "[%s] deny %s request, capability mismatch 0x%x\n",
2218 ether_sprintf(wh->i_addr2),
2219 reassoc ? "reassoc" : "assoc", capinfo);
1015 IEEE80211_SEND_MGMT(ic, ni, resp,
1016 IEEE80211_STATUS_CAPINFO);
2220 IEEE80211_SEND_MGMT(ic, ni, resp,
2221 IEEE80211_STATUS_CAPINFO);
2222 ieee80211_node_leave(ic, ni);
1017 ic->ic_stats.is_rx_assoc_capmismatch++;
1018 return;
1019 }
1020 ieee80211_setup_rates(ic, ni, rates, xrates,
1021 IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE |
1022 IEEE80211_F_DONEGO | IEEE80211_F_DODEL);
1023 if (ni->ni_rates.rs_nrates == 0) {
2223 ic->ic_stats.is_rx_assoc_capmismatch++;
2224 return;
2225 }
2226 ieee80211_setup_rates(ic, ni, rates, xrates,
2227 IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE |
2228 IEEE80211_F_DONEGO | IEEE80211_F_DODEL);
2229 if (ni->ni_rates.rs_nrates == 0) {
1024 IEEE80211_DPRINTF(("%s: rate unmatch for %s\n",
1025 __func__, ether_sprintf(wh->i_addr2)));
1026 ni->ni_associd = 0;
2230 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY,
2231 "[%s] deny %s request, rate set mismatch\n",
2232 ether_sprintf(wh->i_addr2),
2233 reassoc ? "reassoc" : "assoc");
1027 IEEE80211_SEND_MGMT(ic, ni, resp,
1028 IEEE80211_STATUS_BASIC_RATE);
2234 IEEE80211_SEND_MGMT(ic, ni, resp,
2235 IEEE80211_STATUS_BASIC_RATE);
2236 ieee80211_node_leave(ic, ni);
1029 ic->ic_stats.is_rx_assoc_norate++;
1030 return;
1031 }
1032 ni->ni_rssi = rssi;
1033 ni->ni_rstamp = rstamp;
1034 ni->ni_intval = bintval;
1035 ni->ni_capinfo = capinfo;
1036 ni->ni_chan = ic->ic_bss->ni_chan;
1037 ni->ni_fhdwell = ic->ic_bss->ni_fhdwell;
1038 ni->ni_fhindex = ic->ic_bss->ni_fhindex;
2237 ic->ic_stats.is_rx_assoc_norate++;
2238 return;
2239 }
2240 ni->ni_rssi = rssi;
2241 ni->ni_rstamp = rstamp;
2242 ni->ni_intval = bintval;
2243 ni->ni_capinfo = capinfo;
2244 ni->ni_chan = ic->ic_bss->ni_chan;
2245 ni->ni_fhdwell = ic->ic_bss->ni_fhdwell;
2246 ni->ni_fhindex = ic->ic_bss->ni_fhindex;
1039 if (ni->ni_associd == 0) {
1040 /* XXX handle rollover at 2007 */
1041 /* XXX guarantee uniqueness */
1042 ni->ni_associd = 0xc000 | ic->ic_bss->ni_associd++;
1043 newassoc = 1;
1044 } else
1045 newassoc = 0;
1046 /* XXX for 11g must turn off short slot time if long
1047 slot time sta associates */
1048 IEEE80211_SEND_MGMT(ic, ni, resp, IEEE80211_STATUS_SUCCESS);
1049 if (ifp->if_flags & IFF_DEBUG)
1050 if_printf(ifp, "station %s %s associated\n",
1051 (newassoc ? "newly" : "already"),
1052 ether_sprintf(ni->ni_macaddr));
1053 /* give driver a chance to setup state like ni_txrate */
1054 if (ic->ic_newassoc)
1055 (*ic->ic_newassoc)(ic, ni, newassoc);
2247 if (wpa != NULL) {
2248 /*
2249 * Record WPA/RSN parameters for station, mark
2250 * node as using WPA and record information element
2251 * for applications that require it.
2252 */
2253 ni->ni_rsn = rsn;
2254 ieee80211_saveie(&ni->ni_wpa_ie, wpa);
2255 } else if (ni->ni_wpa_ie != NULL) {
2256 /*
2257 * Flush any state from a previous association.
2258 */
2259 FREE(ni->ni_wpa_ie, M_DEVBUF);
2260 ni->ni_wpa_ie = NULL;
2261 }
2262 if (wme != NULL) {
2263 /*
2264 * Record WME parameters for station, mark node
2265 * as capable of QoS and record information
2266 * element for applications that require it.
2267 */
2268 ieee80211_saveie(&ni->ni_wme_ie, wme);
2269 ni->ni_flags |= IEEE80211_NODE_QOS;
2270 } else if (ni->ni_wme_ie != NULL) {
2271 /*
2272 * Flush any state from a previous association.
2273 */
2274 FREE(ni->ni_wme_ie, M_DEVBUF);
2275 ni->ni_wme_ie = NULL;
2276 ni->ni_flags &= ~IEEE80211_NODE_QOS;
2277 }
2278 ieee80211_node_join(ic, ni, resp);
1056 break;
1057 }
1058
1059 case IEEE80211_FC0_SUBTYPE_ASSOC_RESP:
1060 case IEEE80211_FC0_SUBTYPE_REASSOC_RESP: {
2279 break;
2280 }
2281
2282 case IEEE80211_FC0_SUBTYPE_ASSOC_RESP:
2283 case IEEE80211_FC0_SUBTYPE_REASSOC_RESP: {
2284 u_int16_t capinfo, associd;
1061 u_int16_t status;
1062
1063 if (ic->ic_opmode != IEEE80211_M_STA ||
2285 u_int16_t status;
2286
2287 if (ic->ic_opmode != IEEE80211_M_STA ||
1064 ic->ic_state != IEEE80211_S_ASSOC)
2288 ic->ic_state != IEEE80211_S_ASSOC) {
2289 ic->ic_stats.is_rx_mgtdiscard++;
1065 return;
2290 return;
2291 }
1066
1067 /*
1068 * asresp frame format
1069 * [2] capability information
1070 * [2] status
1071 * [2] association ID
1072 * [tlv] supported rates
1073 * [tlv] extended supported rates
2292
2293 /*
2294 * asresp frame format
2295 * [2] capability information
2296 * [2] status
2297 * [2] association ID
2298 * [tlv] supported rates
2299 * [tlv] extended supported rates
2300 * [tlv] WME
1074 */
1075 IEEE80211_VERIFY_LENGTH(efrm - frm, 6);
1076 ni = ic->ic_bss;
2301 */
2302 IEEE80211_VERIFY_LENGTH(efrm - frm, 6);
2303 ni = ic->ic_bss;
1077 ni->ni_capinfo = le16toh(*(u_int16_t *)frm);
2304 capinfo = le16toh(*(u_int16_t *)frm);
1078 frm += 2;
2305 frm += 2;
1079
1080 status = le16toh(*(u_int16_t *)frm);
1081 frm += 2;
1082 if (status != 0) {
2306 status = le16toh(*(u_int16_t *)frm);
2307 frm += 2;
2308 if (status != 0) {
1083 if_printf(ifp, "association failed (reason %d) for %s\n",
1084 status, ether_sprintf(wh->i_addr3));
1085 if (ni != ic->ic_bss)
2309 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC,
2310 "[%s] %sassoc failed (reason %d)\n",
2311 ether_sprintf(wh->i_addr2),
2312 ISREASSOC(subtype) ? "re" : "", status);
2313 if (ni != ic->ic_bss) /* XXX never true? */
1086 ni->ni_fails++;
2314 ni->ni_fails++;
1087 ic->ic_stats.is_rx_auth_fail++;
2315 ic->ic_stats.is_rx_auth_fail++; /* XXX */
1088 return;
1089 }
2316 return;
2317 }
1090 ni->ni_associd = le16toh(*(u_int16_t *)frm);
2318 associd = le16toh(*(u_int16_t *)frm);
1091 frm += 2;
1092
2319 frm += 2;
2320
1093 rates = xrates = NULL;
2321 rates = xrates = wpa = wme = NULL;
1094 while (frm < efrm) {
1095 switch (*frm) {
1096 case IEEE80211_ELEMID_RATES:
1097 rates = frm;
1098 break;
1099 case IEEE80211_ELEMID_XRATES:
1100 xrates = frm;
1101 break;
2322 while (frm < efrm) {
2323 switch (*frm) {
2324 case IEEE80211_ELEMID_RATES:
2325 rates = frm;
2326 break;
2327 case IEEE80211_ELEMID_XRATES:
2328 xrates = frm;
2329 break;
2330 case IEEE80211_ELEMID_VENDOR:
2331 if (iswmeoui(frm))
2332 wme = frm;
2333 /* XXX Atheros OUI support */
2334 break;
1102 }
1103 frm += frm[1] + 2;
1104 }
1105
1106 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE);
1107 ieee80211_setup_rates(ic, ni, rates, xrates,
1108 IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE |
1109 IEEE80211_F_DONEGO | IEEE80211_F_DODEL);
2335 }
2336 frm += frm[1] + 2;
2337 }
2338
2339 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE);
2340 ieee80211_setup_rates(ic, ni, rates, xrates,
2341 IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE |
2342 IEEE80211_F_DONEGO | IEEE80211_F_DODEL);
1110 if (ni->ni_rates.rs_nrates != 0)
1111 ieee80211_new_state(ic, IEEE80211_S_RUN,
1112 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
2343 if (ni->ni_rates.rs_nrates == 0) {
2344 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC,
2345 "[%s] %sassoc failed (rate set mismatch)\n",
2346 ether_sprintf(wh->i_addr2),
2347 ISREASSOC(subtype) ? "re" : "");
2348 if (ni != ic->ic_bss) /* XXX never true? */
2349 ni->ni_fails++;
2350 ic->ic_stats.is_rx_assoc_norate++;
2351 return;
2352 }
2353
2354 ni->ni_capinfo = capinfo;
2355 ni->ni_associd = associd;
2356 if (wme != NULL && ieee80211_parse_wmeparams(ic, wme, wh)) {
2357 ni->ni_flags |= IEEE80211_NODE_QOS;
2358 ieee80211_wme_updateparams(ic);
2359 } else
2360 ni->ni_flags &= ~IEEE80211_NODE_QOS;
2361 /*
2362 * Configure state now that we are associated.
2363 *
2364 * XXX may need different/additional driver callbacks?
2365 */
2366 if (ic->ic_curmode == IEEE80211_MODE_11A ||
2367 (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE)) {
2368 ic->ic_flags |= IEEE80211_F_SHPREAMBLE;
2369 ic->ic_flags &= ~IEEE80211_F_USEBARKER;
2370 } else {
2371 ic->ic_flags &= ~IEEE80211_F_SHPREAMBLE;
2372 ic->ic_flags |= IEEE80211_F_USEBARKER;
2373 }
2374 ieee80211_set_shortslottime(ic,
2375 ic->ic_curmode == IEEE80211_MODE_11A ||
2376 (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME));
2377 /*
2378 * Honor ERP protection.
2379 *
2380 * NB: ni_erp should zero for non-11g operation.
2381 * XXX check ic_curmode anyway?
2382 */
2383 if (ni->ni_erp & IEEE80211_ERP_USE_PROTECTION)
2384 ic->ic_flags |= IEEE80211_F_USEPROT;
2385 else
2386 ic->ic_flags &= ~IEEE80211_F_USEPROT;
2387 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC,
2388 "[%s] %sassoc success: %s preamble, %s slot time%s%s\n",
2389 ether_sprintf(wh->i_addr2),
2390 ISREASSOC(subtype) ? "re" : "",
2391 ic->ic_flags&IEEE80211_F_SHPREAMBLE ? "short" : "long",
2392 ic->ic_flags&IEEE80211_F_SHSLOT ? "short" : "long",
2393 ic->ic_flags&IEEE80211_F_USEPROT ? ", protection" : "",
2394 ni->ni_flags & IEEE80211_NODE_QOS ? ", QoS" : ""
2395 );
2396 ieee80211_new_state(ic, IEEE80211_S_RUN, subtype);
1113 break;
1114 }
1115
1116 case IEEE80211_FC0_SUBTYPE_DEAUTH: {
1117 u_int16_t reason;
2397 break;
2398 }
2399
2400 case IEEE80211_FC0_SUBTYPE_DEAUTH: {
2401 u_int16_t reason;
2402
2403 if (ic->ic_state == IEEE80211_S_SCAN) {
2404 ic->ic_stats.is_rx_mgtdiscard++;
2405 return;
2406 }
1118 /*
1119 * deauth frame format
1120 * [2] reason
1121 */
1122 IEEE80211_VERIFY_LENGTH(efrm - frm, 2);
1123 reason = le16toh(*(u_int16_t *)frm);
1124 ic->ic_stats.is_rx_deauth++;
2407 /*
2408 * deauth frame format
2409 * [2] reason
2410 */
2411 IEEE80211_VERIFY_LENGTH(efrm - frm, 2);
2412 reason = le16toh(*(u_int16_t *)frm);
2413 ic->ic_stats.is_rx_deauth++;
2414 IEEE80211_NODE_STAT(ni, rx_deauth);
1125 switch (ic->ic_opmode) {
1126 case IEEE80211_M_STA:
1127 ieee80211_new_state(ic, IEEE80211_S_AUTH,
1128 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
1129 break;
1130 case IEEE80211_M_HOSTAP:
1131 if (ni != ic->ic_bss) {
2415 switch (ic->ic_opmode) {
2416 case IEEE80211_M_STA:
2417 ieee80211_new_state(ic, IEEE80211_S_AUTH,
2418 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
2419 break;
2420 case IEEE80211_M_HOSTAP:
2421 if (ni != ic->ic_bss) {
1132 if (ifp->if_flags & IFF_DEBUG)
1133 if_printf(ifp, "station %s deauthenticated"
1134 " by peer (reason %d)\n",
1135 ether_sprintf(ni->ni_macaddr), reason);
1136 /* node will be free'd on return */
1137 ieee80211_unref_node(&ni);
2422 IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH,
2423 "station %s deauthenticated by peer "
2424 "(reason %d)\n",
2425 ether_sprintf(ni->ni_macaddr), reason);
2426 ieee80211_node_leave(ic, ni);
1138 }
1139 break;
1140 default:
2427 }
2428 break;
2429 default:
2430 ic->ic_stats.is_rx_mgtdiscard++;
1141 break;
1142 }
1143 break;
1144 }
1145
1146 case IEEE80211_FC0_SUBTYPE_DISASSOC: {
1147 u_int16_t reason;
2431 break;
2432 }
2433 break;
2434 }
2435
2436 case IEEE80211_FC0_SUBTYPE_DISASSOC: {
2437 u_int16_t reason;
2438
2439 if (ic->ic_state != IEEE80211_S_RUN &&
2440 ic->ic_state != IEEE80211_S_AUTH) {
2441 ic->ic_stats.is_rx_mgtdiscard++;
2442 return;
2443 }
1148 /*
1149 * disassoc frame format
1150 * [2] reason
1151 */
1152 IEEE80211_VERIFY_LENGTH(efrm - frm, 2);
1153 reason = le16toh(*(u_int16_t *)frm);
1154 ic->ic_stats.is_rx_disassoc++;
2444 /*
2445 * disassoc frame format
2446 * [2] reason
2447 */
2448 IEEE80211_VERIFY_LENGTH(efrm - frm, 2);
2449 reason = le16toh(*(u_int16_t *)frm);
2450 ic->ic_stats.is_rx_disassoc++;
2451 IEEE80211_NODE_STAT(ni, rx_disassoc);
1155 switch (ic->ic_opmode) {
1156 case IEEE80211_M_STA:
1157 ieee80211_new_state(ic, IEEE80211_S_ASSOC,
1158 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
1159 break;
1160 case IEEE80211_M_HOSTAP:
1161 if (ni != ic->ic_bss) {
2452 switch (ic->ic_opmode) {
2453 case IEEE80211_M_STA:
2454 ieee80211_new_state(ic, IEEE80211_S_ASSOC,
2455 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
2456 break;
2457 case IEEE80211_M_HOSTAP:
2458 if (ni != ic->ic_bss) {
1162 if (ifp->if_flags & IFF_DEBUG)
1163 if_printf(ifp, "station %s disassociated"
1164 " by peer (reason %d)\n",
1165 ether_sprintf(ni->ni_macaddr), reason);
1166 ni->ni_associd = 0;
1167 /* XXX node reclaimed how? */
2459 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC,
2460 "[%s] sta disassociated by peer (reason %d)\n",
2461 ether_sprintf(ni->ni_macaddr), reason);
2462 ieee80211_node_leave(ic, ni);
1168 }
1169 break;
1170 default:
2463 }
2464 break;
2465 default:
2466 ic->ic_stats.is_rx_mgtdiscard++;
1171 break;
1172 }
1173 break;
1174 }
1175 default:
2467 break;
2468 }
2469 break;
2470 }
2471 default:
1176 IEEE80211_DPRINTF(("%s: mgmt frame with subtype 0x%x not "
1177 "handled\n", __func__, subtype));
2472 IEEE80211_DISCARD(ic, IEEE80211_MSG_ANY,
2473 wh, "mgt", "subtype 0x%x not handled", subtype);
1178 ic->ic_stats.is_rx_badsubtype++;
1179 break;
1180 }
2474 ic->ic_stats.is_rx_badsubtype++;
2475 break;
2476 }
2477#undef ISREASSOC
2478#undef ISPROBE
1181}
1182#undef IEEE80211_VERIFY_LENGTH
1183#undef IEEE80211_VERIFY_ELEMENT
2479}
2480#undef IEEE80211_VERIFY_LENGTH
2481#undef IEEE80211_VERIFY_ELEMENT
2482
2483/*
2484 * Handle station power-save state change.
2485 */
2486static void
2487ieee80211_node_pwrsave(struct ieee80211_node *ni, int enable)
2488{
2489 struct ieee80211com *ic = ni->ni_ic;
2490 struct mbuf *m;
2491
2492 if (enable) {
2493 if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) == 0)
2494 ic->ic_ps_sta++;
2495 ni->ni_flags |= IEEE80211_NODE_PWR_MGT;
2496 IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER,
2497 "[%s] power save mode on, %u sta's in ps mode\n",
2498 ether_sprintf(ni->ni_macaddr), ic->ic_ps_sta);
2499 return;
2500 }
2501
2502 if (ni->ni_flags & IEEE80211_NODE_PWR_MGT)
2503 ic->ic_ps_sta--;
2504 ni->ni_flags &= ~IEEE80211_NODE_PWR_MGT;
2505 IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER,
2506 "[%s] power save mode off, %u sta's in ps mode\n",
2507 ether_sprintf(ni->ni_macaddr), ic->ic_ps_sta);
2508 /* XXX if no stations in ps mode, flush mc frames */
2509
2510 /*
2511 * Flush queued unicast frames.
2512 */
2513 if (IEEE80211_NODE_SAVEQ_QLEN(ni) == 0) {
2514 ic->ic_set_tim(ic, ni, 0); /* just in case */
2515 return;
2516 }
2517 IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER,
2518 "[%s] flush ps queue, %u packets queued\n",
2519 ether_sprintf(ni->ni_macaddr), IEEE80211_NODE_SAVEQ_QLEN(ni));
2520 for (;;) {
2521 int qlen;
2522
2523 IEEE80211_NODE_SAVEQ_DEQUEUE(ni, m, qlen);
2524 if (m == NULL)
2525 break;
2526 /*
2527 * If this is the last packet, turn off the TIM bit.
2528 * If there are more packets, set the more packets bit
2529 * in the packet dispatched to the station.
2530 */
2531 if (qlen != 0) {
2532 struct ieee80211_frame_min *wh =
2533 mtod(m, struct ieee80211_frame_min *);
2534 wh->i_fc[1] |= IEEE80211_FC1_MORE_DATA;
2535 }
2536 /* XXX need different driver interface */
2537 /* XXX bypasses q max */
2538 IF_ENQUEUE(&ic->ic_ifp->if_snd, m);
2539 }
2540}
2541
2542/*
2543 * Process a received ps-poll frame.
2544 */
2545static void
2546ieee80211_recv_pspoll(struct ieee80211com *ic,
2547 struct ieee80211_node *ni, struct mbuf *m0)
2548{
2549 struct ieee80211_frame_min *wh;
2550 struct mbuf *m;
2551 u_int16_t aid;
2552 int qlen;
2553
2554 wh = mtod(m0, struct ieee80211_frame_min *);
2555 if (ni->ni_associd == 0) {
2556 IEEE80211_DISCARD(ic, IEEE80211_MSG_POWER | IEEE80211_MSG_DEBUG,
2557 (struct ieee80211_frame *) wh, "ps-poll",
2558 "%s", "unassociated station");
2559 ic->ic_stats.is_ps_unassoc++;
2560 IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_DEAUTH,
2561 IEEE80211_REASON_NOT_ASSOCED);
2562 return;
2563 }
2564
2565 aid = le16toh(*(u_int16_t *)wh->i_dur);
2566 if (aid != ni->ni_associd) {
2567 IEEE80211_DISCARD(ic, IEEE80211_MSG_POWER | IEEE80211_MSG_DEBUG,
2568 (struct ieee80211_frame *) wh, "ps-poll",
2569 "aid mismatch: sta aid 0x%x poll aid 0x%x",
2570 ni->ni_associd, aid);
2571 ic->ic_stats.is_ps_badaid++;
2572 IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_DEAUTH,
2573 IEEE80211_REASON_NOT_ASSOCED);
2574 return;
2575 }
2576
2577 /* Okay, take the first queued packet and put it out... */
2578 IEEE80211_NODE_SAVEQ_DEQUEUE(ni, m, qlen);
2579 if (m == NULL) {
2580 IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER,
2581 "[%s] recv ps-poll, but queue empty\n",
2582 ether_sprintf(wh->i_addr2));
2583 ieee80211_send_nulldata(ic, ni);
2584 ic->ic_stats.is_ps_qempty++; /* XXX node stat */
2585 ic->ic_set_tim(ic, ni, 0); /* just in case */
2586 return;
2587 }
2588 /*
2589 * If there are more packets, set the more packets bit
2590 * in the packet dispatched to the station; otherwise
2591 * turn off the TIM bit.
2592 */
2593 if (qlen != 0) {
2594 IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER,
2595 "[%s] recv ps-poll, send packet, %u still queued\n",
2596 ether_sprintf(ni->ni_macaddr), qlen);
2597 wh = mtod(m, struct ieee80211_frame_min *);
2598 wh->i_fc[1] |= IEEE80211_FC1_MORE_DATA;
2599 } else {
2600 IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER,
2601 "[%s] recv ps-poll, send packet, queue empty\n",
2602 ether_sprintf(ni->ni_macaddr));
2603 ic->ic_set_tim(ic, ni, 0);
2604 }
2605 m->m_flags |= M_PWR_SAV; /* bypass PS handling */
2606 IF_ENQUEUE(&ic->ic_ifp->if_snd, m);
2607}
2608
2609#ifdef IEEE80211_DEBUG
2610/*
2611 * Debugging support.
2612 */
2613
2614/*
2615 * Return the bssid of a frame.
2616 */
2617static const u_int8_t *
2618ieee80211_getbssid(struct ieee80211com *ic, const struct ieee80211_frame *wh)
2619{
2620 if (ic->ic_opmode == IEEE80211_M_STA)
2621 return wh->i_addr2;
2622 if ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) != IEEE80211_FC1_DIR_NODS)
2623 return wh->i_addr1;
2624 if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == IEEE80211_FC0_SUBTYPE_PS_POLL)
2625 return wh->i_addr1;
2626 return wh->i_addr3;
2627}
2628
2629static void
2630ieee80211_discard_frame(struct ieee80211com *ic,
2631 const struct ieee80211_frame *wh,
2632 const char *type, const char *fmt, ...)
2633{
2634 va_list ap;
2635
2636 printf("[%s] discard ", ether_sprintf(ieee80211_getbssid(ic, wh)));
2637 if (type != NULL)
2638 printf(" %s frame, ", type);
2639 else
2640 printf(" frame, ");
2641 va_start(ap, fmt);
2642 vprintf(fmt, ap);
2643 va_end(ap);
2644 printf("\n");
2645}
2646
2647static void
2648ieee80211_discard_ie(struct ieee80211com *ic,
2649 const struct ieee80211_frame *wh,
2650 const char *type, const char *fmt, ...)
2651{
2652 va_list ap;
2653
2654 printf("[%s] discard ", ether_sprintf(ieee80211_getbssid(ic, wh)));
2655 if (type != NULL)
2656 printf(" %s information element, ", type);
2657 else
2658 printf(" information element, ");
2659 va_start(ap, fmt);
2660 vprintf(fmt, ap);
2661 va_end(ap);
2662 printf("\n");
2663}
2664
2665static void
2666ieee80211_discard_mac(struct ieee80211com *ic,
2667 const u_int8_t mac[IEEE80211_ADDR_LEN],
2668 const char *type, const char *fmt, ...)
2669{
2670 va_list ap;
2671
2672 printf("[%s] discard ", ether_sprintf(mac));
2673 if (type != NULL)
2674 printf(" %s frame, ", type);
2675 else
2676 printf(" frame, ");
2677 va_start(ap, fmt);
2678 vprintf(fmt, ap);
2679 va_end(ap);
2680 printf("\n");
2681}
2682#endif /* IEEE80211_DEBUG */