Advertisement
rala

netlink issue

Jun 12th, 2015
283
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.82 KB | None | 0 0
  1. //// ----------- caller.c ------------------
  2. /* includes */
  3. int main ()
  4.     struct wireless_stats ofs;
  5.     while (true)
  6.     {
  7.         get_wireless_stats(&ofs);
  8.         /* use retrieved data */
  9.    
  10.         sleep_seconds(10);
  11.     }
  12. return 0;
  13.  
  14. //// --------- wireless_stats.c -----------
  15. /* includes */
  16. struct wireless_stats *shared_stats;
  17.  
  18. void get_wireless_stats(struct wireless_stats *ofs)
  19. {
  20.     struct nl_sock *sk;
  21.     struct nl_msg *msg;
  22.     int family_id;
  23.     int err;
  24.  
  25.     shared_stats = ofs;
  26.     sk = nl_socket_alloc();
  27.     genl_connect(sk);
  28.  
  29.     // WARNING, the docs say we must call genl_family_put() later and we don't!    
  30.     family_id = genl_ctrl_resolve(sk, "nl80211");
  31.    
  32.     nl_socket_modify_cb(sk, NL_CB_VALID, NL_CB_CUSTOM,
  33.         stats_handler, NULL);
  34.    
  35.     // WARNING, we aren't cleaning it later.
  36.     msg = nlmsg_alloc();
  37.     genlmsg_put(msg, 0, 0, family_id, 0, NLM_F_DUMP, NL80211_CMD_GET_STATION, 0;
  38.     NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex("mesh0"));
  39.    
  40.     // WARNING, deprecated function. Should use nl_send_auto
  41.     err = nl_send_auto_complete(sk, msg);
  42.     nl_recvmsgs_default(sk);
  43.     /*
  44.     // Question 1 scenario
  45.     nl_socket_free(sk);
  46.     nlsmg_free(msg);
  47.     */
  48.     return 0;
  49.    
  50.     // Not sure who comes here, but it isn't part of the success workflow, and is required at compilation time.
  51. nla_put_failure:
  52.     nlmsg_free(msg);
  53.     // WARNING, shouldn't I also [close and] free the socket?
  54.     return err;
  55. }
  56.  
  57. static int stats_handler(struct nl_msg *msg, void *arg)
  58. {
  59.     struct nlattr *tb[NL80211_ATTR_MAX + 1];
  60.     struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
  61.     struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
  62.    
  63.     static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
  64.         [NL80211_STA_INFO_INACTIVE_TIME] = { .type = NLA_U32 },
  65.         /* [ ... ] */
  66.         [NL80211_STA_INFO_CHAIN_SIGNAL_AVG] = { .type = NLA_NESTED },
  67.     };
  68.  
  69.     nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
  70.           genlmsg_attrlen(gnlh, 0), NULL);
  71.  
  72.     if (!tb[NL80211_ATTR_STA_INFO]) {
  73.         fprintf(stderr, "sta stats missing!\n");
  74.         return NL_SKIP;
  75.     }
  76.     if (nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,
  77.                  tb[NL80211_ATTR_STA_INFO],
  78.                  stats_policy)) {
  79.         fprintf(stderr, "failed to parse nested attributes!\n");
  80.         return NL_SKIP;
  81.     }
  82.  
  83.     // Here I save the stats to 'shared_stats'
  84.    
  85.     if (sinfo[NL80211_STA_INFO_RX_BYTES])
  86.         shared_stats->rx_bytes = nla_get_u32(sinfo[NL80211_STA_INFO_RX_BYTES]);
  87.  
  88.     /* [ ... ] */
  89.  
  90.     if (sinfo[NL80211_STA_INFO_PLID])
  91.         shared_stats->mesh_plid = nla_get_u16(sinfo[NL80211_STA_INFO_PLID]);
  92.     }
  93.    
  94.     // If I try to free 'msg' here, my program explodes at runtime
  95.    
  96.     return NL_SKIP;
  97. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement