]> git.ipfire.org Git - thirdparty/iw.git/blobdiff - scan.c
bump version to 6.9
[thirdparty/iw.git] / scan.c
diff --git a/scan.c b/scan.c
index e8a7afdfb00d46843ef44dd23f4d96340477e2ff..faf406d237de428c69e9738c7c8f4d4417b003da 100644 (file)
--- a/scan.c
+++ b/scan.c
@@ -202,6 +202,10 @@ int parse_sched_scan(struct nl_msg *msg, int *argc, char ***argv)
                                err = parse_random_mac_addr(msg, v[0] + 9);
                                if (err)
                                        goto nla_put_failure;
+                       } else if (!strncmp(v[0], "coloc", 5)) {
+                               flags |= NL80211_SCAN_FLAG_COLOCATED_6GHZ;
+                       } else if (!strncmp(v[0], "flush", 5)) {
+                               flags |= NL80211_SCAN_FLAG_FLUSH;
                        } else {
                                /* this element is not for us, so
                                 * return to continue parsing.
@@ -345,6 +349,8 @@ int parse_sched_scan(struct nl_msg *msg, int *argc, char ***argv)
                nla_put_nested(msg, NL80211_ATTR_SCAN_SSIDS, ssids);
        if (have_freqs)
                nla_put_nested(msg, NL80211_ATTR_SCAN_FREQUENCIES, freqs);
+       else
+               flags |= NL80211_SCAN_FLAG_COLOCATED_6GHZ;
        if (have_matchset)
                nla_put_nested(msg, NL80211_ATTR_SCHED_SCAN_MATCH, matchset);
        if (have_plans)
@@ -421,6 +427,9 @@ static int handle_scan(struct nl80211_state *state,
                        } else if (strcmp(argv[i], "ap-force") == 0) {
                                flags |= NL80211_SCAN_FLAG_AP;
                                break;
+                       } else if (strcmp(argv[i], "coloc") == 0) {
+                               flags |= NL80211_SCAN_FLAG_COLOCATED_6GHZ;
+                               break;
                        } else if (strcmp(argv[i], "duration-mandatory") == 0) {
                                duration_mandatory = true;
                                break;
@@ -508,6 +517,8 @@ static int handle_scan(struct nl80211_state *state,
 
        if (have_freqs)
                nla_put_nested(msg, NL80211_ATTR_SCAN_FREQUENCIES, freqs);
+       else
+               flags |=  NL80211_SCAN_FLAG_COLOCATED_6GHZ;
        if (flags)
                NLA_PUT_U32(msg, NL80211_ATTR_SCAN_FLAGS, flags);
        if (duration)
@@ -586,10 +597,10 @@ static void print_rm_enabled_capabilities(const uint8_t type, uint8_t len,
                            const uint8_t *data,
                            const struct print_ies_data *ie_buffer)
 {
-       __u64 capa = data[0] |
-                    data[1] << 8 |
-                    data[2] << 16 |
-                    data[3] << 24 |
+       __u64 capa = ((__u64) data[0]) |
+                    ((__u64) data[1]) << 8 |
+                    ((__u64) data[2]) << 16 |
+                    ((__u64) data[3]) << 24 |
                     ((__u64) data[4]) << 32;
 
        printf("\n");
@@ -732,6 +743,21 @@ static void print_erp(const uint8_t type, uint8_t len, const uint8_t *data,
        printf("\n");
 }
 
+static void print_ap_channel_report(const uint8_t type, uint8_t len, const uint8_t *data,
+                                   const struct print_ies_data *ie_buffer)
+{
+       uint8_t oper_class = data[0];
+       int i;
+
+       printf("\n");
+       printf("\t\t * operating class: %d\n", oper_class);
+       printf("\t\t * channel(s):");
+       for (i = 1; i < len; ++i) {
+               printf(" %d", data[i]);
+       }
+       printf("\n");
+}
+
 static void print_cipher(const uint8_t *data)
 {
        if (memcmp(data, ms_oui, 3) == 0) {
@@ -1003,6 +1029,8 @@ static void _print_rsn_ie(const char *defcipher, const char *defauth,
                        printf(" SPP-AMSDU-capable");
                if (capa & 0x0800)
                        printf(" SPP-AMSDU-required");
+               if (capa & 0x2000)
+                       printf(" Extended-Key-ID");
                printf(" (0x%.4x)\n", capa);
                data += 2;
                len -= 2;
@@ -1131,10 +1159,10 @@ static void print_interworking(const uint8_t type, uint8_t len,
                printf("\t\tVenue Type: %i\n", (int)(data[2]));
        }
        if (len == 9)
-               printf("\t\tHESSID: %02hx:%02hx:%02hx:%02hx:%02hx:%02hx\n",
+               printf("\t\tHESSID: %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n",
                       data[3], data[4], data[5], data[6], data[7], data[8]);
        else if (len == 7)
-               printf("\t\tHESSID: %02hx:%02hx:%02hx:%02hx:%02hx:%02hx\n",
+               printf("\t\tHESSID: %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n",
                       data[1], data[2], data[3], data[4], data[5], data[6]);
 }
 
@@ -1193,7 +1221,7 @@ static void print_11u_rcon(const uint8_t type, uint8_t len, const uint8_t *data,
                        printf("Invalid IE length.\n");
                } else {
                        for (idx = 0; idx < ln0; idx++) {
-                               printf("%02hx", data[2 + idx]);
+                               printf("%02hhx", data[2 + idx]);
                        }
                        printf("\n");
                }
@@ -1205,7 +1233,7 @@ static void print_11u_rcon(const uint8_t type, uint8_t len, const uint8_t *data,
                        printf("Invalid IE length.\n");
                } else {
                        for (idx = 0; idx < ln1; idx++) {
-                               printf("%02hx", data[2 + ln0 + idx]);
+                               printf("%02hhx", data[2 + ln0 + idx]);
                        }
                        printf("\n");
                }
@@ -1217,7 +1245,7 @@ static void print_11u_rcon(const uint8_t type, uint8_t len, const uint8_t *data,
                        printf("Invalid IE length.\n");
                } else {
                        for (idx = 0; idx < ln2; idx++) {
-                               printf("%02hx", data[2 + ln0 + ln1 + idx]);
+                               printf("%02hhx", data[2 + ln0 + ln1 + idx]);
                        }
                        printf("\n");
                }
@@ -1417,8 +1445,12 @@ static void print_capabilities(const uint8_t type, uint8_t len,
                        CAPA(72, "Reserved");
                        CAPA(73, "Extended Spectrum Management Capable");
                        CAPA(74, "Reserved");
+                       CAPA(77, "TWT Requester Support");
+                       CAPA(78, "TWT Responder Support");
+                       CAPA(79, "OBSS Narrow Bandwith RU in UL OFDMA Tolerance Support");
+
                        default:
-                               printf(" %d", bit);
+                               printf(" %d", bit + base);
                                break;
                        }
 #undef ADD_BIT_VAL
@@ -1474,8 +1506,8 @@ static void print_vht_capa(const uint8_t type, uint8_t len, const uint8_t *data,
                           const struct print_ies_data *ie_buffer)
 {
        printf("\n");
-       print_vht_info(data[0] | (data[1] << 8) |
-                      (data[2] << 16) | (data[3] << 24),
+       print_vht_info((__u32) data[0] | ((__u32)data[1] << 8) |
+                      ((__u32)data[2] << 16) | ((__u32)data[3] << 24),
                       data + 4);
 }
 
@@ -1540,7 +1572,7 @@ static void print_measurement_pilot_tx(const uint8_t type, uint8_t len,
        printf("\n");
        printf("\t\t * interval: %d TUs\n", data[0]);
 
-       if(len <= 1)
+       if (len <= 1)
                return;
 
        p = (uint8_t *) data + 1;
@@ -1647,6 +1679,101 @@ static void print_mesh_conf(const uint8_t type, uint8_t len,
                printf("\t\t\t Mesh Power Save Level\n");
 }
 
+static void print_s1g_capa(const uint8_t type, uint8_t len,
+                           const uint8_t *data,
+                           const struct print_ies_data *ie_buffer)
+{
+       printf("\n");
+       print_s1g_capability(data);
+}
+
+static void print_short_beacon_int(const uint8_t type, uint8_t len,
+                           const uint8_t *data,
+                           const struct print_ies_data *ie_buffer)
+{
+       printf(" %d\n", (data[1] << 8) | data[0]);
+}
+
+static void print_s1g_oper(const uint8_t type, uint8_t len,
+                           const uint8_t *data,
+                           const struct print_ies_data *ie_buffer)
+{
+       int oper_ch_width, prim_ch_width;
+       int prim_ch_width_subfield = data[0] & 0x1;
+
+       prim_ch_width = 2;
+
+       /* B1-B4 BSS channel width subfield */
+       switch ((data[0] >> 1) & 0xf) {
+       case 0:
+               oper_ch_width = 1;
+               prim_ch_width = 1;
+               if (!prim_ch_width_subfield) {
+                       oper_ch_width = -1;
+                       prim_ch_width = -1;
+               }
+       break;
+       case 1:
+               oper_ch_width = 2;
+               if (prim_ch_width_subfield)
+                       prim_ch_width = 1;
+               break;
+       case 3:
+               oper_ch_width = 4;
+               if (prim_ch_width_subfield)
+                       prim_ch_width = 1;
+               break;
+       case 7:
+               oper_ch_width = 8;
+               if (prim_ch_width_subfield)
+                       prim_ch_width = 1;
+               break;
+       case 15:
+               oper_ch_width = 16;
+               if (prim_ch_width_subfield)
+                       prim_ch_width = 1;
+               break;
+       default:
+               oper_ch_width = -1;
+               prim_ch_width = -1;
+               break;
+       }
+
+       printf("\n");
+       printf("\t\tChannel width:\n");
+       if (oper_ch_width == -1 || prim_ch_width == -1) {
+               printf("\t\t\tBSS primary channel width: invalid\n");
+               printf("\t\t\tBSS operating channel width: invalid\n");
+       } else {
+               printf("\t\t\tBSS primary channel width: %d MHz\n", prim_ch_width);
+               printf("\t\t\tBSS operating channel width: %d MHz\n", oper_ch_width);
+       }
+       if (data[0] & BIT(5))
+               printf("\t\t\t1 MHz primary channel located at the lower side of 2 MHz\n");
+       else
+               printf("\t\t\t1 MHz primary channel located at the upper side of 2 MHz\n");
+
+       if (data[0] & BIT(7))
+               printf("\t\t\tMCS 10 not recommended\n");
+
+       printf("\t\t* operating class: %d\n", data[1]);
+       printf("\t\t* primary channel number: %d\n", data[2]);
+
+       printf("\t\t* channel index: %d\n", data[3]);
+
+       printf("\t\tMax S1G MCS Map:\n");
+       printf("\t\t\tFor 1 SS: %s\n", s1g_ss_max_support((data[4] >> 2) & 0x3));
+       printf("\t\t\tFor 2 SS: %s\n", s1g_ss_max_support((data[4] >> 6) & 0x3));
+       printf("\t\t\tFor 3 SS: %s\n", s1g_ss_max_support((data[5] >> 2) & 0x3));
+       printf("\t\t\tFor 4 SS: %s\n", s1g_ss_max_support((data[5] >> 6) & 0x3));
+
+       printf("\t\tMin S1G MCS Map:\n");
+       printf("\t\t\tFor 1 SS: %s\n", s1g_ss_min_support(data[4] & 0x3));
+       printf("\t\t\tFor 2 SS: %s\n", s1g_ss_min_support((data[4] >> 4) & 0x3));
+       printf("\t\t\tFor 3 SS: %s\n", s1g_ss_min_support(data[5] & 0x3));
+       printf("\t\t\tFor 4 SS: %s\n", s1g_ss_min_support((data[5] >> 4) & 0x3));
+}
+
 struct ie_print {
        const char *name;
        void (*print)(const uint8_t type, uint8_t len, const uint8_t *data,
@@ -1689,7 +1816,8 @@ static void print_ie(const struct ie_print *p, const uint8_t type, uint8_t len,
 }
 
 static const struct ie_print ieprinters[] = {
-       [0] = { "SSID", print_ssid, 0, 32, BIT(PRINT_SCAN) | BIT(PRINT_LINK), },
+       [0] = { "SSID", print_ssid, 0, 32,
+                BIT(PRINT_SCAN) | BIT(PRINT_LINK) | BIT(PRINT_LINK_MLO_MLD), },
        [1] = { "Supported rates", print_supprates, 0, 255, BIT(PRINT_SCAN), },
        [3] = { "DS Parameter set", print_ds, 1, 1, BIT(PRINT_SCAN), },
        [5] = { "TIM", print_tim, 4, 255, BIT(PRINT_SCAN), },
@@ -1701,6 +1829,7 @@ static const struct ie_print ieprinters[] = {
        [42] = { "ERP", print_erp, 1, 255, BIT(PRINT_SCAN), },
        [45] = { "HT capabilities", print_ht_capa, 26, 26, BIT(PRINT_SCAN), },
        [47] = { "ERP D4.0", print_erp, 1, 255, BIT(PRINT_SCAN), },
+       [51] = { "AP Channel Report", print_ap_channel_report, 1, 255, BIT(PRINT_SCAN), },
        [59] = { "Supported operating classes", print_supp_op_classes, 1, 255, BIT(PRINT_SCAN), },
        [66] = { "Measurement Pilot Transmission", print_measurement_pilot_tx, 1, 255, BIT(PRINT_SCAN), },
        [74] = { "Overlapping BSS scan params", print_obss_scan_params, 14, 255, BIT(PRINT_SCAN), },
@@ -1718,6 +1847,9 @@ static const struct ie_print ieprinters[] = {
        [108] = { "802.11u Advertisement", print_11u_advert, 0, 255, BIT(PRINT_SCAN), },
        [111] = { "802.11u Roaming Consortium", print_11u_rcon, 2, 255, BIT(PRINT_SCAN), },
        [195] = { "Transmit Power Envelope", print_tx_power_envelope, 2, 5, BIT(PRINT_SCAN), },
+       [214] = { "Short beacon interval", print_short_beacon_int, 2, 2, BIT(PRINT_SCAN), },
+       [217] = { "S1G capabilities", print_s1g_capa, 15, 15, BIT(PRINT_SCAN), },
+       [232] = { "S1G operation", print_s1g_oper, 6, 6, BIT(PRINT_SCAN), },
 };
 
 static void print_wifi_wpa(const uint8_t type, uint8_t len, const uint8_t *data,
@@ -1827,12 +1959,17 @@ static void print_wifi_wps(const uint8_t type, uint8_t len, const uint8_t *data,
        while (len >= 4) {
                subtype = (data[0] << 8) + data[1];
                sublen = (data[2] << 8) + data[3];
-               if (sublen > len)
+               if (sublen > len - 4)
                        break;
 
                switch (subtype) {
                case 0x104a:
                        tab_on_first(&first);
+                       if (sublen < 1) {
+                               printf("\t * Version: (invalid "
+                                      "length %d)\n", sublen);
+                               break;
+                       }
                        printf("\t * Version: %d.%d\n", data[4] >> 4, data[4] & 0xF);
                        break;
                case 0x1011:
@@ -1843,8 +1980,8 @@ static void print_wifi_wps(const uint8_t type, uint8_t len, const uint8_t *data,
                        uint16_t id;
                        tab_on_first(&first);
                        if (sublen != 2) {
-                               printf("\t * Device Password ID: (invalid "
-                                      "length %d)\n", sublen);
+                               printf("\t * Device Password ID: (invalid length %d)\n",
+                                      sublen);
                                break;
                        }
                        id = data[4] << 8 | data[5];
@@ -1865,20 +2002,41 @@ static void print_wifi_wps(const uint8_t type, uint8_t len, const uint8_t *data,
                        printf("\t * Model Number: %.*s\n", sublen, data + 4);
                        break;
                case 0x103b: {
-                       __u8 val = data[4];
+                       __u8 val;
+
+                       if (sublen < 1) {
+                               printf("\t * Response Type: (invalid length %d)\n",
+                                      sublen);
+                               break;
+                       }
+                       val = data[4];
                        tab_on_first(&first);
                        printf("\t * Response Type: %d%s\n",
                               val, val == 3 ? " (AP)" : "");
                        break;
                }
                case 0x103c: {
-                       __u8 val = data[4];
+                       __u8 val;
+
+                       if (sublen < 1) {
+                               printf("\t * RF Bands: (invalid length %d)\n",
+                                      sublen);
+                               break;
+                       }
+                       val = data[4];
                        tab_on_first(&first);
                        printf("\t * RF Bands: 0x%x\n", val);
                        break;
                }
                case 0x1041: {
-                       __u8 val = data[4];
+                       __u8 val;
+
+                       if (sublen < 1) {
+                               printf("\t * Selected Registrar: (invalid length %d)\n",
+                                      sublen);
+                               break;
+                       }
+                       val = data[4];
                        tab_on_first(&first);
                        printf("\t * Selected Registrar: 0x%x\n", val);
                        break;
@@ -1888,7 +2046,14 @@ static void print_wifi_wps(const uint8_t type, uint8_t len, const uint8_t *data,
                        printf("\t * Serial Number: %.*s\n", sublen, data + 4);
                        break;
                case 0x1044: {
-                       __u8 val = data[4];
+                       __u8 val;
+
+                       if (sublen < 1) {
+                               printf("\t * Wi-Fi Protected Setup State: (invalid length %d)\n",
+                                      sublen);
+                               break;
+                       }
+                       val = data[4];
                        tab_on_first(&first);
                        printf("\t * Wi-Fi Protected Setup State: %d%s%s\n",
                               val,
@@ -1910,11 +2075,26 @@ static void print_wifi_wps(const uint8_t type, uint8_t len, const uint8_t *data,
                                data[12], data[13], data[14], data[15],
                                data[16], data[17], data[18], data[19]);
                        break;
+               case 0x1049:
+                       tab_on_first(&first);
+                       if (sublen == 6 &&
+                           data[4] == 0x00 &&
+                           data[5] == 0x37 &&
+                           data[6] == 0x2a &&
+                           data[7] == 0x00 &&
+                           data[8] == 0x01) {
+                               uint8_t v2 = data[9];
+                               printf("\t * Version2: %d.%d\n", v2 >> 4, v2 & 0xf);
+                       } else {
+                               printf("\t * Unknown vendor extension. len=%u\n",
+                                      sublen);
+                       }
+                       break;
                case 0x1054: {
                        tab_on_first(&first);
                        if (sublen != 8) {
-                               printf("\t * Primary Device Type: (invalid "
-                                      "length %d)\n", sublen);
+                               printf("\t * Primary Device Type: (invalid length %d)\n",
+                                      sublen);
                                break;
                        }
                        printf("\t * Primary Device Type: "
@@ -1925,15 +2105,29 @@ static void print_wifi_wps(const uint8_t type, uint8_t len, const uint8_t *data,
                        break;
                }
                case 0x1057: {
-                       __u8 val = data[4];
+                       __u8 val;
                        tab_on_first(&first);
+                       if (sublen < 1) {
+                               printf("\t * AP setup locked: (invalid length %d)\n",
+                                      sublen);
+                               break;
+                       }
+                       val = data[4];
                        printf("\t * AP setup locked: 0x%.2x\n", val);
                        break;
                }
                case 0x1008:
                case 0x1053: {
-                       __u16 meth = (data[4] << 8) + data[5];
-                       bool comma = false;
+                       __u16 meth;
+                       bool comma;
+
+                       if (sublen < 2) {
+                               printf("\t * Config methods: (invalid length %d)\n",
+                                      sublen);
+                               break;
+                       }
+                       meth = (data[4] << 8) + data[5];
+                       comma = false;
                        tab_on_first(&first);
                        printf("\t * %sConfig methods:",
                               subtype == 0x1053 ? "Selected Registrar ": "");
@@ -2045,7 +2239,7 @@ static inline void print_p2p(const uint8_t type, uint8_t len,
                case 0x12: /* invitation flags */
                case 0xdd: /* vendor specific */
                default: {
-                       const __u8 *subdata = data + 4;
+                       const __u8 *subdata = data + 3;
                        __u16 tmplen = sublen;
 
                        tab_on_first(&first);
@@ -2183,6 +2377,44 @@ static void print_vendor(unsigned char len, unsigned char *data,
        printf("\n");
 }
 
+static void print_he_capa(const uint8_t type, uint8_t len, const uint8_t *data,
+                         const struct print_ies_data *ie_buffer)
+{
+       printf("\n");
+       print_he_capability(data, len);
+}
+
+static const struct ie_print ext_printers[] = {
+       [35] = { "HE capabilities", print_he_capa, 21, 54, BIT(PRINT_SCAN), },
+};
+
+static void print_extension(unsigned char len, unsigned char *ie,
+                           bool unknown, enum print_ie_type ptype)
+{
+       unsigned char tag;
+
+       if (len < 1) {
+               printf("\tExtension IE: <empty>\n");
+               return;
+       }
+
+       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);
+               return;
+       }
+
+       if (unknown) {
+               int i;
+
+               printf("\tUnknown Extension ID (%d):", ie[0]);
+               for (i = 1; i < len; i++)
+                       printf(" %.2x", ie[i]);
+               printf("\n");
+       }
+}
+
 void print_ies(unsigned char *ie, int ielen, bool unknown,
               enum print_ie_type ptype)
 {
@@ -2196,11 +2428,14 @@ void print_ies(unsigned char *ie, int ielen, bool unknown,
        while (ielen >= 2 && ielen - 2 >= ie[1]) {
                if (ie[0] < ARRAY_SIZE(ieprinters) &&
                    ieprinters[ie[0]].name &&
-                   ieprinters[ie[0]].flags & BIT(ptype)) {
+                   ieprinters[ie[0]].flags & BIT(ptype) &&
+                           ie[1] > 0) {
                        print_ie(&ieprinters[ie[0]],
                                 ie[0], ie[1], ie + 2, &ie_buffer);
                } 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);
                } else if (unknown) {
                        int i;
 
@@ -2287,6 +2522,7 @@ static int print_bss_handler(struct nl_msg *msg, void *arg)
        static struct nla_policy bss_policy[NL80211_BSS_MAX + 1] = {
                [NL80211_BSS_TSF] = { .type = NLA_U64 },
                [NL80211_BSS_FREQUENCY] = { .type = NLA_U32 },
+               [NL80211_BSS_FREQUENCY_OFFSET] = { .type = NLA_U32 },
                [NL80211_BSS_BSSID] = { },
                [NL80211_BSS_BEACON_INTERVAL] = { .type = NLA_U16 },
                [NL80211_BSS_CAPABILITY] = { .type = NLA_U16 },
@@ -2359,7 +2595,12 @@ static int print_bss_handler(struct nl_msg *msg, void *arg)
        }
        if (bss[NL80211_BSS_FREQUENCY]) {
                int freq = nla_get_u32(bss[NL80211_BSS_FREQUENCY]);
-               printf("\tfreq: %d\n", freq);
+               if (bss[NL80211_BSS_FREQUENCY_OFFSET])
+                       printf("\tfreq: %d.%d\n", freq,
+                           nla_get_u32(bss[NL80211_BSS_FREQUENCY_OFFSET]));
+               else
+                       printf("\tfreq: %d\n", freq);
+
                if (freq > 45000)
                        is_dmg = true;
        }
@@ -2520,7 +2761,7 @@ COMMAND(scan, dump, "[-u]",
        NL80211_CMD_GET_SCAN, NLM_F_DUMP, CIB_NETDEV, handle_scan_dump,
        "Dump the current scan results. If -u is specified, print unknown\n"
        "data in scan results.");
-COMMAND(scan, trigger, "[freq <freq>*] [duration <dur>] [ies <hex as 00:11:..>] [meshid <meshid>] [lowpri,flush,ap-force,duration-mandatory] [randomise[=<addr>/<mask>]] [ssid <ssid>*|passive]",
+COMMAND(scan, trigger, "[freq <freq>*] [duration <dur>] [ies <hex as 00:11:..>] [meshid <meshid>] [lowpri,flush,ap-force,duration-mandatory,coloc] [randomise[=<addr>/<mask>]] [ssid <ssid>*|passive]",
        NL80211_CMD_TRIGGER_SCAN, 0, CIB_NETDEV, handle_scan,
         "Trigger a scan on the given frequencies with probing for the given\n"
         "SSIDs (or wildcard if not given) unless passive scanning is requested.\n"