]> git.ipfire.org Git - thirdparty/iw.git/blobdiff - util.c
nan: fix memory leak
[thirdparty/iw.git] / util.c
diff --git a/util.c b/util.c
index 276c8cab96c97b9b3fa396e326222cb58275a138..2fa0b746048d34f6b7665c58cf8df6e00c90f83e 100644 (file)
--- a/util.c
+++ b/util.c
@@ -5,7 +5,7 @@
 #include "iw.h"
 #include "nl80211.h"
 
-void mac_addr_n2a(char *mac_addr, unsigned char *arg)
+void mac_addr_n2a(char *mac_addr, const unsigned char *arg)
 {
        int i, l;
 
@@ -273,6 +273,18 @@ static const char *commands[NL80211_CMD_MAX + 1] = {
        [NL80211_CMD_NAN_MATCH] = "nan_match",
        [NL80211_CMD_SET_MULTICAST_TO_UNICAST] = "set_multicast_to_unicast",
        [NL80211_CMD_UPDATE_CONNECT_PARAMS] = "update_connect_params",
+       [NL80211_CMD_SET_PMK] = "set_pmk",
+       [NL80211_CMD_DEL_PMK] = "del_pmk",
+       [NL80211_CMD_PORT_AUTHORIZED] = "port_authorized",
+       [NL80211_CMD_RELOAD_REGDB] = "reload_regdb",
+       [NL80211_CMD_EXTERNAL_AUTH] = "external_auth",
+       [NL80211_CMD_STA_OPMODE_CHANGED] = "sta_opmode_changed",
+       [NL80211_CMD_CONTROL_PORT_FRAME] = "control_port_frame",
+       [NL80211_CMD_GET_FTM_RESPONDER_STATS] = "get_ftm_responder_stats",
+       [NL80211_CMD_PEER_MEASUREMENT_START] = "peer_measurement_start",
+       [NL80211_CMD_PEER_MEASUREMENT_RESULT] = "peer_measurement_result",
+       [NL80211_CMD_PEER_MEASUREMENT_COMPLETE] = "peer_measurement_complete",
+       [NL80211_CMD_NOTIFY_RADAR] = "notify_radar",
 };
 
 static char cmdbuf[100];
@@ -368,7 +380,7 @@ static int hex2byte(const char *hex)
        return (d1 << 4) | d2;
 }
 
-static char *hex2bin(const char *hex, char *buf)
+char *hex2bin(const char *hex, char *buf)
 {
        char *result = buf;
        int d;
@@ -413,23 +425,23 @@ static int parse_cipher_suite(const char *cipher_str)
        return -EINVAL;
 }
 
-int parse_keys(struct nl_msg *msg, char **argv, int argc)
+int parse_keys(struct nl_msg *msg, char **argv[], int *argc)
 {
        struct nlattr *keys;
        int i = 0;
        bool have_default = false;
-       char *arg = *argv;
+       char *arg = **argv;
        char keybuf[13];
        int pos = 0;
 
-       if (!argc)
+       if (!*argc)
                return 1;
 
        if (!memcmp(&arg[pos], "psk", 3)) {
                char psk_keybuf[32];
                int cipher_suite, akm_suite;
 
-               if (argc != 4)
+               if (*argc < 4)
                        goto explain;
 
                pos+=3;
@@ -447,9 +459,9 @@ int parse_keys(struct nl_msg *msg, char **argv, int argc)
                NLA_PUT(msg, NL80211_ATTR_PMK, 32, psk_keybuf);
                NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE, NL80211_AUTHTYPE_OPEN_SYSTEM);
 
-               argv++;
-               argc--;
-               arg = *argv;
+               *argv += 1;
+               *argc -= 1;
+               arg = **argv;
 
                akm_suite = parse_akm_suite(arg);
                if (akm_suite < 0)
@@ -457,9 +469,9 @@ int parse_keys(struct nl_msg *msg, char **argv, int argc)
 
                NLA_PUT_U32(msg, NL80211_ATTR_AKM_SUITES, akm_suite);
 
-               argv++;
-               argc--;
-               arg = *argv;
+               *argv += 1;
+               *argc -= 1;
+               arg = **argv;
 
                cipher_suite = parse_cipher_suite(arg);
                if (cipher_suite < 0)
@@ -467,9 +479,9 @@ int parse_keys(struct nl_msg *msg, char **argv, int argc)
 
                NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITES_PAIRWISE, cipher_suite);
 
-               argv++;
-               argc--;
-               arg = *argv;
+               *argv += 1;
+               *argc -= 1;
+               arg = **argv;
 
                cipher_suite = parse_cipher_suite(arg);
                if (cipher_suite < 0)
@@ -477,6 +489,8 @@ int parse_keys(struct nl_msg *msg, char **argv, int argc)
 
                NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP, cipher_suite);
 
+               *argv += 1;
+               *argc -= 1;
                return 0;
        }
 
@@ -491,7 +505,7 @@ int parse_keys(struct nl_msg *msg, char **argv, int argc)
                struct nlattr *key = nla_nest_start(msg, ++i);
                char *keydata;
 
-               arg = *argv;
+               arg = **argv;
                pos = 0;
 
                if (!key)
@@ -514,12 +528,14 @@ int parse_keys(struct nl_msg *msg, char **argv, int argc)
                switch (strlen(keydata)) {
                case 10:
                        keydata = hex2bin(keydata, keybuf);
+                       /* fall through */
                case 5:
                        NLA_PUT_U32(msg, NL80211_KEY_CIPHER, 0x000FAC01);
                        keylen = 5;
                        break;
                case 26:
                        keydata = hex2bin(keydata, keybuf);
+                       /* fall through */
                case 13:
                        NLA_PUT_U32(msg, NL80211_KEY_CIPHER, 0x000FAC05);
                        keylen = 13;
@@ -533,15 +549,15 @@ int parse_keys(struct nl_msg *msg, char **argv, int argc)
 
                NLA_PUT(msg, NL80211_KEY_DATA, keylen, keydata);
 
-               argv++;
-               argc--;
+               *argv += 1;
+               *argc -= 1;
 
                /* one key should be TX key */
-               if (!have_default && !argc)
+               if (!have_default && !*argc)
                        NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT);
 
                nla_nest_end(msg, key);
-       } while (argc);
+       } while (*argc);
 
        nla_nest_end(msg, keys);
 
@@ -1123,3 +1139,40 @@ int get_cf1(const struct chanmode *chanmode, unsigned long freq)
 
        return cf1;
 }
+
+int parse_random_mac_addr(struct nl_msg *msg, char *addrs)
+{
+       char *a_addr, *a_mask, *sep;
+       unsigned char addr[ETH_ALEN], mask[ETH_ALEN];
+
+       if (!*addrs) {
+               /* randomise all but the multicast bit */
+               NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN,
+                       "\x00\x00\x00\x00\x00\x00");
+               NLA_PUT(msg, NL80211_ATTR_MAC_MASK, ETH_ALEN,
+                       "\x01\x00\x00\x00\x00\x00");
+               return 0;
+       }
+
+       if (*addrs != '=')
+               return 1;
+
+       addrs++;
+       sep = strchr(addrs, '/');
+       a_addr = addrs;
+
+       if (!sep)
+               return 1;
+
+       *sep = 0;
+       a_mask = sep + 1;
+       if (mac_addr_a2n(addr, a_addr) || mac_addr_a2n(mask, a_mask))
+               return 1;
+
+       NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
+       NLA_PUT(msg, NL80211_ATTR_MAC_MASK, ETH_ALEN, mask);
+
+       return 0;
+ nla_put_failure:
+       return -ENOBUFS;
+}