Lines Matching +full:bypass +full:- +full:slot +full:- +full:no
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (c) 2007-2008 Sam Leffler, Errno Consulting
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
79 ic->ic_vattach[IEEE80211_M_HOSTAP] = hostap_vattach; in ieee80211_hostap_attach()
95 vap->iv_newstate = hostap_newstate; in hostap_vattach()
96 vap->iv_input = hostap_input; in hostap_vattach()
97 vap->iv_recv_mgmt = hostap_recv_mgmt; in hostap_vattach()
98 vap->iv_recv_ctl = hostap_recv_ctl; in hostap_vattach()
99 vap->iv_opdetach = hostap_vdetach; in hostap_vattach()
100 vap->iv_deliver_data = hostap_deliver_data; in hostap_vattach()
101 vap->iv_recv_pspoll = ieee80211_recv_pspoll; in hostap_vattach()
108 if (ni->ni_associd != 0) { in sta_disassoc()
118 struct ieee80211vap *vap = ni->ni_vap; in sta_csa()
120 if (ni->ni_associd != 0) in sta_csa()
121 if (ni->ni_inact > vap->iv_inact_init) { in sta_csa()
122 ni->ni_inact = vap->iv_inact_init; in sta_csa()
124 "%s: inact %u", __func__, ni->ni_inact); in sta_csa()
132 if (ni->ni_associd != 0) in sta_drop()
137 * Does a channel change require associated stations to re-associate
139 * bands or similar (e.g. HT -> legacy).
144 return ((ic->ic_bsschan->ic_flags ^ ic->ic_csa_newchan->ic_flags) & in isbandchange()
155 struct ieee80211com *ic = vap->iv_ic; in hostap_newstate()
160 ostate = vap->iv_state; in hostap_newstate()
161 IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, "%s: %s -> %s (%d)\n", in hostap_newstate()
164 vap->iv_state = nstate; /* state transition */ in hostap_newstate()
177 ieee80211_iterate_nodes_vap(&ic->ic_sta, vap, in hostap_newstate()
184 /* NB: optimize INIT -> INIT case */ in hostap_newstate()
187 if (vap->iv_auth->ia_detach != NULL) in hostap_newstate()
188 vap->iv_auth->ia_detach(vap); in hostap_newstate()
194 ieee80211_iterate_nodes_vap(&ic->ic_sta, vap, in hostap_newstate()
202 vap->iv_flags_ext &= ~IEEE80211_FEXT_NONERP_PR; in hostap_newstate()
203 vap->iv_flags_ht &= ~IEEE80211_FHT_NONHT_PR; in hostap_newstate()
210 * XXX no need to stop if ostate RUN but it's ok in hostap_newstate()
215 if (vap->iv_des_chan != IEEE80211_CHAN_ANYC && in hostap_newstate()
216 !IEEE80211_IS_CHAN_RADAR(vap->iv_des_chan)) { in hostap_newstate()
218 * Already have a channel; bypass the in hostap_newstate()
223 ieee80211_create_ibss(vap, vap->iv_des_chan); in hostap_newstate()
233 if (vap->iv_flags_ext & IEEE80211_FEXT_SCANREQ) { in hostap_newstate()
235 vap->iv_scanreq_flags, in hostap_newstate()
236 vap->iv_scanreq_duration, in hostap_newstate()
237 vap->iv_scanreq_mindwell, in hostap_newstate()
238 vap->iv_scanreq_maxdwell, in hostap_newstate()
239 vap->iv_scanreq_nssid, vap->iv_scanreq_ssid); in hostap_newstate()
240 vap->iv_flags_ext &= ~IEEE80211_FEXT_SCANREQ; in hostap_newstate()
262 if (vap->iv_flags & IEEE80211_F_WPA) { in hostap_newstate()
268 * Already have a channel; bypass the in hostap_newstate()
271 * back to do a RUN->RUN state change. in hostap_newstate()
275 ic->ic_curchan, vap->iv_flags_ht)); in hostap_newstate()
281 * expires and no radar was detected; no need to in hostap_newstate()
290 ieee80211_iterate_nodes_vap(&ic->ic_sta, vap, in hostap_newstate()
296 ieee80211_node_set_chan(vap->iv_bss, in hostap_newstate()
297 ieee80211_ht_adjust_channel(ic, ic->ic_curchan, in hostap_newstate()
298 ieee80211_htchanflags(vap->iv_bss->ni_chan))); in hostap_newstate()
299 /* XXX bypass debug msgs */ in hostap_newstate()
305 struct ieee80211_node *ni = vap->iv_bss; in hostap_newstate()
308 ether_sprintf(ni->ni_bssid)); in hostap_newstate()
309 ieee80211_print_essid(ni->ni_essid, in hostap_newstate()
310 ni->ni_esslen); in hostap_newstate()
312 ieee80211_chan2ieee(ic, ic->ic_curchan), in hostap_newstate()
324 if (vap->iv_auth->ia_attach != NULL) { in hostap_newstate()
326 vap->iv_auth->ia_attach(vap); in hostap_newstate()
327 } else if (vap->iv_auth->ia_detach != NULL) { in hostap_newstate()
328 vap->iv_auth->ia_detach(vap); in hostap_newstate()
330 ieee80211_node_authorize(vap->iv_bss); in hostap_newstate()
336 * stations as they must re-associate before they in hostap_newstate()
341 ieee80211_iterate_nodes_vap(&ic->ic_sta, vap, in hostap_newstate()
356 struct ifnet *ifp = vap->iv_ifp; in hostap_deliver_data()
359 m->m_flags &= ~(M_MCAST | M_BCAST); in hostap_deliver_data()
362 KASSERT(vap->iv_opmode == IEEE80211_M_HOSTAP, in hostap_deliver_data()
363 ("gack, opmode %d", vap->iv_opmode)); in hostap_deliver_data()
369 IEEE80211_NODE_STAT_ADD(ni, rx_bytes, m->m_pkthdr.len); in hostap_deliver_data()
370 if (ETHER_IS_MULTICAST(eh->ether_dhost)) { in hostap_deliver_data()
371 m->m_flags |= M_MCAST; /* XXX M_BCAST? */ in hostap_deliver_data()
377 if ((vap->iv_flags & IEEE80211_F_NOBRIDGE) == 0) { in hostap_deliver_data()
380 if (m->m_flags & M_MCAST) { in hostap_deliver_data()
385 mcopy->m_flags |= M_MCAST; in hostap_deliver_data()
395 &vap->iv_ic->ic_sta, vap, eh->ether_dhost); in hostap_deliver_data()
403 if (sta != vap->iv_bss) { in hostap_deliver_data()
408 vap->iv_stats.is_rx_unauth++; in hostap_deliver_data()
421 m->m_pkthdr.rcvif = ifp; in hostap_deliver_data()
422 if (m->m_flags & M_MCAST) { in hostap_deliver_data()
429 if (ni->ni_vlan != 0) { in hostap_deliver_data()
431 m->m_pkthdr.ether_vtag = ni->ni_vlan; in hostap_deliver_data()
432 m->m_flags |= M_VLANTAG; in hostap_deliver_data()
450 return (vap->iv_ic->ic_flags & IEEE80211_F_SCAN); in doprint()
471 struct ieee80211vap *vap = ni->ni_vap; in hostap_input()
472 struct ieee80211com *ic = ni->ni_ic; in hostap_input()
473 struct ifnet *ifp = vap->iv_ifp; in hostap_input()
488 if ((rxs != NULL) && (rxs->c_pktflags & IEEE80211_RX_F_DECRYPTED)) in hostap_input()
491 if (m->m_flags & M_AMPDU_MPDU) { in hostap_input()
493 * Fastpath for A-MPDU reorder q resubmission. Frames in hostap_input()
497 * with the M_AMPDU_MPDU flag and we can bypass most of in hostap_input()
502 dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK; in hostap_input()
509 ni->ni_inact = ni->ni_inact_reload; in hostap_input()
511 type = -1; /* undefined */ in hostap_input()
513 if (m->m_pkthdr.len < sizeof(struct ieee80211_frame_min)) { in hostap_input()
515 ni->ni_macaddr, NULL, in hostap_input()
516 "too short (1): len %u", m->m_pkthdr.len); in hostap_input()
517 vap->iv_stats.is_rx_tooshort++; in hostap_input()
521 * Bit of a cheat here, we use a pointer for a 3-address in hostap_input()
530 ni->ni_macaddr, NULL, "wrong version, fc %02x:%02x", in hostap_input()
531 wh->i_fc[0], wh->i_fc[1]); in hostap_input()
532 vap->iv_stats.is_rx_badversion++; in hostap_input()
536 dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK; in hostap_input()
537 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; in hostap_input()
538 subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; in hostap_input()
539 if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) { in hostap_input()
541 bssid = wh->i_addr1; in hostap_input()
543 bssid = wh->i_addr1; in hostap_input()
545 if (m->m_pkthdr.len < sizeof(struct ieee80211_frame)) { in hostap_input()
547 IEEE80211_MSG_ANY, ni->ni_macaddr, in hostap_input()
549 m->m_pkthdr.len); in hostap_input()
550 vap->iv_stats.is_rx_tooshort++; in hostap_input()
553 bssid = wh->i_addr3; in hostap_input()
560 !IEEE80211_ADDR_EQ(bssid, vap->iv_bss->ni_bssid) && in hostap_input()
566 vap->iv_stats.is_rx_wrongbss++; in hostap_input()
570 IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi); in hostap_input()
571 ni->ni_noise = nf; in hostap_input()
576 ic->ic_wme.wme_hipri_traffic++; in hostap_input()
585 if (m->m_len < hdrspace && in hostap_input()
588 ni->ni_macaddr, NULL, in hostap_input()
590 vap->iv_stats.is_rx_tooshort++; in hostap_input()
595 (vap->iv_flags & IEEE80211_F_DWDS)))) { in hostap_input()
604 "4-address data", in hostap_input()
607 vap->iv_stats.is_rx_wrongdir++; in hostap_input()
611 if (ni == vap->iv_bss) { in hostap_input()
614 ieee80211_send_error(ni, wh->i_addr2, in hostap_input()
617 vap->iv_stats.is_rx_notassoc++; in hostap_input()
620 if (ni->ni_associd == 0) { in hostap_input()
626 vap->iv_stats.is_rx_notassoc++; in hostap_input()
632 * XXX out-of-order A-MPDU frames? in hostap_input()
634 if (((wh->i_fc[1] & IEEE80211_FC1_PWR_MGT) ^ in hostap_input()
635 (ni->ni_flags & IEEE80211_NODE_PWR_MGT))) in hostap_input()
636 vap->iv_node_ps(ni, in hostap_input()
637 wh->i_fc[1] & IEEE80211_FC1_PWR_MGT); in hostap_input()
639 * For 4-address packets handle WDS discovery in hostap_input()
643 if (dir == IEEE80211_FC1_DIR_DSTODS && ni->ni_wdsvap == NULL) { in hostap_input()
648 "4-address data", in hostap_input()
650 vap->iv_stats.is_rx_unauth++; in hostap_input()
659 * Handle A-MPDU re-ordering. If the frame is to be in hostap_input()
664 if ((m->m_flags & M_AMPDU) && in hostap_input()
680 if ((vap->iv_flags & IEEE80211_F_PRIVACY) == 0) { in hostap_input()
686 vap->iv_stats.is_rx_noprivacy++; in hostap_input()
696 wh->i_fc[1] &= ~IEEE80211_FC1_PROTECTED; in hostap_input()
704 * Save QoS bits for use below--before we strip the header. in hostap_input()
714 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { in hostap_input()
721 wh = NULL; /* no longer valid, catch any uses */ in hostap_input()
728 ni->ni_macaddr, "data", "%s", "demic error"); in hostap_input()
729 vap->iv_stats.is_rx_demicfail++; in hostap_input()
748 ni->ni_macaddr, "data", "%s", "decap error"); in hostap_input()
749 vap->iv_stats.is_rx_decap++; in hostap_input()
759 * Deny any non-PAE frames received prior to in hostap_input()
760 * authorization. For open/shared-key in hostap_input()
767 eh->ether_type != htons(ETHERTYPE_PAE)) { in hostap_input()
769 ni->ni_macaddr, "data", "unauthorized or " in hostap_input()
771 eh == NULL ? -1 : eh->ether_type, in hostap_input()
772 m->m_pkthdr.len); in hostap_input()
773 vap->iv_stats.is_rx_unauth++; in hostap_input()
780 * any non-PAE frames received without encryption. in hostap_input()
782 if ((vap->iv_flags & IEEE80211_F_DROPUNENC) && in hostap_input()
783 ((has_decrypted == 0) && (m->m_flags & M_WEP) == 0) && in hostap_input()
786 eh->ether_type != htons(ETHERTYPE_PAE))) { in hostap_input()
790 vap->iv_stats.is_rx_unencrypted++; in hostap_input()
807 if (dir == IEEE80211_FC1_DIR_DSTODS && ni->ni_wdsvap != NULL) in hostap_input()
808 ieee80211_deliver_data(ni->ni_wdsvap, ni, m); in hostap_input()
814 vap->iv_stats.is_rx_mgmt++; in hostap_input()
819 vap->iv_stats.is_rx_wrongdir++; in hostap_input()
822 if (m->m_pkthdr.len < sizeof(struct ieee80211_frame)) { in hostap_input()
824 ni->ni_macaddr, "mgt", "too short: len %u", in hostap_input()
825 m->m_pkthdr.len); in hostap_input()
826 vap->iv_stats.is_rx_tooshort++; in hostap_input()
829 if (IEEE80211_IS_MULTICAST(wh->i_addr2)) { in hostap_input()
833 ether_sprintf(wh->i_addr2)); in hostap_input()
834 vap->iv_stats.is_rx_mgtdiscard++; /* XXX stat */ in hostap_input()
843 ether_sprintf(wh->i_addr2), rssi); in hostap_input()
855 vap->iv_stats.is_rx_mgtdiscard++; /* XXX */ in hostap_input()
858 if ((vap->iv_flags & IEEE80211_F_PRIVACY) == 0) { in hostap_input()
864 vap->iv_stats.is_rx_noprivacy++; in hostap_input()
873 wh->i_fc[1] &= ~IEEE80211_FC1_PROTECTED; in hostap_input()
884 vap->iv_recv_mgmt(ni, m, subtype, rxs, rssi, nf); in hostap_input()
888 vap->iv_stats.is_rx_ctl++; in hostap_input()
891 vap->iv_recv_ctl(ni, m, subtype); in hostap_input()
914 struct ieee80211vap *vap = ni->ni_vap; in hostap_auth_open()
916 KASSERT(vap->iv_state == IEEE80211_S_RUN, ("state %d", vap->iv_state)); in hostap_auth_open()
918 if (ni->ni_authmode == IEEE80211_AUTH_SHARED) { in hostap_auth_open()
920 ni->ni_macaddr, "open auth", in hostap_auth_open()
921 "bad sta auth mode %u", ni->ni_authmode); in hostap_auth_open()
922 vap->iv_stats.is_rx_bad_auth++; /* XXX */ in hostap_auth_open()
928 if (ni->ni_challenge != NULL) { in hostap_auth_open()
929 IEEE80211_FREE(ni->ni_challenge, M_80211_NODE); in hostap_auth_open()
930 ni->ni_challenge = NULL; in hostap_auth_open()
933 ieee80211_send_error(ni, wh->i_addr2, in hostap_auth_open()
939 vap->iv_stats.is_rx_bad_auth++; in hostap_auth_open()
943 if (ni == vap->iv_bss) { in hostap_auth_open()
944 ni = ieee80211_dup_bss(vap, wh->i_addr2); in hostap_auth_open()
947 } else if ((ni->ni_flags & IEEE80211_NODE_AREF) == 0) in hostap_auth_open()
954 ni->ni_flags |= IEEE80211_NODE_AREF; in hostap_auth_open()
959 ni->ni_flags |= IEEE80211_NODE_ASSOCID; in hostap_auth_open()
961 if (vap->iv_acl != NULL && in hostap_auth_open()
962 vap->iv_acl->iac_getpolicy(vap) == IEEE80211_MACCMD_POLICY_RADIUS) { in hostap_auth_open()
971 IEEE80211_MSG_AUTH | IEEE80211_MSG_ACL, ni->ni_macaddr, in hostap_auth_open()
977 IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH, ni->ni_macaddr, in hostap_auth_open()
983 if (ni->ni_authmode != IEEE80211_AUTH_8021X) in hostap_auth_open()
993 struct ieee80211vap *vap = ni->ni_vap; in hostap_auth_shared()
997 KASSERT(vap->iv_state == IEEE80211_S_RUN, ("state %d", vap->iv_state)); in hostap_auth_shared()
1000 * NB: this can happen as we allow pre-shared key in hostap_auth_shared()
1007 if ((vap->iv_flags & IEEE80211_F_PRIVACY) == 0) { in hostap_auth_shared()
1009 ni->ni_macaddr, "shared key auth", in hostap_auth_shared()
1015 * Pre-shared key authentication is evil; accept in hostap_auth_shared()
1019 if (ni->ni_authmode != IEEE80211_AUTH_AUTO && in hostap_auth_shared()
1020 ni->ni_authmode != IEEE80211_AUTH_SHARED) { in hostap_auth_shared()
1022 ni->ni_macaddr, "shared key auth", in hostap_auth_shared()
1023 "bad sta auth mode %u", ni->ni_authmode); in hostap_auth_shared()
1024 vap->iv_stats.is_rx_bad_auth++; /* XXX maybe a unique error? */ in hostap_auth_shared()
1031 if ((frm[1] + 2) > (efrm - frm)) { in hostap_auth_shared()
1033 ni->ni_macaddr, "shared key auth", in hostap_auth_shared()
1035 frm[0], (frm[1] + 2) - (efrm - frm)); in hostap_auth_shared()
1036 vap->iv_stats.is_rx_bad_auth++; in hostap_auth_shared()
1049 ni->ni_macaddr, "shared key auth", in hostap_auth_shared()
1050 "%s", "no challenge"); in hostap_auth_shared()
1051 vap->iv_stats.is_rx_bad_auth++; in hostap_auth_shared()
1057 ni->ni_macaddr, "shared key auth", in hostap_auth_shared()
1059 vap->iv_stats.is_rx_bad_auth++; in hostap_auth_shared()
1073 if (ni == vap->iv_bss) { in hostap_auth_shared()
1074 ni = ieee80211_dup_bss(vap, wh->i_addr2); in hostap_auth_shared()
1076 /* NB: no way to return an error */ in hostap_auth_shared()
1083 if ((ni->ni_flags & IEEE80211_NODE_AREF) == 0) in hostap_auth_shared()
1094 ni->ni_flags |= IEEE80211_NODE_AREF; in hostap_auth_shared()
1099 ni->ni_flags |= IEEE80211_NODE_ASSOCID; in hostap_auth_shared()
1100 IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi); in hostap_auth_shared()
1101 ni->ni_noise = nf; in hostap_auth_shared()
1106 net80211_get_random_bytes(ni->ni_challenge, in hostap_auth_shared()
1117 if (vap->iv_acl != NULL && in hostap_auth_shared()
1118 vap->iv_acl->iac_getpolicy(vap) == IEEE80211_MACCMD_POLICY_RADIUS) { in hostap_auth_shared()
1121 ni->ni_macaddr, in hostap_auth_shared()
1129 if (ni == vap->iv_bss) { in hostap_auth_shared()
1131 ni->ni_macaddr, "shared key response", in hostap_auth_shared()
1136 if (ni->ni_challenge == NULL) { in hostap_auth_shared()
1138 ni->ni_macaddr, "shared key response", in hostap_auth_shared()
1139 "%s", "no challenge recorded"); in hostap_auth_shared()
1140 vap->iv_stats.is_rx_bad_auth++; in hostap_auth_shared()
1144 if (memcmp(ni->ni_challenge, &challenge[2], in hostap_auth_shared()
1147 ni->ni_macaddr, "shared key response", in hostap_auth_shared()
1149 vap->iv_stats.is_rx_auth_fail++; in hostap_auth_shared()
1159 ni->ni_macaddr, "shared key auth", in hostap_auth_shared()
1161 vap->iv_stats.is_rx_bad_auth++; in hostap_auth_shared()
1172 ieee80211_send_error(ni, wh->i_addr2, in hostap_auth_shared()
1208 /* Note: no GCM cipher in the legacy WPA1 OUI */ in wpa_cipher()
1256 * Other, variable-length data, must be checked separately. in ieee80211_parse_wpa()
1258 if ((vap->iv_flags & IEEE80211_F_WPA1) == 0) { in ieee80211_parse_wpa()
1261 wh, "WPA", "not WPA, flags 0x%x", vap->iv_flags); in ieee80211_parse_wpa()
1270 frm += 6, len -= 4; /* NB: len is payload only */ in ieee80211_parse_wpa()
1279 frm += 2, len -= 2; in ieee80211_parse_wpa()
1284 error = wpa_cipher(frm, &rsn->rsn_mcastkeylen, &rsn->rsn_mcastcipher); in ieee80211_parse_wpa()
1292 frm += 4, len -= 4; in ieee80211_parse_wpa()
1296 frm += 2, len -= 2; in ieee80211_parse_wpa()
1305 for (; n > 0; n--) { in ieee80211_parse_wpa()
1308 error = wpa_cipher(frm, &rsn->rsn_ucastkeylen, &cipher); in ieee80211_parse_wpa()
1312 frm += 4, len -= 4; in ieee80211_parse_wpa()
1317 wh, "WPA", "no usable pairwise cipher suite found (w=%d)", in ieee80211_parse_wpa()
1323 rsn->rsn_ucastcipher = IEEE80211_CIPHER_AES_CCM; in ieee80211_parse_wpa()
1325 rsn->rsn_ucastcipher = IEEE80211_CIPHER_TKIP; in ieee80211_parse_wpa()
1329 frm += 2, len -= 2; in ieee80211_parse_wpa()
1338 for (; n > 0; n--) { in ieee80211_parse_wpa()
1340 frm += 4, len -= 4; in ieee80211_parse_wpa()
1343 rsn->rsn_keymgmt = WPA_ASE_8021X_UNSPEC; in ieee80211_parse_wpa()
1345 rsn->rsn_keymgmt = WPA_ASE_8021X_PSK; in ieee80211_parse_wpa()
1348 rsn->rsn_caps = le16dec(frm); in ieee80211_parse_wpa()
1436 * Other, variable-length data, must be checked separately. in ieee80211_parse_rsn()
1438 if ((vap->iv_flags & IEEE80211_F_WPA2) == 0) { in ieee80211_parse_rsn()
1441 wh, "WPA", "not RSN, flags 0x%x", vap->iv_flags); in ieee80211_parse_rsn()
1459 frm += 2, len -= 2; in ieee80211_parse_rsn()
1464 error = rsn_cipher(frm, &rsn->rsn_mcastkeylen, &rsn->rsn_mcastcipher); in ieee80211_parse_rsn()
1472 if (rsn->rsn_mcastcipher == IEEE80211_CIPHER_NONE) { in ieee80211_parse_rsn()
1476 rsn->rsn_mcastcipher); in ieee80211_parse_rsn()
1479 frm += 4, len -= 4; in ieee80211_parse_rsn()
1483 frm += 2, len -= 2; in ieee80211_parse_rsn()
1493 for (; n > 0; n--) { in ieee80211_parse_rsn()
1496 error = rsn_cipher(frm, &rsn->rsn_ucastkeylen, &cipher); in ieee80211_parse_rsn()
1500 frm += 4, len -= 4; in ieee80211_parse_rsn()
1503 rsn->rsn_ucastcipher = IEEE80211_CIPHER_AES_GCM_128; in ieee80211_parse_rsn()
1505 rsn->rsn_ucastcipher = IEEE80211_CIPHER_AES_CCM; in ieee80211_parse_rsn()
1507 rsn->rsn_ucastcipher = IEEE80211_CIPHER_AES_OCB; in ieee80211_parse_rsn()
1509 rsn->rsn_ucastcipher = IEEE80211_CIPHER_TKIP; in ieee80211_parse_rsn()
1511 (rsn->rsn_mcastcipher == IEEE80211_CIPHER_WEP || in ieee80211_parse_rsn()
1512 rsn->rsn_mcastcipher == IEEE80211_CIPHER_TKIP)) in ieee80211_parse_rsn()
1513 rsn->rsn_ucastcipher = IEEE80211_CIPHER_NONE; in ieee80211_parse_rsn()
1517 wh, "RSN", "no usable pairwise cipher suite found (w=%d)", in ieee80211_parse_rsn()
1524 frm += 2, len -= 2; in ieee80211_parse_rsn()
1533 for (; n > 0; n--) { in ieee80211_parse_rsn()
1535 frm += 4, len -= 4; in ieee80211_parse_rsn()
1538 rsn->rsn_keymgmt = RSN_ASE_8021X_UNSPEC; in ieee80211_parse_rsn()
1540 rsn->rsn_keymgmt = RSN_ASE_8021X_PSK; in ieee80211_parse_rsn()
1544 rsn->rsn_caps = le16dec(frm); in ieee80211_parse_rsn()
1545 frm += 2, len -= 2; in ieee80211_parse_rsn()
1563 struct ieee80211vap *vap = ni->ni_vap; in wpa_assocreq()
1567 ni->ni_flags &= ~(IEEE80211_NODE_WPS|IEEE80211_NODE_TSN); in wpa_assocreq()
1569 if (vap->iv_flags_ext & IEEE80211_FEXT_WPS) { in wpa_assocreq()
1571 * W-Fi Protected Setup (WPS) permits in wpa_assocreq()
1575 ni->ni_flags |= IEEE80211_NODE_WPS; in wpa_assocreq()
1578 if ((vap->iv_flags_ext & IEEE80211_FEXT_TSN) && in wpa_assocreq()
1584 ni->ni_flags |= IEEE80211_NODE_TSN; in wpa_assocreq()
1588 wh, NULL, "%s", "no WPA/RSN IE in association request"); in wpa_assocreq()
1589 vap->iv_stats.is_rx_assoc_badwpaie++; in wpa_assocreq()
1595 switch (vap->iv_flags & IEEE80211_F_WPA) { in wpa_assocreq()
1610 vap->iv_stats.is_rx_assoc_badwpaie++; in wpa_assocreq()
1622 /* XXX wpa->rsn fallback? */ in wpa_assocreq()
1624 vap->iv_stats.is_rx_assoc_badwpaie++; in wpa_assocreq()
1630 rsnparms->rsn_mcastcipher, rsnparms->rsn_mcastkeylen, in wpa_assocreq()
1631 rsnparms->rsn_ucastcipher, rsnparms->rsn_ucastkeylen, in wpa_assocreq()
1632 rsnparms->rsn_keymgmt, rsnparms->rsn_caps); in wpa_assocreq()
1657 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_deliver_l2uf()
1665 "%s", "no mbuf for l2uf frame"); in ieee80211_deliver_l2uf()
1666 vap->iv_stats.is_rx_nobuf++; /* XXX not right */ in ieee80211_deliver_l2uf()
1670 eh = &l2uf->eh; in ieee80211_deliver_l2uf()
1672 IEEE80211_ADDR_COPY(eh->ether_dhost, in ieee80211_deliver_l2uf()
1675 IEEE80211_ADDR_COPY(eh->ether_shost, ni->ni_macaddr); in ieee80211_deliver_l2uf()
1676 eh->ether_type = htons(sizeof(*l2uf) - sizeof(*eh)); in ieee80211_deliver_l2uf()
1678 l2uf->dsap = 0; in ieee80211_deliver_l2uf()
1679 l2uf->ssap = 0; in ieee80211_deliver_l2uf()
1680 l2uf->control = 0xf5; in ieee80211_deliver_l2uf()
1681 l2uf->xid[0] = 0x81; in ieee80211_deliver_l2uf()
1682 l2uf->xid[1] = 0x80; in ieee80211_deliver_l2uf()
1683 l2uf->xid[2] = 0x00; in ieee80211_deliver_l2uf()
1685 m->m_pkthdr.len = m->m_len = sizeof(*l2uf); in ieee80211_deliver_l2uf()
1693 IEEE80211_NOTE_MAC(ni->ni_vap, IEEE80211_MSG_ANY, wh->i_addr2, in ratesetmismatch()
1704 struct ieee80211vap *vap = ni->ni_vap; in capinfomismatch()
1706 IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_ANY, wh->i_addr2, in capinfomismatch()
1711 vap->iv_stats.is_rx_assoc_capmismatch++; in capinfomismatch()
1718 IEEE80211_NOTE_MAC(ni->ni_vap, IEEE80211_MSG_ANY, wh->i_addr2, in htcapmismatch()
1720 /* XXX no better code */ in htcapmismatch()
1729 struct ieee80211vap *vap = ni->ni_vap; in authalgreject()
1733 vap->iv_stats.is_rx_auth_unsupported++; in authalgreject()
1734 ieee80211_send_error(ni, wh->i_addr2, IEEE80211_FC0_SUBTYPE_AUTH, in authalgreject()
1743 return (ht->hi_byte2 & IEEE80211_HTINFO_OPMODE) == in ishtmixed()
1767 * The 802.11 specification only allows HT A-MPDU to be performed
1769 * implementations may not meet the timing required for A-MPDU
1773 * @returns true if the cipher is valid for HT A-MPDU, false otherwise
1791 struct ieee80211vap *vap = ni->ni_vap; in hostap_recv_mgmt()
1792 struct ieee80211com *ic = ni->ni_ic; in hostap_recv_mgmt()
1802 efrm = mtod(m0, uint8_t *) + m0->m_len; in hostap_recv_mgmt()
1807 * otherwise we check beacon frames for overlapping non-ERP in hostap_recv_mgmt()
1810 if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) { in hostap_recv_mgmt()
1811 vap->iv_stats.is_rx_mgtdiscard++; in hostap_recv_mgmt()
1818 /* NB: accept off-channel frames */ in hostap_recv_mgmt()
1819 /* XXX TODO: use rxstatus to determine off-channel details */ in hostap_recv_mgmt()
1820 if (ieee80211_parse_beacon(ni, m0, ic->ic_curchan, &scan) &~ IEEE80211_BPARSE_OFFCHAN) in hostap_recv_mgmt()
1826 vap->iv_stats.is_rx_beacon++; /* XXX remove */ in hostap_recv_mgmt()
1833 if (ic->ic_flags & IEEE80211_F_SCAN) { in hostap_recv_mgmt()
1835 (ic->ic_flags_ext & IEEE80211_FEXT_PROBECHAN)) { in hostap_recv_mgmt()
1845 ic->ic_flags_ext &= ~IEEE80211_FEXT_PROBECHAN; in hostap_recv_mgmt()
1847 ieee80211_add_scan(vap, ic->ic_curchan, &scan, wh, in hostap_recv_mgmt()
1857 if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan) && in hostap_recv_mgmt()
1858 scan.status == 0 && /* NB: on-channel */ in hostap_recv_mgmt()
1859 ((scan.erp & 0x100) == 0 || /* NB: no ERP, 11b sta*/ in hostap_recv_mgmt()
1861 vap->iv_lastnonerp = ticks; in hostap_recv_mgmt()
1862 vap->iv_flags_ext |= IEEE80211_FEXT_NONERP_PR; in hostap_recv_mgmt()
1866 if (vap->iv_protmode != IEEE80211_PROT_NONE && in hostap_recv_mgmt()
1867 (vap->iv_flags & IEEE80211_F_USEPROT) == 0) { in hostap_recv_mgmt()
1870 "non-ERP present on channel %d " in hostap_recv_mgmt()
1873 ic->ic_curchan->ic_ieee, in hostap_recv_mgmt()
1875 vap->iv_flags |= IEEE80211_F_USEPROT; in hostap_recv_mgmt()
1880 * Check beacon for non-HT station on HT channel in hostap_recv_mgmt()
1883 if (IEEE80211_IS_CHAN_HT(ic->ic_curchan)) { in hostap_recv_mgmt()
1890 if (!IEEE80211_IS_CHAN_HT40(ic->ic_curchan)) in hostap_recv_mgmt()
1892 if (scan.chan != ic->ic_curchan->ic_extieee) in hostap_recv_mgmt()
1910 if (vap->iv_state != IEEE80211_S_RUN) { in hostap_recv_mgmt()
1911 vap->iv_stats.is_rx_mgtdiscard++; in hostap_recv_mgmt()
1917 if (vap->iv_acl != NULL && !vap->iv_acl->iac_check(vap, wh)) { in hostap_recv_mgmt()
1920 vap->iv_stats.is_rx_acl++; in hostap_recv_mgmt()
1930 while (efrm - frm > 1) { in hostap_recv_mgmt()
1931 IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2, return); in hostap_recv_mgmt()
1948 IEEE80211_RATE_MAXSIZE - rates[1], return); in hostap_recv_mgmt()
1950 IEEE80211_VERIFY_SSID(vap->iv_bss, ssid, return); in hostap_recv_mgmt()
1951 if ((vap->iv_flags & IEEE80211_F_HIDESSID) && ssid[1] == 0) { in hostap_recv_mgmt()
1954 "%s", "no ssid with ssid suppression enabled"); in hostap_recv_mgmt()
1955 vap->iv_stats.is_rx_ssidmismatch++; /*XXX*/ in hostap_recv_mgmt()
1960 IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_INPUT, wh->i_addr2, in hostap_recv_mgmt()
1965 * only a bare-bones rate set, communicate this to in hostap_recv_mgmt()
1968 ieee80211_send_proberesp(vap, wh->i_addr2, in hostap_recv_mgmt()
1975 if (vap->iv_state != IEEE80211_S_RUN) { in hostap_recv_mgmt()
1976 vap->iv_stats.is_rx_mgtdiscard++; in hostap_recv_mgmt()
1979 if (!IEEE80211_ADDR_EQ(wh->i_addr3, vap->iv_bss->ni_bssid)) { in hostap_recv_mgmt()
1982 vap->iv_stats.is_rx_wrongbss++; /*XXX unique stat?*/ in hostap_recv_mgmt()
1992 IEEE80211_VERIFY_LENGTH(efrm - frm, 6, return); in hostap_recv_mgmt()
1996 IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_AUTH, wh->i_addr2, in hostap_recv_mgmt()
2001 if (vap->iv_acl != NULL && !vap->iv_acl->iac_check(vap, wh)) { in hostap_recv_mgmt()
2004 vap->iv_stats.is_rx_acl++; in hostap_recv_mgmt()
2005 ieee80211_send_error(ni, wh->i_addr2, in hostap_recv_mgmt()
2010 if (vap->iv_flags & IEEE80211_F_COUNTERM) { in hostap_recv_mgmt()
2014 vap->iv_stats.is_rx_auth_countermeasures++; in hostap_recv_mgmt()
2015 ieee80211_send_error(ni, wh->i_addr2, in hostap_recv_mgmt()
2051 if (vap->iv_state != IEEE80211_S_RUN) { in hostap_recv_mgmt()
2052 vap->iv_stats.is_rx_mgtdiscard++; in hostap_recv_mgmt()
2055 if (!IEEE80211_ADDR_EQ(wh->i_addr3, vap->iv_bss->ni_bssid)) { in hostap_recv_mgmt()
2058 vap->iv_stats.is_rx_assoc_bss++; in hostap_recv_mgmt()
2068 if (ni == vap->iv_bss) { in hostap_recv_mgmt()
2069 IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_ANY, wh->i_addr2, in hostap_recv_mgmt()
2072 ieee80211_send_error(ni, wh->i_addr2, in hostap_recv_mgmt()
2075 vap->iv_stats.is_rx_assoc_notauth++; in hostap_recv_mgmt()
2091 IEEE80211_VERIFY_LENGTH(efrm - frm, (reassoc ? 10 : 4), return); in hostap_recv_mgmt()
2099 while (efrm - frm > 1) { in hostap_recv_mgmt()
2100 IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2, return); in hostap_recv_mgmt()
2132 else if (vap->iv_flags_ht & IEEE80211_FHT_HTCOMPAT) { in hostap_recv_mgmt()
2143 IEEE80211_RATE_MAXSIZE - rates[1], return); in hostap_recv_mgmt()
2145 IEEE80211_VERIFY_SSID(vap->iv_bss, ssid, return); in hostap_recv_mgmt()
2149 4 + sizeof(struct ieee80211_ie_htcap)-2 : in hostap_recv_mgmt()
2150 sizeof(struct ieee80211_ie_htcap)-2, in hostap_recv_mgmt()
2166 if ((vap->iv_flags & IEEE80211_F_WPA) && in hostap_recv_mgmt()
2170 if (ni->ni_challenge != NULL) { in hostap_recv_mgmt()
2171 IEEE80211_FREE(ni->ni_challenge, M_80211_NODE); in hostap_recv_mgmt()
2172 ni->ni_challenge = NULL; in hostap_recv_mgmt()
2181 * Disallow re-associate w/ invalid slot time setting. in hostap_recv_mgmt()
2183 if (ni->ni_associd != 0 && in hostap_recv_mgmt()
2184 IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan) && in hostap_recv_mgmt()
2185 ((ni->ni_capinfo ^ capinfo) & IEEE80211_CAPINFO_SHORT_SLOTTIME)) { in hostap_recv_mgmt()
2187 "slot time", capinfo); in hostap_recv_mgmt()
2195 vap->iv_stats.is_rx_assoc_norate++; in hostap_recv_mgmt()
2199 * If constrained to 11g-only stations reject an in hostap_recv_mgmt()
2200 * 11b-only station. We cheat a bit here by looking in hostap_recv_mgmt()
2204 if ((vap->iv_flags & IEEE80211_F_PUREG) && rate < 48) { in hostap_recv_mgmt()
2206 vap->iv_stats.is_rx_assoc_norate++; in hostap_recv_mgmt()
2213 ni->ni_chan = vap->iv_bss->ni_chan; in hostap_recv_mgmt()
2216 if (IEEE80211_IS_CHAN_VHT(ni->ni_chan) && in hostap_recv_mgmt()
2220 } else if (ni->ni_flags & IEEE80211_NODE_VHT) in hostap_recv_mgmt()
2224 if (IEEE80211_IS_CHAN_HT(ni->ni_chan) && htcap != NULL) { in hostap_recv_mgmt()
2231 vap->iv_stats.is_ht_assoc_norate++; in hostap_recv_mgmt()
2236 } else if (ni->ni_flags & IEEE80211_NODE_HT) in hostap_recv_mgmt()
2239 /* Finally - this will use HT/VHT info to change node channel */ in hostap_recv_mgmt()
2240 if (IEEE80211_IS_CHAN_HT(ni->ni_chan) && htcap != NULL) { in hostap_recv_mgmt()
2245 /* Always do ff node cleanup; for A-MSDU */ in hostap_recv_mgmt()
2250 * or AES-CCM / AES-GCM; the 802.11n spec only specifies these in hostap_recv_mgmt()
2254 * TODO: before landing, find exactly where in 802.11-2020 this in hostap_recv_mgmt()
2257 if ((ni->ni_flags & IEEE80211_NODE_HT) && in hostap_recv_mgmt()
2258 (((vap->iv_flags & IEEE80211_F_WPA) && in hostap_recv_mgmt()
2260 (vap->iv_flags & (IEEE80211_F_WPA|IEEE80211_F_PRIVACY)) == IEEE80211_F_PRIVACY)) { in hostap_recv_mgmt()
2268 /* Always do ff node cleanup; for A-MSDU */ in hostap_recv_mgmt()
2271 vap->iv_stats.is_ht_assoc_downgrade++; in hostap_recv_mgmt()
2274 * If constrained to 11n-only stations reject legacy stations. in hostap_recv_mgmt()
2276 if ((vap->iv_flags_ht & IEEE80211_FHT_PUREN) && in hostap_recv_mgmt()
2277 (ni->ni_flags & IEEE80211_NODE_HT) == 0) { in hostap_recv_mgmt()
2279 vap->iv_stats.is_ht_assoc_nohtcap++; in hostap_recv_mgmt()
2282 IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi); in hostap_recv_mgmt()
2283 ni->ni_noise = nf; in hostap_recv_mgmt()
2284 ni->ni_intval = lintval; in hostap_recv_mgmt()
2285 ni->ni_capinfo = capinfo; in hostap_recv_mgmt()
2286 ni->ni_fhdwell = vap->iv_bss->ni_fhdwell; in hostap_recv_mgmt()
2287 ni->ni_fhindex = vap->iv_bss->ni_fhindex; in hostap_recv_mgmt()
2292 if (ieee80211_ies_init(&ni->ni_ies, sfrm, efrm - sfrm)) { in hostap_recv_mgmt()
2293 #define setie(_ie, _off) ieee80211_ies_setie(ni->ni_ies, _ie, _off) in hostap_recv_mgmt()
2295 setie(wpa_ie, wpa - sfrm); in hostap_recv_mgmt()
2297 setie(rsn_ie, rsn - sfrm); in hostap_recv_mgmt()
2299 setie(htcap_ie, htcap - sfrm); in hostap_recv_mgmt()
2301 setie(wme_ie, wme - sfrm); in hostap_recv_mgmt()
2305 ni->ni_flags |= IEEE80211_NODE_QOS; in hostap_recv_mgmt()
2307 if (ni->ni_uapsd != 0) in hostap_recv_mgmt()
2308 ni->ni_flags |= in hostap_recv_mgmt()
2311 ni->ni_flags &= in hostap_recv_mgmt()
2315 ni->ni_flags &= in hostap_recv_mgmt()
2320 setie(ath_ie, ath - sfrm); in hostap_recv_mgmt()
2324 ieee80211_parse_ath(ni, ni->ni_ies.ath_ie); in hostap_recv_mgmt()
2327 ni->ni_ath_flags = 0; in hostap_recv_mgmt()
2330 ni->ni_flags &= ~IEEE80211_NODE_QOS; in hostap_recv_mgmt()
2331 ni->ni_flags &= ~IEEE80211_NODE_UAPSD; in hostap_recv_mgmt()
2332 ni->ni_ath_flags = 0; in hostap_recv_mgmt()
2345 if (vap->iv_state != IEEE80211_S_RUN || in hostap_recv_mgmt()
2347 !IEEE80211_ADDR_EQ(wh->i_addr1, vap->iv_myaddr)) { in hostap_recv_mgmt()
2348 vap->iv_stats.is_rx_mgtdiscard++; in hostap_recv_mgmt()
2355 IEEE80211_VERIFY_LENGTH(efrm - frm, 2, return); in hostap_recv_mgmt()
2360 vap->iv_stats.is_rx_deauth++; in hostap_recv_mgmt()
2363 vap->iv_stats.is_rx_disassoc++; in hostap_recv_mgmt()
2370 if (ni != vap->iv_bss) in hostap_recv_mgmt()
2377 if (ni == vap->iv_bss) { in hostap_recv_mgmt()
2380 vap->iv_stats.is_rx_mgtdiscard++; in hostap_recv_mgmt()
2381 } else if (!IEEE80211_ADDR_EQ(vap->iv_myaddr, wh->i_addr1) && in hostap_recv_mgmt()
2382 !IEEE80211_IS_MULTICAST(wh->i_addr1)) { in hostap_recv_mgmt()
2385 vap->iv_stats.is_rx_mgtdiscard++; in hostap_recv_mgmt()
2386 } else if (vap->iv_state != IEEE80211_S_RUN) { in hostap_recv_mgmt()
2389 ieee80211_state_name[vap->iv_state]); in hostap_recv_mgmt()
2390 vap->iv_stats.is_rx_mgtdiscard++; in hostap_recv_mgmt()
2393 (void)ic->ic_recv_action(ni, wh, frm, efrm); in hostap_recv_mgmt()
2403 vap->iv_stats.is_rx_mgtdiscard++; in hostap_recv_mgmt()
2409 vap->iv_stats.is_rx_badsubtype++; in hostap_recv_mgmt()
2419 ni->ni_vap->iv_recv_pspoll(ni, m); in hostap_recv_ctl()
2428 * Process a received ps-poll frame.
2433 struct ieee80211vap *vap = ni->ni_vap; in ieee80211_recv_pspoll()
2434 struct ieee80211com *ic = vap->iv_ic; in ieee80211_recv_pspoll()
2441 if (ni->ni_associd == 0) { in ieee80211_recv_pspoll()
2446 vap->iv_stats.is_ps_unassoc++; in ieee80211_recv_pspoll()
2452 aid = le16toh(*(uint16_t *)wh->i_dur); in ieee80211_recv_pspoll()
2453 if (aid != ni->ni_associd) { in ieee80211_recv_pspoll()
2458 ni->ni_associd, aid); in ieee80211_recv_pspoll()
2459 vap->iv_stats.is_ps_badaid++; in ieee80211_recv_pspoll()
2474 IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_POWER, wh->i_addr2, in ieee80211_recv_pspoll()
2475 "%s", "recv ps-poll, but queue empty"); in ieee80211_recv_pspoll()
2477 vap->iv_stats.is_ps_qempty++; /* XXX node stat */ in ieee80211_recv_pspoll()
2478 if (vap->iv_set_tim != NULL) in ieee80211_recv_pspoll()
2479 vap->iv_set_tim(ni, 0); /* just in case */ in ieee80211_recv_pspoll()
2489 "recv ps-poll, send packet, %u still queued", qlen); in ieee80211_recv_pspoll()
2490 m->m_flags |= M_MORE_DATA; in ieee80211_recv_pspoll()
2493 "%s", "recv ps-poll, send packet, queue empty"); in ieee80211_recv_pspoll()
2494 if (vap->iv_set_tim != NULL) in ieee80211_recv_pspoll()
2495 vap->iv_set_tim(ni, 0); in ieee80211_recv_pspoll()
2497 m->m_flags |= M_PWR_SAV; /* bypass PS handling */ in ieee80211_recv_pspoll()
2504 if (m->m_flags & M_ENCAP) { in ieee80211_recv_pspoll()