PERFORCE change 64713 for review

Sam Leffler sam at FreeBSD.org
Tue Nov 9 12:28:20 PST 2004


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

Change 64713 by sam at sam_ebb on 2004/11/09 20:27:19

	o incomplete get station info support
	o pad scan results structure
	o add ibss stats

Affected files ...

.. //depot/projects/wifi/sys/net80211/ieee80211_ioctl.c#11 edit
.. //depot/projects/wifi/sys/net80211/ieee80211_ioctl.h#5 edit

Differences ...

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

@@ -948,12 +948,41 @@
 	return error;
 }
 
+static void
+get_scan_result(struct ieee80211req_scan_result *sr,
+	const struct ieee80211_node *ni)
+{
+	struct ieee80211com *ic = ni->ni_ic;
+
+	memset(sr, 0, sizeof(*sr));
+	sr->isr_ssid_len = ni->ni_esslen;
+	if (ni->ni_wpa_ie != NULL)
+		sr->isr_ie_len += 2+ni->ni_wpa_ie[1];
+	if (ni->ni_wme_ie != NULL)
+		sr->isr_ie_len += 2+ni->ni_wme_ie[1];
+	sr->isr_len = sizeof(*sr) + sr->isr_ssid_len + sr->isr_ie_len;
+	sr->isr_len = roundup(sr->isr_len, sizeof(u_int32_t));
+	if (ni->ni_chan != IEEE80211_CHAN_ANYC) {
+		sr->isr_freq = ni->ni_chan->ic_freq;
+		sr->isr_flags = ni->ni_chan->ic_flags;
+	}
+	sr->isr_rssi = ic->ic_node_getrssi(ni);
+	sr->isr_intval = ni->ni_intval;
+	sr->isr_capinfo = ni->ni_capinfo;
+	sr->isr_erp = ni->ni_erp;
+	IEEE80211_ADDR_COPY(sr->isr_bssid, ni->ni_bssid);
+	sr->isr_nrates = ni->ni_rates.rs_nrates;
+	if (sr->isr_nrates > 15)
+		sr->isr_nrates = 15;
+	memcpy(sr->isr_rates, ni->ni_rates.rs_rates, sr->isr_nrates);
+}
+
 static int
 ieee80211_ioctl_getscanresults(struct ieee80211com *ic, struct ieee80211req *ireq)
 {
 	union {
 		struct ieee80211req_scan_result res;
-		char data[512];
+		char data[512];		/* XXX shrink? */
 	} u;
 	struct ieee80211req_scan_result *sr = &u.res;
 	struct ieee80211_node_table *nt;
@@ -967,30 +996,14 @@
 	/* XXX locking */
 	nt =  &ic->ic_scan;
 	TAILQ_FOREACH(ni, &nt->nt_node, ni_list) {
-		sr->isr_ssid_len = ni->ni_esslen;
-		sr->isr_ie_len = 0;
-		if (ni->ni_wpa_ie != NULL)
-			sr->isr_ie_len += 2+ni->ni_wpa_ie[1];
-		if (ni->ni_wme_ie != NULL)
-			sr->isr_ie_len += 2+ni->ni_wme_ie[1];
-		sr->isr_len = sizeof(*sr) + sr->isr_ssid_len + sr->isr_ie_len;
+		/* NB: skip pre-scan node state */ 
+		if (ni->ni_chan == IEEE80211_CHAN_ANYC)
+			continue;
+		get_scan_result(sr, ni);
 		if (sr->isr_len > sizeof(u))
 			continue;		/* XXX */
 		if (space < sr->isr_len)
 			break;
-		sr->isr_freq = ni->ni_chan->ic_freq;
-		sr->isr_flags = ni->ni_chan->ic_flags;
-		sr->isr_noise = 0;
-		sr->isr_rssi = ic->ic_node_getrssi(ni);
-		sr->isr_intval = ni->ni_intval;
-		sr->isr_capinfo = ni->ni_capinfo;
-		sr->isr_erp = ni->ni_erp;
-		IEEE80211_ADDR_COPY(sr->isr_bssid, ni->ni_bssid);
-		sr->isr_nrates = ni->ni_rates.rs_nrates;
-		if (sr->isr_nrates > 15)
-			sr->isr_nrates = 15;
-		memcpy(sr->isr_rates, ni->ni_rates.rs_rates, sr->isr_nrates);
-		sr->isr_scangen = 0;		/* XXX to be added */
 		cp = (u_int8_t *)(sr+1);
 		memcpy(cp, ni->ni_essid, ni->ni_esslen);
 		cp += ni->ni_esslen;
@@ -1012,7 +1025,92 @@
 	return error;
 }
 
+static void
+get_sta_info(struct ieee80211req_sta_info *si, const struct ieee80211_node *ni)
+{
+	struct ieee80211com *ic = ni->ni_ic;
+
+	si->isi_ie_len = 0;
+	if (ni->ni_wpa_ie != NULL)
+		si->isi_ie_len += 2+ni->ni_wpa_ie[1];
+	if (ni->ni_wme_ie != NULL)
+		si->isi_ie_len += 2+ni->ni_wme_ie[1];
+	si->isi_len = sizeof(*si) + si->isi_ie_len, sizeof(u_int32_t);
+	si->isi_len = roundup(si->isi_len, sizeof(u_int32_t));
+	si->isi_freq = ni->ni_chan->ic_freq;
+	si->isi_flags = ni->ni_chan->ic_flags;
+	si->isi_state = ni->ni_flags;
+	si->isi_authmode = ni->ni_authmode;
+	si->isi_rssi = ic->ic_node_getrssi(ni);
+	si->isi_capinfo = ni->ni_capinfo;
+	si->isi_erp = ni->ni_erp;
+	IEEE80211_ADDR_COPY(si->isi_macaddr, ni->ni_macaddr);
+	si->isi_nrates = ni->ni_rates.rs_nrates;
+	if (si->isi_nrates > 15)
+		si->isi_nrates = 15;
+	memcpy(si->isi_rates, ni->ni_rates.rs_rates, si->isi_nrates);
+	si->isi_txrate = ni->ni_txrate;
+	si->isi_associd = ni->ni_associd;
+	si->isi_txpower = ni->ni_txpower;
+	si->isi_vlan = ni->ni_vlan;
+	si->isi_txseq = ni->ni_txseq;
+	si->isi_rxseq = ni->ni_rxseq;
+	memcpy(si->isi_rxseqs, ni->ni_rxseqs, sizeof(ni->ni_rxseqs));
+	if (ic->ic_opmode == IEEE80211_M_IBSS || ni->ni_associd != 0)
+		si->isi_inact = ic->ic_inact_run;
+	else if (ieee80211_node_is_authorized(ni))
+		si->isi_inact = ic->ic_inact_auth;
+	else
+		si->isi_inact = ic->ic_inact_init;
+	si->isi_inact = (si->isi_inact - ni->ni_inact) * IEEE80211_INACT_WAIT;
+}
+
 static int
+ieee80211_ioctl_getstainfo(struct ieee80211com *ic, struct ieee80211req *ireq)
+{
+	union {
+		struct ieee80211req_sta_info info;
+		char data[512];		/* XXX shrink? */
+	} u;
+	struct ieee80211req_sta_info *si = &u.info;
+	struct ieee80211_node_table *nt;
+	struct ieee80211_node *ni;
+	int error, space;
+	u_int8_t *p, *cp;
+
+	nt =  ic->ic_sta;
+	if (nt == NULL)
+		return EINVAL;
+	p = ireq->i_data;
+	space = ireq->i_len;
+	error = 0;
+	/* XXX locking */
+	TAILQ_FOREACH(ni, &nt->nt_node, ni_list) {
+		get_sta_info(si, ni);
+		if (si->isi_len > sizeof(u))
+			continue;		/* XXX */
+		if (space < si->isi_len)
+			break;
+		cp = (u_int8_t *)(si+1);
+		if (ni->ni_wpa_ie != NULL) {
+			memcpy(cp, ni->ni_wpa_ie, 2+ni->ni_wpa_ie[1]);
+			cp += 2+ni->ni_wpa_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];
+		}
+		error = copyout(si, p, si->isi_len);
+		if (error)
+			break;
+		p += si->isi_len;
+		space -= si->isi_len;
+	}
+	ireq->i_len -= space;
+	return error;
+}
+
+static int
 ieee80211_ioctl_get80211(struct ieee80211com *ic, u_long cmd, struct ieee80211req *ireq)
 {
 	const struct ieee80211_rsnparms *rsn = &ic->ic_bss->ni_rsn;
@@ -1201,6 +1299,9 @@
 	case IEEE80211_IOC_INACT_INIT:
 		ireq->i_val = ic->ic_inact_init * IEEE80211_INACT_WAIT;
 		break;
+	case IEEE80211_IOC_STA_INFO:
+		error = ieee80211_ioctl_getstainfo(ic, ireq);
+		break;
 	default:
 		error = EINVAL;
 		break;

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

@@ -164,6 +164,8 @@
 	u_int32_t	is_crypto_attachfail;	/* cipher attach failed */
 	u_int32_t	is_crypto_swfallback;	/* cipher fallback to s/w */
 	u_int32_t	is_crypto_keyfail;	/* driver key alloc failed */
+	u_int32_t	is_ibss_capmismatch;	/* merge failed-cap mismatch */
+	u_int32_t	is_ibss_norate;		/* merge failed-rate mismatch */
 };
 
 /*
@@ -264,6 +266,48 @@
 	struct ieee80211_nodestats is_stats;
 };
 
+/*
+ * Station information block; the mac address is used
+ * to retrieve other data like stats, unicast key, etc.
+ */
+struct ieee80211req_sta_info {
+	u_int16_t	isi_len;		/* length (mult of 4) */
+	u_int16_t	isi_freq;		/* MHz */
+	u_int16_t	isi_flags;		/* channel flags */
+	u_int16_t	isi_state;		/* state flags */
+	u_int8_t	isi_authmode;		/* authentication algorithm */
+	u_int8_t	isi_rssi;
+	u_int8_t	isi_capinfo;		/* capabilities */
+	u_int8_t	isi_erp;		/* ERP element */
+	u_int8_t	isi_macaddr[IEEE80211_ADDR_LEN];
+	u_int8_t	isi_nrates;
+	u_int8_t	isi_rates[15];		/* negotiated rates */
+	u_int8_t	isi_txrate;		/* index to isi_rates[] */
+	u_int8_t	isi_ie_len;		/* IE length */
+	u_int16_t	isi_associd;		/* assoc response */
+	u_int16_t	isi_txpower;		/* current tx power */
+	u_int16_t	isi_vlan;		/* vlan tag */
+	u_int16_t	isi_txseq;		/* seq to be transmitted */
+	u_int16_t	isi_rxseq;		/* seq previous received */
+	u_int16_t	isi_rxseqs[16];		/* seq previous for qos frames*/
+	u_int16_t	isi_inact;		/* inactivity timer */
+	/* XXX frag state? */
+	/* variable length IE data */
+};
+
+/*
+ * Retrieve per-station information; to retrieve all
+ * specify a mac address of ff:ff:ff:ff:ff:ff.
+ */
+struct ieee80211req_sta_req {
+	union {
+		/* NB: explicitly force 64-bit alignment */
+		u_int8_t	macaddr[IEEE80211_ADDR_LEN];
+		u_int64_t	pad;
+	} is_u;
+	struct ieee80211req_sta_info info[1];	/* variable length */
+};
+
 #ifdef __FreeBSD__
 /*
  * FreeBSD-style ioctls.
@@ -336,26 +380,30 @@
 #define	IEEE80211_IOC_INACT		42	/* station inactivity timeout */
 #define	IEEE80211_IOC_INACT_AUTH	43	/* station auth inact timeout */
 #define	IEEE80211_IOC_INACT_INIT	44	/* station init inact timeout */
