PERFORCE change 87499 for review

Sam Leffler sam at FreeBSD.org
Wed Nov 30 04:18:35 GMT 2005


http://perforce.freebsd.org/chv.cgi?CH=87499

Change 87499 by sam at sam_ebb on 2005/11/30 04:17:13

	handle ap's that beacon both wpa and rsn:
	o record both ie's
	o add new ioctl to return both (existing ioctl cannot
	  handle it but is kept for compatbility)

Affected files ...

.. //depot/projects/wifi/sys/net80211/ieee80211_input.c#70 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_ioctl.c#54 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_ioctl.h#32 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_node.c#70 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_node.h#36 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_scan.h#5 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_scan_sta.c#8 edit

Differences ...

==== //depot/projects/wifi/sys/net80211/ieee80211_input.c#70 (text+ko) ====

@@ -1919,7 +1919,7 @@
 #define	ISREASSOC(_st)	((_st) == IEEE80211_FC0_SUBTYPE_REASSOC_RESP)
 	struct ieee80211_frame *wh;
 	u_int8_t *frm, *efrm;
-	u_int8_t *ssid, *rates, *xrates, *wpa, *wme, *ath;
+	u_int8_t *ssid, *rates, *xrates, *wpa, *rsn, *wme, *ath;
 	int reassoc, resp, allocbs;
 	u_int8_t rate;
 
@@ -2015,7 +2015,7 @@
 				scan.erp = frm[2];
 				break;
 			case IEEE80211_ELEMID_RSN:
-				scan.wpa = frm;
+				scan.rsn = frm;
 				break;
 			case IEEE80211_ELEMID_VENDOR:
 				if (iswpaoui(frm))
