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 */ |
|