Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 8 Feb 2003 12:07:24 -0800 (PST)
From:      Sam Leffler <sam@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 24839 for review
Message-ID:  <200302082007.h18K7OLg055527@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=24839

Change 24839 by sam@sam_ebb on 2003/02/08 12:07:17

	partial fix to dstumbler problem: return previous AP scanning
	   interface
	revert wicontrol to use previous AP scanning interface

Affected files ...

.. //depot/projects/wlan/sys/dev/wi/if_wi.c#2 edit
.. //depot/projects/wlan/usr.sbin/wicontrol/wicontrol.c#2 edit

Differences ...

==== //depot/projects/wlan/sys/dev/wi/if_wi.c#2 (text+ko) ====

@@ -113,7 +113,7 @@
 
 #if !defined(lint)
 static const char rcsid[] =
-  "$FreeBSD: src/sys/dev/wi/if_wi.c,v 1.128 2003/02/02 06:35:46 imp Exp $";
+  "$FreeBSD: src/sys/dev/wi/if_wi.c,v 1.127 2003/01/21 08:55:45 alfred Exp $";
 #endif
 
 static void wi_start(struct ifnet *);
@@ -147,7 +147,7 @@
 
 static int  wi_newstate(void *, enum ieee80211_state);
 
-static int  wi_scan_ap(struct wi_softc *);
+static int  wi_scan_ap(struct wi_softc *, u_int16_t, u_int16_t);
 static void wi_scan_result(struct wi_softc *, int, int);
 
 static void wi_dump_pkt(struct wi_frame *, struct ieee80211_node *, int rssi);
@@ -782,8 +782,8 @@
 		if_printf(ifp, "interface not running\n");
 		wi_stop(ifp, 0);
 	}
+	DPRINTF(("wi_init: return %d\n", error));
 	WI_UNLOCK(sc);
-	DPRINTF(("wi_init: return %d\n", error));
 	return;
 }
 
@@ -1345,6 +1345,14 @@
 	len = le16toh(frmhdr.wi_dat_len);
 	off = ALIGN(sizeof(struct ieee80211_frame));
 
+	if (off + len > MCLBYTES) {
+		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX);
+		ifp->if_ierrors++;
+		DPRINTF(("wi_rx_intr: oversized packet (off %u len %u)\n",
+			off, len));
+		return;
+	}
+
 	MGETHDR(m, M_NOWAIT, MT_DATA);
 	if (m == NULL) {
 		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX);
@@ -1496,6 +1504,7 @@
 	fid = CSR_READ_2(sc, WI_INFO_FID);
 	wi_read_bap(sc, fid, 0, ltbuf, sizeof(ltbuf));
 
