X-Git-Url: http://git.archive.openwrt.org/?a=blobdiff_plain;ds=sidebyside;f=iwinfo_nl80211.c;h=63b70d5bed89df107dd3fc379bc23d8902a703fc;hb=fd9e17be0c43bd6b8df5371f0b353747bc563874;hp=60537fc4dc4a1b703b3c08745013bd422aafe18d;hpb=5aef442328121483ac0b7925c0422e92788c9e7b;p=project%2Fiwinfo.git diff --git a/iwinfo_nl80211.c b/iwinfo_nl80211.c index 60537fc..63b70d5 100644 --- a/iwinfo_nl80211.c +++ b/iwinfo_nl80211.c @@ -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); @@ -247,6 +245,9 @@ static int nl80211_phy_idx_from_uci_path(struct uci_section *s) snprintf(buf, sizeof(buf), "/sys/devices/%s/ieee80211/*/index", opt); /**/ if (glob(buf, 0, NULL, &gl)) + snprintf(buf, sizeof(buf), "/sys/devices/platform/%s/ieee80211/*/index", opt); /**/ + + if (glob(buf, 0, NULL, &gl)) return -1; if (gl.gl_pathc > 0) @@ -268,7 +269,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 +567,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 +604,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 +893,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 +951,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 +984,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 +1043,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 +1188,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; } @@ -1615,6 +1628,48 @@ static int nl80211_get_phyname(const char *ifname, char *buf) } +static void nl80211_parse_rateinfo(struct nlattr **ri, + struct iwinfo_rate_entry *re) +{ + if (ri[NL80211_RATE_INFO_BITRATE32]) + re->rate = nla_get_u32(ri[NL80211_RATE_INFO_BITRATE32]) * 100; + else if (ri[NL80211_RATE_INFO_BITRATE]) + re->rate = nla_get_u16(ri[NL80211_RATE_INFO_BITRATE]) * 100; + + if (ri[NL80211_RATE_INFO_VHT_MCS]) + { + re->is_vht = 1; + re->mcs = nla_get_u8(ri[NL80211_RATE_INFO_VHT_MCS]); + + if (ri[NL80211_RATE_INFO_VHT_NSS]) + re->nss = nla_get_u8(ri[NL80211_RATE_INFO_VHT_NSS]); + } + else if (ri[NL80211_RATE_INFO_MCS]) + { + re->is_ht = 1; + re->mcs = nla_get_u8(ri[NL80211_RATE_INFO_MCS]); + } + + if (ri[NL80211_RATE_INFO_5_MHZ_WIDTH]) + re->mhz = 5; + else if (ri[NL80211_RATE_INFO_10_MHZ_WIDTH]) + re->mhz = 10; + else if (ri[NL80211_RATE_INFO_40_MHZ_WIDTH]) + re->mhz = 40; + else if (ri[NL80211_RATE_INFO_80_MHZ_WIDTH]) + re->mhz = 80; + else if (ri[NL80211_RATE_INFO_80P80_MHZ_WIDTH] || + ri[NL80211_RATE_INFO_160_MHZ_WIDTH]) + re->mhz = 160; + else + re->mhz = 20; + + if (ri[NL80211_RATE_INFO_SHORT_GI]) + re->is_short_gi = 1; + + re->is_40mhz = (re->mhz == 40); +} + static int nl80211_get_assoclist_cb(struct nl_msg *msg, void *arg) { struct nl80211_array_buf *arr = arg; @@ -1622,6 +1677,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 +1686,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] = { @@ -1665,37 +1728,57 @@ static int nl80211_get_assoclist_cb(struct nl_msg *msg, void *arg) if (sinfo[NL80211_STA_INFO_RX_BITRATE] && !nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_RX_BITRATE], rate_policy)) - { - if (rinfo[NL80211_RATE_INFO_BITRATE]) - e->rx_rate.rate = - nla_get_u16(rinfo[NL80211_RATE_INFO_BITRATE]) * 100; - - if (rinfo[NL80211_RATE_INFO_MCS]) - e->rx_rate.mcs = nla_get_u8(rinfo[NL80211_RATE_INFO_MCS]); - - if (rinfo[NL80211_RATE_INFO_40_MHZ_WIDTH]) - e->rx_rate.is_40mhz = 1; - - if (rinfo[NL80211_RATE_INFO_SHORT_GI]) - e->rx_rate.is_short_gi = 1; - } + nl80211_parse_rateinfo(rinfo, &e->rx_rate); if (sinfo[NL80211_STA_INFO_TX_BITRATE] && !nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_TX_BITRATE], rate_policy)) + nl80211_parse_rateinfo(rinfo, &e->tx_rate); + + 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]) { - if (rinfo[NL80211_RATE_INFO_BITRATE]) - e->tx_rate.rate = - nla_get_u16(rinfo[NL80211_RATE_INFO_BITRATE]) * 100; + 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 (rinfo[NL80211_RATE_INFO_MCS]) - e->tx_rate.mcs = nla_get_u8(rinfo[NL80211_RATE_INFO_MCS]); + 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 (rinfo[NL80211_RATE_INFO_40_MHZ_WIDTH]) - e->tx_rate.is_40mhz = 1; + if (sta_flags->mask & BIT(NL80211_STA_FLAG_WME) && + sta_flags->set & BIT(NL80211_STA_FLAG_WME)) + e->is_wme = 1; - if (rinfo[NL80211_RATE_INFO_SHORT_GI]) - e->tx_rate.is_short_gi = 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; } } @@ -1944,15 +2027,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 +2156,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 +2416,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 +2500,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 +2509,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 +2606,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 = { 0 }; req = nl80211_msg(ifname, NL80211_CMD_GET_WIPHY, 0); if (req) @@ -2552,7 +2627,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 = { 0 }; req = nl80211_msg(ifname, NL80211_CMD_GET_WIPHY, 0); if (req) @@ -2639,7 +2714,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 */