PERFORCE change 64712 for review

Sam Leffler sam at FreeBSD.org
Tue Nov 9 12:25:16 PST 2004


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

Change 64712 by sam at sam_ebb on 2004/11/09 20:24:29

	add start of list support; can list station and scan tables

Affected files ...

.. //depot/projects/wifi/sbin/ifconfig/ifieee80211.c#6 edit

Differences ...

==== //depot/projects/wifi/sbin/ifconfig/ifieee80211.c#6 (text+ko) ====

@@ -546,6 +546,113 @@
 	}
 }
 
+/*
+ * Copy the ssid string contents into buf, truncating to fit.  If the
+ * ssid is entirely printable then just copy intact.  Otherwise convert
+ * to hexadecimal.  If the result is truncated then replace the last
+ * three characters with "...".
+ */
+static size_t
+copy_essid(char buf[], size_t bufsize, const u_int8_t *essid, size_t essid_len)
+{
+	const u_int8_t *p; 
+	size_t maxlen;
+	int i;
+
+	if (essid_len > bufsize)
+		maxlen = bufsize;
+	else
+		maxlen = essid_len;
+	/* determine printable or not */
+	for (i = 0, p = essid; i < maxlen; i++, p++) {
+		if (*p < ' ' || *p > 0x7e)
+			break;
+	}
+	if (i != maxlen) {		/* not printable, print as hex */
+		if (bufsize < 3)
+			return 0;
+		strlcpy(buf, "0x", bufsize);
+		bufsize -= 2;
+		p = essid;
+		for (i = 0; i < maxlen && bufsize >= 2; i++) {
+			sprintf(&buf[2+2*i], "%02x", *p++);
+			bufsize -= 2;
+		}
+		maxlen = 2+2*i;
+	} else {			/* printable, truncate as needed */
+		memcpy(buf, essid, maxlen);
+	}
+	if (maxlen != essid_len)
+		memcpy(buf+maxlen-3, "...", 3);
+	return maxlen;
+}
+
+static void
+list_scan(int s)
+{
+	uint8_t buf[24*1024];
+	struct ieee80211req ireq;
+	char ssid[14];
+	uint8_t *cp;
+	int len;
+
+	(void) memset(&ireq, 0, sizeof(ireq));
+	(void) strncpy(ireq.i_name, name, sizeof(ireq.i_name));
+	ireq.i_type = IEEE80211_IOC_SCAN_RESULTS;
+	ireq.i_data = buf;
+	ireq.i_len = sizeof(buf);
+	if (ioctl(s, SIOCG80211, &ireq) < 0)
+		errx(1, "unable to get scan results");
+	len = ireq.i_len;
+	if (len < sizeof(struct ieee80211req_scan_result))
+		return;
+
+	printf("%-14.14s  %-17.17s  %4s %4s  %-5s %3s %4s\n"
+		, "SSID"
+		, "BSSID"
+		, "CHAN"
+		, "RATE"
+		, "S:N"
+		, "INT"
+		, "CAPS"
+	);
+	cp = buf;
+	do {
+		struct ieee80211req_scan_result *sr;
+		uint8_t *vp;
+
+		sr = (struct ieee80211req_scan_result *) cp;
+		vp = (u_int8_t *)(sr+1);
+		printf("%-14.*s  %s  %3d  %3dM %2d:%-2d  %3d %-4.4s"
+			, copy_essid(ssid, sizeof(ssid), vp, sr->isr_ssid_len)
+				, ssid
+			, ether_ntoa((const struct ether_addr *) sr->isr_bssid)
+			, ieee80211_mhz2ieee(sr->isr_freq)
+			, getmaxrate(sr->isr_rates, sr->isr_nrates)
+			, sr->isr_rssi, sr->isr_noise
+			, sr->isr_intval
+			, getcaps(sr->isr_capinfo)
+		);
+
+		if (sr->isr_ie_len > 0) {
+			vp += sr->isr_ssid_len;
+			switch (vp[0]) {
+			case IEEE80211_ELEMID_VENDOR:
+				if (vp[1] < 2 + 4 ||
+				    memcmp(&vp[2], "\x00\x50\xf2\x01", 4) != 0)
+					break;
+				printie("WPA", vp, 2+vp[1], 24);
+				break;
+			case IEEE80211_ELEMID_RSN:
+				printie("RSN", vp, 2+vp[1], 24);
+				break;
+			}
+		}
+		printf("\n");
+		cp += sr->isr_len, len -= sr->isr_len;
+	} while (len >= sizeof(struct ieee80211req_scan_result));
+}
+
 #include <net80211/ieee80211_freebsd.h>
 
 static void