@@ -2371,7 +2371,7 @@
 	case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
 	case IEEE80211_FC0_SUBTYPE_REASSOC_REQ: {
 		u_int16_t capinfo, lintval;
-		struct ieee80211_rsnparms rsn;
+		struct ieee80211_rsnparms rsnparms;
 		u_int8_t reason;
 
 		if (ic->ic_opmode != IEEE80211_M_HOSTAP ||
@@ -2411,7 +2411,7 @@
 		lintval = le16toh(*(u_int16_t *)frm);	frm += 2;
 		if (reassoc)
 			frm += 6;	/* ignore current AP info */
-		ssid = rates = xrates = wpa = wme = ath = NULL;
+		ssid = rates = xrates = wpa = rsn = wme = ath = NULL;
 		while (frm < efrm) {
 			switch (*frm) {
 			case IEEE80211_ELEMID_SSID:
@@ -2425,7 +2425,7 @@
 				break;
 			/* XXX verify only one of RSN and WPA ie's? */
 			case IEEE80211_ELEMID_RSN:
-				wpa = frm;
+				rsn = frm;
 				break;
 			case IEEE80211_ELEMID_VENDOR:
 				if (iswpaoui(frm))
@@ -2453,8 +2453,21 @@
 			ic->ic_stats.is_rx_assoc_notauth++;
 			return;
 		}
-		/* assert right associstion security credentials */
-		if (wpa == NULL && (ic->ic_flags & IEEE80211_F_WPA)) {
+		/* assert right association security credentials */
+		switch (ic->ic_flags & IEEE80211_F_WPA) {
+		case IEEE80211_F_WPA1:
+			if (wpa == NULL)
+				goto badwparsn;
+			break;
+		case IEEE80211_F_WPA2:
+			if (rsn == NULL)
+				goto badwparsn;
+			break;
+		case IEEE80211_F_WPA1|IEEE80211_F_WPA2:
+			if (wpa != NULL || rsn != NULL)
+				break;
+			/* fall thru... */
+		badwparsn:
 			IEEE80211_DPRINTF(ic,
 			    IEEE80211_MSG_ASSOC | IEEE80211_MSG_WPA,
 			    "[%s] no WPA/RSN IE in association request\n",
@@ -2463,23 +2476,22 @@
 			    IEEE80211_FC0_SUBTYPE_DEAUTH,
 			    IEEE80211_REASON_RSN_REQUIRED);
 			ieee80211_node_leave(ic, ni);
-			/* XXX distinguish WPA/RSN? */
 			ic->ic_stats.is_rx_assoc_badwpaie++;
 			return;	
 		}
-		if (wpa != NULL) {
+		if (wpa != NULL || rsn != NULL) {
 			/*
-			 * Parse WPA information element.  Note that
+			 * Parse WPA/RSN information element.  Note that
 			 * we initialize the param block from the node
 			 * state so that information in the IE overrides
 			 * our defaults.  The resulting parameters are
 			 * installed below after the association is assured.
 			 */
-			rsn = ni->ni_rsn;
+			rsnparms = ni->ni_rsn;
 			if (wpa[0] != IEEE80211_ELEMID_RSN)
-				reason = ieee80211_parse_wpa(ic, wpa, &rsn, wh);
+				reason = ieee80211_parse_wpa(ic, wpa, &rsnparms, wh);
 			else
-				reason = ieee80211_parse_rsn(ic, wpa, &rsn, wh);
+				reason = ieee80211_parse_rsn(ic, wpa, &rsnparms, wh);
 			if (reason != 0) {
 				IEEE80211_SEND_MGMT(ic, ni,
 				    IEEE80211_FC0_SUBTYPE_DEAUTH, reason);
@@ -2493,9 +2505,9 @@
 			    "[%s] %s ie: mc %u/%u uc %u/%u key %u caps 0x%x\n",
 			    ether_sprintf(wh->i_addr2),
 			    wpa[0] != IEEE80211_ELEMID_RSN ?  "WPA" : "RSN",
-			    rsn.rsn_mcastcipher, rsn.rsn_mcastkeylen,
-			    rsn.rsn_ucastcipher, rsn.rsn_ucastkeylen,
-			    rsn.rsn_keymgmt, rsn.rsn_caps);
+			    rsnparms.rsn_mcastcipher, rsnparms.rsn_mcastkeylen,
+			    rsnparms.rsn_ucastcipher, rsnparms.rsn_ucastkeylen,
+			    rsnparms.rsn_keymgmt, rsnparms.rsn_caps);
 		}
 		/* discard challenge after association */
 		if (ni->ni_challenge != NULL) {
@@ -2545,11 +2557,11 @@
 		ni->ni_fhindex = ic->ic_bss->ni_fhindex;
 		if (wpa != NULL) {
 			/*
-			 * Record WPA/RSN parameters for station, mark
+			 * Record WPA parameters for station, mark
 			 * node as using WPA and record information element
 			 * for applications that require it.
 			 */
-			ni->ni_rsn = rsn;
+			ni->ni_rsn = rsnparms;
 			ieee80211_saveie(&ni->ni_wpa_ie, wpa);
 		} else if (ni->ni_wpa_ie != NULL) {
 			/*
@@ -2558,6 +2570,21 @@
 			FREE(ni->ni_wpa_ie, M_80211_NODE);
 			ni->ni_wpa_ie = NULL;
 		}
+		if (rsn != NULL) {
+			/*
+			 * Record RSN parameters for station, mark
+			 * node as using WPA and record information element
+			 * for applications that require it.
+			 */
+			ni->ni_rsn = rsnparms;
+			ieee80211_saveie(&ni->ni_rsn_ie, rsn);
+		} else if (ni->ni_wpa_ie != NULL) {
+			/*
+			 * Flush any state from a previous association.
+			 */
+			FREE(ni->ni_rsn_ie, M_80211_NODE);
+			ni->ni_rsn_ie = NULL;
+		}
 		if (wme != NULL) {
 			/*
 			 * Record WME parameters for station, mark node

==== //depot/projects/wifi/sys/net80211/ieee80211_ioctl.c#54 (text+ko) ====

@@ -181,10 +181,10 @@
 }
 
 static int
-ieee80211_ioctl_getwpaie(struct ieee80211com *ic, struct ieee80211req *ireq)
+ieee80211_ioctl_getwpaie(struct ieee80211com *ic, struct ieee80211req *ireq, int req)
 {
 	struct ieee80211_node *ni;
-	struct ieee80211req_wpaie wpaie;
+	struct ieee80211req_wpaie2 wpaie;
 	int error;
 
 	if (ireq->i_len < IEEE80211_ADDR_LEN)
@@ -202,9 +202,29 @@
 			ielen = sizeof(wpaie.wpa_ie);
 		memcpy(wpaie.wpa_ie, ni->ni_wpa_ie, ielen);
 	}
+	if (req == IEEE80211_IOC_WPAIE2) {
+		memset(wpaie.rsn_ie, 0, sizeof(wpaie.rsn_ie));
+		if (ni->ni_rsn_ie != NULL) {
+			int ielen = ni->ni_rsn_ie[1] + 2;
+			if (ielen > sizeof(wpaie.rsn_ie))
+				ielen = sizeof(wpaie.rsn_ie);
+			memcpy(wpaie.rsn_ie, ni->ni_rsn_ie, ielen);
+		}
+		if (ireq->i_len > sizeof(struct ieee80211req_wpaie2))
+			ireq->i_len = sizeof(struct ieee80211req_wpaie2);
+	} else {
+		/* compatibility op, may overwrite wpa ie */
+		/* XXX check ic_flags? */
+		if (ni->ni_rsn_ie != NULL) {
+			int ielen = ni->ni_rsn_ie[1] + 2;
+			if (ielen > sizeof(wpaie.wpa_ie))
+				ielen = sizeof(wpaie.wpa_ie);
+			memcpy(wpaie.wpa_ie, ni->ni_rsn_ie, ielen);
+		}
+		if (ireq->i_len > sizeof(struct ieee80211req_wpaie))
+			ireq->i_len = sizeof(struct ieee80211req_wpaie);
+	}
 	ieee80211_free_node(ni);
-	if (ireq->i_len > sizeof(wpaie))
-		ireq->i_len = sizeof(wpaie);
 	return copyout(&wpaie, ireq->i_data, ireq->i_len);
 }
 
@@ -245,6 +265,8 @@
 	*ielen = 0;
 	if (se->se_wpa_ie != NULL)
 		*ielen += 2+se->se_wpa_ie[1];
+	if (se->se_rsn_ie != NULL)
+		*ielen += 2+se->se_rsn_ie[1];
 	if (se->se_wme_ie != NULL)
 		*ielen += 2+se->se_wme_ie[1];
 	if (se->se_ath_ie != NULL)
@@ -302,6 +324,10 @@
 		memcpy(cp, se->se_wpa_ie, 2+se->se_wpa_ie[1]);
 		cp += 2+se->se_wpa_ie[1];
 	}
+	if (se->se_rsn_ie != NULL) {
+		memcpy(cp, se->se_rsn_ie, 2+se->se_rsn_ie[1]);
+		cp += 2+se->se_rsn_ie[1];
+	}
 	if (se->se_wme_ie != NULL) {
 		memcpy(cp, se->se_wme_ie, 2+se->se_wme_ie[1]);
 		cp += 2+se->se_wme_ie[1];
@@ -361,6 +387,8 @@
 	*ielen = 0;
 	if (ni->ni_wpa_ie != NULL)
 		*ielen += 2+ni->ni_wpa_ie[1];
+	if (ni->ni_rsn_ie != NULL)
+		*ielen += 2+ni->ni_rsn_ie[1];
 	if (ni->ni_wme_ie != NULL)
 		*ielen += 2+ni->ni_wme_ie[1];
 	if (ni->ni_ath_ie != NULL)
@@ -440,6 +468,10 @@
 		memcpy(cp, ni->ni_wpa_ie, 2+ni->ni_wpa_ie[1]);
 		cp += 2+ni->ni_wpa_ie[1];
 	}
+	if (ni->ni_rsn_ie != NULL) {
+		memcpy(cp, ni->ni_rsn_ie, 2+ni->ni_rsn_ie[1]);
+		cp += 2+ni->ni_rsn_ie[1];
+	}
 	if (ni->ni_wme_ie != NULL) {
 		memcpy(cp, ni->ni_wme_ie, 2+ni->ni_wme_ie[1]);
 		cp += 2+ni->ni_wme_ie[1];
@@ -767,7 +799,10 @@
 				ireq->i_data, ireq->i_len);
 		break;
 	case IEEE80211_IOC_WPAIE:
-		error = ieee80211_ioctl_getwpaie(ic, ireq);
+		error = ieee80211_ioctl_getwpaie(ic, ireq, ireq->i_type);
+		break;
+	case IEEE80211_IOC_WPAIE2:
+		error = ieee80211_ioctl_getwpaie(ic, ireq, ireq->i_type);
 		break;
 	case IEEE80211_IOC_SCAN_RESULTS:
 		error = ieee80211_ioctl_getscanresults(ic, ireq);
@@ -1044,6 +1079,7 @@
 		return error;
 	switch (mlme.im_op) {
 	case IEEE80211_MLME_ASSOC:
+		/* XXX ibss/ahdemo */
 		if (ic->ic_opmode == IEEE80211_M_STA) {
 			struct scanlookup lookup;
 

==== //depot/projects/wifi/sys/net80211/ieee80211_ioctl.h#32 (text+ko) ====

@@ -281,9 +281,14 @@
 /*
  * Retrieve the WPA/RSN information element for an associated station.
  */
-struct ieee80211req_wpaie {
+struct ieee80211req_wpaie {	/* old version w/ only one ie */
+	u_int8_t	wpa_macaddr[IEEE80211_ADDR_LEN];
+	u_int8_t	wpa_ie[IEEE80211_MAX_OPT_IE];
+};
+struct ieee80211req_wpaie2 {
 	u_int8_t	wpa_macaddr[IEEE80211_ADDR_LEN];
 	u_int8_t	wpa_ie[IEEE80211_MAX_OPT_IE];
+	u_int8_t	rsn_ie[IEEE80211_MAX_OPT_IE];
 };
 
 /*
@@ -458,6 +463,7 @@
 #define	IEEE80211_IOC_ROAM_RATE_11G	71	/* tx rate threshold in 11g */
 #define	IEEE80211_IOC_MCAST_RATE	72	/* tx rate for mcast frames */
 #define	IEEE80211_IOC_FRAGTHRESHOLD	73	/* tx fragmentation threshold */
+#define	IEEE80211_IOC_WPAIE2		74	/* WPA+RSN info elements */
 
 /*
  * Scan result data returned for IEEE80211_IOC_SCAN_RESULTS.

==== //depot/projects/wifi/sys/net80211/ieee80211_node.c#70 (text+ko) ====

@@ -591,6 +591,8 @@
 	ni->ni_noise = se->se_noise;
 	if (se->se_wpa_ie != NULL)
 		ieee80211_saveie(&ni->ni_wpa_ie, se->se_wpa_ie);
+	if (se->se_rsn_ie != NULL)
+		ieee80211_saveie(&ni->ni_rsn_ie, se->se_rsn_ie);
 	if (se->se_wme_ie != NULL)
 		ieee80211_saveie(&ni->ni_wme_ie, se->se_wme_ie);
 	if (se->se_ath_ie != NULL)
@@ -699,6 +701,8 @@
 	ic->ic_node_cleanup(ni);
 	if (ni->ni_wpa_ie != NULL)
 		FREE(ni->ni_wpa_ie, M_80211_NODE);
+	if (ni->ni_rsn_ie != NULL)
+		FREE(ni->ni_rsn_ie, M_80211_NODE);
 	if (ni->ni_wme_ie != NULL)
 		FREE(ni->ni_wme_ie, M_80211_NODE);
 	if (ni->ni_ath_ie != NULL)
@@ -920,6 +924,8 @@
 		ieee80211_saveie(&ni->ni_wme_ie, sp->wme);
 	if (sp->wpa != NULL)
 		ieee80211_saveie(&ni->ni_wpa_ie, sp->wpa);
+	if (sp->rsn != NULL)
+		ieee80211_saveie(&ni->ni_rsn_ie, sp->rsn);
 	if (sp->ath != NULL)
 		ieee80211_saveath(ni, sp->ath);
 

==== //depot/projects/wifi/sys/net80211/ieee80211_node.h#36 (text+ko) ====

@@ -115,7 +115,8 @@
 	u_int16_t		ni_txpower;	/* current transmit power */
 	u_int16_t		ni_vlan;	/* vlan tag */
 	u_int32_t		*ni_challenge;	/* shared-key challenge */
-	u_int8_t		*ni_wpa_ie;	/* captured WPA/RSN ie */
+	u_int8_t		*ni_wpa_ie;	/* captured WPA ie */
+	u_int8_t		*ni_rsn_ie;	/* captured RSN ie */
 	u_int8_t		*ni_wme_ie;	/* captured WME ie */
 	u_int8_t		*ni_ath_ie;	/* captured Atheros ie */
 	u_int16_t		ni_txseqs[17];	/* tx seq per-tid */

==== //depot/projects/wifi/sys/net80211/ieee80211_scan.h#5 (text+ko) ====

@@ -136,6 +136,7 @@
 	u_int8_t	*xrates;
 	u_int8_t	*doth;
 	u_int8_t	*wpa;
+	u_int8_t	*rsn;
 	u_int8_t	*wme;
 	u_int8_t	*ath;
 };
@@ -165,7 +166,8 @@
 	int8_t		se_rssi;	/* avg'd recv ssi */
 	int8_t		se_noise;	/* noise floor */
 	u_int8_t	se_dtimperiod;	/* DTIM period */
-	u_int8_t	*se_wpa_ie;	/* captured WPA/RSN ie */
+	u_int8_t	*se_wpa_ie;	/* captured WPA ie */
+	u_int8_t	*se_rsn_ie;	/* captured RSN ie */
 	u_int8_t	*se_wme_ie;	/* captured WME ie */
 	u_int8_t	*se_ath_ie;	/* captured Atheros ie */
 	u_int		se_age;		/* age of entry (0 on create) */

==== //depot/projects/wifi/sys/net80211/ieee80211_scan_sta.c#8 (text+ko) ====

@@ -275,6 +275,7 @@
 	}
 	saveie(&ise->se_wme_ie, sp->wme);
 	saveie(&ise->se_wpa_ie, sp->wpa);
+	saveie(&ise->se_rsn_ie, sp->rsn);
 	saveie(&ise->se_ath_ie, sp->ath);
 
 	/* clear failure count after STA_FAIL_AGE passes */


More information about the p4-projects mailing list