123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- #include "monitor.h"
- #include <linux/nl80211.h>
- #include <net/if.h>
- #include <netlink/attr.h>
- #include <netlink/genl/genl.h>
- #include <netlink/handlers.h>
- #include <netlink/msg.h>
- #include <netlink/netlink.h>
- #include <netlink/socket.h>
- #include <unistd.h>
- #include "log.h"
- static int oldval = 0.f;
- static monitor_callback *setter = NULL;
- static FILE *log_output;
- int keep_running = 1;
- static int getWifiInfo_callback(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];
- nla_parse(tb,
- NL80211_ATTR_MAX,
- genlmsg_attrdata(gnlh, 0),
- genlmsg_attrlen(gnlh, 0),
- NULL);
- if (!tb[NL80211_ATTR_STA_INFO]) {
- log_err("GET_WIFI_INFO", "sta stats missing!\n");
- return NL_SKIP;
- }
- if (nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,
- tb[NL80211_ATTR_STA_INFO], stats_policy)) {
- log_err("GET_WIFI_INFO", "failed to parse nested attributes!\n");
- return NL_SKIP;
- }
- if (sinfo[NL80211_STA_INFO_SIGNAL]) {
- ((Wifi*)arg)->signal = 100+(int8_t)nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL]);
- }
- return NL_OK;
- }
- static int getWifiStatus(Netlink *nl, Wifi *w) {
- nl->result = 1;
- struct nl_msg* msg = nlmsg_alloc();
- if (!msg) {
- log_err("GET_WIFI_STATUS", "Failed to allocate netlink message.\n");
- return -2;
- }
- genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, nl->id, 0, NLM_F_DUMP,
- NL80211_CMD_GET_STATION, 0);
- nla_put_u32(msg, NL80211_ATTR_IFINDEX, w->ifindex);
- nl_send_auto(nl->socket, msg);
- while (nl->result > 0) { nl_recvmsgs(nl->socket, nl->cb1); }
- nlmsg_free(msg);
- return 0;
- }
- void monitor(const char *ifname, monitor_callback *callback, unsigned long interval) {
- setter = callback;
- Netlink nl;
- Wifi w;
- w.ifindex = if_nametoindex(ifname); // todo it’s ioctl -> change to netlink
- nl.id = initNl80211(&nl, &w, getWifiInfo_callback);
- if (nl.id < 0) {
- log_err("MONITOR", "Error initializing netlink 802.11\n");
- exit(EXIT_FAILURE);
- }
- do {
- getWifiStatus(&nl, &w);
- if (w.signal != oldval) {
- int status = setter(oldval, w.signal, &w);
- if (status > 0)
- oldval=w.signal;
- }
- sleep(interval);
- } while(keep_running);
- log_out("MONITOR", "Exiting gracefully...\n");
- nl_cb_put(nl.cb1);
- nl_close(nl.socket);
- nl_socket_free(nl.socket);
- }
|