From: Alex Gavin Date: Wed, 28 May 2025 04:13:30 +0000 (-0700) Subject: iw: scan: Add partial Multi-Link element printing X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fheads%2Fmaster;p=thirdparty%2Fiw.git iw: scan: Add partial Multi-Link element printing Only print some basic items to start. Minimum and maximum length values are computed from the specification. Maximum only includes Common Info and does not consider Link Info. Signed-off-by: Alex Gavin Link: https://patch.msgid.link/20250528041330.83464-1-alex.gavin@candelatech.com [code style, spelling fixes] Signed-off-by: Johannes Berg --- diff --git a/ieee80211.h b/ieee80211.h index c31041e..2e6b68b 100644 --- a/ieee80211.h +++ b/ieee80211.h @@ -100,6 +100,7 @@ enum elem_id_ext { EID_EXT_HE_CAPABILITY = 35, EID_EXT_HE_OPERATION = 36, EID_EXT_EHT_OPERATION = 106, + EID_EXT_MULTI_LINK = 107, EID_EXT_EHT_CAPABILITY = 108, }; diff --git a/iw.h b/iw.h index a423431..145b058 100644 --- a/iw.h +++ b/iw.h @@ -247,6 +247,7 @@ void print_he_operation(const uint8_t *ie, int len); void print_he_info(struct nlattr *nl_iftype); void print_eht_capability(const uint8_t *ie, int len, const uint8_t *he_cap, bool from_ap); +void print_multi_link(const uint8_t *ie, int len); void print_eht_operation(const uint8_t *ie, int len); void print_eht_info(struct nlattr *nl_iftype, int band); void print_s1g_capability(const uint8_t *caps); diff --git a/scan.c b/scan.c index 263d2e3..facb503 100644 --- a/scan.c +++ b/scan.c @@ -2426,6 +2426,13 @@ static void print_eht_capa(const uint8_t type, uint8_t len, print_eht_capability(data, len, ctx->he_cap, ctx->from_ap); } +static void _print_multi_link(const uint8_t type, uint8_t len, const uint8_t *data, + const struct ie_context *ctx) +{ + printf("\n"); + print_multi_link(data, len); +} + static void print_eht_oper(const uint8_t type, uint8_t len, const uint8_t *data, const struct ie_context *ctx) { @@ -2437,6 +2444,7 @@ 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), }, + [EID_EXT_MULTI_LINK] = { "Multi-Link", _print_multi_link, 5, 23, BIT(PRINT_SCAN), }, [EID_EXT_EHT_OPERATION] = { "EHT Operation", print_eht_oper, 5, 10, BIT(PRINT_SCAN), }, }; diff --git a/util.c b/util.c index 7067ca4..36c1185 100644 --- a/util.c +++ b/util.c @@ -1934,6 +1934,63 @@ void print_he_operation(const uint8_t *ie, int len) } } +void print_multi_link(const uint8_t *ie, int len) +{ + uint16_t eml_capa = 0; + uint16_t mld_capa = 0; + uint16_t presence_bitmap = (ie[1] << 8) | ie[0]; + bool link_id_info_present = presence_bitmap & 0x0010; + bool bss_param_change_present = presence_bitmap & 0x0020; + bool medium_sync_delay_present = presence_bitmap & 0x0040; + bool eml_capabilities_present = presence_bitmap & 0x0080; + bool mld_capabilities_present = presence_bitmap & 0x0100; + uint8_t common_info_len = ie[2] - 1; + uint8_t offset = 3; + char mld_mac[20]; + + mac_addr_n2a(mld_mac, (uint8_t *)ie + offset); + printf("\t\tMLD MAC: %s\n", mld_mac); + offset += 6; + + // Link ID Info + if (offset < common_info_len && link_id_info_present) { + printf("\t\tLink ID: %d\n", ie[offset] & 0xF); + offset += 1; + } + + // BSS Parameters Change Count + if (offset < common_info_len && bss_param_change_present) + offset += 1; + + // Medium Synchronization Delay Information + if (offset < common_info_len && medium_sync_delay_present) + offset += 2; + + // EML Capabilities + if (offset < common_info_len && eml_capabilities_present) { + eml_capa = (ie[offset + 1] << 8) | ie[offset]; + printf("\t\t\tEML Capabilities: 0x%04x\n", eml_capa); + + if (eml_capa & 0x0001) + printf("\t\t\t\tEMLSR Support\n"); + if (eml_capa & 0x0080) + printf("\t\t\t\tEMLMR Support\n"); + + offset += 2; + } + + // MLD Capabilities and Operations + if (offset < common_info_len && mld_capabilities_present) { + mld_capa = (ie[offset + 1] << 8) | ie[offset]; + printf("\t\t\tMLD Capabilities and Operations: 0x%04x\n", mld_capa); + + // This is zero-indexed (i.e. 0 means 1 simulataneous link, 1 means 2, etc) + printf("\t\t\t\tMaximum Number of Simultaneous Links: %d\n", mld_capa & 0xF); + + offset += 2; + } +} + void print_eht_operation(const uint8_t *ie, int len) { uint8_t oper_parameters = ie[0];