@@ -586,51 +693,62 @@
 static void
 set80211scan(const char *val, int d, int s, const struct afswtch *rafp)
 {
+	scan_and_wait(s);
+	list_scan(s);
+}
+
+static void
+list_stations(int s)
+{
 	uint8_t buf[24*1024];
 	struct ieee80211req ireq;
 	uint8_t *cp;
 	int len;
 
-	scan_and_wait(s);
-
 	(void) memset(&ireq, 0, sizeof(ireq));
 	(void) strncpy(ireq.i_name, name, sizeof(ireq.i_name));
-	ireq.i_type = IEEE80211_IOC_SCAN_RESULTS;
+	ireq.i_type = IEEE80211_IOC_STA_INFO;
 	ireq.i_data = buf;
 	ireq.i_len = sizeof(buf);
 	if (ioctl(s, SIOCG80211, &ireq) < 0)
-		errx(1, "unable to get scan results");
+		errx(1, "unable to get station information");
 	len = ireq.i_len;
-	if (len >= sizeof(struct ieee80211req_scan_result))
-		printf("%-14.14s  %-17.17s  %4s %4s  %-5s %3s %4s\n"
-			, "SSID"
-			, "BSSID"
-			, "CHAN"
-			, "RATE"
-			, "S:N"
-			, "INT"
-			, "CAPS"
-		);
+	if (len < sizeof(struct ieee80211req_sta_info))
+		return;
+
+	printf("%-17.17s %4s %4s %4s %4s %4s %6s %6s %4s %4s\n"
+		, "ADDR"
+		, "AID"
+		, "CHAN"
+		, "RATE"
+		, "RSSI"
+		, "IDLE"
+		, "TXSEQ"
+		, "RXSEQ"
+		, "CAPS"
+		, "ERP"
+	);
 	cp = buf;
-	while (len >= sizeof(struct ieee80211req_scan_result)) {
-		struct ieee80211req_scan_result *sr;
+	do {
+		struct ieee80211req_sta_info *si;
 		uint8_t *vp;
 
-		sr = (struct ieee80211req_scan_result *) cp;
-		/* XXX clean ssid string */
-		vp = (u_int8_t *)(sr+1);
-		printf("%-14.*s  %s  %3d  %3dM %2d:%-2d  %3d %-4.4s"
-			, sr->isr_ssid_len, vp
-			, ether_ntoa((const struct ether_addr *) sr->isr_bssid)
-			, ieee80211_mhz2ieee(sr->isr_freq)
-			, getmaxrate(sr->isr_rates, sr->isr_nrates)
-			, sr->isr_rssi, sr->isr_noise
-			, sr->isr_intval
-			, getcaps(sr->isr_capinfo)
+		si = (struct ieee80211req_sta_info *) cp;
+		vp = (u_int8_t *)(si+1);
+		printf("%s %4u %4d %3dM %4d %4d %6d %6d %-4.4s %3x"
+			, ether_ntoa((const struct ether_addr*) si->isi_macaddr)
+			, IEEE80211_AID(si->isi_associd)
+			, ieee80211_mhz2ieee(si->isi_freq)
+			, (si->isi_rates[si->isi_txrate] & IEEE80211_RATE_VAL)/2
+			, si->isi_rssi
+			, si->isi_inact
+			, si->isi_txseq
+			, si->isi_rxseq
+			, getcaps(si->isi_capinfo)
+			, si->isi_erp
 		);
 
-		if (sr->isr_ie_len > 0) {
-			vp += sr->isr_ssid_len;
+		if (si->isi_ie_len > 0) {
 			switch (vp[0]) {
 			case IEEE80211_ELEMID_VENDOR:
 				if (vp[1] < 2 + 4 ||
@@ -641,11 +759,47 @@
 			case IEEE80211_ELEMID_RSN:
 				printie("RSN", vp, 2+vp[1], 24);
 				break;
+			/* XXX WME */
 			}
 		}
 		printf("\n");
-		cp += sr->isr_len, len -= sr->isr_len;
-	}
+		cp += si->isi_len, len -= si->isi_len;
+	} while (len >= sizeof(struct ieee80211req_sta_info));
+}
+
+static void
+list_channels(int s)
+{
+}
+
+static void
+list_keys(int s)
+{
+}
+
+static void
+list_capabilities(int s)
+{
+}
+
+static void
+set80211list(const char *arg, int d, int s, const struct afswtch *rafp)
+{
+#define	iseq(a,b)	(strncasecmp(a,b,sizeof(b)-1) == 0)
+
+	if (iseq(arg, "sta"))
+		list_stations(s);
+	else if (iseq(arg, "scan") || iseq(arg, "ap"))
+		list_scan(s);
+	else if (iseq(arg, "chan") || iseq(arg, "freq"))
+		list_channels(s);
+	else if (iseq(arg, "keys"))
+		list_keys(s);
+	else if (iseq(arg, "caps"))
+		list_capabilities(s);
+	else
+		errx(1, "Don't know how to list %s for %s", arg, name);
+#undef iseq
 }
 
 enum ieee80211_opmode {
@@ -1277,6 +1431,7 @@
 	{ "bssid",	NEXTARG,	set80211bssid },
 	{ "ap",		NEXTARG,	set80211bssid },
 	{ "scan",	0,		set80211scan },
+	{ "list",	NEXTARG,	set80211list },
 };
 static struct afswtch af_ieee80211 = {
 	.af_name	= "ieee80211",


More information about the p4-projects mailing list