Module Name:    src
Committed By:   maxv
Date:           Tue Jan 16 16:00:17 UTC 2018

Modified Files:
        src/sys/net80211: ieee80211_input.c

Log Message:
Introduce ieee80211_recv_mgmt_assoc_resp.


To generate a diff of this commit:
cvs rdiff -u -r1.100 -r1.101 src/sys/net80211/ieee80211_input.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/net80211/ieee80211_input.c
diff -u src/sys/net80211/ieee80211_input.c:1.100 src/sys/net80211/ieee80211_input.c:1.101
--- src/sys/net80211/ieee80211_input.c:1.100	Tue Jan 16 15:55:14 2018
+++ src/sys/net80211/ieee80211_input.c	Tue Jan 16 16:00:17 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: ieee80211_input.c,v 1.100 2018/01/16 15:55:14 maxv Exp $	*/
+/*	$NetBSD: ieee80211_input.c,v 1.101 2018/01/16 16:00:17 maxv Exp $	*/
 
 /*
  * Copyright (c) 2001 Atsushi Onoe
@@ -37,7 +37,7 @@
 __FBSDID("$FreeBSD: src/sys/net80211/ieee80211_input.c,v 1.81 2005/08/10 16:22:29 sam Exp $");
 #endif
 #ifdef __NetBSD__
-__KERNEL_RCSID(0, "$NetBSD: ieee80211_input.c,v 1.100 2018/01/16 15:55:14 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ieee80211_input.c,v 1.101 2018/01/16 16:00:17 maxv Exp $");
 #endif
 
 #ifdef _KERNEL_OPT
@@ -2668,17 +2668,148 @@ ieee80211_recv_mgmt_assoc_req(struct iee
 	ieee80211_node_join(ic, ni, resp);
 }
 
+#define	ISREASSOC(_st)	((_st) == IEEE80211_FC0_SUBTYPE_REASSOC_RESP)
+
+static void
+ieee80211_recv_mgmt_assoc_resp(struct ieee80211com *ic, struct mbuf *m0,
+    struct ieee80211_node *ni, int subtype, int rssi, u_int32_t rstamp)
+{
+	struct ieee80211_frame *wh;
+	u_int8_t *frm, *efrm;
+	u_int8_t *rates, *xrates, *wpa, *wme;
+	u_int8_t rate;
+	IEEE80211_DEBUGVAR(char ebuf[3 * ETHER_ADDR_LEN]);
+
+	wh = mtod(m0, struct ieee80211_frame *);
+	frm = (u_int8_t *)(wh + 1);
+	efrm = mtod(m0, u_int8_t *) + m0->m_len;
+
+	u_int16_t capinfo, associd;
+	u_int16_t status;
+
+	if (ic->ic_opmode != IEEE80211_M_STA ||
+	    ic->ic_state != IEEE80211_S_ASSOC) {
+		ic->ic_stats.is_rx_mgtdiscard++;
+		return;
+	}
+
+	/*
+	 * asresp frame format
+	 *	[2] capability information
+	 *	[2] status
+	 *	[2] association ID
+	 *	[tlv] supported rates
+	 *	[tlv] extended supported rates
+	 *	[tlv] WME
+	 */
+	IEEE80211_VERIFY_LENGTH(efrm - frm, 6);
+	ni = ic->ic_bss;
+	capinfo = le16toh(*(u_int16_t *)frm);
+	frm += 2;
+	status = le16toh(*(u_int16_t *)frm);
+	frm += 2;
+	if (status != 0) {
+		IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC,
+		    "[%s] %sassoc failed (reason %d)\n",
+		    ether_snprintf(ebuf, sizeof(ebuf), wh->i_addr2),
+		    ISREASSOC(subtype) ?  "re" : "", status);
+		if (ni != ic->ic_bss)	/* XXX never true? */
+			ni->ni_fails++;
+		ic->ic_stats.is_rx_auth_fail++;	/* XXX */
+		return;
+	}
+	associd = le16toh(*(u_int16_t *)frm);
+	frm += 2;
+
+	rates = xrates = wpa = wme = NULL;
+	while (frm < efrm) {
+		switch (*frm) {
+		case IEEE80211_ELEMID_RATES:
+			rates = frm;
+			break;
+		case IEEE80211_ELEMID_XRATES:
+			xrates = frm;
+			break;
+		case IEEE80211_ELEMID_VENDOR:
+			if (iswmeoui(frm))
+				wme = frm;
+			/* XXX Atheros OUI support */
+			break;
+		}
+		frm += frm[1] + 2;
+	}
+
+	IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE);
+	rate = ieee80211_setup_rates(ni, rates, xrates,
+			IEEE80211_R_DOSORT | IEEE80211_R_DOFRATE |
+			IEEE80211_R_DONEGO | IEEE80211_R_DODEL);
+	if (rate & IEEE80211_RATE_BASIC) {
+		IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC,
+		    "[%s] %sassoc failed (rate set mismatch)\n",
+		    ether_snprintf(ebuf, sizeof(ebuf), wh->i_addr2),
+		    ISREASSOC(subtype) ?  "re" : "");
+		if (ni != ic->ic_bss)	/* XXX never true? */
+			ni->ni_fails++;
+		ic->ic_stats.is_rx_assoc_norate++;
+		ieee80211_new_state(ic, IEEE80211_S_SCAN, 0);
+		return;
+	}
+
+	ni->ni_capinfo = capinfo;
+	ni->ni_associd = associd;
+	if (wme != NULL &&
+	    ieee80211_parse_wmeparams(ic, wme, wh) >= 0) {
+		ni->ni_flags |= IEEE80211_NODE_QOS;
+		ieee80211_wme_updateparams(ic);
+	} else
+		ni->ni_flags &= ~IEEE80211_NODE_QOS;
+	/*
+	 * Configure state now that we are associated.
+	 *
+	 * XXX may need different/additional driver callbacks?
+	 */
+	if (ic->ic_curmode == IEEE80211_MODE_11A ||
+	    (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE)) {
+		ic->ic_flags |= IEEE80211_F_SHPREAMBLE;
+		ic->ic_flags &= ~IEEE80211_F_USEBARKER;
+	} else {
+		ic->ic_flags &= ~IEEE80211_F_SHPREAMBLE;
+		ic->ic_flags |= IEEE80211_F_USEBARKER;
+	}
+	ieee80211_set_shortslottime(ic,
+		ic->ic_curmode == IEEE80211_MODE_11A ||
+		(ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME));
+	/*
+	 * Honor ERP protection.
+	 *
+	 * NB: ni_erp should zero for non-11g operation.
+	 * XXX check ic_curmode anyway?
+	 */
+	if (ic->ic_curmode == IEEE80211_MODE_11G &&
+	    (ni->ni_erp & IEEE80211_ERP_USE_PROTECTION))
+		ic->ic_flags |= IEEE80211_F_USEPROT;
+	else
+		ic->ic_flags &= ~IEEE80211_F_USEPROT;
+	IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC,
+	    "[%s] %sassoc success: %s preamble, %s slot time%s%s\n",
+	    ether_snprintf(ebuf, sizeof(ebuf), wh->i_addr2),
+	    ISREASSOC(subtype) ? "re" : "",
+	    ic->ic_flags&IEEE80211_F_SHPREAMBLE ? "short" : "long",
+	    ic->ic_flags&IEEE80211_F_SHSLOT ? "short" : "long",
+	    ic->ic_flags&IEEE80211_F_USEPROT ? ", protection" : "",
+	    ni->ni_flags & IEEE80211_NODE_QOS ? ", QoS" : ""
+	);
+	ieee80211_new_state(ic, IEEE80211_S_RUN, subtype);
+}
+
 /* -------------------------------------------------------------------------- */
 
 void
 ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
     struct ieee80211_node *ni, int subtype, int rssi, u_int32_t rstamp)
 {
-#define	ISREASSOC(_st)	((_st) == IEEE80211_FC0_SUBTYPE_REASSOC_RESP)
 	struct ieee80211_frame *wh;
 	u_int8_t *frm, *efrm;
-	u_int8_t *rates, *xrates, *wpa, *wme;
-	u_int8_t rate;
 	IEEE80211_DEBUGVAR(char ebuf[3 * ETHER_ADDR_LEN]);
 
 	wh = mtod(m0, struct ieee80211_frame *);
@@ -2705,125 +2836,9 @@ ieee80211_recv_mgmt(struct ieee80211com 
 		return;
 
 	case IEEE80211_FC0_SUBTYPE_ASSOC_RESP:
-	case IEEE80211_FC0_SUBTYPE_REASSOC_RESP: {
-		u_int16_t capinfo, associd;
-		u_int16_t status;
-
-		if (ic->ic_opmode != IEEE80211_M_STA ||
-		    ic->ic_state != IEEE80211_S_ASSOC) {
-			ic->ic_stats.is_rx_mgtdiscard++;
-			return;
-		}
-
-		/*
-		 * asresp frame format
-		 *	[2] capability information
-		 *	[2] status
-		 *	[2] association ID
-		 *	[tlv] supported rates
-		 *	[tlv] extended supported rates
-		 *	[tlv] WME
-		 */
-		IEEE80211_VERIFY_LENGTH(efrm - frm, 6);
-		ni = ic->ic_bss;
-		capinfo = le16toh(*(u_int16_t *)frm);
-		frm += 2;
-		status = le16toh(*(u_int16_t *)frm);
-		frm += 2;
-		if (status != 0) {
-			IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC,
-			    "[%s] %sassoc failed (reason %d)\n",
-			    ether_snprintf(ebuf, sizeof(ebuf), wh->i_addr2),
-			    ISREASSOC(subtype) ?  "re" : "", status);
-			if (ni != ic->ic_bss)	/* XXX never true? */
-				ni->ni_fails++;
-			ic->ic_stats.is_rx_auth_fail++;	/* XXX */
-			return;
-		}
-		associd = le16toh(*(u_int16_t *)frm);
-		frm += 2;
-
-		rates = xrates = wpa = wme = NULL;
-		while (frm < efrm) {
-			switch (*frm) {
-			case IEEE80211_ELEMID_RATES:
-				rates = frm;
-				break;
-			case IEEE80211_ELEMID_XRATES:
-				xrates = frm;
-				break;
-			case IEEE80211_ELEMID_VENDOR:
-				if (iswmeoui(frm))
-					wme = frm;
-				/* XXX Atheros OUI support */
-				break;
-			}
-			frm += frm[1] + 2;
-		}
-
-		IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE);
-		rate = ieee80211_setup_rates(ni, rates, xrates,
-				IEEE80211_R_DOSORT | IEEE80211_R_DOFRATE |
-				IEEE80211_R_DONEGO | IEEE80211_R_DODEL);
-		if (rate & IEEE80211_RATE_BASIC) {
-			IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC,
-			    "[%s] %sassoc failed (rate set mismatch)\n",
-			    ether_snprintf(ebuf, sizeof(ebuf), wh->i_addr2),
-			    ISREASSOC(subtype) ?  "re" : "");
-			if (ni != ic->ic_bss)	/* XXX never true? */
-				ni->ni_fails++;
-			ic->ic_stats.is_rx_assoc_norate++;
-			ieee80211_new_state(ic, IEEE80211_S_SCAN, 0);
-			return;
-		}
-
-		ni->ni_capinfo = capinfo;
-		ni->ni_associd = associd;
-		if (wme != NULL &&
-		    ieee80211_parse_wmeparams(ic, wme, wh) >= 0) {
-			ni->ni_flags |= IEEE80211_NODE_QOS;
-			ieee80211_wme_updateparams(ic);
-		} else
-			ni->ni_flags &= ~IEEE80211_NODE_QOS;
-		/*
-		 * Configure state now that we are associated.
-		 *
-		 * XXX may need different/additional driver callbacks?
-		 */
-		if (ic->ic_curmode == IEEE80211_MODE_11A ||
-		    (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE)) {
-			ic->ic_flags |= IEEE80211_F_SHPREAMBLE;
-			ic->ic_flags &= ~IEEE80211_F_USEBARKER;
-		} else {
-			ic->ic_flags &= ~IEEE80211_F_SHPREAMBLE;
-			ic->ic_flags |= IEEE80211_F_USEBARKER;
-		}
-		ieee80211_set_shortslottime(ic,
-			ic->ic_curmode == IEEE80211_MODE_11A ||
-			(ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME));
-		/*
-		 * Honor ERP protection.
-		 *
-		 * NB: ni_erp should zero for non-11g operation.
-		 * XXX check ic_curmode anyway?
-		 */
-		if (ic->ic_curmode == IEEE80211_MODE_11G &&
-		    (ni->ni_erp & IEEE80211_ERP_USE_PROTECTION))
-			ic->ic_flags |= IEEE80211_F_USEPROT;
-		else
-			ic->ic_flags &= ~IEEE80211_F_USEPROT;
-		IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC,
-		    "[%s] %sassoc success: %s preamble, %s slot time%s%s\n",
-		    ether_snprintf(ebuf, sizeof(ebuf), wh->i_addr2),
-		    ISREASSOC(subtype) ? "re" : "",
-		    ic->ic_flags&IEEE80211_F_SHPREAMBLE ? "short" : "long",
-		    ic->ic_flags&IEEE80211_F_SHSLOT ? "short" : "long",
-		    ic->ic_flags&IEEE80211_F_USEPROT ? ", protection" : "",
-		    ni->ni_flags & IEEE80211_NODE_QOS ? ", QoS" : ""
-		);
-		ieee80211_new_state(ic, IEEE80211_S_RUN, subtype);
-		break;
-	}
+	case IEEE80211_FC0_SUBTYPE_REASSOC_RESP:
+		ieee80211_recv_mgmt_assoc_resp(ic, m0, ni, subtype, rssi, rstamp);
+		return;
 
 	case IEEE80211_FC0_SUBTYPE_DEAUTH: {
 		u_int16_t reason;

Reply via email to