iwinfo: assign explicit length to IWINFO_*_NAMES[] to fix compile issues
[project/iwinfo.git] / iwinfo_nl80211.c
index 60537fc..67d551c 100644 (file)
@@ -31,6 +31,8 @@
 
 #define min(x, y) ((x) < (y)) ? (x) : (y)
 
+#define BIT(x) (1ULL<<(x))
+
 static struct nl80211_state *nls = NULL;
 
 static void nl80211_close(void)
@@ -216,10 +218,6 @@ static struct nl80211_msg_conveyor * nl80211_new(struct genl_family *family,
        return &cv;
 
 err:
-nla_put_failure:
-       if (cb)
-               nl_cb_put(cb);
-
        if (req)
                nlmsg_free(req);
 
@@ -268,7 +266,7 @@ static int nl80211_phy_idx_from_uci_macaddr(struct uci_section *s)
        if (!opt)
                return -1;
 
-       snprintf(buf, sizeof(buf), "/sys/class/ieee80211/*", opt);      /**/
+       snprintf(buf, sizeof(buf), "/sys/class/ieee80211/*");   /**/
        if (glob(buf, 0, NULL, &gl))
                return -1;
 
@@ -566,7 +564,7 @@ static char * nl80211_ifname2phy(const char *ifname)
 
 static char * nl80211_phy2ifname(const char *ifname)
 {
-       int fd, ifidx = -1, cifidx = -1, phyidx = -1;
+       int ifidx = -1, cifidx = -1, phyidx = -1;
        char buffer[64];
        static char nif[IFNAMSIZ] = { 0 };
 
@@ -603,7 +601,7 @@ static char * nl80211_phy2ifname(const char *ifname)
                                            ((ifidx < 0) || (cifidx < ifidx)))
                                        {
                                                ifidx = cifidx;
-                                               strncpy(nif, e->d_name, sizeof(nif));
+                                               strncpy(nif, e->d_name, sizeof(nif) - 1);
                                        }
                                }
                        }
