return buf;
}
+static const char *format_band(int band)
+{
+ const char *name;
+
+ name = iwinfo_band_name(band);
+ if (name)
+ return name;
+
+ return "unknown";
+}
+
static char * format_channel(int ch)
{
- static char buf[8];
+ static char buf[16];
if (ch <= 0)
snprintf(buf, sizeof(buf), "unknown");
static char * format_frequency(int freq)
{
- static char buf[10];
+ static char buf[11];
if (freq <= 0)
snprintf(buf, sizeof(buf), "unknown");
return buf;
}
+static char * format_freqflags(uint32_t flags)
+{
+ static char str[512] = "[";
+ char *pos = str + 1;
+ int i;
+
+ if (!flags)
+ return "";
+
+ for (i = 0; i < IWINFO_FREQ_FLAG_COUNT; i++)
+ if (flags & (1 << i))
+ pos += sprintf(pos, "%s, ", IWINFO_FREQ_FLAG_NAMES[i]);
+
+ *(pos - 2) = ']';
+ *(pos - 1) = 0;
+
+ return str;
+}
+
static char * format_txpower(int pwr)
{
- static char buf[10];
+ static char buf[16];
if (pwr < 0)
snprintf(buf, sizeof(buf), "unknown");
static char * format_quality(int qual)
{
- static char buf[8];
+ static char buf[16];
if (qual < 0)
snprintf(buf, sizeof(buf), "unknown");
static char * format_quality_max(int qmax)
{
- static char buf[8];
+ static char buf[16];
if (qmax < 0)
snprintf(buf, sizeof(buf), "unknown");
static char * format_rate(int rate)
{
- static char buf[14];
+ static char buf[18];
if (rate <= 0)
snprintf(buf, sizeof(buf), "unknown");
{
static char str[128] = { 0 };
char *pos = str;
+ int i;
- if (ciphers & IWINFO_CIPHER_WEP40)
- pos += sprintf(pos, "WEP-40, ");
-
- if (ciphers & IWINFO_CIPHER_WEP104)
- pos += sprintf(pos, "WEP-104, ");
-
- if (ciphers & IWINFO_CIPHER_TKIP)
- pos += sprintf(pos, "TKIP, ");
-
- if (ciphers & IWINFO_CIPHER_CCMP)
- pos += sprintf(pos, "CCMP, ");
-
- if (ciphers & IWINFO_CIPHER_WRAP)
- pos += sprintf(pos, "WRAP, ");
-
- if (ciphers & IWINFO_CIPHER_AESOCB)
- pos += sprintf(pos, "AES-OCB, ");
-
- if (ciphers & IWINFO_CIPHER_CKIP)
- pos += sprintf(pos, "CKIP, ");
-
- if (!ciphers || (ciphers & IWINFO_CIPHER_NONE))
- pos += sprintf(pos, "NONE, ");
+ for (i = 0; i < IWINFO_CIPHER_COUNT; i++)
+ if (ciphers & (1 << i))
+ pos += sprintf(pos, "%s, ", IWINFO_CIPHER_NAMES[i]);
*(pos - 2) = 0;
{
static char str[64] = { 0 };
char *pos = str;
+ int i;
- if (suites & IWINFO_KMGMT_PSK)
- pos += sprintf(pos, "PSK/");
-
- if (suites & IWINFO_KMGMT_8021x)
- pos += sprintf(pos, "802.1X/");
-
- if (!suites || (suites & IWINFO_KMGMT_NONE))
- pos += sprintf(pos, "NONE/");
+ for (i = 0; i < IWINFO_KMGMT_COUNT; i++)
+ if (suites & (1 << i))
+ pos += sprintf(pos, "%s/", IWINFO_KMGMT_NAMES[i]);
*(pos - 1) = 0;
static char * format_encryption(struct iwinfo_crypto_entry *c)
{
static char buf[512];
+ char *pos = buf;
+ int i, n;
if (!c)
{
/* WPA */
else if (c->wpa_version)
{
- switch (c->wpa_version) {
- case 3:
- snprintf(buf, sizeof(buf), "mixed WPA/WPA2 %s (%s)",
- format_enc_suites(c->auth_suites),
- format_enc_ciphers(c->pair_ciphers | c->group_ciphers));
- break;
+ for (i = 0, n = 0; i < 3; i++)
+ if (c->wpa_version & (1 << i))
+ n++;
- case 2:
- snprintf(buf, sizeof(buf), "WPA2 %s (%s)",
- format_enc_suites(c->auth_suites),
- format_enc_ciphers(c->pair_ciphers | c->group_ciphers));
- break;
+ if (n > 1)
+ pos += sprintf(pos, "mixed ");
- case 1:
- snprintf(buf, sizeof(buf), "WPA %s (%s)",
- format_enc_suites(c->auth_suites),
- format_enc_ciphers(c->pair_ciphers | c->group_ciphers));
- break;
- }
+ for (i = 0; i < 3; i++)
+ if (c->wpa_version & (1 << i))
+ {
+ if (i)
+ pos += sprintf(pos, "WPA%d/", i + 1);
+ else
+ pos += sprintf(pos, "WPA/");
+ }
+
+ pos--;
+
+ sprintf(pos, " %s (%s)",
+ format_enc_suites(c->auth_suites),
+ format_enc_ciphers(c->pair_ciphers | c->group_ciphers));
}
else
{
static char * format_hwmodes(int modes)
{
- static char buf[12];
+ static char buf[32] = "802.11";
- if (modes <= 0)
+ if (iwinfo_format_hwmodes(modes, buf + 6, sizeof(buf) - 6) < 1)
snprintf(buf, sizeof(buf), "unknown");
- else
- snprintf(buf, sizeof(buf), "802.11%s%s%s%s%s",
- (modes & IWINFO_80211_A) ? "a" : "",
- (modes & IWINFO_80211_B) ? "b" : "",
- (modes & IWINFO_80211_G) ? "g" : "",
- (modes & IWINFO_80211_N) ? "n" : "",
- (modes & IWINFO_80211_AC) ? "ac" : "");
return buf;
}
static char * format_assocrate(struct iwinfo_rate_entry *r)
{
- static char buf[40];
+ static char buf[80];
char *p = buf;
int l = sizeof(buf);
p += snprintf(p, l, "%s", format_rate(r->rate));
l = sizeof(buf) - (p - buf);
- if (r->mcs >= 0)
+ if (r->is_ht)
{
- p += snprintf(p, l, ", MCS %d, %dMHz", r->mcs, 20 + r->is_40mhz*20);
+ p += snprintf(p, l, ", MCS %d, %dMHz", r->mcs, r->mhz);
+ l = sizeof(buf) - (p - buf);
+ }
+ else if (r->is_vht)
+ {
+ p += snprintf(p, l, ", VHT-MCS %d, %dMHz", r->mcs, r->mhz);
l = sizeof(buf) - (p - buf);
- if (r->is_short_gi)
- p += snprintf(p, l, ", short GI");
+ if (r->nss)
+ {
+ p += snprintf(p, l, ", VHT-NSS %d", r->nss);
+ l = sizeof(buf) - (p - buf);
+ }
+ }
+ else if (r->is_he)
+ {
+ p += snprintf(p, l, ", HE-MCS %d, %dMHz", r->mcs, r->mhz);
+ l = sizeof(buf) - (p - buf);
+
+ p += snprintf(p, l, ", HE-NSS %d", r->nss);
+ l = sizeof(buf) - (p - buf);
+
+ p += snprintf(p, l, ", HE-GI %d", r->he_gi);
+ l = sizeof(buf) - (p - buf);
+
+ p += snprintf(p, l, ", HE-DCM %d", r->he_dcm);
+ l = sizeof(buf) - (p - buf);
+ }
+ else if (r->is_eht)
+ {
+ p += snprintf(p, l, ", EHT-MCS %d, %dMHz", r->mcs, r->mhz_hi * 256 + r->mhz);
+ l = sizeof(buf) - (p - buf);
+
+ p += snprintf(p, l, ", EHT-NSS %d", r->nss);
+ l = sizeof(buf) - (p - buf);
+
+ p += snprintf(p, l, ", EHT-GI %d", r->eht_gi);
+ l = sizeof(buf) - (p - buf);
}
}
return buf;
}
+static const char* format_chan_width(bool vht, uint8_t width)
+{
+ if (!vht && width < ARRAY_SIZE(ht_chan_width))
+ switch (ht_chan_width[width]) {
+ case 20: return "20 MHz";
+ case 2040: return "40 MHz or higher";
+ }
+
+ if (vht && width < ARRAY_SIZE(vht_chan_width))
+ switch (vht_chan_width[width]) {
+ case 40: return "20 or 40 MHz";
+ case 80: return "80 MHz";
+ case 8080: return "80+80 MHz";
+ case 160: return "160 MHz";
+ }
+
+ return "unknown";
+}
+
static const char * print_type(const struct iwinfo_ops *iw, const char *ifname)
{
if (!iw->hardware_id(ifname, (char *)&ids))
{
- snprintf(buf, sizeof(buf), "%04X:%04X %04X:%04X",
- ids.vendor_id, ids.device_id,
- ids.subsystem_vendor_id, ids.subsystem_device_id);
+ if (strlen(ids.compatible) > 0)
+ snprintf(buf, sizeof(buf), "embedded");
+ else if (ids.vendor_id == 0 && ids.device_id == 0 &&
+ ids.subsystem_vendor_id != 0 && ids.subsystem_device_id != 0)
+ snprintf(buf, sizeof(buf), "USB %04X:%04X",
+ ids.subsystem_vendor_id, ids.subsystem_device_id);
+ else
+ snprintf(buf, sizeof(buf), "%04X:%04X %04X:%04X",
+ ids.vendor_id, ids.device_id,
+ ids.subsystem_vendor_id, ids.subsystem_device_id);
}
else
{
return format_channel(ch);
}
+static char * print_center_chan1(const struct iwinfo_ops *iw, const char *ifname)
+{
+ int ch;
+ if (iw->center_chan1(ifname, &ch))
+ ch = -1;
+
+ return format_channel(ch);
+}
+
+static char * print_center_chan2(const struct iwinfo_ops *iw, const char *ifname)
+{
+ int ch;
+ if (iw->center_chan2(ifname, &ch))
+ ch = -1;
+
+ return format_channel(ch);
+}
+
static char * print_frequency(const struct iwinfo_ops *iw, const char *ifname)
{
int freq;
return format_hwmodes(modes);
}
+static const char *print_htmode(const struct iwinfo_ops *iw, const char *ifname)
+{
+ int mode;
+ const char *name;
+ if (iw->htmode(ifname, &mode))
+ mode = -1;
+
+ name = iwinfo_htmode_name(mode);
+ if (name)
+ return name;
+
+ return "unknown";
+}
+
static char * print_mbssid_supp(const struct iwinfo_ops *iw, const char *ifname)
{
int supp;
print_ssid(iw, ifname));
printf(" Access Point: %s\n",
print_bssid(iw, ifname));
- printf(" Mode: %s Channel: %s (%s)\n",
+ printf(" Mode: %s Channel: %s (%s) HT Mode: %s\n",
print_mode(iw, ifname),
print_channel(iw, ifname),
- print_frequency(iw, ifname));
+ print_frequency(iw, ifname),
+ print_htmode(iw, ifname));
+ if (iw->center_chan1 != NULL) {
+ printf(" Center Channel 1: %s",
+ print_center_chan1(iw, ifname));
+ printf(" 2: %s\n", print_center_chan2(iw, ifname));
+ }
printf(" Tx-Power: %s Link Quality: %s/%s\n",
print_txpower(iw, ifname),
print_quality(iw, ifname),
format_bssid(e->mac));
printf(" ESSID: %s\n",
format_ssid(e->ssid));
- printf(" Mode: %s Channel: %s\n",
+ printf(" Mode: %s Frequency: %s Band: %s Channel: %s\n",
IWINFO_OPMODE_NAMES[e->mode],
+ format_frequency(e->mhz),
+ format_band(e->band),
format_channel(e->channel));
printf(" Signal: %s Quality: %s/%s\n",
format_signal(e->signal - 0x100),
format_quality(e->quality),
format_quality_max(e->quality_max));
- printf(" Encryption: %s\n\n",
+ printf(" Encryption: %s\n",
format_encryption(&e->crypto));
+ printf(" HT Operation:\n");
+ printf(" Primary Channel: %d\n",
+ e->ht_chan_info.primary_chan);
+ printf(" Secondary Channel Offset: %s\n",
+ ht_secondary_offset[e->ht_chan_info.secondary_chan_off]);
+ printf(" Channel Width: %s\n",
+ format_chan_width(false, e->ht_chan_info.chan_width));
+
+ if (e->vht_chan_info.center_chan_1) {
+ printf(" VHT Operation:\n");
+ printf(" Center Frequency 1: %d\n",
+ e->vht_chan_info.center_chan_1);
+ printf(" Center Frequency 2: %d\n",
+ e->vht_chan_info.center_chan_2);
+ printf(" Channel Width: %s\n",
+ format_chan_width(true, e->vht_chan_info.chan_width));
+ }
+
+ printf("\n");
}
}
static void print_freqlist(const struct iwinfo_ops *iw, const char *ifname)
{
- int i, len, ch;
+ int i, len, freq;
char buf[IWINFO_BUFSIZE];
struct iwinfo_freqlist_entry *e;
return;
}
- if (iw->channel(ifname, &ch))
- ch = -1;
+ if (iw->frequency(ifname, &freq))
+ freq = -1;
for (i = 0; i < len; i += sizeof(struct iwinfo_freqlist_entry))
{
e = (struct iwinfo_freqlist_entry *) &buf[i];
- printf("%s %s (Channel %s)%s\n",
- (ch == e->channel) ? "*" : " ",
+ printf("%s %s (Band: %s, Channel %s) %s\n",
+ (freq == e->mhz) ? "*" : " ",
format_frequency(e->mhz),
+ format_band(e->band),
format_channel(e->channel),
- e->restricted ? " [restricted]" : "");
+ format_freqflags(e->flags));
}
}
e->rx_packets
);
- printf(" TX: %-38s %8d Pkts.\n\n",
+ printf(" TX: %-38s %8d Pkts.\n",
format_assocrate(&e->tx_rate),
e->tx_packets
);
+
+ printf(" expected throughput: %s\n\n",
+ format_rate(e->thr));
}
}
}
}
+static void print_htmodelist(const struct iwinfo_ops *iw, const char *ifname)
+{
+ int i, htmodes = 0;
+
+ if (iw->htmodelist(ifname, &htmodes))
+ {
+ printf("No HT mode information available\n");
+ return;
+ }
+
+ for (i = 0; i < IWINFO_HTMODE_COUNT; i++)
+ if (htmodes & (1 << i))
+ printf("%s ", IWINFO_HTMODE_NAMES[i]);
+
+ printf("\n");
+}
+
static void lookup_phy(const struct iwinfo_ops *iw, const char *section)
{
char buf[IWINFO_BUFSIZE];
}
+static void lookup_path(const struct iwinfo_ops *iw, const char *phy)
+{
+ const char *path;
+
+ if (!iw->phy_path || iw->phy_path(phy, &path) || !path)
+ return;
+
+ printf("%s\n", path);
+}
+
int main(int argc, char **argv)
{
int i, rv = 0;
" iwinfo <device> freqlist\n"
" iwinfo <device> assoclist\n"
" iwinfo <device> countrylist\n"
+ " iwinfo <device> htmodelist\n"
" iwinfo <backend> phyname <section>\n"
);
}
else
{
+ if (!strcmp(argv[2], "path")) {
+ lookup_path(iw, argv[3]);
+ return 0;
+ }
switch (argv[2][0])
{
case 'p':
print_countrylist(iw, argv[1]);
break;
+ case 'h':
+ print_htmodelist(iw, argv[1]);
+ break;
+
default:
fprintf(stderr, "Unknown command: %s\n", argv[i]);
rv = 1;
}
}
-out:
iwinfo_finish();
return rv;