PERFORCE change 64114 for review

Sam Leffler sam at FreeBSD.org
Tue Nov 2 13:35:11 PST 2004


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

Change 64114 by sam at sam_ebb on 2004/11/02 21:35:06

	first cut at scanning

Affected files ...

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

Differences ...

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

@@ -481,11 +481,139 @@
 	}
 }
 
+static int
+getmaxrate(uint8_t rates[15], uint8_t nrates)
+{
+	int i, maxrate = -1;
+
+	for (i = 0; i < nrates; i++) {
+		int rate = rates[i] & IEEE80211_RATE_VAL;
+		if (rate > maxrate)
+			maxrate = rate;
+	}
+	return maxrate / 2;
+}
+
+static const char *
+getcaps(int capinfo)
+{
+	static char capstring[32];
+	char *cp = capstring;
+
+	if (capinfo & IEEE80211_CAPINFO_ESS)
+		*cp++ = 'E';
+	if (capinfo & IEEE80211_CAPINFO_IBSS)
+		*cp++ = 'I';
+	if (capinfo & IEEE80211_CAPINFO_CF_POLLABLE)
+		*cp++ = 'c';
+	if (capinfo & IEEE80211_CAPINFO_CF_POLLREQ)
+		*cp++ = 'C';
+	if (capinfo & IEEE80211_CAPINFO_PRIVACY)
+		*cp++ = 'P';
+	if (capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE)
+		*cp++ = 'S';
+	if (capinfo & IEEE80211_CAPINFO_PBCC)
+		*cp++ = 'B';
+	if (capinfo & IEEE80211_CAPINFO_CHNL_AGILITY)
+		*cp++ = 'A';
+	if (capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME)
+		*cp++ = 's';
+	if (capinfo & IEEE80211_CAPINFO_RSN)
+		*cp++ = 'R';
+	if (capinfo & IEEE80211_CAPINFO_DSSSOFDM)
+		*cp++ = 'D';
+	*cp = '\0';
+	return capstring;
+}
+
 static void
+printie(const char* tag, const uint8_t *ie, size_t ielen, int maxlen)
+{
+	printf("%s", tag);
+	if (verbose) {
+		maxlen -= strlen(tag)+2;
+		if (2*ielen > maxlen)
+			maxlen--;
+		printf("<");
+		for (; ielen > 0; ie++, ielen--) {
+			if (maxlen-- <= 0)
+				break;
+			printf("%02x", *ie);
+		}
+		if (ielen != 0)
+			printf("-");
+		printf(">");
+	}
+}
+
+static void
 set80211scan(const char *val, int d, int s, const struct afswtch *rafp)
 {
-	/* XXX optional ssid */
-	set80211(s, IEEE80211_IOC_SCAN_REQ, 0, 0, NULL);
+	uint8_t buf[24*1024];
+	struct ieee80211req ireq;
+	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_REQ;
+	/* NB: only root can trigger a scan so ignore errors */
+	(void) ioctl(s, SIOCS80211, &ireq);
+
+	ireq.i_type = IEEE80211_IOC_SCAN_RESULTS;
+	ireq.i_data = buf;
+	ireq.i_len = sizeof(buf);
+	while (ioctl(s, SIOCG80211, &ireq) < 0) {
+		if (errno != EINPROGRESS)
+			errx(1, "unable to get scan results");
+		sleep(1);
+	}
+	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"
+		);
+	cp = buf;
+	while (len >= sizeof(struct ieee80211req_scan_result)) {
+		struct ieee80211req_scan_result *sr;
+		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)
+		);
+
+		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;
+	}
 }
 
 enum ieee80211_opmode {
@@ -1116,7 +1244,7 @@
 	{ "chanlist",	NEXTARG,	set80211chanlist },
 	{ "bssid",	NEXTARG,	set80211bssid },
 	{ "ap",		NEXTARG,	set80211bssid },
-	{ "scan",	OPTARG,		set80211scan },
+	{ "scan",	0,		set80211scan },
 };
 static struct afswtch af_ieee80211 = {
 	.af_name	= "ieee80211",


More information about the p4-projects mailing list