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/iwapi.c | 225 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 225 insertions(+) create mode 100644 src/iwapi.c (limited to 'src/iwapi.c') diff --git a/src/iwapi.c b/src/iwapi.c new file mode 100644 index 0000000..5662548 --- /dev/null +++ b/src/iwapi.c @@ -0,0 +1,225 @@ +#include +#include +#include +#include +#include +#include "iwapi.h" + +int iw_set_essid(struct interface *i, const char* essid) { + struct iwreq req; + char e[IW_ESSID_MAX_SIZE + 1]; + + memset(&req, 0, sizeof(req)); + strncpy(req.ifr_ifrn.ifrn_name, i->name, IFNAMSIZ); + + if (essid && *essid) { + memset(&e, 0, sizeof(e)); + strncpy(e, essid, IW_ESSID_MAX_SIZE); + + req.u.essid.pointer = e; + req.u.essid.length = strlen(essid) + 1; + req.u.essid.flags = 1; + } + + if (ioctl(i->fd, SIOCSIWESSID, &req) < 0) { + fprintf(stderr, "ioctl(SIOCSIWESSID): %s\n", strerror(errno)); + return -1; + } + + return 0; +} + +int iw_set_mode(struct interface *i, int m) { + struct iwreq req; + + memset(&req, 0, sizeof(req)); + strncpy(req.ifr_ifrn.ifrn_name, i->name, IFNAMSIZ); + req.u.mode = m; + + if (ioctl(i->fd, SIOCSIWMODE, &req) < 0) { + fprintf(stderr, "ioctl(SIOCSIWMODE): %s\n", strerror(errno)); + return -1; + } + + return 0; +} + +int iw_set_freq(struct interface *i, struct iw_freq *f) { + struct iwreq req; + + memset(&req, 0, sizeof(req)); + strncpy(req.ifr_ifrn.ifrn_name, i->name, IFNAMSIZ); + req.u.freq = *f; + + if (ioctl(i->fd, SIOCSIWFREQ, &req) < 0) { + fprintf(stderr, "ioctl(SIOCSIWFREQ): %s\n", strerror(errno)); + return -1; + } + + return 0; +} + +int iw_set_ap(struct interface *i, struct hw_addr *ap) { + struct iwreq req; + + memset(&req, 0, sizeof(req)); + strncpy(req.ifr_ifrn.ifrn_name, i->name, IFNAMSIZ); + + req.u.ap_addr.sa_family = ARPHRD_ETHER; + memcpy(req.u.ap_addr.sa_data, ap->addr, ETH_ALEN); + + if (ioctl(i->fd, SIOCSIWAP, &req) < 0) { + fprintf(stderr, "ioctl(SIOCSIWAP): %s\n", strerror(errno)); + return -1; + } + + return 0; +} + +int iw_scan(struct interface *i) { + struct iwreq req; + + memset(&req, 0, sizeof(req)); + strncpy(req.ifr_ifrn.ifrn_name, i->name, IFNAMSIZ); + + req.u.param.flags = IW_SCAN_DEFAULT; + req.u.param.value = 0; + + if (ioctl(i->fd, SIOCSIWSCAN, &req) < 0) { + fprintf(stderr, "ioctl(SIOCSIWSCAN): %s\n", strerror(errno)); + return -1; + } + +// fprintf(stderr, "scan!\n"); + + return 0; +} + + +int iw_scan_result(struct interface *i, int (*callback)(struct ap_info* ap)) { + struct ap_info ap; + int f, l, hs; + struct iwreq req; + struct iw_event *e; + uint8_t buffer[IW_SCAN_MAX_DATA]; + + assert(i && callback); + + memset(&req, 0, sizeof(req)); + strncpy(req.ifr_ifrn.ifrn_name, i->name, IFNAMSIZ); + + req.u.data.pointer = buffer; + req.u.data.flags = 0; + req.u.data.length = sizeof(buffer); + + if (ioctl(i->fd, SIOCGIWSCAN, &req) < 0) { + if (errno == EAGAIN) + return 1; + + fprintf(stderr, "ioctl(SIOCGIWSCAN): %s\n", strerror(errno)); + return -1; + } + +// fprintf(stderr, "scan response!\n"); + + e = (struct iw_event*) req.u.data.pointer; + l = req.u.data.length; + f = 0; + hs = sizeof(struct iw_event)-sizeof(union iwreq_data); + while (l >= sizeof(struct iw_event)) { + if (e->len < hs) { + fprintf(stderr, "Recieved bogus wireless event\n"); + return -1; + } + + if (!f) + memset(&ap, 0, sizeof(ap)); + + switch (e->cmd) { + + case SIOCGIWAP: + + f = 1; + + if (e->len < hs + sizeof(struct sockaddr)) { + fprintf(stderr, "Corrupt scan result (1)\n"); + return -1; + } + + memcpy(&ap.ap, e->u.ap_addr.sa_data, ETH_ALEN); + break; + + + case SIOCGIWESSID: + + if (e->len < hs + sizeof(struct iw_point)) { + fprintf(stderr, "Corrupt scan result (2)\n"); + return -1; + } + + memset(&ap.essid, 0, sizeof(ap.essid)); + memcpy(&ap.essid, ((uint8_t*) e)+hs+sizeof(struct iw_point), MIN(sizeof(ap.essid)-1, e->len-hs-sizeof(struct iw_point))); + + f |= 2; + + break; + + case SIOCGIWMODE: + + if (e->len < hs + sizeof(__u32)) { + fprintf(stderr, "Corrupt scan result (3)\n"); + return -1; + } + + if (e->u.mode != IW_MODE_MASTER) + f = 0; // Ignore non-APs + else + f |= 4; + + break; + + case SIOCGIWFREQ: + if (e->len < hs + sizeof(struct iw_freq)) { + fprintf(stderr, "Corrupt scan result (4)\n"); + return -1; + } + + memcpy(&ap.freq, &e->u.freq, sizeof(struct iw_freq)); + f |= 8; + break; + } + + if (f == 15) { + + //fprintf(stderr, "Scan successful\n"); + + if (callback(&ap) < 0) + return -1; + + f = 0; + } + + + l -= e->len; + e = (struct iw_event*) (((uint8_t*) e) + e->len); + } + return 0; +} + +int iw_tune(struct interface *i, struct ap_info *ap) { + assert(i && ap); + + if (iw_set_mode(i, IW_MODE_INFRA) < 0) + return -1; + + if (iw_set_essid(i, ap->essid) < 0) + return -1; + + if (iw_set_freq(i, &ap->freq) < 0) + return -1; + + if (iw_set_ap(i, &ap->ap) < 0) + return -1; + + return 0; +} -- cgit