]> git.ipfire.org Git - thirdparty/iw.git/blobdiff - phy.c
validate tx power argument is a number
[thirdparty/iw.git] / phy.c
diff --git a/phy.c b/phy.c
index 5a87024c0fef622da972a931f151d543bc86d8ce..91042b469fa72b04a01b5d9be06e77aa0cd94014 100644 (file)
--- a/phy.c
+++ b/phy.c
@@ -1,6 +1,7 @@
 #include <stdbool.h>
 #include <errno.h>
 #include <net/if.h>
+#include <strings.h>
 
 #include <netlink/genl/genl.h>
 #include <netlink/genl/family.h>
@@ -31,6 +32,7 @@ COMMAND(set, name, "<new name>", NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_name,
 static int handle_freqchan(struct nl_msg *msg, bool chan,
                           int argc, char **argv)
 {
+       char *end;
        static const struct {
                const char *name;
                unsigned int val;
@@ -57,7 +59,12 @@ static int handle_freqchan(struct nl_msg *msg, bool chan,
                        return 1;
        }
 
-       freq = strtoul(argv[0], NULL, 10);
+       if (!*argv[0])
+               return 1;
+       freq = strtoul(argv[0], &end, 10);
+       if (*end)
+               return 1;
+
        if (chan)
                freq = ieee80211_channel_to_frequency(freq);
 
@@ -104,8 +111,15 @@ static int handle_fragmentation(struct nl80211_state *state,
 
        if (strcmp("off", argv[0]) == 0)
                frag = -1;
-       else
-               frag = strtoul(argv[0], NULL, 10);
+       else {
+               char *end;
+
+               if (!*argv[0])
+                       return 1;
+               frag = strtoul(argv[0], &end, 10);
+               if (*end != '\0')
+                       return 1;
+       }
 
        NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD, frag);
 
@@ -128,8 +142,15 @@ static int handle_rts(struct nl80211_state *state,
 
        if (strcmp("off", argv[0]) == 0)
                rts = -1;
-       else
-               rts = strtoul(argv[0], NULL, 10);
+       else {
+               char *end;
+
+               if (!*argv[0])
+                       return 1;
+               rts = strtoul(argv[0], &end, 10);
+               if (*end != '\0')
+                       return 1;
+       }
 
        NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, rts);
 
@@ -151,6 +172,9 @@ static int handle_netns(struct nl80211_state *state,
        if (argc != 1)
                return 1;
 
+       if (!*argv[0])
+               return 1;
+
        NLA_PUT_U32(msg, NL80211_ATTR_PID,
                    strtoul(argv[0], &end, 10)); 
 
@@ -170,15 +194,21 @@ static int handle_coverage(struct nl80211_state *state,
                        struct nl_msg *msg,
                        int argc, char **argv)
 {
+       char *end;
        unsigned int coverage;
 
        if (argc != 1)
                return 1;
 
-       coverage = strtoul(argv[0], NULL, 10);
+       if (!*argv[0])
+               return 1;
+       coverage = strtoul(argv[0], &end, 10);
        if (coverage > 255)
                return 1;
 
+       if (*end)
+               return 1;
+
        NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_COVERAGE_CLASS, coverage);
 
        return 0;
@@ -195,12 +225,19 @@ static int handle_distance(struct nl80211_state *state,
                        struct nl_msg *msg,
                        int argc, char **argv)
 {
+       char *end;
        unsigned int distance, coverage;
 
        if (argc != 1)
                return 1;
 
-       distance = strtoul(argv[0], NULL, 10);
+       if (!*argv[0])
+               return 1;
+
+       distance = strtoul(argv[0], &end, 10);
+
+       if (*end)
+               return 1;
 
        /*
         * Divide double the distance by the speed of light in m/usec (300) to
@@ -222,3 +259,93 @@ COMMAND(set, distance, "<distance>",
        NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_distance,
        "Set appropriate coverage class for given link distance in meters.\n"
        "Valid values: 0 - 114750");
+
+static int handle_txpower(struct nl80211_state *state,
+                         struct nl_cb *cb,
+                         struct nl_msg *msg,
+                         int argc, char **argv)
+{
+       enum nl80211_tx_power_setting type;
+       int mbm;
+
+       /* get the required args */
+       if (argc != 1 && argc != 2)
+               return 1;
+
+       if (!strcmp(argv[0], "auto"))
+               type = NL80211_TX_POWER_AUTOMATIC;
+       else if (!strcmp(argv[0], "fixed"))
+               type = NL80211_TX_POWER_FIXED;
+       else if (!strcmp(argv[0], "limit"))
+               type = NL80211_TX_POWER_LIMITED;
+       else {
+               printf("Invalid parameter: %s\n", argv[0]);
+               return 2;
+       }
+
+       NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_TX_POWER_SETTING, type);
+
+       if (type != NL80211_TX_POWER_AUTOMATIC) {
+               char *endptr;
+               if (argc != 2) {
+                       printf("Missing TX power level argument.\n");
+                       return 2;
+               }
+
+               mbm = strtol(argv[1], &endptr, 10);
+               if (!*endptr)
+                       return 2;
+               NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_TX_POWER_LEVEL, mbm);
+       } else if (argc != 1)
+               return 1;
+
+       return 0;
+
+ nla_put_failure:
+       return -ENOBUFS;
+}
+COMMAND(set, txpower, "<auto|fixed|limit> [<tx power in mBm>]",
+       NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_txpower,
+       "Specify transmit power level and setting type.");
+COMMAND(set, txpower, "<auto|fixed|limit> [<tx power in mBm>]",
+       NL80211_CMD_SET_WIPHY, 0, CIB_NETDEV, handle_txpower,
+       "Specify transmit power level and setting type.");
+
+static int handle_antenna(struct nl80211_state *state,
+                         struct nl_cb *cb,
+                         struct nl_msg *msg,
+                         int argc, char **argv)
+{
+       char *end;
+       uint32_t tx_ant = 0, rx_ant = 0;
+
+       if (argc == 1 && strcmp(argv[0], "all") == 0) {
+               tx_ant = 0xffffffff;
+               rx_ant = 0xffffffff;
+       } else if (argc == 1) {
+               tx_ant = rx_ant = strtoul(argv[0], &end, 0);
+               if (*end)
+                       return 1;
+       }
+       else if (argc == 2) {
+               tx_ant = strtoul(argv[0], &end, 0);
+               if (*end)
+                       return 1;
+               rx_ant = strtoul(argv[1], &end, 0);
+               if (*end)
+                       return 1;
+       } else
+               return 1;
+
+       NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_ANTENNA_TX, tx_ant);
+       NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_ANTENNA_RX, rx_ant);
+
+       return 0;
+
+ nla_put_failure:
+       return -ENOBUFS;
+}
+COMMAND(set, antenna, "<bitmap> | all | <tx bitmap> <rx bitmap>",
+       NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_antenna,
+       "Set a bitmap of allowed antennas to use for TX and RX.\n"
+       "The driver may reject antenna configurations it cannot support.");