1 1.117 yamt /* $NetBSD: ieee80211_input.c,v 1.117 2022/11/19 07:57:51 yamt Exp $ */ 2 1.92 maxv 3 1.92 maxv /* 4 1.1 dyoung * Copyright (c) 2001 Atsushi Onoe 5 1.40 dyoung * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting 6 1.1 dyoung * All rights reserved. 7 1.1 dyoung * 8 1.1 dyoung * Redistribution and use in source and binary forms, with or without 9 1.1 dyoung * modification, are permitted provided that the following conditions 10 1.1 dyoung * are met: 11 1.1 dyoung * 1. Redistributions of source code must retain the above copyright 12 1.1 dyoung * notice, this list of conditions and the following disclaimer. 13 1.1 dyoung * 2. Redistributions in binary form must reproduce the above copyright 14 1.1 dyoung * notice, this list of conditions and the following disclaimer in the 15 1.1 dyoung * documentation and/or other materials provided with the distribution. 16 1.1 dyoung * 3. The name of the author may not be used to endorse or promote products 17 1.1 dyoung * derived from this software without specific prior written permission. 18 1.1 dyoung * 19 1.1 dyoung * Alternatively, this software may be distributed under the terms of the 20 1.1 dyoung * GNU General Public License ("GPL") version 2 as published by the Free 21 1.1 dyoung * Software Foundation. 22 1.1 dyoung * 23 1.1 dyoung * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 24 1.1 dyoung * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 25 1.1 dyoung * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 1.1 dyoung * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 27 1.1 dyoung * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 28 1.1 dyoung * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 1.1 dyoung * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 1.1 dyoung * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 1.1 dyoung * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 1.1 dyoung * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 1.1 dyoung */ 34 1.1 dyoung 35 1.1 dyoung #include <sys/cdefs.h> 36 1.3 dyoung #ifdef __FreeBSD__ 37 1.47 skrll __FBSDID("$FreeBSD: src/sys/net80211/ieee80211_input.c,v 1.81 2005/08/10 16:22:29 sam Exp $"); 38 1.40 dyoung #endif 39 1.40 dyoung #ifdef __NetBSD__ 40 1.117 yamt __KERNEL_RCSID(0, "$NetBSD: ieee80211_input.c,v 1.117 2022/11/19 07:57:51 yamt Exp $"); 41 1.3 dyoung #endif 42 1.1 dyoung 43 1.79 pooka #ifdef _KERNEL_OPT 44 1.1 dyoung #include "opt_inet.h" 45 1.79 pooka #endif 46 1.1 dyoung 47 1.1 dyoung #include <sys/param.h> 48 1.38 perry #include <sys/systm.h> 49 1.85 christos #include <sys/mbuf.h> 50 1.1 dyoung #include <sys/malloc.h> 51 1.40 dyoung #include <sys/endian.h> 52 1.1 dyoung #include <sys/kernel.h> 53 1.74 christos 54 1.1 dyoung #include <sys/socket.h> 55 1.1 dyoung #include <sys/sockio.h> 56 1.1 dyoung #include <sys/endian.h> 57 1.1 dyoung #include <sys/errno.h> 58 1.1 dyoung #include <sys/proc.h> 59 1.1 dyoung #include <sys/sysctl.h> 60 1.87 nonaka #include <sys/cpu.h> 61 1.1 dyoung 62 1.1 dyoung #include <net/if.h> 63 1.1 dyoung #include <net/if_media.h> 64 1.1 dyoung #include <net/if_arp.h> 65 1.4 dyoung #include <net/if_ether.h> 66 1.1 dyoung #include <net/if_llc.h> 67 1.1 dyoung 68 1.1 dyoung #include <net80211/ieee80211_var.h> 69 1.1 dyoung 70 1.1 dyoung #include <net/bpf.h> 71 1.1 dyoung 72 1.1 dyoung #ifdef INET 73 1.74 christos #include <netinet/in.h> 74 1.4 dyoung #include <net/if_ether.h> 75 1.4 dyoung #endif 76 1.1 dyoung 77 1.31 dyoung const struct timeval ieee80211_merge_print_intvl = {.tv_sec = 1, .tv_usec = 0}; 78 1.31 dyoung 79 1.40 dyoung #ifdef IEEE80211_DEBUG 80 1.5 dyoung 81 1.26 mycroft /* 82 1.26 mycroft * Decide if a received management frame should be 83 1.26 mycroft * printed when debugging is enabled. This filters some 84 1.26 mycroft * of the less interesting frames that come frequently 85 1.26 mycroft * (e.g. beacons). 86 1.26 mycroft */ 87 1.26 mycroft static __inline int 88 1.26 mycroft doprint(struct ieee80211com *ic, int subtype) 89 1.26 mycroft { 90 1.26 mycroft switch (subtype) { 91 1.26 mycroft case IEEE80211_FC0_SUBTYPE_BEACON: 92 1.40 dyoung return (ic->ic_flags & IEEE80211_F_SCAN); 93 1.26 mycroft case IEEE80211_FC0_SUBTYPE_PROBE_REQ: 94 1.26 mycroft return (ic->ic_opmode == IEEE80211_M_IBSS); 95 1.26 mycroft } 96 1.26 mycroft return 1; 97 1.26 mycroft } 98 1.40 dyoung 99 1.40 dyoung /* 100 1.40 dyoung * Emit a debug message about discarding a frame or information 101 1.40 dyoung * element. One format is for extracting the mac address from 102 1.40 dyoung * the frame header; the other is for when a header is not 103 1.40 dyoung * available or otherwise appropriate. 104 1.40 dyoung */ 105 1.40 dyoung #define IEEE80211_DISCARD(_ic, _m, _wh, _type, _fmt, ...) do { \ 106 1.40 dyoung if ((_ic)->ic_debug & (_m)) \ 107 1.40 dyoung ieee80211_discard_frame(_ic, _wh, _type, _fmt, __VA_ARGS__);\ 108 1.40 dyoung } while (0) 109 1.40 dyoung #define IEEE80211_DISCARD_IE(_ic, _m, _wh, _type, _fmt, ...) do { \ 110 1.40 dyoung if ((_ic)->ic_debug & (_m)) \ 111 1.40 dyoung ieee80211_discard_ie(_ic, _wh, _type, _fmt, __VA_ARGS__);\ 112 1.40 dyoung } while (0) 113 1.40 dyoung #define IEEE80211_DISCARD_MAC(_ic, _m, _mac, _type, _fmt, ...) do { \ 114 1.40 dyoung if ((_ic)->ic_debug & (_m)) \ 115 1.40 dyoung ieee80211_discard_mac(_ic, _mac, _type, _fmt, __VA_ARGS__);\ 116 1.40 dyoung } while (0) 117 1.85 christos #define IEEE80211_DEBUGVAR(a) a 118 1.40 dyoung 119 1.40 dyoung static const u_int8_t *ieee80211_getbssid(struct ieee80211com *, 120 1.40 dyoung const struct ieee80211_frame *); 121 1.40 dyoung static void ieee80211_discard_frame(struct ieee80211com *, 122 1.40 dyoung const struct ieee80211_frame *, const char *type, const char *fmt, ...); 123 1.40 dyoung static void ieee80211_discard_ie(struct ieee80211com *, 124 1.40 dyoung const struct ieee80211_frame *, const char *type, const char *fmt, ...); 125 1.40 dyoung static void ieee80211_discard_mac(struct ieee80211com *, 126 1.40 dyoung const u_int8_t mac[IEEE80211_ADDR_LEN], const char *type, 127 1.40 dyoung const char *fmt, ...); 128 1.40 dyoung #else 129 1.40 dyoung #define IEEE80211_DISCARD(_ic, _m, _wh, _type, _fmt, ...) 130 1.40 dyoung #define IEEE80211_DISCARD_IE(_ic, _m, _wh, _type, _fmt, ...) 131 1.40 dyoung #define IEEE80211_DISCARD_MAC(_ic, _m, _mac, _type, _fmt, ...) 132 1.85 christos #define IEEE80211_DEBUGVAR(a) 133 1.40 dyoung #endif /* IEEE80211_DEBUG */ 134 1.40 dyoung 135 1.113 maxv static struct mbuf *ieee80211_defrag(struct ieee80211_node *, 136 1.113 maxv struct mbuf *, int); 137 1.113 maxv static struct mbuf *ieee80211_decap(struct mbuf *, int); 138 1.44 dyoung static void ieee80211_send_error(struct ieee80211com *, struct ieee80211_node *, 139 1.92 maxv const u_int8_t *mac, int subtype, int arg); 140 1.47 skrll static void ieee80211_deliver_data(struct ieee80211com *, 141 1.47 skrll struct ieee80211_node *, struct mbuf *); 142 1.57 dyoung #ifndef IEEE80211_NO_HOSTAP 143 1.40 dyoung static void ieee80211_node_pwrsave(struct ieee80211_node *, int enable); 144 1.40 dyoung static void ieee80211_recv_pspoll(struct ieee80211com *, 145 1.40 dyoung struct ieee80211_node *, struct mbuf *); 146 1.41 dyoung #endif /* !IEEE80211_NO_HOSTAP */ 147 1.56 dyoung static void ieee80211_update_adhoc_node(struct ieee80211com *, 148 1.56 dyoung struct ieee80211_node *, struct ieee80211_frame *, 149 1.56 dyoung struct ieee80211_scanparams *, int, u_int32_t); 150 1.26 mycroft 151 1.93 maxv /* -------------------------------------------------------------------------- */ 152 1.93 maxv 153 1.93 maxv /* 154 1.93 maxv * Input code for a DATA frame. 155 1.93 maxv */ 156 1.93 maxv static int 157 1.93 maxv ieee80211_input_data(struct ieee80211com *ic, struct mbuf **mp, 158 1.93 maxv struct ieee80211_node *ni) 159 1.93 maxv { 160 1.93 maxv struct ifnet *ifp = ic->ic_ifp; 161 1.93 maxv struct ieee80211_key *key; 162 1.93 maxv struct ieee80211_frame *wh; 163 1.93 maxv u_int8_t dir, subtype; 164 1.93 maxv struct ether_header *eh; 165 1.93 maxv struct mbuf *m = *mp; 166 1.93 maxv int hdrspace; 167 1.93 maxv 168 1.93 maxv wh = mtod(m, struct ieee80211_frame *); 169 1.93 maxv dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK; 170 1.93 maxv subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; 171 1.93 maxv 172 1.93 maxv hdrspace = ieee80211_hdrspace(ic, wh); 173 1.93 maxv 174 1.93 maxv if (m->m_len < hdrspace && 175 1.93 maxv (m = m_pullup(m, hdrspace)) == NULL) { 176 1.93 maxv ic->ic_stats.is_rx_tooshort++; 177 1.94 maxv goto out; 178 1.93 maxv } 179 1.93 maxv wh = mtod(m, struct ieee80211_frame *); 180 1.93 maxv 181 1.93 maxv switch (ic->ic_opmode) { 182 1.93 maxv case IEEE80211_M_STA: 183 1.93 maxv if (dir != IEEE80211_FC1_DIR_FROMDS) { 184 1.93 maxv IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT, 185 1.117 yamt wh, "data", "unknown dir 0x%x", dir); 186 1.93 maxv ic->ic_stats.is_rx_wrongdir++; 187 1.93 maxv goto out; 188 1.93 maxv } 189 1.93 maxv if ((ifp->if_flags & IFF_SIMPLEX) && 190 1.93 maxv IEEE80211_IS_MULTICAST(wh->i_addr1) && 191 1.93 maxv IEEE80211_ADDR_EQ(wh->i_addr3, ic->ic_myaddr)) { 192 1.93 maxv /* 193 1.93 maxv * In IEEE802.11 network, multicast packet 194 1.93 maxv * sent from me is broadcast from AP. 195 1.93 maxv * It should be silently discarded for 196 1.93 maxv * SIMPLEX interface. 197 1.93 maxv */ 198 1.93 maxv IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT, 199 1.93 maxv wh, NULL, "%s", "multicast echo"); 200 1.93 maxv ic->ic_stats.is_rx_mcastecho++; 201 1.93 maxv goto out; 202 1.93 maxv } 203 1.93 maxv break; 204 1.93 maxv 205 1.93 maxv case IEEE80211_M_IBSS: 206 1.93 maxv case IEEE80211_M_AHDEMO: 207 1.93 maxv if (dir != IEEE80211_FC1_DIR_NODS) { 208 1.93 maxv IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT, 209 1.117 yamt wh, "data", "unknown dir 0x%x", dir); 210 1.93 maxv ic->ic_stats.is_rx_wrongdir++; 211 1.93 maxv goto out; 212 1.93 maxv } 213 1.93 maxv /* XXX no power-save support */ 214 1.93 maxv break; 215 1.93 maxv 216 1.93 maxv case IEEE80211_M_HOSTAP: 217 1.93 maxv #ifndef IEEE80211_NO_HOSTAP 218 1.93 maxv if (dir != IEEE80211_FC1_DIR_TODS) { 219 1.93 maxv IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT, 220 1.117 yamt wh, "data", "unknown dir 0x%x", dir); 221 1.93 maxv ic->ic_stats.is_rx_wrongdir++; 222 1.93 maxv goto out; 223 1.93 maxv } 224 1.93 maxv /* check if source STA is associated */ 225 1.93 maxv if (ni == ic->ic_bss) { 226 1.93 maxv IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT, 227 1.93 maxv wh, "data", "%s", "unknown src"); 228 1.93 maxv ieee80211_send_error(ic, ni, wh->i_addr2, 229 1.93 maxv IEEE80211_FC0_SUBTYPE_DEAUTH, 230 1.93 maxv IEEE80211_REASON_NOT_AUTHED); 231 1.93 maxv ic->ic_stats.is_rx_notassoc++; 232 1.93 maxv goto err; 233 1.93 maxv } 234 1.93 maxv if (ni->ni_associd == 0) { 235 1.93 maxv IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT, 236 1.93 maxv wh, "data", "%s", "unassoc src"); 237 1.93 maxv IEEE80211_SEND_MGMT(ic, ni, 238 1.93 maxv IEEE80211_FC0_SUBTYPE_DISASSOC, 239 1.93 maxv IEEE80211_REASON_NOT_ASSOCED); 240 1.93 maxv ic->ic_stats.is_rx_notassoc++; 241 1.93 maxv goto err; 242 1.93 maxv } 243 1.93 maxv 244 1.93 maxv /* 245 1.93 maxv * Check for power save state change. 246 1.93 maxv */ 247 1.93 maxv if (((wh->i_fc[1] & IEEE80211_FC1_PWR_MGT) ^ 248 1.93 maxv (ni->ni_flags & IEEE80211_NODE_PWR_MGT))) 249 1.93 maxv ieee80211_node_pwrsave(ni, 250 1.93 maxv wh->i_fc[1] & IEEE80211_FC1_PWR_MGT); 251 1.93 maxv #endif /* !IEEE80211_NO_HOSTAP */ 252 1.93 maxv break; 253 1.93 maxv 254 1.93 maxv default: 255 1.93 maxv /* XXX here to keep compiler happy */ 256 1.93 maxv goto out; 257 1.93 maxv } 258 1.93 maxv 259 1.93 maxv /* 260 1.93 maxv * Handle privacy requirements. Note that we 261 1.93 maxv * must not be preempted from here until after 262 1.93 maxv * we (potentially) call ieee80211_crypto_demic; 263 1.93 maxv * otherwise we may violate assumptions in the 264 1.93 maxv * crypto cipher modules used to do delayed update 265 1.93 maxv * of replay sequence numbers. 266 1.93 maxv */ 267 1.93 maxv if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 268 1.93 maxv if ((ic->ic_flags & IEEE80211_F_PRIVACY) == 0) { 269 1.93 maxv /* 270 1.93 maxv * Discard encrypted frames when privacy is off. 271 1.93 maxv */ 272 1.93 maxv IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT, 273 1.93 maxv wh, "WEP", "%s", "PRIVACY off"); 274 1.93 maxv ic->ic_stats.is_rx_noprivacy++; 275 1.93 maxv IEEE80211_NODE_STAT(ni, rx_noprivacy); 276 1.93 maxv goto out; 277 1.93 maxv } 278 1.93 maxv key = ieee80211_crypto_decap(ic, ni, &m, hdrspace); 279 1.93 maxv if (key == NULL) { 280 1.93 maxv /* NB: stats+msgs handled in crypto_decap */ 281 1.93 maxv IEEE80211_NODE_STAT(ni, rx_wepfail); 282 1.93 maxv goto out; 283 1.93 maxv } 284 1.93 maxv wh = mtod(m, struct ieee80211_frame *); 285 1.93 maxv wh->i_fc[1] &= ~IEEE80211_FC1_WEP; 286 1.93 maxv } else { 287 1.93 maxv key = NULL; 288 1.93 maxv } 289 1.93 maxv 290 1.93 maxv /* 291 1.93 maxv * Next up, any fragmentation. 292 1.93 maxv */ 293 1.93 maxv if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { 294 1.113 maxv m = ieee80211_defrag(ni, m, hdrspace); 295 1.93 maxv if (m == NULL) { 296 1.93 maxv /* Fragment dropped or frame not complete yet */ 297 1.93 maxv goto out; 298 1.93 maxv } 299 1.93 maxv } 300 1.93 maxv 301 1.93 maxv /* 302 1.94 maxv * Next, strip any MSDU crypto bits. 303 1.93 maxv */ 304 1.93 maxv if (key != NULL && !ieee80211_crypto_demic(ic, key, m, 0)) { 305 1.93 maxv IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_INPUT, 306 1.93 maxv ni->ni_macaddr, "data", "%s", "demic error"); 307 1.93 maxv IEEE80211_NODE_STAT(ni, rx_demicfail); 308 1.93 maxv goto out; 309 1.93 maxv } 310 1.93 maxv 311 1.93 maxv /* copy to listener after decrypt */ 312 1.114 msaitoh bpf_mtap3(ic->ic_rawbpf, m, BPF_D_IN); 313 1.93 maxv 314 1.93 maxv /* 315 1.93 maxv * Finally, strip the 802.11 header. 316 1.93 maxv */ 317 1.113 maxv m = ieee80211_decap(m, hdrspace); 318 1.93 maxv if (m == NULL) { 319 1.93 maxv /* don't count Null data frames as errors */ 320 1.93 maxv if (subtype == IEEE80211_FC0_SUBTYPE_NODATA) 321 1.93 maxv goto out; 322 1.93 maxv IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_INPUT, 323 1.93 maxv ni->ni_macaddr, "data", "%s", "decap error"); 324 1.93 maxv ic->ic_stats.is_rx_decap++; 325 1.93 maxv IEEE80211_NODE_STAT(ni, rx_decap); 326 1.93 maxv goto err; 327 1.93 maxv } 328 1.93 maxv 329 1.93 maxv eh = mtod(m, struct ether_header *); 330 1.93 maxv if (!ieee80211_node_is_authorized(ni)) { 331 1.93 maxv /* 332 1.93 maxv * Deny any non-PAE frames received prior to 333 1.93 maxv * authorization. For open/shared-key 334 1.93 maxv * authentication the port is mark authorized 335 1.93 maxv * after authentication completes. For 802.1x 336 1.93 maxv * the port is not marked authorized by the 337 1.93 maxv * authenticator until the handshake has completed. 338 1.93 maxv */ 339 1.93 maxv if (eh->ether_type != htons(ETHERTYPE_PAE)) { 340 1.93 maxv IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_INPUT, 341 1.93 maxv eh->ether_shost, "data", 342 1.93 maxv "unauthorized port: ether type 0x%x len %u", 343 1.93 maxv eh->ether_type, m->m_pkthdr.len); 344 1.93 maxv ic->ic_stats.is_rx_unauth++; 345 1.93 maxv IEEE80211_NODE_STAT(ni, rx_unauth); 346 1.93 maxv goto err; 347 1.93 maxv } 348 1.93 maxv } else { 349 1.93 maxv /* 350 1.93 maxv * When denying unencrypted frames, discard 351 1.93 maxv * any non-PAE frames received without encryption. 352 1.93 maxv */ 353 1.93 maxv if ((ic->ic_flags & IEEE80211_F_DROPUNENC) && 354 1.109 maxv key == NULL && eh->ether_type != htons(ETHERTYPE_PAE)) { 355 1.93 maxv /* 356 1.93 maxv * Drop unencrypted frames. 357 1.93 maxv */ 358 1.93 maxv ic->ic_stats.is_rx_unencrypted++; 359 1.93 maxv IEEE80211_NODE_STAT(ni, rx_unencrypted); 360 1.93 maxv goto out; 361 1.93 maxv } 362 1.93 maxv } 363 1.93 maxv 364 1.116 thorpej if_statinc(ifp, if_ipackets); 365 1.93 maxv IEEE80211_NODE_STAT(ni, rx_data); 366 1.93 maxv IEEE80211_NODE_STAT_ADD(ni, rx_bytes, m->m_pkthdr.len); 367 1.93 maxv 368 1.93 maxv ieee80211_deliver_data(ic, ni, m); 369 1.93 maxv 370 1.93 maxv *mp = NULL; 371 1.93 maxv return 0; 372 1.93 maxv 373 1.93 maxv err: 374 1.116 thorpej if_statinc(ifp, if_ierrors); 375 1.93 maxv out: 376 1.93 maxv *mp = m; 377 1.93 maxv return -1; 378 1.93 maxv } 379 1.93 maxv 380 1.93 maxv /* 381 1.93 maxv * Input code for a MANAGEMENT frame. 382 1.93 maxv */ 383 1.93 maxv static int 384 1.93 maxv ieee80211_input_management(struct ieee80211com *ic, struct mbuf **mp, 385 1.93 maxv struct ieee80211_node *ni, int rssi, u_int32_t rstamp) 386 1.93 maxv { 387 1.93 maxv IEEE80211_DEBUGVAR(char ebuf[3 * ETHER_ADDR_LEN]); 388 1.93 maxv struct ifnet *ifp = ic->ic_ifp; 389 1.93 maxv struct ieee80211_key *key; 390 1.93 maxv struct ieee80211_frame *wh; 391 1.93 maxv u_int8_t dir, subtype; 392 1.93 maxv struct mbuf *m = *mp; 393 1.93 maxv int hdrspace; 394 1.93 maxv 395 1.93 maxv wh = mtod(m, struct ieee80211_frame *); 396 1.93 maxv dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK; 397 1.93 maxv subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; 398 1.93 maxv 399 1.93 maxv IEEE80211_NODE_STAT(ni, rx_mgmt); 400 1.93 maxv if (dir != IEEE80211_FC1_DIR_NODS) { 401 1.93 maxv IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT, 402 1.117 yamt wh, "data", "unknown dir 0x%x", dir); 403 1.93 maxv ic->ic_stats.is_rx_wrongdir++; 404 1.93 maxv goto err; 405 1.93 maxv } 406 1.109 maxv if (m->m_len < sizeof(struct ieee80211_frame)) { 407 1.109 maxv IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_ANY, ni->ni_macaddr, 408 1.109 maxv "mgt", "too short: len %u", m->m_len); 409 1.93 maxv ic->ic_stats.is_rx_tooshort++; 410 1.93 maxv goto out; 411 1.93 maxv } 412 1.93 maxv #ifdef IEEE80211_DEBUG 413 1.93 maxv if ((ieee80211_msg_debug(ic) && doprint(ic, subtype)) || 414 1.93 maxv ieee80211_msg_dumppkts(ic)) { 415 1.93 maxv if_printf(ic->ic_ifp, "received %s from %s rssi %d\n", 416 1.93 maxv ieee80211_mgt_subtype_name[subtype >> 417 1.93 maxv IEEE80211_FC0_SUBTYPE_SHIFT], 418 1.93 maxv ether_snprintf(ebuf, sizeof(ebuf), wh->i_addr2), 419 1.93 maxv rssi); 420 1.93 maxv } 421 1.93 maxv #endif 422 1.93 maxv 423 1.93 maxv if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 424 1.93 maxv if (subtype != IEEE80211_FC0_SUBTYPE_AUTH) { 425 1.93 maxv /* 426 1.93 maxv * Only shared key auth frames with a challenge 427 1.93 maxv * should be encrypted, discard all others. 428 1.93 maxv */ 429 1.93 maxv IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT, 430 1.93 maxv wh, ieee80211_mgt_subtype_name[subtype >> 431 1.93 maxv IEEE80211_FC0_SUBTYPE_SHIFT], 432 1.93 maxv "%s", "WEP set but not permitted"); 433 1.93 maxv ic->ic_stats.is_rx_mgtdiscard++; /* XXX */ 434 1.93 maxv goto out; 435 1.93 maxv } 436 1.93 maxv if ((ic->ic_flags & IEEE80211_F_PRIVACY) == 0) { 437 1.93 maxv /* 438 1.93 maxv * Discard encrypted frames when privacy is off. 439 1.93 maxv */ 440 1.93 maxv IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT, 441 1.93 maxv wh, "mgt", "%s", "WEP set but PRIVACY off"); 442 1.93 maxv ic->ic_stats.is_rx_noprivacy++; 443 1.93 maxv goto out; 444 1.93 maxv } 445 1.93 maxv hdrspace = ieee80211_hdrspace(ic, wh); 446 1.93 maxv key = ieee80211_crypto_decap(ic, ni, &m, hdrspace); 447 1.93 maxv if (key == NULL) { 448 1.93 maxv /* NB: stats+msgs handled in crypto_decap */ 449 1.93 maxv goto out; 450 1.93 maxv } 451 1.93 maxv wh = mtod(m, struct ieee80211_frame *); 452 1.93 maxv wh->i_fc[1] &= ~IEEE80211_FC1_WEP; 453 1.93 maxv } 454 1.93 maxv 455 1.114 msaitoh bpf_mtap3(ic->ic_rawbpf, m, BPF_D_IN); 456 1.93 maxv (*ic->ic_recv_mgmt)(ic, m, ni, subtype, rssi, rstamp); 457 1.93 maxv m_freem(m); 458 1.93 maxv 459 1.93 maxv *mp = NULL; 460 1.93 maxv return 0; 461 1.93 maxv 462 1.93 maxv err: 463 1.116 thorpej if_statinc(ifp, if_ierrors); 464 1.93 maxv out: 465 1.93 maxv *mp = m; 466 1.93 maxv return -1; 467 1.93 maxv } 468 1.93 maxv 469 1.93 maxv /* 470 1.93 maxv * Input code for a CONTROL frame. 471 1.93 maxv */ 472 1.93 maxv static void 473 1.93 maxv ieee80211_input_control(struct ieee80211com *ic, struct mbuf *m, 474 1.93 maxv struct ieee80211_node *ni) 475 1.93 maxv { 476 1.93 maxv IEEE80211_NODE_STAT(ni, rx_ctrl); 477 1.93 maxv ic->ic_stats.is_rx_ctl++; 478 1.93 maxv 479 1.93 maxv #ifndef IEEE80211_NO_HOSTAP 480 1.93 maxv if (ic->ic_opmode == IEEE80211_M_HOSTAP) { 481 1.93 maxv struct ieee80211_frame *wh; 482 1.93 maxv u_int8_t subtype; 483 1.93 maxv 484 1.93 maxv wh = mtod(m, struct ieee80211_frame *); 485 1.93 maxv subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; 486 1.93 maxv 487 1.93 maxv switch (subtype) { 488 1.93 maxv case IEEE80211_FC0_SUBTYPE_PS_POLL: 489 1.93 maxv ieee80211_recv_pspoll(ic, ni, m); 490 1.93 maxv break; 491 1.93 maxv } 492 1.93 maxv } 493 1.93 maxv #endif 494 1.93 maxv } 495 1.93 maxv 496 1.93 maxv /* -------------------------------------------------------------------------- */ 497 1.93 maxv 498 1.1 dyoung /* 499 1.1 dyoung * Process a received frame. The node associated with the sender 500 1.1 dyoung * should be supplied. If nothing was found in the node table then 501 1.1 dyoung * the caller is assumed to supply a reference to ic_bss instead. 502 1.1 dyoung * The RSSI and a timestamp are also supplied. The RSSI data is used 503 1.1 dyoung * during AP scanning to select a AP to associate with; it can have 504 1.1 dyoung * any units so long as values have consistent units and higher values 505 1.1 dyoung * mean ``better signal''. The receive timestamp is currently not used 506 1.1 dyoung * by the 802.11 layer. 507 1.1 dyoung */ 508 1.40 dyoung int 509 1.40 dyoung ieee80211_input(struct ieee80211com *ic, struct mbuf *m, 510 1.40 dyoung struct ieee80211_node *ni, int rssi, u_int32_t rstamp) 511 1.1 dyoung { 512 1.40 dyoung #define SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0) 513 1.40 dyoung #define HAS_SEQ(type) ((type & 0x4) == 0) 514 1.40 dyoung struct ifnet *ifp = ic->ic_ifp; 515 1.1 dyoung struct ieee80211_frame *wh; 516 1.93 maxv u_int8_t dir, type; 517 1.1 dyoung u_int16_t rxseq; 518 1.85 christos IEEE80211_DEBUGVAR(char ebuf[3 * ETHER_ADDR_LEN]); 519 1.93 maxv int ret; 520 1.1 dyoung 521 1.87 nonaka KASSERT(!cpu_intr_p()); 522 1.87 nonaka 523 1.17 dyoung IASSERT(ni != NULL, ("null node")); 524 1.40 dyoung ni->ni_inact = ni->ni_inact_reload; 525 1.1 dyoung 526 1.16 dyoung /* trim CRC here so WEP can find its own CRC at the end of packet. */ 527 1.1 dyoung if (m->m_flags & M_HASFCS) { 528 1.1 dyoung m_adj(m, -IEEE80211_CRC_LEN); 529 1.1 dyoung m->m_flags &= ~M_HASFCS; 530 1.1 dyoung } 531 1.40 dyoung type = -1; /* undefined */ 532 1.92 maxv 533 1.16 dyoung /* 534 1.16 dyoung * In monitor mode, send everything directly to bpf. 535 1.16 dyoung * XXX may want to include the CRC 536 1.16 dyoung */ 537 1.40 dyoung if (ic->ic_opmode == IEEE80211_M_MONITOR) 538 1.16 dyoung goto out; 539 1.1 dyoung 540 1.109 maxv if (m->m_len < sizeof(struct ieee80211_frame_min)) { 541 1.40 dyoung IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_ANY, 542 1.40 dyoung ni->ni_macaddr, NULL, 543 1.109 maxv "too short (1): len %u", m->m_len); 544 1.40 dyoung ic->ic_stats.is_rx_tooshort++; 545 1.40 dyoung goto out; 546 1.40 dyoung } 547 1.92 maxv 548 1.40 dyoung /* 549 1.40 dyoung * Bit of a cheat here, we use a pointer for a 3-address 550 1.40 dyoung * frame format but don't reference fields past outside 551 1.40 dyoung * ieee80211_frame_min w/o first validating the data is 552 1.40 dyoung * present. 553 1.40 dyoung */ 554 1.1 dyoung wh = mtod(m, struct ieee80211_frame *); 555 1.40 dyoung 556 1.1 dyoung if ((wh->i_fc[0] & IEEE80211_FC0_VERSION_MASK) != 557 1.1 dyoung IEEE80211_FC0_VERSION_0) { 558 1.40 dyoung IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_ANY, 559 1.40 dyoung ni->ni_macaddr, NULL, "wrong version %x", wh->i_fc[0]); 560 1.16 dyoung ic->ic_stats.is_rx_badversion++; 561 1.1 dyoung goto err; 562 1.1 dyoung } 563 1.1 dyoung 564 1.1 dyoung dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK; 565 1.16 dyoung type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 566 1.92 maxv 567 1.40 dyoung if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) { 568 1.92 maxv u_int8_t *bssid; 569 1.92 maxv 570 1.40 dyoung switch (ic->ic_opmode) { 571 1.40 dyoung case IEEE80211_M_STA: 572 1.40 dyoung bssid = wh->i_addr2; 573 1.40 dyoung if (!IEEE80211_ADDR_EQ(bssid, ni->ni_bssid)) { 574 1.40 dyoung /* not interested in */ 575 1.40 dyoung IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_INPUT, 576 1.85 christos bssid, NULL, "node %s, %s", 577 1.85 christos ether_snprintf(ebuf, sizeof(ebuf), 578 1.85 christos ni->ni_bssid), "not to bss"); 579 1.40 dyoung ic->ic_stats.is_rx_wrongbss++; 580 1.40 dyoung goto out; 581 1.40 dyoung } 582 1.84 mlelstv 583 1.92 maxv /* 584 1.92 maxv * Filter out packets not directed to us in case the 585 1.92 maxv * device is in promiscuous mode 586 1.84 mlelstv */ 587 1.92 maxv if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && 588 1.92 maxv !IEEE80211_ADDR_EQ(wh->i_addr1, ic->ic_myaddr)) { 589 1.84 mlelstv IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_INPUT, 590 1.84 mlelstv bssid, NULL, "not to cur sta: lladdr=%6D, addr1=%6D", 591 1.84 mlelstv ic->ic_myaddr, ":", wh->i_addr1, ":"); 592 1.84 mlelstv ic->ic_stats.is_rx_wrongbss++; 593 1.84 mlelstv goto out; 594 1.84 mlelstv } 595 1.40 dyoung break; 596 1.92 maxv 597 1.40 dyoung case IEEE80211_M_IBSS: 598 1.40 dyoung case IEEE80211_M_AHDEMO: 599 1.40 dyoung case IEEE80211_M_HOSTAP: 600 1.40 dyoung if (dir != IEEE80211_FC1_DIR_NODS) 601 1.40 dyoung bssid = wh->i_addr1; 602 1.40 dyoung else if (type == IEEE80211_FC0_TYPE_CTL) 603 1.40 dyoung bssid = wh->i_addr1; 604 1.40 dyoung else { 605 1.109 maxv if (m->m_len < sizeof(struct ieee80211_frame)) { 606 1.40 dyoung IEEE80211_DISCARD_MAC(ic, 607 1.40 dyoung IEEE80211_MSG_ANY, ni->ni_macaddr, 608 1.40 dyoung NULL, "too short (2): len %u", 609 1.109 maxv m->m_len); 610 1.40 dyoung ic->ic_stats.is_rx_tooshort++; 611 1.40 dyoung goto out; 612 1.40 dyoung } 613 1.40 dyoung bssid = wh->i_addr3; 614 1.40 dyoung } 615 1.40 dyoung if (type != IEEE80211_FC0_TYPE_DATA) 616 1.40 dyoung break; 617 1.92 maxv 618 1.40 dyoung /* 619 1.40 dyoung * Data frame, validate the bssid. 620 1.40 dyoung */ 621 1.40 dyoung if (!IEEE80211_ADDR_EQ(bssid, ic->ic_bss->ni_bssid) && 622 1.40 dyoung !IEEE80211_ADDR_EQ(bssid, ifp->if_broadcastaddr)) { 623 1.40 dyoung /* not interested in */ 624 1.85 christos IEEE80211_DEBUGVAR( 625 1.85 christos char bbuf[3 * ETHER_ADDR_LEN]); 626 1.40 dyoung IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_INPUT, 627 1.85 christos bssid, NULL, "bss %s, broadcast %s, %s", 628 1.85 christos ether_snprintf(ebuf, sizeof(ebuf), 629 1.85 christos ic->ic_bss->ni_bssid), 630 1.85 christos ether_snprintf(bbuf, sizeof(bbuf), 631 1.85 christos ifp->if_broadcastaddr), "not to bss"); 632 1.40 dyoung ic->ic_stats.is_rx_wrongbss++; 633 1.40 dyoung goto out; 634 1.40 dyoung } 635 1.92 maxv 636 1.40 dyoung /* 637 1.40 dyoung * For adhoc mode we cons up a node when it doesn't 638 1.92 maxv * exist. This should probably be done after an ACL 639 1.92 maxv * check. 640 1.40 dyoung */ 641 1.40 dyoung if (ni == ic->ic_bss && 642 1.50 dyoung ic->ic_opmode != IEEE80211_M_HOSTAP && 643 1.50 dyoung !IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) { 644 1.40 dyoung /* 645 1.40 dyoung * Fake up a node for this newly 646 1.40 dyoung * discovered member of the IBSS. 647 1.40 dyoung */ 648 1.40 dyoung ni = ieee80211_fakeup_adhoc_node(&ic->ic_sta, 649 1.92 maxv wh->i_addr2); 650 1.40 dyoung if (ni == NULL) { 651 1.40 dyoung /* NB: stat kept for alloc failure */ 652 1.40 dyoung goto err; 653 1.40 dyoung } 654 1.40 dyoung } 655 1.40 dyoung break; 656 1.92 maxv 657 1.40 dyoung default: 658 1.40 dyoung goto out; 659 1.40 dyoung } 660 1.92 maxv 661 1.1 dyoung ni->ni_rssi = rssi; 662 1.1 dyoung ni->ni_rstamp = rstamp; 663 1.92 maxv 664 1.83 mlelstv if (HAS_SEQ(type) && (ic->ic_opmode != IEEE80211_M_STA || 665 1.83 mlelstv !IEEE80211_IS_MULTICAST(wh->i_addr1))) { 666 1.83 mlelstv u_int8_t tid, retry; 667 1.83 mlelstv u_int16_t rxno, orxno; 668 1.83 mlelstv 669 1.75 christos if (ieee80211_has_qos(wh)) { 670 1.92 maxv struct ieee80211_qosframe *qosf; 671 1.92 maxv 672 1.109 maxv if (m->m_len < sizeof(struct ieee80211_qosframe)) { 673 1.109 maxv IEEE80211_DISCARD_MAC(ic, 674 1.109 maxv IEEE80211_MSG_ANY, 675 1.109 maxv ni->ni_macaddr, NULL, 676 1.109 maxv "too short (1): len %u", m->m_len); 677 1.109 maxv ic->ic_stats.is_rx_tooshort++; 678 1.109 maxv goto out; 679 1.109 maxv } 680 1.92 maxv qosf = mtod(m, struct ieee80211_qosframe *); 681 1.92 maxv 682 1.92 maxv tid = qosf->i_qos[0] & IEEE80211_QOS_TID; 683 1.44 dyoung if (TID_TO_WME_AC(tid) >= WME_AC_VI) 684 1.40 dyoung ic->ic_wme.wme_hipri_traffic++; 685 1.40 dyoung tid++; 686 1.92 maxv } else { 687 1.40 dyoung tid = 0; 688 1.92 maxv } 689 1.92 maxv 690 1.40 dyoung rxseq = le16toh(*(u_int16_t *)wh->i_seq); 691 1.83 mlelstv retry = wh->i_fc[1] & IEEE80211_FC1_RETRY; 692 1.83 mlelstv rxno = rxseq >> IEEE80211_SEQ_SEQ_SHIFT; 693 1.83 mlelstv orxno = ni->ni_rxseqs[tid] >> IEEE80211_SEQ_SEQ_SHIFT; 694 1.92 maxv 695 1.83 mlelstv if (retry && ( 696 1.83 mlelstv (orxno == 4095 && rxno == orxno) || 697 1.83 mlelstv (orxno != 4095 && 698 1.83 mlelstv SEQ_LEQ(rxseq, ni->ni_rxseqs[tid])) 699 1.83 mlelstv )) { 700 1.40 dyoung /* duplicate, discard */ 701 1.40 dyoung IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_INPUT, 702 1.40 dyoung bssid, "duplicate", 703 1.40 dyoung "seqno <%u,%u> fragno <%u,%u> tid %u", 704 1.83 mlelstv rxno, 705 1.83 mlelstv orxno, 706 1.40 dyoung rxseq & IEEE80211_SEQ_FRAG_MASK, 707 1.40 dyoung ni->ni_rxseqs[tid] & 708 1.40 dyoung IEEE80211_SEQ_FRAG_MASK, 709 1.40 dyoung tid); 710 1.40 dyoung ic->ic_stats.is_rx_dup++; 711 1.40 dyoung IEEE80211_NODE_STAT(ni, rx_dup); 712 1.40 dyoung goto out; 713 1.40 dyoung } 714 1.40 dyoung ni->ni_rxseqs[tid] = rxseq; 715 1.5 dyoung } 716 1.5 dyoung } 717 1.5 dyoung 718 1.16 dyoung switch (type) { 719 1.1 dyoung case IEEE80211_FC0_TYPE_DATA: 720 1.93 maxv ret = ieee80211_input_data(ic, &m, ni); 721 1.93 maxv if (ret == -1) { 722 1.40 dyoung goto out; 723 1.40 dyoung } 724 1.40 dyoung return IEEE80211_FC0_TYPE_DATA; 725 1.1 dyoung 726 1.1 dyoung case IEEE80211_FC0_TYPE_MGT: 727 1.93 maxv ret = ieee80211_input_management(ic, &m, ni, rssi, rstamp); 728 1.93 maxv if (ret == -1) { 729 1.1 dyoung goto out; 730 1.16 dyoung } 731 1.93 maxv return IEEE80211_FC0_TYPE_MGT; 732 1.1 dyoung 733 1.1 dyoung case IEEE80211_FC0_TYPE_CTL: 734 1.93 maxv ieee80211_input_control(ic, m, ni); 735 1.5 dyoung goto out; 736 1.93 maxv 737 1.1 dyoung default: 738 1.40 dyoung IEEE80211_DISCARD(ic, IEEE80211_MSG_ANY, 739 1.40 dyoung wh, NULL, "bad frame type 0x%x", type); 740 1.1 dyoung /* should not come here */ 741 1.1 dyoung break; 742 1.1 dyoung } 743 1.92 maxv 744 1.40 dyoung err: 745 1.116 thorpej if_statinc(ifp, if_ierrors); 746 1.92 maxv 747 1.40 dyoung out: 748 1.1 dyoung if (m != NULL) { 749 1.114 msaitoh bpf_mtap3(ic->ic_rawbpf, m, BPF_D_IN); 750 1.1 dyoung m_freem(m); 751 1.1 dyoung } 752 1.40 dyoung return type; 753 1.40 dyoung #undef SEQ_LEQ 754 1.40 dyoung } 755 1.40 dyoung 756 1.40 dyoung /* 757 1.92 maxv * This function reassembles fragments. 758 1.40 dyoung */ 759 1.40 dyoung static struct mbuf * 760 1.113 maxv ieee80211_defrag(struct ieee80211_node *ni, struct mbuf *m, int hdrspace) 761 1.40 dyoung { 762 1.40 dyoung struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *); 763 1.40 dyoung struct ieee80211_frame *lwh; 764 1.112 maxv u_int16_t rxseq, iseq; 765 1.40 dyoung u_int8_t fragno; 766 1.94 maxv const u_int8_t more_frag = wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG; 767 1.40 dyoung struct mbuf *mfrag; 768 1.40 dyoung 769 1.40 dyoung IASSERT(!IEEE80211_IS_MULTICAST(wh->i_addr1), ("multicast fragm?")); 770 1.40 dyoung 771 1.112 maxv iseq = *(u_int16_t *)wh->i_seq; 772 1.112 maxv rxseq = le16toh(iseq); 773 1.40 dyoung fragno = rxseq & IEEE80211_SEQ_FRAG_MASK; 774 1.40 dyoung 775 1.40 dyoung /* Quick way out, if there's nothing to defragment */ 776 1.40 dyoung if (!more_frag && fragno == 0 && ni->ni_rxfrag[0] == NULL) 777 1.40 dyoung return m; 778 1.40 dyoung 779 1.40 dyoung /* 780 1.40 dyoung * Remove frag to insure it doesn't get reaped by timer. 781 1.40 dyoung */ 782 1.40 dyoung if (ni->ni_table == NULL) { 783 1.40 dyoung /* 784 1.40 dyoung * Should never happen. If the node is orphaned (not in 785 1.40 dyoung * the table) then input packets should not reach here. 786 1.40 dyoung * Otherwise, a concurrent request that yanks the table 787 1.40 dyoung * should be blocked by other interlocking and/or by first 788 1.40 dyoung * shutting the driver down. Regardless, be defensive 789 1.40 dyoung * here and just bail 790 1.40 dyoung */ 791 1.40 dyoung /* XXX need msg+stat */ 792 1.40 dyoung m_freem(m); 793 1.40 dyoung return NULL; 794 1.40 dyoung } 795 1.40 dyoung IEEE80211_NODE_LOCK(ni->ni_table); 796 1.40 dyoung mfrag = ni->ni_rxfrag[0]; 797 1.40 dyoung ni->ni_rxfrag[0] = NULL; 798 1.40 dyoung IEEE80211_NODE_UNLOCK(ni->ni_table); 799 1.40 dyoung 800 1.40 dyoung /* 801 1.40 dyoung * Validate new fragment is in order and 802 1.40 dyoung * related to the previous ones. 803 1.40 dyoung */ 804 1.40 dyoung if (mfrag != NULL) { 805 1.40 dyoung u_int16_t last_rxseq; 806 1.40 dyoung 807 1.40 dyoung lwh = mtod(mfrag, struct ieee80211_frame *); 808 1.40 dyoung last_rxseq = le16toh(*(u_int16_t *)lwh->i_seq); 809 1.40 dyoung /* NB: check seq # and frag together */ 810 1.40 dyoung if (rxseq != last_rxseq+1 || 811 1.40 dyoung !IEEE80211_ADDR_EQ(wh->i_addr1, lwh->i_addr1) || 812 1.40 dyoung !IEEE80211_ADDR_EQ(wh->i_addr2, lwh->i_addr2)) { 813 1.40 dyoung /* 814 1.40 dyoung * Unrelated fragment or no space for it, 815 1.40 dyoung * clear current fragments. 816 1.40 dyoung */ 817 1.40 dyoung m_freem(mfrag); 818 1.40 dyoung mfrag = NULL; 819 1.40 dyoung } 820 1.40 dyoung } 821 1.40 dyoung 822 1.94 maxv if (mfrag == NULL) { 823 1.40 dyoung if (fragno != 0) { /* !first fragment, discard */ 824 1.40 dyoung IEEE80211_NODE_STAT(ni, rx_defrag); 825 1.40 dyoung m_freem(m); 826 1.40 dyoung return NULL; 827 1.40 dyoung } 828 1.40 dyoung mfrag = m; 829 1.94 maxv } else { 830 1.112 maxv int mlen; 831 1.112 maxv 832 1.94 maxv /* Strip header and concatenate */ 833 1.94 maxv m_adj(m, hdrspace); 834 1.112 maxv mlen = m->m_pkthdr.len; 835 1.40 dyoung m_cat(mfrag, m); 836 1.94 maxv 837 1.40 dyoung /* NB: m_cat doesn't update the packet header */ 838 1.112 maxv mfrag->m_pkthdr.len += mlen; 839 1.94 maxv 840 1.40 dyoung /* track last seqnum and fragno */ 841 1.40 dyoung lwh = mtod(mfrag, struct ieee80211_frame *); 842 1.112 maxv *(u_int16_t *)lwh->i_seq = iseq; 843 1.40 dyoung } 844 1.94 maxv 845 1.94 maxv if (more_frag) { 846 1.94 maxv /* more to come, save */ 847 1.40 dyoung ni->ni_rxfragstamp = ticks; 848 1.40 dyoung ni->ni_rxfrag[0] = mfrag; 849 1.40 dyoung mfrag = NULL; 850 1.40 dyoung } 851 1.94 maxv 852 1.40 dyoung return mfrag; 853 1.1 dyoung } 854 1.1 dyoung 855 1.47 skrll static void 856 1.47 skrll ieee80211_deliver_data(struct ieee80211com *ic, 857 1.47 skrll struct ieee80211_node *ni, struct mbuf *m) 858 1.47 skrll { 859 1.47 skrll struct ether_header *eh = mtod(m, struct ether_header *); 860 1.47 skrll struct ifnet *ifp = ic->ic_ifp; 861 1.68 joerg int error; 862 1.47 skrll 863 1.47 skrll /* perform as a bridge within the AP */ 864 1.47 skrll if (ic->ic_opmode == IEEE80211_M_HOSTAP && 865 1.47 skrll (ic->ic_flags & IEEE80211_F_NOBRIDGE) == 0) { 866 1.47 skrll struct mbuf *m1 = NULL; 867 1.47 skrll 868 1.47 skrll if (ETHER_IS_MULTICAST(eh->ether_dhost)) { 869 1.47 skrll m1 = m_copypacket(m, M_DONTWAIT); 870 1.47 skrll if (m1 == NULL) 871 1.116 thorpej if_statinc(ifp, if_oerrors); 872 1.47 skrll else 873 1.47 skrll m1->m_flags |= M_MCAST; 874 1.47 skrll } else { 875 1.47 skrll /* 876 1.47 skrll * Check if the destination is known; if so 877 1.47 skrll * and the port is authorized dispatch directly. 878 1.47 skrll */ 879 1.47 skrll struct ieee80211_node *sta = 880 1.47 skrll ieee80211_find_node(&ic->ic_sta, eh->ether_dhost); 881 1.47 skrll if (sta != NULL) { 882 1.47 skrll if (ieee80211_node_is_authorized(sta)) { 883 1.47 skrll /* 884 1.47 skrll * Beware of sending to ourself; this 885 1.47 skrll * needs to happen via the normal 886 1.47 skrll * input path. 887 1.47 skrll */ 888 1.47 skrll if (sta != ic->ic_bss) { 889 1.47 skrll m1 = m; 890 1.47 skrll m = NULL; 891 1.47 skrll } 892 1.47 skrll } else { 893 1.47 skrll ic->ic_stats.is_rx_unauth++; 894 1.47 skrll IEEE80211_NODE_STAT(sta, rx_unauth); 895 1.47 skrll } 896 1.47 skrll ieee80211_free_node(sta); 897 1.47 skrll } 898 1.47 skrll } 899 1.95 maxv 900 1.47 skrll if (m1 != NULL) { 901 1.47 skrll int len; 902 1.47 skrll #ifdef ALTQ 903 1.47 skrll if (ALTQ_IS_ENABLED(&ifp->if_snd)) { 904 1.81 knakahar altq_etherclassify(&ifp->if_snd, m1); 905 1.47 skrll } 906 1.47 skrll #endif 907 1.47 skrll len = m1->m_pkthdr.len; 908 1.82 knakahar IFQ_ENQUEUE(&ifp->if_snd, m1, error); 909 1.68 joerg if (error) { 910 1.116 thorpej if_statinc(ifp, if_oerrors); 911 1.95 maxv m_freem(m); 912 1.68 joerg m = NULL; 913 1.68 joerg } 914 1.116 thorpej if_statadd(ifp, if_obytes, len); 915 1.47 skrll } 916 1.47 skrll } 917 1.95 maxv 918 1.47 skrll if (m != NULL) { 919 1.89 knakahar if (ni->ni_vlan != 0) 920 1.89 knakahar vlan_set_tag(m, ni->ni_vlan); 921 1.80 ozaki 922 1.80 ozaki /* 923 1.80 ozaki * XXX once ieee80211_input (or rxintr itself) runs in softint 924 1.80 ozaki * we have to change here too to use if_input. 925 1.80 ozaki */ 926 1.80 ozaki KASSERT(ifp->if_percpuq); 927 1.80 ozaki if_percpuq_enqueue(ifp->if_percpuq, m); 928 1.47 skrll } 929 1.95 maxv 930 1.47 skrll return; 931 1.47 skrll } 932 1.47 skrll 933 1.40 dyoung static struct mbuf * 934 1.113 maxv ieee80211_decap(struct mbuf *m, int hdrlen) 935 1.1 dyoung { 936 1.94 maxv struct ieee80211_qosframe_addr4 wh; /* Max size address frames */ 937 1.1 dyoung struct ether_header *eh; 938 1.1 dyoung struct llc *llc; 939 1.1 dyoung 940 1.44 dyoung if (m->m_len < hdrlen + sizeof(*llc) && 941 1.44 dyoung (m = m_pullup(m, hdrlen + sizeof(*llc))) == NULL) { 942 1.40 dyoung return NULL; 943 1.1 dyoung } 944 1.94 maxv 945 1.65 christos memcpy(&wh, mtod(m, void *), hdrlen); 946 1.94 maxv 947 1.65 christos llc = (struct llc *)(mtod(m, char *) + hdrlen); 948 1.94 maxv if (llc->llc_dsap == LLC_SNAP_LSAP && 949 1.94 maxv llc->llc_ssap == LLC_SNAP_LSAP && 950 1.94 maxv llc->llc_control == LLC_UI && 951 1.94 maxv llc->llc_snap.org_code[0] == 0 && 952 1.94 maxv llc->llc_snap.org_code[1] == 0 && 953 1.94 maxv llc->llc_snap.org_code[2] == 0) { 954 1.44 dyoung m_adj(m, hdrlen + sizeof(struct llc) - sizeof(*eh)); 955 1.1 dyoung llc = NULL; 956 1.1 dyoung } else { 957 1.94 maxv /* Keep the LLC after the Ethernet header. */ 958 1.44 dyoung m_adj(m, hdrlen - sizeof(*eh)); 959 1.1 dyoung } 960 1.94 maxv 961 1.1 dyoung eh = mtod(m, struct ether_header *); 962 1.94 maxv 963 1.1 dyoung switch (wh.i_fc[1] & IEEE80211_FC1_DIR_MASK) { 964 1.1 dyoung case IEEE80211_FC1_DIR_NODS: 965 1.1 dyoung IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr1); 966 1.1 dyoung IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr2); 967 1.1 dyoung break; 968 1.1 dyoung case IEEE80211_FC1_DIR_TODS: 969 1.1 dyoung IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr3); 970 1.1 dyoung IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr2); 971 1.1 dyoung break; 972 1.1 dyoung case IEEE80211_FC1_DIR_FROMDS: 973 1.1 dyoung IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr1); 974 1.1 dyoung IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr3); 975 1.1 dyoung break; 976 1.1 dyoung case IEEE80211_FC1_DIR_DSTODS: 977 1.44 dyoung IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr3); 978 1.44 dyoung IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr4); 979 1.44 dyoung break; 980 1.1 dyoung } 981 1.94 maxv 982 1.1 dyoung #ifdef ALIGNED_POINTER 983 1.66 christos if (!ALIGNED_POINTER(mtod(m, char *) + sizeof(*eh), u_int32_t)) { 984 1.1 dyoung struct mbuf *n, *n0, **np; 985 1.65 christos char *newdata; 986 1.1 dyoung int off, pktlen; 987 1.1 dyoung 988 1.1 dyoung n0 = NULL; 989 1.1 dyoung np = &n0; 990 1.1 dyoung off = 0; 991 1.1 dyoung pktlen = m->m_pkthdr.len; 992 1.1 dyoung while (pktlen > off) { 993 1.1 dyoung if (n0 == NULL) { 994 1.1 dyoung MGETHDR(n, M_DONTWAIT, MT_DATA); 995 1.1 dyoung if (n == NULL) { 996 1.1 dyoung m_freem(m); 997 1.1 dyoung return NULL; 998 1.1 dyoung } 999 1.115 maxv m_move_pkthdr(n, m); 1000 1.1 dyoung n->m_len = MHLEN; 1001 1.1 dyoung } else { 1002 1.1 dyoung MGET(n, M_DONTWAIT, MT_DATA); 1003 1.1 dyoung if (n == NULL) { 1004 1.1 dyoung m_freem(m); 1005 1.1 dyoung m_freem(n0); 1006 1.1 dyoung return NULL; 1007 1.1 dyoung } 1008 1.1 dyoung n->m_len = MLEN; 1009 1.1 dyoung } 1010 1.1 dyoung if (pktlen - off >= MINCLSIZE) { 1011 1.1 dyoung MCLGET(n, M_DONTWAIT); 1012 1.1 dyoung if (n->m_flags & M_EXT) 1013 1.1 dyoung n->m_len = n->m_ext.ext_size; 1014 1.1 dyoung } 1015 1.1 dyoung if (n0 == NULL) { 1016 1.1 dyoung newdata = 1017 1.65 christos (char *)ALIGN(n->m_data + sizeof(*eh)) - 1018 1.1 dyoung sizeof(*eh); 1019 1.1 dyoung n->m_len -= newdata - n->m_data; 1020 1.1 dyoung n->m_data = newdata; 1021 1.1 dyoung } 1022 1.1 dyoung if (n->m_len > pktlen - off) 1023 1.1 dyoung n->m_len = pktlen - off; 1024 1.65 christos m_copydata(m, off, n->m_len, mtod(n, void *)); 1025 1.1 dyoung off += n->m_len; 1026 1.1 dyoung *np = n; 1027 1.1 dyoung np = &n->m_next; 1028 1.1 dyoung } 1029 1.1 dyoung m_freem(m); 1030 1.1 dyoung m = n0; 1031 1.1 dyoung } 1032 1.1 dyoung #endif /* ALIGNED_POINTER */ 1033 1.94 maxv 1034 1.1 dyoung if (llc != NULL) { 1035 1.1 dyoung eh = mtod(m, struct ether_header *); 1036 1.1 dyoung eh->ether_type = htons(m->m_pkthdr.len - sizeof(*eh)); 1037 1.1 dyoung } 1038 1.94 maxv 1039 1.1 dyoung return m; 1040 1.1 dyoung } 1041 1.1 dyoung 1042 1.1 dyoung /* 1043 1.1 dyoung * Install received rate set information in the node's state block. 1044 1.1 dyoung */ 1045 1.47 skrll int 1046 1.108 maxv ieee80211_setup_rates(struct ieee80211_node *ni, const u_int8_t *rates, 1047 1.108 maxv const u_int8_t *xrates, int flags) 1048 1.1 dyoung { 1049 1.47 skrll struct ieee80211com *ic = ni->ni_ic; 1050 1.1 dyoung struct ieee80211_rateset *rs = &ni->ni_rates; 1051 1.1 dyoung 1052 1.1 dyoung memset(rs, 0, sizeof(*rs)); 1053 1.108 maxv 1054 1.1 dyoung rs->rs_nrates = rates[1]; 1055 1.1 dyoung memcpy(rs->rs_rates, rates + 2, rs->rs_nrates); 1056 1.108 maxv 1057 1.1 dyoung if (xrates != NULL) { 1058 1.1 dyoung u_int8_t nxrates; 1059 1.108 maxv size_t totalrate; 1060 1.108 maxv 1061 1.1 dyoung /* 1062 1.1 dyoung * Tack on 11g extended supported rate element. 1063 1.1 dyoung */ 1064 1.1 dyoung nxrates = xrates[1]; 1065 1.108 maxv totalrate = (size_t)rs->rs_nrates + (size_t)nxrates; 1066 1.108 maxv 1067 1.108 maxv if (totalrate > IEEE80211_RATE_MAXSIZE) { 1068 1.85 christos IEEE80211_DEBUGVAR(char ebuf[3 * ETHER_ADDR_LEN]); 1069 1.1 dyoung nxrates = IEEE80211_RATE_MAXSIZE - rs->rs_nrates; 1070 1.25 mycroft IEEE80211_DPRINTF(ic, IEEE80211_MSG_XRATE, 1071 1.40 dyoung "[%s] extended rate set too large;" 1072 1.40 dyoung " only using %u of %u rates\n", 1073 1.85 christos ether_snprintf(ebuf, sizeof(ebuf), ni->ni_macaddr), 1074 1.85 christos nxrates, xrates[1]); 1075 1.16 dyoung ic->ic_stats.is_rx_rstoobig++; 1076 1.1 dyoung } 1077 1.108 maxv 1078 1.1 dyoung memcpy(rs->rs_rates + rs->rs_nrates, xrates+2, nxrates); 1079 1.1 dyoung rs->rs_nrates += nxrates; 1080 1.1 dyoung } 1081 1.108 maxv 1082 1.47 skrll return ieee80211_fix_rate(ni, flags); 1083 1.1 dyoung } 1084 1.1 dyoung 1085 1.7 dyoung static void 1086 1.7 dyoung ieee80211_auth_open(struct ieee80211com *ic, struct ieee80211_frame *wh, 1087 1.64 christos struct ieee80211_node *ni, int rssi, u_int32_t rstamp, 1088 1.63 christos u_int16_t seq, u_int16_t status) 1089 1.7 dyoung { 1090 1.85 christos IEEE80211_DEBUGVAR(char ebuf[3 * ETHER_ADDR_LEN]); 1091 1.40 dyoung 1092 1.44 dyoung if (ni->ni_authmode == IEEE80211_AUTH_SHARED) { 1093 1.44 dyoung IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH, 1094 1.44 dyoung ni->ni_macaddr, "open auth", 1095 1.44 dyoung "bad sta auth mode %u", ni->ni_authmode); 1096 1.44 dyoung ic->ic_stats.is_rx_bad_auth++; /* XXX */ 1097 1.109 maxv 1098 1.44 dyoung if (ic->ic_opmode == IEEE80211_M_HOSTAP) { 1099 1.44 dyoung /* XXX hack to workaround calling convention */ 1100 1.74 christos ieee80211_send_error(ic, ni, wh->i_addr2, 1101 1.44 dyoung IEEE80211_FC0_SUBTYPE_AUTH, 1102 1.44 dyoung (seq + 1) | (IEEE80211_STATUS_ALG<<16)); 1103 1.44 dyoung } 1104 1.44 dyoung return; 1105 1.44 dyoung } 1106 1.109 maxv 1107 1.7 dyoung switch (ic->ic_opmode) { 1108 1.7 dyoung case IEEE80211_M_IBSS: 1109 1.7 dyoung case IEEE80211_M_AHDEMO: 1110 1.44 dyoung case IEEE80211_M_MONITOR: 1111 1.7 dyoung /* should not come here */ 1112 1.44 dyoung IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH, 1113 1.44 dyoung ni->ni_macaddr, "open auth", 1114 1.44 dyoung "bad operating mode %u", ic->ic_opmode); 1115 1.7 dyoung break; 1116 1.7 dyoung 1117 1.7 dyoung case IEEE80211_M_HOSTAP: 1118 1.41 dyoung #ifndef IEEE80211_NO_HOSTAP 1119 1.11 mycroft if (ic->ic_state != IEEE80211_S_RUN || 1120 1.16 dyoung seq != IEEE80211_AUTH_OPEN_REQUEST) { 1121 1.16 dyoung ic->ic_stats.is_rx_bad_auth++; 1122 1.7 dyoung return; 1123 1.16 dyoung } 1124 1.109 maxv 1125 1.40 dyoung /* always accept open authentication requests */ 1126 1.7 dyoung if (ni == ic->ic_bss) { 1127 1.40 dyoung ni = ieee80211_dup_bss(&ic->ic_sta, wh->i_addr2); 1128 1.40 dyoung if (ni == NULL) 1129 1.7 dyoung return; 1130 1.109 maxv } else if ((ni->ni_flags & IEEE80211_NODE_AREF) == 0) { 1131 1.109 maxv (void)ieee80211_ref_node(ni); 1132 1.109 maxv } 1133 1.109 maxv 1134 1.44 dyoung /* 1135 1.78 snj * Mark the node as referenced to reflect that its 1136 1.44 dyoung * reference count has been bumped to insure it remains 1137 1.44 dyoung * after the transaction completes. 1138 1.44 dyoung */ 1139 1.44 dyoung ni->ni_flags |= IEEE80211_NODE_AREF; 1140 1.44 dyoung 1141 1.109 maxv IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_AUTH, 1142 1.109 maxv seq + 1); 1143 1.26 mycroft IEEE80211_DPRINTF(ic, IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH, 1144 1.40 dyoung "[%s] station authenticated (open)\n", 1145 1.85 christos ether_snprintf(ebuf, sizeof(ebuf), ni->ni_macaddr)); 1146 1.109 maxv 1147 1.44 dyoung /* 1148 1.44 dyoung * When 802.1x is not in use mark the port 1149 1.44 dyoung * authorized at this point so traffic can flow. 1150 1.44 dyoung */ 1151 1.44 dyoung if (ni->ni_authmode != IEEE80211_AUTH_8021X) 1152 1.47 skrll ieee80211_node_authorize(ni); 1153 1.41 dyoung #endif /* !IEEE80211_NO_HOSTAP */ 1154 1.7 dyoung break; 1155 1.26 mycroft 1156 1.7 dyoung case IEEE80211_M_STA: 1157 1.7 dyoung if (ic->ic_state != IEEE80211_S_AUTH || 1158 1.16 dyoung seq != IEEE80211_AUTH_OPEN_RESPONSE) { 1159 1.16 dyoung ic->ic_stats.is_rx_bad_auth++; 1160 1.7 dyoung return; 1161 1.16 dyoung } 1162 1.7 dyoung if (status != 0) { 1163 1.26 mycroft IEEE80211_DPRINTF(ic, 1164 1.26 mycroft IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH, 1165 1.40 dyoung "[%s] open auth failed (reason %d)\n", 1166 1.85 christos ether_snprintf(ebuf, sizeof(ebuf), ni->ni_macaddr), 1167 1.85 christos status); 1168 1.109 maxv 1169 1.40 dyoung /* XXX can this happen? */ 1170 1.7 dyoung if (ni != ic->ic_bss) 1171 1.7 dyoung ni->ni_fails++; 1172 1.109 maxv 1173 1.16 dyoung ic->ic_stats.is_rx_auth_fail++; 1174 1.44 dyoung ieee80211_new_state(ic, IEEE80211_S_SCAN, 0); 1175 1.109 maxv } else { 1176 1.44 dyoung ieee80211_new_state(ic, IEEE80211_S_ASSOC, 1177 1.44 dyoung wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 1178 1.109 maxv } 1179 1.7 dyoung break; 1180 1.7 dyoung } 1181 1.7 dyoung } 1182 1.7 dyoung 1183 1.44 dyoung /* 1184 1.44 dyoung * Send a management frame error response to the specified 1185 1.44 dyoung * station. If ni is associated with the station then use 1186 1.44 dyoung * it; otherwise allocate a temporary node suitable for 1187 1.44 dyoung * transmitting the frame and then free the reference so 1188 1.44 dyoung * it will go away as soon as the frame has been transmitted. 1189 1.44 dyoung */ 1190 1.44 dyoung static void 1191 1.44 dyoung ieee80211_send_error(struct ieee80211com *ic, struct ieee80211_node *ni, 1192 1.109 maxv const u_int8_t *mac, int subtype, int arg) 1193 1.44 dyoung { 1194 1.109 maxv bool istmp; 1195 1.44 dyoung 1196 1.44 dyoung if (ni == ic->ic_bss) { 1197 1.47 skrll ni = ieee80211_tmp_node(ic, mac); 1198 1.44 dyoung if (ni == NULL) { 1199 1.44 dyoung /* XXX msg */ 1200 1.44 dyoung return; 1201 1.44 dyoung } 1202 1.109 maxv istmp = true; 1203 1.109 maxv } else { 1204 1.109 maxv istmp = false; 1205 1.109 maxv } 1206 1.109 maxv 1207 1.44 dyoung IEEE80211_SEND_MGMT(ic, ni, subtype, arg); 1208 1.44 dyoung if (istmp) 1209 1.44 dyoung ieee80211_free_node(ni); 1210 1.44 dyoung } 1211 1.44 dyoung 1212 1.40 dyoung static int 1213 1.40 dyoung alloc_challenge(struct ieee80211com *ic, struct ieee80211_node *ni) 1214 1.40 dyoung { 1215 1.109 maxv if (ni->ni_challenge == NULL) { 1216 1.67 cegger ni->ni_challenge = malloc(IEEE80211_CHALLENGE_LEN, 1217 1.40 dyoung M_DEVBUF, M_NOWAIT); 1218 1.109 maxv } 1219 1.40 dyoung if (ni->ni_challenge == NULL) { 1220 1.109 maxv IEEE80211_DEBUGVAR(char ebuf[3 * ETHER_ADDR_LEN]); 1221 1.85 christos 1222 1.40 dyoung IEEE80211_DPRINTF(ic, IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH, 1223 1.40 dyoung "[%s] shared key challenge alloc failed\n", 1224 1.85 christos ether_snprintf(ebuf, sizeof(ebuf), ni->ni_macaddr)); 1225 1.40 dyoung /* XXX statistic */ 1226 1.40 dyoung } 1227 1.40 dyoung return (ni->ni_challenge != NULL); 1228 1.40 dyoung } 1229 1.40 dyoung 1230 1.40 dyoung /* XXX TODO: add statistics */ 1231 1.7 dyoung static void 1232 1.7 dyoung ieee80211_auth_shared(struct ieee80211com *ic, struct ieee80211_frame *wh, 1233 1.7 dyoung u_int8_t *frm, u_int8_t *efrm, struct ieee80211_node *ni, int rssi, 1234 1.7 dyoung u_int32_t rstamp, u_int16_t seq, u_int16_t status) 1235 1.7 dyoung { 1236 1.40 dyoung u_int8_t *challenge; 1237 1.41 dyoung int estatus; 1238 1.85 christos IEEE80211_DEBUGVAR(char ebuf[3 * ETHER_ADDR_LEN]); 1239 1.7 dyoung 1240 1.40 dyoung /* 1241 1.40 dyoung * NB: this can happen as we allow pre-shared key 1242 1.40 dyoung * authentication to be enabled w/o wep being turned 1243 1.40 dyoung * on so that configuration of these can be done 1244 1.40 dyoung * in any order. It may be better to enforce the 1245 1.40 dyoung * ordering in which case this check would just be 1246 1.40 dyoung * for sanity/consistency. 1247 1.40 dyoung */ 1248 1.28 mycroft if ((ic->ic_flags & IEEE80211_F_PRIVACY) == 0) { 1249 1.40 dyoung IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH, 1250 1.40 dyoung ni->ni_macaddr, "shared key auth", 1251 1.40 dyoung "%s", " PRIVACY is disabled"); 1252 1.40 dyoung estatus = IEEE80211_STATUS_ALG; 1253 1.40 dyoung goto bad; 1254 1.40 dyoung } 1255 1.109 maxv 1256 1.40 dyoung /* 1257 1.40 dyoung * Pre-shared key authentication is evil; accept 1258 1.40 dyoung * it only if explicitly configured (it is supported 1259 1.40 dyoung * mainly for compatibility with clients like OS X). 1260 1.40 dyoung */ 1261 1.40 dyoung if (ni->ni_authmode != IEEE80211_AUTH_AUTO && 1262 1.40 dyoung ni->ni_authmode != IEEE80211_AUTH_SHARED) { 1263 1.40 dyoung IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH, 1264 1.40 dyoung ni->ni_macaddr, "shared key auth", 1265 1.40 dyoung "bad sta auth mode %u", ni->ni_authmode); 1266 1.40 dyoung ic->ic_stats.is_rx_bad_auth++; /* XXX maybe a unique error? */ 1267 1.40 dyoung estatus = IEEE80211_STATUS_ALG; 1268 1.40 dyoung goto bad; 1269 1.7 dyoung } 1270 1.7 dyoung 1271 1.40 dyoung challenge = NULL; 1272 1.7 dyoung if (frm + 1 < efrm) { 1273 1.40 dyoung if ((frm[1] + 2) > (efrm - frm)) { 1274 1.40 dyoung IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH, 1275 1.40 dyoung ni->ni_macaddr, "shared key auth", 1276 1.40 dyoung "ie %d/%d too long", 1277 1.40 dyoung frm[0], (frm[1] + 2) - (efrm - frm)); 1278 1.16 dyoung ic->ic_stats.is_rx_bad_auth++; 1279 1.40 dyoung estatus = IEEE80211_STATUS_CHALLENGE; 1280 1.40 dyoung goto bad; 1281 1.7 dyoung } 1282 1.7 dyoung if (*frm == IEEE80211_ELEMID_CHALLENGE) 1283 1.7 dyoung challenge = frm; 1284 1.7 dyoung frm += frm[1] + 2; 1285 1.7 dyoung } 1286 1.109 maxv 1287 1.7 dyoung switch (seq) { 1288 1.7 dyoung case IEEE80211_AUTH_SHARED_CHALLENGE: 1289 1.7 dyoung case IEEE80211_AUTH_SHARED_RESPONSE: 1290 1.7 dyoung if (challenge == NULL) { 1291 1.40 dyoung IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH, 1292 1.40 dyoung ni->ni_macaddr, "shared key auth", 1293 1.40 dyoung "%s", "no challenge"); 1294 1.16 dyoung ic->ic_stats.is_rx_bad_auth++; 1295 1.40 dyoung estatus = IEEE80211_STATUS_CHALLENGE; 1296 1.40 dyoung goto bad; 1297 1.7 dyoung } 1298 1.7 dyoung if (challenge[1] != IEEE80211_CHALLENGE_LEN) { 1299 1.40 dyoung IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH, 1300 1.40 dyoung ni->ni_macaddr, "shared key auth", 1301 1.40 dyoung "bad challenge len %d", challenge[1]); 1302 1.16 dyoung ic->ic_stats.is_rx_bad_auth++; 1303 1.40 dyoung estatus = IEEE80211_STATUS_CHALLENGE; 1304 1.40 dyoung goto bad; 1305 1.7 dyoung } 1306 1.7 dyoung default: 1307 1.7 dyoung break; 1308 1.7 dyoung } 1309 1.109 maxv 1310 1.7 dyoung switch (ic->ic_opmode) { 1311 1.7 dyoung case IEEE80211_M_MONITOR: 1312 1.7 dyoung case IEEE80211_M_AHDEMO: 1313 1.7 dyoung case IEEE80211_M_IBSS: 1314 1.40 dyoung IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH, 1315 1.40 dyoung ni->ni_macaddr, "shared key auth", 1316 1.40 dyoung "bad operating mode %u", ic->ic_opmode); 1317 1.7 dyoung return; 1318 1.109 maxv 1319 1.7 dyoung case IEEE80211_M_HOSTAP: 1320 1.41 dyoung #ifndef IEEE80211_NO_HOSTAP 1321 1.41 dyoung { 1322 1.41 dyoung int allocbs; 1323 1.7 dyoung if (ic->ic_state != IEEE80211_S_RUN) { 1324 1.40 dyoung IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH, 1325 1.40 dyoung ni->ni_macaddr, "shared key auth", 1326 1.40 dyoung "bad state %u", ic->ic_state); 1327 1.40 dyoung estatus = IEEE80211_STATUS_ALG; /* XXX */ 1328 1.40 dyoung goto bad; 1329 1.7 dyoung } 1330 1.7 dyoung switch (seq) { 1331 1.7 dyoung case IEEE80211_AUTH_SHARED_REQUEST: 1332 1.7 dyoung if (ni == ic->ic_bss) { 1333 1.40 dyoung ni = ieee80211_dup_bss(&ic->ic_sta, wh->i_addr2); 1334 1.16 dyoung if (ni == NULL) { 1335 1.40 dyoung /* NB: no way to return an error */ 1336 1.7 dyoung return; 1337 1.16 dyoung } 1338 1.40 dyoung allocbs = 1; 1339 1.40 dyoung } else { 1340 1.44 dyoung if ((ni->ni_flags & IEEE80211_NODE_AREF) == 0) 1341 1.109 maxv (void)ieee80211_ref_node(ni); 1342 1.40 dyoung allocbs = 0; 1343 1.40 dyoung } 1344 1.85 christos __USE(allocbs); 1345 1.109 maxv 1346 1.44 dyoung /* 1347 1.78 snj * Mark the node as referenced to reflect that its 1348 1.44 dyoung * reference count has been bumped to insure it remains 1349 1.44 dyoung * after the transaction completes. 1350 1.44 dyoung */ 1351 1.44 dyoung ni->ni_flags |= IEEE80211_NODE_AREF; 1352 1.40 dyoung ni->ni_rssi = rssi; 1353 1.40 dyoung ni->ni_rstamp = rstamp; 1354 1.40 dyoung if (!alloc_challenge(ic, ni)) { 1355 1.40 dyoung /* NB: don't return error so they rexmit */ 1356 1.40 dyoung return; 1357 1.40 dyoung } 1358 1.109 maxv 1359 1.40 dyoung get_random_bytes(ni->ni_challenge, 1360 1.40 dyoung IEEE80211_CHALLENGE_LEN); 1361 1.109 maxv 1362 1.40 dyoung IEEE80211_DPRINTF(ic, 1363 1.40 dyoung IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH, 1364 1.40 dyoung "[%s] shared key %sauth request\n", 1365 1.85 christos ether_snprintf(ebuf, sizeof(ebuf), 1366 1.85 christos ni->ni_macaddr), 1367 1.40 dyoung allocbs ? "" : "re"); 1368 1.40 dyoung break; 1369 1.109 maxv 1370 1.40 dyoung case IEEE80211_AUTH_SHARED_RESPONSE: 1371 1.40 dyoung if (ni == ic->ic_bss) { 1372 1.40 dyoung IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH, 1373 1.40 dyoung ni->ni_macaddr, "shared key response", 1374 1.40 dyoung "%s", "unknown station"); 1375 1.40 dyoung /* NB: don't send a response */ 1376 1.40 dyoung return; 1377 1.40 dyoung } 1378 1.109 maxv 1379 1.7 dyoung if (ni->ni_challenge == NULL) { 1380 1.40 dyoung IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH, 1381 1.40 dyoung ni->ni_macaddr, "shared key response", 1382 1.40 dyoung "%s", "no challenge recorded"); 1383 1.40 dyoung ic->ic_stats.is_rx_bad_auth++; 1384 1.40 dyoung estatus = IEEE80211_STATUS_CHALLENGE; 1385 1.40 dyoung goto bad; 1386 1.40 dyoung } 1387 1.109 maxv 1388 1.40 dyoung if (memcmp(ni->ni_challenge, &challenge[2], 1389 1.109 maxv challenge[1]) != 0) { 1390 1.40 dyoung IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH, 1391 1.40 dyoung ni->ni_macaddr, "shared key response", 1392 1.40 dyoung "%s", "challenge mismatch"); 1393 1.40 dyoung ic->ic_stats.is_rx_auth_fail++; 1394 1.40 dyoung estatus = IEEE80211_STATUS_CHALLENGE; 1395 1.40 dyoung goto bad; 1396 1.40 dyoung } 1397 1.109 maxv 1398 1.40 dyoung IEEE80211_DPRINTF(ic, 1399 1.40 dyoung IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH, 1400 1.40 dyoung "[%s] station authenticated (shared key)\n", 1401 1.85 christos ether_snprintf(ebuf, sizeof(ebuf), ni->ni_macaddr)); 1402 1.109 maxv 1403 1.47 skrll ieee80211_node_authorize(ni); 1404 1.40 dyoung break; 1405 1.109 maxv 1406 1.40 dyoung default: 1407 1.40 dyoung IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH, 1408 1.40 dyoung ni->ni_macaddr, "shared key auth", 1409 1.40 dyoung "bad seq %d", seq); 1410 1.40 dyoung ic->ic_stats.is_rx_bad_auth++; 1411 1.40 dyoung estatus = IEEE80211_STATUS_SEQUENCE; 1412 1.40 dyoung goto bad; 1413 1.40 dyoung } 1414 1.109 maxv 1415 1.109 maxv IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_AUTH, 1416 1.109 maxv seq + 1); 1417 1.41 dyoung } 1418 1.41 dyoung #endif /* !IEEE80211_NO_HOSTAP */ 1419 1.40 dyoung break; 1420 1.40 dyoung 1421 1.40 dyoung case IEEE80211_M_STA: 1422 1.40 dyoung if (ic->ic_state != IEEE80211_S_AUTH) 1423 1.40 dyoung return; 1424 1.40 dyoung switch (seq) { 1425 1.40 dyoung case IEEE80211_AUTH_SHARED_PASS: 1426 1.40 dyoung if (ni->ni_challenge != NULL) { 1427 1.67 cegger free(ni->ni_challenge, M_DEVBUF); 1428 1.40 dyoung ni->ni_challenge = NULL; 1429 1.40 dyoung } 1430 1.40 dyoung if (status != 0) { 1431 1.40 dyoung IEEE80211_DPRINTF(ic, 1432 1.40 dyoung IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH, 1433 1.40 dyoung "[%s] shared key auth failed (reason %d)\n", 1434 1.85 christos ether_snprintf(ebuf, sizeof(ebuf), 1435 1.85 christos ieee80211_getbssid(ic, wh)), 1436 1.40 dyoung status); 1437 1.109 maxv 1438 1.40 dyoung /* XXX can this happen? */ 1439 1.40 dyoung if (ni != ic->ic_bss) 1440 1.40 dyoung ni->ni_fails++; 1441 1.109 maxv 1442 1.40 dyoung ic->ic_stats.is_rx_auth_fail++; 1443 1.7 dyoung return; 1444 1.7 dyoung } 1445 1.109 maxv 1446 1.40 dyoung ieee80211_new_state(ic, IEEE80211_S_ASSOC, 1447 1.40 dyoung wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 1448 1.40 dyoung break; 1449 1.109 maxv 1450 1.40 dyoung case IEEE80211_AUTH_SHARED_CHALLENGE: 1451 1.40 dyoung if (!alloc_challenge(ic, ni)) 1452 1.40 dyoung return; 1453 1.40 dyoung /* XXX could optimize by passing recvd challenge */ 1454 1.40 dyoung memcpy(ni->ni_challenge, &challenge[2], challenge[1]); 1455 1.109 maxv 1456 1.109 maxv IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_AUTH, 1457 1.109 maxv seq + 1); 1458 1.40 dyoung break; 1459 1.109 maxv 1460 1.40 dyoung default: 1461 1.40 dyoung IEEE80211_DISCARD(ic, IEEE80211_MSG_AUTH, 1462 1.40 dyoung wh, "shared key auth", "bad seq %d", seq); 1463 1.40 dyoung ic->ic_stats.is_rx_bad_auth++; 1464 1.40 dyoung return; 1465 1.40 dyoung } 1466 1.40 dyoung break; 1467 1.40 dyoung } 1468 1.40 dyoung return; 1469 1.109 maxv 1470 1.40 dyoung bad: 1471 1.41 dyoung #ifndef IEEE80211_NO_HOSTAP 1472 1.40 dyoung /* 1473 1.40 dyoung * Send an error response; but only when operating as an AP. 1474 1.40 dyoung */ 1475 1.40 dyoung if (ic->ic_opmode == IEEE80211_M_HOSTAP) { 1476 1.40 dyoung /* XXX hack to workaround calling convention */ 1477 1.44 dyoung ieee80211_send_error(ic, ni, wh->i_addr2, 1478 1.44 dyoung IEEE80211_FC0_SUBTYPE_AUTH, 1479 1.44 dyoung (seq + 1) | (estatus<<16)); 1480 1.44 dyoung } else if (ic->ic_opmode == IEEE80211_M_STA) { 1481 1.44 dyoung /* 1482 1.44 dyoung * Kick the state machine. This short-circuits 1483 1.44 dyoung * using the mgt frame timeout to trigger the 1484 1.44 dyoung * state transition. 1485 1.44 dyoung */ 1486 1.44 dyoung if (ic->ic_state == IEEE80211_S_AUTH) 1487 1.44 dyoung ieee80211_new_state(ic, IEEE80211_S_SCAN, 0); 1488 1.40 dyoung } 1489 1.41 dyoung #else 1490 1.41 dyoung ; 1491 1.41 dyoung #endif /* !IEEE80211_NO_HOSTAP */ 1492 1.40 dyoung } 1493 1.40 dyoung 1494 1.40 dyoung #ifdef IEEE80211_DEBUG 1495 1.40 dyoung static void 1496 1.64 christos ieee80211_ssid_mismatch(struct ieee80211com *ic, const char *tag, 1497 1.40 dyoung u_int8_t mac[IEEE80211_ADDR_LEN], u_int8_t *ssid) 1498 1.40 dyoung { 1499 1.85 christos char ebuf[3 * ETHER_ADDR_LEN]; 1500 1.85 christos 1501 1.40 dyoung printf("[%s] discard %s frame, ssid mismatch: ", 1502 1.85 christos ether_snprintf(ebuf, sizeof(ebuf), mac), tag); 1503 1.40 dyoung ieee80211_print_essid(ssid + 2, ssid[1]); 1504 1.40 dyoung printf("\n"); 1505 1.40 dyoung } 1506 1.40 dyoung 1507 1.40 dyoung #define IEEE80211_VERIFY_SSID(_ni, _ssid) do { \ 1508 1.40 dyoung if ((_ssid)[1] != 0 && \ 1509 1.40 dyoung ((_ssid)[1] != (_ni)->ni_esslen || \ 1510 1.40 dyoung memcmp((_ssid) + 2, (_ni)->ni_essid, (_ssid)[1]) != 0)) { \ 1511 1.40 dyoung if (ieee80211_msg_input(ic)) \ 1512 1.40 dyoung ieee80211_ssid_mismatch(ic, \ 1513 1.40 dyoung ieee80211_mgt_subtype_name[subtype >> \ 1514 1.40 dyoung IEEE80211_FC0_SUBTYPE_SHIFT], \ 1515 1.40 dyoung wh->i_addr2, _ssid); \ 1516 1.40 dyoung ic->ic_stats.is_rx_ssidmismatch++; \ 1517 1.40 dyoung return; \ 1518 1.40 dyoung } \ 1519 1.40 dyoung } while (0) 1520 1.40 dyoung #else /* !IEEE80211_DEBUG */ 1521 1.40 dyoung #define IEEE80211_VERIFY_SSID(_ni, _ssid) do { \ 1522 1.40 dyoung if ((_ssid)[1] != 0 && \ 1523 1.40 dyoung ((_ssid)[1] != (_ni)->ni_esslen || \ 1524 1.40 dyoung memcmp((_ssid) + 2, (_ni)->ni_essid, (_ssid)[1]) != 0)) { \ 1525 1.40 dyoung ic->ic_stats.is_rx_ssidmismatch++; \ 1526 1.40 dyoung return; \ 1527 1.40 dyoung } \ 1528 1.40 dyoung } while (0) 1529 1.40 dyoung #endif /* !IEEE80211_DEBUG */ 1530 1.40 dyoung 1531 1.76 christos /* unaligned little endian access */ 1532 1.40 dyoung #define LE_READ_2(p) \ 1533 1.40 dyoung ((u_int16_t) \ 1534 1.40 dyoung ((((const u_int8_t *)(p))[0] ) | \ 1535 1.40 dyoung (((const u_int8_t *)(p))[1] << 8))) 1536 1.40 dyoung #define LE_READ_4(p) \ 1537 1.40 dyoung ((u_int32_t) \ 1538 1.40 dyoung ((((const u_int8_t *)(p))[0] ) | \ 1539 1.40 dyoung (((const u_int8_t *)(p))[1] << 8) | \ 1540 1.40 dyoung (((const u_int8_t *)(p))[2] << 16) | \ 1541 1.40 dyoung (((const u_int8_t *)(p))[3] << 24))) 1542 1.40 dyoung 1543 1.62 christos static __inline int 1544 1.40 dyoung iswpaoui(const u_int8_t *frm) 1545 1.40 dyoung { 1546 1.40 dyoung return frm[1] > 3 && LE_READ_4(frm+2) == ((WPA_OUI_TYPE<<24)|WPA_OUI); 1547 1.40 dyoung } 1548 1.40 dyoung 1549 1.62 christos static __inline int 1550 1.40 dyoung iswmeoui(const u_int8_t *frm) 1551 1.40 dyoung { 1552 1.40 dyoung return frm[1] > 3 && LE_READ_4(frm+2) == ((WME_OUI_TYPE<<24)|WME_OUI); 1553 1.40 dyoung } 1554 1.40 dyoung 1555 1.62 christos static __inline int 1556 1.40 dyoung iswmeparam(const u_int8_t *frm) 1557 1.40 dyoung { 1558 1.40 dyoung return frm[1] > 5 && LE_READ_4(frm+2) == ((WME_OUI_TYPE<<24)|WME_OUI) && 1559 1.40 dyoung frm[6] == WME_PARAM_OUI_SUBTYPE; 1560 1.40 dyoung } 1561 1.40 dyoung 1562 1.62 christos static __inline int 1563 1.40 dyoung iswmeinfo(const u_int8_t *frm) 1564 1.40 dyoung { 1565 1.40 dyoung return frm[1] > 5 && LE_READ_4(frm+2) == ((WME_OUI_TYPE<<24)|WME_OUI) && 1566 1.40 dyoung frm[6] == WME_INFO_OUI_SUBTYPE; 1567 1.40 dyoung } 1568 1.40 dyoung 1569 1.40 dyoung /* 1570 1.40 dyoung * Convert a WPA cipher selector OUI to an internal 1571 1.40 dyoung * cipher algorithm. Where appropriate we also 1572 1.40 dyoung * record any key length. 1573 1.40 dyoung */ 1574 1.40 dyoung static int 1575 1.40 dyoung wpa_cipher(u_int8_t *sel, u_int8_t *keylen) 1576 1.40 dyoung { 1577 1.40 dyoung #define WPA_SEL(x) (((x)<<24)|WPA_OUI) 1578 1.40 dyoung u_int32_t w = LE_READ_4(sel); 1579 1.40 dyoung 1580 1.40 dyoung switch (w) { 1581 1.40 dyoung case WPA_SEL(WPA_CSE_NULL): 1582 1.40 dyoung return IEEE80211_CIPHER_NONE; 1583 1.40 dyoung case WPA_SEL(WPA_CSE_WEP40): 1584 1.40 dyoung if (keylen) 1585 1.40 dyoung *keylen = 40 / NBBY; 1586 1.40 dyoung return IEEE80211_CIPHER_WEP; 1587 1.40 dyoung case WPA_SEL(WPA_CSE_WEP104): 1588 1.40 dyoung if (keylen) 1589 1.40 dyoung *keylen = 104 / NBBY; 1590 1.40 dyoung return IEEE80211_CIPHER_WEP; 1591 1.40 dyoung case WPA_SEL(WPA_CSE_TKIP): 1592 1.40 dyoung return IEEE80211_CIPHER_TKIP; 1593 1.40 dyoung case WPA_SEL(WPA_CSE_CCMP): 1594 1.40 dyoung return IEEE80211_CIPHER_AES_CCM; 1595 1.40 dyoung } 1596 1.40 dyoung return 32; /* NB: so 1<< is discarded */ 1597 1.40 dyoung #undef WPA_SEL 1598 1.40 dyoung } 1599 1.40 dyoung 1600 1.40 dyoung /* 1601 1.40 dyoung * Convert a WPA key management/authentication algorithm 1602 1.40 dyoung * to an internal code. 1603 1.40 dyoung */ 1604 1.40 dyoung static int 1605 1.40 dyoung wpa_keymgmt(u_int8_t *sel) 1606 1.40 dyoung { 1607 1.40 dyoung #define WPA_SEL(x) (((x)<<24)|WPA_OUI) 1608 1.40 dyoung u_int32_t w = LE_READ_4(sel); 1609 1.40 dyoung 1610 1.40 dyoung switch (w) { 1611 1.40 dyoung case WPA_SEL(WPA_ASE_8021X_UNSPEC): 1612 1.40 dyoung return WPA_ASE_8021X_UNSPEC; 1613 1.40 dyoung case WPA_SEL(WPA_ASE_8021X_PSK): 1614 1.40 dyoung return WPA_ASE_8021X_PSK; 1615 1.40 dyoung case WPA_SEL(WPA_ASE_NONE): 1616 1.40 dyoung return WPA_ASE_NONE; 1617 1.40 dyoung } 1618 1.40 dyoung return 0; /* NB: so is discarded */ 1619 1.40 dyoung #undef WPA_SEL 1620 1.40 dyoung } 1621 1.40 dyoung 1622 1.40 dyoung /* 1623 1.40 dyoung * Parse a WPA information element to collect parameters 1624 1.40 dyoung * and validate the parameters against what has been 1625 1.40 dyoung * configured for the system. 1626 1.40 dyoung */ 1627 1.40 dyoung static int 1628 1.40 dyoung ieee80211_parse_wpa(struct ieee80211com *ic, u_int8_t *frm, 1629 1.109 maxv struct ieee80211_rsnparms *rsn, const struct ieee80211_frame *wh) 1630 1.40 dyoung { 1631 1.40 dyoung u_int8_t len = frm[1]; 1632 1.40 dyoung u_int32_t w; 1633 1.40 dyoung int n; 1634 1.40 dyoung 1635 1.47 skrll if ((ic->ic_flags & IEEE80211_F_WPA1) == 0) { 1636 1.47 skrll IEEE80211_DISCARD_IE(ic, 1637 1.47 skrll IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1638 1.47 skrll wh, "WPA", "not WPA, flags 0x%x", ic->ic_flags); 1639 1.47 skrll return IEEE80211_REASON_IE_INVALID; 1640 1.47 skrll } 1641 1.109 maxv 1642 1.109 maxv /* 1643 1.109 maxv * Check the length once for fixed parts: OUI, type, 1644 1.109 maxv * version, mcast cipher, and 2 selector counts. 1645 1.109 maxv * Other, variable-length data, must be checked separately. 1646 1.109 maxv */ 1647 1.40 dyoung if (len < 14) { 1648 1.40 dyoung IEEE80211_DISCARD_IE(ic, 1649 1.40 dyoung IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1650 1.40 dyoung wh, "WPA", "too short, len %u", len); 1651 1.40 dyoung return IEEE80211_REASON_IE_INVALID; 1652 1.40 dyoung } 1653 1.109 maxv 1654 1.109 maxv frm += 2; /* beginning of payload */ 1655 1.109 maxv frm += 4, len -= 4; 1656 1.109 maxv 1657 1.40 dyoung /* NB: iswapoui already validated the OUI and type */ 1658 1.40 dyoung w = LE_READ_2(frm); 1659 1.40 dyoung if (w != WPA_VERSION) { 1660 1.40 dyoung IEEE80211_DISCARD_IE(ic, 1661 1.40 dyoung IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1662 1.40 dyoung wh, "WPA", "bad version %u", w); 1663 1.40 dyoung return IEEE80211_REASON_IE_INVALID; 1664 1.40 dyoung } 1665 1.40 dyoung frm += 2, len -= 2; 1666 1.40 dyoung 1667 1.40 dyoung /* multicast/group cipher */ 1668 1.40 dyoung w = wpa_cipher(frm, &rsn->rsn_mcastkeylen); 1669 1.40 dyoung if (w != rsn->rsn_mcastcipher) { 1670 1.40 dyoung IEEE80211_DISCARD_IE(ic, 1671 1.40 dyoung IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1672 1.40 dyoung wh, "WPA", "mcast cipher mismatch; got %u, expected %u", 1673 1.40 dyoung w, rsn->rsn_mcastcipher); 1674 1.40 dyoung return IEEE80211_REASON_IE_INVALID; 1675 1.40 dyoung } 1676 1.40 dyoung frm += 4, len -= 4; 1677 1.40 dyoung 1678 1.40 dyoung /* unicast ciphers */ 1679 1.40 dyoung n = LE_READ_2(frm); 1680 1.40 dyoung frm += 2, len -= 2; 1681 1.40 dyoung if (len < n*4+2) { 1682 1.40 dyoung IEEE80211_DISCARD_IE(ic, 1683 1.40 dyoung IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1684 1.40 dyoung wh, "WPA", "ucast cipher data too short; len %u, n %u", 1685 1.40 dyoung len, n); 1686 1.40 dyoung return IEEE80211_REASON_IE_INVALID; 1687 1.40 dyoung } 1688 1.40 dyoung w = 0; 1689 1.40 dyoung for (; n > 0; n--) { 1690 1.109 maxv w |= 1 << wpa_cipher(frm, &rsn->rsn_ucastkeylen); 1691 1.40 dyoung frm += 4, len -= 4; 1692 1.40 dyoung } 1693 1.40 dyoung w &= rsn->rsn_ucastcipherset; 1694 1.40 dyoung if (w == 0) { 1695 1.40 dyoung IEEE80211_DISCARD_IE(ic, 1696 1.40 dyoung IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1697 1.40 dyoung wh, "WPA", "%s", "ucast cipher set empty"); 1698 1.40 dyoung return IEEE80211_REASON_IE_INVALID; 1699 1.40 dyoung } 1700 1.109 maxv if (w & (1 << IEEE80211_CIPHER_TKIP)) 1701 1.40 dyoung rsn->rsn_ucastcipher = IEEE80211_CIPHER_TKIP; 1702 1.40 dyoung else 1703 1.40 dyoung rsn->rsn_ucastcipher = IEEE80211_CIPHER_AES_CCM; 1704 1.40 dyoung 1705 1.40 dyoung /* key management algorithms */ 1706 1.40 dyoung n = LE_READ_2(frm); 1707 1.40 dyoung frm += 2, len -= 2; 1708 1.40 dyoung if (len < n*4) { 1709 1.40 dyoung IEEE80211_DISCARD_IE(ic, 1710 1.40 dyoung IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1711 1.40 dyoung wh, "WPA", "key mgmt alg data too short; len %u, n %u", 1712 1.40 dyoung len, n); 1713 1.40 dyoung return IEEE80211_REASON_IE_INVALID; 1714 1.40 dyoung } 1715 1.40 dyoung w = 0; 1716 1.40 dyoung for (; n > 0; n--) { 1717 1.40 dyoung w |= wpa_keymgmt(frm); 1718 1.40 dyoung frm += 4, len -= 4; 1719 1.40 dyoung } 1720 1.40 dyoung w &= rsn->rsn_keymgmtset; 1721 1.40 dyoung if (w == 0) { 1722 1.40 dyoung IEEE80211_DISCARD_IE(ic, 1723 1.40 dyoung IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1724 1.40 dyoung wh, "WPA", "%s", "no acceptable key mgmt alg"); 1725 1.40 dyoung return IEEE80211_REASON_IE_INVALID; 1726 1.40 dyoung } 1727 1.40 dyoung if (w & WPA_ASE_8021X_UNSPEC) 1728 1.40 dyoung rsn->rsn_keymgmt = WPA_ASE_8021X_UNSPEC; 1729 1.40 dyoung else 1730 1.40 dyoung rsn->rsn_keymgmt = WPA_ASE_8021X_PSK; 1731 1.40 dyoung 1732 1.40 dyoung if (len > 2) /* optional capabilities */ 1733 1.40 dyoung rsn->rsn_caps = LE_READ_2(frm); 1734 1.40 dyoung 1735 1.40 dyoung return 0; 1736 1.40 dyoung } 1737 1.40 dyoung 1738 1.40 dyoung /* 1739 1.40 dyoung * Convert an RSN cipher selector OUI to an internal 1740 1.40 dyoung * cipher algorithm. Where appropriate we also 1741 1.40 dyoung * record any key length. 1742 1.40 dyoung */ 1743 1.40 dyoung static int 1744 1.40 dyoung rsn_cipher(u_int8_t *sel, u_int8_t *keylen) 1745 1.40 dyoung { 1746 1.40 dyoung #define RSN_SEL(x) (((x)<<24)|RSN_OUI) 1747 1.40 dyoung u_int32_t w = LE_READ_4(sel); 1748 1.40 dyoung 1749 1.40 dyoung switch (w) { 1750 1.40 dyoung case RSN_SEL(RSN_CSE_NULL): 1751 1.40 dyoung return IEEE80211_CIPHER_NONE; 1752 1.40 dyoung case RSN_SEL(RSN_CSE_WEP40): 1753 1.40 dyoung if (keylen) 1754 1.40 dyoung *keylen = 40 / NBBY; 1755 1.40 dyoung return IEEE80211_CIPHER_WEP; 1756 1.40 dyoung case RSN_SEL(RSN_CSE_WEP104): 1757 1.40 dyoung if (keylen) 1758 1.40 dyoung *keylen = 104 / NBBY; 1759 1.40 dyoung return IEEE80211_CIPHER_WEP; 1760 1.40 dyoung case RSN_SEL(RSN_CSE_TKIP): 1761 1.40 dyoung return IEEE80211_CIPHER_TKIP; 1762 1.40 dyoung case RSN_SEL(RSN_CSE_CCMP): 1763 1.40 dyoung return IEEE80211_CIPHER_AES_CCM; 1764 1.40 dyoung case RSN_SEL(RSN_CSE_WRAP): 1765 1.40 dyoung return IEEE80211_CIPHER_AES_OCB; 1766 1.40 dyoung } 1767 1.40 dyoung return 32; /* NB: so 1<< is discarded */ 1768 1.40 dyoung #undef WPA_SEL 1769 1.40 dyoung } 1770 1.40 dyoung 1771 1.40 dyoung /* 1772 1.40 dyoung * Convert an RSN key management/authentication algorithm 1773 1.40 dyoung * to an internal code. 1774 1.40 dyoung */ 1775 1.40 dyoung static int 1776 1.40 dyoung rsn_keymgmt(u_int8_t *sel) 1777 1.40 dyoung { 1778 1.40 dyoung #define RSN_SEL(x) (((x)<<24)|RSN_OUI) 1779 1.40 dyoung u_int32_t w = LE_READ_4(sel); 1780 1.40 dyoung 1781 1.40 dyoung switch (w) { 1782 1.40 dyoung case RSN_SEL(RSN_ASE_8021X_UNSPEC): 1783 1.40 dyoung return RSN_ASE_8021X_UNSPEC; 1784 1.40 dyoung case RSN_SEL(RSN_ASE_8021X_PSK): 1785 1.40 dyoung return RSN_ASE_8021X_PSK; 1786 1.40 dyoung case RSN_SEL(RSN_ASE_NONE): 1787 1.40 dyoung return RSN_ASE_NONE; 1788 1.40 dyoung } 1789 1.40 dyoung return 0; /* NB: so is discarded */ 1790 1.40 dyoung #undef RSN_SEL 1791 1.40 dyoung } 1792 1.40 dyoung 1793 1.40 dyoung /* 1794 1.40 dyoung * Parse a WPA/RSN information element to collect parameters 1795 1.40 dyoung * and validate the parameters against what has been 1796 1.40 dyoung * configured for the system. 1797 1.40 dyoung */ 1798 1.40 dyoung static int 1799 1.40 dyoung ieee80211_parse_rsn(struct ieee80211com *ic, u_int8_t *frm, 1800 1.109 maxv struct ieee80211_rsnparms *rsn, const struct ieee80211_frame *wh) 1801 1.40 dyoung { 1802 1.40 dyoung u_int8_t len = frm[1]; 1803 1.40 dyoung u_int32_t w; 1804 1.40 dyoung int n; 1805 1.40 dyoung 1806 1.47 skrll if ((ic->ic_flags & IEEE80211_F_WPA2) == 0) { 1807 1.47 skrll IEEE80211_DISCARD_IE(ic, 1808 1.47 skrll IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1809 1.47 skrll wh, "WPA", "not RSN, flags 0x%x", ic->ic_flags); 1810 1.47 skrll return IEEE80211_REASON_IE_INVALID; 1811 1.47 skrll } 1812 1.109 maxv 1813 1.109 maxv /* 1814 1.109 maxv * Check the length once for fixed parts: 1815 1.109 maxv * version, mcast cipher, and 2 selector counts. 1816 1.109 maxv * Other, variable-length data, must be checked separately. 1817 1.109 maxv */ 1818 1.40 dyoung if (len < 10) { 1819 1.40 dyoung IEEE80211_DISCARD_IE(ic, 1820 1.40 dyoung IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1821 1.40 dyoung wh, "RSN", "too short, len %u", len); 1822 1.40 dyoung return IEEE80211_REASON_IE_INVALID; 1823 1.40 dyoung } 1824 1.109 maxv 1825 1.109 maxv frm += 2; /* beginning of payload */ 1826 1.40 dyoung w = LE_READ_2(frm); 1827 1.40 dyoung if (w != RSN_VERSION) { 1828 1.40 dyoung IEEE80211_DISCARD_IE(ic, 1829 1.40 dyoung IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1830 1.40 dyoung wh, "RSN", "bad version %u", w); 1831 1.40 dyoung return IEEE80211_REASON_IE_INVALID; 1832 1.40 dyoung } 1833 1.40 dyoung frm += 2, len -= 2; 1834 1.40 dyoung 1835 1.40 dyoung /* multicast/group cipher */ 1836 1.40 dyoung w = rsn_cipher(frm, &rsn->rsn_mcastkeylen); 1837 1.40 dyoung if (w != rsn->rsn_mcastcipher) { 1838 1.40 dyoung IEEE80211_DISCARD_IE(ic, 1839 1.40 dyoung IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1840 1.40 dyoung wh, "RSN", "mcast cipher mismatch; got %u, expected %u", 1841 1.40 dyoung w, rsn->rsn_mcastcipher); 1842 1.40 dyoung return IEEE80211_REASON_IE_INVALID; 1843 1.40 dyoung } 1844 1.40 dyoung frm += 4, len -= 4; 1845 1.40 dyoung 1846 1.40 dyoung /* unicast ciphers */ 1847 1.40 dyoung n = LE_READ_2(frm); 1848 1.40 dyoung frm += 2, len -= 2; 1849 1.40 dyoung if (len < n*4+2) { 1850 1.40 dyoung IEEE80211_DISCARD_IE(ic, 1851 1.40 dyoung IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1852 1.40 dyoung wh, "RSN", "ucast cipher data too short; len %u, n %u", 1853 1.40 dyoung len, n); 1854 1.40 dyoung return IEEE80211_REASON_IE_INVALID; 1855 1.40 dyoung } 1856 1.40 dyoung w = 0; 1857 1.40 dyoung for (; n > 0; n--) { 1858 1.109 maxv w |= 1 << rsn_cipher(frm, &rsn->rsn_ucastkeylen); 1859 1.40 dyoung frm += 4, len -= 4; 1860 1.40 dyoung } 1861 1.40 dyoung w &= rsn->rsn_ucastcipherset; 1862 1.40 dyoung if (w == 0) { 1863 1.40 dyoung IEEE80211_DISCARD_IE(ic, 1864 1.40 dyoung IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1865 1.40 dyoung wh, "RSN", "%s", "ucast cipher set empty"); 1866 1.40 dyoung return IEEE80211_REASON_IE_INVALID; 1867 1.40 dyoung } 1868 1.109 maxv if (w & (1 << IEEE80211_CIPHER_TKIP)) 1869 1.40 dyoung rsn->rsn_ucastcipher = IEEE80211_CIPHER_TKIP; 1870 1.40 dyoung else 1871 1.40 dyoung rsn->rsn_ucastcipher = IEEE80211_CIPHER_AES_CCM; 1872 1.40 dyoung 1873 1.40 dyoung /* key management algorithms */ 1874 1.40 dyoung n = LE_READ_2(frm); 1875 1.40 dyoung frm += 2, len -= 2; 1876 1.40 dyoung if (len < n*4) { 1877 1.74 christos IEEE80211_DISCARD_IE(ic, 1878 1.40 dyoung IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1879 1.40 dyoung wh, "RSN", "key mgmt alg data too short; len %u, n %u", 1880 1.40 dyoung len, n); 1881 1.40 dyoung return IEEE80211_REASON_IE_INVALID; 1882 1.40 dyoung } 1883 1.40 dyoung w = 0; 1884 1.40 dyoung for (; n > 0; n--) { 1885 1.40 dyoung w |= rsn_keymgmt(frm); 1886 1.40 dyoung frm += 4, len -= 4; 1887 1.40 dyoung } 1888 1.40 dyoung w &= rsn->rsn_keymgmtset; 1889 1.40 dyoung if (w == 0) { 1890 1.40 dyoung IEEE80211_DISCARD_IE(ic, 1891 1.40 dyoung IEEE80211_MSG_ELEMID | IEEE80211_MSG_WPA, 1892 1.40 dyoung wh, "RSN", "%s", "no acceptable key mgmt alg"); 1893 1.40 dyoung return IEEE80211_REASON_IE_INVALID; 1894 1.40 dyoung } 1895 1.40 dyoung if (w & RSN_ASE_8021X_UNSPEC) 1896 1.40 dyoung rsn->rsn_keymgmt = RSN_ASE_8021X_UNSPEC; 1897 1.40 dyoung else 1898 1.40 dyoung rsn->rsn_keymgmt = RSN_ASE_8021X_PSK; 1899 1.40 dyoung 1900 1.40 dyoung /* optional RSN capabilities */ 1901 1.40 dyoung if (len > 2) 1902 1.40 dyoung rsn->rsn_caps = LE_READ_2(frm); 1903 1.40 dyoung /* XXXPMKID */ 1904 1.40 dyoung 1905 1.40 dyoung return 0; 1906 1.40 dyoung } 1907 1.40 dyoung 1908 1.40 dyoung static int 1909 1.40 dyoung ieee80211_parse_wmeparams(struct ieee80211com *ic, u_int8_t *frm, 1910 1.109 maxv const struct ieee80211_frame *wh) 1911 1.40 dyoung { 1912 1.40 dyoung #define MS(_v, _f) (((_v) & _f) >> _f##_S) 1913 1.40 dyoung struct ieee80211_wme_state *wme = &ic->ic_wme; 1914 1.40 dyoung u_int len = frm[1], qosinfo; 1915 1.40 dyoung int i; 1916 1.40 dyoung 1917 1.40 dyoung if (len < sizeof(struct ieee80211_wme_param)-2) { 1918 1.40 dyoung IEEE80211_DISCARD_IE(ic, 1919 1.40 dyoung IEEE80211_MSG_ELEMID | IEEE80211_MSG_WME, 1920 1.40 dyoung wh, "WME", "too short, len %u", len); 1921 1.40 dyoung return -1; 1922 1.40 dyoung } 1923 1.108 maxv 1924 1.72 christos qosinfo = frm[offsetof(struct ieee80211_wme_param, param_qosInfo)]; 1925 1.40 dyoung qosinfo &= WME_QOSINFO_COUNT; 1926 1.108 maxv 1927 1.40 dyoung /* XXX do proper check for wraparound */ 1928 1.40 dyoung if (qosinfo == wme->wme_wmeChanParams.cap_info) 1929 1.40 dyoung return 0; 1930 1.108 maxv 1931 1.72 christos frm += offsetof(struct ieee80211_wme_param, params_acParams); 1932 1.40 dyoung for (i = 0; i < WME_NUM_AC; i++) { 1933 1.40 dyoung struct wmeParams *wmep = 1934 1.40 dyoung &wme->wme_wmeChanParams.cap_wmeParams[i]; 1935 1.40 dyoung /* NB: ACI not used */ 1936 1.40 dyoung wmep->wmep_acm = MS(frm[0], WME_PARAM_ACM); 1937 1.40 dyoung wmep->wmep_aifsn = MS(frm[0], WME_PARAM_AIFSN); 1938 1.40 dyoung wmep->wmep_logcwmin = MS(frm[1], WME_PARAM_LOGCWMIN); 1939 1.40 dyoung wmep->wmep_logcwmax = MS(frm[1], WME_PARAM_LOGCWMAX); 1940 1.40 dyoung wmep->wmep_txopLimit = LE_READ_2(frm+2); 1941 1.40 dyoung frm += 4; 1942 1.40 dyoung } 1943 1.108 maxv 1944 1.40 dyoung wme->wme_wmeChanParams.cap_info = qosinfo; 1945 1.40 dyoung return 1; 1946 1.40 dyoung #undef MS 1947 1.40 dyoung } 1948 1.40 dyoung 1949 1.47 skrll void 1950 1.40 dyoung ieee80211_saveie(u_int8_t **iep, const u_int8_t *ie) 1951 1.40 dyoung { 1952 1.40 dyoung u_int ielen = ie[1]+2; 1953 1.109 maxv 1954 1.109 maxv /* Record information element for later use. */ 1955 1.40 dyoung if (*iep == NULL || (*iep)[1] != ie[1]) { 1956 1.40 dyoung if (*iep != NULL) 1957 1.67 cegger free(*iep, M_DEVBUF); 1958 1.58 christos *iep = malloc(ielen, M_DEVBUF, M_NOWAIT); 1959 1.40 dyoung } 1960 1.40 dyoung if (*iep != NULL) 1961 1.40 dyoung memcpy(*iep, ie, ielen); 1962 1.40 dyoung /* XXX note failure */ 1963 1.40 dyoung } 1964 1.40 dyoung 1965 1.56 dyoung static void 1966 1.56 dyoung ieee80211_update_adhoc_node(struct ieee80211com *ic, struct ieee80211_node *ni, 1967 1.56 dyoung struct ieee80211_frame *wh, struct ieee80211_scanparams *scan, int rssi, 1968 1.56 dyoung u_int32_t rstamp) 1969 1.56 dyoung { 1970 1.56 dyoung if (!IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) { 1971 1.56 dyoung /* 1972 1.56 dyoung * Create a new entry in the neighbor table. 1973 1.56 dyoung * Records the TSF. 1974 1.56 dyoung */ 1975 1.56 dyoung if ((ni = ieee80211_add_neighbor(ic, wh, scan)) == NULL) 1976 1.56 dyoung return; 1977 1.56 dyoung } else if (ni->ni_capinfo == 0) { 1978 1.56 dyoung /* 1979 1.56 dyoung * Initialize a node that was "faked up." Records 1980 1.56 dyoung * the TSF. 1981 1.56 dyoung * 1982 1.56 dyoung * No need to check for a change of BSSID: ni could 1983 1.56 dyoung * not have been the IBSS (ic_bss) 1984 1.56 dyoung */ 1985 1.56 dyoung ieee80211_init_neighbor(ic, ni, wh, scan, 0); 1986 1.56 dyoung } else { 1987 1.56 dyoung /* Record TSF for potential resync. */ 1988 1.107 maxv memcpy(ni->ni_tstamp.data, scan->sp_tstamp, sizeof(ni->ni_tstamp)); 1989 1.56 dyoung } 1990 1.56 dyoung 1991 1.56 dyoung ni->ni_rssi = rssi; 1992 1.56 dyoung ni->ni_rstamp = rstamp; 1993 1.56 dyoung 1994 1.56 dyoung /* Mark a neighbor's change of BSSID. */ 1995 1.56 dyoung if (IEEE80211_ADDR_EQ(wh->i_addr3, ni->ni_bssid)) 1996 1.56 dyoung return; 1997 1.56 dyoung 1998 1.56 dyoung IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3); 1999 1.56 dyoung 2000 1.56 dyoung if (ni != ic->ic_bss) 2001 1.56 dyoung return; 2002 1.56 dyoung else if (ic->ic_flags & IEEE80211_F_DESBSSID) { 2003 1.56 dyoung /* 2004 1.56 dyoung * Now, ni does not represent a network we 2005 1.56 dyoung * want to belong to, so start a scan. 2006 1.56 dyoung */ 2007 1.56 dyoung ieee80211_new_state(ic, IEEE80211_S_SCAN, 0); 2008 1.56 dyoung return; 2009 1.56 dyoung } else { 2010 1.56 dyoung /* 2011 1.56 dyoung * A RUN->RUN transition lets the driver 2012 1.56 dyoung * reprogram its BSSID filter. 2013 1.56 dyoung * 2014 1.56 dyoung * No need to SCAN, we already belong to 2015 1.56 dyoung * an IBSS that meets our criteria: channel, 2016 1.56 dyoung * SSID, etc. It could be harmful to scan, 2017 1.56 dyoung * too: if a scan does not detect nodes 2018 1.56 dyoung * belonging to my current IBSS, then we 2019 1.56 dyoung * will create a new IBSS at the end of 2020 1.56 dyoung * the scan, needlessly splitting the 2021 1.56 dyoung * network. 2022 1.56 dyoung */ 2023 1.56 dyoung ieee80211_new_state(ic, IEEE80211_S_RUN, 0); 2024 1.56 dyoung } 2025 1.56 dyoung } 2026 1.56 dyoung 2027 1.98 maxv /* -------------------------------------------------------------------------- */ 2028 1.98 maxv 2029 1.105 maxv #define IEEE80211_VERIFY_ELEMENT(__elem, __maxlen) do { \ 2030 1.105 maxv if ((__elem) == NULL) { \ 2031 1.105 maxv IEEE80211_DISCARD(ic, IEEE80211_MSG_ELEMID, \ 2032 1.105 maxv wh, ieee80211_mgt_subtype_name[subtype >> \ 2033 1.105 maxv IEEE80211_FC0_SUBTYPE_SHIFT], \ 2034 1.105 maxv "%s", "no " #__elem ); \ 2035 1.105 maxv ic->ic_stats.is_rx_elem_missing++; \ 2036 1.105 maxv return; \ 2037 1.105 maxv } \ 2038 1.105 maxv if ((__elem)[1] > (__maxlen)) { \ 2039 1.105 maxv IEEE80211_DISCARD(ic, IEEE80211_MSG_ELEMID, \ 2040 1.105 maxv wh, ieee80211_mgt_subtype_name[subtype >> \ 2041 1.105 maxv IEEE80211_FC0_SUBTYPE_SHIFT], \ 2042 1.105 maxv "bad " #__elem " len %d", (__elem)[1]); \ 2043 1.105 maxv ic->ic_stats.is_rx_elem_toobig++; \ 2044 1.105 maxv return; \ 2045 1.105 maxv } \ 2046 1.105 maxv } while (0) 2047 1.105 maxv 2048 1.105 maxv #define IEEE80211_VERIFY_LENGTH(_len, _minlen) do { \ 2049 1.109 maxv if ((size_t)(_len) < (size_t)(_minlen)) { \ 2050 1.105 maxv IEEE80211_DISCARD(ic, IEEE80211_MSG_ELEMID, \ 2051 1.105 maxv wh, ieee80211_mgt_subtype_name[subtype >> \ 2052 1.105 maxv IEEE80211_FC0_SUBTYPE_SHIFT], \ 2053 1.105 maxv "%s", "ie too short"); \ 2054 1.105 maxv ic->ic_stats.is_rx_elem_toosmall++; \ 2055 1.105 maxv return; \ 2056 1.105 maxv } \ 2057 1.105 maxv } while (0) 2058 1.105 maxv 2059 1.98 maxv static void 2060 1.98 maxv ieee80211_recv_mgmt_beacon(struct ieee80211com *ic, struct mbuf *m0, 2061 1.96 maxv struct ieee80211_node *ni, int subtype, int rssi, u_int32_t rstamp) 2062 1.1 dyoung { 2063 1.1 dyoung struct ieee80211_frame *wh; 2064 1.1 dyoung u_int8_t *frm, *efrm; 2065 1.85 christos IEEE80211_DEBUGVAR(char ebuf[3 * ETHER_ADDR_LEN]); 2066 1.98 maxv struct ieee80211_scanparams scan; 2067 1.1 dyoung 2068 1.1 dyoung wh = mtod(m0, struct ieee80211_frame *); 2069 1.96 maxv frm = (u_int8_t *)(wh + 1); 2070 1.1 dyoung efrm = mtod(m0, u_int8_t *) + m0->m_len; 2071 1.96 maxv 2072 1.98 maxv /* 2073 1.98 maxv * We process beacon/probe response frames: 2074 1.98 maxv * o when scanning, or 2075 1.98 maxv * o station mode when associated (to collect state 2076 1.98 maxv * updates such as 802.11g slot time), or 2077 1.98 maxv * o adhoc mode (to discover neighbors) 2078 1.98 maxv * Frames otherwise received are discarded. 2079 1.98 maxv */ 2080 1.98 maxv if (!((ic->ic_flags & IEEE80211_F_SCAN) || 2081 1.98 maxv (ic->ic_opmode == IEEE80211_M_STA && ni->ni_associd) || 2082 1.98 maxv ic->ic_opmode == IEEE80211_M_IBSS)) { 2083 1.98 maxv ic->ic_stats.is_rx_mgtdiscard++; 2084 1.98 maxv return; 2085 1.98 maxv } 2086 1.1 dyoung 2087 1.98 maxv /* 2088 1.98 maxv * beacon/probe response frame format 2089 1.98 maxv * [8] time stamp 2090 1.98 maxv * [2] beacon interval 2091 1.98 maxv * [2] capability information 2092 1.98 maxv * [tlv] ssid 2093 1.98 maxv * [tlv] supported rates 2094 1.98 maxv * [tlv] country information 2095 1.98 maxv * [tlv] parameter set (FH/DS) 2096 1.98 maxv * [tlv] erp information 2097 1.98 maxv * [tlv] extended supported rates 2098 1.98 maxv * [tlv] WME 2099 1.98 maxv * [tlv] WPA or RSN 2100 1.98 maxv */ 2101 1.98 maxv IEEE80211_VERIFY_LENGTH(efrm - frm, 12); 2102 1.98 maxv memset(&scan, 0, sizeof(scan)); 2103 1.107 maxv scan.sp_tstamp = frm; frm += 8; 2104 1.107 maxv scan.sp_bintval = le16toh(*(u_int16_t *)frm); frm += 2; 2105 1.107 maxv scan.sp_capinfo = le16toh(*(u_int16_t *)frm); frm += 2; 2106 1.107 maxv scan.sp_bchan = ieee80211_chan2ieee(ic, ic->ic_curchan); 2107 1.107 maxv scan.sp_chan = scan.sp_bchan; 2108 1.98 maxv 2109 1.98 maxv while (frm + 1 < efrm) { 2110 1.98 maxv IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2); 2111 1.98 maxv 2112 1.98 maxv switch (*frm) { 2113 1.98 maxv case IEEE80211_ELEMID_SSID: 2114 1.106 maxv /* no length check needed */ 2115 1.107 maxv scan.sp_ssid = frm; 2116 1.98 maxv break; 2117 1.98 maxv case IEEE80211_ELEMID_RATES: 2118 1.106 maxv /* no length check needed */ 2119 1.107 maxv scan.sp_rates = frm; 2120 1.98 maxv break; 2121 1.98 maxv case IEEE80211_ELEMID_COUNTRY: 2122 1.106 maxv /* XXX: we don't do anything with this? */ 2123 1.107 maxv scan.sp_country = frm; 2124 1.98 maxv break; 2125 1.98 maxv case IEEE80211_ELEMID_FHPARMS: 2126 1.98 maxv IEEE80211_VERIFY_LENGTH(frm[1], 5); 2127 1.98 maxv if (ic->ic_phytype == IEEE80211_T_FH) { 2128 1.107 maxv scan.sp_fhdwell = LE_READ_2(&frm[2]); 2129 1.107 maxv scan.sp_chan = IEEE80211_FH_CHAN(frm[4], frm[5]); 2130 1.107 maxv scan.sp_fhindex = frm[6]; 2131 1.98 maxv } 2132 1.98 maxv break; 2133 1.98 maxv case IEEE80211_ELEMID_DSPARMS: 2134 1.98 maxv /* 2135 1.98 maxv * XXX hack this since depending on phytype 2136 1.98 maxv * is problematic for multi-mode devices. 2137 1.98 maxv */ 2138 1.98 maxv IEEE80211_VERIFY_LENGTH(frm[1], 1); 2139 1.98 maxv if (ic->ic_phytype != IEEE80211_T_FH) 2140 1.107 maxv scan.sp_chan = frm[2]; 2141 1.98 maxv break; 2142 1.98 maxv case IEEE80211_ELEMID_TIM: 2143 1.98 maxv /* XXX ATIM? */ 2144 1.110 maxv IEEE80211_VERIFY_LENGTH(frm[1], 4); 2145 1.107 maxv scan.sp_tim = frm; 2146 1.107 maxv scan.sp_timoff = frm - mtod(m0, u_int8_t *); 2147 1.98 maxv break; 2148 1.98 maxv case IEEE80211_ELEMID_IBSSPARMS: 2149 1.98 maxv break; 2150 1.98 maxv case IEEE80211_ELEMID_XRATES: 2151 1.107 maxv scan.sp_xrates = frm; 2152 1.98 maxv break; 2153 1.98 maxv case IEEE80211_ELEMID_ERP: 2154 1.98 maxv if (frm[1] != 1) { 2155 1.104 maxv IEEE80211_DISCARD_IE(ic, IEEE80211_MSG_ELEMID, 2156 1.104 maxv wh, "ERP", "bad len %u", frm[1]); 2157 1.98 maxv ic->ic_stats.is_rx_elem_toobig++; 2158 1.1 dyoung break; 2159 1.98 maxv } 2160 1.107 maxv scan.sp_erp = frm[2]; 2161 1.98 maxv break; 2162 1.98 maxv case IEEE80211_ELEMID_RSN: 2163 1.106 maxv /* no length check needed */ 2164 1.107 maxv scan.sp_wpa = frm; 2165 1.98 maxv break; 2166 1.98 maxv case IEEE80211_ELEMID_VENDOR: 2167 1.106 maxv /* no length check needed */ 2168 1.98 maxv if (iswpaoui(frm)) 2169 1.107 maxv scan.sp_wpa = frm; 2170 1.98 maxv else if (iswmeparam(frm) || iswmeinfo(frm)) 2171 1.107 maxv scan.sp_wme = frm; 2172 1.98 maxv /* XXX Atheros OUI support */ 2173 1.98 maxv break; 2174 1.98 maxv default: 2175 1.98 maxv IEEE80211_DISCARD_IE(ic, IEEE80211_MSG_ELEMID, 2176 1.104 maxv wh, "unhandled", "id %u, len %u", *frm, frm[1]); 2177 1.98 maxv ic->ic_stats.is_rx_elem_unknown++; 2178 1.98 maxv break; 2179 1.98 maxv } 2180 1.96 maxv 2181 1.98 maxv frm += frm[1] + 2; 2182 1.98 maxv } 2183 1.96 maxv 2184 1.107 maxv IEEE80211_VERIFY_ELEMENT(scan.sp_rates, IEEE80211_RATE_MAXSIZE); 2185 1.107 maxv IEEE80211_VERIFY_ELEMENT(scan.sp_ssid, IEEE80211_NWID_LEN); 2186 1.96 maxv 2187 1.98 maxv if ( 2188 1.1 dyoung #if IEEE80211_CHAN_MAX < 255 2189 1.107 maxv scan.sp_chan > IEEE80211_CHAN_MAX || 2190 1.1 dyoung #endif 2191 1.107 maxv isclr(ic->ic_chan_active, scan.sp_chan)) { 2192 1.98 maxv IEEE80211_DISCARD(ic, 2193 1.98 maxv IEEE80211_MSG_ELEMID | IEEE80211_MSG_INPUT, 2194 1.98 maxv wh, ieee80211_mgt_subtype_name[subtype >> 2195 1.98 maxv IEEE80211_FC0_SUBTYPE_SHIFT], 2196 1.107 maxv "invalid channel %u", scan.sp_chan); 2197 1.98 maxv ic->ic_stats.is_rx_badchan++; 2198 1.98 maxv return; 2199 1.98 maxv } 2200 1.104 maxv 2201 1.107 maxv if (scan.sp_chan != scan.sp_bchan && 2202 1.98 maxv ic->ic_phytype != IEEE80211_T_FH) { 2203 1.98 maxv /* 2204 1.98 maxv * Frame was received on a channel different from the 2205 1.98 maxv * one indicated in the DS params element id; 2206 1.98 maxv * silently discard it. 2207 1.98 maxv * 2208 1.98 maxv * NB: this can happen due to signal leakage. 2209 1.98 maxv * But we should take it for FH phy because 2210 1.98 maxv * the rssi value should be correct even for 2211 1.98 maxv * different hop pattern in FH. 2212 1.98 maxv */ 2213 1.98 maxv IEEE80211_DISCARD(ic, 2214 1.98 maxv IEEE80211_MSG_ELEMID | IEEE80211_MSG_INPUT, 2215 1.98 maxv wh, ieee80211_mgt_subtype_name[subtype >> 2216 1.98 maxv IEEE80211_FC0_SUBTYPE_SHIFT], 2217 1.107 maxv "for off-channel %u", scan.sp_chan); 2218 1.98 maxv ic->ic_stats.is_rx_chanmismatch++; 2219 1.98 maxv return; 2220 1.98 maxv } 2221 1.104 maxv 2222 1.107 maxv if (!(IEEE80211_BINTVAL_MIN <= scan.sp_bintval && 2223 1.107 maxv scan.sp_bintval <= IEEE80211_BINTVAL_MAX)) { 2224 1.98 maxv IEEE80211_DISCARD(ic, 2225 1.98 maxv IEEE80211_MSG_ELEMID | IEEE80211_MSG_INPUT, 2226 1.98 maxv wh, ieee80211_mgt_subtype_name[subtype >> 2227 1.98 maxv IEEE80211_FC0_SUBTYPE_SHIFT], 2228 1.107 maxv "bogus beacon interval", scan.sp_bintval); 2229 1.98 maxv ic->ic_stats.is_rx_badbintval++; 2230 1.98 maxv return; 2231 1.98 maxv } 2232 1.98 maxv 2233 1.98 maxv if (ni != ic->ic_bss) { 2234 1.98 maxv ni = ieee80211_refine_node_for_beacon(ic, ni, 2235 1.107 maxv &ic->ic_channels[scan.sp_chan], scan.sp_ssid); 2236 1.98 maxv } 2237 1.104 maxv 2238 1.98 maxv /* 2239 1.98 maxv * Count frame now that we know it's to be processed. 2240 1.98 maxv */ 2241 1.98 maxv if (subtype == IEEE80211_FC0_SUBTYPE_BEACON) { 2242 1.108 maxv ic->ic_stats.is_rx_beacon++; 2243 1.98 maxv IEEE80211_NODE_STAT(ni, rx_beacons); 2244 1.104 maxv } else { 2245 1.98 maxv IEEE80211_NODE_STAT(ni, rx_proberesp); 2246 1.104 maxv } 2247 1.98 maxv 2248 1.98 maxv /* 2249 1.98 maxv * When operating in station mode, check for state updates. 2250 1.98 maxv * Be careful to ignore beacons received while doing a 2251 1.98 maxv * background scan. We consider only 11g/WMM stuff right now. 2252 1.98 maxv */ 2253 1.104 maxv if (ic->ic_opmode == IEEE80211_M_STA && ni->ni_associd != 0 && 2254 1.98 maxv ((ic->ic_flags & IEEE80211_F_SCAN) == 0 || 2255 1.98 maxv IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_bssid))) { 2256 1.98 maxv /* record tsf of last beacon */ 2257 1.107 maxv memcpy(ni->ni_tstamp.data, scan.sp_tstamp, sizeof(ni->ni_tstamp)); 2258 1.104 maxv 2259 1.107 maxv if (ni->ni_erp != scan.sp_erp) { 2260 1.98 maxv IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC, 2261 1.98 maxv "[%s] erp change: was 0x%x, now 0x%x\n", 2262 1.98 maxv ether_snprintf(ebuf, sizeof(ebuf), 2263 1.107 maxv wh->i_addr2), ni->ni_erp, scan.sp_erp); 2264 1.109 maxv 2265 1.98 maxv if (ic->ic_curmode == IEEE80211_MODE_11G && 2266 1.109 maxv (ni->ni_erp & IEEE80211_ERP_USE_PROTECTION)) { 2267 1.98 maxv ic->ic_flags |= IEEE80211_F_USEPROT; 2268 1.109 maxv } else { 2269 1.98 maxv ic->ic_flags &= ~IEEE80211_F_USEPROT; 2270 1.109 maxv } 2271 1.107 maxv ni->ni_erp = scan.sp_erp; 2272 1.1 dyoung } 2273 1.104 maxv 2274 1.107 maxv if ((ni->ni_capinfo ^ scan.sp_capinfo) & IEEE80211_CAPINFO_SHORT_SLOTTIME) { 2275 1.98 maxv IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC, 2276 1.98 maxv "[%s] capabilities change: before 0x%x," 2277 1.98 maxv " now 0x%x\n", 2278 1.98 maxv ether_snprintf(ebuf, sizeof(ebuf), 2279 1.98 maxv wh->i_addr2), 2280 1.107 maxv ni->ni_capinfo, scan.sp_capinfo); 2281 1.1 dyoung /* 2282 1.98 maxv * NB: we assume short preamble doesn't 2283 1.98 maxv * change dynamically 2284 1.1 dyoung */ 2285 1.98 maxv ieee80211_set_shortslottime(ic, 2286 1.104 maxv ic->ic_curmode == IEEE80211_MODE_11A || 2287 1.104 maxv (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME)); 2288 1.107 maxv ni->ni_capinfo = scan.sp_capinfo; 2289 1.98 maxv } 2290 1.104 maxv 2291 1.107 maxv if (scan.sp_wme != NULL && (ni->ni_flags & IEEE80211_NODE_QOS) && 2292 1.107 maxv ieee80211_parse_wmeparams(ic, scan.sp_wme, wh) > 0) { 2293 1.98 maxv ieee80211_wme_updateparams(ic); 2294 1.104 maxv } 2295 1.104 maxv 2296 1.107 maxv if (scan.sp_tim != NULL) { 2297 1.98 maxv struct ieee80211_tim_ie *ie = 2298 1.107 maxv (struct ieee80211_tim_ie *)scan.sp_tim; 2299 1.40 dyoung 2300 1.98 maxv ni->ni_dtim_count = ie->tim_count; 2301 1.98 maxv ni->ni_dtim_period = ie->tim_period; 2302 1.1 dyoung } 2303 1.104 maxv 2304 1.104 maxv if (ic->ic_flags & IEEE80211_F_SCAN) { 2305 1.104 maxv ieee80211_add_scan(ic, &scan, wh, subtype, rssi, 2306 1.104 maxv rstamp); 2307 1.104 maxv } 2308 1.104 maxv 2309 1.98 maxv ic->ic_bmiss_count = 0; 2310 1.98 maxv return; 2311 1.98 maxv } 2312 1.98 maxv 2313 1.98 maxv /* 2314 1.98 maxv * If scanning, just pass information to the scan module. 2315 1.98 maxv */ 2316 1.98 maxv if (ic->ic_flags & IEEE80211_F_SCAN) { 2317 1.98 maxv if (ic->ic_flags_ext & IEEE80211_FEXT_PROBECHAN) { 2318 1.98 maxv /* 2319 1.98 maxv * Actively scanning a channel marked passive; 2320 1.98 maxv * send a probe request now that we know there 2321 1.98 maxv * is 802.11 traffic present. 2322 1.98 maxv * 2323 1.98 maxv * XXX check if the beacon we recv'd gives 2324 1.98 maxv * us what we need and suppress the probe req 2325 1.98 maxv */ 2326 1.98 maxv ieee80211_probe_curchan(ic, 1); 2327 1.98 maxv ic->ic_flags_ext &= ~IEEE80211_FEXT_PROBECHAN; 2328 1.33 mycroft } 2329 1.104 maxv ieee80211_add_scan(ic, &scan, wh, subtype, rssi, rstamp); 2330 1.98 maxv return; 2331 1.98 maxv } 2332 1.104 maxv 2333 1.107 maxv if (scan.sp_capinfo & IEEE80211_CAPINFO_IBSS) { 2334 1.98 maxv ieee80211_update_adhoc_node(ic, ni, wh, &scan, rssi, rstamp); 2335 1.104 maxv } 2336 1.98 maxv } 2337 1.98 maxv 2338 1.98 maxv static void 2339 1.98 maxv ieee80211_recv_mgmt_probe_req(struct ieee80211com *ic, struct mbuf *m0, 2340 1.98 maxv struct ieee80211_node *ni, int subtype, int rssi, u_int32_t rstamp) 2341 1.98 maxv { 2342 1.98 maxv struct ieee80211_frame *wh; 2343 1.98 maxv u_int8_t *frm, *efrm; 2344 1.98 maxv u_int8_t *ssid, *rates, *xrates; 2345 1.109 maxv bool need_free = false; 2346 1.98 maxv u_int8_t rate; 2347 1.98 maxv IEEE80211_DEBUGVAR(char ebuf[3 * ETHER_ADDR_LEN]); 2348 1.98 maxv 2349 1.98 maxv wh = mtod(m0, struct ieee80211_frame *); 2350 1.98 maxv frm = (u_int8_t *)(wh + 1); 2351 1.98 maxv efrm = mtod(m0, u_int8_t *) + m0->m_len; 2352 1.98 maxv 2353 1.98 maxv if (ic->ic_opmode == IEEE80211_M_STA || 2354 1.98 maxv ic->ic_state != IEEE80211_S_RUN) { 2355 1.98 maxv ic->ic_stats.is_rx_mgtdiscard++; 2356 1.98 maxv return; 2357 1.98 maxv } 2358 1.98 maxv if (IEEE80211_IS_MULTICAST(wh->i_addr2)) { 2359 1.98 maxv /* frame must be directed */ 2360 1.109 maxv ic->ic_stats.is_rx_mgtdiscard++; 2361 1.98 maxv return; 2362 1.1 dyoung } 2363 1.1 dyoung 2364 1.98 maxv /* 2365 1.98 maxv * prreq frame format 2366 1.98 maxv * [tlv] ssid 2367 1.98 maxv * [tlv] supported rates 2368 1.98 maxv * [tlv] extended supported rates 2369 1.98 maxv */ 2370 1.98 maxv ssid = rates = xrates = NULL; 2371 1.109 maxv while (frm + 1 < efrm) { 2372 1.109 maxv IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2); 2373 1.109 maxv 2374 1.98 maxv switch (*frm) { 2375 1.98 maxv case IEEE80211_ELEMID_SSID: 2376 1.98 maxv ssid = frm; 2377 1.98 maxv break; 2378 1.98 maxv case IEEE80211_ELEMID_RATES: 2379 1.98 maxv rates = frm; 2380 1.98 maxv break; 2381 1.98 maxv case IEEE80211_ELEMID_XRATES: 2382 1.98 maxv xrates = frm; 2383 1.98 maxv break; 2384 1.40 dyoung } 2385 1.109 maxv 2386 1.98 maxv frm += frm[1] + 2; 2387 1.98 maxv } 2388 1.104 maxv 2389 1.98 maxv IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE); 2390 1.98 maxv IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN); 2391 1.98 maxv IEEE80211_VERIFY_SSID(ic->ic_bss, ssid); 2392 1.104 maxv 2393 1.98 maxv if ((ic->ic_flags & IEEE80211_F_HIDESSID) && ssid[1] == 0) { 2394 1.98 maxv IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT, 2395 1.98 maxv wh, ieee80211_mgt_subtype_name[subtype >> 2396 1.104 maxv IEEE80211_FC0_SUBTYPE_SHIFT], 2397 1.98 maxv "%s", "no ssid with ssid suppression enabled"); 2398 1.98 maxv ic->ic_stats.is_rx_ssidmismatch++; /*XXX*/ 2399 1.98 maxv return; 2400 1.98 maxv } 2401 1.1 dyoung 2402 1.98 maxv if (ni == ic->ic_bss) { 2403 1.104 maxv if (ic->ic_opmode != IEEE80211_M_IBSS) { 2404 1.98 maxv ni = ieee80211_tmp_node(ic, wh->i_addr2); 2405 1.109 maxv need_free = true; 2406 1.104 maxv } else if (IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) { 2407 1.98 maxv ; 2408 1.104 maxv } else { 2409 1.98 maxv /* 2410 1.98 maxv * XXX Cannot tell if the sender is operating 2411 1.98 maxv * in ibss mode. But we need a new node to 2412 1.98 maxv * send the response so blindly add them to the 2413 1.98 maxv * neighbor table. 2414 1.98 maxv */ 2415 1.98 maxv ni = ieee80211_fakeup_adhoc_node(&ic->ic_sta, 2416 1.98 maxv wh->i_addr2); 2417 1.1 dyoung } 2418 1.98 maxv if (ni == NULL) 2419 1.40 dyoung return; 2420 1.104 maxv } 2421 1.104 maxv 2422 1.104 maxv IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC, "[%s] recv probe req\n", 2423 1.104 maxv ether_snprintf(ebuf, sizeof(ebuf), wh->i_addr2)); 2424 1.104 maxv 2425 1.98 maxv ni->ni_rssi = rssi; 2426 1.98 maxv ni->ni_rstamp = rstamp; 2427 1.98 maxv rate = ieee80211_setup_rates(ni, rates, xrates, 2428 1.109 maxv IEEE80211_R_DOSORT | IEEE80211_R_DOFRATE | 2429 1.109 maxv IEEE80211_R_DONEGO | IEEE80211_R_DODEL); 2430 1.104 maxv 2431 1.98 maxv if (rate & IEEE80211_RATE_BASIC) { 2432 1.98 maxv IEEE80211_DISCARD(ic, IEEE80211_MSG_XRATE, 2433 1.98 maxv wh, ieee80211_mgt_subtype_name[subtype >> 2434 1.104 maxv IEEE80211_FC0_SUBTYPE_SHIFT], 2435 1.98 maxv "%s", "recv'd rate set invalid"); 2436 1.98 maxv } else { 2437 1.98 maxv IEEE80211_SEND_MGMT(ic, ni, 2438 1.104 maxv IEEE80211_FC0_SUBTYPE_PROBE_RESP, 0); 2439 1.98 maxv } 2440 1.104 maxv 2441 1.109 maxv if (need_free) { 2442 1.98 maxv /* reclaim immediately */ 2443 1.98 maxv ieee80211_free_node(ni); 2444 1.98 maxv } 2445 1.98 maxv } 2446 1.98 maxv 2447 1.99 maxv static void 2448 1.99 maxv ieee80211_recv_mgmt_auth(struct ieee80211com *ic, struct mbuf *m0, 2449 1.99 maxv struct ieee80211_node *ni, int subtype, int rssi, u_int32_t rstamp) 2450 1.99 maxv { 2451 1.99 maxv struct ieee80211_frame *wh; 2452 1.99 maxv u_int8_t *frm, *efrm; 2453 1.99 maxv IEEE80211_DEBUGVAR(char ebuf[3 * ETHER_ADDR_LEN]); 2454 1.104 maxv u_int16_t algo, seq, status; 2455 1.99 maxv 2456 1.99 maxv wh = mtod(m0, struct ieee80211_frame *); 2457 1.99 maxv frm = (u_int8_t *)(wh + 1); 2458 1.99 maxv efrm = mtod(m0, u_int8_t *) + m0->m_len; 2459 1.99 maxv 2460 1.99 maxv /* 2461 1.99 maxv * auth frame format 2462 1.99 maxv * [2] algorithm 2463 1.99 maxv * [2] sequence 2464 1.99 maxv * [2] status 2465 1.99 maxv * [tlv*] challenge 2466 1.99 maxv */ 2467 1.99 maxv IEEE80211_VERIFY_LENGTH(efrm - frm, 6); 2468 1.99 maxv algo = le16toh(*(u_int16_t *)frm); 2469 1.99 maxv seq = le16toh(*(u_int16_t *)(frm + 2)); 2470 1.99 maxv status = le16toh(*(u_int16_t *)(frm + 4)); 2471 1.104 maxv 2472 1.99 maxv IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH, 2473 1.99 maxv "[%s] recv auth frame with algorithm %d seq %d\n", 2474 1.99 maxv ether_snprintf(ebuf, sizeof(ebuf), wh->i_addr2), algo, seq); 2475 1.104 maxv 2476 1.99 maxv /* 2477 1.99 maxv * Consult the ACL policy module if setup. 2478 1.99 maxv */ 2479 1.104 maxv if (ic->ic_acl != NULL && !ic->ic_acl->iac_check(ic, wh->i_addr2)) { 2480 1.99 maxv IEEE80211_DISCARD(ic, IEEE80211_MSG_ACL, 2481 1.99 maxv wh, "auth", "%s", "disallowed by ACL"); 2482 1.99 maxv ic->ic_stats.is_rx_acl++; 2483 1.99 maxv if (ic->ic_opmode == IEEE80211_M_HOSTAP) { 2484 1.99 maxv IEEE80211_SEND_MGMT(ic, ni, 2485 1.99 maxv IEEE80211_FC0_SUBTYPE_AUTH, 2486 1.99 maxv (seq+1) | (IEEE80211_STATUS_UNSPECIFIED<<16)); 2487 1.99 maxv } 2488 1.99 maxv return; 2489 1.99 maxv } 2490 1.104 maxv 2491 1.99 maxv if (ic->ic_flags & IEEE80211_F_COUNTERM) { 2492 1.99 maxv IEEE80211_DISCARD(ic, 2493 1.99 maxv IEEE80211_MSG_AUTH | IEEE80211_MSG_CRYPTO, 2494 1.99 maxv wh, "auth", "%s", "TKIP countermeasures enabled"); 2495 1.99 maxv ic->ic_stats.is_rx_auth_countermeasures++; 2496 1.99 maxv #ifndef IEEE80211_NO_HOSTAP 2497 1.99 maxv if (ic->ic_opmode == IEEE80211_M_HOSTAP) { 2498 1.99 maxv IEEE80211_SEND_MGMT(ic, ni, 2499 1.99 maxv IEEE80211_FC0_SUBTYPE_AUTH, 2500 1.99 maxv IEEE80211_REASON_MIC_FAILURE); 2501 1.99 maxv } 2502 1.104 maxv #endif 2503 1.99 maxv return; 2504 1.99 maxv } 2505 1.104 maxv 2506 1.109 maxv if (algo == IEEE80211_AUTH_ALG_SHARED) { 2507 1.99 maxv ieee80211_auth_shared(ic, wh, frm + 6, efrm, ni, rssi, 2508 1.99 maxv rstamp, seq, status); 2509 1.109 maxv } else if (algo == IEEE80211_AUTH_ALG_OPEN) { 2510 1.109 maxv ieee80211_auth_open(ic, wh, ni, rssi, rstamp, seq, status); 2511 1.109 maxv } else { 2512 1.99 maxv IEEE80211_DISCARD(ic, IEEE80211_MSG_ANY, 2513 1.99 maxv wh, "auth", "unsupported alg %d", algo); 2514 1.99 maxv ic->ic_stats.is_rx_auth_unsupported++; 2515 1.99 maxv #ifndef IEEE80211_NO_HOSTAP 2516 1.99 maxv if (ic->ic_opmode == IEEE80211_M_HOSTAP) { 2517 1.99 maxv /* XXX not right */ 2518 1.99 maxv IEEE80211_SEND_MGMT(ic, ni, 2519 1.99 maxv IEEE80211_FC0_SUBTYPE_AUTH, 2520 1.99 maxv (seq+1) | (IEEE80211_STATUS_ALG<<16)); 2521 1.99 maxv } 2522 1.104 maxv #endif 2523 1.99 maxv } 2524 1.99 maxv } 2525 1.99 maxv 2526 1.100 maxv static void 2527 1.100 maxv ieee80211_recv_mgmt_assoc_req(struct ieee80211com *ic, struct mbuf *m0, 2528 1.100 maxv struct ieee80211_node *ni, int subtype, int rssi, u_int32_t rstamp) 2529 1.100 maxv { 2530 1.100 maxv struct ieee80211_frame *wh; 2531 1.100 maxv u_int8_t *frm, *efrm; 2532 1.100 maxv u_int8_t *ssid, *rates, *xrates, *wpa, *wme; 2533 1.100 maxv int reassoc, resp; 2534 1.100 maxv u_int8_t rate; 2535 1.100 maxv IEEE80211_DEBUGVAR(char ebuf[3 * ETHER_ADDR_LEN]); 2536 1.104 maxv u_int16_t capinfo, lintval; 2537 1.104 maxv struct ieee80211_rsnparms rsn; 2538 1.104 maxv u_int8_t reason; 2539 1.100 maxv 2540 1.100 maxv wh = mtod(m0, struct ieee80211_frame *); 2541 1.100 maxv frm = (u_int8_t *)(wh + 1); 2542 1.100 maxv efrm = mtod(m0, u_int8_t *) + m0->m_len; 2543 1.100 maxv 2544 1.100 maxv if (ic->ic_opmode != IEEE80211_M_HOSTAP || 2545 1.100 maxv ic->ic_state != IEEE80211_S_RUN) { 2546 1.100 maxv ic->ic_stats.is_rx_mgtdiscard++; 2547 1.100 maxv return; 2548 1.100 maxv } 2549 1.100 maxv 2550 1.100 maxv if (subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ) { 2551 1.100 maxv reassoc = 1; 2552 1.100 maxv resp = IEEE80211_FC0_SUBTYPE_REASSOC_RESP; 2553 1.100 maxv } else { 2554 1.100 maxv reassoc = 0; 2555 1.100 maxv resp = IEEE80211_FC0_SUBTYPE_ASSOC_RESP; 2556 1.100 maxv } 2557 1.104 maxv 2558 1.100 maxv /* 2559 1.100 maxv * asreq frame format 2560 1.100 maxv * [2] capability information 2561 1.100 maxv * [2] listen interval 2562 1.100 maxv * [6*] current AP address (reassoc only) 2563 1.100 maxv * [tlv] ssid 2564 1.100 maxv * [tlv] supported rates 2565 1.100 maxv * [tlv] extended supported rates 2566 1.100 maxv * [tlv] WPA or RSN 2567 1.100 maxv */ 2568 1.100 maxv IEEE80211_VERIFY_LENGTH(efrm - frm, (reassoc ? 10 : 4)); 2569 1.109 maxv 2570 1.100 maxv if (!IEEE80211_ADDR_EQ(wh->i_addr3, ic->ic_bss->ni_bssid)) { 2571 1.100 maxv IEEE80211_DISCARD(ic, IEEE80211_MSG_ANY, 2572 1.100 maxv wh, ieee80211_mgt_subtype_name[subtype >> 2573 1.100 maxv IEEE80211_FC0_SUBTYPE_SHIFT], 2574 1.100 maxv "%s", "wrong bssid"); 2575 1.100 maxv ic->ic_stats.is_rx_assoc_bss++; 2576 1.100 maxv return; 2577 1.100 maxv } 2578 1.104 maxv 2579 1.100 maxv capinfo = le16toh(*(u_int16_t *)frm); frm += 2; 2580 1.100 maxv lintval = le16toh(*(u_int16_t *)frm); frm += 2; 2581 1.100 maxv if (reassoc) 2582 1.100 maxv frm += 6; /* ignore current AP info */ 2583 1.104 maxv 2584 1.100 maxv ssid = rates = xrates = wpa = wme = NULL; 2585 1.109 maxv while (frm + 1 < efrm) { 2586 1.109 maxv IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2); 2587 1.109 maxv 2588 1.100 maxv switch (*frm) { 2589 1.100 maxv case IEEE80211_ELEMID_SSID: 2590 1.100 maxv ssid = frm; 2591 1.100 maxv break; 2592 1.100 maxv case IEEE80211_ELEMID_RATES: 2593 1.100 maxv rates = frm; 2594 1.100 maxv break; 2595 1.100 maxv case IEEE80211_ELEMID_XRATES: 2596 1.100 maxv xrates = frm; 2597 1.100 maxv break; 2598 1.100 maxv /* XXX verify only one of RSN and WPA ie's? */ 2599 1.100 maxv case IEEE80211_ELEMID_RSN: 2600 1.100 maxv wpa = frm; 2601 1.100 maxv break; 2602 1.100 maxv case IEEE80211_ELEMID_VENDOR: 2603 1.100 maxv if (iswpaoui(frm)) 2604 1.100 maxv wpa = frm; 2605 1.100 maxv else if (iswmeinfo(frm)) 2606 1.100 maxv wme = frm; 2607 1.100 maxv /* XXX Atheros OUI support */ 2608 1.100 maxv break; 2609 1.100 maxv } 2610 1.109 maxv 2611 1.100 maxv frm += frm[1] + 2; 2612 1.100 maxv } 2613 1.104 maxv 2614 1.100 maxv IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE); 2615 1.100 maxv IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN); 2616 1.100 maxv IEEE80211_VERIFY_SSID(ic->ic_bss, ssid); 2617 1.100 maxv 2618 1.100 maxv if (ni == ic->ic_bss) { 2619 1.100 maxv IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY, 2620 1.100 maxv "[%s] deny %s request, sta not authenticated\n", 2621 1.100 maxv ether_snprintf(ebuf, sizeof(ebuf), wh->i_addr2), 2622 1.100 maxv reassoc ? "reassoc" : "assoc"); 2623 1.100 maxv ieee80211_send_error(ic, ni, wh->i_addr2, 2624 1.100 maxv IEEE80211_FC0_SUBTYPE_DEAUTH, 2625 1.100 maxv IEEE80211_REASON_ASSOC_NOT_AUTHED); 2626 1.100 maxv ic->ic_stats.is_rx_assoc_notauth++; 2627 1.100 maxv return; 2628 1.100 maxv } 2629 1.104 maxv 2630 1.109 maxv /* assert right association security credentials */ 2631 1.100 maxv if (wpa == NULL && (ic->ic_flags & IEEE80211_F_WPA)) { 2632 1.100 maxv IEEE80211_DPRINTF(ic, 2633 1.100 maxv IEEE80211_MSG_ASSOC | IEEE80211_MSG_WPA, 2634 1.100 maxv "[%s] no WPA/RSN IE in association request\n", 2635 1.100 maxv ether_snprintf(ebuf, sizeof(ebuf), wh->i_addr2)); 2636 1.109 maxv 2637 1.100 maxv IEEE80211_SEND_MGMT(ic, ni, 2638 1.100 maxv IEEE80211_FC0_SUBTYPE_DEAUTH, 2639 1.100 maxv IEEE80211_REASON_RSN_REQUIRED); 2640 1.100 maxv ieee80211_node_leave(ic, ni); 2641 1.109 maxv 2642 1.100 maxv /* XXX distinguish WPA/RSN? */ 2643 1.100 maxv ic->ic_stats.is_rx_assoc_badwpaie++; 2644 1.100 maxv return; 2645 1.100 maxv } 2646 1.104 maxv 2647 1.100 maxv if (wpa != NULL) { 2648 1.100 maxv /* 2649 1.100 maxv * Parse WPA information element. Note that 2650 1.100 maxv * we initialize the param block from the node 2651 1.100 maxv * state so that information in the IE overrides 2652 1.100 maxv * our defaults. The resulting parameters are 2653 1.100 maxv * installed below after the association is assured. 2654 1.100 maxv */ 2655 1.100 maxv rsn = ni->ni_rsn; 2656 1.100 maxv if (wpa[0] != IEEE80211_ELEMID_RSN) 2657 1.100 maxv reason = ieee80211_parse_wpa(ic, wpa, &rsn, wh); 2658 1.100 maxv else 2659 1.100 maxv reason = ieee80211_parse_rsn(ic, wpa, &rsn, wh); 2660 1.109 maxv 2661 1.100 maxv if (reason != 0) { 2662 1.100 maxv IEEE80211_SEND_MGMT(ic, ni, 2663 1.100 maxv IEEE80211_FC0_SUBTYPE_DEAUTH, reason); 2664 1.100 maxv ieee80211_node_leave(ic, ni); 2665 1.109 maxv 2666 1.100 maxv /* XXX distinguish WPA/RSN? */ 2667 1.100 maxv ic->ic_stats.is_rx_assoc_badwpaie++; 2668 1.100 maxv return; 2669 1.100 maxv } 2670 1.109 maxv 2671 1.100 maxv IEEE80211_DPRINTF(ic, 2672 1.100 maxv IEEE80211_MSG_ASSOC | IEEE80211_MSG_WPA, 2673 1.100 maxv "[%s] %s ie: mc %u/%u uc %u/%u key %u caps 0x%x\n", 2674 1.100 maxv ether_snprintf(ebuf, sizeof(ebuf), wh->i_addr2), 2675 1.100 maxv wpa[0] != IEEE80211_ELEMID_RSN ? "WPA" : "RSN", 2676 1.100 maxv rsn.rsn_mcastcipher, rsn.rsn_mcastkeylen, 2677 1.100 maxv rsn.rsn_ucastcipher, rsn.rsn_ucastkeylen, 2678 1.100 maxv rsn.rsn_keymgmt, rsn.rsn_caps); 2679 1.100 maxv } 2680 1.104 maxv 2681 1.100 maxv /* discard challenge after association */ 2682 1.100 maxv if (ni->ni_challenge != NULL) { 2683 1.100 maxv free(ni->ni_challenge, M_DEVBUF); 2684 1.100 maxv ni->ni_challenge = NULL; 2685 1.100 maxv } 2686 1.104 maxv 2687 1.100 maxv /* NB: 802.11 spec says to ignore station's privacy bit */ 2688 1.100 maxv if ((capinfo & IEEE80211_CAPINFO_ESS) == 0) { 2689 1.100 maxv IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY, 2690 1.100 maxv "[%s] deny %s request, capability mismatch 0x%x\n", 2691 1.100 maxv ether_snprintf(ebuf, sizeof(ebuf), wh->i_addr2), 2692 1.100 maxv reassoc ? "reassoc" : "assoc", capinfo); 2693 1.100 maxv IEEE80211_SEND_MGMT(ic, ni, resp, 2694 1.100 maxv IEEE80211_STATUS_CAPINFO); 2695 1.100 maxv ieee80211_node_leave(ic, ni); 2696 1.100 maxv ic->ic_stats.is_rx_assoc_capmismatch++; 2697 1.100 maxv return; 2698 1.100 maxv } 2699 1.104 maxv 2700 1.100 maxv rate = ieee80211_setup_rates(ni, rates, xrates, 2701 1.104 maxv IEEE80211_R_DOSORT | IEEE80211_R_DOFRATE | 2702 1.104 maxv IEEE80211_R_DONEGO | IEEE80211_R_DODEL); 2703 1.104 maxv 2704 1.100 maxv /* 2705 1.100 maxv * If constrained to 11g-only stations reject an 2706 1.100 maxv * 11b-only station. We cheat a bit here by looking 2707 1.100 maxv * at the max negotiated xmit rate and assuming anyone 2708 1.100 maxv * with a best rate <24Mb/s is an 11b station. 2709 1.100 maxv */ 2710 1.100 maxv if ((rate & IEEE80211_RATE_BASIC) || 2711 1.100 maxv ((ic->ic_flags & IEEE80211_F_PUREG) && rate < 48)) { 2712 1.100 maxv IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY, 2713 1.100 maxv "[%s] deny %s request, rate set mismatch\n", 2714 1.100 maxv ether_snprintf(ebuf, sizeof(ebuf), wh->i_addr2), 2715 1.100 maxv reassoc ? "reassoc" : "assoc"); 2716 1.100 maxv IEEE80211_SEND_MGMT(ic, ni, resp, 2717 1.100 maxv IEEE80211_STATUS_BASIC_RATE); 2718 1.100 maxv ieee80211_node_leave(ic, ni); 2719 1.100 maxv ic->ic_stats.is_rx_assoc_norate++; 2720 1.100 maxv return; 2721 1.100 maxv } 2722 1.104 maxv 2723 1.100 maxv ni->ni_rssi = rssi; 2724 1.100 maxv ni->ni_rstamp = rstamp; 2725 1.100 maxv ni->ni_intval = lintval; 2726 1.100 maxv ni->ni_capinfo = capinfo; 2727 1.100 maxv ni->ni_chan = ic->ic_bss->ni_chan; 2728 1.100 maxv ni->ni_fhdwell = ic->ic_bss->ni_fhdwell; 2729 1.100 maxv ni->ni_fhindex = ic->ic_bss->ni_fhindex; 2730 1.104 maxv 2731 1.100 maxv if (wpa != NULL) { 2732 1.100 maxv /* 2733 1.100 maxv * Record WPA/RSN parameters for station, mark 2734 1.100 maxv * node as using WPA and record information element 2735 1.100 maxv * for applications that require it. 2736 1.100 maxv */ 2737 1.100 maxv ni->ni_rsn = rsn; 2738 1.100 maxv ieee80211_saveie(&ni->ni_wpa_ie, wpa); 2739 1.100 maxv } else if (ni->ni_wpa_ie != NULL) { 2740 1.100 maxv /* 2741 1.100 maxv * Flush any state from a previous association. 2742 1.100 maxv */ 2743 1.100 maxv free(ni->ni_wpa_ie, M_DEVBUF); 2744 1.100 maxv ni->ni_wpa_ie = NULL; 2745 1.100 maxv } 2746 1.104 maxv 2747 1.100 maxv if (wme != NULL) { 2748 1.100 maxv /* 2749 1.100 maxv * Record WME parameters for station, mark node 2750 1.100 maxv * as capable of QoS and record information 2751 1.100 maxv * element for applications that require it. 2752 1.100 maxv */ 2753 1.100 maxv ieee80211_saveie(&ni->ni_wme_ie, wme); 2754 1.100 maxv ni->ni_flags |= IEEE80211_NODE_QOS; 2755 1.100 maxv } else if (ni->ni_wme_ie != NULL) { 2756 1.100 maxv /* 2757 1.100 maxv * Flush any state from a previous association. 2758 1.100 maxv */ 2759 1.100 maxv free(ni->ni_wme_ie, M_DEVBUF); 2760 1.100 maxv ni->ni_wme_ie = NULL; 2761 1.100 maxv ni->ni_flags &= ~IEEE80211_NODE_QOS; 2762 1.100 maxv } 2763 1.104 maxv 2764 1.100 maxv ieee80211_node_join(ic, ni, resp); 2765 1.100 maxv } 2766 1.100 maxv 2767 1.101 maxv #define ISREASSOC(_st) ((_st) == IEEE80211_FC0_SUBTYPE_REASSOC_RESP) 2768 1.101 maxv 2769 1.101 maxv static void 2770 1.101 maxv ieee80211_recv_mgmt_assoc_resp(struct ieee80211com *ic, struct mbuf *m0, 2771 1.101 maxv struct ieee80211_node *ni, int subtype, int rssi, u_int32_t rstamp) 2772 1.101 maxv { 2773 1.101 maxv struct ieee80211_frame *wh; 2774 1.101 maxv u_int8_t *frm, *efrm; 2775 1.109 maxv u_int8_t *rates, *xrates, *wme; 2776 1.101 maxv u_int8_t rate; 2777 1.101 maxv IEEE80211_DEBUGVAR(char ebuf[3 * ETHER_ADDR_LEN]); 2778 1.104 maxv u_int16_t capinfo, associd; 2779 1.104 maxv u_int16_t status; 2780 1.101 maxv 2781 1.101 maxv wh = mtod(m0, struct ieee80211_frame *); 2782 1.101 maxv frm = (u_int8_t *)(wh + 1); 2783 1.101 maxv efrm = mtod(m0, u_int8_t *) + m0->m_len; 2784 1.101 maxv 2785 1.101 maxv if (ic->ic_opmode != IEEE80211_M_STA || 2786 1.101 maxv ic->ic_state != IEEE80211_S_ASSOC) { 2787 1.101 maxv ic->ic_stats.is_rx_mgtdiscard++; 2788 1.101 maxv return; 2789 1.101 maxv } 2790 1.101 maxv 2791 1.101 maxv /* 2792 1.101 maxv * asresp frame format 2793 1.101 maxv * [2] capability information 2794 1.101 maxv * [2] status 2795 1.101 maxv * [2] association ID 2796 1.101 maxv * [tlv] supported rates 2797 1.101 maxv * [tlv] extended supported rates 2798 1.101 maxv * [tlv] WME 2799 1.101 maxv */ 2800 1.101 maxv IEEE80211_VERIFY_LENGTH(efrm - frm, 6); 2801 1.101 maxv ni = ic->ic_bss; 2802 1.101 maxv capinfo = le16toh(*(u_int16_t *)frm); 2803 1.101 maxv frm += 2; 2804 1.101 maxv status = le16toh(*(u_int16_t *)frm); 2805 1.101 maxv frm += 2; 2806 1.101 maxv if (status != 0) { 2807 1.101 maxv IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC, 2808 1.101 maxv "[%s] %sassoc failed (reason %d)\n", 2809 1.101 maxv ether_snprintf(ebuf, sizeof(ebuf), wh->i_addr2), 2810 1.101 maxv ISREASSOC(subtype) ? "re" : "", status); 2811 1.101 maxv if (ni != ic->ic_bss) /* XXX never true? */ 2812 1.101 maxv ni->ni_fails++; 2813 1.101 maxv ic->ic_stats.is_rx_auth_fail++; /* XXX */ 2814 1.101 maxv return; 2815 1.101 maxv } 2816 1.101 maxv associd = le16toh(*(u_int16_t *)frm); 2817 1.101 maxv frm += 2; 2818 1.101 maxv 2819 1.109 maxv rates = xrates = wme = NULL; 2820 1.109 maxv while (frm + 1 < efrm) { 2821 1.109 maxv IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2); 2822 1.109 maxv 2823 1.101 maxv switch (*frm) { 2824 1.101 maxv case IEEE80211_ELEMID_RATES: 2825 1.101 maxv rates = frm; 2826 1.101 maxv break; 2827 1.101 maxv case IEEE80211_ELEMID_XRATES: 2828 1.101 maxv xrates = frm; 2829 1.101 maxv break; 2830 1.101 maxv case IEEE80211_ELEMID_VENDOR: 2831 1.101 maxv if (iswmeoui(frm)) 2832 1.101 maxv wme = frm; 2833 1.101 maxv /* XXX Atheros OUI support */ 2834 1.101 maxv break; 2835 1.101 maxv } 2836 1.109 maxv 2837 1.101 maxv frm += frm[1] + 2; 2838 1.101 maxv } 2839 1.101 maxv 2840 1.101 maxv IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE); 2841 1.109 maxv 2842 1.101 maxv rate = ieee80211_setup_rates(ni, rates, xrates, 2843 1.109 maxv IEEE80211_R_DOSORT | IEEE80211_R_DOFRATE | 2844 1.109 maxv IEEE80211_R_DONEGO | IEEE80211_R_DODEL); 2845 1.109 maxv 2846 1.101 maxv if (rate & IEEE80211_RATE_BASIC) { 2847 1.101 maxv IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC, 2848 1.101 maxv "[%s] %sassoc failed (rate set mismatch)\n", 2849 1.101 maxv ether_snprintf(ebuf, sizeof(ebuf), wh->i_addr2), 2850 1.101 maxv ISREASSOC(subtype) ? "re" : ""); 2851 1.101 maxv if (ni != ic->ic_bss) /* XXX never true? */ 2852 1.101 maxv ni->ni_fails++; 2853 1.101 maxv ic->ic_stats.is_rx_assoc_norate++; 2854 1.101 maxv ieee80211_new_state(ic, IEEE80211_S_SCAN, 0); 2855 1.101 maxv return; 2856 1.101 maxv } 2857 1.101 maxv 2858 1.101 maxv ni->ni_capinfo = capinfo; 2859 1.101 maxv ni->ni_associd = associd; 2860 1.109 maxv if (wme != NULL && ieee80211_parse_wmeparams(ic, wme, wh) >= 0) { 2861 1.101 maxv ni->ni_flags |= IEEE80211_NODE_QOS; 2862 1.101 maxv ieee80211_wme_updateparams(ic); 2863 1.104 maxv } else { 2864 1.101 maxv ni->ni_flags &= ~IEEE80211_NODE_QOS; 2865 1.104 maxv } 2866 1.104 maxv 2867 1.101 maxv /* 2868 1.101 maxv * Configure state now that we are associated. 2869 1.101 maxv * 2870 1.101 maxv * XXX may need different/additional driver callbacks? 2871 1.101 maxv */ 2872 1.101 maxv if (ic->ic_curmode == IEEE80211_MODE_11A || 2873 1.101 maxv (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE)) { 2874 1.101 maxv ic->ic_flags |= IEEE80211_F_SHPREAMBLE; 2875 1.101 maxv ic->ic_flags &= ~IEEE80211_F_USEBARKER; 2876 1.101 maxv } else { 2877 1.101 maxv ic->ic_flags &= ~IEEE80211_F_SHPREAMBLE; 2878 1.101 maxv ic->ic_flags |= IEEE80211_F_USEBARKER; 2879 1.101 maxv } 2880 1.101 maxv ieee80211_set_shortslottime(ic, 2881 1.104 maxv ic->ic_curmode == IEEE80211_MODE_11A || 2882 1.104 maxv (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME)); 2883 1.104 maxv 2884 1.101 maxv /* 2885 1.101 maxv * Honor ERP protection. 2886 1.101 maxv * 2887 1.101 maxv * NB: ni_erp should zero for non-11g operation. 2888 1.101 maxv * XXX check ic_curmode anyway? 2889 1.101 maxv */ 2890 1.101 maxv if (ic->ic_curmode == IEEE80211_MODE_11G && 2891 1.109 maxv (ni->ni_erp & IEEE80211_ERP_USE_PROTECTION)) { 2892 1.101 maxv ic->ic_flags |= IEEE80211_F_USEPROT; 2893 1.109 maxv } else { 2894 1.101 maxv ic->ic_flags &= ~IEEE80211_F_USEPROT; 2895 1.109 maxv } 2896 1.104 maxv 2897 1.101 maxv IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC, 2898 1.101 maxv "[%s] %sassoc success: %s preamble, %s slot time%s%s\n", 2899 1.101 maxv ether_snprintf(ebuf, sizeof(ebuf), wh->i_addr2), 2900 1.101 maxv ISREASSOC(subtype) ? "re" : "", 2901 1.101 maxv ic->ic_flags&IEEE80211_F_SHPREAMBLE ? "short" : "long", 2902 1.101 maxv ic->ic_flags&IEEE80211_F_SHSLOT ? "short" : "long", 2903 1.101 maxv ic->ic_flags&IEEE80211_F_USEPROT ? ", protection" : "", 2904 1.101 maxv ni->ni_flags & IEEE80211_NODE_QOS ? ", QoS" : "" 2905 1.101 maxv ); 2906 1.104 maxv 2907 1.101 maxv ieee80211_new_state(ic, IEEE80211_S_RUN, subtype); 2908 1.101 maxv } 2909 1.101 maxv 2910 1.102 maxv static void 2911 1.102 maxv ieee80211_recv_mgmt_deauth(struct ieee80211com *ic, struct mbuf *m0, 2912 1.102 maxv struct ieee80211_node *ni, int subtype, int rssi, u_int32_t rstamp) 2913 1.102 maxv { 2914 1.102 maxv struct ieee80211_frame *wh; 2915 1.102 maxv u_int8_t *frm, *efrm; 2916 1.102 maxv IEEE80211_DEBUGVAR(char ebuf[3 * ETHER_ADDR_LEN]); 2917 1.104 maxv u_int16_t reason; 2918 1.102 maxv 2919 1.102 maxv wh = mtod(m0, struct ieee80211_frame *); 2920 1.102 maxv frm = (u_int8_t *)(wh + 1); 2921 1.102 maxv efrm = mtod(m0, u_int8_t *) + m0->m_len; 2922 1.102 maxv 2923 1.102 maxv if (ic->ic_state == IEEE80211_S_SCAN) { 2924 1.102 maxv ic->ic_stats.is_rx_mgtdiscard++; 2925 1.102 maxv return; 2926 1.102 maxv } 2927 1.104 maxv 2928 1.102 maxv /* 2929 1.102 maxv * deauth frame format 2930 1.102 maxv * [2] reason 2931 1.102 maxv */ 2932 1.102 maxv IEEE80211_VERIFY_LENGTH(efrm - frm, 2); 2933 1.102 maxv reason = le16toh(*(u_int16_t *)frm); 2934 1.102 maxv __USE(reason); 2935 1.102 maxv ic->ic_stats.is_rx_deauth++; 2936 1.102 maxv IEEE80211_NODE_STAT(ni, rx_deauth); 2937 1.102 maxv 2938 1.102 maxv if (!IEEE80211_ADDR_EQ(wh->i_addr1, ic->ic_myaddr)) { 2939 1.102 maxv /* Not intended for this station. */ 2940 1.102 maxv ic->ic_stats.is_rx_mgtdiscard++; 2941 1.102 maxv return; 2942 1.102 maxv } 2943 1.104 maxv 2944 1.102 maxv IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH, 2945 1.102 maxv "[%s] recv deauthenticate (reason %d)\n", 2946 1.102 maxv ether_snprintf(ebuf, sizeof(ebuf), ni->ni_macaddr), reason); 2947 1.104 maxv 2948 1.102 maxv switch (ic->ic_opmode) { 2949 1.102 maxv case IEEE80211_M_STA: 2950 1.102 maxv ieee80211_new_state(ic, IEEE80211_S_AUTH, 2951 1.102 maxv wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 2952 1.102 maxv break; 2953 1.102 maxv case IEEE80211_M_HOSTAP: 2954 1.102 maxv #ifndef IEEE80211_NO_HOSTAP 2955 1.102 maxv if (ni != ic->ic_bss) 2956 1.102 maxv ieee80211_node_leave(ic, ni); 2957 1.104 maxv #endif 2958 1.102 maxv break; 2959 1.102 maxv default: 2960 1.102 maxv ic->ic_stats.is_rx_mgtdiscard++; 2961 1.102 maxv break; 2962 1.102 maxv } 2963 1.102 maxv } 2964 1.102 maxv 2965 1.103 maxv static void 2966 1.103 maxv ieee80211_recv_mgmt_disassoc(struct ieee80211com *ic, struct mbuf *m0, 2967 1.103 maxv struct ieee80211_node *ni, int subtype, int rssi, u_int32_t rstamp) 2968 1.103 maxv { 2969 1.103 maxv struct ieee80211_frame *wh; 2970 1.103 maxv u_int8_t *frm, *efrm; 2971 1.103 maxv IEEE80211_DEBUGVAR(char ebuf[3 * ETHER_ADDR_LEN]); 2972 1.104 maxv u_int16_t reason; 2973 1.103 maxv 2974 1.103 maxv wh = mtod(m0, struct ieee80211_frame *); 2975 1.103 maxv frm = (u_int8_t *)(wh + 1); 2976 1.103 maxv efrm = mtod(m0, u_int8_t *) + m0->m_len; 2977 1.103 maxv 2978 1.103 maxv if (ic->ic_state != IEEE80211_S_RUN && 2979 1.103 maxv ic->ic_state != IEEE80211_S_ASSOC && 2980 1.103 maxv ic->ic_state != IEEE80211_S_AUTH) { 2981 1.103 maxv ic->ic_stats.is_rx_mgtdiscard++; 2982 1.103 maxv return; 2983 1.103 maxv } 2984 1.104 maxv 2985 1.103 maxv /* 2986 1.103 maxv * disassoc frame format 2987 1.103 maxv * [2] reason 2988 1.103 maxv */ 2989 1.103 maxv IEEE80211_VERIFY_LENGTH(efrm - frm, 2); 2990 1.103 maxv reason = le16toh(*(u_int16_t *)frm); 2991 1.103 maxv __USE(reason); 2992 1.103 maxv ic->ic_stats.is_rx_disassoc++; 2993 1.103 maxv IEEE80211_NODE_STAT(ni, rx_disassoc); 2994 1.103 maxv 2995 1.103 maxv if (!IEEE80211_ADDR_EQ(wh->i_addr1, ic->ic_myaddr)) { 2996 1.103 maxv /* Not intended for this station. */ 2997 1.103 maxv ic->ic_stats.is_rx_mgtdiscard++; 2998 1.103 maxv return; 2999 1.103 maxv } 3000 1.104 maxv 3001 1.103 maxv IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC, 3002 1.103 maxv "[%s] recv disassociate (reason %d)\n", 3003 1.103 maxv ether_snprintf(ebuf, sizeof(ebuf), ni->ni_macaddr), reason); 3004 1.104 maxv 3005 1.103 maxv switch (ic->ic_opmode) { 3006 1.103 maxv case IEEE80211_M_STA: 3007 1.103 maxv ieee80211_new_state(ic, IEEE80211_S_ASSOC, 3008 1.103 maxv wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 3009 1.103 maxv break; 3010 1.103 maxv case IEEE80211_M_HOSTAP: 3011 1.103 maxv #ifndef IEEE80211_NO_HOSTAP 3012 1.103 maxv if (ni != ic->ic_bss) 3013 1.103 maxv ieee80211_node_leave(ic, ni); 3014 1.104 maxv #endif 3015 1.103 maxv break; 3016 1.103 maxv default: 3017 1.103 maxv ic->ic_stats.is_rx_mgtdiscard++; 3018 1.103 maxv break; 3019 1.103 maxv } 3020 1.103 maxv } 3021 1.103 maxv 3022 1.105 maxv #undef ISREASSOC 3023 1.105 maxv #undef IEEE80211_VERIFY_LENGTH 3024 1.105 maxv #undef IEEE80211_VERIFY_ELEMENT 3025 1.105 maxv 3026 1.98 maxv /* -------------------------------------------------------------------------- */ 3027 1.98 maxv 3028 1.98 maxv void 3029 1.98 maxv ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0, 3030 1.98 maxv struct ieee80211_node *ni, int subtype, int rssi, u_int32_t rstamp) 3031 1.98 maxv { 3032 1.98 maxv struct ieee80211_frame *wh; 3033 1.98 maxv 3034 1.98 maxv wh = mtod(m0, struct ieee80211_frame *); 3035 1.98 maxv 3036 1.98 maxv switch (subtype) { 3037 1.98 maxv case IEEE80211_FC0_SUBTYPE_PROBE_RESP: 3038 1.98 maxv case IEEE80211_FC0_SUBTYPE_BEACON: 3039 1.98 maxv ieee80211_recv_mgmt_beacon(ic, m0, ni, subtype, rssi, rstamp); 3040 1.98 maxv return; 3041 1.1 dyoung 3042 1.98 maxv case IEEE80211_FC0_SUBTYPE_PROBE_REQ: 3043 1.98 maxv ieee80211_recv_mgmt_probe_req(ic, m0, ni, subtype, rssi, rstamp); 3044 1.98 maxv return; 3045 1.1 dyoung 3046 1.99 maxv case IEEE80211_FC0_SUBTYPE_AUTH: 3047 1.99 maxv ieee80211_recv_mgmt_auth(ic, m0, ni, subtype, rssi, rstamp); 3048 1.99 maxv return; 3049 1.1 dyoung 3050 1.1 dyoung case IEEE80211_FC0_SUBTYPE_ASSOC_REQ: 3051 1.100 maxv case IEEE80211_FC0_SUBTYPE_REASSOC_REQ: 3052 1.100 maxv ieee80211_recv_mgmt_assoc_req(ic, m0, ni, subtype, rssi, rstamp); 3053 1.100 maxv return; 3054 1.1 dyoung 3055 1.1 dyoung case IEEE80211_FC0_SUBTYPE_ASSOC_RESP: 3056 1.101 maxv case IEEE80211_FC0_SUBTYPE_REASSOC_RESP: 3057 1.101 maxv ieee80211_recv_mgmt_assoc_resp(ic, m0, ni, subtype, rssi, rstamp); 3058 1.101 maxv return; 3059 1.1 dyoung 3060 1.102 maxv case IEEE80211_FC0_SUBTYPE_DEAUTH: 3061 1.102 maxv ieee80211_recv_mgmt_deauth(ic, m0, ni, subtype, rssi, rstamp); 3062 1.102 maxv return; 3063 1.1 dyoung 3064 1.103 maxv case IEEE80211_FC0_SUBTYPE_DISASSOC: 3065 1.103 maxv ieee80211_recv_mgmt_disassoc(ic, m0, ni, subtype, rssi, rstamp); 3066 1.103 maxv return; 3067 1.40 dyoung 3068 1.1 dyoung default: 3069 1.40 dyoung IEEE80211_DISCARD(ic, IEEE80211_MSG_ANY, 3070 1.40 dyoung wh, "mgt", "subtype 0x%x not handled", subtype); 3071 1.16 dyoung ic->ic_stats.is_rx_badsubtype++; 3072 1.1 dyoung break; 3073 1.1 dyoung } 3074 1.103 maxv } 3075 1.103 maxv 3076 1.41 dyoung #ifndef IEEE80211_NO_HOSTAP 3077 1.40 dyoung /* 3078 1.40 dyoung * Handle station power-save state change. 3079 1.40 dyoung */ 3080 1.5 dyoung static void 3081 1.40 dyoung ieee80211_node_pwrsave(struct ieee80211_node *ni, int enable) 3082 1.5 dyoung { 3083 1.40 dyoung struct ieee80211com *ic = ni->ni_ic; 3084 1.5 dyoung struct mbuf *m; 3085 1.85 christos IEEE80211_DEBUGVAR(char ebuf[3 * ETHER_ADDR_LEN]); 3086 1.5 dyoung 3087 1.40 dyoung if (enable) { 3088 1.40 dyoung if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) == 0) 3089 1.40 dyoung ic->ic_ps_sta++; 3090 1.40 dyoung ni->ni_flags |= IEEE80211_NODE_PWR_MGT; 3091 1.40 dyoung IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER, 3092 1.40 dyoung "[%s] power save mode on, %u sta's in ps mode\n", 3093 1.85 christos ether_snprintf(ebuf, sizeof(ebuf), ni->ni_macaddr), 3094 1.85 christos ic->ic_ps_sta); 3095 1.5 dyoung return; 3096 1.40 dyoung } 3097 1.5 dyoung 3098 1.40 dyoung if (ni->ni_flags & IEEE80211_NODE_PWR_MGT) 3099 1.40 dyoung ic->ic_ps_sta--; 3100 1.40 dyoung ni->ni_flags &= ~IEEE80211_NODE_PWR_MGT; 3101 1.40 dyoung IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER, 3102 1.40 dyoung "[%s] power save mode off, %u sta's in ps mode\n", 3103 1.85 christos ether_snprintf(ebuf, sizeof(ebuf), ni->ni_macaddr), ic->ic_ps_sta); 3104 1.40 dyoung /* XXX if no stations in ps mode, flush mc frames */ 3105 1.5 dyoung 3106 1.40 dyoung /* 3107 1.40 dyoung * Flush queued unicast frames. 3108 1.40 dyoung */ 3109 1.40 dyoung if (IEEE80211_NODE_SAVEQ_QLEN(ni) == 0) { 3110 1.44 dyoung if (ic->ic_set_tim != NULL) 3111 1.47 skrll ic->ic_set_tim(ni, 0); /* just in case */ 3112 1.5 dyoung return; 3113 1.5 dyoung } 3114 1.109 maxv 3115 1.40 dyoung IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER, 3116 1.40 dyoung "[%s] flush ps queue, %u packets queued\n", 3117 1.85 christos ether_snprintf(ebuf, sizeof(ebuf), ni->ni_macaddr), 3118 1.85 christos IEEE80211_NODE_SAVEQ_QLEN(ni)); 3119 1.109 maxv 3120 1.40 dyoung for (;;) { 3121 1.40 dyoung int qlen; 3122 1.40 dyoung 3123 1.40 dyoung IEEE80211_NODE_SAVEQ_DEQUEUE(ni, m, qlen); 3124 1.40 dyoung if (m == NULL) 3125 1.40 dyoung break; 3126 1.109 maxv 3127 1.74 christos /* 3128 1.40 dyoung * If this is the last packet, turn off the TIM bit. 3129 1.40 dyoung * If there are more packets, set the more packets bit 3130 1.44 dyoung * in the mbuf so ieee80211_encap will mark the 802.11 3131 1.44 dyoung * head to indicate more data frames will follow. 3132 1.40 dyoung */ 3133 1.44 dyoung if (qlen != 0) 3134 1.44 dyoung m->m_flags |= M_MORE_DATA; 3135 1.109 maxv 3136 1.40 dyoung /* XXX need different driver interface */ 3137 1.40 dyoung /* XXX bypasses q max */ 3138 1.40 dyoung IF_ENQUEUE(&ic->ic_ifp->if_snd, m); 3139 1.40 dyoung } 3140 1.109 maxv 3141 1.44 dyoung if (ic->ic_set_tim != NULL) 3142 1.47 skrll ic->ic_set_tim(ni, 0); 3143 1.40 dyoung } 3144 1.5 dyoung 3145 1.40 dyoung /* 3146 1.40 dyoung * Process a received ps-poll frame. 3147 1.40 dyoung */ 3148 1.40 dyoung static void 3149 1.109 maxv ieee80211_recv_pspoll(struct ieee80211com *ic, struct ieee80211_node *ni, 3150 1.109 maxv struct mbuf *m0) 3151 1.40 dyoung { 3152 1.40 dyoung struct ieee80211_frame_min *wh; 3153 1.40 dyoung struct mbuf *m; 3154 1.40 dyoung u_int16_t aid; 3155 1.40 dyoung int qlen; 3156 1.85 christos IEEE80211_DEBUGVAR(char ebuf[3 * ETHER_ADDR_LEN]); 3157 1.40 dyoung 3158 1.40 dyoung wh = mtod(m0, struct ieee80211_frame_min *); 3159 1.40 dyoung if (ni->ni_associd == 0) { 3160 1.40 dyoung IEEE80211_DISCARD(ic, IEEE80211_MSG_POWER | IEEE80211_MSG_DEBUG, 3161 1.109 maxv (struct ieee80211_frame *)wh, "ps-poll", 3162 1.40 dyoung "%s", "unassociated station"); 3163 1.40 dyoung ic->ic_stats.is_ps_unassoc++; 3164 1.40 dyoung IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_DEAUTH, 3165 1.40 dyoung IEEE80211_REASON_NOT_ASSOCED); 3166 1.5 dyoung return; 3167 1.5 dyoung } 3168 1.5 dyoung 3169 1.40 dyoung aid = le16toh(*(u_int16_t *)wh->i_dur); 3170 1.5 dyoung if (aid != ni->ni_associd) { 3171 1.40 dyoung IEEE80211_DISCARD(ic, IEEE80211_MSG_POWER | IEEE80211_MSG_DEBUG, 3172 1.109 maxv (struct ieee80211_frame *)wh, "ps-poll", 3173 1.40 dyoung "aid mismatch: sta aid 0x%x poll aid 0x%x", 3174 1.40 dyoung ni->ni_associd, aid); 3175 1.40 dyoung ic->ic_stats.is_ps_badaid++; 3176 1.40 dyoung IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_DEAUTH, 3177 1.40 dyoung IEEE80211_REASON_NOT_ASSOCED); 3178 1.5 dyoung return; 3179 1.5 dyoung } 3180 1.5 dyoung 3181 1.5 dyoung /* Okay, take the first queued packet and put it out... */ 3182 1.40 dyoung IEEE80211_NODE_SAVEQ_DEQUEUE(ni, m, qlen); 3183 1.5 dyoung if (m == NULL) { 3184 1.40 dyoung IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER, 3185 1.40 dyoung "[%s] recv ps-poll, but queue empty\n", 3186 1.85 christos ether_snprintf(ebuf, sizeof(ebuf), wh->i_addr2)); 3187 1.47 skrll ieee80211_send_nulldata(ieee80211_ref_node(ni)); 3188 1.40 dyoung ic->ic_stats.is_ps_qempty++; /* XXX node stat */ 3189 1.44 dyoung if (ic->ic_set_tim != NULL) 3190 1.47 skrll ic->ic_set_tim(ni, 0); /* just in case */ 3191 1.5 dyoung return; 3192 1.5 dyoung } 3193 1.109 maxv 3194 1.74 christos /* 3195 1.40 dyoung * If there are more packets, set the more packets bit 3196 1.40 dyoung * in the packet dispatched to the station; otherwise 3197 1.40 dyoung * turn off the TIM bit. 3198 1.5 dyoung */ 3199 1.40 dyoung if (qlen != 0) { 3200 1.40 dyoung IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER, 3201 1.40 dyoung "[%s] recv ps-poll, send packet, %u still queued\n", 3202 1.85 christos ether_snprintf(ebuf, sizeof(ebuf), ni->ni_macaddr), qlen); 3203 1.44 dyoung m->m_flags |= M_MORE_DATA; 3204 1.5 dyoung } else { 3205 1.40 dyoung IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER, 3206 1.40 dyoung "[%s] recv ps-poll, send packet, queue empty\n", 3207 1.85 christos ether_snprintf(ebuf, sizeof(ebuf), ni->ni_macaddr)); 3208 1.44 dyoung if (ic->ic_set_tim != NULL) 3209 1.47 skrll ic->ic_set_tim(ni, 0); 3210 1.5 dyoung } 3211 1.109 maxv 3212 1.40 dyoung m->m_flags |= M_PWR_SAV; /* bypass PS handling */ 3213 1.40 dyoung IF_ENQUEUE(&ic->ic_ifp->if_snd, m); 3214 1.40 dyoung } 3215 1.41 dyoung #endif /* !IEEE80211_NO_HOSTAP */ 3216 1.5 dyoung 3217 1.40 dyoung #ifdef IEEE80211_DEBUG 3218 1.40 dyoung /* 3219 1.40 dyoung * Debugging support. 3220 1.40 dyoung */ 3221 1.5 dyoung 3222 1.40 dyoung /* 3223 1.40 dyoung * Return the bssid of a frame. 3224 1.40 dyoung */ 3225 1.40 dyoung static const u_int8_t * 3226 1.40 dyoung ieee80211_getbssid(struct ieee80211com *ic, const struct ieee80211_frame *wh) 3227 1.40 dyoung { 3228 1.40 dyoung if (ic->ic_opmode == IEEE80211_M_STA) 3229 1.40 dyoung return wh->i_addr2; 3230 1.40 dyoung if ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) != IEEE80211_FC1_DIR_NODS) 3231 1.40 dyoung return wh->i_addr1; 3232 1.40 dyoung if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == IEEE80211_FC0_SUBTYPE_PS_POLL) 3233 1.40 dyoung return wh->i_addr1; 3234 1.40 dyoung return wh->i_addr3; 3235 1.1 dyoung } 3236 1.31 dyoung 3237 1.47 skrll void 3238 1.47 skrll ieee80211_note(struct ieee80211com *ic, const char *fmt, ...) 3239 1.47 skrll { 3240 1.47 skrll char buf[128]; /* XXX */ 3241 1.47 skrll va_list ap; 3242 1.47 skrll 3243 1.47 skrll va_start(ap, fmt); 3244 1.47 skrll vsnprintf(buf, sizeof(buf), fmt, ap); 3245 1.47 skrll va_end(ap); 3246 1.47 skrll 3247 1.47 skrll if_printf(ic->ic_ifp, "%s", buf); /* NB: no \n */ 3248 1.47 skrll } 3249 1.47 skrll 3250 1.47 skrll void 3251 1.47 skrll ieee80211_note_mac(struct ieee80211com *ic, 3252 1.47 skrll const u_int8_t mac[IEEE80211_ADDR_LEN], 3253 1.47 skrll const char *fmt, ...) 3254 1.47 skrll { 3255 1.47 skrll char buf[128]; /* XXX */ 3256 1.47 skrll va_list ap; 3257 1.85 christos char ebuf[3 * ETHER_ADDR_LEN]; 3258 1.47 skrll 3259 1.47 skrll va_start(ap, fmt); 3260 1.47 skrll vsnprintf(buf, sizeof(buf), fmt, ap); 3261 1.47 skrll va_end(ap); 3262 1.85 christos if_printf(ic->ic_ifp, "[%s] %s\n", ether_snprintf(ebuf, sizeof(ebuf), 3263 1.85 christos mac), buf); 3264 1.47 skrll } 3265 1.47 skrll 3266 1.40 dyoung static void 3267 1.40 dyoung ieee80211_discard_frame(struct ieee80211com *ic, 3268 1.40 dyoung const struct ieee80211_frame *wh, 3269 1.40 dyoung const char *type, const char *fmt, ...) 3270 1.31 dyoung { 3271 1.40 dyoung va_list ap; 3272 1.85 christos char ebuf[3 * ETHER_ADDR_LEN]; 3273 1.31 dyoung 3274 1.47 skrll printf("[%s:%s] discard ", ic->ic_ifp->if_xname, 3275 1.85 christos ether_snprintf(ebuf, sizeof(ebuf), ieee80211_getbssid(ic, wh))); 3276 1.40 dyoung if (type != NULL) 3277 1.47 skrll printf("%s frame, ", type); 3278 1.40 dyoung else 3279 1.47 skrll printf("frame, "); 3280 1.40 dyoung va_start(ap, fmt); 3281 1.40 dyoung vprintf(fmt, ap); 3282 1.40 dyoung va_end(ap); 3283 1.40 dyoung printf("\n"); 3284 1.31 dyoung } 3285 1.31 dyoung 3286 1.40 dyoung static void 3287 1.40 dyoung ieee80211_discard_ie(struct ieee80211com *ic, 3288 1.40 dyoung const struct ieee80211_frame *wh, 3289 1.40 dyoung const char *type, const char *fmt, ...) 3290 1.31 dyoung { 3291 1.40 dyoung va_list ap; 3292 1.85 christos char ebuf[3 * ETHER_ADDR_LEN]; 3293 1.31 dyoung 3294 1.47 skrll printf("[%s:%s] discard ", ic->ic_ifp->if_xname, 3295 1.85 christos ether_snprintf(ebuf, sizeof(ebuf), ieee80211_getbssid(ic, wh))); 3296 1.40 dyoung if (type != NULL) 3297 1.47 skrll printf("%s information element, ", type); 3298 1.40 dyoung else 3299 1.47 skrll printf("information element, "); 3300 1.40 dyoung va_start(ap, fmt); 3301 1.40 dyoung vprintf(fmt, ap); 3302 1.40 dyoung va_end(ap); 3303 1.40 dyoung printf("\n"); 3304 1.40 dyoung } 3305 1.31 dyoung 3306 1.40 dyoung static void 3307 1.40 dyoung ieee80211_discard_mac(struct ieee80211com *ic, 3308 1.40 dyoung const u_int8_t mac[IEEE80211_ADDR_LEN], 3309 1.40 dyoung const char *type, const char *fmt, ...) 3310 1.40 dyoung { 3311 1.40 dyoung va_list ap; 3312 1.85 christos char ebuf[3 * ETHER_ADDR_LEN]; 3313 1.31 dyoung 3314 1.85 christos printf("[%s:%s] discard ", ic->ic_ifp->if_xname, 3315 1.85 christos ether_snprintf(ebuf, sizeof(ebuf), mac)); 3316 1.40 dyoung if (type != NULL) 3317 1.47 skrll printf("%s frame, ", type); 3318 1.40 dyoung else 3319 1.47 skrll printf("frame, "); 3320 1.40 dyoung va_start(ap, fmt); 3321 1.40 dyoung vprintf(fmt, ap); 3322 1.40 dyoung va_end(ap); 3323 1.40 dyoung printf("\n"); 3324 1.31 dyoung } 3325 1.40 dyoung #endif /* IEEE80211_DEBUG */ 3326