| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: ieee80211_input.c,v 1.102 2018/01/16 16:04:16 maxv Exp $ */ | | 1 | /* $NetBSD: ieee80211_input.c,v 1.103 2018/01/16 16:09:30 maxv Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 2001 Atsushi Onoe | | 4 | * Copyright (c) 2001 Atsushi Onoe |
5 | * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting | | 5 | * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting |
6 | * All rights reserved. | | 6 | * All rights reserved. |
7 | * | | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | | 8 | * Redistribution and use in source and binary forms, with or without |
9 | * modification, are permitted provided that the following conditions | | 9 | * modification, are permitted provided that the following conditions |
10 | * are met: | | 10 | * are met: |
11 | * 1. Redistributions of source code must retain the above copyright | | 11 | * 1. Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. | | 12 | * notice, this list of conditions and the following disclaimer. |
13 | * 2. Redistributions in binary form must reproduce the above copyright | | 13 | * 2. Redistributions in binary form must reproduce the above copyright |
14 | * notice, this list of conditions and the following disclaimer in the | | 14 | * notice, this list of conditions and the following disclaimer in the |
| @@ -27,27 +27,27 @@ | | | @@ -27,27 +27,27 @@ |
27 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | | 27 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
28 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | | 28 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | | 29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
30 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | | 30 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | | 31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | | 32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
33 | */ | | 33 | */ |
34 | | | 34 | |
35 | #include <sys/cdefs.h> | | 35 | #include <sys/cdefs.h> |
36 | #ifdef __FreeBSD__ | | 36 | #ifdef __FreeBSD__ |
37 | __FBSDID("$FreeBSD: src/sys/net80211/ieee80211_input.c,v 1.81 2005/08/10 16:22:29 sam Exp $"); | | 37 | __FBSDID("$FreeBSD: src/sys/net80211/ieee80211_input.c,v 1.81 2005/08/10 16:22:29 sam Exp $"); |
38 | #endif | | 38 | #endif |
39 | #ifdef __NetBSD__ | | 39 | #ifdef __NetBSD__ |
40 | __KERNEL_RCSID(0, "$NetBSD: ieee80211_input.c,v 1.102 2018/01/16 16:04:16 maxv Exp $"); | | 40 | __KERNEL_RCSID(0, "$NetBSD: ieee80211_input.c,v 1.103 2018/01/16 16:09:30 maxv Exp $"); |
41 | #endif | | 41 | #endif |
42 | | | 42 | |
43 | #ifdef _KERNEL_OPT | | 43 | #ifdef _KERNEL_OPT |
44 | #include "opt_inet.h" | | 44 | #include "opt_inet.h" |
45 | #endif | | 45 | #endif |
46 | | | 46 | |
47 | #include <sys/param.h> | | 47 | #include <sys/param.h> |
48 | #include <sys/systm.h> | | 48 | #include <sys/systm.h> |
49 | #include <sys/mbuf.h> | | 49 | #include <sys/mbuf.h> |
50 | #include <sys/malloc.h> | | 50 | #include <sys/malloc.h> |
51 | #include <sys/endian.h> | | 51 | #include <sys/endian.h> |
52 | #include <sys/kernel.h> | | 52 | #include <sys/kernel.h> |
53 | | | 53 | |
| @@ -2845,40 +2845,91 @@ ieee80211_recv_mgmt_deauth(struct ieee80 | | | @@ -2845,40 +2845,91 @@ ieee80211_recv_mgmt_deauth(struct ieee80 |
2845 | break; | | 2845 | break; |
2846 | case IEEE80211_M_HOSTAP: | | 2846 | case IEEE80211_M_HOSTAP: |
2847 | #ifndef IEEE80211_NO_HOSTAP | | 2847 | #ifndef IEEE80211_NO_HOSTAP |
2848 | if (ni != ic->ic_bss) | | 2848 | if (ni != ic->ic_bss) |
2849 | ieee80211_node_leave(ic, ni); | | 2849 | ieee80211_node_leave(ic, ni); |
2850 | #endif /* !IEEE80211_NO_HOSTAP */ | | 2850 | #endif /* !IEEE80211_NO_HOSTAP */ |
2851 | break; | | 2851 | break; |
2852 | default: | | 2852 | default: |
2853 | ic->ic_stats.is_rx_mgtdiscard++; | | 2853 | ic->ic_stats.is_rx_mgtdiscard++; |
2854 | break; | | 2854 | break; |
2855 | } | | 2855 | } |
2856 | } | | 2856 | } |
2857 | | | 2857 | |
2858 | /* -------------------------------------------------------------------------- */ | | 2858 | static void |
2859 | | | 2859 | ieee80211_recv_mgmt_disassoc(struct ieee80211com *ic, struct mbuf *m0, |
2860 | void | | | |
2861 | ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0, | | | |
2862 | struct ieee80211_node *ni, int subtype, int rssi, u_int32_t rstamp) | | 2860 | struct ieee80211_node *ni, int subtype, int rssi, u_int32_t rstamp) |
2863 | { | | 2861 | { |
2864 | struct ieee80211_frame *wh; | | 2862 | struct ieee80211_frame *wh; |
2865 | u_int8_t *frm, *efrm; | | 2863 | u_int8_t *frm, *efrm; |
2866 | IEEE80211_DEBUGVAR(char ebuf[3 * ETHER_ADDR_LEN]); | | 2864 | IEEE80211_DEBUGVAR(char ebuf[3 * ETHER_ADDR_LEN]); |
2867 | | | 2865 | |
2868 | wh = mtod(m0, struct ieee80211_frame *); | | 2866 | wh = mtod(m0, struct ieee80211_frame *); |
2869 | frm = (u_int8_t *)(wh + 1); | | 2867 | frm = (u_int8_t *)(wh + 1); |
2870 | efrm = mtod(m0, u_int8_t *) + m0->m_len; | | 2868 | efrm = mtod(m0, u_int8_t *) + m0->m_len; |
2871 | | | 2869 | |
| | | 2870 | u_int16_t reason; |
| | | 2871 | |
| | | 2872 | if (ic->ic_state != IEEE80211_S_RUN && |
| | | 2873 | ic->ic_state != IEEE80211_S_ASSOC && |
| | | 2874 | ic->ic_state != IEEE80211_S_AUTH) { |
| | | 2875 | ic->ic_stats.is_rx_mgtdiscard++; |
| | | 2876 | return; |
| | | 2877 | } |
| | | 2878 | /* |
| | | 2879 | * disassoc frame format |
| | | 2880 | * [2] reason |
| | | 2881 | */ |
| | | 2882 | IEEE80211_VERIFY_LENGTH(efrm - frm, 2); |
| | | 2883 | reason = le16toh(*(u_int16_t *)frm); |
| | | 2884 | __USE(reason); |
| | | 2885 | ic->ic_stats.is_rx_disassoc++; |
| | | 2886 | IEEE80211_NODE_STAT(ni, rx_disassoc); |
| | | 2887 | |
| | | 2888 | if (!IEEE80211_ADDR_EQ(wh->i_addr1, ic->ic_myaddr)) { |
| | | 2889 | /* Not intended for this station. */ |
| | | 2890 | ic->ic_stats.is_rx_mgtdiscard++; |
| | | 2891 | return; |
| | | 2892 | } |
| | | 2893 | IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC, |
| | | 2894 | "[%s] recv disassociate (reason %d)\n", |
| | | 2895 | ether_snprintf(ebuf, sizeof(ebuf), ni->ni_macaddr), reason); |
| | | 2896 | switch (ic->ic_opmode) { |
| | | 2897 | case IEEE80211_M_STA: |
| | | 2898 | ieee80211_new_state(ic, IEEE80211_S_ASSOC, |
| | | 2899 | wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); |
| | | 2900 | break; |
| | | 2901 | case IEEE80211_M_HOSTAP: |
| | | 2902 | #ifndef IEEE80211_NO_HOSTAP |
| | | 2903 | if (ni != ic->ic_bss) |
| | | 2904 | ieee80211_node_leave(ic, ni); |
| | | 2905 | #endif /* !IEEE80211_NO_HOSTAP */ |
| | | 2906 | break; |
| | | 2907 | default: |
| | | 2908 | ic->ic_stats.is_rx_mgtdiscard++; |
| | | 2909 | break; |
| | | 2910 | } |
| | | 2911 | } |
| | | 2912 | |
| | | 2913 | /* -------------------------------------------------------------------------- */ |
| | | 2914 | |
| | | 2915 | void |
| | | 2916 | ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0, |
| | | 2917 | struct ieee80211_node *ni, int subtype, int rssi, u_int32_t rstamp) |
| | | 2918 | { |
| | | 2919 | struct ieee80211_frame *wh; |
| | | 2920 | |
| | | 2921 | wh = mtod(m0, struct ieee80211_frame *); |
| | | 2922 | |
2872 | switch (subtype) { | | 2923 | switch (subtype) { |
2873 | case IEEE80211_FC0_SUBTYPE_PROBE_RESP: | | 2924 | case IEEE80211_FC0_SUBTYPE_PROBE_RESP: |
2874 | case IEEE80211_FC0_SUBTYPE_BEACON: | | 2925 | case IEEE80211_FC0_SUBTYPE_BEACON: |
2875 | ieee80211_recv_mgmt_beacon(ic, m0, ni, subtype, rssi, rstamp); | | 2926 | ieee80211_recv_mgmt_beacon(ic, m0, ni, subtype, rssi, rstamp); |
2876 | return; | | 2927 | return; |
2877 | | | 2928 | |
2878 | case IEEE80211_FC0_SUBTYPE_PROBE_REQ: | | 2929 | case IEEE80211_FC0_SUBTYPE_PROBE_REQ: |
2879 | ieee80211_recv_mgmt_probe_req(ic, m0, ni, subtype, rssi, rstamp); | | 2930 | ieee80211_recv_mgmt_probe_req(ic, m0, ni, subtype, rssi, rstamp); |
2880 | return; | | 2931 | return; |
2881 | | | 2932 | |
2882 | case IEEE80211_FC0_SUBTYPE_AUTH: | | 2933 | case IEEE80211_FC0_SUBTYPE_AUTH: |
2883 | ieee80211_recv_mgmt_auth(ic, m0, ni, subtype, rssi, rstamp); | | 2934 | ieee80211_recv_mgmt_auth(ic, m0, ni, subtype, rssi, rstamp); |
2884 | return; | | 2935 | return; |
| @@ -2887,78 +2938,39 @@ ieee80211_recv_mgmt(struct ieee80211com | | | @@ -2887,78 +2938,39 @@ ieee80211_recv_mgmt(struct ieee80211com |
2887 | case IEEE80211_FC0_SUBTYPE_REASSOC_REQ: | | 2938 | case IEEE80211_FC0_SUBTYPE_REASSOC_REQ: |
2888 | ieee80211_recv_mgmt_assoc_req(ic, m0, ni, subtype, rssi, rstamp); | | 2939 | ieee80211_recv_mgmt_assoc_req(ic, m0, ni, subtype, rssi, rstamp); |
2889 | return; | | 2940 | return; |
2890 | | | 2941 | |
2891 | case IEEE80211_FC0_SUBTYPE_ASSOC_RESP: | | 2942 | case IEEE80211_FC0_SUBTYPE_ASSOC_RESP: |
2892 | case IEEE80211_FC0_SUBTYPE_REASSOC_RESP: | | 2943 | case IEEE80211_FC0_SUBTYPE_REASSOC_RESP: |
2893 | ieee80211_recv_mgmt_assoc_resp(ic, m0, ni, subtype, rssi, rstamp); | | 2944 | ieee80211_recv_mgmt_assoc_resp(ic, m0, ni, subtype, rssi, rstamp); |
2894 | return; | | 2945 | return; |
2895 | | | 2946 | |
2896 | case IEEE80211_FC0_SUBTYPE_DEAUTH: | | 2947 | case IEEE80211_FC0_SUBTYPE_DEAUTH: |
2897 | ieee80211_recv_mgmt_deauth(ic, m0, ni, subtype, rssi, rstamp); | | 2948 | ieee80211_recv_mgmt_deauth(ic, m0, ni, subtype, rssi, rstamp); |
2898 | return; | | 2949 | return; |
2899 | | | 2950 | |
2900 | case IEEE80211_FC0_SUBTYPE_DISASSOC: { | | 2951 | case IEEE80211_FC0_SUBTYPE_DISASSOC: |
2901 | u_int16_t reason; | | 2952 | ieee80211_recv_mgmt_disassoc(ic, m0, ni, subtype, rssi, rstamp); |
| | | 2953 | return; |
2902 | | | 2954 | |
2903 | if (ic->ic_state != IEEE80211_S_RUN && | | | |
2904 | ic->ic_state != IEEE80211_S_ASSOC && | | | |
2905 | ic->ic_state != IEEE80211_S_AUTH) { | | | |
2906 | ic->ic_stats.is_rx_mgtdiscard++; | | | |
2907 | return; | | | |
2908 | } | | | |
2909 | /* | | | |
2910 | * disassoc frame format | | | |
2911 | * [2] reason | | | |
2912 | */ | | | |
2913 | IEEE80211_VERIFY_LENGTH(efrm - frm, 2); | | | |
2914 | reason = le16toh(*(u_int16_t *)frm); | | | |
2915 | __USE(reason); | | | |
2916 | ic->ic_stats.is_rx_disassoc++; | | | |
2917 | IEEE80211_NODE_STAT(ni, rx_disassoc); | | | |
2918 | | | | |
2919 | if (!IEEE80211_ADDR_EQ(wh->i_addr1, ic->ic_myaddr)) { | | | |
2920 | /* Not intended for this station. */ | | | |
2921 | ic->ic_stats.is_rx_mgtdiscard++; | | | |
2922 | break; | | | |
2923 | } | | | |
2924 | IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC, | | | |
2925 | "[%s] recv disassociate (reason %d)\n", | | | |
2926 | ether_snprintf(ebuf, sizeof(ebuf), ni->ni_macaddr), reason); | | | |
2927 | switch (ic->ic_opmode) { | | | |
2928 | case IEEE80211_M_STA: | | | |
2929 | ieee80211_new_state(ic, IEEE80211_S_ASSOC, | | | |
2930 | wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); | | | |
2931 | break; | | | |
2932 | case IEEE80211_M_HOSTAP: | | | |
2933 | #ifndef IEEE80211_NO_HOSTAP | | | |
2934 | if (ni != ic->ic_bss) | | | |
2935 | ieee80211_node_leave(ic, ni); | | | |
2936 | #endif /* !IEEE80211_NO_HOSTAP */ | | | |
2937 | break; | | | |
2938 | default: | | | |
2939 | ic->ic_stats.is_rx_mgtdiscard++; | | | |
2940 | break; | | | |
2941 | } | | | |
2942 | break; | | | |
2943 | } | | | |
2944 | default: | | 2955 | default: |
2945 | IEEE80211_DISCARD(ic, IEEE80211_MSG_ANY, | | 2956 | IEEE80211_DISCARD(ic, IEEE80211_MSG_ANY, |
2946 | wh, "mgt", "subtype 0x%x not handled", subtype); | | 2957 | wh, "mgt", "subtype 0x%x not handled", subtype); |
2947 | ic->ic_stats.is_rx_badsubtype++; | | 2958 | ic->ic_stats.is_rx_badsubtype++; |
2948 | break; | | 2959 | break; |
2949 | } | | 2960 | } |
2950 | #undef ISREASSOC | | | |
2951 | } | | 2961 | } |
| | | 2962 | |
| | | 2963 | #undef ISREASSOC |
2952 | #undef IEEE80211_VERIFY_LENGTH | | 2964 | #undef IEEE80211_VERIFY_LENGTH |
2953 | #undef IEEE80211_VERIFY_ELEMENT | | 2965 | #undef IEEE80211_VERIFY_ELEMENT |
2954 | | | 2966 | |
2955 | #ifndef IEEE80211_NO_HOSTAP | | 2967 | #ifndef IEEE80211_NO_HOSTAP |
2956 | /* | | 2968 | /* |
2957 | * Handle station power-save state change. | | 2969 | * Handle station power-save state change. |
2958 | */ | | 2970 | */ |
2959 | static void | | 2971 | static void |
2960 | ieee80211_node_pwrsave(struct ieee80211_node *ni, int enable) | | 2972 | ieee80211_node_pwrsave(struct ieee80211_node *ni, int enable) |
2961 | { | | 2973 | { |
2962 | struct ieee80211com *ic = ni->ni_ic; | | 2974 | struct ieee80211com *ic = ni->ni_ic; |
2963 | struct mbuf *m; | | 2975 | struct mbuf *m; |
2964 | IEEE80211_DEBUGVAR(char ebuf[3 * ETHER_ADDR_LEN]); | | 2976 | IEEE80211_DEBUGVAR(char ebuf[3 * ETHER_ADDR_LEN]); |