From 3e81b0123b4bbfedbdc1135a6a4305c347f91a3a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 9 Aug 2003 16:41:59 +0000 Subject: Initial commit git-svn-id: file:///home/lennart/svn/public/aeswepd/trunk@3 022f378f-78c4-0310-b860-d162c87e6274 --- src/assocwatch.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 src/assocwatch.c (limited to 'src/assocwatch.c') diff --git a/src/assocwatch.c b/src/assocwatch.c new file mode 100644 index 0000000..c3bf5f2 --- /dev/null +++ b/src/assocwatch.c @@ -0,0 +1,88 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "wireless.h" + +#include "util.h" +#include "assocwatch.h" +#include "nlapi.h" + +static int handle_wireless_event(int idx, uint8_t *data, int l, int (*cb) (int idx, struct hw_addr *a)) { + struct iw_event *e; + int hs; + struct hw_addr ap; + + e = (struct iw_event*) data; + hs = sizeof(struct iw_event)-sizeof(union iwreq_data); + while (l >= sizeof(struct iw_event)) { + + if (e->len < hs) { + daemon_log(LOG_ERR, "ASSOCWATCH: Recieved corrupt wireless event\n"); + return -1; + } + + switch (e->cmd) { + + case SIOCGIWAP: + if (e->len < hs + sizeof(struct sockaddr)) { + daemon_log(LOG_ERR, "ASSOCWATCH: Recieved corrupt AP wireless event\n"); + return -1; + } + + memcpy(ap.addr, e->u.ap_addr.sa_data, ETH_ALEN); + + if (cb(idx, is_assoc_ap(&ap) ? &ap : NULL) < 0) + return -1; + + return 0; + } + + l -= e->len; + e = (struct iw_event*) (((uint8_t*) e) + e->len); + } + + return 0; +} + +static int callback(struct nlmsghdr *n, void *u) { + int (*cb) (int idx, struct hw_addr *a) = u; + + if (n->nlmsg_type == RTM_NEWLINK) { + struct ifinfomsg* ifi; + struct rtattr *a; + int la; + + if (n->nlmsg_len < NLMSG_LENGTH(sizeof(struct ifinfomsg))) { + daemon_log(LOG_ERR, "ASSOCWATCH: Corrupt NETLINK message\n"); + return -1; + } + + ifi = NLMSG_DATA(n); + a = (void*) ifi + NLMSG_ALIGN(sizeof(struct ifinfomsg)); + la = NLMSG_PAYLOAD(n, sizeof(struct ifinfomsg)); + + while (RTA_OK(a, la)) { + if(a->rta_type == IFLA_WIRELESS) + handle_wireless_event(ifi->ifi_index, RTA_DATA(a), RTA_PAYLOAD(a), cb); + + a = RTA_NEXT(a, la); + } + } + + return 0; +} + + +int assocwatch_init(int (*cb) (int idx, struct hw_addr *a)) { + return nlapi_register(callback, cb); +} -- cgit