@@ -892,10 +890,9 @@ static int __nl80211_wpactl_query(const char *ifname, ...)
 
 static char * nl80211_ifadd(const char *ifname)
 {
-       int phyidx;
        char *rv = NULL, path[PATH_MAX];
        static char nif[IFNAMSIZ] = { 0 };
-       struct nl80211_msg_conveyor *req, *res;
+       struct nl80211_msg_conveyor *req;
        FILE *sysfs;
 
        req = nl80211_msg(ifname, NL80211_CMD_NEW_INTERFACE, 0);
@@ -951,7 +948,7 @@ static void nl80211_hostapd_hup(const char *ifname)
        if (phy)
        {
                snprintf(buf, sizeof(buf), "/var/run/wifi-%s.pid", phy);
-               if ((fd = open(buf, O_RDONLY)) > 0)
+               if ((fd = open(buf, O_RDONLY)) >= 0)
                {
                        if (read(fd, buf, sizeof(buf)) > 0)
                                pid = atoi(buf);
@@ -984,7 +981,7 @@ static int nl80211_get_ssid_bssid_cb(struct nl_msg *msg, void *arg)
        struct nlattr *bss[NL80211_BSS_MAX + 1];
 
        static struct nla_policy bss_policy[NL80211_BSS_MAX + 1] = {
-               [NL80211_BSS_INFORMATION_ELEMENTS] = {                 },
+               [NL80211_BSS_INFORMATION_ELEMENTS] = { 0 },
                [NL80211_BSS_STATUS]               = { .type = NLA_U32 },
        };
 
@@ -1043,7 +1040,7 @@ static int nl80211_get_ssid(const char *ifname, char *buf)
        res = nl80211_phy2ifname(ifname);
        req = nl80211_msg(res ? res : ifname, NL80211_CMD_GET_SCAN, NLM_F_DUMP);
 
-       sb.ssid = buf;
+       sb.ssid = (unsigned char *)buf;
        *buf = 0;
 
        if (req)
@@ -1188,22 +1185,35 @@ static int nl80211_get_channel(const char *ifname, int *buf)
        return -1;
 }
 
+static int nl80211_get_txpower_cb(struct nl_msg *msg, void *arg)
+{
+       int *buf = arg;
+       struct nlattr **tb = nl80211_parse(msg);
+
+       if (tb[NL80211_ATTR_WIPHY_TX_POWER_LEVEL])
+               *buf = iwinfo_mbm2dbm(nla_get_u32(tb[NL80211_ATTR_WIPHY_TX_POWER_LEVEL]));
+
+       return NL_SKIP;
+}
 
 static int nl80211_get_txpower(const char *ifname, int *buf)
 {
-#if 0
        char *res;
-       char path[PATH_MAX];
+       struct nl80211_msg_conveyor *req;
 
-       res = nl80211_ifname2phy(ifname);
-       snprintf(path, sizeof(path), "/sys/kernel/debug/ieee80211/%s/power",
-                res ? res : ifname);
+       res = nl80211_phy2ifname(ifname);
+       req = nl80211_msg(res ? res : ifname, NL80211_CMD_GET_INTERFACE, 0);
 
-       if ((*buf = nl80211_readint(path)) > -1)
-               return 0;
-#endif
+       if (req)
+       {
+               *buf = 0;
+               nl80211_send(req, nl80211_get_txpower_cb, buf);
+               nl80211_free(req);
+               if (*buf)
+                       return 0;
+       }
 
-       return wext_ops.txpower(ifname, buf);
+       return -1;
 }
 
 
@@ -1622,6 +1632,7 @@ static int nl80211_get_assoclist_cb(struct nl_msg *msg, void *arg)
        struct nlattr **attr = nl80211_parse(msg);
        struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
        struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
+       struct nl80211_sta_flag_update *sta_flags;
 
        static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
                [NL80211_STA_INFO_INACTIVE_TIME] = { .type = NLA_U32    },
@@ -1630,6 +1641,13 @@ static int nl80211_get_assoclist_cb(struct nl_msg *msg, void *arg)
                [NL80211_STA_INFO_RX_BITRATE]    = { .type = NLA_NESTED },
                [NL80211_STA_INFO_TX_BITRATE]    = { .type = NLA_NESTED },
                [NL80211_STA_INFO_SIGNAL]        = { .type = NLA_U8     },
+               [NL80211_STA_INFO_RX_BYTES]      = { .type = NLA_U32    },
+               [NL80211_STA_INFO_TX_BYTES]      = { .type = NLA_U32    },
+               [NL80211_STA_INFO_TX_RETRIES]    = { .type = NLA_U32    },
+               [NL80211_STA_INFO_TX_FAILED]     = { .type = NLA_U32    },
+               [NL80211_STA_INFO_T_OFFSET]      = { .type = NLA_U64    },
+               [NL80211_STA_INFO_STA_FLAGS] =
+                       { .minlen = sizeof(struct nl80211_sta_flag_update) },
        };
 
        static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = {
@@ -1697,6 +1715,52 @@ static int nl80211_get_assoclist_cb(struct nl_msg *msg, void *arg)
                        if (rinfo[NL80211_RATE_INFO_SHORT_GI])
                                e->tx_rate.is_short_gi = 1;
                }
+
+               if (sinfo[NL80211_STA_INFO_RX_BYTES])
+                       e->rx_bytes = nla_get_u32(sinfo[NL80211_STA_INFO_RX_BYTES]);
+
+               if (sinfo[NL80211_STA_INFO_TX_BYTES])
+                       e->tx_bytes = nla_get_u32(sinfo[NL80211_STA_INFO_TX_BYTES]);
+
+               if (sinfo[NL80211_STA_INFO_TX_RETRIES])
+                       e->tx_retries = nla_get_u32(sinfo[NL80211_STA_INFO_TX_RETRIES]);
+
+               if (sinfo[NL80211_STA_INFO_TX_FAILED])
+                       e->tx_failed = nla_get_u32(sinfo[NL80211_STA_INFO_TX_FAILED]);
+
+               if (sinfo[NL80211_STA_INFO_T_OFFSET])
+                       e->t_offset = nla_get_u64(sinfo[NL80211_STA_INFO_T_OFFSET]);
+
+               /* Station flags */
+               if (sinfo[NL80211_STA_INFO_STA_FLAGS])
+               {
+                       sta_flags = (struct nl80211_sta_flag_update *)
+                               nla_data(sinfo[NL80211_STA_INFO_STA_FLAGS]);
+
+                       if (sta_flags->mask & BIT(NL80211_STA_FLAG_AUTHORIZED) &&
+                           sta_flags->set & BIT(NL80211_STA_FLAG_AUTHORIZED))
+                               e->is_authorized = 1;
+
+                       if (sta_flags->mask & BIT(NL80211_STA_FLAG_AUTHENTICATED) &&
+                           sta_flags->set & BIT(NL80211_STA_FLAG_AUTHENTICATED))
+                               e->is_authenticated = 1;
+
+                       if (sta_flags->mask & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) &&
+                           sta_flags->set & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE))
+                               e->is_preamble_short = 1;
+
+                       if (sta_flags->mask & BIT(NL80211_STA_FLAG_WME) &&
+                           sta_flags->set & BIT(NL80211_STA_FLAG_WME))
+                               e->is_wme = 1;
+
+                       if (sta_flags->mask & BIT(NL80211_STA_FLAG_MFP) &&
+                           sta_flags->set & BIT(NL80211_STA_FLAG_MFP))
+                               e->is_mfp = 1;
+
+                       if (sta_flags->mask & BIT(NL80211_STA_FLAG_TDLS_PEER) &&
+                           sta_flags->set & BIT(NL80211_STA_FLAG_TDLS_PEER))
+                               e->is_tdls = 1;
+               }
        }
 
        e->noise = 0; /* filled in by caller */
