Deleted Added
full compact
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