Date: Tue, 9 Nov 2004 20:25:15 GMT From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 64712 for review Message-ID: <200411092025.iA9KPFEL042452@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=64712 Change 64712 by sam@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",
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200411092025.iA9KPFEL042452>