+	DPRINTF(("wi_info_intr: type 0x%x\n", le16toh(ltbuf[1])));
 	switch (le16toh(ltbuf[1])) {
 
 	case WI_INFO_LINK_STAT:
@@ -1695,7 +1704,8 @@
 	struct ieee80211com *ic = &sc->sc_ic;
 	struct ifreq *ifr = (struct ifreq *)data;
 	struct wi_req wreq;
-	int len, n, error, mif, val;
+	struct wi_scan_res *res;
+	int len, n, error, mif, val, off, i;
 
 	error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
 	if (error)
@@ -1773,7 +1783,6 @@
 		break;
 
 	case WI_RID_READ_APS:
-	case WI_RID_SCAN_RES:		/* XXX */
 		if (ic->ic_opmode == IEEE80211_M_HOSTAP)
 			return ieee80211_cfgget(ifp, cmd, data);
 		if (sc->sc_scan_timer > 0) {
@@ -1814,6 +1823,57 @@
 	case WI_RID_READ_CACHE:
 		return ieee80211_cfgget(ifp, cmd, data);
 
+	case WI_RID_SCAN_RES:		/* compatibility interface */
+		if (ic->ic_opmode == IEEE80211_M_HOSTAP)
+			return ieee80211_cfgget(ifp, cmd, data);
+		if (sc->sc_scan_timer > 0) {
+			error = EINPROGRESS;
+			break;
+		}
+		n = sc->sc_naps;
+		off = sc->sc_firmware_type != WI_LUCENT ?
+			sizeof(struct wi_scan_p2_hdr) : 0;
+		if (len < off + sizeof(struct wi_scan_res) * n)
+			n = (len - off) / sizeof(struct wi_scan_res);
+		len = off + sizeof(struct wi_scan_res) * n;
+		if (off != 0) {
+			struct wi_scan_p2_hdr *p2 = (struct wi_scan_p2_hdr *)wreq.wi_val;
+			/*
+			 * Prepend Prism-specific header.
+			 */
+			if (len < sizeof(struct wi_scan_p2_hdr)) {
+				error = ENOSPC;
+				break;
+			}
+			p2 = (struct wi_scan_p2_hdr *)wreq.wi_val;
+			p2->wi_rsvd = 0;
+			p2->wi_reason = n;	/* XXX */
+		}
+		for (i = 0; i < n; i++) {
+			const struct wi_apinfo *ap = &sc->sc_aps[i];
+
+			res = (struct wi_scan_res *)((char *)wreq.wi_val + off);
+			res->wi_chan = ap->channel;
+			res->wi_noise = ap->noise;
+			res->wi_signal = ap->signal;
+			IEEE80211_ADDR_COPY(res->wi_bssid, ap->bssid);
+			res->wi_interval = ap->interval;
+			res->wi_capinfo = ap->capinfo;
+			res->wi_ssid_len = ap->namelen;
+			memcpy(res->wi_ssid, ap->name,
+				IEEE80211_NWID_LEN);
+			if (sc->sc_firmware_type != WI_LUCENT) {
+				/* XXX not saved from Prism cards */
+				memset(res->wi_srates, 0,
+					sizeof(res->wi_srates));
+				res->wi_rate = ap->rate;
+				res->wi_rsvd = 0;
+				off += WI_PRISM2_RES_SIZE;
+			} else
+				off += WI_WAVELAN_RES_SIZE;
+		}
+		break;
+
 	default:
 		if (sc->sc_enabled) {
 			error = wi_read_rid(sc, wreq.wi_type, wreq.wi_val,
@@ -1867,7 +1927,7 @@
 	error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
 	if (error)
 		return error;
-	len = (wreq.wi_len - 1) * 2;
+	len = wreq.wi_len ? (wreq.wi_len - 1) * 2 : 0;
 	switch (wreq.wi_type) {
 	case WI_RID_DBM_ADJUST:
 		return ENODEV;
@@ -1960,7 +2020,12 @@
 
 	case WI_RID_SCAN_APS:
 		if (sc->sc_enabled && ic->ic_opmode != IEEE80211_M_HOSTAP)
-			error = wi_scan_ap(sc);
+			error = wi_scan_ap(sc, 0x3fff, 0x000f);
+		break;
+
+	case WI_RID_SCAN_REQ:		/* compatibility interface */
+		if (sc->sc_enabled && ic->ic_opmode != IEEE80211_M_HOSTAP)
+			error = wi_scan_ap(sc, wreq.wi_val[0], wreq.wi_val[1]);
 		break;
 
 	case WI_RID_MGMT_XMIT:
@@ -1990,6 +2055,18 @@
 	case WI_RID_PROCFRAME:		/* ignore for compatibility */
 		break;
 
+	case WI_RID_OWN_SSID:
+		if (le16toh(wreq.wi_val[0]) * 2 > len ||
+		    le16toh(wreq.wi_val[0]) > IEEE80211_NWID_LEN) {
+			error = ENOSPC;
+			break;
+		}
+		memset(ic->ic_des_essid, 0, IEEE80211_NWID_LEN);
+		ic->ic_des_esslen = le16toh(wreq.wi_val[0]) * 2;
+		memcpy(ic->ic_des_essid, &wreq.wi_val[1], ic->ic_des_esslen);
+		error = ENETRESET;
+		break;
+
 	default:
 		if (sc->sc_enabled) {
 			error = wi_write_rid(sc, wreq.wi_type, wreq.wi_val,
@@ -2478,7 +2555,7 @@
 }
 
 static int
-wi_scan_ap(struct wi_softc *sc)
+wi_scan_ap(struct wi_softc *sc, u_int16_t chanmask, u_int16_t txrate)
 {
 	int error = 0;
 	u_int16_t val[2];
@@ -2490,8 +2567,8 @@
 		(void)wi_cmd(sc, WI_CMD_INQUIRE, WI_INFO_SCAN_RESULTS, 0, 0);
 		break;
 	case WI_INTERSIL:
-		val[0] = 0x3fff;	/* channel */
-		val[1] = 0x000f;	/* tx rate */
+		val[0] = chanmask;	/* channel */
+		val[1] = txrate;	/* tx rate */
 		error = wi_write_rid(sc, WI_RID_SCAN_REQ, val, sizeof(val));
 		break;
 	case WI_SYMBOL:
@@ -2506,7 +2583,8 @@
 	if (error == 0) {
 		sc->sc_scan_timer = WI_SCAN_WAIT;
 		sc->sc_ic.ic_if.if_timer = 1;
-		DPRINTF(("wi_scan_ap: start scanning\n"));
+		DPRINTF(("wi_scan_ap: start scanning, "
+			"chamask 0x%x txrate 0x%x\n, chanmask, txrate"));
 	}
 	return error;
 }

==== //depot/projects/wlan/usr.sbin/wicontrol/wicontrol.c#2 (text+ko) ====

@@ -34,7 +34,7 @@
 static const char copyright[] = "@(#) Copyright (c) 1997, 1998, 1999\
 	Bill Paul. All rights reserved.";
 static const char rcsid[] =
-	"$FreeBSD: src/usr.sbin/wicontrol/wicontrol.c,v 1.32 2003/01/21 07:28:57 mdodd Exp $";
+	"$FreeBSD: src/usr.sbin/wicontrol/wicontrol.c,v 1.29 2002/10/08 19:41:12 jhb Exp $";
 #endif /* not lint */
 
 #include <sys/types.h>
@@ -67,10 +67,10 @@
 static void wi_setbytes(const char *, int, char *, int);
 static void wi_setword(const char *, int, int);
 static void wi_sethex(const char *, int, char *);
+static void wi_printaps(struct wi_req *);
 static void wi_printwords(struct wi_req *);
 static void wi_printbool(struct wi_req *);
 static void wi_printhex(struct wi_req *);
-static void wi_printaps(struct wi_req *);
 static void wi_dumpinfo(const char *);
 static void wi_dumpstats(const char *);
 static void wi_setkeys(const char *, char *, int);
@@ -495,10 +495,10 @@
 	return;
 }
 
-static int
+static float
 get_wiaprate(int inrate)
 {
-	int rate;
+	float rate;
 
 	switch (inrate) {
 	case WI_APRATE_1:
@@ -527,11 +527,11 @@
 void
 wi_printaplist(const char *iface)
 {
-	int			prism2;
+	int			prism2, len, i = 0, j;
 	struct wi_req		wreq;
-	struct wi_apinfo	*w;
-	int i, nstations;
-	float rate;
+	struct wi_scan_p2_hdr	*wi_p2_h;
+	struct wi_scan_res	*res;
+	float			rate;
 
 	if (!quiet)
 		printf("Available APs:\n");
@@ -544,8 +544,13 @@
 	prism2 = wreq.wi_val[0];
 
 	/* send out a scan request */
-	wreq.wi_len = 1;
-	wreq.wi_type = WI_RID_SCAN_APS;
+	wreq.wi_len = prism2 ? 3 : 1;
+	wreq.wi_type = WI_RID_SCAN_REQ;
+
+	if (prism2) {
+		wreq.wi_val[0] = 0x3FFF;
+		wreq.wi_val[1] = 0x000F;
+	}
 
 	wi_setval(iface, &wreq);
 
@@ -561,34 +566,58 @@
 		wreq.wi_type = WI_RID_SCAN_RES;
 	} while (wi_getval(iface, &wreq) == -1 && errno == EINPROGRESS);
 
-	nstations = *(int *)wreq.wi_val;
+	if (prism2) {
+		wi_p2_h = (struct wi_scan_p2_hdr *)wreq.wi_val;
+
+		/* if the reason is 0, this info is invalid */
+		if (wi_p2_h->wi_reason == 0)
+			return;
+
+		i = 4;
+	}
+
+	len = prism2 ? WI_PRISM2_RES_SIZE : WI_WAVELAN_RES_SIZE;
+
 	if (!quiet) {
+		int nstations = ((wreq.wi_len * 2) - i) / len;
 		printf("%d station%s:\n", nstations, nstations == 1 ? "" : "s");
 		printf("SSID                 BSSID             Chan    SN   S   N   Intrvl  Capinfo\n");
 	}
-	w =  (struct wi_apinfo *)(((char *)&wreq.wi_val) + sizeof(int));
-	for ( i = 0; i < nstations; i++, w++) {
-		printf("%-20.*s %02x:%02x:%02x:%02x:%02x:%02x   %-2d "
-		    "[ %3d %3d %3d ]    %-3d  "
-		    , w->namelen, w->name
-		    , w->bssid[0]&0xff, w->bssid[1]&0xff
-		    , w->bssid[2]&0xff, w->bssid[3]&0xff
-		    , w->bssid[4]&0xff, w->bssid[5]&0xff
-		    , w->channel
-		    , w->quality, w->signal, w->noise
-		    , w->interval
-		);
+	for (; i < (wreq.wi_len * 2) - len; i += len) {
+		res = (struct wi_scan_res *)((char *)wreq.wi_val + i);
+
+		res->wi_ssid[res->wi_ssid_len] = '\0';
+
+		printf("    %-8s  [ %02x:%02x:%02x:%02x:%02x:%02x ]  [ %-2d ]  "
+		    "[ %d %d %d ]  %-3d  ", res->wi_ssid,
+		    res->wi_bssid[0], res->wi_bssid[1], res->wi_bssid[2],
+		    res->wi_bssid[3], res->wi_bssid[4], res->wi_bssid[5],
+		    res->wi_chan, res->wi_signal - res->wi_noise,
+		    res->wi_signal, res->wi_noise, res->wi_interval);
 
-		if (!quiet) {
+		if (!quiet && res->wi_capinfo) {
 			printf("[ ");
-			if (w->capinfo & IEEE80211_CAPINFO_ESS)
-				printf("ESS ");
-			if (w->capinfo & IEEE80211_CAPINFO_PRIVACY)
-				printf("WEP ");
-			printf("]\n              ");
+			if (res->wi_capinfo & WI_CAPINFO_ESS)
+				printf("ess ");
+			if (res->wi_capinfo & WI_CAPINFO_IBSS)
+				printf("ibss ");
+			if (res->wi_capinfo & WI_CAPINFO_PRIV)
+				printf("priv ");
+			printf("]  ");
+		}
 
-			rate = get_wiaprate(w->rate);
-			if (rate) printf("* %2.1f *\n", rate);
+		if (prism2 && res->wi_srates[0] != 0) {
+			printf("\n              [ ");
+			for (j = 0; res->wi_srates[j] != 0; j++) {
+				res->wi_srates[j] = res->wi_srates[j] &
+				    WI_VAR_SRATES_MASK;
+				printf("%d.%d ", res->wi_srates[j] / 2,
+				    (res->wi_srates[j] % 2) * 5);
+			}
+			printf("]  ");
+			rate = get_wiaprate(res->wi_rate);
+			if (rate)
+				printf("* %2.1f *\n", rate);
 		}
 		putchar('\n');
 	}

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe p4-projects" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200302082007.h18K7OLg055527>