summaryrefslogtreecommitdiffstats
path: root/src/interface.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/interface.c')
-rw-r--r--src/interface.c88
1 files changed, 88 insertions, 0 deletions
diff --git a/src/interface.c b/src/interface.c
new file mode 100644
index 0000000..5fa7dfb
--- /dev/null
+++ b/src/interface.c
@@ -0,0 +1,88 @@
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+
+#include "interface.h"
+#include "util.h"
+
+struct interface *interface_open(char *name) {
+ struct interface* i = NULL;
+
+ if (!(i = (struct interface*) malloc(sizeof(struct interface))))
+ return NULL;
+
+ memset(i, 0, sizeof(struct interface));
+ strncpy(i->name, name, IFNAMSIZ);
+
+ if ((i->fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
+ fprintf(stderr, "socket(): %s\n", strerror(errno));
+ goto fail;
+ }
+
+ return i;
+
+fail:
+
+ if (i)
+ interface_close(i);
+
+ return NULL;
+}
+
+void interface_close(struct interface *i) {
+ assert(i);
+
+ if (i->fd >= 0)
+ close(i->fd);
+
+ free(i);
+}
+
+int interface_is_assoc(struct interface *i, struct hw_addr *ap) {
+ struct hw_addr ap2;
+ struct iwreq req;
+ struct iw_statistics q;
+
+ assert(i);
+
+ if (ap)
+ memset(ap->addr, 0, ETH_ALEN);
+
+ memset(&req, 0, sizeof(req));
+ strncpy(req.ifr_ifrn.ifrn_name, i->name, IFNAMSIZ);
+
+ if (ioctl(i->fd, SIOCGIWAP, &req) < 0) {
+ fprintf(stderr, "Failed to get AP address\n");
+ return -1;
+ }
+
+ memcpy(ap2.addr, &(req.u.ap_addr.sa_data), ETH_ALEN);
+
+ if (!is_assoc_ap(&ap2))
+ return 0;
+
+ memset(&req, 0, sizeof(req));
+ strncpy(req.ifr_ifrn.ifrn_name, i->name, IFNAMSIZ);
+
+ req.u.data.pointer = (caddr_t) &q;
+ req.u.data.length = sizeof(q);
+ req.u.data.flags = 1;
+
+ if (ioctl(i->fd, SIOCGIWSTATS, &req) < 0) {
+ fprintf(stderr, "Failed to get interface quality\n");
+ return -1;
+ }
+
+
+ if (q.qual.qual <= 0)
+ return 0;
+
+ if (ap)
+ memcpy(ap->addr, ap2.addr, ETH_ALEN);
+
+ return 1;
+}