]> git.ipfire.org Git - thirdparty/iw.git/commitdiff
add interface get command
authorJohannes Berg <johannes@sipsolutions.net>
Tue, 16 Sep 2008 12:50:11 +0000 (14:50 +0200)
committerJohannes Berg <johannes@sipsolutions.net>
Tue, 16 Sep 2008 12:50:11 +0000 (14:50 +0200)
info.c
interface.c
iw.h
util.c

diff --git a/info.c b/info.c
index 694a5584cf967e7d403fdc78b6a43e95649ca213..fa2a69622ad1699a552a48a9161b9cd67ed7daab 100644 (file)
--- a/info.c
+++ b/info.c
@@ -42,17 +42,6 @@ static int print_phy_handler(struct nl_msg *msg, void *arg)
                [NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE] = { .type = NLA_FLAG },
        };
 
-       static const char *ifmodes[NL80211_IFTYPE_MAX + 1] = {
-               "unspecified",
-               "IBSS",
-               "Station",
-               "AP",
-               "AP(VLAN)",
-               "WDS",
-               "Monitor",
-               "mesh point"
-       };
-
        struct nlattr *nl_band;
        struct nlattr *nl_freq;
        struct nlattr *nl_rate;
@@ -117,12 +106,8 @@ static int print_phy_handler(struct nl_msg *msg, void *arg)
                return NL_SKIP;
 
        printf("Supported interface modes:\n");
-       nla_for_each_nested(nl_mode, tb_msg[NL80211_ATTR_SUPPORTED_IFTYPES], rem_mode) {
-               if (nl_mode->nla_type > NL80211_IFTYPE_MAX)
-                       printf("\t * Unknown mode (%d)\n", nl_mode->nla_type);
-               else
-                       printf("\t * %s\n", ifmodes[nl_mode->nla_type]);
-       }
+       nla_for_each_nested(nl_mode, tb_msg[NL80211_ATTR_SUPPORTED_IFTYPES], rem_mode)
+               printf("\t * %s\n", iftype_name(nl_mode->nla_type));
 
        return NL_SKIP;
 }
@@ -141,7 +126,7 @@ int handle_info(struct nl80211_state *state, char *phy, char *dev)
 {
        struct nl_msg *msg;
        int err = -1;
-       struct nl_cb *cb = NULL;
+       struct nl_cb *cb;
        int finished;
 
        msg = nlmsg_alloc();
index f1b038c814d83963f55dac16fe3a7ec15372b711..a9c1731ad078a6a9d35b8ffe079764aa2fc6a590 100644 (file)
@@ -170,6 +170,84 @@ static int handle_interface_del(struct nl80211_state *state,
        return 0;
 }
 
+static int print_iface_handler(struct nl_msg *msg, void *arg)
+{
+       struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
+       struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
+
+       nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
+                 genlmsg_attrlen(gnlh, 0), NULL);
+
+       if (tb_msg[NL80211_ATTR_IFNAME])
+               printf("Interface %s\n", nla_get_string(tb_msg[NL80211_ATTR_IFNAME]));
+       if (tb_msg[NL80211_ATTR_IFINDEX])
+               printf("\tifindex %d\n", nla_get_u32(tb_msg[NL80211_ATTR_IFINDEX]));
+       if (tb_msg[NL80211_ATTR_IFTYPE])
+               printf("\ttype %s\n", iftype_name(nla_get_u32(tb_msg[NL80211_ATTR_IFTYPE])));
+
+       return NL_SKIP;
+}
+
+static int ack_wait_handler(struct nl_msg *msg, void *arg)
+{
+       int *finished = arg;
+
+       *finished = 1;
+       return NL_STOP;
+}
+
+static int handle_interface_info(struct nl80211_state *state,
+                                char *phy, char *dev,
+                                int argc, char **argv, int flags)
+{
+       int err = -ENOBUFS;
+       struct nl_msg *msg;
+       struct nl_cb *cb = NULL;
+       int finished = 0;
+
+       if (argc) {
+               fprintf(stderr, "too many arguments\n");
+               return -1;
+       }
+
+        msg = nlmsg_alloc();
+       if (!msg)
+               return -1;
+
+       genlmsg_put(msg, 0, 0, genl_family_get_id(state->nl80211), 0,
+                   flags, NL80211_CMD_GET_INTERFACE, 0);
+       if (!dev) {
+               fprintf(stderr, "need device\n");
+               nlmsg_free(msg);
+               return -1;
+       }
+       NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(dev));
+
+       cb = nl_cb_alloc(NL_CB_CUSTOM);
+       if (!cb)
+               goto out;
+
+       if (nl_send_auto_complete(state->nl_handle, msg) < 0)
+               goto out;
+
+       nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_iface_handler, NULL);
+       nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_wait_handler, &finished);
+
+       err = nl_recvmsgs(state->nl_handle, cb);
+
+       if (!finished)
+               err = nl_wait_for_ack(state->nl_handle);
+
+       if (err)
+               fprintf(stderr, "failed to get information: %d\n", err);
+
+ out:
+ nla_put_failure:
+       nlmsg_free(msg);
+       nl_cb_put(cb);
+       return 0;
+}
+
 int handle_interface(struct nl80211_state *state,
                     char *phy, char *dev, int argc, char **argv)
 {
@@ -187,6 +265,10 @@ int handle_interface(struct nl80211_state *state,
                return handle_interface_add(state, phy, dev, argc, argv);
        else if (strcmp(cmd, "del") == 0)
                return handle_interface_del(state, phy, dev, argc, argv);
+       else if (strcmp(cmd, "get") == 0)
+               return handle_interface_info(state, phy, dev, argc, argv, 0);
+       else if (strcmp(cmd, "dump") == 0)
+               return handle_interface_info(state, phy, dev, argc, argv, NLM_F_DUMP);
 
        printf("invalid interface command %s\n", cmd);
        return -1;
diff --git a/iw.h b/iw.h
index e02305990a3b48e5954156339b0aa287d939193f..f4f5b3e930a26c71bfa04230058d08b362eff860 100644 (file)
--- a/iw.h
+++ b/iw.h
@@ -1,6 +1,7 @@
 #ifndef __IW_H
 #define __IW_H
 
+#include <linux/nl80211.h>
 #include <netlink/genl/genl.h>
 #include <netlink/genl/family.h>
 #include <netlink/genl/ctrl.h>
@@ -31,4 +32,6 @@ int handle_reg(struct nl80211_state *state,
 int mac_addr_a2n(unsigned char *mac_addr, char *arg);
 int mac_addr_n2a(char *mac_addr, unsigned char *arg);
 
+const char *iftype_name(enum nl80211_iftype iftype);
+
 #endif /* __IW_H */
diff --git a/util.c b/util.c
index 7f0df56ef9ef8694e24eec1dcbfa38879c2bbffd..0212867a2914116869f9e42140841e1621ff7e39 100644 (file)
--- a/util.c
+++ b/util.c
@@ -1,3 +1,4 @@
+#include <linux/nl80211.h>
 #include "iw.h"
 
 int mac_addr_n2a(char *mac_addr, unsigned char *arg)
@@ -43,3 +44,24 @@ int mac_addr_a2n(unsigned char *mac_addr, char *arg)
 
        return 0;
 }
+
+static const char *ifmodes[NL80211_IFTYPE_MAX + 1] = {
+       "unspecified",
+       "IBSS",
+       "Station",
+       "AP",
+       "AP(VLAN)",
+       "WDS",
+       "Monitor",
+       "mesh point"
+};
+
+static char modebuf[100];
+
+const char *iftype_name(enum nl80211_iftype iftype)
+{
+       if (iftype <= NL80211_IFTYPE_MAX)
+               return ifmodes[iftype];
+       sprintf(modebuf, "Unknown mode (%d)", iftype);
+       return modebuf;
+}