]> git.ipfire.org Git - thirdparty/iw.git/commitdiff
iw: scan: Add partial Multi-Link element printing main master
authorAlex Gavin <alex.gavin@candelatech.com>
Wed, 28 May 2025 04:13:30 +0000 (21:13 -0700)
committerJohannes Berg <johannes.berg@intel.com>
Tue, 24 Jun 2025 07:41:15 +0000 (09:41 +0200)
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 <alex.gavin@candelatech.com>
Link: https://patch.msgid.link/20250528041330.83464-1-alex.gavin@candelatech.com
[code style, spelling fixes]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
ieee80211.h
iw.h
scan.c
util.c

index c31041ee19e35595272e60ea26bb3ab38e76faff..2e6b68b59451bdf9722b08d7bc6a29876bf56232 100644 (file)
@@ -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 a423431847f840d31ad21d8c27477ce928bb8453..145b058d86ba3c7ae16ffcfd5fdb5e92f7966955 100644 (file)
--- 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 263d2e33218378072da294381ec1bed69c493d79..facb503508769ce19885ed7d2b8b087682762e25 100644 (file)
--- 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 7067ca43c1a21f5ab244dd79d768a7d279fb4fd3..36c118513e3ffa78398011ee803b90faff440760 100644 (file)
--- 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];