1/*- 2 * Copyright (c) 2001 Atsushi Onoe 3 * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 17 unchanged lines hidden (view full) --- 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33#include <sys/cdefs.h> |
34__FBSDID("$FreeBSD: head/sys/net80211/ieee80211_input.c 121180 2003-10-17 23:15:30Z sam $"); |
35 36#include "opt_inet.h" 37 38#include <sys/param.h> 39#include <sys/systm.h> 40#include <sys/mbuf.h> 41#include <sys/malloc.h> 42#include <sys/kernel.h> --- 65 unchanged lines hidden (view full) --- 108 109 wh = mtod(m, struct ieee80211_frame *); 110 if ((wh->i_fc[0] & IEEE80211_FC0_VERSION_MASK) != 111 IEEE80211_FC0_VERSION_0) { 112 if (ifp->if_flags & IFF_DEBUG) 113 if_printf(ifp, "receive packet with wrong version: %x\n", 114 wh->i_fc[0]); 115 ieee80211_unref_node(&ni); |
116 ic->ic_stats.is_rx_badversion++; |
117 goto err; 118 } 119 120 dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK; 121 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 122 /* 123 * NB: We are not yet prepared to handle control frames, 124 * but permitting drivers to send them to us allows 125 * them to go through bpf tapping at the 802.11 layer. 126 */ 127 if (m->m_pkthdr.len < sizeof(struct ieee80211_frame)) { |
128 /* XXX statistic */ |
129 IEEE80211_DPRINTF2(("%s: frame too short, len %u\n", 130 __func__, m->m_pkthdr.len)); |
131 ic->ic_stats.is_rx_tooshort++; |
132 goto out; /* XXX */ 133 } 134 if (ic->ic_state != IEEE80211_S_SCAN) { 135 switch (ic->ic_opmode) { 136 case IEEE80211_M_STA: 137 if (!IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_bssid)) { |
138 /* not interested in */ |
139 IEEE80211_DPRINTF2(("%s: discard frame from " 140 "bss %s\n", __func__, 141 ether_sprintf(wh->i_addr2))); |
142 ic->ic_stats.is_rx_wrongbss++; |
143 goto out; 144 } 145 break; 146 case IEEE80211_M_IBSS: 147 case IEEE80211_M_AHDEMO: 148 case IEEE80211_M_HOSTAP: 149 if (dir == IEEE80211_FC1_DIR_NODS) 150 bssid = wh->i_addr3; 151 else 152 bssid = wh->i_addr1; 153 if (!IEEE80211_ADDR_EQ(bssid, ic->ic_bss->ni_bssid) && 154 !IEEE80211_ADDR_EQ(bssid, ifp->if_broadcastaddr)) { 155 /* not interested in */ 156 IEEE80211_DPRINTF2(("%s: discard frame from " 157 "bss %s\n", __func__, 158 ether_sprintf(bssid))); |
159 ic->ic_stats.is_rx_wrongbss++; |
160 goto out; 161 } 162 break; 163 case IEEE80211_M_MONITOR: 164 goto out; 165 default: 166 /* XXX catch bad values */ 167 break; 168 } 169 ni->ni_rssi = rssi; 170 ni->ni_rstamp = rstamp; 171 rxseq = ni->ni_rxseq; 172 ni->ni_rxseq = 173 le16toh(*(u_int16_t *)wh->i_seq) >> IEEE80211_SEQ_SEQ_SHIFT; 174 /* TODO: fragment */ 175 if ((wh->i_fc[1] & IEEE80211_FC1_RETRY) && 176 rxseq == ni->ni_rxseq) { 177 /* duplicate, silently discarded */ |
178 ic->ic_stats.is_rx_dup++; /* XXX per-station stat */ |
179 goto out; 180 } 181 ni->ni_inact = 0; 182 } 183 184 switch (type) { 185 case IEEE80211_FC0_TYPE_DATA: 186 switch (ic->ic_opmode) { 187 case IEEE80211_M_STA: |
188 if (dir != IEEE80211_FC1_DIR_FROMDS) { 189 ic->ic_stats.is_rx_wrongdir++; |
190 goto out; |
191 } |
192 if ((ifp->if_flags & IFF_SIMPLEX) && 193 IEEE80211_IS_MULTICAST(wh->i_addr1) && 194 IEEE80211_ADDR_EQ(wh->i_addr3, ic->ic_myaddr)) { 195 /* 196 * In IEEE802.11 network, multicast packet 197 * sent from me is broadcasted from AP. 198 * It should be silently discarded for 199 * SIMPLEX interface. 200 */ |
201 ic->ic_stats.is_rx_mcastecho++; |
202 goto out; 203 } 204 break; 205 case IEEE80211_M_IBSS: 206 case IEEE80211_M_AHDEMO: |
207 if (dir != IEEE80211_FC1_DIR_NODS) { 208 ic->ic_stats.is_rx_wrongdir++; |
209 goto out; |
210 } |
211 break; 212 case IEEE80211_M_HOSTAP: |
213 if (dir != IEEE80211_FC1_DIR_TODS) { 214 ic->ic_stats.is_rx_wrongdir++; |
215 goto out; |
216 } |
217 /* check if source STA is associated */ 218 if (ni == ic->ic_bss) { 219 IEEE80211_DPRINTF(("%s: data from unknown src " 220 "%s\n", __func__, 221 ether_sprintf(wh->i_addr2))); 222 /* NB: caller deals with reference */ 223 ni = ieee80211_dup_bss(ic, wh->i_addr2); 224 if (ni != NULL) { 225 IEEE80211_SEND_MGMT(ic, ni, 226 IEEE80211_FC0_SUBTYPE_DEAUTH, 227 IEEE80211_REASON_NOT_AUTHED); 228 ieee80211_free_node(ic, ni); 229 } |
230 ic->ic_stats.is_rx_notassoc++; |
231 goto err; 232 } 233 if (ni->ni_associd == 0) { 234 IEEE80211_DPRINTF(("ieee80211_input: " 235 "data from unassoc src %s\n", 236 ether_sprintf(wh->i_addr2))); 237 IEEE80211_SEND_MGMT(ic, ni, 238 IEEE80211_FC0_SUBTYPE_DISASSOC, 239 IEEE80211_REASON_NOT_ASSOCED); 240 ieee80211_unref_node(&ni); |
241 ic->ic_stats.is_rx_notassoc++; |
242 goto err; 243 } 244 break; 245 case IEEE80211_M_MONITOR: 246 break; 247 } 248 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 249 if (ic->ic_flags & IEEE80211_F_WEPON) { 250 m = ieee80211_wep_crypt(ifp, m, 0); |
251 if (m == NULL) { 252 ic->ic_stats.is_rx_wepfail++; |
253 goto err; |
254 } |
255 wh = mtod(m, struct ieee80211_frame *); |
256 } else { 257 ic->ic_stats.is_rx_nowep++; |
258 goto out; |
259 } |
260 } 261 /* copy to listener after decrypt */ 262 if (ic->ic_rawbpf) 263 bpf_mtap(ic->ic_rawbpf, m); 264 m = ieee80211_decap(ifp, m); |
265 if (m == NULL) { 266 ic->ic_stats.is_rx_decap++; |
267 goto err; |
268 } |
269 ifp->if_ipackets++; 270 271 /* perform as a bridge within the AP */ 272 m1 = NULL; 273 if (ic->ic_opmode == IEEE80211_M_HOSTAP) { 274 eh = mtod(m, struct ether_header *); 275 if (ETHER_IS_MULTICAST(eh->ether_dhost)) { 276 m1 = m_copypacket(m, M_DONTWAIT); --- 24 unchanged lines hidden (view full) --- 301 ifp->if_obytes += len; 302 } 303 } 304 if (m != NULL) 305 (*ifp->if_input)(ifp, m); 306 return; 307 308 case IEEE80211_FC0_TYPE_MGT: |
309 if (dir != IEEE80211_FC1_DIR_NODS) { 310 ic->ic_stats.is_rx_wrongdir++; |
311 goto err; |
312 } 313 if (ic->ic_opmode == IEEE80211_M_AHDEMO) { 314 ic->ic_stats.is_rx_ahdemo_mgt++; |
315 goto out; |
316 } |
317 subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; 318 319 /* drop frames without interest */ 320 if (ic->ic_state == IEEE80211_S_SCAN) { 321 if (subtype != IEEE80211_FC0_SUBTYPE_BEACON && |
322 subtype != IEEE80211_FC0_SUBTYPE_PROBE_RESP) { 323 ic->ic_stats.is_rx_mgtdiscard++; |
324 goto out; |
325 } |
326 } else { 327 if (ic->ic_opmode != IEEE80211_M_IBSS && |
328 subtype == IEEE80211_FC0_SUBTYPE_BEACON) { 329 ic->ic_stats.is_rx_mgtdiscard++; |
330 goto out; |
331 } |
332 } 333 334 if (ifp->if_flags & IFF_DEBUG) { 335 /* avoid to print too many frames */ 336 int doprint = 0; 337 338 switch (subtype) { 339 case IEEE80211_FC0_SUBTYPE_BEACON: --- 19 unchanged lines hidden (view full) --- 359 } 360 if (ic->ic_rawbpf) 361 bpf_mtap(ic->ic_rawbpf, m); 362 (*ic->ic_recv_mgmt)(ic, m, ni, subtype, rssi, rstamp); 363 m_freem(m); 364 return; 365 366 case IEEE80211_FC0_TYPE_CTL: |
367 ic->ic_stats.is_rx_ctl++; |
368 goto out; 369 default: 370 IEEE80211_DPRINTF(("%s: bad type %x\n", __func__, type)); 371 /* should not come here */ 372 break; 373 } 374 err: 375 ifp->if_ierrors++; --- 123 unchanged lines hidden (view full) --- 499 * Tack on 11g extended supported rate element. 500 */ 501 nxrates = xrates[1]; 502 if (rs->rs_nrates + nxrates > IEEE80211_RATE_MAXSIZE) { 503 nxrates = IEEE80211_RATE_MAXSIZE - rs->rs_nrates; 504 IEEE80211_DPRINTF(("%s: extended rate set too large;" 505 " only using %u of %u rates\n", 506 __func__, nxrates, xrates[1])); |
507 ic->ic_stats.is_rx_rstoobig++; |
508 } 509 memcpy(rs->rs_rates + rs->rs_nrates, xrates+2, nxrates); 510 rs->rs_nrates += nxrates; 511 } 512 return ieee80211_fix_rate(ic, ni, flags); 513} 514 |
515/* Verify the existence and length of __elem or get out. */ 516#define IEEE80211_VERIFY_ELEMENT(__elem, __maxlen) do { \ 517 if ((__elem) == NULL) { \ 518 IEEE80211_DPRINTF(("%s: no " #__elem "in %s frame\n", \ 519 __func__, ieee80211_mgt_subtype_name[subtype >> \ 520 IEEE80211_FC0_SUBTYPE_SHIFT])); \ |
521 ic->ic_stats.is_rx_elem_missing++; \ |
522 return; \ 523 } \ 524 if ((__elem)[1] > (__maxlen)) { \ 525 IEEE80211_DPRINTF(("%s: bad " #__elem " len %d in %s " \ 526 "frame from %s\n", __func__, (__elem)[1], \ 527 ieee80211_mgt_subtype_name[subtype >> \ 528 IEEE80211_FC0_SUBTYPE_SHIFT], \ 529 ether_sprintf(wh->i_addr2))); \ |
530 ic->ic_stats.is_rx_elem_toobig++; \ |
531 return; \ 532 } \ 533} while (0) 534 535#define IEEE80211_VERIFY_LENGTH(_len, _minlen) do { \ 536 if ((_len) < (_minlen)) { \ 537 IEEE80211_DPRINTF(("%s: %s frame too short from %s\n", \ 538 __func__, \ 539 ieee80211_mgt_subtype_name[subtype >> \ 540 IEEE80211_FC0_SUBTYPE_SHIFT], \ 541 ether_sprintf(wh->i_addr2))); \ |
542 ic->ic_stats.is_rx_elem_toosmall++; \ |
543 return; \ 544 } \ 545} while (0) 546 547void 548ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0, 549 struct ieee80211_node *ni, 550 int subtype, int rssi, u_int32_t rstamp) --- 74 unchanged lines hidden (view full) --- 625 case IEEE80211_ELEMID_XRATES: 626 xrates = frm; 627 break; 628 case IEEE80211_ELEMID_ERP: 629 if (frm[1] != 1) { 630 IEEE80211_DPRINTF(("%s: invalid ERP " 631 "element; length %u, expecting " 632 "1\n", __func__, frm[1])); |
633 ic->ic_stats.is_rx_elem_toobig++; |
634 break; 635 } 636 erp = frm[2]; 637 break; 638 default: 639 IEEE80211_DPRINTF2(("%s: element id %u/len %u " 640 "ignored\n", __func__, *frm, frm[1])); |
641 ic->ic_stats.is_rx_elem_unknown++; |
642 break; 643 } 644 frm += frm[1] + 2; 645 } 646 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE); 647 IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN); 648 if ( 649#if IEEE80211_CHAN_MAX < 255 650 chan > IEEE80211_CHAN_MAX || 651#endif 652 isclr(ic->ic_chan_active, chan)) { 653 IEEE80211_DPRINTF(("%s: ignore %s with invalid channel " 654 "%u\n", __func__, 655 ISPROBE(subtype) ? "probe response" : "beacon", 656 chan)); |
657 ic->ic_stats.is_rx_badchan++; |
658 return; 659 } 660 if (chan != bchan) { 661 /* 662 * Frame was received on a channel different from the 663 * one indicated in the DS/FH params element id; 664 * silently discard it. 665 * 666 * NB: this can happen due to signal leakage. 667 */ 668 IEEE80211_DPRINTF(("%s: ignore %s on channel %u marked " 669 "for channel %u\n", __func__, 670 ISPROBE(subtype) ? "probe response" : "beacon", 671 bchan, chan)); |
672 ic->ic_stats.is_rx_chanmismatch++; |
673 return; 674 } 675 676 /* 677 * Use mac and channel for lookup so we collect all 678 * potential AP's when scanning. Otherwise we may 679 * see the same AP on multiple channels and will only 680 * record the last one. We could filter APs here based --- 18 unchanged lines hidden (view full) --- 699 le16toh(*(u_int16_t *)bintval), erp); 700 if (country) 701 printf("%s: country info %*D\n", 702 __func__, country[1], country+2, " "); 703 } 704#endif 705 if (ni == NULL) { 706 ni = ieee80211_alloc_node(ic, wh->i_addr2); |
707 if (ni == NULL) { 708 ic->ic_stats.is_rx_nodealloc++; |
709 return; |
710 } |
711 ni->ni_esslen = ssid[1]; 712 memset(ni->ni_essid, 0, sizeof(ni->ni_essid)); 713 memcpy(ni->ni_essid, ssid + 2, ssid[1]); 714 } else if (ssid[1] != 0 && ISPROBE(subtype)) { 715 /* 716 * Update ESSID at probe response to adopt hidden AP by 717 * Lucent/Cisco, which announces null ESSID in beacon. 718 */ --- 54 unchanged lines hidden (view full) --- 773 memcmp(ssid + 2, ic->ic_bss->ni_essid, ic->ic_bss->ni_esslen) != 0)) { 774#ifdef IEEE80211_DEBUG 775 if (ieee80211_debug) { 776 printf("%s: ssid unmatch ", __func__); 777 ieee80211_print_essid(ssid + 2, ssid[1]); 778 printf(" from %s\n", ether_sprintf(wh->i_addr2)); 779 } 780#endif |
781 ic->ic_stats.is_rx_ssidmismatch++; |
782 return; 783 } 784 785 if (ni == ic->ic_bss) { 786 ni = ieee80211_dup_bss(ic, wh->i_addr2); |
787 if (ni == NULL) { 788 ic->ic_stats.is_rx_nodealloc++; |
789 return; |
790 } |
791 IEEE80211_DPRINTF(("%s: new req from %s\n", 792 __func__, ether_sprintf(wh->i_addr2))); 793 allocbs = 1; 794 } else 795 allocbs = 0; 796 ni->ni_rssi = rssi; 797 ni->ni_rstamp = rstamp; 798 rate = ieee80211_setup_rates(ic, ni, rates, xrates, --- 28 unchanged lines hidden (view full) --- 827 IEEE80211_VERIFY_LENGTH(efrm - frm, 6); 828 algo = le16toh(*(u_int16_t *)frm); 829 seq = le16toh(*(u_int16_t *)(frm + 2)); 830 status = le16toh(*(u_int16_t *)(frm + 4)); 831 if (algo != IEEE80211_AUTH_ALG_OPEN) { 832 /* TODO: shared key auth */ 833 IEEE80211_DPRINTF(("%s: unsupported auth %d from %s\n", 834 __func__, algo, ether_sprintf(wh->i_addr2))); |
835 ic->ic_stats.is_rx_auth_unsupported++; |
836 return; 837 } |
838 if (ic->ic_state != IEEE80211_S_RUN) { 839 IEEE80211_DPRINTF(("%s: discard auth from %s; " 840 "state %u\n", __func__, 841 ether_sprintf(wh->i_addr2), ic->ic_state)); 842 ic->ic_stats.is_rx_bad_auth++; 843 break; 844 } 845 if (seq != (ic->ic_opmode == IEEE80211_M_STA ? 2 : 1)) { 846 IEEE80211_DPRINTF(("%s: discard auth from %s; seq %u\n", 847 __func__, ether_sprintf(wh->i_addr2), seq)); 848 ic->ic_stats.is_rx_bad_auth++; 849 break; 850 } |
851 switch (ic->ic_opmode) { 852 case IEEE80211_M_IBSS: |
853 ieee80211_new_state(ic, IEEE80211_S_AUTH, 854 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 855 break; 856 857 case IEEE80211_M_AHDEMO: 858 /* should not come here */ 859 break; 860 861 case IEEE80211_M_HOSTAP: |
862 if (ni == ic->ic_bss) { 863 ni = ieee80211_alloc_node(ic, wh->i_addr2); |
864 if (ni == NULL) { 865 ic->ic_stats.is_rx_nodealloc++; |
866 return; |
867 } |
868 IEEE80211_ADDR_COPY(ni->ni_bssid, ic->ic_bss->ni_bssid); 869 ni->ni_rssi = rssi; 870 ni->ni_rstamp = rstamp; 871 ni->ni_chan = ic->ic_bss->ni_chan; 872 allocbs = 1; 873 } else 874 allocbs = 0; 875 IEEE80211_SEND_MGMT(ic, ni, 876 IEEE80211_FC0_SUBTYPE_AUTH, 2); 877 if (ifp->if_flags & IFF_DEBUG) 878 if_printf(ifp, "station %s %s authenticated\n", 879 (allocbs ? "newly" : "already"), 880 ether_sprintf(ni->ni_macaddr)); 881 break; 882 883 case IEEE80211_M_STA: |
884 if (status != 0) { 885 if_printf(&ic->ic_if, 886 "authentication failed (reason %d) for %s\n", 887 status, 888 ether_sprintf(wh->i_addr3)); 889 if (ni != ic->ic_bss) 890 ni->ni_fails++; |
891 ic->ic_stats.is_rx_auth_fail++; |
892 return; 893 } 894 ieee80211_new_state(ic, IEEE80211_S_ASSOC, 895 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 896 break; 897 case IEEE80211_M_MONITOR: 898 break; 899 } --- 23 unchanged lines hidden (view full) --- 923 * [tlv] ssid 924 * [tlv] supported rates 925 * [tlv] extended supported rates 926 */ 927 IEEE80211_VERIFY_LENGTH(efrm - frm, (reassoc ? 10 : 4)); 928 if (!IEEE80211_ADDR_EQ(wh->i_addr3, ic->ic_bss->ni_bssid)) { 929 IEEE80211_DPRINTF(("%s: ignore other bss from %s\n", 930 __func__, ether_sprintf(wh->i_addr2))); |
931 ic->ic_stats.is_rx_assoc_bss++; |
932 return; 933 } 934 capinfo = le16toh(*(u_int16_t *)frm); frm += 2; 935 bintval = le16toh(*(u_int16_t *)frm); frm += 2; 936 if (reassoc) 937 frm += 6; /* ignore current AP info */ 938 ssid = rates = xrates = NULL; 939 while (frm < efrm) { --- 16 unchanged lines hidden (view full) --- 956 memcmp(ssid + 2, ic->ic_bss->ni_essid, ssid[1]) != 0) { 957#ifdef IEEE80211_DEBUG 958 if (ieee80211_debug) { 959 printf("%s: ssid unmatch ", __func__); 960 ieee80211_print_essid(ssid + 2, ssid[1]); 961 printf(" from %s\n", ether_sprintf(wh->i_addr2)); 962 } 963#endif |
964 ic->ic_stats.is_rx_ssidmismatch++; |
965 return; 966 } 967 if (ni == ic->ic_bss) { 968 IEEE80211_DPRINTF(("%s: not authenticated for %s\n", 969 __func__, ether_sprintf(wh->i_addr2))); 970 ni = ieee80211_dup_bss(ic, wh->i_addr2); 971 if (ni != NULL) { 972 IEEE80211_SEND_MGMT(ic, ni, 973 IEEE80211_FC0_SUBTYPE_DEAUTH, 974 IEEE80211_REASON_ASSOC_NOT_AUTHED); 975 ieee80211_free_node(ic, ni); 976 } |
977 ic->ic_stats.is_rx_assoc_notauth++; |
978 return; 979 } 980 /* XXX per-node cipher suite */ 981 /* XXX some stations use the privacy bit for handling APs 982 that suport both encrypted and unencrypted traffic */ 983 if ((capinfo & IEEE80211_CAPINFO_ESS) == 0 || 984 (capinfo & IEEE80211_CAPINFO_PRIVACY) != 985 ((ic->ic_flags & IEEE80211_F_WEPON) ? 986 IEEE80211_CAPINFO_PRIVACY : 0)) { 987 IEEE80211_DPRINTF(("%s: capability mismatch %x for %s\n", 988 __func__, capinfo, ether_sprintf(wh->i_addr2))); 989 ni->ni_associd = 0; 990 IEEE80211_SEND_MGMT(ic, ni, resp, 991 IEEE80211_STATUS_CAPINFO); |
992 ic->ic_stats.is_rx_assoc_capmismatch++; |
993 return; 994 } 995 ieee80211_setup_rates(ic, ni, rates, xrates, 996 IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE | 997 IEEE80211_F_DONEGO | IEEE80211_F_DODEL); 998 if (ni->ni_rates.rs_nrates == 0) { 999 IEEE80211_DPRINTF(("%s: rate unmatch for %s\n", 1000 __func__, ether_sprintf(wh->i_addr2))); 1001 ni->ni_associd = 0; 1002 IEEE80211_SEND_MGMT(ic, ni, resp, 1003 IEEE80211_STATUS_BASIC_RATE); |
1004 ic->ic_stats.is_rx_assoc_norate++; |
1005 return; 1006 } 1007 ni->ni_rssi = rssi; 1008 ni->ni_rstamp = rstamp; 1009 ni->ni_intval = bintval; 1010 ni->ni_capinfo = capinfo; 1011 ni->ni_chan = ic->ic_bss->ni_chan; 1012 ni->ni_fhdwell = ic->ic_bss->ni_fhdwell; --- 41 unchanged lines hidden (view full) --- 1054 1055 status = le16toh(*(u_int16_t *)frm); 1056 frm += 2; 1057 if (status != 0) { 1058 if_printf(ifp, "association failed (reason %d) for %s\n", 1059 status, ether_sprintf(wh->i_addr3)); 1060 if (ni != ic->ic_bss) 1061 ni->ni_fails++; |
1062 ic->ic_stats.is_rx_auth_fail++; |
1063 return; 1064 } 1065 ni->ni_associd = le16toh(*(u_int16_t *)frm); 1066 frm += 2; 1067 1068 rates = xrates = NULL; 1069 while (frm < efrm) { 1070 switch (*frm) { --- 20 unchanged lines hidden (view full) --- 1091 case IEEE80211_FC0_SUBTYPE_DEAUTH: { 1092 u_int16_t reason; 1093 /* 1094 * deauth frame format 1095 * [2] reason 1096 */ 1097 IEEE80211_VERIFY_LENGTH(efrm - frm, 2); 1098 reason = le16toh(*(u_int16_t *)frm); |
1099 ic->ic_stats.is_rx_deauth++; |
1100 switch (ic->ic_opmode) { 1101 case IEEE80211_M_STA: 1102 ieee80211_new_state(ic, IEEE80211_S_AUTH, 1103 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 1104 break; 1105 case IEEE80211_M_HOSTAP: 1106 if (ni != ic->ic_bss) { 1107 if (ifp->if_flags & IFF_DEBUG) --- 13 unchanged lines hidden (view full) --- 1121 case IEEE80211_FC0_SUBTYPE_DISASSOC: { 1122 u_int16_t reason; 1123 /* 1124 * disassoc frame format 1125 * [2] reason 1126 */ 1127 IEEE80211_VERIFY_LENGTH(efrm - frm, 2); 1128 reason = le16toh(*(u_int16_t *)frm); |
1129 ic->ic_stats.is_rx_disassoc++; |
1130 switch (ic->ic_opmode) { 1131 case IEEE80211_M_STA: 1132 ieee80211_new_state(ic, IEEE80211_S_ASSOC, 1133 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 1134 break; 1135 case IEEE80211_M_HOSTAP: 1136 if (ni != ic->ic_bss) { 1137 if (ifp->if_flags & IFF_DEBUG) --- 7 unchanged lines hidden (view full) --- 1145 default: 1146 break; 1147 } 1148 break; 1149 } 1150 default: 1151 IEEE80211_DPRINTF(("%s: mgmt frame with subtype 0x%x not " 1152 "handled\n", __func__, subtype)); |
1153 ic->ic_stats.is_rx_badsubtype++; |
1154 break; 1155 } 1156#undef ISPROBE 1157} 1158#undef IEEE80211_VERIFY_LENGTH 1159#undef IEEE80211_VERIFY_ELEMENT |