From 4322d8323cc41f1175ab5724b64b803a8997c495 Mon Sep 17 00:00:00 2001 From: Jan-Philipp Litza Date: Sun, 4 Dec 2016 19:51:41 +0100 Subject: [PATCH] gluon-airtime: Autodetect interfaces --- package/gluon-airtime/src/Makefile | 4 +- package/gluon-airtime/src/airtime-test.c | 20 ++++--- package/gluon-airtime/src/airtime.c | 22 +------- package/gluon-airtime/src/airtime.h | 7 +-- package/gluon-airtime/src/ifaces.c | 66 ++++++++++++++++++++++++ package/gluon-airtime/src/ifaces.h | 9 ++++ package/gluon-airtime/src/respondd.c | 25 +++++---- 7 files changed, 104 insertions(+), 49 deletions(-) create mode 100644 package/gluon-airtime/src/ifaces.c create mode 100644 package/gluon-airtime/src/ifaces.h diff --git a/package/gluon-airtime/src/Makefile b/package/gluon-airtime/src/Makefile index 025c98db..1a6c0ed0 100644 --- a/package/gluon-airtime/src/Makefile +++ b/package/gluon-airtime/src/Makefile @@ -14,10 +14,10 @@ all: respondd.so %.c: %.h # sudo apt install libnl-3-dev -airtime-test: airtime.c airtime-test.c +airtime-test: airtime.c ifaces.c airtime-test.c $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -fPIC -D_GNU_SOURCE -lnl-tiny -o $@ $^ $(LDLIBS) -respondd.so: airtime.c respondd.c +respondd.so: airtime.c ifaces.c respondd.c $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -shared -fPIC -D_GNU_SOURCE -lnl-tiny -o $@ $^ $(LDLIBS) clean: diff --git a/package/gluon-airtime/src/airtime-test.c b/package/gluon-airtime/src/airtime-test.c index 85773f9e..a82861f1 100644 --- a/package/gluon-airtime/src/airtime-test.c +++ b/package/gluon-airtime/src/airtime-test.c @@ -1,19 +1,23 @@ #include +#include #include "airtime.h" +#include "ifaces.h" void print_result(struct airtime_result *); int main(int argc, char *argv[]) { - struct airtime *a; + struct airtime_result a; + struct iface_list *ifaces; + void *freeptr; - if (argc != 3) { - fprintf(stderr,"Usage: %s \n", argv[0]); - return 1; + ifaces = get_ifaces(); + while (ifaces != NULL) { + get_airtime(&a, ifaces->ifx); + print_result(&a); + freeptr = ifaces; + ifaces = ifaces->next; + free(freeptr); } - - a = get_airtime(argv[1], argv[2]); - print_result(&a->radio0); - print_result(&a->radio1); } void print_result(struct airtime_result *result){ diff --git a/package/gluon-airtime/src/airtime.c b/package/gluon-airtime/src/airtime.c index 108d6d56..e8c18427 100644 --- a/package/gluon-airtime/src/airtime.c +++ b/package/gluon-airtime/src/airtime.c @@ -33,11 +33,6 @@ #include "airtime.h" -static struct airtime cur_airtime = { - { .frequency = 0 }, - { .frequency = 0 }, -}; - /* * Excerpt from nl80211.h: * enum nl80211_survey_info - survey information @@ -103,9 +98,9 @@ abort: return NL_SKIP; } -static int get_airtime_for_interface(struct airtime_result *result, const char *interface) { +int get_airtime(struct airtime_result *result, int ifx) { int error = 0; - int ctrl, ifx; + int ctrl; struct nl_sock *sk = NULL; struct nl_msg *msg = NULL; @@ -118,12 +113,6 @@ static int get_airtime_for_interface(struct airtime_result *result, const char * CHECK(nl_socket_modify_cb(sk, NL_CB_VALID, NL_CB_CUSTOM, survey_airtime_handler, result) == 0); CHECK(msg = nlmsg_alloc()); - /* device does not exist */ - if (!(ifx = if_nametoindex(interface))){ - error = -1; - goto out; - } - /* TODO: check return? */ genlmsg_put(msg, 0, 0, ctrl, 0, NLM_F_DUMP, NL80211_CMD_GET_SURVEY, 0); @@ -144,10 +133,3 @@ out: return error; } - -struct airtime* get_airtime(const char *wifi_0_dev, const char *wifi_1_dev) { - get_airtime_for_interface(&cur_airtime.radio0, wifi_0_dev); - get_airtime_for_interface(&cur_airtime.radio1, wifi_1_dev); - - return &cur_airtime; -} diff --git a/package/gluon-airtime/src/airtime.h b/package/gluon-airtime/src/airtime.h index c0c8bb93..c7c5fbb9 100644 --- a/package/gluon-airtime/src/airtime.h +++ b/package/gluon-airtime/src/airtime.h @@ -11,9 +11,4 @@ struct airtime_result { uint8_t noise; }; -struct airtime { - struct airtime_result radio0; - struct airtime_result radio1; -}; - -struct airtime* get_airtime(const char *radio0, const char *radio1); +int get_airtime(struct airtime_result *result, int ifx); diff --git a/package/gluon-airtime/src/ifaces.c b/package/gluon-airtime/src/ifaces.c new file mode 100644 index 00000000..cbb9ff18 --- /dev/null +++ b/package/gluon-airtime/src/ifaces.c @@ -0,0 +1,66 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "ifaces.h" + +static int iface_dump_handler(struct nl_msg *msg, struct iface_list **arg) { + struct nlattr *tb[NL80211_ATTR_MAX + 1]; + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + int wiphy; + struct iface_list **last_next; + + nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL); + + wiphy = nla_get_u32(tb[NL80211_ATTR_WIPHY]); + for (last_next = arg; *last_next != NULL; last_next = &(*last_next)->next) { + if ((*last_next)->wiphy == wiphy) + goto abort; + } + *last_next = malloc(sizeof(**last_next)); + (*last_next)->next = NULL; + (*last_next)->ifx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]); + (*last_next)->wiphy = wiphy; + +abort: + return NL_SKIP; +} + +struct iface_list *get_ifaces() { + int ctrl; + struct nl_sock *sk = NULL; + struct nl_msg *msg = NULL; + struct iface_list *ifaces = NULL; + +#define CHECK(x) { if (!(x)) { fprintf(stderr, "airtime.c: error on line %d\n", __LINE__); goto out; } } + + CHECK(sk = nl_socket_alloc()); + CHECK(genl_connect(sk) >= 0); + + CHECK(ctrl = genl_ctrl_resolve(sk, NL80211_GENL_NAME)); + CHECK(nl_socket_modify_cb(sk, NL_CB_VALID, NL_CB_CUSTOM, (nl_recvmsg_msg_cb_t) iface_dump_handler, &ifaces) == 0); + CHECK(msg = nlmsg_alloc()); + + /* TODO: check return? */ + genlmsg_put(msg, 0, 0, ctrl, 0, NLM_F_DUMP, NL80211_CMD_GET_INTERFACE, 0); + + CHECK(nl_send_auto_complete(sk, msg) >= 0); + CHECK(nl_recvmsgs_default(sk) >= 0); + +#undef CHECK + + return ifaces; + +out: + if (msg) + nlmsg_free(msg); + + if (sk) + nl_socket_free(sk); + + return NULL; +} diff --git a/package/gluon-airtime/src/ifaces.h b/package/gluon-airtime/src/ifaces.h new file mode 100644 index 00000000..ea13ee34 --- /dev/null +++ b/package/gluon-airtime/src/ifaces.h @@ -0,0 +1,9 @@ +#pragma once + +struct iface_list { + int ifx; + int wiphy; + struct iface_list *next; +}; + +struct iface_list *get_ifaces(); diff --git a/package/gluon-airtime/src/respondd.c b/package/gluon-airtime/src/respondd.c index cc4c0497..d4c0a511 100644 --- a/package/gluon-airtime/src/respondd.c +++ b/package/gluon-airtime/src/respondd.c @@ -4,9 +4,7 @@ #include #include "airtime.h" - -static const char const *wifi_0_dev = "client0"; -static const char const *wifi_1_dev = "client1"; +#include "ifaces.h" void fill_airtime_json(struct airtime_result *air, struct json_object *wireless) { struct json_object *obj = NULL; @@ -26,12 +24,10 @@ void fill_airtime_json(struct airtime_result *air, struct json_object *wireless) } static struct json_object *respondd_provider_statistics(void) { - struct airtime *airtime = NULL; + struct airtime_result airtime; struct json_object *result, *wireless; - - airtime = get_airtime(wifi_0_dev, wifi_1_dev); - if (!airtime) - return NULL; + struct iface_list *ifaces; + void *freeptr; result = json_object_new_object(); if (!result) @@ -43,11 +39,14 @@ static struct json_object *respondd_provider_statistics(void) { return NULL; } - if (airtime->radio0.frequency) - fill_airtime_json(&airtime->radio0, wireless); - - if (airtime->radio1.frequency) - fill_airtime_json(&airtime->radio1, wireless); + ifaces = get_ifaces(); + while (ifaces != NULL) { + get_airtime(&airtime, ifaces->ifx); + fill_airtime_json(&airtime, wireless); + freeptr = ifaces; + ifaces = ifaces->next; + free(freeptr); + } json_object_object_add(result, "wireless", wireless); return result;