@@ -1944,15 +2008,15 @@ static int nl80211_get_scanlist_cb(struct nl_msg *msg, void *arg)
        static struct nla_policy bss_policy[NL80211_BSS_MAX + 1] = {
                [NL80211_BSS_TSF]                  = { .type = NLA_U64 },
                [NL80211_BSS_FREQUENCY]            = { .type = NLA_U32 },
-               [NL80211_BSS_BSSID]                = {                 },
+               [NL80211_BSS_BSSID]                = { 0 },
                [NL80211_BSS_BEACON_INTERVAL]      = { .type = NLA_U16 },
                [NL80211_BSS_CAPABILITY]           = { .type = NLA_U16 },
-               [NL80211_BSS_INFORMATION_ELEMENTS] = {                 },
+               [NL80211_BSS_INFORMATION_ELEMENTS] = { 0 },
                [NL80211_BSS_SIGNAL_MBM]           = { .type = NLA_U32 },
                [NL80211_BSS_SIGNAL_UNSPEC]        = { .type = NLA_U8  },
                [NL80211_BSS_STATUS]               = { .type = NLA_U32 },
                [NL80211_BSS_SEEN_MS_AGO]          = { .type = NLA_U32 },
-               [NL80211_BSS_BEACON_IES]           = {                 },
+               [NL80211_BSS_BEACON_IES]           = { 0 },
        };
 
        if (!tb[NL80211_ATTR_BSS] ||
@@ -2073,7 +2137,7 @@ static int wpasupp_ssid_decode(const char *in, char *out, int outlen)
                                break;
 
                        case 'e':
-                               out[len++] = '\e'; in++;
+                               out[len++] = '\033'; in++;
                                break;
 
                        case 'x':
@@ -2333,15 +2397,6 @@ static int nl80211_get_freqlist_cb(struct nl_msg *msg, void *arg)
        struct nlattr *freqs[NL80211_FREQUENCY_ATTR_MAX + 1];
        struct nlattr *band, *freq;
 
-       static struct nla_policy freq_policy[NL80211_FREQUENCY_ATTR_MAX + 1] = {
-               [NL80211_FREQUENCY_ATTR_FREQ]         = { .type = NLA_U32  },
-               [NL80211_FREQUENCY_ATTR_DISABLED]     = { .type = NLA_FLAG },
-               [NL80211_FREQUENCY_ATTR_PASSIVE_SCAN] = { .type = NLA_FLAG },
-               [NL80211_FREQUENCY_ATTR_NO_IBSS]      = { .type = NLA_FLAG },
-               [NL80211_FREQUENCY_ATTR_RADAR]        = { .type = NLA_FLAG },
-               [NL80211_FREQUENCY_ATTR_MAX_TX_POWER] = { .type = NLA_U32  },
-       };
-
        nla_for_each_nested(band, attr[NL80211_ATTR_WIPHY_BANDS], bands_remain)
        {
                nla_parse(bands, NL80211_BAND_ATTR_MAX,
@@ -2426,7 +2481,7 @@ static int nl80211_get_country(const char *ifname, char *buf)
 
 static int nl80211_get_countrylist(const char *ifname, char *buf, int *len)
 {
-       int i, count;
+       int count;
        struct iwinfo_country_entry *e = (struct iwinfo_country_entry *)buf;
        const struct iwinfo_iso3166_label *l;
 
@@ -2435,6 +2490,7 @@ static int nl80211_get_countrylist(const char *ifname, char *buf, int *len)
                e->iso3166 = l->iso3166;
                e->ccode[0] = (l->iso3166 / 256);
                e->ccode[1] = (l->iso3166 % 256);
+               e->ccode[2] = 0;
        }
 
        *len = (count * sizeof(struct iwinfo_country_entry));
@@ -2531,7 +2587,7 @@ static int nl80211_get_modelist_cb(struct nl_msg *msg, void *arg)
 static int nl80211_get_hwmodelist(const char *ifname, int *buf)
 {
        struct nl80211_msg_conveyor *req;
-       struct nl80211_modes m = { };
+       struct nl80211_modes m = { };
 
        req = nl80211_msg(ifname, NL80211_CMD_GET_WIPHY, 0);
        if (req)
@@ -2552,7 +2608,7 @@ static int nl80211_get_hwmodelist(const char *ifname, int *buf)
 static int nl80211_get_htmodelist(const char *ifname, int *buf)
 {
        struct nl80211_msg_conveyor *req;
-       struct nl80211_modes m = { };
+       struct nl80211_modes m = { };
 
        req = nl80211_msg(ifname, NL80211_CMD_GET_WIPHY, 0);
        if (req)
@@ -2639,7 +2695,7 @@ static int nl80211_get_mbssid_support(const char *ifname, int *buf)
 
 static int nl80211_get_hardware_id(const char *ifname, char *buf)
 {
-       int rv;
+       int rv = -1;
        char *res;
 
        /* Got a radioX pseudo interface, find some interface on it or create one */