if (bss[NL80211_BSS_INFORMATION_ELEMENTS])
print_ies(nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS]),
nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]),
- false, PRINT_LINK_MLO_MLD);
+ false, PRINT_LINK_MLO_MLD, false);
}
} else {
memcpy(result->sta_addr, nla_data(bss[NL80211_BSS_BSSID]), 6);
if (bss[NL80211_BSS_INFORMATION_ELEMENTS])
print_ies(nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS]),
nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]),
- false, result->mld ? PRINT_LINK_MLO_LINK : PRINT_LINK);
+ false, result->mld ? PRINT_LINK_MLO_LINK : PRINT_LINK,
+ false);
if (bss[NL80211_BSS_FREQUENCY_OFFSET])
freq_offset = nla_get_u32(bss[NL80211_BSS_FREQUENCY_OFFSET]);
}
struct ie_context {
+ bool from_ap;
bool is_vht_cap;
+ const uint8_t *he_cap;
};
static void print_ssid(const uint8_t type, uint8_t len, const uint8_t *data,
print_he_operation(data, len);
}
+static void print_eht_capa(const uint8_t type, uint8_t len,
+ const uint8_t *data, const struct ie_context *ctx)
+{
+ printf("\n");
+ print_eht_capability(data, len, ctx->he_cap, ctx->from_ap);
+}
+
static const struct ie_print ext_printers[] = {
[EID_EXT_HE_CAPABILITY] = { "HE capabilities", print_he_capa, 21, 54, BIT(PRINT_SCAN), },
[EID_EXT_HE_OPERATION] = { "HE Operation", print_he_oper, 6, 15, BIT(PRINT_SCAN), },
+ [EID_EXT_EHT_CAPABILITY] = { "EHT capabilities", print_eht_capa, 13, 30, BIT(PRINT_SCAN), },
};
static void print_extension(unsigned char len, unsigned char *ie,
+ const struct ie_context *ctx,
bool unknown, enum print_ie_type ptype)
{
unsigned char tag;
tag = ie[0];
if (tag < ARRAY_SIZE(ext_printers) && ext_printers[tag].name &&
ext_printers[tag].flags & BIT(ptype)) {
- print_ie(&ext_printers[tag], tag, len - 1, ie + 1, NULL);
+ print_ie(&ext_printers[tag], tag, len - 1, ie + 1, ctx);
return;
}
}
static void init_context(struct ie_context *ctx,
- unsigned char *ie, int ielen)
+ unsigned char *ie, int ielen, bool from_ap)
{
unsigned char *pos = ie;
int remaining = ielen;
if (!ie || !ielen)
return;
+ ctx->from_ap = from_ap;
+
while (remaining >= 2 && remaining - 2 >= pos[1]) {
switch (pos[0]) {
case EID_VHT_CAPABILITY:
ctx->is_vht_cap = true;
break;
+ case EID_EXTENSION:
+ switch (pos[2]) {
+ case EID_EXT_HE_CAPABILITY:
+ ctx->he_cap = pos + 3;
+ break;
+ }
+ break;
}
remaining -= pos[1] + 2;
}
void print_ies(unsigned char *ie, int ielen, bool unknown,
- enum print_ie_type ptype)
+ enum print_ie_type ptype, bool from_ap)
{
struct ie_context ctx;
if (!ie)
return;
- init_context(&ctx, ie, ielen);
+ init_context(&ctx, ie, ielen, from_ap);
while (ielen >= 2 && ielen - 2 >= ie[1]) {
if (ie[0] < ARRAY_SIZE(ieprinters) &&
} else if (ie[0] == 221 /* vendor */) {
print_vendor(ie[1], ie + 2, unknown, ptype);
} else if (ie[0] == 255 /* extension */) {
- print_extension(ie[1], ie + 2, unknown, ptype);
+ print_extension(ie[1], ie + 2, &ctx, unknown, ptype);
} else if (unknown) {
int i;
printf("\tInformation elements from Probe Response "
"frame:\n");
print_ies(nla_data(ies), nla_len(ies),
- params->unknown, params->type);
+ params->unknown, params->type, true);
}
if (bss[NL80211_BSS_BEACON_IES] && show--) {
printf("\tInformation elements from Beacon frame:\n");
print_ies(nla_data(bss[NL80211_BSS_BEACON_IES]),
nla_len(bss[NL80211_BSS_BEACON_IES]),
- params->unknown, params->type);
+ params->unknown, params->type, true);
}
return NL_SKIP;