ieee80211_input.c (118886) | ieee80211_input.c (119150) |
---|---|
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> | 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 118886 2003-08-13 21:49:35Z sam $"); | 34__FBSDID("$FreeBSD: head/sys/net80211/ieee80211_input.c 119150 2003-08-19 22:17:04Z 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> --- 18 unchanged lines hidden (view full) --- 61 62#include <net/bpf.h> 63 64#ifdef INET 65#include <netinet/in.h> 66#include <netinet/if_ether.h> 67#endif 68 | 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> --- 18 unchanged lines hidden (view full) --- 61 62#include <net/bpf.h> 63 64#ifdef INET 65#include <netinet/in.h> 66#include <netinet/if_ether.h> 67#endif 68 |
69/* 70 * Process a received frame. The node associated with the sender 71 * should be supplied. If nothing was found in the node table then 72 * the caller is assumed to supply a reference to ic_bss instead. 73 * The RSSI and a timestamp are also supplied. The RSSI data is used 74 * during AP scanning to select a AP to associate with; it can have 75 * any units so long as values have consistent units and higher values 76 * mean ``better signal''. The receive timestamp is currently not used 77 * by the 802.11 layer. 78 */ |
|
69void | 79void |
70ieee80211_input(struct ifnet *ifp, struct mbuf *m, 71 int rssi, u_int32_t rstamp, u_int rantenna) | 80ieee80211_input(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni, 81 int rssi, u_int32_t rstamp) |
72{ 73 struct ieee80211com *ic = (void *)ifp; | 82{ 83 struct ieee80211com *ic = (void *)ifp; |
74 struct ieee80211_node *ni = NULL; | |
75 struct ieee80211_frame *wh; 76 struct ether_header *eh; 77 struct mbuf *m1; 78 int len; 79 u_int8_t dir, subtype; 80 u_int8_t *bssid; 81 u_int16_t rxseq; 82 | 84 struct ieee80211_frame *wh; 85 struct ether_header *eh; 86 struct mbuf *m1; 87 int len; 88 u_int8_t dir, subtype; 89 u_int8_t *bssid; 90 u_int16_t rxseq; 91 |
92 KASSERT(ni != NULL, ("null node")); 93 |
|
83 /* trim CRC here for WEP can find its own CRC at the end of packet. */ 84 if (m->m_flags & M_HASFCS) { 85 m_adj(m, -IEEE80211_CRC_LEN); 86 m->m_flags &= ~M_HASFCS; 87 } 88 89 wh = mtod(m, struct ieee80211_frame *); 90 if ((wh->i_fc[0] & IEEE80211_FC0_VERSION_MASK) != 91 IEEE80211_FC0_VERSION_0) { 92 if (ifp->if_flags & IFF_DEBUG) 93 if_printf(ifp, "receive packet with wrong version: %x\n", 94 wh->i_fc[0]); | 94 /* trim CRC here for WEP can find its own CRC at the end of packet. */ 95 if (m->m_flags & M_HASFCS) { 96 m_adj(m, -IEEE80211_CRC_LEN); 97 m->m_flags &= ~M_HASFCS; 98 } 99 100 wh = mtod(m, struct ieee80211_frame *); 101 if ((wh->i_fc[0] & IEEE80211_FC0_VERSION_MASK) != 102 IEEE80211_FC0_VERSION_0) { 103 if (ifp->if_flags & IFF_DEBUG) 104 if_printf(ifp, "receive packet with wrong version: %x\n", 105 wh->i_fc[0]); |
106 ieee80211_unref_node(&ni); |
|
95 goto err; 96 } 97 98 dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK; 99 100 if (ic->ic_state != IEEE80211_S_SCAN) { 101 switch (ic->ic_opmode) { 102 case IEEE80211_M_STA: | 107 goto err; 108 } 109 110 dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK; 111 112 if (ic->ic_state != IEEE80211_S_SCAN) { 113 switch (ic->ic_opmode) { 114 case IEEE80211_M_STA: |
103 ni = ieee80211_ref_node(ic->ic_bss); | |
104 if (!IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_bssid)) { 105 IEEE80211_DPRINTF2(("%s: discard frame from " 106 "bss %s\n", __func__, 107 ether_sprintf(wh->i_addr2))); 108 /* not interested in */ | 115 if (!IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_bssid)) { 116 IEEE80211_DPRINTF2(("%s: discard frame from " 117 "bss %s\n", __func__, 118 ether_sprintf(wh->i_addr2))); 119 /* not interested in */ |
109 ieee80211_unref_node(&ni); | |
110 goto out; 111 } 112 break; 113 case IEEE80211_M_IBSS: 114 case IEEE80211_M_AHDEMO: 115 case IEEE80211_M_HOSTAP: 116 if (dir == IEEE80211_FC1_DIR_NODS) 117 bssid = wh->i_addr3; 118 else 119 bssid = wh->i_addr1; 120 if (!IEEE80211_ADDR_EQ(bssid, ic->ic_bss->ni_bssid) && 121 !IEEE80211_ADDR_EQ(bssid, ifp->if_broadcastaddr)) { 122 /* not interested in */ 123 IEEE80211_DPRINTF2(("%s: other bss %s\n", 124 __func__, ether_sprintf(wh->i_addr3))); 125 goto out; 126 } | 120 goto out; 121 } 122 break; 123 case IEEE80211_M_IBSS: 124 case IEEE80211_M_AHDEMO: 125 case IEEE80211_M_HOSTAP: 126 if (dir == IEEE80211_FC1_DIR_NODS) 127 bssid = wh->i_addr3; 128 else 129 bssid = wh->i_addr1; 130 if (!IEEE80211_ADDR_EQ(bssid, ic->ic_bss->ni_bssid) && 131 !IEEE80211_ADDR_EQ(bssid, ifp->if_broadcastaddr)) { 132 /* not interested in */ 133 IEEE80211_DPRINTF2(("%s: other bss %s\n", 134 __func__, ether_sprintf(wh->i_addr3))); 135 goto out; 136 } |
127 ni = ieee80211_find_node(ic, wh->i_addr2); 128 if (ni == NULL) { 129 IEEE80211_DPRINTF2(("%s: warning, unknown src " 130 "%s\n", __func__, 131 ether_sprintf(wh->i_addr2))); 132 /* 133 * NB: Node allocation is handled in the 134 * management handling routines. Just fake 135 * up a reference to the hosts's node to do 136 * the stuff below. 137 */ 138 ni = ieee80211_ref_node(ic->ic_bss); 139 } | |
140 break; 141 case IEEE80211_M_MONITOR: 142 /* NB: this should collect everything */ 143 goto out; 144 default: 145 /* XXX catch bad values */ 146 break; 147 } 148 ni->ni_rssi = rssi; 149 ni->ni_rstamp = rstamp; | 137 break; 138 case IEEE80211_M_MONITOR: 139 /* NB: this should collect everything */ 140 goto out; 141 default: 142 /* XXX catch bad values */ 143 break; 144 } 145 ni->ni_rssi = rssi; 146 ni->ni_rstamp = rstamp; |
150 ni->ni_rantenna = rantenna; | |
151 rxseq = ni->ni_rxseq; 152 ni->ni_rxseq = 153 le16toh(*(u_int16_t *)wh->i_seq) >> IEEE80211_SEQ_SEQ_SHIFT; 154 /* TODO: fragment */ 155 if ((wh->i_fc[1] & IEEE80211_FC1_RETRY) && 156 rxseq == ni->ni_rxseq) { 157 /* duplicate, silently discarded */ | 147 rxseq = ni->ni_rxseq; 148 ni->ni_rxseq = 149 le16toh(*(u_int16_t *)wh->i_seq) >> IEEE80211_SEQ_SEQ_SHIFT; 150 /* TODO: fragment */ 151 if ((wh->i_fc[1] & IEEE80211_FC1_RETRY) && 152 rxseq == ni->ni_rxseq) { 153 /* duplicate, silently discarded */ |
158 ieee80211_unref_node(&ni); | |
159 goto out; 160 } 161 ni->ni_inact = 0; | 154 goto out; 155 } 156 ni->ni_inact = 0; |
162 ieee80211_unref_node(&ni); | |
163 } 164 165 switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) { 166 case IEEE80211_FC0_TYPE_DATA: 167 switch (ic->ic_opmode) { 168 case IEEE80211_M_STA: 169 if (dir != IEEE80211_FC1_DIR_FROMDS) 170 goto out; --- 13 unchanged lines hidden (view full) --- 184 case IEEE80211_M_AHDEMO: 185 if (dir != IEEE80211_FC1_DIR_NODS) 186 goto out; 187 break; 188 case IEEE80211_M_HOSTAP: 189 if (dir != IEEE80211_FC1_DIR_TODS) 190 goto out; 191 /* check if source STA is associated */ | 157 } 158 159 switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) { 160 case IEEE80211_FC0_TYPE_DATA: 161 switch (ic->ic_opmode) { 162 case IEEE80211_M_STA: 163 if (dir != IEEE80211_FC1_DIR_FROMDS) 164 goto out; --- 13 unchanged lines hidden (view full) --- 178 case IEEE80211_M_AHDEMO: 179 if (dir != IEEE80211_FC1_DIR_NODS) 180 goto out; 181 break; 182 case IEEE80211_M_HOSTAP: 183 if (dir != IEEE80211_FC1_DIR_TODS) 184 goto out; 185 /* check if source STA is associated */ |
192 ni = ieee80211_find_node(ic, wh->i_addr2); 193 if (ni == NULL) { | 186 if (ni == ic->ic_bss) { |
194 IEEE80211_DPRINTF(("%s: data from unknown src " 195 "%s\n", __func__, 196 ether_sprintf(wh->i_addr2))); | 187 IEEE80211_DPRINTF(("%s: data from unknown src " 188 "%s\n", __func__, 189 ether_sprintf(wh->i_addr2))); |
190 /* NB: caller deals with reference */ |
|
197 ni = ieee80211_dup_bss(ic, wh->i_addr2); 198 if (ni != NULL) { 199 IEEE80211_SEND_MGMT(ic, ni, 200 IEEE80211_FC0_SUBTYPE_DEAUTH, 201 IEEE80211_REASON_NOT_AUTHED); 202 ieee80211_free_node(ic, ni); 203 } 204 goto err; 205 } 206 if (ni->ni_associd == 0) { 207 IEEE80211_DPRINTF(("ieee80211_input: " 208 "data from unassoc src %s\n", 209 ether_sprintf(wh->i_addr2))); 210 IEEE80211_SEND_MGMT(ic, ni, 211 IEEE80211_FC0_SUBTYPE_DISASSOC, 212 IEEE80211_REASON_NOT_ASSOCED); 213 ieee80211_unref_node(&ni); 214 goto err; 215 } | 191 ni = ieee80211_dup_bss(ic, wh->i_addr2); 192 if (ni != NULL) { 193 IEEE80211_SEND_MGMT(ic, ni, 194 IEEE80211_FC0_SUBTYPE_DEAUTH, 195 IEEE80211_REASON_NOT_AUTHED); 196 ieee80211_free_node(ic, ni); 197 } 198 goto err; 199 } 200 if (ni->ni_associd == 0) { 201 IEEE80211_DPRINTF(("ieee80211_input: " 202 "data from unassoc src %s\n", 203 ether_sprintf(wh->i_addr2))); 204 IEEE80211_SEND_MGMT(ic, ni, 205 IEEE80211_FC0_SUBTYPE_DISASSOC, 206 IEEE80211_REASON_NOT_ASSOCED); 207 ieee80211_unref_node(&ni); 208 goto err; 209 } |
216 ieee80211_unref_node(&ni); | |
217 break; 218 case IEEE80211_M_MONITOR: 219 break; 220 } 221 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 222 if (ic->ic_flags & IEEE80211_F_WEPON) { 223 m = ieee80211_wep_crypt(ifp, m, 0); 224 if (m == NULL) --- 10 unchanged lines hidden (view full) --- 235 goto err; 236 ifp->if_ipackets++; 237 238 /* perform as a bridge within the AP */ 239 m1 = NULL; 240 if (ic->ic_opmode == IEEE80211_M_HOSTAP) { 241 eh = mtod(m, struct ether_header *); 242 if (ETHER_IS_MULTICAST(eh->ether_dhost)) { | 210 break; 211 case IEEE80211_M_MONITOR: 212 break; 213 } 214 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 215 if (ic->ic_flags & IEEE80211_F_WEPON) { 216 m = ieee80211_wep_crypt(ifp, m, 0); 217 if (m == NULL) --- 10 unchanged lines hidden (view full) --- 228 goto err; 229 ifp->if_ipackets++; 230 231 /* perform as a bridge within the AP */ 232 m1 = NULL; 233 if (ic->ic_opmode == IEEE80211_M_HOSTAP) { 234 eh = mtod(m, struct ether_header *); 235 if (ETHER_IS_MULTICAST(eh->ether_dhost)) { |
243 m1 = m_copym(m, 0, M_COPYALL, M_DONTWAIT); | 236 m1 = m_copypacket(m, M_DONTWAIT); |
244 if (m1 == NULL) 245 ifp->if_oerrors++; 246 else 247 m1->m_flags |= M_MCAST; 248 } else { 249 ni = ieee80211_find_node(ic, eh->ether_dhost); 250 if (ni != NULL) { 251 if (ni->ni_associd != 0) { --- 61 unchanged lines hidden (view full) --- 313 if (doprint) 314 if_printf(ifp, "received %s from %s rssi %d\n", 315 ieee80211_mgt_subtype_name[subtype 316 >> IEEE80211_FC0_SUBTYPE_SHIFT], 317 ether_sprintf(wh->i_addr2), rssi); 318 } 319 if (ic->ic_rawbpf) 320 bpf_mtap(ic->ic_rawbpf, m); | 237 if (m1 == NULL) 238 ifp->if_oerrors++; 239 else 240 m1->m_flags |= M_MCAST; 241 } else { 242 ni = ieee80211_find_node(ic, eh->ether_dhost); 243 if (ni != NULL) { 244 if (ni->ni_associd != 0) { --- 61 unchanged lines hidden (view full) --- 306 if (doprint) 307 if_printf(ifp, "received %s from %s rssi %d\n", 308 ieee80211_mgt_subtype_name[subtype 309 >> IEEE80211_FC0_SUBTYPE_SHIFT], 310 ether_sprintf(wh->i_addr2), rssi); 311 } 312 if (ic->ic_rawbpf) 313 bpf_mtap(ic->ic_rawbpf, m); |
321 (*ic->ic_recv_mgmt)(ic, m, subtype, rssi, rstamp, rantenna); | 314 (*ic->ic_recv_mgmt)(ic, m, ni, subtype, rssi, rstamp); |
322 m_freem(m); 323 return; 324 325 case IEEE80211_FC0_TYPE_CTL: 326 default: 327 IEEE80211_DPRINTF(("%s: bad type %x\n", __func__, wh->i_fc[0])); 328 /* should not come here */ 329 break; --- 164 unchanged lines hidden (view full) --- 494 ieee80211_mgt_subtype_name[subtype >> \ 495 IEEE80211_FC0_SUBTYPE_SHIFT], \ 496 ether_sprintf(wh->i_addr2))); \ 497 return; \ 498 } \ 499} while (0) 500 501void | 315 m_freem(m); 316 return; 317 318 case IEEE80211_FC0_TYPE_CTL: 319 default: 320 IEEE80211_DPRINTF(("%s: bad type %x\n", __func__, wh->i_fc[0])); 321 /* should not come here */ 322 break; --- 164 unchanged lines hidden (view full) --- 487 ieee80211_mgt_subtype_name[subtype >> \ 488 IEEE80211_FC0_SUBTYPE_SHIFT], \ 489 ether_sprintf(wh->i_addr2))); \ 490 return; \ 491 } \ 492} while (0) 493 494void |
502ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0, int subtype, 503 int rssi, u_int32_t rstamp, u_int rantenna) | 495ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0, 496 struct ieee80211_node *ni, 497 int subtype, int rssi, u_int32_t rstamp) |
504{ 505#define ISPROBE(_st) ((_st) == IEEE80211_FC0_SUBTYPE_PROBE_RESP) 506 struct ifnet *ifp = &ic->ic_if; 507 struct ieee80211_frame *wh; | 498{ 499#define ISPROBE(_st) ((_st) == IEEE80211_FC0_SUBTYPE_PROBE_RESP) 500 struct ifnet *ifp = &ic->ic_if; 501 struct ieee80211_frame *wh; |
508 struct ieee80211_node *ni; | |
509 u_int8_t *frm, *efrm; 510 u_int8_t *ssid, *rates, *xrates; 511 int reassoc, resp, newassoc, allocbs; 512 513 wh = mtod(m0, struct ieee80211_frame *); 514 frm = (u_int8_t *)&wh[1]; 515 efrm = mtod(m0, u_int8_t *) + m0->m_len; 516 switch (subtype) { --- 150 unchanged lines hidden (view full) --- 667 */ 668 ni->ni_esslen = ssid[1]; 669 memset(ni->ni_essid, 0, sizeof(ni->ni_essid)); 670 memcpy(ni->ni_essid, ssid + 2, ssid[1]); 671 } 672 IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3); 673 ni->ni_rssi = rssi; 674 ni->ni_rstamp = rstamp; | 502 u_int8_t *frm, *efrm; 503 u_int8_t *ssid, *rates, *xrates; 504 int reassoc, resp, newassoc, allocbs; 505 506 wh = mtod(m0, struct ieee80211_frame *); 507 frm = (u_int8_t *)&wh[1]; 508 efrm = mtod(m0, u_int8_t *) + m0->m_len; 509 switch (subtype) { --- 150 unchanged lines hidden (view full) --- 660 */ 661 ni->ni_esslen = ssid[1]; 662 memset(ni->ni_essid, 0, sizeof(ni->ni_essid)); 663 memcpy(ni->ni_essid, ssid + 2, ssid[1]); 664 } 665 IEEE80211_ADDR_COPY(ni->ni_bssid, wh->i_addr3); 666 ni->ni_rssi = rssi; 667 ni->ni_rstamp = rstamp; |
675 ni->ni_rantenna = rantenna; | |
676 memcpy(ni->ni_tstamp, tstamp, sizeof(ni->ni_tstamp)); 677 ni->ni_intval = le16toh(*(u_int16_t *)bintval); 678 ni->ni_capinfo = le16toh(*(u_int16_t *)capinfo); 679 /* XXX validate channel # */ 680 ni->ni_chan = &ic->ic_channels[chan]; 681 ni->ni_fhdwell = fhdwell; 682 ni->ni_fhindex = fhindex; 683 ni->ni_erp = erp; --- 42 unchanged lines hidden (view full) --- 726 printf("%s: ssid unmatch ", __func__); 727 ieee80211_print_essid(ssid + 2, ssid[1]); 728 printf(" from %s\n", ether_sprintf(wh->i_addr2)); 729 } 730#endif 731 return; 732 } 733 | 668 memcpy(ni->ni_tstamp, tstamp, sizeof(ni->ni_tstamp)); 669 ni->ni_intval = le16toh(*(u_int16_t *)bintval); 670 ni->ni_capinfo = le16toh(*(u_int16_t *)capinfo); 671 /* XXX validate channel # */ 672 ni->ni_chan = &ic->ic_channels[chan]; 673 ni->ni_fhdwell = fhdwell; 674 ni->ni_fhindex = fhindex; 675 ni->ni_erp = erp; --- 42 unchanged lines hidden (view full) --- 718 printf("%s: ssid unmatch ", __func__); 719 ieee80211_print_essid(ssid + 2, ssid[1]); 720 printf(" from %s\n", ether_sprintf(wh->i_addr2)); 721 } 722#endif 723 return; 724 } 725 |
734 ni = ieee80211_find_node(ic, wh->i_addr2); 735 if (ni == NULL) { | 726 if (ni == ic->ic_bss) { |
736 ni = ieee80211_dup_bss(ic, wh->i_addr2); 737 if (ni == NULL) 738 return; 739 IEEE80211_DPRINTF(("%s: new req from %s\n", 740 __func__, ether_sprintf(wh->i_addr2))); 741 allocbs = 1; 742 } else 743 allocbs = 0; 744 ni->ni_rssi = rssi; 745 ni->ni_rstamp = rstamp; | 727 ni = ieee80211_dup_bss(ic, wh->i_addr2); 728 if (ni == NULL) 729 return; 730 IEEE80211_DPRINTF(("%s: new req from %s\n", 731 __func__, ether_sprintf(wh->i_addr2))); 732 allocbs = 1; 733 } else 734 allocbs = 0; 735 ni->ni_rssi = rssi; 736 ni->ni_rstamp = rstamp; |
746 ni->ni_rantenna = rantenna; | |
747 rate = ieee80211_setup_rates(ic, ni, rates, xrates, 748 IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE 749 | IEEE80211_F_DONEGO | IEEE80211_F_DODEL); 750 if (rate & IEEE80211_RATE_BASIC) { 751 IEEE80211_DPRINTF(("%s: rate negotiation failed: %s\n", 752 __func__,ether_sprintf(wh->i_addr2))); 753 } else { | 737 rate = ieee80211_setup_rates(ic, ni, rates, xrates, 738 IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE 739 | IEEE80211_F_DONEGO | IEEE80211_F_DODEL); 740 if (rate & IEEE80211_RATE_BASIC) { 741 IEEE80211_DPRINTF(("%s: rate negotiation failed: %s\n", 742 __func__,ether_sprintf(wh->i_addr2))); 743 } else { |
754 IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_PROBE_RESP, 755 0); | 744 IEEE80211_SEND_MGMT(ic, ni, 745 IEEE80211_FC0_SUBTYPE_PROBE_RESP, 0); |
756 } | 746 } |
757 if (allocbs && ic->ic_opmode == IEEE80211_M_HOSTAP) 758 ieee80211_free_node(ic, ni); 759 else 760 ieee80211_unref_node(&ni); | 747 if (allocbs) { 748 /* XXX just use free? */ 749 if (ic->ic_opmode == IEEE80211_M_HOSTAP) 750 ieee80211_free_node(ic, ni); 751 else 752 ieee80211_unref_node(&ni); 753 } |
761 break; 762 } 763 764 case IEEE80211_FC0_SUBTYPE_AUTH: { 765 u_int16_t algo, seq, status; 766 /* 767 * auth frame format 768 * [2] algorithm --- 21 unchanged lines hidden (view full) --- 790 791 case IEEE80211_M_AHDEMO: 792 /* should not come here */ 793 break; 794 795 case IEEE80211_M_HOSTAP: 796 if (ic->ic_state != IEEE80211_S_RUN || seq != 1) 797 return; | 754 break; 755 } 756 757 case IEEE80211_FC0_SUBTYPE_AUTH: { 758 u_int16_t algo, seq, status; 759 /* 760 * auth frame format 761 * [2] algorithm --- 21 unchanged lines hidden (view full) --- 783 784 case IEEE80211_M_AHDEMO: 785 /* should not come here */ 786 break; 787 788 case IEEE80211_M_HOSTAP: 789 if (ic->ic_state != IEEE80211_S_RUN || seq != 1) 790 return; |
798 allocbs = 0; 799 ni = ieee80211_find_node(ic, wh->i_addr2); 800 if (ni == NULL) { | 791 if (ni == ic->ic_bss) { |
801 ni = ieee80211_alloc_node(ic, wh->i_addr2); 802 if (ni == NULL) 803 return; 804 IEEE80211_ADDR_COPY(ni->ni_bssid, ic->ic_bss->ni_bssid); 805 ni->ni_rssi = rssi; 806 ni->ni_rstamp = rstamp; | 792 ni = ieee80211_alloc_node(ic, wh->i_addr2); 793 if (ni == NULL) 794 return; 795 IEEE80211_ADDR_COPY(ni->ni_bssid, ic->ic_bss->ni_bssid); 796 ni->ni_rssi = rssi; 797 ni->ni_rstamp = rstamp; |
807 ni->ni_rantenna = rantenna; | |
808 ni->ni_chan = ic->ic_bss->ni_chan; 809 allocbs = 1; | 798 ni->ni_chan = ic->ic_bss->ni_chan; 799 allocbs = 1; |
810 } 811 IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_AUTH, 2); | 800 } else 801 allocbs = 0; 802 IEEE80211_SEND_MGMT(ic, ni, 803 IEEE80211_FC0_SUBTYPE_AUTH, 2); |
812 if (ifp->if_flags & IFF_DEBUG) 813 if_printf(ifp, "station %s %s authenticated\n", 814 (allocbs ? "newly" : "already"), 815 ether_sprintf(ni->ni_macaddr)); | 804 if (ifp->if_flags & IFF_DEBUG) 805 if_printf(ifp, "station %s %s authenticated\n", 806 (allocbs ? "newly" : "already"), 807 ether_sprintf(ni->ni_macaddr)); |
816 ieee80211_unref_node(&ni); | |
817 break; 818 819 case IEEE80211_M_STA: 820 if (ic->ic_state != IEEE80211_S_AUTH || seq != 2) 821 return; 822 if (status != 0) { 823 if_printf(&ic->ic_if, 824 "authentication failed (reason %d) for %s\n", 825 status, 826 ether_sprintf(wh->i_addr3)); | 808 break; 809 810 case IEEE80211_M_STA: 811 if (ic->ic_state != IEEE80211_S_AUTH || seq != 2) 812 return; 813 if (status != 0) { 814 if_printf(&ic->ic_if, 815 "authentication failed (reason %d) for %s\n", 816 status, 817 ether_sprintf(wh->i_addr3)); |
827 ni = ieee80211_find_node(ic, wh->i_addr2); 828 if (ni != NULL) { | 818 if (ni != ic->ic_bss) |
829 ni->ni_fails++; | 819 ni->ni_fails++; |
830 ieee80211_unref_node(&ni); 831 } | |
832 return; 833 } 834 ieee80211_new_state(ic, IEEE80211_S_ASSOC, 835 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 836 break; 837 case IEEE80211_M_MONITOR: 838 break; 839 } --- 57 unchanged lines hidden (view full) --- 897 if (ieee80211_debug) { 898 printf("%s: ssid unmatch ", __func__); 899 ieee80211_print_essid(ssid + 2, ssid[1]); 900 printf(" from %s\n", ether_sprintf(wh->i_addr2)); 901 } 902#endif 903 return; 904 } | 820 return; 821 } 822 ieee80211_new_state(ic, IEEE80211_S_ASSOC, 823 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 824 break; 825 case IEEE80211_M_MONITOR: 826 break; 827 } --- 57 unchanged lines hidden (view full) --- 885 if (ieee80211_debug) { 886 printf("%s: ssid unmatch ", __func__); 887 ieee80211_print_essid(ssid + 2, ssid[1]); 888 printf(" from %s\n", ether_sprintf(wh->i_addr2)); 889 } 890#endif 891 return; 892 } |
905 ni = ieee80211_find_node(ic, wh->i_addr2); 906 if (ni == NULL) { | 893 if (ni == ic->ic_bss) { |
907 IEEE80211_DPRINTF(("%s: not authenticated for %s\n", 908 __func__, ether_sprintf(wh->i_addr2))); 909 ni = ieee80211_dup_bss(ic, wh->i_addr2); | 894 IEEE80211_DPRINTF(("%s: not authenticated for %s\n", 895 __func__, ether_sprintf(wh->i_addr2))); 896 ni = ieee80211_dup_bss(ic, wh->i_addr2); |
910 if (ni == NULL) 911 return; 912 IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_DEAUTH, 913 IEEE80211_REASON_ASSOC_NOT_AUTHED); 914 ieee80211_free_node(ic, ni); | 897 if (ni != NULL) { 898 IEEE80211_SEND_MGMT(ic, ni, 899 IEEE80211_FC0_SUBTYPE_DEAUTH, 900 IEEE80211_REASON_ASSOC_NOT_AUTHED); 901 ieee80211_free_node(ic, ni); 902 } |
915 return; 916 } 917 /* XXX per-node cipher suite */ 918 /* XXX some stations use the privacy bit for handling APs 919 that suport both encrypted and unencrypted traffic */ 920 if ((capinfo & IEEE80211_CAPINFO_ESS) == 0 || 921 (capinfo & IEEE80211_CAPINFO_PRIVACY) != 922 ((ic->ic_flags & IEEE80211_F_WEPON) ? 923 IEEE80211_CAPINFO_PRIVACY : 0)) { 924 IEEE80211_DPRINTF(("%s: capability mismatch %x for %s\n", 925 __func__, capinfo, ether_sprintf(wh->i_addr2))); 926 ni->ni_associd = 0; | 903 return; 904 } 905 /* XXX per-node cipher suite */ 906 /* XXX some stations use the privacy bit for handling APs 907 that suport both encrypted and unencrypted traffic */ 908 if ((capinfo & IEEE80211_CAPINFO_ESS) == 0 || 909 (capinfo & IEEE80211_CAPINFO_PRIVACY) != 910 ((ic->ic_flags & IEEE80211_F_WEPON) ? 911 IEEE80211_CAPINFO_PRIVACY : 0)) { 912 IEEE80211_DPRINTF(("%s: capability mismatch %x for %s\n", 913 __func__, capinfo, ether_sprintf(wh->i_addr2))); 914 ni->ni_associd = 0; |
927 IEEE80211_SEND_MGMT(ic, ni, resp, IEEE80211_STATUS_CAPINFO); 928 ieee80211_unref_node(&ni); | 915 IEEE80211_SEND_MGMT(ic, ni, resp, 916 IEEE80211_STATUS_CAPINFO); |
929 return; 930 } 931 ieee80211_setup_rates(ic, ni, rates, xrates, 932 IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE | 933 IEEE80211_F_DONEGO | IEEE80211_F_DODEL); 934 if (ni->ni_rates.rs_nrates == 0) { 935 IEEE80211_DPRINTF(("%s: rate unmatch for %s\n", 936 __func__, ether_sprintf(wh->i_addr2))); 937 ni->ni_associd = 0; | 917 return; 918 } 919 ieee80211_setup_rates(ic, ni, rates, xrates, 920 IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE | 921 IEEE80211_F_DONEGO | IEEE80211_F_DODEL); 922 if (ni->ni_rates.rs_nrates == 0) { 923 IEEE80211_DPRINTF(("%s: rate unmatch for %s\n", 924 __func__, ether_sprintf(wh->i_addr2))); 925 ni->ni_associd = 0; |
938 IEEE80211_SEND_MGMT(ic, ni, resp, IEEE80211_STATUS_BASIC_RATE); 939 ieee80211_unref_node(&ni); | 926 IEEE80211_SEND_MGMT(ic, ni, resp, 927 IEEE80211_STATUS_BASIC_RATE); |
940 return; 941 } 942 ni->ni_rssi = rssi; 943 ni->ni_rstamp = rstamp; | 928 return; 929 } 930 ni->ni_rssi = rssi; 931 ni->ni_rstamp = rstamp; |
944 ni->ni_rantenna = rantenna; | |
945 ni->ni_intval = bintval; 946 ni->ni_capinfo = capinfo; 947 ni->ni_chan = ic->ic_bss->ni_chan; 948 ni->ni_fhdwell = ic->ic_bss->ni_fhdwell; 949 ni->ni_fhindex = ic->ic_bss->ni_fhindex; 950 if (ni->ni_associd == 0) { 951 /* XXX handle rollover at 2007 */ 952 /* XXX guarantee uniqueness */ --- 6 unchanged lines hidden (view full) --- 959 IEEE80211_SEND_MGMT(ic, ni, resp, IEEE80211_STATUS_SUCCESS); 960 if (ifp->if_flags & IFF_DEBUG) 961 if_printf(ifp, "station %s %s associated\n", 962 (newassoc ? "newly" : "already"), 963 ether_sprintf(ni->ni_macaddr)); 964 /* give driver a chance to setup state like ni_txrate */ 965 if (ic->ic_newassoc) 966 (*ic->ic_newassoc)(ic, ni, newassoc); | 932 ni->ni_intval = bintval; 933 ni->ni_capinfo = capinfo; 934 ni->ni_chan = ic->ic_bss->ni_chan; 935 ni->ni_fhdwell = ic->ic_bss->ni_fhdwell; 936 ni->ni_fhindex = ic->ic_bss->ni_fhindex; 937 if (ni->ni_associd == 0) { 938 /* XXX handle rollover at 2007 */ 939 /* XXX guarantee uniqueness */ --- 6 unchanged lines hidden (view full) --- 946 IEEE80211_SEND_MGMT(ic, ni, resp, IEEE80211_STATUS_SUCCESS); 947 if (ifp->if_flags & IFF_DEBUG) 948 if_printf(ifp, "station %s %s associated\n", 949 (newassoc ? "newly" : "already"), 950 ether_sprintf(ni->ni_macaddr)); 951 /* give driver a chance to setup state like ni_txrate */ 952 if (ic->ic_newassoc) 953 (*ic->ic_newassoc)(ic, ni, newassoc); |
967 ieee80211_unref_node(&ni); | |
968 break; 969 } 970 971 case IEEE80211_FC0_SUBTYPE_ASSOC_RESP: 972 case IEEE80211_FC0_SUBTYPE_REASSOC_RESP: { 973 u_int16_t status; 974 975 if (ic->ic_opmode != IEEE80211_M_STA || --- 13 unchanged lines hidden (view full) --- 989 ni->ni_capinfo = le16toh(*(u_int16_t *)frm); 990 frm += 2; 991 992 status = le16toh(*(u_int16_t *)frm); 993 frm += 2; 994 if (status != 0) { 995 if_printf(ifp, "association failed (reason %d) for %s\n", 996 status, ether_sprintf(wh->i_addr3)); | 954 break; 955 } 956 957 case IEEE80211_FC0_SUBTYPE_ASSOC_RESP: 958 case IEEE80211_FC0_SUBTYPE_REASSOC_RESP: { 959 u_int16_t status; 960 961 if (ic->ic_opmode != IEEE80211_M_STA || --- 13 unchanged lines hidden (view full) --- 975 ni->ni_capinfo = le16toh(*(u_int16_t *)frm); 976 frm += 2; 977 978 status = le16toh(*(u_int16_t *)frm); 979 frm += 2; 980 if (status != 0) { 981 if_printf(ifp, "association failed (reason %d) for %s\n", 982 status, ether_sprintf(wh->i_addr3)); |
997 ni = ieee80211_find_node(ic, wh->i_addr2); 998 if (ni != NULL) { | 983 if (ni != ic->ic_bss) |
999 ni->ni_fails++; | 984 ni->ni_fails++; |
1000 ieee80211_unref_node(&ni); 1001 } | |
1002 return; 1003 } 1004 ni->ni_associd = le16toh(*(u_int16_t *)frm); 1005 frm += 2; 1006 1007 rates = xrates = NULL; 1008 while (frm < efrm) { 1009 switch (*frm) { --- 26 unchanged lines hidden (view full) --- 1036 IEEE80211_VERIFY_LENGTH(efrm - frm, 2); 1037 reason = le16toh(*(u_int16_t *)frm); 1038 switch (ic->ic_opmode) { 1039 case IEEE80211_M_STA: 1040 ieee80211_new_state(ic, IEEE80211_S_AUTH, 1041 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 1042 break; 1043 case IEEE80211_M_HOSTAP: | 985 return; 986 } 987 ni->ni_associd = le16toh(*(u_int16_t *)frm); 988 frm += 2; 989 990 rates = xrates = NULL; 991 while (frm < efrm) { 992 switch (*frm) { --- 26 unchanged lines hidden (view full) --- 1019 IEEE80211_VERIFY_LENGTH(efrm - frm, 2); 1020 reason = le16toh(*(u_int16_t *)frm); 1021 switch (ic->ic_opmode) { 1022 case IEEE80211_M_STA: 1023 ieee80211_new_state(ic, IEEE80211_S_AUTH, 1024 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 1025 break; 1026 case IEEE80211_M_HOSTAP: |
1044 ni = ieee80211_find_node(ic, wh->i_addr2); 1045 if (ni != NULL) { | 1027 if (ni != ic->ic_bss) { |
1046 if (ifp->if_flags & IFF_DEBUG) 1047 if_printf(ifp, "station %s deauthenticated" 1048 " by peer (reason %d)\n", 1049 ether_sprintf(ni->ni_macaddr), reason); | 1028 if (ifp->if_flags & IFF_DEBUG) 1029 if_printf(ifp, "station %s deauthenticated" 1030 " by peer (reason %d)\n", 1031 ether_sprintf(ni->ni_macaddr), reason); |
1050 ieee80211_free_node(ic, ni); | 1032 /* node will be free'd on return */ 1033 ieee80211_unref_node(&ni); |
1051 } 1052 break; 1053 default: 1054 break; 1055 } 1056 break; 1057 } 1058 --- 6 unchanged lines hidden (view full) --- 1065 IEEE80211_VERIFY_LENGTH(efrm - frm, 2); 1066 reason = le16toh(*(u_int16_t *)frm); 1067 switch (ic->ic_opmode) { 1068 case IEEE80211_M_STA: 1069 ieee80211_new_state(ic, IEEE80211_S_ASSOC, 1070 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 1071 break; 1072 case IEEE80211_M_HOSTAP: | 1034 } 1035 break; 1036 default: 1037 break; 1038 } 1039 break; 1040 } 1041 --- 6 unchanged lines hidden (view full) --- 1048 IEEE80211_VERIFY_LENGTH(efrm - frm, 2); 1049 reason = le16toh(*(u_int16_t *)frm); 1050 switch (ic->ic_opmode) { 1051 case IEEE80211_M_STA: 1052 ieee80211_new_state(ic, IEEE80211_S_ASSOC, 1053 wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK); 1054 break; 1055 case IEEE80211_M_HOSTAP: |
1073 ni = ieee80211_find_node(ic, wh->i_addr2); 1074 if (ni != NULL) { | 1056 if (ni != ic->ic_bss) { |
1075 if (ifp->if_flags & IFF_DEBUG) 1076 if_printf(ifp, "station %s disassociated" 1077 " by peer (reason %d)\n", 1078 ether_sprintf(ni->ni_macaddr), reason); 1079 ni->ni_associd = 0; | 1057 if (ifp->if_flags & IFF_DEBUG) 1058 if_printf(ifp, "station %s disassociated" 1059 " by peer (reason %d)\n", 1060 ether_sprintf(ni->ni_macaddr), reason); 1061 ni->ni_associd = 0; |
1080 ieee80211_unref_node(&ni); | 1062 /* XXX node reclaimed how? */ |
1081 } 1082 break; 1083 default: 1084 break; 1085 } 1086 break; 1087 } 1088 default: 1089 IEEE80211_DPRINTF(("%s: mgmt frame with subtype 0x%x not " 1090 "handled\n", __func__, subtype)); 1091 break; 1092 } 1093#undef ISPROBE 1094} 1095#undef IEEE80211_VERIFY_LENGTH 1096#undef IEEE80211_VERIFY_ELEMENT | 1063 } 1064 break; 1065 default: 1066 break; 1067 } 1068 break; 1069 } 1070 default: 1071 IEEE80211_DPRINTF(("%s: mgmt frame with subtype 0x%x not " 1072 "handled\n", __func__, subtype)); 1073 break; 1074 } 1075#undef ISPROBE 1076} 1077#undef IEEE80211_VERIFY_LENGTH 1078#undef IEEE80211_VERIFY_ELEMENT |