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