memset(nif, 0, sizeof(nif));
- snprintf(buffer, sizeof(buffer),
- "/sys/class/ieee80211/phy%d/device/net", phyidx);
-
- if ((d = opendir(buffer)) != NULL)
+ if ((d = opendir("/sys/class/net")) != NULL)
{
while ((e = readdir(d)) != NULL)
{
+ snprintf(buffer, sizeof(buffer),
+ "/sys/class/net/%s/phy80211/index", e->d_name);
+ if (nl80211_readint(buffer) != phyidx)
+ continue;
+
snprintf(buffer, sizeof(buffer),
"/sys/class/net/%s/ifindex", e->d_name);
cifidx = nl80211_readint(buffer);
struct nlattr **tb = nl80211_parse(msg);
struct nlattr *bss[NL80211_BSS_MAX + 1];
- static struct nla_policy bss_policy[NL80211_BSS_MAX + 1] = {
+ static const struct nla_policy bss_policy[NL80211_BSS_MAX + 1] = {
[NL80211_BSS_INFORMATION_ELEMENTS] = { 0 },
[NL80211_BSS_STATUS] = { .type = NLA_U32 },
};
struct nlattr **attr = nl80211_parse(msg);
struct nlattr *binfo[NL80211_BSS_MAX + 1];
- static struct nla_policy bss_policy[NL80211_BSS_MAX + 1] = {
+ static const struct nla_policy bss_policy[NL80211_BSS_MAX + 1] = {
[NL80211_BSS_FREQUENCY] = { .type = NLA_U32 },
[NL80211_BSS_STATUS] = { .type = NLA_U32 },
};
struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
- static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
+ static const struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
[NL80211_STA_INFO_INACTIVE_TIME] = { .type = NLA_U32 },
[NL80211_STA_INFO_RX_BYTES] = { .type = NLA_U32 },
[NL80211_STA_INFO_TX_BYTES] = { .type = NLA_U32 },
+ [NL80211_STA_INFO_RX_BYTES64] = { .type = NLA_U64 },
+ [NL80211_STA_INFO_TX_BYTES64] = { .type = NLA_U64 },
[NL80211_STA_INFO_RX_PACKETS] = { .type = NLA_U32 },
[NL80211_STA_INFO_TX_PACKETS] = { .type = NLA_U32 },
[NL80211_STA_INFO_SIGNAL] = { .type = NLA_U8 },
[NL80211_STA_INFO_PLINK_STATE] = { .type = NLA_U8 },
};
- static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = {
+ static const struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = {
[NL80211_RATE_INFO_BITRATE] = { .type = NLA_U16 },
[NL80211_RATE_INFO_MCS] = { .type = NLA_U8 },
[NL80211_RATE_INFO_40_MHZ_WIDTH] = { .type = NLA_FLAG },
struct nlattr **tb = nl80211_parse(msg);
struct nlattr *si[NL80211_SURVEY_INFO_MAX + 1];
- static struct nla_policy sp[NL80211_SURVEY_INFO_MAX + 1] = {
+ static const struct nla_policy sp[NL80211_SURVEY_INFO_MAX + 1] = {
[NL80211_SURVEY_INFO_FREQUENCY] = { .type = NLA_U32 },
[NL80211_SURVEY_INFO_NOISE] = { .type = NLA_U8 },
};
return 0;
}
-static struct {
+static const struct {
const char *match;
int version;
int suite;
}
}
-static struct {
+static const struct {
const char *match;
int cipher;
} wpa_cipher_strings[] = {
else if (ri[NL80211_RATE_INFO_BITRATE])
re->rate = nla_get_u16(ri[NL80211_RATE_INFO_BITRATE]) * 100;
- if (ri[NL80211_RATE_INFO_HE_MCS])
+ if (ri[NL80211_RATE_INFO_EHT_MCS])
+ {
+ re->is_eht = 1;
+ re->mcs = nla_get_u8(ri[NL80211_RATE_INFO_EHT_MCS]);
+
+ if (ri[NL80211_RATE_INFO_EHT_NSS])
+ re->nss = nla_get_u8(ri[NL80211_RATE_INFO_EHT_NSS]);
+ if (ri[NL80211_RATE_INFO_EHT_GI])
+ re->eht_gi = nla_get_u8(ri[NL80211_RATE_INFO_EHT_GI]);
+ }
+ else if (ri[NL80211_RATE_INFO_HE_MCS])
{
re->is_he = 1;
re->mcs = nla_get_u8(ri[NL80211_RATE_INFO_HE_MCS]);
else if (ri[NL80211_RATE_INFO_80P80_MHZ_WIDTH] ||
ri[NL80211_RATE_INFO_160_MHZ_WIDTH])
re->mhz = 160;
+ else if (ri[NL80211_RATE_INFO_320_MHZ_WIDTH])
+ re->mhz_hi = 320 / 256, re->mhz = 320 % 256;
else
re->mhz = 20;
struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1];
int rc;
- static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = {
+ static const struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = {
[NL80211_SURVEY_INFO_FREQUENCY] = { .type = NLA_U32 },
[NL80211_SURVEY_INFO_NOISE] = { .type = NLA_U8 },
[NL80211_SURVEY_INFO_TIME] = { .type = NLA_U64 },
struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
struct nl80211_sta_flag_update *sta_flags;
- static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
+ static const struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
[NL80211_STA_INFO_INACTIVE_TIME] = { .type = NLA_U32 },
[NL80211_STA_INFO_RX_PACKETS] = { .type = NLA_U32 },
[NL80211_STA_INFO_TX_PACKETS] = { .type = NLA_U32 },
[NL80211_STA_INFO_SIGNAL_AVG] = { .type = NLA_U8 },
[NL80211_STA_INFO_RX_BYTES] = { .type = NLA_U32 },
[NL80211_STA_INFO_TX_BYTES] = { .type = NLA_U32 },
+ [NL80211_STA_INFO_RX_BYTES64] = { .type = NLA_U64 },
+ [NL80211_STA_INFO_TX_BYTES64] = { .type = NLA_U64 },
[NL80211_STA_INFO_TX_RETRIES] = { .type = NLA_U32 },
[NL80211_STA_INFO_TX_FAILED] = { .type = NLA_U32 },
[NL80211_STA_INFO_CONNECTED_TIME]= { .type = NLA_U32 },
[NL80211_STA_INFO_NONPEER_PM] = { .type = NLA_U32 },
};
- static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = {
+ static const struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = {
[NL80211_RATE_INFO_BITRATE] = { .type = NLA_U16 },
[NL80211_RATE_INFO_MCS] = { .type = NLA_U8 },
[NL80211_RATE_INFO_40_MHZ_WIDTH] = { .type = NLA_FLAG },
sinfo[NL80211_STA_INFO_TX_BITRATE], rate_policy))
nl80211_parse_rateinfo(rinfo, &e->tx_rate);
- if (sinfo[NL80211_STA_INFO_RX_BYTES])
+ if (sinfo[NL80211_STA_INFO_RX_BYTES64])
+ e->rx_bytes = nla_get_u64(sinfo[NL80211_STA_INFO_RX_BYTES64]);
+ else if (sinfo[NL80211_STA_INFO_RX_BYTES])
e->rx_bytes = nla_get_u32(sinfo[NL80211_STA_INFO_RX_BYTES]);
- if (sinfo[NL80211_STA_INFO_TX_BYTES])
+ if (sinfo[NL80211_STA_INFO_TX_BYTES64])
+ e->tx_bytes = nla_get_u64(sinfo[NL80211_STA_INFO_TX_BYTES64]);
+ else if (sinfo[NL80211_STA_INFO_TX_BYTES])
e->tx_bytes = nla_get_u32(sinfo[NL80211_STA_INFO_TX_BYTES]);
if (sinfo[NL80211_STA_INFO_TX_RETRIES])
struct nlattr *freqs[NL80211_FREQUENCY_ATTR_MAX + 1];
struct nlattr *band, *freq;
- static struct nla_policy freq_policy[NL80211_FREQUENCY_ATTR_MAX + 1] = {
+ static const struct nla_policy freq_policy[NL80211_FREQUENCY_ATTR_MAX + 1] = {
[NL80211_FREQUENCY_ATTR_FREQ] = { .type = NLA_U32 },
[NL80211_FREQUENCY_ATTR_DISABLED] = { .type = NLA_FLAG },
[NL80211_FREQUENCY_ATTR_PASSIVE_SCAN] = { .type = NLA_FLAG },
struct nlattr **tb = nl80211_parse(msg);
struct nlattr *bss[NL80211_BSS_MAX + 1];
- static struct nla_policy bss_policy[NL80211_BSS_MAX + 1] = {
+ static const struct nla_policy bss_policy[NL80211_BSS_MAX + 1] = {
[NL80211_BSS_TSF] = { .type = NLA_U64 },
[NL80211_BSS_FREQUENCY] = { .type = NLA_U32 },
[NL80211_BSS_BSSID] = { 0 },
uint16_t nl_ht;
uint32_t nl_vht;
uint16_t he_phy_cap[6];
+ uint16_t eht_phy_cap[9];
};
static void nl80211_eval_modelist(struct nl80211_modes *m)
m->ht |= IWINFO_HTMODE_HE160 | IWINFO_HTMODE_HE80_80;
}
+ if (m->eht_phy_cap[0] != 0) {
+ m->hw |= IWINFO_80211_BE;
+ m->ht |= IWINFO_HTMODE_EHT20;
+
+ if (m->he_phy_cap[0] & BIT(9))
+ m->ht |= IWINFO_HTMODE_EHT40;
+ if (m->he_phy_cap[0] & BIT(10))
+ m->ht |= IWINFO_HTMODE_EHT40 | IWINFO_HTMODE_EHT80;
+ if (m->he_phy_cap[0] & BIT(11))
+ m->ht |= IWINFO_HTMODE_EHT160;
+ if (m->he_phy_cap[0] & BIT(12))
+ m->ht |= IWINFO_HTMODE_EHT160 | IWINFO_HTMODE_EHT80_80;
+ if ((m->eht_phy_cap[0] & BIT(9)) && (m->bands & IWINFO_BAND_6))
+ m->ht |= IWINFO_HTMODE_EHT320;
+ }
+
if (m->bands & IWINFO_BAND_24)
{
m->hw |= IWINFO_80211_B;
nla_for_each_nested(nl_iftype, bands[NL80211_BAND_ATTR_IFTYPE_DATA], rem_band) {
nla_parse(tb, NL80211_BAND_IFTYPE_ATTR_MAX,
nla_data(nl_iftype), nla_len(nl_iftype), NULL);
+
+ // HE
if (tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY]) {
len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY]);
nla_data(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY]),
len);
}
+
+ // EHT
+ if (tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY]) {
+ len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY]);
+
+ if (len > sizeof(m->eht_phy_cap) - 1)
+ len = sizeof(m->eht_phy_cap) - 1;
+ memcpy(&((uint8_t *)m->eht_phy_cap)[1],
+ nla_data(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY]),
+ len);
+ }
}
}
}
char *res, b[2] = { 0 };
int err;
bool he = false;
+ bool eht = false;
res = nl80211_phy2ifname(ifname);
*buf = 0;
if (err)
return -1;
+ if (nl80211_hostapd_query(res ? res : ifname, "ieee80211be", b, sizeof(b)))
+ eht = b[0] == '1';
+
if (nl80211_hostapd_query(res ? res : ifname, "ieee80211ax", b, sizeof(b)))
he = b[0] == '1';
else if (nl80211_wpactl_query(res ? res : ifname, "wifi_generation", b, sizeof(b)))
switch (chn.width) {
case NL80211_CHAN_WIDTH_20:
if (he)
- *buf = IWINFO_HTMODE_HE20;
+ *buf = (eht == true) ? IWINFO_HTMODE_EHT20 : IWINFO_HTMODE_HE20;
else if (chn.mode == -1)
*buf = IWINFO_HTMODE_VHT20;
else
break;
case NL80211_CHAN_WIDTH_40:
if (he)
- *buf = IWINFO_HTMODE_HE40;
+ *buf = (eht == true) ? IWINFO_HTMODE_EHT40 : IWINFO_HTMODE_HE40;
else if (chn.mode == -1)
*buf = IWINFO_HTMODE_VHT40;
else
break;
case NL80211_CHAN_WIDTH_80:
if (he)
- *buf = IWINFO_HTMODE_HE80;
+ *buf = (eht == true) ? IWINFO_HTMODE_EHT80 : IWINFO_HTMODE_HE80;
else
*buf = IWINFO_HTMODE_VHT80;
break;
case NL80211_CHAN_WIDTH_80P80:
if (he)
- *buf = IWINFO_HTMODE_HE80_80;
+ *buf = (eht == true) ? IWINFO_HTMODE_EHT80_80 : IWINFO_HTMODE_HE80_80;
else
*buf = IWINFO_HTMODE_VHT80_80;
break;
case NL80211_CHAN_WIDTH_160:
if (he)
- *buf = IWINFO_HTMODE_HE160;
+ *buf = (eht == true) ? IWINFO_HTMODE_EHT160 : IWINFO_HTMODE_HE160;
else
*buf = IWINFO_HTMODE_VHT160;
break;
+ case NL80211_CHAN_WIDTH_320:
+ *buf = IWINFO_HTMODE_EHT320;
+ break;
case NL80211_CHAN_WIDTH_5:
case NL80211_CHAN_WIDTH_10:
case NL80211_CHAN_WIDTH_20_NOHT:
nla_for_each_nested(comb, attr[NL80211_ATTR_INTERFACE_COMBINATIONS], comb_rem)
{
- static struct nla_policy iface_combination_policy[NUM_NL80211_IFACE_COMB] = {
+ static const struct nla_policy iface_combination_policy[NUM_NL80211_IFACE_COMB] = {
[NL80211_IFACE_COMB_LIMITS] = { .type = NLA_NESTED },
[NL80211_IFACE_COMB_MAXNUM] = { .type = NLA_U32 },
};
struct nlattr *tb_comb[NUM_NL80211_IFACE_COMB+1];
- static struct nla_policy iface_limit_policy[NUM_NL80211_IFACE_LIMIT] = {
+ static const struct nla_policy iface_limit_policy[NUM_NL80211_IFACE_LIMIT] = {
[NL80211_IFACE_LIMIT_TYPES] = { .type = NLA_NESTED },
[NL80211_IFACE_LIMIT_MAX] = { .type = NLA_U32 },
};