+#define	IEEE80211_IOC_STA_INFO		45	/* station/neighbor info */
 
 #ifndef IEEE80211_CHAN_ANY
 #define	IEEE80211_CHAN_ANY	0xffff		/* token for ``any channel'' */
 #endif
 
+/*
+ * Scan result data returned for IEEE80211_IOC_SCAN_RESULTS.
+ */
 struct ieee80211req_scan_result {
-	u_int16_t	isr_len;			/* length (mult of 4) */
-	u_int16_t	isr_freq;			/* MHz */
-	u_int16_t	isr_flags;			/* channel flags */
+	u_int16_t	isr_len;		/* length (mult of 4) */
+	u_int16_t	isr_freq;		/* MHz */
+	u_int16_t	isr_flags;		/* channel flags */
 	u_int8_t	isr_noise;
 	u_int8_t	isr_rssi;
-	u_int8_t	isr_intval;			/* beacon interval */
-	u_int8_t	isr_capinfo;			/* capabilities */
-	u_int8_t	isr_erp;			/* ERP element */
+	u_int8_t	isr_intval;		/* beacon interval */
+	u_int8_t	isr_capinfo;		/* capabilities */
+	u_int8_t	isr_erp;		/* ERP element */
 	u_int8_t	isr_bssid[IEEE80211_ADDR_LEN];
 	u_int8_t	isr_nrates;
-	u_int8_t	isr_rates[15];			/* XXX */
-	u_int8_t	isr_ssid_len;			/* SSID length */
-	u_int8_t	isr_ie_len;			/* IE length */
-	u_int8_t	isr_scangen;			/* scan generation # */
+	u_int8_t	isr_rates[15];		/* XXX */
+	u_int8_t	isr_ssid_len;		/* SSID length */
+	u_int8_t	isr_ie_len;		/* IE length */
+	u_int8_t	isr_pad[5];
 	/* variable length SSID followed by IE data */
 };
 


More information about the p4-projects mailing list