]> git.ipfire.org Git - thirdparty/iw.git/commitdiff
show interface combinations
authorJohannes Berg <johannes.berg@intel.com>
Fri, 13 May 2011 14:53:51 +0000 (16:53 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Tue, 24 May 2011 15:50:21 +0000 (08:50 -0700)
info.c

diff --git a/info.c b/info.c
index b9c08b5a1fb570f80a0e3710a1d09fea6e8d18da..aa2812af5aec0bec3ebc8af2f970a080949197e5 100644 (file)
--- a/info.c
+++ b/info.c
@@ -186,6 +186,80 @@ static int print_phy_handler(struct nl_msg *msg, void *arg)
                        printf("\t\t * %s\n", iftype_name(nla_type(nl_mode)));
        }
 
+       if (tb_msg[NL80211_ATTR_SOFTWARE_IFTYPES]) {
+               printf("\tsoftware interface modes (can always be added):\n");
+               nla_for_each_nested(nl_mode, tb_msg[NL80211_ATTR_SOFTWARE_IFTYPES], rem_mode)
+                       printf("\t\t * %s\n", iftype_name(nla_type(nl_mode)));
+       }
+
+       if (tb_msg[NL80211_ATTR_INTERFACE_COMBINATIONS]) {
+               struct nlattr *nl_combi;
+               int rem_combi;
+
+               printf("\tvalid interface combinations:\n");
+
+               nla_for_each_nested(nl_combi, tb_msg[NL80211_ATTR_INTERFACE_COMBINATIONS], rem_combi) {
+                       static struct nla_policy iface_combination_policy[NUM_NL80211_IFACE_COMB] = {
+                               [NL80211_IFACE_COMB_LIMITS] = { .type = NLA_NESTED },
+                               [NL80211_IFACE_COMB_MAXNUM] = { .type = NLA_U32 },
+                               [NL80211_IFACE_COMB_STA_AP_BI_MATCH] = { .type = NLA_FLAG },
+                               [NL80211_IFACE_COMB_NUM_CHANNELS] = { .type = NLA_U32 },
+                       };
+                       struct nlattr *tb_comb[NUM_NL80211_IFACE_COMB];
+                       static struct nla_policy iface_limit_policy[NUM_NL80211_IFACE_LIMIT] = {
+                               [NL80211_IFACE_LIMIT_TYPES] = { .type = NLA_NESTED },
+                               [NL80211_IFACE_LIMIT_MAX] = { .type = NLA_U32 },
+                       };
+                       struct nlattr *tb_limit[NUM_NL80211_IFACE_LIMIT];
+                       struct nlattr *nl_limit;
+                       int err, rem_limit;
+                       bool comma = false;
+
+                       printf("\t\t * ");
+
+                       err = nla_parse_nested(tb_comb, MAX_NL80211_IFACE_COMB,
+                                              nl_combi, iface_combination_policy);
+                       if (err || !tb_comb[NL80211_IFACE_COMB_LIMITS] ||
+                           !tb_comb[NL80211_IFACE_COMB_MAXNUM] ||
+                           !tb_comb[NL80211_IFACE_COMB_NUM_CHANNELS]) {
+                               printf(" <failed to parse>\n");
+                               goto broken_combination;
+                       }
+
+                       nla_for_each_nested(nl_limit, tb_comb[NL80211_IFACE_COMB_LIMITS], rem_limit) {
+                               bool ift_comma = false;
+
+                               err = nla_parse_nested(tb_limit, MAX_NL80211_IFACE_LIMIT,
+                                                      nl_limit, iface_limit_policy);
+                               if (err || !tb_limit[NL80211_IFACE_LIMIT_TYPES]) {
+                                       printf("<failed to parse>\n");
+                                       goto broken_combination;
+                               }
+
+                               if (comma)
+                                       printf(", ");
+                               comma = true;
+                               printf("#{");
+
+                               nla_for_each_nested(nl_mode, tb_limit[NL80211_IFACE_LIMIT_TYPES], rem_mode) {
+                                       printf("%s %s", ift_comma ? "," : "",
+                                               iftype_name(nla_type(nl_mode)));
+                                       ift_comma = true;
+                               }
+                               printf(" } <= %u", nla_get_u32(tb_limit[NL80211_IFACE_LIMIT_MAX]));
+                       }
+                       printf(",\n\t\t   ");
+
+                       printf("total <= %d, #channels <= %d%s\n",
+                               nla_get_u32(tb_comb[NL80211_IFACE_COMB_MAXNUM]),
+                               nla_get_u32(tb_comb[NL80211_IFACE_COMB_NUM_CHANNELS]),
+                               tb_comb[NL80211_IFACE_COMB_STA_AP_BI_MATCH] ?
+                                       ", STA/AP BI must match" : "");
+broken_combination:
+                       ;
+               }
+       }
+
        if (tb_msg[NL80211_ATTR_SUPPORTED_COMMANDS]) {
                printf("\tSupported commands:\n");
                nla_for_each_nested(nl_cmd, tb_msg[NL80211_ATTR_SUPPORTED_COMMANDS], rem_cmd)