Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //// ----------- caller.c ------------------
- /* includes */
- int main ()
- struct wireless_stats ofs;
- while (true)
- {
- get_wireless_stats(&ofs);
- /* use retrieved data */
- sleep_seconds(10);
- }
- return 0;
- //// --------- wireless_stats.c -----------
- /* includes */
- struct wireless_stats *shared_stats;
- void get_wireless_stats(struct wireless_stats *ofs)
- {
- struct nl_sock *sk;
- struct nl_msg *msg;
- int family_id;
- int err;
- shared_stats = ofs;
- sk = nl_socket_alloc();
- genl_connect(sk);
- // WARNING, the docs say we must call genl_family_put() later and we don't!
- family_id = genl_ctrl_resolve(sk, "nl80211");
- nl_socket_modify_cb(sk, NL_CB_VALID, NL_CB_CUSTOM,
- stats_handler, NULL);
- // WARNING, we aren't cleaning it later.
- msg = nlmsg_alloc();
- genlmsg_put(msg, 0, 0, family_id, 0, NLM_F_DUMP, NL80211_CMD_GET_STATION, 0;
- NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex("mesh0"));
- // WARNING, deprecated function. Should use nl_send_auto
- err = nl_send_auto_complete(sk, msg);
- nl_recvmsgs_default(sk);
- /*
- // Question 1 scenario
- nl_socket_free(sk);
- nlsmg_free(msg);
- */
- return 0;
- // Not sure who comes here, but it isn't part of the success workflow, and is required at compilation time.
- nla_put_failure:
- nlmsg_free(msg);
- // WARNING, shouldn't I also [close and] free the socket?
- return err;
- }
- static int stats_handler(struct nl_msg *msg, void *arg)
- {
- struct nlattr *tb[NL80211_ATTR_MAX + 1];
- struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
- struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
- static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
- [NL80211_STA_INFO_INACTIVE_TIME] = { .type = NLA_U32 },
- /* [ ... ] */
- [NL80211_STA_INFO_CHAIN_SIGNAL_AVG] = { .type = NLA_NESTED },
- };
- nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
- genlmsg_attrlen(gnlh, 0), NULL);
- if (!tb[NL80211_ATTR_STA_INFO]) {
- fprintf(stderr, "sta stats missing!\n");
- return NL_SKIP;
- }
- if (nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,
- tb[NL80211_ATTR_STA_INFO],
- stats_policy)) {
- fprintf(stderr, "failed to parse nested attributes!\n");
- return NL_SKIP;
- }
- // Here I save the stats to 'shared_stats'
- if (sinfo[NL80211_STA_INFO_RX_BYTES])
- shared_stats->rx_bytes = nla_get_u32(sinfo[NL80211_STA_INFO_RX_BYTES]);
- /* [ ... ] */
- if (sinfo[NL80211_STA_INFO_PLID])
- shared_stats->mesh_plid = nla_get_u16(sinfo[NL80211_STA_INFO_PLID]);
- }
- // If I try to free 'msg' here, my program explodes at runtime
- return NL_SKIP;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement