]> git.ipfire.org Git - thirdparty/iw.git/commitdiff
iw: add support for VHT MU-MIMO air sniffer
authorAviya Erenfeld <aviya.erenfeld@intel.com>
Thu, 3 Dec 2015 10:11:31 +0000 (12:11 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Tue, 18 Oct 2016 05:43:20 +0000 (07:43 +0200)
Add support for MU-MIMO air sniffer by extending the
"set monitor" command, adding two options:

mumimo-groupid: for MU-MIMO-monitoring according a given MU-MIMO
                groupID

mumimo-follow-mac: for MU-MIMO-monitoring a station according
                   to its MAC address

Signed-off-by: Aviya Erenfeld <aviya.erenfeld@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
interface.c
iw.h

index 2802235b6cd31baa64aeb775e80c76c4186d80a0..dfa1d5eacd7608ace4e4f73825c1da5c53c9d8e7 100644 (file)
@@ -16,7 +16,9 @@
                        "control:  show control frames\n"\
                        "otherbss: show frames from other BSSes\n"\
                        "cook:     use cooked mode\n"\
-                       "active:   use active mode (ACK incoming unicast packets)"
+                       "active:   use active mode (ACK incoming unicast packets)\n"\
+                       "mumimo-groupid <GROUP_ID>: use MUMIMO according to a group id\n"\
+                       "mumimo-follow-mac <MAC_ADDRESS>: use MUMIMO according to a MAC address"
 
 SECTION(interface);
 
@@ -30,6 +32,55 @@ static char *mntr_flags[NL80211_MNTR_FLAG_MAX + 1] = {
        "active",
 };
 
+static int parse_mumimo_options(int *_argc, char ***_argv, struct nl_msg *msg)
+{
+       uint8_t mumimo_group[VHT_MUMIMO_GROUP_LEN];
+       unsigned char mac_addr[ETH_ALEN];
+       char **argv = *_argv;
+       int argc = *_argc;
+       int i;
+       unsigned int val;
+
+       if (strcmp(*argv, "mumimo-groupid") == 0) {
+               argc--;
+               argv++;
+               if (!argc || strlen(*argv) != VHT_MUMIMO_GROUP_LEN*2) {
+                       fprintf(stderr, "Invalid groupID: %s\n", *argv);
+                       return 1;
+               }
+
+               for (i = 0; i < VHT_MUMIMO_GROUP_LEN; i++) {
+                       if (sscanf((*argv) + i*2, "%2x", &val) != 1) {
+                               fprintf(stderr, "Failed reading groupID\n");
+                               return 1;
+                       }
+                       mumimo_group[i] = val;
+               }
+
+               NLA_PUT(msg,
+                       NL80211_ATTR_MU_MIMO_GROUP_DATA,
+                       VHT_MUMIMO_GROUP_LEN,
+                       mumimo_group);
+               argc--;
+               argv++;
+       } else if (strcmp(*argv, "mumimo-follow-mac") == 0) {
+               argc--;
+               argv++;
+               if (!argc || mac_addr_a2n(mac_addr, *argv)) {
+                       fprintf(stderr, "Invalid MAC address\n");
+                       return 1;
+               }
+               NLA_PUT(msg, NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR,
+                       ETH_ALEN, mac_addr);
+               argc--;
+               argv++;
+       }
+ nla_put_failure:
+       *_argc = argc;
+       *_argv = argv;
+       return 0;
+}
+
 static int parse_mntr_flags(int *_argc, char ***_argv,
                            struct nl_msg *msg)
 {
@@ -45,6 +96,15 @@ static int parse_mntr_flags(int *_argc, char ***_argv,
 
        while (argc) {
                int ok = 0;
+
+               /* parse MU-MIMO options */
+               err = parse_mumimo_options(&argc, &argv, msg);
+               if (err)
+                       goto out;
+               else if (!argc)
+                       break;
+
+               /* parse monitor flags */
                for (flag = __NL80211_MNTR_FLAG_INVALID;
                     flag <= NL80211_MNTR_FLAG_MAX; flag++) {
                        if (strcmp(*argv, mntr_flags[flag]) == 0) {
@@ -405,6 +465,8 @@ static int handle_interface_set(struct nl80211_state *state,
        switch (parse_mntr_flags(&argc, &argv, msg)) {
        case 0:
                return 0;
+       case 1:
+               return 1;
        case -ENOMEM:
                fprintf(stderr, "failed to allocate flags\n");
                return 2;
diff --git a/iw.h b/iw.h
index b58e8395bce60b809bf4524a17550e4e3cc21926..2837bd338d7c887c6344a5a1ec19e65542859e51 100644 (file)
--- a/iw.h
+++ b/iw.h
@@ -12,6 +12,7 @@
 #include "ieee80211.h"
 
 #define ETH_ALEN 6
+#define VHT_MUMIMO_GROUP_LEN 24
 
 /* libnl 1.x compatibility code */
 #if !defined(CONFIG_LIBNL20) && !defined(CONFIG_LIBNL30)